diff options
| author | yum <yum.food.vr@gmail.com> | 2026-01-13 20:42:27 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-01-13 22:27:33 -0800 |
| commit | ad551018904f13b8af0d1c4c2aa8380ac57de89a (patch) | |
| tree | 9915d06a03988cacd3c13131edc32946d7c9876d /impostor.cginc | |
| parent | 6df5a9a34d81d1200231b974fcc85f89e80eb63e (diff) | |
Impostors: fix depth capture
Diffstat (limited to 'impostor.cginc')
| -rw-r--r-- | impostor.cginc | 67 |
1 files changed, 59 insertions, 8 deletions
diff --git a/impostor.cginc b/impostor.cginc index e265438..f6c0d72 100644 --- a/impostor.cginc +++ b/impostor.cginc @@ -6,13 +6,16 @@ SamplerState bilinear_clamp_s; Texture2D _ImpostorAtlas; +Texture2D _ImpostorDepthAtlas; int _GridResolution; +float _SphereRadius; float _Cutoff; float3 _ImpostorMainCameraPos; #ifndef IMPOSTOR_SHADOW_PASS float4 _Color; float _DebugMode; +float _DebugDepth; #endif float2 HemiOctEncode(float3 N) { @@ -45,6 +48,10 @@ float4 SampleAtlas(float2 uv, float2 cell) { return _ImpostorAtlas.Sample(bilinear_clamp_s, (cell + uv) / _GridResolution); } +float SampleDepthAtlas(float2 uv, float2 cell) { + return _ImpostorDepthAtlas.Sample(bilinear_clamp_s, (cell + uv) / _GridResolution).r; +} + // ============================================================================ // Vertex/Fragment // ============================================================================ @@ -62,10 +69,15 @@ struct v2f { V2F_SHADOW_CASTER; #else float4 pos : SV_POSITION; - UNITY_FOG_COORDS(3) + UNITY_FOG_COORDS(7) #endif float2 uv : TEXCOORD1; float2 cell : TEXCOORD2; + // For depth reconstruction + float3 worldPos : TEXCOORD3; + float3 viewWS : TEXCOORD4; + float3 center : TEXCOORD5; + float radius : TEXCOORD6; UNITY_VERTEX_OUTPUT_STEREO }; @@ -108,22 +120,61 @@ v2f vert(appdata v) { BillboardBasis(snapOS, right, up); o.uv = float2(1 - (dot(localOff, right) + 0.5), dot(localOff, up) + 0.5); o.cell = float2(cell); + + // Pass data for depth reconstruction + float3 viewWS = normalize(camPos - center); + o.worldPos = worldPos; + o.viewWS = viewWS; + o.center = center; + o.radius = _SphereRadius * scale.x; + return o; } +#ifdef IMPOSTOR_SHADOW_PASS +// Shadow pass - just alpha test, no depth output float4 frag(v2f i) : SV_Target { float4 col = SampleAtlas(i.uv, i.cell); -#ifndef IMPOSTOR_SHADOW_PASS - if (_DebugMode > 0.5) return float4(1, 0, 0, 1); - col *= _Color; -#endif clip(col.a - _Cutoff); -#ifdef IMPOSTOR_SHADOW_PASS SHADOW_CASTER_FRAGMENT(i) +} #else +// Forward pass - with depth output +struct FragOutput { + float4 color : SV_Target; + float depth : SV_Depth; +}; + +FragOutput frag(v2f i) { + FragOutput o; + + float4 col = SampleAtlas(i.uv, i.cell); + float depth = SampleDepthAtlas(i.uv, i.cell); + + // Compute depth-corrected world position + // depth=0 means front of sphere (toward camera), depth=1 means back (away from camera) + float3 depthWorldPos = i.worldPos - i.viewWS * (2.0 * depth - 1.0) * i.radius; + + // Convert to clip space depth + float4 clipPos = mul(UNITY_MATRIX_VP, float4(depthWorldPos, 1.0)); + o.depth = clipPos.z / clipPos.w; + + if (_DebugMode > 0.5) { + o.color = float4(i.uv, 0, 1); + return o; + } + if (_DebugDepth > 0.5) { + o.color = float4(depth.xxx, 1); + return o; + } + + col *= _Color; + clip(col.a - _Cutoff); + UNITY_APPLY_FOG(i.fogCoord, col); - return col; -#endif + o.color = col; + return o; } +#endif #endif |
