@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 +1 @@
1
- {"version":3,"file":"sampleMaterial.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/sampleMaterial.wgsl.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,6EAA6E;AAC7E,iIAAiI;AACjI,MAAM,UAAU,wBAAwB,CAAC,uBAAuB,GAAG,IAAI,EAAE,cAAc,GAAG,KAAK;IAC7F,OAAO,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8ChB,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;mFAC4D,CAAC,CAAC,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmCvI,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,yEAAkF,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA6InH,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;CAU7B,CAAC,CAAC,CAAC,EAAE;;;;;;EAMJ,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;CAG7B,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;EAwBJ,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;CAU7B,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyDJ,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;CAKtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8Df,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;CAE7B,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BL,CAAC;AAEF,CAAC;AAED,eAAe,wBAAwB,EAAE,CAAC","sourcesContent":["// Next-event estimation with resampled importance sampling over the light\n// candidates, followed by BSDF (or phase function) sampling, as described in\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral\nexport function createSampleMaterialWgsl(hasAnisotropyDirections = true, hasCoatNormals = false) {\n return /* wgsl */ `\n\nstruct ShadowRayWork {\n ray: Ray,\n maxDistance: f32,\n triangleIndex: i32,\n contribution: vec3f,\n // RIS target of the candidate. The discrete light-selection PMF is excluded\n // and represented by the candidate's unbiased contribution weight instead.\n risTarget: f32,\n lightSelectionPmf: f32,\n valid: bool,\n}\n\nfn PrepareDirectLight(\n si: ptr<function, SurfaceInteraction>,\n ma: OpenPbrResolvedMaterial,\n prepared: OpenPbrPreparedBsdf,\n path: ptr<function, Path>,\n ffnormal: vec3f,\n isSurface: bool,\n candidateIndex: u32,\n candidateCount: u32,\n shadowWork: ptr<function, ShadowRayWork>\n) -> bool {\n (*shadowWork).valid = false;\n (*shadowWork).lightSelectionPmf = 0.0;\n (*shadowWork).risTarget = 0.0;\n let lightRnd = vec3f(sample2D(lightDim(candidateIndex, 1u)), sample1D(lightDim(candidateIndex, 0u)));\n\n var lightSample: LightSampleRec;\n sampleLightForNEECandidate(\n (*si).position,\n lightRnd,\n candidateIndex,\n candidateCount,\n &lightSample\n );\n var Li = lightSample.emission;\n\n let lightDir = lightSample.direction;\n let viewDir = -(*path).ray.d;\n let lightPdf = lightSample.pdf;\n let lightSelectionPmf = lightSample.selectionPmf;\n // Keep direct-light culling consistent with the two-sided BSDF evaluation.\n // The raw imported normal can point away from the camera on interior walls.\n ${hasCoatNormals ? /* wgsl */ `var cosThetaL = dot(ffnormal, lightDir);\n if (isSurface && ma.coatNormalEnabled) { cosThetaL = dot(ma.geometricNormal, lightDir); }` : 'let cosThetaL = dot(ffnormal, lightDir);'}\n\n if (lightPdf <= 0.0 || lightSelectionPmf <= 0.0 ||\n max(max(Li.x, Li.y), Li.z) <= 0.0) {\n return false;\n }\n\n var scatteringPdf = 0.0;\n var f = vec3f(0.0);\n if (isSurface) {\n // Evaluate the cheap BSDF terms before paying for a scene traversal.\n // Back-facing, delta, and otherwise zero-contribution samples can stop here.\n if (cosThetaL <= 0.0 && ma.transmissionWeight <= 0.0 && ma.subsurfaceWeight <= 0.0) {\n return false;\n }\n f = openpbr_eval_prepared(prepared, lightDir, &scatteringPdf);\n }\n else {\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(viewDir, lightDir),\n (*si).mediumAnisotropy\n );\n f = vec3f(scatteringPdf);\n }\n\n if (scatteringPdf <= 0.0 || max(max(f.x, f.y), f.z) <= 0.0) {\n return false;\n }\n\n var lightRay: Ray;\n var shadowOrigin = (*si).position + EPS * lightDir;\n if (isSurface) {\n shadowOrigin = offsetSurfaceRay((*si).position, (*si).faceNormal, lightDir);\n let shadowTerminatorCutoff = 0.1;\n var normalLight = dot((*si).normal, lightDir);\n${hasCoatNormals ? /* wgsl */ ` if (ma.coatNormalEnabled) { normalLight = dot((*si).faceNormal, lightDir); }` : ''}\n let geometricNormal = select(\n (*si).faceNormal,\n -(*si).faceNormal,\n normalLight < 0.0\n );\n normalLight = abs(normalLight);\n let geometricLight = dot(geometricNormal, lightDir);\n let offsetAmount = select(\n clamp(1.0 - geometricLight / shadowTerminatorCutoff, 0.0, 1.0),\n clamp(\n 2.0 - (geometricLight + normalLight) / shadowTerminatorCutoff,\n 0.0,\n 1.0\n ),\n normalLight < shadowTerminatorCutoff\n );\n shadowOrigin += (*si).shadowOffset * offsetAmount;\n }\n // Falcor offsets sampled emissive positions along the light normal, then\n // derives the visibility ray from that offset endpoint. Without the target\n // offset, our any-hit traversal sees the sampled light triangle itself and\n // rejects virtually every emissive NEE sample as occluded.\n var visibilityDirection = lightDir;\n var visibilityDistance = lightSample.dist - EPS;\n if (lightSample.sourceType == 1u) {\n let lightEndpoint =\n (*si).position + lightSample.direction * lightSample.dist;\n let offsetLightEndpoint = lightEndpoint + EPS * lightSample.normal;\n let toOffsetLight = offsetLightEndpoint - shadowOrigin;\n visibilityDistance = length(toOffsetLight);\n visibilityDirection = normalize(toOffsetLight);\n }\n initRay(&lightRay, shadowOrigin, visibilityDirection);\n\n // The continuation of a surface transmission sees the displayed background.\n // Evaluate that same endpoint for the environment proposal, so both MIS\n // strategies estimate the same radiance even for a separate/grounded skybox.\n if (isSurface && cosThetaL < 0.0 && lightSample.sourceType == 0u) {\n let background = sampleSceneBackground(lightRay);\n Li = background.rgb * background.a;\n }\n if (SPECTRAL) {\n Li = sampling_spectral_rgb_filter(Li, (*si).wavelength);\n }\n\n // A directional source is a delta distribution and cannot be reached by\n // the BSDF-sampling strategy, so its light-sampled contribution has weight 1.\n let misWeight = select(\n neeMISWeight(lightPdf, scatteringPdf),\n 1.0,\n lightSample.isDelta\n );\n if (misWeight > 0.0) {\n let unweightedContribution = Li * f / lightPdf * (*path).beta;\n (*shadowWork).risTarget = max(\n dot(max(unweightedContribution * lightSelectionPmf, vec3f(0.0)), luminance),\n 0.0\n );\n (*shadowWork).ray = lightRay;\n (*shadowWork).maxDistance = visibilityDistance;\n (*shadowWork).triangleIndex = (*si).triangleIndex;\n (*shadowWork).contribution = misWeight * unweightedContribution;\n (*shadowWork).lightSelectionPmf = lightSelectionPmf;\n (*shadowWork).valid = true;\n return true;\n }\n return false;\n}\n\nfn DirectLight(\n si: ptr<function, SurfaceInteraction>,\n ma: OpenPbrResolvedMaterial,\n prepared: OpenPbrPreparedBsdf,\n path: ptr<function, Path>,\n ffnormal: vec3f,\n isSurface: bool\n) {\n let candidateCount = neeCandidateCount();\n var selected: ShadowRayWork;\n selected.valid = false;\n var selectedTarget = 0.0;\n var scalarWeightSum = 0.0;\n // Streaming weighted reservoir sampling over the light candidates. Only the\n // selected candidate traces a shadow ray.\n for (var candidateIndex = 0u; candidateIndex < candidateCount; candidateIndex++) {\n var candidate: ShadowRayWork;\n let candidateValid = PrepareDirectLight(\n si, ma, prepared, path, ffnormal, isSurface,\n candidateIndex, candidateCount, &candidate);\n if (candidateCount == 1u) {\n if (!candidateValid) { return; }\n selected = candidate;\n break;\n }\n if (!candidateValid) { continue; }\n let scalarWeight = candidate.risTarget / max(candidate.lightSelectionPmf, 1e-20);\n if (!(scalarWeight > 0.0) || scalarWeight != scalarWeight) { continue; }\n scalarWeightSum += scalarWeight;\n if (!selected.valid ||\n lightCandidateRandom(candidateIndex) * scalarWeightSum <= scalarWeight) {\n selected = candidate;\n selectedTarget = candidate.risTarget;\n }\n }\n var candidateUCW = 1.0;\n if (candidateCount > 1u) {\n if (!selected.valid || selectedTarget <= 0.0) { return; }\n // RIS unbiased contribution weight, normalized by the target rather than\n // target / selection PMF.\n candidateUCW = selected.lightSelectionPmf * scalarWeightSum /\n (f32(candidateCount) * selectedTarget);\n }\n if (selected.valid &&\n !intersectSceneShadow(selected.ray, selected.maxDistance, selected.triangleIndex)) {\n (*path).li += selected.contribution * candidateUCW;\n }\n}\n\nfn emissiveHitMisWeight(\n si: ptr<function, SurfaceInteraction>,\n path: ptr<function, Path>\n) -> f32 {\n if ((*path).fromEye || rtUniform.lightWeightTotal <= 0.0 ||\n i32(materialsBuffer[(*si).materialIndex].matType) == UNLIT) {\n return 1.0;\n }\n let samplingLuminance = dot(\n materialsBuffer[(*si).materialIndex].emission,\n luminance\n );\n let cosLight = dot((*si).faceNormal, -(*path).ray.d);\n if (samplingLuminance <= 0.0 || cosLight <= 0.0) {\n return 1.0;\n }\n let hitDistance = distance((*si).position, (*path).ray.o);\n let lightPdf = samplingLuminance / rtUniform.lightWeightTotal *\n hitDistance * hitDistance / max(cosLight, 1e-8);\n return bsdfMISWeight((*path).scatteringPdf, lightPdf);\n}\n\n${hasCoatNormals ? /* wgsl */ `\n// Keep each shading frame in the geometric/view hemisphere. This correction\n// does not replace the face normal used for topology or ray offsets.\nfn coat_frame_normal(input: vec3f, face: vec3f, view: vec3f) -> vec3f {\n let front = dot(face, view) >= 0.0;\n let ffFace = select(-face, face, front);\n let ffInput = select(-input, input, front);\n if (dot(input, face) <= 0.0 || dot(ffInput, view) <= 1e-6) { return ffFace; }\n return ffInput;\n}\n` : ''}\nfn SampleMaterial(\n si: ptr<function, SurfaceInteraction>,\n ma: ptr<function, OpenPbrResolvedMaterial>,\n path: ptr<function, Path>\n) {\n${hasCoatNormals ? /* wgsl */ `\n let originalFace = (*si).faceNormal;\n let originalNormal = (*si).normal;\n` : ''}\n var ndv1: f32 = -dot((*si).faceNormal, (*path).ray.d);\n var ndv2: f32 = -dot((*si).normal, (*path).ray.d);\n if (((*ma).transmissionWeight > 0.0 || (*ma).subsurfaceWeight > 0.0) && (*ma).thinWalled) {\n // Always treat thin material as entering medium\n if (ndv1 < 0.0) {\n (*si).faceNormal = -(*si).faceNormal;\n ndv1 = -ndv1;\n }\n if (ndv2 < 0.0) {\n (*si).normal = -(*si).normal;\n ndv2 = -ndv2;\n }\n }\n // In same edge cases normal is not torwards the camera while we can still see the face.\n // We need to choose faceNormal in this case.\n var useFaceN: bool = ndv1 >= 0.0 && ndv2 < 0.0;\n var ndv: f32 = select(ndv2, ndv1, useFaceN);\n var N: vec3f = select((*si).normal, (*si).faceNormal, useFaceN);\n\n (*ma).inside = ndv <= 0.0 && !(*ma).thinWalled;\n // In or out\n (*ma).relativeIor = select((*ma).specularIor, (1.0 / (*ma).specularIor), ndv > 0.0);\n var ffnormal = select(-N, N, ndv >= 0.0);\n${hasCoatNormals ? /* wgsl */ `\n if ((*ma).coatNormalEnabled) {\n let view = -(*path).ray.d;\n let geometricView = dot(originalFace, view);\n (*ma).geometricNormal = select(-originalFace, originalFace, geometricView >= 0.0);\n ffnormal = coat_frame_normal(originalNormal, originalFace, view);\n (*ma).coatNormal = coat_frame_normal((*si).coatNormal, originalFace, view);\n (*ma).inside = geometricView <= 0.0 && !(*ma).thinWalled;\n (*ma).relativeIor = select((*ma).specularIor, 1.0 / (*ma).specularIor, geometricView > 0.0 || (*ma).thinWalled);\n }\n` : ''}\n\n (*path).scatteringIsDelta = false;\n var mediumSampled = false;\n var crossedBoundary = false;\n let mediumType = (*si).mediumType;\n\n var scatteringPdf: f32;\n var scatterDir: vec3f;\n\n if (HAS_MEDIUM) {\n let d = distance((*si).position, (*path).ray.o);\n let segmentOrigin = (*path).ray.o;\n let extinction = (*si).mediumExtinction;\n let scattering = min((*si).mediumScattering, extinction);\n let majorant = max(max(extinction.x, extinction.y), extinction.z);\n if (mediumType > 0 && majorant > 0.0) {\n // Sample one RGB extinction channel and divide by the mixture PDF. This\n // avoids high-variance majorant weights for channel-dependent SSS radii.\n let mediumChannel = min(i32(sample1D(bounceDim(MEDIUM_CHANNEL)) * 3.0), 2);\n let channelExtinction = extinction[mediumChannel];\n let scatterDist = select(\n d,\n min(-log(max(sample1D(bounceDim(MEDIUM_DISTANCE)), 1e-7)) / channelExtinction, d),\n channelExtinction > 0.0\n );\n mediumSampled = scatterDist < d;\n let transmittance = exp(-extinction * scatterDist);\n let density = select(\n transmittance,\n extinction * transmittance,\n mediumSampled\n );\n let mediumPdf = max((density.x + density.y + density.z) / 3.0, 1e-8);\n if (mediumSampled) {\n (*path).beta *= transmittance * scattering / mediumPdf;\n // Move from the start of the segment, not from its end surface.\n (*path).ray.o = segmentOrigin + scatterDist * (*path).ray.d;\n (*si).position = (*path).ray.o;\n }\n else {\n (*path).beta *= transmittance / mediumPdf;\n }\n }\n }\n\n if (!mediumSampled) {\n (*path).li += emissiveHitMisWeight(si, path) * (*ma).emission * (*path).beta;\n }\n if ((*ma).materialType == UNLIT) {\n (*path).abort = true;\n return;\n }\n // Surface and medium events share the light estimator. Emission is added\n // before NEE, then the continuation direction is sampled.\n var prepared: OpenPbrPreparedBsdf;\n if (!mediumSampled) {\n${hasAnisotropyDirections ? /* wgsl */ `\n (*ma).directionTangent = (*si).directionTangent;\n (*ma).directionBitangent = (*si).directionBitangent;\n (*ma).geometryTangent = (*si).geometryTangent;\n (*ma).geometryBitangent = (*si).geometryBitangent;\n` : /* wgsl */ ``}\n prepared = openpbr_prepare((*si).tangent, *ma, -(*path).ray.d, ffnormal);\n }\n DirectLight(si, *ma, prepared, path, ffnormal, !mediumSampled);\n if (mediumSampled) {\n // Pick a new direction based on the phase function.\n scatterDir = sampling_henyey_greenstein(\n -(*path).ray.d,\n (*si).mediumAnisotropy,\n sample2D(bounceDim(PHASE_DIRECTION))\n );\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(scatterDir, -(*path).ray.d),\n (*si).mediumAnisotropy\n );\n }\n else {\n // Sample BSDF for color and outgoing direction\n var isNextRefraction: bool;\n var sampledLobeRoughness = 1.0;\n var sampledLobeSpecular = false;\n var sampledLobeDiffuse = true;\n var sampledLobeIndex = u32(OPENPBR_LOBE_DIFFUSE);\n var sampledMarginalPdf = 0.0;\n let matRnd = vec3f(sample2D(bounceDim(BSDF_DIRECTION)), sample1D(bounceDim(BSDF_LOBE)));\n var fullResponse = vec3f(0.0);\n let f = openpbr_sample_prepared(\n prepared,\n matRnd,\n &scatterDir,\n &scatteringPdf,\n &isNextRefraction,\n &sampledLobeRoughness,\n &sampledLobeSpecular,\n &sampledLobeDiffuse,\n &sampledLobeIndex,\n &sampledMarginalPdf,\n &fullResponse\n );\n // A rejected microfacet proposal (including failed refraction), or a\n // material with no scattering lobes, has no continuation. Keep emission\n // and NEE already accumulated at this vertex, but never trace a default\n // direction with the incoming throughput: that invents extra light paths.\n if (!(scatteringPdf > 0.0) ||\n !all(f == f) || !all(abs(f) < vec3f(3.402823e38)) ||\n dot(scatterDir, scatterDir) < 0.5) {\n (*path).scatteringPdf = 0.0;\n (*path).abort = true;\n return;\n }\n // Exactly index-matched solid transmission is a discrete null boundary;\n // environment NEE has no competing density for that event.\n (*path).scatteringIsDelta = !prepared.material.thinWalled &&\n abs(prepared.material.relativeIor - 1.0) <= 1e-6 &&\n prepared.probabilities[OPENPBR_LOBE_TRANSMISSION] >= 1.0 - 1e-6;\n (*path).beta *= f / scatteringPdf;\n\n crossedBoundary = isNextRefraction && !(*ma).thinWalled;\n (*path).isNextRefraction = isNextRefraction;\n // TODO prefer the opaque surface when transmission surface and opaque surface are overlapped.\n // Or the ray go out from transmission material will miss the opque surface.\n (*path).ray.o = (*si).position + EPS * scatterDir;\n${hasCoatNormals ? /* wgsl */ `\n if ((*ma).coatNormalEnabled) { (*path).ray.o = (*si).position + EPS * select(-originalFace, originalFace, dot(originalFace, scatterDir) >= 0.0); }\n` : ''}\n }\n (*path).scatteringPdf = scatteringPdf;\n (*path).ray.d = scatterDir;\n if (mediumSampled) {\n (*path).isNextRefraction = false;\n }\n\n (*path).fromEye = false;\n\n if (HAS_MEDIUM) {\n // Reflections stay in the current medium. Enter or leave only after the\n // BSDF actually sampled transmission through a medium boundary.\n if (!mediumSampled && crossedBoundary && (*ma).mediumType > 0) {\n if (ndv1 >= 0.0) {\n (*si).mediumType = (*ma).mediumType;\n (*si).mediumExtinction = (*ma).mediumExtinction;\n (*si).mediumScattering = (*ma).mediumScattering;\n (*si).mediumAnisotropy = (*ma).mediumAnisotropy;\n }\n else {\n (*si).mediumType = 0;\n (*si).mediumExtinction = vec3f(0.0);\n (*si).mediumScattering = vec3f(0.0);\n (*si).mediumAnisotropy = 0.0;\n }\n }\n }\n}\n`;\n\n}\n\nexport default createSampleMaterialWgsl();\n"]}
1
+ {"version":3,"file":"sampleMaterial.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/sampleMaterial.wgsl.ts"],"names":[],"mappings":"AAAA,0EAA0E;AAC1E,6EAA6E;AAC7E,iIAAiI;AACjI,MAAM,UAAU,wBAAwB,CAAC,uBAAuB,GAAG,IAAI,EAAE,cAAc,GAAG,KAAK;IAC7F,OAAO,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAoChB,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;mFAC4D,CAAC,CAAC,CAAC,0CAA0C;;;;;;;;;;;;;;;;;EAiBvI,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC,yEAAkF,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiIzG,cAAc,CAAC,CAAC,CAAC,8GAA8G,CAAC,CAAC,CAAC,uBAAuB;;;;;;;;;;;;;;;;;;EAkB7J,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;kFAC2D,CAAC,CAAC,CAAC,UAAU,CAAC,0CAA0C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA0DrJ,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;CAU7B,CAAC,CAAC,CAAC,EAAE;;;;;;EAMJ,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;CAG7B,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;EAwBJ,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;CAU7B,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAyDJ,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;CAKtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAgCf,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;CAE7B,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6BL,CAAC;AAEF,CAAC;AAED,eAAe,wBAAwB,EAAE,CAAC","sourcesContent":["// Next-event estimation with resampled importance sampling over the light\n// candidates, followed by BSDF (or phase function) sampling, as described in\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral\nexport function createSampleMaterialWgsl(hasAnisotropyDirections = true, hasCoatNormals = false) {\n return /* wgsl */ `\n\nstruct ShadowRayWork {\n ray: Ray,\n maxDistance: f32,\n triangleIndex: i32,\n contribution: vec3f,\n // RIS target of the candidate. The discrete light-selection PMF is excluded\n // and represented by the candidate's unbiased contribution weight instead.\n risTarget: f32,\n lightSelectionPmf: f32,\n valid: bool,\n}\n\nfn finishDirectLight(\n si: ptr<function, SurfaceInteraction>,\n ma: OpenPbrResolvedMaterial,\n path: ptr<function, Path>,\n ffnormal: vec3f,\n isSurface: bool,\n lightSample: LightSampleRec,\n f: vec3f,\n scatteringPdf: f32,\n shadowWork: ptr<function, ShadowRayWork>\n) -> bool {\n (*shadowWork).valid = false;\n (*shadowWork).lightSelectionPmf = 0.0;\n (*shadowWork).risTarget = 0.0;\n var Li = lightSample.emission;\n\n let lightDir = lightSample.direction;\n let viewDir = -(*path).ray.d;\n let lightPdf = lightSample.pdf;\n let lightSelectionPmf = lightSample.selectionPmf;\n // Keep direct-light culling consistent with the two-sided BSDF evaluation.\n // The raw imported normal can point away from the camera on interior walls.\n ${hasCoatNormals ? /* wgsl */ `var cosThetaL = dot(ffnormal, lightDir);\n if (isSurface && ma.coatNormalEnabled) { cosThetaL = dot(ma.geometricNormal, lightDir); }` : 'let cosThetaL = dot(ffnormal, lightDir);'}\n\n if ((lightPdf <= 0.0) | (lightSelectionPmf <= 0.0) |\n (max(max(Li.x, Li.y), Li.z) <= 0.0)) {\n return false;\n }\n\n if ((scatteringPdf <= 0.0) | (max(max(f.x, f.y), f.z) <= 0.0)) {\n return false;\n }\n\n var lightRay: Ray;\n var shadowOrigin = (*si).position + EPS * lightDir;\n if (isSurface) {\n shadowOrigin = offsetSurfaceRay((*si).position, (*si).faceNormal, lightDir);\n let shadowTerminatorCutoff = 0.1;\n var normalLight = dot((*si).normal, lightDir);\n${hasCoatNormals ? /* wgsl */ ` if (ma.coatNormalEnabled) { normalLight = dot((*si).faceNormal, lightDir); }` : ''}\n let geometricNormal = select(\n (*si).faceNormal,\n -(*si).faceNormal,\n normalLight < 0.0\n );\n normalLight = abs(normalLight);\n let geometricLight = dot(geometricNormal, lightDir);\n let offsetAmount = select(\n clamp(1.0 - geometricLight / shadowTerminatorCutoff, 0.0, 1.0),\n clamp(\n 2.0 - (geometricLight + normalLight) / shadowTerminatorCutoff,\n 0.0,\n 1.0\n ),\n normalLight < shadowTerminatorCutoff\n );\n shadowOrigin += (*si).shadowOffset * offsetAmount;\n }\n // Falcor offsets sampled emissive positions along the light normal, then\n // derives the visibility ray from that offset endpoint. Without the target\n // offset, our any-hit traversal sees the sampled light triangle itself and\n // rejects virtually every emissive NEE sample as occluded.\n var visibilityDirection = lightDir;\n var visibilityDistance = lightSample.dist - EPS;\n if (lightSample.sourceType == 1u) {\n let lightEndpoint =\n (*si).position + lightSample.direction * lightSample.dist;\n let offsetLightEndpoint = lightEndpoint + EPS * lightSample.normal;\n let toOffsetLight = offsetLightEndpoint - shadowOrigin;\n visibilityDistance = length(toOffsetLight);\n visibilityDirection = normalize(toOffsetLight);\n }\n initRay(&lightRay, shadowOrigin, visibilityDirection);\n\n // The continuation of a surface transmission sees the displayed background.\n // Evaluate that same endpoint for the environment proposal, so both MIS\n // strategies estimate the same radiance even for a separate/grounded skybox.\n if (isSurface & (cosThetaL < 0.0) & (lightSample.sourceType == 0u)) {\n let background = sampleSceneBackground(lightRay);\n Li = background.rgb * background.a;\n }\n if (SPECTRAL) {\n Li = sampling_spectral_rgb_filter(Li, (*si).wavelength);\n }\n\n // A directional source is a delta distribution and cannot be reached by\n // the BSDF-sampling strategy, so its light-sampled contribution has weight 1.\n let misWeight = select(\n neeMISWeight(lightPdf, scatteringPdf),\n 1.0,\n lightSample.isDelta\n );\n if (misWeight > 0.0) {\n let unweightedContribution = Li * f / lightPdf * (*path).beta;\n (*shadowWork).risTarget = max(\n dot(max(unweightedContribution * lightSelectionPmf, vec3f(0.0)), luminance),\n 0.0\n );\n (*shadowWork).ray = lightRay;\n (*shadowWork).maxDistance = visibilityDistance;\n (*shadowWork).triangleIndex = (*si).triangleIndex;\n (*shadowWork).contribution = misWeight * unweightedContribution;\n (*shadowWork).lightSelectionPmf = lightSelectionPmf;\n (*shadowWork).valid = true;\n return true;\n }\n return false;\n}\n\nstruct ScatteringWork {\n direction: vec3f,\n response: vec3f,\n pdf: f32,\n transmission: bool,\n}\n\nfn sampleScattering(\n si: ptr<function, SurfaceInteraction>,\n ma: OpenPbrResolvedMaterial,\n prepared: OpenPbrPreparedBsdf,\n path: ptr<function, Path>,\n ffnormal: vec3f,\n isSurface: bool\n) -> ScatteringWork {\n let candidateCount = neeCandidateCount();\n var selected: ShadowRayWork;\n selected.valid = false;\n var selectedTarget = 0.0;\n var scalarWeightSum = 0.0;\n var result: ScatteringWork;\n // The final iteration samples the continuation after NEE and its shadow ray.\n // Both proposals use one BSDF evaluation call site, avoiding a second inlined\n // optical graph. Keep all random draws and visibility queries in their\n // original order, including the short-circuit reservoir replacement draw.\n for (var event = 0u; event <= candidateCount; event++) {\n let continuation = event == candidateCount;\n var lightSample: LightSampleRec;\n var lightDir: vec3f;\n var scatteringPdf = 0.0;\n var response = vec3f(0.0);\n var discrete = false;\n if (continuation) {\n var candidateUCW = 1.0;\n var valid = selected.valid;\n if (candidateCount > 1u) {\n valid = valid & (selectedTarget > 0.0);\n if (valid) {\n candidateUCW = selected.lightSelectionPmf * scalarWeightSum /\n (f32(candidateCount) * selectedTarget);\n }\n }\n if (valid && !intersectSceneShadow(selected.ray, selected.maxDistance, selected.triangleIndex)) {\n (*path).li += selected.contribution * candidateUCW;\n }\n if (!isSurface) {\n result.direction = sampling_henyey_greenstein(-(*path).ray.d,\n (*si).mediumAnisotropy, sample2D(bounceDim(PHASE_DIRECTION)));\n result.pdf = sampling_henyey_greenstein_phase(\n dot(result.direction, -(*path).ray.d), (*si).mediumAnisotropy);\n return result;\n }\n let matRnd = vec3f(sample2D(bounceDim(BSDF_DIRECTION)), sample1D(bounceDim(BSDF_LOBE)));\n discrete = !prepared.material.thinWalled &\n (abs(prepared.material.relativeIor - 1.0) <= 1e-6) &\n (prepared.probabilities[OPENPBR_LOBE_TRANSMISSION] >= 1.0 - 1e-6);\n if (discrete) {\n lightDir = openpbr_to_world(prepared.basis, -prepared.viewLocal);\n response = openpbr_transmission_tint(prepared.material) * openpbr_coat_base_scale(prepared,\n ${hasCoatNormals ? 'select(-prepared.viewLocal.z, dot(prepared.coatBasis.normal, lightDir), prepared.material.coatNormalEnabled)' : '-prepared.viewLocal.z'});\n scatteringPdf = 1.0;\n result.transmission = true;\n } else {\n var roughness = 1.0; var specular = false; var diffuse = true;\n var lobe = u32(OPENPBR_LOBE_DIFFUSE);\n // Use locals rather than member pointers for Naga's SPIR-V writer.\n var transmission = false;\n if (!openpbr_sample_direction(prepared, matRnd, &lightDir, &transmission,\n &roughness, &specular, &diffuse, &lobe)) { return result; }\n result.transmission = transmission;\n }\n } else {\n let lightRnd = vec3f(sample2D(lightDim(event, 1u)), sample1D(lightDim(event, 0u)));\n sampleLightForNEECandidate((*si).position, lightRnd, event, candidateCount, &lightSample);\n lightDir = lightSample.direction;\n if ((lightSample.pdf <= 0.0) | (lightSample.selectionPmf <= 0.0) |\n (max(max(lightSample.emission.x, lightSample.emission.y), lightSample.emission.z) <= 0.0)) { continue; }\n ${hasCoatNormals ? /* wgsl */ `var cosThetaL = dot(ffnormal, lightDir);\n if (isSurface & ma.coatNormalEnabled) { cosThetaL = dot(ma.geometricNormal, lightDir); }` : /* wgsl */ `let cosThetaL = dot(ffnormal, lightDir);`}\n if (isSurface & (cosThetaL <= 0.0) & (ma.transmissionWeight <= 0.0) & (ma.subsurfaceWeight <= 0.0)) { continue; }\n }\n if (!discrete) {\n if (isSurface) {\n response = openpbr_eval_prepared(prepared, lightDir, &scatteringPdf);\n } else {\n scatteringPdf = sampling_henyey_greenstein_phase(\n dot(-(*path).ray.d, lightDir), (*si).mediumAnisotropy);\n response = vec3f(scatteringPdf);\n }\n }\n if (continuation) {\n result.direction = lightDir; result.response = response; result.pdf = scatteringPdf;\n return result;\n }\n var candidate: ShadowRayWork;\n let candidateValid = finishDirectLight(si, ma, path, ffnormal, isSurface,\n lightSample, response, scatteringPdf, &candidate);\n if (!candidateValid) { continue; }\n if (candidateCount == 1u) {\n selected = candidate;\n continue;\n }\n let scalarWeight = candidate.risTarget / max(candidate.lightSelectionPmf, 1e-20);\n if (!(scalarWeight > 0.0) | (scalarWeight != scalarWeight)) { continue; }\n scalarWeightSum += scalarWeight;\n if (!selected.valid ||\n lightCandidateRandom(event) * scalarWeightSum <= scalarWeight) {\n selected = candidate;\n selectedTarget = candidate.risTarget;\n }\n }\n return result;\n}\n\nfn emissiveHitMisWeight(\n si: ptr<function, SurfaceInteraction>,\n path: ptr<function, Path>\n) -> f32 {\n if ((*path).fromEye | (rtUniform.lightWeightTotal <= 0.0) |\n (i32(materialsBuffer[(*si).materialIndex].matType) == UNLIT)) {\n return 1.0;\n }\n let samplingLuminance = dot(\n materialsBuffer[(*si).materialIndex].emission,\n luminance\n );\n let cosLight = dot((*si).faceNormal, -(*path).ray.d);\n if ((samplingLuminance <= 0.0) | (cosLight <= 0.0)) {\n return 1.0;\n }\n let hitDistance = distance((*si).position, (*path).ray.o);\n let lightPdf = samplingLuminance / rtUniform.lightWeightTotal *\n hitDistance * hitDistance / max(cosLight, 1e-8);\n return bsdfMISWeight((*path).scatteringPdf, lightPdf);\n}\n\n${hasCoatNormals ? /* wgsl */ `\n// Keep each shading frame in the geometric/view hemisphere. This correction\n// does not replace the face normal used for topology or ray offsets.\nfn coat_frame_normal(input: vec3f, face: vec3f, view: vec3f) -> vec3f {\n let front = dot(face, view) >= 0.0;\n let ffFace = select(-face, face, front);\n let ffInput = select(-input, input, front);\n if ((dot(input, face) <= 0.0) | (dot(ffInput, view) <= 1e-6)) { return ffFace; }\n return ffInput;\n}\n` : ''}\nfn SampleMaterial(\n si: ptr<function, SurfaceInteraction>,\n ma: ptr<function, OpenPbrResolvedMaterial>,\n path: ptr<function, Path>\n) {\n${hasCoatNormals ? /* wgsl */ `\n let originalFace = (*si).faceNormal;\n let originalNormal = (*si).normal;\n` : ''}\n var ndv1: f32 = -dot((*si).faceNormal, (*path).ray.d);\n var ndv2: f32 = -dot((*si).normal, (*path).ray.d);\n if ((((*ma).transmissionWeight > 0.0) | ((*ma).subsurfaceWeight > 0.0)) & (*ma).thinWalled) {\n // Always treat thin material as entering medium\n if (ndv1 < 0.0) {\n (*si).faceNormal = -(*si).faceNormal;\n ndv1 = -ndv1;\n }\n if (ndv2 < 0.0) {\n (*si).normal = -(*si).normal;\n ndv2 = -ndv2;\n }\n }\n // In same edge cases normal is not torwards the camera while we can still see the face.\n // We need to choose faceNormal in this case.\n var useFaceN: bool = (ndv1 >= 0.0) & (ndv2 < 0.0);\n var ndv: f32 = select(ndv2, ndv1, useFaceN);\n var N: vec3f = select((*si).normal, (*si).faceNormal, useFaceN);\n\n (*ma).inside = (ndv <= 0.0) & !(*ma).thinWalled;\n // In or out\n (*ma).relativeIor = select((*ma).specularIor, (1.0 / (*ma).specularIor), ndv > 0.0);\n var ffnormal = select(-N, N, ndv >= 0.0);\n${hasCoatNormals ? /* wgsl */ `\n if ((*ma).coatNormalEnabled) {\n let view = -(*path).ray.d;\n let geometricView = dot(originalFace, view);\n (*ma).geometricNormal = select(-originalFace, originalFace, geometricView >= 0.0);\n ffnormal = coat_frame_normal(originalNormal, originalFace, view);\n (*ma).coatNormal = coat_frame_normal((*si).coatNormal, originalFace, view);\n (*ma).inside = (geometricView <= 0.0) & !(*ma).thinWalled;\n (*ma).relativeIor = select((*ma).specularIor, 1.0 / (*ma).specularIor, (geometricView > 0.0) | (*ma).thinWalled);\n }\n` : ''}\n\n (*path).scatteringIsDelta = false;\n var mediumSampled = false;\n var crossedBoundary = false;\n let mediumType = (*si).mediumType;\n\n var scatteringPdf: f32;\n var scatterDir: vec3f;\n\n if (HAS_MEDIUM) {\n let d = distance((*si).position, (*path).ray.o);\n let segmentOrigin = (*path).ray.o;\n let extinction = (*si).mediumExtinction;\n let scattering = min((*si).mediumScattering, extinction);\n let majorant = max(max(extinction.x, extinction.y), extinction.z);\n if ((mediumType > 0) & (majorant > 0.0)) {\n // Sample one RGB extinction channel and divide by the mixture PDF. This\n // avoids high-variance majorant weights for channel-dependent SSS radii.\n let mediumChannel = min(i32(sample1D(bounceDim(MEDIUM_CHANNEL)) * 3.0), 2);\n let channelExtinction = extinction[mediumChannel];\n let scatterDist = select(\n d,\n min(-log(max(sample1D(bounceDim(MEDIUM_DISTANCE)), 1e-7)) / channelExtinction, d),\n channelExtinction > 0.0\n );\n mediumSampled = scatterDist < d;\n let transmittance = exp(-extinction * scatterDist);\n let density = select(\n transmittance,\n extinction * transmittance,\n mediumSampled\n );\n let mediumPdf = max((density.x + density.y + density.z) / 3.0, 1e-8);\n if (mediumSampled) {\n (*path).beta *= transmittance * scattering / mediumPdf;\n // Move from the start of the segment, not from its end surface.\n (*path).ray.o = segmentOrigin + scatterDist * (*path).ray.d;\n (*si).position = (*path).ray.o;\n }\n else {\n (*path).beta *= transmittance / mediumPdf;\n }\n }\n }\n\n if (!mediumSampled) {\n (*path).li += emissiveHitMisWeight(si, path) * (*ma).emission * (*path).beta;\n }\n if ((*ma).materialType == UNLIT) {\n (*path).abort = true;\n return;\n }\n // Surface and medium events share the light estimator. Emission is added\n // before NEE, then the continuation direction is sampled.\n var prepared: OpenPbrPreparedBsdf;\n if (!mediumSampled) {\n${hasAnisotropyDirections ? /* wgsl */ `\n (*ma).directionTangent = (*si).directionTangent;\n (*ma).directionBitangent = (*si).directionBitangent;\n (*ma).geometryTangent = (*si).geometryTangent;\n (*ma).geometryBitangent = (*si).geometryBitangent;\n` : /* wgsl */ ``}\n prepared = openpbr_prepare((*si).tangent, *ma, -(*path).ray.d, ffnormal);\n }\n let scattered = sampleScattering(si, *ma, prepared, path, ffnormal, !mediumSampled);\n scatterDir = scattered.direction;\n scatteringPdf = scattered.pdf;\n if (!mediumSampled) {\n let f = scattered.response;\n let isNextRefraction = scattered.transmission;\n // A rejected microfacet proposal (including failed refraction), or a\n // material with no scattering lobes, has no continuation. Keep emission\n // and NEE already accumulated at this vertex, but never trace a default\n // direction with the incoming throughput: that invents extra light paths.\n if (!(scatteringPdf > 0.0) |\n !all(f == f) | !all(abs(f) < vec3f(3.402823e38)) |\n (dot(scatterDir, scatterDir) < 0.5)) {\n (*path).scatteringPdf = 0.0;\n (*path).abort = true;\n return;\n }\n // Exactly index-matched solid transmission is a discrete null boundary;\n // environment NEE has no competing density for that event.\n (*path).scatteringIsDelta = !prepared.material.thinWalled &\n (abs(prepared.material.relativeIor - 1.0) <= 1e-6) &\n (prepared.probabilities[OPENPBR_LOBE_TRANSMISSION] >= 1.0 - 1e-6);\n (*path).beta *= f / scatteringPdf;\n\n crossedBoundary = isNextRefraction & !(*ma).thinWalled;\n (*path).isNextRefraction = isNextRefraction;\n // TODO prefer the opaque surface when transmission surface and opaque surface are overlapped.\n // Or the ray go out from transmission material will miss the opque surface.\n (*path).ray.o = (*si).position + EPS * scatterDir;\n${hasCoatNormals ? /* wgsl */ `\n if ((*ma).coatNormalEnabled) { (*path).ray.o = (*si).position + EPS * select(-originalFace, originalFace, dot(originalFace, scatterDir) >= 0.0); }\n` : ''}\n }\n (*path).scatteringPdf = scatteringPdf;\n (*path).ray.d = scatterDir;\n if (mediumSampled) {\n (*path).isNextRefraction = false;\n }\n\n (*path).fromEye = false;\n\n if (HAS_MEDIUM) {\n // Reflections stay in the current medium. Enter or leave only after the\n // BSDF actually sampled transmission through a medium boundary.\n if (!mediumSampled & crossedBoundary & ((*ma).mediumType > 0)) {\n if (ndv1 >= 0.0) {\n (*si).mediumType = (*ma).mediumType;\n (*si).mediumExtinction = (*ma).mediumExtinction;\n (*si).mediumScattering = (*ma).mediumScattering;\n (*si).mediumAnisotropy = (*ma).mediumAnisotropy;\n }\n else {\n (*si).mediumType = 0;\n (*si).mediumExtinction = vec3f(0.0);\n (*si).mediumScattering = vec3f(0.0);\n (*si).mediumAnisotropy = 0.0;\n }\n }\n }\n}\n`;\n\n}\n\nexport default createSampleMaterialWgsl();\n"]}
@@ -1,2 +1,2 @@
1
- declare const _default: "\n\n// A one-sample binary shadow test leaves scattered fully dark pixels far\n// from the occluder at low sample counts. Averaging a few light samples per\n// primary hit costs only shadow rays and lets the mask settle much sooner.\nconst SHADOW_CATCHER_LIGHT_SAMPLES = 4u;\n\nfn sampleShadowCatcher(si: SurfaceInteraction, bounce: i32, path: ptr<function, Path>) {\n let viewDir = -(*path).ray.d;\n\n // The unified table also contains emissive mesh lights.\n if (rtUniform.lightChoiceCount > 0) {\n var shadow = 0.0;\n for (var candidate = 0u; candidate < SHADOW_CATCHER_LIGHT_SAMPLES; candidate++) {\n var lightSample: LightSampleRec;\n let lightRnd = vec3f(sample2D(lightDim(candidate, 1u)), sample1D(lightDim(candidate, 0u)));\n sampleLight(si.position, lightRnd, &lightSample, false);\n let lightDir = lightSample.direction;\n let cosThetaL = dot(si.normal, lightDir);\n let orientation = dot(si.normal, viewDir) * cosThetaL;\n if (lightSample.pdf > 0.0 && orientation >= 0.0) {\n var ray: Ray;\n initRay(&ray, si.position + EPS * lightDir, lightDir);\n if (intersectSceneShadow(ray, lightSample.dist - EPS, si.triangleIndex)) {\n shadow += 1.0;\n }\n }\n }\n // WebGPU's compose pass consumes shadow opacity directly.\n (*path).alpha = shadow / f32(SHADOW_CATCHER_LIGHT_SAMPLES);\n }\n (*path).fromEye = false;\n}\n";
1
+ declare const _default: "\n\n// A one-sample binary shadow test leaves scattered fully dark pixels far\n// from the occluder at low sample counts. Averaging a few light samples per\n// primary hit costs only shadow rays and lets the mask settle much sooner.\nconst SHADOW_CATCHER_LIGHT_SAMPLES = 4u;\n\n// Returns the occluded and the total count of light samples that reach the\n// visible side of this hit. The shadow opacity is the ratio of their sums over\n// all samples; samples that carry no light, such as those from below the\n// receiver, do not dilute it. Weighting by Le * cos / pdf instead is unbiased\n// but noisier, because the environment CDF dilates bright texels.\nfn sampleShadowCatcher(si: SurfaceInteraction, bounce: i32, path: ptr<function, Path>) -> vec2f {\n let viewDir = -(*path).ray.d;\n var counts = vec2f(0.0);\n\n // The catcher table holds only the environment and analytic lights, as in\n // WebGL 2: emissive meshes are scene objects, not light in the plate.\n if (rtUniform.shadowCatcherChoiceCount > 0) {\n for (var candidate = 0u; candidate < SHADOW_CATCHER_LIGHT_SAMPLES; candidate++) {\n var lightSample: LightSampleRec;\n let lightRnd = vec3f(sample2D(lightDim(candidate, 1u)), sample1D(lightDim(candidate, 0u)));\n sampleLightChoiceTable(\n si.position,\n lightRnd,\n rtUniform.shadowCatcherChoiceOffset,\n rtUniform.shadowCatcherChoiceCount,\n 1.0,\n &lightSample\n );\n let lightDir = lightSample.direction;\n let cosThetaL = dot(si.normal, lightDir);\n let orientation = dot(si.normal, viewDir) * cosThetaL;\n if (lightSample.pdf > 0.0 && orientation >= 0.0) {\n if (dot(lightSample.emission, luminance) * abs(cosThetaL) > 0.0) {\n var ray: Ray;\n initRay(&ray, si.position + EPS * lightDir, lightDir);\n let occluded = intersectSceneShadow(ray, lightSample.dist - EPS, si.triangleIndex);\n counts += vec2f(select(0.0, 1.0, occluded), 1.0);\n }\n }\n }\n }\n (*path).fromEye = false;\n return counts;\n}\n";
2
2
  export default _default;
