Fog by view depth again

Fogging by depth buffer value, as Direct3D 9's documentation suggests for IMVU's projections, looks nothing like the client; fogging by view depth matched it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
dhkatzandClaude Opus 5.5 committed 2026-10-28 06:16:57 -07:00
1 parent a04dba18c1
commit 1a45bf9a86
2 files changed
+8 -7

No files matched your search

+6 -5
View File
@@ -3,10 +3,8 @@
// environment's ambient light, plus each light's color times max(0, N.L); no specular or emissive light;
// - textures: none (the lit color), one (times the lit color), or two (the second blended over the first by its
// alpha, then times the lit color), both on the vertex's texture coordinates with their own transforms;
// - an alpha test passing pixels whose alpha is greater than the reference, then linear fog. Direct3D 9 fogs by
// distance from the eye only for projections with +1 as their (3, 4) element; IMVU's (right-handed) have -1, so
// it fogs by the depth buffer's value (0 to 1) against the fog's start and end (in scene units, 1 to 50 in
// rooms): in effect, no fog. Reproduced as is.
// - an alpha test passing pixels whose alpha is greater than the reference, then linear fog by view depth (checked
// against the client: fogging by depth buffer value instead looks nothing like it).
//
// Particles (vs_sprite) are Direct3D 9 point sprites there: camera-facing squares, viewport height / distance pixels
// across (1 to 64), textured over the whole square; here each is drawn as an instance of a 4-vertex strip.
@@ -50,6 +48,7 @@ struct PSInput
float4 Color : COLOR0;
float2 TexCoord0 : TEXCOORD0;
float2 TexCoord1 : TEXCOORD1;
float Depth : TEXCOORD2;
};
void vs_main(in VSInput input, out PSInput output)
@@ -57,6 +56,7 @@ void vs_main(in VSInput input, out PSInput output)
float4 world = mul(float4(input.Position, 1.0), g_World);
float4 view = mul(world, g_View);
output.Position = mul(view, g_Projection);
output.Depth = abs(view.z);
float4 material = float4(1.0, 1.0, 1.0, 1.0);
#if HAS_COLORS
@@ -105,6 +105,7 @@ void vs_sprite(in SpriteInput input, out PSInput output)
float2 corner = float2((input.Corner & 1) != 0 ? 1.0 : -1.0, (input.Corner & 2) != 0 ? -1.0 : 1.0);
clip.xy += corner * size / g_Viewport.xy * clip.w; // half the size each way, in clip space
output.Position = clip;
output.Depth = abs(view.z);
// No normals: lit by the ambient light alone.
float4 material = input.Color.zyxw;
@@ -138,7 +139,7 @@ float4 ps_main(in PSInput input) : SV_Target
}
if (g_Fog.z > 0.5)
{
float visible = saturate((g_Fog.y - input.Position.z) / max(g_Fog.y - g_Fog.x, 1e-6));
float visible = saturate((g_Fog.y - input.Depth) / max(g_Fog.y - g_Fog.x, 1e-6));
color.rgb = lerp(g_FogColor.rgb, color.rgb, visible);
}
return color;