与 GL_TEXTURE_3D 一起工作

Working with GL_TEXTURE_3D

我正在尝试读取一个文件,该文件表示在渲染体积时要映射到颜色的值。即,每个体素都有其在输入文件中表示的颜色。下面是一个虚拟测试文件:

4 4 4
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0
1 1 1 1
1 1 1 1
1 1 1 1
1 1 1 1
0 0 0 0
0 0 0 0
0 0 0 0
0 0 0 0

它应该用顶部黑色定义一个值,然后是白色层、黑色层和白色层。

我是这样读的:

int width, height, depth;
file >> width;
file >> height;
file >> depth;

printf("Texture data: %d, %d, %d\n", width, height, depth);

// Creating buffer
unsigned char buffer[height][width][depth];

// Reading content
int v;
for (int i = 0; i < height; i ++) {
    for (int j = 0; j < width; j ++) {
        for (int k = 0; k < depth; k ++) {
            file >> v;
            buffer[i][j][k] = v * 255;
        }
    }
}

这就是我创建纹理的方式:

// Create one OpenGL texture
GLuint textureID;
glGenTextures(1, &textureID);

// "Bind" the newly created texture : all future texture functions will modify this texture
glBindTexture(GL_TEXTURE_3D, textureID);

// Give the image to OpenGL
glTexImage3D(GL_TEXTURE_3D, 0, GL_RED, height, width, depth, 0, GL_RED, GL_UNSIGNED_BYTE, buffer);

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

这些是将用于构建我的 VAO 的值:

_modelCoordinates = { -1.0, -1.0,  1.0,
                       1.0, -1.0,  1.0,
                       1.0,  1.0,  1.0,
                      -1.0,  1.0,  1.0,
                      -1.0, -1.0, -1.0,
                       1.0, -1.0, -1.0,
                       1.0,  1.0, -1.0,
                      -1.0,  1.0, -1.0 };

_modelIndices = { 0, 1, 2,
                  2, 3, 0,
                  1, 5, 6,
                  6, 2, 1,
                  7, 6, 5,
                  5, 4, 7,
                  4, 0, 3,
                  3, 7, 4,
                  4, 5, 1,
                  1, 0, 4,
                  3, 2, 6,
                  6, 7, 3 };

_textureCoordinates = {  0.0, 0.0, 1.0,
                         1.0, 0.0, 1.0,
                         1.0, 1.0, 1.0,
                         0.0, 1.0, 1.0,
                         0.0, 0.0, 0.0,
                         1.0, 0.0, 0.0,
                         1.0, 1.0, 0.0,
                         0.0, 1.0, 0.0 };

最后,这是我的着色器:

  1. 顶点着色器:

.

#version 410 core

uniform mat4 mvMatrix;
uniform mat4 pMatrix;

in vec4 vPosition;
in vec3 texCoord;

// Input for the fragment shader
smooth out vec3 uv;

void main() {
    gl_Position = pMatrix * mvMatrix * vPosition;
    uv = texCoord;
}   
  1. 片段着色器:

.

#version 410 core

uniform sampler3D tex;

in vec3 uv;
out vec4 fragColor;

void main()
{ 
   vec3 color = texture(tex, uv).rrr;
   fragColor.rgb = color;
}

加载制服和属性值后,绘制体积:

_modelView = modelView;
_projection = projection;

_succeed = Bind();
if (_succeed)
{
    glBindVertexArray(_vao);
    LoadUniformVariables();
    glDrawElements(GL_TRIANGLES, _modelIndices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}
UnBind();

然而,我得到的只是一个空白卷:

我不知道如何正确设置纹理坐标以及如何正确实现这种情况下的片段着色器。

看起来你的纹理坐标没有正确分配给面顶点,所以应该修复。 但是您似乎期望 OpenGL 会 "magically" 为您执行某种体积光栅化。 并且不会进行任何纹理坐标固定做.

使用您编写的片段着色器,只会对体积数据的切片进行采样。您需要做的是编写一个片段着色器,该着色器实际上通过纹理发送光线并在光线穿过的每个样本处对其进行采样。 GPU Gems 中有一整章是关于体积渲染的:

http://http.developer.nvidia.com/GPUGems/gpugems_ch39.html

添加这些行后:

glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);

一切正常。