Unity渲染路径详解1
渲染路径概述
渲染路径可以理解为应用层信息在着色器当中接收怎样的数据输入,经过怎样的处理,最后以怎样的方式呈现在二维平面上。
不同的渲染路径要求的信息不同,计算方式不用,计算量不同,消耗便不同。针对不同的平台,不同的硬件环境,应该选择适合的渲染路径。
在Unity中不同的渲染路径对应着不同光照信息的输入,不同光照的处理方式,不同的阴影生成方式,最后不同的呈现方式等等。
在Unity当中通过为Pass定义特殊Tag和特定的编译指令来控制使用的渲染路径,获得对应的光照信息。
前向渲染、正向渲染(Forward Rendering Path)
在Unity当中使用定义LightMode为ForwardBase和ForwardAdd 两种Tag的两个Pass来实现前向渲染:
Pass{
Tags{
"LightMode" = "ForwardBase" }
}
Pass{
Tags{
"LightMode" = "ForwardAdd" }
}
在场景当中,一个物体可能会受到多个光源的影响,如果对这些光源都采取同一种光照计算方式(比如逐像素光照),那么对应的消耗可能会很高,而且一些光源本身对物体的影响并不大,所以应该根据光源的特质分类进行计算,达到可以令人满意的效果。
在前向渲染当中,采用的分类策略为:
最亮的光源采取逐像素光照;而后最多4个光源采用逐顶点光照;其余的光源采用SH光照(球谐函数光照,计算速度更快,这里暂时不做详解)
那么根据什么来对一个光源进行分类呢?主要有以下要求:
1. Render Mode设置为Not Important的光源总是采用逐顶点光照或者SH光照
2. 最亮的directional light总是逐像素光照
3. Render Mode设置为Important的光源总是采用逐像素光照
4. 如果以上分类之后逐像素光照的光源还是小于Quality Setting当中的Pixel Light Count ,则更多的光源按照逐像素光照进行处理,按照亮度排序。
将所有的光源分类之后,要在哪里进行处理呢?同样也有要求:
ForwardBase Pass处理一个逐像素directional light和所有的逐顶点/SH光源。
ForwardAdd Pass处理其余的逐像素光照。
其余实现细节
Bass Pass中一般还会实现光照贴图、环境光以及自发光效果。在这个Pass当中的directional light可以实现阴影。另外使用光照贴图的物体不会受到SH光源的影响。
如果使用OnlyDirectional Tag,那么Bass Pass将只会处理directional light、光照贴图、环境光以及自发光效果,不会处理SH光源和逐顶点光源。
Addtional Pass对每一个逐像素光源都处理一次,在这个Pass当中默认处理光源是没有阴影的,除非定义multi_compile_fwdadd_fullshadows指令。
Unity 具体代码实现
我找到一份比较有参考价值的Unity Forward Rendering 的代码实现(Unity Stander Shader内部实现),这里给到工程的链接
我们只截取和前向渲染相关的部分:
Pass
{
Name "FORWARD"
Tags {
"LightMode" = "ForwardBase" }
Blend [_SrcBlend] [_DstBlend]
ZWrite [_ZWrite]
CGPROGRAM
#pragma target 3.0
// -------------------------------------