Unity Shader - URP ShadowCast ShadowRecieve - 投影 和 接受阴影
文章目录
- 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 properties 添加上:
总之 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 - 投影 和 接受阴影相关推荐
- Unity Shader - URP Instancing
URP 中的内置 GPU Instancing 的使用,和 Built-in RP 之前的宏定义名字是一样的,而且功能也是一样的,所以:使用方法和 Built-in RP 中没任何却别 Shader ...
- Unity Shader - URP Fog - URP 管线下的雾效
文章目录 参考 LitForwardPass.hlsl 临摹使用 Test/URPFog 只要 Fog_Linear 变体的 效果 问题 修复 References 管线:URP URP:7.7.1 ...
- Unity Shader - URP - 抄作业 - Deep Crack - 裂痕深坑 - SRP Batch优化
文章目录 环境 思路 建模 Houdini 设置好 Geometry + Curve + Extrude 3ds max 设置好参考背景图 使用:创建/图形/线,来勾勒刨面 封口刨面 转为可编辑多边形 ...
- Unity Shader - Custom DirectionalLight ShadowMap 自定义方向光的ShadowMap
文章目录 思路 实践 在方向光的位置,放一个正交相机 调整光源相机参数 将光源投影空间的正交视锥体画出来 投射阴影 接收阴影 改进 超出Shadow map的默认为光照 添加光照处理 添加PCF柔滑整 ...
- Unity Shader - 模仿RenderImage制作全屏Quad,可以制作自定义后处理的流程
文章目录 先尝试GL类来制作 Shader CSharp 画个三角型 画个全屏的Quad 发现GL没有RenderTarget之类的 使用CommandBuffer来绘制全屏的Quad GL渲染到目标 ...
- Unity Shader 学习笔记(4)URP渲染管线带阴影PBR-Shader模板 -- 新增可自定义阴影颜色
材质面板截图 功能实现(URP渲染管线下): 1.进一步优化Shader结构和算法: 2.包含PBR材质: 3.投射和接收阴影,并升级支持自定义阴影颜色: 4.支持点光源照射(但不支持点光源阴影). ...
- Unity Shader - 搬砖日志 - URP PBR (抄作业篇,持续更新~)
文章目录 目的 环境 PBR 主要渲染方程 D 项 GGB(desmos) D_Term 完整 Shader G 项 GGB G_Term 完整 Shader F 项 GGB F_Term 完整 Sh ...
- Unity Shader 学习笔记(3)URP渲染管线带阴影PBR-Shader模板(ASE优化版本)
此 Shader 已经不是最新版本,最新版本见本专栏的第四篇文章: Unity Shader 学习笔记(4) 材质面板截图: 功能实现(URP渲染管线下): PBR材质.投射和接收阴影. 代码展示: ...
- Unity Shader - 在 URP 获取 Ambient(环境光) 颜色
之前在 Unity Built-in 管线中,我们在自定义 shader 中,可以使用一下代码来获取 Ambient 环境光的颜色: fixed3 ambient = UNITY_LIGHTMODEL ...
最新文章
- SFB 项目经验-81-在企业内部外部限制访问ECP
- python分支结构使用if保留字吗_关于Python分支结构,以下选项中描述不正确的是...
- 给你总结了这些对付幂等性的套路
- 计算机视觉与深度学习 | 像素坐标转相机坐标转世界坐标,求R,t(附C++和Python源代码)
- 关于谨防诈骗的温馨提示
- mybatis修改mysql变量_Java通过MyBatis框架对MySQL数据进行增删查改的基本方法
- ubuntu16.04終端補全忽略大小寫
- 服务器系统网卡驱动装不上,网卡驱动装不上去怎么办?
- 创业者创业之前,应该思考如下这些问题
- C++11 多线程线程共享数据
- 微服务和分布式的区别_大话中台三:中台的搭建,分布式与微服务
- Tricks(三十七)—— C++ string类 split 的实现
- Matplotlib_库的安装
- 综合计算机工时,计算机辅助工时定额制定与管理系统的研究与开发
- 3D 文件格式 - 对应厂商
- Web前端不同阶段工资待遇如何?前端开发真的很值钱吗?
- camera驱动电源配置_[ROS] 安装 USB Camera 驱动并调用
- 一个refine/refactor的例子
- 2021 ICPC Southeastern Europe Regional Contest 树上dfs+思维
- 嵌入式地理信息系统技术
热门文章
- Django 2.1.7 项目技巧 - 创建apps应用目录归纳所有应用
- 什么是虚拟 DOM ?
- Java游戏雀圣麻将,《梦幻麻将馆9雀圣争霸》游戏全程攻略
- QVariant类及QVariant与自定义数据类型转换的方法
- 计算机毕业设计JAVA图书个性化推荐系统mybatis+源码+调试部署+系统+数据库+lw
- 宝瓷林【名贵釉系列】宫廷秘釉“茶叶末”
- JavaScript知识点整理(十三)- DOM -(2)操作元素
- AI芯片:寒武纪ShiDianNao结构分析
- 【数据结构】开端序幕
- 一句话理解青蛙跳台阶(C语言递归求解)每日一题