@meimu/mutracer 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (211) hide show
  1. package/README.md +3 -0
  2. package/dist/assets/bvh.worker.js +1 -1
  3. package/dist/mutracer.umd.js +8949 -7915
  4. package/docs/api.md +42 -21
  5. package/docs/caustics.md +80 -0
  6. package/docs/materials.md +5 -4
  7. package/docs/progressive-rendering.md +50 -9
  8. package/docs/technical/continuous-spectrum.md +93 -0
  9. package/docs/updates.md +3 -1
  10. package/docs/viewer-checklist.md +65 -0
  11. package/docs/viewer.md +7 -5
  12. package/lib/Display.js +1 -1
  13. package/lib/Display.js.map +1 -1
  14. package/lib/Engine.d.ts +2 -0
  15. package/lib/Engine.js +47 -12
  16. package/lib/Engine.js.map +1 -1
  17. package/lib/Render.d.ts +61 -13
  18. package/lib/Render.js +169 -19
  19. package/lib/Render.js.map +1 -1
  20. package/lib/RenderLoop.d.ts +7 -3
  21. package/lib/RenderLoop.js +68 -44
  22. package/lib/RenderLoop.js.map +1 -1
  23. package/lib/main.d.ts +1 -1
  24. package/lib/main.js.map +1 -1
  25. package/lib/oidn.d.ts +1 -1
  26. package/lib/oidnBundledWeights.cdn.d.ts +2 -2
  27. package/lib/renderer/GPUTraceQueue.d.ts +2 -1
  28. package/lib/renderer/GPUTraceQueue.js +3 -1
  29. package/lib/renderer/GPUTraceQueue.js.map +1 -1
  30. package/lib/renderer/RenderingPipeline.d.ts +4 -0
  31. package/lib/renderer/RenderingPipeline.js.map +1 -1
  32. package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
  33. package/lib/renderer/WGPUCausticLightPass.js +217 -0
  34. package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
  35. package/lib/renderer/WGPUEnvMapDistribution.js +18 -18
  36. package/lib/renderer/WGPUFullQuadPass.js +3 -3
  37. package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
  38. package/lib/renderer/WGPUPhotonMap.js +191 -0
  39. package/lib/renderer/WGPUPhotonMap.js.map +1 -0
  40. package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
  41. package/lib/renderer/WGPURayTraceOutput.js +122 -28
  42. package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
  43. package/lib/renderer/WGPURayTracePass.d.ts +48 -17
  44. package/lib/renderer/WGPURayTracePass.js +538 -340
  45. package/lib/renderer/WGPURayTracePass.js.map +1 -1
  46. package/lib/renderer/WGPURenderingPipeline.js +83 -47
  47. package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
  48. package/lib/renderer/WebGLFullQuadPass.d.ts +2 -1
  49. package/lib/renderer/WebGLFullQuadPass.js +4 -0
  50. package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
  51. package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
  52. package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
  53. package/lib/renderer/WebGLRayTracePass.d.ts +6 -1
  54. package/lib/renderer/WebGLRayTracePass.js +43 -6
  55. package/lib/renderer/WebGLRayTracePass.js.map +1 -1
  56. package/lib/renderer/WebGLRenderingPipeline.js +10 -14
  57. package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
  58. package/lib/renderer/WebGLSkyBaker.js +60 -60
  59. package/lib/renderer/accumulationTarget.d.ts +2 -1
  60. package/lib/renderer/accumulationTarget.js.map +1 -1
  61. package/lib/renderer/causticDiagnostics.d.ts +31 -0
  62. package/lib/renderer/causticDiagnostics.js +5 -0
  63. package/lib/renderer/causticDiagnostics.js.map +1 -0
  64. package/lib/renderer/causticEmission.d.ts +10 -0
  65. package/lib/renderer/causticEmission.js +40 -0
  66. package/lib/renderer/causticEmission.js.map +1 -0
  67. package/lib/renderer/causticUniform.d.ts +12 -0
  68. package/lib/renderer/causticUniform.js +22 -0
  69. package/lib/renderer/causticUniform.js.map +1 -0
  70. package/lib/renderer/caustics.d.ts +16 -0
  71. package/lib/renderer/caustics.js +93 -0
  72. package/lib/renderer/caustics.js.map +1 -0
  73. package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
  74. package/lib/renderer/glsl/aovReflectance.glsl.js +53 -53
  75. package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
  76. package/lib/renderer/glsl/aovTrace.frag.js +33 -33
  77. package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -9
  78. package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
  79. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
  80. package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
  81. package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -73
  82. package/lib/renderer/glsl/chunks/intersect.glsl.js +426 -428
  83. package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
  84. package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
  85. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +156 -153
  86. package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
  87. package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
  88. package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
  89. package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
  90. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
  91. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +68 -63
  92. package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
  93. package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
  94. package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
  95. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
  96. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +140 -117
  97. package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
  98. package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
  99. package/lib/renderer/glsl/chunks/sampling.glsl.js +89 -92
  100. package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
  101. package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
  102. package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
  103. package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
  104. package/lib/renderer/glsl/depthQuery.frag.js +2 -2
  105. package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
  106. package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
  107. package/lib/renderer/glsl/rayTrace.frag.js +260 -237
  108. package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
  109. package/lib/renderer/glsl/shadowCatcher.frag.js +26 -26
  110. package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
  111. package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
  112. package/lib/renderer/lightSampling.d.ts +3 -2
  113. package/lib/renderer/lightSampling.js +14 -8
  114. package/lib/renderer/lightSampling.js.map +1 -1
  115. package/lib/renderer/progressiveScheduler.js +4 -3
  116. package/lib/renderer/progressiveScheduler.js.map +1 -1
  117. package/lib/renderer/renderPipeline.d.ts +1 -0
  118. package/lib/renderer/renderPipeline.js.map +1 -1
  119. package/lib/renderer/researchTransport.d.ts +31 -0
  120. package/lib/renderer/researchTransport.js +5 -0
  121. package/lib/renderer/researchTransport.js.map +1 -0
  122. package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
  123. package/lib/renderer/sceneLayoutSchema.js +2 -2
  124. package/lib/renderer/sceneLayoutSchema.js.map +1 -1
  125. package/lib/renderer/scratchSampling.js +6 -6
  126. package/lib/renderer/spectrum.d.ts +21 -0
  127. package/lib/renderer/spectrum.js +154 -0
  128. package/lib/renderer/spectrum.js.map +1 -0
  129. package/lib/renderer/webglLightSampling.d.ts +39 -0
  130. package/lib/renderer/webglLightSampling.js +15 -0
  131. package/lib/renderer/webglLightSampling.js.map +1 -0
  132. package/lib/renderer/wgpuBindlessSource.js +3 -3
  133. package/lib/renderer/wgpuShaderSource.d.ts +7 -0
  134. package/lib/renderer/wgpuShaderSource.js +2 -0
  135. package/lib/renderer/wgpuShaderSource.js.map +1 -1
  136. package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
  137. package/lib/renderer/wgsl/aovReflectance.wgsl.js +55 -55
  138. package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
  139. package/lib/renderer/wgsl/aovResolve.wgsl.js +2 -2
  140. package/lib/renderer/wgsl/aovSnapshot.wgsl.js +1 -1
  141. package/lib/renderer/wgsl/aovTrace.wgsl.js +33 -33
  142. package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
  143. package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
  144. package/lib/renderer/wgsl/causticLight.compute.js +537 -0
  145. package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
  146. package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
  147. package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
  148. package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
  149. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
  150. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
  151. package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
  152. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
  153. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
  154. package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
  155. package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
  156. package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
  157. package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
  158. package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
  159. package/lib/renderer/wgsl/chunks/envMap.wgsl.js +37 -37
  160. package/lib/renderer/wgsl/chunks/intersect.wgsl.js +598 -592
  161. package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
  162. package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +14 -14
  163. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
  164. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +75 -73
  165. package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
  166. package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +794 -794
  167. package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
  168. package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
  169. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +2 -1
  170. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +35 -25
  171. package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
  172. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
  173. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +142 -138
  174. package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
  175. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
  176. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +204 -187
  177. package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
  178. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
  179. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +11 -11
  180. package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
  181. package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
  182. package/lib/renderer/wgsl/chunks/sampling.wgsl.js +89 -93
  183. package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
  184. package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
  185. package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
  186. package/lib/renderer/wgsl/compose.frag.wgsl.js +98 -98
  187. package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
  188. package/lib/renderer/wgsl/depthQuery.wgsl.js +2 -2
  189. package/lib/renderer/wgsl/jnlm.compute.js +74 -74
  190. package/lib/renderer/wgsl/offlineAdaptive.compute.js +25 -25
  191. package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
  192. package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
  193. package/lib/renderer/wgsl/photonMap.compute.js +352 -0
  194. package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
  195. package/lib/renderer/wgsl/proceduralSky.compute.js +64 -64
  196. package/lib/renderer/wgsl/rayTrace.compute.d.ts +9 -1
  197. package/lib/renderer/wgsl/rayTrace.compute.js +448 -522
  198. package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
  199. package/lib/scene/MaterialState.d.ts +2 -2
  200. package/lib/scene/MaterialState.js +2 -2
  201. package/lib/scene/MaterialState.js.map +1 -1
  202. package/lib/settings/render.d.ts +11 -0
  203. package/lib/settings/render.js +1 -0
  204. package/lib/settings/render.js.map +1 -1
  205. package/lib/util/fromTHREE.js +2 -2
  206. package/lib/util/fromTHREE.js.map +1 -1
  207. package/lib/version.d.ts +1 -1
  208. package/lib/version.js +1 -1
  209. package/lib/version.js.map +1 -1
  210. package/llms.txt +2 -1
  211. package/package.json +3 -3
