@aura3d/engine 3.0.0 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (349) hide show
  1. package/README.md +24 -5
  2. package/dist/animation/AnimationMixer.d.ts +4 -1
  3. package/dist/animation/AnimationMixer.d.ts.map +1 -1
  4. package/dist/animation/AnimationMixer.js +36 -29
  5. package/dist/animation/AnimationMixer.js.map +1 -1
  6. package/dist/animation/FootIk.d.ts +9 -0
  7. package/dist/animation/FootIk.d.ts.map +1 -1
  8. package/dist/animation/FootIk.js +22 -8
  9. package/dist/animation/FootIk.js.map +1 -1
  10. package/dist/animation/HumanoidRetargeting.d.ts +6 -2
  11. package/dist/animation/HumanoidRetargeting.d.ts.map +1 -1
  12. package/dist/animation/HumanoidRetargeting.js +18 -8
  13. package/dist/animation/HumanoidRetargeting.js.map +1 -1
  14. package/dist/animation/LocomotionEvidence.d.ts +34 -0
  15. package/dist/animation/LocomotionEvidence.d.ts.map +1 -0
  16. package/dist/animation/LocomotionEvidence.js +48 -0
  17. package/dist/animation/LocomotionEvidence.js.map +1 -0
  18. package/dist/animation/RootMotion.d.ts +13 -4
  19. package/dist/animation/RootMotion.d.ts.map +1 -1
  20. package/dist/animation/RootMotion.js +21 -1
  21. package/dist/animation/RootMotion.js.map +1 -1
  22. package/dist/animation/index.d.ts +1 -0
  23. package/dist/animation/index.d.ts.map +1 -1
  24. package/dist/animation/index.js +1 -0
  25. package/dist/animation/index.js.map +1 -1
  26. package/dist/assets/GLTFAnimationRuntime.d.ts +84 -4
  27. package/dist/assets/GLTFAnimationRuntime.d.ts.map +1 -1
  28. package/dist/assets/GLTFAnimationRuntime.js +308 -23
  29. package/dist/assets/GLTFAnimationRuntime.js.map +1 -1
  30. package/dist/assets/GLTFCompressionDecoders.d.ts +1 -0
  31. package/dist/assets/GLTFCompressionDecoders.d.ts.map +1 -1
  32. package/dist/assets/GLTFCompressionDecoders.js +20 -5
  33. package/dist/assets/GLTFCompressionDecoders.js.map +1 -1
  34. package/dist/assets/GLTFLoader.d.ts.map +1 -1
  35. package/dist/assets/GLTFLoader.js +21 -7
  36. package/dist/assets/GLTFLoader.js.map +1 -1
  37. package/dist/assets/KTX2BasisTextureTranscoder.d.ts.map +1 -1
  38. package/dist/assets/KTX2BasisTextureTranscoder.js +8 -0
  39. package/dist/assets/KTX2BasisTextureTranscoder.js.map +1 -1
  40. package/dist/controls/MapControls.d.ts +1 -1
  41. package/dist/controls/MapControls.d.ts.map +1 -1
  42. package/dist/controls/MapControls.js +3 -3
  43. package/dist/controls/MapControls.js.map +1 -1
  44. package/dist/controls/OrbitControls.d.ts +17 -3
  45. package/dist/controls/OrbitControls.d.ts.map +1 -1
  46. package/dist/controls/OrbitControls.js +24 -7
  47. package/dist/controls/OrbitControls.js.map +1 -1
  48. package/dist/controls/TrackballControls.d.ts.map +1 -1
  49. package/dist/controls/TrackballControls.js +2 -0
  50. package/dist/controls/TrackballControls.js.map +1 -1
  51. package/dist/create-aura3d/index.js +1 -1
  52. package/dist/engine/agent-api/AnimationController.d.ts +5 -1
  53. package/dist/engine/agent-api/AnimationController.d.ts.map +1 -1
  54. package/dist/engine/agent-api/AnimationController.js +5 -0
  55. package/dist/engine/agent-api/AnimationController.js.map +1 -1
  56. package/dist/engine/agent-api/CameraProjection.d.ts +2 -0
  57. package/dist/engine/agent-api/CameraProjection.d.ts.map +1 -0
  58. package/dist/engine/agent-api/CameraProjection.js +2 -0
  59. package/dist/engine/agent-api/CameraProjection.js.map +1 -0
  60. package/dist/engine/agent-api/DeferredFrameResources.d.ts +2 -0
  61. package/dist/engine/agent-api/DeferredFrameResources.d.ts.map +1 -0
  62. package/dist/engine/agent-api/DeferredFrameResources.js +2 -0
  63. package/dist/engine/agent-api/DeferredFrameResources.js.map +1 -0
  64. package/dist/engine/agent-api/FootPlanting.d.ts +6 -0
  65. package/dist/engine/agent-api/FootPlanting.d.ts.map +1 -1
  66. package/dist/engine/agent-api/FootPlanting.js +2 -1
  67. package/dist/engine/agent-api/FootPlanting.js.map +1 -1
  68. package/dist/engine/agent-api/GameCameraRigs.d.ts.map +1 -1
  69. package/dist/engine/agent-api/GameCameraRigs.js +7 -2
  70. package/dist/engine/agent-api/GameCameraRigs.js.map +1 -1
  71. package/dist/engine/agent-api/LabelTelemetry.d.ts +8 -2
  72. package/dist/engine/agent-api/LabelTelemetry.d.ts.map +1 -1
  73. package/dist/engine/agent-api/LabelTelemetry.js +18 -4
  74. package/dist/engine/agent-api/LabelTelemetry.js.map +1 -1
  75. package/dist/engine/agent-api/ModelInstanceMatrices.d.ts +2 -0
  76. package/dist/engine/agent-api/ModelInstanceMatrices.d.ts.map +1 -0
  77. package/dist/engine/agent-api/ModelInstanceMatrices.js +2 -0
  78. package/dist/engine/agent-api/ModelInstanceMatrices.js.map +1 -0
  79. package/dist/engine/agent-api/NavigationCrowds.d.ts +28 -0
  80. package/dist/engine/agent-api/NavigationCrowds.d.ts.map +1 -1
  81. package/dist/engine/agent-api/NavigationCrowds.js +73 -1
  82. package/dist/engine/agent-api/NavigationCrowds.js.map +1 -1
  83. package/dist/engine/agent-api/PngTexturePixels.d.ts +9 -0
  84. package/dist/engine/agent-api/PngTexturePixels.d.ts.map +1 -0
  85. package/dist/engine/agent-api/PngTexturePixels.js +53 -0
  86. package/dist/engine/agent-api/PngTexturePixels.js.map +1 -0
  87. package/dist/engine/agent-api/RootDiagnosticSnapshot.d.ts +2 -0
  88. package/dist/engine/agent-api/RootDiagnosticSnapshot.d.ts.map +1 -0
  89. package/dist/engine/agent-api/RootDiagnosticSnapshot.js +2 -0
  90. package/dist/engine/agent-api/RootDiagnosticSnapshot.js.map +1 -0
  91. package/dist/engine/agent-api/RootFrameClock.d.ts +2 -0
  92. package/dist/engine/agent-api/RootFrameClock.d.ts.map +1 -0
  93. package/dist/engine/agent-api/RootFrameClock.js +2 -0
  94. package/dist/engine/agent-api/RootFrameClock.js.map +1 -0
  95. package/dist/engine/agent-api/RootPerformanceQuality.d.ts +2 -0
  96. package/dist/engine/agent-api/RootPerformanceQuality.d.ts.map +1 -0
  97. package/dist/engine/agent-api/RootPerformanceQuality.js +2 -0
  98. package/dist/engine/agent-api/RootPerformanceQuality.js.map +1 -0
  99. package/dist/engine/agent-api/RootRuntimeSupport.d.ts +61 -0
  100. package/dist/engine/agent-api/RootRuntimeSupport.d.ts.map +1 -0
  101. package/dist/engine/agent-api/RootRuntimeSupport.js +127 -0
  102. package/dist/engine/agent-api/RootRuntimeSupport.js.map +1 -0
  103. package/dist/engine/agent-api/RuntimeNodeHandle.d.ts +22 -0
  104. package/dist/engine/agent-api/RuntimeNodeHandle.d.ts.map +1 -1
  105. package/dist/engine/agent-api/RuntimeNodeHandle.js.map +1 -1
  106. package/dist/engine/agent-api/WorldLabelRenderer.d.ts +13 -2
  107. package/dist/engine/agent-api/WorldLabelRenderer.d.ts.map +1 -1
  108. package/dist/engine/agent-api/WorldLabelRenderer.js +58 -26
  109. package/dist/engine/agent-api/WorldLabelRenderer.js.map +1 -1
  110. package/dist/engine/agent-api/index.d.ts +103 -8
  111. package/dist/engine/agent-api/index.d.ts.map +1 -1
  112. package/dist/engine/agent-api/index.js +750 -242
  113. package/dist/engine/agent-api/index.js.map +1 -1
  114. package/dist/engine/agent-api/product-viewer-runtime.d.ts.map +1 -1
  115. package/dist/engine/production-runtime/RootGpuParticleWorkload.d.ts +34 -0
  116. package/dist/engine/production-runtime/RootGpuParticleWorkload.d.ts.map +1 -0
  117. package/dist/engine/production-runtime/RootGpuParticleWorkload.js +117 -0
  118. package/dist/engine/production-runtime/RootGpuParticleWorkload.js.map +1 -0
  119. package/dist/engine/production-runtime/RootRenderSourceBridge.d.ts +2 -0
  120. package/dist/engine/production-runtime/RootRenderSourceBridge.d.ts.map +1 -0
  121. package/dist/engine/production-runtime/RootRenderSourceBridge.js +2 -0
  122. package/dist/engine/production-runtime/RootRenderSourceBridge.js.map +1 -0
  123. package/dist/engine/production-runtime/TypedGLBActor.d.ts +6 -0
  124. package/dist/engine/production-runtime/TypedGLBActor.d.ts.map +1 -1
  125. package/dist/engine/production-runtime/TypedGLBActor.js +13 -0
  126. package/dist/engine/production-runtime/TypedGLBActor.js.map +1 -1
  127. package/dist/engine/production-runtime/index.d.ts +2 -0
  128. package/dist/engine/production-runtime/index.d.ts.map +1 -1
  129. package/dist/engine/production-runtime/index.js +2 -0
  130. package/dist/engine/production-runtime/index.js.map +1 -1
  131. package/dist/input/Haptics.d.ts +1 -1
  132. package/dist/input/Haptics.js +1 -1
  133. package/dist/input/InputSystem.d.ts.map +1 -1
  134. package/dist/input/InputSystem.js +1 -0
  135. package/dist/input/InputSystem.js.map +1 -1
  136. package/dist/input/PointerDevice.d.ts +1 -0
  137. package/dist/input/PointerDevice.d.ts.map +1 -1
  138. package/dist/input/PointerDevice.js +1 -1
  139. package/dist/input/PointerDevice.js.map +1 -1
  140. package/dist/input/controls/OrbitControls.d.ts +44 -1
  141. package/dist/input/controls/OrbitControls.d.ts.map +1 -1
  142. package/dist/input/controls/OrbitControls.js +151 -12
  143. package/dist/input/controls/OrbitControls.js.map +1 -1
  144. package/dist/lean/base.d.ts +1 -1
  145. package/dist/lean/base.d.ts.map +1 -1
  146. package/dist/lean/base.js +1 -1
  147. package/dist/lean/base.js.map +1 -1
  148. package/dist/lean/index.js +1 -1
  149. package/dist/lean/index.js.map +1 -1
  150. package/dist/navigation-recast/index.d.ts +116 -0
  151. package/dist/navigation-recast/index.d.ts.map +1 -0
  152. package/dist/navigation-recast/index.js +247 -0
  153. package/dist/navigation-recast/index.js.map +1 -0
  154. package/dist/physics-rapier/HeightfieldLayout.d.ts +12 -0
  155. package/dist/physics-rapier/HeightfieldLayout.d.ts.map +1 -0
  156. package/dist/physics-rapier/HeightfieldLayout.js +19 -0
  157. package/dist/physics-rapier/HeightfieldLayout.js.map +1 -0
  158. package/dist/physics-rapier/index.d.ts.map +1 -1
  159. package/dist/physics-rapier/index.js +2 -1
  160. package/dist/physics-rapier/index.js.map +1 -1
  161. package/dist/rendering/CascadedShadowMaps.d.ts.map +1 -1
  162. package/dist/rendering/CascadedShadowMaps.js +3 -1
  163. package/dist/rendering/CascadedShadowMaps.js.map +1 -1
  164. package/dist/rendering/ExtensionScalarAtlas.d.ts +18 -0
  165. package/dist/rendering/ExtensionScalarAtlas.d.ts.map +1 -0
  166. package/dist/rendering/ExtensionScalarAtlas.js +107 -0
  167. package/dist/rendering/ExtensionScalarAtlas.js.map +1 -0
  168. package/dist/rendering/LeanWebGL2Device.d.ts +265 -0
  169. package/dist/rendering/LeanWebGL2Device.d.ts.map +1 -0
  170. package/dist/rendering/LeanWebGL2Device.js +4001 -0
  171. package/dist/rendering/LeanWebGL2Device.js.map +1 -0
  172. package/dist/rendering/MaterialBinding.js +1 -1
  173. package/dist/rendering/MaterialBinding.js.map +1 -1
  174. package/dist/rendering/PlanarReflection.d.ts +2 -2
  175. package/dist/rendering/PlanarReflection.js +3 -3
  176. package/dist/rendering/PlanarReflection.js.map +1 -1
  177. package/dist/rendering/PostProcessPass.d.ts +19 -0
  178. package/dist/rendering/PostProcessPass.d.ts.map +1 -1
  179. package/dist/rendering/PostProcessPass.js +64 -32
  180. package/dist/rendering/PostProcessPass.js.map +1 -1
  181. package/dist/rendering/ProjectionMath.d.ts +3 -0
  182. package/dist/rendering/ProjectionMath.d.ts.map +1 -0
  183. package/dist/rendering/ProjectionMath.js +26 -0
  184. package/dist/rendering/ProjectionMath.js.map +1 -0
  185. package/dist/rendering/ReflectionSurfaces.d.ts +4 -1
  186. package/dist/rendering/ReflectionSurfaces.d.ts.map +1 -1
  187. package/dist/rendering/ReflectionSurfaces.js +10 -1
  188. package/dist/rendering/ReflectionSurfaces.js.map +1 -1
  189. package/dist/rendering/RenderDevice.d.ts +5 -0
  190. package/dist/rendering/RenderDevice.d.ts.map +1 -1
  191. package/dist/rendering/RenderDevice.js.map +1 -1
  192. package/dist/rendering/Renderer.d.ts +9 -0
  193. package/dist/rendering/Renderer.d.ts.map +1 -1
  194. package/dist/rendering/Renderer.js +94 -8
  195. package/dist/rendering/Renderer.js.map +1 -1
  196. package/dist/rendering/RendererPostprocessPlan.d.ts +16 -3
  197. package/dist/rendering/RendererPostprocessPlan.d.ts.map +1 -1
  198. package/dist/rendering/RendererPostprocessPlan.js +16 -2
  199. package/dist/rendering/RendererPostprocessPlan.js.map +1 -1
  200. package/dist/rendering/ScreenSpaceReflectionPass.d.ts +43 -0
  201. package/dist/rendering/ScreenSpaceReflectionPass.d.ts.map +1 -0
  202. package/dist/rendering/ScreenSpaceReflectionPass.js +58 -0
  203. package/dist/rendering/ScreenSpaceReflectionPass.js.map +1 -0
  204. package/dist/rendering/ShaderLibrary.d.ts.map +1 -1
  205. package/dist/rendering/ShaderLibrary.js +168 -197
  206. package/dist/rendering/ShaderLibrary.js.map +1 -1
  207. package/dist/rendering/ShaderLibraryCore.d.ts +3 -0
  208. package/dist/rendering/ShaderLibraryCore.d.ts.map +1 -1
  209. package/dist/rendering/ShaderLibraryCore.js +3 -0
  210. package/dist/rendering/ShaderLibraryCore.js.map +1 -1
  211. package/dist/rendering/TemporalHistory.d.ts +37 -0
  212. package/dist/rendering/TemporalHistory.d.ts.map +1 -0
  213. package/dist/rendering/TemporalHistory.js +135 -0
  214. package/dist/rendering/TemporalHistory.js.map +1 -0
  215. package/dist/rendering/TemporalMath.d.ts +3 -0
  216. package/dist/rendering/TemporalMath.d.ts.map +1 -0
  217. package/dist/rendering/TemporalMath.js +9 -0
  218. package/dist/rendering/TemporalMath.js.map +1 -0
  219. package/dist/rendering/TexturedPBRMaterial.d.ts +3 -0
  220. package/dist/rendering/TexturedPBRMaterial.d.ts.map +1 -1
  221. package/dist/rendering/TexturedPBRMaterial.js +65 -3
  222. package/dist/rendering/TexturedPBRMaterial.js.map +1 -1
  223. package/dist/rendering/WebGL2Device.d.ts +15 -0
  224. package/dist/rendering/WebGL2Device.d.ts.map +1 -1
  225. package/dist/rendering/WebGL2Device.js +328 -90
  226. package/dist/rendering/WebGL2Device.js.map +1 -1
  227. package/dist/rendering/WebGPUDevice.d.ts +16 -5
  228. package/dist/rendering/WebGPUDevice.d.ts.map +1 -1
  229. package/dist/rendering/WebGPUDevice.js +357 -58
  230. package/dist/rendering/WebGPUDevice.js.map +1 -1
  231. package/dist/rendering/WebGPUExtensionAtlas.d.ts +6 -0
  232. package/dist/rendering/WebGPUExtensionAtlas.d.ts.map +1 -0
  233. package/dist/rendering/WebGPUExtensionAtlas.js +225 -0
  234. package/dist/rendering/WebGPUExtensionAtlas.js.map +1 -0
  235. package/dist/rendering/effects/GPUParticleBackend.d.ts +4 -2
  236. package/dist/rendering/effects/GPUParticleBackend.d.ts.map +1 -1
  237. package/dist/rendering/effects/GPUParticleBackend.js +20 -2
  238. package/dist/rendering/effects/GPUParticleBackend.js.map +1 -1
  239. package/dist/rendering/effects/ResidentGPUParticleRenderer.d.ts +158 -0
  240. package/dist/rendering/effects/ResidentGPUParticleRenderer.d.ts.map +1 -0
  241. package/dist/rendering/effects/ResidentGPUParticleRenderer.js +576 -0
  242. package/dist/rendering/effects/ResidentGPUParticleRenderer.js.map +1 -0
  243. package/dist/rendering/extension-scalar-atlas.d.ts +3 -0
  244. package/dist/rendering/extension-scalar-atlas.d.ts.map +1 -0
  245. package/dist/rendering/extension-scalar-atlas.js +2 -0
  246. package/dist/rendering/extension-scalar-atlas.js.map +1 -0
  247. package/dist/rendering/index.d.ts +1 -0
  248. package/dist/rendering/index.d.ts.map +1 -1
  249. package/dist/rendering/index.js +1 -0
  250. package/dist/rendering/index.js.map +1 -1
  251. package/dist/rendering/lean/LeanProductionRenderer.d.ts.map +1 -1
  252. package/dist/rendering/lean/LeanProductionRenderer.js +2 -2
  253. package/dist/rendering/lean/LeanProductionRenderer.js.map +1 -1
  254. package/dist/rendering/lean-core-runtime.d.ts +13 -0
  255. package/dist/rendering/lean-core-runtime.d.ts.map +1 -0
  256. package/dist/rendering/lean-core-runtime.js +10 -0
  257. package/dist/rendering/lean-core-runtime.js.map +1 -0
  258. package/dist/rendering/postprocess/NativeBloomPyramid.d.ts +17 -1
  259. package/dist/rendering/postprocess/NativeBloomPyramid.d.ts.map +1 -1
  260. package/dist/rendering/postprocess/NativeBloomPyramid.js +31 -1
  261. package/dist/rendering/postprocess/NativeBloomPyramid.js.map +1 -1
  262. package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts +1 -0
  263. package/dist/rendering/production-runtime/ProductionRendererTypes.d.ts.map +1 -1
  264. package/dist/rendering/production-runtime/ProductionRendererTypes.js.map +1 -1
  265. package/dist/rendering/production-runtime/ProductionRuntimeRenderer.d.ts +3 -0
  266. package/dist/rendering/production-runtime/ProductionRuntimeRenderer.d.ts.map +1 -1
  267. package/dist/rendering/production-runtime/ProductionRuntimeRenderer.js +8 -1
  268. package/dist/rendering/production-runtime/ProductionRuntimeRenderer.js.map +1 -1
  269. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.d.ts +4 -0
  270. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.d.ts.map +1 -1
  271. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js +15 -0
  272. package/dist/rendering/production-runtime/ProductionWebGL2Renderer.js.map +1 -1
  273. package/dist/rendering/production-runtime/ProductionWebGPURenderer.d.ts +7 -1
  274. package/dist/rendering/production-runtime/ProductionWebGPURenderer.d.ts.map +1 -1
  275. package/dist/rendering/production-runtime/ProductionWebGPURenderer.js +28 -2
  276. package/dist/rendering/production-runtime/ProductionWebGPURenderer.js.map +1 -1
  277. package/dist/rendering/production-runtime/framegraph/FrameGraph.d.ts +4 -2
  278. package/dist/rendering/production-runtime/framegraph/FrameGraph.d.ts.map +1 -1
  279. package/dist/rendering/production-runtime/framegraph/FrameGraph.js +62 -4
  280. package/dist/rendering/production-runtime/framegraph/FrameGraph.js.map +1 -1
  281. package/dist/rendering/production-runtime/framegraph/NativeFrameGraphBindings.d.ts +32 -0
  282. package/dist/rendering/production-runtime/framegraph/NativeFrameGraphBindings.d.ts.map +1 -0
  283. package/dist/rendering/production-runtime/framegraph/NativeFrameGraphBindings.js +111 -0
  284. package/dist/rendering/production-runtime/framegraph/NativeFrameGraphBindings.js.map +1 -0
  285. package/dist/rendering/production-runtime/framegraph/RenderPass.d.ts +23 -0
  286. package/dist/rendering/production-runtime/framegraph/RenderPass.d.ts.map +1 -1
  287. package/dist/rendering/production-runtime/framegraph/RenderPass.js +87 -1
  288. package/dist/rendering/production-runtime/framegraph/RenderPass.js.map +1 -1
  289. package/dist/rendering/production-runtime/index.d.ts +2 -0
  290. package/dist/rendering/production-runtime/index.d.ts.map +1 -1
  291. package/dist/rendering/production-runtime/index.js +1 -0
  292. package/dist/rendering/production-runtime/index.js.map +1 -1
  293. package/dist/rendering/production-runtime/passes/DepthPrepass.d.ts +4 -12
  294. package/dist/rendering/production-runtime/passes/DepthPrepass.d.ts.map +1 -1
  295. package/dist/rendering/production-runtime/passes/DepthPrepass.js +3 -11
  296. package/dist/rendering/production-runtime/passes/DepthPrepass.js.map +1 -1
  297. package/dist/rendering/production-runtime/passes/FramegraphTopology.js +1 -1
  298. package/dist/rendering/production-runtime/passes/FramegraphTopology.js.map +1 -1
  299. package/dist/rendering/production-runtime/passes/OpaquePass.d.ts +3 -8
  300. package/dist/rendering/production-runtime/passes/OpaquePass.d.ts.map +1 -1
  301. package/dist/rendering/production-runtime/passes/OpaquePass.js +3 -1
  302. package/dist/rendering/production-runtime/passes/OpaquePass.js.map +1 -1
  303. package/dist/rendering/production-runtime/passes/ShadowPass.d.ts +3 -8
  304. package/dist/rendering/production-runtime/passes/ShadowPass.d.ts.map +1 -1
  305. package/dist/rendering/production-runtime/passes/ShadowPass.js +2 -0
  306. package/dist/rendering/production-runtime/passes/ShadowPass.js.map +1 -1
  307. package/dist/rendering/production-runtime/passes/SkyboxPass.d.ts +3 -7
  308. package/dist/rendering/production-runtime/passes/SkyboxPass.d.ts.map +1 -1
  309. package/dist/rendering/production-runtime/passes/SkyboxPass.js +2 -0
  310. package/dist/rendering/production-runtime/passes/SkyboxPass.js.map +1 -1
  311. package/dist/rendering/production-runtime/passes/ToneMappingPass.d.ts +7 -10
  312. package/dist/rendering/production-runtime/passes/ToneMappingPass.d.ts.map +1 -1
  313. package/dist/rendering/production-runtime/passes/ToneMappingPass.js +9 -0
  314. package/dist/rendering/production-runtime/passes/ToneMappingPass.js.map +1 -1
  315. package/dist/rendering/production-runtime/passes/TransparentPass.d.ts +4 -9
  316. package/dist/rendering/production-runtime/passes/TransparentPass.d.ts.map +1 -1
  317. package/dist/rendering/production-runtime/passes/TransparentPass.js +6 -1
  318. package/dist/rendering/production-runtime/passes/TransparentPass.js.map +1 -1
  319. package/dist/rendering/reflection-surfaces.d.ts +5 -0
  320. package/dist/rendering/reflection-surfaces.d.ts.map +1 -0
  321. package/dist/rendering/reflection-surfaces.js +3 -0
  322. package/dist/rendering/reflection-surfaces.js.map +1 -0
  323. package/dist/rendering/webgpu/WebGPUPostShaders.d.ts +2 -3
  324. package/dist/rendering/webgpu/WebGPUPostShaders.d.ts.map +1 -1
  325. package/dist/rendering/webgpu/WebGPUPostShaders.js +2 -3
  326. package/dist/rendering/webgpu/WebGPUPostShaders.js.map +1 -1
  327. package/dist/rendering/webgpu/WebGPUTemporal.d.ts +17 -0
  328. package/dist/rendering/webgpu/WebGPUTemporal.d.ts.map +1 -0
  329. package/dist/rendering/webgpu/WebGPUTemporal.js +64 -0
  330. package/dist/rendering/webgpu/WebGPUTemporal.js.map +1 -0
  331. package/dist/rendering/webgpu.d.ts +6 -0
  332. package/dist/rendering/webgpu.d.ts.map +1 -1
  333. package/dist/rendering/webgpu.js +4 -0
  334. package/dist/rendering/webgpu.js.map +1 -1
  335. package/package.json +37 -24
  336. package/templates/cinematic-scene/package.json +2 -2
  337. package/templates/cinematic-scene/src/main.ts +14 -2
  338. package/templates/mini-game/package.json +2 -2
  339. package/templates/product-viewer/package.json +2 -2
  340. package/templates/production-asset-inspector/package.json +1 -1
  341. package/templates/production-material-studio/package.json +1 -1
  342. package/templates/production-product-configurator/package.json +1 -1
  343. package/templates/production-product-viewer/package.json +1 -1
  344. package/templates/cinematic-scene/node_modules/.vite/deps/_metadata.json +0 -8
  345. package/templates/cinematic-scene/node_modules/.vite/deps/package.json +0 -3
  346. package/templates/cinematic-scene/test-results/.last-run.json +0 -6
  347. package/templates/cinematic-scene/test-results/route-health-Aura3D-cinematic-scene-reaches-ready-state/error-context.md +0 -64
  348. package/templates/product-viewer/node_modules/.vite/deps/_metadata.json +0 -8
  349. package/templates/product-viewer/node_modules/.vite/deps/package.json +0 -3
