文章目录

  • Shadow Caster
    • Using URP Shadow Caster Pass
    • Using Custom Shadow Caster Pass
      • 先来看看 [没有] apply shadow bias 版本的
      • 再来看看 [有] apply shadow bias 版本的
    • CBuffer 定义位置建议
      • 会不会浪费 CBUFFER 空间
  • Shadow Rerieve
  • 优化
    • Shadow Pancaking
    • Shadow Distance Fade out
    • 提升阴影的掠射角的质量
  • 完整的 Shader
  • References
  • Extended reading

因为近期需要将之前 Built-in RP 升级到 URP,所以啊,要调整的内容真的是多

其中,在以前自定义 shader 中使用到 阴影的部分,都需要调整一下,使用 URP 自带的 shader API(如果自己写阴影方案,但是又没有 unity 引擎源码,你会遇到一堆问题,例如,你可以看看我之前写的一篇:Unity Shader - Custom Shadow Map (New Version) - 这其中就遇到 LOD 问题ReplaceShader 功能不够强大的问题


Shadow Caster

  • 使用 URP 中现有 Shader 的 Shadow Caster Pass
  • 自己写一个,一般如果做项目的话,都自己写,出问题也能自己修改

Using URP Shadow Caster Pass

OK,下面将的是:使用 URP 的 Shadow Caster Pass
ShaderLab 中引用其他 Shader 中的 Pass 是很简单的用到:UsePass,如下:

        // jave.lin : 使用 Universal 中自带的 Universal Render Pipeline/Lit Shader 中的 ShadowCaster PassUsePass "Universal Render Pipeline/Lit/ShadowCaster"

用现成的多数情况下是比较方便的,但就是限制在使用现有的功能,虽然说可以修改 URP 的 shader ,但是如果你升级 URP 版本就不方便了

使用 URP 的 Shadow Caster 需要注意:该 Pass 使用了 Instancing,如果你的材质没有开启Instancing 开关,那么可以在 FrameDebugger 看到是没有合批的,一个一个的绘制,效率低下,如下图:

如果我们在材质勾上 instancing 就可以看到合批了

有两个选择:那么要 instancing? 还是 SRP Batcher 呢?这要看你自己去权衡,但是这里有一些建议:

  • 如果大量绘制的网格一致,那么建议用 instancing

    • 如果用上 instancing,那么你的其他 pass 最好都同步添加上 instancing 的支持
  • 如果网格不一致,但是 shader ,且 shader 变体一致,那么建议用 SRP Batcher

如何 SRP Batcher 主要是将 uniform 变量都划分到对应的 CBuffer 块中,可以查看我之前一篇:Unity Shader - shader lab 的 SRP Batcher compatible 兼容性


Using Custom Shadow Caster Pass

OK,下面将的是自定义的 Shadow Caster Pass

自定义的好处就是,可以在很多功能上根据自己的需求来设置,最大化优化,但前提就是你要足够熟悉

从文档、还有 URP 的代码来看,shader 变体 需要注意几点:

  • Shader Pass 的 LightMode Tag,要设置为:ShadowCaster,Like This : Tags{"LightMode" = "ShadowCaster"} 底层 pass filter 需要

  • #pragma multi_compile _ _MAIN_LIGHT_SHADOWS 控制是否开启、关闭接受功能的 变体,在 Light 的 Component 中调整:Shadow Type 即可看到效果

  • #pragma shader_feature _ALPHATEST_ON shader_feature 的 alpha test 变体,便于树叶之类的镂空需要

    • 同时 shader properties 添加上:[Toggle] _ALPHATEST ("Alpha Test On", Float) = 0 便于材质上调整

总之 shader 变体就设置下面几个就好:

            #pragma multi_compile _ _MAIN_LIGHT_SHADOWS#pragma multi_compile _ _SHADOWS_SOFT#pragma shader_feature _ALPHATEST_ON

如果说,你能确定你的 shader 不需要某些变体,如:已确定:需要阴影、且是软阴影,且是 alpha test 镂空,那么直接 #define 即可,不需要 Off 的情况,那么将这些变体宏统统改为 #define 明文定义,如下:

            #define _MAIN_LIGHT_SHADOWS#define _SHADOWS_SOFT#define _ALPHATEST_ON

这样即可减少变体数量,但是代价就是不能中途同过 Shader.EnabledKeyword, 或是 Shader.DisabledKeyword C# 脚本API 来控制变体开关了,这需要你根据自己项目实际情况来选择


先来看看 [没有] apply shadow bias 版本的

这和 Built-in RP 中的应用算法不太一样,但是这个可读性比 Built-in RP 的高很多,这两个参数具体在:
UniversalRenderPipelineAsset 资源的 Shadow/Depth Bias 和 Normal Bias

  • Depth Bias 是,相对灯光方向的深度偏移
  • Normal Bias 是相对 Rim 边缘强度做深度偏移

这两个参数都可以在:Shadows.hlsl 文件中的 ApplyShadowBias 方法中看到是如何应用的:

float3 ApplyShadowBias(float3 positionWS, float3 normalWS, float3 lightDirection)
{float invNdotL = 1.0 - saturate(dot(lightDirection, normalWS));float scale = invNdotL * _ShadowBias.y;// normal bias is negative since we want to apply an inset normal offsetpositionWS = lightDirection * _ShadowBias.xxx + positionWS;positionWS = normalWS * scale.xxx + positionWS;return positionWS;
}

对应 Shader 的 Shadow Caster Pass 如下

        Pass // jave.lin : 没有 ApplyShadowBias{Name "ShadowCaster"Tags{ "LightMode" = "ShadowCaster" }HLSLPROGRAM#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#pragma vertex vert#pragma fragment frag#pragma shader_feature _ALPHATEST_ON// jave.lin : 根据你的 alpha test 是否开启而定//#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_Astruct a2v {float4 vertex : POSITION;float2 uv : TEXCOORD0;};struct v2f {float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;};v2f vert(a2v v){v2f o = (v2f)0;o.vertex = TransformObjectToHClip(v.vertex.xyz);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}real4 frag(v2f i) : SV_Target{#if _ALPHATEST_ONhalf4 col = tex2D(_MainTex, i.uv);clip(col.a - 0.001);
#endifreturn 0;}ENDHLSL}

再来看看 [有] apply shadow bias 版本的

应用了 两个 bias 参数后,在 Depth Bias, Normal Bias 调整才能看到效果

shader 的 Shadow Caster Pass,如下:

        Pass // jave.lin : 有 ApplyShadowBias{Name "ShadowCaster"Tags{ "LightMode" = "ShadowCaster" }HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"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;float4 _ShadowBias; // x: depth bias, y: normal biashalf4 _MainLightShadowParams;  // (x: shadowStrength, y: 1.0 if soft shadows, 0.0 otherwise)// jave.lin 直接将:Shadows.hlsl 中的 ApplyShadowBias copy 过来float3 ApplyShadowBias(float3 positionWS, float3 normalWS, float3 lightDirection){float invNdotL = 1.0 - saturate(dot(lightDirection, normalWS));float scale = invNdotL * _ShadowBias.y;// normal bias is negative since we want to apply an inset normal offsetpositionWS = lightDirection * _ShadowBias.xxx + positionWS;positionWS = normalWS * scale.xxx + positionWS;return positionWS;}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);o.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}real4 frag(v2f i) : SV_Target{#if _ALPHATEST_ONhalf4 col = tex2D(_MainTex, i.uv);clip(col.a - 0.001);
#endifreturn 0;}ENDHLSL}

CBuffer 定义位置建议

如果你的 shader lab 中各个 pass 使用到的 cbuffer 都最好定义在同一块,而不是每个 pass 中独立定义,这样才能最大限度发挥 SRP Batcher ,也提高 SRP Batcher Compatible 的可能

如:

Shader "xxx"
{Properties { ... }SubShader{Pass {Name "Body"CBUFFER_START(UnityPerMaterial)float4 _Params;CBUFFER_END}Pass {Name "ShadowCaster"CBUFFER_START(UnityPerMaterial)float4 _Params;CBUFFER_END}}
}

如上代码,可以看到 Body, ShadowCaster 两个 Pass 中都有 CBUFFER 块的定义那么建议改为:

Shader "xxx"
{Properties { ... }SubShader{HLSLINCLUDECBUFFER_START(UnityPerMaterial)float4 _Params;CBUFFER_ENDENDHLSLPass {Name "Body"}Pass {Name "ShadowCaster"}}
}

就是把 CBUFFER 块定义在 HLSLINCLUDE ... ENDHLSL 中,也可以定义在独立的 *.hlsl 中,然后 #include "YourCBufferDef.hlsl" 进来也是可以的


会不会浪费 CBUFFER 空间

浪费肯定会有的,但是,你要知道 CBUFFER 是共享的,而且我们这个不是 PerDraw 而是 PerMaterial 的 CBUFFER,几乎可以忽略不计,而且对 SRP Batcher Compatible 的话,通常情况下是有助于性能提升的


Shadow Rerieve

和 Built-in RP 中一样,在渲染提示的 Pass 中,只要添加对 Shadow Map 采样,在做深度比较,然后影响着色亮度即可达到 阴影 效果,下面是主要的渲染实体的 Pass 代码,主要看带有:jave.lin : shadow recieve 的注释部分的代码

        Pass{HLSLPROGRAM//#define _MAIN_LIGHT_SHADOWS//#define _SHADOWS_SOFT//#define _ALPHATEST_ON#pragma multi_compile _ _MAIN_LIGHT_SHADOWS#pragma multi_compile _ _SHADOWS_SOFT#pragma shader_feature _ALPHATEST_ON#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;};struct v2f{float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;float4 shadowCoord : TEXCOORD1; // jave.lin : shadow recieve 在给到 fragment 时,要有阴影坐标};//CBUFFER_START(UnityPerMaterial)//    half4 _Color;//    half4 _Color1;//    float4 _MainTex_ST;//CBUFFER_ENDsampler2D _MainTex;v2f vert (appdata v){v2f o;//o.vertex = mul(UNITY_MATRIX_MVP, v.vertex);//o.vertex = TransformObjectToHClip(v.vertex.xyz);float3 worldPos = TransformObjectToWorld(v.vertex.xyz);o.vertex = TransformWorldToHClip(worldPos);o.uv = TRANSFORM_TEX(v.uv, _MainTex);o.shadowCoord = TransformWorldToShadowCoord(worldPos); // jave.lin : shadow recieve 将 世界坐标 转到 灯光坐标(阴影坐标)return o;}half4 frag(v2f i) : SV_Target{half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);//Light mainLight = GetMainLight(i.shadowCoord); // jave.lin : shadow recieve 获取 shadowAttenuation 衰减值//half shadow = mainLight.shadowAttenuation;//return shadow;//return unity_IndirectSpecColor;half shadow = MainLightRealtimeShadow(i.shadowCoord); // jave.lin : shadow recieve 如果不需要用到 Light 结构的数据,可以直接使用该接口来获取//real4 ambient = UNITY_LIGHTMODEL_AMBIENT;//real4 ambient = glstate_lightmodel_ambient;half4 col = tex2D(_MainTex, i.uv);half4 finalCol = col * _Color * _Color1;// 直接用 ambient 作为阴影色效果不太好//finalCol.rgb = lerp(ambient.rgb, finalCol.rgb, shadow);// 混合后的效果好很多finalCol.rgb = lerp(finalCol.rgb * ambient.rgb, finalCol.rgb, shadow); // jave.lin : shadow recieve 我们可以将 ambient 作为阴影色// jave.lin : shadow recieve 部分写法可以是:finalCol.rgb *= shadow; 也是看个人的项目需求来定return finalCol;}ENDHLSL}

优化


Shadow Pancaking

阴影花纹(Shadow Pancaking)
引用 cat like coding 的博文中的图:

处理方式:

            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);// jave.lin : 参考 cat like coding 博主的处理方式
#if UNITY_REVERSED_Zo.vertex.z = min(o.vertex.z, o.vertex.w * UNITY_NEAR_CLIP_VALUE);
#elseo.vertex.z = max(o.vertex.z, o.vertex.w * UNITY_NEAR_CLIP_VALUE);
#endifo.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}

处理后的效果

理解 cat like coding 博主的这么处理的思路:

             // jave.lin : 参考 cat like coding 博主的处理方式
#if UNITY_REVERSED_Zo.vertex.z = min(o.vertex.z, o.vertex.w * UNITY_NEAR_CLIP_VALUE);
#elseo.vertex.z = max(o.vertex.z, o.vertex.w * UNITY_NEAR_CLIP_VALUE);
#endif

首先:UNITY_NEAR_CLIP_VALUE 单单从字面上理解就是 Unity相机的近截面值

这是里相机最近的有效值

我们知道,如果多边形的某些顶点如果离镜头过近,那么就会被 裁减掉

那么如果我们的 shadow space 空间的 camera 在拍摄某个 opaque 物体时,shadowmap 的内容就会出现镂空的问题,如下图:

解决它的方法就是:判断如果某些点比近截面还要 近

那么我们就将 这些点压扁到近截面 一样的位置就可以了

如下图:


Shadow Distance Fade out

阴影的距离淡出

下面的 smoothstep 中 第一个参数是:开始弹出距离,第二个是,结束淡出距离,vz 就是 view space z 的意思

一般可以参数话调整,但是在 URP 中是没有这两个值的,你也可以扩展 URP 的脚本来控制

只要将下面的代码,再 fragment shader 中处理一下就可以了,传入一个 世界坐标位置,所以你可以理解为,将:世界坐标转为 视图坐标,取得 z 值做为距离

下面是在 FS 中计算 VZ 的,可以优化成:在 VS 中计算 VZ,然后作为 V2F 的插值变量传给 FS 即可

float GetDistanceFade(float3 positionWS)
{float4 posVS = mul(GetWorldToViewMatrix(), float4(positionWS, 1));//return posVS.z;
#if UNITY_REVERSED_Zfloat vz = -posVS.z;
#elsefloat vz = posVS.z;
#endif// jave.lin : 30.0 : start fade out distance, 40.0 : end fade out distancefloat fade = 1 - smoothstep(30.0, 40.0, vz);return fade;
}

应用 fade out 值:

half shadow = MainLightRealtimeShadow(i.shadowCoord); // jave.lin : shadow recieve 如果不需要用到 Light 结构的数据,可以直接使用该接口来获取
half shadowFadeOut = GetDistanceFade(i.positionWS); // jave.lin : 计算 shadow fade out
shadow = lerp(1, shadow, shadowFadeOut); // jave.lin : 阴影 shadow fade out

输出一下 fade out 值,效果如下图:


提升阴影的掠射角的质量

之前在项目中,发现很多 几何体表面 与 灯光方向 接近平行时,阴影会出现很多瑕疵

优化方法也比较简单,代码如下:

// jave.lin 优化 几何体表面 与 灯光方向 接近平行时,阴影会出现很多瑕疵的问题
half shadow = MainLightRealtimeShadow(i.shadowCoord); // jave.lin : shadow recieve 如果不需要用到 Light 结构的数据,可以直接使用该接口来获取
halfshadowFadeOut = GetDistanceFade(i.positionWS); // jave.lin : 计算 shadow fade out
shadow = lerp(1, shadow, shadowFadeOut); // jave.lin : 阴影 shadow fade out// 假如你这里有个:diffuse
...
half diffuse = max(dot(N, L));
diffuse = min(diffuse, shadow);half specular = ...half factor = diffuse + specular * shadow;// 这样使用 factor 来控制光阴的瑕疵就会少很多

完整的 Shader

// jave.lin 2021/10/14Shader "Test/UnlitSTD"
{Properties{_MainTex ("Texture", 2D) = "white" {}_Color ("Color", Color) = (1, 1, 1, 1)_Color1 ("Color1", Color) = (1, 1, 1, 1)[Toggle] _ALPHATEST ("Alpha Test On", Float) = 0}SubShader{Tags { "RenderType"="Opaque" }LOD 100HLSLINCLUDE#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"CBUFFER_START(UnityPerMaterial)half4 _Color;half4 _Color1;float4 _MainTex_ST;CBUFFER_ENDENDHLSLPass{HLSLPROGRAM//#define _MAIN_LIGHT_SHADOWS//#define _SHADOWS_SOFT//#define _ALPHATEST_ON#pragma multi_compile _ _MAIN_LIGHT_SHADOWS#pragma multi_compile _ _SHADOWS_SOFT#pragma shader_feature _ALPHATEST_ON#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;};struct v2f{float4 vertex : SV_POSITION;float2 uv : TEXCOORD0;float4 shadowCoord : TEXCOORD1; // jave.lin : shadow recieve 在给到 fragment 时,要有阴影坐标float3 positionWS : TEXCOORD2;};//CBUFFER_START(UnityPerMaterial)//    half4 _Color;//    half4 _Color1;//    float4 _MainTex_ST;//CBUFFER_ENDsampler2D _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.shadowCoord = TransformWorldToShadowCoord(o.positionWS); // jave.lin : shadow recieve 将 世界坐标 转到 灯光坐标(阴影坐标)return o;}float GetDistanceFade(float3 positionWS){float4 posVS = mul(GetWorldToViewMatrix(), float4(positionWS, 1));//return posVS.z;#if UNITY_REVERSED_Zfloat vz = -posVS.z;#elsefloat vz = posVS.z;#endif// jave.lin : 30.0 : start fade out distance, 40.0 : end fade out distancefloat fade = 1 - smoothstep(30.0, 40.0, vz);return fade;}half4 frag(v2f i) : SV_Target{half3 ambient = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);//Light mainLight = GetMainLight(i.shadowCoord); // jave.lin : shadow recieve 获取 shadowAttenuation 衰减值//half shadow = mainLight.shadowAttenuation;//return shadow;//return unity_IndirectSpecColor;half shadow = MainLightRealtimeShadow(i.shadowCoord); // jave.lin : shadow recieve 如果不需要用到 Light 结构的数据,可以直接使用该接口来获取half shadowFadeOut = GetDistanceFade(i.positionWS); // jave.lin : 计算 shadow fade outshadow = lerp(1, shadow, shadowFadeOut); // jave.lin : 阴影 shadow fade out//real4 ambient = UNITY_LIGHTMODEL_AMBIENT;//real4 ambient = glstate_lightmodel_ambient;half4 col = tex2D(_MainTex, i.uv);half4 finalCol = col * _Color * _Color1;// 直接用 ambient 作为阴影色效果不太好//finalCol.rgb = lerp(ambient.rgb, finalCol.rgb, shadow);// 混合后的效果好很多finalCol.rgb = lerp(finalCol.rgb * ambient.rgb, finalCol.rgb, shadow); // jave.lin : shadow recieve 我们可以将 ambient 作为阴影色// jave.lin : shadow recieve 部分写法可以是:finalCol.rgb *= shadow; 也是看个人的项目需求来定return finalCol;}ENDHLSL}Pass // jave.lin : 有 ApplyShadowBias{Name "ShadowCaster"Tags{ "LightMode" = "ShadowCaster" }HLSLPROGRAM#pragma vertex vert#pragma fragment frag#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"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;float4 _ShadowBias; // x: depth bias, y: normal biashalf4 _MainLightShadowParams;  // (x: shadowStrength, y: 1.0 if soft shadows, 0.0 otherwise)// jave.lin 直接将:Shadows.hlsl 中的 ApplyShadowBias copy 过来float3 ApplyShadowBias(float3 positionWS, float3 normalWS, float3 lightDirection){float invNdotL = 1.0 - saturate(dot(lightDirection, normalWS));float scale = invNdotL * _ShadowBias.y;// normal bias is negative since we want to apply an inset normal offsetpositionWS = lightDirection * _ShadowBias.xxx + positionWS;positionWS = normalWS * scale.xxx + positionWS;return positionWS;}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);// jave.lin : 参考 cat like coding 博主的处理方式
#if UNITY_REVERSED_Zo.vertex.z = min(o.vertex.z, o.vertex.w * UNITY_NEAR_CLIP_VALUE);
#elseo.vertex.z = max(o.vertex.z, o.vertex.w * UNITY_NEAR_CLIP_VALUE);
#endifo.uv = TRANSFORM_TEX(v.uv, _MainTex);return o;}real4 frag(v2f i) : SV_Target{#if _ALPHATEST_ONhalf4 col = tex2D(_MainTex, i.uv);clip(col.a - 0.001);
#endifreturn 0;}ENDHLSL}//        Pass // jave.lin : 没有 ApplyShadowBias
//        {//            Name "ShadowCaster"
//            Tags{ "LightMode" = "ShadowCaster" }
//            HLSLPROGRAM
//            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
//            #pragma vertex vert
//            #pragma fragment frag
//            #pragma shader_feature _ALPHATEST_ON
//            // jave.lin : 根据你的 alpha test 是否开启而定
//            //#pragma shader_feature _SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A
//            struct a2v {//                float4 vertex : POSITION;
//                float2 uv : TEXCOORD0;
//            };
//            struct v2f {//                float4 vertex : SV_POSITION;
//                float2 uv : TEXCOORD0;
//            };
//            v2f vert(a2v v)
//            {//                v2f o = (v2f)0;
//                o.vertex = TransformObjectToHClip(v.vertex.xyz);
//                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
//        }// jave.lin : 使用 Universal 中自带的 Universal Render Pipeline/Lit Shader 中的 ShadowCaster Pass//UsePass "Universal Render Pipeline/Lit/ShadowCaster"}
}

References

  • 关于SHADOWS_SCREEN - URP 下的阴影
  • 如何在unity的URP下实现阴影
  • Unity URP Shader 支持内置阴影

Extended reading

  • Unity通用渲染管线(URP)系列(四)——方向阴影(Cascaded Shadow Maps) - 此篇引用的是 国外 cat like coding 博主的文章,有非常详细的讲解

Unity Shader - URP ShadowCast ShadowRecieve - 投影 和 接受阴影相关推荐

  1. Unity Shader - URP Instancing

    URP 中的内置 GPU Instancing 的使用,和 Built-in RP 之前的宏定义名字是一样的,而且功能也是一样的,所以:使用方法和 Built-in RP 中没任何却别 Shader ...

  2. Unity Shader - URP Fog - URP 管线下的雾效

    文章目录 参考 LitForwardPass.hlsl 临摹使用 Test/URPFog 只要 Fog_Linear 变体的 效果 问题 修复 References 管线:URP URP:7.7.1 ...

  3. Unity Shader - URP - 抄作业 - Deep Crack - 裂痕深坑 - SRP Batch优化

    文章目录 环境 思路 建模 Houdini 设置好 Geometry + Curve + Extrude 3ds max 设置好参考背景图 使用:创建/图形/线,来勾勒刨面 封口刨面 转为可编辑多边形 ...

  4. Unity Shader - Custom DirectionalLight ShadowMap 自定义方向光的ShadowMap

    文章目录 思路 实践 在方向光的位置,放一个正交相机 调整光源相机参数 将光源投影空间的正交视锥体画出来 投射阴影 接收阴影 改进 超出Shadow map的默认为光照 添加光照处理 添加PCF柔滑整 ...

  5. Unity Shader - 模仿RenderImage制作全屏Quad,可以制作自定义后处理的流程

    文章目录 先尝试GL类来制作 Shader CSharp 画个三角型 画个全屏的Quad 发现GL没有RenderTarget之类的 使用CommandBuffer来绘制全屏的Quad GL渲染到目标 ...

  6. Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色

    材质面板截图 功能实现(URP渲染管线下): 1.进一步优化Shader结构和算法: 2.包含PBR材质: 3.投射和接收阴影,并升级支持自定义阴影颜色: 4.支持点光源照射(但不支持点光源阴影). ...

  7. Unity Shader - 搬砖日志 - URP PBR (抄作业篇,持续更新~)

    文章目录 目的 环境 PBR 主要渲染方程 D 项 GGB(desmos) D_Term 完整 Shader G 项 GGB G_Term 完整 Shader F 项 GGB F_Term 完整 Sh ...

  8. Unity Shader 学习笔记(3)URP渲染管线带阴影PBR-Shader模板(ASE优化版本)

    此 Shader 已经不是最新版本,最新版本见本专栏的第四篇文章: Unity Shader 学习笔记(4) 材质面板截图: 功能实现(URP渲染管线下): PBR材质.投射和接收阴影. 代码展示: ...

  9. Unity Shader - 在 URP 获取 Ambient(环境光) 颜色

    之前在 Unity Built-in 管线中,我们在自定义 shader 中,可以使用一下代码来获取 Ambient 环境光的颜色: fixed3 ambient = UNITY_LIGHTMODEL ...

最新文章

  1. SFB 项目经验-81-在企业内部外部限制访问ECP
  2. python分支结构使用if保留字吗_关于Python分支结构,以下选项中描述不正确的是...
  3. 给你总结了这些对付幂等性的套路
  4. 计算机视觉与深度学习 | 像素坐标转相机坐标转世界坐标,求R,t(附C++和Python源代码)
  5. 关于谨防诈骗的温馨提示
  6. mybatis修改mysql变量_Java通过MyBatis框架对MySQL数据进行增删查改的基本方法
  7. ubuntu16.04終端補全忽略大小寫
  8. 服务器系统网卡驱动装不上,网卡驱动装不上去怎么办?
  9. 创业者创业之前,应该思考如下这些问题
  10. C++11 多线程线程共享数据
  11. 微服务和分布式的区别_大话中台三:中台的搭建,分布式与微服务
  12. Tricks(三十七)—— C++ string类 split 的实现
  13. Matplotlib_库的安装
  14. 综合计算机工时,计算机辅助工时定额制定与管理系统的研究与开发
  15. 3D 文件格式 - 对应厂商
  16. Web前端不同阶段工资待遇如何?前端开发真的很值钱吗?
  17. camera驱动电源配置_[ROS] 安装 USB Camera 驱动并调用
  18. 一个refine/refactor的例子
  19. 2021 ICPC Southeastern Europe Regional Contest 树上dfs+思维
  20. 嵌入式地理信息系统技术

热门文章

  1. Django 2.1.7 项目技巧 - 创建apps应用目录归纳所有应用
  2. 什么是虚拟 DOM ?
  3. Java游戏雀圣麻将,《梦幻麻将馆9雀圣争霸》游戏全程攻略
  4. QVariant类及QVariant与自定义数据类型转换的方法
  5. 计算机毕业设计JAVA图书个性化推荐系统mybatis+源码+调试部署+系统+数据库+lw
  6. 宝瓷林【名贵釉系列】宫廷秘釉“茶叶末”
  7. JavaScript知识点整理(十三)- DOM -(2)操作元素
  8. AI芯片:寒武纪ShiDianNao结构分析
  9. 【数据结构】开端序幕
  10. 一句话理解青蛙跳台阶(C语言递归求解)每日一题