Add shadowcaster blur support to shaders

Introduces a _BlurPixels property and related parameters to BlendinShader and LitParticles shaders, enabling blurred shadowcaster sampling. Updates Shadowcaster.cginc to support blurred texture sampling using tex2Dgrad when blur is enabled. Also adjusts light intensity calculation in LightStrength.hlsl to remove NdotL multiplication for consistency with new shadow handling.
This commit is contained in:
DeMuenu
2025-10-01 14:48:44 +02:00
parent 0e633983cf
commit 8e740bd636
4 changed files with 40 additions and 14 deletions

View File

@@ -15,6 +15,8 @@ Shader "DeMuenu/World/Hoppou/RevealStandart"
//Moonlight
_InverseSqareMultiplier ("Inverse Square Multiplier", Float) = 1
_LightCutoffDistance ("Light Cutoff Distance", Float) = 100
_BlurPixels ("Shadowcaster Blur Pixels", Float) = 0
//Moonlight END
@@ -107,6 +109,10 @@ Shader "DeMuenu/World/Hoppou/RevealStandart"
float4 _Udon_OutSideColor_2;
float _Udon_MinBrightnessShadow_2;
float _BlurPixels;
float4 _Udon_shadowCasterTex_1_TexelSize; // xy = 1/width, 1/height
float4 _Udon_shadowCasterTex_2_TexelSize;
v2f vert (appdata v)
{
v2f o;
@@ -170,20 +176,19 @@ Shader "DeMuenu/World/Hoppou/RevealStandart"
float4 sc1 = SampleShadowcasterPlaneWS_Basis(
_Udon_LightPositions[LightCounter].xyz, i.worldPos,
_Udon_Plane_Origin_1.xyz, _Udon_Plane_Uinv_1.xyz, _Udon_Plane_Vinv_1.xyz, _Udon_Plane_Normal_1.xyz,
_Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1);
_Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1, _BlurPixels, _Udon_shadowCasterTex_1_TexelSize.xy);
ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1);
}
if (_Udon_ShadowMapIndex[LightCounter] > 1.5)
{
float4 sc2 = SampleShadowcasterPlaneWS_Basis(
_Udon_LightPositions[LightCounter].xyz, i.worldPos,
_Udon_Plane_Origin_2.xyz, _Udon_Plane_Uinv_2.xyz, _Udon_Plane_Vinv_2.xyz, _Udon_Plane_Normal_2.xyz,
_Udon_shadowCasterTex_2, _Udon_OutSideColor_2, _Udon_shadowCasterColor_2);
_Udon_shadowCasterTex_2, _Udon_OutSideColor_2, _Udon_shadowCasterColor_2, _BlurPixels, _Udon_shadowCasterTex_2_TexelSize.xy);
ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2);
}
dmax = dmax + contrib * float4(LightColor, 1) * ShadowCasterMult_1 * ShadowCasterMult_2;
dmax = dmax + contrib * float4(LightColor, 1) * NdotL * ShadowCasterMult_1 * ShadowCasterMult_2;
}

View File

@@ -6,7 +6,7 @@
{ \
contrib = _Udon_LightColors[LightCounter].a / max(1e-4, max(0, max(1, distanceFromLight - radius) * invSqMul) * max(0, max(1, distanceFromLight - radius) * invSqMul)); \
\
dIntensity += contrib * NdotL; \
dIntensity += contrib; \
} \
else if (_Udon_LightType[LightCounter] == 1) \
{ \
@@ -17,7 +17,7 @@
contrib= 1 - step(threshold, contrib); \
\
contrib = contrib * invSq; \
dIntensity += contrib * NdotL; \
dIntensity += contrib; \
} \
float3 LightColor = _Udon_LightColors[LightCounter].xyz; \

View File

