Draw particles, match the client's fog, and measure frame delay
Particles (point sprites) are drawn as instanced camera-facing squares sized like Direct3D 9's. Fog is by depth buffer value, as Direct3D 9 does with IMVU's projections. At most one frame is queued for display, frames carry the adapter's timestamp so the renderer process logs the delay to presenting, and the log's lines from several processes no longer mix. Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
1 parent
42fc55cb91
commit
a04dba18c1
12 files changed
+293
-90
No files matched your search
@@ -3,7 +3,13 @@
|
||||
// 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 by view depth.
|
||||
// - 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.
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
// Compiled for each combination of the vertex streams present (HAS_NORMALS, HAS_TEX_COORDS, HAS_COLORS) and the
|
||||
// number of textures (TEXTURES).
|
||||
@@ -21,6 +27,7 @@ cbuffer Constants
|
||||
float4 g_FogColor; // rgb
|
||||
float4 g_Fog; // x: start, y: end, z: on
|
||||
float4 g_Flags; // x: lighting on, y: alpha test on, z: alpha reference (0-255)
|
||||
float4 g_Viewport; // xy: size in pixels
|
||||
};
|
||||
|
||||
struct VSInput
|
||||
@@ -43,7 +50,6 @@ struct PSInput
|
||||
float4 Color : COLOR0;
|
||||
float2 TexCoord0 : TEXCOORD0;
|
||||
float2 TexCoord1 : TEXCOORD1;
|
||||
float Depth : TEXCOORD2;
|
||||
};
|
||||
|
||||
void vs_main(in VSInput input, out PSInput output)
|
||||
@@ -51,7 +57,6 @@ 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
|
||||
@@ -85,6 +90,29 @@ void vs_main(in VSInput input, out PSInput output)
|
||||
output.TexCoord1 = float2(dot(uv, g_TexTransform1[0].xyz), dot(uv, g_TexTransform1[1].xyz));
|
||||
}
|
||||
|
||||
struct SpriteInput
|
||||
{
|
||||
float3 Position : ATTRIB0;
|
||||
float4 Color : ATTRIB3; // bytes B, G, R, A
|
||||
uint Corner : SV_VertexID;
|
||||
};
|
||||
|
||||
void vs_sprite(in SpriteInput input, out PSInput output)
|
||||
{
|
||||
float4 view = mul(mul(float4(input.Position, 1.0), g_World), g_View);
|
||||
float4 clip = mul(view, g_Projection);
|
||||
float size = clamp(g_Viewport.y / max(length(view.xyz), 1e-4), 1.0, 64.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
|
||||
output.Position = clip;
|
||||
|
||||
// No normals: lit by the ambient light alone.
|
||||
float4 material = input.Color.zyxw;
|
||||
output.Color = g_Flags.x > 0.5 ? float4(saturate(g_Ambient.rgb * material.rgb), material.a) : material;
|
||||
output.TexCoord0 = float2(corner.x * 0.5 + 0.5, 0.5 - corner.y * 0.5);
|
||||
output.TexCoord1 = output.TexCoord0;
|
||||
}
|
||||
|
||||
#if TEXTURES >= 1
|
||||
Texture2D g_Texture0;
|
||||
SamplerState g_Texture0_sampler;
|
||||
@@ -110,7 +138,7 @@ float4 ps_main(in PSInput input) : SV_Target
|
||||
}
|
||||
if (g_Fog.z > 0.5)
|
||||
{
|
||||
float visible = saturate((g_Fog.y - input.Depth) / max(g_Fog.y - g_Fog.x, 1e-6));
|
||||
float visible = saturate((g_Fog.y - input.Position.z) / max(g_Fog.y - g_Fog.x, 1e-6));
|
||||
color.rgb = lerp(g_FogColor.rgb, color.rgb, visible);
|
||||
}
|
||||
return color;
|
||||
|
||||
Reference in new issue
Block a user