@meimu/mutracer 0.1.5 → 0.3.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 (590) hide show
  1. package/LICENSES/Classroom-CC0.txt +121 -0
  2. package/README.md +10 -7
  3. package/THIRD_PARTY_NOTICES.md +13 -8
  4. package/dist/assets/bvh.worker.js +1 -1
  5. package/dist/mutracer.umd.js +12316 -9228
  6. package/docs/api.md +232 -21
  7. package/docs/caustics.md +80 -0
  8. package/docs/denoising.md +30 -15
  9. package/docs/materials.md +6 -5
  10. package/docs/performance.md +5 -2
  11. package/docs/progressive-rendering.md +73 -1
  12. package/docs/technical/continuous-spectrum.md +93 -0
  13. package/docs/threejs.md +14 -5
  14. package/docs/updates.md +46 -2
  15. package/docs/viewer-checklist.md +65 -0
  16. package/docs/viewer.md +15 -8
  17. package/lib/Display.d.ts +13 -2
  18. package/lib/Display.js +28 -7
  19. package/lib/Display.js.map +1 -1
  20. package/lib/Engine.d.ts +4 -0
  21. package/lib/Engine.js +99 -37
  22. package/lib/Engine.js.map +1 -1
  23. package/lib/Render.d.ts +98 -15
  24. package/lib/Render.js +275 -27
  25. package/lib/Render.js.map +1 -1
  26. package/lib/RenderLoop.d.ts +11 -1
  27. package/lib/RenderLoop.js +120 -15
  28. package/lib/RenderLoop.js.map +1 -1
  29. package/lib/main.d.ts +6 -3
  30. package/lib/main.js +1 -0
  31. package/lib/main.js.map +1 -1
  32. package/lib/math/access.d.ts +4 -0
  33. package/lib/math/access.js +10 -0
  34. package/lib/math/access.js.map +1 -0
  35. package/lib/math/mat3.d.ts +4 -0
  36. package/lib/math/mat3.js +54 -0
  37. package/lib/math/mat3.js.map +1 -0
  38. package/lib/math/mat4.d.ts +19 -0
  39. package/lib/math/mat4.js +413 -0
  40. package/lib/math/mat4.js.map +1 -0
  41. package/lib/math/storage.d.ts +6 -0
  42. package/lib/math/storage.js +22 -0
  43. package/lib/math/storage.js.map +1 -0
  44. package/lib/math/types.d.ts +3 -0
  45. package/lib/math/types.js +2 -0
  46. package/lib/math/types.js.map +1 -0
  47. package/lib/math/vec2.d.ts +13 -0
  48. package/lib/math/vec2.js +52 -0
  49. package/lib/math/vec2.js.map +1 -0
  50. package/lib/math/vec3.d.ts +23 -0
  51. package/lib/math/vec3.js +139 -0
  52. package/lib/math/vec3.js.map +1 -0
  53. package/lib/math.d.ts +5 -17
  54. package/lib/math.js +5 -55
  55. package/lib/math.js.map +1 -1
  56. package/lib/oidn.d.ts +1 -1
  57. package/lib/oidn.js +4 -2
  58. package/lib/oidn.js.map +1 -1
  59. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  60. package/lib/renderer/AovPrimitiveCache.d.ts +10 -0
  61. package/lib/renderer/AovPrimitiveCache.js +48 -0
  62. package/lib/renderer/AovPrimitiveCache.js.map +1 -0
  63. package/lib/renderer/Box3.d.ts +5 -0
  64. package/lib/renderer/Box3.js +9 -0
  65. package/lib/renderer/Box3.js.map +1 -0
  66. package/lib/renderer/GPUTraceQueue.d.ts +11 -0
  67. package/lib/renderer/GPUTraceQueue.js +33 -0
  68. package/lib/renderer/GPUTraceQueue.js.map +1 -0
  69. package/lib/renderer/MaterialData.d.ts +15 -0
  70. package/lib/renderer/MaterialData.js +61 -0
  71. package/lib/renderer/MaterialData.js.map +1 -0
  72. package/lib/renderer/MaterialTable.d.ts +11 -98
  73. package/lib/renderer/MaterialTable.js +34 -412
  74. package/lib/renderer/MaterialTable.js.map +1 -1
  75. package/lib/renderer/RenderingPipeline.d.ts +36 -13
  76. package/lib/renderer/RenderingPipeline.js +1 -17
  77. package/lib/renderer/RenderingPipeline.js.map +1 -1
  78. package/lib/renderer/TileRender.d.ts +0 -1
  79. package/lib/renderer/TileRender.js +14 -1
  80. package/lib/renderer/TileRender.js.map +1 -1
  81. package/lib/renderer/WGPUAov.d.ts +39 -0
  82. package/lib/renderer/WGPUAov.js +239 -0
  83. package/lib/renderer/WGPUAov.js.map +1 -0
  84. package/lib/renderer/WGPUBindlessMaterialData.d.ts +17 -0
  85. package/lib/renderer/WGPUBindlessMaterialData.js +48 -0
  86. package/lib/renderer/WGPUBindlessMaterialData.js.map +1 -0
  87. package/lib/renderer/WGPUBindlessTextures.d.ts +47 -0
  88. package/lib/renderer/WGPUBindlessTextures.js +180 -0
  89. package/lib/renderer/WGPUBindlessTextures.js.map +1 -0
  90. package/lib/renderer/WGPUBloomPass.js +17 -97
  91. package/lib/renderer/WGPUBloomPass.js.map +1 -1
  92. package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
  93. package/lib/renderer/WGPUCausticLightPass.js +217 -0
  94. package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
  95. package/lib/renderer/WGPUComputePass.d.ts +1 -1
  96. package/lib/renderer/WGPUComputePass.js.map +1 -1
  97. package/lib/renderer/WGPUEnvMapDistribution.d.ts +12 -0
  98. package/lib/renderer/WGPUEnvMapDistribution.js +150 -0
  99. package/lib/renderer/WGPUEnvMapDistribution.js.map +1 -0
  100. package/lib/renderer/WGPUFullQuadPass.js +10 -9
  101. package/lib/renderer/WGPUFullQuadPass.js.map +1 -1
  102. package/lib/renderer/WGPUJNLMDenoiser.d.ts +1 -20
  103. package/lib/renderer/WGPUJNLMDenoiser.js +4 -267
  104. package/lib/renderer/WGPUJNLMDenoiser.js.map +1 -1
  105. package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
  106. package/lib/renderer/WGPUPhotonMap.js +191 -0
  107. package/lib/renderer/WGPUPhotonMap.js.map +1 -0
  108. package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
  109. package/lib/renderer/WGPURayTraceOutput.js +132 -29
  110. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  111. package/lib/renderer/WGPURayTracePass.d.ts +83 -56
  112. package/lib/renderer/WGPURayTracePass.js +884 -837
  113. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  114. package/lib/renderer/WGPURenderingPipeline.d.ts +5 -3
  115. package/lib/renderer/WGPURenderingPipeline.js +297 -82
  116. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  117. package/lib/renderer/WGPUShaderCache.d.ts +2 -2
  118. package/lib/renderer/WGPUShaderCache.js +10 -5
  119. package/lib/renderer/WGPUShaderCache.js.map +1 -1
  120. package/lib/renderer/WGPUShaderCapabilities.d.ts +10 -0
  121. package/lib/renderer/WGPUShaderCapabilities.js +54 -0
  122. package/lib/renderer/WGPUShaderCapabilities.js.map +1 -0
  123. package/lib/renderer/WGPUSkyBaker.d.ts +13 -0
  124. package/lib/renderer/WGPUSkyBaker.js +85 -0
  125. package/lib/renderer/WGPUSkyBaker.js.map +1 -0
  126. package/lib/renderer/WebGLAov.d.ts +41 -0
  127. package/lib/renderer/WebGLAov.js +106 -0
  128. package/lib/renderer/WebGLAov.js.map +1 -0
  129. package/lib/renderer/WebGLFullQuadPass.d.ts +7 -4
  130. package/lib/renderer/WebGLFullQuadPass.js +22 -2
  131. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  132. package/lib/renderer/WebGLJNLMDenoiser.d.ts +1 -1
  133. package/lib/renderer/WebGLJNLMDenoiser.js +83 -74
  134. package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
  135. package/lib/renderer/WebGLRayTraceOutputPass.js +7 -4
  136. package/lib/renderer/WebGLRayTraceOutputPass.js.map +1 -1
  137. package/lib/renderer/WebGLRayTracePass.d.ts +18 -3
  138. package/lib/renderer/WebGLRayTracePass.js +121 -9
  139. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  140. package/lib/renderer/WebGLRenderingPipeline.js +126 -22
  141. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  142. package/lib/renderer/WebGLSkyBaker.d.ts +39 -0
  143. package/lib/renderer/WebGLSkyBaker.js +422 -0
  144. package/lib/renderer/WebGLSkyBaker.js.map +1 -0
  145. package/lib/renderer/WebGLSkySource.d.ts +9 -0
  146. package/lib/renderer/WebGLSkySource.js +28 -0
  147. package/lib/renderer/WebGLSkySource.js.map +1 -0
  148. package/lib/renderer/accumulationTarget.d.ts +6 -0
  149. package/lib/renderer/accumulationTarget.js.map +1 -1
  150. package/lib/renderer/aov.d.ts +42 -0
  151. package/lib/renderer/aov.js +50 -0
  152. package/lib/renderer/aov.js.map +1 -0
  153. package/lib/renderer/aovDisplay.d.ts +14 -0
  154. package/lib/renderer/aovDisplay.js +32 -0
  155. package/lib/renderer/aovDisplay.js.map +1 -0
  156. package/lib/renderer/aovScene.d.ts +21 -0
  157. package/lib/renderer/aovScene.js +139 -0
  158. package/lib/renderer/aovScene.js.map +1 -0
  159. package/lib/renderer/binnedSahBvh.js +2 -1
  160. package/lib/renderer/binnedSahBvh.js.map +1 -1
  161. package/lib/renderer/bvhAccel.d.ts +20 -10
  162. package/lib/renderer/bvhAccel.js +168 -58
  163. package/lib/renderer/bvhAccel.js.map +1 -1
  164. package/lib/renderer/bvhWorkerBuild.d.ts +1 -0
  165. package/lib/renderer/cameraSnapshot.js +2 -1
  166. package/lib/renderer/cameraSnapshot.js.map +1 -1
  167. package/lib/renderer/cameraUniform.d.ts +2 -0
  168. package/lib/renderer/cameraUniform.js +12 -0
  169. package/lib/renderer/cameraUniform.js.map +1 -0
  170. package/lib/renderer/causticDiagnostics.d.ts +31 -0
  171. package/lib/renderer/causticDiagnostics.js +5 -0
  172. package/lib/renderer/causticDiagnostics.js.map +1 -0
  173. package/lib/renderer/causticEmission.d.ts +10 -0
  174. package/lib/renderer/causticEmission.js +40 -0
  175. package/lib/renderer/causticEmission.js.map +1 -0
  176. package/lib/renderer/causticUniform.d.ts +12 -0
  177. package/lib/renderer/causticUniform.js +22 -0
  178. package/lib/renderer/causticUniform.js.map +1 -0
  179. package/lib/renderer/caustics.d.ts +16 -0
  180. package/lib/renderer/caustics.js +93 -0
  181. package/lib/renderer/caustics.js.map +1 -0
  182. package/lib/renderer/committedScene.js +4 -0
  183. package/lib/renderer/committedScene.js.map +1 -1
  184. package/lib/renderer/denoiser.d.ts +3 -11
  185. package/lib/renderer/denoiser.js.map +1 -1
  186. package/lib/renderer/depthQuery.js +4 -1
  187. package/lib/renderer/depthQuery.js.map +1 -1
  188. package/lib/renderer/displacementPreparation.d.ts +11 -0
  189. package/lib/renderer/displacementPreparation.js +351 -0
  190. package/lib/renderer/displacementPreparation.js.map +1 -0
  191. package/lib/renderer/displacementRange.d.ts +1 -0
  192. package/lib/renderer/displacementRange.js +9 -0
  193. package/lib/renderer/displacementRange.js.map +1 -0
  194. package/lib/renderer/displayParityDiagnostics.d.ts +11 -0
  195. package/lib/renderer/displayParityDiagnostics.js +2 -0
  196. package/lib/renderer/displayParityDiagnostics.js.map +1 -0
  197. package/lib/renderer/envMapCreation.d.ts +9 -8
  198. package/lib/renderer/envMapCreation.js +36 -12
  199. package/lib/renderer/envMapCreation.js.map +1 -1
  200. package/lib/renderer/envMapDistribution.d.ts +12 -2
  201. package/lib/renderer/envMapDistribution.js +43 -34
  202. package/lib/renderer/envMapDistribution.js.map +1 -1
  203. package/lib/renderer/geometryBvhBounds.d.ts +4 -0
  204. package/lib/renderer/geometryBvhBounds.js +82 -0
  205. package/lib/renderer/geometryBvhBounds.js.map +1 -0
  206. package/lib/renderer/geometryUpdateState.d.ts +32 -0
  207. package/lib/renderer/geometryUpdateState.js +2 -0
  208. package/lib/renderer/geometryUpdateState.js.map +1 -0
  209. package/lib/renderer/geometryUpdates.d.ts +17 -9
  210. package/lib/renderer/geometryUpdates.js +92 -33
  211. package/lib/renderer/geometryUpdates.js.map +1 -1
  212. package/lib/renderer/glsl/aovDisplay.frag.d.ts +3 -0
  213. package/lib/renderer/glsl/aovDisplay.frag.js +54 -0
  214. package/lib/renderer/glsl/aovDisplay.frag.js.map +1 -0
  215. package/lib/renderer/glsl/aovReflectance.glsl.d.ts +2 -0
  216. package/lib/renderer/glsl/aovReflectance.glsl.js +87 -0
  217. package/lib/renderer/glsl/aovReflectance.glsl.js.map +1 -0
  218. package/lib/renderer/glsl/aovReflectanceSamples.glsl.d.ts +2 -0
  219. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +135 -0
  220. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js.map +1 -0
  221. package/lib/renderer/glsl/aovTrace.frag.d.ts +2 -0
  222. package/lib/renderer/glsl/aovTrace.frag.js +121 -0
  223. package/lib/renderer/glsl/aovTrace.frag.js.map +1 -0
  224. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
  225. package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
  226. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
  227. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
  228. package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -67
  229. package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
  230. package/lib/renderer/glsl/chunks/intersect.glsl.js +432 -434
  231. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  232. package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
  233. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +160 -157
  234. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  235. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +802 -802
  236. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  237. package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
  238. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
  239. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +72 -67
  240. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  241. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
  242. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  243. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
  244. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +143 -120
  245. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  246. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +21 -18
  247. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -1
  248. package/lib/renderer/glsl/chunks/sampling.glsl.js +91 -94
  249. package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
  250. package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
  251. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  252. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +12 -12
  253. package/lib/renderer/glsl/chunks/uvProjection.glsl.js.map +1 -1
  254. package/lib/renderer/glsl/depthQuery.frag.js +7 -7
  255. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +17 -9
  256. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js.map +1 -1
  257. package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
  258. package/lib/renderer/glsl/rayTrace.frag.js +271 -248
  259. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  260. package/lib/renderer/glsl/shadowCatcher.frag.js +37 -32
  261. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  262. package/lib/renderer/glsl/webglPipeline.frag.js +65 -60
  263. package/lib/renderer/glsl/webglPipeline.frag.js.map +1 -1
  264. package/lib/renderer/lightConstants.d.ts +10 -0
  265. package/lib/renderer/lightConstants.js +11 -0
  266. package/lib/renderer/lightConstants.js.map +1 -0
  267. package/lib/renderer/lightCore.d.ts +12 -0
  268. package/lib/renderer/lightCore.js +13 -0
  269. package/lib/renderer/lightCore.js.map +1 -0
  270. package/lib/renderer/lightSampling.d.ts +22 -18
  271. package/lib/renderer/lightSampling.js +135 -62
  272. package/lib/renderer/lightSampling.js.map +1 -1
  273. package/lib/renderer/lightsData.d.ts +21 -0
  274. package/lib/renderer/lightsData.js +192 -0
  275. package/lib/renderer/lightsData.js.map +1 -0
  276. package/lib/renderer/lightsUtil.d.ts +3 -26
  277. package/lib/renderer/lightsUtil.js +3 -153
  278. package/lib/renderer/lightsUtil.js.map +1 -1
  279. package/lib/renderer/materialBufferData.d.ts +70 -0
  280. package/lib/renderer/materialBufferData.js +2 -0
  281. package/lib/renderer/materialBufferData.js.map +1 -0
  282. package/lib/renderer/materialConstants.d.ts +11 -0
  283. package/lib/renderer/materialConstants.js +11 -0
  284. package/lib/renderer/materialConstants.js.map +1 -1
  285. package/lib/renderer/materialCore.d.ts +8 -0
  286. package/lib/renderer/materialCore.js +9 -0
  287. package/lib/renderer/materialCore.js.map +1 -0
  288. package/lib/renderer/materialEmission.d.ts +2 -2
  289. package/lib/renderer/materialEmission.js +3 -3
  290. package/lib/renderer/materialEmission.js.map +1 -1
  291. package/lib/renderer/materialLayout.d.ts +2 -101
  292. package/lib/renderer/materialLayout.js +110 -172
  293. package/lib/renderer/materialLayout.js.map +1 -1
  294. package/lib/renderer/materialLayoutSchema.d.ts +26 -0
  295. package/lib/renderer/materialLayoutSchema.js +172 -0
  296. package/lib/renderer/materialLayoutSchema.js.map +1 -0
  297. package/lib/renderer/materialParams.d.ts +69 -0
  298. package/lib/renderer/materialParams.js +272 -0
  299. package/lib/renderer/materialParams.js.map +1 -0
  300. package/lib/renderer/materialTextureSlots.d.ts +14 -324
  301. package/lib/renderer/materialTextureSlots.js +21 -8
  302. package/lib/renderer/materialTextureSlots.js.map +1 -1
  303. package/lib/renderer/materialTextures.d.ts +6 -0
  304. package/lib/renderer/{texturesFromMaterials.js → materialTextures.js} +1 -2
  305. package/lib/renderer/materialTextures.js.map +1 -0
  306. package/lib/renderer/mergeMeshesToGeometry.js +6 -147
  307. package/lib/renderer/mergeMeshesToGeometry.js.map +1 -1
  308. package/lib/renderer/meshInstances.d.ts +4 -21
  309. package/lib/renderer/meshInstances.js +10 -56
  310. package/lib/renderer/meshInstances.js.map +1 -1
  311. package/lib/renderer/oidnNetwork.d.ts +2 -2
  312. package/lib/renderer/oidnNetwork.js +1 -1
  313. package/lib/renderer/oidnNetwork.js.map +1 -1
  314. package/lib/renderer/openPbrEnergyLut.js +850 -846
  315. package/lib/renderer/openPbrEnergyLut.js.map +1 -1
  316. package/lib/renderer/ownedDenoiser.d.ts +9 -0
  317. package/lib/renderer/ownedDenoiser.js +2 -0
  318. package/lib/renderer/ownedDenoiser.js.map +1 -0
  319. package/lib/renderer/packedMeshInstances.d.ts +23 -0
  320. package/lib/renderer/packedMeshInstances.js +80 -0
  321. package/lib/renderer/packedMeshInstances.js.map +1 -0
  322. package/lib/renderer/prepareMeshBVH.d.ts +12 -47
  323. package/lib/renderer/prepareMeshBVH.js +21 -642
  324. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  325. package/lib/renderer/proceduralEnvironmentPower.d.ts +3 -0
  326. package/lib/renderer/proceduralEnvironmentPower.js +8 -0
  327. package/lib/renderer/proceduralEnvironmentPower.js.map +1 -0
  328. package/lib/renderer/progressiveScheduler.d.ts +1 -0
  329. package/lib/renderer/progressiveScheduler.js +7 -3
  330. package/lib/renderer/progressiveScheduler.js.map +1 -1
  331. package/lib/renderer/renderPipeline.d.ts +4 -1
  332. package/lib/renderer/renderPipeline.js.map +1 -1
  333. package/lib/renderer/renderingLimits.d.ts +9 -0
  334. package/lib/renderer/renderingLimits.js +18 -0
  335. package/lib/renderer/renderingLimits.js.map +1 -0
  336. package/lib/renderer/researchTransport.d.ts +31 -0
  337. package/lib/renderer/researchTransport.js +5 -0
  338. package/lib/renderer/researchTransport.js.map +1 -0
  339. package/lib/renderer/sceneAssembly.d.ts +73 -0
  340. package/lib/renderer/sceneAssembly.js +109 -0
  341. package/lib/renderer/sceneAssembly.js.map +1 -0
  342. package/lib/renderer/sceneChangeCore.d.ts +39 -0
  343. package/lib/renderer/sceneChangeCore.js +307 -0
  344. package/lib/renderer/sceneChangeCore.js.map +1 -0
  345. package/lib/renderer/sceneChangeDetector.d.ts +3 -6
  346. package/lib/renderer/sceneChangeDetector.js +24 -150
  347. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  348. package/lib/renderer/sceneLayoutSchema.d.ts +119 -0
  349. package/lib/renderer/sceneLayoutSchema.js +111 -0
  350. package/lib/renderer/sceneLayoutSchema.js.map +1 -0
  351. package/lib/renderer/sceneLightChanges.d.ts +3 -3
  352. package/lib/renderer/sceneLightChanges.js.map +1 -1
  353. package/lib/renderer/scenePreparation.d.ts +55 -0
  354. package/lib/renderer/scenePreparation.js +360 -0
  355. package/lib/renderer/scenePreparation.js.map +1 -0
  356. package/lib/renderer/scratchSampling.js +18 -18
  357. package/lib/renderer/scratchSampling.js.map +1 -1
  358. package/lib/renderer/shader.d.ts +2 -0
  359. package/lib/renderer/shader.js +2 -0
  360. package/lib/renderer/shader.js.map +1 -1
  361. package/lib/renderer/shaderCapabilities.d.ts +23 -0
  362. package/lib/renderer/shaderCapabilities.js +55 -0
  363. package/lib/renderer/shaderCapabilities.js.map +1 -0
  364. package/lib/renderer/shaderCapacity.d.ts +2 -0
  365. package/lib/renderer/shaderCapacity.js +5 -0
  366. package/lib/renderer/shaderCapacity.js.map +1 -0
  367. package/lib/renderer/skyModel.d.ts +9 -0
  368. package/lib/renderer/skyModel.js +10 -0
  369. package/lib/renderer/skyModel.js.map +1 -0
  370. package/lib/renderer/spectrum.d.ts +21 -0
  371. package/lib/renderer/spectrum.js +154 -0
  372. package/lib/renderer/spectrum.js.map +1 -0
  373. package/lib/renderer/textureAtlas.d.ts +60 -0
  374. package/lib/renderer/textureAtlas.js +145 -0
  375. package/lib/renderer/textureAtlas.js.map +1 -0
  376. package/lib/renderer/textureAtlasPixels.d.ts +7 -0
  377. package/lib/renderer/textureAtlasPixels.js +68 -0
  378. package/lib/renderer/textureAtlasPixels.js.map +1 -0
  379. package/lib/renderer/util.d.ts +1 -1
  380. package/lib/renderer/util.js.map +1 -1
  381. package/lib/renderer/webgl.d.ts +9 -2
  382. package/lib/renderer/webgl.js +54 -9
  383. package/lib/renderer/webgl.js.map +1 -1
  384. package/lib/renderer/webglLightSampling.d.ts +39 -0
  385. package/lib/renderer/webglLightSampling.js +15 -0
  386. package/lib/renderer/webglLightSampling.js.map +1 -0
  387. package/lib/renderer/wgpuBindless.d.ts +26 -0
  388. package/lib/renderer/wgpuBindless.js +95 -0
  389. package/lib/renderer/wgpuBindless.js.map +1 -0
  390. package/lib/renderer/wgpuBindlessSource.d.ts +2 -0
  391. package/lib/renderer/wgpuBindlessSource.js +51 -0
  392. package/lib/renderer/wgpuBindlessSource.js.map +1 -0
  393. package/lib/renderer/wgpuMaterialConstants.d.ts +4 -0
  394. package/lib/renderer/wgpuMaterialConstants.js +52 -0
  395. package/lib/renderer/wgpuMaterialConstants.js.map +1 -0
  396. package/lib/renderer/wgpuSceneUniform.d.ts +42 -0
  397. package/lib/renderer/wgpuSceneUniform.js +125 -0
  398. package/lib/renderer/wgpuSceneUniform.js.map +1 -0
  399. package/lib/renderer/wgpuShaderSource.d.ts +22 -0
  400. package/lib/renderer/wgpuShaderSource.js +33 -0
  401. package/lib/renderer/wgpuShaderSource.js.map +1 -0
  402. package/lib/renderer/wgsl/aovDisplay.wgsl.d.ts +1 -0
  403. package/lib/renderer/wgsl/aovDisplay.wgsl.js +70 -0
  404. package/lib/renderer/wgsl/aovDisplay.wgsl.js.map +1 -0
  405. package/lib/renderer/wgsl/aovReflectance.wgsl.d.ts +2 -0
  406. package/lib/renderer/wgsl/aovReflectance.wgsl.js +98 -0
  407. package/lib/renderer/wgsl/aovReflectance.wgsl.js.map +1 -0
  408. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.d.ts +2 -0
  409. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +135 -0
  410. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js.map +1 -0
  411. package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +5 -0
  412. package/lib/renderer/wgsl/aovResolve.wgsl.js +38 -0
  413. package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -0
  414. package/lib/renderer/wgsl/aovSnapshot.wgsl.d.ts +4 -0
  415. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +21 -0
  416. package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -0
  417. package/lib/renderer/wgsl/aovTrace.wgsl.d.ts +2 -0
  418. package/lib/renderer/wgsl/aovTrace.wgsl.js +115 -0
  419. package/lib/renderer/wgsl/aovTrace.wgsl.js.map +1 -0
  420. package/lib/renderer/wgsl/bloom.wgsl.d.ts +13 -0
  421. package/lib/renderer/wgsl/bloom.wgsl.js +92 -0
  422. package/lib/renderer/wgsl/bloom.wgsl.js.map +1 -0
  423. package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
  424. package/lib/renderer/wgsl/causticLight.compute.js +537 -0
  425. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
  426. package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
  427. package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
  428. package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
  429. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
  430. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
  431. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
  432. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
  433. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
  434. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
  435. package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
  436. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
  437. package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
  438. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  439. package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
  440. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +41 -35
  441. package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
  442. package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +13 -1
  443. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +747 -704
  444. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  445. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +16 -16
  446. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
  447. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +4 -1
  448. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +83 -79
  449. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  450. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +855 -857
  451. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js.map +1 -1
  452. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +137 -137
  453. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  454. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +3 -1
  455. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +52 -32
  456. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  457. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
  458. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +152 -144
  459. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
  460. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  461. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +269 -245
  462. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  463. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
  464. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +27 -14
  465. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
  466. package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
  467. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +91 -95
  468. package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
  469. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +1 -1
  470. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +1 -0
  471. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -1
  472. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
  473. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +12 -12
  474. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js.map +1 -1
  475. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +8 -3
  476. package/lib/renderer/wgsl/compose.frag.wgsl.js +143 -118
  477. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
  478. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  479. package/lib/renderer/wgsl/depthQuery.wgsl.js +7 -7
  480. package/lib/renderer/wgsl/jnlm.compute.d.ts +25 -0
  481. package/lib/renderer/wgsl/jnlm.compute.js +315 -0
  482. package/lib/renderer/wgsl/jnlm.compute.js.map +1 -0
  483. package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
  484. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.d.ts +1 -0
  485. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +17 -0
  486. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js.map +1 -0
  487. package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
  488. package/lib/renderer/wgsl/photonMap.compute.js +352 -0
  489. package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
  490. package/lib/renderer/wgsl/proceduralSky.compute.d.ts +1 -0
  491. package/lib/renderer/wgsl/proceduralSky.compute.js +198 -0
  492. package/lib/renderer/wgsl/proceduralSky.compute.js.map +1 -0
  493. package/lib/renderer/wgsl/rayTrace.compute.d.ts +25 -1
  494. package/lib/renderer/wgsl/rayTrace.compute.js +645 -500
  495. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  496. package/lib/scene/Camera.js +7 -3
  497. package/lib/scene/Camera.js.map +1 -1
  498. package/lib/scene/EnvironmentLight.d.ts +5 -9
  499. package/lib/scene/EnvironmentLight.js +4 -14
  500. package/lib/scene/EnvironmentLight.js.map +1 -1
  501. package/lib/scene/EnvironmentLightState.d.ts +18 -0
  502. package/lib/scene/EnvironmentLightState.js +19 -0
  503. package/lib/scene/EnvironmentLightState.js.map +1 -0
  504. package/lib/scene/Geometry.d.ts +12 -6
  505. package/lib/scene/Geometry.js +37 -13
  506. package/lib/scene/Geometry.js.map +1 -1
  507. package/lib/scene/InstanceState.d.ts +39 -0
  508. package/lib/scene/InstanceState.js +77 -0
  509. package/lib/scene/InstanceState.js.map +1 -0
  510. package/lib/scene/InstancedMesh.d.ts +1 -1
  511. package/lib/scene/InstancedMesh.js +3 -0
  512. package/lib/scene/InstancedMesh.js.map +1 -1
  513. package/lib/scene/MaterialState.d.ts +209 -0
  514. package/lib/scene/MaterialState.js +231 -0
  515. package/lib/scene/MaterialState.js.map +1 -0
  516. package/lib/scene/Mesh.d.ts +4 -6
  517. package/lib/scene/Mesh.js +3 -11
  518. package/lib/scene/Mesh.js.map +1 -1
  519. package/lib/scene/MeshState.d.ts +20 -0
  520. package/lib/scene/MeshState.js +35 -0
  521. package/lib/scene/MeshState.js.map +1 -0
  522. package/lib/scene/OpenPBRMaterial.d.ts +6 -168
  523. package/lib/scene/OpenPBRMaterial.js +5 -223
  524. package/lib/scene/OpenPBRMaterial.js.map +1 -1
  525. package/lib/scene/PixelTexture.d.ts +6 -0
  526. package/lib/scene/PixelTexture.js +10 -0
  527. package/lib/scene/PixelTexture.js.map +1 -0
  528. package/lib/scene/ProceduralSky.d.ts +24 -0
  529. package/lib/scene/ProceduralSky.js +40 -0
  530. package/lib/scene/ProceduralSky.js.map +1 -0
  531. package/lib/scene/RectLight.d.ts +2 -13
  532. package/lib/scene/RectLight.js +3 -21
  533. package/lib/scene/RectLight.js.map +1 -1
  534. package/lib/scene/RectLightState.d.ts +31 -0
  535. package/lib/scene/RectLightState.js +26 -0
  536. package/lib/scene/RectLightState.js.map +1 -0
  537. package/lib/scene/Scene.d.ts +15 -4
  538. package/lib/scene/Scene.js.map +1 -1
  539. package/lib/scene/SceneNode.js +7 -6
  540. package/lib/scene/SceneNode.js.map +1 -1
  541. package/lib/scene/Texture.d.ts +10 -41
  542. package/lib/scene/Texture.js +4 -33
  543. package/lib/scene/Texture.js.map +1 -1
  544. package/lib/scene/TextureState.d.ts +35 -0
  545. package/lib/scene/TextureState.js +35 -0
  546. package/lib/scene/TextureState.js.map +1 -0
  547. package/lib/scene/attributeData.d.ts +4 -0
  548. package/lib/scene/attributeData.js +10 -0
  549. package/lib/scene/attributeData.js.map +1 -0
  550. package/lib/scene/lightState.d.ts +8 -0
  551. package/lib/scene/lightState.js +2 -0
  552. package/lib/scene/lightState.js.map +1 -0
  553. package/lib/scene/openPbrSchema.d.ts +7 -12
  554. package/lib/scene/openPbrSchema.js +273 -28
  555. package/lib/scene/openPbrSchema.js.map +1 -1
  556. package/lib/scene/skyParameters.d.ts +20 -0
  557. package/lib/scene/skyParameters.js +28 -0
  558. package/lib/scene/skyParameters.js.map +1 -0
  559. package/lib/scene/textureData.d.ts +9 -0
  560. package/lib/scene/textureData.js +2 -0
  561. package/lib/scene/textureData.js.map +1 -0
  562. package/lib/scene/texturePixels.d.ts +6 -0
  563. package/lib/scene/texturePixels.js +10 -0
  564. package/lib/scene/texturePixels.js.map +1 -0
  565. package/lib/settings/display.d.ts +33 -0
  566. package/lib/settings/display.js +7 -0
  567. package/lib/settings/display.js.map +1 -1
  568. package/lib/settings/render.d.ts +36 -3
  569. package/lib/settings/render.js +4 -1
  570. package/lib/settings/render.js.map +1 -1
  571. package/lib/tinybvh/tinybvh.wasm +0 -0
  572. package/lib/util/commonGeometry.js +7 -7
  573. package/lib/util/commonGeometry.js.map +1 -1
  574. package/lib/util/fromTHREE.d.ts +4 -1
  575. package/lib/util/fromTHREE.js +20 -7
  576. package/lib/util/fromTHREE.js.map +1 -1
  577. package/lib/util/geometry.js +42 -29
  578. package/lib/util/geometry.js.map +1 -1
  579. package/lib/util/loadRGBE.js +3 -4
  580. package/lib/util/loadRGBE.js.map +1 -1
  581. package/lib/util/studioLighting.d.ts +18 -0
  582. package/lib/util/studioLighting.js +36 -0
  583. package/lib/util/studioLighting.js.map +1 -0
  584. package/lib/version.d.ts +1 -1
  585. package/lib/version.js +1 -1
  586. package/lib/version.js.map +1 -1
  587. package/llms.txt +5 -0
  588. package/package.json +33 -7
  589. package/lib/renderer/texturesFromMaterials.d.ts +0 -6
  590. package/lib/renderer/texturesFromMaterials.js.map +0 -1
