@meimu/mutracer 0.1.4 → 0.2.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 (529) hide show
  1. package/LICENSES/Classroom-CC0.txt +121 -0
  2. package/README.md +7 -7
  3. package/THIRD_PARTY_NOTICES.md +13 -8
  4. package/dist/assets/bvh.worker.js +1 -1
  5. package/dist/mutracer.umd.js +10421 -8363
  6. package/docs/api.md +202 -11
  7. package/docs/denoising.md +30 -15
  8. package/docs/materials.md +18 -27
  9. package/docs/performance.md +5 -2
  10. package/docs/progressive-rendering.md +32 -1
  11. package/docs/threejs.md +19 -10
  12. package/docs/updates.md +44 -2
  13. package/docs/viewer.md +41 -3
  14. package/lib/Display.d.ts +13 -2
  15. package/lib/Display.js +27 -6
  16. package/lib/Display.js.map +1 -1
  17. package/lib/Engine.d.ts +2 -0
  18. package/lib/Engine.js +52 -25
  19. package/lib/Engine.js.map +1 -1
  20. package/lib/Render.d.ts +44 -9
  21. package/lib/Render.js +115 -17
  22. package/lib/Render.js.map +1 -1
  23. package/lib/RenderLoop.d.ts +7 -1
  24. package/lib/RenderLoop.js +94 -13
  25. package/lib/RenderLoop.js.map +1 -1
  26. package/lib/main.d.ts +6 -3
  27. package/lib/main.js +1 -0
  28. package/lib/main.js.map +1 -1
  29. package/lib/math/access.d.ts +4 -0
  30. package/lib/math/access.js +10 -0
  31. package/lib/math/access.js.map +1 -0
  32. package/lib/math/mat3.d.ts +4 -0
  33. package/lib/math/mat3.js +54 -0
  34. package/lib/math/mat3.js.map +1 -0
  35. package/lib/math/mat4.d.ts +19 -0
  36. package/lib/math/mat4.js +413 -0
  37. package/lib/math/mat4.js.map +1 -0
  38. package/lib/math/storage.d.ts +6 -0
  39. package/lib/math/storage.js +22 -0
  40. package/lib/math/storage.js.map +1 -0
  41. package/lib/math/types.d.ts +3 -0
  42. package/lib/math/types.js +2 -0
  43. package/lib/math/types.js.map +1 -0
  44. package/lib/math/vec2.d.ts +13 -0
  45. package/lib/math/vec2.js +52 -0
  46. package/lib/math/vec2.js.map +1 -0
  47. package/lib/math/vec3.d.ts +23 -0
  48. package/lib/math/vec3.js +139 -0
  49. package/lib/math/vec3.js.map +1 -0
  50. package/lib/math.d.ts +5 -17
  51. package/lib/math.js +5 -55
  52. package/lib/math.js.map +1 -1
  53. package/lib/oidn.d.ts +1 -1
  54. package/lib/oidn.js +4 -2
  55. package/lib/oidn.js.map +1 -1
  56. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  57. package/lib/renderer/AovPrimitiveCache.d.ts +10 -0
  58. package/lib/renderer/AovPrimitiveCache.js +48 -0
  59. package/lib/renderer/AovPrimitiveCache.js.map +1 -0
  60. package/lib/renderer/Box3.d.ts +5 -0
  61. package/lib/renderer/Box3.js +9 -0
  62. package/lib/renderer/Box3.js.map +1 -0
  63. package/lib/renderer/GPUTraceQueue.d.ts +10 -0
  64. package/lib/renderer/GPUTraceQueue.js +31 -0
  65. package/lib/renderer/GPUTraceQueue.js.map +1 -0
  66. package/lib/renderer/MaterialData.d.ts +15 -0
  67. package/lib/renderer/MaterialData.js +61 -0
  68. package/lib/renderer/MaterialData.js.map +1 -0
  69. package/lib/renderer/MaterialTable.d.ts +11 -98
  70. package/lib/renderer/MaterialTable.js +34 -412
  71. package/lib/renderer/MaterialTable.js.map +1 -1
  72. package/lib/renderer/RenderingPipeline.d.ts +32 -13
  73. package/lib/renderer/RenderingPipeline.js +1 -17
  74. package/lib/renderer/RenderingPipeline.js.map +1 -1
  75. package/lib/renderer/TileRender.d.ts +0 -1
  76. package/lib/renderer/TileRender.js +14 -1
  77. package/lib/renderer/TileRender.js.map +1 -1
  78. package/lib/renderer/WGPUAov.d.ts +39 -0
  79. package/lib/renderer/WGPUAov.js +239 -0
  80. package/lib/renderer/WGPUAov.js.map +1 -0
  81. package/lib/renderer/WGPUBindlessMaterialData.d.ts +17 -0
  82. package/lib/renderer/WGPUBindlessMaterialData.js +48 -0
  83. package/lib/renderer/WGPUBindlessMaterialData.js.map +1 -0
  84. package/lib/renderer/WGPUBindlessTextures.d.ts +47 -0
  85. package/lib/renderer/WGPUBindlessTextures.js +180 -0
  86. package/lib/renderer/WGPUBindlessTextures.js.map +1 -0
  87. package/lib/renderer/WGPUBloomPass.js +17 -97
  88. package/lib/renderer/WGPUBloomPass.js.map +1 -1
  89. package/lib/renderer/WGPUComputePass.d.ts +1 -1
  90. package/lib/renderer/WGPUComputePass.js.map +1 -1
  91. package/lib/renderer/WGPUEnvMapDistribution.d.ts +12 -0
  92. package/lib/renderer/WGPUEnvMapDistribution.js +150 -0
  93. package/lib/renderer/WGPUEnvMapDistribution.js.map +1 -0
  94. package/lib/renderer/WGPUFullQuadPass.js +10 -9
  95. package/lib/renderer/WGPUFullQuadPass.js.map +1 -1
  96. package/lib/renderer/WGPUJNLMDenoiser.d.ts +1 -20
  97. package/lib/renderer/WGPUJNLMDenoiser.js +4 -267
  98. package/lib/renderer/WGPUJNLMDenoiser.js.map +1 -1
  99. package/lib/renderer/WGPURayTraceOutput.js +26 -17
  100. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  101. package/lib/renderer/WGPURayTracePass.d.ts +36 -40
  102. package/lib/renderer/WGPURayTracePass.js +399 -548
  103. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  104. package/lib/renderer/WGPURenderingPipeline.d.ts +5 -3
  105. package/lib/renderer/WGPURenderingPipeline.js +239 -60
  106. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  107. package/lib/renderer/WGPUShaderCache.d.ts +2 -2
  108. package/lib/renderer/WGPUShaderCache.js +10 -5
  109. package/lib/renderer/WGPUShaderCache.js.map +1 -1
  110. package/lib/renderer/WGPUShaderCapabilities.d.ts +10 -0
  111. package/lib/renderer/WGPUShaderCapabilities.js +54 -0
  112. package/lib/renderer/WGPUShaderCapabilities.js.map +1 -0
  113. package/lib/renderer/WGPUSkyBaker.d.ts +13 -0
  114. package/lib/renderer/WGPUSkyBaker.js +85 -0
  115. package/lib/renderer/WGPUSkyBaker.js.map +1 -0
  116. package/lib/renderer/WebGLAov.d.ts +41 -0
  117. package/lib/renderer/WebGLAov.js +106 -0
  118. package/lib/renderer/WebGLAov.js.map +1 -0
  119. package/lib/renderer/WebGLFullQuadPass.d.ts +5 -3
  120. package/lib/renderer/WebGLFullQuadPass.js +18 -2
  121. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  122. package/lib/renderer/WebGLJNLMDenoiser.d.ts +1 -1
  123. package/lib/renderer/WebGLJNLMDenoiser.js +83 -74
  124. package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
  125. package/lib/renderer/WebGLRayTraceOutputPass.js +7 -4
  126. package/lib/renderer/WebGLRayTraceOutputPass.js.map +1 -1
  127. package/lib/renderer/WebGLRayTracePass.d.ts +12 -2
  128. package/lib/renderer/WebGLRayTracePass.js +83 -7
  129. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  130. package/lib/renderer/WebGLRenderingPipeline.js +116 -8
  131. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  132. package/lib/renderer/WebGLSkyBaker.d.ts +39 -0
  133. package/lib/renderer/WebGLSkyBaker.js +422 -0
  134. package/lib/renderer/WebGLSkyBaker.js.map +1 -0
  135. package/lib/renderer/WebGLSkySource.d.ts +9 -0
  136. package/lib/renderer/WebGLSkySource.js +28 -0
  137. package/lib/renderer/WebGLSkySource.js.map +1 -0
  138. package/lib/renderer/accumulationTarget.d.ts +5 -0
  139. package/lib/renderer/accumulationTarget.js.map +1 -1
  140. package/lib/renderer/aov.d.ts +42 -0
  141. package/lib/renderer/aov.js +50 -0
  142. package/lib/renderer/aov.js.map +1 -0
  143. package/lib/renderer/aovDisplay.d.ts +14 -0
  144. package/lib/renderer/aovDisplay.js +32 -0
  145. package/lib/renderer/aovDisplay.js.map +1 -0
  146. package/lib/renderer/aovScene.d.ts +21 -0
  147. package/lib/renderer/aovScene.js +139 -0
  148. package/lib/renderer/aovScene.js.map +1 -0
  149. package/lib/renderer/binnedSahBvh.js +2 -1
  150. package/lib/renderer/binnedSahBvh.js.map +1 -1
  151. package/lib/renderer/bvhAccel.d.ts +20 -10
  152. package/lib/renderer/bvhAccel.js +168 -58
  153. package/lib/renderer/bvhAccel.js.map +1 -1
  154. package/lib/renderer/bvhWorkerBuild.d.ts +1 -0
  155. package/lib/renderer/cameraSnapshot.js +2 -1
  156. package/lib/renderer/cameraSnapshot.js.map +1 -1
  157. package/lib/renderer/cameraUniform.d.ts +2 -0
  158. package/lib/renderer/cameraUniform.js +12 -0
  159. package/lib/renderer/cameraUniform.js.map +1 -0
  160. package/lib/renderer/committedScene.js +4 -0
  161. package/lib/renderer/committedScene.js.map +1 -1
  162. package/lib/renderer/denoiser.d.ts +3 -11
  163. package/lib/renderer/denoiser.js.map +1 -1
  164. package/lib/renderer/depthQuery.js +4 -1
  165. package/lib/renderer/depthQuery.js.map +1 -1
  166. package/lib/renderer/displacementPreparation.d.ts +11 -0
  167. package/lib/renderer/displacementPreparation.js +351 -0
  168. package/lib/renderer/displacementPreparation.js.map +1 -0
  169. package/lib/renderer/displacementRange.d.ts +1 -0
  170. package/lib/renderer/displacementRange.js +9 -0
  171. package/lib/renderer/displacementRange.js.map +1 -0
  172. package/lib/renderer/displayParityDiagnostics.d.ts +11 -0
  173. package/lib/renderer/displayParityDiagnostics.js +2 -0
  174. package/lib/renderer/displayParityDiagnostics.js.map +1 -0
  175. package/lib/renderer/envMapCreation.d.ts +9 -8
  176. package/lib/renderer/envMapCreation.js +36 -12
  177. package/lib/renderer/envMapCreation.js.map +1 -1
  178. package/lib/renderer/envMapDistribution.d.ts +12 -2
  179. package/lib/renderer/envMapDistribution.js +43 -34
  180. package/lib/renderer/envMapDistribution.js.map +1 -1
  181. package/lib/renderer/geometryBvhBounds.d.ts +4 -0
  182. package/lib/renderer/geometryBvhBounds.js +82 -0
  183. package/lib/renderer/geometryBvhBounds.js.map +1 -0
  184. package/lib/renderer/geometryUpdateState.d.ts +32 -0
  185. package/lib/renderer/geometryUpdateState.js +2 -0
  186. package/lib/renderer/geometryUpdateState.js.map +1 -0
  187. package/lib/renderer/geometryUpdates.d.ts +17 -9
  188. package/lib/renderer/geometryUpdates.js +92 -33
  189. package/lib/renderer/geometryUpdates.js.map +1 -1
  190. package/lib/renderer/glsl/aovDisplay.frag.d.ts +3 -0
  191. package/lib/renderer/glsl/aovDisplay.frag.js +54 -0
  192. package/lib/renderer/glsl/aovDisplay.frag.js.map +1 -0
  193. package/lib/renderer/glsl/aovReflectance.glsl.d.ts +2 -0
  194. package/lib/renderer/glsl/aovReflectance.glsl.js +87 -0
  195. package/lib/renderer/glsl/aovReflectance.glsl.js.map +1 -0
  196. package/lib/renderer/glsl/aovReflectanceSamples.glsl.d.ts +2 -0
  197. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +135 -0
  198. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js.map +1 -0
  199. package/lib/renderer/glsl/aovTrace.frag.d.ts +2 -0
  200. package/lib/renderer/glsl/aovTrace.frag.js +121 -0
  201. package/lib/renderer/glsl/aovTrace.frag.js.map +1 -0
  202. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
  203. package/lib/renderer/glsl/chunks/envMap.glsl.js +80 -74
  204. package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
  205. package/lib/renderer/glsl/chunks/intersect.glsl.js +437 -435
  206. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  207. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +146 -145
  208. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  209. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +821 -821
  210. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
  211. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  212. package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
  213. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +51 -51
  214. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  215. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +80 -80
  216. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +108 -108
  217. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  218. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +20 -17
  219. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -1
  220. package/lib/renderer/glsl/chunks/sampling.glsl.js +93 -93
  221. package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
  222. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  223. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +12 -12
  224. package/lib/renderer/glsl/chunks/uvProjection.glsl.js.map +1 -1
  225. package/lib/renderer/glsl/depthQuery.frag.js +7 -7
  226. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +17 -9
  227. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js.map +1 -1
  228. package/lib/renderer/glsl/rayTrace.frag.js +191 -191
  229. package/lib/renderer/glsl/shadowCatcher.frag.js +25 -20
  230. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  231. package/lib/renderer/glsl/webglPipeline.frag.js +65 -60
  232. package/lib/renderer/glsl/webglPipeline.frag.js.map +1 -1
  233. package/lib/renderer/lightConstants.d.ts +10 -0
  234. package/lib/renderer/lightConstants.js +11 -0
  235. package/lib/renderer/lightConstants.js.map +1 -0
  236. package/lib/renderer/lightCore.d.ts +12 -0
  237. package/lib/renderer/lightCore.js +13 -0
  238. package/lib/renderer/lightCore.js.map +1 -0
  239. package/lib/renderer/lightSampling.d.ts +20 -17
  240. package/lib/renderer/lightSampling.js +123 -56
  241. package/lib/renderer/lightSampling.js.map +1 -1
  242. package/lib/renderer/lightsData.d.ts +21 -0
  243. package/lib/renderer/lightsData.js +192 -0
  244. package/lib/renderer/lightsData.js.map +1 -0
  245. package/lib/renderer/lightsUtil.d.ts +3 -26
  246. package/lib/renderer/lightsUtil.js +3 -153
  247. package/lib/renderer/lightsUtil.js.map +1 -1
  248. package/lib/renderer/materialBufferData.d.ts +70 -0
  249. package/lib/renderer/materialBufferData.js +2 -0
  250. package/lib/renderer/materialBufferData.js.map +1 -0
  251. package/lib/renderer/materialConstants.d.ts +11 -0
  252. package/lib/renderer/materialConstants.js +11 -0
  253. package/lib/renderer/materialConstants.js.map +1 -1
  254. package/lib/renderer/materialCore.d.ts +8 -0
  255. package/lib/renderer/materialCore.js +9 -0
  256. package/lib/renderer/materialCore.js.map +1 -0
  257. package/lib/renderer/materialEmission.d.ts +2 -2
  258. package/lib/renderer/materialEmission.js +3 -3
  259. package/lib/renderer/materialEmission.js.map +1 -1
  260. package/lib/renderer/materialLayout.d.ts +2 -101
  261. package/lib/renderer/materialLayout.js +110 -172
  262. package/lib/renderer/materialLayout.js.map +1 -1
  263. package/lib/renderer/materialLayoutSchema.d.ts +26 -0
  264. package/lib/renderer/materialLayoutSchema.js +172 -0
  265. package/lib/renderer/materialLayoutSchema.js.map +1 -0
  266. package/lib/renderer/materialParams.d.ts +69 -0
  267. package/lib/renderer/materialParams.js +272 -0
  268. package/lib/renderer/materialParams.js.map +1 -0
  269. package/lib/renderer/materialTextureSlots.d.ts +14 -324
  270. package/lib/renderer/materialTextureSlots.js +21 -8
  271. package/lib/renderer/materialTextureSlots.js.map +1 -1
  272. package/lib/renderer/materialTextures.d.ts +6 -0
  273. package/lib/renderer/{texturesFromMaterials.js → materialTextures.js} +1 -2
  274. package/lib/renderer/materialTextures.js.map +1 -0
  275. package/lib/renderer/mergeMeshesToGeometry.js +6 -147
  276. package/lib/renderer/mergeMeshesToGeometry.js.map +1 -1
  277. package/lib/renderer/meshInstances.d.ts +4 -21
  278. package/lib/renderer/meshInstances.js +10 -56
  279. package/lib/renderer/meshInstances.js.map +1 -1
  280. package/lib/renderer/oidnNetwork.d.ts +2 -2
  281. package/lib/renderer/oidnNetwork.js +1 -1
  282. package/lib/renderer/oidnNetwork.js.map +1 -1
  283. package/lib/renderer/openPbrEnergyLut.js +850 -846
  284. package/lib/renderer/openPbrEnergyLut.js.map +1 -1
  285. package/lib/renderer/ownedDenoiser.d.ts +9 -0
  286. package/lib/renderer/ownedDenoiser.js +2 -0
  287. package/lib/renderer/ownedDenoiser.js.map +1 -0
  288. package/lib/renderer/packedMeshInstances.d.ts +23 -0
  289. package/lib/renderer/packedMeshInstances.js +80 -0
  290. package/lib/renderer/packedMeshInstances.js.map +1 -0
  291. package/lib/renderer/prepareMeshBVH.d.ts +12 -47
  292. package/lib/renderer/prepareMeshBVH.js +21 -642
  293. package/lib/renderer/prepareMeshBVH.js.map +1 -1
  294. package/lib/renderer/proceduralEnvironmentPower.d.ts +3 -0
  295. package/lib/renderer/proceduralEnvironmentPower.js +8 -0
  296. package/lib/renderer/proceduralEnvironmentPower.js.map +1 -0
  297. package/lib/renderer/progressiveScheduler.d.ts +1 -0
  298. package/lib/renderer/progressiveScheduler.js +3 -0
  299. package/lib/renderer/progressiveScheduler.js.map +1 -1
  300. package/lib/renderer/renderPipeline.d.ts +3 -1
  301. package/lib/renderer/renderPipeline.js.map +1 -1
  302. package/lib/renderer/renderingLimits.d.ts +9 -0
  303. package/lib/renderer/renderingLimits.js +18 -0
  304. package/lib/renderer/renderingLimits.js.map +1 -0
  305. package/lib/renderer/sceneAssembly.d.ts +73 -0
  306. package/lib/renderer/sceneAssembly.js +109 -0
  307. package/lib/renderer/sceneAssembly.js.map +1 -0
  308. package/lib/renderer/sceneChangeCore.d.ts +39 -0
  309. package/lib/renderer/sceneChangeCore.js +307 -0
  310. package/lib/renderer/sceneChangeCore.js.map +1 -0
  311. package/lib/renderer/sceneChangeDetector.d.ts +3 -6
  312. package/lib/renderer/sceneChangeDetector.js +24 -150
  313. package/lib/renderer/sceneChangeDetector.js.map +1 -1
  314. package/lib/renderer/sceneLayoutSchema.d.ts +118 -0
  315. package/lib/renderer/sceneLayoutSchema.js +111 -0
  316. package/lib/renderer/sceneLayoutSchema.js.map +1 -0
  317. package/lib/renderer/sceneLightChanges.d.ts +3 -3
  318. package/lib/renderer/sceneLightChanges.js.map +1 -1
  319. package/lib/renderer/scenePreparation.d.ts +55 -0
  320. package/lib/renderer/scenePreparation.js +360 -0
  321. package/lib/renderer/scenePreparation.js.map +1 -0
  322. package/lib/renderer/scratchSampling.js +18 -18
  323. package/lib/renderer/scratchSampling.js.map +1 -1
  324. package/lib/renderer/shader.d.ts +2 -0
  325. package/lib/renderer/shader.js +2 -0
  326. package/lib/renderer/shader.js.map +1 -1
  327. package/lib/renderer/shaderCapabilities.d.ts +23 -0
  328. package/lib/renderer/shaderCapabilities.js +55 -0
  329. package/lib/renderer/shaderCapabilities.js.map +1 -0
  330. package/lib/renderer/shaderCapacity.d.ts +2 -0
  331. package/lib/renderer/shaderCapacity.js +5 -0
  332. package/lib/renderer/shaderCapacity.js.map +1 -0
  333. package/lib/renderer/skyModel.d.ts +9 -0
  334. package/lib/renderer/skyModel.js +10 -0
  335. package/lib/renderer/skyModel.js.map +1 -0
  336. package/lib/renderer/textureAtlas.d.ts +60 -0
  337. package/lib/renderer/textureAtlas.js +145 -0
  338. package/lib/renderer/textureAtlas.js.map +1 -0
  339. package/lib/renderer/textureAtlasPixels.d.ts +7 -0
  340. package/lib/renderer/textureAtlasPixels.js +68 -0
  341. package/lib/renderer/textureAtlasPixels.js.map +1 -0
  342. package/lib/renderer/util.d.ts +1 -1
  343. package/lib/renderer/util.js.map +1 -1
  344. package/lib/renderer/webgl.d.ts +9 -2
  345. package/lib/renderer/webgl.js +54 -9
  346. package/lib/renderer/webgl.js.map +1 -1
  347. package/lib/renderer/wgpuBindless.d.ts +26 -0
  348. package/lib/renderer/wgpuBindless.js +95 -0
  349. package/lib/renderer/wgpuBindless.js.map +1 -0
  350. package/lib/renderer/wgpuBindlessSource.d.ts +2 -0
  351. package/lib/renderer/wgpuBindlessSource.js +51 -0
  352. package/lib/renderer/wgpuBindlessSource.js.map +1 -0
  353. package/lib/renderer/wgpuMaterialConstants.d.ts +4 -0
  354. package/lib/renderer/wgpuMaterialConstants.js +52 -0
  355. package/lib/renderer/wgpuMaterialConstants.js.map +1 -0
  356. package/lib/renderer/wgpuSceneUniform.d.ts +42 -0
  357. package/lib/renderer/wgpuSceneUniform.js +125 -0
  358. package/lib/renderer/wgpuSceneUniform.js.map +1 -0
  359. package/lib/renderer/wgpuShaderSource.d.ts +15 -0
  360. package/lib/renderer/wgpuShaderSource.js +31 -0
  361. package/lib/renderer/wgpuShaderSource.js.map +1 -0
  362. package/lib/renderer/wgsl/aovDisplay.wgsl.d.ts +1 -0
  363. package/lib/renderer/wgsl/aovDisplay.wgsl.js +70 -0
  364. package/lib/renderer/wgsl/aovDisplay.wgsl.js.map +1 -0
  365. package/lib/renderer/wgsl/aovReflectance.wgsl.d.ts +2 -0
  366. package/lib/renderer/wgsl/aovReflectance.wgsl.js +98 -0
  367. package/lib/renderer/wgsl/aovReflectance.wgsl.js.map +1 -0
  368. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.d.ts +2 -0
  369. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +135 -0
  370. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js.map +1 -0
  371. package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +5 -0
  372. package/lib/renderer/wgsl/aovResolve.wgsl.js +38 -0
  373. package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -0
  374. package/lib/renderer/wgsl/aovSnapshot.wgsl.d.ts +4 -0
  375. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +21 -0
  376. package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -0
  377. package/lib/renderer/wgsl/aovTrace.wgsl.d.ts +2 -0
  378. package/lib/renderer/wgsl/aovTrace.wgsl.js +115 -0
  379. package/lib/renderer/wgsl/aovTrace.wgsl.js.map +1 -0
  380. package/lib/renderer/wgsl/bloom.wgsl.d.ts +13 -0
  381. package/lib/renderer/wgsl/bloom.wgsl.js +92 -0
  382. package/lib/renderer/wgsl/bloom.wgsl.js.map +1 -0
  383. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  384. package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
  385. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +43 -37
  386. package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
  387. package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +13 -1
  388. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +743 -706
  389. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  390. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +16 -16
  391. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
  392. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +3 -1
  393. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +86 -83
  394. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  395. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +855 -857
  396. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js.map +1 -1
  397. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
  398. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  399. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +2 -1
  400. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +42 -32
  401. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  402. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
  403. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +152 -148
  404. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
  405. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +239 -232
  406. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  407. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
  408. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +26 -13
  409. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
  410. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +91 -91
  411. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +1 -1
  412. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +1 -0
  413. package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -1
  414. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
  415. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +12 -12
  416. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js.map +1 -1
  417. package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +8 -3
  418. package/lib/renderer/wgsl/compose.frag.wgsl.js +143 -118
  419. package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
  420. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  421. package/lib/renderer/wgsl/depthQuery.wgsl.js +7 -7
  422. package/lib/renderer/wgsl/jnlm.compute.d.ts +25 -0
  423. package/lib/renderer/wgsl/jnlm.compute.js +315 -0
  424. package/lib/renderer/wgsl/jnlm.compute.js.map +1 -0
  425. package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
  426. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.d.ts +1 -0
  427. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +17 -0
  428. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js.map +1 -0
  429. package/lib/renderer/wgsl/proceduralSky.compute.d.ts +1 -0
  430. package/lib/renderer/wgsl/proceduralSky.compute.js +198 -0
  431. package/lib/renderer/wgsl/proceduralSky.compute.js.map +1 -0
  432. package/lib/renderer/wgsl/rayTrace.compute.d.ts +17 -1
  433. package/lib/renderer/wgsl/rayTrace.compute.js +612 -393
  434. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  435. package/lib/scene/Camera.js +7 -3
  436. package/lib/scene/Camera.js.map +1 -1
  437. package/lib/scene/EnvironmentLight.d.ts +5 -9
  438. package/lib/scene/EnvironmentLight.js +4 -14
  439. package/lib/scene/EnvironmentLight.js.map +1 -1
  440. package/lib/scene/EnvironmentLightState.d.ts +18 -0
  441. package/lib/scene/EnvironmentLightState.js +19 -0
  442. package/lib/scene/EnvironmentLightState.js.map +1 -0
  443. package/lib/scene/Geometry.d.ts +12 -6
  444. package/lib/scene/Geometry.js +37 -13
  445. package/lib/scene/Geometry.js.map +1 -1
  446. package/lib/scene/InstanceState.d.ts +39 -0
  447. package/lib/scene/InstanceState.js +77 -0
  448. package/lib/scene/InstanceState.js.map +1 -0
  449. package/lib/scene/InstancedMesh.d.ts +1 -1
  450. package/lib/scene/InstancedMesh.js +3 -0
  451. package/lib/scene/InstancedMesh.js.map +1 -1
  452. package/lib/scene/MaterialState.d.ts +209 -0
  453. package/lib/scene/MaterialState.js +231 -0
  454. package/lib/scene/MaterialState.js.map +1 -0
  455. package/lib/scene/Mesh.d.ts +4 -6
  456. package/lib/scene/Mesh.js +3 -11
  457. package/lib/scene/Mesh.js.map +1 -1
  458. package/lib/scene/MeshState.d.ts +20 -0
  459. package/lib/scene/MeshState.js +35 -0
  460. package/lib/scene/MeshState.js.map +1 -0
  461. package/lib/scene/OpenPBRMaterial.d.ts +7 -169
  462. package/lib/scene/OpenPBRMaterial.js +5 -223
  463. package/lib/scene/OpenPBRMaterial.js.map +1 -1
  464. package/lib/scene/PixelTexture.d.ts +6 -0
  465. package/lib/scene/PixelTexture.js +10 -0
  466. package/lib/scene/PixelTexture.js.map +1 -0
  467. package/lib/scene/ProceduralSky.d.ts +24 -0
  468. package/lib/scene/ProceduralSky.js +40 -0
  469. package/lib/scene/ProceduralSky.js.map +1 -0
  470. package/lib/scene/RectLight.d.ts +2 -13
  471. package/lib/scene/RectLight.js +3 -21
  472. package/lib/scene/RectLight.js.map +1 -1
  473. package/lib/scene/RectLightState.d.ts +31 -0
  474. package/lib/scene/RectLightState.js +26 -0
  475. package/lib/scene/RectLightState.js.map +1 -0
  476. package/lib/scene/Scene.d.ts +15 -4
  477. package/lib/scene/Scene.js.map +1 -1
  478. package/lib/scene/SceneNode.js +7 -6
  479. package/lib/scene/SceneNode.js.map +1 -1
  480. package/lib/scene/Texture.d.ts +10 -41
  481. package/lib/scene/Texture.js +4 -33
  482. package/lib/scene/Texture.js.map +1 -1
  483. package/lib/scene/TextureState.d.ts +35 -0
  484. package/lib/scene/TextureState.js +35 -0
  485. package/lib/scene/TextureState.js.map +1 -0
  486. package/lib/scene/attributeData.d.ts +4 -0
  487. package/lib/scene/attributeData.js +10 -0
  488. package/lib/scene/attributeData.js.map +1 -0
  489. package/lib/scene/lightState.d.ts +8 -0
  490. package/lib/scene/lightState.js +2 -0
  491. package/lib/scene/lightState.js.map +1 -0
  492. package/lib/scene/openPbrSchema.d.ts +7 -12
  493. package/lib/scene/openPbrSchema.js +273 -28
  494. package/lib/scene/openPbrSchema.js.map +1 -1
  495. package/lib/scene/skyParameters.d.ts +20 -0
  496. package/lib/scene/skyParameters.js +28 -0
  497. package/lib/scene/skyParameters.js.map +1 -0
  498. package/lib/scene/textureData.d.ts +9 -0
  499. package/lib/scene/textureData.js +2 -0
  500. package/lib/scene/textureData.js.map +1 -0
  501. package/lib/scene/texturePixels.d.ts +6 -0
  502. package/lib/scene/texturePixels.js +10 -0
  503. package/lib/scene/texturePixels.js.map +1 -0
  504. package/lib/settings/display.d.ts +33 -0
  505. package/lib/settings/display.js +7 -0
  506. package/lib/settings/display.js.map +1 -1
  507. package/lib/settings/render.d.ts +25 -3
  508. package/lib/settings/render.js +3 -1
  509. package/lib/settings/render.js.map +1 -1
  510. package/lib/tinybvh/tinybvh.wasm +0 -0
  511. package/lib/util/commonGeometry.js +7 -7
  512. package/lib/util/commonGeometry.js.map +1 -1
  513. package/lib/util/fromTHREE.d.ts +4 -1
  514. package/lib/util/fromTHREE.js +18 -5
  515. package/lib/util/fromTHREE.js.map +1 -1
  516. package/lib/util/geometry.js +42 -29
  517. package/lib/util/geometry.js.map +1 -1
  518. package/lib/util/loadRGBE.js +3 -4
  519. package/lib/util/loadRGBE.js.map +1 -1
  520. package/lib/util/studioLighting.d.ts +18 -0
  521. package/lib/util/studioLighting.js +36 -0
  522. package/lib/util/studioLighting.js.map +1 -0
  523. package/lib/version.d.ts +1 -1
  524. package/lib/version.js +1 -1
  525. package/lib/version.js.map +1 -1
  526. package/llms.txt +4 -0
  527. package/package.json +31 -5
  528. package/lib/renderer/texturesFromMaterials.d.ts +0 -6
  529. package/lib/renderer/texturesFromMaterials.js.map +0 -1
