Twinklebear / webgl-volume-raycaster

A WebGL Volume Raycaster

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

render result has some noises

polluxll opened this issue · comments

I add a new data for sample, and set volDims = [172, 128, 12],this is the result picture.
volumn

I do use a hash to add some per-pixel offset and noise which you can try disabling, but without that you'll see some more structured artifact from the sampling. That might be similar to what you see there.

It could also be due to the small size of the volume, just 12 voxels along z is pretty small. So you might be able to change the volume_scale uniform to resize it properly. Is it a subset of some larger volume? Or it has some voxel scaling that should be applied?

Very thanks for reply,the data from weather forecasting, it has only 12 levles on z axis.
A curved shape appears when I changed the volume_scale .
var volScale = [volDims[0] / longestAxis, volDims[1] / longestAxis,
volDims[2] / longestAxis/10
];
volumn

Interesting, that my be more likely to be some aliasing effects from the camera ray samples. Since I take a fixed step size, you can actually see this without the hashing enabled as some kind of half-spheres along the dataset. The hash helps break this up and replace the aliasing with noise, but it might not work as well for such thin datasets.

Finally,I use a linear interpolation for my data on z axis.
The webgl2 cann't be supported by all browsers(https://caniuse.com/#search=webgl2), does this code can be used by weblg1?

Unfortunately no, this requires WebGL2 for 3D texture support, since they weren't available in WebGL1. It is possible to work around this by splitting the 3D texture into a bunch of 2D slices instead and putting them in a 2D texture array (I think this is supported on WebGL1?). However, you'll have to manually do the interpolation between slices since you won't get the trilinear interpolation done for you now (since they're separate 2D textures). This site http://www.lebarba.com/ has a write up on how it works, you can still follow the same method I use for creating the rays and raymarching, but will want to use their approach for sampling the 2D texture array as a "volume" instead.

So,I just need to replace texture function by sampleVolume function on reference
(https://github.com/lebarba/WebGLVolumeRendering/blob/master/Web/Index.html) ,
and convert data to a png image file with all the Z slices one next to the other.
volumn

Exactly, then you load those as a single 2d texture and sample them with their function. One thing you might want to be careful about is that if you don't put a border row/column of empty pixels around each slice you could see some artifacts at the edges of the slices where you end up interpolating with voxels from the following slice.

I changing the code to webgl1,but an unsolvable problem happend !!!!

for (float t = t_hit.x; t < t_hit.y; t += dt) {}

ERROR: 0:66: 't' : Loop index cannot be initialized with non-constant expression

Ah shoot, I forgot that was still a restriction in WebGL1. You'll have to change it to take a fixed number of samples, like:

for (int i = 0; i < MAX_STEPS; ++i) {
}

and then adjust dt so that it steps through the whole volume after MAX_STEPS steps, here

vec3 dt_vec = 1.0 / (vec3(MAX_STEPS) * abs(ray_dir));

I think MAX_STEPS has to be some hardcoded constant. You could also make it really high and then just check if t >= t_hit.y and break out of the loop:

for (int i = 0; i < MAX_STEPS; ++i) {
    if (t >= t_hit.y) {
        break;
    }

    // at the end of the loop, advance t
    t += dt;
}

Thanks very much for your guidance.

Happy to help! If you've got stuff working I'll close this issue