通过blender建了一棵简陋的树,注意叶片的法线要半球形化,使其光影变化不至于太过混乱。

物体投放阴影,包含了自身叶片的相互遮挡,和向周边树干沙地投放阴影,在ShadowCaster的pass中实现。


(资料图片仅供参考)

接收阴影包括接收自身遮挡产生的阴影,和其他物品的阴影,在UniversalForward实现。

代码如下

Shader "toon/tree_leaves"

{

Properties

{

_MainTex ("纹理贴图", 2D) = "white" {}

_Color("基本颜色",color) = (1,1,1,1)

_ShadowColor("暗部颜色",color) = (1,1,1,1)

}

SubShader

{

Tags { "RenderPipe"="UniversalPipeline" }

LOD 100

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"

struct appdata

{

float4 vertex : POSITION;

float2 uv : TEXCOORD0;

float3 normal:NORMAL;

};

struct v2f

{

float2 uv : TEXCOORD0;

float4 pos : SV_POSITION;

float3 normalWS:TEXCOORD2;

float3 posWS:TEXCOORD3;

};

CBUFFER_START(UnityPerMaterial)

TEXTURE2D(_MainTex);SAMPLER(sampler_MainTex);

half4 _Color;

half4 _ShadowColor;

CBUFFER_END

ENDHLSL

pass{

Name "BaseColor"

Tags{"LightMode"="UniversalForward" "RenderType"="TransparentCutOut" "Queue"="AlphaTest" }

Cull Off

HLSLPROGRAM

#pragma vertex vert

#pragma fragment frag

#pragma multi_compile _ _MAIN_LIGHT_SHADOWS  _MAIN_LIGHT_SHADOWS_CASCADE

#pragma multi_compile_fragment _ _SHADOWS_SOFT

#pragma multi_compile _ Anti_Aliasing_ON

v2f vert (appdata v)

{

v2f o;

o.pos = TransformObjectToHClip(v.vertex);

o.uv = v.uv;

o.posWS=mul(unity_ObjectToWorld,v.vertex);

o.normalWS = TransformObjectToWorldNormal(v.normal);

return o;

}

half4 frag (v2f i) : SV_Target

{

//获取主光

float4 shadowcoords=TransformWorldToShadowCoord(i.posWS);

Light mainlight=GetMainLight(shadowcoords);

half3 L=normalize(mainlight.direction);

half3 N=normalize(i.normalWS);

half ln=saturate(dot(L,N));

half shadow=MainLightRealtimeShadow(shadowcoords)*ln;    //接收阴影

half alpha=SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv).w;

half4 col=lerp(_ShadowColor,_Color,shadow);

clip(alpha-0.1);

return col;

}

ENDHLSL

}

pass { //投射阴影,向自身和周围物体投射

Name "ShadowCast"

Tags{ "LightMode" = "ShadowCaster" }

Cull Off

HLSLPROGRAM

#pragma vertex vertshadow

#pragma fragment fragshadow

v2f vertshadow(appdata v)

{

v2f o;

o.posWS= TransformObjectToWorld(v.vertex);

o.uv=v.uv;

Light mainlight=GetMainLight();

o.normalWS= TransformObjectToWorldNormal(v.normal);

o.pos=TransformWorldToHClip(ApplyShadowBias(o.posWS,o.normalWS,mainlight.direction));

return o;

}

half4 fragshadow(v2f i) : SV_Target

{

float alpha=SAMPLE_TEXTURE2D(_MainTex,sampler_MainTex,i.uv).w;

clip(alpha-0.1);

return 0;

}

ENDHLSL

}

}

}

推荐内容