简体   繁体   English

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

[英]Render FBO to screen taking into account Depth

Target: OpenGL ES 3.0 目标:OpenGL ES 3.0

Suppose my default Framebuffer (the screen) already contains part of my scene rendered; 假设我的默认帧缓冲区(屏幕)已经包含渲染的场景的一部分; its color and depth buffers contain valid data. 其颜色和深度缓冲区包含有效数据。

Now suppose I have another part of the scene rendered to an intermediate FBO 'fbo1' already. 现在假设我已经将场景的另一部分渲染到了中间FBO'fbo1'。 Its color data is kept in texture 'mColor', which is attached to fbo1.COLOR0 attachment, and its depth is kept in another texture 'mDepth', which is attached to the DEPTH attachment of yet another FBO 'fbo2'. 它的颜色数据保存在纹理'mColor'中,该纹理附加到fbo1.COLOR0附件中,其深度保存在另一个纹理'mDepth'中,该纹理附加在另一个FBO'fbo2'的DEPTH附件中。

Now I would like to take mColor and render it to the Screen, taking into account the depth from mDepth. 现在,我要考虑mDepth的深度,将mColor渲染到屏幕上。 I know how to render a texture containing only color data to the screen, but I don't know how to do so taking into account the mDepth. 我知道如何在屏幕上渲染仅包含颜色数据的纹理,但考虑到mDepth,我不知道如何进行渲染。

Essentially it looks like when we render the Quad textured with mColor to the screen, we need to compare the Screen's depth buffer not with the depth from the Quad, but with depth from mDepth. 从本质上讲,当我们将具有mColor的Quad渲染到屏幕上时,我们需要将Screen的深度缓冲区与Quad的深度而不是Quad的深度进行比较。 How to do that? 怎么做?

You could use your FBO's depth as a texture. 您可以将FBO的深度用作纹理。 When you draw the FBO's content, you draw the color pass and write gl_FragDepth manually from the FBO's depth texture. 绘制FBO的内容时,您将绘制颜色传递并从FBO的深度纹理中手动编写gl_FragDepth。 After that you can draw all your other scene content with proper depth test enabled. 之后,您可以启用适当的深度测试来绘制所有其他场景内容。

If you are splitting your pipeline and rendering FBO0 in multiple passes interleaved with off-screen rendering then the simple answer is "you're doing it wrong". 如果您要分割流水线并在与屏幕外渲染交错的多个通道中渲染FBO0,则简单的答案是“您做错了”。

You're forcing the GPU to write out and read-back your intermediate states which is horribly inefficient, in particular on mobile with tile-based architectures. 您正在强迫GPU写入和回读中间状态,这是极其低效的,尤其是在具有基于图块的架构的移动设备上。

Render each off-screen pass first, and then render the window surface (FBO0) to completion in a single pass. 首先渲染每个屏幕外的通道,然后一次渲染窗口表面(FBO0)的轮廓。

We need to compare the Screen's depth buffer not with the depth from the Quad, but with depth from mDepth. 我们需要将屏幕的深度缓冲区与四边形的深度而不是四边形的深度进行比较。 How to do that? 怎么做?

Load the depth value from the depth texture, and assign that value to gl_FragDepth in your fragment shaders. 从深度纹理加载深度值,然后将该值分配给片段着色器中的gl_FragDepth However this will force all of your fragments to a late-zs depth update, which is horribly slow compared to using the real triangle z-value at early-zs as you have to run the shader before you determine if you need to keep the fragment or not. 但是,这将迫使所有片段进行zs后期深度更新,这与在zs早期使用真实三角形z值相比要慢得多,因为在确定是否需要保留片段之前必须运行着色器或不。 So, as per the above I'd suggest redesigning your rendering pipeline so you don't need to do this ... 因此,按照上述建议,我建议重新设计渲染管道,这样您就不需要这样做了……

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM