@meimu/mutracer 0.0.0-stage → 0.1.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 (536) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES/Apache-2.0.txt +202 -0
  3. package/LICENSES/GLSL-PathTracer-MIT.txt +21 -0
  4. package/LICENSES/GlMatrix-MIT.txt +19 -0
  5. package/LICENSES/KinoBloom-MIT.txt +21 -0
  6. package/LICENSES/OIDNWeb-MIT.txt +21 -0
  7. package/LICENSES/Octicons-MIT.txt +21 -0
  8. package/LICENSES/RayTracingRenderer-MIT.txt +21 -0
  9. package/LICENSES/TinyBVH-MIT.txt +21 -0
  10. package/LICENSES/WebGPUUtils-MIT.txt +21 -0
  11. package/LICENSES/ZetaRay-MIT.txt +21 -0
  12. package/README.md +195 -2
  13. package/THIRD_PARTY_NOTICES.md +160 -0
  14. package/dist/assets/bvh.worker.js +1 -0
  15. package/dist/mutracer.umd.js +14352 -0
  16. package/docs/api.md +394 -0
  17. package/docs/bvh.md +141 -0
  18. package/docs/denoising.md +301 -0
  19. package/docs/getting-started.md +308 -0
  20. package/docs/materials.md +281 -0
  21. package/docs/performance.md +85 -0
  22. package/docs/post-processing.md +87 -0
  23. package/docs/progressive-rendering.md +144 -0
  24. package/docs/sampling.md +40 -0
  25. package/docs/threejs.md +273 -0
  26. package/docs/todo.md +61 -0
  27. package/docs/updates.md +208 -0
  28. package/lib/Display.d.ts +72 -0
  29. package/lib/Display.js +121 -0
  30. package/lib/Display.js.map +1 -0
  31. package/lib/Engine.d.ts +161 -0
  32. package/lib/Engine.js +681 -0
  33. package/lib/Engine.js.map +1 -0
  34. package/lib/Render.d.ts +256 -0
  35. package/lib/Render.js +671 -0
  36. package/lib/Render.js.map +1 -0
  37. package/lib/RenderLoop.d.ts +76 -0
  38. package/lib/RenderLoop.js +204 -0
  39. package/lib/RenderLoop.js.map +1 -0
  40. package/lib/Sync.d.ts +19 -0
  41. package/lib/Sync.js +19 -0
  42. package/lib/Sync.js.map +1 -0
  43. package/lib/constants.d.ts +2 -0
  44. package/lib/constants.js +3 -0
  45. package/lib/constants.js.map +1 -0
  46. package/lib/main.d.ts +56 -0
  47. package/lib/main.js +43 -0
  48. package/lib/main.js.map +1 -0
  49. package/lib/math.d.ts +23 -0
  50. package/lib/math.js +56 -0
  51. package/lib/math.js.map +1 -0
  52. package/lib/oidn.d.ts +45 -0
  53. package/lib/oidn.js +42 -0
  54. package/lib/oidn.js.map +1 -0
  55. package/lib/oidnBundledWeights.cdn.d.ts +2 -0
  56. package/lib/oidnBundledWeights.cdn.js +5 -0
  57. package/lib/oidnBundledWeights.cdn.js.map +1 -0
  58. package/lib/oidnBundledWeights.d.ts +2 -0
  59. package/lib/oidnBundledWeights.js +4 -0
  60. package/lib/oidnBundledWeights.js.map +1 -0
  61. package/lib/renderer/DisplayPostProcess.d.ts +14 -0
  62. package/lib/renderer/DisplayPostProcess.js +41 -0
  63. package/lib/renderer/DisplayPostProcess.js.map +1 -0
  64. package/lib/renderer/MaterialTable.d.ts +119 -0
  65. package/lib/renderer/MaterialTable.js +550 -0
  66. package/lib/renderer/MaterialTable.js.map +1 -0
  67. package/lib/renderer/OfflineAdaptiveSampling.d.ts +47 -0
  68. package/lib/renderer/OfflineAdaptiveSampling.js +36 -0
  69. package/lib/renderer/OfflineAdaptiveSampling.js.map +1 -0
  70. package/lib/renderer/RenderingPipeline.d.ts +232 -0
  71. package/lib/renderer/RenderingPipeline.js +18 -0
  72. package/lib/renderer/RenderingPipeline.js.map +1 -0
  73. package/lib/renderer/ScratchPool.d.ts +13 -0
  74. package/lib/renderer/ScratchPool.js +21 -0
  75. package/lib/renderer/ScratchPool.js.map +1 -0
  76. package/lib/renderer/TileRender.d.ts +44 -0
  77. package/lib/renderer/TileRender.js +283 -0
  78. package/lib/renderer/TileRender.js.map +1 -0
  79. package/lib/renderer/WGPUBloomPass.d.ts +17 -0
  80. package/lib/renderer/WGPUBloomPass.js +243 -0
  81. package/lib/renderer/WGPUBloomPass.js.map +1 -0
  82. package/lib/renderer/WGPUCanvasSurface.d.ts +21 -0
  83. package/lib/renderer/WGPUCanvasSurface.js +48 -0
  84. package/lib/renderer/WGPUCanvasSurface.js.map +1 -0
  85. package/lib/renderer/WGPUComputePass.d.ts +73 -0
  86. package/lib/renderer/WGPUComputePass.js +317 -0
  87. package/lib/renderer/WGPUComputePass.js.map +1 -0
  88. package/lib/renderer/WGPUFullQuadPass.d.ts +73 -0
  89. package/lib/renderer/WGPUFullQuadPass.js +389 -0
  90. package/lib/renderer/WGPUFullQuadPass.js.map +1 -0
  91. package/lib/renderer/WGPUHDRPeakMeter.d.ts +19 -0
  92. package/lib/renderer/WGPUHDRPeakMeter.js +112 -0
  93. package/lib/renderer/WGPUHDRPeakMeter.js.map +1 -0
  94. package/lib/renderer/WGPUJNLMDenoiser.d.ts +61 -0
  95. package/lib/renderer/WGPUJNLMDenoiser.js +412 -0
  96. package/lib/renderer/WGPUJNLMDenoiser.js.map +1 -0
  97. package/lib/renderer/WGPURayTraceOutput.d.ts +44 -0
  98. package/lib/renderer/WGPURayTraceOutput.js +368 -0
  99. package/lib/renderer/WGPURayTraceOutput.js.map +1 -0
  100. package/lib/renderer/WGPURayTracePass.d.ts +284 -0
  101. package/lib/renderer/WGPURayTracePass.js +2323 -0
  102. package/lib/renderer/WGPURayTracePass.js.map +1 -0
  103. package/lib/renderer/WGPURenderingPipeline.d.ts +9 -0
  104. package/lib/renderer/WGPURenderingPipeline.js +1446 -0
  105. package/lib/renderer/WGPURenderingPipeline.js.map +1 -0
  106. package/lib/renderer/WGPUSceneFeatures.d.ts +3 -0
  107. package/lib/renderer/WGPUSceneFeatures.js +20 -0
  108. package/lib/renderer/WGPUSceneFeatures.js.map +1 -0
  109. package/lib/renderer/WGPUScratchBuffer.d.ts +9 -0
  110. package/lib/renderer/WGPUScratchBuffer.js +21 -0
  111. package/lib/renderer/WGPUScratchBuffer.js.map +1 -0
  112. package/lib/renderer/WGPUScratchTexture.d.ts +10 -0
  113. package/lib/renderer/WGPUScratchTexture.js +27 -0
  114. package/lib/renderer/WGPUScratchTexture.js.map +1 -0
  115. package/lib/renderer/WGPUShaderCache.d.ts +26 -0
  116. package/lib/renderer/WGPUShaderCache.js +103 -0
  117. package/lib/renderer/WGPUShaderCache.js.map +1 -0
  118. package/lib/renderer/WebGLBloomPass.d.ts +18 -0
  119. package/lib/renderer/WebGLBloomPass.js +113 -0
  120. package/lib/renderer/WebGLBloomPass.js.map +1 -0
  121. package/lib/renderer/WebGLFullQuadPass.d.ts +65 -0
  122. package/lib/renderer/WebGLFullQuadPass.js +208 -0
  123. package/lib/renderer/WebGLFullQuadPass.js.map +1 -0
  124. package/lib/renderer/WebGLJNLMDenoiser.d.ts +32 -0
  125. package/lib/renderer/WebGLJNLMDenoiser.js +328 -0
  126. package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -0
  127. package/lib/renderer/WebGLRayTraceOutputPass.d.ts +20 -0
  128. package/lib/renderer/WebGLRayTraceOutputPass.js +106 -0
  129. package/lib/renderer/WebGLRayTraceOutputPass.js.map +1 -0
  130. package/lib/renderer/WebGLRayTracePass.d.ts +142 -0
  131. package/lib/renderer/WebGLRayTracePass.js +845 -0
  132. package/lib/renderer/WebGLRayTracePass.js.map +1 -0
  133. package/lib/renderer/WebGLReadback.d.ts +4 -0
  134. package/lib/renderer/WebGLReadback.js +75 -0
  135. package/lib/renderer/WebGLReadback.js.map +1 -0
  136. package/lib/renderer/WebGLRenderingPipeline.d.ts +4 -0
  137. package/lib/renderer/WebGLRenderingPipeline.js +510 -0
  138. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -0
  139. package/lib/renderer/WebGLScratchCopy.d.ts +10 -0
  140. package/lib/renderer/WebGLScratchCopy.js +27 -0
  141. package/lib/renderer/WebGLScratchCopy.js.map +1 -0
  142. package/lib/renderer/accumulationTarget.d.ts +26 -0
  143. package/lib/renderer/accumulationTarget.js +2 -0
  144. package/lib/renderer/accumulationTarget.js.map +1 -0
  145. package/lib/renderer/binnedSahBvh.d.ts +31 -0
  146. package/lib/renderer/binnedSahBvh.js +263 -0
  147. package/lib/renderer/binnedSahBvh.js.map +1 -0
  148. package/lib/renderer/bvh.worker.d.ts +1 -0
  149. package/lib/renderer/bvh.worker.js +16 -0
  150. package/lib/renderer/bvh.worker.js.map +1 -0
  151. package/lib/renderer/bvhAccel.d.ts +81 -0
  152. package/lib/renderer/bvhAccel.js +621 -0
  153. package/lib/renderer/bvhAccel.js.map +1 -0
  154. package/lib/renderer/bvhWorkerBuild.d.ts +12 -0
  155. package/lib/renderer/bvhWorkerBuild.js +17 -0
  156. package/lib/renderer/bvhWorkerBuild.js.map +1 -0
  157. package/lib/renderer/bvhWorkerClient.d.ts +57 -0
  158. package/lib/renderer/bvhWorkerClient.js +166 -0
  159. package/lib/renderer/bvhWorkerClient.js.map +1 -0
  160. package/lib/renderer/cameraLens.d.ts +5 -0
  161. package/lib/renderer/cameraLens.js +15 -0
  162. package/lib/renderer/cameraLens.js.map +1 -0
  163. package/lib/renderer/cameraSnapshot.d.ts +3 -0
  164. package/lib/renderer/cameraSnapshot.js +7 -0
  165. package/lib/renderer/cameraSnapshot.js.map +1 -0
  166. package/lib/renderer/committedScene.d.ts +13 -0
  167. package/lib/renderer/committedScene.js +121 -0
  168. package/lib/renderer/committedScene.js.map +1 -0
  169. package/lib/renderer/dataTextureUtil.d.ts +32 -0
  170. package/lib/renderer/dataTextureUtil.js +46 -0
  171. package/lib/renderer/dataTextureUtil.js.map +1 -0
  172. package/lib/renderer/denoiser.d.ts +65 -0
  173. package/lib/renderer/denoiser.js +2 -0
  174. package/lib/renderer/denoiser.js.map +1 -0
  175. package/lib/renderer/depthQuery.d.ts +14 -0
  176. package/lib/renderer/depthQuery.js +14 -0
  177. package/lib/renderer/depthQuery.js.map +1 -0
  178. package/lib/renderer/deviceRequirements.d.ts +23 -0
  179. package/lib/renderer/deviceRequirements.js +50 -0
  180. package/lib/renderer/deviceRequirements.js.map +1 -0
  181. package/lib/renderer/envMapCreation.d.ts +10 -0
  182. package/lib/renderer/envMapCreation.js +96 -0
  183. package/lib/renderer/envMapCreation.js.map +1 -0
  184. package/lib/renderer/envMapDistribution.d.ts +9 -0
  185. package/lib/renderer/envMapDistribution.js +107 -0
  186. package/lib/renderer/envMapDistribution.js.map +1 -0
  187. package/lib/renderer/float16.d.ts +1 -0
  188. package/lib/renderer/float16.js +19 -0
  189. package/lib/renderer/float16.js.map +1 -0
  190. package/lib/renderer/geometryBvh.d.ts +11 -0
  191. package/lib/renderer/geometryBvh.js +24 -0
  192. package/lib/renderer/geometryBvh.js.map +1 -0
  193. package/lib/renderer/geometryUpdates.d.ts +28 -0
  194. package/lib/renderer/geometryUpdates.js +131 -0
  195. package/lib/renderer/geometryUpdates.js.map +1 -0
  196. package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +2 -0
  197. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +37 -0
  198. package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -0
  199. package/lib/renderer/glsl/chunks/common.glsl.d.ts +2 -0
  200. package/lib/renderer/glsl/chunks/common.glsl.js +17 -0
  201. package/lib/renderer/glsl/chunks/common.glsl.js.map +1 -0
  202. package/lib/renderer/glsl/chunks/envMap.glsl.d.ts +2 -0
  203. package/lib/renderer/glsl/chunks/envMap.glsl.js +192 -0
  204. package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -0
  205. package/lib/renderer/glsl/chunks/intersect.glsl.d.ts +2 -0
  206. package/lib/renderer/glsl/chunks/intersect.glsl.js +1091 -0
  207. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -0
  208. package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +2 -0
  209. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +371 -0
  210. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -0
  211. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.d.ts +2 -0
  212. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +1767 -0
  213. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -0
  214. package/lib/renderer/glsl/chunks/rand.glsl.d.ts +2 -0
  215. package/lib/renderer/glsl/chunks/rand.glsl.js +26 -0
  216. package/lib/renderer/glsl/chunks/rand.glsl.js.map +1 -0
  217. package/lib/renderer/glsl/chunks/random.glsl.d.ts +2 -0
  218. package/lib/renderer/glsl/chunks/random.glsl.js +27 -0
  219. package/lib/renderer/glsl/chunks/random.glsl.js.map +1 -0
  220. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +2 -0
  221. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +287 -0
  222. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -0
  223. package/lib/renderer/glsl/chunks/sampleLight.glsl.d.ts +2 -0
  224. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +254 -0
  225. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -0
  226. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +2 -0
  227. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +279 -0
  228. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -0
  229. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.d.ts +2 -0
  230. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +48 -0
  231. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -0
  232. package/lib/renderer/glsl/chunks/sampling.glsl.d.ts +2 -0
  233. package/lib/renderer/glsl/chunks/sampling.glsl.js +194 -0
  234. package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -0
  235. package/lib/renderer/glsl/chunks/sobol.glsl.d.ts +2 -0
  236. package/lib/renderer/glsl/chunks/sobol.glsl.js +170 -0
  237. package/lib/renderer/glsl/chunks/sobol.glsl.js.map +1 -0
  238. package/lib/renderer/glsl/chunks/textureLinear.glsl.d.ts +2 -0
  239. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +27 -0
  240. package/lib/renderer/glsl/chunks/textureLinear.glsl.js.map +1 -0
  241. package/lib/renderer/glsl/chunks/uvProjection.glsl.d.ts +2 -0
  242. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +72 -0
  243. package/lib/renderer/glsl/chunks/uvProjection.glsl.js.map +1 -0
  244. package/lib/renderer/glsl/depthQuery.frag.d.ts +3 -0
  245. package/lib/renderer/glsl/depthQuery.frag.js +55 -0
  246. package/lib/renderer/glsl/depthQuery.frag.js.map +1 -0
  247. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.d.ts +6 -0
  248. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +46 -0
  249. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js.map +1 -0
  250. package/lib/renderer/glsl/rayTrace.frag.d.ts +2 -0
  251. package/lib/renderer/glsl/rayTrace.frag.js +619 -0
  252. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -0
  253. package/lib/renderer/glsl/shadowCatcher.frag.d.ts +3 -0
  254. package/lib/renderer/glsl/shadowCatcher.frag.js +119 -0
  255. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -0
  256. package/lib/renderer/glsl/webglPipeline.frag.d.ts +4 -0
  257. package/lib/renderer/glsl/webglPipeline.frag.js +208 -0
  258. package/lib/renderer/glsl/webglPipeline.frag.js.map +1 -0
  259. package/lib/renderer/gpuMemory.d.ts +2 -0
  260. package/lib/renderer/gpuMemory.js +10 -0
  261. package/lib/renderer/gpuMemory.js.map +1 -0
  262. package/lib/renderer/halton.d.ts +1 -0
  263. package/lib/renderer/halton.js +15 -0
  264. package/lib/renderer/halton.js.map +1 -0
  265. package/lib/renderer/jnlm.d.ts +85 -0
  266. package/lib/renderer/jnlm.js +87 -0
  267. package/lib/renderer/jnlm.js.map +1 -0
  268. package/lib/renderer/lightSampling.d.ts +75 -0
  269. package/lib/renderer/lightSampling.js +305 -0
  270. package/lib/renderer/lightSampling.js.map +1 -0
  271. package/lib/renderer/lightsUtil.d.ts +26 -0
  272. package/lib/renderer/lightsUtil.js +154 -0
  273. package/lib/renderer/lightsUtil.js.map +1 -0
  274. package/lib/renderer/materialChanges.d.ts +13 -0
  275. package/lib/renderer/materialChanges.js +59 -0
  276. package/lib/renderer/materialChanges.js.map +1 -0
  277. package/lib/renderer/materialComparison.generated.d.ts +5 -0
  278. package/lib/renderer/materialComparison.generated.js +655 -0
  279. package/lib/renderer/materialComparison.generated.js.map +1 -0
  280. package/lib/renderer/materialConstants.d.ts +6 -0
  281. package/lib/renderer/materialConstants.js +3 -0
  282. package/lib/renderer/materialConstants.js.map +1 -0
  283. package/lib/renderer/materialEmission.d.ts +9 -0
  284. package/lib/renderer/materialEmission.js +21 -0
  285. package/lib/renderer/materialEmission.js.map +1 -0
  286. package/lib/renderer/materialIndices.d.ts +7 -0
  287. package/lib/renderer/materialIndices.js +34 -0
  288. package/lib/renderer/materialIndices.js.map +1 -0
  289. package/lib/renderer/materialLayout.d.ts +102 -0
  290. package/lib/renderer/materialLayout.js +189 -0
  291. package/lib/renderer/materialLayout.js.map +1 -0
  292. package/lib/renderer/materialTextureSlots.d.ts +537 -0
  293. package/lib/renderer/materialTextureSlots.js +219 -0
  294. package/lib/renderer/materialTextureSlots.js.map +1 -0
  295. package/lib/renderer/mergeMeshesToGeometry.d.ts +8 -0
  296. package/lib/renderer/mergeMeshesToGeometry.js +236 -0
  297. package/lib/renderer/mergeMeshesToGeometry.js.map +1 -0
  298. package/lib/renderer/meshInstances.d.ts +23 -0
  299. package/lib/renderer/meshInstances.js +66 -0
  300. package/lib/renderer/meshInstances.js.map +1 -0
  301. package/lib/renderer/meshMembership.d.ts +10 -0
  302. package/lib/renderer/meshMembership.js +72 -0
  303. package/lib/renderer/meshMembership.js.map +1 -0
  304. package/lib/renderer/oidnNetwork.d.ts +20 -0
  305. package/lib/renderer/oidnNetwork.js +123 -0
  306. package/lib/renderer/oidnNetwork.js.map +1 -0
  307. package/lib/renderer/openPbrEnergyLut.d.ts +32 -0
  308. package/lib/renderer/openPbrEnergyLut.js +965 -0
  309. package/lib/renderer/openPbrEnergyLut.js.map +1 -0
  310. package/lib/renderer/pathLimits.d.ts +4 -0
  311. package/lib/renderer/pathLimits.js +7 -0
  312. package/lib/renderer/pathLimits.js.map +1 -0
  313. package/lib/renderer/prepareMeshBVH.d.ts +110 -0
  314. package/lib/renderer/prepareMeshBVH.js +857 -0
  315. package/lib/renderer/prepareMeshBVH.js.map +1 -0
  316. package/lib/renderer/progressiveScheduler.d.ts +11 -0
  317. package/lib/renderer/progressiveScheduler.js +19 -0
  318. package/lib/renderer/progressiveScheduler.js.map +1 -0
  319. package/lib/renderer/renderPipeline.d.ts +57 -0
  320. package/lib/renderer/renderPipeline.js +49 -0
  321. package/lib/renderer/renderPipeline.js.map +1 -0
  322. package/lib/renderer/sampling.d.ts +10 -0
  323. package/lib/renderer/sampling.js +28 -0
  324. package/lib/renderer/sampling.js.map +1 -0
  325. package/lib/renderer/sceneChangeDetector.d.ts +29 -0
  326. package/lib/renderer/sceneChangeDetector.js +232 -0
  327. package/lib/renderer/sceneChangeDetector.js.map +1 -0
  328. package/lib/renderer/sceneLightChanges.d.ts +14 -0
  329. package/lib/renderer/sceneLightChanges.js +34 -0
  330. package/lib/renderer/sceneLightChanges.js.map +1 -0
  331. package/lib/renderer/scratchSampling.d.ts +3 -0
  332. package/lib/renderer/scratchSampling.js +39 -0
  333. package/lib/renderer/scratchSampling.js.map +1 -0
  334. package/lib/renderer/shader.d.ts +37 -0
  335. package/lib/renderer/shader.js +41 -0
  336. package/lib/renderer/shader.js.map +1 -0
  337. package/lib/renderer/staticBvhPreparation.d.ts +24 -0
  338. package/lib/renderer/staticBvhPreparation.js +116 -0
  339. package/lib/renderer/staticBvhPreparation.js.map +1 -0
  340. package/lib/renderer/textureRegion.d.ts +8 -0
  341. package/lib/renderer/textureRegion.js +9 -0
  342. package/lib/renderer/textureRegion.js.map +1 -0
  343. package/lib/renderer/texturesFromMaterials.d.ts +6 -0
  344. package/lib/renderer/texturesFromMaterials.js +37 -0
  345. package/lib/renderer/texturesFromMaterials.js.map +1 -0
  346. package/lib/renderer/util.d.ts +17 -0
  347. package/lib/renderer/util.js +56 -0
  348. package/lib/renderer/util.js.map +1 -0
  349. package/lib/renderer/webgl.d.ts +131 -0
  350. package/lib/renderer/webgl.js +586 -0
  351. package/lib/renderer/webgl.js.map +1 -0
  352. package/lib/renderer/webglShaders.d.ts +4 -0
  353. package/lib/renderer/webglShaders.js +41 -0
  354. package/lib/renderer/webglShaders.js.map +1 -0
  355. package/lib/renderer/wgsl/chunks/common.wgsl.d.ts +2 -0
  356. package/lib/renderer/wgsl/chunks/common.wgsl.js +23 -0
  357. package/lib/renderer/wgsl/chunks/common.wgsl.js.map +1 -0
  358. package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +2 -0
  359. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +128 -0
  360. package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -0
  361. package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -0
  362. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +1441 -0
  363. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -0
  364. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +8 -0
  365. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +85 -0
  366. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -0
  367. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +7 -0
  368. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +315 -0
  369. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -0
  370. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.d.ts +3 -0
  371. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +1737 -0
  372. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js.map +1 -0
  373. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +4 -0
  374. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +352 -0
  375. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -0
  376. package/lib/renderer/wgsl/chunks/rand.wgsl.d.ts +2 -0
  377. package/lib/renderer/wgsl/chunks/rand.wgsl.js +25 -0
  378. package/lib/renderer/wgsl/chunks/rand.wgsl.js.map +1 -0
  379. package/lib/renderer/wgsl/chunks/random.wgsl.d.ts +1 -0
  380. package/lib/renderer/wgsl/chunks/random.wgsl.js +2 -0
  381. package/lib/renderer/wgsl/chunks/random.wgsl.js.map +1 -0
  382. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +5 -0
  383. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +328 -0
  384. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -0
  385. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +2 -0
  386. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +400 -0
  387. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -0
  388. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +3 -0
  389. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +439 -0
  390. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -0
  391. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +2 -0
  392. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +40 -0
  393. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -0
  394. package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +2 -0
  395. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +198 -0
  396. package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -0
  397. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +8 -0
  398. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +16 -0
  399. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -0
  400. package/lib/renderer/wgsl/chunks/sobol.wgsl.d.ts +2 -0
  401. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +170 -0
  402. package/lib/renderer/wgsl/chunks/sobol.wgsl.js.map +1 -0
  403. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.d.ts +2 -0
  404. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +42 -0
  405. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js.map +1 -0
  406. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +5 -0
  407. package/lib/renderer/wgsl/compose.frag.wgsl.js +218 -0
  408. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -0
  409. package/lib/renderer/wgsl/customDenoise.wgsl.d.ts +4 -0
  410. package/lib/renderer/wgsl/customDenoise.wgsl.js +28 -0
  411. package/lib/renderer/wgsl/customDenoise.wgsl.js.map +1 -0
  412. package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +3 -0
  413. package/lib/renderer/wgsl/depthQuery.wgsl.js +34 -0
  414. package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -0
  415. package/lib/renderer/wgsl/offlineAdaptive.compute.d.ts +2 -0
  416. package/lib/renderer/wgsl/offlineAdaptive.compute.js +108 -0
  417. package/lib/renderer/wgsl/offlineAdaptive.compute.js.map +1 -0
  418. package/lib/renderer/wgsl/rayTrace.compute.d.ts +16 -0
  419. package/lib/renderer/wgsl/rayTrace.compute.js +923 -0
  420. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -0
  421. package/lib/scene/AmbientLight.d.ts +17 -0
  422. package/lib/scene/AmbientLight.js +15 -0
  423. package/lib/scene/AmbientLight.js.map +1 -0
  424. package/lib/scene/Camera.d.ts +78 -0
  425. package/lib/scene/Camera.js +111 -0
  426. package/lib/scene/Camera.js.map +1 -0
  427. package/lib/scene/DirectionalLight.d.ts +18 -0
  428. package/lib/scene/DirectionalLight.js +17 -0
  429. package/lib/scene/DirectionalLight.js.map +1 -0
  430. package/lib/scene/EnvironmentLight.d.ts +14 -0
  431. package/lib/scene/EnvironmentLight.js +14 -0
  432. package/lib/scene/EnvironmentLight.js.map +1 -0
  433. package/lib/scene/Geometry.d.ts +87 -0
  434. package/lib/scene/Geometry.js +108 -0
  435. package/lib/scene/Geometry.js.map +1 -0
  436. package/lib/scene/IESProfile.d.ts +19 -0
  437. package/lib/scene/IESProfile.js +165 -0
  438. package/lib/scene/IESProfile.js.map +1 -0
  439. package/lib/scene/InstancedMesh.d.ts +43 -0
  440. package/lib/scene/InstancedMesh.js +79 -0
  441. package/lib/scene/InstancedMesh.js.map +1 -0
  442. package/lib/scene/Mesh.d.ts +14 -0
  443. package/lib/scene/Mesh.js +17 -0
  444. package/lib/scene/Mesh.js.map +1 -0
  445. package/lib/scene/OpenPBRMaterial.d.ts +224 -0
  446. package/lib/scene/OpenPBRMaterial.js +240 -0
  447. package/lib/scene/OpenPBRMaterial.js.map +1 -0
  448. package/lib/scene/RectLight.d.ts +31 -0
  449. package/lib/scene/RectLight.js +26 -0
  450. package/lib/scene/RectLight.js.map +1 -0
  451. package/lib/scene/Scene.d.ts +55 -0
  452. package/lib/scene/Scene.js +2 -0
  453. package/lib/scene/Scene.js.map +1 -0
  454. package/lib/scene/SceneNode.d.ts +16 -0
  455. package/lib/scene/SceneNode.js +33 -0
  456. package/lib/scene/SceneNode.js.map +1 -0
  457. package/lib/scene/SphereLight.d.ts +22 -0
  458. package/lib/scene/SphereLight.js +20 -0
  459. package/lib/scene/SphereLight.js.map +1 -0
  460. package/lib/scene/SpotLight.d.ts +35 -0
  461. package/lib/scene/SpotLight.js +29 -0
  462. package/lib/scene/SpotLight.js.map +1 -0
  463. package/lib/scene/Texture.d.ts +38 -0
  464. package/lib/scene/Texture.js +37 -0
  465. package/lib/scene/Texture.js.map +1 -0
  466. package/lib/scene/anisotropyParameters.d.ts +1 -0
  467. package/lib/scene/anisotropyParameters.js +13 -0
  468. package/lib/scene/anisotropyParameters.js.map +1 -0
  469. package/lib/scene/geometryChanges.d.ts +5 -0
  470. package/lib/scene/geometryChanges.js +18 -0
  471. package/lib/scene/geometryChanges.js.map +1 -0
  472. package/lib/scene/materialTextureNames.d.ts +2 -0
  473. package/lib/scene/materialTextureNames.js +9 -0
  474. package/lib/scene/materialTextureNames.js.map +1 -0
  475. package/lib/scene/openPbrSchema.d.ts +400 -0
  476. package/lib/scene/openPbrSchema.js +149 -0
  477. package/lib/scene/openPbrSchema.js.map +1 -0
  478. package/lib/scene/thinFilmParameters.d.ts +4 -0
  479. package/lib/scene/thinFilmParameters.js +12 -0
  480. package/lib/scene/thinFilmParameters.js.map +1 -0
  481. package/lib/settings/display.d.ts +118 -0
  482. package/lib/settings/display.js +34 -0
  483. package/lib/settings/display.js.map +1 -0
  484. package/lib/settings/engine.d.ts +37 -0
  485. package/lib/settings/engine.js +26 -0
  486. package/lib/settings/engine.js.map +1 -0
  487. package/lib/settings/render.d.ts +178 -0
  488. package/lib/settings/render.js +36 -0
  489. package/lib/settings/render.js.map +1 -0
  490. package/lib/tinybvh/LICENSE +21 -0
  491. package/lib/tinybvh/TinyBvhBuilder.d.ts +17 -0
  492. package/lib/tinybvh/TinyBvhBuilder.js +211 -0
  493. package/lib/tinybvh/TinyBvhBuilder.js.map +1 -0
  494. package/lib/tinybvh/tinybvh.wasm +0 -0
  495. package/lib/types.d.ts +13 -0
  496. package/lib/types.js +2 -0
  497. package/lib/types.js.map +1 -0
  498. package/lib/util/canvas.d.ts +2 -0
  499. package/lib/util/canvas.js +13 -0
  500. package/lib/util/canvas.js.map +1 -0
  501. package/lib/util/commonGeometry.d.ts +15 -0
  502. package/lib/util/commonGeometry.js +240 -0
  503. package/lib/util/commonGeometry.js.map +1 -0
  504. package/lib/util/events.d.ts +7 -0
  505. package/lib/util/events.js +23 -0
  506. package/lib/util/events.js.map +1 -0
  507. package/lib/util/frame.d.ts +2 -0
  508. package/lib/util/frame.js +10 -0
  509. package/lib/util/frame.js.map +1 -0
  510. package/lib/util/fromTHREE.d.ts +100 -0
  511. package/lib/util/fromTHREE.js +1063 -0
  512. package/lib/util/fromTHREE.js.map +1 -0
  513. package/lib/util/geometry.d.ts +13 -0
  514. package/lib/util/geometry.js +292 -0
  515. package/lib/util/geometry.js.map +1 -0
  516. package/lib/util/loadRGBE.d.ts +7 -0
  517. package/lib/util/loadRGBE.js +168 -0
  518. package/lib/util/loadRGBE.js.map +1 -0
  519. package/lib/util/math.d.ts +8 -0
  520. package/lib/util/math.js +64 -0
  521. package/lib/util/math.js.map +1 -0
  522. package/lib/util/mesh.d.ts +7 -0
  523. package/lib/util/mesh.js +20 -0
  524. package/lib/util/mesh.js.map +1 -0
  525. package/lib/util/threeDeformation.d.ts +20 -0
  526. package/lib/util/threeDeformation.js +218 -0
  527. package/lib/util/threeDeformation.js.map +1 -0
  528. package/lib/version.d.ts +2 -0
  529. package/lib/version.js +3 -0
  530. package/lib/version.js.map +1 -0
  531. package/llms.txt +62 -0
  532. package/oidn/weights/LICENSE.txt +202 -0
  533. package/oidn/weights/README.md +43 -0
  534. package/oidn/weights/rt_hdr_alb_nrm.tza +0 -0
  535. package/oidn/weights/rt_hdr_alb_nrm_small.tza +0 -0
  536. package/package.json +124 -4
