reze-engine 0.14.0 → 0.15.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (93) hide show
  1. package/README.md +81 -108
  2. package/dist/engine.d.ts +1 -7
  3. package/dist/engine.d.ts.map +1 -1
  4. package/dist/engine.js +4 -7
  5. package/dist/gpu-profile.d.ts +19 -0
  6. package/dist/gpu-profile.d.ts.map +1 -0
  7. package/dist/gpu-profile.js +120 -0
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +1 -1
  11. package/dist/physics/body.d.ts +32 -0
  12. package/dist/physics/body.d.ts.map +1 -0
  13. package/dist/physics/body.js +245 -0
  14. package/dist/physics/constraint.d.ts +30 -0
  15. package/dist/physics/constraint.d.ts.map +1 -0
  16. package/dist/physics/constraint.js +115 -0
  17. package/dist/physics/contact.d.ts +60 -0
  18. package/dist/physics/contact.d.ts.map +1 -0
  19. package/dist/physics/contact.js +723 -0
  20. package/dist/physics/index.d.ts +4 -0
  21. package/dist/physics/index.d.ts.map +1 -0
  22. package/dist/physics/index.js +3 -0
  23. package/dist/physics/physics.d.ts +31 -0
  24. package/dist/physics/physics.d.ts.map +1 -0
  25. package/dist/physics/physics.js +209 -0
  26. package/dist/physics/profile.d.ts +18 -0
  27. package/dist/physics/profile.d.ts.map +1 -0
  28. package/dist/physics/profile.js +44 -0
  29. package/dist/physics/solver.d.ts +5 -0
  30. package/dist/physics/solver.d.ts.map +1 -0
  31. package/dist/physics/solver.js +559 -0
  32. package/dist/physics/types.d.ts +46 -0
  33. package/dist/physics/types.d.ts.map +1 -0
  34. package/dist/physics/types.js +12 -0
  35. package/dist/physics/world.d.ts +12 -0
  36. package/dist/physics/world.d.ts.map +1 -0
  37. package/dist/physics/world.js +146 -0
  38. package/dist/shaders/materials/hair.d.ts +1 -1
  39. package/dist/shaders/materials/hair.d.ts.map +1 -1
  40. package/dist/shaders/materials/hair.js +2 -2
  41. package/package.json +3 -6
  42. package/src/engine.ts +5 -9
  43. package/src/index.ts +1 -1
  44. package/src/physics/body.ts +334 -0
  45. package/src/physics/constraint.ts +181 -0
  46. package/src/physics/contact.ts +996 -0
  47. package/src/physics/index.ts +8 -0
  48. package/src/physics/physics.ts +253 -0
  49. package/src/physics/solver.ts +577 -0
  50. package/src/physics/types.ts +50 -0
  51. package/src/physics/world.ts +152 -0
  52. package/src/shaders/materials/hair.ts +2 -2
  53. package/dist/ammo-loader.d.ts +0 -3
  54. package/dist/ammo-loader.d.ts.map +0 -1
  55. package/dist/ammo-loader.js +0 -26
  56. package/dist/physics.d.ts +0 -86
  57. package/dist/physics.d.ts.map +0 -1
  58. package/dist/physics.js +0 -527
  59. package/dist/shaders/body.d.ts +0 -2
  60. package/dist/shaders/body.d.ts.map +0 -1
  61. package/dist/shaders/body.js +0 -199
  62. package/dist/shaders/classify.d.ts +0 -4
  63. package/dist/shaders/classify.d.ts.map +0 -1
  64. package/dist/shaders/classify.js +0 -12
  65. package/dist/shaders/cloth_rough.d.ts +0 -2
  66. package/dist/shaders/cloth_rough.d.ts.map +0 -1
  67. package/dist/shaders/cloth_rough.js +0 -178
  68. package/dist/shaders/cloth_smooth.d.ts +0 -2
  69. package/dist/shaders/cloth_smooth.d.ts.map +0 -1
  70. package/dist/shaders/cloth_smooth.js +0 -174
  71. package/dist/shaders/default.d.ts +0 -2
  72. package/dist/shaders/default.d.ts.map +0 -1
  73. package/dist/shaders/default.js +0 -171
  74. package/dist/shaders/eye.d.ts +0 -2
  75. package/dist/shaders/eye.d.ts.map +0 -1
  76. package/dist/shaders/eye.js +0 -146
  77. package/dist/shaders/face.d.ts +0 -2
  78. package/dist/shaders/face.d.ts.map +0 -1
  79. package/dist/shaders/face.js +0 -199
  80. package/dist/shaders/hair.d.ts +0 -2
  81. package/dist/shaders/hair.d.ts.map +0 -1
  82. package/dist/shaders/hair.js +0 -176
  83. package/dist/shaders/metal.d.ts +0 -2
  84. package/dist/shaders/metal.d.ts.map +0 -1
  85. package/dist/shaders/metal.js +0 -174
  86. package/dist/shaders/nodes.d.ts +0 -2
  87. package/dist/shaders/nodes.d.ts.map +0 -1
  88. package/dist/shaders/nodes.js +0 -456
  89. package/dist/shaders/stockings.d.ts +0 -2
  90. package/dist/shaders/stockings.d.ts.map +0 -1
  91. package/dist/shaders/stockings.js +0 -244
  92. package/src/ammo-loader.ts +0 -31
  93. package/src/physics.ts +0 -706
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Reze Engine
2
2
 
3
- A minimal-dependency WebGPU engine for real-time MMD/PMX rendering. Only external dependency is Ammo.js for physics.
3
+ **Zero-runtime-dependency** WebGPU engine for real-time MMD/PMX rendering. Renderer, animation, IK, and physics all in TypeScript.
4
4
 
5
5
  ![screenshot](./screenshot.png)
6
6
 
@@ -17,8 +17,9 @@ npm install reze-engine
17
17
  - **HDR pipeline** with bloom mip pyramid, Filmic tone mapping, 4× MSAA, tile-memory-friendly on Apple Silicon
18
18
  - **Alpha-hashed transparency** (Wyman & McGuire 2017) for self-overlapping transparent meshes like stockings
19
19
  - **Screen-space outlines** on opaque + transparent materials
20
- - **See-through hair over eyes** — stencil-gated MMD post-alpha-eye so eyes read at 50% through hair silhouettes
21
- - **VMD animation** with IK solver and Bullet physics
20
+ - **See-through hair over eyes** — stencil-gated MMD post-alpha-eye so eyes read at 75% through hair silhouettes
21
+ - **In-house TS physics** sequential-impulse 6DOF spring solver, sphere/box/capsule contacts, split-impulse position correction, fixed-step substepping
22
+ - **VMD animation** with IK solver
22
23
  - **Orbit camera** with bone-follow mode
23
24
  - **GPU picking** (double-click/tap)
24
25
  - **Ground plane** with PCF shadow mapping
@@ -109,7 +110,7 @@ engine.dispose()
109
110
 
110
111
  Use a hidden `<input type="file" webkitdirectory multiple>` (or drag/drop) and pass the resulting `FileList` or `File[]` into the engine. Textures resolve relative to the chosen PMX file inside that tree.
111
112
 
112
- **Important:** read `input.files` into a normal array **before** setting `input.value = ""`. The browsers `FileList` is _live_ — clearing the input empties it.
113
+ **Important:** read `input.files` into a normal array **before** setting `input.value = ""`. The browser's `FileList` is _live_ — clearing the input empties it.
113
114
 
