@aura3d/engine 1.4.4 → 1.5.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.
Files changed (487) hide show
  1. package/README.md +65 -30
  2. package/dist/animation/Retargeting.d.ts +12 -0
  3. package/dist/animation/Retargeting.d.ts.map +1 -0
  4. package/dist/animation/Retargeting.js +19 -0
  5. package/dist/animation/Retargeting.js.map +1 -0
  6. package/dist/assets/GLTFLoader.d.ts +4 -0
  7. package/dist/assets/GLTFLoader.d.ts.map +1 -1
  8. package/dist/assets/GLTFLoader.js +39 -4
  9. package/dist/assets/GLTFLoader.js.map +1 -1
  10. package/dist/assets/GLTFRenderResources.d.ts +16 -0
  11. package/dist/assets/GLTFRenderResources.d.ts.map +1 -1
  12. package/dist/assets/GLTFRenderResources.js +42 -2
  13. package/dist/assets/GLTFRenderResources.js.map +1 -1
  14. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.d.ts +6 -0
  15. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.d.ts.map +1 -1
  16. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.js +2 -1
  17. package/dist/assets/asset-corpus/ProductionGLTFRenderPipeline.js.map +1 -1
  18. package/dist/assets/index.d.ts +0 -1
  19. package/dist/assets/index.d.ts.map +1 -1
  20. package/dist/assets/index.js +0 -1
  21. package/dist/assets/index.js.map +1 -1
  22. package/dist/assets/loaders/index.d.ts +0 -1
  23. package/dist/assets/loaders/index.d.ts.map +1 -1
  24. package/dist/assets/loaders/index.js +0 -1
  25. package/dist/assets/loaders/index.js.map +1 -1
  26. package/dist/aura3d-cli/asset-intent.d.ts +148 -0
  27. package/dist/aura3d-cli/asset-intent.d.ts.map +1 -0
  28. package/dist/aura3d-cli/asset-intent.js +145 -0
  29. package/dist/aura3d-cli/asset-intent.js.map +1 -0
  30. package/dist/aura3d-cli/asset-role-admission.d.ts +174 -0
  31. package/dist/aura3d-cli/asset-role-admission.d.ts.map +1 -0
  32. package/dist/aura3d-cli/asset-role-admission.js +381 -0
  33. package/dist/aura3d-cli/asset-role-admission.js.map +1 -0
  34. package/dist/aura3d-cli/asset-screening-effects.d.ts +95 -0
  35. package/dist/aura3d-cli/asset-screening-effects.d.ts.map +1 -0
  36. package/dist/aura3d-cli/asset-screening-effects.js +321 -0
  37. package/dist/aura3d-cli/asset-screening-effects.js.map +1 -0
  38. package/dist/aura3d-cli/asset-screening-pipeline.d.ts +132 -0
  39. package/dist/aura3d-cli/asset-screening-pipeline.d.ts.map +1 -0
  40. package/dist/aura3d-cli/asset-screening-pipeline.js +277 -0
  41. package/dist/aura3d-cli/asset-screening-pipeline.js.map +1 -0
  42. package/dist/aura3d-cli/cartoon-asset-profiles.d.ts +15 -0
  43. package/dist/aura3d-cli/cartoon-asset-profiles.d.ts.map +1 -0
  44. package/dist/aura3d-cli/cartoon-asset-profiles.js +46 -0
  45. package/dist/aura3d-cli/cartoon-asset-profiles.js.map +1 -0
  46. package/dist/aura3d-cli/cli-help.js +1 -1
  47. package/dist/aura3d-cli/cli.js +16 -2
  48. package/dist/aura3d-cli/cli.js.map +1 -1
  49. package/dist/aura3d-cli/index.d.ts +8 -0
  50. package/dist/aura3d-cli/index.d.ts.map +1 -1
  51. package/dist/aura3d-cli/index.js +390 -17
  52. package/dist/aura3d-cli/index.js.map +1 -1
  53. package/dist/aura3d-cli/pull-bridge/search.d.ts +4 -0
  54. package/dist/aura3d-cli/pull-bridge/search.d.ts.map +1 -1
  55. package/dist/aura3d-cli/pull-bridge/search.js +22 -0
  56. package/dist/aura3d-cli/pull-bridge/search.js.map +1 -1
  57. package/dist/aura3d-cli/pull-bridge.d.ts +20 -5
  58. package/dist/aura3d-cli/pull-bridge.d.ts.map +1 -1
  59. package/dist/aura3d-cli/pull-bridge.js +38 -1
  60. package/dist/aura3d-cli/pull-bridge.js.map +1 -1
  61. package/dist/controls/ControlState.d.ts +1 -1
  62. package/dist/controls/ControlState.d.ts.map +1 -1
  63. package/dist/controls/DragControls.d.ts +21 -1
  64. package/dist/controls/DragControls.d.ts.map +1 -1
  65. package/dist/controls/DragControls.js +24 -2
  66. package/dist/controls/DragControls.js.map +1 -1
  67. package/dist/controls/FirstPersonControls.d.ts +10 -1
  68. package/dist/controls/FirstPersonControls.d.ts.map +1 -1
  69. package/dist/controls/FirstPersonControls.js +18 -2
  70. package/dist/controls/FirstPersonControls.js.map +1 -1
  71. package/dist/controls/FlyControls.d.ts +42 -0
  72. package/dist/controls/FlyControls.d.ts.map +1 -1
  73. package/dist/controls/FlyControls.js +106 -3
  74. package/dist/controls/FlyControls.js.map +1 -1
  75. package/dist/controls/MapControls.d.ts +13 -0
  76. package/dist/controls/MapControls.d.ts.map +1 -1
  77. package/dist/controls/MapControls.js +40 -2
  78. package/dist/controls/MapControls.js.map +1 -1
  79. package/dist/controls/OrbitControls.d.ts +54 -0
  80. package/dist/controls/OrbitControls.d.ts.map +1 -1
  81. package/dist/controls/OrbitControls.js +133 -0
  82. package/dist/controls/OrbitControls.js.map +1 -1
  83. package/dist/controls/PointerLockControls.d.ts +12 -5
  84. package/dist/controls/PointerLockControls.d.ts.map +1 -1
  85. package/dist/controls/PointerLockControls.js +30 -11
  86. package/dist/controls/PointerLockControls.js.map +1 -1
  87. package/dist/controls/SelectionManager.d.ts +22 -1
  88. package/dist/controls/SelectionManager.d.ts.map +1 -1
  89. package/dist/controls/SelectionManager.js +64 -6
  90. package/dist/controls/SelectionManager.js.map +1 -1
  91. package/dist/controls/TransformControls.d.ts +135 -1
  92. package/dist/controls/TransformControls.d.ts.map +1 -1
  93. package/dist/controls/TransformControls.js +534 -10
  94. package/dist/controls/TransformControls.js.map +1 -1
  95. package/dist/controls/index.d.ts +7 -2
  96. package/dist/controls/index.d.ts.map +1 -1
  97. package/dist/controls/index.js +1 -1
  98. package/dist/controls/index.js.map +1 -1
  99. package/dist/create-aura3d/index.js +1 -1
  100. package/dist/create-aura3d/showcase-spec-game-geometry-extractor.d.ts +2 -0
  101. package/dist/create-aura3d/showcase-spec-game-geometry-extractor.d.ts.map +1 -1
  102. package/dist/create-aura3d/showcase-spec-game-geometry-extractor.js +781 -46
  103. package/dist/create-aura3d/showcase-spec-game-geometry-extractor.js.map +1 -1
  104. package/dist/create-aura3d/showcase-spec-game-template-evidence.d.ts.map +1 -1
  105. package/dist/create-aura3d/showcase-spec-game-template-evidence.js +24 -4
  106. package/dist/create-aura3d/showcase-spec-game-template-evidence.js.map +1 -1
  107. package/dist/create-aura3d/showcase-spec-platformer-artifacts.d.ts.map +1 -1
  108. package/dist/create-aura3d/showcase-spec-platformer-artifacts.js +28 -17
  109. package/dist/create-aura3d/showcase-spec-platformer-artifacts.js.map +1 -1
  110. package/dist/create-aura3d/showcase-spec-racing-artifacts.d.ts.map +1 -1
  111. package/dist/create-aura3d/showcase-spec-racing-artifacts.js +10 -5
  112. package/dist/create-aura3d/showcase-spec-racing-artifacts.js.map +1 -1
  113. package/dist/create-aura3d/showcase-spec-replacement-candidates.js +26 -0
  114. package/dist/create-aura3d/showcase-spec-replacement-candidates.js.map +1 -1
  115. package/dist/ecs/components/MeshComponent.d.ts +5 -2
  116. package/dist/ecs/components/MeshComponent.d.ts.map +1 -1
  117. package/dist/ecs/components/MeshComponent.js.map +1 -1
  118. package/dist/editor-runtime/CartoonSceneEditor.d.ts +111 -0
  119. package/dist/editor-runtime/CartoonSceneEditor.d.ts.map +1 -0
  120. package/dist/editor-runtime/CartoonSceneEditor.js +285 -0
  121. package/dist/editor-runtime/CartoonSceneEditor.js.map +1 -0
  122. package/dist/editor-runtime/InteractiveTransformGizmo.d.ts +142 -0
  123. package/dist/editor-runtime/InteractiveTransformGizmo.d.ts.map +1 -0
  124. package/dist/editor-runtime/InteractiveTransformGizmo.js +468 -0
  125. package/dist/editor-runtime/InteractiveTransformGizmo.js.map +1 -0
  126. package/dist/editor-runtime/index.d.ts +2 -0
  127. package/dist/editor-runtime/index.d.ts.map +1 -1
  128. package/dist/editor-runtime/index.js +1 -0
  129. package/dist/editor-runtime/index.js.map +1 -1
  130. package/dist/engine/agent-api/CartoonAssetManifest.d.ts +50 -0
  131. package/dist/engine/agent-api/CartoonAssetManifest.d.ts.map +1 -0
  132. package/dist/engine/agent-api/CartoonAssetManifest.js +65 -0
  133. package/dist/engine/agent-api/CartoonAssetManifest.js.map +1 -0
  134. package/dist/engine/agent-api/CartoonDirector.d.ts +120 -0
  135. package/dist/engine/agent-api/CartoonDirector.d.ts.map +1 -0
  136. package/dist/engine/agent-api/CartoonDirector.js +432 -0
  137. package/dist/engine/agent-api/CartoonDirector.js.map +1 -0
  138. package/dist/engine/agent-api/CartoonEpisodePackage.d.ts +51 -0
  139. package/dist/engine/agent-api/CartoonEpisodePackage.d.ts.map +1 -0
  140. package/dist/engine/agent-api/CartoonEpisodePackage.js +79 -0
  141. package/dist/engine/agent-api/CartoonEpisodePackage.js.map +1 -0
  142. package/dist/engine/agent-api/CartoonMotionQuality.d.ts +83 -0
  143. package/dist/engine/agent-api/CartoonMotionQuality.d.ts.map +1 -0
  144. package/dist/engine/agent-api/CartoonMotionQuality.js +128 -0
  145. package/dist/engine/agent-api/CartoonMotionQuality.js.map +1 -0
  146. package/dist/engine/agent-api/CartoonPerformance.d.ts +150 -0
  147. package/dist/engine/agent-api/CartoonPerformance.d.ts.map +1 -0
  148. package/dist/engine/agent-api/CartoonPerformance.js +345 -0
  149. package/dist/engine/agent-api/CartoonPerformance.js.map +1 -0
  150. package/dist/engine/agent-api/CartoonRenderQueue.d.ts +143 -0
  151. package/dist/engine/agent-api/CartoonRenderQueue.d.ts.map +1 -0
  152. package/dist/engine/agent-api/CartoonRenderQueue.js +410 -0
  153. package/dist/engine/agent-api/CartoonRenderQueue.js.map +1 -0
  154. package/dist/engine/agent-api/CartoonRouteProof.d.ts +112 -0
  155. package/dist/engine/agent-api/CartoonRouteProof.d.ts.map +1 -0
  156. package/dist/engine/agent-api/CartoonRouteProof.js +127 -0
  157. package/dist/engine/agent-api/CartoonRouteProof.js.map +1 -0
  158. package/dist/engine/agent-api/GameEvidence.d.ts +1 -0
  159. package/dist/engine/agent-api/GameEvidence.d.ts.map +1 -1
  160. package/dist/engine/agent-api/GameEvidence.js +1 -0
  161. package/dist/engine/agent-api/GameEvidence.js.map +1 -1
  162. package/dist/engine/agent-api/GameGenreKits.d.ts +13 -0
  163. package/dist/engine/agent-api/GameGenreKits.d.ts.map +1 -1
  164. package/dist/engine/agent-api/GameGenreKits.js +57 -11
  165. package/dist/engine/agent-api/GameGenreKits.js.map +1 -1
  166. package/dist/engine/agent-api/GameRuntime.d.ts +1 -0
  167. package/dist/engine/agent-api/GameRuntime.d.ts.map +1 -1
  168. package/dist/engine/agent-api/GameRuntime.js +1 -0
  169. package/dist/engine/agent-api/GameRuntime.js.map +1 -1
  170. package/dist/engine/agent-api/GameSceneGeometryBindings.d.ts +12 -0
  171. package/dist/engine/agent-api/GameSceneGeometryBindings.d.ts.map +1 -1
  172. package/dist/engine/agent-api/GameSceneGeometryBindings.js +2 -0
  173. package/dist/engine/agent-api/GameSceneGeometryBindings.js.map +1 -1
  174. package/dist/engine/agent-api/LayeredSceneComposition.d.ts +295 -0
  175. package/dist/engine/agent-api/LayeredSceneComposition.d.ts.map +1 -0
  176. package/dist/engine/agent-api/LayeredSceneComposition.js +387 -0
  177. package/dist/engine/agent-api/LayeredSceneComposition.js.map +1 -0
  178. package/dist/engine/agent-api/SceneGroundingUtils.d.ts +62 -0
  179. package/dist/engine/agent-api/SceneGroundingUtils.d.ts.map +1 -1
  180. package/dist/engine/agent-api/SceneGroundingUtils.js +37 -0
  181. package/dist/engine/agent-api/SceneGroundingUtils.js.map +1 -1
  182. package/dist/engine/agent-api/SubjectFramingUtils.d.ts +127 -0
  183. package/dist/engine/agent-api/SubjectFramingUtils.d.ts.map +1 -0
  184. package/dist/engine/agent-api/SubjectFramingUtils.js +126 -0
  185. package/dist/engine/agent-api/SubjectFramingUtils.js.map +1 -0
  186. package/dist/engine/agent-api/TouchControlBinding.d.ts +81 -0
  187. package/dist/engine/agent-api/TouchControlBinding.d.ts.map +1 -0
  188. package/dist/engine/agent-api/TouchControlBinding.js +116 -0
  189. package/dist/engine/agent-api/TouchControlBinding.js.map +1 -0
  190. package/dist/engine/agent-api/index.d.ts +39 -0
  191. package/dist/engine/agent-api/index.d.ts.map +1 -1
  192. package/dist/engine/agent-api/index.js +546 -74
  193. package/dist/engine/agent-api/index.js.map +1 -1
  194. package/dist/engine/agent-api/product-viewer-runtime.d.ts.map +1 -1
  195. package/dist/engine/production-runtime/GameRenderPreset.d.ts +32 -0
  196. package/dist/engine/production-runtime/GameRenderPreset.d.ts.map +1 -1
  197. package/dist/engine/production-runtime/GameRenderPreset.js +37 -2
  198. package/dist/engine/production-runtime/GameRenderPreset.js.map +1 -1
  199. package/dist/engine/production-runtime/TypedGLBActor.d.ts +8 -0
  200. package/dist/engine/production-runtime/TypedGLBActor.d.ts.map +1 -1
  201. package/dist/engine/production-runtime/TypedGLBActor.js +2 -1
  202. package/dist/engine/production-runtime/TypedGLBActor.js.map +1 -1
  203. package/dist/input/controls/PointerLockControls.d.ts +1 -1
  204. package/dist/input/controls/PointerLockControls.d.ts.map +1 -1
  205. package/dist/input/controls/PointerLockControls.js +12 -0
  206. package/dist/input/controls/PointerLockControls.js.map +1 -1
  207. package/dist/physics/Collider.d.ts +1 -1
  208. package/dist/physics/Collider.d.ts.map +1 -1
  209. package/dist/physics/Collider.js +2 -2
  210. package/dist/physics/Collider.js.map +1 -1
  211. package/dist/physics/CollisionEvents.d.ts +1 -0
  212. package/dist/physics/CollisionEvents.d.ts.map +1 -1
  213. package/dist/physics/CollisionEvents.js.map +1 -1
  214. package/dist/physics/NarrowPhase.d.ts +11 -0
  215. package/dist/physics/NarrowPhase.d.ts.map +1 -0
  216. package/dist/physics/NarrowPhase.js +565 -0
  217. package/dist/physics/NarrowPhase.js.map +1 -0
  218. package/dist/physics/PhysicsDebugDraw.js +19 -1
  219. package/dist/physics/PhysicsDebugDraw.js.map +1 -1
  220. package/dist/physics/PhysicsWorld.d.ts +43 -0
  221. package/dist/physics/PhysicsWorld.d.ts.map +1 -1
  222. package/dist/physics/PhysicsWorld.js +305 -30
  223. package/dist/physics/PhysicsWorld.js.map +1 -1
  224. package/dist/physics/RigidBody.d.ts +8 -1
  225. package/dist/physics/RigidBody.d.ts.map +1 -1
  226. package/dist/physics/RigidBody.js +32 -5
  227. package/dist/physics/RigidBody.js.map +1 -1
  228. package/dist/physics/Shape.d.ts +16 -2
  229. package/dist/physics/Shape.d.ts.map +1 -1
  230. package/dist/physics/Shape.js +93 -31
  231. package/dist/physics/Shape.js.map +1 -1
  232. package/dist/physics/TimeOfImpact.d.ts +15 -0
  233. package/dist/physics/TimeOfImpact.d.ts.map +1 -0
  234. package/dist/physics/TimeOfImpact.js +81 -0
  235. package/dist/physics/TimeOfImpact.js.map +1 -0
  236. package/dist/physics/index.d.ts +2 -0
  237. package/dist/physics/index.d.ts.map +1 -1
  238. package/dist/physics/index.js +2 -0
  239. package/dist/physics/index.js.map +1 -1
  240. package/dist/rendering/CascadedShadowMaps.d.ts +9 -1
  241. package/dist/rendering/CascadedShadowMaps.d.ts.map +1 -1
  242. package/dist/rendering/CascadedShadowMaps.js +68 -0
  243. package/dist/rendering/CascadedShadowMaps.js.map +1 -1
  244. package/dist/rendering/ClusteredForwardLighting.d.ts +28 -0
  245. package/dist/rendering/ClusteredForwardLighting.d.ts.map +1 -0
  246. package/dist/rendering/ClusteredForwardLighting.js +156 -0
  247. package/dist/rendering/ClusteredForwardLighting.js.map +1 -0
  248. package/dist/rendering/DepthPass.d.ts +14 -1
  249. package/dist/rendering/DepthPass.d.ts.map +1 -1
  250. package/dist/rendering/DepthPass.js +19 -4
  251. package/dist/rendering/DepthPass.js.map +1 -1
  252. package/dist/rendering/EnvironmentMapResources.d.ts +59 -1
  253. package/dist/rendering/EnvironmentMapResources.d.ts.map +1 -1
  254. package/dist/rendering/EnvironmentMapResources.js +140 -100
  255. package/dist/rendering/EnvironmentMapResources.js.map +1 -1
  256. package/dist/rendering/EnvironmentPlatform.d.ts +3 -2
  257. package/dist/rendering/EnvironmentPlatform.d.ts.map +1 -1
  258. package/dist/rendering/EnvironmentPlatform.js +99 -44
  259. package/dist/rendering/EnvironmentPlatform.js.map +1 -1
  260. package/dist/rendering/ForwardPass.d.ts +37 -0
  261. package/dist/rendering/ForwardPass.d.ts.map +1 -1
  262. package/dist/rendering/ForwardPass.js +234 -7
  263. package/dist/rendering/ForwardPass.js.map +1 -1
  264. package/dist/rendering/Geometry.d.ts +19 -0
  265. package/dist/rendering/Geometry.d.ts.map +1 -1
  266. package/dist/rendering/Geometry.js +64 -0
  267. package/dist/rendering/Geometry.js.map +1 -1
  268. package/dist/rendering/IBL.d.ts.map +1 -1
  269. package/dist/rendering/IBL.js +0 -1
  270. package/dist/rendering/IBL.js.map +1 -1
  271. package/dist/rendering/LightCollector.d.ts +5 -1
  272. package/dist/rendering/LightCollector.d.ts.map +1 -1
  273. package/dist/rendering/LightCollector.js +16 -3
  274. package/dist/rendering/LightCollector.js.map +1 -1
  275. package/dist/rendering/LightUniforms.d.ts +26 -1
  276. package/dist/rendering/LightUniforms.d.ts.map +1 -1
  277. package/dist/rendering/LightUniforms.js +140 -8
  278. package/dist/rendering/LightUniforms.js.map +1 -1
  279. package/dist/rendering/LightingRig.d.ts +77 -0
  280. package/dist/rendering/LightingRig.d.ts.map +1 -1
  281. package/dist/rendering/LightingRig.js +100 -11
  282. package/dist/rendering/LightingRig.js.map +1 -1
  283. package/dist/rendering/MeshConsolidation.d.ts +63 -0
  284. package/dist/rendering/MeshConsolidation.d.ts.map +1 -0
  285. package/dist/rendering/MeshConsolidation.js +251 -0
  286. package/dist/rendering/MeshConsolidation.js.map +1 -0
  287. package/dist/rendering/PMREM.d.ts +13 -1
  288. package/dist/rendering/PMREM.d.ts.map +1 -1
  289. package/dist/rendering/PMREM.js +18 -4
  290. package/dist/rendering/PMREM.js.map +1 -1
  291. package/dist/rendering/PostProcessPass.d.ts +24 -2
  292. package/dist/rendering/PostProcessPass.d.ts.map +1 -1
  293. package/dist/rendering/PostProcessPass.js +136 -18
  294. package/dist/rendering/PostProcessPass.js.map +1 -1
  295. package/dist/rendering/PrimitiveSubmissionAudit.d.ts +195 -0
  296. package/dist/rendering/PrimitiveSubmissionAudit.d.ts.map +1 -0
  297. package/dist/rendering/PrimitiveSubmissionAudit.js +280 -0
  298. package/dist/rendering/PrimitiveSubmissionAudit.js.map +1 -0
  299. package/dist/rendering/ProductTurntableFixtures.d.ts.map +1 -1
  300. package/dist/rendering/ProductTurntableFixtures.js +93 -13
  301. package/dist/rendering/ProductTurntableFixtures.js.map +1 -1
  302. package/dist/rendering/ReflectionProbe.d.ts +59 -0
  303. package/dist/rendering/ReflectionProbe.d.ts.map +1 -1
  304. package/dist/rendering/ReflectionProbe.js +224 -0
  305. package/dist/rendering/ReflectionProbe.js.map +1 -1
  306. package/dist/rendering/ReflectionSurfaces.d.ts +4 -2
  307. package/dist/rendering/ReflectionSurfaces.d.ts.map +1 -1
  308. package/dist/rendering/ReflectionSurfaces.js +13 -8
  309. package/dist/rendering/ReflectionSurfaces.js.map +1 -1
  310. package/dist/rendering/RenderBackend.d.ts +1 -1
  311. package/dist/rendering/RenderBackend.d.ts.map +1 -1
  312. package/dist/rendering/RenderBackend.js +5 -1
  313. package/dist/rendering/RenderBackend.js.map +1 -1
  314. package/dist/rendering/RenderDevice.d.ts +13 -2
  315. package/dist/rendering/RenderDevice.d.ts.map +1 -1
  316. package/dist/rendering/RenderDevice.js +5 -2
  317. package/dist/rendering/RenderDevice.js.map +1 -1
  318. package/dist/rendering/Renderer.d.ts +41 -1
  319. package/dist/rendering/Renderer.d.ts.map +1 -1
  320. package/dist/rendering/Renderer.js +406 -61
  321. package/dist/rendering/Renderer.js.map +1 -1
  322. package/dist/rendering/RendererPostprocessPlan.d.ts +10 -3
  323. package/dist/rendering/RendererPostprocessPlan.d.ts.map +1 -1
  324. package/dist/rendering/RendererPostprocessPlan.js +25 -5
  325. package/dist/rendering/RendererPostprocessPlan.js.map +1 -1
  326. package/dist/rendering/RendererVisualPipelineReport.d.ts +3 -2
  327. package/dist/rendering/RendererVisualPipelineReport.d.ts.map +1 -1
  328. package/dist/rendering/RendererVisualPipelineReport.js +2 -0
  329. package/dist/rendering/RendererVisualPipelineReport.js.map +1 -1
  330. package/dist/rendering/ScreenSpaceLineMaterial.d.ts +34 -0
  331. package/dist/rendering/ScreenSpaceLineMaterial.d.ts.map +1 -0
  332. package/dist/rendering/ScreenSpaceLineMaterial.js +93 -0
  333. package/dist/rendering/ScreenSpaceLineMaterial.js.map +1 -0
  334. package/dist/rendering/ShaderChunks.d.ts +7 -0
  335. package/dist/rendering/ShaderChunks.d.ts.map +1 -1
  336. package/dist/rendering/ShaderChunks.js +137 -0
  337. package/dist/rendering/ShaderChunks.js.map +1 -1
  338. package/dist/rendering/ShaderLibrary.d.ts +17 -0
  339. package/dist/rendering/ShaderLibrary.d.ts.map +1 -1
  340. package/dist/rendering/ShaderLibrary.js +940 -98
  341. package/dist/rendering/ShaderLibrary.js.map +1 -1
  342. package/dist/rendering/ShadowPass.d.ts +10 -0
  343. package/dist/rendering/ShadowPass.d.ts.map +1 -1
  344. package/dist/rendering/ShadowPass.js +8 -1
  345. package/dist/rendering/ShadowPass.js.map +1 -1
  346. package/dist/rendering/SkinnedLitMaterial.d.ts +6 -0
  347. package/dist/rendering/SkinnedLitMaterial.d.ts.map +1 -1
  348. package/dist/rendering/SkinnedLitMaterial.js +22 -8
  349. package/dist/rendering/SkinnedLitMaterial.js.map +1 -1
  350. package/dist/rendering/SkinnedUnlitMaterial.d.ts +8 -0
  351. package/dist/rendering/SkinnedUnlitMaterial.d.ts.map +1 -1
  352. package/dist/rendering/SkinnedUnlitMaterial.js +26 -9
  353. package/dist/rendering/SkinnedUnlitMaterial.js.map +1 -1
  354. package/dist/rendering/SpecularPrefilter.d.ts +42 -0
  355. package/dist/rendering/SpecularPrefilter.d.ts.map +1 -0
  356. package/dist/rendering/SpecularPrefilter.js +480 -0
  357. package/dist/rendering/SpecularPrefilter.js.map +1 -0
  358. package/dist/rendering/TerrainFixtures.d.ts +24 -0
  359. package/dist/rendering/TerrainFixtures.d.ts.map +1 -1
  360. package/dist/rendering/TerrainFixtures.js +96 -0
  361. package/dist/rendering/TerrainFixtures.js.map +1 -1
  362. package/dist/rendering/Texture.d.ts +7 -0
  363. package/dist/rendering/Texture.d.ts.map +1 -1
  364. package/dist/rendering/Texture.js +9 -0
  365. package/dist/rendering/Texture.js.map +1 -1
  366. package/dist/rendering/VertexFormat.d.ts +34 -1
  367. package/dist/rendering/VertexFormat.d.ts.map +1 -1
  368. package/dist/rendering/VertexFormat.js +61 -0
  369. package/dist/rendering/VertexFormat.js.map +1 -1
  370. package/dist/rendering/WebGL2Device.d.ts +48 -0
  371. package/dist/rendering/WebGL2Device.d.ts.map +1 -1
  372. package/dist/rendering/WebGL2Device.js +1298 -44
  373. package/dist/rendering/WebGL2Device.js.map +1 -1
  374. package/dist/rendering/WebGPUDevice.d.ts +7 -2
  375. package/dist/rendering/WebGPUDevice.d.ts.map +1 -1
  376. package/dist/rendering/WebGPUDevice.js +111 -17
  377. package/dist/rendering/WebGPUDevice.js.map +1 -1
  378. package/dist/rendering/WebGPUSkinningLimits.d.ts +14 -0
  379. package/dist/rendering/WebGPUSkinningLimits.d.ts.map +1 -0
  380. package/dist/rendering/WebGPUSkinningLimits.js +14 -0
  381. package/dist/rendering/WebGPUSkinningLimits.js.map +1 -0
  382. package/dist/rendering/cartoon/CartoonMaterialStyle.d.ts +19 -0
  383. package/dist/rendering/cartoon/CartoonMaterialStyle.d.ts.map +1 -0
  384. package/dist/rendering/cartoon/CartoonMaterialStyle.js +13 -0
  385. package/dist/rendering/cartoon/CartoonMaterialStyle.js.map +1 -0
  386. package/dist/rendering/cartoon/CartoonRenderPreset.d.ts +36 -0
  387. package/dist/rendering/cartoon/CartoonRenderPreset.d.ts.map +1 -0
  388. package/dist/rendering/cartoon/CartoonRenderPreset.js +23 -0
  389. package/dist/rendering/cartoon/CartoonRenderPreset.js.map +1 -0
  390. package/dist/rendering/cartoon/CartoonToonMaterial.d.ts +130 -0
  391. package/dist/rendering/cartoon/CartoonToonMaterial.d.ts.map +1 -0
  392. package/dist/rendering/cartoon/CartoonToonMaterial.js +303 -0
  393. package/dist/rendering/cartoon/CartoonToonMaterial.js.map +1 -0
  394. package/dist/rendering/cartoon/CartoonVisualQuality.d.ts +28 -0
  395. package/dist/rendering/cartoon/CartoonVisualQuality.d.ts.map +1 -0
  396. package/dist/rendering/cartoon/CartoonVisualQuality.js +39 -0
  397. package/dist/rendering/cartoon/CartoonVisualQuality.js.map +1 -0
  398. package/dist/rendering/cartoon/applyCartoonRenderPreset.d.ts +79 -0
  399. package/dist/rendering/cartoon/applyCartoonRenderPreset.d.ts.map +1 -0
  400. package/dist/rendering/cartoon/applyCartoonRenderPreset.js +88 -0
  401. package/dist/rendering/cartoon/applyCartoonRenderPreset.js.map +1 -0
  402. package/dist/rendering/cartoon/index.d.ts +6 -0
  403. package/dist/rendering/cartoon/index.d.ts.map +1 -0
  404. package/dist/rendering/cartoon/index.js +6 -0
  405. package/dist/rendering/cartoon/index.js.map +1 -0
  406. package/dist/rendering/index.d.ts +26 -15
  407. package/dist/rendering/index.d.ts.map +1 -1
  408. package/dist/rendering/index.js +15 -9
  409. package/dist/rendering/index.js.map +1 -1
  410. package/dist/rendering/postprocess/NativeLdrEffectLuts.d.ts +93 -0
  411. package/dist/rendering/postprocess/NativeLdrEffectLuts.d.ts.map +1 -0
  412. package/dist/rendering/postprocess/NativeLdrEffectLuts.js +202 -0
  413. package/dist/rendering/postprocess/NativeLdrEffectLuts.js.map +1 -0
  414. package/dist/rendering/production-runtime/PBRHDRPipeline.d.ts.map +1 -1
  415. package/dist/rendering/production-runtime/PBRHDRPipeline.js +3 -0
  416. package/dist/rendering/production-runtime/PBRHDRPipeline.js.map +1 -1
  417. package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts +1 -0
  418. package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts.map +1 -1
  419. package/dist/rendering/production-runtime/ProductionRendererTypes.js.map +1 -1
  420. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.d.ts.map +1 -1
  421. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js +5 -3
  422. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js.map +1 -1
  423. package/dist/rendering/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
  424. package/dist/rendering/production-runtime/ProductionWebGPURenderer.js +9 -5
  425. package/dist/rendering/production-runtime/ProductionWebGPURenderer.js.map +1 -1
  426. package/dist/rendering/production-runtime/TransmissionBackdropCapture.d.ts +5 -0
  427. package/dist/rendering/production-runtime/TransmissionBackdropCapture.d.ts.map +1 -1
  428. package/dist/rendering/production-runtime/TransmissionBackdropCapture.js +40 -0
  429. package/dist/rendering/production-runtime/TransmissionBackdropCapture.js.map +1 -1
  430. package/dist/rendering/production-runtime/environment/HDRLoader.d.ts +6 -0
  431. package/dist/rendering/production-runtime/environment/HDRLoader.d.ts.map +1 -1
  432. package/dist/rendering/production-runtime/environment/HDRLoader.js +19 -0
  433. package/dist/rendering/production-runtime/environment/HDRLoader.js.map +1 -1
  434. package/dist/rendering/production-runtime/index.d.ts +3 -1
  435. package/dist/rendering/production-runtime/index.d.ts.map +1 -1
  436. package/dist/rendering/production-runtime/index.js +1 -0
  437. package/dist/rendering/production-runtime/index.js.map +1 -1
  438. package/dist/scene/Light.d.ts +1 -1
  439. package/dist/scene/Light.d.ts.map +1 -1
  440. package/dist/scene/RectAreaLight.d.ts +22 -0
  441. package/dist/scene/RectAreaLight.d.ts.map +1 -0
  442. package/dist/scene/RectAreaLight.js +46 -0
  443. package/dist/scene/RectAreaLight.js.map +1 -0
  444. package/dist/scene/Scene.d.ts +6 -1
  445. package/dist/scene/Scene.d.ts.map +1 -1
  446. package/dist/scene/Scene.js +8 -1
  447. package/dist/scene/Scene.js.map +1 -1
  448. package/dist/scene/SceneSerializer.d.ts +3 -1
  449. package/dist/scene/SceneSerializer.d.ts.map +1 -1
  450. package/dist/scene/SceneSerializer.js +14 -7
  451. package/dist/scene/SceneSerializer.js.map +1 -1
  452. package/dist/scene/index.d.ts +1 -0
  453. package/dist/scene/index.d.ts.map +1 -1
  454. package/dist/scene/index.js +1 -0
  455. package/dist/scene/index.js.map +1 -1
  456. package/dist/scripting/CartoonNodeCategories.d.ts +3 -0
  457. package/dist/scripting/CartoonNodeCategories.d.ts.map +1 -0
  458. package/dist/scripting/CartoonNodeCategories.js +9 -0
  459. package/dist/scripting/CartoonNodeCategories.js.map +1 -0
  460. package/dist/scripting/CartoonVisualNodes.d.ts +3 -0
  461. package/dist/scripting/CartoonVisualNodes.d.ts.map +1 -0
  462. package/dist/scripting/CartoonVisualNodes.js +41 -0
  463. package/dist/scripting/CartoonVisualNodes.js.map +1 -0
  464. package/package.json +124 -113
  465. package/templates/cinematic-scene/package.json +1 -1
  466. package/templates/mini-game/package.json +1 -1
  467. package/templates/product-viewer/package.json +1 -1
  468. package/templates/production-asset-inspector/README.md +5 -0
  469. package/templates/production-asset-inspector/asset-manifest.json +9 -0
  470. package/templates/production-asset-inspector/index.html +2 -0
  471. package/templates/production-asset-inspector/package.json +17 -0
  472. package/templates/production-asset-inspector/src/main.ts +16 -0
  473. package/templates/production-material-studio/README.md +5 -0
  474. package/templates/production-material-studio/asset-manifest.json +9 -0
  475. package/templates/production-material-studio/index.html +2 -0
  476. package/templates/production-material-studio/package.json +17 -0
  477. package/templates/production-material-studio/src/main.ts +16 -0
  478. package/templates/production-product-configurator/README.md +5 -0
  479. package/templates/production-product-configurator/asset-manifest.json +9 -0
  480. package/templates/production-product-configurator/index.html +2 -0
  481. package/templates/production-product-configurator/package.json +17 -0
  482. package/templates/production-product-configurator/src/main.ts +16 -0
  483. package/templates/production-product-viewer/README.md +7 -0
  484. package/templates/production-product-viewer/asset-manifest.json +8 -0
  485. package/templates/production-product-viewer/index.html +26 -0
  486. package/templates/production-product-viewer/package.json +17 -0
  487. package/templates/production-product-viewer/src/main.ts +70 -0
