首页 > 其他分享 >前向渲染和延迟渲染

前向渲染和延迟渲染

时间:2024-02-28 12:33:34浏览次数:20  
标签:渲染 几何体 前向 计算 光照 延迟

前向渲染

先计算光照再裁剪。

前向渲染是现在最基础,也是最多引擎使用的标准。前向渲染的流程是给定一个几何体,引擎对其进行从顶点到像素着色器的一系列计算,然后输出到最终的图像缓冲区。场景中有多个几何体时,引擎就是对其挨个进行渲染,完成一个再继续下一个。

前向渲染的问题

前向渲染有一个问题就是无效渲染太多,比如场景中有四个物体,互相之间存在叠压关系,按照前向渲染的流程,先前渲染了一个物体之后,它的一部分被后一个渲染的物体挡住了,那么被挡住的这部分就是无效的计算,毕竟我们在屏幕上是看不到这部分的。
另一个问题在于难以支持过多的光源,对于每个需要逐像素计算的光源,渲染一个几何体的时候需要逐个做一次光照计算。如果有一个场景,其中有10个几何体需要进行渲染,有四个光源对整个场景产生影响,那么渲染整个场景需要进行40次光照计算。而且其中还有很多的计算被挡住了。

前向渲染的优点

如果需要在场景中使用多个着色模型,甚至是每个几何体都使用不同的着色模型和渲染技术,前向渲染是可以很好的支持的。
另外,因为前向渲染这种逐个渲染的特点,它非常适合渲染半透明物体。
image

上面图中就是简单的前向着色的示意图。一个几何模型,进入渲染流程中,首先就是要经过顶点着色器(vertex shader)的计算,顶点着色器一般会对顶点做空间变换,有的还有顶点位移和UV偏移等计算。经过顶点着色器之后就到了曲面细分着色器(subdivision shader),这个阶段是可选的,用来给模型的表面增加顶点数,并且产生更细微的凹凸,当然游戏中的大部分模型是不会做这个阶段的计算的,一般用在高质量游戏的渲染。几何着色器(geometry shader)也是可选的,一般会用来做基于模型表面的顶点渲染出一片草丛等功能。像素着色器(fragment shader)当然是大部分模型都要经历的,用来做采样贴图和计算光照等计算。

前向渲染的优化策略——前向实时剔除(在光照计算前就剔除被遮挡的部分)

Early-z : 传统的渲染管线中深度测试是在计算完光照之后才进行的,但是计算完光照再进行深度剔除,被挡到的部分就白计算了。在光栅化阶段,每个模型的深度就已经写入深度缓存了,为什么不先进行深度剔除再计算光照呢?这就是Early-z功能,这也是现在所有硬件和渲染管线都有的功能。
Z-Prepass :上面说的Early-Z优化虽然是在每个模型计算光照之前就进行了深度剔除,但是还是不能完全避免无效光照计算的问题。比如第一个模型渲染的时候,深度通道是没有信息的,这时哪怕这个模型会被后来渲染的模型完全遮挡,它也会计算光照。Z-Prepass就可以解决这个问题,首先把整个场景中的模型都渲染一遍,全部都写入Z-Buffer ,这次渲染除了Z-Buffer其他的信息都不计算。然后再渲染一遍场景,这次渲染关闭深度写入,每个像素和Z-Buffer中已经存在的深度信息进行对比,只有通过测试的像素才会计算光照。这种方法虽然避免了无效的光照计算,但是却执行了两次顶点着色器,所以最好是在场景中物体的光照计算非常复杂但是顶点数量却不是很多的情况下使用。
Hi-Z :上面两种方法都是在GPU段进行的,而Hi-Z这种方法是在CPU端进行的,在几何体被提交到GPU之前会进行遮挡测试,如果几何体被别的物体遮挡了就不会提交到GPU 。这种方法直接减少了GPU需要渲染的几何体数量,适用于细碎且数量多的模型。

延迟渲染

先裁剪再计算光照。

延迟渲染可以支持大量的实时光照,所以现在的大型电脑游戏基本都已经是延迟渲染了。
延迟渲染就是把光照计算延迟到深度测试之后的渲染方式,延迟着色适合在场景中实时光照很多的情况下使用,而且延迟着色可以对每个光源都按逐像素的方式计算。那Z-prepass也是先渲染出深度缓存进行深度测试后再计算光照的,和延迟渲染有什么不同?最大的不同点就在于G-buffer ,Z-prepass在深度测试后也还是按照一个几何体渲染完再进行下一个这种方式来渲染的 ,延迟渲染是几何体的信息传递到G -buffer之后就和几何体没多大关系了,接下来的操作都是对G-buffer进行的。
如果说前向渲染中几何体数量N和光照数量M产生的计算量是N*M的话延迟渲染产生的计算量就是N+M 。这是因为延迟渲染的思路就是先把几何体的信息都渲染到二维空间中(G-Buffer),然后把G-Buffer整体进行光照计算,G-Buffer中存在的信息都是会最终呈现在屏幕上的,不会有无效计算。
那么G-Buffer中到底会储存哪些信息?不同的引擎对于G-Buffer的处理也是不一样的,对于一个针对PBR渲染的引擎来说,至少会有深度、模板、颜色、法线、世界位置、金属、粗糙、高光这些信息。
image

延迟渲染的优点

