OpenGL实现Volume Rendering 大致步骤

OpenGL实现Volume Rendering 大致步骤

1D TF Code

在混合volume render程序中的1D TF code
1. RGBA都为0~255,正好一个byte,unsigned int,char型。
2. 一个节点(传输函数上的关键节点)上的信息为:intensity+color[RBGA]。
3. 透明度值a用0~255存储,用的时候(float)/255.f。
4. intensity大的点在update的时候必须>=原来intensity比其小的店,比较,移动等问题,用插入排序。

绘制纹理

绘制一共需要3个纹理
1. 一个3D texture 存放体数据。
2. 3个2D texture: ray casting 起始位置纹理,ray casting 结束位置纹理(存放的是起始和技术位置的深度值),一张深度纹理,即为2张纹理的差值。
3. 1个1D texture 存放1DTF数据。244*4个byte。

GLSL过程

GLSL过程
1. 创建shader -> glCreateShader();
2. shader读入char* -> glShaderSource();
3. 编译shader -> glCompileShader();
4. 创建program -> glCreateProgram();
5. 将shader连到program上 -> glAttachShader();
6. 链接program -> glLinkProgram();

程序流程

程序流程
1. init
1. 初始化GLSL
2. 初始化texture,分配空间,glTexImage2D();
3. 将纹理都绑定到一个帧缓存对象。FBO需要opengl3.0或者使用扩展glew,或者用代替的framebufferobject.h/.cpp。
4. 根据raw数据长宽高,载入数据到char*,再绑定到3D纹理。
5. 绑定传输函数1Dtexture。
2. render
1. updateTFtexture,看看传输函数是否变化,有变化重新产生纹理。
2. 绘制起始位置纹理:绑定FBO,转换视角,glDrawBuffer绘制到绑定的纹理上,绘制一个立方体,将顶点坐标信息当做纹理坐标。
3. 绘制结束位置纹理:同上,绘制前用glDepthFunc(GL_GREATER);绘制后用glDepthFunc(GL_LESS);
4. boundingBox的片段着色器为: void main { gl_FragColor = gl_TexCoord[0];//直接将纹理坐标赋值给最终颜色。 }
5. glUseProgram(raycastingProgram);
6. glActiveTexture()激活纹理,内容始终是GL_TEXTURE0+gen出来的纹理id。
7. 穿入这些纹理。
8. 将产生的最终结果绘制到窗口大小的矩形上。
9. 使用正交投影。
10. raycasting glsl代码:

GLSL Code

#extension GL_ARB_texture_rectangle : enable
uniform sampler1D texTransfunc;
uniform sampler2DRect texStartPos;
uniform sampler2DRect texEndPos;
uniform sampler3D texVolume;
uniform float step;
 
void main()
{
     vec3 rayStart = texture2DRect(texStartPos, gl_TexCoord[0].st).xyz;
    vec3 rayEnd = texture2DRect(texEndPos, gl_TexCoord[0].st).xyz;
    vec3 start2end = rayEnd - rayStart;
 
    if (start2end.x == 0.0 && start2end.y == 0.0 && start2end.z == 0.0) {
        gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
        return;
    }
    vec4 color = vec4(0, 0, 0, 0);
    vec3 direction = normalize(start2end);
    float distance = dot(direction, start2end);
    int steps = distance / step;
    for(int i = 0; i < 2048; ++i) {
         if(i >= steps)
             break;
        vec3 samplePoint  = rayStart + direction * step * (i + 0.5);
        float scalar = texture3D(texVolume, samplePoint).x;
        vec4 sampledColor = texture1D(texTransfunc, scalar);
        color = color + sampledColor * vec4(sampledColor.aaa, 1.0) * (1.0 - color.a);
        if(color.a > 0.99)
            break;
    }
    color = color + vec4(1, 1, 1, 0) * (1.0 - color.a);
    color.a = 1;
    gl_FragColor = color;
     //gl_FragColor = texture2DRect(texStartPos, gl_TexCoord[0].st);
}

引用的文件地址:http://neversayever.com/blog/2012/01/1901/。但是估计网站没有更新,因此不能访问。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值