@@ -10,31 +10,44 @@ export default /*wgsl*/ `
10
10
 
11
11
  const SHADOW_CATCHER_LIGHT_SAMPLES = 4u;
12
12
 
13
- fn sampleShadowCatcher(si: ad, bounce: i32, aa: ptr<function, Path>) {
14
- let oT = -(*aa).ray.d;
15
13
 
16
14
 
17
- if (rtUniform.lightChoiceCount > 0) {
18
- var shadow = 0.0;
15
+
16
+
17
+
18
+ fn sampleShadowCatcher(si: SurfaceInteraction, bounce: i32, aa: ptr<function, Path>) -> vec2f {
19
+ let qY = -(*aa).ray.d;
20
+ var counts = vec2f(0.0);
21
+
22
+
23
+
24
+ if (rtUniform.shadowCatcherChoiceCount > 0) {
19
25
  for (var candidate = 0u; candidate < SHADOW_CATCHER_LIGHT_SAMPLES; candidate++) {
20
26
  var lightSample: LightSampleRec;
21
- let ln = vec3f(fo(rd(candidate, 1u)), dz(rd(candidate, 0u)));
22
- sampleLight(si.position, ln, &lightSample, false);
27
+ let lV = vec3f(dZ(sl(candidate, 1u)), dp(sl(candidate, 0u)));
28
+ hv(
29
+ si.position,
30
+ lV,
31
+ rtUniform.shadowCatcherChoiceOffset,
32
+ rtUniform.shadowCatcherChoiceCount,
33
+ 1.0,
34
+ &lightSample
35
+ );
23
36
  let lightDir = lightSample.direction;
24
37
  let cosThetaL = dot(si.normal, lightDir);
25
- let pM = dot(si.normal, oT) * cosThetaL;
26
- if (lightSample.pdf > 0.0 && pM >= 0.0) {
38
+ let qB = dot(si.normal, qY) * cosThetaL;
39
+ if (lightSample.pdf > 0.0 && qB >= 0.0) {
40
+ if (dot(lightSample.emission, luminance) * abs(cosThetaL) > 0.0) {
27
41
  var ray: Ray;
28
- iC(&ray, si.position + EPS * lightDir, lightDir);
29
- if (ex(ray, lightSample.dist - EPS, si.triangleIndex)) {
30
- shadow += 1.0;
42
+ gC(&ray, si.position + EPS * lightDir, lightDir);
43
+ let lY = intersectSceneShadow(ray, lightSample.dist - EPS, si.triangleIndex);
44
+ counts += vec2f(select(0.0, 1.0, lY), 1.0);
31
45
  }
32
46
  }
33
47
  }
34
-
35
- (*aa).alpha = shadow / f32(SHADOW_CATCHER_LIGHT_SAMPLES);
36
48
  }
37
49
  (*aa).fromEye = false;
50
+ return counts;
38
51
  }
39
52
  `;
