217 lines
6.4 KiB
Plaintext
217 lines
6.4 KiB
Plaintext
|
|
Shader "Unlit/PlanarShadow"
|
||
|
|
{
|
||
|
|
|
||
|
|
SubShader
|
||
|
|
{
|
||
|
|
HLSLINCLUDE
|
||
|
|
|
||
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||
|
|
|
||
|
|
#ifdef LOW_SOFT_QUALITY
|
||
|
|
#define OPERATOR_SIZE 10
|
||
|
|
#elif defined(MEDIUM_SOFT_QUALITY)
|
||
|
|
#define OPERATOR_SIZE 16
|
||
|
|
#else
|
||
|
|
#define OPERATOR_SIZE 32
|
||
|
|
#endif
|
||
|
|
|
||
|
|
struct Varyings
|
||
|
|
{
|
||
|
|
float4 vertex : SV_POSITION;
|
||
|
|
float2 uv : TEXCOORD0;
|
||
|
|
};
|
||
|
|
|
||
|
|
TEXTURE2D(_SourceTex);
|
||
|
|
SAMPLER(sampler_SourceTex);
|
||
|
|
|
||
|
|
TEXTURE2D(_DistanceTex);
|
||
|
|
SAMPLER(sampler_DistanceTex);
|
||
|
|
|
||
|
|
SAMPLER(sampler_LinearClamp);
|
||
|
|
|
||
|
|
float4 _PossionOperator[32];
|
||
|
|
float4 _EdgeMapTexelSize;
|
||
|
|
float4 _SourceTex_TexelSize;
|
||
|
|
float2 _ShadowScreenHDir;
|
||
|
|
float2 _ShadowScreenVDir;
|
||
|
|
float _MinSoft;
|
||
|
|
float _SoftScaleByDistance;
|
||
|
|
|
||
|
|
Varyings FullScreenVert(uint vertexID: SV_VertexID)
|
||
|
|
{
|
||
|
|
Varyings o;
|
||
|
|
o.vertex = GetFullScreenTriangleVertexPosition(vertexID);
|
||
|
|
o.uv = GetFullScreenTriangleTexCoord(vertexID);
|
||
|
|
return o;
|
||
|
|
}
|
||
|
|
|
||
|
|
half4 buildSoftEdgeVFrag(Varyings input) : SV_Target
|
||
|
|
{
|
||
|
|
half2 uv = input.uv;
|
||
|
|
half2 uvStep = _EdgeMapTexelSize.xy * _ShadowScreenVDir * 0.6f;
|
||
|
|
UNITY_UNROLL
|
||
|
|
for(int i = 0;i<4;i++)
|
||
|
|
{
|
||
|
|
half dis = SAMPLE_TEXTURE2D(_SourceTex, sampler_SourceTex, uv - i * uvStep).r;
|
||
|
|
if(dis > 0)
|
||
|
|
return dis;
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
half4 buildSoftEdgeHFrag(Varyings input) : SV_Target
|
||
|
|
{
|
||
|
|
half2 uv = input.uv;
|
||
|
|
half2 uvStep = _SourceTex_TexelSize.xy * _ShadowScreenHDir* 0.6f;
|
||
|
|
UNITY_UNROLL
|
||
|
|
for(int i = 0; i < 6; i++)
|
||
|
|
{
|
||
|
|
half dis = SAMPLE_TEXTURE2D(_SourceTex, sampler_SourceTex, uv - i * uvStep).r;
|
||
|
|
half dis2 = SAMPLE_TEXTURE2D(_SourceTex, sampler_SourceTex, uv + i * uvStep).r;
|
||
|
|
if(dis > 0)
|
||
|
|
return dis;
|
||
|
|
if(dis2 > 0)
|
||
|
|
return dis2;
|
||
|
|
}
|
||
|
|
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
half4 CircleVisiualFrag(Varyings input) : SV_Target
|
||
|
|
{
|
||
|
|
half2 uv = input.uv;
|
||
|
|
half blurSize = SAMPLE_TEXTURE2D(_DistanceTex, sampler_DistanceTex, uv).r;
|
||
|
|
half2 uvStep = _SourceTex_TexelSize.xy * (_MinSoft + (1 - _MinSoft) * blurSize) * _SoftScaleByDistance;
|
||
|
|
half col = 0;
|
||
|
|
|
||
|
|
if(blurSize == 0)
|
||
|
|
return SAMPLE_TEXTURE2D(_SourceTex, sampler_LinearClamp, uv).g;
|
||
|
|
UNITY_UNROLL
|
||
|
|
for(int i = 0; i < OPERATOR_SIZE;i++)
|
||
|
|
{
|
||
|
|
col += SAMPLE_TEXTURE2D(_SourceTex, sampler_LinearClamp, uv + uvStep * _PossionOperator[i].xy).g * _PossionOperator[i].z;
|
||
|
|
}
|
||
|
|
return half4(col.rrr,1);
|
||
|
|
}
|
||
|
|
|
||
|
|
ENDHLSL
|
||
|
|
|
||
|
|
Pass
|
||
|
|
{
|
||
|
|
Name "BlurV"
|
||
|
|
|
||
|
|
HLSLPROGRAM
|
||
|
|
#pragma vertex FullScreenVert
|
||
|
|
#pragma fragment buildSoftEdgeVFrag
|
||
|
|
ENDHLSL
|
||
|
|
}
|
||
|
|
|
||
|
|
Pass
|
||
|
|
{
|
||
|
|
Name "BlurH"
|
||
|
|
|
||
|
|
HLSLPROGRAM
|
||
|
|
#pragma vertex FullScreenVert
|
||
|
|
#pragma fragment buildSoftEdgeHFrag
|
||
|
|
ENDHLSL
|
||
|
|
}
|
||
|
|
|
||
|
|
Pass
|
||
|
|
{
|
||
|
|
Name "CircleVisiual"
|
||
|
|
|
||
|
|
HLSLPROGRAM
|
||
|
|
#pragma multi_compile _ LOW_SOFT_QUALITY MEDIUM_SOFT_QUALITY
|
||
|
|
#pragma vertex FullScreenVert
|
||
|
|
#pragma fragment CircleVisiualFrag
|
||
|
|
ENDHLSL
|
||
|
|
}
|
||
|
|
|
||
|
|
Pass
|
||
|
|
{
|
||
|
|
Tags { "LightMode" = "PlanarShadow" }
|
||
|
|
|
||
|
|
HLSLPROGRAM
|
||
|
|
#pragma vertex vert
|
||
|
|
#pragma fragment frag
|
||
|
|
#pragma multi_compile_instancing
|
||
|
|
#pragma enable_d3d11_debug_symbols
|
||
|
|
#pragma shader_feature_local TRANSPARENT_SHADOW_CASTER
|
||
|
|
|
||
|
|
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||
|
|
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
|
||
|
|
|
||
|
|
float4 _PlanarShadowCastPlane;
|
||
|
|
float _PlanarShadowMaxSoftDistance;
|
||
|
|
half4 _PlanarShadowColor;
|
||
|
|
|
||
|
|
TEXTURE2D(_PlanarShadowMap);
|
||
|
|
SAMPLER(sampler_PlanarShadowMap);
|
||
|
|
|
||
|
|
void CastVertexToPlane(float3 oriPositionWS, float3 lightDirection, out float3 positionWS, out float shadowSoftScale, float objtY)
|
||
|
|
{
|
||
|
|
float3 planeNor = _PlanarShadowCastPlane.xyz;
|
||
|
|
float w = _PlanarShadowCastPlane.w + objtY;
|
||
|
|
// https://zhuanlan.zhihu.com/p/42781261
|
||
|
|
float castDistance = (w - dot(oriPositionWS.xyz, planeNor)) / dot(lightDirection, planeNor);
|
||
|
|
positionWS = oriPositionWS.xyz + castDistance * lightDirection;
|
||
|
|
shadowSoftScale = max(0, castDistance / _PlanarShadowMaxSoftDistance);
|
||
|
|
}
|
||
|
|
|
||
|
|
half3 GetPlanarScreenShadowAttenuation(float2 screenUV)
|
||
|
|
{
|
||
|
|
#ifdef PLANAR_SHADOW
|
||
|
|
half attenutaion = SAMPLE_TEXTURE2D(_PlanarShadowMap, sampler_PlanarShadowMap, screenUV).r;
|
||
|
|
return lerp(1, _PlanarShadowColor, attenutaion);
|
||
|
|
#else
|
||
|
|
return 1;
|
||
|
|
#endif
|
||
|
|
}
|
||
|
|
|
||
|
|
struct attribute
|
||
|
|
{
|
||
|
|
float4 vertex : POSITION;
|
||
|
|
float2 uv : TEXCOORD;
|
||
|
|
};
|
||
|
|
|
||
|
|
struct v2f
|
||
|
|
{
|
||
|
|
float4 vertex : SV_POSITION;
|
||
|
|
float2 uv : TEXCOORD0;
|
||
|
|
float softValue : TEXCOORD1;
|
||
|
|
};
|
||
|
|
|
||
|
|
sampler2D _MainTexture;
|
||
|
|
|
||
|
|
v2f vert (attribute v)
|
||
|
|
{
|
||
|
|
v2f o;
|
||
|
|
float4 worldPos = mul(UNITY_MATRIX_M, v.vertex);
|
||
|
|
float3 lightDir = -_MainLightPosition.xyz;
|
||
|
|
float y = UNITY_MATRIX_M[1][3];
|
||
|
|
float3 castPosWS;
|
||
|
|
float softValue;
|
||
|
|
CastVertexToPlane(worldPos.xyz, lightDir, castPosWS, softValue, y);
|
||
|
|
o.softValue = softValue;
|
||
|
|
o.vertex = mul(UNITY_MATRIX_VP, float4(castPosWS, 1));
|
||
|
|
o.uv = v.uv;
|
||
|
|
return o;
|
||
|
|
}
|
||
|
|
|
||
|
|
half4 frag (v2f i) : SV_Target
|
||
|
|
{
|
||
|
|
#ifdef TRANSPARENT_SHADOW_CASTER
|
||
|
|
float4 col = tex2D(_MainTexture, i.uv);
|
||
|
|
#else
|
||
|
|
float4 col = 1;
|
||
|
|
#endif
|
||
|
|
return half4(i.softValue,col.a,0, 0);
|
||
|
|
}
|
||
|
|
ENDHLSL
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|