UnityShader-复杂的光照

渲染路径


在Unity中,渲染路径决定了光照是如何应用到UnityShader中的。在UnityShader中需要为每一个Pass指定渲染路径,该Shader的光照计算才能正常进行。

Pass{
	Tags { "LightModel" = "ForwardBase"}
}

Unity5.0之后主要有四种渲染路径:前向渲染路径(Forward)、延迟渲染路径(Deferred)和旧版顶点照明渲染路径(Legacy Vertex Lit)、旧版延迟渲染路径(Legacy Deferred(light prepass)),可以在Edit->Projecting-Graphics中进行设置。设置渲染路径,Unity会把光照属性按渲染流程准备好,可以通过Unity提供的内置光照变量来访问这些属性。

标 签 名描 述
Always不管使用哪种渲染路径,该Pass总是会被渲染,但不会计算任何光照
ForwardBase用于前向渲染。该Pass会计算环境光、最重要的平行光、逐顶点/SH光源和Lightmaps
ForwardAdd用于前向渲染。该Pass会计算额外的逐像素光源,每个Pass对应一个光源
Deferred用于延迟渲染。该Pass会计算额外的逐像素光源,每个Pass对应一个光源
ShadowCaster把物体的深度信息渲染到阴影映射纹理(shadowmap)或一张深度纹理中
PrepassBase用于遗留的延迟渲染。该Pass会渲染法线和高光反射的指数部分
PrepassFinal用于遗留的延迟渲染。该Pass通过合并纹理、光照和自发光来渲染得到最后的颜色
Vertex、VertexLMRGBM和VertexLM用于遗留的顶点照明选软
Unity中的前向渲染

原理: 渲染对象的渲染图元时,计算两个缓冲区的信息(颜色缓冲区和深度缓冲区),利用深度缓冲来决定一个片元是否可见,如果可见就更新颜色缓冲区的颜色值,否则就丢弃。
前向渲染路径处理光照的三种方式: 逐顶点处理、逐像素处理、球谐函数(SH)处理。
决定一个光源使用哪种处理模式取决于它的类型和渲染模式。光源类型指的是平行光还是其他类型的光源,渲染模式指的是Render Mode变量,可以设置成Important或者Not Important。判断规则如下:

  • 场景中最亮的平行光按逐像素处理。
  • Render Mode 为 Not Important的光源,会逐顶点或者SH处理。
  • Render Mode 为 Important的光源,会逐像素处理。
  • 如果上面得到的逐像素光源小于Quality Setting中的逐像素光源数量,会有过更多光源以逐像素的方式进行渲染。
    Render Mode变量

前向渲染有两种Pass:

  • Base Pass。一般一个Unity Shader定义一个(双面渲染的话两个),执行一次。
  • Additional Pass。如果有N个光源影响该物体,就会执行N次。
    前向渲染的两种Pass

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

名 称类 型描述
_LightColorfloat4该Pass处理的逐像素光源的颜色
_WorldSpaceLightPos0float4_WorldSpaceLightPos0.xyz是该pass处理的逐像素光源的位置。如果该光源是平行光,那么_WorldSpaceLightPos0.w是0,其他光源类型w值为1
_LightMatrix0float4x4从世界空间到光源空间的变换矩阵。可以用于采样的cookie和光强衰减纹理
unity_4LightPosX0,unity_4LightPosY0,unity_4LightPosZ0float4仅用于Base Pass。前4个非重要的电光源在世界空间中的位置
unity_4LightAtten0float4仅用于Base Pass。存储了前4个非常重要的电光源的衰减因子
unity_LightColorhalf4[4]仅用于Base Pass。存储了前4个非重要的点光源的颜色

顶点照明渲染路径(Vertex)

即逐顶点计算光照。硬件配置要求最低,运算性能最高,效果最差的类型,不支持逐像素效果(如:阴影、法线映射、高精度高光反射等)。

顶点照明渲染可以使用的内置变量和函数:

名 称类 型描 述
unity_LightColorhalf4[8]光源颜色
unity_LightPositionfloat4[8]xyz分量是视角空间中的光源位置。如果光源是平行光,那么z分量值为0,其他光源类型z分量值为1
unity_LightAttenhalf4[8]光源衰减因子。如果光源是聚光灯,x分量是cos(spotAngle/2),y分量是1/cos(spotAngle/4);如果是其他类型的官员,x分量是-1,uy分量是1.z分量是衰减的平方w分量是光源范围开根号的结果
unity_SpotDirectionfloat4[8]如果光源是聚光灯的话,值为视角空间的聚光灯的位置;如果是其他类型的官员,值为(0,0,1,0)
延迟渲染路径(Deferred)

使用额外的缓冲区(G缓冲,Geometry-buffer),存储离摄像机最近的表明的其他信息(表面法线、位置、材质属性等)。避免前向渲染在大量实时光照下时的性能急速下降。实现就用两个Pass,与场景光源数目无关,而是和屏幕空间大小有关。

主要包含两个Pass:

  1. 第一个Pass:只计算哪些片元可见(深度缓冲技术),可见的就存到G缓冲中。
  2. 第二个Pass:利用G缓冲中的片元信息,计算光照。

缺点:

  • 不支持真正的抗锯齿(anti-aliasing)功能。
  • 不能处理半透明物体。
  • 显卡必须支持MRT(Multiple Render Targets)、Shader Mode3.0及以上、深度渲染纹理以及双面的模版缓冲。

光照衰减


Unity默认使用纹理查找的方式来计算逐像素的点光源和聚光灯的衰减。使用这种方法可以在一定程度上提升性能,而且得到的效果大部分情况下都是良好的,但是存在一些弊端:

  • 需要预处理得到采样为例,而且纹理的大小也会影响衰减的精度。
  • 不直观,同时也不方便,因此一旦把数据存储到查找表中,我们就无法使用其他的数学公式来计算衰减。

1.光照衰减纹理
UNITY_ATTEN_CHANNEL:可以得到衰减纹理中衰减值所在分量。
光照衰减纹理
  需要预处理得到采样纹理,纹理的大小会影响衰减精度。类似渐变纹理,(0, 0)表示与光源重合时的衰减值,(1, 1)为离光源空间最大距离的衰减值。
  Unity内部使用_LightTexture0的纹理来计算光源衰减。利用_LightMatrix0变换矩阵来计算点在光源空间的位置。

// 计算衰减纹理坐标值
float3 lightCoord = mul(_LightMatrix0, float4(i.worldPosition, 1)).xyz;
// 根据坐标对纹理采样,用dot点乘就是直接做距离的平方,`.rr`的意思就是取得到rgb值的r作为一个新的二维坐标即(r, r)。
fixed atten = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).UNITY_ATTEN_CHANNEL;

2. 数学公式计算衰减,使用的是线性衰减:

flaot distance = length(_WorldSpaceLightPos0.xyz) - i.worldPosition.xyz);
atten = 1.0 / distance;

阴影


Pass {
    Tags {"LightMode"="ShadowCaster"}
    CGPROGRAM
    #pragma vertex vert
    #pragma fragment frag
    #pragma multi_compile_shadowcaster
    #include "UnityCG.cginc"     

    struct v2f {
    	V2F_SHADOW_CASTER;;

	v2f vert (a2v v){
	    v2f o;
	    TRANSFER_SHADOW_CASTER_NORMALOFFSET(o)
	    return o;
	}
	fixed4 frag(v2f i) : SV_Target {
		SHADOW_CASTER_FRAGMENT(i)
	}
    ENDCG
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cchoop

有用的话请杯肥宅水

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值