@@ -1,23 +1,27 @@
1
- import { Bounds3 as SceneBounds3, Camera, DirectionalLight, Light, PointLight, Scene, SpotLight, identityMat4, invertMat4, multiplyMat4, orthographicMat4, perspectiveMat4, transformPoint } from "../scene/index.js";
1
+ import { Bounds3 as SceneBounds3, Camera, DirectionalLight, Light, PerspectiveCamera, PointLight, Scene, SpotLight, identityMat4, invertMat4, multiplyMat4, orthographicMat4, perspectiveMat4, transformPoint, toMathMat4 } from "../scene/index.js";
2
+ import { Frustum } from "../math/index.js";
2
3
  import { createRenderDevice } from "./RenderBackend.js";
3
4
  import { RenderDeviceError } from "./RenderDevice.js";
4
5
  import { ENVIRONMENT_BACKGROUND_COLOR_RESOURCE, EnvironmentBackgroundPass } from "./EnvironmentBackgroundPass.js";
5
6
  import { ForwardPass } from "./ForwardPass.js";
7
+ import { CascadedShadowMaps, CascadedShadowPass, shadowCameraFitViewProjectionMatrix } from "./CascadedShadowMaps.js";
6
8
  import { LightCollector } from "./LightCollector.js";
7
9
  import { Geometry } from "./Geometry.js";
