urp 实现阴影ShadowCast 简单实例

   目录:

        1、urp阴影shader实现

        2、漫反射光照和兰伯特光照效果展示

        3、 注意事项

        从build-in内置渲染管线到urp渲染管线其中有个比较大的变化就是shadowCast写法变化,这里给出一个简单的shader实现阴影的效果。具体内容就不做细说,各位看官直接看代码

 1)urp阴影shader实现

Shader "test/Shadowcast"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        //因为有多个pass,公共包含的提取出来
         HLSLINCLUDE
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"
            CBUFFER_START(UnityPerMaterial)
                float4 _MainTex_ST;
            CBUFFER_END
        ENDHLSL


        Pass
        {
            HLSLPROGRAM
            //需要一盏全局光
            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS
            //是否开启软阴影
            #pragma multi_compile _ _SHADOWS_SOFT
            



            #pragma vertex vert
            #pragma fragment frag

            // #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            // #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
            #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/CommonMaterial.hlsl"
            // #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };

            struct v2f
            {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                float3 positionWS : TEXCOORD1;
                float3 worldNormal : TEXCOORD2;
                
            };
            //Light数据结构
            // struct Light
            // {
            //     half3   direction;
            //     half3   color;
            //     half    distanceAttenuation;
            //     half    shadowAttenuation;
            // };

            sampler2D _MainTex;

            v2f vert (appdata v)
            {
                v2f o;
                //o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);
                //o.vertex = TransformObjectToHClip(v.vertex.xyz);
                o.positionWS = TransformObjectToWorld(v.vertex.xyz);
                o.vertex = TransformWorldToHClip(o.positionWS);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                o.worldNormal = TransformObjectToWorldNormal(v.normal);
                //o.shadowCoord = TransformWorldToShadowCoord(o.positionWS);
                return o;
            }
            half4 frag(v2f i) : SV_Target
            {

                half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
                half3 worldNormal = normalize(i.worldNormal);
                //获取主光源,这是urp 内置shader的函数,具体内容查看light数据结构
                Light light = GetMainLight();
            
                half3 worldLightDir = light.direction;

                //下面有两种光照模式,自己可以屏蔽试下效果
                //兰伯特光照模型---1
                //half3 pow = saturate(dot(worldNormal,worldLightDir)*0.5+0.5);

                //漫反射光照---2
                half3 pow = saturate(dot(worldNormal,worldLightDir));
                half3 diffuse = light.color.rgb * pow;

                half4 finalCol = tex2D(_MainTex, i.uv);

                return half4(finalCol.rgb*(diffuse+ambient),1);


            }
            ENDHLSL
        }

        pass
        {

            Name "ShadowCast"

			Tags{ "LightMode" = "ShadowCaster" }

             HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

             //开启ALPHA 测试,主要是做镂空
            #pragma shader_feature _ALPHATEST_ON


            struct a2v {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                float3 normal : NORMAL;
            };
            struct v2f {
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            // 以下三个 uniform 在 URP shadows.hlsl 相关代码中可以看到没有放到 CBuffer 块中,所以我们只要在 定义为不同的 uniform 即可
             float3 _LightDirection;
             sampler2D _MainTex;

            v2f vert(a2v v)
            {
                v2f o = (v2f)0;
                float3 worldPos = TransformObjectToWorld(v.vertex.xyz);
                half3 normalWS = TransformObjectToWorldNormal(v.normal);


                worldPos = ApplyShadowBias(worldPos,normalWS,_LightDirection);
                o.vertex = TransformWorldToHClip(worldPos);

                #if UNITY_REVERSED_Z
    			o.vertex.z = min(o.vertex.z, o.vertex.w * UNITY_NEAR_CLIP_VALUE);
#else
    			o.vertex.z = max(o.vertex.z, o.vertex.w * UNITY_NEAR_CLIP_VALUE);
#endif
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                return o;

            }

            real4 frag(v2f i) : SV_Target
            {
                //支持透明镂空阴影
#if _ALPHATEST_ON
                half4 col = tex2D(_MainTex, i.uv);
                clip(col.a - 0.001);
#endif
                return 0;
            }

            ENDHLSL
        }
    }
}

2)漫反射光照和兰伯特光照效果展示

        1、漫反射光照效果:

                        

        2、兰伯特光照效果 

                         

3) 注意事项

        场景中需要一盏平行光作为主光源

猜你喜欢

转载自blog.csdn.net/lejian/article/details/126091579