diff --git a/docs/interface.md b/docs/interface.md index 7dc01f8..2e1bc28 100644 --- a/docs/interface.md +++ b/docs/interface.md @@ -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 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. -- Fog: linear table fog. Direct3D 9 fogs by eye distance only for projections whose (3, 4) element is +1; IMVU's are - right-handed (-1), so it fogs by depth buffer value (0 to 1) against start 1 and end 50: in effect no fog. +- Fog: linear table fog, start 1 and end 50 in rooms. Fogging by view depth matches the client; by depth buffer + value (as Direct3D 9's documentation suggests for projections like IMVU's) doesn't. - Still unknown: render targets, `CompoundRegion` (texture update 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. diff --git a/renderer/shaders/fixed_function.hlsl b/renderer/shaders/fixed_function.hlsl index 931f593..38c99c4 100644 --- a/renderer/shaders/fixed_function.hlsl +++ b/renderer/shaders/fixed_function.hlsl @@ -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;