Part1. Unity前向渲染的介绍
1.1 前向渲染的基本原理
前向渲染的主要特点是针对每个物体,对于每个光源都会分别进行一次光照计算,最后的颜色值是由所有光源的光照结果混合而成的,比如场景中有M个物体,N个光源,则渲染整个场景需要N × M个Pass,可以看到如果光源数目多,前向渲染的开销是非常巨大的
为了解决这个开销问题,选让引擎常常会限制在每个物体上进行逐像素光照的数目,Unity引擎也是这样做的
1.2 Unity中前向渲染的实现原理
Unity的前向渲染中,实现光照有三种方式:逐像素处理、逐顶点处理、球谐函数(SH),它们的开销是依次递减的
Unity中,我们可以手动设置光照的重要度模式,有三种可选:Important, Not Important, Auto
设置为Important的光源,总是按照逐像素方式进行处理
设置为Not Important的光源,会按照逐顶点或者SH的方式处理
设置为Auto的光源,将由Unity根据光源对于物体的影响程度,对光源进行重要度排序,然后分配逐顶点、逐像素、SH方式的使用
1.3 Base Pass
前向渲染的Pass被分为两类:Base Pass 和 Additional Pass
Base Pass只会执行一次(如果定义了多个Bass Pass,也可能执行多次)
Bass Pass需要处理一个逐像素的平行光和其他所有逐顶点光源和SH光源,如果存在多个平行光,引擎会选择将最重要的平行光传递给Base Pass处理
环境光和自发光的实现也是在Base Pass中实现的,因为如果在Additional Pass中实现这些效果,由于Additional Pass是多次执行的,对于每个光源都会执行一次Additional Pass,这就会造成多个环境光和自发光的叠加,这是我们不希望看到的,而Base Pass只会执行一次,适用于处理环境光和自发光
Bass Pass是默认开启阴影的
1.4 Additional Pass
Additional Pass是多次执行的,对于每个光源都会执行一次Additional Pass
Additional Pass需要对其余所有的逐像素光源进行处理,即每个逐像素光源调用一次Additional Pass
Additional Pass默认不开启阴影,我们也可以使用#pragma multi_compile_fwdadd_fullshadows代替#pragma multi_compile_fwdadd编译指令来开启阴影
Additional Pass需要开启混合模式,因为每个逐顶点光源是依次计算的,我们不能直接覆盖上一次的计算颜色,而需要进行混合
Part2.代码实现一个典型的前向渲染Shader
Pass {
// Pass for ambient light & first pixel light (directional light)
Tags { "LightMode"="ForwardBase" }
CGPROGRAM
// 需要添加base pass的编译指令
#pragma multi_compile_fwdbase
#pragma vertex vert
#pragma fragment frag
#include "Lighting.cginc&#