Files
chameleon/Assets/Unused/HeroCutout.hlsl
T
admin e351336b39 Reorganize project folders and clean up editor tooling
Move editor scripts to Assets/Scripts/Editor (PlaySceneWindow, SceneCollection),
move DefaultNetworkPrefabs and the Main Camera custom blends asset into
Assets/Settings, and shelve the unused HeroCutout shader/include under
Assets/Unused. Rename the Chameleon background texture, delete the obsolete
DefaultParentForEditor script and New Lighting Settings asset, add a The Room
SceneCollection asset, and drop the redundant Assets menu entry from the
StraightenKnees tool.
2026-06-29 16:23:50 +02:00

47 lines
2.0 KiB
HLSL

#ifndef HERO_CUTOUT_INCLUDED
#define HERO_CUTOUT_INCLUDED
// Screen-space radial "hero cutout": clips occluder fragments that sit inside a circle around the
// on-screen player AND in front of it, punching a clean see-through hole toward the character.
//
// These two globals are driven every frame by HeroCutout.cs (Shader.SetGlobalVector). They live
// OUTSIDE UnityPerMaterial, so the SRP Batcher is unaffected. When the effect is disabled
// (_HeroCutoutDepthOn.y < 0.5, also the zero-initialised default) ApplyHeroCutout early-outs and the
// shader renders exactly like URP/Lit.
// _HeroCutoutPosRadius : xy = hero viewport pos (0..1, bottom-left), z = radius, w = feather
// radius/feather are in normalized viewport-HEIGHT units
// _HeroCutoutDepthOn : x = hero eye-space depth (incl. bias), y = enabled (0/1)
float4 _HeroCutoutPosRadius;
float4 _HeroCutoutDepthOn;
// Interleaved-gradient noise -> screen-door dither, gives the circle a soft edge with no extra
// textures or includes.
float HeroCutoutDither(float2 positionSS)
{
return frac(52.9829189 * frac(dot(positionSS, float2(0.06711056, 0.00583715))));
}
void ApplyHeroCutout(float4 positionCS)
{
if (_HeroCutoutDepthOn.y < 0.5)
return;
// Flip-correct screen UV (matches Camera.WorldToViewportPoint's bottom-left convention).
float2 uv = GetNormalizedScreenSpaceUV(positionCS);
float2 delta = uv - _HeroCutoutPosRadius.xy;
delta.x *= _ScreenParams.x / max(_ScreenParams.y, 1.0); // aspect-correct -> a round circle
float dist = length(delta);
float radius = _HeroCutoutPosRadius.z;
float feather = max(_HeroCutoutPosRadius.w, 1e-4);
float inside = 1.0 - smoothstep(radius - feather, radius, dist); // 1 inside, 0 outside
// Only hole geometry between the camera and the hero; anything at/behind the player stays solid.
float eyeDepth = LinearEyeDepth(positionCS.z, _ZBufferParams);
float inFront = step(eyeDepth, _HeroCutoutDepthOn.x);
float cut = inside * inFront;
clip(HeroCutoutDither(positionCS.xy) - cut);
}
#endif