8
10
  import {} from "./MorphTarget.js";
9
- import { computeSkinnedMorphTargetWeightedBounds } from "./SkinningBounds.js";
11
+ import { computeSkinnedGeometryBounds, computeSkinnedMorphTargetWeightedBounds } from "./SkinningBounds.js";
10
12
  import { RenderGraph } from "./RenderGraph.js";
11
- import { BloomPass, FXAAPass, ToneMappingPass, bloomFloatPixels, bloomPixels, chromaticAberrationPixels, colorGradePixels, contactShadowPixels, createDepthTextureBinding, depthOfFieldPixels, filmGrainPixels, fusedLdrPostprocessPixels, fxaaPixels, motionBlurPixels, outlinePixels, ssaoPixels, ssrPixels, taaPixels, toneMapFloatPixels, toneMapPixels, writePostProcessPixels } from "./PostProcessPass.js";
13
+ import { BloomPass, FXAAPass, ToneMappingPass, bloomFloatPixels, bloomPixels, chromaticAberrationPixels, colorGradePixels, contactShadowPixels, createDepthTextureBinding, depthOfFieldPixels, filmGrainPixels, fusedLdrPostprocessPixels, fxaaPixels, motionBlurPixels, outlinePixels, ssaoPixels, ssrPixels, taaPixels, toneMapFloatPixels, toneMapPixels, volumetricLightPixels, writePostProcessPixels } from "./PostProcessPass.js";
12
14
  import { createRendererPostprocessPasses, createRendererPostprocessPlanDiagnostics } from "./RendererPostprocessPlan.js";
