将FBO渲染到屏幕时考虑深度

时间:2017-01-28 00:14:42

标签: opengl-es depth-buffer

目标:OpenGL ES 3.0

假设我的默认帧缓冲区(屏幕)已经包含我渲染的部分场景;它的颜色和深度缓冲区包含有效数据。

现在假设我已经将场景的另一部分渲染到中间FBO“fbo1”了。它的颜色数据保存在纹理'mColor'中,附加到fbo1.COLOR0附件,其深度保存在另一个纹理'mDepth'中,该纹理附加到另一个FBO'fbo2'的DEPTH附件上。

现在我想拍摄mColor并将其渲染到屏幕,同时考虑到mDepth的深度。我知道如何将仅包含颜色数据的纹理渲染到屏幕上,但我不知道如何考虑mDepth。

基本上看起来当我们将带有mColor纹理的Quad渲染到屏幕时,我们需要比较Screen的深度缓冲区而不是Quad的深度,但深度来自mDepth。怎么做?

2 个答案:

答案 0 :(得分:1)

您可以将FBO的深度用作纹理。绘制FBO的内容时,绘制颜色传递并从FBO的深度纹理手动编写gl_FragDepth。之后,您可以通过启用适当的深度测试来绘制所有其他场景内容。

答案 1 :(得分:1)

如果要拆分管道并在多个通道中渲染FBO0与屏幕外渲染交错,那么简单的答案就是“你做错了”。

你迫使GPU写出并回读你的中间状态,这种状态非常低效,特别是在基于磁贴的架构的移动设备上。

首先渲染每个离屏通道,然后在一次通过中渲染窗口表面(FBO0)。

  

我们需要将屏幕的深度缓冲区与Quad的深度进行比较,但深度与mDepth进行比较。怎么做?

从深度纹理加载深度值,并将该值分配给片段着色器中的gl_FragDepth。然而,这会强制所有碎片进行晚期zs深度更新,与在早期zs使用真实三角形z值相比,这是非常慢的,因为在确定是否需要保留碎片之前必须运行着色器或不。所以,按照上面的说法,我建议重新设计渲染管道,这样你就不需要这样做了......