@@ -1,9 +1,16 @@
1
+ import { hdrResolveWGSL } from './wgsl/compose.frag.wgsl.js';
2
+ import { oidnAuxiliaryDefine } from './wgsl/oidnAuxiliary.wgsl.js';
3
+ import { displayAovKind, DEFAULT_AOV_DISPLAY } from './aovDisplay.js';
4
+ import { WGPUAov } from './WGPUAov.js';
5
+ import { aovMask } from './aov.js';
6
+ import { scheduleFrame } from '../util/frame.js';
1
7
  import { DisplayPostProcess } from './DisplayPostProcess.js';
2
8
  import { customDenoiseLayersMain, customDenoiseCoverageMain } from './wgsl/customDenoise.wgsl.js';
3
9
  import { WGPUCanvasSurface } from './WGPUCanvasSurface.js';
4
10
  import { WGPUScratchBuffer } from './WGPUScratchBuffer.js';
5
11
  import { WGPUScratchTexture } from './WGPUScratchTexture.js';
6
12
  import { ScratchPool } from './ScratchPool.js';
13
+ import { GPUTraceQueue } from './GPUTraceQueue.js';
7
14
  import { makeRenderPipeline } from './renderPipeline.js';
8
15
  import { textureBytes } from './gpuMemory.js';
9
16
  import { WGPUFullQuadPass } from './WGPUFullQuadPass.js';
@@ -21,54 +28,44 @@ export const oidnAlbedoSrgbEncodeMain = /* wgsl */ `
21
28
  if (globalId.x >= u32(imageSize.x) || globalId.y >= u32(imageSize.y)) { return; }
22
29
  let index = globalId.x + globalId.y * u32(imageSize.x);
23
30
  let raw = textureLoad(in_albedo, vec2u(globalId.xy), 0);
24
- let linear = clamp(raw.rgb, vec3f(0.0), vec3f(1.0));
25
- let encoded = select(
26
- 1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055,
27
- 12.92 * linear,
28
- linear <= vec3f(0.0031308)
29
- );
31
+ let encoded = sT(raw.rgb);
30
32
  out_albedo[index] = vec4f(encoded, raw.a);
31
33
  `;
32
34
  export const oidnAlbedoSrgbDecodeMain = /* wgsl */ `
33
35
  if (globalId.x >= u32(imageSize.x) || globalId.y >= u32(imageSize.y)) { return; }
34
36
  let index = globalId.x + globalId.y * u32(imageSize.x);
35
37
  let filtered = in_albedo[index];
36
- let encoded = clamp(filtered.rgb, vec3f(0.0), vec3f(1.0));
37
- let linear = select(
38
- pow((encoded + 0.055) / 1.055, vec3f(2.4)),
39
- encoded / 12.92,
40
- encoded <= vec3f(0.04045)
41
- );
38
+ let linear = sS(filtered.rgb);
42
39
  var result = linear;
43
- let jg = textureLoad(in_rawAlbedo, vec2i(globalId.xy), 0).a;
40
+ let jD = textureLoad(in_rawAlbedo, vec2i(globalId.xy), 0).a;
44
41
  if (preserveSurfaceTexture != 0u) {
45
42
 
46
43
 
47
44
 
48
- let fP = vec2i(globalId.xy);
49
- let center = textureLoad(in_rawNormal, fP, 0);
45
+ let pixel = vec2i(globalId.xy);
46
+ let center = textureLoad(in_rawNormal, pixel, 0);
50
47
  let n = normalize(center.rgb * 2.0 - 1.0 + vec3f(1e-8));
51
- var ng = 0.0;
48
+ var oc = 0.0;
52
49
  for (var y = -1; y <= 1; y++) {
53
50
  for (var x = -1; x <= 1; x++) {
54
- let tV = textureLoad(in_rawNormal,
55
- clamp(fP + vec2i(x, y), vec2i(0), imageSize - 1), 0);
56
- let nn = normalize(tV.rgb * 2.0 - 1.0 + vec3f(1e-8));
57
- ng = max(ng,
58
- max(1.0 - dot(n, nn), abs(center.a - tV.a)));
51
+ let vw = textureLoad(in_rawNormal,
52
+ clamp(pixel + vec2i(x, y), vec2i(0), imageSize - 1), 0);
53
+ let nn = normalize(vw.rgb * 2.0 - 1.0 + vec3f(1e-8));
54
+ oc = max(oc,
55
+ max(1.0 - dot(n, nn), abs(center.a - vw.a)));
59
56
  }
60
57
  }
61
- let un = smoothstep(0.02, 0.1, ng);
62
- let raw = clamp(textureLoad(in_rawAlbedo, fP, 0).rgb,
58
+ let vO = smoothstep(0.02, 0.1, oc);
59
+ let raw = clamp(textureLoad(in_rawAlbedo, pixel, 0).rgb,
63
60
  vec3f(0.0), vec3f(1.0));
64
- result = mix(raw, linear, un);
61
+ result = mix(raw, linear, vO);
65
62
  }
66
- out_albedo[index] = vec4f(result, jg);
63
+ out_albedo[index] = vec4f(result, jD);
67
64
  `;
