diff options
| author | yum <yum.food.vr@gmail.com> | 2026-01-17 17:35:13 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-01-17 17:37:06 -0800 |
| commit | b925b4b1bf79e3d6f930a4d799a7194673b62bde (patch) | |
| tree | 1c45dbf95f66c4948ef6bcf64d9622b259fce624 /impostor.cginc | |
| parent | c6923a553c98da7805407fe1fbfdb6c69c8d7530 (diff) | |
Impostors: continue work on depth, getting closer
Diffstat (limited to 'impostor.cginc')
| -rw-r--r-- | impostor.cginc | 26 |
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; } |