13
15
  import { createDefaultShaderLibrary } from "./ShaderLibrary.js";
14
16
  import { ShadowMap } from "./ShadowMap.js";
15
17
  import { ShadowPass } from "./ShadowPass.js";
16
18
  import { Sampler } from "./Sampler.js";
19
+ import {} from "./Texture.js";
17
20
  import { TextureBinding } from "./TextureBinding.js";
18
21
  import { computePerspectiveCameraFrame } from "./CameraFraming.js";
19
22
  import { assertRendererFeatures, createRendererFeatureReport } from "./RendererFeatureGates.js";
20
23
  import { batchStaticRenderItems } from "./SceneOptimization.js";
24
+ import { createStaticMeshConsolidationCache } from "./MeshConsolidation.js";
21
25
  export const DEFAULT_RENDERER_AUTO_FRAME_OPTIONS = {
22
26
  paddingRatio: 0.14,
23
27
  yawRadians: -0.38,
@@ -67,6 +71,23 @@ export class Renderer {
67
71
  device;
68
72
  graph = new RenderGraph();
69
73
  shaderLibrary;
74
+ /**
75
+ * Depth target reused by the renderer-owned shadow pass across frames.
76
+ *
77
+ * A new `ShadowPass` is constructed per frame, so letting the pass own its target reallocated
78
+ * textures and re-ran `checkFramebufferStatus` every frame. Keyed by size so a shadow-size change
79
+ * still reallocates exactly once.
80
+ */
81
+ shadowDepthTarget = null;
82
+ /**
83
+ * Forward-color target reused by the postprocess path across frames.
84
+ *
85
+ * This was allocated fresh inside every `render()` call and pushed onto `ownedTargets`, which
86
+ * disposes it at end of frame. Creating a render target allocates textures and runs
87
+ * `checkFramebufferStatus` — both synchronous GPU operations — so an animating postprocess route
88
+ * paid a full target build-and-teardown every frame.
89
+ */
90
+ forwardColorTarget = null;
70
91
  canvas;
71
92
  width;
72
93
  height;
@@ -199,13 +220,11 @@ export class Renderer {
199
220
  backend: this.device.kind
200
221
  });
201
222
  }
