summaryrefslogtreecommitdiffstats
path: root/impostor.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-01-13 20:42:27 -0800
committeryum <yum.food.vr@gmail.com>2026-01-13 22:27:33 -0800
commitad551018904f13b8af0d1c4c2aa8380ac57de89a (patch)
tree9915d06a03988cacd3c13131edc32946d7c9876d /impostor.cginc
parent6df5a9a34d81d1200231b974fcc85f89e80eb63e (diff)
Impostors: fix depth capture
Diffstat (limited to 'impostor.cginc')
-rw-r--r--impostor.cginc67
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