@@ -1 +1 @@
1
- {"version":3,"file":"sampleLight.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/sampleLight.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,8BAA8B,EAC9B,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,eAAe,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAkVkB,wBAAwB;;;;;;;4BAOjC,qBAAqB;;;;;;;;wDAQO,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgD3F,CAAC","sourcesContent":["import {\n LIGHT_CHOICE_ANALYTIC,\n LIGHT_CHOICE_EMISSIVE_TRIANGLE,\n LIGHT_CHOICE_ENVIRONMENT\n} from '../../lightConstants.js';\n\nexport default /*wgsl */ `\nfn light_sample_sphere(light: Light, scatterPos: vec3f, randomV2: vec2f, lightSample: ptr<function, LightSampleRec>) {\n let centerOffset = light.position - scatterPos;\n let centerDistance = length(centerOffset);\n if (light.radiusOrSpread <= 0.0) {\n // A zero-radius sphere is a point emitter. The stored emission is\n // luminous intensity, so convert it to incident radiance here rather\n // than approximating the delta source as a tiny area sphere.\n if (centerDistance <= 1e-6) {\n (*lightSample).direction = vec3f(0.0, 0.0, 1.0);\n (*lightSample).normal = vec3f(0.0, 0.0, -1.0);\n (*lightSample).dist = 0.0;\n (*lightSample).pdf = 1.0;\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).isDelta = true;\n return;\n }\n (*lightSample).direction = centerOffset / centerDistance;\n (*lightSample).normal = -(*lightSample).direction;\n (*lightSample).dist = centerDistance;\n (*lightSample).pdf = 1.0;\n (*lightSample).emission = light.emission /\n max(centerDistance * centerDistance, 1e-8);\n (*lightSample).isDelta = true;\n return;\n }\n let radius = max(light.radiusOrSpread, 1e-6);\n (*lightSample).isDelta = false;\n var sampledDirection: vec3f;\n\n if (centerDistance <= radius) {\n let z = 1.0 - 2.0 * randomV2.x;\n let radial = sqrt(max(0.0, 1.0 - z * z));\n let azimuth = TWOPI * randomV2.y;\n sampledDirection = vec3f(\n radial * cos(azimuth),\n radial * sin(azimuth),\n z\n );\n (*lightSample).pdf = INV4PI;\n }\n else {\n let sphereAxis = centerOffset / centerDistance;\n let sinThetaMaxSquared = min(\n 1.0,\n radius * radius / (centerDistance * centerDistance)\n );\n let cosThetaMax = sqrt(max(0.0, 1.0 - sinThetaMaxSquared));\n let cosTheta = mix(1.0, cosThetaMax, randomV2.x);\n let sinTheta = sqrt(max(0.0, 1.0 - cosTheta * cosTheta));\n let azimuth = TWOPI * randomV2.y;\n var tangent: vec3f;\n var bitangent: vec3f;\n sampling_orthonormal_basis(sphereAxis, &tangent, &bitangent);\n sampledDirection = sphereAxis * cosTheta\n + tangent * (sinTheta * cos(azimuth))\n + bitangent * (sinTheta * sin(azimuth));\n (*lightSample).pdf = 1.0 / max(\n TWOPI * (1.0 - cosThetaMax),\n 1e-8\n );\n }\n\n let centerProjection = dot(sampledDirection, centerOffset);\n let centerOffsetSquared = dot(centerOffset, centerOffset);\n let discriminant = centerProjection * centerProjection\n - centerOffsetSquared + radius * radius;\n let nearDistance = centerProjection - sqrt(max(0.0, discriminant));\n let farDistance = centerProjection + sqrt(max(0.0, discriminant));\n (*lightSample).dist = select(farDistance, nearDistance, nearDistance > 1e-6);\n (*lightSample).direction = sampledDirection;\n let lightSurfacePos = scatterPos + sampledDirection * (*lightSample).dist;\n (*lightSample).normal = normalize(lightSurfacePos - light.position);\n (*lightSample).emission = light.emission;\n}\n\nfn light_apply_rect_texture(\n light: Light,\n surfacePoint: vec3f,\n lowerLeft: vec3f,\n result: ptr<function, LightSampleRec>\n) {\n if (light.textureIndex < 0.0) {\n return;\n }\n let width = length(light.u);\n let height = length(light.v);\n let relative = surfacePoint - lowerLeft;\n let uv = vec2f(\n dot(relative, light.u / width) / width,\n dot(relative, light.v / height) / height\n );\n (*result).emission *= sampleMap(i32(light.textureIndex), uv).rgb;\n}\n\nfn light_sample_rect(\n light: Light,\n shadingPoint: vec3f,\n samplePoint: vec2f,\n result: ptr<function, LightSampleRec>\n) {\n let normal = normalize(cross(light.u, light.v));\n let lowerLeft = light.position - 0.5 * (light.u + light.v);\n let spread = clamp(light.radiusOrSpread, 0.0, 1.0);\n\n if (spread <= 0.001) {\n let planeDistance = dot(normal, shadingPoint - light.position);\n let surfacePoint = shadingPoint - normal * planeDistance;\n let relative = surfacePoint - lowerLeft;\n let width = length(light.u);\n let height = length(light.v);\n let uv = vec2f(\n dot(relative, light.u / width) / width,\n dot(relative, light.v / height) / height\n );\n if (planeDistance <= 0.0 || any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\n (*result).emission = vec3f(0.0);\n (*result).pdf = 0.0;\n return;\n }\n (*result).direction = -normal;\n (*result).dist = planeDistance;\n (*result).normal = normal;\n (*result).emission = light.emission;\n (*result).pdf = 1.0;\n (*result).isDelta = true;\n light_apply_rect_texture(light, surfacePoint, lowerLeft, result);\n return;\n }\n\n let surfacePoint = lowerLeft\n + light.u * samplePoint.x\n + light.v * samplePoint.y;\n let offset = surfacePoint - shadingPoint;\n let distanceSquared = dot(offset, offset);\n (*result).dist = sqrt(distanceSquared);\n (*result).direction = offset / (*result).dist;\n (*result).normal = normal;\n let emitterCosine = dot(-(*result).direction, normal);\n let spreadCosine = cos(0.5 * PI * spread);\n if (emitterCosine <= 0.0 || emitterCosine < spreadCosine) {\n (*result).emission = vec3f(0.0);\n (*result).pdf = 0.0;\n return;\n }\n (*result).emission = light.emission;\n (*result).pdf = distanceSquared / max(light.area * emitterCosine, 1e-8);\n light_apply_rect_texture(light, surfacePoint, lowerLeft, result);\n}\n\nfn light_sample_directional(\n light: Light,\n result: ptr<function, LightSampleRec>\n) {\n (*result).direction = normalize(-light.u);\n (*result).normal = -(*result).direction;\n (*result).emission = light.emission;\n (*result).dist = INF;\n (*result).pdf = 1.0;\n (*result).isDelta = true;\n}\n\nfn light_sample_spot(\n light: Light,\n shadingPoint: vec3f,\n samplePoint: vec2f,\n result: ptr<function, LightSampleRec>\n) {\n light_sample_sphere(light, shadingPoint, samplePoint, result);\n let surfacePoint = shadingPoint + (*result).direction * (*result).dist;\n let lightToSurface = normalize(shadingPoint - surfacePoint);\n (*result).emission *= evaluateSpotEmissionMultiplier(light, lightToSurface);\n}\n\nfn sampleAnalyticLight(\n light: Light,\n shadingPoint: vec3f,\n samplePoint: vec2f,\n result: ptr<function, LightSampleRec>\n) {\n let lightType = i32(light.litType);\n if (HAS_SCENE_RECT_LIGHT && lightType == RECT_LIGHT) {\n light_sample_rect(light, shadingPoint, samplePoint, result);\n return;\n }\n if (HAS_SCENE_SPHERE_LIGHT && lightType == SPHERE_LIGHT) {\n light_sample_sphere(light, shadingPoint, samplePoint, result);\n return;\n }\n if (HAS_SCENE_SPOT_LIGHT && lightType == SPOT_LIGHT) {\n light_sample_spot(light, shadingPoint, samplePoint, result);\n return;\n }\n if (HAS_SCENE_DIRECTIONAL_LIGHT && lightType == DIRECTIONAL_LIGHT) {\n light_sample_directional(light, result);\n }\n}\n\nfn sampleEnvLight(randomV2: vec2f, lightSample: ptr<function, LightSampleRec>) {\n var uv: vec2f;\n // Naga's SPIR-V writer cannot pass a struct-member pointer as a call argument.\n var pdf: f32;\n let direction = sampleEnvmap(randomV2, &uv, &pdf);\n (*lightSample).pdf = pdf;\n (*lightSample).direction = direction;\n (*lightSample).emission = textureLinear(envMap, uv).rgb;\n (*lightSample).dist = INF;\n}\n\nfn loadLightSamplingTexel(texelIndex: i32) -> vec4f {\n let width = rtUniform.lightSamplingTextureWidth;\n return textureLoad(\n lightSamplingData,\n vec2i(texelIndex % width, texelIndex / width),\n 0\n );\n}\n\nfn getEmissiveTriangle(index: i32) -> EmissiveTriangle {\n let offset = index * 6;\n let a = loadLightSamplingTexel(offset);\n let b = loadLightSamplingTexel(offset + 1);\n let c = loadLightSamplingTexel(offset + 2);\n let d = loadLightSamplingTexel(offset + 3);\n let e = loadLightSamplingTexel(offset + 4);\n let f = loadLightSamplingTexel(offset + 5);\n return EmissiveTriangle(\n a.xyz, a.w,\n b.xyz, b.w,\n c.xyz, c.w,\n d.xy, d.zw, e.xy,\n e.zw, f.xy, f.zw\n );\n}\n\nfn getLightChoice(index: i32) -> LightChoice {\n let data = loadLightSamplingTexel(rtUniform.lightChoiceTexelOffset + index);\n return LightChoice(\n data.x,\n bitcast<i32>(data.y),\n bitcast<i32>(data.z),\n bitcast<i32>(data.w)\n );\n}\n\nfn getLightChoiceFromTable(tableOffset: i32, index: i32) -> LightChoice {\n return getLightChoice(tableOffset + index);\n}\n\nfn stratifyLightChoiceRandom(\n rnd: vec3f,\n candidateIndex: u32,\n candidateCount: u32\n) -> vec3f {\n var stratified = rnd;\n let count = max(candidateCount, 1u);\n stratified.z = (rnd.z + f32(min(candidateIndex, count - 1u))) /\n f32(count);\n return stratified;\n}\n\nfn sampleEmissiveTriangleLight(\n triangle: EmissiveTriangle,\n scatterPos: vec3f,\n randomV2: vec2f,\n lightSample: ptr<function, LightSampleRec>\n) {\n let sqrtU = sqrt(randomV2.x);\n let barycentric = vec3f(\n 1.0 - sqrtU,\n sqrtU * (1.0 - randomV2.y),\n sqrtU * randomV2.y\n );\n let lightPosition =\n barycentric.x * triangle.p0 +\n barycentric.y * triangle.p1 +\n barycentric.z * triangle.p2;\n let uv =\n barycentric.x * triangle.uv0 +\n barycentric.y * triangle.uv1 +\n barycentric.z * triangle.uv2;\n let secondaryUv =\n barycentric.x * triangle.secondaryUv0 +\n barycentric.y * triangle.secondaryUv1 +\n barycentric.z * triangle.secondaryUv2;\n let normal = normalize(cross(triangle.p1 - triangle.p0, triangle.p2 - triangle.p0));\n (*lightSample).direction = lightPosition - scatterPos;\n (*lightSample).dist = length((*lightSample).direction);\n if ((*lightSample).dist <= EPS) {\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).pdf = 0.0;\n return;\n }\n (*lightSample).direction /= (*lightSample).dist;\n (*lightSample).normal = normal;\n let cosLight = dot(normal, -(*lightSample).direction);\n if (cosLight <= 0.0) {\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).pdf = 0.0;\n return;\n }\n (*lightSample).emission = getMaterialEmission(\n i32(triangle.materialIndex), uv, secondaryUv\n );\n (*lightSample).selectionPmf = triangle.selectionPmf;\n (*lightSample).pdf = triangle.selectionPmf *\n ((*lightSample).dist * (*lightSample).dist) /\n max(triangle.area * cosLight, 1e-8);\n}\n\nfn sampleLightChoiceTable(\n scatterPos: vec3f,\n rnd: vec3f,\n tableOffset: i32,\n choiceCount: i32,\n selectionPmfScale: f32,\n lightSample: ptr<function, LightSampleRec>\n) {\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).pdf = 0.0;\n (*lightSample).selectionPmf = 0.0;\n (*lightSample).dist = INF;\n (*lightSample).isDelta = false;\n (*lightSample).sourceType = 0u;\n (*lightSample).sourceIndex = 0xffffffffu;\n if (choiceCount <= 0) {\n return;\n }\n\n let scaledChoice = rnd.z * f32(choiceCount);\n let column = min(i32(scaledChoice), choiceCount - 1);\n let columnChoice = getLightChoiceFromTable(tableOffset, column);\n let selectedIndex = select(\n columnChoice.aliasIndex,\n column,\n fract(scaledChoice) < columnChoice.probability\n );\n let choice = getLightChoiceFromTable(tableOffset, selectedIndex);\n if (USE_ENVMAP && choice.sourceType == ${LIGHT_CHOICE_ENVIRONMENT}) {\n (*lightSample).sourceType = 0u;\n (*lightSample).sourceIndex = u32(choice.sourceIndex);\n sampleEnvLight(rnd.xy, lightSample);\n (*lightSample).selectionPmf = rtUniform.envLightPmf;\n (*lightSample).pdf *= rtUniform.envLightPmf;\n }\n else if (choice.sourceType == ${LIGHT_CHOICE_ANALYTIC}) {\n (*lightSample).sourceType = 2u;\n (*lightSample).sourceIndex = u32(choice.sourceIndex);\n let light = analyticLights[choice.sourceIndex];\n sampleAnalyticLight(light, scatterPos, rnd.xy, lightSample);\n (*lightSample).selectionPmf = light.selectionPmf;\n (*lightSample).pdf *= light.selectionPmf;\n }\n else if (HAS_SCENE_EMISSIVE_LIGHT && choice.sourceType == ${LIGHT_CHOICE_EMISSIVE_TRIANGLE}) {\n (*lightSample).sourceType = 1u;\n (*lightSample).sourceIndex = u32(choice.sourceIndex);\n sampleEmissiveTriangleLight(\n getEmissiveTriangle(choice.sourceIndex),\n scatterPos,\n rnd.xy,\n lightSample\n );\n }\n (*lightSample).selectionPmf *= selectionPmfScale;\n (*lightSample).pdf *= selectionPmfScale;\n}\n\nfn sampleLight(\n scatterPos: vec3f,\n rnd: vec3f,\n lightSample: ptr<function, LightSampleRec>,\n distByIntensity: bool\n) {\n sampleLightChoiceTable(\n scatterPos,\n rnd,\n 0,\n rtUniform.lightChoiceCount,\n 1.0,\n lightSample\n );\n}\n\n// Light choice for one of the resampled NEE candidates. The selection random\n// number is stratified across the candidates.\nfn sampleLightForNEECandidate(\n scatterPos: vec3f,\n rnd: vec3f,\n candidateIndex: u32,\n candidateCount: u32,\n lightSample: ptr<function, LightSampleRec>\n) {\n sampleLightChoiceTable(\n scatterPos,\n stratifyLightChoiceRandom(rnd, candidateIndex, candidateCount),\n 0,\n rtUniform.lightChoiceCount,\n 1.0,\n lightSample\n );\n}\n`;\n"]}
1
+ {"version":3,"file":"sampleLight.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/sampleLight.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,qBAAqB,EACrB,8BAA8B,EAC9B,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAEjC,eAAe,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAsVkB,wBAAwB;;;;;;;gCAOjC,qBAAqB;;;;;;;;4DAQO,8BAA8B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgD3F,CAAC","sourcesContent":["import {\n LIGHT_CHOICE_ANALYTIC,\n LIGHT_CHOICE_EMISSIVE_TRIANGLE,\n LIGHT_CHOICE_ENVIRONMENT\n} from '../../lightConstants.js';\n\nexport default /*wgsl */ `\nfn light_sample_sphere(light: Light, scatterPos: vec3f, randomV2: vec2f, lightSample: ptr<function, LightSampleRec>) {\n let centerOffset = light.position - scatterPos;\n let centerDistance = length(centerOffset);\n if (light.radiusOrSpread <= 0.0) {\n // A zero-radius sphere is a point emitter. The stored emission is\n // luminous intensity, so convert it to incident radiance here rather\n // than approximating the delta source as a tiny area sphere.\n if (centerDistance <= 1e-6) {\n (*lightSample).direction = vec3f(0.0, 0.0, 1.0);\n (*lightSample).normal = vec3f(0.0, 0.0, -1.0);\n (*lightSample).dist = 0.0;\n (*lightSample).pdf = 1.0;\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).isDelta = true;\n return;\n }\n (*lightSample).direction = centerOffset / centerDistance;\n (*lightSample).normal = -(*lightSample).direction;\n (*lightSample).dist = centerDistance;\n (*lightSample).pdf = 1.0;\n (*lightSample).emission = light.emission /\n max(centerDistance * centerDistance, 1e-8);\n (*lightSample).isDelta = true;\n return;\n }\n let radius = max(light.radiusOrSpread, 1e-6);\n (*lightSample).isDelta = false;\n var sampledDirection: vec3f;\n\n if (centerDistance <= radius) {\n let z = 1.0 - 2.0 * randomV2.x;\n let radial = sqrt(max(0.0, 1.0 - z * z));\n let azimuth = TWOPI * randomV2.y;\n sampledDirection = vec3f(\n radial * cos(azimuth),\n radial * sin(azimuth),\n z\n );\n (*lightSample).pdf = INV4PI;\n }\n else {\n let sphereAxis = centerOffset / centerDistance;\n let sinThetaMaxSquared = min(\n 1.0,\n radius * radius / (centerDistance * centerDistance)\n );\n let cosThetaMax = sqrt(max(0.0, 1.0 - sinThetaMaxSquared));\n // Rationalize 1 - cos(thetaMax): subtracting nearly equal f32 values\n // quantizes small emitters' solid angles into visible irradiance bands.\n let oneMinusCosThetaMax = sinThetaMaxSquared / (1.0 + cosThetaMax);\n let oneMinusCosTheta = randomV2.x * oneMinusCosThetaMax;\n let cosTheta = 1.0 - oneMinusCosTheta;\n let sinTheta = sqrt(max(0.0, oneMinusCosTheta * (2.0 - oneMinusCosTheta)));\n let azimuth = TWOPI * randomV2.y;\n var tangent: vec3f;\n var bitangent: vec3f;\n sampling_orthonormal_basis(sphereAxis, &tangent, &bitangent);\n sampledDirection = sphereAxis * cosTheta\n + tangent * (sinTheta * cos(azimuth))\n + bitangent * (sinTheta * sin(azimuth));\n (*lightSample).pdf = 1.0 / max(\n TWOPI * oneMinusCosThetaMax,\n 1e-8\n );\n }\n\n let centerProjection = dot(sampledDirection, centerOffset);\n let centerOffsetSquared = dot(centerOffset, centerOffset);\n let discriminant = centerProjection * centerProjection\n - centerOffsetSquared + radius * radius;\n let nearDistance = centerProjection - sqrt(max(0.0, discriminant));\n let farDistance = centerProjection + sqrt(max(0.0, discriminant));\n (*lightSample).dist = select(farDistance, nearDistance, nearDistance > 1e-6);\n (*lightSample).direction = sampledDirection;\n let lightSurfacePos = scatterPos + sampledDirection * (*lightSample).dist;\n (*lightSample).normal = normalize(lightSurfacePos - light.position);\n (*lightSample).emission = light.emission;\n}\n\nfn light_apply_rect_texture(\n light: Light,\n surfacePoint: vec3f,\n lowerLeft: vec3f,\n result: ptr<function, LightSampleRec>\n) {\n if (light.textureIndex < 0.0) {\n return;\n }\n let width = length(light.u);\n let height = length(light.v);\n let relative = surfacePoint - lowerLeft;\n let uv = vec2f(\n dot(relative, light.u / width) / width,\n dot(relative, light.v / height) / height\n );\n (*result).emission *= sampleMap(i32(light.textureIndex), uv).rgb;\n}\n\nfn light_sample_rect(\n light: Light,\n shadingPoint: vec3f,\n samplePoint: vec2f,\n result: ptr<function, LightSampleRec>\n) {\n let normal = normalize(cross(light.u, light.v));\n let lowerLeft = light.position - 0.5 * (light.u + light.v);\n let spread = clamp(light.radiusOrSpread, 0.0, 1.0);\n\n if (spread <= 0.001) {\n let planeDistance = dot(normal, shadingPoint - light.position);\n let surfacePoint = shadingPoint - normal * planeDistance;\n let relative = surfacePoint - lowerLeft;\n let width = length(light.u);\n let height = length(light.v);\n let uv = vec2f(\n dot(relative, light.u / width) / width,\n dot(relative, light.v / height) / height\n );\n if (planeDistance <= 0.0 || any(uv < vec2f(0.0)) || any(uv > vec2f(1.0))) {\n (*result).emission = vec3f(0.0);\n (*result).pdf = 0.0;\n return;\n }\n (*result).direction = -normal;\n (*result).dist = planeDistance;\n (*result).normal = normal;\n (*result).emission = light.emission;\n (*result).pdf = 1.0;\n (*result).isDelta = true;\n light_apply_rect_texture(light, surfacePoint, lowerLeft, result);\n return;\n }\n\n let surfacePoint = lowerLeft\n + light.u * samplePoint.x\n + light.v * samplePoint.y;\n let offset = surfacePoint - shadingPoint;\n let distanceSquared = dot(offset, offset);\n (*result).dist = sqrt(distanceSquared);\n (*result).direction = offset / (*result).dist;\n (*result).normal = normal;\n let emitterCosine = dot(-(*result).direction, normal);\n let spreadCosine = cos(0.5 * PI * spread);\n if (emitterCosine <= 0.0 || emitterCosine < spreadCosine) {\n (*result).emission = vec3f(0.0);\n (*result).pdf = 0.0;\n return;\n }\n (*result).emission = light.emission;\n (*result).pdf = distanceSquared / max(light.area * emitterCosine, 1e-8);\n light_apply_rect_texture(light, surfacePoint, lowerLeft, result);\n}\n\nfn light_sample_directional(\n light: Light,\n result: ptr<function, LightSampleRec>\n) {\n (*result).direction = normalize(-light.u);\n (*result).normal = -(*result).direction;\n (*result).emission = light.emission;\n (*result).dist = INF;\n (*result).pdf = 1.0;\n (*result).isDelta = true;\n}\n\nfn light_sample_spot(\n light: Light,\n shadingPoint: vec3f,\n samplePoint: vec2f,\n result: ptr<function, LightSampleRec>\n) {\n light_sample_sphere(light, shadingPoint, samplePoint, result);\n let surfacePoint = shadingPoint + (*result).direction * (*result).dist;\n let lightToSurface = normalize(shadingPoint - surfacePoint);\n (*result).emission *= evaluateSpotEmissionMultiplier(light, lightToSurface);\n}\n\nfn sampleAnalyticLight(\n light: Light,\n shadingPoint: vec3f,\n samplePoint: vec2f,\n result: ptr<function, LightSampleRec>\n) {\n let lightType = i32(light.litType);\n if (HAS_SCENE_RECT_LIGHT && lightType == RECT_LIGHT) {\n light_sample_rect(light, shadingPoint, samplePoint, result);\n return;\n }\n if (HAS_SCENE_SPHERE_LIGHT && lightType == SPHERE_LIGHT) {\n light_sample_sphere(light, shadingPoint, samplePoint, result);\n return;\n }\n if (HAS_SCENE_SPOT_LIGHT && lightType == SPOT_LIGHT) {\n light_sample_spot(light, shadingPoint, samplePoint, result);\n return;\n }\n if (HAS_SCENE_DIRECTIONAL_LIGHT && lightType == DIRECTIONAL_LIGHT) {\n light_sample_directional(light, result);\n }\n}\n\nfn sampleEnvLight(randomV2: vec2f, lightSample: ptr<function, LightSampleRec>) {\n var uv: vec2f;\n // Naga's SPIR-V writer cannot pass a struct-member pointer as a call argument.\n var pdf: f32;\n let direction = sampleEnvmap(randomV2, &uv, &pdf);\n (*lightSample).pdf = pdf;\n (*lightSample).direction = direction;\n (*lightSample).emission = textureLinear(envMap, uv).rgb;\n (*lightSample).dist = INF;\n}\n\nfn loadLightSamplingTexel(texelIndex: i32) -> vec4f {\n let width = rtUniform.lightSamplingTextureWidth;\n return textureLoad(\n lightSamplingData,\n vec2i(texelIndex % width, texelIndex / width),\n 0\n );\n}\n\nfn getEmissiveTriangle(index: i32) -> EmissiveTriangle {\n let offset = index * 6;\n let a = loadLightSamplingTexel(offset);\n let b = loadLightSamplingTexel(offset + 1);\n let c = loadLightSamplingTexel(offset + 2);\n let d = loadLightSamplingTexel(offset + 3);\n let e = loadLightSamplingTexel(offset + 4);\n let f = loadLightSamplingTexel(offset + 5);\n return EmissiveTriangle(\n a.xyz, a.w,\n b.xyz, b.w,\n c.xyz, c.w,\n d.xy, d.zw, e.xy,\n e.zw, f.xy, f.zw\n );\n}\n\nfn getLightChoice(index: i32) -> LightChoice {\n let data = loadLightSamplingTexel(rtUniform.lightChoiceTexelOffset + index);\n return LightChoice(\n data.x,\n bitcast<i32>(data.y),\n bitcast<i32>(data.z),\n bitcast<i32>(data.w)\n );\n}\n\nfn getLightChoiceFromTable(tableOffset: i32, index: i32) -> LightChoice {\n return getLightChoice(tableOffset + index);\n}\n\nfn stratifyLightChoiceRandom(\n rnd: vec3f,\n candidateIndex: u32,\n candidateCount: u32\n) -> vec3f {\n var stratified = rnd;\n let count = max(candidateCount, 1u);\n stratified.z = (rnd.z + f32(min(candidateIndex, count - 1u))) /\n f32(count);\n return stratified;\n}\n\nfn sampleEmissiveTriangleLight(\n triangle: EmissiveTriangle,\n scatterPos: vec3f,\n randomV2: vec2f,\n lightSample: ptr<function, LightSampleRec>\n) {\n let sqrtU = sqrt(randomV2.x);\n let barycentric = vec3f(\n 1.0 - sqrtU,\n sqrtU * (1.0 - randomV2.y),\n sqrtU * randomV2.y\n );\n let lightPosition =\n barycentric.x * triangle.p0 +\n barycentric.y * triangle.p1 +\n barycentric.z * triangle.p2;\n let uv =\n barycentric.x * triangle.uv0 +\n barycentric.y * triangle.uv1 +\n barycentric.z * triangle.uv2;\n let secondaryUv =\n barycentric.x * triangle.secondaryUv0 +\n barycentric.y * triangle.secondaryUv1 +\n barycentric.z * triangle.secondaryUv2;\n let normal = normalize(cross(triangle.p1 - triangle.p0, triangle.p2 - triangle.p0));\n (*lightSample).direction = lightPosition - scatterPos;\n (*lightSample).dist = length((*lightSample).direction);\n if ((*lightSample).dist <= EPS) {\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).pdf = 0.0;\n return;\n }\n (*lightSample).direction /= (*lightSample).dist;\n (*lightSample).normal = normal;\n let cosLight = dot(normal, -(*lightSample).direction);\n if (cosLight <= 0.0) {\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).pdf = 0.0;\n return;\n }\n (*lightSample).emission = getMaterialEmission(\n i32(triangle.materialIndex), uv, secondaryUv\n );\n (*lightSample).selectionPmf = triangle.selectionPmf;\n (*lightSample).pdf = triangle.selectionPmf *\n ((*lightSample).dist * (*lightSample).dist) /\n max(triangle.area * cosLight, 1e-8);\n}\n\nfn sampleLightChoiceTable(\n scatterPos: vec3f,\n rnd: vec3f,\n tableOffset: i32,\n choiceCount: i32,\n selectionPmfScale: f32,\n lightSample: ptr<function, LightSampleRec>\n) {\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).pdf = 0.0;\n (*lightSample).selectionPmf = 0.0;\n (*lightSample).dist = INF;\n (*lightSample).isDelta = false;\n (*lightSample).sourceType = 0u;\n (*lightSample).sourceIndex = 0xffffffffu;\n if (choiceCount <= 0) {\n return;\n }\n\n let scaledChoice = rnd.z * f32(choiceCount);\n let column = min(i32(scaledChoice), choiceCount - 1);\n let columnChoice = getLightChoiceFromTable(tableOffset, column);\n let selectedIndex = select(\n columnChoice.aliasIndex,\n column,\n fract(scaledChoice) < columnChoice.probability\n );\n let choice = getLightChoiceFromTable(tableOffset, selectedIndex);\n if (USE_ENVMAP && choice.sourceType == ${LIGHT_CHOICE_ENVIRONMENT}) {\n (*lightSample).sourceType = 0u;\n (*lightSample).sourceIndex = u32(choice.sourceIndex);\n sampleEnvLight(rnd.xy, lightSample);\n (*lightSample).selectionPmf = rtUniform.envLightPmf;\n (*lightSample).pdf *= rtUniform.envLightPmf;\n }\n else if (choice.sourceType == ${LIGHT_CHOICE_ANALYTIC}) {\n (*lightSample).sourceType = 2u;\n (*lightSample).sourceIndex = u32(choice.sourceIndex);\n let light = analyticLights[choice.sourceIndex];\n sampleAnalyticLight(light, scatterPos, rnd.xy, lightSample);\n (*lightSample).selectionPmf = light.selectionPmf;\n (*lightSample).pdf *= light.selectionPmf;\n }\n else if (HAS_SCENE_EMISSIVE_LIGHT && choice.sourceType == ${LIGHT_CHOICE_EMISSIVE_TRIANGLE}) {\n (*lightSample).sourceType = 1u;\n (*lightSample).sourceIndex = u32(choice.sourceIndex);\n sampleEmissiveTriangleLight(\n getEmissiveTriangle(choice.sourceIndex),\n scatterPos,\n rnd.xy,\n lightSample\n );\n }\n (*lightSample).selectionPmf *= selectionPmfScale;\n (*lightSample).pdf *= selectionPmfScale;\n}\n\nfn sampleLight(\n scatterPos: vec3f,\n rnd: vec3f,\n lightSample: ptr<function, LightSampleRec>,\n distByIntensity: bool\n) {\n sampleLightChoiceTable(\n scatterPos,\n rnd,\n 0,\n rtUniform.lightChoiceCount,\n 1.0,\n lightSample\n );\n}\n\n// Light choice for one of the resampled NEE candidates. The selection random\n// number is stratified across the candidates.\nfn sampleLightForNEECandidate(\n scatterPos: vec3f,\n rnd: vec3f,\n candidateIndex: u32,\n candidateCount: u32,\n lightSample: ptr<function, LightSampleRec>\n) {\n sampleLightChoiceTable(\n scatterPos,\n stratifyLightChoiceRandom(rnd, candidateIndex, candidateCount),\n 0,\n rtUniform.lightChoiceCount,\n 1.0,\n lightSample\n );\n}\n`;\n"]}
@@ -1,3 +1,3 @@
1
- export declare function createSampleMaterialWgsl(hasAnisotropyDirections?: boolean, hasCoatNormals?: boolean): string;
1
+ export declare function createSampleMaterialWgsl(hasAnisotropyDirections?: boolean, hasCoatNormals?: boolean, caustics?: boolean, researchContribution?: string, photonMapping?: boolean): string;
2
2
  declare const _default: string;
3
3
  export default _default;