202
- const forwardTarget = this.device.createRenderTarget({
203
- width: this.width,
204
- height: this.height,
205
- label: "renderer-forward-color",
206
- format,
207
- depth: requiresDepthTexture ? "texture" : true
208
- });
223
+ const sampleCount = postprocess.sampleCount ?? (this.device.kind === "webgpu" && requiresDepthTexture ? 1 : 4);
224
+ // Reused across frames. It still occupies `ownedTargets[0]`, because the postprocess chain and
225
+ // the diagnostics builder both read the forward target from that slot; the end-of-frame
226
+ // disposal loop skips it via `isReusedTarget` so the reuse is safe.
227
+ const forwardTarget = this.ensureForwardColorTarget(format, requiresDepthTexture, sampleCount);
209
228
  ownedTargets.push(forwardTarget);
210
229
  this.device.setRenderTarget(forwardTarget);
211
230
  }
@@ -217,7 +236,8 @@ export class Renderer {
217
236
  items,
218
237
  lights,
219
238
  ownedTargets,
220
- ownedShadowPasses
239
+ ownedShadowPasses,
240
+ camera: resolvedCamera?.camera
221
241
  });
222
242
  if (postprocess) {
223
243
  const forwardTarget = ownedTargets[0];
@@ -246,6 +266,8 @@ export class Renderer {
246
266
  inputColorResource: environmentBackground ? ENVIRONMENT_BACKGROUND_COLOR_RESOURCE : undefined,
247
267
  shadowMap: rendererShadowMap,
248
268
  cameraPosition,
269
+ cameraViewMatrix: resolvedCamera?.viewMatrix,
270
+ cameraViewProjectionMatrix: cameraViewProjection,
249
271
  outputColorSpace: postprocess ? "linear" : "srgb",
250
272
  shaderLibrary: this.shaderLibrary
251
273
  }));
@@ -260,6 +282,10 @@ export class Renderer {
260
282
  shadowPass.dispose();
261
283
  }
262
284
  for (const target of ownedTargets) {
285
+ // The reused forward-color target outlives the frame; disposing it here would reintroduce a
286
+ // per-frame allocation.
287
+ if (this.isReusedTarget(target))
288
+ continue;
263
289
  target.dispose();
264
290
  }
265
291
  }
@@ -335,13 +361,11 @@ export class Renderer {
335
361
  backend: this.device.kind
336
362
  });
337
363
  }
338
- const forwardTarget = this.device.createRenderTarget({
339
- width: this.width,
340
- height: this.height,
341
- label: "renderer-forward-color",
342
- format,
343
- depth: requiresDepthTexture ? "texture" : true
344
- });
364
+ const sampleCount = postprocess.sampleCount ?? (this.device.kind === "webgpu" && requiresDepthTexture ? 1 : 4);
365
+ // Reused across frames. It still occupies `ownedTargets[0]`, because the postprocess chain and
366
+ // the diagnostics builder both read the forward target from that slot; the end-of-frame
367
+ // disposal loop skips it via `isReusedTarget` so the reuse is safe.
368
+ const forwardTarget = this.ensureForwardColorTarget(format, requiresDepthTexture, sampleCount);
345
369
  ownedTargets.push(forwardTarget);
346
370
  this.device.setRenderTarget(forwardTarget);
347
371
  }
@@ -353,7 +377,8 @@ export class Renderer {
353
377
  items,
354
378
  lights,
355
379
  ownedTargets,
356
- ownedShadowPasses
380
+ ownedShadowPasses,
381
+ camera: resolvedCamera?.camera
357
382
  });
358
383
  if (postprocess) {
359
384
  const forwardTarget = ownedTargets[0];
@@ -382,6 +407,8 @@ export class Renderer {
382
407
  inputColorResource: environmentBackground ? ENVIRONMENT_BACKGROUND_COLOR_RESOURCE : undefined,
383
408
  shadowMap: rendererShadowMap,
384
409
  cameraPosition,
410
+ cameraViewMatrix: resolvedCamera?.viewMatrix,
411
+ cameraViewProjectionMatrix: cameraViewProjection,
385
412
  outputColorSpace: postprocess ? "linear" : "srgb",
386
413
  shaderLibrary: this.shaderLibrary
387
414
  }));
@@ -396,6 +423,10 @@ export class Renderer {
396
423
  shadowPass.dispose();
397
424
  }
398
425
  for (const target of ownedTargets) {
426
+ // The reused forward-color target outlives the frame; disposing it here would reintroduce a
427
+ // per-frame allocation.
428
+ if (this.isReusedTarget(target))
429
+ continue;
399
430
  target.dispose();
400
431
  }
401
432
  }
