Rendering
WMMD rendering: a toon pipeline verified by golden images
Forward toon shading with WBOIT transparency, ESM shadows, SSAO and RT AO, IBL and bloom — and the headless snapshot infrastructure that keeps it honest.
The renderer’s job in an MMD engine is unusual: it has to produce stylized toon output that matches an established look, while carrying enough modern lighting to survive being embedded in a concert stage or an AR scene. WMMD does this on wgpu, behind a render interface that knows nothing about GPUs.
The passes
wmmd-render-wgpu owns the whole GPU side: a forward toon pass, weighted-blended order-independent transparency (WBOIT), screen-space ambient occlusion with an optional ray-traced AO path behind the ray-query feature, image-based lighting, exponential shadow maps for soft shadows, and bloom. An optional ONNX-based texture upscaling path exists behind its own feature flag, off by default because the dependency is heavy.
There is also a second backend, sylveon, an EEVEE-like renderer compiled into the editor by default. It carries the more cinematic work — depth of field with autofocus, and a McGuire-style tile-based motion blur pipeline that ships off by default — and it has its own GPU profiler that can append per-pass timings as JSON Lines for later analysis.
Transparency is where MMD content is hardest. Hair in particular sits at the intersection of alpha-blended materials, depth writes, and ambient occlusion, and getting it wrong shows immediately: hair that fails to occlude what is behind it, or that vanishes from the AO structure entirely. Both of those were tracked as explicit defects and resolved — hair geometry now participates in the ray proxy structure, and hair depth keys drive a composite step that rejects incorrectly ordered fragments.
The two-pass host loop
Because the renderer never owns the swapchain, the editor’s frame is explicit: render the scene into an encoder, render egui panels into the same encoder with a load operation that preserves the scene, submit, then present. Panels live in a separate crate from the renderer entirely, which is what allows a host with no UI at all — an export job, an AR surface — to drive the same render path.
Golden images as the correctness contract
The part that makes the rest maintainable: WMMD renders headlessly to PNG and compares against golden images, with a snapshot runner in the tools crate. A stylized renderer has no analytic ground truth, so the reference is a previously approved frame, and a change that alters pixels has to justify itself. In practice this is how shadow fidelity, material and specular behavior, and depth-of-field rebuilds have been evaluated — render the same scene and framing before and after, then compare against a calibrated reference rather than an opinion.
That discipline is also why the engine’s rules forbid naming a specific model anywhere in shipped code. A snapshot is a reproduction case, not a target: the fix has to hold across arbitrary PMX and VMD inputs, and the test has to say so.