使用2D纹理在OpenGL中进行体绘制

时间:2017-06-05 13:32:15

标签: opengl graphics rendering jogl volume-rendering

为什么我们必须根据相机的视角在不同方向上对齐纹理?它应该不一样吗?(如果我启用了深度测试)

First Slide Second Slide

编辑1:

我用自己的程序来测试它。

这是我的渲染功能代码。

        if (position.z >= 0) pz = true;
        else pz = false;

        if (lz != pz) {
            slice.clear();
            printf("Changed !!! :: %s", (pz?"Positive Z":"Negative Z") );
            if (pz) {
                for (float i = 0; i < count; ++i) {
                    slice.push_back( glm::vec2( -SIZE/2 + SIZE * i / (count-1), i ) );
                }
                lz = pz;
            } else {
                for (float i = count-1; i >= 0; --i) {
                    slice.push_back( glm::vec2( -SIZE/2 + SIZE * i / (count-1), i ) );
                }
                lz = pz;
            }
            glBindBuffer(GL_ARRAY_BUFFER, ibo);
            glBufferData(GL_ARRAY_BUFFER, slice.size()* 2 *sizeof(float), &slice[0], GL_STATIC_DRAW);
        }

        glUseProgram(programID);
        glBindVertexArray(vao);
        glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, texture);
        glEnableVertexAttribArray(0);
        glEnableVertexAttribArray(1);
        glEnableVertexAttribArray(2);
        glDrawArraysInstanced(GL_TRIANGLES, 0, 6, slice.size());
        glDisableVertexAttribArray(0);
        glDisableVertexAttribArray(1);
        glDisableVertexAttribArray(2);
        glBindVertexArray(0);

矢量“切片”包含2个浮点数(z位置和切片的id)。它对每个实例都是唯一的。没有这个“if(lz!= pz)...”子句,我只能看到+ ve Z方向的模型。

编辑2:

这是一个观点。 enter image description here

但是当我的相机移动到z = 0附近时,部分纹理无法看到。 我试图关闭深度测试然后我看到纹理在后面。为什么前面的纹理消失了? enter image description here

  1. 启用深度测试
  2. 禁用背面剔除
  3. 启用Alpha测试
  4. 编辑3:

    我将“if(lz!= pz)...”子句更改为以下代码,现在每件事都运行正常。但我仍然不明白为什么。

            slice.clear();
            for (float i = 0; i < count; ++i) { // position is a vector representing the location of the camera
                if (-SIZE/2 + SIZE * i / (count-1) >= position.z) break;
                slice.push_back( glm::vec2( -SIZE/2 + SIZE * i / (count-1), i ) );
            }
    
            for (float i = count-1; i >= 0; --i) {
                if (-SIZE/2 + SIZE * i / (count-1) < position.z) break;
                slice.push_back( glm::vec2( -SIZE/2 + SIZE * i / (count-1), i ) );
            }
    

    enter image description here 虽然它看起来不吸引人,但它按预期工作。对于每一帧,我根据相机的位置对切片进行了排序。

    编辑4:

    我的alpha测试代码

    glEnable (GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.1);
    

    这两行是在init()函数中。

1 个答案:

答案 0 :(得分:1)

基本上我在这里看到两个问题:

为什么选择最接近摄像机方向的轴?

因为否则切片甚至可能无法填满卷的整个屏幕区域。想象一下,您渲染的切片平行于XY平面,但相机沿X轴看,即从侧面看&#39;。然后你会看到切片之间的间隙。像这样:

Plates

为什么渲染回到前面?

这并不总是必要的。原则上,如果启用alpha测试和深度测试,则可以按任何顺序进行渲染。但是,体绘制通常假定支持部分透明的数据,在这种情况下,通常的alpha混合方程可以将几何体渲染回来。