@@ -435,9 +466,51 @@ export class Renderer {
435
466
  dispose() {
436
467
  this.animationLoop?.stop();
437
468
  this.animationLoop = null;
469
+ this.shadowDepthTarget?.dispose();
470
+ this.shadowDepthTarget = null;
471
+ this.forwardColorTarget?.target.dispose();
472
+ this.forwardColorTarget = null;
438
473
  this.device.dispose();
439
474
  this.disposed = true;
440
475
  }
476
+ /** True for renderer-lifetime targets that must survive end-of-frame disposal. */
477
+ isReusedTarget(target) {
478
+ return target === this.forwardColorTarget?.target || target === this.shadowDepthTarget;
479
+ }
480
+ /** Allocates the shared forward-color target once per distinct configuration. */
481
+ ensureForwardColorTarget(format, requiresDepthTexture, sampleCount) {
482
+ const key = `${this.width}x${this.height}:${format}:${requiresDepthTexture ? "depth-texture" : "depth"}:${sampleCount}`;
483
+ const cached = this.forwardColorTarget;
484
+ if (cached && cached.key === key && !cached.target.disposed)
485
+ return cached.target;
486
+ cached?.target.dispose();
487
+ const target = this.device.createRenderTarget({
488
+ width: this.width,
489
+ height: this.height,
490
+ label: "renderer-forward-color",
491
+ format,
492
+ depth: requiresDepthTexture ? "texture" : true,
493
+ sampleCount
494
+ });
495
+ this.forwardColorTarget = { target, key };
496
+ return target;
497
+ }
498
+ /** Allocates the shared shadow depth target once, reallocating only when the size changes. */
499
+ ensureShadowDepthTarget(size) {
500
+ const existing = this.shadowDepthTarget;
501
+ if (existing && !existing.disposed && existing.width === size && existing.height === size)
502
+ return existing;
503
+ existing?.dispose();
504
+ const target = this.device.createRenderTarget({
505
+ width: size,
506
+ height: size,
507
+ label: "renderer-shadow-depth-color",
508
+ format: "rgba8",
509
+ depth: this.device.info.capabilities?.includes("depth-textures") ? "texture" : true
510
+ });
511
+ this.shadowDepthTarget = target;
512
+ return target;
513
+ }
441
514
  assertAlive() {
442
515
  if (this.disposed || this.device.disposed) {
443
516
  throw new RenderDeviceError("Renderer is disposed", "DISPOSED_DEVICE");
@@ -470,7 +543,7 @@ export class Renderer {
470
543
  }
471
544
  return;
472
545
  }
473
- if (this.executeFusedLdrPostprocess(current, passes, outputTarget))
546
+ if (this.executeFusedLdrPostprocess(current, passes, outputTarget, postprocess.execution === "cpu-deterministic"))
474
547
  return;
475
548
  for (let index = 0; index < passes.length; index += 1) {
476
549
  const pass = passes[index];
@@ -542,10 +615,21 @@ export class Renderer {
542
615
  current = target;
543
616
  }
544
617
  }
545
- executeFusedLdrPostprocess(current, passes, outputTarget) {
618
+ executeFusedLdrPostprocess(current, passes, outputTarget, forceCpuDeterministic = false) {
546
619
  if (!canFuseLdrPostprocess(current, passes))
547
620
  return false;
548
- if (this.device.presentLdrPostprocess) {
621
+ if (!forceCpuDeterministic && !this.device.presentLdrPostprocess && passes.some((pass) => pass.name === "depth-of-field" || pass.name === "motion-blur" || pass.name === "ssao" || pass.name === "ssr" || pass.name === "taa"))
622
+ return false;
623
+ // A caller that supplies its own `depth` array for depth-of-field/SSAO/SSR gets a plain
624
+ // depth renderbuffer, because `postprocessRequiresDepthTexture` only requests a
625
+ // sampleable depth texture when the renderer has to generate the depth itself. The
626
+ // backend's fused path samples `depthTextureHandle` regardless and used to throw
627
+ // `WEBGL_LDR_POSTPROCESS_DEPTH_REQUIRED`, failing the whole render rather than falling
628
+ // back. Declining fusion here routes those passes through the per-pass CPU path, which
629
+ // consumes the caller's depth directly and is the behaviour the options already imply.
630
+ if (!forceCpuDeterministic && !current.depthTexture && passes.some((pass) => pass.name === "depth-of-field" || pass.name === "ssao" || pass.name === "ssr"))
631
+ return false;
632
+ if (!forceCpuDeterministic && this.device.presentLdrPostprocess) {
549
633
  this.device.presentLdrPostprocess(current, {
550
634
  passes: passes.map((pass) => ({
551
635
  name: pass.name,
@@ -582,7 +666,7 @@ export class Renderer {
582
666
  }
583
667
  return;
584
668
  }
585
- if (await this.executeFusedLdrPostprocessAsync(current, passes, outputTarget))
669
+ if (await this.executeFusedLdrPostprocessAsync(current, passes, outputTarget, postprocess.execution === "cpu-deterministic"))
586
670
  return;
587
671
  for (let index = 0; index < passes.length; index += 1) {
588
672
  const pass = passes[index];
@@ -651,10 +735,21 @@ export class Renderer {
651
735
  current = target;
652
736
  }
653
737
  }
654
- async executeFusedLdrPostprocessAsync(current, passes, outputTarget) {
738
+ async executeFusedLdrPostprocessAsync(current, passes, outputTarget, forceCpuDeterministic = false) {
655
739
  if (!canFuseLdrPostprocess(current, passes))
656
740
  return false;
657
- if (this.device.presentLdrPostprocess) {
741
+ if (!forceCpuDeterministic && !this.device.presentLdrPostprocess && passes.some((pass) => pass.name === "depth-of-field" || pass.name === "motion-blur" || pass.name === "ssao" || pass.name === "ssr" || pass.name === "taa"))
742
+ return false;
743
+ // A caller that supplies its own `depth` array for depth-of-field/SSAO/SSR gets a plain
744
+ // depth renderbuffer, because `postprocessRequiresDepthTexture` only requests a
745
+ // sampleable depth texture when the renderer has to generate the depth itself. The
746
+ // backend's fused path samples `depthTextureHandle` regardless and used to throw
747
+ // `WEBGL_LDR_POSTPROCESS_DEPTH_REQUIRED`, failing the whole render rather than falling
748
+ // back. Declining fusion here routes those passes through the per-pass CPU path, which
749
+ // consumes the caller's depth directly and is the behaviour the options already imply.
750
+ if (!forceCpuDeterministic && !current.depthTexture && passes.some((pass) => pass.name === "depth-of-field" || pass.name === "ssao" || pass.name === "ssr"))
751
+ return false;
752
+ if (!forceCpuDeterministic && this.device.presentLdrPostprocess) {
658
753
  this.device.presentLdrPostprocess(current, {
659
754
  passes: passes.map((pass) => ({
660
755
  name: pass.name,
@@ -687,19 +782,21 @@ export class Renderer {
687
782
  ? filmGrainPixels(input, source.width, source.height, pass.options).pixels
688
783
  : pass.name === "depth-of-field"
689
784
  ? depthOfFieldPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
690
- : pass.name === "motion-blur"
691
- ? motionBlurPixels(input, source.width, source.height, pass.options).pixels
692
- : pass.name === "contact-shadow"
693
- ? contactShadowPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
694
- : pass.name === "ssao"
695
- ? ssaoPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
696
- : pass.name === "ssr"
697
- ? ssrPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
698
- : pass.name === "taa"
699
- ? taaPixels(input, source.width, source.height, pass.options).pixels
700
- : pass.name === "outline"
701
- ? outlinePixels(input, source.width, source.height, pass.options).pixels
702
- : undefined;
785
+ : pass.name === "volumetric-light"
786
+ ? volumetricLightPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
787
+ : pass.name === "motion-blur"
788
+ ? motionBlurPixels(input, source.width, source.height, pass.options).pixels
789
+ : pass.name === "contact-shadow"
790
+ ? contactShadowPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
791
+ : pass.name === "ssao"
792
+ ? ssaoPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
793
+ : pass.name === "ssr"
794
+ ? ssrPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
795
+ : pass.name === "taa"
796
+ ? taaPixels(input, source.width, source.height, pass.options).pixels
797
+ : pass.name === "outline"
798
+ ? outlinePixels(input, source.width, source.height, pass.options).pixels
799
+ : undefined;
703
800
  if (!result) {
704
801
  throw new RenderDeviceError("Renderer postprocess pass is outside the supported renderer pass catalog", "POSTPROCESS_PASS_UNKNOWN", {
705
802
  pass: pass.name
@@ -720,19 +817,21 @@ export class Renderer {
720
817
  ? filmGrainPixels(input, source.width, source.height, pass.options).pixels
721
818
  : pass.name === "depth-of-field"
722
819
  ? depthOfFieldPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
723
- : pass.name === "motion-blur"
724
- ? motionBlurPixels(input, source.width, source.height, pass.options).pixels
725
- : pass.name === "contact-shadow"
726
- ? contactShadowPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
727
- : pass.name === "ssao"
728
- ? ssaoPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
729
- : pass.name === "ssr"
730
- ? ssrPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
731
- : pass.name === "taa"
732
- ? taaPixels(input, source.width, source.height, pass.options).pixels
733
- : pass.name === "outline"
734
- ? outlinePixels(input, source.width, source.height, pass.options).pixels
735
- : undefined;
820
+ : pass.name === "volumetric-light"
821
+ ? volumetricLightPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
822
+ : pass.name === "motion-blur"
823
+ ? motionBlurPixels(input, source.width, source.height, pass.options).pixels
824
+ : pass.name === "contact-shadow"
825
+ ? contactShadowPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
826
+ : pass.name === "ssao"
827
+ ? ssaoPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
828
+ : pass.name === "ssr"
829
+ ? ssrPixels(input, source.width, source.height, withRendererDepth(pass.options, rendererDepth)).pixels
830
+ : pass.name === "taa"
831
+ ? taaPixels(input, source.width, source.height, pass.options).pixels
832
+ : pass.name === "outline"
833
+ ? outlinePixels(input, source.width, source.height, pass.options).pixels
834
+ : undefined;
736
835
  if (!result) {
737
836
  throw new RenderDeviceError("Renderer postprocess pass is outside the supported renderer pass catalog", "POSTPROCESS_PASS_UNKNOWN", {
738
837
  pass: pass.name
@@ -798,6 +897,17 @@ export class Renderer {
798
897
  lightType: light.constructor.name
799
898
  });
800
899
  }
900
+ if (light instanceof DirectionalLight
901
+ && options.camera instanceof PerspectiveCamera
902
+ && (options.shadowOptions.cascadeCount ?? 1) > 1) {
903
+ return this.executeRendererCascadedShadowMap({
904
+ shadowOptions: options.shadowOptions,
905
+ items: options.items,
906
+ ownedShadowPasses: options.ownedShadowPasses,
907
+ light,
908
+ camera: options.camera
909
+ });
910
+ }
801
911
  const lightMatrix = options.shadowOptions.lightMatrix
802
912
  ? toMat4(options.shadowOptions.lightMatrix, "shadow.lightMatrix")
803
913
  : createRendererOwnedShadowMatrix(light, options.items, firstShadowCastingCollectedLight(options.lights));
@@ -815,7 +925,8 @@ export class Renderer {
815
925
  casters: options.items,
816
926
  shadowMap,
817
927
  viewProjectionMatrix: lightMatrix,
818
- shaderLibrary: this.shaderLibrary
928
+ shaderLibrary: this.shaderLibrary,
929
+ renderTarget: this.ensureShadowDepthTarget(shadowMap.size)
819
930
  });
820
931
  options.ownedShadowPasses.push(shadowPass);
821
932
  const result = shadowPass.execute({ device: this.device, width: this.width, height: this.height });
@@ -836,6 +947,77 @@ export class Renderer {
836
947
  filterKernel: options.shadowOptions.filterKernel
837
948
  }) ?? undefined;
838
949
  }
950
+ executeRendererCascadedShadowMap(options) {
951
+ const cascadeCount = options.shadowOptions.cascadeCount ?? 4;
952
+ if (!Number.isInteger(cascadeCount) || cascadeCount < 2 || cascadeCount > 4) {
953
+ throw new RenderDeviceError("Renderer cascadeCount must be an integer in [2, 4].", "SHADOW_CASCADE_CONTRACT", { cascadeCount });
954
+ }
955
+ options.camera.transform.updateWorld(undefined, true);
956
+ const position = cameraWorldPosition(options.camera);
957
+ const world = options.camera.transform.worldMatrix;
958
+ const target = [
959
+ position[0] - (world[8] ?? 0),
960
+ position[1] - (world[9] ?? 0),
961
+ position[2] - (world[10] ?? 1)
962
+ ];
963
+ const cascades = new CascadedShadowMaps({
964
+ cascadeCount,
965
+ near: options.camera.near,
966
+ far: options.camera.far,
967
+ lambda: options.shadowOptions.cascadeLambda ?? 0.6,
968
+ size: options.shadowOptions.size,
969
+ bias: options.shadowOptions.bias,
970
+ filter: options.shadowOptions.filter,
971
+ pcfRadius: options.shadowOptions.pcfRadius,
972
+ pcfSamples: options.shadowOptions.pcfSamples,
973
+ label: options.shadowOptions.label ?? "renderer-csm"
974
+ });
975
+ const fits = cascades.computeStableCameraFits({
976
+ camera: {
977
+ position,
978
+ target,
979
+ fovYRadians: options.camera.fovYRadians,
980
+ aspect: options.camera.aspect
981
+ },
982
+ lightDirection: options.light.getDirection(),
983
+ casters: [],
984
+ receivers: [],
985
+ padding: options.shadowOptions.cascadePadding ?? 0.25,
986
+ stabilize: true
987
+ });
988
+ const lightMatrices = fits.map(shadowCameraFitViewProjectionMatrix);
989
+ const cascadePass = new CascadedShadowPass({
990
+ light: options.light,
991
+ casters: options.items,
992
+ cascades,
993
+ viewProjectionMatrices: lightMatrices,
994
+ shaderLibrary: this.shaderLibrary
995
+ });
996
+ const result = cascadePass.execute({ device: this.device, width: this.width, height: this.height });
997
+ options.ownedShadowPasses.push(cascadePass);
998
+ if (!result.rendered)
999
+ return undefined;
1000
+ const maps = cascadePass.getForwardShadowMaps({
1001
+ lightMatrices,
1002
+ strength: options.shadowOptions.strength,
1003
+ slopeBias: options.shadowOptions.slopeBias,
1004
+ texelSize: options.shadowOptions.texelSize,
1005
+ bias: options.shadowOptions.bias,
1006
+ filterKernel: options.shadowOptions.filterKernel
1007
+ });
1008
+ const first = maps[0];
1009
+ if (!first || maps.length !== result.cascades.length)
1010
+ return undefined;
1011
+ return {
1012
+ ...first,
1013
+ cascades: result.cascades.map((cascade, index) => ({
1014
+ index: cascade.index,
1015
+ near: cascade.split.near,
1016
+ far: cascade.split.far,
1017
+ shadowMap: maps[index]
1018
+ }))
1019
+ };
1020
+ }
839
1021
  executeRendererPointShadowMap(options) {
840
1022
  if (!this.device.writeRenderTargetPixels) {
841
1023
  throw new RenderDeviceError("Renderer-owned point shadows require render-target pixel upload for the point-light atlas.", "POINT_SHADOW_ATLAS_UPLOAD_UNSUPPORTED", {
@@ -1230,7 +1412,7 @@ function lookAtMatrix(eye, target, up) {
1230
1412
  ];
1231
1413
  }
1232
1414
  function createDirectionalShadowMatrix(items, lightDirection) {
1233
- const bounds = collectRenderItemBounds(items);
1415
+ const bounds = collectShadowCoverageBounds(items);
1234
1416
  if (!bounds || bounds.isEmpty()) {
1235
1417
  return identityMat4();
1236
1418
  }
@@ -1344,7 +1526,8 @@ function collectCameraPolicy(source) {
1344
1526
  return "identity";
1345
1527
  }
1346
1528
  function postprocessRequiresDepthTexture(postprocess) {
1347
- return Boolean((postprocess.depthOfField && !postprocess.depthOfField.depth) ||
1529
+ return Boolean((postprocess.volumetricLight && !postprocess.volumetricLight.depth) ||
1530
+ (postprocess.depthOfField && !postprocess.depthOfField.depth) ||
1348
1531
  (postprocess.contactShadow && !postprocess.contactShadow.depth) ||
1349
1532
  (postprocess.ssao && !postprocess.ssao.depth) ||
1350
1533
  (postprocess.ssr && !postprocess.ssr.depth));
@@ -1353,23 +1536,37 @@ function canFuseLdrPostprocess(source, passes) {
1353
1536
  const sourceIsHdr = isHdrRenderTarget(source);
1354
1537
  return passes.length > 1
1355
1538
  && (!sourceIsHdr || passes[0]?.name === "tone-mapping")
1356
- && passes.every((pass) => pass.name === "tone-mapping" || pass.name === "color-grade" || pass.name === "fxaa")
1539
+ && passes.every((pass) => pass.name === "bloom" || pass.name === "tone-mapping" || pass.name === "color-grade" || pass.name === "depth-of-field" || pass.name === "motion-blur" || pass.name === "ssao" || pass.name === "ssr" || pass.name === "taa" || pass.name === "outline" || pass.name === "fxaa")
1357
1540
  && passes.every((pass, index) => {
1358
1541
  const previousRank = index === 0 ? -1 : ldrFusionPassRank(passes[index - 1].name);
1359
1542
  return ldrFusionPassRank(pass.name) >= previousRank;
1360
1543
  });
1361
1544
  }
1362
1545
  function ldrFusionPassRank(name) {
1546
+ if (name === "bloom")
1547
+ return -1;
1363
1548
  if (name === "tone-mapping")
1364
1549
  return 0;
1365
1550
  if (name === "color-grade")
1366
1551
  return 1;
1367
- if (name === "fxaa")
1552
+ if (name === "depth-of-field")
1368
1553
  return 2;
1554
+ if (name === "motion-blur")
1555
+ return 3;
1556
+ if (name === "ssao")
1557
+ return 4;
1558
+ if (name === "ssr")
1559
+ return 5;
1560
+ if (name === "taa")
1561
+ return 6;
1562
+ if (name === "outline")
1563
+ return 7;
1564
+ if (name === "fxaa")
1565
+ return 8;
1369
1566
  return Number.POSITIVE_INFINITY;
1370
1567
  }
1371
1568
  function isDepthPostprocessPass(name) {
1372
- return name === "depth-of-field" || name === "contact-shadow" || name === "ssao" || name === "ssr";
1569
+ return name === "volumetric-light" || name === "depth-of-field" || name === "contact-shadow" || name === "ssao" || name === "ssr";
1373
1570
  }
1374
1571
  function postprocessPassHasDepth(options) {
1375
1572
  return typeof options === "object" && options !== null && "depth" in options && Boolean(options.depth);
@@ -1425,17 +1622,142 @@ function collectRenderItemsWithDiagnostics(source, cameraViewProjection, camera)
1425
1622
  explicitItems.push(...source.renderItems);
1426
1623
  }
1427
1624
  if (explicitItems.length > 0) {
1428
- const optimizedItems = applyRendererOwnedStaticBatching(source, explicitItems);
1625
+ const cullingFrustum = explicitCullingFrustum(source, cameraViewProjection, camera);
1626
+ const visibleItems = cullExplicitRenderItems(explicitItems, cullingFrustum, diagnostics);
1627
+ const optimizedItems = applyRendererOwnedStaticBatching(source, applyRendererOwnedStaticMeshConsolidation(source, visibleItems));
1429
1628
  const projectedItems = applyViewProjection(optimizedItems, cameraViewProjection);
1430
- diagnostics.submittedObjects += explicitItems.length;
1431
- diagnostics.visibleObjects += explicitItems.length;
1432
1629
  items.push(...projectedItems);
1433
1630
  }
1434
1631
  return { items, diagnostics };
1435
1632
  }
1633
+ function explicitCullingFrustum(source, cameraViewProjection, camera) {
1634
+ // Explicit render-item sources were historically never culled, so culling
1635
+ // stays opt-in: only an explicit `frustumCulling: true` turns it on.
1636
+ if (source.frustumCulling !== true)
1637
+ return undefined;
1638
+ if (camera)
1639
+ return camera.frustum;
1640
+ if (!cameraViewProjection)
1641
+ return undefined;
1642
+ return Frustum.fromMatrix(toMathMat4(cameraViewProjection));
1643
+ }
1644
+ function cullExplicitRenderItems(items, frustum, diagnostics) {
1645
+ if (!frustum) {
1646
+ diagnostics.submittedObjects += items.length;
1647
+ diagnostics.visibleObjects += items.length;
1648
+ return items;
1649
+ }
1650
+ const visible = [];
1651
+ for (const item of items) {
1652
+ diagnostics.submittedObjects += 1;
1653
+ if (!isFrustumCullableRenderItem(item)) {
1654
+ diagnostics.visibleObjects += 1;
1655
+ visible.push(item);
1656
+ continue;
1657
+ }
1658
+ diagnostics.frustumTestedObjects += 1;
1659
+ const bounds = explicitRenderItemWorldBounds(item);
1660
+ if (!frustum.intersectsBox(bounds.toMathBox())) {
1661
+ diagnostics.culledObjects += 1;
1662
+ continue;
1663
+ }
1664
+ diagnostics.visibleObjects += 1;
1665
+ visible.push(item);
1666
+ }
1667
+ return visible;
1668
+ }
1669
+ function isFrustumCullableRenderItem(item) {
1670
+ if (item.drawRange !== undefined)
1671
+ return false;
1672
+ if (item.morphTargets !== undefined || item.morphWeights !== undefined)
1673
+ return false;
1674
+ return true;
1675
+ }
1676
+ function explicitRenderItemWorldBounds(item) {
1677
+ const modelMatrix = toMat4(item.modelMatrix ?? identityMat4(), "modelMatrix", item.label);
1678
+ if (item.skinning) {
1679
+ const local = skinnedItemLocalBounds(item.geometry, item.skinning);
1680
+ return boundsFromLocal(local, modelMatrix, item.instanceTransforms);
1681
+ }
1682
+ return boundsFromLocal(item.geometry.bounds, modelMatrix, item.instanceTransforms);
1683
+ }
1684
+ function boundsFromLocal(envelope, modelMatrix, instanceTransforms) {
1685
+ const local = new SceneBounds3([envelope.min[0], envelope.min[1], envelope.min[2]], [envelope.max[0], envelope.max[1], envelope.max[2]]);
1686
+ if (!instanceTransforms || instanceTransforms.length < 16) {
1687
+ return local.transform(modelMatrix);
1688
+ }
1689
+ let bounds = new SceneBounds3();
1690
+ for (let offset = 0; offset + 16 <= instanceTransforms.length; offset += 16) {
1691
+ const instanceMatrix = toMat4(instanceTransforms.slice(offset, offset + 16), "instanceTransforms");
1692
+ bounds = bounds.union(local.transform(multiplyMat4(modelMatrix, instanceMatrix)));
1693
+ }
1694
+ return bounds;
1695
+ }
1696
+ const skinnedCullingBoundsCache = new WeakMap();
1697
+ function skinnedItemLocalBounds(geometry, skinning) {
1698
+ const cached = skinnedCullingBoundsCache.get(geometry);
1699
+ if (cached && float32ArraysEqual(cached.matrices, skinning.matrices)) {
1700
+ return cached.bounds;
1701
+ }
1702
+ const bounds = computeSkinnedGeometryBounds(geometry, skinning);
1703
+ skinnedCullingBoundsCache.set(geometry, { matrices: new Float32Array(skinning.matrices), bounds });
1704
+ return bounds;
1705
+ }
1706
+ function float32ArraysEqual(left, right) {
1707
+ if (left.length !== right.length)
1708
+ return false;
1709
+ for (let index = 0; index < left.length; index += 1) {
1710
+ if (left[index] !== right[index])
1711
+ return false;
1712
+ }
1713
+ return true;
1714
+ }
1436
1715
  const staticBatchGeometryIds = new WeakMap();
1437
1716
  const staticBatchMaterialIds = new WeakMap();
1438
1717
  let nextStaticBatchResourceId = 1;
1718
+ /**
1719
+ * Merges shared-material static geometry, then hands the result to batching.
1720
+ *
1721
+ * Consolidation runs first because it reduces distinct geometries; whatever it leaves unmerged (single
1722
+ * items, oversized meshes, non-indexed topology) can still be instanced by batching afterwards.
1723
+ */
1724
+ const staticMeshConsolidationCaches = new WeakMap();
1725
+ function applyRendererOwnedStaticMeshConsolidation(source, items) {
1726
+ if (!source.staticMeshConsolidation)
1727
+ return items;
1728
+ const mergeable = [];
1729
+ const passthrough = [];
1730
+ for (const item of items) {
1731
+ // The same eligibility rule as batching: anything skinned, morphed, instanced, or draw-ranged is
1732
+ // not static geometry and must not have a transform baked into it.
1733
+ if (isStaticBatchCandidate(item)) {
1734
+ mergeable.push({
1735
+ geometry: item.geometry,
1736
+ material: item.material,
1737
+ modelMatrix: item.modelMatrix ?? identityMat4(),
1738
+ ...(item.label ? { label: item.label } : {})
1739
+ });
1740
+ }
1741
+ else {
1742
+ passthrough.push(item);
1743
+ }
1744
+ }
1745
+ if (mergeable.length === 0)
1746
+ return items;
1747
+ const options = source.staticMeshConsolidation === true ? {} : source.staticMeshConsolidation;
1748
+ // Cached per render source: merging walks every vertex, so repeating it each frame costs far more
1749
+ // than the draw calls it saves.
1750
+ let cache = staticMeshConsolidationCaches.get(source);
1751
+ if (!cache) {
1752
+ cache = createStaticMeshConsolidationCache();
1753
+ staticMeshConsolidationCaches.set(source, cache);
1754
+ }
1755
+ const consolidated = cache.consolidate(mergeable, {
1756
+ labelPrefix: "renderer-consolidated-mesh",
1757
+ ...options
1758
+ });
1759
+ return [...passthrough, ...consolidated.renderItems];
1760
+ }
1439
1761
  function applyRendererOwnedStaticBatching(source, items) {
1440
1762
  if (!source.staticBatching)
1441
1763
  return items;
@@ -1883,9 +2205,26 @@ function createAutoFrameCamera(source, items, width, height) {
1883
2205
  };
1884
2206
  }
1885
2207
  function collectRenderItemBounds(items) {
2208
+ return collectItemBounds(items, true);
2209
+ }
2210
+ /**
2211
+ * Bounds over every render item, including those excluded from camera
2212
+ * auto-framing.
2213
+ *
2214
+ * `includeInAutoFrame` answers "should the camera frame this?", which is a
2215
+ * composition choice. It must not decide which geometry a shadow frustum covers:
2216
+ * a large ground plane or backdrop is commonly excluded from auto-framing while
2217
+ * still being the surface that receives shadows. Fitting the light frustum to the
2218
+ * auto-frame subset shrinks it to the caster alone, so the receiver falls outside
2219
+ * the shadow map and no shadow is ever visible.
2220
+ */
2221
+ function collectShadowCoverageBounds(items) {
2222
+ return collectItemBounds(items, false);
2223
+ }
2224
+ function collectItemBounds(items, respectAutoFrameExclusion) {
1886
2225
  let bounds;
1887
2226
  for (const item of items) {
1888
- if (item.includeInAutoFrame === false)
2227
+ if (respectAutoFrameExclusion && item.includeInAutoFrame === false)
1889
2228
  continue;
1890
2229
  const itemBounds = renderableWorldBounds(item.geometry, toMat4(item.modelMatrix ?? identityMat4(), "modelMatrix", item.label), item.instanceTransforms, item.morphTargets, item.morphWeights, item.skinning);
1891
2230
  bounds = bounds ? bounds.union(itemBounds) : itemBounds;
@@ -1932,6 +2271,7 @@ function resolveCamera(source, camera, viewport, options = {}) {
1932
2271
  const viewMatrix = resolved.viewMatrix ? toMat4(resolved.viewMatrix, "viewMatrix") : undefined;
1933
2272
  return {
1934
2273
  viewProjectionMatrix: toMat4(resolved.viewProjectionMatrix, "viewProjectionMatrix"),
2274
+ ...(viewMatrix ? { viewMatrix } : {}),
1935
2275
  ...(resolved instanceof Camera
1936
2276
  ? { camera: resolved, cameraPosition: cameraWorldPosition(resolved) }
1937
2277
  : viewMatrix
@@ -1943,6 +2283,7 @@ function resolveCamera(source, camera, viewport, options = {}) {
1943
2283
  const viewMatrix = toMat4(resolved.viewMatrix, "viewMatrix");
1944
2284
  return {
1945
2285
  viewProjectionMatrix: multiplyMat4(toMat4(resolved.projectionMatrix, "projectionMatrix"), viewMatrix),
2286
+ viewMatrix,
1946
2287
  ...(resolved instanceof Camera
1947
2288
  ? { camera: resolved, cameraPosition: cameraWorldPosition(resolved) }
1948
2289
  : { cameraPosition: cameraPositionFromViewMatrix(viewMatrix) })
@@ -2052,7 +2393,11 @@ function createDefaultRendererDirectLights() {
2052
2393
  intensity: light.intensity,
2053
2394
  position: [0, 0, 0],
2054
2395
  direction: normalizeDefaultLightDirection(light.direction),
2396
+ right: [1, 0, 0],
2397
+ up: [0, 1, 0],
2055
2398
  range: 0,
2399
+ width: 0,
2400
+ height: 0,
2056
2401
  spotAngle: 0,
2057
2402
  penumbra: 0,
2058
2403
  castsShadow: false,