MMD Player

A personal WebGPU viewer for checking source PMX models

Side Project · Three.js WebGPU · TSL Shader · JavaScript · tomlim2.github.io/mmd-anju

Motivation

I used the viewer myself to check source PMX models and distinguish their issues from problems introduced during conversion. I was its sole user.

Solution

I built checks for skinning, textures, and outline flags, along with skeleton and motion-compatibility analysis. On that validation foundation, I also explored WebGPU shading and lightweight effects driven by motion timing.

Automatic Motion Compatibility Analysis

Analyzes VMD motion files to calculate bone match rates against PMX models, and automatically detects IK conflicts and source model families. Game studio PMX models also follow these families — e.g., Honkai: Star Rail uses the DIVA family, Genshin Impact uses the ミリシタ family.

Bone Compatibility Analysis — match rates, IK conflicts, source model detection

Bone compatibility analysis

FamilyCharacteristics
あにまさ式 (Animasa)Default MMD model, minimal bone set (~30)
TDA式Includes semi-standard bones (上半身2, 腕捩, etc.)
YYB式TDA-based + extended auxiliary bones
にがもん式Compact bone set, non-Vocaloid characters
つみだんご式High-density custom bones (325), 50 expressions
ミリシタRomanized bone names, incompatible with standard VMD

Motion-synced Effects — Precompute Experiment

I experimented with precomputing effect timing from VMD motion data on the CPU and combining it with light type, position, and color. The resulting motion-synced effects illustrated an R&D direction for track-based visual effects.

6 types: Foot Ripple, Spark Burst, Ground Reflect, Falling/Rising Light, Velocity Effect

Motion-synced bloom and particles

TSL Toon Shading — PMX Material Conversion

PMX matcap + additive overlay + alpha converted to TSL MeshBasicNodeMaterial. On this model, textureSample() was called 2–3 times per fragment for the same texture — cached the node once and reused it. Also pulled opacity out of Fn() to fix a bug where materials went invisible in the reflector pass.

Before and after TSL toon shader fix — white regions resolved to transparent overlay

Before — alpha ignored, white fill / After — additive overlay + transparency

Post-Process Pipeline — TSL Node Graph

Post-process stack on TSL nodes: bloom, ACES tone mapping, saturation, contrast, color temperature, film grain, vignette. Each effect has its own uniform so they can be toggled independently at runtime.

The pipeline builds two output chains that share the same uniforms but split at bloom. Turning bloom off swaps the output node — the GPU never runs the downsample+blur passes, not just at strength 0 but actually gone from the graph. When the whole PP is off, it falls back to the renderer's tone mapping directly.

Before Post-Process

Before — Raw render

After Post-Process

After — ACES, CA, contrast, grain

Result

CategoryResult
Source VerificationA web viewer for checking source PMX models separately from converted results
Motion VerificationSupports 6 model families, automatic bone match rate/IK conflict detection
Effect Precompute6 types — Motion-synced effect experiments
Post-ProcessRemove unused passes by swapping bloom nodes; fall back to the renderer when post-processing is off
Tech ValidationWebGPU + TSL shaders in a real project
StatusActive — next: physics bone simulation (rigid body + joint), gaussian splatting background
FX control panels — VFX, Post-Process, and PMX tabs

Real-time FX controls — VFX (particles, mirror), Post-Process (bloom, ACES, CA, grain), PMX (outline, FOV)

NPR Shading & Look Development PMX to VRM Pipeline