68
65
  export const oidnNormalSanitizeMain = /* wgsl */ `
69
66
  if (globalId.x >= u32(imageSize.x) || globalId.y >= u32(imageSize.y)) { return; }
70
67
  let index = globalId.x + globalId.y * u32(imageSize.x);
71
- out_normal[index] = vec4f(clamp(in_normal[index].rgb, vec3f(0.0), vec3f(1.0)), 1.0);
68
+ out_normal[index] = vec4f(rL(in_normal[index].rgb), 1.0);
72
69
  `;
73
70
  function createTimeQuery(device) {
74
71
  try {
@@ -95,17 +92,25 @@ function createTimeQuery(device) {
95
92
  return undefined;
96
93
  }
97
94
  }
98
- function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scratch, customJobs) {
95
+ function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scratch, customJobs, traceQueue) {
99
96
  let sampleRenderedCallback = () => { };
100
- let allowMultipleSamplesPerFrame = false;
97
+ let batchSamples = false;
98
+ let realtimeBatchBudgetMs = Infinity;
99
+ // Samples traced between display frames skip the resolve and composition;
100
+ // the next presentation or read resolves them once.
101
+ let realtimeDeferPostProcess = false;
102
+ let postProcessPending = false;
101
103
  let offlineSamplesPerBatch = 0;
102
104
  let deferPostProcess = false;
103
105
  let sampleSequenceOffset = 0;
106
+ const aov = new WGPUAov(device);
107
+ let aovCamera;
104
108
  let sampleCount = 0;
105
109
  let elapsedFrameTime = 32;
106
110
  let elapsedTileTime;
107
111
  let tileTimingGeneration = 0;
108
112
  let lastGpuTraceTiming;
113
+ let displayTrace;
109
114
  let diagnosticsReadbackPromise = Promise.resolve();
110
115
  let isFirstFrame = true;
111
116
  let disposed = false;
@@ -127,6 +132,8 @@ function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scrat
127
132
  let denoiseValid = false;
128
133
  let maxTimePerTile = 21;
129
134
  let bloomIntensity = 0;
135
+ // Sample count of this accumulation's last bloom refresh.
136
+ let bloomSamples = 0;
130
137
  let bloomThreshold = 1;
131
138
  let bloomRadius = 0.6;
132
139
  let exposure = 1;
@@ -139,6 +146,7 @@ function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scrat
139
146
  let hdrOutputRequested = false;
140
147
  let hdrOutputActive = false;
141
148
  let output = 'final';
149
+ let aovDisplayOptions = DEFAULT_AOV_DISPLAY;
142
150
  let shadowCatcherColor = vec3.create();
143
151
  let shadowCatcherAlpha = 1;
144
152
  let pageLeaveTime = performance.now();
@@ -248,12 +256,14 @@ function makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scrat
248
256
  inputs: ['colorTex', 'coverageTex'],
249
257
  outputs: ['color'],
250
258
  uniforms: [{ label: 'flatBackgroundColor', type: 'vec4f', data: [0, 0, 0, 0] }],
259
+ fsDefine: hdrResolveWGSL,
251
260
  fsMain: /* wgsl */ `
252
261
  var color = load_colorTex(uv, 0);
253
262
  let coverage = clamp(load_coverageTex(uv, 0).a, 0.0, 1.0);
254
- if (flatBackgroundColor.a > 0.5 && coverage > 0.0) {
255
- color = vec4f(color.rgb * coverage, color.a);
256
- }
263
+ color = vec4f(
264
+ jQ(color.r, coverage, flatBackgroundColor.a > 0.5, true),
265
+ jQ(color.g, coverage, flatBackgroundColor.a > 0.5, true),
266
+ jQ(color.b, coverage, flatBackgroundColor.a > 0.5, true), color.a);
257
267
  output.color = color;
258
268
  `
259
269
  }));
