使用GL_TEXTURE_3D

时间:2017-01-23 17:05:58

标签: opengl glsl 3d-texture

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

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. Vertex Shader:
  2. #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. Frag Shader:
    2. #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();
      

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

      enter image description here

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

2 个答案:

答案 0 :(得分:1)

看起来您的纹理坐标未正确分配给面顶点,因此应该修复。 然而您似乎期望OpenGL会“神奇地”为您执行某种体积光栅化。并且没有任何纹理坐标修复会 >

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

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

答案 1 :(得分: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);

一切都很好。