Unity ShaderLab开发实战(二)渲染路径

       渲染路径决定了光照如何应用在Shader中,需要为每个Pass指定要使用的渲染路径,这样光照计算才可以被正确进行。Unity--Edit--Project Setting--Player--Other Setting--Rendering Path里可以设置,也可以在相机的渲染路径设置中覆盖Project Setting中的设置。三种(前向渲染路径(Forward Rendering Path),延迟渲染路径(Deferred Rendering Path,5.X版本后有两种),顶点照明渲染路径(Vertex Lit Rendering Path))。eg:

        Pass

        {

             Tags { "LightMode" = "ForwardBase" }

       }

       LightMode标签支持的渲染路径设置选项:

       为一个Pass设置了前向渲染路径的标签,会告诉Unity把光照属性按前向渲染的流程准备好,然后可以通过提供的内置光照变量访问这些属性。如果没设置,那么取到的光照变量可能有问题。

一、前向渲染路径:

        原理:每进行一次完整的前向渲染,会渲染该对象的渲染图元,并计算颜色缓冲区和深度缓冲区的信息。深度缓冲决定片元是否可见,如果可见则更新颜色缓冲区的颜色值。如果一个物体在多个逐像素光源的影响区域内,则该物体需要执行多个Pass。每个Pass计算一个逐像素光源的光照结果,帧缓冲中将这些结果混合成最终的颜色。如果N个物品M个光源则有N*M个Pass。

       Unity中前向渲染路径有三种处理光照的方式:逐顶点,逐像素,球谐函数(SH)处理。决定光源使用哪种处理模式的是这个Light的类型和渲染模式(Important)设置。具体:

       1、场景中最亮的平行光逐像素处理。

       2、RenderMode为Not Important的逐顶点或者SH处理。

       3、RenderMode设置为Important表示逐像素光源。

       4、如果上面得到最终的逐像素光源数量小于Quality Setting中的逐像素光源数量,则会有更多的光源以逐像素的方式渲染。

       前向渲染有两种Pass:Base Pass和Additional Pass。两种Pass如下,摘自《Unity Shader入门精要》

      Blend One One:Additional Pass开启和设置了混合模式,因为希望与上次的光照结果在帧缓存中叠加,而不是覆盖。

      一个Shader通常一个Base Pass和一个Additional Pass, 一个Bass Pass通常只会执行一次,Additional Pass有可能多次调用。除了第一个Pixel平行光之外,每个其他Pixel光源都会在—个单独的Additional Pass内被执行,也就是说场景中的Pixel光源数为n,则Additional Pass会被执行n-1次,是上个结果的叠加。

       可以使用UnityCGcginc中的shade4PointLights函数在ForwardBase中计算Vertex光源的照明。对于Pixel光源,必须使用
_WorldspaceLightPos0和_LightColor0来计算。

       前向渲染可以使用的内置光照变量:

       前向渲染可以使用的内置光照函数:

二、顶点照明渲染路径(前向渲染路径的一个子集,Unity5中已经基本不用了)

三、延迟渲染路径

       很明显,前向渲染有效率问题,多个Pass时有很多重复计算。

        延迟渲染有两个Pass,用了额外的缓冲区:G缓冲,存储了表面的一些信息(法线,位置,材质属性等)。第一个Pass不进行任何光照计算,只计算哪些片元可见,可见的话就把它的相关信息放在G缓冲区中。第二个Pass,利用G缓冲区的片元信息进行真正的光照计算。效率不依赖于光源和场景复杂度,依赖于屏幕空间大小。所以,延迟渲染适合场景中光源多时,但是不能处理半透明物体,对显卡也有要求。

     Unity中有两种延迟渲染,一种是5之前的,一种是新的。

实战:

        1.当shader中存在多个不同渲染路径的pass时,怎么办?

        Unity在Defend渲染路径下,会找在Defend渲染模式下的Pass,不会执行其他的Pass,如果没找到,再找Forward模式的Pass,返回,如果没找,再找VertexLit模式下的Pass;在Forward渲染模式下,先找Forward模式的Pass,返回,如果没找,再找VertexLit模式下的Pass。所以只会执行一个渲染路径下的Pass,不会同时执行多个不同渲染路径下的Pass。

         2.Always Pass是按照在代码中的位置先后执行的。

猜你喜欢

转载自blog.csdn.net/jfy307596479/article/details/84832636
今日推荐