opengl创建一个用于读取的深度模板纹理

标签 opengl textures

我在应用程序中使用延迟渲染,并且尝试创建一个包含深度和模板的纹理。

glTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH24_STENCIL8, width, height, 0,
???, GL_FLOAT, 0);

现在 opengl 对于这个特定的纹理想要什么格式的枚举。我尝试了几个,但都出现错误

此外,访问纹理的深度和模板部分的正确 glsl 语法是什么。据我所知,深度纹理通常是统一的sampler2Dshadow。但我会吗

float depth = texture(depthstenciltex,uv).r;// <- first bit ? all 32 bit ? 24 bit ?
float stencil = texture(depthstenciltex,uv).a;

最佳答案

Now what format enum does opengl want for this particular texture.

您遇到的问题是深度+模板是一个完全奇怪的数据组合。前 24 位(深度)是定点,其余 8 位(模板)是无符号整数。这需要特殊的打包数据类型:GL_UNSIGNED_INT_24_8

Also, what is the correct glsl syntax to access the depth and stencil part of the texture. I understand that depth texture are usually uniform sampler2Dshadow.

实际上,您永远无法使用相同的采样器制服对这两件事进行采样,原因如下:

OpenGL Shading Language 4.50 Specification  -  8.9 Texture Functions  -  p. 158

For depth/stencil textures, the sampler type should match the component being accessed as set through the OpenGL API. When the depth/stencil texture mode is set to GL_DEPTH_COMPONENT, a floating-point sampler type should be used. When the depth/stencil texture mode is set to GL_STENCIL_INDEX, an unsigned integer sampler type should be used. Doing a texture lookup with an unsupported combination will return undefined values.

这意味着,如果您想在着色器中同时使用深度和模板,则必须使用纹理 View (OpenGL 4.2+) 并将这些纹理绑定(bind)到两个不同的纹理图像单元(每个 View 具有不同的状态) GL_DEPTH_STENCIL_TEXTURE_MODE)。这两件事加在一起意味着您至少需要 OpenGL 4.4 实现。

对深度和模板进行采样的片段着色器:

#version 440
// Sampling the stencil index of a depth+stencil texture became core in OpenGL 4.4

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

创建模板 View 纹理:

// Alternate view of the image data in `depth_stencil_texture`
GLuint stencil_view;
glGenTextures (&stencil_view, 1);
glTextureView (stencil_view, GL_TEXTURE_2D, depth_stencil_tex,
               GL_DEPTH24_STENCIL8, 0, 1, 0, 1);

// ^^^ This requires `depth_stencil_tex` be allocated using `glTexStorage2D (...)`
//       to satisfy `GL_TEXTURE_IMMUTABLE_FORMAT` == `GL_TRUE`

此着色器的 OpenGL 状态设置:

// Texture Image Unit 0 will treat it as a depth texture
glActiveTexture (GL_TEXTURE0);
glBindTexture   (GL_TEXTURE_2D, depth_stencil_tex);
glTexParameteri (GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_DEPTH_COMPONENT);

// Texture Image Unit 1 will treat the stencil view of depth_stencil_tex accordingly
glActiveTexture (GL_TEXTURE1);
glBindTexture   (GL_TEXTURE_2D, stencil_view);
glTexParameteri (GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);

关于opengl创建一个用于读取的深度模板纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27535727/

相关文章:

c++ - 如何在 OpenGL 中创建 3D 太阳系星空背景?

opengl - 纹理数组大小的限制是什么?

c - OpenGL 纹理映射 : Whole object is a single texel's color

c++ - 一次绘制调用即可绘制数千个图元

c++ - 四边形上的 OpenGL 纹理未对齐

c++ - OpenGL使用统一缓冲区作为数组

textures - 从 Maya 导出时,DAE 文件图像纹理不会显示在 Aframe 中

c - 纹理映射到在 OpenGL 中使用 GL_QUAD_STRIP 制作的圆柱体

c++ - DirectX11 纹理坐标和顶点

ios - ASyncDisplayKit (Texture) - 调整可见节点的大小