一、渲染路径
1.什么是渲染路径(Rendering Path)
● 是决定光照实现的方式。(也就是当前渲染目标使用的光照流程)
二、渲染方式
首先看一下两者的直观的不同
前向/正向渲染-Forward Rendering
一句话概括:每个光照都计算
1、流程
● 如图所示,流程为:
○ 待渲染几何体 → 顶点着色器 → 片元着色器 → 渲染目标
○ 在渲染每一帧的时,每一个顶点/片元都要执行一次片元着色器代码,这时需要将所有的光照信息传到片元着色器中。
● 虽然大部分情况下的光照都趋向于小型化,而且照亮区域也不大,但即便是离这个像素所对应的世界空间的位置很远的光源,光照计算还是会把所有的光源考虑进去的。
● 简单来说就是不管光源的影响大不大,计算的时候都会把所有光源计算进去,这样就会造成一个很大的浪费
2、规则(如何渲染每一帧的)和注意事项
● 发生在顶点处理阶段,会计算所有顶点的光照。全平台支持
○ 规则1:最亮的几个光源会被实现为像素光照
○ 规则2:然后就是,最多四个光源会被实现为顶点光照
○ 规则3:剩下的光源会实现为效率较高的球面调谐光照(Spherical Hamanic),这是一种模拟光照
● 补充说明
○ 最亮的那盏光一定是像素光照
○ Light的Render Mode是important的光一定是像素光照
○ 如果前面的两条加起来的像素光照小于Quality Setting里的Pixel Light Count(最大像素光照数量),那么从剩下的光源中找出最亮的那几盏光源,实现为像素光照。
○ 最后剩下的光源,按照规则2或3。
○ 在base pass里执行一盏像素光、所有的顶点光和球面调谐光照,并且进行阴影计算。
○ 其余的像素光每盏一个Additional Pass,并且这些pass里没有阴影计算。
○ 场景中看到的阴影,全是base pass里计算出最亮那盏像素光的阴影,其他像素光是不计算阴影的。
● 最多的光源数是可以更改的
○ 以Unity中的为例,在project setting中
所以,如果一个物体受到n个光源影响,那么每个片元着色器执行代码时,都必须把n个光源传递给着色器中进行计算
延迟渲染-Deferred Rendering
一句话概括:先不计算光照,延迟到最后再一起计算
1、什么是延迟渲染
● 主要用来解决大量光照渲染的方案
● 延迟渲染的实质是:
○ 先不要做迭代三角形做光照计算,而是先找出来你能看到的所有像素,再去迭代光照。
○ 直接迭代三角形的话,由于大量三角形是看不到的,会造成极大的浪费。
2、流程
● 流程为:待渲染几何体 → 顶点着色器 → MRT → 光照计算 → 渲染目标
● 过程可以拆分为两个pass
○ 第一个pass:几何处理通路。
■ 首先将场景渲染一次,获取到的待渲染对象的各种几何信息存储到名为G-buffer的缓冲区中,这些缓冲区用来之后进行更复杂的光照计算。
■ 由于有深度测试,所以最终写入G-buffer中的,都是离摄像机最近的片元的集合属性,这就意味着,在G-buffer中的片元必定要进行光照计算。
○ 第二个pass:光照处理通路。
■ 这个pass会遍历所有G-buffer中的位置、颜色、法线等参数,执行一次光照计算。
Multiple Render Target(MRT)是一种指可以使绘制程序在单帧中同时渲染多个Render Target,也就是一次Draw可以将不同的信息分别画入多个Surface。是利用Pixel Shader实现Post-Process效果中很重要的一部分。每像素的数据保存到不同的缓冲区当中。这样的好处就是这些缓冲区数据由此可以成为照片级光照效果着色器的参数。!
在这种方法的帮助下,光照可以在所有几何图形被渲染以后最后进行应用,不再需要进行多步的渲染。因而这种技术也可以被称为延期着色(Deferred Shading)。存储在这种类型的表面中的数据可以包括位置、法线、颜色以及材质的信息。
3、一些注意事项
● G-buffer的概念
○ G-Buffer,全称Geometric Buffer ,译作几何缓冲区,它主要用于存储每个像素对应的位置(Position),法线(Normal),漫反射颜色(Diffuse Color)以及其他有用材质参数。
■ 根据这些信息,就可以在像空间(二维空间)中对每个像素进行光照处理。
○ UE4默认使用的是延迟管线
■ 我们在视图模式—缓冲显示—总览,就可以看到所有G-buffer的预览
● 延迟渲染不支持透明物体的渲染
○ 因为没有深度信息
○ 延迟渲染中的透明物体渲染方式和前向渲染相同
三、不同渲染路径的特性
1、后处理方式不同
● 如何需要深度信息进行后处理的话
○ 前向渲染需要单独渲染出一张深度图
○ 延迟渲染直接用G-buffer中的深度信息计算即可
2、着色计算不同(shader)
● 延迟渲染
○ 因为是最后统一计算光照的,所以只能算一个光照模型(如果需要其他光照模型,只能切换pass)
3、抗锯齿方式不同
● 后续具体说明
四、不同渲染路径的优劣
1、前向渲染的优点、缺点
优点
● 1.支持半透明渲染
● 2.支持使用多个光照pass
● 3.支持自定义光照计算方式
○ (延迟渲染是渲染到Gbuffer,再一起计算光照,所以不支持每一个物体用单独的光照方式计算)
缺点
● 1.光源数量对计算复杂度影响巨大
● 2.访问深度等数据需要额外计算(需要再渲染一张深度图)
2、延迟渲染的优点、缺点
优点
● 1.大量光照场景的情况下,优势明显
● 2.只渲染可见像素,节省计算量
● 3.对后处理支持良好(例如深度信息:直接拿G-buffer中的就行)
● 4.用更少的shader(所有的物体光照模型都一样,很多东西不用再定义了)
缺点
● 1.对MSAA支持不友好
● 2.透明物体渲染存在问题(深度问题,只渲染力物体最近的物体,渲染透明度时会出现问题)
● 3.占用大量的显存带宽
○ 涉及一个clear的操作,如果不清理的话,后边可以继续获取到
○ 每一帧都需要几张rt在显存中传输、清理等,会更耗带宽
● 4.只能使用同一个光照pass
五、其他部分
1、渲染路径的设置
● Project Setting中进行设置
2、TBDR
● 有两个TBDR,名字一样,内容不同
● 第一个:
○ 是SIGGRAPH2010提出的,作为传统Defferred Rendering的另一种主要改进,**分块延迟渲染(Tile-Based Deferred Rendering,TBDR)**旨在合理分摊开销(amortize overhead),自SIGGRAPH 2010上提出以来逐渐为业界所了解。基于延迟渲染的优化方式,通过分块来降低带宽内存用量(解决带宽和内存问题)
延迟渲染的分块,把整个图像分为很多块,再一块一块的渲染
● 第二个:
○ PowerVR基于手机GPU的TBR框架提出的改进,通过HSR减少Overdraw
○ TBDR这个架构是PowerVR提出来的对TBR的一次改进,在TBR的基础上再加了一个Deferred。
○ 通过做一些可见性测试来减少Overdraw
○ 涉及手机GPU架构,和延迟渲染没什么关系
3、其他渲染路径
1延迟光照(Light Pre-Pass / Deferred Lighting)
● 减少G-buffer占用的过多开销,支持多种光照模型
● 和延迟渲染的区别:
○ 用更少的buffe信息,着色计算的时候用的是forward,所以第三步开始都是前向渲染(可以对不同的物体进行不同的光照模型)
2Forward+(即Tiled Forward Rendering,分块正向渲染)
● 减少带宽,支持多光源,强制需要一个preZ
○ 通过分块索引的方式,以及深度和法线信息来到需要进行光照计算的片元进行光照计算。
○ 需要法线和深度的后处理需要单独渲染一个rt出来
○ 强制使用了一个preZ(如果没涉及过这个概念的话,可以理解为进行了一个深度预计算)
3 群组渲染(Clustered Rendering)
● 带宽相对减少,多光源下效率提升
● 分为forward和deferred两种
● 详细补充拓展:https://zhuanlan.zhihu.com/p/54694743
4、延迟渲染中MSAA存在的问题
● 前边补充的图里有提到“NO MSAA Possible”,也就是说延迟渲染管线不支持MSAA
● MSAA在延迟渲染中存在的问题:像素已经被光栅化了,所以没法用更大的像素来渲染。
5、不同path下光源shader的编写
● 详情请看官方文档
6、PreZ(Zprepass)
● 实际上就是一个深度计算
● 和深度图的区别
○ 都是深度信息
■ PreZ是用一个pass,只算深度
■ 深度图是算成了一张RT(RenderTexture),把深度信息绘制到了一张RT上。
○ 具体用途:
■ 大规模草、透明排序会用到PreZ
● early-z 和 PreZ的区别
○ early-z,自动的,对面数有要求(硬件自动)
○ PreZ,当early-z失效的时候,或者需要深度图的时候,一种手动代替的方案
● 后边课程还会细讲
7、一些补充
● Unity的urp是不支持延迟渲染的,老管线支持。
● UE默认管线就是延迟渲染管线
● 一般延迟渲染用于主机/大项目