40
53
  //# sourceMappingURL=sampleShadowCatcher.wgsl.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sampleShadowCatcher.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,2EAA2E;AAC3E,iIAAiI;AAEjI,eAAe,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiCvB,CAAC","sourcesContent":["// Portions adapted from ray-tracing-renderer@0.10.15\n// (https://github.com/hoverinc/ray-tracing-renderer).\n// Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.\n\n// Estimate the direct lighting integral using multiple importance sampling\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral\n\nexport default /*wgsl*/ `\n\n// A one-sample binary shadow test leaves scattered fully dark pixels far\n// from the occluder at low sample counts. Averaging a few light samples per\n// primary hit costs only shadow rays and lets the mask settle much sooner.\nconst SHADOW_CATCHER_LIGHT_SAMPLES = 4u;\n\nfn sampleShadowCatcher(si: SurfaceInteraction, bounce: i32, path: ptr<function, Path>) {\n let viewDir = -(*path).ray.d;\n\n // The unified table also contains emissive mesh lights.\n if (rtUniform.lightChoiceCount > 0) {\n var shadow = 0.0;\n for (var candidate = 0u; candidate < SHADOW_CATCHER_LIGHT_SAMPLES; candidate++) {\n var lightSample: LightSampleRec;\n let lightRnd = vec3f(sample2D(lightDim(candidate, 1u)), sample1D(lightDim(candidate, 0u)));\n sampleLight(si.position, lightRnd, &lightSample, false);\n let lightDir = lightSample.direction;\n let cosThetaL = dot(si.normal, lightDir);\n let orientation = dot(si.normal, viewDir) * cosThetaL;\n if (lightSample.pdf > 0.0 && orientation >= 0.0) {\n var ray: Ray;\n initRay(&ray, si.position + EPS * lightDir, lightDir);\n if (intersectSceneShadow(ray, lightSample.dist - EPS, si.triangleIndex)) {\n shadow += 1.0;\n }\n }\n }\n // WebGPU's compose pass consumes shadow opacity directly.\n (*path).alpha = shadow / f32(SHADOW_CATCHER_LIGHT_SAMPLES);\n }\n (*path).fromEye = false;\n}\n`;\n"]}
