3D纹理展示方式之RayMarch(光线投射)(glsl源码说明)

Demo:http://www.artvily.com/renderCase?sample=tex3DRayMarch

3D纹理在基于volume rendering的渲染机制的相关应用中有着广泛的应用。应用的领域非常广泛,例如考古、医学、材料科学,游戏等等。
一般来说3D纹理,可以理解为具有三个维度(width,height,depth)的数据类似于三维数组。一般的2D纹理我们可以认为它就是一张图片(实际就是一段内存(主内存和显存)中的数据), 那么3D纹理可以理解为在depth维度叠在一起的若干张图。那么描述3D纹理数据的大小就是width*height*depth * stride,这个stride具体要看你用多少个字节来表示3D纹理数据中的一个(voxel)。在片段着色器中访问的时候使用(s,t,r)或者(x,y,z)纹理空间坐标,采样器就会依据你自定义的NEAREST或者LINEAR来获得插值结果->当前片段通过纹理坐标(x,y,z)对应得到的纹理数据。这个数据可以可以直接展示出来也可以作为其他计算的输入数据例如光照或者体积光/雾/流体等。

上图是使用 ray march(光线投射)机制,来获得片段对应的3D纹理数据。先看片段着色代码:

// es3 glsl shader code
vec4 color4 = vec4(0.0);
// 光线步进值
float stepDis = 5.0;
float dis = 0.0;
vec3 pv;
for(int i = 0; i < 100; ++i)
{
    // 计算当前光线到达位置的空间坐标,v_ray是光线前进方向的单位矢量,v_pos是当前最靠近摄像机近平面的片段的空间坐标
    pv = v_pos + v_ray * dis;
    // 由片段在对应空间的(x,y,z)坐标计算得到(s,t,r)纹理空间坐标
    pv.xyz /= 405.0;
    // 获取3D纹理的对应值
    color4.w = texture(u_samper3D, pv).x;
    // 制定阈值
    if(color4.w > 0.6)
    {
        break;
    }
    // 光线前进一步 
    dis += stepDis;
}
if(color4.w < 0.6) discard;
// 下面两行是计算一个片段颜色
color4.xy = pv.xy;
color4.xyz *= u_color.xyz;
// 片段输出结果
OutputColor = color4;

上述代码展示了ray march 机制。shader toy上很多样例都是用这个机制做的。

更多我这里使用的ray march机制demo请见: https://blog.csdn.net/vily_lei/article/category/8083293

猜你喜欢

转载自blog.csdn.net/vily_lei/article/details/87308445