@@ -1,10 +1,12 @@
1
+ import { temporalAccumulationWeight } from "./TemporalMath.js";
2
+ import { invertSsrProjection } from "./ProjectionMath.js";
1
3
  import { RenderDeviceError, resolveGpuTargetOwner, spreadGpuTargetInventory, } from "./RenderDevice.js";
2
4
  import { Texture, isCompressedTextureFormat, isFloatColorTextureFormat } from "./Texture.js";
3
5
  import { isTextureBinding, TextureBinding } from "./TextureBinding.js";
4
6
  import {} from "./VertexFormat.js";
5
7
  import { WebGL2StateCache } from "./WebGL2StateCache.js";
6
8
  import { BLOOM_BRIGHT_LUT_HEIGHT, BLOOM_BRIGHT_LUT_WIDTH, BLOOM_COMPOSITE_LUT_SIZE, OUTLINE_BLEND_LUT_WIDTH, OUTLINE_LIMB_RADIX, createOutlineBlendLut, createOutlineGradientBound, createBloomBrightThresholdLut, createBloomCompositeLut } from "./postprocess/NativeLdrEffectLuts.js";
7
- import { normalizeBloomQualityPreset, resolveBloomPyramidPlan, } from "./postprocess/NativeBloomPyramid.js";
9
+ import { normalizeBloomQualityPreset, resolveBloomPyramidBlurRadii, resolveBloomPyramidPlan, resolveBloomPyramidResponseGain, } from "./postprocess/NativeBloomPyramid.js";
8
10
  const WEBGL_CUBE_FACES = ["px", "nx", "py", "ny", "pz", "nz"];