@@ -0,0 +1,93 @@
1
+ import { computeGeometryBounds } from './geometryBvhBounds.js';
2
+ import { matrixStorage } from '../math/storage.js';
3
+ import { read, write } from '../math/access.js';
4
+ import { meshInstanceCount, meshInstanceTransform } from './meshInstances.js';
5
+ import { mat4, vec3 } from '../math.js';
6
+ import { resolveMaterialAlphaMode } from '../scene/MaterialState.js';
7
+ export const CAUSTIC_ROUGHNESS_MAX = 0.1;
8
+ /** Material-only classification, shared by caster collection and GPU estimators. */
9
+ export function isCausticSpecular(m) {
10
+ return m.baseWeight * (1 - m.baseMetalness) * (1 - m.transmissionWeight) <= 1e-6 &&
11
+ m.subsurfaceWeight <= 0 && m.fuzzWeight <= 0 && m.coatWeight <= 0 && m.specularRoughness <= CAUSTIC_ROUGHNESS_MAX;
12
+ }
13
+ const casterBounds = new WeakMap();
14
+ function localCasterBounds(geometry) {
15
+ const cached = casterBounds.get(geometry), positions = geometry.position.array;
16
+ if (cached && cached.version === geometry.version && cached.positions === positions)
17
+ return cached.bounds;
18
+ const value = computeGeometryBounds(geometry), bounds = [matrixStorage(value[0]), matrixStorage(value[1])];
19
+ casterBounds.set(geometry, { version: geometry.version, positions, bounds });
20
+ return bounds;
21
+ }
22
+ /** One conservative world-space sphere per smooth mesh instance. */
23
+ export function causticCasterSpheres(meshes) {
24
+ const spheres = [];
25
+ const matrix = mat4.create(), point = vec3.create();
26
+ for (const mesh of meshes) {
27
+ if (!mesh.materials.some(isCausticSpecular))
28
+ continue;
29
+ // Geometry.boundingBox is optional caller metadata and starts at zero.
30
+ // Caster collection must also work for a raw public Geometry descriptor.
31
+ const bounds = localCasterBounds(mesh.geometry), minCorner = bounds[0], maxCorner = bounds[1];
32
+ if (!Number.isFinite(minCorner[0]) || !Number.isFinite(maxCorner[0]))
33
+ continue;
34
+ let expansion = 0;
35
+ for (const material of mesh.materials)
36
+ if (isCausticSpecular(material))
37
+ expansion = Math.max(expansion, Math.abs(material.displacementBias) + (material.displacementMap ? Math.abs(material.displacementScale) : 0));
38
+ for (let instance = 0; instance < meshInstanceCount(mesh); instance++) {
39
+ const min = [Infinity, Infinity, Infinity], max = [-Infinity, -Infinity, -Infinity];
40
+ meshInstanceTransform(mesh, instance, matrix);
41
+ for (let corner = 0; corner < 8; corner++) {
42
+ for (let axis = 0; axis < 3; axis++)
43
+ write(point, axis, ((corner & (1 << axis)) ? maxCorner[axis] + expansion : minCorner[axis] - expansion));
44
+ vec3.transformMat4(point, point, matrix);
45
+ for (let axis = 0; axis < 3; axis++) {
46
+ min[axis] = Math.min(min[axis], read(point, axis));
47
+ max[axis] = Math.max(max[axis], read(point, axis));
48
+ }
49
+ }
50
+ spheres.push([(min[0] + max[0]) * .5, (min[1] + max[1]) * .5, (min[2] + max[2]) * .5, Math.hypot(max[0] - min[0], max[1] - min[1], max[2] - min[2]) * .501]);
51
+ }
52
+ }
53
+ return spheres;
54
+ }
55
+ /** Conservative sphere enclosing the caster mixture. */
56
+ export function causticCasterSphere(meshes) {
57
+ const spheres = causticCasterSpheres(meshes);
58
+ if (!spheres.length)
59
+ return [0, 0, 0, 0];
60
+ const min = [Infinity, Infinity, Infinity], max = [-Infinity, -Infinity, -Infinity];
61
+ for (const s of spheres) {
62
+ const components = [s[0], s[1], s[2]];
63
+ for (let i = 0; i < 3; i++) {
64
+ min[i] = Math.min(min[i], components[i] - s[3]);
65
+ max[i] = Math.max(max[i], components[i] + s[3]);
66
+ }
67
+ }
68
+ const center = min.map((v, i) => (v + max[i]) * .5);
69
+ let radius = 0;
70
+ for (const s of spheres)
71
+ radius = Math.max(radius, Math.hypot(s[0] - center[0], s[1] - center[1], s[2] - center[2]) + s[3]);
72
+ return [center[0], center[1], center[2], radius];
73
+ }
74
+ /** CPU reference for the solid-angle mixture, including overlapping cones. */
75
+ export function casterDirectionPdf(origin, direction, spheres, weights = []) {
76
+ let total = 0, overlaps = 0;
77
+ for (const [index, s] of spheres.entries()) {
78
+ const weight = weights[index] ?? 1;
79
+ const d = Math.hypot(s[0] - origin[0], s[1] - origin[1], s[2] - origin[2]);
80
+ const cosine = d > s[3] ? Math.sqrt(Math.max(0, 1 - (s[3] / d) ** 2)) : -1;
81
+ total += 2 * Math.PI * (1 - cosine) * weight;
82
+ if (d <= s[3] || ((s[0] - origin[0]) * direction[0] + (s[1] - origin[1]) * direction[1] + (s[2] - origin[2]) * direction[2]) / d >= cosine)
83
+ overlaps += weight;
84
+ }
85
+ return total > 0 ? overlaps / total : 0;
86
+ }
87
+ /** Stochastic smooth coverage currently disagrees with PT energy.
88
+ * Keep those scenes on PT until transport and endpoint weights are verified.
89
+ */
90
+ export function hasStochasticCausticCaster(meshes) {
91
+ return meshes.some(mesh => mesh.materials.some(m => isCausticSpecular(m) && resolveMaterialAlphaMode(m) === 'blend'));
92
+ }
93
+ //# sourceMappingURL=caustics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"caustics.js","sourceRoot":"","sources":["../../src/renderer/caustics.ts"],"names":[],"mappings":"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","sourcesContent":["import {computeGeometryBounds} from './geometryBvhBounds.js';\nimport type Geometry from '../scene/Geometry.js';\nimport {matrixStorage} from '../math/storage.js';\nimport {read,write} from '../math/access.js';\nimport type Mesh from '../scene/MeshState.js';\nimport {meshInstanceCount,meshInstanceTransform} from './meshInstances.js';\nimport {mat4,vec3} from '../math.js';\nimport type OpenPBRMaterial from '../scene/MaterialState.js';\nimport {resolveMaterialAlphaMode} from '../scene/MaterialState.js';\n\nexport const CAUSTIC_ROUGHNESS_MAX = 0.1;\n/** Material-only classification, shared by caster collection and GPU estimators. */\nexport function isCausticSpecular(m: Pick<OpenPBRMaterial, 'baseWeight' | 'baseMetalness' | 'transmissionWeight' | 'subsurfaceWeight' | 'fuzzWeight' | 'coatWeight' | 'specularRoughness'>) {\n return m.baseWeight * (1 - m.baseMetalness) * (1 - m.transmissionWeight) <= 1e-6 &&\n m.subsurfaceWeight <= 0 && m.fuzzWeight <= 0 && m.coatWeight <= 0 && m.specularRoughness <= CAUSTIC_ROUGHNESS_MAX;\n}\n\nexport type CasterSphere = [number,number,number,number];\nconst casterBounds=new WeakMap<Geometry,{version:number;positions:Float32Array;bounds:[Float64Array,Float64Array]}>();\nfunction localCasterBounds(geometry:Geometry){\n const cached=casterBounds.get(geometry),positions=geometry.position.array;\n if(cached&&cached.version===geometry.version&&cached.positions===positions)return cached.bounds;\n const value=computeGeometryBounds(geometry),bounds:[Float64Array,Float64Array]=[matrixStorage(value[0]),matrixStorage(value[1])];\n casterBounds.set(geometry,{version:geometry.version,positions,bounds});return bounds;\n}\n/** One conservative world-space sphere per smooth mesh instance. */\nexport function causticCasterSpheres(meshes: readonly Mesh[]): CasterSphere[] {\n const spheres:CasterSphere[]=[];\n const matrix=mat4.create(),point=vec3.create();\n for(const mesh of meshes) {\n if(!mesh.materials.some(isCausticSpecular))continue;\n // Geometry.boundingBox is optional caller metadata and starts at zero.\n // Caster collection must also work for a raw public Geometry descriptor.\n const bounds=localCasterBounds(mesh.geometry),minCorner=bounds[0],maxCorner=bounds[1];\n if(!Number.isFinite(minCorner[0])||!Number.isFinite(maxCorner[0]))continue;\n let expansion=0;\n for(const material of mesh.materials)if(isCausticSpecular(material))expansion=Math.max(expansion,\n Math.abs(material.displacementBias)+(material.displacementMap?Math.abs(material.displacementScale):0));\n for(let instance=0;instance<meshInstanceCount(mesh);instance++) {\n const min=[Infinity,Infinity,Infinity],max=[-Infinity,-Infinity,-Infinity];\n meshInstanceTransform(mesh,instance,matrix);\n for(let corner=0;corner<8;corner++) {\n for(let axis=0;axis<3;axis++)write(point,axis,((corner&(1<<axis))?maxCorner[axis]+expansion:minCorner[axis]-expansion));\n vec3.transformMat4(point,point,matrix);\n for(let axis=0;axis<3;axis++){min[axis]=Math.min(min[axis],read(point,axis));max[axis]=Math.max(max[axis],read(point,axis));}\n }\n spheres.push([(min[0]+max[0])*.5,(min[1]+max[1])*.5,(min[2]+max[2])*.5,Math.hypot(max[0]-min[0],max[1]-min[1],max[2]-min[2])*.501]);\n }\n }\n return spheres;\n}\n/** Conservative sphere enclosing the caster mixture. */\nexport function causticCasterSphere(meshes:readonly Mesh[]):CasterSphere {\n const spheres=causticCasterSpheres(meshes);if(!spheres.length)return [0,0,0,0];\n const min=[Infinity,Infinity,Infinity],max=[-Infinity,-Infinity,-Infinity];\n for(const s of spheres){const components:number[]=[s[0],s[1],s[2]];for(let i=0;i<3;i++){min[i]=Math.min(min[i],components[i]-s[3]);max[i]=Math.max(max[i],components[i]+s[3]);}}\n const center=min.map((v,i)=>(v+max[i])*.5);\n let radius=0;for(const s of spheres)radius=Math.max(radius,Math.hypot(s[0]-center[0],s[1]-center[1],s[2]-center[2])+s[3]);\n return [center[0],center[1],center[2],radius];\n}\n/** CPU reference for the solid-angle mixture, including overlapping cones. */\nexport function casterDirectionPdf(origin:readonly number[],direction:readonly number[],spheres:readonly CasterSphere[],weights:readonly number[]=[]) {\n let total=0,overlaps=0;\n for(const [index,s] of spheres.entries()){const weight=weights[index]??1;const d=Math.hypot(s[0]-origin[0],s[1]-origin[1],s[2]-origin[2]);\n const cosine=d>s[3]?Math.sqrt(Math.max(0,1-(s[3]/d)**2)):-1;\n total+=2*Math.PI*(1-cosine)*weight;\n if(d<=s[3]||((s[0]-origin[0])*direction[0]+(s[1]-origin[1])*direction[1]+(s[2]-origin[2])*direction[2])/d>=cosine)overlaps+=weight;\n }\n return total>0?overlaps/total:0;\n}\n\n/** Stochastic smooth coverage currently disagrees with PT energy.\n * Keep those scenes on PT until transport and endpoint weights are verified.\n */\nexport function hasStochasticCausticCaster(meshes:readonly Mesh[]){\n return meshes.some(mesh=>mesh.materials.some(m=>isCausticSpecular(m)&&resolveMaterialAlphaMode(m)==='blend'));\n}\n"]}
@@ -1,3 +1,5 @@
1
+ import MeshState from '../scene/MeshState.js';
2
+ import MaterialState from '../scene/MaterialState.js';
1
3
  import { createCanvas } from '../util/canvas.js';