114
115
  1. **`parsePmxFolderInput(fileList)`** — returns a tagged result (`empty` | `not_directory` | `no_pmx` | `single` | `multiple`). For `single`, you already have `files` and `pmxFile`. For `multiple`, show a picker (dropdown) of `pmxRelativePaths`, then resolve with **`pmxFileAtRelativePath(files, path)`**.
115
116
  2. **`engine.loadModel(name, { files, pmxFile })`** — `pmxFile` selects which `.pmx` when the folder contains several.
@@ -231,9 +232,6 @@ Blender-style scene config — `world` = environment lighting, `sun` = the direc
231
232
  },
232
233
  onRaycast: (modelName, material, bone, screenX, screenY) => void,
233
234
  onGizmoDrag: (event: GizmoDragEvent) => void,
234
- physicsOptions: {
235
- constraintSolverKeywords: string[],
236
- },
237
235
  }
238
236
  ```
239
237
 
@@ -258,14 +256,14 @@ engine.setSelectedBone(modelName | null, boneName | null) // shows the
258
256
 
259
257
  ```typescript
260
258
  type GizmoDragEvent = {
261
- modelName: string;
262
- boneName: string;
263
- boneIndex: number;
264
- kind: "rotate" | "translate";
265
- localRotation: Quat; // target absolute local rotation
266
- localTranslation: Vec3; // target absolute local translation
267
- phase?: "start" | "end"; // undefined during drag moves
268
- };
259
+ modelName: string
260
+ boneName: string
261
+ boneIndex: number
262
+ kind: "rotate" | "translate"
263
+ localRotation: Quat // target absolute local rotation
264
+ localTranslation: Vec3 // target absolute local translation
265
+ phase?: "start" | "end" // undefined during drag moves
266
+ }
269
267
  ```
270
268
 
271
269
  Fires once with `phase: "start"` on mousedown, on every mousemove (no phase), once with `phase: "end"` on mouseup. While drag is active the engine consumes any mouse input inside the gizmo's bounding sphere so camera orbit never conflicts with a drag — mousedown outside the sphere routes to camera as normal.
@@ -275,139 +273,114 @@ Fires once with `phase: "start"` on mousedown, on every mousemove (no phase), on
275
273
  ```javascript
276
274
  // Runtime override (no clip editor — this is what web/page.tsx does).
277
275
  onGizmoDrag: (e) => {
278
- const model = engine.getModel(e.modelName);
279
- if (!model) return;
276
+ const model = engine.getModel(e.modelName)
277
+ if (!model) return
280
278
  if (e.phase === "start") {
281
- model.pause();
282
- model.setClipApplySuspended(true); // stop clip re-sampling from wiping the edit
283
- return;
279
+ model.pause()
280
+ model.setClipApplySuspended(true) // stop clip re-sampling from wiping the edit
281
+ return
284
282
  }
285
- if (e.phase === "end") return;
283
+ if (e.phase === "end") return
286
284
  if (e.kind === "rotate")
287
- model.rotateBones({ [e.boneName]: e.localRotation }, 0); // 0 = instant write
288
- else model.setBoneLocalTranslation(e.boneIndex, e.localTranslation);
289
- };
285
+ model.rotateBones({ [e.boneName]: e.localRotation }, 0) // 0 = instant write
286
+ else
287
+ model.setBoneLocalTranslation(e.boneIndex, e.localTranslation)
288
+ }
290
289
  // Pressing play/seek auto-clears the suspend flag → animation resumes, edit is lost
291
290
  // (expected runtime-override semantic).
292
291
 
293
292
  // Keyframe edit (animation editor — studio-style).
294
293
  onGizmoDrag: (e) => {
295
- if (e.phase === "start") {
296
- beginUndoGroup();
297
- return;
298
- }
299
- if (e.phase === "end") {
300
- commitUndoGroup();
301
- return;
302
- }
303
- const kf = findOrCreateKeyframe(clip, e.boneName, currentFrame);
304
- kf.rotation = e.localRotation;
305
- kf.translation = e.localTranslation;
306
- model.loadClip(clipName, clip);
307
- model.seek(currentTime);
294
+ if (e.phase === "start") { beginUndoGroup(); return }
295
+ if (e.phase === "end") { commitUndoGroup(); return }
296
+ const kf = findOrCreateKeyframe(clip, e.boneName, currentFrame)
297
+ kf.rotation = e.localRotation
298
+ kf.translation = e.localTranslation
299
+ model.loadClip(clipName, clip)
300
+ model.seek(currentTime)
308
301
  // The re-sampled clip now produces the edited pose — no suspend flag needed.
309
- };
302
+ }
310
303
  ```
311
304
 
312
305
  Note the asymmetry: rotation uses `rotateBones({ name, q }, 0)` (the tween-based API reduces to an instant write when duration is 0) while translation uses `setBoneLocalTranslation(idx, v)` — `moveBones` can't be used because it converts VMD-relative input to local, and the gizmo's output is already local.
313
306
 
314
- `constraintSolverKeywords` — joints whose name contains any keyword use the Bullet 2.75 constraint solver; all others keep the stable Ammo 2.82+ default. See [babylon-mmd: Fix Constraint Behavior](https://noname0310.github.io/babylon-mmd/docs/reference/runtime/apply-physics-to-mmd-models/#fix-constraint-behavior) for details.
315
-
316
- ## Rendering
307
+ ## Physics
317
308
 
318
- Each surface combines an NPR stack with a Principled-style BSDF, mixed per material so anime characters keep their flat illustrated look while highlights and reflections stay grounded. Every per-material shader is ~40–120 lines of distinctive code standing on a small set of shared WGSL primitives (`engine/src/shaders/materials/`).
309
+ In-house sequential-impulse rigid-body solver, no external physics dependency. Targets PMX rigs (sphere / box / capsule colliders, 6DOF spring joints) at quality comparable to Bullet's defaults in ~1.5k lines of TypeScript.
319
310
 
320
- ### Anatomy of a material shader
311
+ ### Pipeline
321
312
 
322
- Every material's fragment shader is the same 7-stage pipeline. The order is fixed; the content is per-material:
313
+ Per substep:
323
314
 
324
315
  ```
