Unity shader学习之阴影,衰减统一处理
使用unity AutoLight.cginc文件里的内置函数 UNITY_LIGHT_ATTENUATION
shader如下:
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)' Shader "Custom/Forward Rendering" { Properties { _MainTex("Main Texture", 2D) = "white" {} _Specular("Specular", Color) = (1,1,1,1) _Gloss("Gloss", Range(8,256)) = 8 } SubShader { Pass { Tags { "LightMode" = "ForwardBase" } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #include "UnityCg.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" sampler2D _MainTex; fixed4 _Specular; float _Gloss; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 worldNormal : TEXCOORD1; float4 worldPos: TEXCOORD2; SHADOW_COORDS(3) }; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.uv; o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex); TRANSFER_SHADOW(o); return o; } fixed4 frag(v2f i) : SV_TARGET { fixed4 albedo = tex2D(_MainTex, i.uv); fixed4 ambient = albedo * UNITY_LIGHTMODEL_AMBIENT; float3 worldLight = normalize(UnityWorldSpaceLightDir(i.worldPos.xyz)); float3 worldView = normalize(UnityWorldSpaceViewDir(i.worldPos.xyz)); fixed4 diff = albedo * _LightColor0 * max(0, dot(i.worldNormal, worldLight)); float3 halfDir = normalize(worldView + worldLight); fixed4 spec = albedo * _Specular * pow(max(0, dot(halfDir, i.worldNormal)), _Gloss); UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos.xyz); fixed4 col = ambient + (diff + spec) * atten; return col; } ENDCG } Pass { Tags { "LightMode" = "ForwardAdd" } Blend One One CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdadd_fullshadows // 添加阴影效果 #include "UnityCg.cginc" #include "Lighting.cginc" #include "AutoLight.cginc" sampler2D _MainTex; fixed4 _Specular; float _Gloss; struct appdata { float4 vertex : POSITION; float2 uv : TEXCOORD0; float3 normal : NORMAL; }; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; float3 worldNormal : TEXCOORD1; float4 worldPos: TEXCOORD2; SHADOW_COORDS(3) }; v2f vert(appdata v) { v2f o; o.pos = UnityObjectToClipPos(v.vertex); o.uv = v.uv; o.worldNormal = UnityObjectToWorldNormal(v.normal); o.worldPos = mul(unity_ObjectToWorld, v.vertex); TRANSFER_SHADOW(o); return o; } fixed4 frag(v2f i) : SV_TARGET { fixed4 albedo = tex2D(_MainTex, i.uv); float3 worldLight = normalize(UnityWorldSpaceLightDir(i.worldPos.xyz)); float3 worldView = normalize(UnityWorldSpaceViewDir(i.worldPos.xyz)); fixed4 diff = albedo * _LightColor0 * max(0, dot(i.worldNormal, worldLight)); float3 halfDir = normalize(worldView + worldLight); fixed4 spec = albedo * _Specular * pow(max(0, dot(halfDir, i.worldNormal)), _Gloss); UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos.xyz); fixed4 col = (diff + spec) * atten; return col; } ENDCG } } Fallback "VertexLit" }
效果如下: