@vgai/engine 0.5.21 → 0.5.23
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 +6 -3
- package/dist/adapter/adapter-module.d.ts.map +1 -1
- package/dist/adapter/adapter-module.js +2 -4
- package/dist/adapter/adapter-surface.d.ts +1 -1
- package/dist/adapter/adapter-surface.js +1 -1
- package/dist/adapter/authoring.d.ts +19 -21
- package/dist/adapter/authoring.d.ts.map +1 -1
- package/dist/adapter/authoring.js +2 -2
- package/dist/adapter/binding.d.ts +341 -0
- package/dist/adapter/binding.d.ts.map +1 -0
- package/dist/adapter/binding.js +148 -0
- package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -1
- package/dist/adapter/colyseus-networking-adapter.js +23 -4
- package/dist/adapter/entrypoint-selection-readers.d.ts +24 -0
- package/dist/adapter/entrypoint-selection-readers.d.ts.map +1 -0
- package/dist/adapter/entrypoint-selection-readers.js +63 -0
- package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -1
- package/dist/adapter/entrypoint-selection-source.js +1 -44
- package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
- package/dist/adapter/finders/scenes-from-entrypoint-selection.js +1 -52
- package/dist/adapter/host-context.d.ts +46 -15
- package/dist/adapter/host-context.d.ts.map +1 -1
- package/dist/adapter/host-context.js +2 -9
- package/dist/adapter/index.d.ts +11 -12
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter/index.js +9 -10
- package/dist/adapter/ingest/game-contract.d.ts +0 -3
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
- package/dist/adapter/ingest/game-contract.js +0 -3
- package/dist/adapter/ingest/scene-capture.d.ts +19 -23
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
- package/dist/adapter/ingest/scene-capture.js +143 -17
- package/dist/adapter/ingest/visible-capture-window.d.ts +34 -0
- package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
- package/dist/adapter/manifest-interpreter.d.ts +59 -0
- package/dist/adapter/manifest-interpreter.d.ts.map +1 -0
- package/dist/adapter/manifest-interpreter.js +50 -0
- package/dist/adapter/native-debug-module.d.ts +71 -3
- package/dist/adapter/native-debug-module.d.ts.map +1 -1
- package/dist/adapter/native-debug-module.js +146 -10
- package/dist/adapter/rapier-physics-adapter.d.ts +31 -1
- package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -1
- package/dist/adapter/rapier-physics-adapter.js +50 -36
- package/dist/adapter/renderer-config.d.ts +3 -3
- package/dist/adapter/renderer-config.js +3 -3
- package/dist/adapter/root-adapter.d.ts +7 -7
- package/dist/adapter/root-adapter.js +4 -4
- package/dist/adapter/system-adapter.d.ts +45 -7
- package/dist/adapter/system-adapter.d.ts.map +1 -1
- package/dist/adapter/system-seam-contract.d.ts +3 -3
- package/dist/adapter/system-seam-contract.js +3 -3
- package/dist/adapter/system-slot.d.ts +168 -0
- package/dist/adapter/system-slot.d.ts.map +1 -0
- package/dist/adapter/system-slot.js +229 -0
- package/dist/adapter/transform.d.ts +11 -1
- package/dist/adapter/transform.d.ts.map +1 -1
- package/dist/ai/navigation.d.ts +17 -1
- package/dist/ai/navigation.d.ts.map +1 -1
- package/dist/ai/navigation.js +26 -5
- package/dist/animation/anim-graph-types.d.ts +11 -3
- package/dist/animation/anim-graph-types.d.ts.map +1 -1
- package/dist/animation/theatre-clock-binding.d.ts +4 -4
- package/dist/animation/theatre-clock-binding.js +4 -4
- package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
- package/dist/animation/xstate-animation-binding.js +2 -2
- package/dist/animation/xstate-animation-meta.d.ts +13 -0
- package/dist/animation/xstate-animation-meta.d.ts.map +1 -1
- package/dist/animation/xstate-animation-meta.js +14 -0
- package/dist/asset-formats/index.d.ts +4 -7
- package/dist/asset-formats/index.d.ts.map +1 -1
- package/dist/asset-formats/index.js +4 -7
- package/dist/asset-formats/render-env.d.ts +5 -8
- package/dist/asset-formats/render-env.d.ts.map +1 -1
- package/dist/asset-formats/render-env.js +3 -6
- package/dist/asset-parse-error.d.ts +2 -5
- package/dist/asset-parse-error.d.ts.map +1 -1
- package/dist/asset-parse-error.js +2 -5
- package/dist/audio/bus-mixer.d.ts +101 -0
- package/dist/audio/bus-mixer.d.ts.map +1 -0
- package/dist/audio/bus-mixer.js +115 -0
- package/dist/canvas-react/index.d.ts +5 -12
- package/dist/canvas-react/index.d.ts.map +1 -1
- package/dist/canvas-react/index.js +5 -12
- package/dist/canvas-react/pixi-react-root-factory.d.ts +34 -21
- package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
- package/dist/canvas-react/pixi-react-root-factory.js +274 -36
- package/dist/core/countdown-timer.d.ts +118 -0
- package/dist/core/countdown-timer.d.ts.map +1 -0
- package/dist/core/countdown-timer.js +137 -0
- package/dist/core/deferred-commands.d.ts +127 -0
- package/dist/core/deferred-commands.d.ts.map +1 -0
- package/dist/core/deferred-commands.js +132 -0
- package/dist/core/frame-pacing.d.ts +1 -1
- package/dist/core/frame-pacing.js +2 -2
- package/dist/core/game-loop.d.ts +1 -3
- package/dist/core/game-loop.d.ts.map +1 -1
- package/dist/core/game-loop.js +1 -3
- package/dist/core/seeded-random.d.ts +1 -1
- package/dist/core/sim-clock.d.ts +19 -8
- package/dist/core/sim-clock.d.ts.map +1 -1
- package/dist/core/sim-clock.js +18 -7
- package/dist/core/types.d.ts +1 -3
- package/dist/core/types.d.ts.map +1 -1
- package/dist/defaults.d.ts +6 -14
- package/dist/defaults.d.ts.map +1 -1
- package/dist/defaults.js +6 -14
- package/dist/dev/instruments.d.ts +38 -11
- package/dist/dev/instruments.d.ts.map +1 -1
- package/dist/dev/instruments.js +81 -11
- package/dist/dev/register-render-vitals.d.ts +1 -4
- package/dist/dev/register-render-vitals.d.ts.map +1 -1
- package/dist/dev/register-render-vitals.js +1 -4
- package/dist/dev/render-debug-adapter.d.ts +2 -3
- package/dist/dev/render-debug-adapter.d.ts.map +1 -1
- package/dist/dev/render-debug-adapter.js +2 -3
- package/dist/dev/render-vitals.d.ts +3 -3
- package/dist/dev/render-vitals.js +3 -3
- package/dist/dev/webgl-frame-capture.d.ts +1 -1
- package/dist/dev/webgl-frame-capture.js +1 -1
- package/dist/index.d.ts +2 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -4
- package/dist/input/host-pointer.d.ts +122 -0
- package/dist/input/host-pointer.d.ts.map +1 -0
- package/dist/input/host-pointer.js +160 -0
- package/dist/input/input-manager.d.ts +33 -5
- package/dist/input/input-manager.d.ts.map +1 -1
- package/dist/input/input-manager.js +48 -13
- package/dist/input/rebind-controller.d.ts.map +1 -1
- package/dist/input/rebind-controller.js +6 -8
- package/dist/input/schema.d.ts.map +1 -1
- package/dist/input/schema.js +56 -28
- package/dist/manifest/filename.d.ts.map +1 -1
- package/dist/manifest/filename.js +8 -12
- package/dist/manifest/load.d.ts +10 -10
- package/dist/manifest/load.d.ts.map +1 -1
- package/dist/manifest/load.js +9 -6
- package/dist/manifest/schema.d.ts +17 -21
- package/dist/manifest/schema.d.ts.map +1 -1
- package/dist/manifest/schema.js +45 -35
- package/dist/physics/collider-dimensions.d.ts +8 -12
- package/dist/physics/collider-dimensions.d.ts.map +1 -1
- package/dist/physics/collider-dimensions.js +8 -12
- package/dist/pixi/scene-capture.d.ts +11 -13
- package/dist/pixi/scene-capture.d.ts.map +1 -1
- package/dist/react/world-state.d.ts +1 -1
- package/dist/react/world-state.d.ts.map +1 -1
- package/dist/render/directional-shadow-fit.d.ts +88 -0
- package/dist/render/directional-shadow-fit.d.ts.map +1 -0
- package/dist/render/directional-shadow-fit.js +133 -0
- package/dist/render/environment-capture.d.ts +68 -0
- package/dist/render/environment-capture.d.ts.map +1 -0
- package/dist/render/environment-capture.js +90 -0
- package/dist/render/ibl-override-material.d.ts +97 -0
- package/dist/render/ibl-override-material.d.ts.map +1 -0
- package/dist/render/ibl-override-material.js +114 -0
- package/dist/render/light-camera-factory.d.ts +5 -7
- package/dist/render/light-camera-factory.d.ts.map +1 -1
- package/dist/render/light-camera-factory.js +8 -11
- package/dist/render/material-factory.js +1 -1
- package/dist/render/render-batch-system.d.ts.map +1 -1
- package/dist/render/render-features.d.ts +17 -6
- package/dist/render/render-features.d.ts.map +1 -1
- package/dist/render/render-features.js +0 -28
- package/dist/runtime/create-runtime.d.ts +34 -25
- package/dist/runtime/create-runtime.d.ts.map +1 -1
- package/dist/runtime/create-runtime.js +218 -93
- package/dist/runtime/debug-registry.d.ts +77 -8
- package/dist/runtime/debug-registry.d.ts.map +1 -1
- package/dist/runtime/debug-registry.js +3 -3
- package/dist/runtime/dev-build.d.ts +2 -2
- package/dist/runtime/dev-build.js +2 -2
- package/dist/runtime/game-input-seams.d.ts +51 -0
- package/dist/runtime/game-input-seams.d.ts.map +1 -0
- package/dist/runtime/game-input-seams.js +86 -0
- package/dist/runtime/game.d.ts +104 -40
- package/dist/runtime/game.d.ts.map +1 -1
- package/dist/runtime/game.js +119 -61
- package/dist/runtime/mount-game.d.ts +0 -16
- package/dist/runtime/mount-game.d.ts.map +1 -1
- package/dist/runtime/mount-game.js +26 -41
- package/dist/runtime/mount-manifest.d.ts +22 -14
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +22 -20
- package/dist/runtime/playtest.d.ts +22 -0
- package/dist/runtime/playtest.d.ts.map +1 -0
- package/dist/runtime/playtest.js +12 -0
- package/dist/runtime/state-bridge.d.ts +2 -3
- package/dist/runtime/state-bridge.d.ts.map +1 -1
- package/dist/runtime/state-bridge.js +1 -0
- package/dist/setup/setup-audio.d.ts +12 -0
- package/dist/setup/setup-audio.d.ts.map +1 -1
- package/dist/setup/setup-audio.js +9 -10
- package/dist/setup/setup-renderer.d.ts +2 -25
- package/dist/setup/setup-renderer.d.ts.map +1 -1
- package/dist/setup/setup-renderer.js +2 -31
- package/dist/world3d-react/index.d.ts +15 -25
- package/dist/world3d-react/index.d.ts.map +1 -1
- package/dist/world3d-react/index.js +15 -25
- package/dist/world3d-react/r3f-root-factory.d.ts +28 -34
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
- package/dist/world3d-react/r3f-root-factory.js +403 -57
- package/dist/world3d-react/rapier-physics-bridge.d.ts +30 -17
- package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
- package/dist/world3d-react/rapier-physics-bridge.js +143 -58
- package/package.json +1 -1
- package/schemas/engine-capabilities.json +16 -14
- package/schemas/vgai-project.schema.json +35 -26
- package/src/adapter/adapter-module.ts +2 -4
- package/src/adapter/adapter-surface.ts +1 -1
- package/src/adapter/authoring.ts +19 -21
- package/src/adapter/binding.ts +468 -0
- package/src/adapter/colyseus-networking-adapter.ts +20 -5
- package/src/adapter/entrypoint-selection-readers.ts +66 -0
- package/src/adapter/entrypoint-selection-source.ts +1 -40
- package/src/adapter/finders/scenes-from-entrypoint-selection.ts +1 -48
- package/src/adapter/host-context.ts +45 -15
- package/src/adapter/index.ts +23 -11
- package/src/adapter/ingest/game-contract.ts +0 -3
- package/src/adapter/ingest/scene-capture.ts +190 -39
- package/src/adapter/ingest/visible-capture-window.ts +35 -0
- package/src/adapter/manifest-interpreter.ts +64 -0
- package/src/adapter/native-debug-module.ts +248 -15
- package/src/adapter/rapier-physics-adapter.ts +76 -20
- package/src/adapter/renderer-config.ts +3 -3
- package/src/adapter/root-adapter.ts +7 -7
- package/src/adapter/system-adapter.ts +43 -8
- package/src/adapter/system-seam-contract.ts +3 -3
- package/src/adapter/system-slot.ts +291 -0
- package/src/adapter/transform.ts +18 -1
- package/src/ai/navigation.ts +30 -3
- package/src/animation/anim-graph-types.ts +11 -3
- package/src/animation/theatre-clock-binding.ts +4 -4
- package/src/animation/xstate-animation-binding.ts +2 -2
- package/src/animation/xstate-animation-meta.ts +16 -0
- package/src/asset-formats/index.ts +4 -7
- package/src/asset-formats/render-env.ts +3 -6
- package/src/asset-parse-error.ts +2 -5
- package/src/audio/bus-mixer.ts +161 -0
- package/src/canvas-react/index.ts +5 -21
- package/src/canvas-react/pixi-react-root-factory.tsx +301 -39
- package/src/core/countdown-timer.ts +188 -0
- package/src/core/deferred-commands.ts +174 -0
- package/src/core/frame-pacing.ts +2 -2
- package/src/core/game-loop.ts +1 -3
- package/src/core/seeded-random.ts +1 -1
- package/src/core/sim-clock.ts +19 -8
- package/src/core/types.ts +1 -3
- package/src/defaults.ts +6 -14
- package/src/dev/instruments.ts +108 -11
- package/src/dev/register-render-vitals.ts +1 -4
- package/src/dev/render-debug-adapter.ts +2 -3
- package/src/dev/render-vitals.ts +3 -3
- package/src/dev/webgl-frame-capture.ts +1 -1
- package/src/index.ts +2 -5
- package/src/input/host-pointer.ts +230 -0
- package/src/input/input-manager.ts +49 -13
- package/src/input/input-types.ts +1 -1
- package/src/input/rebind-controller.ts +6 -8
- package/src/input/schema.ts +216 -188
- package/src/manifest/filename.ts +8 -12
- package/src/manifest/load.ts +17 -13
- package/src/manifest/schema.ts +55 -47
- package/src/physics/collider-dimensions.ts +8 -12
- package/src/pixi/scene-capture.ts +12 -15
- package/src/react/world-state.tsx +1 -1
- package/src/render/directional-shadow-fit.ts +156 -0
- package/src/render/environment-capture.ts +102 -0
- package/src/render/ibl-override-material.ts +170 -0
- package/src/render/light-camera-factory.ts +8 -11
- package/src/render/material-factory.ts +1 -1
- package/src/render/render-batch-system.ts +14 -6
- package/src/render/render-features.ts +17 -35
- package/src/runtime/create-runtime.ts +270 -108
- package/src/runtime/debug-registry.ts +84 -8
- package/src/runtime/dev-build.ts +2 -2
- package/src/runtime/game-input-seams.ts +108 -0
- package/src/runtime/game.ts +231 -85
- package/src/runtime/mount-game.ts +31 -57
- package/src/runtime/mount-manifest.ts +47 -36
- package/src/runtime/playtest.ts +22 -0
- package/src/runtime/state-bridge.ts +3 -3
- package/src/setup/setup-audio.ts +21 -11
- package/src/setup/setup-renderer.ts +2 -61
- package/src/world3d-react/index.ts +15 -31
- package/src/world3d-react/r3f-root-factory.tsx +451 -60
- package/src/world3d-react/rapier-physics-bridge.tsx +154 -58
- package/dist/adapter/setup-three-root-adapter.d.ts +0 -86
- package/dist/adapter/setup-three-root-adapter.d.ts.map +0 -1
- package/dist/adapter/setup-three-root-adapter.js +0 -908
- package/dist/animation/clip-map.d.ts +0 -12
- package/dist/animation/clip-map.d.ts.map +0 -1
- package/dist/animation/clip-map.js +0 -31
- package/dist/asset-registry.d.ts +0 -38
- package/dist/asset-registry.d.ts.map +0 -1
- package/dist/asset-registry.js +0 -66
- package/dist/canvas-react/engine-bridge.d.ts +0 -45
- package/dist/canvas-react/engine-bridge.d.ts.map +0 -1
- package/dist/canvas-react/engine-bridge.js +0 -45
- package/dist/canvas-react/pixi-react-adapter.d.ts +0 -77
- package/dist/canvas-react/pixi-react-adapter.d.ts.map +0 -1
- package/dist/canvas-react/pixi-react-adapter.js +0 -294
- package/dist/canvas-react/world-context.d.ts +0 -98
- package/dist/canvas-react/world-context.d.ts.map +0 -1
- package/dist/canvas-react/world-context.js +0 -173
- package/dist/dev/debug-draw.d.ts +0 -24
- package/dist/dev/debug-draw.d.ts.map +0 -1
- package/dist/dev/debug-draw.js +0 -73
- package/dist/render/auto-batcher.d.ts +0 -34
- package/dist/render/auto-batcher.d.ts.map +0 -1
- package/dist/render/auto-batcher.js +0 -140
- package/dist/render/lod.d.ts +0 -13
- package/dist/render/lod.d.ts.map +0 -1
- package/dist/render/lod.js +0 -16
- package/dist/runtime/types.d.ts +0 -303
- package/dist/runtime/types.d.ts.map +0 -1
- package/dist/runtime/types.js +0 -1
- package/dist/world3d-react/engine-bridge.d.ts +0 -47
- package/dist/world3d-react/engine-bridge.d.ts.map +0 -1
- package/dist/world3d-react/engine-bridge.js +0 -73
- package/dist/world3d-react/r3f-adapter.d.ts +0 -58
- package/dist/world3d-react/r3f-adapter.d.ts.map +0 -1
- package/dist/world3d-react/r3f-adapter.js +0 -634
- package/dist/world3d-react/world-context.d.ts +0 -182
- package/dist/world3d-react/world-context.d.ts.map +0 -1
- package/dist/world3d-react/world-context.js +0 -235
- package/src/adapter/setup-three-root-adapter.ts +0 -1032
- package/src/animation/clip-map.ts +0 -34
- package/src/asset-registry.ts +0 -89
- package/src/canvas-react/engine-bridge.ts +0 -59
- package/src/canvas-react/pixi-react-adapter.tsx +0 -356
- package/src/canvas-react/world-context.ts +0 -253
- package/src/dev/debug-draw.ts +0 -80
- package/src/render/auto-batcher.ts +0 -168
- package/src/render/lod.ts +0 -17
- package/src/runtime/types.ts +0 -328
- package/src/world3d-react/engine-bridge.ts +0 -86
- package/src/world3d-react/r3f-adapter.tsx +0 -717
- package/src/world3d-react/world-context.ts +0 -358
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Replace Three's image-based-lighting functions on a `MeshStandardMaterial`,
|
|
3
|
+
* per fragment, without forking three.
|
|
4
|
+
*
|
|
5
|
+
* A local-probe system cannot express itself as `material.envMap`: one envMap
|
|
6
|
+
* per object picks ONE environment for the whole draw, and the decisive work —
|
|
7
|
+
* which probe volume contains this fragment, how it fades at the boundary,
|
|
8
|
+
* what happens where volumes overlap — is per-fragment and can differ across a
|
|
9
|
+
* single `InstancedMesh`. Every such system therefore does the same three
|
|
10
|
+
* things to three's own program, and this module is that shared mechanism:
|
|
11
|
+
*
|
|
12
|
+
* 1. take `ShaderChunk.envmap_physical_pars_fragment` and rename its two
|
|
13
|
+
* entry points, so the caller's replacement can still call them as its
|
|
14
|
+
* fallback ({@link baseIblFunctions});
|
|
15
|
+
* 2. publish the fragment's world position as a varying, spliced into
|
|
16
|
+
* `<worldpos_vertex>` under `USE_ENVMAP` ({@link IBL_WORLD_POSITION});
|
|
17
|
+
* 3. swap the fragment chunk for the caller's own GLSL and extend the
|
|
18
|
+
* program cache key so the variant is not shared with an unpatched
|
|
19
|
+
* material ({@link overrideMaterialIbl}).
|
|
20
|
+
*
|
|
21
|
+
* What the caller keeps is exactly what makes its system ITS system: the
|
|
22
|
+
* lighting model in the GLSL body, the uniforms behind it, and how probes are
|
|
23
|
+
* discovered, scheduled and captured. This module decides none of that — it
|
|
24
|
+
* hands back three's own shader object and gets out of the way.
|
|
25
|
+
*
|
|
26
|
+
* Consumers today: the `reflections` capability's native probe system, and
|
|
27
|
+
* `godot-compat`'s Godot 3 `ReflectionProbe`, whose per-fragment models are
|
|
28
|
+
* deliberately different renderers over this one splice.
|
|
29
|
+
*/
|
|
30
|
+
import { type Mesh, type MeshStandardMaterial, ShaderChunk } from 'three';
|
|
31
|
+
|
|
32
|
+
/** The shader object three hands to `onBeforeCompile`. */
|
|
33
|
+
export type IblOverrideShader = Parameters<MeshStandardMaterial['onBeforeCompile']>[0];
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The `varying vec3` the vertex splice publishes and the fragment body reads.
|
|
37
|
+
*
|
|
38
|
+
* It is ONE name across every consumer on purpose: the splice that declares it
|
|
39
|
+
* lives here, so a per-consumer name would be a string two files have to agree
|
|
40
|
+
* on with nothing checking that they do.
|
|
41
|
+
*/
|
|
42
|
+
export const IBL_WORLD_POSITION = 'vgaiIblWorldPosition';
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Three's own IBL chunk with `getIBLIrradiance`/`getIBLRadiance` renamed to
|
|
46
|
+
* `getBaseIBLIrradiance`/`getBaseIBLRadiance`.
|
|
47
|
+
*
|
|
48
|
+
* A replacement chunk defines the original names itself; calling the renamed
|
|
49
|
+
* pair is how it falls back to the scene environment where no probe applies.
|
|
50
|
+
*/
|
|
51
|
+
export function baseIblFunctions(): string {
|
|
52
|
+
return ShaderChunk.envmap_physical_pars_fragment
|
|
53
|
+
.replaceAll('getIBLIrradiance', 'getBaseIBLIrradiance')
|
|
54
|
+
.replaceAll('getIBLRadiance', 'getBaseIBLRadiance');
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Every material a mesh draws with that {@link overrideMaterialIbl} accepts.
|
|
59
|
+
*
|
|
60
|
+
* `isMeshStandardMaterial` is true for `MeshPhysicalMaterial` too, which is the
|
|
61
|
+
* intent: both compile the physical IBL chunk this module replaces.
|
|
62
|
+
*/
|
|
63
|
+
export function standardMaterialsOf(mesh: Mesh): readonly MeshStandardMaterial[] {
|
|
64
|
+
const materials = Array.isArray(mesh.material) ? mesh.material : [mesh.material];
|
|
65
|
+
return materials.filter((material): material is MeshStandardMaterial =>
|
|
66
|
+
Boolean((material as MeshStandardMaterial).isMeshStandardMaterial),
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export interface IblOverrideOptions {
|
|
71
|
+
/**
|
|
72
|
+
* The GLSL that replaces `#include <envmap_physical_pars_fragment>`. Read at
|
|
73
|
+
* COMPILE time, not at install time, so a caller whose probe count is still
|
|
74
|
+
* settling does not have to reinstall to change it.
|
|
75
|
+
*/
|
|
76
|
+
readonly fragment: () => string;
|
|
77
|
+
/**
|
|
78
|
+
* Appended to the material's own `customProgramCacheKey`, after a `|`. Must
|
|
79
|
+
* distinguish every shape of {@link IblOverrideOptions.fragment} the caller
|
|
80
|
+
* can produce — a probe COUNT belongs in here, because it changes the
|
|
81
|
+
* declared uniform array sizes.
|
|
82
|
+
*/
|
|
83
|
+
readonly cacheKey: () => string;
|
|
84
|
+
/**
|
|
85
|
+
* Runs at the end of `onBeforeCompile`, with the shader three is compiling.
|
|
86
|
+
* Seed uniforms here: this is the only moment the caller is handed the
|
|
87
|
+
* object whose `uniforms` map the program will read.
|
|
88
|
+
*/
|
|
89
|
+
readonly onCompile?: (shader: IblOverrideShader) => void;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface IblOverride {
|
|
93
|
+
readonly material: MeshStandardMaterial;
|
|
94
|
+
/**
|
|
95
|
+
* The shader three compiled this material with, or null before the first
|
|
96
|
+
* compile and after {@link IblOverride.restore}. Uniform writes go through
|
|
97
|
+
* `shader.uniforms`.
|
|
98
|
+
*/
|
|
99
|
+
readonly shader: IblOverrideShader | null;
|
|
100
|
+
/** Put the material's own `onBeforeCompile`/`customProgramCacheKey` back. */
|
|
101
|
+
restore(): void;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* Install the override. The returned handle is the only way to reach the
|
|
106
|
+
* compiled shader or to undo the patch; the material is otherwise untouched
|
|
107
|
+
* (in particular this never assigns `envMap`, which stays the caller's).
|
|
108
|
+
*
|
|
109
|
+
* The caller's own `onBeforeCompile` runs FIRST and its result is what gets
|
|
110
|
+
* spliced, so an override composes over a material that already had one.
|
|
111
|
+
*/
|
|
112
|
+
export function overrideMaterialIbl(
|
|
113
|
+
material: MeshStandardMaterial,
|
|
114
|
+
options: IblOverrideOptions,
|
|
115
|
+
): IblOverride {
|
|
116
|
+
const previousCompile = material.onBeforeCompile;
|
|
117
|
+
const previousCacheKey = material.customProgramCacheKey;
|
|
118
|
+
let compiled: IblOverrideShader | null = null;
|
|
119
|
+
|
|
120
|
+
material.onBeforeCompile = (shader, renderer) => {
|
|
121
|
+
previousCompile.call(material, shader, renderer);
|
|
122
|
+
requireChunk(shader.vertexShader, '#include <worldpos_vertex>');
|
|
123
|
+
requireChunk(shader.fragmentShader, '#include <envmap_physical_pars_fragment>');
|
|
124
|
+
shader.vertexShader = `varying vec3 ${IBL_WORLD_POSITION};\n${shader.vertexShader.replace(
|
|
125
|
+
'#include <worldpos_vertex>',
|
|
126
|
+
`#include <worldpos_vertex>
|
|
127
|
+
#if defined(USE_ENVMAP)
|
|
128
|
+
${IBL_WORLD_POSITION} = worldPosition.xyz;
|
|
129
|
+
#endif`,
|
|
130
|
+
)}`;
|
|
131
|
+
shader.fragmentShader = `varying vec3 ${IBL_WORLD_POSITION};\n${shader.fragmentShader.replace(
|
|
132
|
+
'#include <envmap_physical_pars_fragment>',
|
|
133
|
+
options.fragment(),
|
|
134
|
+
)}`;
|
|
135
|
+
compiled = shader;
|
|
136
|
+
options.onCompile?.(shader);
|
|
137
|
+
};
|
|
138
|
+
material.customProgramCacheKey = () => `${previousCacheKey.call(material)}|${options.cacheKey()}`;
|
|
139
|
+
material.needsUpdate = true;
|
|
140
|
+
|
|
141
|
+
return {
|
|
142
|
+
material,
|
|
143
|
+
get shader() {
|
|
144
|
+
return compiled;
|
|
145
|
+
},
|
|
146
|
+
restore() {
|
|
147
|
+
material.onBeforeCompile = previousCompile;
|
|
148
|
+
material.customProgramCacheKey = previousCacheKey;
|
|
149
|
+
material.needsUpdate = true;
|
|
150
|
+
compiled = null;
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* A missing chunk is a NAMED error rather than a silent no-op.
|
|
157
|
+
*
|
|
158
|
+
* `String.replace` with no match returns the string unchanged, which would
|
|
159
|
+
* leave the varying declared and never assigned — a shader that links and
|
|
160
|
+
* renders the wrong thing. The only way to reach this today is a preceding
|
|
161
|
+
* `onBeforeCompile` in the same chain having already replaced the chunk (two
|
|
162
|
+
* IBL overrides stacked on one material), and that is worth a message naming
|
|
163
|
+
* the chunk instead of a black frame.
|
|
164
|
+
*/
|
|
165
|
+
function requireChunk(source: string, chunk: string): void {
|
|
166
|
+
if (source.includes(chunk)) return;
|
|
167
|
+
throw new Error(
|
|
168
|
+
`overrideMaterialIbl needs three's ${chunk} shader chunk, and this material's program no longer contains it.`,
|
|
169
|
+
);
|
|
170
|
+
}
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Shared light + camera factory
|
|
2
|
+
* Shared light + camera factory — the ONE place light/camera fallbacks are
|
|
3
|
+
* decided, and it decides them by READING `DEFAULTS.light`/`DEFAULTS.camera`.
|
|
3
4
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* '#ffffff', fov 60, near 0.1, far 1000, etc.) that happened to agree with
|
|
8
|
-
* `DEFAULTS.light`/`DEFAULTS.camera` by luck rather than by reading them. Any
|
|
9
|
-
* edit to one copy (or to `DEFAULTS`) could silently diverge from the other.
|
|
5
|
+
* A second copy hardcoding the same literals (color '#ffffff', fov 60, near
|
|
6
|
+
* 0.1, far 1000) would agree by luck rather than by construction, and any
|
|
7
|
+
* edit to either copy — or to `DEFAULTS` — would silently diverge.
|
|
10
8
|
*
|
|
11
9
|
* This module is now the ONE place that builds a `THREE.Light`/`THREE.Camera`
|
|
12
10
|
* from a `LightDescriptor`/`CameraDescriptor` descriptor, reading its fallbacks from
|
|
@@ -22,10 +20,9 @@ import * as THREE from 'three';
|
|
|
22
20
|
// `three/addons/*` alias (package.json `exports`: `"./addons/*":
|
|
23
21
|
// "./examples/jsm/*"` — the identical file as
|
|
24
22
|
// `three/examples/jsm/lights/RectAreaLightUniformsLib.js`) because a literal
|
|
25
|
-
// `/examples/` specifier trips
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
// to three.js's addon folder naming).
|
|
23
|
+
// `/examples/` specifier trips this repo's game/editor-example import guard —
|
|
24
|
+
// a same-substring false positive against our own `src/examples/` convention,
|
|
25
|
+
// unrelated to three.js's addon folder naming.
|
|
29
26
|
import { RectAreaLightUniformsLib } from 'three/addons/lights/RectAreaLightUniformsLib.js';
|
|
30
27
|
import type { CameraDescriptor } from '../asset-formats/camera';
|
|
31
28
|
import type { LightDescriptor } from '../asset-formats/light';
|
|
@@ -65,7 +65,7 @@ export function createMaterial(mat?: MaterialDescriptor): THREE.Material {
|
|
|
65
65
|
// R1c — every fallback below reads DEFAULTS.material.* instead of
|
|
66
66
|
// duplicating its value as a bare literal, so DEFAULTS stays the single
|
|
67
67
|
// source of truth for what an omitted field renders as (see
|
|
68
|
-
//
|
|
68
|
+
// `material-factory.test.ts`'s
|
|
69
69
|
// "omitted-field" locks, which fail if either copy drifts from the other).
|
|
70
70
|
const dMat = DEFAULTS.material;
|
|
71
71
|
const sideValue = mat.side ?? dMat.side;
|
|
@@ -13,21 +13,29 @@ import { staticBatchSignature } from './structural-signature';
|
|
|
13
13
|
* N logical objects → 1 draw call, ~0 CPU/frame. This is the classic "static
|
|
14
14
|
* batching" technique (cf. Unity/PlayCanvas static batch groups).
|
|
15
15
|
*
|
|
16
|
-
* Strategy 1 (keep identity, don't merge). Moving entities (boids-style,
|
|
17
|
-
* concern
|
|
16
|
+
* Strategy 1 (keep identity, don't merge). Moving entities (boids-style,
|
|
17
|
+
* all-frame churn) are a separate concern, and the engine does not answer it:
|
|
18
|
+
* a game's production answer is the `static-batch` capability's `<Frozen>`
|
|
19
|
+
* (see the scope note below).
|
|
18
20
|
*
|
|
19
21
|
* Eligibility (anything failing stays an ordinary draw — degrade, don't break):
|
|
20
22
|
* - plain THREE.Mesh (not Instanced/Skinned/Batched)
|
|
21
23
|
* - single, opaque material (transparency needs per-object sorting)
|
|
22
24
|
* - group of ≥2 sharing (geometry, material, shadow flags)
|
|
23
|
-
* -
|
|
25
|
+
* - (there is no per-entity opt-out setting: this docblock used to name
|
|
26
|
+
* `entity.render.autoBatch === false`, a render-feature field NO CODE HERE
|
|
27
|
+
* OR ANYWHERE EVER READ. The field was deleted with R-2's coverage fix;
|
|
28
|
+
* opting a subtree out is the `static-batch` capability's `<Frozen>`
|
|
29
|
+
* declaration, per the scope note below.)
|
|
24
30
|
* - STATIC members (no physics/components/animation) → detached; MOVING members →
|
|
25
31
|
* kept in-graph hidden + dirty-synced each frame. A bucket may split into both.
|
|
26
32
|
*
|
|
27
33
|
* Scope / limitations (v1):
|
|
28
|
-
* - NOT WIRED: nothing in the engine calls build()
|
|
29
|
-
*
|
|
30
|
-
*
|
|
34
|
+
* - NOT WIRED: nothing in the engine calls build(), and nothing constructs
|
|
35
|
+
* this class. The only remaining reference is the hosted editor's
|
|
36
|
+
* project-script module map (`editor/src/browser-project-scripts.ts`),
|
|
37
|
+
* which loads the module so a project script MAY drive it; the example
|
|
38
|
+
* that used to is gone. That is settled, not pending: a game's
|
|
31
39
|
* production answer is the `static-batch` capability's `<Frozen>`, a
|
|
32
40
|
* DECLARED mount-static subtree in the game's own TSX, and `dev/static-
|
|
33
41
|
* batch-advisor.ts` is what routes an author to it by measurement. Full-
|
|
@@ -2,12 +2,23 @@ import { z } from 'zod';
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* The render-feature registry — single source of truth for every togglable render
|
|
5
|
-
* setting. The
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
5
|
+
* setting. The render-env schema (`asset-formats/render-env.ts`) and the cascade
|
|
6
|
+
* resolver (`resolveRenderSettings`) are both derived from this list, so
|
|
7
|
+
* "everything togglable" stays consistent by construction (same posture as the
|
|
8
|
+
* component/material/instancer registries).
|
|
9
|
+
*
|
|
10
|
+
* EVERY ENTRY HERE MUST HAVE A RUNTIME READER of its resolved value, and that is
|
|
11
|
+
* now enforced: `schema-reader-coverage.test.ts` derives its walk from this
|
|
12
|
+
* array, so adding a feature adds a described schema path that fails coverage
|
|
13
|
+
* until `schema-consumption-map.ts` names the file that reads it.
|
|
14
|
+
*
|
|
15
|
+
* Three entries were deleted when that enforcement first ran, having reached it
|
|
16
|
+
* with no reader at all: `autoBatch` (its only mention was a COMMENT in
|
|
17
|
+
* `render-batch-system.ts`, a class whose own header says nothing calls it),
|
|
18
|
+
* `lod`, and `backend` (which offered a `webgpu` option while
|
|
19
|
+
* `setup-renderer.ts` unconditionally constructs a `THREE.WebGLRenderer`). A
|
|
20
|
+
* toggle that changes nothing is worse than a missing one — it tells an author
|
|
21
|
+
* the engine has a dial it does not have.
|
|
11
22
|
*/
|
|
12
23
|
|
|
13
24
|
export type RenderFeatureValue = boolean | number | string;
|
|
@@ -37,16 +48,6 @@ export interface RenderFeature {
|
|
|
37
48
|
}
|
|
38
49
|
|
|
39
50
|
export const RENDER_FEATURES: readonly RenderFeature[] = [
|
|
40
|
-
{
|
|
41
|
-
key: 'autoBatch',
|
|
42
|
-
label: 'Auto-batching',
|
|
43
|
-
description:
|
|
44
|
-
'Automatically batch entities sharing geometry+material into one draw call (InstancedMesh/BatchedMesh) while keeping each Object3D as the handle. The headline perf win; opt out per-entity for custom-shader/skinned meshes.',
|
|
45
|
-
kind: 'toggle',
|
|
46
|
-
default: true,
|
|
47
|
-
apply: 'live',
|
|
48
|
-
perEntity: true,
|
|
49
|
-
},
|
|
50
51
|
{
|
|
51
52
|
key: 'frustumCulling',
|
|
52
53
|
label: 'Frustum culling',
|
|
@@ -56,15 +57,6 @@ export const RENDER_FEATURES: readonly RenderFeature[] = [
|
|
|
56
57
|
apply: 'live',
|
|
57
58
|
perEntity: true,
|
|
58
59
|
},
|
|
59
|
-
{
|
|
60
|
-
key: 'lod',
|
|
61
|
-
label: 'Level of detail',
|
|
62
|
-
description: 'Distance-based geometry swap (LOD) for eligible entities.',
|
|
63
|
-
kind: 'toggle',
|
|
64
|
-
default: true,
|
|
65
|
-
apply: 'live',
|
|
66
|
-
perEntity: true,
|
|
67
|
-
},
|
|
68
60
|
{
|
|
69
61
|
key: 'shadows',
|
|
70
62
|
label: 'Shadows',
|
|
@@ -103,16 +95,6 @@ export const RENDER_FEATURES: readonly RenderFeature[] = [
|
|
|
103
95
|
apply: 'reload',
|
|
104
96
|
perEntity: false,
|
|
105
97
|
},
|
|
106
|
-
{
|
|
107
|
-
key: 'backend',
|
|
108
|
-
label: 'Renderer backend',
|
|
109
|
-
description: 'GPU backend: auto picks WebGPU when available, else WebGL2. Applies on reload.',
|
|
110
|
-
kind: 'enum',
|
|
111
|
-
default: 'auto',
|
|
112
|
-
apply: 'reload',
|
|
113
|
-
perEntity: false,
|
|
114
|
-
options: ['auto', 'webgl', 'webgpu'],
|
|
115
|
-
},
|
|
116
98
|
];
|
|
117
99
|
|
|
118
100
|
/** Map for O(1) lookup by key. */
|