325
- (A) Fragment setup n, v, l, sun, amb, shadow ← shared
326
- (B) Texture + alpha tex_rgb, discard ← shared shape
327
- (C) NPR stack → toon + rim + warm + … ← UNIQUE per material
328
- (D) Optional bump → noise → bump_lh ← 3 presets
329
- (E) Principled BSDF → eval_principled(...) ← shared helper
330
- (F) NPR ↔ PBR mix → mix(npr, principled, fac) ← per-material fac
331
- (G) FSOut → color + bloom mask ← shared
316
+ predict velocities broadphase + narrowphase → solve constraints (10 iters)
317
+ split-impulse position correction integrate transforms
332
318
  ```
333
319
 
334
- The simplest material (`default`) uses only A/B/E/Gno NPR stack at all:
320
+ A fixed-timestep accumulator runs the substep at a constant **60 Hz** regardless of render rate, with up to 6 substeps per render frame. Constant `dt` keeps spring impulse, damping, and integration deterministic without it, coupled cloth chains never reach steady state.
335
321
 
336
- ```wgsl
337
- let color = eval_principled(
338
- PrincipledIn(albedo, 0.0, 0.5, 0.5, 1e30, 0.0, 0.0), // metallic, spec, rough, clamp, sheen, sheen_tint
339
- n, l, v, sun, amb, shadow
340
- );
341
- ```
322
+ ### Implementation notes
342
323
 
343
- NPR presets add stage C (and sometimes D) on top, and stage F chooses how NPR-leaning the surface is.
324
+ - **Solver** projected Gauss-Seidel sequential impulse, 10 iterations, joint rows + contact rows in the same loop. Joint constraints are 6DOF springs (3 linear, 3 angular) with stop-ERP for limit correction and a per-axis spring impulse driven by stiffness × position error.
325
+ - **Narrowphase** — analytical per pair: sphere-sphere, sphere-capsule, sphere-box, capsule-capsule, capsule-box. Capsule-capsule emits multiple contact points along nearly-parallel axes for rotational stability (otherwise a single closest-point contact lets cloth pivot freely around the line through that point).
326
+ - **Speculative contacts** — `CONTACT_MARGIN = 0.04` fires contacts at near-touch with signed depth. The push-only impulse clamp keeps them inert until actual overlap, but they prevent fast bodies from crossing a thin surface in a single substep.
327
+ - **Split-impulse position correction** — penetration is resolved by a direct mass-weighted translation along the contact normal *outside* the velocity solver, so joint pulls in the SI loop can't fight the contact's separation.
328
+ - **Kinematic velocity propagation** — bone-driven kinematic bodies have their linear + angular velocities derived from the bone-pose delta each render frame, so joints attached to a fast limb feel the actual motion instead of a position teleport.
329
+ - **Body sleeping** is disabled (cloth must always respond to bone motion); resting bodies rely on per-PMX damping to bleed off micro-velocity.
344
330
 
345
- ### Shared WGSL foundations
331
+ ### API
346
332
 
347
- - **`nodes.ts`** — WGSL mirrors of the Blender shader nodes the presets use: `hue_sat`, `bright_contrast`, `ramp_constant/linear/cardinal`, `mix_overlay/lighten/linear_light`, `fresnel`, `layer_weight_fresnel/facing`, `tex_noise`, `tex_voronoi`, `mapping_point`, `bump_lh`, `normal_map`. Plus a combined DFG + LTC LUT, `eval_principled(PrincipledIn, N, L, V, sun, amb, shadow)`, and `principled_sheen`.
348
- - **`common.ts`** — Uniform structs, bind-group layout (same for every material pipeline), PCF shadow sampler, skinning vertex shader, shared `FSOut`.
349
- - **Per-material files** constants + NPR stack + optional bump + `eval_principled` call + final mix.
333
+ ```javascript
334
+ engine.setPhysicsEnabled(enabled)
335
+ engine.resetPhysics() // re-snap bodies to bone poses, zero velocities
336
+ ```
350
337
 
351
- ### PBR specular core
338
+ That's the entire engine-level surface — physics options live on the PMX rig itself (mass, damping, friction, restitution, joint stiffness / limits, collision groups).
352
339
 
353
- Inside `eval_principled`:
340
+ ## Rendering
354
341
 
355
- - GGX microfacet specular with Schlick Fresnel and Walter–Smith G1
356
- - **Multi-scatter compensation** (Fdez-Agüera 2019) — restores energy at high roughness so metals don't darken
357
- - **Split-sum DFG LUT** (Karis 2013) — drives indirect specular
358
- - **LTC direct-spec scale** (Heitz 2016) — keeps analytic-light specular in the same energy budget as image-based lighting
359
- - **Sheen coarse curve** gated by the `sheen` field on `PrincipledIn`
342
+ Each surface combines an NPR stack with a Principled-style BSDF, mixed per material — anime characters keep their flat illustrated look while highlights and reflections stay grounded. Per-material shaders live in `engine/src/shaders/materials/`.
360
343
 
361
- ### NPR toolbox
344
+ ### Material pipeline
362
345
 
363
- Every preset's stage C is built from these primitives:
346
+ Every fragment shader follows the same 7-stage layout (shared stages from `nodes.ts` / `common.ts`):
347
+
348
+ ```
349
+ (A) Fragment setup → (B) Texture + alpha → (C) NPR stack → (D) Optional bump
350
+ → (E) Principled BSDF → (F) NPR ↔ PBR mix → (G) FSOut
351
+ ```
364
352
 
365
- - **Toon ramps** quantised NdotL through constant or `ramp_constant_edge_aa` (fwidth-based step anti-alias) for cel-shaded shadow terminators
366
- - **HSV remaps** — separate hue/sat/value tints for shadow vs lit zones, layered with mix-overlay against the lit texture for warm-shadow / cool-light shifts
367
- - **Fresnel rim & layer-weight wrap** — `fresnel × layer_weight_facing` (or two stacked fresnels) feeds a MixShader against an emissive backdrop for anime back-light
368
- - **Procedural micro-detail** — 3-octave value noise (PCG hash, fully unrolled) drives bump-from-height for skin and fabric; 3D Voronoi in reflection-coord space drives metallic sparkle
369
- - **Selective emission** — BT.601-luminance-gated boosts (eye iris, face highlights, stockings pattern) that survive into bloom
353
+ The `default` preset uses only A/B/E/G; NPR presets layer C (and sometimes D) on top, with stage F choosing how NPR-leaning the final result is.
370
354
 
371
- ### Per-material NPR stacks
355
+ **PBR core** (`eval_principled`) — GGX microfacet with Schlick Fresnel, Walter–Smith G1, Fdez-Agüera 2019 multi-scatter compensation, Karis 2013 split-sum DFG LUT, Heitz 2016 LTC direct-spec scaling, optional sheen.
372
356
 
373
- Each PMX material is assigned to one of these shaders. The NPR stack column is what's actually in stage C of that file; the Principled column is what gets passed to `eval_principled`.
357
+ **NPR toolbox** toon ramps (constant or fwidth-AA'd), HSV warm-shadow / cool-light remaps, fresnel + layer-weight rims, value-noise bump, 3D Voronoi metallic sparkle, BT.601-luminance-gated emission.
374
358
 
375
- | Preset | NPR stack (stage C) | Principled (stage E) |
376
- | -------------- | ----------------------------------------------------------- | ------------------------------------------------------------- |
377
- | `default` | — | metallic=0, spec=0.5, rough=0.5 |
378
- | `eye` | (emission = albedo × 1.5 added post-eval) | same as default |
379
- | `face` | toon + warm rim + dual-fresnel rim + BT.601 bright-tex gate | spec=0.5, rough=0.3, noise bump, spec clamp=10 |
380
- | `body` | toon + warm rim + fresnel rim + facing rim | spec=0.5, rough=0.3, noise bump, spec clamp=10 |
381
- | `hair` | toon + fresnel rim + bevel (n.y) + bright-tex gate | spec=1.0, rough=0.3, mixed at 20% PBR |
382
- | `cloth_smooth` | toon + bevel + mix-overlay emission (×18) | spec=0.8, rough=0.5 |
383
- | `cloth_rough` | same NPR as `cloth_smooth` | spec=0.8, rough=0.82, live noise bump, spec clamp=10 |
384
- | `metal` | toon + mix-overlay emission (×8) | metallic=1, voronoi-driven base (reflection-coord), rough=0.3 |
385
- | `stockings` | gradient × facing mask + HSV-boosted emission (×5) | metallic=0.1, spec=1, rough=0.5, **sheen=0.7**, hashed alpha |
359
+ | Preset | Notes |
360
+ | -------------- | ------------------------------------------------------------------------------- |
361
+ | `default` | Plain Principled, metallic=0, rough=0.5 |
362
+ | `eye` | Plain + post-eval emission ×1.5 |
363
+ | `face` | Toon + warm rim + dual-fresnel rim + bright-tex gate, noise bump |
364
+ | `body` | Toon + warm rim + fresnel + facing rim, noise bump |
365
+ | `hair` | Toon + fresnel + bevel + bright-tex gate, mixed at 20% PBR |
366
+ | `cloth_smooth` | Toon + bevel + emission overlay (×18) |
367
+ | `cloth_rough` | Same NPR as cloth_smooth, live noise bump, rough=0.82 |
368
+ | `metal` | Toon + emission overlay (×8), voronoi base, metallic=1 |
369
+ | `stockings` | Gradient × facing mask + HSV emission (×5), sheen=0.7, **alpha-hashed** |
386
370
 
387
- Assign presets per-model with `engine.setMaterialPresets(name, map)` (see the [Usage](#usage) example). Material names not listed fall through to `default`.
371
+ Assign per-model with `engine.setMaterialPresets(name, map)`. Unlisted material names fall through to `default`.
388
372
 
389
- ### Shadows, post, output
373
+ ### Post & output
390
374
 
391
375
  - Directional shadow map (2048², depth32float, PCF, normal + depth bias)
392
- - HDR main pass with 4× MSAA. Color is `rg11b10ufloat` paired with an `rg8unorm` aux MRT carrying bloom mask (`.r`) and accumulated alpha (`.g`). The combined footprint fits Apple Silicon TBDR tile memory, so the 4× MSAA buffer resolves in-tile rather than spilling to system memory every frame. Falls back to `rgba16float` when the device does not expose `rg11b10ufloat-renderable`.
393
- - Bloom via threshold + downsample/upsample mip pyramid, gated by the aux bloom-mask channel
376
+ - HDR main pass at 4× MSAA, `rg11b10ufloat` color + `rg8unorm` aux MRT (bloom mask + accumulated alpha) fits Apple Silicon TBDR tile memory so MSAA resolves in-tile. Falls back to `rgba16float` when `rg11b10ufloat-renderable` isn't available.
377
+ - Bloom: threshold + downsample/upsample mip pyramid, gated by aux bloom mask
394
378
  - Filmic tone mapping (LUT extracted from Blender 3.6 OCIO "Filmic / Medium High Contrast")
395
- - Screen-space outline pass (inverted-hull) on opaque and transparent materials
396
-
397
- ### Alpha-hashed transparency
398
-
399
- `stockings` uses the Wyman & McGuire 2017 derivative-aware stochastic discard so self-overlapping transparent meshes (e.g. the front and back of a stocking wrapped around a leg) resolve cleanly under MSAA with opaque-style depth writes. The hash is derived from world-space position, so the dither pattern does not swim when the camera moves.
400
-
401
- ### See-through hair over eyes (MMD post-alpha-eye)
402
-
403
- The classic MMD effect where hair strands covering the eye are rendered at 50% so the iris stays readable — implemented as a single extra pass driven by the stencil buffer, not a two-texture composite.
379
+ - Inverted-hull screen-space outline pass on opaque + transparent
404
380
 
405
- - **Eye pipeline** stamps `stencil = EYE_VALUE` on every fragment it writes, with `cullMode: "front"` and a small negative `depthBias` so only the back half of the eye mesh renders (the MMD trick that keeps eyes from leaking through the back of the head).
406
- - **Main hair pipeline** stencil-tests `not-equal EYE_VALUE` and skips those fragments.
407
- - **Hair-over-eyes pipeline** re-issues the hair draws with `IS_OVER_EYES = true`, stencil-tests `equal EYE_VALUE`, disables depth writes, and alpha blends at 50% — eye-stamped pixels end up `0.5·hair + 0.5·eye` in linear HDR before tonemap.
408
- - **Outline pipeline** stencil-tests `not-equal EYE_VALUE` so edge color does not overwrite the see-through region.
381
+ **Alpha-hashed transparency** (`stockings` only) Wyman & McGuire 2017 derivative-aware stochastic discard with world-space hash, so self-overlapping transparent meshes resolve under MSAA with opaque-style depth writes and the dither doesn't swim with the camera.
409
382
 
410
- Draw order within a model: non-eye/non-hair opaque eye (stamp) hair (skip stamp) outlines (skip stamp) → hair-over-eyes (match stamp).
383
+ **See-through hair over eyes** (MMD post-alpha-eye) — single stencil-gated extra pass: eye stamps `EYE_VALUE`, main hair skips it, an extra hair-over-eyes pass matches it and alpha-blends at 25% in linear HDR before tonemap. Outline pass also skips the stamp so the iris stays readable.
411
384
 
412
385
  ## Projects Using This Engine
413
386
 
package/dist/engine.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import { Quat, Vec3 } from "./math";
2
2
  import { Model } from "./model";
3
- import { type PhysicsOptions } from "./physics";
4
3
  import { type AssetReader } from "./asset-reader";
5
4
  export type MaterialPreset = "default" | "face" | "hair" | "body" | "eye" | "stockings" | "metal" | "cloth_smooth" | "cloth_rough";
6
5
  export type MaterialPresetMap = Partial<Record<MaterialPreset, string[]>>;
@@ -87,7 +86,6 @@ export type EngineOptions = {
87
86
  onRaycast?: RaycastCallback;
88
87
  /** See {@link GizmoDragCallback}. */
89
88
  onGizmoDrag?: GizmoDragCallback;
90
- physicsOptions?: PhysicsOptions;
91
89
  };
92
90
  export declare const DEFAULT_ENGINE_OPTIONS: {
93
91
  world: {
@@ -105,9 +103,6 @@ export declare const DEFAULT_ENGINE_OPTIONS: {
105
103
  fov: number;
106
104
  };
107
105
  onRaycast: undefined;
108
- physicsOptions: {
109
- constraintSolverKeywords: string[];
110
- };
111
106
  };
112
107
  export interface EngineStats {
113
108
  fps: number;
@@ -243,7 +238,6 @@ export declare class Engine {
243
238
  private groundDrawCall;
244
239
  private onRaycast?;
245
240
  private onGizmoDrag?;
246
- private physicsOptions;
247
241
  private lastTouchTime;
248
242
  private readonly DOUBLE_TAP_DELAY;
249
243
  private pickPipeline;
@@ -428,7 +422,7 @@ export declare class Engine {
428
422
  /**
429
423
  * Second hair pass for the see-through-hair effect. Re-draws every hair opaque
430
424
  * draw using `hairOverEyesPipeline` — which stencil-matches `EYE_VALUE` and runs
431
- * the hair shader with `IS_OVER_EYES=true` so alpha is halved. depthWriteEnabled
425
+ * the hair shader with `IS_OVER_EYES=true` so alpha is scaled to 25%. depthWriteEnabled
432
426
  * is off, so the eye's depth stays authoritative for anything drawn after.
433
427
  */
434
428
  private drawHairOverEyes;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAQ,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACzC,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAG/B,OAAO,EAQL,KAAK,WAAW,EACjB,MAAM,gBAAgB,CAAA;AA4BvB,MAAM,MAAM,cAAc,GACtB,SAAS,GACT,MAAM,GACN,MAAM,GACN,MAAM,GACN,KAAK,GACL,WAAW,GACX,OAAO,GACP,cAAc,GACd,aAAa,CAAA;AAEjB,MAAM,MAAM,iBAAiB,GAAG,OAAO,CAAC,MAAM,CAAC,cAAc,EAAE,MAAM,EAAE,CAAC,CAAC,CAAA;AAUzE,MAAM,MAAM,eAAe,GAAG,CAC5B,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,IAAI,EAAE,MAAM,GAAG,IAAI,EACnB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,KACZ,IAAI,CAAA;AAET,kHAAkH;AAClH,MAAM,MAAM,yBAAyB,GAAG;IACtC,KAAK,EAAE,QAAQ,GAAG,IAAI,EAAE,CAAA;IACxB,OAAO,CAAC,EAAE,IAAI,CAAA;CACf,CAAA;AAID,MAAM,MAAM,YAAY,GAAG;IACzB,8FAA8F;IAC9F,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,UAAU,GAAG;IACvB,6DAA6D;IAC7D,KAAK,CAAC,EAAE,IAAI,CAAA;IACZ,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,yFAAyF;IACzF,SAAS,CAAC,EAAE,IAAI,CAAA;CACjB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,kCAAkC;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,gCAAgC;IAChC,MAAM,CAAC,EAAE,IAAI,CAAA;IACb,yCAAyC;IACzC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAED,wFAAwF;AACxF,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,OAAO,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,MAAM,CAAA;IACZ,MAAM,EAAE,MAAM,CAAA;IACd,KAAK,EAAE,IAAI,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;IACjB,KAAK,EAAE,MAAM,CAAA;CACd,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,YAQnC,CAAA;AAED,4HAA4H;AAC5H,MAAM,MAAM,oBAAoB,GAAG;IACjC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAA;IAChB,yDAAyD;IACzD,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,SAAS,GAAG,sBAAsB,CAAA;CACzC,CAAA;AAID,eAAO,MAAM,sBAAsB,EAAE,oBAIpC,CAAA;AAED,MAAM,MAAM,aAAa,GAAG,QAAQ,GAAG,WAAW,CAAA;AAElD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,MAAM,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,IAAI,EAAE,aAAa,CAAA;IACnB,kGAAkG;IAClG,aAAa,EAAE,IAAI,CAAA;IACnB,gBAAgB,EAAE,IAAI,CAAA;IACtB,4EAA4E;IAC5E,KAAK,CAAC,EAAE,OAAO,GAAG,KAAK,CAAA;CACxB;AAED;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAA;AAE/D,MAAM,MAAM,aAAa,GAAG;IAC1B,KAAK,CAAC,EAAE,YAAY,CAAA;IACpB,GAAG,CAAC,EAAE,UAAU,CAAA;IAChB,MAAM,CAAC,EAAE,aAAa,CAAA;IACtB,yEAAyE;IACzE,KAAK,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAA;IAC7B,gFAAgF;IAChF,IAAI,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,CAAA;IACpC,SAAS,CAAC,EAAE,eAAe,CAAA;IAC3B,qCAAqC;IACrC,WAAW,CAAC,EAAE,iBAAiB,CAAA;CAChC,CAAA;AAED,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;CAKlC,CAAA;AAED,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,EAAE,MAAM,CAAA;CAClB;AA2CD,qBAAa,MAAM;IACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAsB;IAE7C,MAAM,CAAC,WAAW,IAAI,MAAM;IAO5B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,OAAO,CAAmB;IAClC,OAAO,CAAC,kBAAkB,CAAmB;IAC7C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,gBAAgB,CAAuB;IAE/C,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,GAAG,CAAqD;IAChE,OAAO,CAAC,YAAY,CAAkD;IACtE,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,UAAU,CAAI;IACtB,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,mBAAmB,CAAoB;IAC/C,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,oBAAoB,CAAoB;IAChD,OAAO,CAAC,2BAA2B,CAAqB;IACxD,OAAO,CAAC,eAAe,CAAoB;IAC3C,OAAO,CAAC,gBAAgB,CAA2D;IACnF,OAAO,CAAC,oBAAoB,CAAC,CAAY;IACzC,OAAO,CAAC,iBAAiB,CAAC,CAAgB;IAC1C,OAAO,CAAC,qBAAqB,CAAoB;IACjD,OAAO,CAAC,2BAA2B,CAA0B;IAC7D,OAAO,CAAC,qBAAqB,CAAoB;IACjD,OAAO,CAAC,4BAA4B,CAAqB;IACzD,OAAO,CAAC,sBAAsB,CAAC,CAAc;IAC7C,OAAO,CAAC,0BAA0B,CAAY;IAC9C,OAAO,CAAC,2BAA2B,CAA0B;IAC7D,OAAO,CAAC,gBAAgB,CAAa;IAGrC,OAAO,CAAC,YAAY,CAA0E;IAC9F,OAAO,CAAC,iBAAiB,CAAY;IACrC,OAAO,CAAC,oBAAoB,CAAY;IACxC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,eAAe,CAAe;IACtC,OAAO,CAAC,oBAAoB,CAAqB;IACjD,OAAO,CAAC,mBAAmB,CAA0B;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAK;IAChD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAM;IAG/C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAO;IAIhD,OAAO,CAAC,UAAU,CAAoD;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAC9C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAO;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,CAAO;IAOtD,OAAO,CAAC,SAAS,CAcF;IACf,OAAO,CAAC,2BAA2B,CAAqB;IACxD,OAAO,CAAC,8BAA8B,CAAqB;IAC3D,OAAO,CAAC,8BAA8B,CAAqB;IAC3D,OAAO,CAAC,8BAA8B,CAAqB;IAC3D,OAAO,CAAC,iCAAiC,CAAqB;IAC9D,OAAO,CAAC,iBAAiB,CAAe;IACxC,OAAO,CAAC,wBAAwB,CAAe;IAC/C,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,iBAAiB,CAAa;IACtC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAI;IAiB7C,OAAO,CAAC,SAAS,CAAkC;IACnD;0FACsF;IACtF,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAI;IAC7C;;;;;;;gGAO4F;IAC5F,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAA+B;IACxE,OAAO,CAAC,sBAAsB,CAAa;IAC3C,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,eAAe,CAAiB;IACxC,OAAO,CAAC,oBAAoB,CAA0B;IACtD,OAAO,CAAC,uBAAuB,CAA0B;IAIzD,OAAO,CAAC,yBAAyB,CAAoB;IACrD,OAAO,CAAC,sBAAsB,CAAoB;IAClD,OAAO,CAAC,wBAAwB,CAAqB;IACrD,OAAO,CAAC,kBAAkB,CAAe;IACzC,OAAO,CAAC,sBAAsB,CAAY;IAE1C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsB;IAQ3D,OAAO,CAAC,YAAY,CAAa;IACjC,OAAO,CAAC,sBAAsB,CAAY;IAC1C,OAAO,CAAC,0BAA0B,CAAY;IAC9C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAsB;IAC3D,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAsB;IAC/D,OAAO,CAAC,iBAAiB,CAAoB;IAC7C,OAAO,CAAC,uBAAuB,CAAoB;IACnD,OAAO,CAAC,qBAAqB,CAAoB;IACjD,OAAO,CAAC,wBAAwB,CAAqB;IACrD,OAAO,CAAC,8BAA8B,CAAqB;IAC3D,OAAO,CAAC,4BAA4B,CAAqB;IACzD,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,iBAAiB,CAAuB;IAChD,OAAO,CAAC,eAAe,CAAuB;IAC9C,OAAO,CAAC,kBAAkB,CAAe;IACzC,OAAO,CAAC,yBAAyB,CAAqB;IACtD,OAAO,CAAC,uBAAuB,CAAqB;IACpD,2EAA2E;IAC3E,OAAO,CAAC,mBAAmB,CAA0B;IACrD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CAAI;IAG5C,OAAO,CAAC,kBAAkB,CAAC,CAAW;IACtC,OAAO,CAAC,iBAAiB,CAAC,CAAW;IACrC,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,kBAAkB,CAAiB;IAC3C,OAAO,CAAC,cAAc,CAAa;IACnC,OAAO,CAAC,WAAW,CAAiB;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAO;IAC9C,OAAO,CAAC,mBAAmB,CAAoB;IAC/C,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,mBAAmB,CAAuB;IAClD,OAAO,CAAC,qBAAqB,CAAC,CAAc;IAC5C,OAAO,CAAC,uBAAuB,CAAa;IAC5C,OAAO,CAAC,0BAA0B,CAAC,CAAW;IAC9C,OAAO,CAAC,cAAc,CAAwB;IAE9C,OAAO,CAAC,SAAS,CAAC,CAAiB;IACnC,OAAO,CAAC,WAAW,CAAC,CAAmB;IACvC,OAAO,CAAC,aAAa,CAAI;IACzB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAM;IAEvC,OAAO,CAAC,YAAY,CAAoB;IACxC,OAAO,CAAC,2BAA2B,CAAqB;IACxD,OAAO,CAAC,8BAA8B,CAAqB;IAC3D,OAAO,CAAC,8BAA8B,CAAqB;IAC3D,OAAO,CAAC,qBAAqB,CAAe;IAC5C,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,gBAAgB,CAAa;IACrC,OAAO,CAAC,kBAAkB,CAAY;IACtC,OAAO,CAAC,WAAW,CAAwC;IAE3D,OAAO,CAAC,cAAc,CAAmC;IACzD,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,uBAAuB,CAAa;IAC5C,OAAO,CAAC,YAAY,CAAgC;IACpD,OAAO,CAAC,eAAe,CAAiC;IACxD,OAAO,CAAC,cAAc,CAA0B;IAChD,OAAO,CAAC,mBAAmB,CAAI;IAG/B,OAAO,CAAC,SAAS,CAAO;IACxB,OAAO,CAAC,cAAc,CAAO;IAG7B,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,oBAAoB,CAAS;IACrC,OAAO,CAAC,kBAAkB,CAA0B;IAEpD,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,qBAAqB,CAAI;IACjC,OAAO,CAAC,aAAa,CAAoB;IACzC,OAAO,CAAC,YAAY,CAAI;IACxB,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,KAAK,CAGZ;IACD,OAAO,CAAC,gBAAgB,CAAsB;IAC9C,OAAO,CAAC,kBAAkB,CAA4B;IACtD,OAAO,CAAC,aAAa,CAAe;IACpC,OAAO,CAAC,aAAa,CAAuB;gBAEhC,MAAM,EAAE,iBAAiB,EAAE,OAAO,CAAC,EAAE,aAAa;IAuB9D,qEAAqE;IACrE,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,YAAY;IAcxE,MAAM,CAAC,0BAA0B,CAAC,OAAO,CAAC,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,oBAAoB;IAShG,uEAAuE;IACvE,eAAe,IAAI,YAAY;IAa/B,uBAAuB,IAAI,oBAAoB;IAK/C,uBAAuB,CAAC,KAAK,EAAE,OAAO,CAAC,oBAAoB,CAAC,GAAG,IAAI;IAUnE,OAAO,CAAC,0BAA0B;IAmBlC,wEAAwE;IACxE,eAAe,CAAC,KAAK,EAAE,OAAO,CAAC,YAAY,CAAC,GAAG,IAAI;IAoBnD,OAAO,CAAC,kBAAkB;IAsBpB,IAAI;IAyCV,OAAO,CAAC,WAAW;IA2EnB,OAAO,CAAC,oBAAoB;IAiC5B,OAAO,CAAC,eAAe;IAqwBvB,OAAO,CAAC,WAAW;IAoBnB,OAAO,CAAC,YAAY;IAkQpB,OAAO,CAAC,UAAU;IAmKlB,OAAO,CAAC,WAAW;IAmBnB,iFAAiF;IACjF,eAAe,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI;IAC9B,gGAAgG;IAChG,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI;IAoB3E,mIAAmI;IACnI,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI;IAY5E,iBAAiB,IAAI,MAAM;IAG3B,iBAAiB,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAGlC,cAAc,IAAI,MAAM;IAGxB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAG/B,aAAa,IAAI,MAAM;IAGvB,aAAa,CAAC,CAAC,EAAE,MAAM,GAAG,IAAI;IAK9B,OAAO,CAAC,aAAa;IAYrB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IASlB,qFAAqF;IACrF,OAAO,CAAC,QAAQ;IAgBhB,gGAAgG;IAChG,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI;IAMrC,0FAA0F;IAC1F,MAAM,CAAC,OAAO,EAAE,UAAU,GAAG,IAAI;IAUjC,QAAQ,IAAI,QAAQ,CAAC;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC;IAGvD,MAAM,IAAI,QAAQ,CAAC;QAAE,KAAK,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,IAAI,CAAA;KAAE,CAAC;IAItE,SAAS,CAAC,OAAO,CAAC,EAAE;QAClB,KAAK,CAAC,EAAE,MAAM,CAAA;QACd,MAAM,CAAC,EAAE,MAAM,CAAA;QACf,YAAY,CAAC,EAAE,IAAI,CAAA;QACnB,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,WAAW,CAAC,EAAE,MAAM,CAAA;QACpB,aAAa,CAAC,EAAE,MAAM,CAAA;QACtB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,aAAa,CAAC,EAAE,IAAI,CAAA;QACpB,aAAa,CAAC,EAAE,MAAM,CAAA;KACvB,GAAG,IAAI;IA4BR,OAAO,CAAC,iBAAiB;IAIzB,QAAQ,IAAI,WAAW;IAIvB,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,IAAI;IAgBnC,cAAc;IAQd,OAAO;IAuBD,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IACvC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,CAAC;IACrD,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,yBAAyB,GAAG,OAAO,CAAC,KAAK,CAAC;IAyB3E,QAAQ,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC;IAcxG,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAiB/B,aAAa,IAAI,MAAM,EAAE;IAIzB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAIpC,qBAAqB,CAAC,gBAAgB,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,IAAI;IAe9D,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAIhF,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,IAAI;IAcxE,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,iBAAiB,GAAG,IAAI;IASvE,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI;IAOnF,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,IAAI;IAOpE,iBAAiB,CAAC,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,OAAO;IAKnE,YAAY,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIpC,YAAY,IAAI,OAAO;IAIvB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIzC,iBAAiB,IAAI,OAAO;IAI5B,YAAY,IAAI,IAAI;IAWpB,OAAO,CAAC,eAAe;IAIvB,OAAO,CAAC,eAAe;IAWvB,OAAO,CAAC,kBAAkB;YAOZ,kBAAkB;IAiHhC,OAAO,CAAC,oBAAoB;IAwE5B,OAAO,CAAC,2BAA2B;IA4DnC,OAAO,CAAC,kBAAkB,CAAO;IACjC,OAAO,CAAC,mBAAmB;YAeb,yBAAyB;IAgIvC,OAAO,CAAC,2BAA2B;IAUnC,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,oBAAoB;YAId,4BAA4B;IAuC1C,OAAO,CAAC,eAAe;IA6CvB,OAAO,CAAC,YAAY;IASpB,OAAO,CAAC,uBAAuB,CAI9B;IAED,OAAO,CAAC,iBAAiB,CA0BxB;IAED,OAAO,CAAC,cAAc;IAStB,OAAO,CAAC,qBAAqB;IAsC7B,OAAO,CAAC,eAAe;IA4CvB,OAAO,CAAC,gBAAgB;IAYxB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,aAAa;IAkBrB,OAAO,CAAC,YAAY;IAqDpB,OAAO,CAAC,cAAc;IA0BtB,OAAO,CAAC,sBAAsB;IAW9B,OAAO,CAAC,QAAQ;IAWhB,OAAO,CAAC,gBAAgB;IAKxB,OAAO,CAAC,oBAAoB,CAoG3B;IAED,OAAO,CAAC,oBAAoB,CAkD3B;IAED,OAAO,CAAC,kBAAkB,CAsBzB;IAED,OAAO,CAAC,cAAc;YA+CR,iBAAiB;IAkD/B,MAAM;IAqHN,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,iBAAiB;IAYzB;;;;;OAKG;IACH,OAAO,CAAC,aAAa;IAoBrB;;;;;OAKG;IACH,OAAO,CAAC,YAAY;IAepB;;;;;OAKG;IACH,OAAO,CAAC,cAAc;IAiBtB;;;;;OAKG;IACH,OAAO,CAAC,gBAAgB;IAexB,OAAO,CAAC,oBAAoB;IAY5B,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,WAAW;CAwBpB"}
package/dist/engine.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { Camera } from "./camera";
2
2
  import { Mat4, Quat, Vec3 } from "./math";
3
3
  import { PmxLoader } from "./pmx-loader";
4
- import { Physics } from "./physics";
4
+ import { RezePhysics } from "./physics";
5
5
  import { createFetchAssetReader, createFileMapAssetReader, deriveBasePathFromPmxPath, fileListToMap, findFirstPmxFileInList, joinAssetPath, normalizeAssetPath, } from "./asset-reader";
6
6
  import { DEFAULT_SHADER_WGSL } from "./shaders/materials/default";
7
7
  import { FACE_SHADER_WGSL } from "./shaders/materials/face";
@@ -53,7 +53,6 @@ export const DEFAULT_ENGINE_OPTIONS = {
53
53
  sun: { color: new Vec3(1.0, 1.0, 1.0), strength: 2.0, direction: new Vec3(-0.0873, -0.3844, 0.919) },
54
54
  camera: { distance: 26.6, target: new Vec3(0, 12.5, 0), fov: Math.PI / 4 },
55
55
  onRaycast: undefined,
56
- physicsOptions: { constraintSolverKeywords: ["胸"] },
57
56
  };
58
57
  export class Engine {
59
58
  static getInstance() {
@@ -106,7 +105,6 @@ export class Engine {
106
105
  this.hasGround = false;
107
106
  this.shadowLightVPMatrix = new Float32Array(16);
108
107
  this.groundDrawCall = null;
109
- this.physicsOptions = DEFAULT_ENGINE_OPTIONS.physicsOptions;
110
108
  this.lastTouchTime = 0;
111
109
  this.DOUBLE_TAP_DELAY = 300;
112
110
  this.pendingPick = null;
@@ -351,7 +349,6 @@ export class Engine {
351
349
  };
352
350
  this.onRaycast = options?.onRaycast;
353
351
  this.onGizmoDrag = options?.onGizmoDrag;
354
- this.physicsOptions = options?.physicsOptions ?? d.physicsOptions;
355
352
  this.bloomSettings = Engine.mergeBloomDefaults(options?.bloom);
356
353
  this.viewTransform = Engine.mergeViewTransformDefaults(options?.view);
357
354
  }
@@ -797,7 +794,7 @@ export class Engine {
797
794
  stencilWriteMask: 0,
798
795
  },
799
796
  });
800
- // Hair-over-eyes: same shader with IS_OVER_EYES=true so alpha is halved at compile time.
797
+ // Hair-over-eyes: same shader with IS_OVER_EYES=true so alpha is scaled to 25% at compile time.
801
798
  // Only fragments where eye stencil == EYE_VALUE pass; depth test still culls fragments
802
799
  // that are further from camera than the eye, so hair behind the eye never shows through.
803
800
  // depthWriteEnabled=false keeps the eye's depth authoritative for everything drawn after.
@@ -2114,7 +2111,7 @@ export class Engine {
2114
2111
  });
2115
2112
  this.device.queue.writeBuffer(indexBuffer, 0, indices);
2116
2113
  const rbs = model.getRigidbodies();
2117
- const physics = rbs.length > 0 ? new Physics(rbs, model.getJoints(), this.physicsOptions) : null;
2114
+ const physics = rbs.length > 0 ? new RezePhysics(rbs, model.getJoints()) : null;
2118
2115
  const shadowBindGroup = this.device.createBindGroup({
2119
2116
  label: `${name}: shadow bind`,
2120
2117
  layout: this.shadowDepthPipeline.getBindGroupLayout(0),
@@ -3033,7 +3030,7 @@ export class Engine {
3033
3030
  /**
3034
3031
  * Second hair pass for the see-through-hair effect. Re-draws every hair opaque
3035
3032
  * draw using `hairOverEyesPipeline` — which stencil-matches `EYE_VALUE` and runs
3036
- * the hair shader with `IS_OVER_EYES=true` so alpha is halved. depthWriteEnabled
3033
+ * the hair shader with `IS_OVER_EYES=true` so alpha is scaled to 25%. depthWriteEnabled
3037
3034
  * is off, so the eye's depth stays authoritative for anything drawn after.
3038
3035
  */
3039
3036
  drawHairOverEyes(pass, inst) {
@@ -0,0 +1,19 @@
1
+ export declare class GpuTimestamp {
2
+ enabled: boolean;
3
+ readonly supported: boolean;
4
+ private device;
5
+ private querySet;
6
+ private resolveBuffer;
7
+ private readbackBuffer;
8
+ private nextSlot;
9
+ private frameLabels;
10
+ private inFlight;
11
+ private pendingLabels;
12
+ constructor(device: GPUDevice);
13
+ private ensureCreated;
14
+ beginFrame(): void;
15
+ wrap(desc: GPURenderPassDescriptor, label: string): GPURenderPassDescriptor;
16
+ endFrame(encoder: GPUCommandEncoder): void;
17
+ afterSubmit(): void;
18
+ }
19
+ //# sourceMappingURL=gpu-profile.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gpu-profile.d.ts","sourceRoot":"","sources":["../src/gpu-profile.ts"],"names":[],"mappings":"AAoBA,qBAAa,YAAY;IACvB,OAAO,UAAQ;IACf,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAA;IAC3B,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,QAAQ,CAA2B;IAC3C,OAAO,CAAC,aAAa,CAAyB;IAC9C,OAAO,CAAC,cAAc,CAAyB;IAC/C,OAAO,CAAC,QAAQ,CAAI;IACpB,OAAO,CAAC,WAAW,CAAe;IAClC,OAAO,CAAC,QAAQ,CAAQ;IAKxB,OAAO,CAAC,aAAa,CAAwB;gBAEjC,MAAM,EAAE,SAAS;IAK7B,OAAO,CAAC,aAAa;IAiBrB,UAAU,IAAI,IAAI;IAWlB,IAAI,CAAC,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,MAAM,GAAG,uBAAuB;IAqB3E,QAAQ,CAAC,OAAO,EAAE,iBAAiB,GAAG,IAAI;IAW1C,WAAW,IAAI,IAAI;CAwBpB"}
@@ -0,0 +1,120 @@
1
+ // WebGPU timestamp-query profiling. Records pass durations into the same
2
+ // profiler module as CPU phases (so the snapshot table mixes both with a
3
+ // "gpu." prefix). Read-only — no effect on rendering output.
4
+ //
5
+ // Pattern (per spec):
6
+ // 1. Each render pass declares timestampWrites { begin, end } slot indices.
7
+ // 2. After all passes, encoder.resolveQuerySet writes uint64 ns timestamps
8
+ // into a QUERY_RESOLVE buffer.
9
+ // 3. We copy the resolve buffer into a MAP_READ readback buffer.
10
+ // 4. Submit. After the GPU finishes, mapAsync resolves; we read durations
11
+ // and record them.
12
+ //
13
+ // One readback buffer with an in-flight gate: if mapAsync hasn't resolved
14
+ // from a previous frame, we skip the copy this frame (no contention, just
15
+ // one frame of dropped sampling).
16
+ import { profiler } from "./physics/profile";
17
+ const MAX_PASSES_PER_FRAME = 64;
18
+ export class GpuTimestamp {
19
+ constructor(device) {
20
+ this.enabled = false;
21
+ this.querySet = null;
22
+ this.resolveBuffer = null;
23
+ this.readbackBuffer = null;
24
+ this.nextSlot = 0;
25
+ this.frameLabels = [];
26
+ this.inFlight = false;
27
+ // Set inside endFrame() when a copy was queued this frame; consumed by
28
+ // afterSubmit() to kick mapAsync. mapAsync must run AFTER queue.submit —
29
+ // calling it before submit puts the buffer into "mapping pending" state,
30
+ // which makes the copy in the encoder illegal.
31
+ this.pendingLabels = null;
32
+ this.device = device;
33
+ this.supported = device.features.has("timestamp-query");
34
+ }
35
+ ensureCreated() {
36
+ if (this.querySet || !this.supported)
37
+ return;
38
+ const slots = MAX_PASSES_PER_FRAME * 2;
39
+ this.querySet = this.device.createQuerySet({ type: "timestamp", count: slots });
40
+ this.resolveBuffer = this.device.createBuffer({
41
+ label: "gpu-timestamp-resolve",
42
+ size: slots * 8,
43
+ usage: GPUBufferUsage.QUERY_RESOLVE | GPUBufferUsage.COPY_SRC,
44
+ });
45
+ this.readbackBuffer = this.device.createBuffer({
46
+ label: "gpu-timestamp-readback",
47
+ size: slots * 8,
48
+ usage: GPUBufferUsage.MAP_READ | GPUBufferUsage.COPY_DST,
49
+ });
50
+ }
51
+ // Called once at the top of each render() before any pass wrap.
52
+ beginFrame() {
53
+ if (!this.enabled || !this.supported)
54
+ return;
55
+ this.ensureCreated();
56
+ this.nextSlot = 0;
57
+ this.frameLabels = [];
58
+ }
59
+ // Wrap a render-pass descriptor with timestampWrites for `label`. If
60
+ // profiling is off / unsupported / out of slots, returns desc unchanged.
61
+ // The same label called multiple times (e.g. each bloom mip) is fine —
62
+ // the profiler accumulates by label.
63
+ wrap(desc, label) {
64
+ if (!this.enabled || !this.querySet)
65
+ return desc;
66
+ if (this.nextSlot + 2 > MAX_PASSES_PER_FRAME * 2)
67
+ return desc;
68
+ const begin = this.nextSlot;
69
+ const end = this.nextSlot + 1;
70
+ this.nextSlot += 2;
71
+ this.frameLabels.push(label);
72
+ return {
73
+ ...desc,
74
+ timestampWrites: {
75
+ querySet: this.querySet,
76
+ beginningOfPassWriteIndex: begin,
77
+ endOfPassWriteIndex: end,
78
+ },
79
+ };
80
+ }
81
+ // Call on the encoder after all passes, BEFORE encoder.finish(). Adds
82
+ // resolveQuerySet + copyBufferToBuffer commands. mapAsync is deferred to
83
+ // afterSubmit() — calling it before submit transitions the readback buffer
84
+ // into "mapping pending" state, which makes the queued copy illegal.
85
+ endFrame(encoder) {
86
+ if (!this.enabled || !this.querySet || this.frameLabels.length === 0)
87
+ return;
88
+ const count = this.frameLabels.length * 2;
89
+ encoder.resolveQuerySet(this.querySet, 0, count, this.resolveBuffer, 0);
90
+ if (this.inFlight)
91
+ return;
92
+ encoder.copyBufferToBuffer(this.resolveBuffer, 0, this.readbackBuffer, 0, count * 8);
93
+ this.pendingLabels = this.frameLabels.slice();
94
+ }
95
+ // Call AFTER device.queue.submit(). Kicks mapAsync if a copy was queued
96
+ // this frame; the .then() reads durations and unmaps.
97
+ afterSubmit() {
98
+ const labels = this.pendingLabels;
99
+ if (!labels)
100
+ return;
101
+ this.pendingLabels = null;
102
+ this.inFlight = true;
103
+ const readback = this.readbackBuffer;
104
+ void readback.mapAsync(GPUMapMode.READ).then(() => {
105
+ const arr = new BigInt64Array(readback.getMappedRange());
106
+ for (let i = 0; i < labels.length; i++) {
107
+ const start = arr[i * 2];
108
+ const end = arr[i * 2 + 1];
109
+ // Per spec, timestamps are nanoseconds.
110
+ const ms = Number(end - start) / 1e6;
111
+ if (ms >= 0 && ms < 1000)
112
+ profiler.record("gpu." + labels[i], ms);
113
+ }
114
+ readback.unmap();
115
+ this.inFlight = false;
116
+ }, () => {
117
+ this.inFlight = false;
118
+ });
119
+ }
120
+ }
package/dist/index.d.ts CHANGED
@@ -4,5 +4,5 @@ export { Model } from "./model";
4
4
  export { Vec3, Quat, Mat4 } from "./math";
5
5
  export type { AnimationClip, AnimationPlayOptions, AnimationProgress, BoneKeyframe, MorphKeyframe, BoneInterpolation, ControlPoint, } from "./animation";
6
6
  export { FPS } from "./animation";
7
- export { Physics, type PhysicsOptions } from "./physics";
7
+ export { RezePhysics } from "./physics";
8
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,qBAAqB,EACrB,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACvG,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACzC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,EAAE,OAAO,EAAE,KAAK,cAAc,EAAE,MAAM,WAAW,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,qBAAqB,EACrB,sBAAsB,EACtB,KAAK,WAAW,EAChB,KAAK,aAAa,EAClB,KAAK,YAAY,EACjB,KAAK,oBAAoB,EACzB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,aAAa,GACnB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACvG,OAAO,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAC/B,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AACzC,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,YAAY,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA"}
package/dist/index.js CHANGED
@@ -3,4 +3,4 @@ export { parsePmxFolderInput, pmxFileAtRelativePath } from "./folder-upload";
3
3
  export { Model } from "./model";
4
4
  export { Vec3, Quat, Mat4 } from "./math";
5
5
  export { FPS } from "./animation";
6
- export { Physics } from "./physics";
6
+ export { RezePhysics } from "./physics";