Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/31.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
OpenGL在延迟渲染器中实现skybox_Opengl_Deferred Rendering - Fatal编程技术网

OpenGL在延迟渲染器中实现skybox

OpenGL在延迟渲染器中实现skybox,opengl,deferred-rendering,Opengl,Deferred Rendering,我试图弄清楚如何在延迟渲染器中渲染天空框,以便它可以包含在后期处理效果中,但是我的几何体阶段在视图空间中,不幸的是,此阶段的天空框将受到其相对于灯光的位置的影响,就像任何对象一样(它的行为类似于远离光源的大盒子,显示得非常暗)。 我的设置(未尝试在后期处理中合并skybox)如下所示: 1:(绑定FBO)将几何体渲染为颜色、法线、位置FBO纹理附件(取消绑定FBO) 2:(绑定FBO)渲染场景并计算屏幕空间中的照明。(取消绑定FBO) 3:(绑定FBO)应用后处理效果(取消绑定FBO) 4:将几

我试图弄清楚如何在延迟渲染器中渲染天空框,以便它可以包含在后期处理效果中,但是我的几何体阶段在视图空间中,不幸的是,此阶段的天空框将受到其相对于灯光的位置的影响,就像任何对象一样(它的行为类似于远离光源的大盒子,显示得非常暗)。 我的设置(未尝试在后期处理中合并skybox)如下所示:

1:(绑定FBO)将几何体渲染为颜色、法线、位置FBO纹理附件(取消绑定FBO)

2:(绑定FBO)渲染场景并计算屏幕空间中的照明。(取消绑定FBO)

3:(绑定FBO)应用后处理效果(取消绑定FBO)

4:将几何体FBO的深度缓冲区blit设置为默认帧缓冲区

5:渲染skybox

我试着把第五步换成第三步 像这样:

2:(绑定FBO)渲染场景并计算屏幕空间中的照明

5:渲染skybox

(解除固定基地运营商绑定)

3:(绑定FBO)应用后处理效果(取消绑定FBO)

4:将几何体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);

然后给它提供它所缺乏的深度信息

在步骤1中渲染场景时,使用了深度缓冲区。因此,在绘制skybox时,需要使用相同深度缓冲区的FBO。但此FBO还需要使用在步骤2中渲染到的彩色图像

现在,这个固定基地运营商不能与第2步中使用的固定基地运营商相同。为什么

因为可能是这样。步骤2读取深度缓冲区以重建位置(如果不是这样,那么您可以从步骤2将深度缓冲区连接到FBO。但是,同样,您也在浪费大量的性能)。但是深度缓冲区也连接到FBO。这使得它具有未定义的行为。即使您没有写入深度,在OpenGL下它仍然未定义

因此,您将需要另一个FBO,它具有步骤1中的深度缓冲区和步骤2中的颜色缓冲区

除非您有权访问。使用该功能,如果您使用关闭对深度缓冲区的写入,它将成为定义的行为。您需要做的只是在执行步骤2之前发出
glTextureBarrier
。因此,如果您有FBO,则不需要另一个FBO


在任何一种情况下,渲染skybox时都要启用深度测试,但是。这将允许剔除实际世界后面的碎片,但是skybox碎片的深度将是无限远的。

然后提供它所缺少的深度信息

在步骤1中渲染场景时,使用了深度缓冲区。因此,在绘制skybox时,需要使用相同深度缓冲区的FBO。但此FBO还需要使用在步骤2中渲染到的彩色图像

现在,这个固定基地运营商不能与第2步中使用的固定基地运营商相同。为什么

因为可能是这样。步骤2读取深度缓冲区以重建位置(如果不是这样,那么您可以从步骤2将深度缓冲区连接到FBO。但是,同样,您也在浪费大量的性能)。但是深度缓冲区也连接到FBO。这使得它具有未定义的行为。即使您没有写入深度,在OpenGL下它仍然未定义

因此,您将需要另一个FBO,它具有步骤1中的深度缓冲区和步骤2中的颜色缓冲区

除非您有权访问。使用该功能,如果您使用关闭对深度缓冲区的写入,它将成为定义的行为。您需要做的只是在执行步骤2之前发出
glTextureBarrier
。因此,如果您有FBO,则不需要另一个FBO


在任何一种情况下,渲染skybox时都要启用深度测试,但是。这将允许剔除真实世界后面的碎片,但是skybox碎片的深度将是无限远的。

因此我提出了一个非常简单的黑客解决方案来解决这个问题,而不必加入任何纹理障碍或干扰深度或颜色缓冲区

实际上,我在延迟渲染过程的几何过程中渲染了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组件作为照明通行证的标志。这里我将其设置为-1

在我的光照过程中,如果我的gAlbedoSpec alpha值为-1,我只选择使用漫反射来为我的长方体着色,而不是添加光照计算

if(Diffuse.a > -1){
FragColor = SphereNormal * vec4(Dlighting, 1.0)+vec4(Slighting, 1.0);
}else{
FragColor = Diffuse ;
}

它相当简单,不需要太多的代码,就能完成任务。

因此,我想出了一个非常简单的解决方案来解决这个问题,而不必加入任何纹理障碍或干扰深度或颜色缓冲区

实际上,我在延迟渲染过程的几何过程中渲染了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组件作为照明通行证的标志。这里我将其设置为-1

在我的光照过程中,如果我的gAlbedoSpec alpha值为-1,我只选择使用漫反射来为我的长方体着色,而不是添加光照计算

if(Diffuse.a > -1){
FragColor = SphereNormal * vec4(Dlighting, 1.0)+vec4(Slighting, 1.0);
}else{
FragColor = Diffuse ;
}
它相当简单,不需要