summaryrefslogtreecommitdiffstats
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
parentc6923a553c98da7805407fe1fbfdb6c69c8d7530 (diff)
Impostors: continue work on depth, getting closer
-rw-r--r--3ner.cginc15
-rw-r--r--DepthBlit.shader11
-rw-r--r--Scripts/Impostors.cs17
-rw-r--r--impostor.cginc26
-rw-r--r--pbr.cginc2
5 files changed, 44 insertions, 27 deletions
diff --git a/3ner.cginc b/3ner.cginc
index ab80a8d..18c23ee 100644
--- a/3ner.cginc
+++ b/3ner.cginc
@@ -258,7 +258,7 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace
#endif
) : SV_Target {
UNITY_SETUP_INSTANCE_ID(i);
-#if defined(SHADOW_CASTER_PASS)
+#if defined(SHADOW_CASTER_PASS) && !(_IMPOSTORS)
return 0;
#endif
@@ -281,18 +281,9 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace
i.normal = pbr.normal;
i.objPos = pbr.objPos;
propagateObjPos(i);
+
float4 imp_clip_pos = UnityObjectToClipPos(i.objPos);
depth = imp_clip_pos.z / imp_clip_pos.w;
- if (false) {
- depth *= 100;
- depth *= depth;
- depth *= depth;
- depth *= 100;
- return float4(depth, depth, depth, 1);
- }
- if (false) {
- return float4(i.objPos, 1);
- }
#endif
#if defined(_DEBUG_VIEW_UNLIT)
@@ -304,7 +295,6 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace
#elif defined(_DEBUG_VIEW_DEPTH)
float2 screen_uv = i.pos.xy / _ScreenParams.xy;
float depth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screen_uv);
- depth = 1.0f - depth;
depth *= 100;
depth *= depth;
depth *= depth;
@@ -323,4 +313,3 @@ float4 frag(v2f i, uint facing : SV_IsFrontFace
}
#endif // __3NER_INC
-
diff --git a/DepthBlit.shader b/DepthBlit.shader
index 4094fe5..b2a512f 100644
--- a/DepthBlit.shader
+++ b/DepthBlit.shader
@@ -20,7 +20,7 @@ Shader "Hidden/yum_food/DepthBlit"
#include "UnityCG.cginc"
- sampler2D _DepthTex;
+ UNITY_DECLARE_DEPTH_TEXTURE(_DepthTex);
float _Near;
float _Far;
@@ -41,7 +41,14 @@ Shader "Hidden/yum_food/DepthBlit"
float4 frag(v2f i) : SV_Target
{
// 0 = near clip plane, 1 = far clip plane.
- return tex2D(_DepthTex, i.uv).r;
+ float rawDepth = SAMPLE_DEPTH_TEXTURE(_DepthTex, i.uv);
+ // Unity uses reversed-Z on most platforms: 1 at near, 0 at far.
+ // Flip to get linear 0-1 (0=near, 1=far) for orthographic cameras.
+ #if defined(UNITY_REVERSED_Z)
+ return 1.0 - rawDepth;
+ #else
+ return rawDepth;
+ #endif
}
ENDCG
}
diff --git a/Scripts/Impostors.cs b/Scripts/Impostors.cs
index e1447b6..9769aa1 100644
--- a/Scripts/Impostors.cs
+++ b/Scripts/Impostors.cs
@@ -298,17 +298,25 @@ public class Impostors : MonoBehaviour
Color[] origAlpha = preserveAlpha ? (Color[])alpha.Clone() : null;
Color[] buffer = (Color[])pixels.Clone();
+ bool[] filled = new bool[pixels.Length];
+ for (int i = 0; i < pixels.Length; i++)
+ filled[i] = alpha[i].a > 0.01f;
+ bool[] filledNext = new bool[filled.Length];
+
int[] dx = { -1, 1, 0, 0 };
int[] dy = { 0, 0, -1, 1 };
for (int iter = 0; iter < iterations; iter++)
{
+ System.Array.Copy(pixels, buffer, pixels.Length);
+ System.Array.Copy(filled, filledNext, filled.Length);
+
for (int y = 0; y < h; y++)
{
for (int x = 0; x < w; x++)
{
int i = y * w + x;
- if (alpha[i].a > 0.01f) continue;
+ if (filled[i]) continue;
Color sum = Color.clear;
int count = 0;
@@ -317,7 +325,7 @@ public class Impostors : MonoBehaviour
int nx = x + dx[d], ny = y + dy[d];
if (nx < 0 || nx >= w || ny < 0 || ny >= h) continue;
int ni = ny * w + nx;
- if (alpha[ni].a > 0.01f || (iter > 0 && pixels[ni].a > 0))
+ if (filled[ni])
{
sum += pixels[ni];
count++;
@@ -327,10 +335,12 @@ public class Impostors : MonoBehaviour
{
buffer[i] = sum / count;
buffer[i].a = 1;
+ filledNext[i] = true;
}
}
}
- var tmp = pixels; pixels = buffer; buffer = tmp;
+ var tmpFilled = filled; filled = filledNext; filledNext = tmpFilled;
+ var tmpPixels = pixels; pixels = buffer; buffer = tmpPixels;
}
if (preserveAlpha)
@@ -488,6 +498,7 @@ public class Impostors : MonoBehaviour
impostorMaterial.SetFloat("_Impostors_Sphere_Radius", sphere_radius_);
impostorMaterial.SetFloat("_Impostors_Near_Clip", nearClippingDistance);
impostorMaterial.SetFloat("_Impostors_Far_Clip", sphere_radius_ * 2f + nearClippingDistance);
+ impostorMaterial.SetFloat("_ZTest", (float)UnityEngine.Rendering.CompareFunction.LessEqual);
impostorMaterial.SetFloat("_Impostors_Enabled", 1);
impostorMaterial.SetFloat("_Impostors_Parallax", 1);
impostorMaterial.SetFloat("_Cull", (float)UnityEngine.Rendering.CullMode.Front);
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;
}
diff --git a/pbr.cginc b/pbr.cginc
index 2aa6be7..076cf65 100644
--- a/pbr.cginc
+++ b/pbr.cginc
@@ -26,6 +26,7 @@ struct Pbr {
#endif
#if defined(_IMPOSTORS)
float3 objPos;
+ float debug; // TODO rm
#endif
};
@@ -170,6 +171,7 @@ Pbr getPbr(v2f i) {
pbr.smoothness = imp.smoothness;
pbr.metallic = imp.metallic;
pbr.objPos = imp.objPos;
+ pbr.debug = imp.debug;
#else
pbr.albedo = _MainTex.Sample(aniso16_trilinear_repeat_s, uv_parallax * _MainTex_ST.xy + _MainTex_ST.zw);
pbr.albedo *= _Color;