reze-engine 0.33.1 → 0.34.0
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.
- package/README.md +7 -3
- package/dist/engine.d.ts +22 -7
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +49 -17
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/physics/physics.d.ts +4 -0
- package/dist/physics/physics.d.ts.map +1 -1
- package/dist/physics/physics.js +7 -0
- package/dist/physics/world.d.ts +33 -0
- package/dist/physics/world.d.ts.map +1 -1
- package/dist/physics/world.js +57 -8
- package/dist/shaders/passes/ground-noise.d.ts +7 -0
- package/dist/shaders/passes/ground-noise.d.ts.map +1 -0
- package/dist/shaders/passes/ground-noise.js +88 -0
- package/dist/shaders/passes/ground.d.ts +1 -1
- package/dist/shaders/passes/ground.d.ts.map +1 -1
- package/dist/shaders/passes/ground.js +52 -19
- package/package.json +1 -1
- package/src/engine.ts +54 -21
- package/src/index.ts +2 -1
- package/src/physics/physics.ts +8 -1
- package/src/physics/world.ts +84 -3
- package/src/shaders/passes/ground.ts +52 -19
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ npm install reze-engine
|
|
|
15
15
|
- **Anime-style rendering** — toon-ramp NPR over a Principled GGX BSDF, mixed per material
|
|
16
16
|
- **Shader-graph materials** — every look is a Blender-style node graph compiled to WGSL; style groups bind any materials to any graph, fully customizable
|
|
17
17
|
- **HDR pipeline** — bloom, Filmic tone mapping, ASC CDL colour grading, 4× MSAA, Apple-TBDR-friendly targets
|
|
18
|
-
- **In-house TS physics** — sequential-impulse rigid bodies for PMX rigs with rest-stable implicit spring-dampers, zero dependencies; structure-of-arrays solver, a world floor so hair and hems rest on the ground instead of clipping through it, and per-frame load shedding that holds framerate on weak devices
|
|
18
|
+
- **In-house TS physics** — sequential-impulse rigid bodies for PMX rigs with rest-stable implicit spring-dampers, zero dependencies; structure-of-arrays solver, scene gravity and wind, a world floor so hair and hems rest on the ground instead of clipping through it, and per-frame load shedding that holds framerate on weak devices
|
|
19
19
|
- **Math library** — the shared Vec3/Quat/Mat4 layer of the Reze family: euler orders, swing-twist, shortest-arc, look-rotation, zero-alloc `*Into` variants
|
|
20
20
|
- **VMD animation** — MMD IK with per-chain enable read from the motion, morphs on a GPU compute path, and VMD export
|
|
21
21
|
- **Clip blending & locomotion** — weighted multi-clip pose blending, crossfades, and a game-style character controller (idle/run/sprint speed blend, authored stop skids, code-driven root motion) — the [demo](https://reze.one) is WASD-playable
|
|
@@ -90,7 +90,7 @@ engine/src/
|
|
|
90
90
|
physics.ts RezePhysics: bone↔body sync, fixed-step accumulator + interpolation
|
|
91
91
|
solver.ts sequential-impulse PGS (joint + contact rows)
|
|
92
92
|
contact.ts narrowphase (analytical sphere/box/capsule pairs) + contact pool
|
|
93
|
-
constraint.ts 6DOF spring joints · world.ts
|
|
93
|
+
constraint.ts 6DOF spring joints · world.ts step, gravity + wind
|
|
94
94
|
body.ts SoA rigid-body store · types.ts
|
|
95
95
|
|
|
96
96
|
shaders/
|
|
@@ -119,6 +119,8 @@ engine.setMaterialVisible(name, material, visible) / toggleMaterialVisible / isM
|
|
|
119
119
|
engine.setIKEnabled(enabled) // engine-wide OFF for hosts that pose bones themselves; ON hands per-chain state to the clip
|
|
120
120
|
engine.setPhysicsEnabled(enabled)
|
|
121
121
|
engine.resetPhysics() // re-pose bodies from animation + zero velocities (call if physics explodes)
|
|
122
|
+
engine.setGravity(vec3) / getGravity() // scene-wide; default (0, -98, 0) — MMD scale, where a character is ~18 units tall
|
|
123
|
+
engine.setWind({ direction, strength, turbulence?, frequency? } | null) / getWind() // scene-wide air; strength is in gravity's units, so 10-30 reads as a breeze through hair and skirt
|
|
122
124
|
|
|
123
125
|
engine.setCameraFollow(model, bone?, offset?) / setCameraFollow(null)
|
|
124
126
|
engine.setCameraTarget(vec3) / setCameraDistance(d) / setCameraAlpha(a) / setCameraBeta(b)
|
|
@@ -337,7 +339,9 @@ In-house sequential-impulse rigid-body solver for PMX rigs (sphere / box / capsu
|
|
|
337
339
|
- **Discontinuity guards** — a bone-pose jump beyond continuous motion (timeline scrub, long stall) rigidly carries each dynamic body along with its kinematic root's transform delta and zeroes momentum instead of dragging cloth across the gap; correction velocities are clamped (120 u/s linear, 30 rad/s angular), per-step travel is capped, and any body that still goes non-finite is restored to its previous substep pose.
|
|
338
340
|
- Sleeping is off (cloth must always react); resting bodies bleed micro-velocity via per-PMX damping.
|
|
339
341
|
|
|
340
|
-
|
|
342
|
+
- **Gravity and wind** are scene-wide and summed once per substep, so wind costs the per-body loop nothing. Wind is an acceleration rather than a drag model: PMX authors already tune per-body damping to get the hang they want, and a second hidden drag term would fight it. Gusting rides a pair of incommensurate sines — one alone is a metronome — and advances on *simulated* time, so an exported take gusts frame-for-frame as its preview did.
|
|
343
|
+
|
|
344
|
+
Engine surface is `setPhysicsEnabled` / `resetPhysics` / `setGravity` / `setWind` — everything else (mass, damping, friction, restitution, joint stiffness/limits, collision groups) lives on the PMX rig.
|
|
341
345
|
|
|
342
346
|
## Rendering
|
|
343
347
|
|
package/dist/engine.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Quat, Vec3 } from "./math";
|
|
2
2
|
import { Model } from "./model";
|
|
3
3
|
import { RezePhysics } from "./physics";
|
|
4
|
+
import type { WindOptions } from "./physics/world";
|
|
4
5
|
import { type AssetReader } from "./asset-reader";
|
|
5
6
|
import { type CompileOptions, type StyleSlot } from "./graph/compile";
|
|
6
7
|
import type { AlphaMode, RenderClass } from "./graph/render-class";
|
|
@@ -402,6 +403,8 @@ export declare class Engine {
|
|
|
402
403
|
private _nextDefaultModelId;
|
|
403
404
|
private ikEnabled;
|
|
404
405
|
private physicsEnabled;
|
|
406
|
+
private gravity;
|
|
407
|
+
private wind;
|
|
405
408
|
private useGpuMorphs;
|
|
406
409
|
private cameraAnimation;
|
|
407
410
|
private cameraTargetModel;
|
|
@@ -585,13 +588,6 @@ export declare class Engine {
|
|
|
585
588
|
}): void;
|
|
586
589
|
private updateLightBuffer;
|
|
587
590
|
getStats(): EngineStats;
|
|
588
|
-
/** Frame-rate cap for the render loop, or null for display-rate. On high-refresh
|
|
589
|
-
* displays (144/240Hz) rAF runs the WHOLE pipeline — physics, IK, blending,
|
|
590
|
-
* passes — that many times per second for no visible gain over ~120 (VMD content
|
|
591
|
-
* is 30fps; blending interpolates). Capping restores the per-second budget. */
|
|
592
|
-
private maxFPS;
|
|
593
|
-
private lastLoopTime;
|
|
594
|
-
setMaxFPS(fps: number | null): void;
|
|
595
591
|
runRenderLoop(callback?: () => void): void;
|
|
596
592
|
stopRenderLoop(): void;
|
|
597
593
|
dispose(): void;
|
|
@@ -630,6 +626,25 @@ export declare class Engine {
|
|
|
630
626
|
getIKEnabled(): boolean;
|
|
631
627
|
setPhysicsEnabled(enabled: boolean): void;
|
|
632
628
|
getPhysicsEnabled(): boolean;
|
|
629
|
+
/**
|
|
630
|
+
* Scene gravity, applied to every model's cloth and hair. The default is
|
|
631
|
+
* (0, -98, 0) — MMD's own scale, where a character stands about 20 units
|
|
632
|
+
* tall. Lower magnitudes float; tilting it sideways hangs everything on a
|
|
633
|
+
* slant, which is the cheap way to fake a strong draught.
|
|
634
|
+
*/
|
|
635
|
+
setGravity(gravity: Vec3): void;
|
|
636
|
+
getGravity(): Vec3;
|
|
637
|
+
/**
|
|
638
|
+
* Air movement across the scene — null is still air.
|
|
639
|
+
*
|
|
640
|
+
* Applied as an acceleration alongside gravity, so `strength` is in the same
|
|
641
|
+
* units: against the default gravity of 98, a strength of 10-30 reads as a
|
|
642
|
+
* breeze through hair and a skirt without lifting them off the body. Gusting
|
|
643
|
+
* is driven by simulated time rather than wall time, so an exported take
|
|
644
|
+
* gusts exactly as the preview did.
|
|
645
|
+
*/
|
|
646
|
+
setWind(wind: WindOptions | null): void;
|
|
647
|
+
getWind(): WindOptions | null;
|
|
633
648
|
resetPhysics(): void;
|
|
634
649
|
private forEachInstance;
|
|
635
650
|
private cpuAnimMs;
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -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":"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"}
|
package/dist/engine.js
CHANGED
|
@@ -325,6 +325,10 @@ export class Engine {
|
|
|
325
325
|
// IK and physics enabled at engine level (same for all models)
|
|
326
326
|
this.ikEnabled = true;
|
|
327
327
|
this.physicsEnabled = true;
|
|
328
|
+
// World-wide, not per-model: MMD treats gravity and wind as properties of the
|
|
329
|
+
// scene, and a model loaded later must arrive into the same air as the rest.
|
|
330
|
+
this.gravity = new Vec3(0, -98, 0);
|
|
331
|
+
this.wind = null;
|
|
328
332
|
// GPU vertex-morph path. Set false BEFORE loadModel to fall back to the CPU path (A/B).
|
|
329
333
|
this.useGpuMorphs = true;
|
|
330
334
|
// VMD camera track (a dedicated camera VMD). When loaded + enabled it drives the shot,
|
|
@@ -371,12 +375,6 @@ export class Engine {
|
|
|
371
375
|
/** When set, render resolution is pinned to this size instead of tracking the
|
|
372
376
|
* canvas's CSS size × devicePixelRatio (see setRenderSize). */
|
|
373
377
|
this.fixedRenderSize = null;
|
|
374
|
-
/** Frame-rate cap for the render loop, or null for display-rate. On high-refresh
|
|
375
|
-
* displays (144/240Hz) rAF runs the WHOLE pipeline — physics, IK, blending,
|
|
376
|
-
* passes — that many times per second for no visible gain over ~120 (VMD content
|
|
377
|
-
* is 30fps; blending interpolates). Capping restores the per-second budget. */
|
|
378
|
-
this.maxFPS = null;
|
|
379
|
-
this.lastLoopTime = 0;
|
|
380
378
|
// CPU frame-time breakdown (EMA-smoothed into getStats): where a frame's
|
|
381
379
|
// milliseconds actually go — animation/IK/blending vs physics vs everything
|
|
382
380
|
// else on the render thread. The first question of any perf report.
|
|
@@ -2562,20 +2560,18 @@ export class Engine {
|
|
|
2562
2560
|
getStats() {
|
|
2563
2561
|
return { ...this.stats };
|
|
2564
2562
|
}
|
|
2565
|
-
|
|
2566
|
-
|
|
2567
|
-
|
|
2563
|
+
// The render loop runs at display rate, always. A frame-rate cap used to be
|
|
2564
|
+
// offered here for high-refresh displays, on the reasoning that VMD content
|
|
2565
|
+
// is 30fps and running the whole pipeline at 240 buys nothing. Nothing ever
|
|
2566
|
+
// called it — every product in the family chases native refresh, because
|
|
2567
|
+
// dropping frames a display can show is the one thing that reads as cheap.
|
|
2568
|
+
// Physics already decouples: it steps at a fixed 60Hz behind an accumulator
|
|
2569
|
+
// and the drawn pose is interpolated between substeps, so a 240Hz display
|
|
2570
|
+
// costs four interpolations per simulation step, not four simulations.
|
|
2568
2571
|
runRenderLoop(callback) {
|
|
2569
2572
|
this.renderLoopCallback = callback || null;
|
|
2570
|
-
const loop = (
|
|
2573
|
+
const loop = () => {
|
|
2571
2574
|
this.animationFrameId = requestAnimationFrame(loop);
|
|
2572
|
-
if (this.maxFPS !== null) {
|
|
2573
|
-
// Tolerate rAF jitter: accept frames within ~half a display tick early.
|
|
2574
|
-
const minInterval = 1000 / this.maxFPS - 2;
|
|
2575
|
-
if (now - this.lastLoopTime < minInterval)
|
|
2576
|
-
return;
|
|
2577
|
-
this.lastLoopTime = now;
|
|
2578
|
-
}
|
|
2579
2575
|
this.render();
|
|
2580
2576
|
if (this.renderLoopCallback) {
|
|
2581
2577
|
this.renderLoopCallback();
|
|
@@ -2813,6 +2809,35 @@ export class Engine {
|
|
|
2813
2809
|
getPhysicsEnabled() {
|
|
2814
2810
|
return this.physicsEnabled;
|
|
2815
2811
|
}
|
|
2812
|
+
/**
|
|
2813
|
+
* Scene gravity, applied to every model's cloth and hair. The default is
|
|
2814
|
+
* (0, -98, 0) — MMD's own scale, where a character stands about 20 units
|
|
2815
|
+
* tall. Lower magnitudes float; tilting it sideways hangs everything on a
|
|
2816
|
+
* slant, which is the cheap way to fake a strong draught.
|
|
2817
|
+
*/
|
|
2818
|
+
setGravity(gravity) {
|
|
2819
|
+
this.gravity = new Vec3(gravity.x, gravity.y, gravity.z);
|
|
2820
|
+
this.forEachInstance((inst) => inst.physics?.setGravity(this.gravity));
|
|
2821
|
+
}
|
|
2822
|
+
getGravity() {
|
|
2823
|
+
return new Vec3(this.gravity.x, this.gravity.y, this.gravity.z);
|
|
2824
|
+
}
|
|
2825
|
+
/**
|
|
2826
|
+
* Air movement across the scene — null is still air.
|
|
2827
|
+
*
|
|
2828
|
+
* Applied as an acceleration alongside gravity, so `strength` is in the same
|
|
2829
|
+
* units: against the default gravity of 98, a strength of 10-30 reads as a
|
|
2830
|
+
* breeze through hair and a skirt without lifting them off the body. Gusting
|
|
2831
|
+
* is driven by simulated time rather than wall time, so an exported take
|
|
2832
|
+
* gusts exactly as the preview did.
|
|
2833
|
+
*/
|
|
2834
|
+
setWind(wind) {
|
|
2835
|
+
this.wind = wind ? { ...wind, direction: new Vec3(wind.direction.x, wind.direction.y, wind.direction.z) } : null;
|
|
2836
|
+
this.forEachInstance((inst) => inst.physics?.setWind(this.wind));
|
|
2837
|
+
}
|
|
2838
|
+
getWind() {
|
|
2839
|
+
return this.wind ? { ...this.wind, direction: new Vec3(this.wind.direction.x, this.wind.direction.y, this.wind.direction.z) } : null;
|
|
2840
|
+
}
|
|
2816
2841
|
resetPhysics() {
|
|
2817
2842
|
this.forEachInstance((inst) => {
|
|
2818
2843
|
if (!inst.physics)
|
|
@@ -2951,6 +2976,13 @@ export class Engine {
|
|
|
2951
2976
|
this.device.queue.writeBuffer(indexBuffer, 0, indices);
|
|
2952
2977
|
const rbs = model.getRigidbodies();
|
|
2953
2978
|
const physics = rbs.length > 0 ? new RezePhysics(rbs, model.getJoints()) : null;
|
|
2979
|
+
// Adopt the scene's air, or a model added mid-session would fall under
|
|
2980
|
+
// different gravity from the ones already on stage.
|
|
2981
|
+
if (physics) {
|
|
2982
|
+
physics.setGravity(this.gravity);
|
|
2983
|
+
if (this.wind)
|
|
2984
|
+
physics.setWind(this.wind);
|
|
2985
|
+
}
|
|
2954
2986
|
const shadowBindGroup = this.device.createBindGroup({
|
|
2955
2987
|
label: `${name}: shadow bind`,
|
|
2956
2988
|
layout: this.shadowDepthPipeline.getBindGroupLayout(0),
|
package/dist/index.d.ts
CHANGED
|
@@ -25,4 +25,5 @@ export { VMDWriter } from "./vmd-writer";
|
|
|
25
25
|
export { PmxLoader } from "./pmx-loader";
|
|
26
26
|
export { CameraAnimation, type CameraPose } from "./camera-animation";
|
|
27
27
|
export { RezePhysics } from "./physics";
|
|
28
|
+
export type { WindOptions } from "./physics/world";
|
|
28
29
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,MAAM,EACN,qBAAqB,EACrB,sBAAsB,EACtB,qBAAqB,EACrB,KAAK,mBAAmB,EACxB,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,cAAc,EACnB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAClB,KAAK,0BAA0B,EAC/B,KAAK,sBAAsB,GAC5B,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,KAAK,oBAAoB,EAAE,MAAM,iBAAiB,CAAA;AACvG,OAAO,EACL,YAAY,EACZ,aAAa,EACb,gBAAgB,EAChB,KAAK,cAAc,EACnB,KAAK,aAAa,EAClB,KAAK,SAAS,GACf,MAAM,iBAAiB,CAAA;AACxB,YAAY,EACV,WAAW,EACX,SAAS,EACT,SAAS,EACT,YAAY,EACZ,WAAW,EACX,UAAU,GACX,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,aAAa,EAAE,KAAK,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,kBAAkB,CAAA;AAC3E,OAAO,EAAE,cAAc,EAAE,KAAK,WAAW,EAAE,KAAK,SAAS,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC7G,YAAY,EACV,UAAU,EACV,eAAe,EACf,sBAAsB,EACtB,qBAAqB,GACtB,MAAM,qBAAqB,CAAA;AAC5B,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAA;AACvD,OAAO,EAAE,kBAAkB,EAAE,MAAM,8BAA8B,CAAA;AACjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAA;AAC/D,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAA;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAA;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAA;AACjD,OAAO,EAAE,KAAK,EAAE,KAAK,aAAa,EAAE,MAAM,SAAS,CAAA;AACnD,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,QAAQ,CAAA;AACrE,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,UAAU,EACV,aAAa,EACb,iBAAiB,EACjB,YAAY,GACb,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,oBAAoB,EACpB,KAAK,eAAe,EACpB,KAAK,iBAAiB,EACtB,KAAK,cAAc,EACnB,KAAK,eAAe,EACpB,KAAK,aAAa,EAClB,KAAK,gBAAgB,EACrB,KAAK,aAAa,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,qBAAqB,EAAE,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAE,KAAK,mBAAmB,EAAE,MAAM,iBAAiB,CAAA;AAC5H,OAAO,EACL,GAAG,EACH,iBAAiB,EACjB,wBAAwB,EACxB,mCAAmC,GACpC,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,SAAS,EAAE,KAAK,cAAc,EAAE,KAAK,OAAO,EAAE,MAAM,cAAc,CAAA;AAC3E,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAA;AACxC,OAAO,EAAE,eAAe,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAA;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,WAAW,CAAA;AACvC,YAAY,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { Vec3, Quat, Mat4 } from "../math";
|
|
2
2
|
import type { Rigidbody, Joint } from "./types";
|
|
3
3
|
import { RigidBodyStore } from "./body";
|
|
4
|
+
import { type WindOptions } from "./world";
|
|
4
5
|
export declare class RezePhysics {
|
|
5
6
|
private rigidbodies;
|
|
6
7
|
private joints;
|
|
@@ -32,6 +33,9 @@ export declare class RezePhysics {
|
|
|
32
33
|
private savePrevState;
|
|
33
34
|
setGravity(gravity: Vec3): void;
|
|
34
35
|
getGravity(): Vec3;
|
|
36
|
+
/** World-wide air movement. See {@link WindOptions}; null is still air. */
|
|
37
|
+
setWind(wind: WindOptions | null): void;
|
|
38
|
+
getWind(): WindOptions | null;
|
|
35
39
|
getRigidbodies(): Rigidbody[];
|
|
36
40
|
getJoints(): Joint[];
|
|
37
41
|
getStore(): RigidBodyStore;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"physics.d.ts","sourceRoot":"","sources":["../../src/physics/physics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;
|
|
1
|
+
{"version":3,"file":"physics.d.ts","sourceRoot":"","sources":["../../src/physics/physics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC1C,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,SAAS,CAAA;AAE/C,OAAO,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AACvC,OAAO,EAAS,KAAK,WAAW,EAAE,MAAM,SAAS,CAAA;AAYjD,qBAAa,WAAW;IACtB,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,KAAK,CAAO;IACpB,OAAO,CAAC,WAAW,CAA0B;IAC7C,OAAO,CAAC,WAAW,CAAa;IAChC,OAAO,CAAC,QAAQ,CAAa;IAC7B,OAAO,CAAC,UAAU,CAAO;IACzB,OAAO,CAAC,SAAS,CAAI;IACrB,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAS;IACvC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAI;IAChC,uEAAuE;IACvE,OAAO,CAAC,aAAa,CAAM;IAC3B,2EAA2E;IAC3E,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAI;IAMjC,OAAO,CAAC,aAAa,CAAc;IACnC,OAAO,CAAC,gBAAgB,CAAc;IAQtC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,eAAe,CAAc;IAMrC,OAAO,CAAC,OAAO,CAAY;IAE3B,OAAO,CAAC,aAAa,CAAY;IAMjC,OAAO,CAAC,WAAW,CAAY;IAG/B,aAAa,SAAI;gBAEL,WAAW,EAAE,SAAS,EAAE,EAAE,MAAM,GAAE,KAAK,EAAO;IA6D1D,OAAO,CAAC,mBAAmB;IA4B3B,OAAO,CAAC,aAAa;IAKrB,UAAU,CAAC,OAAO,EAAE,IAAI,GAAG,IAAI;IAG/B,UAAU,IAAI,IAAI;IAGlB,2EAA2E;IAC3E,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI;IAGvC,OAAO,IAAI,WAAW,GAAG,IAAI;IAG7B,cAAc,IAAI,SAAS,EAAE;IAG7B,SAAS,IAAI,KAAK,EAAE;IAGpB,QAAQ,IAAI,cAAc;IAI1B,sBAAsB,IAAI,KAAK,CAAC;QAAE,QAAQ,EAAE,IAAI,CAAC;QAAC,QAAQ,EAAE,IAAI,CAAA;KAAE,CAAC;IAiBnE,KAAK,CAAC,iBAAiB,EAAE,IAAI,EAAE,GAAG,IAAI;IActC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,EAAE,EAAE,uBAAuB,EAAE,YAAY,GAAG,IAAI;IA6ExF,OAAO,CAAC,iBAAiB;IAuCzB,OAAO,CAAC,uBAAuB;IAqF/B,OAAO,CAAC,yBAAyB;IAgEjC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,OAAO,CAAC,sBAAsB;IA0C9B,OAAO,CAAC,2BAA2B;IA6EnC,OAAO,CAAC,wBAAwB;IA2BhC,OAAO,CAAC,sBAAsB;IAqC9B,OAAO,CAAC,oBAAoB;CA6D7B"}
|
package/dist/physics/physics.js
CHANGED
|
@@ -122,6 +122,13 @@ export class RezePhysics {
|
|
|
122
122
|
getGravity() {
|
|
123
123
|
return this.world.gravity;
|
|
124
124
|
}
|
|
125
|
+
/** World-wide air movement. See {@link WindOptions}; null is still air. */
|
|
126
|
+
setWind(wind) {
|
|
127
|
+
this.world.setWind(wind);
|
|
128
|
+
}
|
|
129
|
+
getWind() {
|
|
130
|
+
return this.world.getWind();
|
|
131
|
+
}
|
|
125
132
|
getRigidbodies() {
|
|
126
133
|
return this.rigidbodies;
|
|
127
134
|
}
|
package/dist/physics/world.d.ts
CHANGED
|
@@ -3,14 +3,47 @@ import type { RigidBodyStore } from "./body";
|
|
|
3
3
|
import type { SixDofSpringConstraint } from "./constraint";
|
|
4
4
|
import { type SolverCache } from "./solver";
|
|
5
5
|
import { type ContactPool } from "./contact";
|
|
6
|
+
/**
|
|
7
|
+
* Air movement across the whole world.
|
|
8
|
+
*
|
|
9
|
+
* Applied as an acceleration alongside gravity, which is the same shape MMD's
|
|
10
|
+
* own wind plugins take and keeps it free: gravity and wind are summed once per
|
|
11
|
+
* substep, so the per-body predict loop is untouched. Terminal velocity comes
|
|
12
|
+
* out of the existing per-body damping rather than a drag model — PMX authors
|
|
13
|
+
* already tune that damping to get the hang they want, and a second, hidden
|
|
14
|
+
* drag term would fight it.
|
|
15
|
+
*/
|
|
16
|
+
export interface WindOptions {
|
|
17
|
+
/** Direction the air travels. Normalised on assignment; a zero vector is off. */
|
|
18
|
+
direction: Vec3;
|
|
19
|
+
/** Acceleration along it, in gravity's units — the built-in gravity is 98. */
|
|
20
|
+
strength: number;
|
|
21
|
+
/** Gust depth, clamped to 0–1. 0 is a steady breeze; 1 swings between still
|
|
22
|
+
* and double. It is a clamp rather than a free scalar because past 1 the
|
|
23
|
+
* swing goes negative and the wind blows backwards on every other beat,
|
|
24
|
+
* which is never what a caller meant by "more turbulent". */
|
|
25
|
+
turbulence?: number;
|
|
26
|
+
/** Gusts per second. */
|
|
27
|
+
frequency?: number;
|
|
28
|
+
}
|
|
6
29
|
export declare class World {
|
|
7
30
|
readonly gravity: Vec3;
|
|
8
31
|
solverIterations: number;
|
|
9
32
|
private dampCacheDt;
|
|
10
33
|
private linDampFactor;
|
|
11
34
|
private angDampFactor;
|
|
35
|
+
private windX;
|
|
36
|
+
private windY;
|
|
37
|
+
private windZ;
|
|
38
|
+
private windTurbulence;
|
|
39
|
+
private windFrequency;
|
|
40
|
+
/** Advances with simulated time, not wall time, so a scrubbed or exported
|
|
41
|
+
* take gusts identically to a live one. */
|
|
42
|
+
private windClock;
|
|
12
43
|
constructor(gravity: Vec3);
|
|
13
44
|
setGravity(g: Vec3): void;
|
|
45
|
+
setWind(wind: WindOptions | null): void;
|
|
46
|
+
getWind(): WindOptions | null;
|
|
14
47
|
step(store: RigidBodyStore, constraints: SixDofSpringConstraint[], cache: SolverCache, contacts: ContactPool, dt: number): void;
|
|
15
48
|
}
|
|
16
49
|
//# sourceMappingURL=world.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../../src/physics/world.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAE5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAO1D,qBAAa,KAAK;IAChB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,gBAAgB,SAAK;IAIrB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,aAAa,CAA4B;
|
|
1
|
+
{"version":3,"file":"world.d.ts","sourceRoot":"","sources":["../../src/physics/world.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAA;AAC9B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAE5C,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAoB,KAAK,WAAW,EAAE,MAAM,UAAU,CAAA;AAC7D,OAAO,EAAgB,KAAK,WAAW,EAAE,MAAM,WAAW,CAAA;AAO1D;;;;;;;;;GASG;AACH,MAAM,WAAW,WAAW;IAC1B,iFAAiF;IACjF,SAAS,EAAE,IAAI,CAAA;IACf,8EAA8E;IAC9E,QAAQ,EAAE,MAAM,CAAA;IAChB;;;kEAG8D;IAC9D,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,wBAAwB;IACxB,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,KAAK;IAChB,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;IACtB,gBAAgB,SAAK;IAIrB,OAAO,CAAC,WAAW,CAAK;IACxB,OAAO,CAAC,aAAa,CAA4B;IACjD,OAAO,CAAC,aAAa,CAA4B;IAIjD,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,cAAc,CAAI;IAC1B,OAAO,CAAC,aAAa,CAAO;IAC5B;gDAC4C;IAC5C,OAAO,CAAC,SAAS,CAAI;gBAET,OAAO,EAAE,IAAI;IAIzB,UAAU,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI;IAMzB,OAAO,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,GAAG,IAAI;IAoBvC,OAAO,IAAI,WAAW,GAAG,IAAI;IAW7B,IAAI,CACF,KAAK,EAAE,cAAc,EACrB,WAAW,EAAE,sBAAsB,EAAE,EACrC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,WAAW,EACrB,EAAE,EAAE,MAAM,GACT,IAAI;CA0KR"}
|
package/dist/physics/world.js
CHANGED
|
@@ -2,11 +2,6 @@ import { Vec3 } from "../math";
|
|
|
2
2
|
import { RigidbodyType } from "./types";
|
|
3
3
|
import { solveConstraints } from "./solver";
|
|
4
4
|
import { findContacts } from "./contact";
|
|
5
|
-
// World step: predict velocities → collide → solve → position correction →
|
|
6
|
-
// integrate. Static and kinematic bodies are skipped during predict and
|
|
7
|
-
// integrate; the parent class syncs them from bones around the step. The
|
|
8
|
-
// solver pass runs on all bodies — kinematic ones have invMass = 0 and
|
|
9
|
-
// act as anchors.
|
|
10
5
|
export class World {
|
|
11
6
|
constructor(gravity) {
|
|
12
7
|
this.solverIterations = 10;
|
|
@@ -15,6 +10,16 @@ export class World {
|
|
|
15
10
|
this.dampCacheDt = -1;
|
|
16
11
|
this.linDampFactor = null;
|
|
17
12
|
this.angDampFactor = null;
|
|
13
|
+
// Wind, resolved to a direction × strength at construction of the options so
|
|
14
|
+
// the step loop only multiplies by a gust scalar.
|
|
15
|
+
this.windX = 0;
|
|
16
|
+
this.windY = 0;
|
|
17
|
+
this.windZ = 0;
|
|
18
|
+
this.windTurbulence = 0;
|
|
19
|
+
this.windFrequency = 0.35;
|
|
20
|
+
/** Advances with simulated time, not wall time, so a scrubbed or exported
|
|
21
|
+
* take gusts identically to a live one. */
|
|
22
|
+
this.windClock = 0;
|
|
18
23
|
this.gravity = new Vec3(gravity.x, gravity.y, gravity.z);
|
|
19
24
|
}
|
|
20
25
|
setGravity(g) {
|
|
@@ -22,6 +27,35 @@ export class World {
|
|
|
22
27
|
this.gravity.y = g.y;
|
|
23
28
|
this.gravity.z = g.z;
|
|
24
29
|
}
|
|
30
|
+
setWind(wind) {
|
|
31
|
+
// Shape first, and unconditionally: bailing out early on a zero strength
|
|
32
|
+
// used to leave turbulence and frequency holding whatever a previous call
|
|
33
|
+
// set, so raising the strength again resurrected settings the caller had
|
|
34
|
+
// since replaced.
|
|
35
|
+
this.windTurbulence = Math.min(1, Math.max(0, wind?.turbulence ?? 0));
|
|
36
|
+
this.windFrequency = Math.max(0, wind?.frequency ?? 0.35);
|
|
37
|
+
const d = wind?.direction;
|
|
38
|
+
const len = d ? Math.hypot(d.x, d.y, d.z) : 0;
|
|
39
|
+
if (!wind || !d || len < 1e-9 || wind.strength === 0) {
|
|
40
|
+
this.windX = this.windY = this.windZ = 0;
|
|
41
|
+
return;
|
|
42
|
+
}
|
|
43
|
+
const s = wind.strength / len;
|
|
44
|
+
this.windX = d.x * s;
|
|
45
|
+
this.windY = d.y * s;
|
|
46
|
+
this.windZ = d.z * s;
|
|
47
|
+
}
|
|
48
|
+
getWind() {
|
|
49
|
+
const strength = Math.hypot(this.windX, this.windY, this.windZ);
|
|
50
|
+
if (strength === 0)
|
|
51
|
+
return null;
|
|
52
|
+
return {
|
|
53
|
+
direction: new Vec3(this.windX / strength, this.windY / strength, this.windZ / strength),
|
|
54
|
+
strength,
|
|
55
|
+
turbulence: this.windTurbulence,
|
|
56
|
+
frequency: this.windFrequency,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
25
59
|
step(store, constraints, cache, contacts, dt) {
|
|
26
60
|
if (dt <= 0)
|
|
27
61
|
return;
|
|
@@ -34,9 +68,24 @@ export class World {
|
|
|
34
68
|
const ldamp = store.linearDamping;
|
|
35
69
|
const adamp = store.angularDamping;
|
|
36
70
|
const invMass = store.invMass;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
71
|
+
// Gravity and wind are the same kind of term, so they are summed here and
|
|
72
|
+
// the predict loop below never learns wind exists.
|
|
73
|
+
let gx = this.gravity.x;
|
|
74
|
+
let gy = this.gravity.y;
|
|
75
|
+
let gz = this.gravity.z;
|
|
76
|
+
if (this.windX !== 0 || this.windY !== 0 || this.windZ !== 0) {
|
|
77
|
+
this.windClock += dt;
|
|
78
|
+
let gust = 1;
|
|
79
|
+
if (this.windTurbulence > 0 && this.windFrequency > 0) {
|
|
80
|
+
// Two incommensurate sines: a single one is a metronome, and real gusts
|
|
81
|
+
// do not repeat on a bar line. Stays within 1 ± turbulence.
|
|
82
|
+
const t = this.windClock * this.windFrequency * Math.PI * 2;
|
|
83
|
+
gust = 1 + this.windTurbulence * 0.5 * (Math.sin(t) + Math.sin(t * 0.37 + 1.3));
|
|
84
|
+
}
|
|
85
|
+
gx += this.windX * gust;
|
|
86
|
+
gy += this.windY * gust;
|
|
87
|
+
gz += this.windZ * gust;
|
|
88
|
+
}
|
|
40
89
|
// 1. Predict — gravity + damping. The pow form (vs the linear
|
|
41
90
|
// 1−damping·dt approximation) stays stable at high PMX damping
|
|
42
91
|
// values like 0.99. Factors are cached (damping and dt are constant).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The tile as 8-bit luminance, plus its mip chain (box-filtered, which is exact
|
|
3
|
+
* for a repeating texture). Mips are the point as much as the speed: procedural
|
|
4
|
+
* noise has no mip chain, so at grazing angles it shimmered.
|
|
5
|
+
*/
|
|
6
|
+
export declare function buildGroundNoiseMips(): Uint8Array[];
|
|
7
|
+
//# sourceMappingURL=ground-noise.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ground-noise.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/ground-noise.ts"],"names":[],"mappings":"AAkDA;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,UAAU,EAAE,CAsCnD"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Bakes the ground's frosted micro-texture into a seamless, mipmapped tile.
|
|
2
|
+
//
|
|
3
|
+
// The shader used to evaluate four octaves of value noise per pixel — sixteen
|
|
4
|
+
// hash rounds — and the ground covers the entire screen as soon as the camera
|
|
5
|
+
// tilts toward the horizon. This produces the same character of pattern once, at
|
|
6
|
+
// load, so the fragment shader pays one filtered fetch instead.
|
|
7
|
+
//
|
|
8
|
+
// SEAMLESS BY CONSTRUCTION. The original hash was not periodic, so a finite
|
|
9
|
+
// crop of it could never tile. Here every octave's lattice wraps at a whole
|
|
10
|
+
// number of cells across the tile, which makes the result repeat exactly at the
|
|
11
|
+
// edges. The pattern is therefore not pixel-identical to the analytic version —
|
|
12
|
+
// it is the same kind of noise, not the same noise. At the default strength of
|
|
13
|
+
// 0.05 it modulates brightness by ±2.5%, where the repeat is not findable by eye.
|
|
14
|
+
import { GROUND_NOISE_RES, GROUND_NOISE_TILE_WORLD } from "./ground";
|
|
15
|
+
/** Lattice cells across the tile at octave 0. The analytic version sampled fbm
|
|
16
|
+
* at worldXZ × 3, so a tile spanning 8 world units covers 24 base cells — the
|
|
17
|
+
* same spatial frequency the surface had before. */
|
|
18
|
+
const BASE_CELLS = GROUND_NOISE_TILE_WORLD * 3;
|
|
19
|
+
const OCTAVES = 4;
|
|
20
|
+
/** Deterministic lattice hash. Integer coordinates are wrapped by the caller,
|
|
21
|
+
* which is what makes the tile seamless. */
|
|
22
|
+
function hash(ix, iy) {
|
|
23
|
+
let h = Math.imul(ix, 374761393) + Math.imul(iy, 668265263);
|
|
24
|
+
h = Math.imul(h ^ (h >>> 13), 1274126177);
|
|
25
|
+
return ((h ^ (h >>> 16)) >>> 0) / 4294967296;
|
|
26
|
+
}
|
|
27
|
+
/** Value noise on a lattice that repeats every `period` cells. */
|
|
28
|
+
function periodicValueNoise(x, y, period) {
|
|
29
|
+
const ix = Math.floor(x);
|
|
30
|
+
const iy = Math.floor(y);
|
|
31
|
+
const fx = x - ix;
|
|
32
|
+
const fy = y - iy;
|
|
33
|
+
// Smoothstep weights — same curve the WGSL used.
|
|
34
|
+
const ux = fx * fx * (3 - 2 * fx);
|
|
35
|
+
const uy = fy * fy * (3 - 2 * fy);
|
|
36
|
+
const x0 = ((ix % period) + period) % period;
|
|
37
|
+
const y0 = ((iy % period) + period) % period;
|
|
38
|
+
const x1 = (x0 + 1) % period;
|
|
39
|
+
const y1 = (y0 + 1) % period;
|
|
40
|
+
const a = hash(x0, y0);
|
|
41
|
+
const b = hash(x1, y0);
|
|
42
|
+
const c = hash(x0, y1);
|
|
43
|
+
const d = hash(x1, y1);
|
|
44
|
+
return (a + (b - a) * ux) * (1 - uy) + (c + (d - c) * ux) * uy;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The tile as 8-bit luminance, plus its mip chain (box-filtered, which is exact
|
|
48
|
+
* for a repeating texture). Mips are the point as much as the speed: procedural
|
|
49
|
+
* noise has no mip chain, so at grazing angles it shimmered.
|
|
50
|
+
*/
|
|
51
|
+
export function buildGroundNoiseMips() {
|
|
52
|
+
const levels = [];
|
|
53
|
+
const res = GROUND_NOISE_RES;
|
|
54
|
+
const base = new Uint8Array(res * res);
|
|
55
|
+
for (let py = 0; py < res; py++) {
|
|
56
|
+
for (let px = 0; px < res; px++) {
|
|
57
|
+
// Texel centre, in units of octave-0 lattice cells.
|
|
58
|
+
const x = ((px + 0.5) / res) * BASE_CELLS;
|
|
59
|
+
const y = ((py + 0.5) / res) * BASE_CELLS;
|
|
60
|
+
let v = 0;
|
|
61
|
+
let amp = 0.5;
|
|
62
|
+
let freq = 1;
|
|
63
|
+
for (let o = 0; o < OCTAVES; o++) {
|
|
64
|
+
v += amp * periodicValueNoise(x * freq, y * freq, BASE_CELLS * freq);
|
|
65
|
+
freq *= 2;
|
|
66
|
+
amp *= 0.5;
|
|
67
|
+
}
|
|
68
|
+
base[py * res + px] = Math.max(0, Math.min(255, Math.round(v * 255)));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
levels.push(base);
|
|
72
|
+
let src = base;
|
|
73
|
+
let size = res;
|
|
74
|
+
while (size > 1) {
|
|
75
|
+
const half = size >> 1;
|
|
76
|
+
const dst = new Uint8Array(half * half);
|
|
77
|
+
for (let y = 0; y < half; y++) {
|
|
78
|
+
for (let x = 0; x < half; x++) {
|
|
79
|
+
const s = y * 2 * size + x * 2;
|
|
80
|
+
dst[y * half + x] = (src[s] + src[s + 1] + src[s + size] + src[s + size + 1] + 2) >> 2;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
levels.push(dst);
|
|
84
|
+
src = dst;
|
|
85
|
+
size = half;
|
|
86
|
+
}
|
|
87
|
+
return levels;
|
|
88
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export declare const GROUND_SHADOW_SHADER_WGSL = "\nstruct CameraUniforms { view: mat4x4f, projection: mat4x4f, viewPos: vec3f, _p: f32, };\nstruct Light { direction: vec4f, color: vec4f, };\nstruct LightUniforms { ambientColor: vec4f, lights: array<Light, 4>, };\nstruct GroundShadowMat {\n diffuseColor: vec3f, fadeStart: f32,\n fadeEnd: f32, shadowStrength: f32, pcfTexel: f32, gridSpacing: f32,\n gridLineWidth: f32, gridLineOpacity: f32, noiseStrength: f32, opacity: f32,\n gridLineColor: vec3f, _pad2: f32,\n};\nstruct LightVP { viewProj: mat4x4f, };\n@group(0) @binding(0) var<uniform> camera: CameraUniforms;\n@group(0) @binding(1) var<uniform> light: LightUniforms;\n@group(0) @binding(2) var shadowMap: texture_depth_2d;\n@group(0) @binding(3) var shadowSampler: sampler_comparison;\n@group(0) @binding(4) var<uniform> material: GroundShadowMat;\n@group(0) @binding(5) var<uniform> lightVP: LightVP;\n\nfn hash2(p: vec2f) -> f32 {\n var p3 = fract(vec3f(p.x, p.y, p.x) * 0.1031);\n p3 += dot(p3, vec3f(p3.y + 33.33, p3.z + 33.33, p3.x + 33.33));\n return fract((p3.x + p3.y) * p3.z);\n}\nfn valueNoise(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(mix(hash2(i), hash2(i + vec2f(1.0, 0.0)), u.x),\n mix(hash2(i + vec2f(0.0, 1.0)), hash2(i + vec2f(1.0, 1.0)), u.x), u.y);\n}\nfn fbmNoise(p: vec2f) -> f32 {\n var v = 0.0;\n var a = 0.5;\n var pp = p;\n for (var i = 0; i < 4; i++) {\n v += a * valueNoise(pp);\n pp *= 2.0;\n a *= 0.5;\n }\n return v;\n}\n\nstruct VO { @builtin(position) position: vec4f, @location(0) worldPos: vec3f, @location(1) normal: vec3f, };\n@vertex fn vs(@location(0) position: vec3f, @location(1) normal: vec3f, @location(2) uv: vec2f) -> VO {\n var o: VO; o.worldPos = position; o.normal = normal;\n o.position = camera.projection * camera.view * vec4f(position, 1.0); return o;\n}\nstruct FSOut { @location(0) color: vec4f, @location(1) mask: vec4f };\n@fragment fn fs(i: VO) -> FSOut {\n let n = normalize(i.normal);\n let centerDist = length(i.worldPos.xz);\n let edgeFade = 1.0 - smoothstep(0.0, 1.0, clamp((centerDist - material.fadeStart) / max(material.fadeEnd - material.fadeStart, 0.001), 0.0, 1.0));\n\n
|
|
1
|
+
export declare const GROUND_SHADOW_SHADER_WGSL = "\nstruct CameraUniforms { view: mat4x4f, projection: mat4x4f, viewPos: vec3f, _p: f32, };\nstruct Light { direction: vec4f, color: vec4f, };\nstruct LightUniforms { ambientColor: vec4f, lights: array<Light, 4>, };\nstruct GroundShadowMat {\n diffuseColor: vec3f, fadeStart: f32,\n fadeEnd: f32, shadowStrength: f32, pcfTexel: f32, gridSpacing: f32,\n gridLineWidth: f32, gridLineOpacity: f32, noiseStrength: f32, opacity: f32,\n gridLineColor: vec3f, _pad2: f32,\n};\nstruct LightVP { viewProj: mat4x4f, };\n@group(0) @binding(0) var<uniform> camera: CameraUniforms;\n@group(0) @binding(1) var<uniform> light: LightUniforms;\n@group(0) @binding(2) var shadowMap: texture_depth_2d;\n@group(0) @binding(3) var shadowSampler: sampler_comparison;\n@group(0) @binding(4) var<uniform> material: GroundShadowMat;\n@group(0) @binding(5) var<uniform> lightVP: LightVP;\n\nfn hash2(p: vec2f) -> f32 {\n var p3 = fract(vec3f(p.x, p.y, p.x) * 0.1031);\n p3 += dot(p3, vec3f(p3.y + 33.33, p3.z + 33.33, p3.x + 33.33));\n return fract((p3.x + p3.y) * p3.z);\n}\nfn valueNoise(p: vec2f) -> f32 {\n let i = floor(p);\n let f = fract(p);\n let u = f * f * (3.0 - 2.0 * f);\n return mix(mix(hash2(i), hash2(i + vec2f(1.0, 0.0)), u.x),\n mix(hash2(i + vec2f(0.0, 1.0)), hash2(i + vec2f(1.0, 1.0)), u.x), u.y);\n}\nfn fbmNoise(p: vec2f) -> f32 {\n var v = 0.0;\n var a = 0.5;\n var pp = p;\n for (var i = 0; i < 4; i++) {\n v += a * valueNoise(pp);\n pp *= 2.0;\n a *= 0.5;\n }\n return v;\n}\n\nstruct VO { @builtin(position) position: vec4f, @location(0) worldPos: vec3f, @location(1) normal: vec3f, };\n@vertex fn vs(@location(0) position: vec3f, @location(1) normal: vec3f, @location(2) uv: vec2f) -> VO {\n var o: VO; o.worldPos = position; o.normal = normal;\n o.position = camera.projection * camera.view * vec4f(position, 1.0); return o;\n}\nstruct FSOut { @location(0) color: vec4f, @location(1) mask: vec4f };\n@fragment fn fs(i: VO) -> FSOut {\n // Derivatives first, unconditionally: WGSL requires fwidth in uniform control\n // flow and everything below branches on world position.\n let gp = i.worldPos.xz / material.gridSpacing;\n let gridDeriv = fwidth(gp);\n\n var out: FSOut;\n let n = normalize(i.normal);\n let centerDist = length(i.worldPos.xz);\n let edgeFade = 1.0 - smoothstep(0.0, 1.0, clamp((centerDist - material.fadeStart) / max(material.fadeEnd - material.fadeStart, 0.001), 0.0, 1.0));\n\n // Past the radial fade every term below is multiplied by edgeFade and the\n // pixel is fully transparent. Shading it anyway produces nothing.\n if (edgeFade <= 0.0) {\n out.color = vec4f(0.0);\n out.mask = vec4f(0.0, 1.0, 0.0, 0.0);\n return out;\n }\n\n let lclip = lightVP.viewProj * vec4f(i.worldPos, 1.0);\n let ndc = lclip.xyz / max(lclip.w, 1e-6);\n // Outside the light's frustum there IS no shadow information \u2014 the clamped\n // border samples compare against unrelated depths and read \"shadowed\",\n // darkening the whole far plane with a visible band at the frustum edge\n // (masked by the opaque surface normally, glaring in green-screen mode where\n // only the shadow-catcher term renders). Fade to fully lit near the border.\n let inZ = select(0.0, 1.0, ndc.z > 0.0 && ndc.z < 1.0);\n let frustum = (1.0 - smoothstep(0.88, 0.96, abs(ndc.x))) * (1.0 - smoothstep(0.88, 0.96, abs(ndc.y))) * inZ;\n\n // THE cost of this shader, measured: a full-screen ground ran 25 shadow\n // comparisons per pixel, and each one is hardware-bilinear, so ~100 depth\n // samples per pixel. Gutting the rest of the shader changed nothing; cutting\n // this is what makes looking down cheap.\n //\n // 3x3 at two-texel spacing covers the same +/-2 texel penumbra the 5x5 at\n // one-texel spacing did \u2014 that kernel was oversampled, its taps overlapping\n // almost entirely once the comparison sampler's own 2x2 filter is counted.\n // Nine taps instead of twenty-five for the same blur radius.\n //\n // Skipped altogether outside the light frustum, where the mix below discards\n // the result anyway: the shadow map covers a small area around the character\n // and the ground is vastly larger than it.\n var vis = 1.0;\n if (frustum > 0.0) {\n let suv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);\n let suv_c = clamp(suv, vec2f(0.02), vec2f(0.98));\n let st = material.pcfTexel * 2.0;\n let compareZ = ndc.z - 0.0035;\n var acc = 0.0;\n for (var y = -1; y <= 1; y++) {\n for (var x = -1; x <= 1; x++) {\n // ...Level, not the implicit-derivative form: identical on a single-mip\n // shadow map, and legal inside this branch.\n acc += textureSampleCompareLevel(shadowMap, shadowSampler, suv_c + vec2f(f32(x), f32(y)) * st, compareZ);\n }\n }\n vis = mix(1.0, acc * (1.0 / 9.0), frustum);\n }\n\n // Frosted/matte micro-texture. Scenes leaving it at zero were still paying\n // sixteen hash rounds a pixel for a tint of exactly 1.\n var noiseTint = 1.0;\n if (material.noiseStrength != 0.0) {\n let noiseVal = fbmNoise(i.worldPos.xz * 3.0);\n noiseTint = 1.0 + (noiseVal - 0.5) * material.noiseStrength;\n }\n\n // Grid lines \u2014 anti-aliased via screen-space derivatives\n let gridFrac = abs(fract(gp - 0.5) - 0.5);\n let halfLine = material.gridLineWidth * 0.5;\n let gridLine = 1.0 - min(\n smoothstep(halfLine - gridDeriv.x, halfLine + gridDeriv.x, gridFrac.x),\n smoothstep(halfLine - gridDeriv.y, halfLine + gridDeriv.y, gridFrac.y)\n );\n let sun = light.ambientColor.xyz + light.lights[0].color.xyz * light.lights[0].color.w * max(dot(n, -light.lights[0].direction.xyz), 0.0);\n let dark = (1.0 - vis) * material.shadowStrength;\n var baseColor = material.diffuseColor * sun * (1.0 - dark * 0.65);\n baseColor *= noiseTint;\n let finalColor = mix(baseColor, material.gridLineColor, gridLine * material.gridLineOpacity * edgeFade);\n // Whole-ground opacity fades the SURFACE (color, grid) but the shadow stays \u2014\n // as opacity drops, the received shadow becomes a translucent dark layer\n // (Blender's Shadow Catcher), so models still feel grounded on a photo or\n // 360 backdrop. At opacity 1 this reduces exactly to the plain surface.\n let surfA = edgeFade * material.opacity;\n let catchA = dark * 0.65 * edgeFade * (1.0 - material.opacity);\n let outA = surfA + catchA;\n out.color = vec4f(finalColor * surfA, outA);\n // mask.r = 0: ground never contributes to bloom. mask.g = 1.0 with src.a =\n // outA turns the aux blend into alpha-over, so the drawable alpha goes\n // from outA at the center to 0 at the radial edge \u2014 letting the page\n // background show through under the premultiplied canvas alphaMode.\n out.mask = vec4f(0.0, 1.0, 0.0, outA);\n return out;\n}\n";
|
|
2
2
|
//# sourceMappingURL=ground.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ground.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/ground.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"ground.d.ts","sourceRoot":"","sources":["../../../src/shaders/passes/ground.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,yBAAyB,gpNA8IrC,CAAA"}
|
|
@@ -49,40 +49,74 @@ struct VO { @builtin(position) position: vec4f, @location(0) worldPos: vec3f, @l
|
|
|
49
49
|
}
|
|
50
50
|
struct FSOut { @location(0) color: vec4f, @location(1) mask: vec4f };
|
|
51
51
|
@fragment fn fs(i: VO) -> FSOut {
|
|
52
|
+
// Derivatives first, unconditionally: WGSL requires fwidth in uniform control
|
|
53
|
+
// flow and everything below branches on world position.
|
|
54
|
+
let gp = i.worldPos.xz / material.gridSpacing;
|
|
55
|
+
let gridDeriv = fwidth(gp);
|
|
56
|
+
|
|
57
|
+
var out: FSOut;
|
|
52
58
|
let n = normalize(i.normal);
|
|
53
59
|
let centerDist = length(i.worldPos.xz);
|
|
54
60
|
let edgeFade = 1.0 - smoothstep(0.0, 1.0, clamp((centerDist - material.fadeStart) / max(material.fadeEnd - material.fadeStart, 0.001), 0.0, 1.0));
|
|
55
61
|
|
|
62
|
+
// Past the radial fade every term below is multiplied by edgeFade and the
|
|
63
|
+
// pixel is fully transparent. Shading it anyway produces nothing.
|
|
64
|
+
if (edgeFade <= 0.0) {
|
|
65
|
+
out.color = vec4f(0.0);
|
|
66
|
+
out.mask = vec4f(0.0, 1.0, 0.0, 0.0);
|
|
67
|
+
return out;
|
|
68
|
+
}
|
|
69
|
+
|
|
56
70
|
let lclip = lightVP.viewProj * vec4f(i.worldPos, 1.0);
|
|
57
71
|
let ndc = lclip.xyz / max(lclip.w, 1e-6);
|
|
58
|
-
let suv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
|
59
|
-
let suv_c = clamp(suv, vec2f(0.02), vec2f(0.98));
|
|
60
|
-
let st = material.pcfTexel;
|
|
61
|
-
let compareZ = ndc.z - 0.0035;
|
|
62
|
-
var vis = 0.0;
|
|
63
|
-
for (var y = -2; y <= 2; y++) {
|
|
64
|
-
for (var x = -2; x <= 2; x++) {
|
|
65
|
-
vis += textureSampleCompare(shadowMap, shadowSampler, suv_c + vec2f(f32(x), f32(y)) * st, compareZ);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
vis *= 0.04;
|
|
69
72
|
// Outside the light's frustum there IS no shadow information — the clamped
|
|
70
|
-
// border samples
|
|
73
|
+
// border samples compare against unrelated depths and read "shadowed",
|
|
71
74
|
// darkening the whole far plane with a visible band at the frustum edge
|
|
72
75
|
// (masked by the opaque surface normally, glaring in green-screen mode where
|
|
73
76
|
// only the shadow-catcher term renders). Fade to fully lit near the border.
|
|
74
77
|
let inZ = select(0.0, 1.0, ndc.z > 0.0 && ndc.z < 1.0);
|
|
75
78
|
let frustum = (1.0 - smoothstep(0.88, 0.96, abs(ndc.x))) * (1.0 - smoothstep(0.88, 0.96, abs(ndc.y))) * inZ;
|
|
76
|
-
vis = mix(1.0, vis, frustum);
|
|
77
79
|
|
|
78
|
-
//
|
|
79
|
-
|
|
80
|
-
|
|
80
|
+
// THE cost of this shader, measured: a full-screen ground ran 25 shadow
|
|
81
|
+
// comparisons per pixel, and each one is hardware-bilinear, so ~100 depth
|
|
82
|
+
// samples per pixel. Gutting the rest of the shader changed nothing; cutting
|
|
83
|
+
// this is what makes looking down cheap.
|
|
84
|
+
//
|
|
85
|
+
// 3x3 at two-texel spacing covers the same +/-2 texel penumbra the 5x5 at
|
|
86
|
+
// one-texel spacing did — that kernel was oversampled, its taps overlapping
|
|
87
|
+
// almost entirely once the comparison sampler's own 2x2 filter is counted.
|
|
88
|
+
// Nine taps instead of twenty-five for the same blur radius.
|
|
89
|
+
//
|
|
90
|
+
// Skipped altogether outside the light frustum, where the mix below discards
|
|
91
|
+
// the result anyway: the shadow map covers a small area around the character
|
|
92
|
+
// and the ground is vastly larger than it.
|
|
93
|
+
var vis = 1.0;
|
|
94
|
+
if (frustum > 0.0) {
|
|
95
|
+
let suv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
|
96
|
+
let suv_c = clamp(suv, vec2f(0.02), vec2f(0.98));
|
|
97
|
+
let st = material.pcfTexel * 2.0;
|
|
98
|
+
let compareZ = ndc.z - 0.0035;
|
|
99
|
+
var acc = 0.0;
|
|
100
|
+
for (var y = -1; y <= 1; y++) {
|
|
101
|
+
for (var x = -1; x <= 1; x++) {
|
|
102
|
+
// ...Level, not the implicit-derivative form: identical on a single-mip
|
|
103
|
+
// shadow map, and legal inside this branch.
|
|
104
|
+
acc += textureSampleCompareLevel(shadowMap, shadowSampler, suv_c + vec2f(f32(x), f32(y)) * st, compareZ);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
vis = mix(1.0, acc * (1.0 / 9.0), frustum);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Frosted/matte micro-texture. Scenes leaving it at zero were still paying
|
|
111
|
+
// sixteen hash rounds a pixel for a tint of exactly 1.
|
|
112
|
+
var noiseTint = 1.0;
|
|
113
|
+
if (material.noiseStrength != 0.0) {
|
|
114
|
+
let noiseVal = fbmNoise(i.worldPos.xz * 3.0);
|
|
115
|
+
noiseTint = 1.0 + (noiseVal - 0.5) * material.noiseStrength;
|
|
116
|
+
}
|
|
81
117
|
|
|
82
118
|
// Grid lines — anti-aliased via screen-space derivatives
|
|
83
|
-
let gp = i.worldPos.xz / material.gridSpacing;
|
|
84
119
|
let gridFrac = abs(fract(gp - 0.5) - 0.5);
|
|
85
|
-
let gridDeriv = fwidth(gp);
|
|
86
120
|
let halfLine = material.gridLineWidth * 0.5;
|
|
87
121
|
let gridLine = 1.0 - min(
|
|
88
122
|
smoothstep(halfLine - gridDeriv.x, halfLine + gridDeriv.x, gridFrac.x),
|
|
@@ -100,7 +134,6 @@ struct FSOut { @location(0) color: vec4f, @location(1) mask: vec4f };
|
|
|
100
134
|
let surfA = edgeFade * material.opacity;
|
|
101
135
|
let catchA = dark * 0.65 * edgeFade * (1.0 - material.opacity);
|
|
102
136
|
let outA = surfA + catchA;
|
|
103
|
-
var out: FSOut;
|
|
104
137
|
out.color = vec4f(finalColor * surfA, outA);
|
|
105
138
|
// mask.r = 0: ground never contributes to bloom. mask.g = 1.0 with src.a =
|
|
106
139
|
// outA turns the aux blend into alpha-over, so the drawable alpha goes
|
package/package.json
CHANGED
package/src/engine.ts
CHANGED
|
@@ -7,6 +7,7 @@ import { VMDLoader } from "./vmd-loader"
|
|
|
7
7
|
import { CameraAnimation } from "./camera-animation"
|
|
8
8
|
import { PmxLoader } from "./pmx-loader"
|
|
9
9
|
import { RezePhysics } from "./physics"
|
|
10
|
+
import type { WindOptions } from "./physics/world"
|
|
10
11
|
import {
|
|
11
12
|
createFetchAssetReader,
|
|
12
13
|
createFileMapAssetReader,
|
|
@@ -799,6 +800,10 @@ export class Engine {
|
|
|
799
800
|
// IK and physics enabled at engine level (same for all models)
|
|
800
801
|
private ikEnabled = true
|
|
801
802
|
private physicsEnabled = true
|
|
803
|
+
// World-wide, not per-model: MMD treats gravity and wind as properties of the
|
|
804
|
+
// scene, and a model loaded later must arrive into the same air as the rest.
|
|
805
|
+
private gravity = new Vec3(0, -98, 0)
|
|
806
|
+
private wind: WindOptions | null = null
|
|
802
807
|
// GPU vertex-morph path. Set false BEFORE loadModel to fall back to the CPU path (A/B).
|
|
803
808
|
private useGpuMorphs = true
|
|
804
809
|
|
|
@@ -2987,32 +2992,20 @@ export class Engine {
|
|
|
2987
2992
|
return { ...this.stats }
|
|
2988
2993
|
}
|
|
2989
2994
|
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
2993
|
-
|
|
2994
|
-
|
|
2995
|
-
|
|
2996
|
-
|
|
2997
|
-
|
|
2998
|
-
this.maxFPS = fps !== null && fps > 0 ? fps : null
|
|
2999
|
-
}
|
|
3000
|
-
|
|
2995
|
+
// The render loop runs at display rate, always. A frame-rate cap used to be
|
|
2996
|
+
// offered here for high-refresh displays, on the reasoning that VMD content
|
|
2997
|
+
// is 30fps and running the whole pipeline at 240 buys nothing. Nothing ever
|
|
2998
|
+
// called it — every product in the family chases native refresh, because
|
|
2999
|
+
// dropping frames a display can show is the one thing that reads as cheap.
|
|
3000
|
+
// Physics already decouples: it steps at a fixed 60Hz behind an accumulator
|
|
3001
|
+
// and the drawn pose is interpolated between substeps, so a 240Hz display
|
|
3002
|
+
// costs four interpolations per simulation step, not four simulations.
|
|
3001
3003
|
runRenderLoop(callback?: () => void) {
|
|
3002
3004
|
this.renderLoopCallback = callback || null
|
|
3003
3005
|
|
|
3004
|
-
const loop = (
|
|
3006
|
+
const loop = () => {
|
|
3005
3007
|
this.animationFrameId = requestAnimationFrame(loop)
|
|
3006
|
-
|
|
3007
|
-
if (this.maxFPS !== null) {
|
|
3008
|
-
// Tolerate rAF jitter: accept frames within ~half a display tick early.
|
|
3009
|
-
const minInterval = 1000 / this.maxFPS - 2
|
|
3010
|
-
if (now - this.lastLoopTime < minInterval) return
|
|
3011
|
-
this.lastLoopTime = now
|
|
3012
|
-
}
|
|
3013
|
-
|
|
3014
3008
|
this.render()
|
|
3015
|
-
|
|
3016
3009
|
if (this.renderLoopCallback) {
|
|
3017
3010
|
this.renderLoopCallback()
|
|
3018
3011
|
}
|
|
@@ -3261,6 +3254,39 @@ export class Engine {
|
|
|
3261
3254
|
return this.physicsEnabled
|
|
3262
3255
|
}
|
|
3263
3256
|
|
|
3257
|
+
/**
|
|
3258
|
+
* Scene gravity, applied to every model's cloth and hair. The default is
|
|
3259
|
+
* (0, -98, 0) — MMD's own scale, where a character stands about 20 units
|
|
3260
|
+
* tall. Lower magnitudes float; tilting it sideways hangs everything on a
|
|
3261
|
+
* slant, which is the cheap way to fake a strong draught.
|
|
3262
|
+
*/
|
|
3263
|
+
setGravity(gravity: Vec3): void {
|
|
3264
|
+
this.gravity = new Vec3(gravity.x, gravity.y, gravity.z)
|
|
3265
|
+
this.forEachInstance((inst) => inst.physics?.setGravity(this.gravity))
|
|
3266
|
+
}
|
|
3267
|
+
|
|
3268
|
+
getGravity(): Vec3 {
|
|
3269
|
+
return new Vec3(this.gravity.x, this.gravity.y, this.gravity.z)
|
|
3270
|
+
}
|
|
3271
|
+
|
|
3272
|
+
/**
|
|
3273
|
+
* Air movement across the scene — null is still air.
|
|
3274
|
+
*
|
|
3275
|
+
* Applied as an acceleration alongside gravity, so `strength` is in the same
|
|
3276
|
+
* units: against the default gravity of 98, a strength of 10-30 reads as a
|
|
3277
|
+
* breeze through hair and a skirt without lifting them off the body. Gusting
|
|
3278
|
+
* is driven by simulated time rather than wall time, so an exported take
|
|
3279
|
+
* gusts exactly as the preview did.
|
|
3280
|
+
*/
|
|
3281
|
+
setWind(wind: WindOptions | null): void {
|
|
3282
|
+
this.wind = wind ? { ...wind, direction: new Vec3(wind.direction.x, wind.direction.y, wind.direction.z) } : null
|
|
3283
|
+
this.forEachInstance((inst) => inst.physics?.setWind(this.wind))
|
|
3284
|
+
}
|
|
3285
|
+
|
|
3286
|
+
getWind(): WindOptions | null {
|
|
3287
|
+
return this.wind ? { ...this.wind, direction: new Vec3(this.wind.direction.x, this.wind.direction.y, this.wind.direction.z) } : null
|
|
3288
|
+
}
|
|
3289
|
+
|
|
3264
3290
|
resetPhysics(): void {
|
|
3265
3291
|
this.forEachInstance((inst) => {
|
|
3266
3292
|
if (!inst.physics) return
|
|
@@ -3433,6 +3459,12 @@ export class Engine {
|
|
|
3433
3459
|
|
|
3434
3460
|
const rbs = model.getRigidbodies()
|
|
3435
3461
|
const physics = rbs.length > 0 ? new RezePhysics(rbs, model.getJoints()) : null
|
|
3462
|
+
// Adopt the scene's air, or a model added mid-session would fall under
|
|
3463
|
+
// different gravity from the ones already on stage.
|
|
3464
|
+
if (physics) {
|
|
3465
|
+
physics.setGravity(this.gravity)
|
|
3466
|
+
if (this.wind) physics.setWind(this.wind)
|
|
3467
|
+
}
|
|
3436
3468
|
|
|
3437
3469
|
const shadowBindGroup = this.device.createBindGroup({
|
|
3438
3470
|
label: `${name}: shadow bind`,
|
|
@@ -3694,6 +3726,7 @@ export class Engine {
|
|
|
3694
3726
|
})
|
|
3695
3727
|
}
|
|
3696
3728
|
|
|
3729
|
+
|
|
3697
3730
|
// Shadow is cast from the visible sun direction — same vector the shader lights with.
|
|
3698
3731
|
/** Whether the shadow map needs clearing — see the shadow pass in `render`.
|
|
3699
3732
|
*
|
package/src/index.ts
CHANGED
|
@@ -86,4 +86,5 @@ export { VMDLoader, type CameraKeyframe, type IkFrame } from "./vmd-loader"
|
|
|
86
86
|
export { VMDWriter } from "./vmd-writer"
|
|
87
87
|
export { PmxLoader } from "./pmx-loader"
|
|
88
88
|
export { CameraAnimation, type CameraPose } from "./camera-animation"
|
|
89
|
-
export { RezePhysics } from "./physics"
|
|
89
|
+
export { RezePhysics } from "./physics"
|
|
90
|
+
export type { WindOptions } from "./physics/world"
|
package/src/physics/physics.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Vec3, Quat, Mat4 } from "../math"
|
|
|
2
2
|
import type { Rigidbody, Joint } from "./types"
|
|
3
3
|
import { RigidbodyType, RigidbodyShape } from "./types"
|
|
4
4
|
import { RigidBodyStore } from "./body"
|
|
5
|
-
import { World } from "./world"
|
|
5
|
+
import { World, type WindOptions } from "./world"
|
|
6
6
|
import { buildConstraints, type SixDofSpringConstraint } from "./constraint"
|
|
7
7
|
import { SolverCache } from "./solver"
|
|
8
8
|
import { ContactPool } from "./contact"
|
|
@@ -166,6 +166,13 @@ export class RezePhysics {
|
|
|
166
166
|
getGravity(): Vec3 {
|
|
167
167
|
return this.world.gravity
|
|
168
168
|
}
|
|
169
|
+
/** World-wide air movement. See {@link WindOptions}; null is still air. */
|
|
170
|
+
setWind(wind: WindOptions | null): void {
|
|
171
|
+
this.world.setWind(wind)
|
|
172
|
+
}
|
|
173
|
+
getWind(): WindOptions | null {
|
|
174
|
+
return this.world.getWind()
|
|
175
|
+
}
|
|
169
176
|
getRigidbodies(): Rigidbody[] {
|
|
170
177
|
return this.rigidbodies
|
|
171
178
|
}
|
package/src/physics/world.ts
CHANGED
|
@@ -10,6 +10,30 @@ import { findContacts, type ContactPool } from "./contact"
|
|
|
10
10
|
// integrate; the parent class syncs them from bones around the step. The
|
|
11
11
|
// solver pass runs on all bodies — kinematic ones have invMass = 0 and
|
|
12
12
|
// act as anchors.
|
|
13
|
+
/**
|
|
14
|
+
* Air movement across the whole world.
|
|
15
|
+
*
|
|
16
|
+
* Applied as an acceleration alongside gravity, which is the same shape MMD's
|
|
17
|
+
* own wind plugins take and keeps it free: gravity and wind are summed once per
|
|
18
|
+
* substep, so the per-body predict loop is untouched. Terminal velocity comes
|
|
19
|
+
* out of the existing per-body damping rather than a drag model — PMX authors
|
|
20
|
+
* already tune that damping to get the hang they want, and a second, hidden
|
|
21
|
+
* drag term would fight it.
|
|
22
|
+
*/
|
|
23
|
+
export interface WindOptions {
|
|
24
|
+
/** Direction the air travels. Normalised on assignment; a zero vector is off. */
|
|
25
|
+
direction: Vec3
|
|
26
|
+
/** Acceleration along it, in gravity's units — the built-in gravity is 98. */
|
|
27
|
+
strength: number
|
|
28
|
+
/** Gust depth, clamped to 0–1. 0 is a steady breeze; 1 swings between still
|
|
29
|
+
* and double. It is a clamp rather than a free scalar because past 1 the
|
|
30
|
+
* swing goes negative and the wind blows backwards on every other beat,
|
|
31
|
+
* which is never what a caller meant by "more turbulent". */
|
|
32
|
+
turbulence?: number
|
|
33
|
+
/** Gusts per second. */
|
|
34
|
+
frequency?: number
|
|
35
|
+
}
|
|
36
|
+
|
|
13
37
|
export class World {
|
|
14
38
|
readonly gravity: Vec3
|
|
15
39
|
solverIterations = 10
|
|
@@ -20,6 +44,17 @@ export class World {
|
|
|
20
44
|
private linDampFactor: Float32Array | null = null
|
|
21
45
|
private angDampFactor: Float32Array | null = null
|
|
22
46
|
|
|
47
|
+
// Wind, resolved to a direction × strength at construction of the options so
|
|
48
|
+
// the step loop only multiplies by a gust scalar.
|
|
49
|
+
private windX = 0
|
|
50
|
+
private windY = 0
|
|
51
|
+
private windZ = 0
|
|
52
|
+
private windTurbulence = 0
|
|
53
|
+
private windFrequency = 0.35
|
|
54
|
+
/** Advances with simulated time, not wall time, so a scrubbed or exported
|
|
55
|
+
* take gusts identically to a live one. */
|
|
56
|
+
private windClock = 0
|
|
57
|
+
|
|
23
58
|
constructor(gravity: Vec3) {
|
|
24
59
|
this.gravity = new Vec3(gravity.x, gravity.y, gravity.z)
|
|
25
60
|
}
|
|
@@ -30,6 +65,37 @@ export class World {
|
|
|
30
65
|
this.gravity.z = g.z
|
|
31
66
|
}
|
|
32
67
|
|
|
68
|
+
setWind(wind: WindOptions | null): void {
|
|
69
|
+
// Shape first, and unconditionally: bailing out early on a zero strength
|
|
70
|
+
// used to leave turbulence and frequency holding whatever a previous call
|
|
71
|
+
// set, so raising the strength again resurrected settings the caller had
|
|
72
|
+
// since replaced.
|
|
73
|
+
this.windTurbulence = Math.min(1, Math.max(0, wind?.turbulence ?? 0))
|
|
74
|
+
this.windFrequency = Math.max(0, wind?.frequency ?? 0.35)
|
|
75
|
+
|
|
76
|
+
const d = wind?.direction
|
|
77
|
+
const len = d ? Math.hypot(d.x, d.y, d.z) : 0
|
|
78
|
+
if (!wind || !d || len < 1e-9 || wind.strength === 0) {
|
|
79
|
+
this.windX = this.windY = this.windZ = 0
|
|
80
|
+
return
|
|
81
|
+
}
|
|
82
|
+
const s = wind.strength / len
|
|
83
|
+
this.windX = d.x * s
|
|
84
|
+
this.windY = d.y * s
|
|
85
|
+
this.windZ = d.z * s
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
getWind(): WindOptions | null {
|
|
89
|
+
const strength = Math.hypot(this.windX, this.windY, this.windZ)
|
|
90
|
+
if (strength === 0) return null
|
|
91
|
+
return {
|
|
92
|
+
direction: new Vec3(this.windX / strength, this.windY / strength, this.windZ / strength),
|
|
93
|
+
strength,
|
|
94
|
+
turbulence: this.windTurbulence,
|
|
95
|
+
frequency: this.windFrequency,
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
33
99
|
step(
|
|
34
100
|
store: RigidBodyStore,
|
|
35
101
|
constraints: SixDofSpringConstraint[],
|
|
@@ -49,9 +115,24 @@ export class World {
|
|
|
49
115
|
const adamp = store.angularDamping
|
|
50
116
|
const invMass = store.invMass
|
|
51
117
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
118
|
+
// Gravity and wind are the same kind of term, so they are summed here and
|
|
119
|
+
// the predict loop below never learns wind exists.
|
|
120
|
+
let gx = this.gravity.x
|
|
121
|
+
let gy = this.gravity.y
|
|
122
|
+
let gz = this.gravity.z
|
|
123
|
+
if (this.windX !== 0 || this.windY !== 0 || this.windZ !== 0) {
|
|
124
|
+
this.windClock += dt
|
|
125
|
+
let gust = 1
|
|
126
|
+
if (this.windTurbulence > 0 && this.windFrequency > 0) {
|
|
127
|
+
// Two incommensurate sines: a single one is a metronome, and real gusts
|
|
128
|
+
// do not repeat on a bar line. Stays within 1 ± turbulence.
|
|
129
|
+
const t = this.windClock * this.windFrequency * Math.PI * 2
|
|
130
|
+
gust = 1 + this.windTurbulence * 0.5 * (Math.sin(t) + Math.sin(t * 0.37 + 1.3))
|
|
131
|
+
}
|
|
132
|
+
gx += this.windX * gust
|
|
133
|
+
gy += this.windY * gust
|
|
134
|
+
gz += this.windZ * gust
|
|
135
|
+
}
|
|
55
136
|
|
|
56
137
|
// 1. Predict — gravity + damping. The pow form (vs the linear
|
|
57
138
|
// 1−damping·dt approximation) stays stable at high PMX damping
|
|
@@ -50,40 +50,74 @@ struct VO { @builtin(position) position: vec4f, @location(0) worldPos: vec3f, @l
|
|
|
50
50
|
}
|
|
51
51
|
struct FSOut { @location(0) color: vec4f, @location(1) mask: vec4f };
|
|
52
52
|
@fragment fn fs(i: VO) -> FSOut {
|
|
53
|
+
// Derivatives first, unconditionally: WGSL requires fwidth in uniform control
|
|
54
|
+
// flow and everything below branches on world position.
|
|
55
|
+
let gp = i.worldPos.xz / material.gridSpacing;
|
|
56
|
+
let gridDeriv = fwidth(gp);
|
|
57
|
+
|
|
58
|
+
var out: FSOut;
|
|
53
59
|
let n = normalize(i.normal);
|
|
54
60
|
let centerDist = length(i.worldPos.xz);
|
|
55
61
|
let edgeFade = 1.0 - smoothstep(0.0, 1.0, clamp((centerDist - material.fadeStart) / max(material.fadeEnd - material.fadeStart, 0.001), 0.0, 1.0));
|
|
56
62
|
|
|
63
|
+
// Past the radial fade every term below is multiplied by edgeFade and the
|
|
64
|
+
// pixel is fully transparent. Shading it anyway produces nothing.
|
|
65
|
+
if (edgeFade <= 0.0) {
|
|
66
|
+
out.color = vec4f(0.0);
|
|
67
|
+
out.mask = vec4f(0.0, 1.0, 0.0, 0.0);
|
|
68
|
+
return out;
|
|
69
|
+
}
|
|
70
|
+
|
|
57
71
|
let lclip = lightVP.viewProj * vec4f(i.worldPos, 1.0);
|
|
58
72
|
let ndc = lclip.xyz / max(lclip.w, 1e-6);
|
|
59
|
-
let suv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
|
60
|
-
let suv_c = clamp(suv, vec2f(0.02), vec2f(0.98));
|
|
61
|
-
let st = material.pcfTexel;
|
|
62
|
-
let compareZ = ndc.z - 0.0035;
|
|
63
|
-
var vis = 0.0;
|
|
64
|
-
for (var y = -2; y <= 2; y++) {
|
|
65
|
-
for (var x = -2; x <= 2; x++) {
|
|
66
|
-
vis += textureSampleCompare(shadowMap, shadowSampler, suv_c + vec2f(f32(x), f32(y)) * st, compareZ);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
vis *= 0.04;
|
|
70
73
|
// Outside the light's frustum there IS no shadow information — the clamped
|
|
71
|
-
// border samples
|
|
74
|
+
// border samples compare against unrelated depths and read "shadowed",
|
|
72
75
|
// darkening the whole far plane with a visible band at the frustum edge
|
|
73
76
|
// (masked by the opaque surface normally, glaring in green-screen mode where
|
|
74
77
|
// only the shadow-catcher term renders). Fade to fully lit near the border.
|
|
75
78
|
let inZ = select(0.0, 1.0, ndc.z > 0.0 && ndc.z < 1.0);
|
|
76
79
|
let frustum = (1.0 - smoothstep(0.88, 0.96, abs(ndc.x))) * (1.0 - smoothstep(0.88, 0.96, abs(ndc.y))) * inZ;
|
|
77
|
-
vis = mix(1.0, vis, frustum);
|
|
78
80
|
|
|
79
|
-
//
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
// THE cost of this shader, measured: a full-screen ground ran 25 shadow
|
|
82
|
+
// comparisons per pixel, and each one is hardware-bilinear, so ~100 depth
|
|
83
|
+
// samples per pixel. Gutting the rest of the shader changed nothing; cutting
|
|
84
|
+
// this is what makes looking down cheap.
|
|
85
|
+
//
|
|
86
|
+
// 3x3 at two-texel spacing covers the same +/-2 texel penumbra the 5x5 at
|
|
87
|
+
// one-texel spacing did — that kernel was oversampled, its taps overlapping
|
|
88
|
+
// almost entirely once the comparison sampler's own 2x2 filter is counted.
|
|
89
|
+
// Nine taps instead of twenty-five for the same blur radius.
|
|
90
|
+
//
|
|
91
|
+
// Skipped altogether outside the light frustum, where the mix below discards
|
|
92
|
+
// the result anyway: the shadow map covers a small area around the character
|
|
93
|
+
// and the ground is vastly larger than it.
|
|
94
|
+
var vis = 1.0;
|
|
95
|
+
if (frustum > 0.0) {
|
|
96
|
+
let suv = vec2f(ndc.x * 0.5 + 0.5, 0.5 - ndc.y * 0.5);
|
|
97
|
+
let suv_c = clamp(suv, vec2f(0.02), vec2f(0.98));
|
|
98
|
+
let st = material.pcfTexel * 2.0;
|
|
99
|
+
let compareZ = ndc.z - 0.0035;
|
|
100
|
+
var acc = 0.0;
|
|
101
|
+
for (var y = -1; y <= 1; y++) {
|
|
102
|
+
for (var x = -1; x <= 1; x++) {
|
|
103
|
+
// ...Level, not the implicit-derivative form: identical on a single-mip
|
|
104
|
+
// shadow map, and legal inside this branch.
|
|
105
|
+
acc += textureSampleCompareLevel(shadowMap, shadowSampler, suv_c + vec2f(f32(x), f32(y)) * st, compareZ);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
vis = mix(1.0, acc * (1.0 / 9.0), frustum);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// Frosted/matte micro-texture. Scenes leaving it at zero were still paying
|
|
112
|
+
// sixteen hash rounds a pixel for a tint of exactly 1.
|
|
113
|
+
var noiseTint = 1.0;
|
|
114
|
+
if (material.noiseStrength != 0.0) {
|
|
115
|
+
let noiseVal = fbmNoise(i.worldPos.xz * 3.0);
|
|
116
|
+
noiseTint = 1.0 + (noiseVal - 0.5) * material.noiseStrength;
|
|
117
|
+
}
|
|
82
118
|
|
|
83
119
|
// Grid lines — anti-aliased via screen-space derivatives
|
|
84
|
-
let gp = i.worldPos.xz / material.gridSpacing;
|
|
85
120
|
let gridFrac = abs(fract(gp - 0.5) - 0.5);
|
|
86
|
-
let gridDeriv = fwidth(gp);
|
|
87
121
|
let halfLine = material.gridLineWidth * 0.5;
|
|
88
122
|
let gridLine = 1.0 - min(
|
|
89
123
|
smoothstep(halfLine - gridDeriv.x, halfLine + gridDeriv.x, gridFrac.x),
|
|
@@ -101,7 +135,6 @@ struct FSOut { @location(0) color: vec4f, @location(1) mask: vec4f };
|
|
|
101
135
|
let surfA = edgeFade * material.opacity;
|
|
102
136
|
let catchA = dark * 0.65 * edgeFade * (1.0 - material.opacity);
|
|
103
137
|
let outA = surfA + catchA;
|
|
104
|
-
var out: FSOut;
|
|
105
138
|
out.color = vec4f(finalColor * surfA, outA);
|
|
106
139
|
// mask.r = 0: ground never contributes to bloom. mask.g = 1.0 with src.a =
|
|
107
140
|
// outA turns the aux blend into alpha-over, so the drawable alpha goes
|