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

+2 -2
View File
@@ -74,8 +74,8 @@ virtual methods, IMVU's code only uses an engine through helpers that call its v
- Particles (`drawPointSprites`): a Visual C++ 2010 `std::vector` of 16-byte points (position, color), drawn as - Particles (`drawPointSprites`): a Visual C++ 2010 `std::vector` of 16-byte points (position, color), drawn as
Direct3D 9 point sprites: squares viewport height / distance pixels across (Direct3D 9's defaults clamp them to Direct3D 9 point sprites: squares viewport height / distance pixels across (Direct3D 9's defaults clamp them to
1 to 64; IMVU sets only the size, 1, and the scale factors 0, 0, 1), textured over the whole square. 1 to 64; IMVU sets only the size, 1, and the scale factors 0, 0, 1), textured over the whole square.
- Fog: linear table fog. Direct3D 9 fogs by eye distance only for projections whose (3, 4) element is +1; IMVU's are - Fog: linear table fog, start 1 and end 50 in rooms. Fogging by view depth matches the client; by depth buffer
right-handed (-1), so it fogs by depth buffer value (0 to 1) against start 1 and end 50: in effect no fog. value (as Direct3D 9's documentation suggests for projections like IMVU's) doesn't.
- Still unknown: render targets, `CompoundRegion` (texture update - Still unknown: render targets, `CompoundRegion` (texture update
regions), `newRenderTexture`'s flags, and what `beginRendering` does with a null target. MSVC orders overloaded regions), `newRenderTexture`'s flags, and what `beginRendering` does with a null target. MSVC orders overloaded
virtual methods unlike their declaration, so our declarations never overload virtual methods. virtual methods unlike their declaration, so our declarations never overload virtual methods.
+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; // 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 // - 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; // 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 // - an alpha test passing pixels whose alpha is greater than the reference, then linear fog by view depth (checked
// distance from the eye only for projections with +1 as their (3, 4) element; IMVU's (right-handed) have -1, so // against the client: fogging by depth buffer value instead looks nothing like it).
// 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.
// //
// Particles (vs_sprite) are Direct3D 9 point sprites there: camera-facing squares, viewport height / distance pixels // 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. // 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; float4 Color : COLOR0;
float2 TexCoord0 : TEXCOORD0; float2 TexCoord0 : TEXCOORD0;
float2 TexCoord1 : TEXCOORD1; float2 TexCoord1 : TEXCOORD1;
float Depth : TEXCOORD2;
}; };
void vs_main(in VSInput input, out PSInput output) 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 world = mul(float4(input.Position, 1.0), g_World);
float4 view = mul(world, g_View); float4 view = mul(world, g_View);
output.Position = mul(view, g_Projection); output.Position = mul(view, g_Projection);
output.Depth = abs(view.z);
float4 material = float4(1.0, 1.0, 1.0, 1.0); float4 material = float4(1.0, 1.0, 1.0, 1.0);
#if HAS_COLORS #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); 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 clip.xy += corner * size / g_Viewport.xy * clip.w; // half the size each way, in clip space
output.Position = clip; output.Position = clip;
output.Depth = abs(view.z);
// No normals: lit by the ambient light alone. // No normals: lit by the ambient light alone.
float4 material = input.Color.zyxw; float4 material = input.Color.zyxw;
@@ -138,7 +139,7 @@ float4 ps_main(in PSInput input) : SV_Target
} }
if (g_Fog.z > 0.5) 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); color.rgb = lerp(g_FogColor.rgb, color.rgb, visible);
} }
return color; return color;