-1

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

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();

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

在此处输入图像描述

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

4

2 回答 2

1

看起来您的纹理坐标未正确分配给面顶点,因此应该修复。但是,您似乎期望 OpenGL 会“神奇地”为您执行某种体积光栅化。并且没有一种纹理坐标固定可以做到这一点

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

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

于 2017-01-23T17:39:37.047 回答
0

添加这些行后:

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);

一切正常。

于 2017-01-24T22:42:33.297 回答