@@ -337,7 +347,6 @@ output.color = color;
337
347
  fsMain: compositeDenoiseDisplayMain,
338
348
  fsDefine: linearToSrgbDefine,
339
349
  uniforms: [
340
- { label: 'hdrOutputEnabled', type: 'f32', data: 0 },
341
350
  { label: 'denoisedAlpha', type: 'f32', data: 0 }
342
351
  ],
343
352
  outputs: ['color'], inputs: ['colorTex', 'composedTex']
@@ -354,6 +363,7 @@ output.color = color;
354
363
  inputs: ['albedo'],
355
364
  outputs: ['albedo'],
356
365
  uniforms: auxiliaryPassUniforms,
366
+ csDefine: oidnAuxiliaryDefine,
357
367
  csMain: oidnAlbedoSrgbEncodeMain
358
368
  }));
359
369
  const oidnAlbedoDecodePass = scratch.get('oidnAlbedoDecodePass', () => new WGPUComputePass('OIDN albedo sRGB decode', device, {
@@ -362,12 +372,14 @@ output.color = color;
362
372
  uniforms: [...auxiliaryPassUniforms, {
363
373
  label: 'preserveSurfaceTexture', type: 'u32', data: 0
364
374
  }],
375
+ csDefine: oidnAuxiliaryDefine,
365
376
  csMain: oidnAlbedoSrgbDecodeMain
366
377
  }));
367
378
  const oidnNormalSanitizePass = scratch.get('oidnNormalSanitizePass', () => new WGPUComputePass('OIDN normal sanitize', device, {
368
379
  inputs: ['normal'],
369
380
  outputs: ['normal'],
370
381
  uniforms: auxiliaryPassUniforms,
382
+ csDefine: oidnAuxiliaryDefine,
371
383
  csMain: oidnNormalSanitizeMain
372
384
  }));
373
385
  oidnAlbedoEncodePass.setOutputParams({ albedo: { channels: 4 } });
@@ -375,11 +387,11 @@ output.color = color;
375
387
  oidnNormalSanitizePass.setOutputParams({ normal: { channels: 4 } });
376
388
  const outputPass = scratch.get('outputPass', () => new WGPUFullQuadPass('output', device, {
377
389
  fsMain: /* wgsl */ `
378
- let vM = min(
390
+ let xs = min(
379
391
  vec2i(uv2 * vec2f(colorTexRegion())),
380
392
  vec2i(colorTexRegion()) - vec2i(1)
381
393
  );
382
- var color = load_colorTex(vM, 0);
394
+ var color = load_colorTex(xs, 0);
383
395
  color = vec4(color.rgb * color.a, color.a);
384
396
  output.color = color;
385
397
  `,
@@ -498,7 +510,6 @@ output.color = color;
498
510
  composePass.setUniform('shadowCatcherAlpha', shadowCatcherAlpha);
499
511
  compositeDenoiseDisplayPass.setSize(renderWidth, renderHeight);
500
512
  compositeDenoiseDisplayPass.setOutputParams({ color: { format: composeColorFormat } });
501
- compositeDenoiseDisplayPass.setUniform('hdrOutputEnabled', +hdrOutputActive);
502
513
  compositeDenoiseDisplayPass.setUniform('denoisedAlpha', denoiseValid && denoisedDisplayLinear ? +rayTracePass.needsDenoiseAlpha() : 0);
503
514
  }
504
515
  function snapshotInput(encoder, key, texture, exact = false) {
@@ -529,6 +540,15 @@ output.color = color;
529
540
  }
530
541
  composePass.setUniform('flatBackgroundColor', resolvedFlatBackground);
531
542
  rawOutputPass.setUniform('flatBackgroundColor', resolvedFlatBackground);
543
+ const aovKind = displayAovKind(output);
544
+ if (aovKind && sampleCount === 0) {
545
+ if (!execution?.aovs?.includes(aovKind))
546
+ throw new Error(`AOV ${aovKind} is not enabled`);
547
+ if (!aov.samples)
548
+ return;
549
+ finishPresentation(encoder, aov.visualize(aovKind, aovDisplayOptions, hdrOutputActive));
550
+ return;
551
+ }
532
552
  if (resolvedSamples < 1)
533
553
  return;
534
554
  prepareComposition();
@@ -550,17 +570,18 @@ output.color = color;
550
570
  }));
551
571
  layers.setOutputParams({ foreground: { format: 'rgba32float' }, background: { format: 'rgba32float' } });
552
572
  layers.setSize(renderWidth, renderHeight);
573
+ displayTrace?.push('CorrectLayers:SceneLinear');
553
574
  layers.createPass(encoder, { originalTex: getFrameInput('color'), filteredTex: denoisedTexture,
554
575
  foregroundTex: foregroundTexture, backgroundTex: catcherBackgroundTexture });
555
576
  foregroundTexture = layers.getOutput('foreground');
556
577
  catcherBackgroundTexture = layers.getOutput('background');
557
578
  }
558
579
  const bloomEnabled = bloomIntensity > 0.0;
559
- // Progressive accumulation refreshes bloom every ten samples.
560
- const samplesSkipped = sampleCount < 10 || sampleCount % 10 > 0;
580
+ // Progressive accumulation refreshes bloom after every ten new samples,
581
+ // including when several samples are resolved at once.
561
582
  const bloomState = scratch.get('bloom state', () => ({ owner: undefined, settings: '', dispose() { } }));
562
583
  const bloomSettings = `${bloomThreshold}/${bloomRadius}/${+(denoiseValid && denoisedHDR)}`;
