i can read the depth and mix it with the rendered image and get a linear fog effect but I can't get a true radial fog. I've been going back and forth with gemini and chatgpt and neither can do it. gemini got me a radial gradient but it's jsut projected flat across all 3d objects.
it's been all day trial after trial
this is what gives me the flat radial gradient
using namespace metal;
struct DepthFogEffectConstants {
float4 fogColor;
float density;
// We no longer need the inverse projection matrix here!
};
kernel void depthFogKernel(
texture2d<half, access::read> inColor [[texture(0)]],
texture2d<float, access::read> inDepth [[texture(1)]],
texture2d<half, access::write> outColor [[texture(2)]],
constant DepthFogEffectConstants& uniforms [[buffer(0)]],
uint2 gid [[thread_position_in_grid]])
{
float w = outColor.get_width();
float h = outColor.get_height();
if (gid.x >= w || gid.y >= h) {
return;
}
half4 originalColor = inColor.read(gid);
float rawDepth = inDepth.read(gid).r;
// 1. Guard check for empty backgrounds/skyboxes
if (rawDepth <= 0.00001f || rawDepth >= 0.9999f) {
outColor.write(originalColor, gid);
return;
}
// 2. Map screen pixels from the center of the lens (-1.0 to 1.0)
float2 screenPos = float2(
((float(gid.x) / w) * 2.0f) - 1.0f,
1.0f - ((float(gid.y) / h) * 2.0f)
);
// 3. Since rawDepth is already acting as a view-space Z proxy,
// we use it to calculate the true spherical ray distance from the lens center.
// The hypotenuse of screen offset (X, Y) and depth (Z) gives the radial distance.
float radialDistance = sqrt(screenPos.x * screenPos.x + screenPos.y * screenPos.y + rawDepth * rawDepth);
// 4. Calculate exponential fog matching your visual test
float fogFactor32 = exp(-radialDistance * uniforms.density);
half fogFactor = half(clamp(fogFactor32, 0.0f, 1.0f));
half4 fogColor = half4(uniforms.fogColor);
// Mix and write colors out cleanly
half4 finalColor = mix(fogColor, originalColor, fogFactor);
outColor.write(radialDistance, gid);
}
in this code i'm just outputing the radial distance to see that calculation and it's just wrong. i don't know what to do anymore