@@ -0,0 +1,857 @@
1
+ import InstancedMesh from '../scene/InstancedMesh.js';
2
+ import { meshInstanceCount, meshInstanceTransform, PackedMeshInstances } from './meshInstances.js';
3
+ import { createCanvas } from '../util/canvas.js';
4
+ import { packMaterialIndexAndWeightToInt } from './materialIndices.js';
5
+ import { getGeometryBvh, setGeometryBvh, geometryBvhConfigMatches } from './geometryBvh.js';
6
+ import { writeMaterialIndices } from './materialIndices.js';
7
+ import { vec2, vec3 } from '../math.js';
8
+ import Geometry, { Attribute } from '../scene/Geometry.js';
9
+ import { buildBLAS } from './bvhAccel.js';
10
+ import { colorLuminance } from './lightSampling.js';
11
+ import { isTextureDataSource } from '../scene/Texture.js';
12
+ import { generateVertexTangents, hasGeneratedVertexTangents } from '../util/geometry.js';
13
+ function computeGeometryBounds(geometry) {
14
+ const min = vec3.fromValues(Infinity, Infinity, Infinity);
15
+ const max = vec3.fromValues(-Infinity, -Infinity, -Infinity);
16
+ const positions = geometry.position.array;
17
+ const stride = geometry.position.itemSize;
18
+ for (let offset = 0; offset + 2 < positions.length; offset += stride) {
19
+ const x = positions[offset];
20
+ const y = positions[offset + 1];
21
+ const z = positions[offset + 2];
22
+ if (!Number.isFinite(x) || !Number.isFinite(y) || !Number.isFinite(z)) {
23
+ continue;
24
+ }
25
+ min[0] = Math.min(min[0], x);
26
+ min[1] = Math.min(min[1], y);
27
+ min[2] = Math.min(min[2], z);
28
+ max[0] = Math.max(max[0], x);
29
+ max[1] = Math.max(max[1], y);
30
+ max[2] = Math.max(max[2], z);
31
+ }
32
+ return [min, max];
33
+ }
34
+ export function getBvhBounds(geometry) {
35
+ const bvh = getGeometryBvh(geometry);
36
+ const floats = new Float32Array(bvh.buffer);
37
+ if (bvh.layout === 'bvh4') {
38
+ return [
39
+ [floats[0], floats[1], floats[2]],
40
+ [
41
+ floats[0] + floats[3],
42
+ floats[1] + floats[4],
43
+ floats[2] + floats[5]
44
+ ]
45
+ ];
46
+ }
47
+ if (bvh.layout === 'bvh-gpu') {
48
+ const words = new Uint32Array(bvh.buffer);
49
+ if (words[11] === 0) {
50
+ return [
51
+ [
52
+ Math.min(floats[0], floats[8]),
53
+ Math.min(floats[1], floats[9]),
54
+ Math.min(floats[2], floats[10])
55
+ ],
56
+ [
57
+ Math.max(floats[4], floats[12]),
58
+ Math.max(floats[5], floats[13]),
59
+ Math.max(floats[6], floats[14])
60
+ ]
61
+ ];
62
+ }
63
+ // A single-leaf BVH_GPU node does not store its own bounds.
64
+ return computeGeometryBounds(geometry);
65
+ }
66
+ if (bvh.layout === 'cwbvh') {
67
+ const words = new Uint32Array(bvh.buffer);
68
+ const header = words[3];
69
+ const signedByte = (value) => (value << 24) >> 24;
70
+ const scale = [
71
+ 2 ** signedByte(header),
72
+ 2 ** signedByte(header >> 8),
73
+ 2 ** signedByte(header >> 16)
74
+ ];
75
+ const min = [floats[0], floats[1], floats[2]];
76
+ const max = [...min];
77
+ for (let slot = 0; slot < 8; slot++) {
78
+ const meta = (words[6 + (slot >> 2)] >> ((slot & 3) * 8)) & 0xff;
79
+ if (!meta)
80
+ continue;
81
+ const shift = (slot & 3) * 8;
82
+ const half = slot >> 2;
83
+ max[0] = Math.max(max[0], min[0] + ((words[14 + half] >> shift) & 0xff) * scale[0]);
84
+ max[1] = Math.max(max[1], min[1] + ((words[16 + half] >> shift) & 0xff) * scale[1]);
85
+ max[2] = Math.max(max[2], min[2] + ((words[18 + half] >> shift) & 0xff) * scale[2]);
86
+ }
87
+ return [min, max];
88
+ }
89
+ return [
90
+ [floats[0], floats[1], floats[2]],
91
+ [floats[4], floats[5], floats[6]]
92
+ ];
93
+ }
94
+ export function computeBounds(_geometry, m, bvhBounds, result = { min: vec3.create(), max: vec3.create() }, p = vec3.create()) {
95
+ const { min, max } = result;
96
+ vec3.set(min, Infinity, Infinity, Infinity);
97
+ vec3.set(max, -Infinity, -Infinity, -Infinity);
98
+ // Transforming the eight BLAS AABB corners is exact for an affine transform
99
+ // and independent of mesh vertex count. The previous rotated path scanned
100
+ // every vertex on every instance update.
101
+ for (let corner = 0; corner < 8; corner++) {
102
+ vec3.set(p, bvhBounds[(corner >> 0) & 1][0], bvhBounds[(corner >> 1) & 1][1], bvhBounds[(corner >> 2) & 1][2]);
103
+ vec3.transformMat4(p, p, m);
104
+ if (!p.every(isFinite))
105
+ continue;
106
+ vec3.min(min, min, p);
107
+ vec3.max(max, max, p);
108
+ }
109
+ return result;
110
+ }
111
+ export function updateMeshInstanceTransforms(bindings, current, dirtyIndices) {
112
+ if (bindings.some(binding => binding.mesh instanceof InstancedMesh)) {
113
+ const packed = new PackedMeshInstances(bindings.reduce((count, binding) => count + meshInstanceCount(binding.mesh), 0));
114
+ const matrix = Array(16).fill(0);
115
+ const boundsScratch = { min: vec3.create(), max: vec3.create() }, pointScratch = vec3.create();
116
+ let sourceIndex = 0;
117
+ for (const binding of bindings) {
118
+ const { mesh, geometry, bvhBounds, blasIndex, materialIndices, displacementScale } = binding;
119
+ for (let i = 0; i < meshInstanceCount(mesh); i++, sourceIndex++) {
120
+ meshInstanceTransform(mesh, i, matrix);
121
+ const bounds = computeBounds(geometry, matrix, bvhBounds, boundsScratch, pointScratch);
122
+ if (!bounds.min.every(Number.isFinite) || !bounds.max.every(Number.isFinite) || !matrix.every(Number.isFinite))
123
+ continue;
124
+ const index = packed.length++;
125
+ packed.sourceIndices[index] = sourceIndex;
126
+ packed.transforms.set(matrix, index * 16);
127
+ packed.bounds.set(bounds.min, index * 6);
128
+ packed.bounds.set(bounds.max, index * 6 + 3);
129
+ packed.blasIndices[index] = blasIndex;
130
+ packed.materials[index] = packMaterialIndexAndWeightToInt(materialIndices[0], 1);
131
+ packed.displacement[index] = displacementScale;
132
+ const colors = mesh instanceof InstancedMesh ? mesh.colors : undefined;
133
+ for (let k = 0; k < 3; k++)
134
+ packed.colors[index * 3 + k] = colors?.[i * 3 + k] ?? 1;
135
+ }
136
+ }
137
+ return packed;
138
+ }
139
+ const update = ({ mesh, geometry, blasIndex, materialIndices, displacementScale, bvhBounds }) => ({
140
+ bounds: computeBounds(geometry, mesh.transform, bvhBounds),
141
+ blasIndex,
142
+ transform: mesh.transform,
143
+ materialsIndices: materialIndices.map((idx) => packMaterialIndexAndWeightToInt(idx, 1)),
144
+ displacementScale
145
+ });
146
+ if (!current || !dirtyIndices)
147
+ return bindings.map(update);
148
+ const next = current.slice();
149
+ dirtyIndices.forEach((index) => {
150
+ const binding = bindings[index];
151
+ if (binding)
152
+ next[index] = update(binding);
153
+ });
154
+ return next;
155
+ }
156
+ /** Returns the first material used for CPU displacement. */
157
+ export function getMeshDisplacementMaterial(mesh) {
158
+ return mesh.materials[0];
159
+ }
160
+ export function getMeshDisplacementMap(mesh) {
161
+ // Not support multiple materials for displacement.
162
+ const material = getMeshDisplacementMaterial(mesh);
163
+ return material.displacementMap;
164
+ }
165
+ export function getMeshDisplacementScale(mesh) {
166
+ return mesh.materials[0].displacementScale;
167
+ }
168
+ const preparedGeometryCache = new WeakMap();
169
+ let displacementTextureId = 1;
170
+ const displacementTextureIds = new WeakMap();
171
+ function getDisplacementTextureId(texture) {
172
+ const identity = texture.source ?? texture;
173
+ let id = displacementTextureIds.get(identity);
174
+ if (id == null) {
175
+ id = displacementTextureId++;
176
+ displacementTextureIds.set(identity, id);
177
+ }
178
+ return id;
179
+ }
180
+ export function getDisplacementTextureDataCacheKey(texture) {
181
+ const image = texture.image;
182
+ return [
183
+ getDisplacementTextureId(texture),
184
+ texture.version,
185
+ image.width,
186
+ image.height
187
+ ].join('|');
188
+ }
189
+ const detailedProjectiveRangeTriangleLimit = 100_000;
190
+ const displacementMinmaxCache = new Map();
191
+ export function getPreparedMeshGeometryCacheKey(mesh) {
192
+ const source = mesh.geometry;
193
+ const material = getMeshDisplacementMaterial(mesh);
194
+ const texture = material?.displacementMap;
195
+ if (!material)
196
+ return undefined;
197
+ // Projective bounds depend on the material projection and height texture.
198
+ if (material.displacementUvProjection !== 'none' && texture && Math.abs(material.displacementScale) > 1e-6) {
199
+ return ['projectiveProjection', source.version, getDisplacementTextureDataCacheKey(texture),
200
+ +texture.flipY, texture.uvScale.join(','), texture.uvOffset.join(','),
201
+ material.displacementScale, material.displacementUvProjectionScale, material.displacementUvProjection].join('|');
202
+ }
203
+ return undefined;
204
+ }
205
+ export function getCachedPreparedMeshGeometry(mesh) {
206
+ const key = getPreparedMeshGeometryCacheKey(mesh);
207
+ if (key == null)
208
+ return mesh.geometry;
209
+ const cached = preparedGeometryCache.get(mesh.geometry)?.get(key);
210
+ if (!cached && key.startsWith('projectiveProjection|')) {
211
+ return cachePreparedMeshGeometry(mesh, new Geometry(mesh.geometry));
212
+ }
213
+ return cached;
214
+ }
215
+ export function cachePreparedMeshGeometry(mesh, generated) {
216
+ const key = getPreparedMeshGeometryCacheKey(mesh);
217
+ if (key == null)
218
+ return mesh.geometry;
219
+ let entries = preparedGeometryCache.get(mesh.geometry);
220
+ if (!entries) {
221
+ entries = new Map();
222
+ preparedGeometryCache.set(mesh.geometry, entries);
223
+ }
224
+ if (entries.size >= 4 && !entries.has(key))
225
+ entries.clear();
226
+ entries.set(key, generated);
227
+ return generated;
228
+ }
229
+ /** Returns cached prepared geometry, or the source while asynchronous preparation is pending. */
230
+ export function getPreparedMeshGeometry(mesh) {
231
+ return getCachedPreparedMeshGeometry(mesh) ?? mesh.geometry;
232
+ }
233
+ export function computeMinmaxCPU(_geometry, heightImage) {
234
+ const w = heightImage.width;
235
+ const minmaxData = [];
236
+ const maxMipLevel = Math.log2(w);
237
+ let heightPixels;
238
+ let sourceChannels;
239
+ let normalizeHeight;
240
+ if (isTextureDataSource(heightImage)) {
241
+ heightPixels = heightImage.data;
242
+ sourceChannels = Math.max(1, Math.floor(heightImage.data.length / (heightImage.width * heightImage.height)));
243
+ const normalized = heightImage.data instanceof Uint8Array ||
244
+ heightImage.data instanceof Uint8ClampedArray;
245
+ normalizeHeight = normalized
246
+ ? (value) => value
247
+ : (value) => Math.round(Math.min(Math.max(value, 0), 1) * 255);
248
+ }
249
+ else {
250
+ const canvas = createCanvas();
251
+ const ctx = canvas.getContext('2d');
252
+ if (!ctx)
253
+ throw new Error('The displacement texture is not CPU-readable.');
254
+ canvas.width = w;
255
+ canvas.height = w;
256
+ ctx.drawImage(heightImage, 0, 0, w, w);
257
+ heightPixels = ctx.getImageData(0, 0, w, w).data;
258
+ sourceChannels = 4;
259
+ normalizeHeight = (value) => value;
260
+ }
261
+ let mipmapSize = w;
262
+ for (let lod = 0; lod <= maxMipLevel; lod++) {
263
+ const prevMinmaxData = minmaxData[Math.max(0, lod - 1)];
264
+ const minmax = new Uint8Array(mipmapSize * mipmapSize * 2);
265
+ minmaxData.push(minmax);
266
+ const channels = lod === 0 ? sourceChannels : 2;
267
+ for (let y = 0; y < mipmapSize; y++) {
268
+ for (let x = 0; x < mipmapSize; x++) {
269
+ const yx = y * mipmapSize + x;
270
+ const idx = yx * channels;
271
+ let min = 0;
272
+ let max = 0;
273
+ if (lod == 0) {
274
+ min = normalizeHeight(heightPixels[idx]);
275
+ max = min;
276
+ if (y < mipmapSize - 1 && x < mipmapSize - 1) {
277
+ const h = normalizeHeight(heightPixels[idx + (mipmapSize + 1) * channels]);
278
+ min = Math.min(min, h);
279
+ max = Math.max(max, h);
280
+ }
281
+ if (y < mipmapSize - 1) {
282
+ const h = normalizeHeight(heightPixels[idx + mipmapSize * channels]);
283
+ min = Math.min(min, h);
284
+ max = Math.max(max, h);
285
+ }
286
+ if (x < mipmapSize - 1) {
287
+ const h = normalizeHeight(heightPixels[idx + channels]);
288
+ min = Math.min(min, h);
289
+ max = Math.max(max, h);
290
+ }
291
+ }
292
+ else {
293
+ const x2 = x * 2;
294
+ const y2 = y * 2;
295
+ const prevMipmapSize = mipmapSize * 2;
296
+ const idx2 = (y2 * prevMipmapSize + x2) * channels;
297
+ const idx2_0 = idx2;
298
+ const idx2_1 = idx2 + channels;
299
+ const idx2_2 = idx2 + prevMipmapSize * channels;
300
+ const idx2_3 = idx2 + prevMipmapSize * channels + channels;
301
+ min = Math.min(prevMinmaxData[idx2_0], prevMinmaxData[idx2_1], prevMinmaxData[idx2_2], prevMinmaxData[idx2_3]);
302
+ max = Math.max(prevMinmaxData[idx2_0 + 1], prevMinmaxData[idx2_1 + 1], prevMinmaxData[idx2_2 + 1], prevMinmaxData[idx2_3 + 1]);
303
+ }
304
+ minmax[yx * 2] = min;
305
+ minmax[yx * 2 + 1] = max;
306
+ }
307
+ }
308
+ mipmapSize = mipmapSize / 2;
309
+ }
310
+ return minmaxData;
311
+ }
312
+ function sphericalProjection(n, uv) {
313
+ const theta = Math.atan2(n[0], n[2]) / (2.0 * Math.PI) + 0.5;
314
+ const phi = Math.acos(n[1]) / Math.PI;
315
+ vec2.set(uv, theta, 1.0 - phi);
316
+ }
317
+ export function sphericalProjectionTriangle(na, nb, nc, uvA, uvB, uvC) {
318
+ sphericalProjection(na, uvA);
319
+ sphericalProjection(nb, uvB);
320
+ sphericalProjection(nc, uvC);
321
+ let onSeam = false;
322
+ for (let i = 0; i < 2; i++) {
323
+ if (Math.abs(uvA[i] - uvB[i]) > 0.5 ||
324
+ Math.abs(uvA[i] - uvC[i]) > 0.5 ||
325
+ Math.abs(uvB[i] - uvC[i]) > 0.5) {
326
+ const maxU = Math.max(uvA[i], uvB[i], uvC[i]);
327
+ if (maxU - uvA[i] > 0.5) {
328
+ uvA[i] += 1.0;
329
+ onSeam = true;
330
+ }
331
+ if (maxU - uvB[i] > 0.5) {
332
+ uvB[i] += 1.0;
333
+ onSeam = true;
334
+ }
335
+ if (maxU - uvC[i] > 0.5) {
336
+ uvC[i] += 1.0;
337
+ onSeam = true;
338
+ }
339
+ }
340
+ }
341
+ return onSeam;
342
+ }
343
+ function getMaxAxisIndex(n) {
344
+ const x = Math.abs(n[0]);
345
+ const y = Math.abs(n[1]);
346
+ const z = Math.abs(n[2]);
347
+ return x > y && x > z ? 0 : y > z ? 1 : 2;
348
+ }
349
+ export function triplanarProjectionTriangle(a, b, c, na, nb, nc, uvA, uvB, uvC) {
350
+ const tmpMaxX = Math.max(Math.abs(na[0]), Math.abs(nb[0]), Math.abs(nc[0]));
351
+ const tmpMaxY = Math.max(Math.abs(na[1]), Math.abs(nb[1]), Math.abs(nc[1]));
352
+ const tmpMaxZ = Math.max(Math.abs(na[2]), Math.abs(nb[2]), Math.abs(nc[2]));
353
+ if (tmpMaxX > tmpMaxY && tmpMaxX > tmpMaxZ) {
354
+ // yz
355
+ vec2.set(uvA, a[1], a[2]);
356
+ vec2.set(uvB, b[1], b[2]);
357
+ vec2.set(uvC, c[1], c[2]);
358
+ }
359
+ else if (tmpMaxY > tmpMaxX && tmpMaxY > tmpMaxZ) {
360
+ // xz
361
+ vec2.set(uvA, a[0], a[2]);
362
+ vec2.set(uvB, b[0], b[2]);
363
+ vec2.set(uvC, c[0], c[2]);
364
+ }
365
+ else {
366
+ // xy
367
+ vec2.set(uvA, a[0], a[1]);
368
+ vec2.set(uvB, b[0], b[1]);
369
+ vec2.set(uvC, c[0], c[1]);
370
+ }
371
+ }
372
+ function findRoots(triAabbMinP, triAabbMaxP, maxDepth, roots) {
373
+ let d = vec2.sub(vec2.create(), triAabbMaxP, triAabbMinP);
374
+ let size = Math.max(d[0], d[1]);
375
+ let startMipLevel = maxDepth - Math.floor(Math.log2(Math.floor(1.0 / size))) - 1;
376
+ if (!isFinite(startMipLevel)) {
377
+ startMipLevel = maxDepth;
378
+ }
379
+ startMipLevel = Math.max(startMipLevel, 0);
380
+ let rootCount = 0;
381
+ while (true) {
382
+ const mipSize = Math.pow(2.0, maxDepth - startMipLevel);
383
+ const minTexelX = Math.floor(mipSize * triAabbMinP[0]);
384
+ const minTexelY = Math.floor(mipSize * triAabbMinP[1]);
385
+ const maxTexelX = Math.floor(mipSize * triAabbMaxP[0]);
386
+ const maxTexelY = Math.floor(mipSize * triAabbMaxP[1]);
387
+ if ((maxTexelX - minTexelX < 2 &&
388
+ maxTexelY - minTexelY < 2 &&
389
+ startMipLevel >= 0) ||
390
+ startMipLevel >= maxDepth) {
391
+ for (let y = minTexelY; y <= maxTexelY; y++) {
392
+ for (let x = minTexelX; x <= maxTexelX; x++) {
393
+ if (rootCount < roots.length) {
394
+ vec3.set(roots[rootCount], Math.floor(x), Math.floor(y), startMipLevel);
395
+ rootCount++;
396
+ }
397
+ }
398
+ }
399
+ break;
400
+ }
401
+ startMipLevel++;
402
+ }
403
+ return rootCount;
404
+ }
405
+ export function getTrianglesDisplacementRange(geometry, heightTexture, material) {
406
+ const indices = geometry.indices.array;
407
+ const uvs = geometry.uv?.array;
408
+ const uvProjection = material.displacementUvProjection;
409
+ if (!heightTexture)
410
+ return;
411
+ if (!uvs && uvProjection === 'none') {
412
+ throw new Error('UV displacement requires texture coordinates; use triplanar, spherical, or cylindrical projection for a UV-less mesh.');
413
+ }
414
+ const heightImage = heightTexture.image;
415
+ const isFlipY = heightTexture.flipY;
416
+ if (!heightImage.width || !heightImage.height) {
417
+ return;
418
+ }
419
+ const triangleCount = indices.length / 3;
420
+ if (triangleCount >= detailedProjectiveRangeTriangleLimit) {
421
+ // A conservative full-height prism is much cheaper to prepare for dense
422
+ // source meshes and remains intersection-safe. Per-triangle UV min/max is
423
+ // retained for smaller meshes where tighter BVH nodes matter more.
424
+ const conservative = new Float32Array(triangleCount * 2);
425
+ for (let triangle = 0; triangle < triangleCount; triangle++) {
426
+ conservative[triangle * 2 + 1] = 1;
427
+ }
428
+ return conservative;
429
+ }
430
+ const minmaxCacheKey = getDisplacementTextureDataCacheKey(heightTexture);
431
+ let minmaxData = displacementMinmaxCache.get(minmaxCacheKey);
432
+ if (!minmaxData) {
433
+ minmaxData = computeMinmaxCPU(geometry, heightImage);
434
+ if (displacementMinmaxCache.size >= 4) {
435
+ displacementMinmaxCache.delete(displacementMinmaxCache.keys().next().value);
436
+ }
437
+ displacementMinmaxCache.set(minmaxCacheKey, minmaxData);
438
+ }
439
+ const maxDepth = Math.log2(heightImage.width);
440
+ const trianglesDisplacementRange = new Float32Array((indices.length / 3) * 2);
441
+ const normal = geometry.normal.array;
442
+ const position = geometry.position.array;
443
+ const uv1 = vec2.create();
444
+ const uv2 = vec2.create();
445
+ const uv3 = vec2.create();
446
+ const p1 = vec3.create();
447
+ const p2 = vec3.create();
448
+ const p3 = vec3.create();
449
+ const n1 = vec3.create();
450
+ const n2 = vec3.create();
451
+ const n3 = vec3.create();
452
+ const isTriplanar = uvProjection === 'triplanar';
453
+ const isSpherical = uvProjection === 'spherical';
454
+ const isCylindrical = uvProjection === 'cylindrical';
455
+ const uvScale = material.displacementUvProjectionScale;
456
+ const minUv = vec2.create();
457
+ const maxUv = vec2.create();
458
+ const roots = [];
459
+ for (let i = 0; i < 100; i++) {
460
+ roots.push([0, 0, 0]);
461
+ }
462
+ for (let i = 0; i < indices.length; i += 3) {
463
+ const i1 = indices[i];
464
+ const i2 = indices[i + 1];
465
+ const i3 = indices[i + 2];
466
+ const i1_2 = i1 * 2;
467
+ const i2_2 = i2 * 2;
468
+ const i3_2 = i3 * 2;
469
+ const i1_3 = i1 * 3;
470
+ const i2_3 = i2 * 3;
471
+ const i3_3 = i3 * 3;
472
+ if (uvs) {
473
+ vec2.set(uv1, uvs[i1_2], uvs[i1_2 + 1]);
474
+ vec2.set(uv2, uvs[i2_2], uvs[i2_2 + 1]);
475
+ vec2.set(uv3, uvs[i3_2], uvs[i3_2 + 1]);
476
+ }
477
+ else {
478
+ vec2.set(uv1, 0, 0);
479
+ vec2.set(uv2, 0, 0);
480
+ vec2.set(uv3, 0, 0);
481
+ }
482
+ let onSeam = false;
483
+ if (isTriplanar || isSpherical || isCylindrical) {
484
+ vec3.set(n1, normal[i1_3], normal[i1_3 + 1], normal[i1_3 + 2]);
485
+ vec3.set(n2, normal[i2_3], normal[i2_3 + 1], normal[i2_3 + 2]);
486
+ vec3.set(n3, normal[i3_3], normal[i3_3 + 1], normal[i3_3 + 2]);
487
+ vec3.normalize(n1, n1);
488
+ vec3.normalize(n2, n2);
489
+ vec3.normalize(n3, n3);
490
+ if (isTriplanar || isSpherical || isCylindrical) {
491
+ vec3.set(p1, position[i1_3], position[i1_3 + 1], position[i1_3 + 2]);
492
+ vec3.set(p2, position[i2_3], position[i2_3 + 1], position[i2_3 + 2]);
493
+ vec3.set(p3, position[i3_3], position[i3_3 + 1], position[i3_3 + 2]);
494
+ }
495
+ if (isTriplanar) {
496
+ // Is on the seam. Needs full prism to avoid empty seams.
497
+ const xMaxIndex = getMaxAxisIndex(n1);
498
+ const yMaxIndex = getMaxAxisIndex(n2);
499
+ const zMaxIndex = getMaxAxisIndex(n3);
500
+ if (!(xMaxIndex === yMaxIndex && yMaxIndex === zMaxIndex)) {
501
+ onSeam = true;
502
+ }
503
+ /* prettier-ignore */
504
+ triplanarProjectionTriangle(p1, p2, p3, n1, n2, n3, uv1, uv2, uv3);
505
+ }
506
+ else if (isSpherical) {
507
+ vec3.normalize(p1, p1);
508
+ vec3.normalize(p2, p2);
509
+ vec3.normalize(p3, p3);
510
+ onSeam = sphericalProjectionTriangle(p1, p2, p3, uv1, uv2, uv3);
511
+ }
512
+ else {
513
+ const u1 = Math.atan2(p1[2], p1[0]) / (Math.PI * 2) + 0.5;
514
+ const u2 = Math.atan2(p2[2], p2[0]) / (Math.PI * 2) + 0.5;
515
+ const u3 = Math.atan2(p3[2], p3[0]) / (Math.PI * 2) + 0.5;
516
+ vec2.set(uv1, u1, p1[1]);
517
+ vec2.set(uv2, u2, p2[1]);
518
+ vec2.set(uv3, u3, p3[1]);
519
+ onSeam = Math.max(u1, u2, u3) - Math.min(u1, u2, u3) > 0.5;
520
+ }
521
+ }
522
+ vec2.scale(uv1, uv1, uvScale);
523
+ vec2.scale(uv2, uv2, uvScale);
524
+ vec2.scale(uv3, uv3, uvScale);
525
+ // TODO PDM don't have zero area triangle issue.
526
+ let minHeight = Infinity;
527
+ let maxHeight = -Infinity;
528
+ if (onSeam) {
529
+ minHeight = 0.0;
530
+ maxHeight = 255.0;
531
+ }
532
+ else {
533
+ vec2.copy(maxUv, uv1);
534
+ vec2.copy(minUv, uv1);
535
+ vec2.min(minUv, minUv, uv2);
536
+ vec2.min(minUv, minUv, uv3);
537
+ vec2.max(maxUv, maxUv, uv2);
538
+ vec2.max(maxUv, maxUv, uv3);
539
+ const rootCount = findRoots(minUv, maxUv, maxDepth, roots);
540
+ for (let k = 0; k < rootCount; k++) {
541
+ const mipLevel = roots[k][2];
542
+ const mipSize = Math.pow(2, maxDepth - mipLevel);
543
+ const minmax = minmaxData[mipLevel];
544
+ const x = ((roots[k][0] % mipSize) + mipSize) % mipSize;
545
+ let y = ((roots[k][1] % mipSize) + mipSize) % mipSize;
546
+ if (isFlipY) {
547
+ y = mipSize - y - 1;
548
+ }
549
+ const idx = (y * mipSize + x) * 2;
550
+ minHeight = Math.min(minHeight, minmax[idx]);
551
+ maxHeight = Math.max(maxHeight, minmax[idx + 1]);
552
+ }
553
+ }
554
+ // TODO this will cause flat surface optimization fail.
555
+ // But not adding bias will leads to small gap between flat surface and displaced surface.
556
+ trianglesDisplacementRange[(i / 3) * 2] = Math.max((Math.floor(minHeight) - 4) / 255, 0);
557
+ trianglesDisplacementRange[(i / 3) * 2 + 1] = Math.min((Math.ceil(maxHeight) + 4) / 255, 1);
558
+ }
559
+ return trianglesDisplacementRange;
560
+ }
561
+ const warnedDirectionGeometry = new WeakSet();
562
+ /** Prepare auto-generated source attributes before the renderer captures array identities. */
563
+ export function ensureMeshGeometryAttributes(meshes) {
564
+ for (const { geometry, materials } of meshes) {
565
+ if (!geometry.tangent && !warnedDirectionGeometry.has(geometry) && materials.some(m => m.anisotropyMap || m.specularAnisotropyRotation !== 0 || m.coatAnisotropyRotation !== 0 || (m.specularAnisotropyModel === 'gltf' && m.specularAnisotropy > 0))) {
566
+ console.warn('MuTracer: anisotropy direction has no vertex tangent; deriving a frame from the selected UV set with a stable fallback for degenerate UVs.');
567
+ warnedDirectionGeometry.add(geometry);
568
+ }
569
+ if (!geometry.position?.array.length)
570
+ continue;
571
+ if (!geometry.normal)
572
+ computeGeometryNormals(geometry);
573
+ if (!geometry.tangent && geometry.uv)
574
+ generateVertexTangents(geometry);
575
+ }
576
+ }
577
+ function getMeshBlasGeometry(mesh) {
578
+ const geometry = getPreparedMeshGeometry(mesh);
579
+ if (!geometry.normal)
580
+ computeGeometryNormals(geometry);
581
+ if (!geometry.tangent && geometry.uv)
582
+ generateVertexTangents(geometry);
583
+ return geometry;
584
+ }
585
+ /** Geometry and displacement inputs shared by synchronous and Worker BLAS builds. */
586
+ export function getMeshBlasInput(mesh) {
587
+ const geometry = getMeshBlasGeometry(mesh);
588
+ const heightMap = getMeshDisplacementMap(mesh);
589
+ const displacementScale = heightMap ? getMeshDisplacementScale(mesh) : 0;
590
+ const trianglesDisplacement = Math.abs(displacementScale) > 1e-6
591
+ ? getTrianglesDisplacementRange(geometry, heightMap, getMeshDisplacementMaterial(mesh))
592
+ : undefined;
593
+ return { geometry, displacementScale, trianglesDisplacement };
594
+ }
595
+ /** Whether a static mesh still needs a BLAS before it can be rendered. */
596
+ export function meshNeedsStaticBvh(mesh, config) {
597
+ return !!mesh.geometry.position?.array.length && !mesh.geometry.dynamic &&
598
+ (!getGeometryBvh(getPreparedMeshGeometry(mesh)) || !!config && !geometryBvhConfigMatches(getPreparedMeshGeometry(mesh), config));
599
+ }
600
+ /** Capture inputs whose changes invalidate an asynchronous BLAS result. */
601
+ export function captureMeshBlasSnapshot(mesh, target) {
602
+ const displacementMap = getMeshDisplacementMap(mesh);
603
+ return {
604
+ geometry: mesh.geometry,
605
+ version: mesh.geometry.version,
606
+ cacheKey: getPreparedMeshGeometryCacheKey(mesh),
607
+ bvh: getGeometryBvh(target),
608
+ displacementMap,
609
+ displacementScale: getMeshDisplacementScale(mesh),
610
+ displacementTextureKey: displacementMap
611
+ ? getDisplacementTextureDataCacheKey(displacementMap) : undefined
612
+ };
613
+ }
614
+ /** Check that a result still belongs to the captured mesh inputs. */
615
+ export function meshBlasSnapshotIsCurrent(mesh, target, snapshot) {
616
+ return mesh.geometry === snapshot.geometry && mesh.geometry.version === snapshot.version &&
617
+ getPreparedMeshGeometryCacheKey(mesh) === snapshot.cacheKey && getGeometryBvh(target) === snapshot.bvh &&
618
+ getMeshDisplacementMap(mesh) === snapshot.displacementMap &&
619
+ getMeshDisplacementScale(mesh) === snapshot.displacementScale &&
620
+ (!snapshot.displacementMap || getDisplacementTextureDataCacheKey(snapshot.displacementMap) ===
621
+ snapshot.displacementTextureKey);
622
+ }
623
+ function prepareMeshGeometryBvh(mesh) {
624
+ const geometry = getMeshBlasGeometry(mesh);
625
+ const displacementScale = getMeshDisplacementMap(mesh) ? getMeshDisplacementScale(mesh) : 0;
626
+ if (geometry.dynamic && getGeometryBvh(geometry)?.builder !== 'builtin')
627
+ setGeometryBvh(geometry, undefined);
628
+ if (!getGeometryBvh(geometry)) {
629
+ const { trianglesDisplacement } = getMeshBlasInput(mesh);
630
+ setGeometryBvh(geometry, buildBLAS(geometry, displacementScale, trianglesDisplacement));
631
+ }
632
+ return { geometry, displacementScale };
633
+ }
634
+ export function updateMeshInstances(meshes) {
635
+ const materialIndexMap = new Map();
636
+ const geometryIndexMap = new Map();
637
+ const geometries = [];
638
+ const materials = [];
639
+ const globalMaterialIndicesMap = [];
640
+ const emissiveBindings = [];
641
+ const instanceBindings = [];
642
+ const instances = meshes
643
+ .filter((mesh) => mesh.geometry.position?.array.length > 0)
644
+ .map((mesh) => {
645
+ let { geometry, displacementScale } = prepareMeshGeometryBvh(mesh);
646
+ const bvhBounds = getBvhBounds(geometry);
647
+ const bounds = computeBounds(geometry, mesh.transform, bvhBounds);
648
+ let geoIdx = geometryIndexMap.get(geometry);
649
+ const materialsIndices = mesh.materials.map((material) => {
650
+ const key = material;
651
+ if (!materialIndexMap.has(key)) {
652
+ materialIndexMap.set(key, materials.length);
653
+ materials.push(material);
654
+ }
655
+ return materialIndexMap.get(key);
656
+ });
657
+ // Explicit vertex indices are global after merging. Batches with a
658
+ // different material table need their own vertex region, even when the
659
+ // table contains just one material. Equal tables can share the region.
660
+ if (geoIdx != null && geometry.materialIndex &&
661
+ (materialsIndices.length !== globalMaterialIndicesMap[geoIdx].length ||
662
+ materialsIndices.some((index, i) => index !== globalMaterialIndicesMap[geoIdx][i]))) {
663
+ const bvh = getGeometryBvh(geometry);
664
+ geometry = new Geometry(geometry);
665
+ setGeometryBvh(geometry, bvh);
666
+ geoIdx = undefined;
667
+ }
668
+ if (geoIdx == null) {
669
+ geoIdx = geometries.length;
670
+ geometryIndexMap.set(geometry, geometries.length);
671
+ geometries.push(geometry);
672
+ // Same number with geometries.
673
+ globalMaterialIndicesMap.push(materialsIndices);
674
+ }
675
+ const instance = {
676
+ bounds,
677
+ blasIndex: geoIdx,
678
+ transform: mesh.transform,
679
+ materialsIndices: materialsIndices.map((idx) => packMaterialIndexAndWeightToInt(idx, 1)),
680
+ displacementScale
681
+ };
682
+ if (!(mesh instanceof InstancedMesh) && (!bounds.min.every(isFinite) ||
683
+ !bounds.max.every(isFinite) ||
684
+ !mesh.transform.every(isFinite))) {
685
+ return undefined;
686
+ }
687
+ if (mesh.materials.some((material) => !material.unlit && !material.shadowCatcher &&
688
+ colorLuminance(material.emissionColor) * material.emissionLuminance > 1e-8)) {
689
+ emissiveBindings.push({ mesh, geometry, materialIndices: materialsIndices });
690
+ }
691
+ instanceBindings.push({
692
+ mesh,
693
+ geometry,
694
+ blasIndex: geoIdx,
695
+ materialIndices: materialsIndices,
696
+ displacementScale,
697
+ bvhBounds
698
+ });
699
+ return instance;
700
+ })
701
+ .filter((instance) => instance != null);
702
+ const geometryRegions = new Map();
703
+ const geometry = mergeGeometry(geometries, globalMaterialIndicesMap, geometryRegions);
704
+ return {
705
+ geometry,
706
+ geometries,
707
+ geometryRegions,
708
+ geometryStates: new Map(instanceBindings.map(binding => {
709
+ const source = binding.mesh.geometry;
710
+ return [source, { topologyVersion: source.topologyVersion, indices: source.indices.array,
711
+ indexCount: source.indices.array.length }];
712
+ })),
713
+ instances: meshes.some(mesh => mesh instanceof InstancedMesh) ? updateMeshInstanceTransforms(instanceBindings) : instances,
714
+ materials,
715
+ instanceBindings,
716
+ emissiveBindings,
717
+ blases: geometries.map((geo) => ({
718
+ bvh: getGeometryBvh(geo),
719
+ verticesCount: geo.vertexCount,
720
+ trainglesCount: geo.indices.array.length / 3
721
+ }))
722
+ };
723
+ }
724
+ function mergeGeometry(geometries, globalMaterialIndicesMap, regions) {
725
+ const totalVertexCount = geometries.reduce((sum, geo) => sum + geo.vertexCount, 0);
726
+ const totalIndexCount = geometries.reduce((sum, geo) => sum + geo.indices.array.length, 0);
727
+ const positionAttrib = new Attribute(new Float32Array(3 * totalVertexCount), 3);
728
+ const normalAttrib = new Attribute(new Float32Array(3 * totalVertexCount), 3);
729
+ const uvAttrib = new Attribute(new Float32Array(2 * totalVertexCount), 2);
730
+ const uv1Attrib = new Attribute(new Float32Array(2 * totalVertexCount), 2);
731
+ const indexAttrib = new Attribute(new Uint32Array(totalIndexCount), 1);
732
+ const materialIndexAttrib = new Attribute(new Int32Array(4 * totalVertexCount), 4);
733
+ const hasColor = geometries.some((geo) => geo.color);
734
+ const hasTangent = geometries.some((geo) => geo.tangent);
735
+ const mergedGeometry = new Geometry({
736
+ position: positionAttrib,
737
+ normal: normalAttrib,
738
+ uv: uvAttrib,
739
+ uv1: uv1Attrib,
740
+ materialIndex: materialIndexAttrib,
741
+ color: hasColor
742
+ ? new Attribute(new Float32Array(3 * totalVertexCount), 3)
743
+ : undefined,
744
+ tangent: hasTangent
745
+ ? new Attribute(new Float32Array(4 * totalVertexCount), 4)
746
+ : undefined,
747
+ indices: indexAttrib
748
+ });
749
+ let currentVertex = 0;
750
+ let currentIndex = 0;
751
+ geometries.forEach((geometry, idx) => {
752
+ const vertexCount = geometry.vertexCount;
753
+ const globalMaterialIndex = globalMaterialIndicesMap[idx];
754
+ regions.set(geometry, { vertexOffset: currentVertex, indexOffset: currentIndex, materialIndices: globalMaterialIndex });
755
+ positionAttrib.array.set(geometry.position.array, currentVertex * 3);
756
+ normalAttrib.array.set(geometry.normal.array, currentVertex * 3);
757
+ if (geometry.uv) {
758
+ uvAttrib.array.set(geometry.uv.array, currentVertex * 2);
759
+ }
760
+ uv1Attrib.array.set((geometry.uv1 ?? geometry.uv)?.array ?? new Float32Array(vertexCount * 2), currentVertex * 2);
761
+ if (geometry.color) {
762
+ mergedGeometry.color.array.set(geometry.color.array, currentVertex * 3);
763
+ }
764
+ if (geometry.tangent) {
765
+ const source = geometry.tangent;
766
+ for (let v = 0; v < vertexCount; v++) {
767
+ for (let c = 0; c < 4; c++)
768
+ mergedGeometry.tangent.array[(currentVertex + v) * 4 + c] =
769
+ c < source.itemSize ? source.array[v * source.itemSize + c] : hasGeneratedVertexTangents(geometry) ? 0 : 2;
770
+ }
771
+ }
772
+ writeMaterialIndices(geometry, globalMaterialIndex, materialIndexAttrib.array, currentVertex);
773
+ const meshIndices = geometry.indices.array;
774
+ for (let i = 0; i < meshIndices.length; i++) {
775
+ indexAttrib.array[currentIndex + i] = currentVertex + meshIndices[i];
776
+ }
777
+ currentVertex += vertexCount;
778
+ currentIndex += meshIndices.length;
779
+ });
780
+ return mergedGeometry;
781
+ }
782
+ function computeGeometryNormals(geometry) {
783
+ const indices = geometry.indices;
784
+ const positions = geometry.position.array;
785
+ geometry.normal = new Attribute(new Float32Array(positions.length), 3);
786
+ const normals = geometry.normal.array;
787
+ const p1 = vec3.create();
788
+ const p2 = vec3.create();
789
+ const p3 = vec3.create();
790
+ const v21 = vec3.create();
791
+ const v32 = vec3.create();
792
+ const n = vec3.create();
793
+ const len = indices
794
+ ? indices.array.length
795
+ : geometry.vertexCount;
796
+ let i1, i2, i3;
797
+ for (let f = 0; f < len;) {
798
+ if (indices) {
799
+ i1 = indices.array[f++];
800
+ i2 = indices.array[f++];
801
+ i3 = indices.array[f++];
802
+ }
803
+ else {
804
+ i1 = f++;
805
+ i2 = f++;
806
+ i3 = f++;
807
+ }
808
+ vec3.set(p1, positions[i1 * 3], positions[i1 * 3 + 1], positions[i1 * 3 + 2]);
809
+ vec3.set(p2, positions[i2 * 3], positions[i2 * 3 + 1], positions[i2 * 3 + 2]);
810
+ vec3.set(p3, positions[i3 * 3], positions[i3 * 3 + 1], positions[i3 * 3 + 2]);
811
+ vec3.sub(v21, p1, p2);
812
+ vec3.sub(v32, p2, p3);
813
+ vec3.cross(n, v21, v32);
814
+ // Already be weighted by the triangle area
815
+ for (let i = 0; i < 3; i++) {
816
+ normals[i1 * 3 + i] = normals[i1 * 3 + i] + n[i];
817
+ normals[i2 * 3 + i] = normals[i2 * 3 + i] + n[i];
818
+ normals[i3 * 3 + i] = normals[i3 * 3 + i] + n[i];
819
+ }
820
+ }
821
+ for (let i = 0; i < normals.length;) {
822
+ vec3.set(n, normals[i], normals[i + 1], normals[i + 2]);
823
+ vec3.normalize(n, n);
824
+ normals[i++] = n[0];
825
+ normals[i++] = n[1];
826
+ normals[i++] = n[2];
827
+ }
828
+ }
829
+ /** Batch records are regenerated together; refit all numeric source slots. */
830
+ export function dirtyMeshInstanceIndices(bindings, meshes, instances) {
831
+ if (instances instanceof PackedMeshInstances)
832
+ return new Set(Array.from({ length: instances.length }, (_, i) => i));
833
+ return new Set(bindings.flatMap((binding, i) => meshes.has(binding.mesh) ? [i] : []));
834
+ }
835
+ /** Refreshes color storage without computing transforms or bounds. Returns packed source slots. */
836
+ export function updateMeshInstanceColors(bindings, instances, meshes) {
837
+ const dirty = new Set();
838
+ if (!(instances instanceof PackedMeshInstances))
839
+ return dirty;
840
+ let sourceStart = 0, packedIndex = 0;
841
+ for (const { mesh } of bindings) {
842
+ const count = meshInstanceCount(mesh), sourceEnd = sourceStart + count;
843
+ while (packedIndex < instances.length && instances.sourceIndices[packedIndex] < sourceEnd) {
844
+ if (meshes.has(mesh)) {
845
+ const localIndex = instances.sourceIndices[packedIndex] - sourceStart;
846
+ const colors = mesh instanceof InstancedMesh ? mesh.colors : undefined;
847
+ for (let k = 0; k < 3; k++)
848
+ instances.colors[packedIndex * 3 + k] = colors?.[localIndex * 3 + k] ?? 1;
849
+ dirty.add(packedIndex);
850
+ }
851
+ packedIndex++;
852
+ }
853
+ sourceStart = sourceEnd;
854
+ }
855
+ return dirty;
856
+ }
857
+ //# sourceMappingURL=prepareMeshBVH.js.map