@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,75 @@
1
+ import { TexturePixelSource, vec3 } from '../math.js';
2
+ import DirectionalLight from '../scene/DirectionalLight.js';
3
+ import Geometry from '../scene/Geometry.js';
4
+ import Mesh from '../scene/Mesh.js';
5
+ import RectLight from '../scene/RectLight.js';
6
+ import SphereLight from '../scene/SphereLight.js';
7
+ import SpotLight from '../scene/SpotLight.js';
8
+ import OpenPBRMaterial from '../scene/OpenPBRMaterial.js';
9
+ export declare const LIGHT_CHOICE_ENVIRONMENT = 1;
10
+ export declare const LIGHT_CHOICE_ANALYTIC = 2;
11
+ export declare const LIGHT_CHOICE_EMISSIVE_TRIANGLE = 3;
12
+ export declare const LIGHT_DOMAIN_ENVIRONMENT = 0;
13
+ export declare const LIGHT_DOMAIN_INFINITE = 1;
14
+ export declare const LIGHT_DOMAIN_LOCAL_AND_EMISSIVE = 2;
15
+ type AnalyticLight = DirectionalLight | SphereLight | SpotLight | RectLight;
16
+ export interface EmissiveTriangle {
17
+ p0: vec3.Vec3Array;
18
+ p1: vec3.Vec3Array;
19
+ p2: vec3.Vec3Array;
20
+ uv0: [number, number];
21
+ uv1: [number, number];
22
+ uv2: [number, number];
23
+ secondaryUv0: [number, number];
24
+ secondaryUv1: [number, number];
25
+ secondaryUv2: [number, number];
26
+ materialIndex: number;
27
+ area: number;
28
+ samplingLuminance: number;
29
+ selectionPmf: number;
30
+ }
31
+ export interface EmissiveMeshBinding {
32
+ mesh: Mesh;
33
+ geometry: Geometry;
34
+ materialIndices: number[];
35
+ }
36
+ export interface LightChoiceInput {
37
+ sourceType: number;
38
+ sourceIndex: number;
39
+ weight: number;
40
+ }
41
+ export interface LightSamplingDistribution {
42
+ choices: Uint32Array;
43
+ pmfs: Float32Array;
44
+ totalWeight: number;
45
+ }
46
+ export declare function colorLuminance(color: ArrayLike<number>): number;
47
+ export declare function estimateAnalyticLightPower(light: AnalyticLight): number;
48
+ export declare function sphereSolidAnglePdf(distanceToCenter: number, radius: number): number;
49
+ /** Packs unique 128² peak-normalized IES profiles four scalar samples per texel. */
50
+ export declare function packIESProfiles(lights: AnalyticLight[], firstTexel?: number): {
51
+ data: Float32Array<ArrayBuffer>;
52
+ offsets: Int32Array<ArrayBuffer>;
53
+ texelCount: number;
54
+ };
55
+ export declare function estimateEnvironmentPower(image?: TexturePixelSource): number;
56
+ /** Reusable typed choices; insertion order matches the sampling distribution. */
57
+ export declare class LightChoiceBuffer {
58
+ count: number;
59
+ sourceTypes: Uint32Array<ArrayBuffer>;
60
+ sourceIndices: Uint32Array<ArrayBuffer>;
61
+ weights: Float64Array<ArrayBuffer>;
62
+ reserve(capacity: number): void;
63
+ push(sourceType: number, sourceIndex: number, weight: number): void;
64
+ }
65
+ /** Builds a Walker alias table. Each 16-byte entry is probability/alias/type/index. */
66
+ export declare function buildLightAliasTable(inputs: LightChoiceInput[] | LightChoiceBuffer): LightSamplingDistribution;
67
+ export declare function collectEmissiveTriangles(bindings: EmissiveMeshBinding[], materials: OpenPBRMaterial[]): EmissiveTriangle[];
68
+ export declare function packEmissiveTriangles(triangles: EmissiveTriangle[], data?: Float32Array): Float32Array<ArrayBufferLike>;
69
+ /** Caches world-space vertices per mesh, independently of emission strength. */
70
+ export declare class EmissiveTriangleCache {
71
+ private _bindings;
72
+ private _triangles;
73
+ collect(bindings: EmissiveMeshBinding[], materials: OpenPBRMaterial[]): EmissiveTriangle[];
74
+ }
75
+ export {};
@@ -0,0 +1,305 @@
1
+ import { materialEmission } from './materialEmission.js';
2
+ import InstancedMesh from '../scene/InstancedMesh.js';
3
+ import { meshInstanceCount, meshInstanceTransform } from './meshInstances.js';
4
+ import { getRectLightArea, getSphereLightArea, getSpotLightArea, getSpotLightRadiance, getSpotLightShapingFluxFactor } from './lightsUtil.js';
5
+ import { localMaterialIndex } from './materialIndices.js';
6
+ import { vec3 } from '../math.js';
7
+ export const LIGHT_CHOICE_ENVIRONMENT = 1;
8
+ export const LIGHT_CHOICE_ANALYTIC = 2;
9
+ export const LIGHT_CHOICE_EMISSIVE_TRIANGLE = 3;
10
+ export const LIGHT_DOMAIN_ENVIRONMENT = 0;
11
+ export const LIGHT_DOMAIN_INFINITE = 1;
12
+ export const LIGHT_DOMAIN_LOCAL_AND_EMISSIVE = 2;
13
+ const luminanceCoefficients = [0.2126, 0.7152, 0.0722];
14
+ export function colorLuminance(color) {
15
+ return Math.max(color[0] * luminanceCoefficients[0] +
16
+ color[1] * luminanceCoefficients[1] +
17
+ color[2] * luminanceCoefficients[2], 0);
18
+ }
19
+ export function estimateAnalyticLightPower(light) {
20
+ const emittedLuminance = colorLuminance(light.color) * light.intensity;
21
+ if (!(emittedLuminance > 0))
22
+ return 0;
23
+ if (light.type === 'RectLight') {
24
+ return emittedLuminance * Math.PI * Math.max(getRectLightArea(light), 0);
25
+ }
26
+ if (light.type === 'SphereLight') {
27
+ if (light.radius === 0)
28
+ return emittedLuminance * 4 * Math.PI;
29
+ return emittedLuminance * Math.PI * Math.max(getSphereLightArea(light), 0);
30
+ }
31
+ if (light.type === 'SpotLight') {
32
+ const radianceLuminance = colorLuminance(light.color) * getSpotLightRadiance(light);
33
+ // The selection power is an approximation and ignores the IES profile.
34
+ if (light.radius === 0) {
35
+ return emittedLuminance *
36
+ 4 * Math.PI *
37
+ getSpotLightShapingFluxFactor(light);
38
+ }
39
+ return (radianceLuminance *
40
+ Math.PI *
41
+ getSpotLightArea(light) *
42
+ getSpotLightShapingFluxFactor(light));
43
+ }
44
+ // A directional light has no finite emitting area. 4π keeps its heuristic
45
+ // weight on roughly the same scale as an environment map integral.
46
+ return emittedLuminance * 4 * Math.PI;
47
+ }
48
+ export function sphereSolidAnglePdf(distanceToCenter, radius) {
49
+ if (distanceToCenter <= radius)
50
+ return 1 / (4 * Math.PI);
51
+ const cosThetaMax = Math.sqrt(Math.max(0, 1 - radius * radius / (distanceToCenter * distanceToCenter)));
52
+ return 1 / Math.max(2 * Math.PI * (1 - cosThetaMax), 1e-8);
53
+ }
54
+ /** Packs unique 128² peak-normalized IES profiles four scalar samples per texel. */
55
+ export function packIESProfiles(lights, firstTexel = 0) {
56
+ const offsets = new Int32Array(lights.length).fill(-1);
57
+ const profiles = [];
58
+ const indices = new Map();
59
+ lights.forEach((light, index) => {
60
+ if (light.type !== 'SpotLight' || !light.iesProfile)
61
+ return;
62
+ let profileIndex = indices.get(light.iesProfile);
63
+ if (profileIndex == null) {
64
+ profileIndex = profiles.length;
65
+ indices.set(light.iesProfile, profileIndex);
66
+ profiles.push(light.iesProfile);
67
+ }
68
+ offsets[index] = firstTexel + profileIndex * ((128 * 128) / 4);
69
+ });
70
+ const data = new Float32Array(profiles.length * 128 * 128);
71
+ profiles.forEach((profile, index) => data.set(profile.data, index * 128 * 128));
72
+ return { data, offsets, texelCount: data.length / 4 };
73
+ }
74
+ const environmentPowers = new WeakMap();
75
+ export function estimateEnvironmentPower(image) {
76
+ if (!image?.data || !image.width || !image.height)
77
+ return 0;
78
+ const cached = environmentPowers.get(image);
79
+ if (cached !== undefined)
80
+ return cached;
81
+ const { data, width, height } = image;
82
+ const channels = Math.max(Math.floor(data.length / (width * height)), 1);
83
+ let weightedLuminance = 0;
84
+ for (let y = 0; y < height; y++) {
85
+ const sinTheta = Math.sin(Math.PI * (y + 0.5) / height);
86
+ for (let x = 0; x < width; x++) {
87
+ const offset = (y * width + x) * channels;
88
+ const scale = (data instanceof Uint8Array || data instanceof Uint8ClampedArray) ? 1 / 255 : 1;
89
+ weightedLuminance +=
90
+ colorLuminance([
91
+ data[offset] * scale,
92
+ data[offset + Math.min(1, channels - 1)] * scale,
93
+ data[offset + Math.min(2, channels - 1)] * scale
94
+ ]) * sinTheta;
95
+ }
96
+ }
97
+ const power = weightedLuminance * (2 * Math.PI * Math.PI) / (width * height);
98
+ environmentPowers.set(image, power);
99
+ return power;
100
+ }
101
+ /** Reusable typed choices; insertion order matches the sampling distribution. */
102
+ export class LightChoiceBuffer {
103
+ count = 0;
104
+ sourceTypes = new Uint32Array(0);
105
+ sourceIndices = new Uint32Array(0);
106
+ weights = new Float64Array(0);
107
+ reserve(capacity) {
108
+ this.count = 0;
109
+ if (this.weights.length < capacity) {
110
+ this.sourceTypes = new Uint32Array(capacity);
111
+ this.sourceIndices = new Uint32Array(capacity);
112
+ this.weights = new Float64Array(capacity);
113
+ }
114
+ }
115
+ push(sourceType, sourceIndex, weight) {
116
+ if (!(weight > 0) || !isFinite(weight))
117
+ return;
118
+ const i = this.count++;
119
+ this.sourceTypes[i] = sourceType;
120
+ this.sourceIndices[i] = sourceIndex;
121
+ this.weights[i] = weight;
122
+ }
123
+ }
124
+ /** Builds a Walker alias table. Each 16-byte entry is probability/alias/type/index. */
125
+ export function buildLightAliasTable(inputs) {
126
+ let active;
127
+ if (inputs instanceof LightChoiceBuffer)
128
+ active = inputs;
129
+ else {
130
+ active = new LightChoiceBuffer();
131
+ active.reserve(inputs.length);
132
+ for (const input of inputs)
133
+ active.push(input.sourceType, input.sourceIndex, input.weight);
134
+ }
135
+ const count = active.count;
136
+ let totalWeight = 0;
137
+ for (let i = 0; i < count; i++)
138
+ totalWeight += active.weights[i];
139
+ if (!count || !(totalWeight > 0))
140
+ return { choices: new Uint32Array(4), pmfs: new Float32Array(0), totalWeight: 0 };
141
+ const pmfs = new Float32Array(count);
142
+ const scaled = new Float64Array(count);
143
+ const small = new Uint32Array(count), large = new Uint32Array(count);
144
+ let smallCount = 0, largeCount = 0;
145
+ for (let i = 0; i < count; i++) {
146
+ pmfs[i] = active.weights[i] / totalWeight;
147
+ scaled[i] = pmfs[i] * count;
148
+ if (scaled[i] < 1)
149
+ small[smallCount++] = i;
150
+ else
151
+ large[largeCount++] = i;
152
+ }
153
+ const buffer = new ArrayBuffer(count * 16);
154
+ const floats = new Float32Array(buffer), ints = new Int32Array(buffer);
155
+ while (smallCount && largeCount) {
156
+ const low = small[--smallCount], high = large[--largeCount];
157
+ floats[low * 4] = scaled[low];
158
+ ints[low * 4 + 1] = high;
159
+ scaled[high] = scaled[high] + scaled[low] - 1;
160
+ if (scaled[high] < 1)
161
+ small[smallCount++] = high;
162
+ else
163
+ large[largeCount++] = high;
164
+ }
165
+ for (let i = 0; i < smallCount; i++) {
166
+ const index = small[i];
167
+ floats[index * 4] = 1;
168
+ ints[index * 4 + 1] = index;
169
+ }
170
+ for (let i = 0; i < largeCount; i++) {
171
+ const index = large[i];
172
+ floats[index * 4] = 1;
173
+ ints[index * 4 + 1] = index;
174
+ }
175
+ for (let i = 0; i < count; i++) {
176
+ ints[i * 4 + 2] = active.sourceTypes[i];
177
+ ints[i * 4 + 3] = active.sourceIndices[i];
178
+ }
179
+ return { choices: new Uint32Array(buffer), pmfs, totalWeight };
180
+ }
181
+ function dominantLocalMaterial(geometry, triangleOffset, materialCount) {
182
+ // Public triangles have the same raw material index on all three corners.
183
+ return localMaterialIndex(geometry, geometry.indices.array[triangleOffset], materialCount);
184
+ }
185
+ export function collectEmissiveTriangles(bindings, materials) {
186
+ const triangles = [];
187
+ const local = [vec3.create(), vec3.create(), vec3.create()];
188
+ const world = [vec3.create(), vec3.create(), vec3.create()];
189
+ const edge0 = vec3.create();
190
+ const edge1 = vec3.create();
191
+ const cross = vec3.create();
192
+ for (const { mesh, geometry, materialIndices } of bindings) {
193
+ const matrix = Array(16).fill(0);
194
+ for (let instance = 0; instance < meshInstanceCount(mesh); instance++) {
195
+ meshInstanceTransform(mesh, instance, matrix);
196
+ const indices = geometry.indices.array;
197
+ const positions = geometry.position.array;
198
+ const uvs = geometry.uv?.array;
199
+ const secondaryUvs = geometry.uv1?.array ?? uvs;
200
+ for (let triangleOffset = 0; triangleOffset < indices.length; triangleOffset += 3) {
201
+ const localMaterialIndex = dominantLocalMaterial(geometry, triangleOffset, materialIndices.length);
202
+ const materialIndex = materialIndices[localMaterialIndex] ?? materialIndices[0] ?? 0;
203
+ const material = materials[materialIndex];
204
+ if (!material || material.shadowCatcher || material.unlit)
205
+ continue;
206
+ const samplingLuminance = colorLuminance(materialEmission(material));
207
+ if (!(samplingLuminance > 1e-8))
208
+ continue;
209
+ const triangleIndices = [
210
+ indices[triangleOffset],
211
+ indices[triangleOffset + 1],
212
+ indices[triangleOffset + 2]
213
+ ];
214
+ for (let corner = 0; corner < 3; corner++) {
215
+ const vertex = triangleIndices[corner];
216
+ vec3.set(local[corner], positions[vertex * geometry.position.itemSize], positions[vertex * geometry.position.itemSize + 1], positions[vertex * geometry.position.itemSize + 2]);
217
+ vec3.transformMat4(world[corner], local[corner], matrix);
218
+ }
219
+ vec3.sub(edge0, world[1], world[0]);
220
+ vec3.sub(edge1, world[2], world[0]);
221
+ vec3.cross(cross, edge0, edge1);
222
+ const area = 0.5 * vec3.length(cross);
223
+ if (!(area > 1e-10) || !isFinite(area))
224
+ continue;
225
+ const triangleUvs = triangleIndices.map((vertex) => uvs
226
+ ? [uvs[vertex * 2], uvs[vertex * 2 + 1]]
227
+ : [0, 0]);
228
+ const triangleSecondaryUvs = triangleIndices.map((vertex) => secondaryUvs
229
+ ? [secondaryUvs[vertex * 2], secondaryUvs[vertex * 2 + 1]]
230
+ : [0, 0]);
231
+ triangles.push({
232
+ p0: vec3.clone(world[0]),
233
+ p1: vec3.clone(world[1]),
234
+ p2: vec3.clone(world[2]),
235
+ uv0: triangleUvs[0],
236
+ uv1: triangleUvs[1],
237
+ uv2: triangleUvs[2],
238
+ secondaryUv0: triangleSecondaryUvs[0],
239
+ secondaryUv1: triangleSecondaryUvs[1],
240
+ secondaryUv2: triangleSecondaryUvs[2],
241
+ materialIndex,
242
+ area,
243
+ samplingLuminance,
244
+ selectionPmf: 0
245
+ });
246
+ }
247
+ }
248
+ }
249
+ return triangles;
250
+ }
251
+ export function packEmissiveTriangles(triangles, data = new Float32Array(Math.max(triangles.length, 1) * 24)) {
252
+ triangles.forEach((triangle, index) => {
253
+ const offset = index * 24;
254
+ data.set(triangle.p0, offset);
255
+ data[offset + 3] = triangle.selectionPmf;
256
+ data.set(triangle.p1, offset + 4);
257
+ data[offset + 7] = triangle.area;
258
+ data.set(triangle.p2, offset + 8);
259
+ data[offset + 11] = triangle.materialIndex;
260
+ data.set(triangle.uv0, offset + 12);
261
+ data.set(triangle.uv1, offset + 14);
262
+ data.set(triangle.uv2, offset + 16);
263
+ data.set(triangle.secondaryUv0, offset + 18);
264
+ data.set(triangle.secondaryUv1, offset + 20);
265
+ data.set(triangle.secondaryUv2, offset + 22);
266
+ });
267
+ return data;
268
+ }
269
+ /** Caches world-space vertices per mesh, independently of emission strength. */
270
+ export class EmissiveTriangleCache {
271
+ _bindings = new WeakMap();
272
+ _triangles = [];
273
+ collect(bindings, materials) {
274
+ this._triangles.length = 0;
275
+ for (const binding of bindings) {
276
+ const { mesh, geometry, materialIndices } = binding;
277
+ const isActive = (index) => {
278
+ const m = materials[index];
279
+ return !!m && !m.unlit && !m.shadowCatcher && colorLuminance(materialEmission(m)) > 1e-8;
280
+ };
281
+ const instanceVersion = mesh instanceof InstancedMesh ? mesh.transformsVersion : 0;
282
+ const instanceCount = meshInstanceCount(mesh);
283
+ const instanceTransforms = mesh instanceof InstancedMesh ? mesh.transforms : undefined;
284
+ let cached = this._bindings.get(mesh);
285
+ if (!cached || cached.geometry !== geometry || cached.version !== geometry.version || cached.instanceVersion !== instanceVersion || cached.instanceCount !== instanceCount || cached.instanceTransforms !== instanceTransforms ||
286
+ cached.indices.length !== materialIndices.length || materialIndices.some((index, i) => cached.indices[i] !== index || cached.activity[i] !== isActive(index)) ||
287
+ mesh.transform.some((value, i) => !Object.is(value, cached.matrix[i]))) {
288
+ cached = { geometry, version: geometry.version, instanceVersion, instanceCount, instanceTransforms, matrix: Float64Array.from(mesh.transform),
289
+ indices: materialIndices.slice(), activity: materialIndices.map(isActive),
290
+ triangles: collectEmissiveTriangles([binding], materials) };
291
+ this._bindings.set(mesh, cached);
292
+ }
293
+ else {
294
+ for (const triangle of cached.triangles) {
295
+ const m = materials[triangle.materialIndex];
296
+ triangle.samplingLuminance = colorLuminance(materialEmission(m));
297
+ }
298
+ }
299
+ for (const triangle of cached.triangles)
300
+ this._triangles.push(triangle);
301
+ }
302
+ return this._triangles;
303
+ }
304
+ }
305
+ //# sourceMappingURL=lightSampling.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightSampling.js","sourceRoot":"","sources":["../../src/renderer/lightSampling.ts"],"names":[],"mappings":"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","sourcesContent":["import { materialEmission } from './materialEmission.js';\nimport InstancedMesh from '../scene/InstancedMesh.js';\nimport { meshInstanceCount, meshInstanceTransform } from './meshInstances.js';\nimport { getRectLightArea, getSphereLightArea, getSpotLightArea, getSpotLightRadiance, getSpotLightShapingFluxFactor } from './lightsUtil.js';\nimport { localMaterialIndex } from './materialIndices.js';\nimport { TexturePixelSource, vec3 } from '../math.js';\nimport DirectionalLight from '../scene/DirectionalLight.js';\nimport Geometry from '../scene/Geometry.js';\nimport Mesh from '../scene/Mesh.js';\nimport RectLight from '../scene/RectLight.js';\nimport SphereLight from '../scene/SphereLight.js';\nimport SpotLight from '../scene/SpotLight.js';\nimport IESProfile from '../scene/IESProfile.js';\nimport OpenPBRMaterial from '../scene/OpenPBRMaterial.js';\n\nexport const LIGHT_CHOICE_ENVIRONMENT = 1;\nexport const LIGHT_CHOICE_ANALYTIC = 2;\nexport const LIGHT_CHOICE_EMISSIVE_TRIANGLE = 3;\n\nexport const LIGHT_DOMAIN_ENVIRONMENT = 0;\nexport const LIGHT_DOMAIN_INFINITE = 1;\nexport const LIGHT_DOMAIN_LOCAL_AND_EMISSIVE = 2;\ntype AnalyticLight = DirectionalLight | SphereLight | SpotLight | RectLight;\n\nexport interface EmissiveTriangle {\n p0: vec3.Vec3Array;\n p1: vec3.Vec3Array;\n p2: vec3.Vec3Array;\n uv0: [number, number];\n uv1: [number, number];\n uv2: [number, number];\n secondaryUv0: [number, number];\n secondaryUv1: [number, number];\n secondaryUv2: [number, number];\n materialIndex: number;\n area: number;\n samplingLuminance: number;\n selectionPmf: number;\n}\n\nexport interface EmissiveMeshBinding {\n mesh: Mesh;\n geometry: Geometry;\n materialIndices: number[];\n}\n\nexport interface LightChoiceInput {\n sourceType: number;\n sourceIndex: number;\n weight: number;\n}\n\nexport interface LightSamplingDistribution {\n choices: Uint32Array;\n pmfs: Float32Array;\n totalWeight: number;\n}\n\nconst luminanceCoefficients = [0.2126, 0.7152, 0.0722] as const;\n\nexport function colorLuminance(color: ArrayLike<number>) {\n return Math.max(\n color[0] * luminanceCoefficients[0] +\n color[1] * luminanceCoefficients[1] +\n color[2] * luminanceCoefficients[2],\n 0\n );\n}\n\nexport function estimateAnalyticLightPower(light: AnalyticLight) {\n const emittedLuminance = colorLuminance(light.color) * light.intensity;\n if (!(emittedLuminance > 0)) return 0;\n if (light.type === 'RectLight') {\n return emittedLuminance * Math.PI * Math.max(getRectLightArea(light), 0);\n }\n if (light.type === 'SphereLight') {\n if (light.radius === 0) return emittedLuminance * 4 * Math.PI;\n return emittedLuminance * Math.PI * Math.max(getSphereLightArea(light), 0);\n }\n if (light.type === 'SpotLight') {\n const radianceLuminance =\n colorLuminance(light.color) * getSpotLightRadiance(light);\n // The selection power is an approximation and ignores the IES profile.\n if (light.radius === 0) {\n return emittedLuminance *\n 4 * Math.PI *\n getSpotLightShapingFluxFactor(light);\n }\n return (\n radianceLuminance *\n Math.PI *\n getSpotLightArea(light) *\n getSpotLightShapingFluxFactor(light)\n );\n }\n // A directional light has no finite emitting area. 4π keeps its heuristic\n // weight on roughly the same scale as an environment map integral.\n return emittedLuminance * 4 * Math.PI;\n}\n\nexport function sphereSolidAnglePdf(distanceToCenter: number, radius: number) {\n if (distanceToCenter <= radius) return 1 / (4 * Math.PI);\n const cosThetaMax = Math.sqrt(\n Math.max(0, 1 - radius * radius / (distanceToCenter * distanceToCenter))\n );\n return 1 / Math.max(2 * Math.PI * (1 - cosThetaMax), 1e-8);\n}\n\n/** Packs unique 128² peak-normalized IES profiles four scalar samples per texel. */\nexport function packIESProfiles(lights: AnalyticLight[], firstTexel = 0) {\n const offsets = new Int32Array(lights.length).fill(-1);\n const profiles: IESProfile[] = [];\n const indices = new Map<IESProfile, number>();\n lights.forEach((light, index) => {\n if (light.type !== 'SpotLight' || !light.iesProfile) return;\n let profileIndex = indices.get(light.iesProfile);\n if (profileIndex == null) {\n profileIndex = profiles.length;\n indices.set(light.iesProfile, profileIndex);\n profiles.push(light.iesProfile);\n }\n offsets[index] = firstTexel + profileIndex * ((128 * 128) / 4);\n });\n const data = new Float32Array(profiles.length * 128 * 128);\n profiles.forEach((profile, index) => data.set(profile.data, index * 128 * 128));\n return { data, offsets, texelCount: data.length / 4 };\n}\n\nconst environmentPowers = new WeakMap<TexturePixelSource, number>();\n\nexport function estimateEnvironmentPower(image?: TexturePixelSource) {\n if (!image?.data || !image.width || !image.height) return 0;\n const cached = environmentPowers.get(image);\n if (cached !== undefined) return cached;\n const { data, width, height } = image;\n const channels = Math.max(Math.floor(data.length / (width * height)), 1);\n let weightedLuminance = 0;\n for (let y = 0; y < height; y++) {\n const sinTheta = Math.sin(Math.PI * (y + 0.5) / height);\n for (let x = 0; x < width; x++) {\n const offset = (y * width + x) * channels;\n const scale = (data instanceof Uint8Array || data instanceof Uint8ClampedArray) ? 1 / 255 : 1;\n weightedLuminance +=\n colorLuminance([\n data[offset] * scale,\n data[offset + Math.min(1, channels - 1)] * scale,\n data[offset + Math.min(2, channels - 1)] * scale\n ]) * sinTheta;\n }\n }\n const power = weightedLuminance * (2 * Math.PI * Math.PI) / (width * height);\n environmentPowers.set(image, power);\n return power;\n}\n\n/** Reusable typed choices; insertion order matches the sampling distribution. */\nexport class LightChoiceBuffer {\n count = 0;\n sourceTypes = new Uint32Array(0);\n sourceIndices = new Uint32Array(0);\n weights = new Float64Array(0);\n reserve(capacity: number) {\n this.count = 0;\n if (this.weights.length < capacity) {\n this.sourceTypes = new Uint32Array(capacity);\n this.sourceIndices = new Uint32Array(capacity);\n this.weights = new Float64Array(capacity);\n }\n }\n push(sourceType: number, sourceIndex: number, weight: number) {\n if (!(weight > 0) || !isFinite(weight)) return;\n const i = this.count++;\n this.sourceTypes[i] = sourceType; this.sourceIndices[i] = sourceIndex; this.weights[i] = weight;\n }\n}\n\n/** Builds a Walker alias table. Each 16-byte entry is probability/alias/type/index. */\nexport function buildLightAliasTable(inputs: LightChoiceInput[] | LightChoiceBuffer): LightSamplingDistribution {\n let active: LightChoiceBuffer;\n if (inputs instanceof LightChoiceBuffer) active = inputs;\n else {\n active = new LightChoiceBuffer(); active.reserve(inputs.length);\n for (const input of inputs) active.push(input.sourceType, input.sourceIndex, input.weight);\n }\n const count = active.count;\n let totalWeight = 0;\n for (let i = 0; i < count; i++) totalWeight += active.weights[i];\n if (!count || !(totalWeight > 0)) return { choices: new Uint32Array(4), pmfs: new Float32Array(0), totalWeight: 0 };\n const pmfs = new Float32Array(count);\n const scaled = new Float64Array(count);\n const small = new Uint32Array(count), large = new Uint32Array(count);\n let smallCount = 0, largeCount = 0;\n for (let i = 0; i < count; i++) {\n pmfs[i] = active.weights[i] / totalWeight;\n scaled[i] = pmfs[i] * count;\n if (scaled[i] < 1) small[smallCount++] = i; else large[largeCount++] = i;\n }\n const buffer = new ArrayBuffer(count * 16);\n const floats = new Float32Array(buffer), ints = new Int32Array(buffer);\n while (smallCount && largeCount) {\n const low = small[--smallCount], high = large[--largeCount];\n floats[low * 4] = scaled[low]; ints[low * 4 + 1] = high;\n scaled[high] = scaled[high] + scaled[low] - 1;\n if (scaled[high] < 1) small[smallCount++] = high; else large[largeCount++] = high;\n }\n for (let i = 0; i < smallCount; i++) { const index = small[i]; floats[index * 4] = 1; ints[index * 4 + 1] = index; }\n for (let i = 0; i < largeCount; i++) { const index = large[i]; floats[index * 4] = 1; ints[index * 4 + 1] = index; }\n for (let i = 0; i < count; i++) { ints[i * 4 + 2] = active.sourceTypes[i]; ints[i * 4 + 3] = active.sourceIndices[i]; }\n return { choices: new Uint32Array(buffer), pmfs, totalWeight };\n}\n\nfunction dominantLocalMaterial(geometry: Geometry, triangleOffset: number, materialCount: number) {\n // Public triangles have the same raw material index on all three corners.\n return localMaterialIndex(geometry, geometry.indices.array[triangleOffset], materialCount);\n}\n\nexport function collectEmissiveTriangles(\n bindings: EmissiveMeshBinding[],\n materials: OpenPBRMaterial[]\n) {\n const triangles: EmissiveTriangle[] = [];\n const local = [vec3.create(), vec3.create(), vec3.create()];\n const world = [vec3.create(), vec3.create(), vec3.create()];\n const edge0 = vec3.create();\n const edge1 = vec3.create();\n const cross = vec3.create();\n\n for (const { mesh, geometry, materialIndices } of bindings) {\n const matrix = Array(16).fill(0);\n for (let instance = 0; instance < meshInstanceCount(mesh); instance++) {\n meshInstanceTransform(mesh, instance, matrix);\n const indices = geometry.indices.array;\n const positions = geometry.position.array;\n const uvs = geometry.uv?.array;\n const secondaryUvs = geometry.uv1?.array ?? uvs;\n for (let triangleOffset = 0; triangleOffset < indices.length; triangleOffset += 3) {\n const localMaterialIndex = dominantLocalMaterial(geometry, triangleOffset, materialIndices.length);\n const materialIndex = materialIndices[localMaterialIndex] ?? materialIndices[0] ?? 0;\n const material = materials[materialIndex];\n if (!material || material.shadowCatcher || material.unlit) continue;\n const samplingLuminance =\n colorLuminance(materialEmission(material));\n if (!(samplingLuminance > 1e-8)) continue;\n\n const triangleIndices = [\n indices[triangleOffset],\n indices[triangleOffset + 1],\n indices[triangleOffset + 2]\n ];\n for (let corner = 0; corner < 3; corner++) {\n const vertex = triangleIndices[corner];\n vec3.set(\n local[corner],\n positions[vertex * geometry.position.itemSize],\n positions[vertex * geometry.position.itemSize + 1],\n positions[vertex * geometry.position.itemSize + 2]\n );\n vec3.transformMat4(world[corner], local[corner], matrix);\n }\n vec3.sub(edge0, world[1], world[0]);\n vec3.sub(edge1, world[2], world[0]);\n vec3.cross(cross, edge0, edge1);\n const area = 0.5 * vec3.length(cross);\n if (!(area > 1e-10) || !isFinite(area)) continue;\n\n const triangleUvs = triangleIndices.map((vertex) =>\n uvs\n ? [uvs[vertex * 2], uvs[vertex * 2 + 1]] as [number, number]\n : [0, 0] as [number, number]\n );\n const triangleSecondaryUvs = triangleIndices.map((vertex) =>\n secondaryUvs\n ? [secondaryUvs[vertex * 2], secondaryUvs[vertex * 2 + 1]] as [number, number]\n : [0, 0] as [number, number]\n );\n triangles.push({\n p0: vec3.clone(world[0]),\n p1: vec3.clone(world[1]),\n p2: vec3.clone(world[2]),\n uv0: triangleUvs[0],\n uv1: triangleUvs[1],\n uv2: triangleUvs[2],\n secondaryUv0: triangleSecondaryUvs[0],\n secondaryUv1: triangleSecondaryUvs[1],\n secondaryUv2: triangleSecondaryUvs[2],\n materialIndex,\n area,\n samplingLuminance,\n selectionPmf: 0\n });\n }\n }\n }\n return triangles;\n}\n\nexport function packEmissiveTriangles(triangles: EmissiveTriangle[], data: Float32Array = new Float32Array(Math.max(triangles.length, 1) * 24)) {\n triangles.forEach((triangle, index) => {\n const offset = index * 24;\n data.set(triangle.p0, offset);\n data[offset + 3] = triangle.selectionPmf;\n data.set(triangle.p1, offset + 4);\n data[offset + 7] = triangle.area;\n data.set(triangle.p2, offset + 8);\n data[offset + 11] = triangle.materialIndex;\n data.set(triangle.uv0, offset + 12);\n data.set(triangle.uv1, offset + 14);\n data.set(triangle.uv2, offset + 16);\n data.set(triangle.secondaryUv0, offset + 18);\n data.set(triangle.secondaryUv1, offset + 20);\n data.set(triangle.secondaryUv2, offset + 22);\n });\n return data;\n}\n\n\n/** Caches world-space vertices per mesh, independently of emission strength. */\nexport class EmissiveTriangleCache {\n private _bindings = new WeakMap<Mesh, { geometry: Geometry; version: number; instanceVersion: number; instanceCount: number; instanceTransforms?: Float32Array; matrix: Float64Array;\n indices: number[]; activity: boolean[]; triangles: EmissiveTriangle[] }>();\n private _triangles: EmissiveTriangle[] = [];\n collect(bindings: EmissiveMeshBinding[], materials: OpenPBRMaterial[]) {\n this._triangles.length = 0;\n for (const binding of bindings) {\n const { mesh, geometry, materialIndices } = binding;\n const isActive = (index: number) => {\n const m = materials[index];\n return !!m && !m.unlit && !m.shadowCatcher && colorLuminance(materialEmission(m)) > 1e-8;\n };\n const instanceVersion = mesh instanceof InstancedMesh ? mesh.transformsVersion : 0;\n const instanceCount = meshInstanceCount(mesh);\n const instanceTransforms = mesh instanceof InstancedMesh ? mesh.transforms : undefined;\n let cached = this._bindings.get(mesh);\n if (!cached || cached.geometry !== geometry || cached.version !== geometry.version || cached.instanceVersion !== instanceVersion || cached.instanceCount !== instanceCount || cached.instanceTransforms !== instanceTransforms ||\n cached.indices.length !== materialIndices.length || materialIndices.some((index, i) =>\n cached!.indices[i] !== index || cached!.activity[i] !== isActive(index)) ||\n mesh.transform.some((value: number, i: number) => !Object.is(value, cached!.matrix[i]))) {\n cached = { geometry, version: geometry.version, instanceVersion, instanceCount, instanceTransforms, matrix: Float64Array.from(mesh.transform),\n indices: materialIndices.slice(), activity: materialIndices.map(isActive),\n triangles: collectEmissiveTriangles([binding], materials) };\n this._bindings.set(mesh, cached);\n } else {\n for (const triangle of cached.triangles) {\n const m = materials[triangle.materialIndex];\n triangle.samplingLuminance = colorLuminance(materialEmission(m));\n }\n }\n for (const triangle of cached.triangles) this._triangles.push(triangle);\n }\n return this._triangles;\n }\n}\n"]}
@@ -0,0 +1,26 @@
1
+ import type { SceneLight, AnalyticLight } from '../scene/Scene.js';
2
+ import type { Vec3 } from '../types.js';
3
+ import DirectionalLight from '../scene/DirectionalLight.js';
4
+ import SphereLight from '../scene/SphereLight.js';
5
+ import RectLight from '../scene/RectLight.js';
6
+ import SpotLight from '../scene/SpotLight.js';
7
+ export declare const CONSTANT_DIRECTIONAL_LIGHT = 1;
8
+ export declare const CONSTANT_SPHERE_LIGHT = 2;
9
+ export declare const CONSTANT_RECT_LIGHT = 3;
10
+ export declare const CONSTANT_SPOT_LIGHT = 4;
11
+ export declare function packLightsToBuffer(lights: (DirectionalLight | RectLight | SphereLight | SpotLight)[], texturesIndices: number[], selectionPmfs?: ArrayLike<number>, selectionCdfs?: ArrayLike<number>, iesProfileTexelOffsets?: ArrayLike<number>): Float32Array<ArrayBuffer>;
12
+ export declare function getRigidLightFrame(light: AnalyticLight): {
13
+ x: Vec3;
14
+ y: [number, number, number];
15
+ direction: Vec3;
16
+ };
17
+ export declare function getLightDirection(light: AnalyticLight): Vec3;
18
+ export declare function getRectLightUOrV(light: RectLight, uOrV: 0 | 1): number[];
19
+ export declare function getRectLightPosition(light: RectLight): Vec3;
20
+ export declare function getRectLightArea(light: RectLight): number;
21
+ export declare function getSphereLightArea(light: SphereLight): number;
22
+ export declare function getSpotLightArea(light: SpotLight): number;
23
+ export declare function getSpotLightRadiance(light: SpotLight): number;
24
+ export declare function getSpotLightShapingFluxFactor(light: SpotLight): number;
25
+ /** Sanitizes invalid mutable light values at the packing boundary; notifications are nonfatal. */
26
+ export declare function validateSceneLights(lights: readonly SceneLight[], onError?: (error: Error) => void): void;
@@ -0,0 +1,154 @@
1
+ export const CONSTANT_DIRECTIONAL_LIGHT = 1;
2
+ export const CONSTANT_SPHERE_LIGHT = 2;
3
+ export const CONSTANT_RECT_LIGHT = 3;
4
+ export const CONSTANT_SPOT_LIGHT = 4;
5
+ export function packLightsToBuffer(lights, texturesIndices, selectionPmfs = [], selectionCdfs = [], iesProfileTexelOffsets = []) {
6
+ validateSceneLights(lights);
7
+ const numLights = lights.length;
8
+ const PIXELS_PER_LIGHT = 6;
9
+ const data = new Float32Array(numLights * PIXELS_PER_LIGHT * 4);
10
+ function packVec3(idx, v) {
11
+ for (let i = 0; i < 3; i++) {
12
+ data[i + idx * 4] = v[i];
13
+ }
14
+ }
15
+ for (let i = 0; i < numLights; i++) {
16
+ const light = lights[i];
17
+ const color = light.color;
18
+ const intensity = light.intensity;
19
+ const off = i * PIXELS_PER_LIGHT;
20
+ packVec3(off, light.position);
21
+ data[off * 4 + 3] = selectionPmfs[i] ?? 1 / Math.max(numLights, 1);
22
+ // emission
23
+ const emissionScale = light.type === 'SpotLight' ? getSpotLightRadiance(light) : intensity;
24
+ packVec3(off + 1, [
25
+ color[0] * emissionScale,
26
+ color[1] * emissionScale,
27
+ color[2] * emissionScale
28
+ ]);
29
+ data[(off + 1) * 4 + 3] = selectionCdfs[i] ?? (i + 1) / numLights;
30
+ if (light.type === 'RectLight') {
31
+ packVec3(off + 2, getRectLightUOrV(light, 0));
32
+ data[(off + 2) * 4 + 3] = light.spread;
33
+ packVec3(off + 3, getRectLightUOrV(light, 1));
34
+ data[(off + 3) * 4 + 3] = texturesIndices[i];
35
+ packVec3(off + 4, [
36
+ light.spread,
37
+ getRectLightArea(light),
38
+ CONSTANT_RECT_LIGHT
39
+ ]);
40
+ }
41
+ else if (light.type === 'SphereLight') {
42
+ packVec3(off + 4, [
43
+ light.radius,
44
+ getSphereLightArea(light),
45
+ CONSTANT_SPHERE_LIGHT
46
+ ]);
47
+ }
48
+ else if (light.type === 'SpotLight') {
49
+ packVec3(off + 2, getLightDirection(light));
50
+ packVec3(off + 3, [
51
+ Math.cos((light.outerAngle * Math.PI) / 180),
52
+ Math.min(1, Math.max(0, 1 - light.innerAngle / light.outerAngle)),
53
+ 0
54
+ ]);
55
+ data[(off + 3) * 4 + 3] = iesProfileTexelOffsets[i] ?? -1;
56
+ packVec3(off + 4, [
57
+ light.radius,
58
+ getSpotLightArea(light),
59
+ CONSTANT_SPOT_LIGHT
60
+ ]);
61
+ }
62
+ else if (light.type === 'DirectionalLight') {
63
+ packVec3(off + 2, getLightDirection(light));
64
+ packVec3(off + 4, [0, 0, CONSTANT_DIRECTIONAL_LIGHT]);
65
+ }
66
+ packVec3(off + 5, getRigidLightFrame(light).x);
67
+ }
68
+ return data;
69
+ }
70
+ export function getRigidLightFrame(light) {
71
+ const m = light.transform;
72
+ const normalize = (v, fallback) => {
73
+ const length = Math.hypot(v[0], v[1], v[2]);
74
+ return length > 1e-12 ? [v[0] / length, v[1] / length, v[2] / length] : fallback;
75
+ };
76
+ const z = normalize([m[8], m[9], m[10]], [0, 0, 1]);
77
+ const projection = m[0] * z[0] + m[1] * z[1] + m[2] * z[2];
78
+ let x = [m[0] - projection * z[0], m[1] - projection * z[1], m[2] - projection * z[2]];
79
+ if (Math.hypot(...x) <= 1e-12)
80
+ x = Math.abs(z[1]) < .99 ? [z[2], 0, -z[0]] : [1, 0, 0];
81
+ x = normalize(x, [1, 0, 0]);
82
+ const y = [z[1] * x[2] - z[2] * x[1], z[2] * x[0] - z[0] * x[2], z[0] * x[1] - z[1] * x[0]];
83
+ return { x, y, direction: [-z[0] || 0, -z[1] || 0, -z[2] || 0] };
84
+ }
85
+ export function getLightDirection(light) { return getRigidLightFrame(light).direction; }
86
+ export function getRectLightUOrV(light, uOrV) {
87
+ const frame = getRigidLightFrame(light), axis = uOrV ? frame.y : frame.x;
88
+ const size = light.size[uOrV] * (uOrV ? -1 : 1);
89
+ return [axis[0] * size, axis[1] * size, axis[2] * size];
90
+ }
91
+ export function getRectLightPosition(light) { return light.position; }
92
+ export function getRectLightArea(light) {
93
+ return light.size[0] * light.size[1];
94
+ }
95
+ export function getSphereLightArea(light) {
96
+ return 4 * Math.PI * light.radius ** 2;
97
+ }
98
+ export function getSpotLightArea(light) {
99
+ return 4 * Math.PI * light.radius ** 2;
100
+ }
101
+ export function getSpotLightRadiance(light) {
102
+ // A zero-radius spot is a point emitter. Its stored emission is luminous
103
+ // intensity (cd), and the shader applies inverse-square attenuation.
104
+ if (light.radius === 0)
105
+ return light.intensity;
106
+ return light.intensity / (Math.PI * light.radius ** 2);
107
+ }
108
+ export function getSpotLightShapingFluxFactor(light) {
109
+ const cosConeAngle = Math.cos((light.outerAngle * Math.PI) / 180);
110
+ const softness = Math.min(1, Math.max(0, 1 - light.innerAngle / light.outerAngle));
111
+ return (1 - cosConeAngle) * (1 - 0.5 * softness) * 0.5;
112
+ }
113
+ const warnedLights = new WeakSet();
114
+ /** Sanitizes invalid mutable light values at the packing boundary; notifications are nonfatal. */
115
+ export function validateSceneLights(lights, onError) {
116
+ for (const light of lights) {
117
+ if (light.type === 'EnvironmentLight')
118
+ continue;
119
+ let invalid = false;
120
+ const clamp = (value, min, max, fallback) => {
121
+ const normalized = Math.min(max, Math.max(min, Number.isFinite(value) ? value : fallback));
122
+ invalid ||= !Object.is(normalized, value);
123
+ return normalized;
124
+ };
125
+ light.intensity = clamp(light.intensity, 0, Number.MAX_VALUE, 1);
126
+ for (let i = 0; i < 3; i++)
127
+ light.color[i] = clamp(light.color[i], 0, Number.MAX_VALUE, 1);
128
+ if (light.type !== 'AmbientLight') {
129
+ for (let i = 0; i < 16; i++)
130
+ if (!Number.isFinite(light.transform[i])) {
131
+ light.transform[i] = i % 5 === 0 ? 1 : 0;
132
+ invalid = true;
133
+ }
134
+ }
135
+ if (light.type === 'RectLight') {
136
+ for (let i = 0; i < 2; i++)
137
+ light.size[i] = clamp(light.size[i], 0, Number.MAX_VALUE, 1);
138
+ light.spread = clamp(light.spread, 0, 1, 1);
139
+ }
140
+ if (light.type === 'SphereLight' || light.type === 'SpotLight')
141
+ light.radius = clamp(light.radius, 0, Number.MAX_VALUE, light.type === 'SpotLight' ? .01 : 1);
142
+ if (light.type === 'SpotLight') {
143
+ light.outerAngle = clamp(light.outerAngle, Number.EPSILON, 180, 45);
144
+ light.innerAngle = clamp(light.innerAngle, 0, light.outerAngle, 30);
145
+ }
146
+ if (invalid && !warnedLights.has(light)) {
147
+ warnedLights.add(light);
148
+ const error = new Error(`Invalid ${light.type} values were clamped.`);
149
+ console.warn(error.message);
150
+ onError?.(error);
151
+ }
152
+ }
153
+ }
154
+ //# sourceMappingURL=lightsUtil.js.map