当场景中所有几何体都写入G-Buffer之后,光照计算就和场景中有多少物体,多少三角形没有关系了。只渲染可见的像素,不会有无效的计算。

延迟渲染的缺点

延迟渲染要求场景中要使用更少的Shader种类,毕竟如果每个模型的每个材质都使用不同的Shader ,那到底应该在G-Buffer中储存哪些信息呢?这对于程序和项目管理上来说可以说是个巨大的优点,可以节省性能,优化流程什么的。但是对美术来说却是个大缺点,因为限制了美术的表现效果。
前向渲染只需要深度缓冲和最终的颜色缓冲就够了,延迟渲染需要缓存的信息实在太多了,这造成了带宽的开销大幅增加。这也是为什么现在的手机游戏基本都是前向渲染的原因,毕竟手机带宽太小,延迟渲染虽然看起来很美好,但是用不了。
对于半透明无能为力,所有半透明的物体都需要等待不透明物体以延迟渲染完成之后,在用前向渲染的方式渲染半透明物体。

分块延迟渲染

虽然延迟渲染已经把光照数量和三角形数量不再关联了,但是当场景中的光源数量不断上升之后,就算是延迟渲染也有点撑不住。
这时就需要分块延迟渲染,它的思路是把G-Buffer分成很多个小块,分析每个小块受到哪些光源的影响,然后逐个分块进行着色,那些受光源影响的数量少的小块就不需要那么多的光照计算了。这种渲染方式在光源数量少的情况下效果不明显,但是光源数量越多它优化的性能也就越多。

标签:渲染,几何体,前向,计算,光照,延迟
From: https://www.cnblogs.com/HalfDog/p/18039916

相关文章

  • 渲染指南:自建渲染农场vs雇用云渲染农场服务
    许多设计师和动画制作人在面临一些对成本和时间敏感的渲染项目时,常常会选择使用云渲染服务。尤其是在截止日期迫近的时候,云渲染服务提供了一种快速和有效的解决方案。另一方面,对于有持续渲染需求的个人或机构,可能会考虑建立自己的渲染服务器群。在做出使用云渲染服务或是自建渲染......
  • 全面了解云渲染:一篇文章带你掌握关键信息
    随着数字内容创作领域的飞速发展,伴随着技术设备的持续升级,我们见证了渲染技术的一个重要转变:从传统依赖个人电脑的方式,转向利用云渲染服务。云渲染利用了其远程强大的处理能力,可经济高效地完成复杂的渲染任务。这项服务为电影、动画和视觉效果等各类渲染工作带来了便利,吸引了广泛......
  • Vue学习笔记18--列表渲染
    总结: <!DOCTYPEhtml><htmllang="en"><head><metacharset="UTF-8"><metaname="viewport"content="width=device-width,initial-scale=1.0"><title>列表渲染</title>&l......
  • Vue学习笔记18--条件渲染
    条件渲染总结:v-if写法:v-if="表达式"v-else-if="表达式"v-else="表达式"适用于:切换频率较低的场景特点:不展示DOM元素直接被移除注意:v-if可以和v-else-if、v-else一起使用,但要求其结构不能被“打断”——即,中间不能有其他元素v-show写法:v-show="表达式"适用于:切......
  • AngularJs 数据渲染完成之后,执行回调方法
     请求远程数据--》数据模型变化--》angularjs监控到模型变化--》重新渲染页面。 注册一个自定义的指令.directive('OnReanderFinsh',[function(){return{restrict:'A',link:function($scope,element,attrs,controller){......
  • 如何渲染最原始的yuv视频数据?
    一.整体思路我们在用纹理增加细节那篇文章中提到过,要将图片渲染在屏幕上,首先要拿到图片的像素数组数据,然后将像素数组数据通过纹理单元传递到片段着色器中,最后通过纹理采样函数将纹理中对应坐标的颜色值采样出来,然后给最终的片段赋予颜色值。现在换成了yuv视频,我们应该如何处......
  • 浏览器渲染原理
    浏览器渲染原理浏览器渲染原理第一步:URL地址解析。第二步:缓存检查通过一个url网址,首先得到的是一个html。渲染过程中,遇到link标签向服务器发送拿到css代码,遇到script标签向服务器发送拿到js代码,遇到img标签向服务器发送拿到图片文件。如果浏览器上有......
  • 【vue3】【router】跳转页面渲染两次问题
    最近做一款毕设遇到一个问题:如图所示部分是因为渲染了两次组件导致执行了两次onMounted加载了相同数据。 router.ts以下是我的路由相关配置: default布局:keepalive App.vue 最后导致这个原因正是因为布局组件default.vue和App.vue同时使用了keepalive,只要任意一边取消......
  • 父子组件渲染销毁过程
    父子组件生命周期执行顺序加载渲染数据过程父组件beforeCreate-->父组件created-->父组件beforeMount-->子组件beforeCreate-->子组件created-->子组件beforeMount-->子组件mounted-->父组件mounted-->更新渲染数据过程父组件beforeUpdate-->子组件......
  • RabbitMq的实践中解决过消息丢失、消息幂等性、消息顺序消费、消息延迟消费等问题;
    1、RabbitMq如何实现消息延迟消费?1.1、延时插件答:延时插件rabbitmq_delayed_message_exchange,下载好之后放到对应plugins目录下,然后启用插件声明交换器类型为x-delayed-message来标示此交换机为延时交换机,发送消息时在header中添加x-delay参数来控制消息的延时时间......