2
4
  import Geometry from '../scene/Geometry.js';
3
5
  import InstancedMesh from '../scene/InstancedMesh.js';
@@ -53,6 +55,8 @@ export class CommittedScene {
53
55
  cloned = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value));
54
56
  this.copies.set(object, cloned);
55
57
  }
58
+ if (value instanceof MeshState || value instanceof MaterialState)
59
+ cloned.aovId = value.aovId;
56
60
  if (this.copying.has(object))
57
61
  return cloned;
58
62
  this.copying.add(object);
@@ -1 +1 @@
1
- {"version":3,"file":"committedScene.js","sourceRoot":"","sources":["../../src/renderer/committedScene.ts"],"names":[],"mappings":"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","sourcesContent":["import {createCanvas} from '../util/canvas.js';\nimport Geometry from '../scene/Geometry.js';\nimport InstancedMesh from '../scene/InstancedMesh.js';\nimport Texture from '../scene/Texture.js';\nimport { copyGeometryChangeState } from '../scene/geometryChanges.js';\nimport { getGeometryBvh, setGeometryBvh } from './geometryBvh.js';\nimport type { Scene } from '../scene/Scene.js';\nimport type { SceneChanges } from './sceneChangeDetector.js';\n\n/** Stable engine-owned mirrors isolate deferred GPU uploads from external edits. */\nexport class CommittedScene {\n private readonly copies = new WeakMap<object, any>();\n private readonly geometryVersions = new WeakMap<Geometry, number>();\n private readonly instanceVersions = new WeakMap<InstancedMesh, {transformsVersion: number; transforms: Float32Array; colorsVersion: number; colors?: Float32Array}>();\n private value?: Scene;\n private readonly copying = new WeakSet<object>();\n\n private copy<T>(value: T, retainGeometryBvh = false): T {\n if (!value || typeof value !== 'object') return value;\n const object = value as object;\n if ((typeof HTMLImageElement !== 'undefined' && object instanceof HTMLImageElement) || (typeof HTMLCanvasElement !== 'undefined' && object instanceof HTMLCanvasElement) ||\n (typeof OffscreenCanvas !== 'undefined' && object instanceof OffscreenCanvas) ||\n (typeof ImageBitmap !== 'undefined' && object instanceof ImageBitmap)) {\n const source = object as HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap;\n let canvas = this.copies.get(object) as HTMLCanvasElement | OffscreenCanvas | undefined;\n if (!canvas) { canvas = createCanvas(source.width, source.height); this.copies.set(object, canvas); }\n canvas.width = source.width; canvas.height = source.height;\n const context = canvas.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null;\n if (!context) throw new Error('Texture snapshot context is not available.');\n context.drawImage(source, 0, 0);\n return canvas as T;\n }\n if (typeof Node !== 'undefined' && object instanceof Node) return value;\n if (value instanceof Geometry && this.geometryVersions.get(value) === value.version) return this.copies.get(value);\n if (ArrayBuffer.isView(value)) {\n const previous = this.copies.get(object);\n if (previous?.constructor === value.constructor && previous.length === (value as any).length) {\n previous.set(value); return previous;\n }\n const cloned = (value as any).slice(); this.copies.set(object, cloned); return cloned;\n }\n if (value instanceof ArrayBuffer) return value.slice(0) as T;\n let cloned = this.copies.get(object);\n if (!cloned) { cloned = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value)); this.copies.set(object, cloned); }\n if (this.copying.has(object)) return cloned;\n this.copying.add(object);\n try {\n for (const key of Object.keys(value)) {\n if (value instanceof InstancedMesh && (key === 'transforms' || key === 'colors')) {\n const previous = this.instanceVersions.get(value);\n const version = key === 'transforms' ? value.transformsVersion : value.colorsVersion;\n const priorVersion = key === 'transforms' ? previous?.transformsVersion : previous?.colorsVersion;\n const array = value[key];\n if (!previous || priorVersion !== version || previous[key] !== array) {\n // Each batch owns its snapshot even when callers share source storage.\n if (!array) cloned[key] = undefined;\n else if (previous?.[key] === array && cloned[key]?.length === array.length) cloned[key].set(array);\n else cloned[key] = array.slice();\n }\n } else cloned[key] = value instanceof Texture && key === 'source' ? value.source : this.copy((value as any)[key], retainGeometryBvh);\n }\n } finally { this.copying.delete(object); }\n if (Array.isArray(value)) cloned.length = value.length;\n if (value instanceof InstancedMesh) this.instanceVersions.set(value, {\n transformsVersion: value.transformsVersion, transforms: value.transforms,\n colorsVersion: value.colorsVersion, colors: value.colors\n });\n if (value instanceof Geometry) {\n this.geometryVersions.set(value, value.version);\n // The renderer builds/refits BVHs on the committed geometry. A source\n // without a precomputed BVH must not erase that tree on every pose edit.\n // Full scene replacements cannot rely on an incremental renderer refit.\n const sourceBvh = getGeometryBvh(value);\n if (sourceBvh || !retainGeometryBvh) setGeometryBvh(cloned, sourceBvh);\n copyGeometryChangeState(value, cloned);\n }\n return cloned;\n }\n\n mirror<T extends object>(source: T): T { return this.copies.get(source); }\n\n capture(scene: Scene, changes: SceneChanges): Scene {\n if (!this.value || changes.meshes === 'full') this.value = { meshes: this.copy(scene.meshes), lights: this.copy(scene.lights), background: this.copy(scene.background) };\n else {\n for (const mesh of changes.transforms) {\n this.copy(mesh.transform);\n if (mesh instanceof InstancedMesh) this.copy(mesh, true);\n }\n for (const mesh of changes.colors) this.copy(mesh, true);\n for (const geometry of changes.geometries) this.copy(geometry, true);\n for (const material of changes.materials) this.copy(material);\n if (changes.lights) this.value.lights = this.copy(scene.lights);\n if (changes.background) this.value.background = this.copy(scene.background);\n }\n return this.value;\n }\n}\n"]}
1
+ {"version":3,"file":"committedScene.js","sourceRoot":"","sources":["../../src/renderer/committedScene.ts"],"names":[],"mappings":"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","sourcesContent":["import MeshState from '../scene/MeshState.js';\nimport MaterialState from '../scene/MaterialState.js';\nimport {createCanvas} from '../util/canvas.js';\nimport Geometry from '../scene/Geometry.js';\nimport InstancedMesh from '../scene/InstancedMesh.js';\nimport Texture from '../scene/Texture.js';\nimport { copyGeometryChangeState } from '../scene/geometryChanges.js';\nimport { getGeometryBvh, setGeometryBvh } from './geometryBvh.js';\nimport type { Scene } from '../scene/Scene.js';\nimport type { SceneChanges } from './sceneChangeDetector.js';\n\n/** Stable engine-owned mirrors isolate deferred GPU uploads from external edits. */\nexport class CommittedScene {\n private readonly copies = new WeakMap<object, any>();\n private readonly geometryVersions = new WeakMap<Geometry, number>();\n private readonly instanceVersions = new WeakMap<InstancedMesh, {transformsVersion: number; transforms: Float32Array; colorsVersion: number; colors?: Float32Array}>();\n private value?: Scene;\n private readonly copying = new WeakSet<object>();\n\n private copy<T>(value: T, retainGeometryBvh = false): T {\n if (!value || typeof value !== 'object') return value;\n const object = value as object;\n if ((typeof HTMLImageElement !== 'undefined' && object instanceof HTMLImageElement) || (typeof HTMLCanvasElement !== 'undefined' && object instanceof HTMLCanvasElement) ||\n (typeof OffscreenCanvas !== 'undefined' && object instanceof OffscreenCanvas) ||\n (typeof ImageBitmap !== 'undefined' && object instanceof ImageBitmap)) {\n const source = object as HTMLImageElement | HTMLCanvasElement | OffscreenCanvas | ImageBitmap;\n let canvas = this.copies.get(object) as HTMLCanvasElement | OffscreenCanvas | undefined;\n if (!canvas) { canvas = createCanvas(source.width, source.height); this.copies.set(object, canvas); }\n canvas.width = source.width; canvas.height = source.height;\n const context = canvas.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D | null;\n if (!context) throw new Error('Texture snapshot context is not available.');\n context.drawImage(source, 0, 0);\n return canvas as T;\n }\n if (typeof Node !== 'undefined' && object instanceof Node) return value;\n if (value instanceof Geometry && this.geometryVersions.get(value) === value.version) return this.copies.get(value);\n if (ArrayBuffer.isView(value)) {\n const previous = this.copies.get(object);\n if (previous?.constructor === value.constructor && previous.length === (value as any).length) {\n previous.set(value); return previous;\n }\n const cloned = (value as any).slice(); this.copies.set(object, cloned); return cloned;\n }\n if (value instanceof ArrayBuffer) return value.slice(0) as T;\n let cloned = this.copies.get(object);\n if (!cloned) { cloned = Array.isArray(value) ? [] : Object.create(Object.getPrototypeOf(value)); this.copies.set(object, cloned); }\n if (value instanceof MeshState || value instanceof MaterialState) cloned.aovId = value.aovId;\n if (this.copying.has(object)) return cloned;\n this.copying.add(object);\n try {\n for (const key of Object.keys(value)) {\n if (value instanceof InstancedMesh && (key === 'transforms' || key === 'colors')) {\n const previous = this.instanceVersions.get(value);\n const version = key === 'transforms' ? value.transformsVersion : value.colorsVersion;\n const priorVersion = key === 'transforms' ? previous?.transformsVersion : previous?.colorsVersion;\n const array = value[key];\n if (!previous || priorVersion !== version || previous[key] !== array) {\n // Each batch owns its snapshot even when callers share source storage.\n if (!array) cloned[key] = undefined;\n else if (previous?.[key] === array && cloned[key]?.length === array.length) cloned[key].set(array);\n else cloned[key] = array.slice();\n }\n } else cloned[key] = value instanceof Texture && key === 'source' ? value.source : this.copy((value as any)[key], retainGeometryBvh);\n }\n } finally { this.copying.delete(object); }\n if (Array.isArray(value)) cloned.length = value.length;\n if (value instanceof InstancedMesh) this.instanceVersions.set(value, {\n transformsVersion: value.transformsVersion, transforms: value.transforms,\n colorsVersion: value.colorsVersion, colors: value.colors\n });\n if (value instanceof Geometry) {\n this.geometryVersions.set(value, value.version);\n // The renderer builds/refits BVHs on the committed geometry. A source\n // without a precomputed BVH must not erase that tree on every pose edit.\n // Full scene replacements cannot rely on an incremental renderer refit.\n const sourceBvh = getGeometryBvh(value);\n if (sourceBvh || !retainGeometryBvh) setGeometryBvh(cloned, sourceBvh);\n copyGeometryChangeState(value, cloned);\n }\n return cloned;\n }\n\n mirror<T extends object>(source: T): T { return this.copies.get(source); }\n\n capture(scene: Scene, changes: SceneChanges): Scene {\n if (!this.value || changes.meshes === 'full') this.value = { meshes: this.copy(scene.meshes), lights: this.copy(scene.lights), background: this.copy(scene.background) };\n else {\n for (const mesh of changes.transforms) {\n this.copy(mesh.transform);\n if (mesh instanceof InstancedMesh) this.copy(mesh, true);\n }\n for (const mesh of changes.colors) this.copy(mesh, true);\n for (const geometry of changes.geometries) this.copy(geometry, true);\n for (const material of changes.materials) this.copy(material);\n if (changes.lights) this.value.lights = this.copy(scene.lights);\n if (changes.background) this.value.background = this.copy(scene.background);\n }\n return this.value;\n }\n}\n"]}
@@ -1,6 +1,5 @@
1
1
  import type { Denoiser } from '../Render.js';
