OpenGL 在延迟渲染器中实现天空盒

     2023-02-22     290

关键词:

【中文标题】OpenGL 在延迟渲染器中实现天空盒【英文标题】:OpenGL implementing skybox in a deferred renderer 【发布时间】:2015-12-19 22:46:16 【问题描述】:

我试图弄清楚如何在延迟渲染器中渲染天空盒,以便它可以包含在后期处理效果中,但是我的几何阶段在视图空间中,不幸的是,这个阶段的天空盒会受到它的位置的影响像任何物体一样相对于光(它的行为就像离光源很远的大盒子,并且显示得很暗)。 我没有尝试在后期处理中加入天空盒的设置如下:

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

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

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

4:将几何 FBO 的深度缓冲区 blit 到默认帧缓冲区

5:渲染天空盒。

我尝试将第 5 步与第 3 步切换 像这样:

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

5:渲染天空盒

(解除绑定FBO)

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

4:将几何 FBO 的深度缓冲区 blit 到默认帧缓冲区

但显然天空盒没有关于场景的深度信息,而是在灯光舞台上渲染。如果我尝试在 2 和 5 之间进行任何深度 blitting,我相信我在进行无效的 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);

【问题讨论】:

嗯,“模型视图”空间不是坐标空间。这是一个从模型转换到(世界到)视图空间的矩阵。这里有趣的是,GL 倾向于跳过的中间部分是延迟着色的方便坐标空间,可能会对您有所帮助。 抱歉,已编辑。 【参考方案1】:

所以我想出了一个非常简单的hacky解决方案来解决这个问题,而无需合并任何纹理障碍或弄乱深度或颜色缓冲区。

我实际上是在延迟渲染过程的几何通道中渲染天空盒几何体,我渲染天空盒并在片段着色器中设置一个标志来为我的天空盒着色,记得修改视图矩阵以使用另一个统一标志移除平移在顶点着色器中。在片段着色器中,我将天空盒颜色设置为这样。这是一个基本的总结,没有粘贴所有的代码。

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;

我在颜色缓冲区中将天空盒的 alpha 分量设置为我的 Lighting pass 的标志。在这里,我将其设置为 -1。

在我的光照通道中,如果我的 gAlbedoSpec alpha 值为 -1,我只需选择使用 Diffuse Only 为我的框着色,而不是添加光照计算。

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

它相当简单,不需要太多代码即可完成工作。

【讨论】:

确保在评估这个“-1”标志时,你只做 一次 例如仅在定向光的 l-pass 中 - 而不是每个点/点/...光,因为您可能设置了“加法”混合模式,因此由于添加了多个光源,您的天空盒会过于明亮最终结果。【参考方案2】:

然后给它它缺少的深度信息。

在步骤 1 中渲染场景时,您使用了深度缓冲区。因此,当您绘制天空盒时,您需要一个使用相同深度缓冲区的 FBO。但是这个 FBO 还需要使用您在第 2 步中渲染的彩色图像。

现在,这个 FBO 不能与您在第 2 步中使用的 FBO 相同。为什么?

因为那将是undefined behavior。据推测,第 2 步从您的深度缓冲区读取以重建位置(如果不是这种情况,那么您可以从第 2 步将深度缓冲区附加到 FBO。但话又说回来,您也在浪费 tons 的性能)。但是该深度缓冲区也附加到 FBO。这使它成为未定义的行为。即使你不写深度,它在 OpenGL 下仍然是未定义的。

因此您将需要另一个 FBO,其中包含第 1 步中的深度缓冲区和第 2 步中的颜色缓冲区。

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

在任何一种情况下,在渲染天空盒时保持启用深度测试,但turn off depth writing。这将允许剔除现实世界后面的片段,但天空盒片段的深度将无限远。

【讨论】:

怎么使用深空盒子材质

...有关可用的天空盒着色器的信息,请参阅天空盒着色器。渲染管线兼容性内置渲染管线和通用渲染管线(URP)都专门使用天空盒来渲染天空。这些天空盒是使用天空盒着色器的材质。高清渲染管线(HDRP)不支持天空盒材质,而是包含... 查看详情

OpenGL:渲染天空盒立方体贴图问题

】OpenGL:渲染天空盒立方体贴图问题【英文标题】:OpenGL:Renderskyboxcubmapissue【发布时间】:2018-11-1414:29:45【问题描述】:我正在创建一个带有立方体贴图的天空盒,所以我使用这个网站来生成立方体贴图的侧面Skyboxgenerator,现在... 查看详情

基于opengl的基础渲染器

一、项目分工刘星魁:实现所有的功能 二、需求分析参考主流的渲染引擎,实现基本的摄影机,天空盒,模型,贴图,粒子系统,以及漫游功能2.软件需求规格说明书   三、原型设计使用素材:  1.天空盒的上... 查看详情

如何在OpenGL中实现灰度渲染?

】如何在OpenGL中实现灰度渲染?【英文标题】:howtoimplementgrayscalerenderinginOpenGL?【发布时间】:2010-10-2610:37:18【问题描述】:在渲染带纹理的多边形场景时,我希望能够在原始颜色渲染和“灰度”模式之间切换。我一直在尝试使... 查看详情

OpenGL ES - 如何在 Blender Cycles Render 中实现光泽着色器?

