UnityShader 學習筆記 8 處理陰影和光照衰減
阿新 • • 發佈:2018-12-25
同時處理陰影和光照衰減的Shader
- 原始碼:
Shader "_MyShader/6_Light/2_ShadowAndAttenuation" { Properties { _DiffuseColor ("DiffuseColor",COLOR) =(1,1,1,1) _SpecularColor ("SpecularColor",COLOR) =(1,1,1,1) _SpecularRange ("SpecularRange",Range(5,100)) = 20 } SubShader { Pass { Tags{"LightMode" = "ForwardBase"} CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdbase #include "Lighting.cginc" #include "AutoLight.cginc" fixed4 _DiffuseColor; fixed4 _SpecularColor; float _SpecularRange; struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; }; struct v2f{ float4 pos:SV_POSITION; fixed3 worldNormalDir:POSITION1; fixed3 worldLightDir:POSITION2; half3 reflectDir:POSITION3; fixed3 worldViewDir:POSITION4; //Blinn-Phong fixed3 blinn_Phong_Dir:POSITION5; //宣告陰影座標 float4 worldPos:POSITION6; SHADOW_COORDS(2) }; v2f vert(a2v v){ v2f o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.worldPos = mul(_Object2World,v.vertex); o.worldLightDir = normalize(_WorldSpaceLightPos0); o.worldNormalDir = normalize(mul(v.normal,(float3x3)_World2Object)); //計算反射向量 o.reflectDir = normalize(reflect(-o.worldLightDir,o.worldNormalDir)); //計算視角向量 o.worldViewDir = normalize(_WorldSpaceCameraPos - mul(_Object2World,v.vertex)); //Blinn-Phong o.blinn_Phong_Dir = normalize(o.worldLightDir + o.worldViewDir); //計算並輸出陰影座標 TRANSFER_SHADOW(o); return o; } fixed4 frag(v2f i):SV_Target{ UNITY_LIGHT_ATTENUATION(atten,i,i.worldPos); //漫反射階段 fixed3 ambientColor=UNITY_LIGHTMODEL_AMBIENT; fixed3 diffuseColor = _LightColor0 * _DiffuseColor*saturate(dot(i.worldNormalDir,i.worldLightDir)); //高光階段 fixed3 specularColor = _LightColor0 * _SpecularColor * pow(saturate(dot(i.reflectDir,i.worldViewDir)),_SpecularRange); //Blinn-Phong光照 //fixed3 specularColor = _LightColor0 * _SpecularColor * pow(saturate(dot(i.worldNormalDir,i.blinn_Phong_Dir)),_SpecularRange); fixed4 col = fixed4(ambientColor + (diffuseColor + specularColor) * atten,1); return col; } ENDCG } //----------------------------------------------------------------------------------------------------- Pass { Tags{"LightMode" = "ForwardAdd"} Blend One One CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma multi_compile_fwdadd_fullshadows #include "Lighting.cginc" #include "AutoLight.cginc" fixed4 _DiffuseColor; fixed4 _SpecularColor; float _SpecularRange; struct a2v { float4 vertex:POSITION; float3 normal:NORMAL; }; struct v2f{ float4 pos:SV_POSITION; fixed3 worldNormalDir:POSITION1; fixed3 worldLightDir:POSITION2; half3 reflectDir:POSITION3; fixed3 worldViewDir:POSITION4; //Blinn-Phong fixed3 blinn_Phong_Dir:POSITION5; float4 worldPos:POSITION6; SHADOW_COORDS(2) }; v2f vert(a2v v){ v2f o; o.pos=mul(UNITY_MATRIX_MVP,v.vertex); o.worldPos = mul(_Object2World,v.vertex); #ifdef USING_DIRECTIONAL_LIGHT o.worldLightDir = normalize(_WorldSpaceLightPos0); #else o.worldLightDir = normalize(_WorldSpaceLightPos0 - o.worldPos); #endif o.worldNormalDir = normalize(mul(v.normal,(float3x3)_World2Object)); //計算反射向量 o.reflectDir = normalize(reflect(-o.worldLightDir,o.worldNormalDir)); //計算視角向量 o.worldViewDir = normalize(_WorldSpaceCameraPos - mul(_Object2World,v.vertex)); //Blinn-Phong o.blinn_Phong_Dir = normalize(o.worldLightDir + o.worldViewDir); TRANSFER_SHADOW(o); return o; } fixed4 frag(v2f i):SV_Target{ UNITY_LIGHT_ATTENUATION(atten, i, i.worldPos.xyz) //漫反射階段 //fixed3 ambientColor=UNITY_LIGHTMODEL_AMBIENT; fixed3 diffuseColor = _LightColor0 * _DiffuseColor*saturate(dot(i.worldNormalDir,i.worldLightDir)); //高光階段 fixed3 specularColor = _LightColor0 * _SpecularColor * pow(saturate(dot(i.reflectDir,i.worldViewDir)),_SpecularRange); //Blinn-Phong光照 //fixed3 specularColor = _LightColor0 * _SpecularColor * pow(saturate(dot(i.worldNormalDir,i.blinn_Phong_Dir)),_SpecularRange); fixed4 col = fixed4((diffuseColor + specularColor) * atten,1); return col; } ENDCG } } FallBack "VertexLit" }