1
+ {"version":3,"file":"sampleShadowCatcher.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,2EAA2E;AAC3E,iIAAiI;AAEjI,eAAe,QAAQ,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CvB,CAAC","sourcesContent":["// Portions adapted from ray-tracing-renderer@0.10.15\n// (https://github.com/hoverinc/ray-tracing-renderer).\n// Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.\n\n// Estimate the direct lighting integral using multiple importance sampling\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Direct_Lighting.html#EstimatingtheDirectLightingIntegral\n\nexport default /*wgsl*/ `\n\n// A one-sample binary shadow test leaves scattered fully dark pixels far\n// from the occluder at low sample counts. Averaging a few light samples per\n// primary hit costs only shadow rays and lets the mask settle much sooner.\nconst SHADOW_CATCHER_LIGHT_SAMPLES = 4u;\n\n// Returns the occluded and the total count of light samples that reach the\n// visible side of this hit. The shadow opacity is the ratio of their sums over\n// all samples; samples that carry no light, such as those from below the\n// receiver, do not dilute it. Weighting by Le * cos / pdf instead is unbiased\n// but noisier, because the environment CDF dilates bright texels.\nfn sampleShadowCatcher(si: SurfaceInteraction, bounce: i32, path: ptr<function, Path>) -> vec2f {\n let viewDir = -(*path).ray.d;\n var counts = vec2f(0.0);\n\n // The catcher table holds only the environment and analytic lights, as in\n // WebGL 2: emissive meshes are scene objects, not light in the plate.\n if (rtUniform.shadowCatcherChoiceCount > 0) {\n for (var candidate = 0u; candidate < SHADOW_CATCHER_LIGHT_SAMPLES; candidate++) {\n var lightSample: LightSampleRec;\n let lightRnd = vec3f(sample2D(lightDim(candidate, 1u)), sample1D(lightDim(candidate, 0u)));\n sampleLightChoiceTable(\n si.position,\n lightRnd,\n rtUniform.shadowCatcherChoiceOffset,\n rtUniform.shadowCatcherChoiceCount,\n 1.0,\n &lightSample\n );\n let lightDir = lightSample.direction;\n let cosThetaL = dot(si.normal, lightDir);\n let orientation = dot(si.normal, viewDir) * cosThetaL;\n if (lightSample.pdf > 0.0 && orientation >= 0.0) {\n if (dot(lightSample.emission, luminance) * abs(cosThetaL) > 0.0) {\n var ray: Ray;\n initRay(&ray, si.position + EPS * lightDir, lightDir);\n let occluded = intersectSceneShadow(ray, lightSample.dist - EPS, si.triangleIndex);\n counts += vec2f(select(0.0, 1.0, occluded), 1.0);\n }\n }\n }\n }\n (*path).fromEye = false;\n return counts;\n}\n`;\n"]}
@@ -3,71 +3,71 @@ export default /*wgsl*/ `
3
3
 
4
4
 
5
5
 
6
- fn aQ(view: vec3f, alpha: vec2f, samplePoint: vec2f) -> vec3f {
7
- let rm = vec3f(alpha, 1.0);
8
- let gj = normalize(rm * view);
9
- let uh = min(gj.z, 1.0);
10
- let qQ = 1.0 + uh;
11
- let rh = (1.0 - samplePoint.y) * qQ;
12
- let rR = samplePoint.y * qQ;
13
- let sI = rh + (1.0 - uh);
14
- let fl = sqrt(max(0.0, sI * rR));
15
- let br = TWOPI * samplePoint.x;
16
- let lJ = vec3f(
17
- gj.x + fl * cos(br),
18
- gj.y + fl * sin(br),
19
- rh
6
+ fn aD(view: vec3f, alpha: vec2f, samplePoint: vec2f) -> vec3f {
7
+ let sv = vec3f(alpha, 1.0);
8
+ let cr = normalize(sv * view);
9
+ let qP = min(cr.z, 1.0);
10
+ let kh = 1.0 + qP;
11
+ let kC = (1.0 - samplePoint.y) * kh;
12
+ let sU = samplePoint.y * kh;
13
+ let tY = kC + (1.0 - qP);
14
+ let ex = sqrt(max(0.0, tY * sU));
15
+ let azimuth = TWOPI * samplePoint.x;
16
+ let mr = vec3f(
17
+ cr.x + ex * cos(azimuth),
18
+ cr.y + ex * sin(azimuth),
19
+ kC
20
20
  );
21
- return normalize(rm * lJ);
21
+ return normalize(sv * mr);
22
22
  }
23
23
 
24
- fn gK(oq: vec3f, alpha: vec2f) -> f32 {
25
- let hr = vec3f(
26
- oq.x / alpha.x,
27
- oq.y / alpha.y,
28
- oq.z
24
+ fn cW(pf: vec3f, alpha: vec2f) -> f32 {
25
+ let hF = vec3f(
26
+ pf.x / alpha.x,
27
+ pf.y / alpha.y,
28
+ pf.z
29
29
  );
30
- let ap = dot(hr, hr);
30
+ let aq = dot(hF, hF);
31
31
  return 1.0 / (
32
- PI * alpha.x * alpha.y * ap * ap
32
+ PI * alpha.x * alpha.y * aq * aq
33
33
  );
34
34
  }
35
35
 
36
- fn bk(direction: vec3f, alpha: vec2f) -> f32 {
37
- let eF = abs(direction.z);
38
- if (eF <= 1e-8) {
36
+ fn aF(direction: vec3f, alpha: vec2f) -> f32 {
37
+ let eQ = abs(direction.z);
38
+ if (eQ <= 1e-8) {
39
39
  return 0.0;
40
40
  }
41
- let ic = alpha * direction.xy;
42
- let lK = dot(ic, ic)
43
- / (eF * eF);
44
- return 2.0 / (1.0 + sqrt(1.0 + lK));
41
+ let iE = alpha * direction.xy;
42
+ let mt = dot(iE, iE)
43
+ / (eQ * eQ);
44
+ return 2.0 / (1.0 + sqrt(1.0 + mt));
45
45
  }
46
46
 
47
- fn aE(au: f32) -> f32 {
48
- let di = clamp(1.0 - au, 0.0, 1.0);
49
- return pow(di, 5.0);
47
+ fn aI(cosine: f32) -> f32 {
48
+ let dw = clamp(1.0 - cosine, 0.0, 1.0);
49
+ return pow(dw, 5.0);
50
50
  }
51
51
 
52
- fn cu(L: f32, cJ: f32) -> f32 {
53
- let iA = clamp(abs(L), 0.0, 1.0);
54
- let kl = cJ * cJ
55
- * max(0.0, 1.0 - iA * iA);
56
- if (kl >= 1.0) {
52
+ fn cC(J: f32, cR: f32) -> f32 {
53
+ let iS = clamp(abs(J), 0.0, 1.0);
54
+ let kQ = cR * cR
55
+ * max(0.0, 1.0 - iS * iS);
56
+ if (kQ >= 1.0) {
57
57
  return 1.0;
58
58
  }
59
59
 
60
- let lU = sqrt(max(0.0, 1.0 - kl));
61
- let ba = (iA - cJ * lU)
62
- / max(iA + cJ * lU, 1e-8);
63
- let pN = (cJ * iA - lU)
64
- / max(cJ * iA + lU, 1e-8);
60
+ let mD = sqrt(max(0.0, 1.0 - kQ));
61
+ let bk = (iS - cR * mD)
62
+ / max(iS + cR * mD, 1e-8);
63
+ let qC = (cR * iS - mD)
64
+ / max(cR * iS + mD, 1e-8);
65
65
  return 0.5 * (
66
- ba * ba + pN * pN
66
+ bk * bk + qC * qC
67
67
  );
68
68
  }
69
69
 
70
- fn gh(samplePoint: vec2f) -> vec2f {
70
+ fn gy(samplePoint: vec2f) -> vec2f {
71
71
  let offset = 2.0 * samplePoint - vec2f(1.0);
72
72
  if (offset.x == 0.0 && offset.y == 0.0) {
73
73
  return vec2f(0.0);
@@ -86,45 +86,45 @@ angle = 0.5 * PI - 0.25 * PI * (offset.x / offset.y);
86
86
  return radius * vec2f(cos(angle), sin(angle));
87
87
  }
88
88
 
89
- fn bi(samplePoint: vec2f) -> vec3f {
90
- let kF = gh(samplePoint);
89
+ fn aO(samplePoint: vec2f) -> vec3f {
90
+ let lk = gy(samplePoint);
91
91
  return vec3f(
92
- kF,
93
- sqrt(max(0.0, 1.0 - dot(kF, kF)))
92
+ lk,
93
+ sqrt(max(0.0, 1.0 - dot(lk, lk)))
94
94
  );
95
95
  }
96
96
 
97
- fn aG(pr: f32, nO: f32) -> f32 {
98
- let scale = max(pr, nO);
97
+ fn aK(qo: f32, oJ: f32) -> f32 {
98
+ let scale = max(qo, oJ);
99
99
  if (scale <= 0.0) {
100
100
  return 0.0;
101
101
  }
102
- let normalized = vec2f(pr, nO) / scale;
103
- let oP = normalized * normalized;
104
- return oP.x / (oP.x + oP.y);
102
+ let normalized = vec2f(qo, oJ) / scale;
103
+ let pL = normalized * normalized;
104
+ return pL.x / (pL.x + pL.y);
105
105
  }
106
106
 
107
- fn aL(
107
+ fn aP(
108
108
  normal: vec3f,
109
109
  tangent: ptr<function, vec3f>,
110
110
  bitangent: ptr<function, vec3f>
111
111
  ) {
112
- let ik = select(-1.0, 1.0, normal.z >= 0.0);
113
- let dW = -1.0 / (ik + normal.z);
114
- let xy = normal.x * normal.y * dW;
112
+ let iI = select(-1.0, 1.0, normal.z >= 0.0);
113
+ let cL = -1.0 / (iI + normal.z);
114
+ let xy = normal.x * normal.y * cL;
115
115
  *tangent = vec3f(
116
- 1.0 + ik * normal.x * normal.x * dW,
117
- ik * xy,
118
- -ik * normal.x
116
+ 1.0 + iI * normal.x * normal.x * cL,
117
+ iI * xy,
118
+ -iI * normal.x
119
119
  );
120
120
  *bitangent = vec3f(
121
121
  xy,
122
- ik + normal.y * normal.y * dW,
122
+ iI + normal.y * normal.y * cL,
123
123
  -normal.y
124
124
  );
125
125
  }
126
126
 
127
- fn ai(rgb: vec3f, wavelength: f32) -> vec3f {
127
+ fn aj(rgb: vec3f, wavelength: f32) -> vec3f {
128
128
  if (wavelength == 0.0) {
129
129
  return rgb;
130
130
  }
@@ -137,62 +137,62 @@ return vec3f(0.0, rgb.g, 0.0);
137
137
  return vec3f(0.0, 0.0, rgb.b);
138
138
  }
139
139
 
140
- fn eN(
140
+ fn ee(
141
141
  wavelength: f32,
142
- hg: f32,
143
- hp: f32,
144
- qs: f32
142
+ hu: f32,
143
+ hD: f32,
144
+ rt: f32
145
145
  ) -> f32 {
146
- if (wavelength == 0.0 || hp <= 0.0) {
147
- return hg;
146
+ if (wavelength == 0.0 || hD <= 0.0) {
147
+ return hu;
148
148
  }
149
149
 
150
150
  let FRAUNHOFER_C = 656.3;
151
151
  let FRAUNHOFER_D = 587.6;
152
152
  let FRAUNHOFER_F = 486.1;
153
- let jR = 1.0 / (
153
+ let kv = 1.0 / (
154
154
  1.0 / (FRAUNHOFER_F * FRAUNHOFER_F)
155
155
  - 1.0 / (FRAUNHOFER_C * FRAUNHOFER_C)
156
156
  );
157
- let nh = max(qs / hp, 1e-6);
158
- let qR = (hg - 1.0) * jR / nh;
159
- let tl = hg
160
- - qR / (FRAUNHOFER_D * FRAUNHOFER_D);
161
- return tl + qR / (wavelength * wavelength);
157
+ let oe = max(rt / hD, 1e-6);
158
+ let rV = (hu - 1.0) * kv / oe;
159
+ let uK = hu
160
+ - rV / (FRAUNHOFER_D * FRAUNHOFER_D);
161
+ return uK + rV / (wavelength * wavelength);
162
162
  }
163
163
 
164
- fn fp(
165
- gy: vec3f,
164
+ fn fH(
165
+ gO: vec3f,
166
166
  anisotropy: f32,
167
167
  samplePoint: vec2f
168
168
  ) -> vec3f {
169
- var au: f32;
169
+ var cosine: f32;
170
170
  if (abs(anisotropy) < 0.001) {
171
- au = 1.0 - 2.0 * samplePoint.y;
171
+ cosine = 1.0 - 2.0 * samplePoint.y;
172
172
  }
173
173
  else {
174
- let ja = (1.0 - anisotropy * anisotropy)
174
+ let ju = (1.0 - anisotropy * anisotropy)
175
175
  / (1.0 + anisotropy - 2.0 * anisotropy * samplePoint.y);
176
- au = (
177
- ja * ja - 1.0 - anisotropy * anisotropy
176
+ cosine = (
177
+ ju * ju - 1.0 - anisotropy * anisotropy
178
178
  ) / (2.0 * anisotropy);
179
179
  }
180
180
 
181
- let ud = sqrt(max(0.0, 1.0 - au * au));
182
- let br = TWOPI * samplePoint.x;
181
+ let vF = sqrt(max(0.0, 1.0 - cosine * cosine));
182
+ let azimuth = TWOPI * samplePoint.x;
183
183
  var tangent: vec3f;
184
184
  var bitangent: vec3f;
185
- aL(gy, &tangent, &bitangent);
186
- return tangent * (ud * cos(br))
187
- + bitangent * (ud * sin(br))
188
- + gy * au;
185
+ aP(gO, &tangent, &bitangent);
186
+ return tangent * (vF * cos(azimuth))
187
+ + bitangent * (vF * sin(azimuth))
188
+ + gO * cosine;
189
189
  }
190
190
 
191
- fn bD(au: f32, anisotropy: f32) -> f32 {
192
- let ap = 1.0 + anisotropy * anisotropy
193
- + 2.0 * anisotropy * au;
191
+ fn bL(cosine: f32, anisotropy: f32) -> f32 {
192
+ let aq = 1.0 + anisotropy * anisotropy
193
+ + 2.0 * anisotropy * cosine;
194
194
  return INV4PI * (1.0 - anisotropy * anisotropy)
195
- / (ap * sqrt(ap));
195
+ / (aq * sqrt(aq));
196
196
  }
197
197
  `;