563
- const needsUpdateBloom = bloomEnabled && sampleCount >= 10 && (!samplesSkipped || bloomState.owner !== targetKey || bloomState.settings !== bloomSettings);
584
+ const needsUpdateBloom = bloomEnabled && sampleCount >= 10 && (sampleCount - bloomSamples >= 10 || bloomState.owner !== targetKey || bloomState.settings !== bloomSettings);
564
585
  let bloomIntensityToUpdate = bloomIntensity;
565
586
  if (needsUpdateBloom) {
566
587
  if (!bloomPass) {
@@ -570,14 +591,17 @@ output.color = color;
570
591
  bloomPass.setSize(renderWidth, renderHeight);
571
592
  bloomState.owner = targetKey;
572
593
  bloomState.settings = bloomSettings;
594
+ bloomSamples = sampleCount;
573
595
  bloomPass.setBrightThreshold(bloomThreshold);
574
596
  bloomPass.setRadius(bloomRadius);
597
+ displayTrace?.push('Bloom:SceneLinear');
575
598
  bloomPass.createPass(encoder, colorTexture);
576
599
  }
577
600
  else if (bloomEnabled && sampleCount < 10) {
578
601
  bloomIntensityToUpdate = 0;
579
602
  }
580
603
  composePass.setUniform('bloomIntensity', bloomIntensityToUpdate);
604
+ displayTrace?.push('Compose:DisplayLinear+DisplayEncoded');
581
605
  composePass.createPass(encoder, {
582
606
  colorTex: colorTexture,
583
607
  foregroundTex: foregroundTexture,
@@ -588,6 +612,7 @@ output.color = color;
588
612
  bloomTex: bloomEnabled && bloomPass ? bloomPass.getOutput() : colorTexture
589
613
  });
590
614
  if (denoiseValid && !denoisedHDR && denoisedDisplayLinear && denoisedTexture) {
615
+ displayTrace?.push('Encode:DisplayEncoded');
591
616
  compositeDenoiseDisplayPass.createPass(encoder, {
592
617
  colorTex: denoisedTexture,
593
618
  composedTex: composePass.getOutput('denoiseColor')
@@ -596,14 +621,24 @@ output.color = color;
596
621
  let displayTexture = (denoiseValid && denoisedBuffer ? (denoisedHDR ? composePass.getOutput('color') : denoisedDisplayLinear
597
622
  ? compositeDenoiseDisplayPass.getOutput('color') : denoisedTexture) : undefined) ||
598
623
  composePass.getOutput('color');
624
+ if (aovKind) {
625
+ if (!execution?.aovs?.includes(aovKind))
626
+ throw new Error(`AOV ${aovKind} is not enabled`);
627
+ displayTexture = aov.visualize(aovKind, aovDisplayOptions, hdrOutputActive);
628
+ }
629
+ finishPresentation(encoder, displayTexture);
630
+ }
631
+ function finishPresentation(encoder, displayTexture) {
599
632
  const activeHDRPeakMeter = hdrOutputActive
600
633
  ? (hdrPeakMeter ??= scratch.get('hdrPeak', () => new WGPUHDRPeakMeter(device)))
601
634
  : undefined;
602
635
  const hdrPeakReadbackSubmitted = activeHDRPeakMeter?.encode(encoder, displayTexture, renderWidth, renderHeight) ?? false;
603
636
  if (output === 'normal' || output === 'albedo') {
637
+ displayTrace?.push('AOV:Raw');
604
638
  displayTexture = getFrameInput(output);
605
639
  }
606
640
  else if (output === 'shadowCatcher') {
641
+ displayTrace?.push('AOV:Raw');
607
642
  displayTexture = getFrameInput('shadowCatcher');
608
643
  }
609
644
  if (displayTexture.width < renderWidth || displayTexture.height < renderHeight) {
@@ -632,6 +667,12 @@ output.color = color;
632
667
  void activeHDRPeakMeter?.resolve();
633
668
  }
634
669
  }
670
+ function flushPostProcess() {
671
+ if (!postProcessPending)
672
+ return;
673
+ postProcessPending = false;
674
+ drawPostProcess(device.createCommandEncoder(), false, true);
675
+ }
635
676
  function trace(camera, maxSamples) {
636
677
  // A call to draw means accumulation has been invalidated. Cancel OIDN
637
678
  // before checking shader compilation: pipeline-affecting parameter changes
@@ -645,8 +686,13 @@ output.color = color;
645
686
  }
646
687
  // Update the camera before compiling and sampling.
647
688
  rayTracePass.setCamera(camera);
689
+ aovCamera = camera;
648
690
  const resetAccumulation = isFirstFrame;
691
+ if (resetAccumulation)
692
+ aov.reset();
649
693
  if (resetAccumulation) {
694
+ postProcessPending = false;
695
+ bloomSamples = 0;
650
696
  denoiseValid = false;
651
697
  tileTimingGeneration++;
652
698
  elapsedTileTime = undefined;
@@ -662,6 +708,8 @@ output.color = color;
662
708
  sampleCount = 0;
663
709
  return true;
664
710
  }
711
+ if (execution?.aovs?.length && !rayTracePass.prepareAovs(execution.aovs))
712
+ return true;
665
713
  // Keep the last completed denoise visible while a static while-converging batch
666
714
  // accumulates, including the incomplete first sample after a scene edit.
667
715
  if (!preserveDenoisedOutput || isFirstFrame) {
@@ -687,16 +735,32 @@ output.color = color;
687
735
  needsUpdatePredicting = false;
688
736
  }
689
737
  const frameSampleCount = sampleCount;
738
+ const sampleTimeMs = lastGpuTraceTiming?.estimatedFullFrameTimeMs;
739
+ const realtime = offlineSamplesPerBatch === 0 && batchSamples;
740
+ const realtimeBudget = Math.min(maxTimePerTile, realtimeBatchBudgetMs);
741
+ if (realtime && !resetAccumulation && !isPredictingFrame && sampleTimeMs !== undefined &&
742
+ traceQueue.available(realtimeBudget) < Math.min(sampleTimeMs, realtimeBudget))
743
+ return false;
744
+ // Only batch a measured, unchanged full-frame workload. New cameras get
745
+ // their first sample immediately; expensive samples retain tiled execution.
746
+ const realtimeBatch = realtime && sampleCount > 0 &&
747
+ !resetAccumulation && !isPredictingFrame && lastGpuTraceTiming?.tileCount === 1 && sampleTimeMs !== undefined &&
748
+ sampleTimeMs <= realtimeBudget / 2;
749
+ const realtimeSamples = realtimeBatch
750
+ ? Math.min(64, Math.floor(traceQueue.available(realtimeBudget) / sampleTimeMs)) : 1;
751
+ if (realtimeBatch && realtimeSamples === 0)
752
+ return false;
753
+ const batchStarted = performance.now();
690
754
  _startRecordFrameTime(!resetAccumulation);
691
755
  const renderSampleTarget = maxSamples;
692
- const batchTarget = Math.min(renderSampleTarget, sampleCount + Math.max(offlineSamplesPerBatch, 1));
756
+ const batchTarget = Math.min(renderSampleTarget, sampleCount + (offlineSamplesPerBatch > 0 ? offlineSamplesPerBatch : realtimeSamples));
693
757
  do {
694
758
  let { xIndex, yIndex, columns, rows, isFirstTile, isLastTile, samplesPerFrame } = (tileRenderWithPredict || tileRender).nextTile(elapsedTileTime);
695
759
  rayTraceOutputPass.setSampleTileGrid(columns, rows);
696
- if (offlineSamplesPerBatch > 0 && columns * rows === 1) {
760
+ if ((offlineSamplesPerBatch > 0 || realtimeBatch) && columns * rows === 1) {
697
761
  samplesPerFrame = batchTarget - sampleCount;
698
762
  }
699
- else if (!allowMultipleSamplesPerFrame) {
763
+ else if (!batchSamples) {
700
764
  samplesPerFrame = 1;
701
765
  }
702
766
  if (columns * rows === 1) {
@@ -708,11 +772,21 @@ output.color = color;
708
772
  sample(sampleCount === 0, [1, 1]);
709
773
  sampleCount++;
710
774
  samplesSubmitted++;
775
+ if (realtime && !isPredictingFrame && sampleTimeMs !== undefined)
776
+ traceQueue.track(sampleTimeMs);
777
+ if (realtimeBatch) {
778
+ // Encoding many tiny samples must also leave the main thread free
779
+ // to receive camera input. Yield before encoding another batch.
780
+ if (performance.now() - batchStarted >= 4)
781
+ break;
782
+ }
711
783
  }
712
784
  }
713
785
  else {
714
786
  rayTracePass.setSampleTiles(columns, rows, xIndex, yIndex);
715
787
  sample(sampleCount === 0 && isFirstTile, [columns, rows]);
788
+ if (realtime && !isPredictingFrame && sampleTimeMs !== undefined)
789
+ traceQueue.track(sampleTimeMs / (columns * rows));
716
790
  if (isLastTile)
717
791
  sampleCount++;
718
792
  }
@@ -727,7 +801,14 @@ output.color = color;
727
801
  sampleCount = 0;
728
802
  return false;
729
803
  }
730
- if (sampleCount !== frameSampleCount && (!deferPostProcess || sampleCount >= renderSampleTarget)) {
804
+ if (sampleCount !== frameSampleCount && execution?.aovs?.length) {
805
+ rayTracePass.renderAovs(aov, camera, sampleCount, execution.aovSamples ?? 16, execution.aovs);
806
+ }
807
+ if (sampleCount !== frameSampleCount && realtime && realtimeDeferPostProcess && sampleCount < renderSampleTarget) {
808
+ postProcessPending = true;
809
+ }
810
+ else if (sampleCount !== frameSampleCount && (!deferPostProcess || sampleCount >= renderSampleTarget)) {
811
+ postProcessPending = false;
731
812
  const encoder = device.createCommandEncoder();
732
813
  drawPostProcess(encoder, sampleCount >= renderSampleTarget, true);
733
814
  }
@@ -856,7 +937,6 @@ output.color = color;
856
937
  hdrPeakMeter?.reset();
857
938
  }
858
939
  compositeDenoiseDisplayPass.setOutputParams({ color: { format: composeColorFormat } });
859
- compositeDenoiseDisplayPass.setUniform('hdrOutputEnabled', hdrOutputActive ? 1 : 0);
860
940
  composePass.setUniform('hdrOutputEnabled', hdrOutputActive ? 1 : 0);
861
941
  return wasActive !== hdrOutputActive;
862
942
  }
@@ -893,6 +973,7 @@ output.color = color;
893
973
  jnlmPass ??= scratch.get('jnlm', () => new WGPUJNLMDenoisePass(device));
894
974
  const rayBuffers = rayTracePass.getOutputBuffer();
895
975
  const encoder = device.createCommandEncoder({ label: 'JNLM denoise' });
976
+ displayTrace?.push('Denoise:DisplayLinear');
896
977
  const output = jnlmPass.encode(encoder, {
897
978
  width: renderWidth,
898
979
  height: renderHeight,
@@ -917,7 +998,7 @@ output.color = color;
917
998
  return completed;
918
999
  });
919
1000
  }
920
- function performCustomDenoise(denoiser, schedule, signal) {
1001
+ function performCustomDenoise(denoiser, schedule, signal, requestedAovs = []) {
921
1002
  const generation = denoiseGeneration;
922
1003
  const controller = activeCustomController = new AbortController();
923
1004
  const abort = () => controller.abort();
@@ -932,7 +1013,15 @@ output.color = color;
932
1013
  const albedo = copyGuide('Custom albedo', getFrameInput('albedo'), true);
933
1014
  const normal = copyGuide('Custom normal', getFrameInput('normal'), true);
934
1015
  const output = scratch.get('Custom output', () => new WGPUScratchBuffer(device)).get(width * height * 16, true);
935
- await denoiser.denoise({ device, width, height, color, albedo, normal, output }, { signal: controller.signal, schedule });
1016
+ const aovs = requestedAovs.length ? aov.snapshot(requestedAovs) : undefined;
1017
+ displayTrace?.push('Denoise:SceneLinear');
1018
+ try {
1019
+ await denoiser.denoise({ device, width, height, color, albedo, normal, output, aovs }, { signal: controller.signal, schedule });
1020
+ }
1021
+ finally {
1022
+ if (aovs)
1023
+ void device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => aov.releaseSnapshot(aovs));
1024
+ }
936
1025
  if (controller.signal.aborted || disposed || generation !== denoiseGeneration)
937
1026
  return false;
938
1027
  const coverage = scratch.get('custom coverage', () => new WGPUComputePass('Custom coverage', device, {
@@ -965,8 +1054,11 @@ output.color = color;
965
1054
  cancelDenoise();
966
1055
  if (isFirstFrame || sampleCount < 1)
967
1056
  return Promise.resolve(false);
1057
+ if (output !== 'final' && output !== 'shadow')
1058
+ return Promise.resolve(true);
1059
+ flushPostProcess();
968
1060
  if (attachedDenoiser.kind === 'custom')
969
- return performCustomDenoise(attachedDenoiser.denoiser, denoiseSchedule, signal);
1061
+ return performCustomDenoise(attachedDenoiser.denoiser, denoiseSchedule, signal, attachedDenoiser.aovs);
970
1062
  denoisedHDR = false;
971
1063
  if (attachedDenoiser.kind === 'jnlm')
972
1064
  return performJNLMDenoise(attachedDenoiser.denoiser);
@@ -991,7 +1083,7 @@ output.color = color;
991
1083
  wholeImage: denoiseSchedule === 'every-sample'
992
1084
  } : {}),
993
1085
  // A preview frame is one whole-image pass. Settled images can take many
994
- // tiles; oidn-web 0.5 runs those back to back by default, which starves
1086
+ // tiles; oidn-webgpu runs those back to back by default, which starves
995
1087
  // the page at 4K, so pace them to display frames instead.
996
1088
  scheduling: denoiseSchedule === 'every-sample' ? 'event-loop' : 'animation-frame'
997
1089
  };
@@ -1081,6 +1173,7 @@ output.color = color;
1081
1173
  return Promise.resolve();
1082
1174
  // Snapshot the complete raw composition; never feed a previous denoise
1083
1175
  // back into the network during progressive updates.
1176
+ displayTrace?.push('Denoise:DisplayLinear');
1084
1177
  return runOIDNPhase(generation, (finish, fail) => denoiser.tileExecute({
1085
1178
  ...convergingTileOptions,
1086
1179
  color: { data: colorInput, ...size },
@@ -1189,6 +1282,7 @@ output.color = color;
1189
1282
  diagnosticsReadbackPromise
1190
1283
  ]).then(() => {
1191
1284
  rayTracePass.releaseTarget(targetKey);
1285
+ aov.dispose();
1192
1286
  denoisedBuffer?.destroy();
1193
1287
  presentationTexture?.destroy();
1194
1288
  displayPostProcess.dispose();
@@ -1215,9 +1309,26 @@ output.color = color;
1215
1309
  const timingKeys = ['bounces', 'bevel', 'bevelSamples', 'directLightCandidates', 'dispersionWavelengths', 'alphaBlendStrategy', 'samplingPattern', 'clamping', 'transmissiveOutputAlphaMin'];
1216
1310
  if (!execution || timingKeys.some(key => execution[key] !== settings[key]))
1217
1311
  invalidateTilePrediction();
1218
- execution = { ...settings };
1312
+ if (settings.aovs?.length && (!Number.isInteger(settings.aovSamples ?? 16) || (settings.aovSamples ?? 16) < 1))
1313
+ throw new RangeError('aovSamples must be a positive integer');
1314
+ const previousMask = aovMask(execution?.aovs ?? []), nextMask = aovMask(settings.aovs ?? []);
1315
+ if (previousMask !== nextMask || execution?.aovSamples !== settings.aovSamples)
1316
+ aov.samples = 0;
1317
+ execution = { ...settings, aovs: [...(settings.aovs ?? [])] };
1318
+ // Presentation may still name the previous preview's AOV. Drop that
1319
+ // selection before tracing with a smaller set; Display validates and
1320
+ // reapplies the current channel when the new image is presented.
1321
+ const displayedAov = displayAovKind(output);
1322
+ if (displayedAov && !settings.aovs?.includes(displayedAov))
1323
+ output = 'final';
1324
+ if (previousMask && !nextMask) {
1325
+ aov.dispose();
1326
+ aov.history.clear();
1327
+ aov.width = aov.height = 0;
1328
+ aov.reset();
1329
+ }
1219
1330
  maxTimePerTile = Math.max(1, settings.timeBudgetMs);
1220
- allowMultipleSamplesPerFrame = settings.allowMultipleSamplesPerFrame;
1331
+ batchSamples = settings.batchSamples;
1221
1332
  tileRender.setDesiredMsPerTile(maxTimePerTile);
1222
1333
  tileRender.setMaxTiles(settings.maxTiles);
1223
1334
  tileRenderWithPredict?.setDesiredMsPerTile(maxTimePerTile);
@@ -1228,6 +1339,10 @@ output.color = color;
1228
1339
  canCompleteSampleWithin(timeBudgetMs) {
1229
1340
  return (lastGpuTraceTiming?.estimatedFullFrameTimeMs ?? elapsedFrameTime) <= timeBudgetMs;
1230
1341
  },
1342
+ setRealtimeBatchBudget(milliseconds) { realtimeBatchBudgetMs = milliseconds; },
1343
+ setRealtimeDeferPostProcess(defer) { realtimeDeferPostProcess = defer; },
1344
+ getRealtimeSampleTime() { return lastGpuTraceTiming?.tileCount === 1 ? lastGpuTraceTiming.estimatedFullFrameTimeMs : undefined; },
1345
+ whenTraceAvailable() { return traceQueue.whenAvailable(); },
1231
1346
  get presentationComplete() { return !!presentationTexture; },
1232
1347
  get presentationDenoised() { return presentationDenoised; },
1233
1348
  present() {
@@ -1242,13 +1357,14 @@ output.color = color;
1242
1357
  getMemory() {
1243
1358
  return {
1244
1359
  width: renderWidth, height: renderHeight,
1245
- bytes: rayTracePass.getTargetMemoryBytes(targetKey) + rayTraceOutputPass.getMemoryBytes() + textureBytes(presentationTexture) + displayPostProcess.getMemoryBytes() + (denoisedBuffer?.size ?? 0)
1360
+ bytes: aov.bytes + rayTracePass.getTargetMemoryBytes(targetKey) + rayTraceOutputPass.getMemoryBytes() + textureBytes(presentationTexture) + displayPostProcess.getMemoryBytes() + (denoisedBuffer?.size ?? 0)
1246
1361
  };
1247
1362
  },
1248
1363
  isFirstFrame() {
1249
1364
  return isFirstFrame;
1250
1365
  },
1251
1366
  restartSamples() {
1367
+ aov.reset();
1252
1368
  // Input edits reset accumulation, not learned throughput. Re-arming a
1253
1369
  // hidden probe here starves continuously changing scenes of visible samples.
1254
1370
  tileTimingGeneration++;
@@ -1257,16 +1373,17 @@ output.color = color;
1257
1373
  denoiseValid = false;
1258
1374
  presentationDenoised = false;
1259
1375
  resolvedSamples = 0;
1376
+ postProcessPending = false;
1377
+ bloomSamples = 0;
1260
1378
  (tileRenderWithPredict || tileRender).reset();
1261
1379
  isPredictingFrame = false;
1262
1380
  isFirstFrame = true;
1263
1381
  sampleCount = 0;
1264
1382
  },
1265
1383
  getOutputTexture(kind) {
1266
- if (resolvedSamples < 1)
1267
- return;
1384
+ flushPostProcess();
1268
1385
  if (kind === 'hdr')
1269
- return getFrameInput('color');
1386
+ return resolvedSamples > 0 ? getFrameInput('color') : undefined;
1270
1387
  return displayPostProcess.output ?? presentationTexture;
1271
1388
  },
1272
1389
  applyPostProcesses(passes, render) {
@@ -1275,8 +1392,9 @@ output.color = color;
1275
1392
  },
1276
1393
  trace,
1277
1394
  drawPostProcess() {
1278
- const encoder = device.createCommandEncoder();
1279
- drawPostProcess(encoder, true);
1395
+ const resolve = postProcessPending;
1396
+ postProcessPending = false;
1397
+ drawPostProcess(device.createCommandEncoder(), true, resolve);
1280
1398
  },
1281
1399
  performDenoise,
1282
1400
  cancelDenoise,
@@ -1291,9 +1409,11 @@ output.color = color;
1291
1409
  const bytesPerRow = Math.ceil(width * 16 / 256) * 256;
1292
1410
  const buffer = device.createBuffer({ size: bytesPerRow * height, usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ });
1293
1411
  const encoder = device.createCommandEncoder();
1294
- readbackPass.setSize(width, height);
1295
- readbackPass.createPass(encoder, { inputTex: image });
1296
- encoder.copyTextureToBuffer({ texture: readbackPass.getOutput('color') }, { buffer, bytesPerRow }, { width, height });
1412
+ const presentationReadback = hdrOutputActive && displayAovKind(output) ? scratch.get('AOV encoded readback', () => new WGPUFullQuadPass('AOV encoded readback', device, { textureWillBeRead: true, inputs: ['inputTex'], outputs: ['color'], fsMain: `let c=load_inputTex(uv,0);let rgb=select(1.055*pow(max(c.rgb,vec3f(0.0)),vec3f(1.0/2.4))-0.055,12.92*c.rgb,c.rgb<=vec3f(0.0031308));output.color=vec4f(rgb,c.a);` })) : readbackPass;
1413
+ presentationReadback.setOutputParams({ color: { format: 'rgba32float' } });
1414
+ presentationReadback.setSize(width, height);
1415
+ presentationReadback.createPass(encoder, { inputTex: image });
1416
+ encoder.copyTextureToBuffer({ texture: presentationReadback.getOutput('color') }, { buffer, bytesPerRow }, { width, height });
1297
1417
  device.queue.submit([encoder.finish()]);
1298
1418
  try {
1299
1419
  await buffer.mapAsync(GPUMapMode.READ);
@@ -1308,7 +1428,32 @@ output.color = color;
1308
1428
  buffer.destroy();
1309
1429
  }
1310
1430
  },
1431
+ aovReady(kind) { return !!execution?.aovs?.includes(kind) && aov.samples > 0; },
1432
+ getAovSamples() { return aov.samples; },
1433
+ restartAovs() { aov.reset(); },
1434
+ refineAovs(camera, samples = sampleCount) {
1435
+ if (samples < 1 || !execution?.aovs?.length)
1436
+ return true;
1437
+ rayTracePass.setCamera(camera);
1438
+ aovCamera = camera;
1439
+ rayTracePass.updatePipeline();
1440
+ if (rayTracePass.isCompilingShader() || !rayTracePass.isPipelineReady())
1441
+ return false;
1442
+ return rayTracePass.renderAovs(aov, camera, samples, execution.aovSamples ?? 16, execution.aovs);
1443
+ },
1444
+ async readAov(kind) {
1445
+ if (!execution?.aovs?.includes(kind) || !aovCamera || (sampleCount < 1 && aov.samples < 1))
1446
+ throw new Error('AOV output is not ready');
1447
+ rayTracePass.setCamera(aovCamera);
1448
+ while (!rayTracePass.renderAovs(aov, aovCamera, Math.max(sampleCount, aov.samples), execution.aovSamples ?? 16, execution.aovs)) {
1449
+ if (disposed)
1450
+ throw new Error('AOV compilation was interrupted');
1451
+ await new Promise(resolve => scheduleFrame(() => resolve()));
1452
+ }
1453
+ return aov.read(kind);
1454
+ },
1311
1455
  async readOutput(kind) {
1456
+ flushPostProcess();
1312
1457
  rawOutputPass.setUniform('flatBackgroundColor', resolvedFlatBackground);
1313
1458
  const width = renderWidth, height = renderHeight;
1314
1459
  const bytesPerRow = Math.ceil(width * 16 / 256) * 256;
@@ -1377,6 +1522,38 @@ output.color = color;
1377
1522
  getTotalSamplesRendered() {
1378
1523
  return sampleCount;
1379
1524
  },
1525
+ /** @internal */
1526
+ _displayParity() {
1527
+ return {
1528
+ record(trace) { displayTrace = trace; },
1529
+ load(input) {
1530
+ cancelDenoise();
1531
+ clearDenoisedOutput();
1532
+ setSize(input.width, input.height);
1533
+ rayTracePass.useTarget(targetKey);
1534
+ rayTracePass.setSize(renderWidth, renderHeight, screenWidth / screenHeight);
1535
+ const buffers = rayTracePass.getOutputBuffer();
1536
+ const shadow = new Float32Array(input.width * input.height * 12);
1537
+ for (let i = 0; i < input.width * input.height; i++) {
1538
+ shadow.set(input.shadow.subarray(i * 8, i * 8 + 8), i * 12);
1539
+ shadow.set(input.moments.subarray(i * 4, i * 4 + 4), i * 12 + 8);
1540
+ }
1541
+ for (const [buffer, data] of [[buffers.color, input.color], [buffers.albedo, input.albedo],
1542
+ [buffers.normal, input.normal], [buffers.shadowCatcher, shadow]])
1543
+ device.queue.writeBuffer(buffer, 0, data);
1544
+ sampleCount = resolvedSamples = input.samples;
1545
+ resolvedHasShadowCatcher = input.catcher;
1546
+ isFirstFrame = false;
1547
+ postProcessPending = false;
1548
+ bloomSamples = 0;
1549
+ rayTraceOutputPass.setSampleCount(sampleCount);
1550
+ rayTraceOutputPass.setSampleTileGrid(1, 1);
1551
+ const encoder = device.createCommandEncoder();
1552
+ rayTraceOutputPass.createPass(encoder, buffers, resolvedHasShadowCatcher);
1553
+ device.queue.submit([encoder.finish()]);
1554
+ }
1555
+ };
1556
+ },
1380
1557
  getDiagnostics() {
1381
1558
  return {
1382
1559
  ...rayTracePass.getDiagnostics(),
@@ -1421,6 +1598,7 @@ output.color = color;
1421
1598
  setOnSampleRendered(cb) {
1422
1599
  sampleRenderedCallback = cb;
1423
1600
  },
1601
+ setAovDisplayOptions(options) { aovDisplayOptions = { ...options, depthRange: [...options.depthRange] }; },
1424
1602
  setOutput(nextOutput) {
1425
1603
  if (output === nextOutput)
1426
1604
  return false;
@@ -1432,7 +1610,8 @@ output.color = color;
1432
1610
  }
1433
1611
  /** Independent render targets, without preview or presentation policy. */
1434
1612
  export function makeWGPURenderTargets(canvas, device, options = {}) {
1435
- const rayTracePass = new WGPURayTracePass(device);
1613
+ const rayTracePass = new WGPURayTracePass(device, options.materialTextures);
1614
+ const traceQueue = new GPUTraceQueue(device.queue);
1436
1615
  const customJobs = new Set();
1437
1616
  const scratch = new ScratchPool(work => {
1438
1617
  // A cancelled custom filter can keep submitting GPU work until its promise settles.
@@ -1443,7 +1622,7 @@ export function makeWGPURenderTargets(canvas, device, options = {}) {
1443
1622
  });
1444
1623
  const surface = scratch.get('canvas', () => new WGPUCanvasSurface(canvas, device, options.presentationFormat ?? navigator.gpu.getPreferredCanvasFormat()));
1445
1624
  return makeRenderPipeline(rayTracePass, () => {
1446
- const target = makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scratch, customJobs);
1625
+ const target = makeWGPUAccumulationTarget(canvas, device, rayTracePass, surface, scratch, customJobs, traceQueue);
1447
1626
  return target;
1448
1627
  }, false, scratch);
1449
1628
  }