@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,422 @@
1
+ /**
2
+ * Physically based clear sky for the viewer's default environment, baked on
3
+ * the GPU into an equirectangular radiance map.
4
+ *
5
+ * Integrates single scattering through a spherical Rayleigh, Mie and ozone
6
+ * atmosphere and adds multiple scattering with the isotropic approximation
7
+ * of Hillaire, "A Scalable and Production Ready Sky and Atmosphere Rendering
8
+ * Technique" (EGSR 2020). Coefficients are the Earth defaults from Bruneton,
9
+ * "Precomputed Atmospheric Scattering" (2008/2017). Formulas only; no code is
10
+ * taken from either reference.
11
+ *
12
+ * WebGL 2 passes: transmittance table, multiple scattering by altitude, a
13
+ * sky-view table by elevation and azimuth relative to the sun, irradiance and
14
+ * exposure, then the map itself with an anti-aliased, limb-darkened sun disk.
15
+ * Distances are in kilometers so float32 keeps the horizon precise.
16
+ */
17
+ import { sunPosition } from '../scene/skyParameters.js';
18
+ import { SUN_RADIUS, TURBIDITY, GROUND_ALBEDO, ILLUMINANCE, REFERENCE_ILLUMINANCE } from './skyModel.js';
19
+ const T_SIZE = [256, 64]; // cos(view zenith) × altitude
20
+ const MS_SIZE = [32, 1]; // altitude
21
+ const SV_SIZE = [96, 192]; // relative azimuth × elevation
22
+ const COMMON = /* glsl */ `#version 300 es
23
+ precision highp float;
24
+ precision highp int;
25
+ precision highp sampler2D;
26
+ out vec4 color;
27
+ const float PI = 3.14159265358979;
28
+ const float R_GROUND = 6360.0;
29
+ const float R_TOP = 6460.0;
30
+ const float CAMERA_ALTITUDE = 0.2;
31
+ const vec3 RAYLEIGH = vec3(5.802e-3, 13.558e-3, 33.1e-3);
32
+ const float MIE_SCATTERING = 3.996e-3;
33
+ const float MIE_EXTINCTION = 4.44e-3;
34
+ const float MIE_G = 0.8;
35
+ const vec3 OZONE = vec3(0.65e-3, 1.881e-3, 0.085e-3);
36
+ const ivec2 T_SIZE = ivec2(${T_SIZE[0]}, ${T_SIZE[1]});
37
+ const int MS_ALTITUDES = ${MS_SIZE[0]};
38
+ const ivec2 SV_SIZE = ivec2(${SV_SIZE[0]}, ${SV_SIZE[1]});
39
+ uniform vec3 uSun;
40
+ uniform float uTurbidity;
41
+ uniform vec3 uAlbedo;
42
+
43
+
44
+ float bj(float r, float mu, float radius) { return (radius - r) * (radius + r) + r * r * mu * mu; }
45
+ bool mV(float r, float mu) { return mu < 0.0 && bj(r, mu, R_GROUND) >= 0.0; }
46
+ float kT(float r, float mu) { return max(-r * mu - sqrt(max(bj(r, mu, R_GROUND), 0.0)), 0.0); }
47
+ float iS(float r, float mu) { return max(-r * mu + sqrt(max(bj(r, mu, R_TOP), 0.0)), 0.0); }
48
+
49
+
50
+ vec3 oo(float r) {
51
+ float h = max(r - R_GROUND, 0.0);
52
+ return vec3(exp(-h / 8.0), exp(-h / 1.2) * uTurbidity, max(0.0, 1.0 - abs(h - 25.0) / 15.0));
53
+ }
54
+ vec3 extinction(vec3 d) { return RAYLEIGH * d.x + MIE_EXTINCTION * d.y + OZONE * d.z; }
55
+
56
+ float mB(float x) { return x * x * (R_TOP - R_GROUND); }
57
+ float hy(float h) { return sqrt(clamp(h / (R_TOP - R_GROUND), 0.0, 1.0)); }
58
+
59
+
60
+ vec3 eR(sampler2D table, vec2 p) {
61
+ ivec2 size = textureSize(table, 0);
62
+ vec2 q = clamp(p, vec2(0.0), vec2(size - 1));
63
+ ivec2 i = min(ivec2(floor(q)), max(size - 2, ivec2(0)));
64
+ vec2 f = clamp(q - vec2(i), 0.0, 1.0);
65
+ ivec2 j = min(i + 1, size - 1);
66
+ vec3 a = texelFetch(table, i, 0).rgb, b = texelFetch(table, ivec2(j.x, i.y), 0).rgb;
67
+ vec3 c = texelFetch(table, ivec2(i.x, j.y), 0).rgb, d = texelFetch(table, j, 0).rgb;
68
+ return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
69
+ }
70
+ `;
71
+ const ATMOSPHERE = /* glsl */ `
72
+ uniform sampler2D uTransmittance;
73
+ uniform sampler2D uMultiple;
74
+ uniform bool uFull;
75
+ uniform vec3 uSkyIrradiance;
76
+
77
+
78
+ vec3 fv(float r, float mu) {
79
+ return eR(uTransmittance, vec2((clamp(mu, -1.0, 1.0) + 1.0) * 0.5 * float(T_SIZE.x - 1),
80
+ hy(r - R_GROUND) * float(T_SIZE.y - 1)));
81
+ }
82
+
83
+ float mI(float nu) {
84
+ float g2 = MIE_G * MIE_G;
85
+ return 3.0 / (8.0 * PI) * ((1.0 - g2) * (1.0 + nu * nu)) / ((2.0 + g2) * pow(1.0 + g2 - 2.0 * MIE_G * nu, 1.5));
86
+ }
87
+
88
+
89
+
90
+
91
+
92
+
93
+ void vG(vec3 origin, vec3 dir, int steps, out vec3 radiance, out vec3 throughput) {
94
+ float r = length(origin);
95
+ float mu = dot(origin, dir) / r;
96
+ bool ground = mV(r, mu);
97
+ float len = ground ? kT(r, mu) : iS(r, mu);
98
+ float nu = dot(dir, uSun);
99
+ float ja = uFull ? 3.0 / (16.0 * PI) * (1.0 + nu * nu) : 1.0 / (4.0 * PI);
100
+ float sh = uFull ? mI(nu) : 1.0 / (4.0 * PI);
101
+ radiance = vec3(0.0);
102
+ throughput = vec3(0.0);
103
+ vec3 view = vec3(1.0);
104
+ float previous = 0.0;
105
+ for (int i = 0; i < steps; i++) {
106
+
107
+ float s = float(i + 1) / float(steps);
108
+ float next = len * s * s;
109
+ float dt = next - previous;
110
+ vec3 p = origin + dir * (0.5 * (previous + next));
111
+ previous = next;
112
+ float pr = length(p);
113
+ vec3 d = oo(pr);
114
+ vec3 e = extinction(d);
115
+ vec3 vk = fv(pr, dot(p, uSun) / pr);
116
+ vec3 np = RAYLEIGH * d.x;
117
+ float nl = MIE_SCATTERING * d.y;
118
+ vec3 ms = vec3(0.0);
119
+ if (uFull) {
120
+ float x = hy(pr - R_GROUND) * float(MS_ALTITUDES - 1);
121
+ ms = eR(uMultiple, vec2(x, 0.0));
122
+ }
123
+ vec3 source = vk * (np * ja + nl * sh) + (np + nl) * ms;
124
+
125
+ vec3 segment = exp(-e * dt);
126
+ vec3 weight = (1.0 - segment) / max(e, vec3(1e-9));
127
+ radiance += view * source * weight;
128
+ throughput += view * (np + nl) * weight;
129
+ view *= segment;
130
+ }
131
+ if (ground) {
132
+ vec3 p = origin + dir * len;
133
+ float pr = length(p);
134
+ float tD = dot(p, uSun) / pr;
135
+ vec3 irradiance = fv(pr, tD) * max(tD, 0.0) + uSkyIrradiance;
136
+ radiance += view * uAlbedo / PI * irradiance;
137
+ }
138
+ }
139
+ `;
140
+ const TRANSMITTANCE = COMMON + /* glsl */ `
141
+ void main() {
142
+ ivec2 p = ivec2(gl_FragCoord.xy);
143
+ float mu = float(p.x) / float(T_SIZE.x - 1) * 2.0 - 1.0;
144
+ float r = R_GROUND + mB(float(p.y) / float(T_SIZE.y - 1));
145
+ if (mV(r, mu)) { color = vec4(0.0, 0.0, 0.0, 1.0); return; }
146
+ float len = iS(r, mu);
147
+ vec3 depth = vec3(0.0);
148
+ const int STEPS = 48;
149
+ for (int i = 0; i < STEPS; i++) {
150
+ float t = (float(i) + 0.5) / float(STEPS) * len;
151
+ depth += extinction(oo(sqrt(t * t + 2.0 * r * mu * t + r * r))) * (len / float(STEPS));
152
+ }
153
+ color = vec4(exp(-depth), 1.0);
154
+ }
155
+ `;
156
+ const MULTIPLE = COMMON + ATMOSPHERE + /* glsl */ `
157
+ void main() {
158
+ float r = R_GROUND + mB(floor(gl_FragCoord.x) / float(MS_ALTITUDES - 1));
159
+ const int DIRECTIONS = 64;
160
+ vec3 second = vec3(0.0), qC = vec3(0.0);
161
+ for (int i = 0; i < DIRECTIONS; i++) {
162
+
163
+ float mu = 1.0 - 2.0 * (float(i) + 0.5) / float(DIRECTIONS);
164
+ float phi = float(i) * PI * (3.0 - sqrt(5.0));
165
+ float s = sqrt(1.0 - mu * mu);
166
+ vec3 radiance, throughput;
167
+ vG(vec3(0.0, r, 0.0), vec3(s * cos(phi), mu, s * sin(phi)), 20, radiance, throughput);
168
+ second += radiance / float(DIRECTIONS);
169
+ qC += throughput / float(DIRECTIONS);
170
+ }
171
+ color = vec4(second / (1.0 - qC), 1.0);
172
+ }
173
+ `;
174
+ // Elevation rows are spaced by the square root so the horizon gets most of them.
175
+ const ELEVATION_MAPPING = /* glsl */ `
176
+ float qd(float row) {
177
+ float x = row / float(SV_SIZE.y - 1) * 2.0 - 1.0;
178
+ return sign(x) * x * x * (PI / 2.0);
179
+ }
180
+ float hL(float e) {
181
+ float x = sign(e) * sqrt(abs(e) / (PI / 2.0));
182
+ return clamp((x + 1.0) * 0.5, 0.0, 1.0) * float(SV_SIZE.y - 1);
183
+ }
184
+ `;
185
+ const SKY_VIEW = COMMON + ATMOSPHERE + ELEVATION_MAPPING + /* glsl */ `
186
+ void main() {
187
+ ivec2 p = ivec2(gl_FragCoord.xy);
188
+ float e = qd(float(p.y));
189
+ float phi = float(p.x) / float(SV_SIZE.x - 1) * PI;
190
+ vec3 radiance, throughput;
191
+ vG(vec3(0.0, R_GROUND + CAMERA_ALTITUDE, 0.0), vec3(cos(e) * cos(phi), sin(e), cos(e) * sin(phi)), 40, radiance, throughput);
192
+ color = vec4(radiance, 1.0);
193
+ }
194
+ `;
195
+ /** Texel 0: sky irradiance on the ground. Texel 1: sun transmittance at the camera and the exposure scale. */
196
+ const IRRADIANCE = COMMON + ELEVATION_MAPPING + /* glsl */ `
197
+ uniform sampler2D uTransmittance;
198
+ uniform sampler2D uSkyView;
199
+ void main() {
200
+ vec3 sky = vec3(0.0);
201
+ const int ROWS = 128, COLUMNS = 48;
202
+ for (int i = 0; i < ROWS; i++) {
203
+ float e = (float(i) + 0.5) / float(ROWS) * (PI / 2.0);
204
+
205
+ float weight = 2.0 * sin(e) * cos(e) * (PI / 2.0 / float(ROWS)) * (PI / float(COLUMNS));
206
+ for (int j = 0; j < COLUMNS; j++) {
207
+ float phi = (float(j) + 0.5) / float(COLUMNS) * PI;
208
+ sky += eR(uSkyView, vec2(phi / PI * float(SV_SIZE.x - 1), hL(e))) * weight;
209
+ }
210
+ }
211
+ if (int(gl_FragCoord.x) == 0) { color = vec4(sky, 1.0); return; }
212
+ float r = R_GROUND + CAMERA_ALTITUDE;
213
+ vec3 vk = eR(uTransmittance, vec2((uSun.y + 1.0) * 0.5 * float(T_SIZE.x - 1), hy(CAMERA_ALTITUDE) * float(T_SIZE.y - 1)));
214
+ vec3 xE = vec3(0.2126, 0.7152, 0.0722);
215
+ float horizontal = dot(sky, xE) + dot(vk, xE) * max(uSun.y, 0.0);
216
+
217
+
218
+ const float REFERENCE = ${REFERENCE_ILLUMINANCE};
219
+ float scale = ${ILLUMINANCE} / sqrt(max(horizontal, REFERENCE * 1e-3) * REFERENCE);
220
+ color = vec4(vk, scale);
221
+ }
222
+ `;
223
+ const MAP = COMMON + ELEVATION_MAPPING + /* glsl */ `
224
+ uniform sampler2D uSkyView;
225
+ uniform sampler2D uIrradiance;
226
+ uniform vec2 uSize;
227
+ uniform float uAzimuth;
228
+ uniform vec3 uSunWorld;
229
+ uniform float uSunRadius;
230
+
231
+
232
+ vec3 gU(vec2 cR) {
233
+ float theta = cR.y / uSize.y * PI;
234
+ float phi = cR.x / uSize.x * 2.0 * PI;
235
+ return vec3(-sin(theta) * cos(phi), cos(theta), -sin(theta) * sin(phi));
236
+ }
237
+
238
+ void main() {
239
+ vec3 dir = gU(gl_FragCoord.xy);
240
+ float dU = abs(atan(dir.z, dir.x) - uAzimuth);
241
+ dU = min(mod(dU, 2.0 * PI), 2.0 * PI - mod(dU, 2.0 * PI));
242
+ float e = asin(clamp(dir.y, -1.0, 1.0));
243
+ vec3 radiance = eR(uSkyView, vec2(dU / PI * float(SV_SIZE.x - 1), hL(e)));
244
+ vec4 sun = texelFetch(uIrradiance, ivec2(1, 0), 0);
245
+
246
+
247
+ float rM = PI / uSize.y;
248
+ if (acos(clamp(dot(dir, uSunWorld), -1.0, 1.0)) < uSunRadius + 3.0 * rM / max(sqrt(1.0 - dir.y * dir.y), 0.05)) {
249
+ const int N = 6;
250
+ const float LIMB = 0.6;
251
+ float coverage = 0.0;
252
+ for (int y = 0; y < N; y++) for (int x = 0; x < N; x++) {
253
+ vec3 d = gU(gl_FragCoord.xy - 0.5 + (vec2(x, y) + 0.5) / float(N));
254
+
255
+ float angle = 2.0 * asin(min(length(d - uSunWorld) * 0.5, 1.0));
256
+ float t = angle / uSunRadius;
257
+ if (t < 1.0) coverage += 1.0 - LIMB * (1.0 - sqrt(1.0 - t * t));
258
+ }
259
+ float rK = 2.0 * PI * (1.0 - cos(uSunRadius));
260
+ radiance += coverage / float(N * N) / (rK * (1.0 - LIMB / 3.0)) * sun.rgb;
261
+ }
262
+ color = vec4(radiance * sun.a, 1.0);
263
+ }
264
+ `;
265
+ const VERTEX = /* glsl */ `#version 300 es
266
+ void main() {
267
+ vec2 p = vec2(gl_VertexID == 1 ? 3.0 : -1.0, gl_VertexID == 2 ? 3.0 : -1.0);
268
+ gl_Position = vec4(p, 0.0, 1.0);
269
+ }
270
+ `;
271
+ /** Bakes skies with its own WebGL 2 context; requires float render targets. */
272
+ export class WebGLSkyBaker {
273
+ gl;
274
+ programs;
275
+ targets;
276
+ map;
277
+ constructor() {
278
+ const canvas = typeof OffscreenCanvas !== 'undefined' ? new OffscreenCanvas(1, 1) : document.createElement('canvas');
279
+ const gl = canvas.getContext('webgl2', { antialias: false, depth: false, stencil: false, alpha: false });
280
+ if (!gl)
281
+ throw new Error('The procedural sky needs WebGL 2.');
282
+ if (!gl.getExtension('EXT_color_buffer_float'))
283
+ throw new Error('The procedural sky needs float render targets (EXT_color_buffer_float).');
284
+ this.gl = gl;
285
+ gl.bindVertexArray(gl.createVertexArray());
286
+ this.programs = {
287
+ transmittance: this.program(TRANSMITTANCE),
288
+ multiple: this.program(MULTIPLE),
289
+ skyView: this.program(SKY_VIEW),
290
+ irradiance: this.program(IRRADIANCE),
291
+ map: this.program(MAP)
292
+ };
293
+ this.targets = {
294
+ transmittance: this.target(...T_SIZE),
295
+ multiple: this.target(...MS_SIZE),
296
+ skyView: this.target(...SV_SIZE),
297
+ irradiance: this.target(2, 1)
298
+ };
299
+ }
300
+ /** Clear sky at a local solar time, in hours. */
301
+ bake(hours, width = 2048, height = 1024) {
302
+ const gl = this.gl;
303
+ if (gl.isContextLost())
304
+ throw new Error('The procedural sky lost its WebGL context.');
305
+ const { elevation, azimuth } = sunPosition(hours);
306
+ const e = deg(elevation), a = deg(azimuth);
307
+ const shared = (program) => {
308
+ gl.useProgram(program);
309
+ this.uniform(program, 'uSun', (l) => gl.uniform3f(l, Math.cos(e), Math.sin(e), 0));
310
+ this.uniform(program, 'uTurbidity', (l) => gl.uniform1f(l, TURBIDITY));
311
+ this.uniform(program, 'uAlbedo', (l) => gl.uniform3fv(l, GROUND_ALBEDO));
312
+ return program;
313
+ };
314
+ const { transmittance, multiple, skyView, irradiance } = this.targets;
315
+ const atmosphere = (program, full, sky) => {
316
+ shared(program);
317
+ this.bind(program, 'uTransmittance', 0, transmittance);
318
+ // The multiple-scattering pass declares but never reads its own target;
319
+ // bind another texture so WebGL sees no feedback loop.
320
+ this.bind(program, 'uMultiple', 1, full ? multiple : irradiance);
321
+ this.uniform(program, 'uFull', (l) => gl.uniform1i(l, full ? 1 : 0));
322
+ this.uniform(program, 'uSkyIrradiance', (l) => gl.uniform3fv(l, sky));
323
+ };
324
+ this.draw(shared(this.programs.transmittance), transmittance);
325
+ atmosphere(this.programs.multiple, false, [0, 0, 0]);
326
+ this.draw(this.programs.multiple, multiple);
327
+ // Upward views first: the ground seen below is lit by that sky.
328
+ atmosphere(this.programs.skyView, true, [0, 0, 0]);
329
+ this.draw(this.programs.skyView, skyView);
330
+ shared(this.programs.irradiance);
331
+ this.bind(this.programs.irradiance, 'uTransmittance', 0, transmittance);
332
+ this.bind(this.programs.irradiance, 'uSkyView', 1, skyView);
333
+ this.draw(this.programs.irradiance, irradiance);
334
+ const sky = this.read(irradiance).subarray(0, 3);
335
+ atmosphere(this.programs.skyView, true, Array.from(sky));
336
+ this.draw(this.programs.skyView, skyView);
337
+ if (!this.map || this.map.width !== width || this.map.height !== height) {
338
+ if (this.map)
339
+ this.release(this.map);
340
+ this.map = this.target(width, height);
341
+ }
342
+ const map = shared(this.programs.map);
343
+ this.bind(map, 'uSkyView', 0, skyView);
344
+ this.bind(map, 'uIrradiance', 1, irradiance);
345
+ this.uniform(map, 'uSize', (l) => gl.uniform2f(l, width, height));
346
+ this.uniform(map, 'uAzimuth', (l) => gl.uniform1f(l, a));
347
+ this.uniform(map, 'uSunWorld', (l) => gl.uniform3f(l, Math.cos(e) * Math.cos(a), Math.sin(e), Math.cos(e) * Math.sin(a)));
348
+ this.uniform(map, 'uSunRadius', (l) => gl.uniform1f(l, deg(SUN_RADIUS)));
349
+ this.draw(map, this.map);
350
+ // Row 0 is the zenith, as in an .hdr file.
351
+ return { data: this.read(this.map), width, height };
352
+ }
353
+ dispose() {
354
+ this.gl.getExtension('WEBGL_lose_context')?.loseContext();
355
+ }
356
+ program(fragment) {
357
+ const gl = this.gl;
358
+ const compile = (type, source) => {
359
+ const shader = gl.createShader(type);
360
+ gl.shaderSource(shader, source);
361
+ gl.compileShader(shader);
362
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS))
363
+ throw new Error(`Sky shader: ${gl.getShaderInfoLog(shader)}`);
364
+ return shader;
365
+ };
366
+ const program = gl.createProgram();
367
+ gl.attachShader(program, compile(gl.VERTEX_SHADER, VERTEX));
368
+ gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fragment));
369
+ gl.linkProgram(program);
370
+ if (!gl.getProgramParameter(program, gl.LINK_STATUS))
371
+ throw new Error(`Sky program: ${gl.getProgramInfoLog(program)}`);
372
+ return program;
373
+ }
374
+ target(width, height) {
375
+ const gl = this.gl;
376
+ const texture = gl.createTexture();
377
+ gl.bindTexture(gl.TEXTURE_2D, texture);
378
+ gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, width, height);
379
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
380
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
381
+ const framebuffer = gl.createFramebuffer();
382
+ gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);
383
+ gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
384
+ if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE)
385
+ throw new Error('The procedural sky cannot render to float textures.');
386
+ return { texture, framebuffer, width, height };
387
+ }
388
+ release(target) {
389
+ this.gl.deleteFramebuffer(target.framebuffer);
390
+ this.gl.deleteTexture(target.texture);
391
+ }
392
+ uniform(program, name, set) {
393
+ const location = this.gl.getUniformLocation(program, name);
394
+ if (location)
395
+ set(location);
396
+ }
397
+ bind(program, name, unit, target) {
398
+ const gl = this.gl;
399
+ gl.activeTexture(gl.TEXTURE0 + unit);
400
+ gl.bindTexture(gl.TEXTURE_2D, target.texture);
401
+ this.uniform(program, name, (l) => gl.uniform1i(l, unit));
402
+ }
403
+ draw(program, target) {
404
+ const gl = this.gl;
405
+ gl.useProgram(program);
406
+ // A texture cannot be sampled while it is the render target.
407
+ gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer);
408
+ gl.viewport(0, 0, target.width, target.height);
409
+ gl.drawArrays(gl.TRIANGLES, 0, 3);
410
+ }
411
+ read(target) {
412
+ const gl = this.gl;
413
+ const data = new Float32Array(target.width * target.height * 4);
414
+ gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer);
415
+ gl.readPixels(0, 0, target.width, target.height, gl.RGBA, gl.FLOAT, data);
416
+ return data;
417
+ }
418
+ }
419
+ function deg(d) {
420
+ return (d * Math.PI) / 180;
421
+ }
422
+ //# sourceMappingURL=WebGLSkyBaker.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebGLSkyBaker.js","sourceRoot":"","sources":["../../src/renderer/WebGLSkyBaker.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Physically based clear sky for the viewer's default environment, baked on\n * the GPU into an equirectangular radiance map.\n *\n * Integrates single scattering through a spherical Rayleigh, Mie and ozone\n * atmosphere and adds multiple scattering with the isotropic approximation\n * of Hillaire, \"A Scalable and Production Ready Sky and Atmosphere Rendering\n * Technique\" (EGSR 2020). Coefficients are the Earth defaults from Bruneton,\n * \"Precomputed Atmospheric Scattering\" (2008/2017). Formulas only; no code is\n * taken from either reference.\n *\n * WebGL 2 passes: transmittance table, multiple scattering by altitude, a\n * sky-view table by elevation and azimuth relative to the sun, irradiance and\n * exposure, then the map itself with an anti-aliased, limb-darkened sun disk.\n * Distances are in kilometers so float32 keeps the horizon precise.\n */\n\nimport { sunPosition } from '../scene/skyParameters.js';\nimport { SUN_RADIUS, TURBIDITY, GROUND_ALBEDO, ILLUMINANCE, REFERENCE_ILLUMINANCE } from './skyModel.js';\n\nexport interface SkyData { data: Float32Array; width: number; height: number; }\n\nconst T_SIZE = [256, 64] as const; // cos(view zenith) × altitude\nconst MS_SIZE = [32, 1] as const; // altitude\nconst SV_SIZE = [96, 192] as const; // relative azimuth × elevation\n\nconst COMMON = /* glsl */ `#version 300 es\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\nout vec4 color;\nconst float PI = 3.14159265358979;\nconst float R_GROUND = 6360.0;\nconst float R_TOP = 6460.0;\nconst float CAMERA_ALTITUDE = 0.2;\nconst vec3 RAYLEIGH = vec3(5.802e-3, 13.558e-3, 33.1e-3);\nconst float MIE_SCATTERING = 3.996e-3;\nconst float MIE_EXTINCTION = 4.44e-3;\nconst float MIE_G = 0.8;\nconst vec3 OZONE = vec3(0.65e-3, 1.881e-3, 0.085e-3);\nconst ivec2 T_SIZE = ivec2(${T_SIZE[0]}, ${T_SIZE[1]});\nconst int MS_ALTITUDES = ${MS_SIZE[0]};\nconst ivec2 SV_SIZE = ivec2(${SV_SIZE[0]}, ${SV_SIZE[1]});\nuniform vec3 uSun; // atmosphere frame: the sun's azimuth is +X\nuniform float uTurbidity;\nuniform vec3 uAlbedo;\n\n// (R - r)(R + r) + r²μ² avoids cancelling planet-sized squares.\nfloat discriminant(float r, float mu, float radius) { return (radius - r) * (radius + r) + r * r * mu * mu; }\nbool hitsGround(float r, float mu) { return mu < 0.0 && discriminant(r, mu, R_GROUND) >= 0.0; }\nfloat distanceToGround(float r, float mu) { return max(-r * mu - sqrt(max(discriminant(r, mu, R_GROUND), 0.0)), 0.0); }\nfloat distanceToTop(float r, float mu) { return max(-r * mu + sqrt(max(discriminant(r, mu, R_TOP), 0.0)), 0.0); }\n\n/** Rayleigh, Mie and ozone densities. */\nvec3 densities(float r) {\n float h = max(r - R_GROUND, 0.0);\n return vec3(exp(-h / 8.0), exp(-h / 1.2) * uTurbidity, max(0.0, 1.0 - abs(h - 25.0) / 15.0));\n}\nvec3 extinction(vec3 d) { return RAYLEIGH * d.x + MIE_EXTINCTION * d.y + OZONE * d.z; }\n\nfloat altitudeAt(float x) { return x * x * (R_TOP - R_GROUND); }\nfloat altitudeCoord(float h) { return sqrt(clamp(h / (R_TOP - R_GROUND), 0.0, 1.0)); }\n\n/** Bilinear lookup in texel-index space; float textures need not be filterable. */\nvec3 fetchLinear(sampler2D table, vec2 p) {\n ivec2 size = textureSize(table, 0);\n vec2 q = clamp(p, vec2(0.0), vec2(size - 1));\n ivec2 i = min(ivec2(floor(q)), max(size - 2, ivec2(0)));\n vec2 f = clamp(q - vec2(i), 0.0, 1.0);\n ivec2 j = min(i + 1, size - 1);\n vec3 a = texelFetch(table, i, 0).rgb, b = texelFetch(table, ivec2(j.x, i.y), 0).rgb;\n vec3 c = texelFetch(table, ivec2(i.x, j.y), 0).rgb, d = texelFetch(table, j, 0).rgb;\n return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);\n}\n`;\n\nconst ATMOSPHERE = /* glsl */ `\nuniform sampler2D uTransmittance;\nuniform sampler2D uMultiple;\nuniform bool uFull;\nuniform vec3 uSkyIrradiance;\n\n/** Transmittance from a point toward the top of the atmosphere. */\nvec3 transmittanceTo(float r, float mu) {\n return fetchLinear(uTransmittance, vec2((clamp(mu, -1.0, 1.0) + 1.0) * 0.5 * float(T_SIZE.x - 1),\n altitudeCoord(r - R_GROUND) * float(T_SIZE.y - 1)));\n}\n\nfloat cornetteShanks(float nu) {\n float g2 = MIE_G * MIE_G;\n return 3.0 / (8.0 * PI) * ((1.0 - g2) * (1.0 + nu * nu)) / ((2.0 + g2) * pow(1.0 + g2 - 2.0 * MIE_G * nu, 1.5));\n}\n\n/**\n * Radiance arriving at origin from dir, for unit solar irradiance. Without\n * uFull it uses isotropic phase and no multiple scattering, and returns the\n * scattered fraction for the multiple-scattering series.\n */\nvoid march(vec3 origin, vec3 dir, int steps, out vec3 radiance, out vec3 throughput) {\n float r = length(origin);\n float mu = dot(origin, dir) / r;\n bool ground = hitsGround(r, mu);\n float len = ground ? distanceToGround(r, mu) : distanceToTop(r, mu);\n float nu = dot(dir, uSun);\n float rayleighPhase = uFull ? 3.0 / (16.0 * PI) * (1.0 + nu * nu) : 1.0 / (4.0 * PI);\n float miePhase = uFull ? cornetteShanks(nu) : 1.0 / (4.0 * PI);\n radiance = vec3(0.0);\n throughput = vec3(0.0);\n vec3 view = vec3(1.0);\n float previous = 0.0;\n for (int i = 0; i < steps; i++) {\n // Quadratic spacing keeps long horizon rays resolved near the camera.\n float s = float(i + 1) / float(steps);\n float next = len * s * s;\n float dt = next - previous;\n vec3 p = origin + dir * (0.5 * (previous + next));\n previous = next;\n float pr = length(p);\n vec3 d = densities(pr);\n vec3 e = extinction(d);\n vec3 sunT = transmittanceTo(pr, dot(p, uSun) / pr);\n vec3 scatterR = RAYLEIGH * d.x;\n float scatterM = MIE_SCATTERING * d.y;\n vec3 ms = vec3(0.0);\n if (uFull) {\n float x = altitudeCoord(pr - R_GROUND) * float(MS_ALTITUDES - 1);\n ms = fetchLinear(uMultiple, vec2(x, 0.0));\n }\n vec3 source = sunT * (scatterR * rayleighPhase + scatterM * miePhase) + (scatterR + scatterM) * ms;\n // Analytic integration of the source over the segment's extinction.\n vec3 segment = exp(-e * dt);\n vec3 weight = (1.0 - segment) / max(e, vec3(1e-9));\n radiance += view * source * weight;\n throughput += view * (scatterR + scatterM) * weight;\n view *= segment;\n }\n if (ground) {\n vec3 p = origin + dir * len;\n float pr = length(p);\n float cosSun = dot(p, uSun) / pr;\n vec3 irradiance = transmittanceTo(pr, cosSun) * max(cosSun, 0.0) + uSkyIrradiance;\n radiance += view * uAlbedo / PI * irradiance;\n }\n}\n`;\n\nconst TRANSMITTANCE = COMMON + /* glsl */ `\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n float mu = float(p.x) / float(T_SIZE.x - 1) * 2.0 - 1.0;\n float r = R_GROUND + altitudeAt(float(p.y) / float(T_SIZE.y - 1));\n if (hitsGround(r, mu)) { color = vec4(0.0, 0.0, 0.0, 1.0); return; }\n float len = distanceToTop(r, mu);\n vec3 depth = vec3(0.0);\n const int STEPS = 48;\n for (int i = 0; i < STEPS; i++) {\n float t = (float(i) + 0.5) / float(STEPS) * len;\n depth += extinction(densities(sqrt(t * t + 2.0 * r * mu * t + r * r))) * (len / float(STEPS));\n }\n color = vec4(exp(-depth), 1.0);\n}\n`;\n\nconst MULTIPLE = COMMON + ATMOSPHERE + /* glsl */ `\nvoid main() {\n float r = R_GROUND + altitudeAt(floor(gl_FragCoord.x) / float(MS_ALTITUDES - 1));\n const int DIRECTIONS = 64;\n vec3 second = vec3(0.0), transfer = vec3(0.0);\n for (int i = 0; i < DIRECTIONS; i++) {\n // Fibonacci sphere; the planet is symmetric about the local vertical.\n float mu = 1.0 - 2.0 * (float(i) + 0.5) / float(DIRECTIONS);\n float phi = float(i) * PI * (3.0 - sqrt(5.0));\n float s = sqrt(1.0 - mu * mu);\n vec3 radiance, throughput;\n march(vec3(0.0, r, 0.0), vec3(s * cos(phi), mu, s * sin(phi)), 20, radiance, throughput);\n second += radiance / float(DIRECTIONS);\n transfer += throughput / float(DIRECTIONS);\n }\n color = vec4(second / (1.0 - transfer), 1.0);\n}\n`;\n\n// Elevation rows are spaced by the square root so the horizon gets most of them.\nconst ELEVATION_MAPPING = /* glsl */ `\nfloat elevationAt(float row) {\n float x = row / float(SV_SIZE.y - 1) * 2.0 - 1.0;\n return sign(x) * x * x * (PI / 2.0);\n}\nfloat elevationCoord(float e) {\n float x = sign(e) * sqrt(abs(e) / (PI / 2.0));\n return clamp((x + 1.0) * 0.5, 0.0, 1.0) * float(SV_SIZE.y - 1);\n}\n`;\n\nconst SKY_VIEW = COMMON + ATMOSPHERE + ELEVATION_MAPPING + /* glsl */ `\nvoid main() {\n ivec2 p = ivec2(gl_FragCoord.xy);\n float e = elevationAt(float(p.y));\n float phi = float(p.x) / float(SV_SIZE.x - 1) * PI;\n vec3 radiance, throughput;\n march(vec3(0.0, R_GROUND + CAMERA_ALTITUDE, 0.0), vec3(cos(e) * cos(phi), sin(e), cos(e) * sin(phi)), 40, radiance, throughput);\n color = vec4(radiance, 1.0);\n}\n`;\n\n/** Texel 0: sky irradiance on the ground. Texel 1: sun transmittance at the camera and the exposure scale. */\nconst IRRADIANCE = COMMON + ELEVATION_MAPPING + /* glsl */ `\nuniform sampler2D uTransmittance;\nuniform sampler2D uSkyView;\nvoid main() {\n vec3 sky = vec3(0.0);\n const int ROWS = 128, COLUMNS = 48;\n for (int i = 0; i < ROWS; i++) {\n float e = (float(i) + 0.5) / float(ROWS) * (PI / 2.0);\n // Mirror-symmetric in azimuth: 2 × half circle, dω = cos e de dφ, cosine = sin e.\n float weight = 2.0 * sin(e) * cos(e) * (PI / 2.0 / float(ROWS)) * (PI / float(COLUMNS));\n for (int j = 0; j < COLUMNS; j++) {\n float phi = (float(j) + 0.5) / float(COLUMNS) * PI;\n sky += fetchLinear(uSkyView, vec2(phi / PI * float(SV_SIZE.x - 1), elevationCoord(e))) * weight;\n }\n }\n if (int(gl_FragCoord.x) == 0) { color = vec4(sky, 1.0); return; }\n float r = R_GROUND + CAMERA_ALTITUDE;\n vec3 sunT = fetchLinear(uTransmittance, vec2((uSun.y + 1.0) * 0.5 * float(T_SIZE.x - 1), altitudeCoord(CAMERA_ALTITUDE) * float(T_SIZE.y - 1)));\n vec3 luma = vec3(0.2126, 0.7152, 0.0722);\n float horizontal = dot(sky, luma) + dot(sunT, luma) * max(uSun.y, 0.0);\n // Half of the change from the reference is compensated, like a camera's\n // partial auto-exposure: low suns stay readable but still look dimmer.\n const float REFERENCE = ${REFERENCE_ILLUMINANCE};\n float scale = ${ILLUMINANCE} / sqrt(max(horizontal, REFERENCE * 1e-3) * REFERENCE);\n color = vec4(sunT, scale);\n}\n`;\n\nconst MAP = COMMON + ELEVATION_MAPPING + /* glsl */ `\nuniform sampler2D uSkyView;\nuniform sampler2D uIrradiance;\nuniform vec2 uSize;\nuniform float uAzimuth;\nuniform vec3 uSunWorld;\nuniform float uSunRadius;\n\n// v = 0 is +Y and u follows atan2(-z, -x), as MuTracer reads equirect maps.\nvec3 mapDirection(vec2 texel) {\n float theta = texel.y / uSize.y * PI;\n float phi = texel.x / uSize.x * 2.0 * PI;\n return vec3(-sin(theta) * cos(phi), cos(theta), -sin(theta) * sin(phi));\n}\n\nvoid main() {\n vec3 dir = mapDirection(gl_FragCoord.xy);\n float relative = abs(atan(dir.z, dir.x) - uAzimuth);\n relative = min(mod(relative, 2.0 * PI), 2.0 * PI - mod(relative, 2.0 * PI));\n float e = asin(clamp(dir.y, -1.0, 1.0));\n vec3 radiance = fetchLinear(uSkyView, vec2(relative / PI * float(SV_SIZE.x - 1), elevationCoord(e)));\n vec4 sun = texelFetch(uIrradiance, ivec2(1, 0), 0);\n // Supersample texels near the sun for an anti-aliased, limb-darkened disk\n // that carries the transmitted unit solar irradiance.\n float texelAngle = PI / uSize.y;\n if (acos(clamp(dot(dir, uSunWorld), -1.0, 1.0)) < uSunRadius + 3.0 * texelAngle / max(sqrt(1.0 - dir.y * dir.y), 0.05)) {\n const int N = 6;\n const float LIMB = 0.6;\n float coverage = 0.0;\n for (int y = 0; y < N; y++) for (int x = 0; x < N; x++) {\n vec3 d = mapDirection(gl_FragCoord.xy - 0.5 + (vec2(x, y) + 0.5) / float(N));\n // Chord length keeps small angles precise in float32.\n float angle = 2.0 * asin(min(length(d - uSunWorld) * 0.5, 1.0));\n float t = angle / uSunRadius;\n if (t < 1.0) coverage += 1.0 - LIMB * (1.0 - sqrt(1.0 - t * t));\n }\n float solidAngle = 2.0 * PI * (1.0 - cos(uSunRadius));\n radiance += coverage / float(N * N) / (solidAngle * (1.0 - LIMB / 3.0)) * sun.rgb;\n }\n color = vec4(radiance * sun.a, 1.0);\n}\n`;\n\nconst VERTEX = /* glsl */ `#version 300 es\nvoid main() {\n vec2 p = vec2(gl_VertexID == 1 ? 3.0 : -1.0, gl_VertexID == 2 ? 3.0 : -1.0);\n gl_Position = vec4(p, 0.0, 1.0);\n}\n`;\n\ninterface Target { texture: WebGLTexture; framebuffer: WebGLFramebuffer; width: number; height: number }\n\n/** Bakes skies with its own WebGL 2 context; requires float render targets. */\nexport class WebGLSkyBaker {\n private readonly gl: WebGL2RenderingContext;\n private readonly programs: Record<'transmittance' | 'multiple' | 'skyView' | 'irradiance' | 'map', WebGLProgram>;\n private readonly targets: Record<'transmittance' | 'multiple' | 'skyView' | 'irradiance', Target>;\n private map?: Target;\n\n constructor() {\n const canvas = typeof OffscreenCanvas !== 'undefined' ? new OffscreenCanvas(1, 1) : document.createElement('canvas');\n const gl = canvas.getContext('webgl2', { antialias: false, depth: false, stencil: false, alpha: false }) as WebGL2RenderingContext | null;\n if (!gl) throw new Error('The procedural sky needs WebGL 2.');\n if (!gl.getExtension('EXT_color_buffer_float')) throw new Error('The procedural sky needs float render targets (EXT_color_buffer_float).');\n this.gl = gl;\n gl.bindVertexArray(gl.createVertexArray());\n this.programs = {\n transmittance: this.program(TRANSMITTANCE),\n multiple: this.program(MULTIPLE),\n skyView: this.program(SKY_VIEW),\n irradiance: this.program(IRRADIANCE),\n map: this.program(MAP)\n };\n this.targets = {\n transmittance: this.target(...T_SIZE),\n multiple: this.target(...MS_SIZE),\n skyView: this.target(...SV_SIZE),\n irradiance: this.target(2, 1)\n };\n }\n\n /** Clear sky at a local solar time, in hours. */\n bake(hours: number, width = 2048, height = 1024): SkyData {\n const gl = this.gl;\n if (gl.isContextLost()) throw new Error('The procedural sky lost its WebGL context.');\n const { elevation, azimuth } = sunPosition(hours);\n const e = deg(elevation), a = deg(azimuth);\n const shared = (program: WebGLProgram) => {\n gl.useProgram(program);\n this.uniform(program, 'uSun', (l) => gl.uniform3f(l, Math.cos(e), Math.sin(e), 0));\n this.uniform(program, 'uTurbidity', (l) => gl.uniform1f(l, TURBIDITY));\n this.uniform(program, 'uAlbedo', (l) => gl.uniform3fv(l, GROUND_ALBEDO));\n return program;\n };\n const { transmittance, multiple, skyView, irradiance } = this.targets;\n const atmosphere = (program: WebGLProgram, full: boolean, sky: number[]) => {\n shared(program);\n this.bind(program, 'uTransmittance', 0, transmittance);\n // The multiple-scattering pass declares but never reads its own target;\n // bind another texture so WebGL sees no feedback loop.\n this.bind(program, 'uMultiple', 1, full ? multiple : irradiance);\n this.uniform(program, 'uFull', (l) => gl.uniform1i(l, full ? 1 : 0));\n this.uniform(program, 'uSkyIrradiance', (l) => gl.uniform3fv(l, sky));\n };\n\n this.draw(shared(this.programs.transmittance), transmittance);\n atmosphere(this.programs.multiple, false, [0, 0, 0]);\n this.draw(this.programs.multiple, multiple);\n // Upward views first: the ground seen below is lit by that sky.\n atmosphere(this.programs.skyView, true, [0, 0, 0]);\n this.draw(this.programs.skyView, skyView);\n shared(this.programs.irradiance);\n this.bind(this.programs.irradiance, 'uTransmittance', 0, transmittance);\n this.bind(this.programs.irradiance, 'uSkyView', 1, skyView);\n this.draw(this.programs.irradiance, irradiance);\n const sky = this.read(irradiance).subarray(0, 3);\n atmosphere(this.programs.skyView, true, Array.from(sky));\n this.draw(this.programs.skyView, skyView);\n\n if (!this.map || this.map.width !== width || this.map.height !== height) {\n if (this.map) this.release(this.map);\n this.map = this.target(width, height);\n }\n const map = shared(this.programs.map);\n this.bind(map, 'uSkyView', 0, skyView);\n this.bind(map, 'uIrradiance', 1, irradiance);\n this.uniform(map, 'uSize', (l) => gl.uniform2f(l, width, height));\n this.uniform(map, 'uAzimuth', (l) => gl.uniform1f(l, a));\n this.uniform(map, 'uSunWorld', (l) => gl.uniform3f(l, Math.cos(e) * Math.cos(a), Math.sin(e), Math.cos(e) * Math.sin(a)));\n this.uniform(map, 'uSunRadius', (l) => gl.uniform1f(l, deg(SUN_RADIUS)));\n this.draw(map, this.map);\n // Row 0 is the zenith, as in an .hdr file.\n return { data: this.read(this.map), width, height };\n }\n\n dispose() {\n this.gl.getExtension('WEBGL_lose_context')?.loseContext();\n }\n\n private program(fragment: string) {\n const gl = this.gl;\n const compile = (type: number, source: string) => {\n const shader = gl.createShader(type)!;\n gl.shaderSource(shader, source);\n gl.compileShader(shader);\n if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) throw new Error(`Sky shader: ${gl.getShaderInfoLog(shader)}`);\n return shader;\n };\n const program = gl.createProgram()!;\n gl.attachShader(program, compile(gl.VERTEX_SHADER, VERTEX));\n gl.attachShader(program, compile(gl.FRAGMENT_SHADER, fragment));\n gl.linkProgram(program);\n if (!gl.getProgramParameter(program, gl.LINK_STATUS)) throw new Error(`Sky program: ${gl.getProgramInfoLog(program)}`);\n return program;\n }\n\n private target(width: number, height: number): Target {\n const gl = this.gl;\n const texture = gl.createTexture()!;\n gl.bindTexture(gl.TEXTURE_2D, texture);\n gl.texStorage2D(gl.TEXTURE_2D, 1, gl.RGBA32F, width, height);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);\n gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);\n const framebuffer = gl.createFramebuffer()!;\n gl.bindFramebuffer(gl.FRAMEBUFFER, framebuffer);\n gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);\n if (gl.checkFramebufferStatus(gl.FRAMEBUFFER) !== gl.FRAMEBUFFER_COMPLETE) throw new Error('The procedural sky cannot render to float textures.');\n return { texture, framebuffer, width, height };\n }\n\n private release(target: Target) {\n this.gl.deleteFramebuffer(target.framebuffer);\n this.gl.deleteTexture(target.texture);\n }\n\n private uniform(program: WebGLProgram, name: string, set: (location: WebGLUniformLocation) => void) {\n const location = this.gl.getUniformLocation(program, name);\n if (location) set(location);\n }\n\n private bind(program: WebGLProgram, name: string, unit: number, target: Target) {\n const gl = this.gl;\n gl.activeTexture(gl.TEXTURE0 + unit);\n gl.bindTexture(gl.TEXTURE_2D, target.texture);\n this.uniform(program, name, (l) => gl.uniform1i(l, unit));\n }\n\n private draw(program: WebGLProgram, target: Target) {\n const gl = this.gl;\n gl.useProgram(program);\n // A texture cannot be sampled while it is the render target.\n gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer);\n gl.viewport(0, 0, target.width, target.height);\n gl.drawArrays(gl.TRIANGLES, 0, 3);\n }\n\n private read(target: Target) {\n const gl = this.gl;\n const data = new Float32Array(target.width * target.height * 4);\n gl.bindFramebuffer(gl.FRAMEBUFFER, target.framebuffer);\n gl.readPixels(0, 0, target.width, target.height, gl.RGBA, gl.FLOAT, data);\n return data;\n }\n}\n\nfunction deg(d: number) {\n return (d * Math.PI) / 180;\n}\n"]}
@@ -0,0 +1,9 @@
1
+ import type { EnvironmentMapSource, EnvironmentSource } from './envMapDistribution.js';
2
+ /** CPU-backed compatibility path for WebGL environment uploads. */
3
+ export declare class WebGLSkySource {
4
+ private baker?;
5
+ private readonly images;
6
+ private sky?;
7
+ resolve(source: EnvironmentSource | undefined): EnvironmentMapSource | undefined;
8
+ dispose(): void;
9
+ }
@@ -0,0 +1,28 @@
1
+ import { WebGLSkyBaker } from './WebGLSkyBaker.js';
2
+ /** CPU-backed compatibility path for WebGL environment uploads. */
3
+ export class WebGLSkySource {
4
+ baker;
5
+ images = new WeakMap();
6
+ sky;
7
+ resolve(source) {
8
+ if (!source || !('sky' in source))
9
+ return source;
10
+ const cached = this.images.get(source);
11
+ if (cached)
12
+ return cached;
13
+ const { width, height, sky: { time }, intensity, ambient } = source;
14
+ this.baker ??= new WebGLSkyBaker();
15
+ if (!this.sky || this.sky.time !== time || this.sky.width !== width || this.sky.height !== height) {
16
+ this.sky = { time, ...this.baker.bake(time, width, height) };
17
+ }
18
+ let data = this.sky.data;
19
+ if (intensity !== 1 || ambient.some(value => value !== 0)) {
20
+ data = data.map((value, index) => index % 4 === 3 ? value : value * intensity + ambient[index % 4]);
21
+ }
22
+ const result = { width, height, data };
23
+ this.images.set(source, result);
24
+ return result;
25
+ }
26
+ dispose() { this.baker?.dispose(); this.baker = undefined; this.sky = undefined; }
27
+ }
28
+ //# sourceMappingURL=WebGLSkySource.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebGLSkySource.js","sourceRoot":"","sources":["../../src/renderer/WebGLSkySource.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,mEAAmE;AACnE,MAAM,OAAO,cAAc;IACjB,KAAK,CAAiB;IACb,MAAM,GAAG,IAAI,OAAO,EAA2C,CAAC;IACzE,GAAG,CAAuE;IAElF,OAAO,CAAC,MAAqC;QAC3C,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAC;YAAE,OAAO,MAAM,CAAC;QACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACvC,IAAI,MAAM;YAAE,OAAO,MAAM,CAAC;QAC1B,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,EAAE,IAAI,EAAE,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,MAAM,CAAC;QACpE,IAAI,CAAC,KAAK,KAAK,IAAI,aAAa,EAAE,CAAC;QACnC,IAAI,CAAC,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,KAAK,KAAK,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;YAClG,IAAI,CAAC,GAAG,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,CAAC;QAC/D,CAAC;QACD,IAAI,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC;QACzB,IAAI,SAAS,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,KAAK,CAAC,CAAC,EAAE,CAAC;YAC1D,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,KAAK,EAAE,EAAE,CAAC,KAAK,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,GAAG,SAAS,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QACtG,CAAC;QACD,MAAM,MAAM,GAAG,EAAE,KAAK,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACvC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAChC,OAAO,MAAM,CAAC;IAChB,CAAC;IACD,OAAO,KAAK,IAAI,CAAC,KAAK,EAAE,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC,IAAI,CAAC,GAAG,GAAG,SAAS,CAAC,CAAC,CAAC;CACnF","sourcesContent":["import type { EnvironmentMapSource, EnvironmentSource } from './envMapDistribution.js';\nimport { WebGLSkyBaker } from './WebGLSkyBaker.js';\n\n/** CPU-backed compatibility path for WebGL environment uploads. */\nexport class WebGLSkySource {\n private baker?: WebGLSkyBaker;\n private readonly images = new WeakMap<EnvironmentSource, EnvironmentMapSource>();\n private sky?: { time: number; width: number; height: number; data: Float32Array };\n\n resolve(source: EnvironmentSource | undefined): EnvironmentMapSource | undefined {\n if (!source || !('sky' in source)) return source;\n const cached = this.images.get(source);\n if (cached) return cached;\n const { width, height, sky: { time }, intensity, ambient } = source;\n this.baker ??= new WebGLSkyBaker();\n if (!this.sky || this.sky.time !== time || this.sky.width !== width || this.sky.height !== height) {\n this.sky = { time, ...this.baker.bake(time, width, height) };\n }\n let data = this.sky.data;\n if (intensity !== 1 || ambient.some(value => value !== 0)) {\n data = data.map((value, index) => index % 4 === 3 ? value : value * intensity + ambient[index % 4]);\n }\n const result = { width, height, data };\n this.images.set(source, result);\n return result;\n }\n dispose() { this.baker?.dispose(); this.baker = undefined; this.sky = undefined; }\n}\n"]}
@@ -10,6 +10,12 @@ export interface TargetPipeline extends RenderPasses {
10
10
  configure(settings: TraceSettings): void;
11
11
  synchronizeBackground(background: Scene['background']): void;
12
12
  canCompleteSampleWithin(timeBudgetMs: number): boolean;
13
+ /** Optional WebGPU throughput controls; do not alter the tile budget. */
14
+ setRealtimeBatchBudget?(milliseconds: number): void;
15
+ setRealtimeDeferPostProcess?(defer: boolean): void;
16
+ getRealtimeSampleTime?(): number | undefined;
17
+ getRealtimeTileTime?(): number | undefined;
18
+ whenTraceAvailable?(): Promise<boolean>;
13
19
  present(): void;
14
20
  readPresentation(): Promise<{
15
21
  width: number;
@@ -1 +1 @@
1
- {"version":3,"file":"accumulationTarget.js","sourceRoot":"","sources":["../../src/renderer/accumulationTarget.ts"],"names":[],"mappings":"","sourcesContent":["import type { Scene } from '../scene/Scene.js';\nimport type { TraceSettings } from './renderPipeline.js';\nimport type { RenderPasses } from './RenderingPipeline.js';\n\n/** Backend-owned execution and outputs of one resident accumulation. */\nexport interface TargetPipeline extends RenderPasses {\n activate(): void;\n invalidateDenoisedOutput(): void;\n /** Refreshes backend timing after structural scene changes; optional without GPU timestamps. */\n invalidateTiming?(): void;\n configure(settings: TraceSettings): void;\n synchronizeBackground(background: Scene['background']): void;\n canCompleteSampleWithin(timeBudgetMs: number): boolean;\n present(): void;\n readPresentation(): Promise<{width: number; height: number; data: Float32Array}>;\n readonly presentationComplete: boolean;\n readonly presentationDenoised: boolean;\n getMemory(): {width: number; height: number; bytes: number};\n}\n"]}
1
+ {"version":3,"file":"accumulationTarget.js","sourceRoot":"","sources":["../../src/renderer/accumulationTarget.ts"],"names":[],"mappings":"","sourcesContent":["import type { Scene } from '../scene/Scene.js';\nimport type { TraceSettings } from './renderPipeline.js';\nimport type { RenderPasses } from './RenderingPipeline.js';\n\n/** Backend-owned execution and outputs of one resident accumulation. */\nexport interface TargetPipeline extends RenderPasses {\n activate(): void;\n invalidateDenoisedOutput(): void;\n /** Refreshes backend timing after structural scene changes; optional without GPU timestamps. */\n invalidateTiming?(): void;\n configure(settings: TraceSettings): void;\n synchronizeBackground(background: Scene['background']): void;\n canCompleteSampleWithin(timeBudgetMs: number): boolean;\n /** Optional WebGPU throughput controls; do not alter the tile budget. */\n setRealtimeBatchBudget?(milliseconds: number): void;\n setRealtimeDeferPostProcess?(defer: boolean): void;\n getRealtimeSampleTime?(): number | undefined;\n getRealtimeTileTime?(): number | undefined;\n whenTraceAvailable?(): Promise<boolean>;\n present(): void;\n readPresentation(): Promise<{width: number; height: number; data: Float32Array}>;\n readonly presentationComplete: boolean;\n readonly presentationDenoised: boolean;\n getMemory(): {width: number; height: number; bytes: number};\n}\n"]}
@@ -0,0 +1,42 @@
1
+ /** Optional primary-surface outputs, separate from beauty and OIDN guides. */
2
+ export type AovKind = 'depth' | 'position' | 'roughness' | 'diffuseAlbedo' | 'specularAlbedo' | 'id' | 'motion';
3
+ export declare const AOV_KINDS: readonly AovKind[];
4
+ export declare const AOV_BACKGROUND_ID = 4294967295;
5
+ export declare const AOV_LAYOUT: {
6
+ readonly accumulatedBytes: 64;
7
+ readonly centerBytes: 32;
8
+ readonly depthRoughness: 0;
9
+ readonly position: 4;
10
+ readonly diffuseAlbedo: 8;
11
+ readonly specularAlbedo: 12;
12
+ readonly id: 0;
13
+ readonly motion: 4;
14
+ };
15
+ export declare function allocateAovId(): number;
16
+ export declare function validateAovId(value: number): number;
17
+ export declare function aovMask(kinds: readonly AovKind[]): number;
18
+ export interface AovInstanceSnapshot {
19
+ object: number;
20
+ instance: number;
21
+ topology: number;
22
+ vertices: number;
23
+ transform: Float32Array;
24
+ }
25
+ export interface AovFrameSnapshot {
26
+ width: number;
27
+ height: number;
28
+ projection: string;
29
+ cameraEye?: Float32Array;
30
+ cameraForward?: Float32Array;
31
+ viewProjection: Float32Array;
32
+ instances: readonly AovInstanceSnapshot[];
33
+ }
34
+ /** Per-render history; camera pose and rigid transforms may change without resetting. */
35
+ export declare class AovHistory {
36
+ private frame?;
37
+ private instances;
38
+ clear(): void;
39
+ previous(next: AovFrameSnapshot): AovFrameSnapshot | undefined;
40
+ match(next: AovFrameSnapshot, instance: AovInstanceSnapshot): AovInstanceSnapshot | undefined;
41
+ accept(frame: AovFrameSnapshot): void;
42
+ }
@@ -0,0 +1,50 @@
1
+ export const AOV_KINDS = ['depth', 'position', 'roughness', 'diffuseAlbedo', 'specularAlbedo', 'id', 'motion'];
2
+ export const AOV_BACKGROUND_ID = 0xffffffff;
3
+ // Four vec4 lanes for accumulated geometry/reflectance; two for center ID/motion.
4
+ // Depth and roughness share a lane; coverage is position.w.
5
+ export const AOV_LAYOUT = { accumulatedBytes: 64, centerBytes: 32,
6
+ depthRoughness: 0, position: 4, diffuseAlbedo: 8, specularAlbedo: 12,
7
+ id: 0, motion: 4 };
8
+ let nextId = 0;
9
+ export function allocateAovId() {
10
+ if (nextId >= AOV_BACKGROUND_ID)
11
+ throw new RangeError('AOV ID space exhausted');
12
+ return nextId++;
13
+ }
14
+ export function validateAovId(value) {
15
+ if (!Number.isInteger(value) || value < 0 || value >= AOV_BACKGROUND_ID)
16
+ throw new RangeError('AOV ID must be uint32 excluding 0xFFFFFFFF');
17
+ return value;
18
+ }
19
+ export function aovMask(kinds) {
20
+ let mask = 0;
21
+ for (const kind of kinds) {
22
+ const index = AOV_KINDS.indexOf(kind);
23
+ if (index < 0)
24
+ throw new RangeError(`Unknown AOV: ${kind}`);
25
+ mask |= 1 << index;
26
+ }
27
+ return mask;
28
+ }
29
+ /** Per-render history; camera pose and rigid transforms may change without resetting. */
30
+ export class AovHistory {
31
+ frame;
32
+ instances = new Map();
33
+ clear() { this.frame = undefined; this.instances.clear(); }
34
+ previous(next) {
35
+ const old = this.frame;
36
+ return old && old.width === next.width && old.height === next.height && old.projection === next.projection ? old : undefined;
37
+ }
38
+ match(next, instance) {
39
+ const old = this.previous(next) ? this.instances.get(`${instance.object}:${instance.instance}`) : undefined;
40
+ return old && old.topology === instance.topology && old.vertices === instance.vertices ? old : undefined;
41
+ }
42
+ accept(frame) {
43
+ this.frame = { ...frame, cameraEye: frame.cameraEye?.slice(), cameraForward: frame.cameraForward?.slice(), viewProjection: frame.viewProjection.slice(),
44
+ instances: frame.instances.map(i => ({ ...i, transform: i.transform.slice() })) };
45
+ this.instances.clear();
46
+ for (const instance of this.frame.instances)
47
+ this.instances.set(`${instance.object}:${instance.instance}`, instance);
48
+ }
49
+ }
50
+ //# sourceMappingURL=aov.js.map