2
2
  import type { JNLMDenoiser } from './jnlm.js';
3
- import type { OIDNDenoiser } from './oidnNetwork.js';
4
3
  export interface OIDNWebGPUData {
5
4
  data: GPUBuffer | GPUTexture;
6
5
  width: number;
@@ -16,9 +15,9 @@ export interface OIDNWeb {
16
15
  albedo: OIDNWeb;
17
16
  normal: OIDNWeb;
18
17
  };
19
- /** Optional serializable execution details exposed by native oidn-web. */
18
+ /** Optional serializable execution details exposed by native oidn-webgpu. */
20
19
  getRuntimeInfo?: () => unknown;
21
- /** Optional shape preparation supported by newer oidn-web runtimes. */
20
+ /** Optional shape preparation supported by newer oidn-webgpu runtimes. */
22
21
  prepareForImage?: (width: number, height: number, options?: {
23
22
  tileOverlap?: number;
24
23
  }) => Promise<void>;
@@ -54,12 +53,5 @@ export type DenoiserHandle = {
54
53
  } | {
55
54
  kind: 'custom';
56
55
  denoiser: Denoiser;
57
- };
58
- /** Only these handles are owned and released by the engine. */
59
- export type OwnedDenoiser = {
60
- kind: 'jnlm';
61
- denoiser: JNLMDenoiser;
62
- } | {
63
- kind: 'oidn';
64
- denoiser: OIDNDenoiser;
56
+ aovs?: readonly import('./aov.js').AovKind[];
65
57
  };
@@ -1 +1 @@
1
- {"version":3,"file":"denoiser.js","sourceRoot":"","sources":["../../src/renderer/denoiser.ts"],"names":[],"mappings":"","sourcesContent":["import type {Denoiser} from '../Render.js';\nimport type {JNLMDenoiser} from './jnlm.js';\nimport type {OIDNDenoiser} from './oidnNetwork.js';\n\nexport interface OIDNWebGPUData {\n data: GPUBuffer | GPUTexture;\n width: number;\n height: number;\n}\nexport interface OIDNWebGPUOutputData {\n data: GPUBuffer;\n width: number;\n height: number;\n}\n\nexport interface OIDNWeb {\n auxiliaryDenoisers?: {\n albedo: OIDNWeb;\n normal: OIDNWeb;\n };\n /** Optional serializable execution details exposed by native oidn-web. */\n getRuntimeInfo?: () => unknown;\n /** Optional shape preparation supported by newer oidn-web runtimes. */\n prepareForImage?: (\n width: number,\n height: number,\n options?: { tileOverlap?: number }\n ) => Promise<void>;\n tileExecute: (opts: {\n color: OIDNWebGPUData;\n albedo?: OIDNWebGPUData;\n normal?: OIDNWebGPUData;\n denoiseAlpha?: boolean;\n wholeImage?: boolean;\n tileOverlap?: number;\n scheduling?: 'animation-frame' | 'event-loop';\n done: (outputData: {\n data: GPUBuffer;\n width: number;\n height: number;\n }) => void;\n error?: (reason: unknown) => void;\n progress?: (\n outputData: OIDNWebGPUOutputData,\n tileData: OIDNWebGPUOutputData | undefined,\n tile: { x: number; y: number; width: number; height: number },\n currentIdx: number,\n totalIdx: number\n ) => void;\n }) => () => void;\n}\n\n/** Explicit private dispatch; built-ins do not implement the public custom interface. */\nexport type DenoiserHandle =\n | {kind: 'jnlm'; denoiser: JNLMDenoiser}\n | {kind: 'oidn'; denoiser: OIDNWeb}\n | {kind: 'custom'; denoiser: Denoiser};\n/** Only these handles are owned and released by the engine. */\nexport type OwnedDenoiser =\n | {kind: 'jnlm'; denoiser: JNLMDenoiser}\n | {kind: 'oidn'; denoiser: OIDNDenoiser};\n"]}
1
+ {"version":3,"file":"denoiser.js","sourceRoot":"","sources":["../../src/renderer/denoiser.ts"],"names":[],"mappings":"","sourcesContent":["import type {Denoiser} from '../Render.js';\nimport type {JNLMDenoiser} from './jnlm.js';\n\nexport interface OIDNWebGPUData {\n data: GPUBuffer | GPUTexture;\n width: number;\n height: number;\n}\nexport interface OIDNWebGPUOutputData {\n data: GPUBuffer;\n width: number;\n height: number;\n}\n\nexport interface OIDNWeb {\n auxiliaryDenoisers?: {\n albedo: OIDNWeb;\n normal: OIDNWeb;\n };\n /** Optional serializable execution details exposed by native oidn-webgpu. */\n getRuntimeInfo?: () => unknown;\n /** Optional shape preparation supported by newer oidn-webgpu runtimes. */\n prepareForImage?: (\n width: number,\n height: number,\n options?: { tileOverlap?: number }\n ) => Promise<void>;\n tileExecute: (opts: {\n color: OIDNWebGPUData;\n albedo?: OIDNWebGPUData;\n normal?: OIDNWebGPUData;\n denoiseAlpha?: boolean;\n wholeImage?: boolean;\n tileOverlap?: number;\n scheduling?: 'animation-frame' | 'event-loop';\n done: (outputData: {\n data: GPUBuffer;\n width: number;\n height: number;\n }) => void;\n error?: (reason: unknown) => void;\n progress?: (\n outputData: OIDNWebGPUOutputData,\n tileData: OIDNWebGPUOutputData | undefined,\n tile: { x: number; y: number; width: number; height: number },\n currentIdx: number,\n totalIdx: number\n ) => void;\n }) => () => void;\n}\n\n/** Explicit private dispatch; built-ins do not implement the public custom interface. */\nexport type DenoiserHandle =\n | {kind: 'jnlm'; denoiser: JNLMDenoiser}\n | {kind: 'oidn'; denoiser: OIDNWeb}\n | {kind: 'custom'; denoiser: Denoiser; aovs?: readonly import('./aov.js').AovKind[]};\n"]}
@@ -9,6 +9,9 @@ export function packDepthSampleArea(area, aspect) {
9
9
  return new Float32Array([area.x, 1 - area.y, area.size / aspect, area.size]);
10
10
  }
11
11
  export function unpackDepthSamples(rgba) {
12
- return Float32Array.from({ length: DEPTH_SAMPLE_COUNT }, (_, i) => rgba[i * 4]);
12
+ const result = new Float32Array(DEPTH_SAMPLE_COUNT);
13
+ for (let i = 0; i < result.length; i++)
14
+ result[i] = rgba[i * 4];
15
+ return result;
13
16
  }
14
17
  //# sourceMappingURL=depthQuery.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"depthQuery.js","sourceRoot":"","sources":["../../src/renderer/depthQuery.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AACnC,MAAM,CAAC,MAAM,kBAAkB,GAAG,iBAAiB,IAAI,CAAC,CAAC;AAEzD,+EAA+E;AAC/E,MAAM,UAAU,mBAAmB,CAAC,IAAqB,EAAE,MAAc;IACvE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC7D,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,UAAU,CAAC,+FAA+F,CAAC,CAAC;IACxH,CAAC;IACD,OAAO,IAAI,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAkB;IACnD,OAAO,YAAY,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAClF,CAAC","sourcesContent":["/** A square depth sampling area in viewport coordinates. */\nexport interface DepthSampleArea {\n /** Horizontal center, 0..1 from the left. Required. */\n x: number;\n /** Vertical center, 0..1 from the top. Required. */\n y: number;\n /** Half height as a fraction of viewport height; 0 samples one point. Required. */\n size: number;\n}\n\nexport const DEPTH_SAMPLE_GRID = 7;\nexport const DEPTH_SAMPLE_COUNT = DEPTH_SAMPLE_GRID ** 2;\n\n/** Bottom-left UV center and half extent, matching both camera-ray shaders. */\nexport function packDepthSampleArea(area: DepthSampleArea, aspect: number) {\n if (![area.x, area.y, area.size, aspect].every(Number.isFinite) ||\n area.x < 0 || area.x > 1 || area.y < 0 || area.y > 1 || area.size < 0 || aspect <= 0) {\n throw new RangeError('Depth sampling requires a viewport center in 0..1, a non-negative size and a positive aspect.');\n }\n return new Float32Array([area.x, 1 - area.y, area.size / aspect, area.size]);\n}\n\nexport function unpackDepthSamples(rgba: Float32Array) {\n return Float32Array.from({ length: DEPTH_SAMPLE_COUNT }, (_, i) => rgba[i * 4]);\n}\n"]}
1
+ {"version":3,"file":"depthQuery.js","sourceRoot":"","sources":["../../src/renderer/depthQuery.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC;AACnC,MAAM,CAAC,MAAM,kBAAkB,GAAG,iBAAiB,IAAI,CAAC,CAAC;AAEzD,+EAA+E;AAC/E,MAAM,UAAU,mBAAmB,CAAC,IAAqB,EAAE,MAAc;IACvE,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC;QAC7D,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,GAAG,CAAC,IAAI,MAAM,IAAI,CAAC,EAAE,CAAC;QACvF,MAAM,IAAI,UAAU,CAAC,+FAA+F,CAAC,CAAC;IACxH,CAAC;IACD,OAAO,IAAI,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC,IAAI,GAAG,MAAM,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,IAAkB;IACnD,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,kBAAkB,CAAC,CAAC;IACpD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,OAAO,MAAM,CAAC;AAChB,CAAC","sourcesContent":["/** A square depth sampling area in viewport coordinates. */\nexport interface DepthSampleArea {\n /** Horizontal center, 0..1 from the left. Required. */\n x: number;\n /** Vertical center, 0..1 from the top. Required. */\n y: number;\n /** Half height as a fraction of viewport height; 0 samples one point. Required. */\n size: number;\n}\n\nexport const DEPTH_SAMPLE_GRID = 7;\nexport const DEPTH_SAMPLE_COUNT = DEPTH_SAMPLE_GRID ** 2;\n\n/** Bottom-left UV center and half extent, matching both camera-ray shaders. */\nexport function packDepthSampleArea(area: DepthSampleArea, aspect: number) {\n if (![area.x, area.y, area.size, aspect].every(Number.isFinite) ||\n area.x < 0 || area.x > 1 || area.y < 0 || area.y > 1 || area.size < 0 || aspect <= 0) {\n throw new RangeError('Depth sampling requires a viewport center in 0..1, a non-negative size and a positive aspect.');\n }\n return new Float32Array([area.x, 1 - area.y, area.size / aspect, area.size]);\n}\n\nexport function unpackDepthSamples(rgba: Float32Array) {\n const result = new Float32Array(DEPTH_SAMPLE_COUNT);\n for (let i = 0; i < result.length; i++) result[i] = rgba[i * 4];\n return result;\n}\n"]}
@@ -0,0 +1,11 @@
1
+ import Geometry from '../scene/Geometry.js';
2
+ import MaterialState from '../scene/MaterialState.js';
3
+ import { vec2, vec3 } from '../math.js';
4
+ export declare function displacementBaseGeometry(geometry: Geometry, bias: number): Geometry;
5
+ export declare function computeDisplacementMinmax(w: number, sourceChannels: number, readHeight: (index: number) => number): Uint8Array<ArrayBufferLike>[];
6
+ export declare function sphericalProjectionTriangle<T0 extends vec3.Vec3Array, T1 extends vec3.Vec3Array, T2 extends vec3.Vec3Array, T3 extends vec2.Vec2Array, T4 extends vec2.Vec2Array, T5 extends vec2.Vec2Array>(na: T0, nb: T1, nc: T2, uvA: T3, uvB: T4, uvC: T5): boolean;
7
+ export declare function triplanarProjectionTriangle<T0 extends vec3.Vec3Array, T1 extends vec3.Vec3Array, T2 extends vec3.Vec3Array, T3 extends vec3.Vec3Array, T4 extends vec3.Vec3Array, T5 extends vec3.Vec3Array, T6 extends vec2.Vec2Array, T7 extends vec2.Vec2Array, T8 extends vec2.Vec2Array>(a: T0, b: T1, c: T2, na: T3, nb: T4, nc: T5, uvA: T6, uvB: T7, uvC: T8): void;
8
+ export declare function conservativeTrianglesDisplacementRange(triangleCount: number): Float32Array | undefined;
9
+ export declare function computeTrianglesDisplacementRange(geometry: Geometry, minmaxData: Uint8Array[], width: number, isFlipY: boolean, material: MaterialState): Float32Array<ArrayBufferLike>;
10
+ /** Conservative source-order AABBs for the actual displacement prism. */
11
+ export declare function displacementPrismAabbs(geometry: Geometry, displacementScale: number): Float32Array;
@@ -0,0 +1,351 @@
1
+ import Geometry, { Attribute } from '../scene/Geometry.js';
2
+ import { vec2, vec3 } from '../math.js';
3
+ import { read, write } from '../math/access.js';
4
+ import { attributeValue, attributeLength } from '../scene/attributeData.js';
5
+ // Use the same normal offset for software BLASes and native procedural AABBs.
6
+ export function displacementBaseGeometry(geometry, bias) {
7
+ if (bias === 0)
8
+ return geometry;
9
+ const positions = geometry.position.array.slice();
10
+ const normals = geometry.normal.array;
11
+ for (let vertex = 0; vertex < geometry.vertexCount; vertex++) {
12
+ const p = vertex * geometry.position.itemSize, n = vertex * geometry.normal.itemSize;
13
+ const length = Math.hypot(normals[n], normals[n + 1], normals[n + 2]);
14
+ if (length > 0) {
15
+ for (let axis = 0; axis < 3; axis++)
16
+ positions[p + axis] += normals[n + axis] / length * bias;
17
+ }
18
+ }
19
+ const result = new Geometry(geometry);
20
+ result.position = new Attribute(positions, geometry.position.itemSize);
21
+ return result;
22
+ }
23
+ // Shared CPU displacement math. Pixel acquisition and caching belong to adapters.
24
+ export function computeDisplacementMinmax(w, sourceChannels, readHeight) {
25
+ const minmaxData = [];
26
+ const maxMipLevel = Math.log2(w);
27
+ let mipmapSize = w;
28
+ for (let lod = 0; lod <= maxMipLevel; lod++) {
29
+ const prevMinmaxData = minmaxData[Math.max(0, lod - 1)];
30
+ const minmax = new Uint8Array(mipmapSize * mipmapSize * 2);
31
+ minmaxData.push(minmax);
32
+ const channels = lod === 0 ? sourceChannels : 2;
33
+ for (let y = 0; y < mipmapSize; y++) {
34
+ for (let x = 0; x < mipmapSize; x++) {
35
+ const yx = y * mipmapSize + x;
36
+ const idx = yx * channels;
37
+ let min = 0;
38
+ let max = 0;
39
+ if (lod == 0) {
40
+ min = readHeight(idx);
41
+ max = min;
42
+ if (y < mipmapSize - 1 && x < mipmapSize - 1) {
43
+ const h = readHeight(idx + (mipmapSize + 1) * channels);
44
+ min = Math.min(min, h);
45
+ max = Math.max(max, h);
46
+ }
47
+ if (y < mipmapSize - 1) {
48
+ const h = readHeight(idx + mipmapSize * channels);
49
+ min = Math.min(min, h);
50
+ max = Math.max(max, h);
51
+ }
52
+ if (x < mipmapSize - 1) {
53
+ const h = readHeight(idx + channels);
54
+ min = Math.min(min, h);
55
+ max = Math.max(max, h);
56
+ }
57
+ }
58
+ else {
59
+ const x2 = x * 2;
60
+ const y2 = y * 2;
61
+ const prevMipmapSize = mipmapSize * 2;
62
+ const idx2 = (y2 * prevMipmapSize + x2) * channels;
63
+ const idx2_0 = idx2;
64
+ const idx2_1 = idx2 + channels;
65
+ const idx2_2 = idx2 + prevMipmapSize * channels;
66
+ const idx2_3 = idx2 + prevMipmapSize * channels + channels;
67
+ min = Math.min(prevMinmaxData[idx2_0], prevMinmaxData[idx2_1], prevMinmaxData[idx2_2], prevMinmaxData[idx2_3]);
68
+ max = Math.max(prevMinmaxData[idx2_0 + 1], prevMinmaxData[idx2_1 + 1], prevMinmaxData[idx2_2 + 1], prevMinmaxData[idx2_3 + 1]);
69
+ }
70
+ minmax[yx * 2] = min;
71
+ minmax[yx * 2 + 1] = max;
72
+ }
73
+ }
74
+ mipmapSize = mipmapSize / 2;
75
+ }
76
+ return minmaxData;
77
+ }
78
+ function sphericalProjection(n, uv) {
79
+ const theta = Math.atan2(read(n, 0), read(n, 2)) / (2.0 * Math.PI) + 0.5;
80
+ const phi = Math.acos(read(n, 1)) / Math.PI;
81
+ vec2.set(uv, theta, 1.0 - phi);
82
+ }
83
+ export function sphericalProjectionTriangle(na, nb, nc, uvA, uvB, uvC) {
84
+ sphericalProjection(na, uvA);
85
+ sphericalProjection(nb, uvB);
86
+ sphericalProjection(nc, uvC);
87
+ let onSeam = false;
88
+ for (let i = 0; i < 2; i++) {
89
+ if (Math.abs(read(uvA, i) - read(uvB, i)) > 0.5 ||
90
+ Math.abs(read(uvA, i) - read(uvC, i)) > 0.5 ||
91
+ Math.abs(read(uvB, i) - read(uvC, i)) > 0.5) {
92
+ const maxU = Math.max(read(uvA, i), read(uvB, i), read(uvC, i));
93
+ if (maxU - read(uvA, i) > 0.5) {
94
+ write(uvA, i, read(uvA, i) + 1.0);
95
+ onSeam = true;
96
+ }
97
+ if (maxU - read(uvB, i) > 0.5) {
98
+ write(uvB, i, read(uvB, i) + 1.0);
99
+ onSeam = true;
100
+ }
101
+ if (maxU - read(uvC, i) > 0.5) {
102
+ write(uvC, i, read(uvC, i) + 1.0);
103
+ onSeam = true;
104
+ }
105
+ }
106
+ }
107
+ return onSeam;
108
+ }
109
+ function getMaxAxisIndex(n) {
110
+ const x = Math.abs(read(n, 0));
111
+ const y = Math.abs(read(n, 1));
112
+ const z = Math.abs(read(n, 2));
113
+ return x > y && x > z ? 0 : y > z ? 1 : 2;
114
+ }
115
+ export function triplanarProjectionTriangle(a, b, c, na, nb, nc, uvA, uvB, uvC) {
116
+ const tmpMaxX = Math.max(Math.abs(read(na, 0)), Math.abs(read(nb, 0)), Math.abs(read(nc, 0)));
117
+ const tmpMaxY = Math.max(Math.abs(read(na, 1)), Math.abs(read(nb, 1)), Math.abs(read(nc, 1)));
118
+ const tmpMaxZ = Math.max(Math.abs(read(na, 2)), Math.abs(read(nb, 2)), Math.abs(read(nc, 2)));
119
+ if (tmpMaxX > tmpMaxY && tmpMaxX > tmpMaxZ) {
120
+ // yz
121
+ vec2.set(uvA, read(a, 1), read(a, 2));
122
+ vec2.set(uvB, read(b, 1), read(b, 2));
123
+ vec2.set(uvC, read(c, 1), read(c, 2));
124
+ }
125
+ else if (tmpMaxY > tmpMaxX && tmpMaxY > tmpMaxZ) {
126
+ // xz
127
+ vec2.set(uvA, read(a, 0), read(a, 2));
128
+ vec2.set(uvB, read(b, 0), read(b, 2));
129
+ vec2.set(uvC, read(c, 0), read(c, 2));
130
+ }
131
+ else {
132
+ // xy
133
+ vec2.set(uvA, read(a, 0), read(a, 1));
134
+ vec2.set(uvB, read(b, 0), read(b, 1));
135
+ vec2.set(uvC, read(c, 0), read(c, 1));
136
+ }
137
+ }
138
+ function findRoots(triAabbMinP, triAabbMaxP, maxDepth, roots) {
139
+ let d = vec2.sub(vec2.create(), triAabbMaxP, triAabbMinP);
140
+ let size = Math.max(d[0], d[1]);
141
+ let startMipLevel = maxDepth - Math.floor(Math.log2(Math.floor(1.0 / size))) - 1;
142
+ if (!isFinite(startMipLevel)) {
143
+ startMipLevel = maxDepth;
144
+ }
145
+ startMipLevel = Math.max(startMipLevel, 0);
146
+ let rootCount = 0;
147
+ while (true) {
148
+ const mipSize = Math.pow(2.0, maxDepth - startMipLevel);
149
+ const minTexelX = Math.floor(mipSize * read(triAabbMinP, 0));
150
+ const minTexelY = Math.floor(mipSize * read(triAabbMinP, 1));
151
+ const maxTexelX = Math.floor(mipSize * read(triAabbMaxP, 0));
152
+ const maxTexelY = Math.floor(mipSize * read(triAabbMaxP, 1));
153
+ if ((maxTexelX - minTexelX < 2 &&
154
+ maxTexelY - minTexelY < 2 &&
155
+ startMipLevel >= 0) ||
156
+ startMipLevel >= maxDepth) {
157
+ for (let y = minTexelY; y <= maxTexelY; y++) {
158
+ for (let x = minTexelX; x <= maxTexelX; x++) {
159
+ if (rootCount < roots.length) {
160
+ vec3.set(roots[rootCount], Math.floor(x), Math.floor(y), startMipLevel);
161
+ rootCount++;
162
+ }
163
+ }
164
+ }
165
+ break;
166
+ }
167
+ startMipLevel++;
168
+ }
169
+ return rootCount;
170
+ }
171
+ export function conservativeTrianglesDisplacementRange(triangleCount) {
172
+ if (triangleCount < 100_000)
173
+ return undefined;
174
+ const ranges = new Float32Array(triangleCount * 2);
175
+ for (let i = 0; i < triangleCount; i++)
176
+ ranges[i * 2 + 1] = 1;
177
+ return ranges;
178
+ }
179
+ export function computeTrianglesDisplacementRange(geometry, minmaxData, width, isFlipY, material) {
180
+ const indices = geometry.indexArray;
181
+ const uvs = geometry.uv?.array;
182
+ const uvProjection = material.displacementUvProjection;
183
+ if (!uvs && uvProjection === 'none')
184
+ throw new Error('UV displacement requires texture coordinates; use triplanar, spherical, or cylindrical projection for a UV-less mesh.');
185
+ const conservative = conservativeTrianglesDisplacementRange(attributeLength(indices) / 3);
186
+ if (conservative)
187
+ return conservative;
188
+ const maxDepth = Math.log2(width);
189
+ const trianglesDisplacementRange = new Float32Array((attributeLength(indices) / 3) * 2);
190
+ const normal = geometry.normal.array;
191
+ const position = geometry.position.array;
192
+ const uv1 = vec2.create();
193
+ const uv2 = vec2.create();
194
+ const uv3 = vec2.create();
195
+ const p1 = vec3.create();
196
+ const p2 = vec3.create();
197
+ const p3 = vec3.create();
198
+ const n1 = vec3.create();
199
+ const n2 = vec3.create();
200
+ const n3 = vec3.create();
201
+ const isTriplanar = uvProjection === 'triplanar';
202
+ const isSpherical = uvProjection === 'spherical';
203
+ const isCylindrical = uvProjection === 'cylindrical';
204
+ const uvScale = material.displacementUvProjectionScale;
205
+ const minUv = vec2.create();
206
+ const maxUv = vec2.create();
207
+ const roots = [];
208
+ for (let i = 0; i < 100; i++) {
209
+ roots.push(new Float64Array(3));
210
+ }
211
+ for (let i = 0; i < attributeLength(indices); i += 3) {
212
+ const i1 = attributeValue(indices, i);
213
+ const i2 = attributeValue(indices, i + 1);
214
+ const i3 = attributeValue(indices, i + 2);
215
+ const i1_2 = i1 * 2;
216
+ const i2_2 = i2 * 2;
217
+ const i3_2 = i3 * 2;
218
+ const i1_3 = i1 * 3;
219
+ const i2_3 = i2 * 3;
220
+ const i3_3 = i3 * 3;
221
+ if (uvs) {
222
+ vec2.set(uv1, attributeValue(uvs, i1_2), attributeValue(uvs, i1_2 + 1));
223
+ vec2.set(uv2, attributeValue(uvs, i2_2), attributeValue(uvs, i2_2 + 1));
224
+ vec2.set(uv3, attributeValue(uvs, i3_2), attributeValue(uvs, i3_2 + 1));
225
+ }
226
+ else {
227
+ vec2.set(uv1, 0, 0);
228
+ vec2.set(uv2, 0, 0);
229
+ vec2.set(uv3, 0, 0);
230
+ }
231
+ let onSeam = false;
232
+ if (isTriplanar || isSpherical || isCylindrical) {
233
+ vec3.set(n1, attributeValue(normal, i1_3), attributeValue(normal, i1_3 + 1), attributeValue(normal, i1_3 + 2));
234
+ vec3.set(n2, attributeValue(normal, i2_3), attributeValue(normal, i2_3 + 1), attributeValue(normal, i2_3 + 2));
235
+ vec3.set(n3, attributeValue(normal, i3_3), attributeValue(normal, i3_3 + 1), attributeValue(normal, i3_3 + 2));
236
+ vec3.normalize(n1, n1);
237
+ vec3.normalize(n2, n2);
238
+ vec3.normalize(n3, n3);
239
+ if (isTriplanar || isSpherical || isCylindrical) {
240
+ vec3.set(p1, attributeValue(position, i1_3), attributeValue(position, i1_3 + 1), attributeValue(position, i1_3 + 2));
241
+ vec3.set(p2, attributeValue(position, i2_3), attributeValue(position, i2_3 + 1), attributeValue(position, i2_3 + 2));
242
+ vec3.set(p3, attributeValue(position, i3_3), attributeValue(position, i3_3 + 1), attributeValue(position, i3_3 + 2));
243
+ }
244
+ if (isTriplanar) {
245
+ // Is on the seam. Needs full prism to avoid empty seams.
246
+ const xMaxIndex = getMaxAxisIndex(n1);
247
+ const yMaxIndex = getMaxAxisIndex(n2);
248
+ const zMaxIndex = getMaxAxisIndex(n3);
249
+ if (!(xMaxIndex === yMaxIndex && yMaxIndex === zMaxIndex)) {
250
+ onSeam = true;
251
+ }
252
+ /* prettier-ignore */
253
+ triplanarProjectionTriangle(p1, p2, p3, n1, n2, n3, uv1, uv2, uv3);
254
+ }
255
+ else if (isSpherical) {
256
+ vec3.normalize(p1, p1);
257
+ vec3.normalize(p2, p2);
258
+ vec3.normalize(p3, p3);
259
+ onSeam = sphericalProjectionTriangle(p1, p2, p3, uv1, uv2, uv3);
260
+ }
261
+ else {
262
+ const u1 = Math.atan2(p1[2], p1[0]) / (Math.PI * 2) + 0.5;
263
+ const u2 = Math.atan2(p2[2], p2[0]) / (Math.PI * 2) + 0.5;
264
+ const u3 = Math.atan2(p3[2], p3[0]) / (Math.PI * 2) + 0.5;
265
+ vec2.set(uv1, u1, p1[1]);
266
+ vec2.set(uv2, u2, p2[1]);
267
+ vec2.set(uv3, u3, p3[1]);
268
+ onSeam = Math.max(u1, u2, u3) - Math.min(u1, u2, u3) > 0.5;
269
+ }
270
+ }
271
+ vec2.scale(uv1, uv1, uvScale);
272
+ vec2.scale(uv2, uv2, uvScale);
273
+ vec2.scale(uv3, uv3, uvScale);
274
+ // TODO PDM don't have zero area triangle issue.
275
+ let minHeight = Infinity;
276
+ let maxHeight = -Infinity;
277
+ if (onSeam) {
278
+ minHeight = 0.0;
279
+ maxHeight = 255.0;
280
+ }
281
+ else {
282
+ vec2.copy(maxUv, uv1);
283
+ vec2.copy(minUv, uv1);
284
+ vec2.min(minUv, minUv, uv2);
285
+ vec2.min(minUv, minUv, uv3);
286
+ vec2.max(maxUv, maxUv, uv2);
287
+ vec2.max(maxUv, maxUv, uv3);
288
+ const rootCount = findRoots(minUv, maxUv, maxDepth, roots);
289
+ for (let k = 0; k < rootCount; k++) {
290
+ const mipLevel = read(roots[k], 2);
291
+ const mipSize = Math.pow(2, maxDepth - mipLevel);
292
+ const minmax = minmaxData[mipLevel];
293
+ const x = ((read(roots[k], 0) % mipSize) + mipSize) % mipSize;
294
+ let y = ((read(roots[k], 1) % mipSize) + mipSize) % mipSize;
295
+ if (isFlipY) {
296
+ y = mipSize - y - 1;
297
+ }
298
+ const idx = (y * mipSize + x) * 2;
299
+ minHeight = Math.min(minHeight, minmax[idx]);
300
+ maxHeight = Math.max(maxHeight, minmax[idx + 1]);
301
+ }
302
+ }
303
+ // TODO this will cause flat surface optimization fail.
304
+ // But not adding bias will leads to small gap between flat surface and displaced surface.
305
+ trianglesDisplacementRange[(i / 3) * 2] = Math.max((Math.floor(minHeight) - 4) / 255, 0);
306
+ trianglesDisplacementRange[(i / 3) * 2 + 1] = Math.min((Math.ceil(maxHeight) + 4) / 255, 1);
307
+ }
308
+ return trianglesDisplacementRange;
309
+ }
310
+ /** Conservative source-order AABBs for the actual displacement prism. */
311
+ export function displacementPrismAabbs(geometry, displacementScale) {
312
+ const indices = geometry.indexArray;
313
+ const count = Math.floor(indices.length / 3);
314
+ const boxes = new Float32Array(count * 6);
315
+ for (let t = 0; t < count; t++) {
316
+ const minimum = [Infinity, Infinity, Infinity], maximum = [-Infinity, -Infinity, -Infinity];
317
+ const ia = indices[t * 3] * 3;
318
+ const ib = indices[t * 3 + 1] * 3;
319
+ const ic = indices[t * 3 + 2] * 3;
320
+ const positions = geometry.position.array;
321
+ const ux = positions[ib] - positions[ia], uy = positions[ib + 1] - positions[ia + 1], uz = positions[ib + 2] - positions[ia + 2];
322
+ const vx = positions[ic] - positions[ia], vy = positions[ic + 1] - positions[ia + 1], vz = positions[ic + 2] - positions[ia + 2];
323
+ const fx = uy * vz - uz * vy, fy = uz * vx - ux * vz, fz = ux * vy - uy * vx;
324
+ const faceLength = Math.hypot(fx, fy, fz);
325
+ for (let c = 0; c < 3; c++) {
326
+ const v = indices[t * 3 + c];
327
+ const nx = geometry.normal.array[v * 3], ny = geometry.normal.array[v * 3 + 1], nz = geometry.normal.array[v * 3 + 2];
328
+ const length = Math.hypot(nx, ny, nz);
329
+ const cosine = Math.abs((nx * fx + ny * fy + nz * fz) / ((length || 1) * (faceLength || 1)));
330
+ const extrusion = cosine > 0 ? displacementScale / cosine : 0;
331
+ for (let a = 0; a < 3; a++) {
332
+ const position = geometry.position.array[v * 3 + a], n = geometry.normal.array[v * 3 + a] / (length || 1);
333
+ const p0 = position;
334
+ const p1 = position + n * extrusion;
335
+ minimum[a] = Math.min(minimum[a], p0, p1);
336
+ maximum[a] = Math.max(maximum[a], p0, p1);
337
+ }
338
+ }
339
+ for (let a = 0; a < 3; a++) {
340
+ const padding = Math.max(1, Math.abs(minimum[a]), Math.abs(maximum[a])) * 1e-6;
341
+ minimum[a] -= padding;
342
+ maximum[a] += padding;
343
+ }
344
+ for (let a = 0; a < 3; a++) {
345
+ boxes[t * 6 + a] = minimum[a];
346
+ boxes[t * 6 + a + 3] = maximum[a];
347
+ }
348
+ }
349
+ return boxes;
350
+ }
351
+ //# sourceMappingURL=displacementPreparation.js.map