目录:
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) 注意事项
场景中需要一盏平行光作为主光源