![](/img/trans.png)
[英]Error when use stencil buffer in FBO(QOpenGLFramebufferObject)
[英]Deferred renderer with stencil buffer FBO
在我的延迟渲染器中,我为我的几何过程创建了一个FBO,在其中,我还使用以下参数将depth +模具缓冲区存储到纹理中:
GL_DEPTH_STENCIL_ATTACHMENT
GL_DEPTH_STENCIL
GL_DEPTH32F_STENCIL8
GL_UNSIGNED_INT_24_8
并且我可以成功地使用深度和模具填充此纹理。
我现在面临的问题是如何使用在几何图形通道中创建的模具缓冲区,以便在其他地方使用它,例如当我进行定向光传递时,我只想处理在可见的几何图形上覆盖的像素我的几何图形通过。
那么,如何使用在几何传递过程中存储的模具缓冲区作进一步使用?
当然,您始终可以使用模板缓冲区进行模板测试。 为了说明如何在基本级别上使用模版测试,以下是一个关键的示例调用,其中您绘制了两遍,其中在第二遍中,我们将排除第一遍中未覆盖的所有像素:
清除帧缓冲区时,请确保包括清除模板缓冲区的位:
glClear(... | GL_STENCIL_BUFFER_BIT);
启用模板测试:
glEnable(GL_STENCIL_TEST);
设置模板功能/操作,以将所有渲染像素的模板缓冲区中的值设置为1:
glStencilFunc(GL_ALWAYS, 1, 1); glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
GL_ALWAYS
指定所有像素均通过模板测试(即不拒绝任何像素)。 GL_REPLACE
指定对于所有渲染像素,模板缓冲区中的值将由参考值替换,该参考值是glStencilFunc()
的第二个参数。
绘制第一遍的几何图形。
将模具功能/操作更改为仅渲染模具缓冲区中值为1的像素:
glStencilFunc(GL_EQUAL, 1, 1); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
GL_EQUAL
指定只有在模板缓冲区值等于参考值1的位置上的像素才能通过模板测试,而所有其他像素都被拒绝。 GL_KEEP
指定在此过程中不修改模板缓冲区中的当前值。
绘制第二遍的几何图形。
但是,按照我阅读您的问题的方式,您正在寻找与众不同的东西。 您想从一个渲染遍历中采样模板缓冲区,然后再进行一次渲染遍历,类似于对深度纹理进行采样的方式。
OpenGL 4.3和更高版本支持此功能。 使用texId
作为深度/模板纹理的名称,关键部分是该纹理参数设置:
glBindTexture(GL_TEXTURE_2D, texId);
glTexParamteri(GL_TEXTURE_2D, GL_DEPTH_STENCIL_TEXTURE_MODE, GL_STENCIL_INDEX);
这指定深度/模板纹理的模板部分应用于采样。 模具纹理仅支持最近的采样,因此请确保您还具有以下值:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
毫不奇怪,基于该值的性质,模具纹理被视为无符号整数纹理。 这意味着着色器代码中的采样器类型需要为usampler2D
:
uniform usampler2D MyStencilTexture;
当您采样纹理时,结果也将是无符号类型:
uvec4 stencilValue = texture(MyStencilTexture, textureCoordinates);
然后,模板值将在stencilValue.r
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.