198
198
  //# sourceMappingURL=sampling.wgsl.js.map
@@ -4,5 +4,5 @@
4
4
  * luminance moments for the built-in denoiser's variance estimate.
5
5
  */
6
6
  export declare const SHADOW_CATCHER_ACCUMULATION_BYTES = 48;
7
- declare const _default: "\nstruct ShadowCatcherAccumulation {\n // Catcher coverage, separated background alpha, catcher background hits, shadow opacity.\n mask: vec4f,\n background: vec4f,\n // Sum of the denoising guide value and of its square (x, y).\n moments: vec4f,\n}\n";
7
+ declare const _default: "\nstruct ShadowCatcherAccumulation {\n // Catcher coverage, separated background alpha, catcher background hits.\n mask: vec4f,\n background: vec4f,\n // Sum of the denoising guide value and of its square (x, y), and of the\n // catcher's occluded and total light sample counts (z, w).\n moments: vec4f,\n}\n";
8
8
  export default _default;
@@ -10,6 +10,7 @@ struct ShadowCatcherAccumulation {
10
10
  mask: vec4f,
11
11
  background: vec4f,
12
12
 
13
+
13
14
  moments: vec4f,
14
15
  }
15
16
  `;
@@ -1 +1 @@
1
- {"version":3,"file":"shadowCatcherAccumulation.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAEpD,eAAe,UAAU,CAAC;;;;;;;;CAQzB,CAAC","sourcesContent":["/**\n * Per-pixel auxiliary accumulation: the shadow-catcher mask, its premultiplied\n * primary background contribution (including opaque flat primary misses), and\n * luminance moments for the built-in denoiser's variance estimate.\n */\nexport const SHADOW_CATCHER_ACCUMULATION_BYTES = 48;\n\nexport default /* wgsl */ `\nstruct ShadowCatcherAccumulation {\n // Catcher coverage, separated background alpha, catcher background hits, shadow opacity.\n mask: vec4f,\n background: vec4f,\n // Sum of the denoising guide value and of its square (x, y).\n moments: vec4f,\n}\n`;\n"]}
1
+ {"version":3,"file":"shadowCatcherAccumulation.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAEpD,eAAe,UAAU,CAAC;;;;;;;;;CASzB,CAAC","sourcesContent":["/**\n * Per-pixel auxiliary accumulation: the shadow-catcher mask, its premultiplied\n * primary background contribution (including opaque flat primary misses), and\n * luminance moments for the built-in denoiser's variance estimate.\n */\nexport const SHADOW_CATCHER_ACCUMULATION_BYTES = 48;\n\nexport default /* wgsl */ `\nstruct ShadowCatcherAccumulation {\n // Catcher coverage, separated background alpha, catcher background hits.\n mask: vec4f,\n background: vec4f,\n // Sum of the denoising guide value and of its square (x, y), and of the\n // catcher's occluded and total light sample counts (z, w).\n moments: vec4f,\n}\n`;\n"]}