OpenGL 3D texture “shine through”

半世苍凉 提交于 2019-12-25 18:48:09

问题


For testing purposes I want to display the first slice of a 3D texture. However it seems that the other slices are also displayed.

My vertex shader:

#version 130

attribute vec4 position;

varying vec2 texcoord;

void main()
{
    gl_Position = position;
    texcoord = position.xy * vec2(0.5) + vec2(0.5);
}

The fragment shader:

#version 130

uniform sampler3D textures[1];

varying vec2 texcoord;

void main()
{
    gl_FragColor = texture3D(textures[0], vec3(texcoord.x, texcoord.y, 0));
}

I bind the texture from my C++ code using

     glTexImage3D(GL_TEXTURE_3D,0,GL_LUMINANCE,rows-1,cols-1,dep-  1,0,GL_RED,GL_UNSIGNED_SHORT, vol.data());

This is how it looks; the whole head should not be visible, only the upper portion of it.


回答1:


When you use linear filtering (value GL_LINEAR for the GL_TEXTURE_MIN_FILTER and/or GL_TEXTURE_MAG_FILTER texture parameters), the value of your samples will generally be determined by the two slices closest to your 3rd texture coordinate.

If the size of your 3D texture in the 3rd dimension is d, the position of the first slice in texture coordinate space is 0.5 / d. This is easiest to understand if you picture each slice having a certain thickness in texture coordinate space. Since you have d slices, and the texture coordinate range is [0.0, 1.0], each slice has thickness 1.0 / d. Therefore, the first slice extends from 0.0 to 1.0 / d, and its center is at 0.5 / d.

When you use 0.0 for the 3rd texture coordinate, this is not the center of the first slice, and linear sampling comes into play. Since 0.0 is at the edge of the texture, the wrap modes become critical. The default wrap mode is GL_REPEAT, meaning that sampling at the edges acts as if the texture was repeated. With this setting, the neighbor of the first slice is the last slice, and texture coordinate 0.0 is exactly in the middle between the first slice and the last slice.

The consequence is that linear sampling with texture coordinate 0.0 will give you the average of the first slice and the last slice.

While GL_REPEAT is the default for the wrap modes, it is rarely what you want, unless your texture really contains a repeating pattern. It's certainly not the right setting in this case. What you need here is:

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


来源:https://stackoverflow.com/questions/31810822/opengl-3d-texture-shine-through

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!