unity shader中點光源(point light)的光照衰減處理

unity 的shader提供了2種光照模式:ForwardBase和ForwardAdd。spa

若是咱們的shader想要處理多種光照,那麼這兩種光照模式就都要被實現到不一樣的pass中。code

其中ForwardBase中處理的必然是平行光,因此想要處理點光源等其它光源須要在ForwardAdd中進行處理。orm

網上不少講解點光源的文章,不少都特別複雜或者根本運行不了,其實處理起來很是簡單,unity已經給咱們提供了現成的宏,供咱們使用:UNITY_LIGHT_ATTENUATIONblog

須要注意的是想要使用這個宏咱們須要引入AutoLight,UnityPBSLighting兩個文件:ip

#include "Autolight.cginc" 
            #include "UnityPBSLighting.cginc"
因爲UNITY_LIGHT_ATTENUATION宏中使用了#ifdef POINT來進行判斷,因此想要使宏生效咱們須要在引入文件以前 #define POINT

最後咱們的ForwardAdd的pass看起來應該是這樣:get

Pass{    
            Tags { "LightMode" = "ForwardAdd"}
            Blend One One
            CGPROGRAM  

            fixed4 _Color;

            #define POINT
        
            #include "Autolight.cginc" 
            #include "UnityPBSLighting.cginc"
            #pragma vertex vert      
            #pragma fragment frag  
            struct a2v{  
                float4 vertex : POSITION;  
                float3 normal : NORMAL;  
            };  
  
            struct v2f {  
                float4 pos : SV_POSITION;  
                float3 worldNormal : TEXCOORD0;  
                float3 worldPos : TEXCOORD1;  
            };  
  
            v2f vert(a2v v) {  
                v2f o;  
                o.pos = UnityObjectToClipPos (v.vertex);  
                o.worldNormal = UnityObjectToWorldNormal(v.normal);  
                o.worldPos =  mul(unity_ObjectToWorld,v.vertex).xyz;  
                return o;  
  
            }  
  
            fixed4 frag(v2f i) : SV_Target{  
                UNITY_LIGHT_ATTENUATION(attenuation, 0, i.worldPos);
                return _Color*attenuation;  
            }  

            ENDCG   
        }

這裏只是簡單的對點光源進行了處理,沒有其它任何內容。it

看下效果:io