我正试图弄清楚如何在延迟渲染器中渲染skybox,以便将其包含在后处理效果中。然而,我的几何阶段在视图空间中,不幸的是,这个阶段的skybox将像任何对象一样受其相对于光的位置的影响(它的行为就像离光源很远的大盒子,显示得很暗)。我的设置没有尝试将skybox纳入后期处理,如下所示:
1:(绑定FBO)将几何体渲染到颜色、法线、定位FBO纹理附件(取消绑定FBO。)。
2:(绑定FBO)渲染场景并计算屏幕空间中的照明。(解除FBO绑定)
3:(绑定FBO)应用后处理效果(解除绑定FBO
4:将Geometry FBO的深度缓冲区blit到默认帧缓冲区
5:渲染skybox。
我试着把第5步换成第3步像这样:
2:(绑定FBO)渲染场景并计算屏幕空间中的照明。
5:渲染skybox
(解除FBO绑定)
3:(绑定FBO)应用后处理效果(解除绑定FBO
4:将Geometry FBO的深度缓冲区blit到默认帧缓冲区
但显然,skybox没有关于场景的深度信息,而是在灯光舞台的顶部进行渲染。如果我试图在2到5之间进行任何深度闪电战,我相信我正在进行无效的GL调用,因为我在调用时已经绑定到FBO
GL30.glBindFramebuffer(GL30.GL_READ_FRAMEBUFFER, DeferredFBO.fbo_handle);
GL30.glBindFramebuffer(GL30.GL_DRAW_FRAMEBUFFER, 0); // Write to default
// framebuffer or a skybox framebuffer
GL30.glBlitFramebuffer(0, 0, DisplayManager.Width,
DisplayManager.Height, 0, 0, DisplayManager.Width,
DisplayManager.Height, GL11.GL_DEPTH_BUFFER_BIT,
GL11.GL_NEAREST);
所以我想出了一个非常简单的解决方案来解决这个问题,而不必加入任何纹理屏障或干扰深度或颜色缓冲区。
实际上,我在"延迟渲染"过程的"几何体"过程中渲染了Skybox几何体,我渲染了Skybox,并在片段着色器中设置了一个标志来为我的Skybox着色,记住要修改视图矩阵以使用顶点着色器中的另一个统一标志来移除平移。在片段着色器中,我将skybox颜色设置为这样。这是一个基本的摘要,没有粘贴所有的代码。
layout (binding = 4) uniform samplerCube cubeMap;
uniform float SkyRender;
void main(){
if(SkyRender){
vec4 SkyColor = texture(cubeMap, skyTexCoords);
gAlbedoSpec.rgb = SkyColor.rgb;
gAlbedoSpec.a = -1;
}else{
gAlbedoSpec.rgb = texture(DiffuseTexture, TexCoords);
gAlbedoSpec.a = texture(SpecularTexture, TexCoords).r;
}
我将"颜色"缓冲区中skybox的alpha组件设置为Lighting过程的标志。这里我将其设置为-1。
在我的照明过程中,如果gAlbedoSpec alpha值为-1,我只需选择使用"仅漫反射"为长方体着色,而不是添加照明计算。
if(Diffuse.a > -1){
FragColor = SphereNormal * vec4(Dlighting, 1.0)+vec4(Slighting, 1.0);
}else{
FragColor = Diffuse ;
}
它相当简单,不需要太多代码,而且可以完成任务。
然后给它所缺少的深度信息。
在步骤1中渲染场景时,使用了深度缓冲区。所以当你画你的天空盒子时,你需要一个使用相同深度缓冲的FBO。但是这个FBO还需要使用在步骤2中渲染到的彩色图像。
现在,这个FBO不能是您在步骤2中使用的相同FBO。为什么?
因为那将是未定义的行为。据推测,步骤2从深度缓冲区中读取以重建位置(如果不是这样,那么您可以从步骤2将深度缓冲区连接到FBO。但话说回来,你也在浪费吨的性能)。但这个深度缓冲区也附在FBO上。这使得它成为一种未定义的行为。即使您没有写入深度,它在OpenGL下仍然是未定义的。
因此,您将需要另一个FBO,它具有来自步骤1的深度缓冲区和来自步骤2的颜色缓冲区。
除非您可以访问OpenGL 4.5/ARB_texture_barrier/NV_texture_barrier。使用该功能,如果使用写入掩码来关闭对深度缓冲区的写入,则它将成为已定义的行为。您所需要做的就是在执行步骤2之前发出一个glTextureBarrier
。所以你不需要另一个联邦调查局,如果你有。
在任何一种情况下,在渲染skybox时都要启用深度测试,但要关闭深度写入。这将允许你的真实世界后面的碎片被剔除,但天空盒子碎片的深度将无限遥远。