现在,OpenGL需要什么格式的枚举来处理这个特定的纹理。
你遇到的问题是深度+模板是一种完全奇怪的数据组合。前24位(深度)是定点数,剩余的8位(模板)是无符号整数。这需要一种特殊的打包数据类型:GL_UNSIGNED_INT_24_8
此外,访问纹理的深度和模板部分的正确glsl语法是什么。我知道深度纹理通常是uniform sampler2Dshadow。
实际上,你永远不能使用同一个采样器uniform来采样这两个东西,原因如下:
对于深度/模板纹理,采样器类型应与通过OpenGL API设置的要访问的组件相匹配。当深度/模板纹理模式设置为GL_DEPTH_COMPONENT
时,应使用浮点采样器类型。当深度/模板纹理模式设置为GL_STENCIL_INDEX
时,应使用无符号整数采样器类型。使用不支持的组合进行纹理查找将返回未定义的值。
这意味着如果你想在着色器中同时使用深度和模板,你将需要使用纹理视图(OpenGL 4.2+)并将这些纹理绑定到两个不同的纹理图像单元(每个视图都有一个不同的GL_DEPTH_STENCIL_TEXTURE_MODE
状态)。这两件事加在一起意味着你至少需要一个OpenGL 4.4实现。
采样深度和模板的片段着色器:
#version 440
layout (binding=0) uniform sampler2D depth_tex;
layout (binding=1) uniform usampler2D stencil_tex;
in vec2 uv;
void main (void) {
float depth = texture (depth_tex, uv);
uint stencil = texture (stencil_tex, uv);
}
创建模板视图纹理:
GLuint stencil_view;
glGenTextures (&stencil_view, 1);
glTextureView (stencil_view, GL_TEXTURE_2D, depth_stencil_tex,
GL_DEPTH24_STENCIL8, 0, 1, 0, 1);
此着色器的OpenGL状态设置:
glActiveTexture (GL_TEXTURE0);
glBindTexture (GL_TEXTURE_2D, depth_stencil_tex);
glTexParameteri (GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);
glActiveTexture (GL_TEXTURE1);
glBindTexture (GL_TEXTURE_2D, stencil_view);
glTexParameteri (GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
GL_DEPTH24_STENCIL8
不是GL_VIEW_CLASS_32_BITS
的成员。然而,由于两个纹理的内部格式完全匹配,所以这并不重要。我已经更新了我的答案。 - Andon M. ColemanglTexParameteri(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_STENCIL_MODE, GL_DEPTH_COMPONENT);
,但是它可以省略,因为GL_DEPTH_TEXTURE_STENCIL_MODE
的初始值就是GL_DEPTH_COMPONENT
。 - plasmacel#version 460
中,对sampler2D
调用texture()
总是返回一个vec4
,对于usampler2D
它将返回uvec4
。我现在不知道该怎么办了... - neo-mashirouint stencilBits = texture(texture0, coord).r;
确实似乎提取了实际的模板字节(假设texture0
是包含深度/模板纹理的usampler2D
,并且启用了GL_STENCIL_INDEX
)。就其价值而言,.g
和.b
属性似乎都始终为 0,而.a
似乎始终为 255。我不知道我是否会相信这些最后的值在硬件上保持一致,但是.r
似乎是答案。 - Sean Werkema