@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.
Files changed (339) hide show
  1. package/README.md +6 -3
  2. package/dist/adapter/adapter-module.d.ts.map +1 -1
  3. package/dist/adapter/adapter-module.js +2 -4
  4. package/dist/adapter/adapter-surface.d.ts +1 -1
  5. package/dist/adapter/adapter-surface.js +1 -1
  6. package/dist/adapter/authoring.d.ts +19 -21
  7. package/dist/adapter/authoring.d.ts.map +1 -1
  8. package/dist/adapter/authoring.js +2 -2
  9. package/dist/adapter/binding.d.ts +341 -0
  10. package/dist/adapter/binding.d.ts.map +1 -0
  11. package/dist/adapter/binding.js +148 -0
  12. package/dist/adapter/colyseus-networking-adapter.d.ts.map +1 -1
  13. package/dist/adapter/colyseus-networking-adapter.js +23 -4
  14. package/dist/adapter/entrypoint-selection-readers.d.ts +24 -0
  15. package/dist/adapter/entrypoint-selection-readers.d.ts.map +1 -0
  16. package/dist/adapter/entrypoint-selection-readers.js +63 -0
  17. package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -1
  18. package/dist/adapter/entrypoint-selection-source.js +1 -44
  19. package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
  20. package/dist/adapter/finders/scenes-from-entrypoint-selection.js +1 -52
  21. package/dist/adapter/host-context.d.ts +46 -15
  22. package/dist/adapter/host-context.d.ts.map +1 -1
  23. package/dist/adapter/host-context.js +2 -9
  24. package/dist/adapter/index.d.ts +11 -12
  25. package/dist/adapter/index.d.ts.map +1 -1
  26. package/dist/adapter/index.js +9 -10
  27. package/dist/adapter/ingest/game-contract.d.ts +0 -3
  28. package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
  29. package/dist/adapter/ingest/game-contract.js +0 -3
  30. package/dist/adapter/ingest/scene-capture.d.ts +19 -23
  31. package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
  32. package/dist/adapter/ingest/scene-capture.js +143 -17
  33. package/dist/adapter/ingest/visible-capture-window.d.ts +34 -0
  34. package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
  35. package/dist/adapter/manifest-interpreter.d.ts +59 -0
  36. package/dist/adapter/manifest-interpreter.d.ts.map +1 -0
  37. package/dist/adapter/manifest-interpreter.js +50 -0
  38. package/dist/adapter/native-debug-module.d.ts +71 -3
  39. package/dist/adapter/native-debug-module.d.ts.map +1 -1
  40. package/dist/adapter/native-debug-module.js +146 -10
  41. package/dist/adapter/rapier-physics-adapter.d.ts +31 -1
  42. package/dist/adapter/rapier-physics-adapter.d.ts.map +1 -1
  43. package/dist/adapter/rapier-physics-adapter.js +50 -36
  44. package/dist/adapter/renderer-config.d.ts +3 -3
  45. package/dist/adapter/renderer-config.js +3 -3
  46. package/dist/adapter/root-adapter.d.ts +7 -7
  47. package/dist/adapter/root-adapter.js +4 -4
  48. package/dist/adapter/system-adapter.d.ts +45 -7
  49. package/dist/adapter/system-adapter.d.ts.map +1 -1
  50. package/dist/adapter/system-seam-contract.d.ts +3 -3
  51. package/dist/adapter/system-seam-contract.js +3 -3
  52. package/dist/adapter/system-slot.d.ts +168 -0
  53. package/dist/adapter/system-slot.d.ts.map +1 -0
  54. package/dist/adapter/system-slot.js +229 -0
  55. package/dist/adapter/transform.d.ts +11 -1
  56. package/dist/adapter/transform.d.ts.map +1 -1
  57. package/dist/ai/navigation.d.ts +17 -1
  58. package/dist/ai/navigation.d.ts.map +1 -1
  59. package/dist/ai/navigation.js +26 -5
  60. package/dist/animation/anim-graph-types.d.ts +11 -3
  61. package/dist/animation/anim-graph-types.d.ts.map +1 -1
  62. package/dist/animation/theatre-clock-binding.d.ts +4 -4
  63. package/dist/animation/theatre-clock-binding.js +4 -4
  64. package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
  65. package/dist/animation/xstate-animation-binding.js +2 -2
  66. package/dist/animation/xstate-animation-meta.d.ts +13 -0
  67. package/dist/animation/xstate-animation-meta.d.ts.map +1 -1
  68. package/dist/animation/xstate-animation-meta.js +14 -0
  69. package/dist/asset-formats/index.d.ts +4 -7
  70. package/dist/asset-formats/index.d.ts.map +1 -1
  71. package/dist/asset-formats/index.js +4 -7
  72. package/dist/asset-formats/render-env.d.ts +5 -8
  73. package/dist/asset-formats/render-env.d.ts.map +1 -1
  74. package/dist/asset-formats/render-env.js +3 -6
  75. package/dist/asset-parse-error.d.ts +2 -5
  76. package/dist/asset-parse-error.d.ts.map +1 -1
  77. package/dist/asset-parse-error.js +2 -5
  78. package/dist/audio/bus-mixer.d.ts +101 -0
  79. package/dist/audio/bus-mixer.d.ts.map +1 -0
  80. package/dist/audio/bus-mixer.js +115 -0
  81. package/dist/canvas-react/index.d.ts +5 -12
  82. package/dist/canvas-react/index.d.ts.map +1 -1
  83. package/dist/canvas-react/index.js +5 -12
  84. package/dist/canvas-react/pixi-react-root-factory.d.ts +34 -21
  85. package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
  86. package/dist/canvas-react/pixi-react-root-factory.js +274 -36
  87. package/dist/core/countdown-timer.d.ts +118 -0
  88. package/dist/core/countdown-timer.d.ts.map +1 -0
  89. package/dist/core/countdown-timer.js +137 -0
  90. package/dist/core/deferred-commands.d.ts +127 -0
  91. package/dist/core/deferred-commands.d.ts.map +1 -0
  92. package/dist/core/deferred-commands.js +132 -0
  93. package/dist/core/frame-pacing.d.ts +1 -1
  94. package/dist/core/frame-pacing.js +2 -2
  95. package/dist/core/game-loop.d.ts +1 -3
  96. package/dist/core/game-loop.d.ts.map +1 -1
  97. package/dist/core/game-loop.js +1 -3
  98. package/dist/core/seeded-random.d.ts +1 -1
  99. package/dist/core/sim-clock.d.ts +19 -8
  100. package/dist/core/sim-clock.d.ts.map +1 -1
  101. package/dist/core/sim-clock.js +18 -7
  102. package/dist/core/types.d.ts +1 -3
  103. package/dist/core/types.d.ts.map +1 -1
  104. package/dist/defaults.d.ts +6 -14
  105. package/dist/defaults.d.ts.map +1 -1
  106. package/dist/defaults.js +6 -14
  107. package/dist/dev/instruments.d.ts +38 -11
  108. package/dist/dev/instruments.d.ts.map +1 -1
  109. package/dist/dev/instruments.js +81 -11
  110. package/dist/dev/register-render-vitals.d.ts +1 -4
  111. package/dist/dev/register-render-vitals.d.ts.map +1 -1
  112. package/dist/dev/register-render-vitals.js +1 -4
  113. package/dist/dev/render-debug-adapter.d.ts +2 -3
  114. package/dist/dev/render-debug-adapter.d.ts.map +1 -1
  115. package/dist/dev/render-debug-adapter.js +2 -3
  116. package/dist/dev/render-vitals.d.ts +3 -3
  117. package/dist/dev/render-vitals.js +3 -3
  118. package/dist/dev/webgl-frame-capture.d.ts +1 -1
  119. package/dist/dev/webgl-frame-capture.js +1 -1
  120. package/dist/index.d.ts +2 -5
  121. package/dist/index.d.ts.map +1 -1
  122. package/dist/index.js +2 -4
  123. package/dist/input/host-pointer.d.ts +122 -0
  124. package/dist/input/host-pointer.d.ts.map +1 -0
  125. package/dist/input/host-pointer.js +160 -0
  126. package/dist/input/input-manager.d.ts +33 -5
  127. package/dist/input/input-manager.d.ts.map +1 -1
  128. package/dist/input/input-manager.js +48 -13
  129. package/dist/input/rebind-controller.d.ts.map +1 -1
  130. package/dist/input/rebind-controller.js +6 -8
  131. package/dist/input/schema.d.ts.map +1 -1
  132. package/dist/input/schema.js +56 -28
  133. package/dist/manifest/filename.d.ts.map +1 -1
  134. package/dist/manifest/filename.js +8 -12
  135. package/dist/manifest/load.d.ts +10 -10
  136. package/dist/manifest/load.d.ts.map +1 -1
  137. package/dist/manifest/load.js +9 -6
  138. package/dist/manifest/schema.d.ts +17 -21
  139. package/dist/manifest/schema.d.ts.map +1 -1
  140. package/dist/manifest/schema.js +45 -35
  141. package/dist/physics/collider-dimensions.d.ts +8 -12
  142. package/dist/physics/collider-dimensions.d.ts.map +1 -1
  143. package/dist/physics/collider-dimensions.js +8 -12
  144. package/dist/pixi/scene-capture.d.ts +11 -13
  145. package/dist/pixi/scene-capture.d.ts.map +1 -1
  146. package/dist/react/world-state.d.ts +1 -1
  147. package/dist/react/world-state.d.ts.map +1 -1
  148. package/dist/render/directional-shadow-fit.d.ts +88 -0
  149. package/dist/render/directional-shadow-fit.d.ts.map +1 -0
  150. package/dist/render/directional-shadow-fit.js +133 -0
  151. package/dist/render/environment-capture.d.ts +68 -0
  152. package/dist/render/environment-capture.d.ts.map +1 -0
  153. package/dist/render/environment-capture.js +90 -0
  154. package/dist/render/ibl-override-material.d.ts +97 -0
  155. package/dist/render/ibl-override-material.d.ts.map +1 -0
  156. package/dist/render/ibl-override-material.js +114 -0
  157. package/dist/render/light-camera-factory.d.ts +5 -7
  158. package/dist/render/light-camera-factory.d.ts.map +1 -1
  159. package/dist/render/light-camera-factory.js +8 -11
  160. package/dist/render/material-factory.js +1 -1
  161. package/dist/render/render-batch-system.d.ts.map +1 -1
  162. package/dist/render/render-features.d.ts +17 -6
  163. package/dist/render/render-features.d.ts.map +1 -1
  164. package/dist/render/render-features.js +0 -28
  165. package/dist/runtime/create-runtime.d.ts +34 -25
  166. package/dist/runtime/create-runtime.d.ts.map +1 -1
  167. package/dist/runtime/create-runtime.js +218 -93
  168. package/dist/runtime/debug-registry.d.ts +77 -8
  169. package/dist/runtime/debug-registry.d.ts.map +1 -1
  170. package/dist/runtime/debug-registry.js +3 -3
  171. package/dist/runtime/dev-build.d.ts +2 -2
  172. package/dist/runtime/dev-build.js +2 -2
  173. package/dist/runtime/game-input-seams.d.ts +51 -0
  174. package/dist/runtime/game-input-seams.d.ts.map +1 -0
  175. package/dist/runtime/game-input-seams.js +86 -0
  176. package/dist/runtime/game.d.ts +104 -40
  177. package/dist/runtime/game.d.ts.map +1 -1
  178. package/dist/runtime/game.js +119 -61
  179. package/dist/runtime/mount-game.d.ts +0 -16
  180. package/dist/runtime/mount-game.d.ts.map +1 -1
  181. package/dist/runtime/mount-game.js +26 -41
  182. package/dist/runtime/mount-manifest.d.ts +22 -14
  183. package/dist/runtime/mount-manifest.d.ts.map +1 -1
  184. package/dist/runtime/mount-manifest.js +22 -20
  185. package/dist/runtime/playtest.d.ts +22 -0
  186. package/dist/runtime/playtest.d.ts.map +1 -0
  187. package/dist/runtime/playtest.js +12 -0
  188. package/dist/runtime/state-bridge.d.ts +2 -3
  189. package/dist/runtime/state-bridge.d.ts.map +1 -1
  190. package/dist/runtime/state-bridge.js +1 -0
  191. package/dist/setup/setup-audio.d.ts +12 -0
  192. package/dist/setup/setup-audio.d.ts.map +1 -1
  193. package/dist/setup/setup-audio.js +9 -10
  194. package/dist/setup/setup-renderer.d.ts +2 -25
  195. package/dist/setup/setup-renderer.d.ts.map +1 -1
  196. package/dist/setup/setup-renderer.js +2 -31
  197. package/dist/world3d-react/index.d.ts +15 -25
  198. package/dist/world3d-react/index.d.ts.map +1 -1
  199. package/dist/world3d-react/index.js +15 -25
  200. package/dist/world3d-react/r3f-root-factory.d.ts +28 -34
  201. package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
  202. package/dist/world3d-react/r3f-root-factory.js +403 -57
  203. package/dist/world3d-react/rapier-physics-bridge.d.ts +30 -17
  204. package/dist/world3d-react/rapier-physics-bridge.d.ts.map +1 -1
  205. package/dist/world3d-react/rapier-physics-bridge.js +143 -58
  206. package/package.json +1 -1
  207. package/schemas/engine-capabilities.json +16 -14
  208. package/schemas/vgai-project.schema.json +35 -26
  209. package/src/adapter/adapter-module.ts +2 -4
  210. package/src/adapter/adapter-surface.ts +1 -1
  211. package/src/adapter/authoring.ts +19 -21
  212. package/src/adapter/binding.ts +468 -0
  213. package/src/adapter/colyseus-networking-adapter.ts +20 -5
  214. package/src/adapter/entrypoint-selection-readers.ts +66 -0
  215. package/src/adapter/entrypoint-selection-source.ts +1 -40
  216. package/src/adapter/finders/scenes-from-entrypoint-selection.ts +1 -48
  217. package/src/adapter/host-context.ts +45 -15
  218. package/src/adapter/index.ts +23 -11
  219. package/src/adapter/ingest/game-contract.ts +0 -3
  220. package/src/adapter/ingest/scene-capture.ts +190 -39
  221. package/src/adapter/ingest/visible-capture-window.ts +35 -0
  222. package/src/adapter/manifest-interpreter.ts +64 -0
  223. package/src/adapter/native-debug-module.ts +248 -15
  224. package/src/adapter/rapier-physics-adapter.ts +76 -20
  225. package/src/adapter/renderer-config.ts +3 -3
  226. package/src/adapter/root-adapter.ts +7 -7
  227. package/src/adapter/system-adapter.ts +43 -8
  228. package/src/adapter/system-seam-contract.ts +3 -3
  229. package/src/adapter/system-slot.ts +291 -0
  230. package/src/adapter/transform.ts +18 -1
  231. package/src/ai/navigation.ts +30 -3
  232. package/src/animation/anim-graph-types.ts +11 -3
  233. package/src/animation/theatre-clock-binding.ts +4 -4
  234. package/src/animation/xstate-animation-binding.ts +2 -2
  235. package/src/animation/xstate-animation-meta.ts +16 -0
  236. package/src/asset-formats/index.ts +4 -7
  237. package/src/asset-formats/render-env.ts +3 -6
  238. package/src/asset-parse-error.ts +2 -5
  239. package/src/audio/bus-mixer.ts +161 -0
  240. package/src/canvas-react/index.ts +5 -21
  241. package/src/canvas-react/pixi-react-root-factory.tsx +301 -39
  242. package/src/core/countdown-timer.ts +188 -0
  243. package/src/core/deferred-commands.ts +174 -0
  244. package/src/core/frame-pacing.ts +2 -2
  245. package/src/core/game-loop.ts +1 -3
  246. package/src/core/seeded-random.ts +1 -1
  247. package/src/core/sim-clock.ts +19 -8
  248. package/src/core/types.ts +1 -3
  249. package/src/defaults.ts +6 -14
  250. package/src/dev/instruments.ts +108 -11
  251. package/src/dev/register-render-vitals.ts +1 -4
  252. package/src/dev/render-debug-adapter.ts +2 -3
  253. package/src/dev/render-vitals.ts +3 -3
  254. package/src/dev/webgl-frame-capture.ts +1 -1
  255. package/src/index.ts +2 -5
  256. package/src/input/host-pointer.ts +230 -0
  257. package/src/input/input-manager.ts +49 -13
  258. package/src/input/input-types.ts +1 -1
  259. package/src/input/rebind-controller.ts +6 -8
  260. package/src/input/schema.ts +216 -188
  261. package/src/manifest/filename.ts +8 -12
  262. package/src/manifest/load.ts +17 -13
  263. package/src/manifest/schema.ts +55 -47
  264. package/src/physics/collider-dimensions.ts +8 -12
  265. package/src/pixi/scene-capture.ts +12 -15
  266. package/src/react/world-state.tsx +1 -1
  267. package/src/render/directional-shadow-fit.ts +156 -0
  268. package/src/render/environment-capture.ts +102 -0
  269. package/src/render/ibl-override-material.ts +170 -0
  270. package/src/render/light-camera-factory.ts +8 -11
  271. package/src/render/material-factory.ts +1 -1
  272. package/src/render/render-batch-system.ts +14 -6
  273. package/src/render/render-features.ts +17 -35
  274. package/src/runtime/create-runtime.ts +270 -108
  275. package/src/runtime/debug-registry.ts +84 -8
  276. package/src/runtime/dev-build.ts +2 -2
  277. package/src/runtime/game-input-seams.ts +108 -0
  278. package/src/runtime/game.ts +231 -85
  279. package/src/runtime/mount-game.ts +31 -57
  280. package/src/runtime/mount-manifest.ts +47 -36
  281. package/src/runtime/playtest.ts +22 -0
  282. package/src/runtime/state-bridge.ts +3 -3
  283. package/src/setup/setup-audio.ts +21 -11
  284. package/src/setup/setup-renderer.ts +2 -61
  285. package/src/world3d-react/index.ts +15 -31
  286. package/src/world3d-react/r3f-root-factory.tsx +451 -60
  287. package/src/world3d-react/rapier-physics-bridge.tsx +154 -58
  288. package/dist/adapter/setup-three-root-adapter.d.ts +0 -86
  289. package/dist/adapter/setup-three-root-adapter.d.ts.map +0 -1
  290. package/dist/adapter/setup-three-root-adapter.js +0 -908
  291. package/dist/animation/clip-map.d.ts +0 -12
  292. package/dist/animation/clip-map.d.ts.map +0 -1
  293. package/dist/animation/clip-map.js +0 -31
  294. package/dist/asset-registry.d.ts +0 -38
  295. package/dist/asset-registry.d.ts.map +0 -1
  296. package/dist/asset-registry.js +0 -66
  297. package/dist/canvas-react/engine-bridge.d.ts +0 -45
  298. package/dist/canvas-react/engine-bridge.d.ts.map +0 -1
  299. package/dist/canvas-react/engine-bridge.js +0 -45
  300. package/dist/canvas-react/pixi-react-adapter.d.ts +0 -77
  301. package/dist/canvas-react/pixi-react-adapter.d.ts.map +0 -1
  302. package/dist/canvas-react/pixi-react-adapter.js +0 -294
  303. package/dist/canvas-react/world-context.d.ts +0 -98
  304. package/dist/canvas-react/world-context.d.ts.map +0 -1
  305. package/dist/canvas-react/world-context.js +0 -173
  306. package/dist/dev/debug-draw.d.ts +0 -24
  307. package/dist/dev/debug-draw.d.ts.map +0 -1
  308. package/dist/dev/debug-draw.js +0 -73
  309. package/dist/render/auto-batcher.d.ts +0 -34
  310. package/dist/render/auto-batcher.d.ts.map +0 -1
  311. package/dist/render/auto-batcher.js +0 -140
  312. package/dist/render/lod.d.ts +0 -13
  313. package/dist/render/lod.d.ts.map +0 -1
  314. package/dist/render/lod.js +0 -16
  315. package/dist/runtime/types.d.ts +0 -303
  316. package/dist/runtime/types.d.ts.map +0 -1
  317. package/dist/runtime/types.js +0 -1
  318. package/dist/world3d-react/engine-bridge.d.ts +0 -47
  319. package/dist/world3d-react/engine-bridge.d.ts.map +0 -1
  320. package/dist/world3d-react/engine-bridge.js +0 -73
  321. package/dist/world3d-react/r3f-adapter.d.ts +0 -58
  322. package/dist/world3d-react/r3f-adapter.d.ts.map +0 -1
  323. package/dist/world3d-react/r3f-adapter.js +0 -634
  324. package/dist/world3d-react/world-context.d.ts +0 -182
  325. package/dist/world3d-react/world-context.d.ts.map +0 -1
  326. package/dist/world3d-react/world-context.js +0 -235
  327. package/src/adapter/setup-three-root-adapter.ts +0 -1032
  328. package/src/animation/clip-map.ts +0 -34
  329. package/src/asset-registry.ts +0 -89
  330. package/src/canvas-react/engine-bridge.ts +0 -59
  331. package/src/canvas-react/pixi-react-adapter.tsx +0 -356
  332. package/src/canvas-react/world-context.ts +0 -253
  333. package/src/dev/debug-draw.ts +0 -80
  334. package/src/render/auto-batcher.ts +0 -168
  335. package/src/render/lod.ts +0 -17
  336. package/src/runtime/types.ts +0 -328
  337. package/src/world3d-react/engine-bridge.ts +0 -86
  338. package/src/world3d-react/r3f-adapter.tsx +0 -717
  339. 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 (T1.13 DEFAULTS truth).
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
- * `createLight`/`createCamera` used to be duplicated verbatim between the
5
- * runtime loader (`scene-loader.ts`) and the editor preview
6
- * (`entity-factory.ts`)both hardcoded the same fallback literals (color
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 `engine-host-no-game-imports.test.ts`'s
26
- // game/editor-example guard (a same-substring false positive against this
27
- // repo's OWN `packages/editor/template/src/examples/` convention, unrelated
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
- // defaults-out-of-scope-consistency.test.ts / material-factory.test.ts's
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, all-frame churn) are a separate
17
- * concern see render/auto-batcher.ts (dynamic).
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
- * - not explicitly opted out (`entity.render.autoBatch === false`)
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() the rendering-scale
29
- * example's render lab is the only driver (via the hosted-module map), and
30
- * no adapter batches automatically. That is settled, not pending: a game's
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 scene schema (`SceneEnvironment.rendering`, `SceneEntity.render`),
6
- * the cascade resolver (`resolveRenderSettings`), the editor UI, and the stats
7
- * overlay are all derived from this list, so "everything togglable" stays
8
- * consistent by construction (same posture as the component/material/instancer
9
- * registries). Adding a feature here gives it a schema field + cascade entry for
10
- * free..
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. */