9
11
  class WebGL2Buffer {
10
12
  id;
@@ -112,6 +114,8 @@ export class WebGL2Device {
112
114
  gl;
113
115
  nextId = 1;
114
116
  drawCalls = 0;
117
+ nativeTemporalPasses = 0;
118
+ nativeTemporalBindings = 0;
115
119
  buffers = new Set();
116
120
  shaders = new Set();
117
121
  renderTargets = new Set();
@@ -137,6 +141,7 @@ export class WebGL2Device {
137
141
  motionBlurVelocityTexture = null;
138
142
  motionBlurVelocitySize = null;
139
143
  taaProgram = null;
144
+ taaPresentationProgram = null;
140
145
  taaHistoryTexture = null;
141
146
  taaHistorySize = null;
142
147
  bloomPingPongResources = null;
@@ -516,7 +521,9 @@ export class WebGL2Device {
516
521
  this.renderTargets.add(target);
517
522
  // Shadow passes label their depth target after the shadow map texture, so the
518
523
  // label is the device-side signal that a shadow depth target was allocated.
519
- if ((descriptor.label ?? "").toLowerCase().includes("shadow"))
524
+ // Cascaded maps use the established renderer-csm-cascade-* labels.
525
+ // Count their actual allocation too, including the first shadow frame.
526
+ if (/shadow|(?:^|-)csm(?:-|$)/i.test(descriptor.label ?? ""))
520
527
  this.shadowRenderTargetsAllocated += 1;
521
528
  this.textures.set(target.colorTexture, colorHandle);
522
529
  this.textureUploadModes.set(target.colorTexture, "rgba8");
@@ -618,6 +625,29 @@ export class WebGL2Device {
618
625
  });
619
626
  }
620
627
  }
628
+ /** Executes the same native SSR kernel used by postprocessing into an owned target. */
629
+ executeReflectionSurfaceSsr(source, normalMask, output, options) {
630
+ this.assertAlive();
631
+ for (const target of [source, normalMask, output]) {
632
+ if (!(target instanceof WebGL2RenderTarget) || !this.renderTargets.has(target) || target.disposed) {
633
+ throw new RenderDeviceError("SSR inputs must be live targets owned by this device", "INVALID_RESOURCE");
634
+ }
635
+ }
636
+ const color = source, normals = normalMask, destination = output;
637
+ if (!color.depthTextureHandle || color === destination || normals === destination
638
+ || color.width !== normals.width || color.height !== normals.height) {
639
+ throw new RenderDeviceError("SSR requires sampleable scene depth, matching normal-mask input, and a separate output", "INVALID_RESOURCE");
640
+ }
641
+ this.resolveMultisampleTarget(color);
642
+ this.resolveMultisampleTarget(normals);
643
+ const state = this.prepareFullscreenPresentation(destination.framebuffer, destination.width, destination.height);
644
+ try {
645
+ this.drawSsrKernel(color.colorHandle, color.depthTextureHandle, destination.width, destination.height, { ...options, normalMask: normals.colorHandle }, this.ensurePresentationVertexArray(), { near: 0.1, far: 1000 });
646
+ }
647
+ finally {
648
+ this.restoreFullscreenPresentationState(state, destination.width, destination.height);
649
+ }
650
+ }
621
651
  presentLdrPostprocess(source, options) {
622
652
  this.assertAlive();
623
653
  if (!(source instanceof WebGL2RenderTarget) || !this.renderTargets.has(source) || source.disposed) {
@@ -701,10 +731,10 @@ export class WebGL2Device {
701
731
  if (outlineOptions) {
702
732
  this.ensureOutlineBlendLutTexture(outlineOptions);
703
733
  }
704
- if (motionBlurOptions) {
734
+ if (motionBlurOptions?.velocity) {
705
735
  this.ensureMotionBlurVelocityTexture(source.width, source.height, motionBlurOptions.velocity);
706
736
  }
707
- if (taaOptions) {
737
+ if (taaOptions?.history) {
708
738
  this.ensureTaaHistoryTexture(source.width, source.height, taaOptions.history);
709
739
  }
710
740
  const outputWidth = webglOutputTarget?.width ?? (this.viewportWidth || this.gl.drawingBufferWidth);
@@ -743,7 +773,7 @@ export class WebGL2Device {
743
773
  this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_blurred"), 1);
744
774
  this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_compositeLut"), 2);
745
775
  this.gl.uniform1i(this.gl.getUniformLocation(pyramidComposite, "u_hdr"), sourceIsHdr ? 1 : 0);
746
- this.gl.uniform1f(this.gl.getUniformLocation(pyramidComposite, "u_intensity"), bloomOptions.intensity);
776
+ this.gl.uniform1f(this.gl.getUniformLocation(pyramidComposite, "u_intensity"), bloomOptions.intensity * resolveBloomPyramidResponseGain(plan));
747
777
  this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
748
778
  ldrSourceHandle = bloomResources.textures[1];
749
779
  // The composited result lives in texture B, so subsequent passes
@@ -1041,6 +1071,8 @@ export class WebGL2Device {
1041
1071
  ["actualViewportHeight", viewport[3] ?? 0],
1042
1072
  ["renderTarget", this.activeRenderTarget?.label ?? null],
1043
1073
  ["drawCalls", this.drawCalls],
1074
+ ["nativeTemporalPasses", this.nativeTemporalPasses],
1075
+ ["nativeTemporalBindings", this.nativeTemporalBindings],
1044
1076
  ["shaderProgramCreates", this.shaderProgramCreateCount],
1045
1077
  ["uniformLocationLookups", this.uniformLocationLookupCount],
1046
1078
  ["bufferUpdates", this.bufferUpdateCount],
@@ -1090,6 +1122,8 @@ export class WebGL2Device {
1090
1122
  shadowRenderTargetsAllocated: this.shadowRenderTargetsAllocated,
1091
1123
  nativeInstancedSubmissions: this.nativeInstancedSubmissions,
1092
1124
  bloom: this.lastBloomDiagnostics,
1125
+ nativeTemporalPasses: this.nativeTemporalPasses,
1126
+ nativeTemporalBindings: this.nativeTemporalBindings,
1093
1127
  samplerAnisotropyUploads: this.samplerAnisotropyUploadCount,
1094
1128
  maxTextureAnisotropy: this.maxTextureAnisotropy,
1095
1129
  stateCacheIssued: stateCacheStats.issued,
@@ -1203,6 +1237,10 @@ export class WebGL2Device {
1203
1237
  this.gl.deleteProgram(this.taaProgram);
1204
1238
  this.taaProgram = null;
1205
1239
  }
1240
+ if (this.taaPresentationProgram) {
1241
+ this.gl.deleteProgram(this.taaPresentationProgram);
1242
+ this.taaPresentationProgram = null;
1243
+ }
1206
1244
  if (this.taaHistoryTexture) {
1207
1245
  this.gl.deleteTexture(this.taaHistoryTexture);
1208
1246
  this.taaHistoryTexture = null;
@@ -1594,6 +1632,7 @@ export class WebGL2Device {
1594
1632
  executeNativeBloomPyramidPasses(sourceTexture, sourceWidth, sourceHeight, resources, fullResStaging, options, vertexArray, hdr) {
1595
1633
  const plan = resources.plan;
1596
1634
  const mipCount = plan.mips.length;
1635
+ const blurRadii = resolveBloomPyramidBlurRadii(plan, options.radius);
1597
1636
  const downsampleProgram = this.ensureBloomDownsampleProgram();
1598
1637
  const brightProgram = this.ensureBloomBrightExtractProgram();
1599
1638
  const blurProgram = this.ensureBloomBlurProgram();
@@ -1602,8 +1641,8 @@ export class WebGL2Device {
1602
1641
  const mipTexture = (level, slot) => resources.textures[level * 2 + slot];
1603
1642
  const mipFramebuffer = (level, slot) => resources.framebuffers[level * 2 + slot];
1604
1643
  const mipSize = (level) => plan.mips[level];
1605
- // Blurred result settles in slot 1 for level 0, slot 0 for levels >= 1.
1606
- const blurredSlot = (level) => (level === 0 ? 1 : 0);
1644
+ // Every level settles in slot 0 after the vertical blur.
1645
+ const blurredSlot = (_level) => 0;
1607
1646
  const drawDownsample = (fromTexture, fromWidth, fromHeight, toFramebuffer, toWidth, toHeight) => {
1608
1647
  this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, toFramebuffer);
1609
1648
  this.gl.viewport(0, 0, toWidth, toHeight);
@@ -1612,6 +1651,7 @@ export class WebGL2Device {
1612
1651
  this.bindFullscreenTexture(0, fromTexture);
1613
1652
  this.gl.uniform1i(this.gl.getUniformLocation(downsampleProgram, "u_source"), 0);
1614
1653
  this.gl.uniform2f(this.gl.getUniformLocation(downsampleProgram, "u_texelSize"), 1 / fromWidth, 1 / fromHeight);
1654
+ this.gl.uniform2f(this.gl.getUniformLocation(downsampleProgram, "u_targetSize"), toWidth, toHeight);
1615
1655
  this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1616
1656
  };
1617
1657
  const drawBrightExtract = (fromTexture, toFramebuffer, size) => {
@@ -1629,7 +1669,7 @@ export class WebGL2Device {
1629
1669
  this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_softKnee"), options.softKnee);
1630
1670
  this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1631
1671
  };
1632
- const drawSeparableBlur = (readTexture, tmpTexture, tmpFramebuffer, outFramebuffer, size) => {
1672
+ const drawSeparableBlur = (readTexture, tmpTexture, tmpFramebuffer, outFramebuffer, size, radius) => {
1633
1673
  // Horizontal into the temp target, vertical back into the output target.
1634
1674
  this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, tmpFramebuffer);
1635
1675
  this.gl.viewport(0, 0, size.width, size.height);
@@ -1638,7 +1678,7 @@ export class WebGL2Device {
1638
1678
  this.bindFullscreenTexture(0, readTexture);
1639
1679
  this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_source"), 0);
1640
1680
  this.gl.uniform2i(this.gl.getUniformLocation(blurProgram, "u_size"), size.width, size.height);
1641
- this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_radius"), options.radius);
1681
+ this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_radius"), radius);
1642
1682
  this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 1);
1643
1683
  this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_hdr"), hdr ? 1 : 0);
1644
1684
  this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
@@ -1647,18 +1687,34 @@ export class WebGL2Device {
1647
1687
  this.gl.uniform1i(this.gl.getUniformLocation(blurProgram, "u_horizontal"), 0);
1648
1688
  this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1649
1689
  };
1650
- // Level 0: downsample, bright-extract into slot 1, blur H into slot 0 and
1651
- // V back into slot 1. Blurred result settles in slot 1.
1690
+ // Extract highlights at the source resolution before the first downsample.
1691
+ // Downsampling the complete scene first averaged narrow emissive sources
1692
+ // below the authored threshold, so balanced/cinematic bloom could execute
1693
+ // all native passes yet remain pixel-identical to disabled output.
1694
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, fullResStaging.framebufferA);
1695
+ this.gl.viewport(0, 0, sourceWidth, sourceHeight);
1696
+ this.gl.useProgram(brightProgram);
1697
+ this.gl.bindVertexArray(vertexArray);
1698
+ this.bindFullscreenTexture(0, sourceTexture);
1699
+ if (brightLut)
1700
+ this.bindFullscreenTexture(1, brightLut);
1701
+ this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_source"), 0);
1702
+ this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_brightLut"), 1);
1703
+ this.gl.uniform1i(this.gl.getUniformLocation(brightProgram, "u_hdr"), hdr ? 1 : 0);
1704
+ this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_threshold"), options.threshold);
1705
+ this.gl.uniform1f(this.gl.getUniformLocation(brightProgram, "u_softKnee"), options.softKnee);
1706
+ this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1707
+ // Level 0 downsamples the extracted highlight field, then blurs H into
1708
+ // slot 1 and V back into slot 0. The result therefore settles in slot 0.
1652
1709
  const level0 = mipSize(0);
1653
- drawDownsample(sourceTexture, sourceWidth, sourceHeight, mipFramebuffer(0, 0), level0.width, level0.height);
1654
- drawBrightExtract(mipTexture(0, 0), mipFramebuffer(0, 1), level0);
1655
- drawSeparableBlur(mipTexture(0, 1), mipTexture(0, 0), mipFramebuffer(0, 0), mipFramebuffer(0, 1), level0);
1710
+ drawDownsample(fullResStaging.textureA, sourceWidth, sourceHeight, mipFramebuffer(0, 0), level0.width, level0.height);
1711
+ drawSeparableBlur(mipTexture(0, 0), mipTexture(0, 1), mipFramebuffer(0, 1), mipFramebuffer(0, 0), level0, blurRadii[0]);
1656
1712
  for (let level = 1; level < mipCount; level += 1) {
1657
1713
  const size = mipSize(level);
1658
1714
  const previous = mipSize(level - 1);
1659
1715
  drawDownsample(mipTexture(level - 1, blurredSlot(level - 1)), previous.width, previous.height, mipFramebuffer(level, 0), size.width, size.height);
1660
1716
  // H into slot 1, V back into slot 0: blurred result settles in slot 0.
1661
- drawSeparableBlur(mipTexture(level, 0), mipTexture(level, 1), mipFramebuffer(level, 1), mipFramebuffer(level, 0), size);
1717
+ drawSeparableBlur(mipTexture(level, 0), mipTexture(level, 1), mipFramebuffer(level, 1), mipFramebuffer(level, 0), size, blurRadii[level]);
1662
1718
  }
1663
1719
  // Accumulate smallest-to-largest, ping-ponging between the two
1664
1720
  // accumulators (a pass must never sample its own bound target).
@@ -1762,23 +1818,35 @@ export class WebGL2Device {
1762
1818
  return targetTexture;
1763
1819
  }
1764
1820
  executeNativeSsrPass(sourceTexture, depthTexture, resources, options, vertexArray, targetIndex, depthRange) {
1765
- const program = this.ensureSsrProgram();
1766
1821
  const targetTexture = resources.textures[targetIndex];
1767
1822
  this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
1768
- this.gl.viewport(0, 0, resources.width, resources.height);
1823
+ this.drawSsrKernel(sourceTexture, depthTexture, resources.width, resources.height, options, vertexArray, depthRange);
1824
+ return targetTexture;
1825
+ }
1826
+ drawSsrKernel(sourceTexture, depthTexture, width, height, options, vertexArray, depthRange) {
1827
+ const program = this.ensureSsrProgram();
1828
+ this.gl.viewport(0, 0, width, height);
1769
1829
  this.gl.useProgram(program);
1770
1830
  this.gl.bindVertexArray(vertexArray);
1771
1831
  this.bindFullscreenTexture(0, sourceTexture);
1772
1832
  this.bindFullscreenTexture(1, depthTexture);
1833
+ this.bindFullscreenTexture(2, options.normalMask ?? sourceTexture);
1773
1834
  this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
1774
1835
  this.gl.uniform1i(this.gl.getUniformLocation(program, "u_depth"), 1);
1775
- this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), resources.width, resources.height);
1836
+ this.gl.uniform1i(this.gl.getUniformLocation(program, "u_normalMask"), 2);
1837
+ this.gl.uniform1i(this.gl.getUniformLocation(program, "u_hasNormalMask"), options.normalMask ? 1 : 0);
1838
+ this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), width, height);
1776
1839
  this.gl.uniform1f(this.gl.getUniformLocation(program, "u_intensity"), options.intensity);
1777
- this.gl.uniform1i(this.gl.getUniformLocation(program, "u_maxDistance"), options.maxDistance);
1840
+ this.gl.uniform1f(this.gl.getUniformLocation(program, "u_maxDistance"), options.maxDistance);
1841
+ this.gl.uniform1i(this.gl.getUniformLocation(program, "u_maxSteps"), options.maxSteps ?? 32);
1842
+ this.gl.uniform1f(this.gl.getUniformLocation(program, "u_thickness"), options.thickness ?? 0.2);
1843
+ if (options.projection && options.inverseProjection) {
1844
+ this.gl.uniformMatrix4fv(this.gl.getUniformLocation(program, "u_projection"), false, options.projection);
1845
+ this.gl.uniformMatrix4fv(this.gl.getUniformLocation(program, "u_inverseProjection"), false, options.inverseProjection);
1846
+ }
1778
1847
  this.gl.uniform1f(this.gl.getUniformLocation(program, "u_depthNear"), depthRange.near);
1779
1848
  this.gl.uniform1f(this.gl.getUniformLocation(program, "u_depthFar"), depthRange.far);
1780
1849
  this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1781
- return targetTexture;
1782
1850
  }
1783
1851
  executeNativeDepthOfFieldPass(sourceTexture, depthTexture, resources, options, vertexArray, targetIndex, depthRange) {
1784
1852
  const program = this.ensureDepthOfFieldProgram();
@@ -1801,7 +1869,7 @@ export class WebGL2Device {
1801
1869
  return targetTexture;
1802
1870
  }
1803
1871
  executeNativeMotionBlurPass(sourceTexture, resources, options, vertexArray, targetIndex) {
1804
- const velocityTexture = this.motionBlurVelocityTexture;
1872
+ const velocityTexture = options.temporal ? this.requireTemporalTarget(options.temporal.velocity, resources.width, resources.height).colorHandle : this.motionBlurVelocityTexture;
1805
1873
  if (!velocityTexture) {
1806
1874
  throw new RenderDeviceError("WebGL2 motion-blur velocity texture was not initialized", "WEBGL_ALLOCATION_FAILED");
1807
1875
  }
@@ -1818,28 +1886,66 @@ export class WebGL2Device {
1818
1886
  this.gl.uniform2i(this.gl.getUniformLocation(program, "u_size"), resources.width, resources.height);
1819
1887
  this.gl.uniform1i(this.gl.getUniformLocation(program, "u_samples"), options.samples);
1820
1888
  this.gl.uniform1f(this.gl.getUniformLocation(program, "u_scale"), options.scale);
1889
+ this.gl.uniform1i(this.gl.getUniformLocation(program, "u_velocityUv"), options.temporal ? 1 : 0);
1890
+ if (options.temporal) {
1891
+ this.nativeTemporalPasses++;
1892
+ this.nativeTemporalBindings++;
1893
+ }
1821
1894
  this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1822
1895
  return targetTexture;
1823
1896
  }
1824
1897
  executeNativeTaaPass(sourceTexture, resources, options, vertexArray, targetIndex) {
1825
- const historyTexture = this.taaHistoryTexture;
1898
+ const temporal = options.temporal;
1899
+ const historyTarget = temporal ? this.requireTemporalTarget(temporal.history, resources.width, resources.height) : undefined;
1900
+ const historyTexture = historyTarget?.colorHandle ?? this.taaHistoryTexture;
1826
1901
  if (!historyTexture) {
1827
1902
  throw new RenderDeviceError("WebGL2 TAA history texture was not initialized", "WEBGL_ALLOCATION_FAILED");
1828
1903
  }
1829
- const program = this.ensureTaaProgram();
1904
+ const accumulationProgram = this.ensureTaaProgram();
1830
1905
  const targetTexture = resources.textures[targetIndex];
1831
- this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
1832
1906
  this.gl.viewport(0, 0, resources.width, resources.height);
1833
- this.gl.useProgram(program);
1907
+ this.gl.useProgram(accumulationProgram);
1834
1908
  this.gl.bindVertexArray(vertexArray);
1835
1909
  this.bindFullscreenTexture(0, sourceTexture);
1836
1910
  this.bindFullscreenTexture(1, historyTexture);
1837
- this.gl.uniform1i(this.gl.getUniformLocation(program, "u_source"), 0);
1838
- this.gl.uniform1i(this.gl.getUniformLocation(program, "u_history"), 1);
1839
- this.gl.uniform1f(this.gl.getUniformLocation(program, "u_blend"), options.blend);
1840
- this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1911
+ this.gl.uniform1i(this.gl.getUniformLocation(accumulationProgram, "u_source"), 0);
1912
+ this.gl.uniform1i(this.gl.getUniformLocation(accumulationProgram, "u_history"), 1);
1913
+ this.gl.uniform1f(this.gl.getUniformLocation(accumulationProgram, "u_blend"), temporal && !temporal.historyValid ? 0 : temporalAccumulationWeight(options.blend, temporal?.historyFrames));
1914
+ this.gl.uniform1i(this.gl.getUniformLocation(accumulationProgram, "u_temporal"), temporal ? 1 : 0);
1915
+ if (temporal) {
1916
+ const velocity = this.requireTemporalTarget(temporal.velocity, resources.width, resources.height);
1917
+ const destination = this.requireTemporalTarget(temporal.historyOutput, resources.width, resources.height);
1918
+ if (destination === historyTarget || destination === velocity || historyTarget === velocity)
1919
+ throw new RenderDeviceError("Temporal targets must not alias", "TEMPORAL_TARGET_ALIAS");
1920
+ this.bindFullscreenTexture(2, velocity.colorHandle);
1921
+ this.gl.uniform1i(this.gl.getUniformLocation(accumulationProgram, "u_velocity"), 2);
1922
+ // Resolve exactly once into the next history target. Presentation reads
1923
+ // this immutable result through a separate program, so display tuning
1924
+ // cannot alter the accumulated history shader or its stored bytes.
1925
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, destination.framebuffer);
1926
+ this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1927
+ const presentationProgram = this.ensureTaaPresentationProgram();
1928
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
1929
+ this.gl.useProgram(presentationProgram);
1930
+ this.bindFullscreenTexture(0, sourceTexture);
1931
+ this.bindFullscreenTexture(1, destination.colorHandle);
1932
+ this.gl.uniform1i(this.gl.getUniformLocation(presentationProgram, "u_source"), 0);
1933
+ this.gl.uniform1i(this.gl.getUniformLocation(presentationProgram, "u_accumulated"), 1);
1934
+ this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1935
+ this.nativeTemporalPasses++;
1936
+ this.nativeTemporalBindings += 3;
1937
+ }
1938
+ else {
1939
+ this.gl.bindFramebuffer(this.gl.FRAMEBUFFER, resources.framebuffers[targetIndex]);
1940
+ this.gl.drawArrays(this.gl.TRIANGLES, 0, 3);
1941
+ }
1841
1942
  return targetTexture;
1842
1943
  }
1944
+ requireTemporalTarget(target, width, height) {
1945
+ if (!(target instanceof WebGL2RenderTarget) || !this.renderTargets.has(target) || target.disposed || target.width !== width || target.height !== height || target.colorTexture.format !== "rgba16f")
1946
+ throw new RenderDeviceError("Temporal input must be a live same-device same-size RGBA16F target", "TEMPORAL_TARGET_INVALID");
1947
+ return target;
1948
+ }
1843
1949
  bindFullscreenTexture(unit, texture) {
1844
1950
  this.gl.activeTexture(this.gl.TEXTURE0 + unit);
1845
1951
  this.gl.bindTexture(this.gl.TEXTURE_2D, texture);
@@ -1872,7 +1978,7 @@ export class WebGL2Device {
1872
1978
  mipCount,
1873
1979
  targetCount: options.quality === "performance" ? 2 : plan.mips.length * 2 + 1,
1874
1980
  targetBytes: (options.quality === "performance" ? pingPongBytes : plan.targetBytes + accumulatorBytes + pingPongBytes),
1875
- compositeGain: options.intensity,
1981
+ compositeGain: options.intensity * resolveBloomPyramidResponseGain(plan),
1876
1982
  threshold: options.threshold,
1877
1983
  intensity: options.intensity,
1878
1984
  softKnee: options.softKnee,
@@ -2336,38 +2442,25 @@ uniform int u_horizontal;
2336
2442
  uniform int u_hdr;
2337
2443
  out vec4 outColor;
2338
2444
 
2339
- uvec4 sourceByte(ivec2 coordinate) {
2340
- ivec2 bounded = clamp(coordinate, ivec2(0), u_size - ivec2(1));
2341
- return uvec4(texelFetch(u_source, bounded, 0) * 255.0 + 0.5);
2445
+ vec4 sourcePixel(ivec2 coordinate) {
2446
+ return texelFetch(u_source, clamp(coordinate, ivec2(0), u_size - ivec2(1)), 0);
2342
2447
  }
2343
2448
 
2344
2449
  void main() {
2345
2450
  ivec2 pixel = ivec2(gl_FragCoord.xy);
2346
- if (u_hdr == 1) {
2347
- vec4 sum = vec4(0.0);
2348
- for (int offset = -16; offset <= 16; offset += 1) {
2349
- if (abs(offset) > u_radius) continue;
2350
- ivec2 sampleCoordinate = pixel + (u_horizontal == 1 ? ivec2(offset, 0) : ivec2(0, offset));
2351
- sum += texelFetch(u_source, clamp(sampleCoordinate, ivec2(0), u_size - ivec2(1)), 0);
2352
- }
2353
- outColor = sum / float(u_radius * 2 + 1);
2354
- return;
2451
+ float sigma = max(float(u_radius) / 3.0, 0.5);
2452
+ float coefficient = 0.39894 / sigma;
2453
+ vec4 sum = sourcePixel(pixel) * coefficient;
2454
+ float weightSum = coefficient;
2455
+ for (int offset = 1; offset <= 16; offset += 1) {
2456
+ if (offset > u_radius) continue;
2457
+ float distance = float(offset);
2458
+ float weight = coefficient * exp(-0.5 * distance * distance / (sigma * sigma));
2459
+ ivec2 delta = u_horizontal == 1 ? ivec2(offset, 0) : ivec2(0, offset);
2460
+ sum += (sourcePixel(pixel + delta) + sourcePixel(pixel - delta)) * weight;
2461
+ weightSum += 2.0 * weight;
2355
2462
  }
2356
- uvec4 sum = uvec4(0u);
2357
- for (int offset = -16; offset <= 16; offset += 1) {
2358
- if (abs(offset) > u_radius) {
2359
- continue;
2360
- }
2361
- ivec2 sampleCoordinate = pixel + (
2362
- u_horizontal == 1
2363
- ? ivec2(offset, 0)
2364
- : ivec2(0, offset)
2365
- );
2366
- sum += sourceByte(sampleCoordinate);
2367
- }
2368
- uint kernelSize = uint(u_radius * 2 + 1);
2369
- uvec4 rounded = (sum * 2u + uvec4(kernelSize)) / uvec4(kernelSize * 2u);
2370
- outColor = vec4(rounded) / 255.0;
2463
+ outColor = sum / max(weightSum, 0.000001);
2371
2464
  }
2372
2465
  `, "webgl2-bloom-blur");
2373
2466
  return this.bloomBlurProgram;
@@ -2421,9 +2514,14 @@ void main() {
2421
2514
  precision highp float;
2422
2515
  uniform sampler2D u_source;
2423
2516
  uniform vec2 u_texelSize;
2517
+ uniform vec2 u_targetSize;
2424
2518
  out vec4 outColor;
2425
2519
  void main() {
2426
- vec2 uv = (gl_FragCoord.xy - 0.5) * u_texelSize;
2520
+ // gl_FragCoord is expressed in destination pixels. Normalize by the
2521
+ // destination size so every downsample covers the complete source image;
2522
+ // multiplying by source texel size cropped a half-size target to the
2523
+ // lower-left quarter of the preceding level.
2524
+ vec2 uv = gl_FragCoord.xy / u_targetSize;
2427
2525
  vec2 e = u_texelSize * 0.5;
2428
2526
  vec4 sum = texture(u_source, uv - e) + texture(u_source, uv + vec2(e.x, -e.y))
2429
2527
  + texture(u_source, uv + vec2(-e.x, e.y)) + texture(u_source, uv + e);
@@ -2590,40 +2688,73 @@ precision highp float;
2590
2688
  precision highp int;
2591
2689
  uniform sampler2D u_source;
2592
2690
  uniform sampler2D u_depth;
2691
+ uniform sampler2D u_normalMask;
2593
2692
  uniform ivec2 u_size;
2594
2693
  uniform float u_intensity;
2595
- uniform int u_maxDistance;
2596
- uniform float u_depthNear;
2597
- uniform float u_depthFar;
2694
+ uniform float u_maxDistance;
2695
+ uniform int u_maxSteps;
2696
+ uniform float u_thickness;
2697
+ uniform int u_hasNormalMask;
2698
+ uniform mat4 u_projection;
2699
+ uniform mat4 u_inverseProjection;
2598
2700
  out vec4 outColor;
2599
-
2600
- // Raw GL depth is nonlinear (0.1/1000 defaults park the play area past 0.97),
2601
- // so every depth-gated comparison below runs on linearized depth. The CPU
2602
- // byte kernel keeps fixture-unit semantics; the divergence is documented at
2603
- // normalizeLdrDepthRange.
2604
- float a3dSsrLinearDepth(float depth) {
2605
- float viewZ = u_depthNear * u_depthFar / max(u_depthFar - depth * (u_depthFar - u_depthNear), 0.0001);
2606
- return clamp((viewZ - u_depthNear) / max(u_depthFar - u_depthNear, 0.0001), 0.0, 1.0);
2701
+ vec3 positionAtDepth(vec2 uv, float depth) {
2702
+ vec4 p = u_inverseProjection * vec4(uv * 2.0 - 1.0, depth * 2.0 - 1.0, 1.0);
2703
+ return p.xyz / p.w;
2704
+ }
2705
+ vec3 positionAt(vec2 uv) {
2706
+ return positionAtDepth(uv, texture(u_depth, uv).r);
2707
+ }
2708
+ vec3 viewDirection(vec2 uv) {
2709
+ return normalize(positionAtDepth(uv, 0.999) - positionAtDepth(uv, 0.0));
2710
+ }
2711
+ vec2 projectPosition(vec3 p) {
2712
+ vec4 clip = u_projection * vec4(p, 1.0);
2713
+ return clip.xy / clip.w * 0.5 + 0.5;
2714
+ }
2715
+ float depthDifference(vec3 p, vec2 uv) {
2716
+ return dot(p - positionAt(uv), viewDirection(uv));
2607
2717
  }
2608
-
2609
2718
  void main() {
2610
- ivec2 pixel = ivec2(gl_FragCoord.xy);
2611
- vec4 target = texelFetch(u_source, pixel, 0);
2612
- float linearDepth = a3dSsrLinearDepth(texelFetch(u_depth, pixel, 0).r);
2613
- int rayDistance = max(1, int(round((1.0 - linearDepth) * float(u_maxDistance))));
2614
- int direction = pixel.x < u_size.x / 2 ? 1 : -1;
2615
- ivec2 samplePixel = ivec2(
2616
- clamp(pixel.x + direction * rayDistance, 0, u_size.x - 1),
2617
- clamp(u_size.y - 1 - pixel.y, 0, u_size.y - 1)
2618
- );
2619
- vec3 reflected = texelFetch(u_source, samplePixel, 0).rgb;
2620
- float sourceLuma = (reflected.r + reflected.g + reflected.b) / 3.0;
2621
- if (sourceLuma < 0.18 || linearDepth > 0.995) {
2622
- outColor = target;
2623
- return;
2719
+ vec2 uv = gl_FragCoord.xy / vec2(u_size);
2720
+ vec4 base = texture(u_source, uv);
2721
+ outColor = base;
2722
+ vec3 origin = positionAt(uv);
2723
+ vec4 normalMask = texture(u_normalMask, uv);
2724
+ vec3 normal = u_hasNormalMask == 1 ? normalize(normalMask.xyz * 2.0 - 1.0) : normalize(cross(dFdx(origin), dFdy(origin)));
2725
+ float roughness = u_hasNormalMask == 1 ? normalMask.a : 0.25;
2726
+ if (texture(u_depth, uv).r >= 0.999999 || (u_hasNormalMask == 1 && normalMask.a == 0.0) || roughness >= 1.0) return;
2727
+ vec3 ray = normalize(reflect(viewDirection(uv), normal));
2728
+ float stepSize = u_maxDistance / float(u_maxSteps);
2729
+ vec3 start = origin + normal * u_thickness;
2730
+ float previous = 0.0;
2731
+ for (int i = 1; i <= 64; ++i) {
2732
+ if (i > u_maxSteps) break;
2733
+ float distanceAlong = float(i) * stepSize;
2734
+ vec3 candidate = start + ray * distanceAlong;
2735
+ vec4 candidateClip = u_projection * vec4(candidate, 1.0);
2736
+ if (candidateClip.w <= 0.0 || abs(candidateClip.z) >= candidateClip.w) break;
2737
+ vec2 hitUV = projectPosition(candidate);
2738
+ if (any(lessThanEqual(hitUV, vec2(0.0))) || any(greaterThanEqual(hitUV, vec2(1.0)))) break;
2739
+ float difference = depthDifference(candidate, hitUV);
2740
+ if (difference >= 0.0 && previous < 0.0) {
2741
+ float lo = distanceAlong - stepSize, hi = distanceAlong;
2742
+ for (int j = 0; j < 5; ++j) {
2743
+ float mid = (lo + hi) * 0.5;
2744
+ vec3 point = start + ray * mid;
2745
+ if (depthDifference(point, projectPosition(point)) >= 0.0) hi = mid; else lo = mid;
2746
+ }
2747
+ candidate = start + ray * hi;
2748
+ hitUV = projectPosition(candidate);
2749
+ difference = depthDifference(candidate, hitUV);
2750
+ if (difference > u_thickness || texture(u_depth, hitUV).r >= 0.999999) break;
2751
+ float edge = smoothstep(0.0, 0.08, min(min(hitUV.x, hitUV.y), min(1.0 - hitUV.x, 1.0 - hitUV.y)));
2752
+ float response = clamp(u_intensity * edge * (1.0 - roughness) * (1.0 - hi / u_maxDistance), 0.0, 1.0);
2753
+ outColor = vec4(mix(base.rgb, texture(u_source, hitUV).rgb, response), base.a);
2754
+ break;
2755
+ }
2756
+ previous = difference;
2624
2757
  }
2625
- float boost = sourceLuma * u_intensity * (1.0 - linearDepth);
2626
- outColor = vec4(clamp(target.rgb + reflected * boost, 0.0, 1.0), target.a);
2627
2758
  }
2628
2759
  `, "webgl2-ssr");
2629
2760
  return this.ssrProgram;
@@ -2690,6 +2821,7 @@ precision highp float;
2690
2821
  precision highp int;
2691
2822
  uniform sampler2D u_source;
2692
2823
  uniform sampler2D u_velocity;
2824
+ uniform bool u_velocityUv;
2693
2825
  uniform ivec2 u_size;
2694
2826
  uniform int u_samples;
2695
2827
  uniform float u_scale;
@@ -2699,6 +2831,8 @@ void main() {
2699
2831
  ivec2 pixel = ivec2(gl_FragCoord.xy);
2700
2832
  vec4 source = texelFetch(u_source, pixel, 0);
2701
2833
  vec2 velocity = texelFetch(u_velocity, pixel, 0).rg * u_scale;
2834
+ if (u_velocityUv) velocity *= vec2(u_size);
2835
+ velocity = clamp(velocity, vec2(-64.0), vec2(64.0));
2702
2836
  if (length(velocity) < 0.01) {
2703
2837
  outColor = source;
2704
2838
  return;
@@ -2723,18 +2857,108 @@ void main() {
2723
2857
  precision highp float;
2724
2858
  uniform sampler2D u_source;
2725
2859
  uniform sampler2D u_history;
2860
+ uniform sampler2D u_velocity;
2726
2861
  uniform float u_blend;
2862
+ uniform bool u_temporal;
2727
2863
  out vec4 outColor;
2864
+ vec4 cubicWeights(float f) {
2865
+ float f2=f*f, f3=f2*f;
2866
+ return vec4(-0.5*f+f2-0.5*f3,1.0-2.5*f2+1.5*f3,0.5*f+2.0*f2-1.5*f3,-0.5*f2+0.5*f3);
2867
+ }
2868
+ vec4 historyAt(vec2 uv) {
2869
+ ivec2 size=textureSize(u_history,0);
2870
+ vec2 position=uv*vec2(size)-0.5;
2871
+ ivec2 base=ivec2(floor(position));
2872
+ vec4 wx=cubicWeights(fract(position.x)), wy=cubicWeights(fract(position.y));
2873
+ vec4 result=vec4(0.0);
2874
+ // Repeated bilinear history reconstruction diffuses a moving edge every
2875
+ // frame. Cubic reconstruction preserves it; the resolve's current-neighbor
2876
+ // clipping below bounds ringing before accumulation.
2877
+ for(int y=0;y<4;y++) for(int x=0;x<4;x++) {
2878
+ result+=texelFetch(u_history,clamp(base+ivec2(x-1,y-1),ivec2(0),size-1),0)*wx[x]*wy[y];
2879
+ }
2880
+ return result;
2881
+ }
2728
2882
 
2729
2883
  void main() {
2730
2884
  ivec2 pixel = ivec2(gl_FragCoord.xy);
2885
+ ivec2 size = textureSize(u_source, 0);
2886
+ vec2 outputUV=(vec2(pixel)+0.5)/vec2(size);
2887
+ // Raster jitter supplies quadrature samples inside the output pixel.
2888
+ // Keep that sample on its pixel's accumulation grid; undoing the jitter
2889
+ // spatially filters it and defeats temporal coverage integration.
2890
+ vec2 sourceUV=outputUV;
2891
+ ivec2 sourcePixel=clamp(ivec2(floor(sourceUV*vec2(size))),ivec2(0),size-1);
2892
+ // Reconstruct current color on the stable output grid before accumulation.
2731
2893
  vec4 source = texelFetch(u_source, pixel, 0);
2732
- vec3 history = texelFetch(u_history, pixel, 0).rgb;
2733
- outColor = vec4(mix(source.rgb, history, u_blend), source.a);
2894
+ vec4 motion = u_temporal ? texelFetch(u_velocity, sourcePixel, 0) : vec4(0.0);
2895
+ // A currently uncovered sample may still carry integrated foreground
2896
+ // coverage in history. Track nearby foreground motion for that coverage,
2897
+ // but retain this pixel's own current/previous depth tags: copying RGBA
2898
+ // wholesale falsely labels background color as a foreground surface.
2899
+ if (u_temporal) {
2900
+ float nearestDepth=motion.b;
2901
+ for(int y=-1;y<=1;y++) for(int x=-1;x<=1;x++) {
2902
+ vec4 candidate=texelFetch(u_velocity,clamp(pixel+ivec2(x,y),ivec2(0),size-1),0);
2903
+ if(candidate.b<nearestDepth) {nearestDepth=candidate.b;motion.xy=candidate.xy;}
2904
+ }
2905
+ }
2906
+ vec2 previousUV = outputUV-motion.xy;
2907
+ vec4 history = u_temporal ? historyAt(previousUV) : texture(u_history, previousUV);
2908
+ float weight = u_blend;
2909
+ if (u_temporal) {
2910
+ // Reprojected history incurs reconstruction error as the footprint moves
2911
+ // across the pixel grid. Reduce its confidence with displacement instead
2912
+ // of repeatedly giving a softened moving edge the stationary .9 weight.
2913
+ // Physical motion itself remains fully represented in previousUV.
2914
+ weight /= 1.0 + length(motion.xy * vec2(size));
2915
+ // Depth is categorical at a silhouette: bilinear alpha interpolation creates
2916
+ // nonexistent surfaces and rejects valid history on every jittered edge.
2917
+ // Test surface presence in the central history footprint. RGB remains
2918
+ // an integrated coverage value reconstructed from the wider cubic kernel.
2919
+ ivec2 previousBase=ivec2(floor(previousUV*vec2(size)-vec2(0.5)));
2920
+ float depthError=1.0;
2921
+ for(int y=0;y<2;y++) for(int x=0;x<2;x++) {
2922
+ float previousDepth=texelFetch(u_history,clamp(previousBase+ivec2(x,y),ivec2(0),size-1),0).a;
2923
+ depthError=min(depthError,abs(previousDepth-motion.a));
2924
+ }
2925
+ if (any(lessThan(previousUV,vec2(0.0))) || any(greaterThanEqual(previousUV,vec2(1.0))) || depthError>0.002) weight=0.0;
2926
+ vec3 lo=source.rgb, hi=source.rgb;
2927
+ for(int y=-1;y<=1;y++) for(int x=-1;x<=1;x++) { vec3 tap=texelFetch(u_source,clamp(pixel+ivec2(x,y),ivec2(0),size-1),0).rgb; lo=min(lo,tap); hi=max(hi,tap); }
2928
+ history.rgb=clamp(history.rgb,lo,hi);
2929
+ }
2930
+ vec3 resolved=mix(source.rgb,history.rgb,weight);
2931
+ outColor=vec4(resolved,u_temporal?motion.b:source.a);
2734
2932
  }
2735
- `, "webgl2-taa");
2933
+ `, "webgl2-taa-accumulation");
2736
2934
  return this.taaProgram;
2737
2935
  }
2936
+ ensureTaaPresentationProgram() {
2937
+ if (this.taaPresentationProgram)
2938
+ return this.taaPresentationProgram;
2939
+ this.taaPresentationProgram = this.createFullscreenProgram(`#version 300 es
2940
+ precision highp float;
2941
+ uniform sampler2D u_source;
2942
+ uniform sampler2D u_accumulated;
2943
+ out vec4 outColor;
2944
+ void main() {
2945
+ ivec2 pixel=ivec2(gl_FragCoord.xy);
2946
+ ivec2 size=textureSize(u_source,0);
2947
+ vec4 source=texelFetch(u_source,pixel,0);
2948
+ vec3 accumulated=texelFetch(u_accumulated,pixel,0).rgb;
2949
+ // Retained native pixels isolate the remaining spatial excess to the
2950
+ // horizontally moving silhouette. Apply a bounded three-tap unsharp resolve
2951
+ // to presentation only; accumulated history remains immutable.
2952
+ vec3 center=mix(source.rgb,accumulated,0.90);
2953
+ ivec2 leftPixel=clamp(pixel+ivec2(-1,0),ivec2(0),size-1);
2954
+ ivec2 rightPixel=clamp(pixel+ivec2(1,0),ivec2(0),size-1);
2955
+ vec3 left=mix(texelFetch(u_source,leftPixel,0).rgb,texelFetch(u_accumulated,leftPixel,0).rgb,0.90);
2956
+ vec3 right=mix(texelFetch(u_source,rightPixel,0).rgb,texelFetch(u_accumulated,rightPixel,0).rgb,0.90);
2957
+ outColor=vec4(clamp(center*1.04-(left+right)*0.02,0.0,1.0),source.a);
2958
+ }
2959
+ `, "webgl2-taa-presentation");
2960
+ return this.taaPresentationProgram;
2961
+ }
2738
2962
  createFullscreenProgram(fragmentSource, label) {
2739
2963
  const vertex = this.compileShader(this.gl.VERTEX_SHADER, `#version 300 es
2740
2964
  precision highp float;
@@ -3821,7 +4045,11 @@ function normalizeNativeSsrOptions(options) {
3821
4045
  if (!Number.isInteger(maxDistance) || maxDistance < 1 || maxDistance > 64) {
3822
4046
  throw new RenderDeviceError("SSR maxDistance must be an integer in [1, 64].", "INVALID_POSTPROCESS_OPTIONS", { maxDistance });
3823
4047
  }
3824
- return { intensity, maxDistance };
4048
+ const projection = options["projection"];
4049
+ if (!(projection instanceof Float32Array))
4050
+ throw new RenderDeviceError("Native SSR requires the actual frame projection or view-projection matrix.", "INVALID_POSTPROCESS_OPTIONS");
4051
+ const inverseProjection = invertSsrProjection(projection);
4052
+ return { intensity, maxDistance, projection, inverseProjection };
3825
4053
  }
3826
4054
  function normalizeNativeDepthOfFieldOptions(options) {
3827
4055
  const focusDepth = depthOfFieldNumberOption(options, "focusDepth", 0.5);
@@ -3841,6 +4069,11 @@ function normalizeNativeDepthOfFieldOptions(options) {
3841
4069
  function normalizeNativeMotionBlurOptions(options, width, height) {
3842
4070
  const samples = motionBlurNumberOption(options, "samples", 5);
3843
4071
  const scale = motionBlurNumberOption(options, "scale", 1);
4072
+ if (options.temporal) {
4073
+ if (!Number.isInteger(samples) || samples < 2 || samples > 16 || scale < 0 || scale > 8)
4074
+ throw new RenderDeviceError("Invalid motion blur samples/scale", "INVALID_POSTPROCESS_OPTIONS");
4075
+ return { samples, scale, temporal: options.temporal };
4076
+ }
3844
4077
  const value = options.velocity;
3845
4078
  if (!(value instanceof Float32Array) && !Array.isArray(value)) {
3846
4079
  throw new RenderDeviceError("Motion blur requires a velocity Float32Array or number array.", "WEBGL_LDR_POSTPROCESS_VELOCITY_REQUIRED");
@@ -3862,6 +4095,11 @@ function normalizeNativeMotionBlurOptions(options, width, height) {
3862
4095
  }
3863
4096
  function normalizeNativeTaaOptions(options, width, height) {
3864
4097
  const blend = taaNumberOption(options, "blend", 0.18);
4098
+ if (options.temporal) {
4099
+ if (blend < 0 || blend > .95)
4100
+ throw new RenderDeviceError("Invalid TAA blend", "INVALID_POSTPROCESS_OPTIONS");
4101
+ return { blend, temporal: options.temporal };
4102
+ }
3865
4103
  const history = options.history;
3866
4104
  if (!(history instanceof Uint8Array)) {
3867
4105
  throw new RenderDeviceError("TAA requires a Uint8Array history buffer.", "WEBGL_LDR_POSTPROCESS_HISTORY_REQUIRED");