目录
Unity中的渲染路径有多种,可以在Editor/ProjectSetting中的Graphics中进行调整。当取消掉Use Defaults时,可以在Rendering Path中进行切换,这里是控制整个项目的渲染路径,其中主要有Forward和Deffered两种,也就是前向渲染和延时渲染
1.前向渲染Forward
1.1 渲染设置
摄像机渲染路径的设置:摄像机也能改变自己的渲染路径,可以直接使用项目中的,也能自己设置单独。
Shader中渲染路径的设置:在Pass块中的Tags中的LightMode设置为ForwardBase或者ForwardAdd
具体为Tags{ "LightMode" = "ForwardBase}和Tags{"LightMode" = "ForwardAdd"}
设置之后同时要添加#pragma multi_compile_fwdbase和#pragma multi_compile_fwdadd
1.2 两个pass块
前向渲染通常使用两个Pass块,一个是ForwardBase,用于计算最重要的光照(一般默认为创建项目时自带的直线光照)以及顶点光照和球谐光照
另一个Pass块是ForwardAdd,用于计算逐像素光源。这个Pass块必须开启Blend混合,如果不开启的话,颜色缓冲区的颜色值就会被覆盖了,这样只会呈现最后一个灯光的ForwardAddPass块(这里可以试一下将Blend One One注释掉,然后再Frame Debug中逐帧查看渲染顺序)
1.3 Unity如何判断光源类型
Unity如何判断哪个光源是逐像素,还是逐顶点,还是球谐的。再光源的面板中可以再RenderMode中看到。它有三个选项,分别是Auto,Important,Not Important。如果某个光源是Important,那么它一定是逐像素的。如果Important的数量大于项目设置的最大逐像素光源数,它仍然会被按照逐像素光源处理。如果是Not Important,它一定是逐顶点的或者球谐的。
如果是Auto的话,那么要看项目设置中的最大逐像素光源数,这个可以在Editor/Project Settings的Quality中的Pixel Light Count中设置,一般默认是4(这里也假设是4)。如果灯光的数量小于4,且都是Auto,那么它们一定会在ForwardAdd中进行计算,也就是会被处理为逐像素。如果Auto的数量大于4,假如有5个,那么其中一个就会被按照顶点光照计算,也就是走ForwardBase的Pass块。那么超过4个的话,Unity如何确定哪些光源会被处理为逐像素或者顶点呢?这里说的是光源对物体的影响程度,包括远近,到物体的强度以及颜色等。但具体如何计算,官网也没给出详细的说明
1.4 性能影响
其中,ForwardBase的Pass块会先被调用,然后是调用ForwardAdd的Pass块,且有几个逐像素光源对这个物体起作用,就会调用几次ForwardAdd的Pass块,如果有多个物体m,n个逐像素光源,且这n个光源对m个物体都起作用,那么就会渲染m*n次,如果项目中m和n过多,项目会非常卡。
2.延时渲染Deffered
2.1 原理
为了解决当逐像素光源过多使用前向渲染的性能问题,延时渲染被重新提了出来。(据说延时渲染提出的要早,不知真假)它的原理很简单。与前向渲染不同,延时渲染在渲染过程中开始并不会直接计算光照,而是会按照正常流程将物体呈现到屏幕像素中去(这里并不会呈现),同时将与光照有关的信息(比如漫反射颜色,高光颜色,法线,切线,深度等)存入G-Buffer缓冲区。这些信息是关于最终呈现到屏幕中的像素的,已经脱离了原来的物体信息了。当存入之后才会进行一系列与光照反射阴影等过程的具体计算,这些计算是根据屏幕上的像素点的信息进行计算的。
2.2 两部分Shdaer
第一部分的Shader是正常的shdaer编写,它应该与材质相关联。但与前向渲染的shdaer不同,在这个shader中,逐片元函数返回的是4个4维向量,一般用一个结构体存储。也就是存储的漫反射与遮罩,高光反射与平滑度,法线,自发光lightmap反射等信息。
第二部分的Shdaer是作为模板来具体计算光照的,它是可选的(Unity有默认模板),它会根据第一部分Shdaer的G-Buffer值来具体计算光照。它在Editor/Project Settings/Graphics中的Deferred中设置的,它可以是Built-in shader,也可以是自己编写的Custom shdaer
2.3 性能影响
宏观上来看(排除反射阴影等造成的影响),如果场景中有m个物体,那么它会先调用m次drawcall将这些物体(无光照计算)呈现到屏幕像素中,同时计算这些像素的光照信息到缓冲区。之后根据这些信息与场景中的n个光源(对m个物体都产生了影响)进行光照计算(其实是根据像素的信息进行计算的)。一共是m + n。也就是与物体和光源数量分别成正比
微观上看,由于只与像素有关,那么它只跟屏幕分辨率有关,像素固定,那么只与光源数量成正比(一台设备)。
2.4 不足
它并不能支持半透明物体的渲染,如果出现半透明物体的渲染,它会另外在ForwardBase中去渲染,具体可以在Frame Debug中查看
它需要非常多的内存来存储G-Buffer
当然它的效果不如前向渲染细致
它不能实现基于硬件的抗锯齿效果