】OpenGLES-如何在BlenderCyclesRender中实现光泽着色器?【英文标题】:OpenGLES-HowtoimplementtheGlossyShaderinBlenderCyclesRender?【发布时间】:2015-01-1320:37:00【问题描述】:在BlenderCycles渲染中,有一个名为Glossy的着色器类型。现在我想在Android... 查看详情

透明天空盒+透明高度图的OpenGL混合问题

】透明天空盒+透明高度图的OpenGL混合问题【英文标题】:OpenGLBlendingproblemwithtransparentskybox+transparentheightmap【发布时间】:2011-02-2619:54:26【问题描述】:这是我的问题。在我渲染一个带有6个透明多边形(GL_BLEND、源GL_ONE、目标GL_ON... 查看详情

在 OpenGL ES 2 中实现 VBO 以渲染精灵

】在OpenGLES2中实现VBO以渲染精灵【英文标题】:ImplementingVBOstorenderspritesinOpenGLES2【发布时间】:2012-12-1415:09:08【问题描述】:我正在尝试实现VBO以提高OpenGL中的渲染速度,虽然我了解整体概念,但我不确定如何在带有精灵的2D中... 查看详情

批处理渲染器 (OpenGL) 的索引问题

】批处理渲染器(OpenGL)的索引问题【英文标题】:IndicesProblemwithaBatchRenderer(OpenGL)【发布时间】:2021-07-1223:41:28【问题描述】:我正在尝试在我正在做的引擎中实现3D对象的批量渲染,但我无法使索引正常。因此,在3D渲染器类中... 查看详情

2022-02-15u3d全栈班007-制作设置天空盒资源

...设置天空盒资源1.下载资源2.创建材质3.Material赋值贴图4.渲染场景5.渲染组件6.渲染组件总结前言在使用Unity开发游戏的时候,设置天空盒肯定是必不可少的。如果使用3D建模,建出天空盒放在场景中会比较麻烦。Unity中提供了简单... 查看详情

androidopengles2.0(十七)——球形天空盒vr效果实现

...这样,万事俱备,我们就可以编译glprogram,并进行球体的渲染了:其中纹理图片如下:渲染的结果如下:绘制出球体之后,我们需要让球与手机的姿态进行同步,也就是当手机背面超下时,我们看到的应该是地面,手机背面朝上... 查看详情

unity天空盒卡通渲染中如何实现云的消散效果

写在前面完成大气渲染之后,接下来就是考虑云渲染了。因为我想做的天空盒本身是想跟着这位大佬Unity卡通渲染程序化天空盒-知乎里叙述的进程来的,里面云实现的是原神里的云,原神又是在崩3的基础上加上了消... 查看详情

在OpenGL中实现VBO,窗口保持黑色

】在OpenGL中实现VBO,窗口保持黑色【英文标题】:ImplementingVBOinOpenGL,thewindowstayblack【发布时间】:2014-04-2119:05:14【问题描述】:我正在尝试通过我的VBO/OpenGL练习来解决一个错误,但在几个小时(几天)之后,我无法找到问题所... 查看详情

opengl学习脚印:立方体纹理和天空包围盒(cubemapsandskybox)

...我的github下载。本节内容整理自:1.Tutorial25:SkyBox2.www.learnopengl.comCubemaps创建Cubemap 查看详情

OpenGL游戏引擎渲染器[关闭]

】OpenGL游戏引擎渲染器[关闭]【英文标题】:OpenGLGameEngineRenderer[closed]【发布时间】:2016-05-0214:39:39【问题描述】:我正在使用OpenGL开发渲染引擎,我想知道:是否应该在模型中创建重复的顶点(对于平面着色,我们需要复制顶... 查看详情

✠opengl-9-天空和背景(代码片段)

目录天空盒天空穹顶实现天空盒从头开始构建天空盒使用OpenGL立方体贴图分析矩阵中值的存储及mat4转mat3原理环境贴图关于reflect函数补充说明天空盒或天空穹顶提供了有效且相对简单的方法,用来生成令人信服的地平线景观... 查看详情

OpenGL延迟渲染:点光源实现

】OpenGL延迟渲染:点光源实现【英文标题】:OpenGLdeferredrendering:pointlightimplementation【发布时间】:2015-04-1416:06:31【问题描述】:我正在尝试使用C#和OpenGL(使用OpenTK)编写延迟渲染器。但不明白我应该如何实现点光源的正常计算... 查看详情

如何在 UITableView 中实现类似 UIImageView 的延迟加载

】如何在UITableView中实现类似UIImageView的延迟加载【英文标题】:HowtoimplementUIImageView-likedelayedloadinginUITableView【发布时间】:2009-11-0312:20:00【问题描述】:背景:我有一个UITableView在每个单元格中显示一个图像。这些图像都是大pdf... 查看详情

Opengl:渲染到立方体贴图?

】Opengl:渲染到立方体贴图?【英文标题】:Opengl:RenderToCubemap?【发布时间】:2020-07-2116:41:52【问题描述】:我正在尝试将3d场景渲染到立方体贴图,但立方体贴图只渲染天空盒,这是我的RenderToCubemap函数:GLuintRenderToCubemap(glm::ve... 查看详情