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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值