@@ -1,14 +1,15 @@
#ifndef SHADOWCASTER_PLANE
#define SHADOWCASTER_PLANE
#include "UnityCG.cginc" // for tex2Dlod, etc.
#include "UnityCG.cginc" // tex2D, tex2Dgrad
static const float WS_EPS = 1e-5;
inline float4 SampleShadowcasterPlaneWS_Basis(
float3 A, float3 B,
float3 P0, float3 Uinv, float3 Vinv, float3 N,
sampler2D tex, float4 OutsideColor, float4 ShadowColor)
sampler2D tex, float4 OutsideColor, float4 ShadowColor,
float blurPixels, float2 texelSize)
{
float3 d = B - A;
float dn = dot(N, d);
@@ -16,6 +17,7 @@ inline float4 SampleShadowcasterPlaneWS_Basis(
float t = dot(N, P0 - A) / dn;
if (t < 0.0 || t > 1.0) return OutsideColor;
float3 hit = A + d * t;
float3 r = hit - P0;
@@ -24,9 +26,21 @@ inline float4 SampleShadowcasterPlaneWS_Basis(
float v = dot(r, Vinv);
if (abs(u) > 0.5 || abs(v) > 0.5) return OutsideColor;
float4 returnColor = tex2D(tex, float2(u + 0.5, v + 0.5)) * ShadowColor;
returnColor = float4(returnColor.rgb * (1 - returnColor.a), 1);
return returnColor;
float2 uv = float2(u + 0.5, v + 0.5);
// If blur is tiny, do the normal one-tap
if (blurPixels <= 0.001)
{
float4 col = tex2D(tex, uv) * ShadowColor;
return float4(col.rgb * (1 - col.a), 1);
}
// Inflate gradients so the sampler picks a higher mip (cheap blur).
float2 g = texelSize * blurPixels;
float4 blurred = tex2Dgrad(tex, uv, float2(g.x, 0), float2(0, g.y));
float4 outCol = blurred * ShadowColor;
return float4(outCol.rgb * (1 - outCol.a), 1);
}
#endif

View File

@@ -9,6 +9,9 @@ Shader "DeMuenu/World/Hoppou/Particles/LitParticles"
//Moonlight
_InverseSqareMultiplier ("Inverse Square Multiplier", Float) = 1
_LightCutoffDistance ("Light Cutoff Distance", Float) = 100
_BlurPixels ("Shadowcaster Blur Pixels", Float) = 0
//Moonlight END
@@ -98,6 +101,11 @@ Shader "DeMuenu/World/Hoppou/Particles/LitParticles"
float4 _Udon_shadowCasterColor_2;
float4 _Udon_OutSideColor_2;
float _Udon_MinBrightnessShadow_2;
float _BlurPixels;
float4 _Udon_shadowCasterTex_1_TexelSize; // xy = 1/width, 1/height
float4 _Udon_shadowCasterTex_2_TexelSize;
v2f vert (appdata v)
{
v2f o;
@@ -144,16 +152,15 @@ Shader "DeMuenu/World/Hoppou/Particles/LitParticles"
float4 sc1 = SampleShadowcasterPlaneWS_Basis(
_Udon_LightPositions[LightCounter].xyz, i.worldPos,
_Udon_Plane_Origin_1.xyz, _Udon_Plane_Uinv_1.xyz, _Udon_Plane_Vinv_1.xyz, _Udon_Plane_Normal_1.xyz,
_Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1);
_Udon_shadowCasterTex_1, _Udon_OutSideColor_1, _Udon_shadowCasterColor_1, _BlurPixels, _Udon_shadowCasterTex_1_TexelSize.xy);
ShadowCasterMult_1 = max(sc1, _Udon_MinBrightnessShadow_1);
}
if (_Udon_ShadowMapIndex[LightCounter] > 1.5)
{
float4 sc2 = SampleShadowcasterPlaneWS_Basis(
_Udon_LightPositions[LightCounter].xyz, i.worldPos,
_Udon_Plane_Origin_2.xyz, _Udon_Plane_Uinv_2.xyz, _Udon_Plane_Vinv_2.xyz, _Udon_Plane_Normal_2.xyz,
_Udon_shadowCasterTex_2, _Udon_OutSideColor_2, _Udon_shadowCasterColor_2);
_Udon_shadowCasterTex_2, _Udon_OutSideColor_2, _Udon_shadowCasterColor_2, _BlurPixels, _Udon_shadowCasterTex_2_TexelSize.xy);
ShadowCasterMult_2 = max(sc2, _Udon_MinBrightnessShadow_2);
}