Shader "NLD_URP/NLD_Scene_Lambert" { Properties { // [MainColor] _BaseColor ("Main Color", color) = (1,1,1,1) [MainTexture] _MainTex ("Texture", 2D) = "white" {} _MaskTex ("Mask", 2D) = "white" {} _OutlineColor("Outline Color",color)=(0.1,0.1,0.2,1) _Outline("Thick of Outline",range(0,0.1))=0.02 _Factor("Factor",range(0,1)) = 0.5 _Smoothness("Smoothness", range(0,1.0)) = 0.5 _shadowScale("ShadowScale", range(0, 1.0)) = 0.5 _specularScaleB("SpecularScaleB", range(0, 10.0)) = 2.0 _Gloss("Gloss", range(0, 10.0)) = 2.0 _SpecialColor("SpecialColor", color) = (1,1,1,1) _SpecialStrengh("_SpecialStrengh", range(0, 10.0)) = 1 _DiffuseStrengh("DiffuseStrengh", range(0, 10)) = 1 _MinDiffuse("MinDiffuse", range(0, 1)) = 0.1 _fadeAlpha("FadeAlpha", range(0, 1.0)) = 1.0 } SubShader { Tags { "RenderType"="Opaque" "RenderPipeline" = "UniversalPipeline" } LOD 100 HLSLINCLUDE #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" struct appdata { float4 positionOS : POSITION; float3 normal : NORMAL; float4 tangent : TANGENT; float2 uv : TEXCOORD0; }; struct v2f { float2 uv : TEXCOORD0; float4 positionHCS : SV_POSITION; float3 normalWS : TEXCOORD1; float3 positionWS : TEXCOORD02; }; TEXTURE2D(_MainTex); SAMPLER(sampler_MainTex); TEXTURE2D(_MaskTex); SAMPLER(sampler_MaskTex); CBUFFER_START(UnityPerMaterial) float4 _MainTex_ST; float4 _MaskTex_ST; half _Smoothness; half _specularScaleB; half _specularScaleG; half _shadowScale; half _Gloss; half4 _SpecialColor; half _SpecialStrengh; half _DiffuseStrengh; half _MinDiffuse; half _Outline; half4 _OutlineColor; half _Factor; half _fadeAlpha; CBUFFER_END ENDHLSL Pass { Cull Back Name "ForwardLit" Tags { "LightMode" = "UniversalForward" } Cull Back ZWrite On ZTest Less Blend SrcAlpha OneMinusSrcAlpha HLSLPROGRAM #pragma vertex vert #pragma fragment frag // 开启接收阴影 #pragma multi_compile _ _MAIN_LIGHT_SHADOWS //主光源阴影 #pragma multi_compile _ _SHADOWS_SOFT //软阴影 #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl" #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl" v2f vert (appdata v) { v2f o; o.positionHCS = TransformObjectToHClip(v.positionOS.xyz); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.normalWS = TransformObjectToWorldNormal(v.normal); o.positionWS = TransformObjectToWorld(v.positionOS.xyz); return o; } half4 frag (const v2f i) : SV_Target { if (_fadeAlpha <= 0.01) { discard; } // sample the texture half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); if (color.a < 0.5) discard; color.a = 1; half4 colorMask = SAMPLE_TEXTURE2D(_MaskTex, sampler_MaskTex, i.uv); //当前模型接收阴影 float4 SHADOW_COORDS = TransformWorldToShadowCoord(i.positionWS); //放入光照数据 Light lightData = GetMainLight(SHADOW_COORDS, i.positionWS, 1); //多光照阴影数据 half shadow = lightData.shadowAttenuation * lightData.distanceAttenuation; color.xyz *= max(shadow, _shadowScale); // Optimize conditional branches using lerp and step color.xyz *= lerp(1.0, _specularScaleB, step(0.5, colorMask.b)); // Calculate lighting half3 worldPos = i.positionWS; half3 cameraPos = _WorldSpaceCameraPos.xyz; half3 viewDir = normalize(cameraPos - worldPos); half3 worldNormal = i.normalWS; half3 lightDir = lightData.direction; float3 reflectDir = normalize(mul(worldNormal , 2) - lightDir); // Phong 模型公式高光反射计算 float3 _speColor = _SpecialColor.xyz; float3 specular = lightData.color.rgb * _speColor * pow(max(0,dot(reflectDir,viewDir)), _Gloss); // half3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz; half diffuse = saturate(dot(lightDir, worldNormal)) * _DiffuseStrengh; diffuse = max(diffuse, _MinDiffuse); half3 litColor = diffuse * color.xyz + specular * _SpecialStrengh; // Apply lighting only where mask.g > 0.5 color.xyz = lerp(color.xyz, litColor, step(0.5, colorMask.g)); color.a = _fadeAlpha; return color; } ENDHLSL } Pass { Name "Outline" Tags {"LightMode"="Outline"} Cull Front ZTest Less ZWrite On HLSLPROGRAM #pragma vertex vert #pragma fragment frag v2f vert (appdata v) { v2f o; o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.normalWS = float3(0, 0, 0); o.positionWS = float3(0, 0, 0); float3 dir = TransformObjectToWorldNormal(v.normal); float3 dir2 = v.normal; float D = dot(dir, dir2); dir = dir*sign(D); dir = dir*_Factor + dir2*(1-_Factor); v.positionOS.xyz += dir*_Outline; o.positionHCS = TransformObjectToHClip(v.positionOS.xyz); return o; } half4 frag (v2f i) : SV_Target { if (_fadeAlpha <= 0.01) { discard; } // sample the texture half4 color = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv); if (color.a < 0.5) discard; half4 c = _OutlineColor; c.a = _fadeAlpha; return c; } ENDHLSL } Pass { Name "ShadowCaster" Tags { "LightMode" = "ShadowCaster" } // ------------------------------------- // Render State Commands ZWrite On ZTest LEqual Cull Back HLSLPROGRAM #pragma target 2.0 // ------------------------------------- // Shader Stages #pragma vertex vert #pragma fragment frag v2f vert (appdata v) { v2f o; o.positionHCS = TransformObjectToHClip(v.positionOS.xyz); o.uv = TRANSFORM_TEX(v.uv, _MainTex); o.normalWS = float3(0, 0, 0); o.positionWS = float3(0, 0, 0); return o; } half4 frag (v2f i) : SV_Target { // 当 fadeAlpha >= 0.99 时,跳过纹理采样和 dithering,直接投射阴影 if (_fadeAlpha >= 0.99h) { return 1; } // 完全透明时不投射阴影 if (_fadeAlpha <= 0.01h) { discard; } // Dithering 实现渐隐阴影效果 half2 p = floor(i.positionHCS.xy); half2 p2 = floor(p * 0.5h); half2 p4 = floor(p2 * 0.5h); half d = frac(dot(p, half2(0.5h, 0.25h)) + dot(p2, half2(0.125h, 0.0625h)) + dot(p4, half2(0.03125h, 0.015625h))); half dither = d * 0.984375h + 0.015625h; half fade = _fadeAlpha * _fadeAlpha * (3.0h - 2.0h * _fadeAlpha); clip(fade - dither); return 1; } ENDHLSL } } }