summaryrefslogtreecommitdiffstats
path: root/impostor.cginc
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2026-01-17 17:35:13 -0800
committeryum <yum.food.vr@gmail.com>2026-01-17 17:37:06 -0800
commitb925b4b1bf79e3d6f930a4d799a7194673b62bde (patch)
tree1c45dbf95f66c4948ef6bcf64d9622b259fce624 /impostor.cginc
parentc6923a553c98da7805407fe1fbfdb6c69c8d7530 (diff)
Impostors: continue work on depth, getting closer
Diffstat (limited to 'impostor.cginc')
-rw-r--r--impostor.cginc26
1 files changed, 17 insertions, 9 deletions
diff --git a/impostor.cginc b/impostor.cginc
index 184a8fe..e84f9db 100644
--- a/impostor.cginc
+++ b/impostor.cginc
@@ -67,9 +67,9 @@ float2 VirtualPlaneUV(float3 frameDir, float3 pivotToCam, float3 vertexToCam) {
#if defined(_IMPOSTORS)
-// Decode linear 0-1 depth (0=near clip, 1=far clip) to world space distance from camera
+// Decode linear 0-1 depth (0=near clip, 1=far clip) to world space distance from camera.
float DecodeImpostorDepth(float linearDepth) {
- return _Impostors_Near_Clip + linearDepth * 2.0f * _Impostors_Sphere_Radius;
+ return lerp(_Impostors_Near_Clip, _Impostors_Far_Clip, linearDepth);
}
float2 ClampUvInCell(float2 uv) {
@@ -90,6 +90,8 @@ struct ImpostorResult {
float metallic;
float smoothness;
float3 objPos;
+ // TODO rm
+ float debug;
};
float SampleImpostorDepthCell(float2 cell, float2 uvInCell, float gridRes) {
@@ -133,9 +135,13 @@ float2 ImpostorParallaxOffsetForFrame(float3 frameDir, float3 pivotToCamOS, floa
float camZ = dot(pivotToCamOS, planeN);
camZ = (abs(camZ) < 1e-4) ? (camZ < 0 ? -1e-4 : 1e-4) : camZ;
- // Decode depth to world space, then normalize to [0,1] range
+ // Convert world-space depth to object space to match scaled impostor.
+ float objScale = max(2.0 * _Impostors_Sphere_Radius, 1e-4);
+ float objRadius = _Impostors_Sphere_Radius / objScale;
+ float objNear = _Impostors_Near_Clip / objScale;
float worldSpaceDepth = DecodeImpostorDepth(encodedDepth);
- float depth01 = (worldSpaceDepth - _Impostors_Near_Clip) / (2.0 * _Impostors_Sphere_Radius);
+ float objectSpaceDepth = worldSpaceDepth / objScale;
+ float depth01 = (objectSpaceDepth - objNear) / (2.0 * objRadius);
// Convert to signed "height" where nearer pixels shift more (matches typical bump-offset convention).
float zSurface = (depth01 - 0.5);
float2 planeCoord = 0.5 - uvBase;
@@ -150,12 +156,14 @@ float3 ReconstructObjectOffsetFromFrame(float3 frameDir, float2 uv, float encode
float3 planeX, planeY, planeN;
FrameBasis(frameDir, planeX, planeY, planeN);
- // UV offset from center, scaled to world units (baking camera spans [-Radius, Radius])
- float2 offsetXY = (0.5 - uv) * 2.0 * _Impostors_Sphere_Radius;
+ float objScale = max(2.0f * _Impostors_Sphere_Radius, 1e-4);
+ float objRadius = _Impostors_Sphere_Radius / objScale;
+ float objNear = _Impostors_Near_Clip / objScale;
+ float objFar = _Impostors_Far_Clip / objScale;
- // Decode depth to world space, convert to offset from center along view direction
- float worldSpaceDepth = DecodeImpostorDepth(encodedDepth);
- float offsetZ = (_Impostors_Sphere_Radius + _Impostors_Near_Clip) - worldSpaceDepth;
+ float2 offsetXY = (0.5f - uv) * 2.0f * objRadius;
+ float objectSpaceDepth = lerp(objNear, objFar, encodedDepth);
+ float offsetZ = (objRadius + objNear) - objectSpaceDepth;
return offsetXY.x * planeX + offsetXY.y * planeY + offsetZ * planeN;
}