@meimu/mutracer 0.1.5 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/Classroom-CC0.txt +121 -0
- package/README.md +10 -7
- package/THIRD_PARTY_NOTICES.md +13 -8
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +12316 -9228
- package/docs/api.md +232 -21
- package/docs/caustics.md +80 -0
- package/docs/denoising.md +30 -15
- package/docs/materials.md +6 -5
- package/docs/performance.md +5 -2
- package/docs/progressive-rendering.md +73 -1
- package/docs/technical/continuous-spectrum.md +93 -0
- package/docs/threejs.md +14 -5
- package/docs/updates.md +46 -2
- package/docs/viewer-checklist.md +65 -0
- package/docs/viewer.md +15 -8
- package/lib/Display.d.ts +13 -2
- package/lib/Display.js +28 -7
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +4 -0
- package/lib/Engine.js +99 -37
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +98 -15
- package/lib/Render.js +275 -27
- package/lib/Render.js.map +1 -1
- package/lib/RenderLoop.d.ts +11 -1
- package/lib/RenderLoop.js +120 -15
- package/lib/RenderLoop.js.map +1 -1
- package/lib/main.d.ts +6 -3
- package/lib/main.js +1 -0
- package/lib/main.js.map +1 -1
- package/lib/math/access.d.ts +4 -0
- package/lib/math/access.js +10 -0
- package/lib/math/access.js.map +1 -0
- package/lib/math/mat3.d.ts +4 -0
- package/lib/math/mat3.js +54 -0
- package/lib/math/mat3.js.map +1 -0
- package/lib/math/mat4.d.ts +19 -0
- package/lib/math/mat4.js +413 -0
- package/lib/math/mat4.js.map +1 -0
- package/lib/math/storage.d.ts +6 -0
- package/lib/math/storage.js +22 -0
- package/lib/math/storage.js.map +1 -0
- package/lib/math/types.d.ts +3 -0
- package/lib/math/types.js +2 -0
- package/lib/math/types.js.map +1 -0
- package/lib/math/vec2.d.ts +13 -0
- package/lib/math/vec2.js +52 -0
- package/lib/math/vec2.js.map +1 -0
- package/lib/math/vec3.d.ts +23 -0
- package/lib/math/vec3.js +139 -0
- package/lib/math/vec3.js.map +1 -0
- package/lib/math.d.ts +5 -17
- package/lib/math.js +5 -55
- package/lib/math.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/oidn.js +4 -2
- package/lib/oidn.js.map +1 -1
- package/lib/oidnBundledWeights.cdn.d.ts +2 -2
- package/lib/renderer/AovPrimitiveCache.d.ts +10 -0
- package/lib/renderer/AovPrimitiveCache.js +48 -0
- package/lib/renderer/AovPrimitiveCache.js.map +1 -0
- package/lib/renderer/Box3.d.ts +5 -0
- package/lib/renderer/Box3.js +9 -0
- package/lib/renderer/Box3.js.map +1 -0
- package/lib/renderer/GPUTraceQueue.d.ts +11 -0
- package/lib/renderer/GPUTraceQueue.js +33 -0
- package/lib/renderer/GPUTraceQueue.js.map +1 -0
- package/lib/renderer/MaterialData.d.ts +15 -0
- package/lib/renderer/MaterialData.js +61 -0
- package/lib/renderer/MaterialData.js.map +1 -0
- package/lib/renderer/MaterialTable.d.ts +11 -98
- package/lib/renderer/MaterialTable.js +34 -412
- package/lib/renderer/MaterialTable.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +36 -13
- package/lib/renderer/RenderingPipeline.js +1 -17
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/TileRender.d.ts +0 -1
- package/lib/renderer/TileRender.js +14 -1
- package/lib/renderer/TileRender.js.map +1 -1
- package/lib/renderer/WGPUAov.d.ts +39 -0
- package/lib/renderer/WGPUAov.js +239 -0
- package/lib/renderer/WGPUAov.js.map +1 -0
- package/lib/renderer/WGPUBindlessMaterialData.d.ts +17 -0
- package/lib/renderer/WGPUBindlessMaterialData.js +48 -0
- package/lib/renderer/WGPUBindlessMaterialData.js.map +1 -0
- package/lib/renderer/WGPUBindlessTextures.d.ts +47 -0
- package/lib/renderer/WGPUBindlessTextures.js +180 -0
- package/lib/renderer/WGPUBindlessTextures.js.map +1 -0
- package/lib/renderer/WGPUBloomPass.js +17 -97
- package/lib/renderer/WGPUBloomPass.js.map +1 -1
- package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
- package/lib/renderer/WGPUCausticLightPass.js +217 -0
- package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
- package/lib/renderer/WGPUComputePass.d.ts +1 -1
- package/lib/renderer/WGPUComputePass.js.map +1 -1
- package/lib/renderer/WGPUEnvMapDistribution.d.ts +12 -0
- package/lib/renderer/WGPUEnvMapDistribution.js +150 -0
- package/lib/renderer/WGPUEnvMapDistribution.js.map +1 -0
- package/lib/renderer/WGPUFullQuadPass.js +10 -9
- package/lib/renderer/WGPUFullQuadPass.js.map +1 -1
- package/lib/renderer/WGPUJNLMDenoiser.d.ts +1 -20
- package/lib/renderer/WGPUJNLMDenoiser.js +4 -267
- package/lib/renderer/WGPUJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
- package/lib/renderer/WGPUPhotonMap.js +191 -0
- package/lib/renderer/WGPUPhotonMap.js.map +1 -0
- package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
- package/lib/renderer/WGPURayTraceOutput.js +132 -29
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.d.ts +83 -56
- package/lib/renderer/WGPURayTracePass.js +884 -837
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.d.ts +5 -3
- package/lib/renderer/WGPURenderingPipeline.js +297 -82
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WGPUShaderCache.d.ts +2 -2
- package/lib/renderer/WGPUShaderCache.js +10 -5
- package/lib/renderer/WGPUShaderCache.js.map +1 -1
- package/lib/renderer/WGPUShaderCapabilities.d.ts +10 -0
- package/lib/renderer/WGPUShaderCapabilities.js +54 -0
- package/lib/renderer/WGPUShaderCapabilities.js.map +1 -0
- package/lib/renderer/WGPUSkyBaker.d.ts +13 -0
- package/lib/renderer/WGPUSkyBaker.js +85 -0
- package/lib/renderer/WGPUSkyBaker.js.map +1 -0
- package/lib/renderer/WebGLAov.d.ts +41 -0
- package/lib/renderer/WebGLAov.js +106 -0
- package/lib/renderer/WebGLAov.js.map +1 -0
- package/lib/renderer/WebGLFullQuadPass.d.ts +7 -4
- package/lib/renderer/WebGLFullQuadPass.js +22 -2
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.d.ts +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +83 -74
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WebGLRayTraceOutputPass.js +7 -4
- package/lib/renderer/WebGLRayTraceOutputPass.js.map +1 -1
- package/lib/renderer/WebGLRayTracePass.d.ts +18 -3
- package/lib/renderer/WebGLRayTracePass.js +121 -9
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +126 -22
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.d.ts +39 -0
- package/lib/renderer/WebGLSkyBaker.js +422 -0
- package/lib/renderer/WebGLSkyBaker.js.map +1 -0
- package/lib/renderer/WebGLSkySource.d.ts +9 -0
- package/lib/renderer/WebGLSkySource.js +28 -0
- package/lib/renderer/WebGLSkySource.js.map +1 -0
- package/lib/renderer/accumulationTarget.d.ts +6 -0
- package/lib/renderer/accumulationTarget.js.map +1 -1
- package/lib/renderer/aov.d.ts +42 -0
- package/lib/renderer/aov.js +50 -0
- package/lib/renderer/aov.js.map +1 -0
- package/lib/renderer/aovDisplay.d.ts +14 -0
- package/lib/renderer/aovDisplay.js +32 -0
- package/lib/renderer/aovDisplay.js.map +1 -0
- package/lib/renderer/aovScene.d.ts +21 -0
- package/lib/renderer/aovScene.js +139 -0
- package/lib/renderer/aovScene.js.map +1 -0
- package/lib/renderer/binnedSahBvh.js +2 -1
- package/lib/renderer/binnedSahBvh.js.map +1 -1
- package/lib/renderer/bvhAccel.d.ts +20 -10
- package/lib/renderer/bvhAccel.js +168 -58
- package/lib/renderer/bvhAccel.js.map +1 -1
- package/lib/renderer/bvhWorkerBuild.d.ts +1 -0
- package/lib/renderer/cameraSnapshot.js +2 -1
- package/lib/renderer/cameraSnapshot.js.map +1 -1
- package/lib/renderer/cameraUniform.d.ts +2 -0
- package/lib/renderer/cameraUniform.js +12 -0
- package/lib/renderer/cameraUniform.js.map +1 -0
- package/lib/renderer/causticDiagnostics.d.ts +31 -0
- package/lib/renderer/causticDiagnostics.js +5 -0
- package/lib/renderer/causticDiagnostics.js.map +1 -0
- package/lib/renderer/causticEmission.d.ts +10 -0
- package/lib/renderer/causticEmission.js +40 -0
- package/lib/renderer/causticEmission.js.map +1 -0
- package/lib/renderer/causticUniform.d.ts +12 -0
- package/lib/renderer/causticUniform.js +22 -0
- package/lib/renderer/causticUniform.js.map +1 -0
- package/lib/renderer/caustics.d.ts +16 -0
- package/lib/renderer/caustics.js +93 -0
- package/lib/renderer/caustics.js.map +1 -0
- package/lib/renderer/committedScene.js +4 -0
- package/lib/renderer/committedScene.js.map +1 -1
- package/lib/renderer/denoiser.d.ts +3 -11
- package/lib/renderer/denoiser.js.map +1 -1
- package/lib/renderer/depthQuery.js +4 -1
- package/lib/renderer/depthQuery.js.map +1 -1
- package/lib/renderer/displacementPreparation.d.ts +11 -0
- package/lib/renderer/displacementPreparation.js +351 -0
- package/lib/renderer/displacementPreparation.js.map +1 -0
- package/lib/renderer/displacementRange.d.ts +1 -0
- package/lib/renderer/displacementRange.js +9 -0
- package/lib/renderer/displacementRange.js.map +1 -0
- package/lib/renderer/displayParityDiagnostics.d.ts +11 -0
- package/lib/renderer/displayParityDiagnostics.js +2 -0
- package/lib/renderer/displayParityDiagnostics.js.map +1 -0
- package/lib/renderer/envMapCreation.d.ts +9 -8
- package/lib/renderer/envMapCreation.js +36 -12
- package/lib/renderer/envMapCreation.js.map +1 -1
- package/lib/renderer/envMapDistribution.d.ts +12 -2
- package/lib/renderer/envMapDistribution.js +43 -34
- package/lib/renderer/envMapDistribution.js.map +1 -1
- package/lib/renderer/geometryBvhBounds.d.ts +4 -0
- package/lib/renderer/geometryBvhBounds.js +82 -0
- package/lib/renderer/geometryBvhBounds.js.map +1 -0
- package/lib/renderer/geometryUpdateState.d.ts +32 -0
- package/lib/renderer/geometryUpdateState.js +2 -0
- package/lib/renderer/geometryUpdateState.js.map +1 -0
- package/lib/renderer/geometryUpdates.d.ts +17 -9
- package/lib/renderer/geometryUpdates.js +92 -33
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/aovDisplay.frag.d.ts +3 -0
- package/lib/renderer/glsl/aovDisplay.frag.js +54 -0
- package/lib/renderer/glsl/aovDisplay.frag.js.map +1 -0
- package/lib/renderer/glsl/aovReflectance.glsl.d.ts +2 -0
- package/lib/renderer/glsl/aovReflectance.glsl.js +87 -0
- package/lib/renderer/glsl/aovReflectance.glsl.js.map +1 -0
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.d.ts +2 -0
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +135 -0
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js.map +1 -0
- package/lib/renderer/glsl/aovTrace.frag.d.ts +2 -0
- package/lib/renderer/glsl/aovTrace.frag.js +121 -0
- package/lib/renderer/glsl/aovTrace.frag.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -67
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/intersect.glsl.js +432 -434
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +160 -157
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +802 -802
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +72 -67
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +143 -120
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +21 -18
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampling.glsl.js +91 -94
- package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js.map +1 -1
- package/lib/renderer/glsl/depthQuery.frag.js +7 -7
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +17 -9
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js.map +1 -1
- package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
- package/lib/renderer/glsl/rayTrace.frag.js +271 -248
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +37 -32
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +65 -60
- package/lib/renderer/glsl/webglPipeline.frag.js.map +1 -1
- package/lib/renderer/lightConstants.d.ts +10 -0
- package/lib/renderer/lightConstants.js +11 -0
- package/lib/renderer/lightConstants.js.map +1 -0
- package/lib/renderer/lightCore.d.ts +12 -0
- package/lib/renderer/lightCore.js +13 -0
- package/lib/renderer/lightCore.js.map +1 -0
- package/lib/renderer/lightSampling.d.ts +22 -18
- package/lib/renderer/lightSampling.js +135 -62
- package/lib/renderer/lightSampling.js.map +1 -1
- package/lib/renderer/lightsData.d.ts +21 -0
- package/lib/renderer/lightsData.js +192 -0
- package/lib/renderer/lightsData.js.map +1 -0
- package/lib/renderer/lightsUtil.d.ts +3 -26
- package/lib/renderer/lightsUtil.js +3 -153
- package/lib/renderer/lightsUtil.js.map +1 -1
- package/lib/renderer/materialBufferData.d.ts +70 -0
- package/lib/renderer/materialBufferData.js +2 -0
- package/lib/renderer/materialBufferData.js.map +1 -0
- package/lib/renderer/materialConstants.d.ts +11 -0
- package/lib/renderer/materialConstants.js +11 -0
- package/lib/renderer/materialConstants.js.map +1 -1
- package/lib/renderer/materialCore.d.ts +8 -0
- package/lib/renderer/materialCore.js +9 -0
- package/lib/renderer/materialCore.js.map +1 -0
- package/lib/renderer/materialEmission.d.ts +2 -2
- package/lib/renderer/materialEmission.js +3 -3
- package/lib/renderer/materialEmission.js.map +1 -1
- package/lib/renderer/materialLayout.d.ts +2 -101
- package/lib/renderer/materialLayout.js +110 -172
- package/lib/renderer/materialLayout.js.map +1 -1
- package/lib/renderer/materialLayoutSchema.d.ts +26 -0
- package/lib/renderer/materialLayoutSchema.js +172 -0
- package/lib/renderer/materialLayoutSchema.js.map +1 -0
- package/lib/renderer/materialParams.d.ts +69 -0
- package/lib/renderer/materialParams.js +272 -0
- package/lib/renderer/materialParams.js.map +1 -0
- package/lib/renderer/materialTextureSlots.d.ts +14 -324
- package/lib/renderer/materialTextureSlots.js +21 -8
- package/lib/renderer/materialTextureSlots.js.map +1 -1
- package/lib/renderer/materialTextures.d.ts +6 -0
- package/lib/renderer/{texturesFromMaterials.js → materialTextures.js} +1 -2
- package/lib/renderer/materialTextures.js.map +1 -0
- package/lib/renderer/mergeMeshesToGeometry.js +6 -147
- package/lib/renderer/mergeMeshesToGeometry.js.map +1 -1
- package/lib/renderer/meshInstances.d.ts +4 -21
- package/lib/renderer/meshInstances.js +10 -56
- package/lib/renderer/meshInstances.js.map +1 -1
- package/lib/renderer/oidnNetwork.d.ts +2 -2
- package/lib/renderer/oidnNetwork.js +1 -1
- package/lib/renderer/oidnNetwork.js.map +1 -1
- package/lib/renderer/openPbrEnergyLut.js +850 -846
- package/lib/renderer/openPbrEnergyLut.js.map +1 -1
- package/lib/renderer/ownedDenoiser.d.ts +9 -0
- package/lib/renderer/ownedDenoiser.js +2 -0
- package/lib/renderer/ownedDenoiser.js.map +1 -0
- package/lib/renderer/packedMeshInstances.d.ts +23 -0
- package/lib/renderer/packedMeshInstances.js +80 -0
- package/lib/renderer/packedMeshInstances.js.map +1 -0
- package/lib/renderer/prepareMeshBVH.d.ts +12 -47
- package/lib/renderer/prepareMeshBVH.js +21 -642
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/proceduralEnvironmentPower.d.ts +3 -0
- package/lib/renderer/proceduralEnvironmentPower.js +8 -0
- package/lib/renderer/proceduralEnvironmentPower.js.map +1 -0
- package/lib/renderer/progressiveScheduler.d.ts +1 -0
- package/lib/renderer/progressiveScheduler.js +7 -3
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +4 -1
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/renderingLimits.d.ts +9 -0
- package/lib/renderer/renderingLimits.js +18 -0
- package/lib/renderer/renderingLimits.js.map +1 -0
- package/lib/renderer/researchTransport.d.ts +31 -0
- package/lib/renderer/researchTransport.js +5 -0
- package/lib/renderer/researchTransport.js.map +1 -0
- package/lib/renderer/sceneAssembly.d.ts +73 -0
- package/lib/renderer/sceneAssembly.js +109 -0
- package/lib/renderer/sceneAssembly.js.map +1 -0
- package/lib/renderer/sceneChangeCore.d.ts +39 -0
- package/lib/renderer/sceneChangeCore.js +307 -0
- package/lib/renderer/sceneChangeCore.js.map +1 -0
- package/lib/renderer/sceneChangeDetector.d.ts +3 -6
- package/lib/renderer/sceneChangeDetector.js +24 -150
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLayoutSchema.d.ts +119 -0
- package/lib/renderer/sceneLayoutSchema.js +111 -0
- package/lib/renderer/sceneLayoutSchema.js.map +1 -0
- package/lib/renderer/sceneLightChanges.d.ts +3 -3
- package/lib/renderer/sceneLightChanges.js.map +1 -1
- package/lib/renderer/scenePreparation.d.ts +55 -0
- package/lib/renderer/scenePreparation.js +360 -0
- package/lib/renderer/scenePreparation.js.map +1 -0
- package/lib/renderer/scratchSampling.js +18 -18
- package/lib/renderer/scratchSampling.js.map +1 -1
- package/lib/renderer/shader.d.ts +2 -0
- package/lib/renderer/shader.js +2 -0
- package/lib/renderer/shader.js.map +1 -1
- package/lib/renderer/shaderCapabilities.d.ts +23 -0
- package/lib/renderer/shaderCapabilities.js +55 -0
- package/lib/renderer/shaderCapabilities.js.map +1 -0
- package/lib/renderer/shaderCapacity.d.ts +2 -0
- package/lib/renderer/shaderCapacity.js +5 -0
- package/lib/renderer/shaderCapacity.js.map +1 -0
- package/lib/renderer/skyModel.d.ts +9 -0
- package/lib/renderer/skyModel.js +10 -0
- package/lib/renderer/skyModel.js.map +1 -0
- package/lib/renderer/spectrum.d.ts +21 -0
- package/lib/renderer/spectrum.js +154 -0
- package/lib/renderer/spectrum.js.map +1 -0
- package/lib/renderer/textureAtlas.d.ts +60 -0
- package/lib/renderer/textureAtlas.js +145 -0
- package/lib/renderer/textureAtlas.js.map +1 -0
- package/lib/renderer/textureAtlasPixels.d.ts +7 -0
- package/lib/renderer/textureAtlasPixels.js +68 -0
- package/lib/renderer/textureAtlasPixels.js.map +1 -0
- package/lib/renderer/util.d.ts +1 -1
- package/lib/renderer/util.js.map +1 -1
- package/lib/renderer/webgl.d.ts +9 -2
- package/lib/renderer/webgl.js +54 -9
- package/lib/renderer/webgl.js.map +1 -1
- package/lib/renderer/webglLightSampling.d.ts +39 -0
- package/lib/renderer/webglLightSampling.js +15 -0
- package/lib/renderer/webglLightSampling.js.map +1 -0
- package/lib/renderer/wgpuBindless.d.ts +26 -0
- package/lib/renderer/wgpuBindless.js +95 -0
- package/lib/renderer/wgpuBindless.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.d.ts +2 -0
- package/lib/renderer/wgpuBindlessSource.js +51 -0
- package/lib/renderer/wgpuBindlessSource.js.map +1 -0
- package/lib/renderer/wgpuMaterialConstants.d.ts +4 -0
- package/lib/renderer/wgpuMaterialConstants.js +52 -0
- package/lib/renderer/wgpuMaterialConstants.js.map +1 -0
- package/lib/renderer/wgpuSceneUniform.d.ts +42 -0
- package/lib/renderer/wgpuSceneUniform.js +125 -0
- package/lib/renderer/wgpuSceneUniform.js.map +1 -0
- package/lib/renderer/wgpuShaderSource.d.ts +22 -0
- package/lib/renderer/wgpuShaderSource.js +33 -0
- package/lib/renderer/wgpuShaderSource.js.map +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +70 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovReflectance.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +98 -0
- package/lib/renderer/wgsl/aovReflectance.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +135 -0
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +5 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js +38 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovSnapshot.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +21 -0
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovTrace.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovTrace.wgsl.js +115 -0
- package/lib/renderer/wgsl/aovTrace.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/bloom.wgsl.d.ts +13 -0
- package/lib/renderer/wgsl/bloom.wgsl.js +92 -0
- package/lib/renderer/wgsl/bloom.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
- package/lib/renderer/wgsl/causticLight.compute.js +537 -0
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +41 -35
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +13 -1
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +747 -704
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +16 -16
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +4 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +83 -79
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +855 -857
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +137 -137
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +3 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +52 -32
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +152 -144
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +269 -245
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +27 -14
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +91 -95
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +1 -0
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +12 -12
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +8 -3
- package/lib/renderer/wgsl/compose.frag.wgsl.js +143 -118
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.js +7 -7
- package/lib/renderer/wgsl/jnlm.compute.d.ts +25 -0
- package/lib/renderer/wgsl/jnlm.compute.js +315 -0
- package/lib/renderer/wgsl/jnlm.compute.js.map +1 -0
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +17 -0
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
- package/lib/renderer/wgsl/photonMap.compute.js +352 -0
- package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
- package/lib/renderer/wgsl/proceduralSky.compute.d.ts +1 -0
- package/lib/renderer/wgsl/proceduralSky.compute.js +198 -0
- package/lib/renderer/wgsl/proceduralSky.compute.js.map +1 -0
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +25 -1
- package/lib/renderer/wgsl/rayTrace.compute.js +645 -500
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/Camera.js +7 -3
- package/lib/scene/Camera.js.map +1 -1
- package/lib/scene/EnvironmentLight.d.ts +5 -9
- package/lib/scene/EnvironmentLight.js +4 -14
- package/lib/scene/EnvironmentLight.js.map +1 -1
- package/lib/scene/EnvironmentLightState.d.ts +18 -0
- package/lib/scene/EnvironmentLightState.js +19 -0
- package/lib/scene/EnvironmentLightState.js.map +1 -0
- package/lib/scene/Geometry.d.ts +12 -6
- package/lib/scene/Geometry.js +37 -13
- package/lib/scene/Geometry.js.map +1 -1
- package/lib/scene/InstanceState.d.ts +39 -0
- package/lib/scene/InstanceState.js +77 -0
- package/lib/scene/InstanceState.js.map +1 -0
- package/lib/scene/InstancedMesh.d.ts +1 -1
- package/lib/scene/InstancedMesh.js +3 -0
- package/lib/scene/InstancedMesh.js.map +1 -1
- package/lib/scene/MaterialState.d.ts +209 -0
- package/lib/scene/MaterialState.js +231 -0
- package/lib/scene/MaterialState.js.map +1 -0
- package/lib/scene/Mesh.d.ts +4 -6
- package/lib/scene/Mesh.js +3 -11
- package/lib/scene/Mesh.js.map +1 -1
- package/lib/scene/MeshState.d.ts +20 -0
- package/lib/scene/MeshState.js +35 -0
- package/lib/scene/MeshState.js.map +1 -0
- package/lib/scene/OpenPBRMaterial.d.ts +6 -168
- package/lib/scene/OpenPBRMaterial.js +5 -223
- package/lib/scene/OpenPBRMaterial.js.map +1 -1
- package/lib/scene/PixelTexture.d.ts +6 -0
- package/lib/scene/PixelTexture.js +10 -0
- package/lib/scene/PixelTexture.js.map +1 -0
- package/lib/scene/ProceduralSky.d.ts +24 -0
- package/lib/scene/ProceduralSky.js +40 -0
- package/lib/scene/ProceduralSky.js.map +1 -0
- package/lib/scene/RectLight.d.ts +2 -13
- package/lib/scene/RectLight.js +3 -21
- package/lib/scene/RectLight.js.map +1 -1
- package/lib/scene/RectLightState.d.ts +31 -0
- package/lib/scene/RectLightState.js +26 -0
- package/lib/scene/RectLightState.js.map +1 -0
- package/lib/scene/Scene.d.ts +15 -4
- package/lib/scene/Scene.js.map +1 -1
- package/lib/scene/SceneNode.js +7 -6
- package/lib/scene/SceneNode.js.map +1 -1
- package/lib/scene/Texture.d.ts +10 -41
- package/lib/scene/Texture.js +4 -33
- package/lib/scene/Texture.js.map +1 -1
- package/lib/scene/TextureState.d.ts +35 -0
- package/lib/scene/TextureState.js +35 -0
- package/lib/scene/TextureState.js.map +1 -0
- package/lib/scene/attributeData.d.ts +4 -0
- package/lib/scene/attributeData.js +10 -0
- package/lib/scene/attributeData.js.map +1 -0
- package/lib/scene/lightState.d.ts +8 -0
- package/lib/scene/lightState.js +2 -0
- package/lib/scene/lightState.js.map +1 -0
- package/lib/scene/openPbrSchema.d.ts +7 -12
- package/lib/scene/openPbrSchema.js +273 -28
- package/lib/scene/openPbrSchema.js.map +1 -1
- package/lib/scene/skyParameters.d.ts +20 -0
- package/lib/scene/skyParameters.js +28 -0
- package/lib/scene/skyParameters.js.map +1 -0
- package/lib/scene/textureData.d.ts +9 -0
- package/lib/scene/textureData.js +2 -0
- package/lib/scene/textureData.js.map +1 -0
- package/lib/scene/texturePixels.d.ts +6 -0
- package/lib/scene/texturePixels.js +10 -0
- package/lib/scene/texturePixels.js.map +1 -0
- package/lib/settings/display.d.ts +33 -0
- package/lib/settings/display.js +7 -0
- package/lib/settings/display.js.map +1 -1
- package/lib/settings/render.d.ts +36 -3
- package/lib/settings/render.js +4 -1
- package/lib/settings/render.js.map +1 -1
- package/lib/tinybvh/tinybvh.wasm +0 -0
- package/lib/util/commonGeometry.js +7 -7
- package/lib/util/commonGeometry.js.map +1 -1
- package/lib/util/fromTHREE.d.ts +4 -1
- package/lib/util/fromTHREE.js +20 -7
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/util/geometry.js +42 -29
- package/lib/util/geometry.js.map +1 -1
- package/lib/util/loadRGBE.js +3 -4
- package/lib/util/loadRGBE.js.map +1 -1
- package/lib/util/studioLighting.d.ts +18 -0
- package/lib/util/studioLighting.js +36 -0
- package/lib/util/studioLighting.js.map +1 -0
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/llms.txt +5 -0
- package/package.json +33 -7
- package/lib/renderer/texturesFromMaterials.d.ts +0 -6
- package/lib/renderer/texturesFromMaterials.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"causticLight.compute.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/causticLight.compute.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,gBAAgB,EAAE,iBAAiB,EAAC,MAAM,wBAAwB,CAAC;AAC3E,OAAO,EAAC,4BAA4B,EAAE,yBAAyB,EAAE,YAAY,EAAC,MAAM,gBAAgB,CAAC;AACrG,OAAO,UAAU,MAAM,6BAA6B,CAAC;AACrD,OAAO,MAAM,MAAM,gCAAgC,CAAC;AACpD,OAAO,OAAO,MAAM,iCAAiC,CAAC;AACtD,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,IAAI,MAAM,+BAA+B,CAAC;AACjD,OAAO,EAAC,wBAAwB,EAAC,MAAM,iCAAiC,CAAC;AACzE,OAAO,SAAS,MAAM,4BAA4B,CAAC;AACnD,OAAO,IAAI,MAAM,uBAAuB,CAAC;AACzC,OAAO,MAAM,MAAM,yBAAyB,CAAC;AAC7C,OAAO,GAAG,MAAM,yBAAyB,CAAC;AAC1C,OAAO,QAAQ,MAAM,2BAA2B,CAAC;AACjD,OAAO,EAAC,qBAAqB,EAAC,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,MAAM,8BAA8B,CAAC;AACjD,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAC/C,OAAO,EAAC,oBAAoB,EAAC,MAAM,2BAA2B,CAAC;AAC/D,OAAO,EAAC,kBAAkB,EAAC,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAC,uBAAuB,EAAC,MAAM,yBAAyB,CAAC;AAEhE,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AACzC,MAAM,CAAC,MAAM,qBAAqB,GAAG,UAAU,CAAC;;;;CAI/C,CAAC;AAEF,8EAA8E;AAC9E,iFAAiF;AACjF,MAAM,UAAU,mBAAmB,CACjC,SAA2C,EAC3C,cAAsB,EACtB,eAAwB,EACxB,OAAyC,cAAc,EACvD,kBAAkB,GAAG,EAAE,EACvB,kBAAkB,GAAG,IAAI;IAEzB,MAAM,MAAM,GAAG,CAAC,CAAC,SAAS,CAAC,yBAAyB,IAAI,CAAC,CAAC,SAAS,CAAC,sBAAsB,EACxF,IAAI,GAAG,CAAC,CAAC,SAAS,CAAC,sBAAsB,CAAC;IAC5C,OAAO,CACL,kBAAkB,CAAC,SAAS,EAAE,IAAI,CAAC;QACnC,UAAU,CAAC;EACb,MAAM,CAAC,IAAI,CAAC,uBAAuB,CAAC;aACnC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,SAAS,IAAI,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC;aACtD,IAAI,CAAC,IAAI,CAAC;EACX,MAAM;EACN,IAAI,CAAC,EAAC,uBAAuB,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;EAC7E,EAAE;EACF,wBAAwB,CAAC,EAAC,uBAAuB,EAAE,MAAM,EAAE,cAAc,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAC,CAAC;EACjG,SAAS,CAAC;YACV,eAAe;YACf,cAAc;YACd,uBAAuB,EAAE,MAAM;YAC/B,cAAc,EAAE,IAAI;YACpB,kBAAkB;SACnB,CAAC;EACA,IAAI;EACJ,MAAM;EACN,GAAG;EACH,QAAQ;EACR,YAAY;EACZ,qBAAqB,CAAC,MAAM,EAAE,IAAI,CAAC;EACnC,KAAK;EACL,UAAU,CAAC,OAAO,CAClB,oEAAoE,EACpE,CAAC,IAAI,EAAE,EAAE,CACP,iCACE,EAAC,cAAc,EAAE,CAAC,EAAE,kBAAkB,EAAE,CAAC,EAAE,uBAAuB,EAAE,CAAC,EAAC,CAAC,IAAI,CAC7E,SAAS,CACZ;EACC,oBAAoB,CAAC,KAAK,EAAE,KAAK,CAAC;EAClC,OAAO;;;;;;;;;;;;;;EAeP,IAAI,KAAK,cAAc;YACrB,CAAC,CAAC,2EAA2E;YAC7E,CAAC,CAAC,GAAG,iBAAiB;;;;;;;;kBAQJ,gBAAgB;;;;;CAMtC;;;;EAIE,qBAAqB;6BAEjB,kBAAkB,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,eAC5D;;;;;;EAMF,kBAAkB,CAAC,CAAC,CAAC,8DAA8D,CAAC,CAAC,CAAC,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmI7F,IAAI,KAAK,cAAc;YACrB,CAAC,CAAC,UAAU,CAAC,GAAG,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiCxB,MAAM;gBACJ,CAAC,CAAC,UAAU,CAAC,oKAAoK;gBACjL,CAAC,CAAC,EACN;EAEE,IAAI;gBACF,CAAC,CAAC,UAAU,CAAC,6GAAmH;gBAChI,CAAC,CAAC,EACN;;;;;;;;;;;;;;;;;;CAkBC;YACG,CAAC,CAAC,EACN;;;;;;;EAOE,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,qCAAqC,CAAC,CAAC,CAAC,EAAE;;;;;;;;;4BASvC,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+CA4FT,yBAAyB;;;;;;;;;;EAU1E,IAAI,KAAK,eAAe,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAsCzE,IAAI,KAAK,cAAc,CAAC,CAAC,CAAC,2BAA2B,CAAC,CAAC,CAAC,EAAE,KACtD,IAAI,KAAK,cAAc;YACrB,CAAC,CAAC,iDAAiD;YACnD,CAAC,CAAC,UAAU,CAAC;;;;;;kBAMC,gBAAgB;;;;;;;;CASlC;;;;;;;;EASF,MAAM;YACJ,CAAC,CAAC,UAAU,CAAC,sKAAsK;YACnL,CAAC,CAAC,EACN;EAEE,IAAI;YACF,CAAC,CAAC,UAAU,CAAC,8GAA8G;YAC3H,CAAC,CAAC,EACN;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAqCC,CACE,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,wBAAwB,GAAG,UAAU,CAAC;;;;;;;;;;;;;CAalD,CAAC;AAEF,iFAAiF;AACjF,MAAM,CAAC,MAAM,6BAA6B,GAAG,UAAU,CAAC;;;;;;;;;;;;;;;CAevD,CAAC","sourcesContent":["import {PHOTON_GRID_SIZE, photonPackingWgsl} from './photonMap.compute.js';\nimport {SPECTRUM_PHOTON_DISTRIBUTION, SPECTRUM_WAVELENGTH_RANGE, spectrumWgsl} from '../spectrum.js';\nimport background from './chunks/background.wgsl.js';\nimport atomic from './chunks/causticAtomic.wgsl.js';\nimport adjoint from './chunks/causticAdjoint.wgsl.js';\nimport common from './chunks/common.wgsl.js';\nimport core from './chunks/rayTraceCore.wgsl.js';\nimport {createMaterialBufferWgsl} from './chunks/materialBuffer.wgsl.js';\nimport intersect from './chunks/intersect.wgsl.js';\nimport rand from './chunks/rand.wgsl.js';\nimport random from './chunks/random.wgsl.js';\nimport env from './chunks/envMap.wgsl.js';\nimport sampling from './chunks/sampling.wgsl.js';\nimport {createOpenPbrBsdfWgsl} from './chunks/openPbrBsdf.wgsl.js';\nimport light from './chunks/sampleLight.wgsl.js';\nimport uv from './chunks/uvProjection.wgsl.js';\nimport {causticPartitionWGSL} from './chunks/caustics.wgsl.js';\nimport {wgpuShaderPreamble} from '../wgpuShaderSource.js';\nimport {WGPU_SCENE_FEATURE_BITS} from '../WGPUSceneFeatures.js';\n\nexport const CAUSTIC_UNIFORM_BYTES = 112;\nexport const causticUnitRandomWgsl = /* wgsl */ `\n fn causticUnitRandom(value:f32)->f32 {\n return clamp((value-EPS)/(1.0-2.0*EPS),0.0,0.99999994);\n }\n`;\n\n// Preserve the dormant R1 uniform slot and shader spelling for source parity.\n// Production packs zero; only an explicitly registered research adapter sets it.\nexport function causticLightCompute(\n constants: Record<string, boolean | number>,\n blasLayoutMask: number,\n hasDisplacement: boolean,\n mode: 'lightTracing' | 'photonMapping' = 'lightTracing',\n sceneIntersections = '',\n fullEmissionRandom = true\n) {\n const frames = !!constants.USE_ANISOTROPY_DIRECTIONS || !!constants.USE_COAT_NORMAL_FRAMES,\n coat = !!constants.USE_COAT_NORMAL_FRAMES;\n return (\n wgpuShaderPreamble(constants, true) +\n /* wgsl */ `\n${Object.keys(WGPU_SCENE_FEATURE_BITS)\n .map((name) => `const ${name} = ${!!constants[name]};`)\n .join('\\n')}\n${common}\n${core({hasAnisotropyDirections: frames, hasCoatNormals: coat, caustics: true})}\n${uv}\n${createMaterialBufferWgsl({hasAnisotropyDirections: frames, hasCoatNormals: coat, caustics: true})}\n${intersect({\n hasDisplacement,\n blasLayoutMask,\n hasAnisotropyDirections: frames,\n hasCoatNormals: coat,\n sceneIntersections\n})}\n${rand}\n${random}\n${env}\n${sampling}\n${spectrumWgsl}\n${createOpenPbrBsdfWgsl(frames, coat)}\n${light}\n${background.replace(\n /\\b(?:USE_BACKGROUND|USE_BACKGROUND_MAP|USE_GROUNDED_BACKGROUND)\\b/g,\n (name) =>\n `((rtUniform.backgroundFlags & ${\n {USE_BACKGROUND: 1, USE_BACKGROUND_MAP: 2, USE_GROUNDED_BACKGROUND: 4}[name]\n }) != 0)`\n)}\n${causticPartitionWGSL(false, false)}\n${adjoint}\n struct CausticLightUniform {\n casterSphere: vec4f,\n viewProjection: mat4x4f,\n photonCount: u32,\n batch: u32,\n mnee: u32,\n cameraScale: f32,\n casterCount: u32,\n choiceCount: u32,\n orthographic: u32,\n experiments: u32,\n }\n @group(3) @binding(0) var<uniform> caustic: CausticLightUniform;\n${\n mode === 'lightTracing'\n ? '@group(3) @binding(1) var<storage,read_write> splats: array<atomic<u32>>;'\n : `${photonPackingWgsl}\n @group(3)@binding(1)var photons:texture_storage_2d<rgba32uint,write>;\n @group(3)@binding(3)var photonDirections:texture_storage_2d<r32uint,write>;\n fn photonStore(i:u32,value:vec4u) {\n let width=textureDimensions(photons).x;\n textureStore(photons,vec2i(vec2u(i%width,i/width)),value);\n }\n fn photonStoreDirections(i:u32,value:u32) {\n let buckets=min(${PHOTON_GRID_SIZE}u,1u<<(32u-countLeadingZeros(max(256u,caustic.photonCount*2u)-1u)));\n let index=8u+buckets*4u+caustic.photonCount*2u+i;\n let width=textureDimensions(photonDirections).x;\n textureStore(photonDirections,vec2i(vec2u(index%width,index/width)),vec4u(value));\n }\n`\n}\n @group(3) @binding(2) var causticDistribution:texture_2d<f32>;\n // Geometric emission PDFs assume the full disk/cone/area support. The generic\n // BSDF sampler contracts randoms by EPS; undo that contraction for these warps.\n${causticUnitRandomWgsl}\nfn causticEmission1D(dim:u32)->f32{return ${\n fullEmissionRandom ? 'causticUnitRandom(sample1D(dim))' : 'sample1D(dim)'\n }\n ;\n}\nfn causticEmission2D(dim:u32)->vec2f {\n let value=sample2D(dim);\n return\n${fullEmissionRandom ? 'vec2f(causticUnitRandom(value.x),causticUnitRandom(value.y))' : 'value'}\n ;\n}\nfn causticLoad(i:u32)->vec4f {\n let width=textureDimensions(causticDistribution).x;\n return textureLoad(causticDistribution,vec2i(vec2u(i%width,i/width)),0);\n}\nfn causticSphere(i:u32)->vec4f {\n return causticLoad(i);\n}\n// Photon emission samples a source surface, independently of any receiver.\n// A NEE sample viewed from the aggregate caster center can reject an emitter\n// which still illuminates another caster, or sample only part of a sphere.\nvar<private> causticEmissionOrigin:vec3f;\nvar<private> causticEmissionAreaPdf:f32;\nfn causticAreaLight(origin:vec3f,position:vec3f,normal:vec3f,emission:vec3f,area:f32,pmf:f32,result:ptr<function,LightSampleRec>) {\n causticEmissionOrigin=position;\n causticEmissionAreaPdf=pmf/max(area,1e-20);\n let offset=position-origin;\n (*result).dist=length(offset);\n (*result).direction=offset/max((*result).dist,1e-20);\n (*result).normal=normal;\n (*result).emission=emission;\n (*result).pdf=pmf;\n}\nfn causticSampleLight(origin:vec3f,rnd:vec3f,result:ptr<function,LightSampleRec>) {\n causticEmissionAreaPdf=0.0;\n (*result).pdf=0.0;\n (*result).sourceType=0u;\n (*result).isDelta=false;\n if(caustic.choiceCount==0u) {\n return;\n }\n let scaled=rnd.z*f32(caustic.choiceCount);\n let column=min(u32(scaled),caustic.choiceCount-1u);\n let entry=causticLoad(caustic.casterCount+column*2u);\n let selected=select(bitcast<u32>(entry.y),column,fract(scaled)<entry.x);\n let choice=bitcast<vec4u>(causticLoad(caustic.casterCount+selected*2u));\n let pmf=causticLoad(caustic.casterCount+selected*2u+1u).x;\n (*result).sourceIndex=choice.w;\n if(choice.z==1u) {\n (*result).sourceType=0u;\n sampleEnvLight(rnd.xy,result);\n (*result).pdf*=pmf;\n }\n else if(choice.z==2u) {\n (*result).sourceType=2u;\n var light=analyticLights[choice.w];\n let kind=i32(light.litType);\n if(kind==RECT_LIGHT) {\n let position=light.position+light.u*(rnd.x-.5)+light.v*(rnd.y-.5);\n causticAreaLight(origin,position,normalize(cross(light.u,light.v)),light.emission,light.area,pmf,result);\n (*result).isDelta=light.radiusOrSpread<=.001;\n light_apply_rect_texture(light,position,light.position-.5*(light.u+light.v),result);\n }\n else if((kind==SPHERE_LIGHT||kind==SPOT_LIGHT)&&light.radiusOrSpread>0.0) {\n let z=1.0-2.0*rnd.x;\n let radial=sqrt(max(0.0,1.0-z*z));\n let normal=vec3f(radial*cos(TWOPI*rnd.y),radial*sin(TWOPI*rnd.y),z);\n causticAreaLight(origin,light.position+light.radiusOrSpread*normal,normal,light.emission,light.area,pmf,result);\n }\n else {\n light.selectionPmf=1.0;\n sampleAnalyticLight(light,origin,rnd.xy,result);\n (*result).pdf*=pmf;\n }\n }\n else {\n (*result).sourceType=1u;\n let triangle=getEmissiveTriangle(i32(choice.w));\n let u=sqrt(rnd.x);\n let bary=vec3f(1.0-u,u*(1.0-rnd.y),u*rnd.y);\n let position=bary.x*triangle.p0+bary.y*triangle.p1+bary.z*triangle.p2;\n let normal=normalize(cross(triangle.p1-triangle.p0,triangle.p2-triangle.p0));\n let uv=bary.x*triangle.uv0+bary.y*triangle.uv1+bary.z*triangle.uv2;\n let uv1=bary.x*triangle.secondaryUv0+bary.y*triangle.secondaryUv1+bary.z*triangle.secondaryUv2;\n causticAreaLight(origin,position,normal,getMaterialEmission(i32(triangle.materialIndex),uv,uv1),triangle.area,pmf,result);\n }\n (*result).selectionPmf=pmf;\n}\nfn causticCosMax(s:vec4f,origin:vec3f)->f32 {\n let distanceSquared=dot(s.xyz-origin,s.xyz-origin);\n return select(-1.0,sqrt(max(0.0,1.0-s.w*s.w/distanceSquared)),distanceSquared>s.w*s.w);\n}\n// A positive floor retains paths from offscreen or occluded casters. The\n// complete weighted mixture PDF below, including overlaps, compensates selection.\nfn causticTargetWeight(s:vec4f)->f32 {\n if((caustic.experiments&2u)==0u) { return 1.0; }\n let clip=caustic.viewProjection*vec4f(s.xyz,1.0);\n let m=caustic.viewProjection;\n let extent=s.w*max(length(vec3f(m[0].x,m[1].x,m[2].x)),length(vec3f(m[0].y,m[1].y,m[2].y)));\n if(clip.w<=0.0||abs(clip.x)>clip.w+extent||abs(clip.y)>clip.w+extent) { return .05; }\n return .05+min(1.0,extent*extent/max(clip.w*clip.w,1e-20));\n}\nfn causticDirection(origin:vec3f,rnd:vec3f,pdf:ptr<function,f32>,targetRadius:ptr<function,f32>)->vec3f {\n var total=0.0;\n for(var i=0u;i<caustic.casterCount;i++) {\n total+=(1.0-causticCosMax(causticSphere(i),origin))*causticTargetWeight(causticSphere(i));\n }\n var choice=rnd.z*total;\n var selected=causticSphere(0u);\n for(var i=0u;i<caustic.casterCount;i++) {\n let sphere=causticSphere(i);\n selected=sphere;\n choice-=(1.0-causticCosMax(sphere,origin))*causticTargetWeight(sphere);\n if(choice<=0.0) {\n break;\n }\n }\n *targetRadius=selected.w;\n let offset=selected.xyz-origin;\n let axis=normalize(select(vec3f(0.0,0.0,1.0),offset,dot(offset,offset)>1e-20));\n let cosine=mix(1.0,causticCosMax(selected,origin),rnd.x);\n let sine=sqrt(max(0.0,1.0-cosine*cosine));\n var t:vec3f;\n var b:vec3f;\n sampling_orthonormal_basis(axis,&t,&b);\n let direction=axis*cosine+(t*cos(TWOPI*rnd.y)+b*sin(TWOPI*rnd.y))*sine;\n // Evaluate the entire mixture, since intersecting bounding cones overlap.\n var overlaps=0.0;\n for(var i=0u;i<caustic.casterCount;i++) {\n let sphere=causticSphere(i);\n let c=causticCosMax(sphere,origin);\n if(c<0.0||dot(normalize(sphere.xyz-origin),direction)>=c) {\n overlaps+=causticTargetWeight(sphere);\n }\n }\n *pdf=overlaps/max(TWOPI*total,1e-20);\n return direction;\n}\n${\n mode === 'lightTracing'\n ? /* wgsl */ `${atomic}\n fn causticCameraConnect(si: SurfaceInteraction, material: OpenPbrResolvedMaterial, incoming: Ray, flux: vec3f, extinction: vec3f) {\n let eye=cameraUniform.viewInv[3].xyz;\n let forward=-normalize(cameraUniform.viewInv[2].xyz);\n let lensSample=causticEmission2D(causticDim(68u));\n let radius=cameraUniform.apertureRadius*sqrt(lensSample.x);\n var lens=eye+radius*(cos(TWOPI*lensSample.y)*cameraUniform.viewInv[0].xyz+sin(TWOPI*lensSample.y)*cameraUniform.viewInv[1].xyz);\n if(caustic.orthographic!=0u) {\n lens=si.position-forward*dot(si.position-eye,forward);\n }\n let toEye=lens-si.position;\n let distanceSquared=dot(toEye,toEye);\n let direction=normalize(toEye);\n let focalPoint=lens+(si.position-lens)*cameraUniform.focusDistance/max(dot(si.position-lens,forward),1e-12);\n let projected=select(focalPoint,si.position,caustic.orthographic!=0u);\n let clip=caustic.viewProjection*vec4f(projected,1.0);\n if(clip.w<=0.0||dot(si.position-eye,forward)<=0.0) {\n return;\n }\n let film=clip.xy/clip.w*0.5+0.5;\n if(any(film<vec2f(0.0))||any(film>=vec2f(1.0))) {\n return;\n }\n var shadow:Ray;\n initRay(&shadow,si.position+EPS*direction,direction);\n if(intersectSceneShadow(shadow,sqrt(distanceSquared)-2.0*EPS,si.triangleIndex,si.instanceIndex)) {\n return;\n }\n var m=material;\n let normal=select(-si.normal,si.normal,dot(si.normal,-incoming.d)>=0.0);\n m.inside=dot(si.faceNormal,-incoming.d)<0.0;\n m.relativeIor=select(1.0/m.specularIor,m.specularIor,m.inside);\n${\n frames\n ? /* wgsl */ ` m.directionTangent=si.directionTangent;m.directionBitangent=si.directionBitangent;m.geometryTangent=si.geometryTangent;m.geometryBitangent=si.geometryBitangent;`\n : ''\n}\n${\n coat\n ? /* wgsl */ ` m.coatNormal=normal;m.geometricNormal=select(-si.faceNormal,si.faceNormal,dot(si.faceNormal,-incoming.d)>=0.0);`\n : ''\n}\n let prepared=openpbr_prepare(si.tangent,m,-incoming.d,normal);\n var pdf:f32;\n let response=openpbr_eval_prepared(prepared,direction,&pdf);\n let cameraCosine=dot(-direction,-normalize(cameraUniform.viewInv[2].xyz));\n if(cameraCosine<=0.0) {\n return;\n }\n let importance=caustic.cameraScale*rtUniform.outputSize.x*rtUniform.outputSize.y /\n select(max(distanceSquared*cameraCosine*cameraCosine*cameraCosine,1e-12),1.0,caustic.orthographic!=0u);\n let transmittance=exp(-extinction*sqrt(distanceSquared));\n let value=flux*transmittance*response*causticAdjoint(-incoming.d,direction,normal,si.faceNormal)*importance/f32(caustic.photonCount);\n let pixel=vec2u(film*rtUniform.outputSize);\n let index=(pixel.x+pixel.y*u32(rtUniform.outputSize.x))*3u;\n causticAtomicAdd(index,value.x);\n causticAtomicAdd(index+1u,value.y);\n causticAtomicAdd(index+2u,value.z);\n}\n`\n : ''\n}\n @compute @workgroup_size(64)\n fn main(@builtin(global_invocation_id) id:vec3u) {\n let photonIndex=id.x+id.y*4194240u;\n if(photonIndex>=caustic.photonCount) {\n return;\n }\n${mode === 'photonMapping' ? 'photonStore(photonIndex,vec4u(0u));' : ''}\n samplingPixel=vec2u(photonIndex%u32(rtUniform.outputSize.x),photonIndex/u32(rtUniform.outputSize.x));\n pixelSampleIndex=caustic.batch;\n samplingBounce=0u;\n hashedCounter=0u;\n rng_initialize(samplingPixel,i32(sampleSeed(caustic.batch,rtUniform.sequenceSeed)));\n var wavelength=0.0;\n var wavelengthPdf=1.0;\n if(SPECTRAL) {\n wavelength=spectrumSample(${SPECTRUM_PHOTON_DISTRIBUTION}u,causticEmission1D(causticDim(69u)),&wavelengthPdf);\n }\n var ls:LightSampleRec;\n causticSampleLight(caustic.casterSphere.xyz,vec3f(causticEmission2D(causticDim(60u)),causticEmission1D(causticDim(61u))),&ls);\n if(ls.pdf<=0.0) {\n return;\n }\n var infinite=ls.sourceType==0u;\n if(ls.sourceType==2u) {\n infinite=i32(analyticLights[ls.sourceIndex].litType)==DIRECTIONAL_LIGHT;\n }\n var origin=caustic.casterSphere.xyz+ls.direction*ls.dist;\n if(causticEmissionAreaPdf>0.0) { origin=causticEmissionOrigin; }\n var direction:vec3f;\n var flux:vec3f;\n var targetRadius=caustic.casterSphere.w;\n if(infinite) {\n direction=-ls.direction;\n // Mixture of projected caster disks. Every overlap contributes to the PDF.\n var area=0.0;\n for(var i=0u;i<caustic.casterCount;i++) {\n let s=causticSphere(i);\n area+=s.w*s.w*causticTargetWeight(s);\n }\n var choice=causticEmission1D(causticDim(63u))*area;\n var sphere=causticSphere(0u);\n for(var i=0u;i<caustic.casterCount;i++) {\n sphere=causticSphere(i);\n choice-=sphere.w*sphere.w*causticTargetWeight(sphere);\n if(choice<=0.0) {\n break;\n }\n }\n targetRadius=sphere.w;\n var t:vec3f;\n var b:vec3f;\n sampling_orthonormal_basis(direction,&t,&b);\n let rnd=causticEmission2D(causticDim(62u));\n origin=sphere.xyz-direction*dot(sphere.xyz-caustic.casterSphere.xyz,direction)-direction*caustic.casterSphere.w;\n origin+=sphere.w*sqrt(rnd.x)*(t*cos(TWOPI*rnd.y)+b*sin(TWOPI*rnd.y));\n var overlaps=0.0;\n for(var i=0u;i<caustic.casterCount;i++) {\n let s=causticSphere(i);\n let offset=origin-s.xyz;\n let projected=offset-direction*dot(offset,direction);\n if(dot(projected,projected)<=s.w*s.w) {\n overlaps+=causticTargetWeight(s);\n }\n }\n let diskPdf=overlaps/max(PI*area,1e-20);\n flux=ls.emission/(ls.pdf*diskPdf);\n }\n else if(ls.sourceType==2u&&i32(analyticLights[ls.sourceIndex].litType)==RECT_LIGHT&&ls.isDelta) {\n // A zero-spread rectangle is a collimated beam, matching PT's delta source.\n direction=ls.normal;\n flux=ls.emission/causticEmissionAreaPdf;\n }\n else {\n var areaPdf=ls.pdf*abs(dot(ls.normal,-ls.direction))/max(ls.dist*ls.dist,1e-20);\n if(causticEmissionAreaPdf>0.0) { areaPdf=causticEmissionAreaPdf; }\n if(ls.isDelta) {\n areaPdf=ls.selectionPmf;\n }\n if(areaPdf<=0.0) {\n return;\n }\n var directionPdf:f32;\n direction=causticDirection(origin,vec3f(causticEmission2D(causticDim(62u)),causticEmission1D(causticDim(63u))),&directionPdf,&targetRadius);\n var emission=ls.emission;\n var emissionCosine=max(0.0,dot(ls.normal,direction));\n if(ls.sourceType==2u) {\n let source=analyticLights[ls.sourceIndex];\n emission=source.emission;\n if(i32(source.litType)==SPOT_LIGHT) {\n emission*=evaluateSpotEmissionMultiplier(source,direction);\n }\n if(ls.isDelta) {\n emissionCosine=1.0;\n }\n if(i32(source.litType)==RECT_LIGHT&&emissionCosine<cos(0.5*PI*source.radiusOrSpread)) {\n return;\n }\n if(i32(source.litType)==RECT_LIGHT) {\n var textured:LightSampleRec;\n textured.emission=emission;\n light_apply_rect_texture(source,origin,source.position-0.5*(source.u+source.v),&textured);\n emission=textured.emission;\n }\n }\n flux=emission*emissionCosine/(areaPdf*directionPdf);\n }\n if(SPECTRAL) {\n flux*=spectrumRgb(wavelength)/(wavelengthPdf*${SPECTRUM_WAVELENGTH_RANGE}.0);\n }\n var ray:Ray;\n initRay(&ray,origin+EPS*direction,direction);\n var chain=0u;\n var singleT=false;\n var extinction=vec3f(0.0);\n var scattering=vec3f(0.0);\n var si:SurfaceInteraction;\n for(var depth=0;\n${mode === 'photonMapping' ? 'depth<=max(rtUniform.bounces,0)' : 'depth<20'}\n ;\n depth++) {\n samplingBounce=u32(depth);\n si.triangleIndex=-1;\n intersectScene(ray,&si,0,true,depth>0);\n if(!si.hit) {\n return;\n }\n var m:OpenPbrResolvedMaterial;\n getMaterial(&m,si.materialIndex,si.uv,si.uv1,si.instanceIndex,si.vertexColor);\n if(m.alpha<1.0&&causticEmission1D(causticDim(79u))>=m.alpha) {\n initRay(&ray,si.position+EPS*ray.d,ray.d);\n continue;\n }\n if(m.materialType==SHADOW_CATCHER) {\n return;\n }\n let segment=distance(ray.o,si.position);\n let channel=min(u32(sample1D(bounceDim(MEDIUM_CHANNEL))*3.0),2u);\n if(extinction[channel]>0.0&&any(scattering>vec3f(0.0))) {\n let sampled=-log(max(sample1D(bounceDim(MEDIUM_DISTANCE)),1e-7))/extinction[channel];\n // A volume event belongs to PT's R3. Surface-reaching photons use the\n // same RGB survival mixture as PT, retaining absorption and scattering.\n if(sampled<segment) {\n return;\n }\n }\n let transmittance=exp(-extinction*segment);\n let survival=(transmittance.x+transmittance.y+transmittance.z)/3.0;\n flux*=transmittance/select(1.0,max(survival,1e-20),any(scattering>vec3f(0.0)));\n if(SPECTRAL) {\n m.specularIor=sampling_cauchy_ior(spectrumIorWavelength(wavelength),m.specularIor,m.transmissionDispersionScale,m.dispersionAbbeNumber);\n }\n if(!isCausticSpecular(m)) {\n let mneeSource=ls.sourceType!=0u;\n let r1=mneeSource&&chain==1u&&singleT&&m.baseWeight*(1.0-m.baseMetalness)*(1.0-m.transmissionWeight)>0.0&&m.subsurfaceWeight==0.0;\n if(chain>0u\n${mode === 'lightTracing' ? '&&!(caustic.mnee!=0u&&r1)' : ''}){${\n mode === 'lightTracing'\n ? 'causticCameraConnect(si,m,ray,flux,extinction);'\n : /* wgsl */ `\n let position=bitcast<vec3u>(si.position);\n photonStore(photonIndex,vec4u(position,photonEncodeFlux(flux)));\n if((caustic.experiments&1u)!=0u) {\n var maximum=1e-8;\n for(var i=0u;i<caustic.casterCount;i++) { maximum=max(maximum,causticSphere(i).w); }\n let buckets=min(${PHOTON_GRID_SIZE}u,1u<<(32u-countLeadingZeros(max(256u,caustic.photonCount*2u)-1u)));\n let index=8u+buckets*4u+caustic.photonCount*3u+photonIndex;\n let width=textureDimensions(photonDirections).x;\n textureStore(photonDirections,vec2i(vec2u(index%width,index/width)),vec4u(bitcast<u32>(targetRadius/maximum)));\n }\n let incoming=vec2u(round(photonEncodeOct(-ray.d)*255.0));\n let normal=vec2u(round(photonEncodeOct(si.faceNormal)*vec2f(255.0,127.0)));\n photonStoreDirections(photonIndex,normal.x|(normal.y<<8u)|(select(0u,1u,r1)<<15u)|(incoming.x<<16u)|(incoming.y<<24u));\n`\n }\n}\nreturn;\n}\nlet view=-ray.d;\nlet normal=select(-si.normal,si.normal,dot(si.normal,view)>=0.0);\nm.inside=dot(si.faceNormal,view)<0.0;\nm.relativeIor=select(1.0/m.specularIor,m.specularIor,m.inside);\n${\n frames\n ? /* wgsl */ ` m.directionTangent=si.directionTangent;m.directionBitangent=si.directionBitangent;m.geometryTangent=si.geometryTangent;m.geometryBitangent=si.geometryBitangent;`\n : ''\n}\n${\n coat\n ? /* wgsl */ ` m.coatNormal=normal;m.geometricNormal=select(-si.faceNormal,si.faceNormal,dot(si.faceNormal,view)>=0.0);`\n : ''\n}\n let prepared=openpbr_prepare(si.tangent,m,view,normal);\n var next:vec3f;\n var pdf:f32;\n var transmission:bool;\n var roughness:f32;\n var specular:bool;\n var diffuse:bool;\n var lobe:u32;\n var marginal:f32;\n var full:vec3f;\n let response=openpbr_sample_prepared(prepared,vec3f(sample2D(bounceDim(BSDF_DIRECTION)),sample1D(bounceDim(BSDF_LOBE))),&next,&pdf,&transmission,&roughness,&specular,&diffuse,&lobe,&marginal,&full);\n if(!(pdf>0.0)) {\n return;\n }\n if(chain==0u&&ls.sourceType==0u&&transmission) {\n var reverse:Ray;\n initRay(&reverse,si.position,-ray.d);\n let bg=sampleSceneBackground(reverse);\n flux*=bg.rgb*bg.a/max(ls.emission,vec3f(1e-20));\n }\n flux*=response/pdf*causticAdjoint(view,next,normal,si.faceNormal);\n // The shared BSDF is a radiance sampler. Cancel its eta_i/eta_t squared\n // factor for adjoint (light-to-camera) propagation.\n if(transmission&&!m.thinWalled) {\n flux/=m.relativeIor*m.relativeIor;\n }\n // Match PT: a clear solid interface does not replace the active medium.\n if(transmission&&!m.thinWalled&&m.mediumType>0) {\n extinction=select(m.mediumExtinction,vec3f(0.0),m.inside);\n scattering=select(m.mediumScattering,vec3f(0.0),m.inside);\n }\n chain++;\n singleT=chain==1u&&((isCausticT(m)&&transmission)||(isCausticR(m)&&!transmission));\n initRay(&ray,si.position+EPS*next,next);\n}\n}\n`\n );\n}\n\nexport const causticAccumulateCompute = /* wgsl */ `\n @group(0) @binding(0) var<storage,read_write> splats:array<atomic<u32>>;\n @group(0) @binding(1) var<storage,read_write> accumulation:array<vec4f>;\n @compute @workgroup_size(64)\n fn main(@builtin(global_invocation_id) id:vec3u, @builtin(num_workgroups) groups:vec3u) {\n // Large images exceed one dispatch row; preserve the linear pixel order.\n let pixel=id.x+id.y*groups.x*64u;\n if(pixel>=arrayLength(&accumulation)) {\n return;\n }\n let i=pixel*3u;\n accumulation[pixel]+=vec4f(vec3f(bitcast<f32>(atomicLoad(&splats[i])),bitcast<f32>(atomicLoad(&splats[i+1u])),bitcast<f32>(atomicLoad(&splats[i+2u]))),1.0);\n }\n`;\n\n/** Native buffer resolve has the same independent batch normalization as web. */\nexport const causticBufferCompositeCompute = /* wgsl */ `\n @group(0)@binding(0)var<storage,read>pt:array<vec4f>;\n @group(0)@binding(1)var<storage,read>caustics:array<vec4f>;\n @group(0)@binding(2)var<storage,read>normal:array<vec4f>;\n @group(0)@binding(3)var<storage,read_write>output:array<vec4f>;\n @compute @workgroup_size(64)fn main(@builtin(global_invocation_id)id:vec3u,@builtin(num_workgroups)groups:vec3u) {\n // Large images exceed one dispatch row; preserve the linear pixel order.\n let pixel=id.x+id.y*groups.x*64u;\n if(pixel>=arrayLength(&output)) {\n return;\n }\n let c=caustics[pixel];\n let p=pt[pixel];\n output[pixel]=vec4f(p.rgb+c.rgb/max(c.a,1.0)*normal[pixel].a,p.a);\n }\n`;\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: "fn groundedSurfaceDistance(point: vec3f, height: f32, radius: f32) -> f32 {\n let pointLength = length(point);\n if (pointLength < 0.00001) {\n return -radius;\n }\n\n let originalY = radius * point.y / pointLength;\n let transitionY = -1.5 * height;\n var surfaceRadius: f32;\n if (originalY >= 0.0) {\n surfaceRadius = radius;\n }\n else if (originalY < transitionY) {\n surfaceRadius = -height * pointLength / point.y;\n }\n else {\n let factor = 1.0\n - originalY * originalY / (3.0 * transitionY * transitionY);\n surfaceRadius = radius * factor;\n }\n return pointLength - surfaceRadius;\n}\n\nfn groundedBackgroundDirection(origin: vec3f, direction: vec3f) -> vec3f {\n if (!USE_GROUNDED_BACKGROUND) {\n return direction;\n }\n let params = rtUniform.groundedBackgroundParams;\n let rayDirection = normalize(direction);\n let center = vec3f(\n rtUniform.groundedBackgroundCenter.x,\n params.z + params.x,\n rtUniform.groundedBackgroundCenter.y\n );\n let localOrigin = origin - center;\n let projectedOrigin = dot(localOrigin, rayDirection);\n let discriminant = projectedOrigin * projectedOrigin\n - dot(localOrigin, localOrigin) + params.y * params.y;\n if (\n discriminant <= 0.0\n || groundedSurfaceDistance(localOrigin, params.x, params.y) > 0.0\n ) {\n return direction;\n }\n\n var farDistance = -projectedOrigin + sqrt(discriminant);\n if (farDistance <= 0.0) {\n return direction;\n }\n\n let sphereHit = localOrigin + rayDirection * farDistance;\n if (sphereHit.y >= 0.0) {\n return normalize(sphereHit);\n }\n\n if (rayDirection.y < -0.00001 && params.y > 1.5 * params.x) {\n let groundDistance = (-params.x - localOrigin.y) / rayDirection.y;\n let groundHit = localOrigin + rayDirection * groundDistance;\n let groundRadius = (2.0 / 3.0)\n * sqrt(params.y * params.y - 2.25 * params.x * params.x);\n if (groundDistance > 0.0 && length(groundHit.xz) <= groundRadius) {\n return normalize(groundHit);\n }\n }\n\n var nearDistance = 0.0;\n for (var i = 0; i < 14; i++) {\n let middleDistance = (nearDistance + farDistance) * 0.5;\n let middlePoint = localOrigin + rayDirection * middleDistance;\n if (groundedSurfaceDistance(middlePoint, params.x, params.y) > 0.0) {\n farDistance = middleDistance;\n }\n else {\n nearDistance = middleDistance;\n }\n }\n let hit = localOrigin + rayDirection * ((nearDistance + farDistance) * 0.5);\n return normalize(hit);\n}\n\nfn sampleSceneBackground(ray: Ray) -> vec4f {\n var bg = vec4f(0.0);\n if (USE_BACKGROUND_MAP) {\n let d = groundedBackgroundDirection(ray.o, ray.d);\n let t = rtUniform.backgroundMapTransform;\n let backgroundDirection = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);\n let rotation = rtUniform.backgroundMapRotation;\n let mapDirection = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * backgroundDirection;\n let backgroundSample = textureLinear(backgroundMap, cartesianToEquirect(mapDirection));\n bg = vec4f(backgroundSample.rgb * t.z, backgroundSample.a);\n }\n else if (USE_BACKGROUND) {\n bg = rtUniform.backgroundColor;\n }\n else if (USE_ENVMAP) {\n bg = textureLinear(envMap, environmentUv(ray.d));\n }\n return bg;\n}\n\n";
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
export default /* wgsl */ `fn di(point: vec3f, height: f32, radius: f32) -> f32 {
|
|
2
|
+
let fQ = length(point);
|
|
3
|
+
if (fQ < 0.00001) {
|
|
4
|
+
return -radius;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
let iG = radius * point.y / fQ;
|
|
8
|
+
let iq = -1.5 * height;
|
|
9
|
+
var eq: f32;
|
|
10
|
+
if (iG >= 0.0) {
|
|
11
|
+
eq = radius;
|
|
12
|
+
}
|
|
13
|
+
else if (iG < iq) {
|
|
14
|
+
eq = -height * fQ / point.y;
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
let cv = 1.0
|
|
18
|
+
- iG * iG / (3.0 * iq * iq);
|
|
19
|
+
eq = radius * cv;
|
|
20
|
+
}
|
|
21
|
+
return fQ - eq;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
fn eM(origin: vec3f, direction: vec3f) -> vec3f {
|
|
25
|
+
if (!USE_GROUNDED_BACKGROUND) {
|
|
26
|
+
return direction;
|
|
27
|
+
}
|
|
28
|
+
let params = rtUniform.groundedBackgroundParams;
|
|
29
|
+
let bS = normalize(direction);
|
|
30
|
+
let center = vec3f(
|
|
31
|
+
rtUniform.groundedBackgroundCenter.x,
|
|
32
|
+
params.z + params.x,
|
|
33
|
+
rtUniform.groundedBackgroundCenter.y
|
|
34
|
+
);
|
|
35
|
+
let bs = origin - center;
|
|
36
|
+
let eE = dot(bs, bS);
|
|
37
|
+
let bj = eE * eE
|
|
38
|
+
- dot(bs, bs) + params.y * params.y;
|
|
39
|
+
if (
|
|
40
|
+
bj <= 0.0
|
|
41
|
+
|| di(bs, params.x, params.y) > 0.0
|
|
42
|
+
) {
|
|
43
|
+
return direction;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
var cw = -eE + sqrt(bj);
|
|
47
|
+
if (cw <= 0.0) {
|
|
48
|
+
return direction;
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
let oA = bs + bS * cw;
|
|
52
|
+
if (oA.y >= 0.0) {
|
|
53
|
+
return normalize(oA);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (bS.y < -0.00001 && params.y > 1.5 * params.x) {
|
|
57
|
+
let hP = (-params.x - bs.y) / bS.y;
|
|
58
|
+
let ot = bs + bS * hP;
|
|
59
|
+
let oT = (2.0 / 3.0)
|
|
60
|
+
* sqrt(params.y * params.y - 2.25 * params.x * params.x);
|
|
61
|
+
if (hP > 0.0 && length(ot.xz) <= oT) {
|
|
62
|
+
return normalize(ot);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
var cI = 0.0;
|
|
67
|
+
for (var i = 0; i < 14; i++) {
|
|
68
|
+
let fd = (cI + cw) * 0.5;
|
|
69
|
+
let qq = bs + bS * fd;
|
|
70
|
+
if (di(qq, params.x, params.y) > 0.0) {
|
|
71
|
+
cw = fd;
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
cI = fd;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
let hit = bs + bS * ((cI + cw) * 0.5);
|
|
78
|
+
return normalize(hit);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
fn ft(ray: Ray) -> vec4f {
|
|
82
|
+
var bg = vec4f(0.0);
|
|
83
|
+
if (USE_BACKGROUND_MAP) {
|
|
84
|
+
let d = eM(ray.o, ray.d);
|
|
85
|
+
let t = rtUniform.backgroundMapTransform;
|
|
86
|
+
let qS = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);
|
|
87
|
+
let rotation = rtUniform.backgroundMapRotation;
|
|
88
|
+
let gU = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * qS;
|
|
89
|
+
let aW = textureLinear(backgroundMap, eF(gU));
|
|
90
|
+
bg = vec4f(aW.rgb * t.z, aW.a);
|
|
91
|
+
}
|
|
92
|
+
else if (USE_BACKGROUND) {
|
|
93
|
+
bg = rtUniform.backgroundColor;
|
|
94
|
+
}
|
|
95
|
+
else if (USE_ENVMAP) {
|
|
96
|
+
bg = textureLinear(envMap, cT(ray.d));
|
|
97
|
+
}
|
|
98
|
+
return bg;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
`;
|
|
102
|
+
//# sourceMappingURL=background.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"background.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/background.wgsl.ts"],"names":[],"mappings":"AAAA,eAAe,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoGzB,CAAC","sourcesContent":["export default /* wgsl */ `fn groundedSurfaceDistance(point: vec3f, height: f32, radius: f32) -> f32 {\n let pointLength = length(point);\n if (pointLength < 0.00001) {\n return -radius;\n }\n\n let originalY = radius * point.y / pointLength;\n let transitionY = -1.5 * height;\n var surfaceRadius: f32;\n if (originalY >= 0.0) {\n surfaceRadius = radius;\n }\n else if (originalY < transitionY) {\n surfaceRadius = -height * pointLength / point.y;\n }\n else {\n let factor = 1.0\n - originalY * originalY / (3.0 * transitionY * transitionY);\n surfaceRadius = radius * factor;\n }\n return pointLength - surfaceRadius;\n}\n\nfn groundedBackgroundDirection(origin: vec3f, direction: vec3f) -> vec3f {\n if (!USE_GROUNDED_BACKGROUND) {\n return direction;\n }\n let params = rtUniform.groundedBackgroundParams;\n let rayDirection = normalize(direction);\n let center = vec3f(\n rtUniform.groundedBackgroundCenter.x,\n params.z + params.x,\n rtUniform.groundedBackgroundCenter.y\n );\n let localOrigin = origin - center;\n let projectedOrigin = dot(localOrigin, rayDirection);\n let discriminant = projectedOrigin * projectedOrigin\n - dot(localOrigin, localOrigin) + params.y * params.y;\n if (\n discriminant <= 0.0\n || groundedSurfaceDistance(localOrigin, params.x, params.y) > 0.0\n ) {\n return direction;\n }\n\n var farDistance = -projectedOrigin + sqrt(discriminant);\n if (farDistance <= 0.0) {\n return direction;\n }\n\n let sphereHit = localOrigin + rayDirection * farDistance;\n if (sphereHit.y >= 0.0) {\n return normalize(sphereHit);\n }\n\n if (rayDirection.y < -0.00001 && params.y > 1.5 * params.x) {\n let groundDistance = (-params.x - localOrigin.y) / rayDirection.y;\n let groundHit = localOrigin + rayDirection * groundDistance;\n let groundRadius = (2.0 / 3.0)\n * sqrt(params.y * params.y - 2.25 * params.x * params.x);\n if (groundDistance > 0.0 && length(groundHit.xz) <= groundRadius) {\n return normalize(groundHit);\n }\n }\n\n var nearDistance = 0.0;\n for (var i = 0; i < 14; i++) {\n let middleDistance = (nearDistance + farDistance) * 0.5;\n let middlePoint = localOrigin + rayDirection * middleDistance;\n if (groundedSurfaceDistance(middlePoint, params.x, params.y) > 0.0) {\n farDistance = middleDistance;\n }\n else {\n nearDistance = middleDistance;\n }\n }\n let hit = localOrigin + rayDirection * ((nearDistance + farDistance) * 0.5);\n return normalize(hit);\n}\n\nfn sampleSceneBackground(ray: Ray) -> vec4f {\n var bg = vec4f(0.0);\n if (USE_BACKGROUND_MAP) {\n let d = groundedBackgroundDirection(ray.o, ray.d);\n let t = rtUniform.backgroundMapTransform;\n let backgroundDirection = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);\n let rotation = rtUniform.backgroundMapRotation;\n let mapDirection = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * backgroundDirection;\n let backgroundSample = textureLinear(backgroundMap, cartesianToEquirect(mapDirection));\n bg = vec4f(backgroundSample.rgb * t.z, backgroundSample.a);\n }\n else if (USE_BACKGROUND) {\n bg = rtUniform.backgroundColor;\n }\n else if (USE_ENVMAP) {\n bg = textureLinear(envMap, environmentUv(ray.d));\n }\n return bg;\n}\n\n`;\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: "\nfn causticAdjoint(view:vec3f,outgoing:vec3f,shading:vec3f,geometric:vec3f)->f32 {\n let numerator=abs(dot(view,shading)*dot(outgoing,geometric));\n let denominator=abs(dot(view,geometric)*dot(outgoing,shading));\n if(denominator==0.0){return 0.0;}\n return numerator/denominator;\n}\n";
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
// Veach's adjoint shading-normal ratio. Directions point away from the vertex;
|
|
2
|
+
// view is toward the preceding light vertex, outgoing toward the camera.
|
|
3
|
+
// Reference: Veach 1997, thesis section 5.3 (mathematical formula, no copied code).
|
|
4
|
+
export default /* wgsl */ `
|
|
5
|
+
fn causticAdjoint(view:vec3f,vJ:vec3f,shading:vec3f,geometric:vec3f)->f32 {
|
|
6
|
+
let iF=abs(dot(view,shading)*dot(vJ,geometric));
|
|
7
|
+
let ah=abs(dot(view,geometric)*dot(vJ,shading));
|
|
8
|
+
if(ah==0.0){return 0.0;}
|
|
9
|
+
return iF/ah;
|
|
10
|
+
}
|
|
11
|
+
`;
|
|
12
|
+
//# sourceMappingURL=causticAdjoint.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"causticAdjoint.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/causticAdjoint.wgsl.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E,yEAAyE;AACzE,oFAAoF;AACpF,eAAe,UAAU,CAAC;;;;;;;CAOzB,CAAC","sourcesContent":["// Veach's adjoint shading-normal ratio. Directions point away from the vertex;\n// view is toward the preceding light vertex, outgoing toward the camera.\n// Reference: Veach 1997, thesis section 5.3 (mathematical formula, no copied code).\nexport default /* wgsl */ `\nfn causticAdjoint(view:vec3f,outgoing:vec3f,shading:vec3f,geometric:vec3f)->f32 {\n let numerator=abs(dot(view,shading)*dot(outgoing,geometric));\n let denominator=abs(dot(view,geometric)*dot(outgoing,shading));\n if(denominator==0.0){return 0.0;}\n return numerator/denominator;\n}\n`;\n"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const _default: "\nfn causticAtomicAdd(index:u32,value:f32) {\n if(!(value>0.0)||!(value<3.402823e38)){return;}\n var previous=atomicLoad(&splats[index]);\n loop {\n let sum=bitcast<f32>(previous)+value;\n let replacement=bitcast<u32>(sum);\n let result=atomicCompareExchangeWeak(&splats[index],previous,replacement);\n if(result.exchanged){break;}\n previous=result.old_value;\n }\n}\n";
|
|
2
|
+
export default _default;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// Float32 addition implemented with u32 compare/exchange works on baseline
|
|
2
|
+
// WebGPU, without a fixed radiance quantum or the Q16.16 saturation ceiling.
|
|
3
|
+
export default /* wgsl */ `
|
|
4
|
+
fn kM(index:u32,value:f32) {
|
|
5
|
+
if(!(value>0.0)||!(value<3.402823e38)){return;}
|
|
6
|
+
var previous=atomicLoad(&splats[index]);
|
|
7
|
+
loop {
|
|
8
|
+
let sum=bitcast<f32>(previous)+value;
|
|
9
|
+
let vN=bitcast<u32>(sum);
|
|
10
|
+
let result=atomicCompareExchangeWeak(&splats[index],previous,vN);
|
|
11
|
+
if(result.exchanged){break;}
|
|
12
|
+
previous=result.old_value;
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
`;
|
|
16
|
+
//# sourceMappingURL=causticAtomic.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"causticAtomic.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/causticAtomic.wgsl.ts"],"names":[],"mappings":"AAAA,2EAA2E;AAC3E,6EAA6E;AAC7E,eAAe,UAAU,CAAC;;;;;;;;;;;;CAYzB,CAAC","sourcesContent":["// Float32 addition implemented with u32 compare/exchange works on baseline\n// WebGPU, without a fixed radiance quantum or the Q16.16 saturation ceiling.\nexport default /* wgsl */ `\nfn causticAtomicAdd(index:u32,value:f32) {\n if(!(value>0.0)||!(value<3.402823e38)){return;}\n var previous=atomicLoad(&splats[index]);\n loop {\n let sum=bitcast<f32>(previous)+value;\n let replacement=bitcast<u32>(sum);\n let result=atomicCompareExchangeWeak(&splats[index],previous,replacement);\n if(result.exchanged){break;}\n previous=result.old_value;\n }\n}\n`;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function causticPartitionWGSL(mnee: boolean, lightTracing: boolean, photonMapping?: boolean, mneeMaxDepth?: number, hot?: boolean, photonMaxDepth?: number): string;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// Smooth classification is independent of the sampled lobe. The single-vertex
|
|
2
|
+
// marker records either an eligible delta transmission or a smooth reflection.
|
|
3
|
+
export function causticPartitionWGSL(mnee, lightTracing, photonMapping = false, mneeMaxDepth = 20, hot = false, photonMaxDepth = 20) {
|
|
4
|
+
return /* wgsl */ `
|
|
5
|
+
fn causticDim(slot:u32)->u32{return 1048576u+samplingBounce*4096u+slot;}
|
|
6
|
+
fn isCausticSpecular(m: OpenPbrResolvedMaterial) -> bool {
|
|
7
|
+
return m.baseWeight * (1.0 - m.baseMetalness) * (1.0 - m.transmissionWeight) <= 1e-6 &&
|
|
8
|
+
m.subsurfaceWeight <= 0.0 && m.fuzzWeight <= 0.0 && m.coatWeight <= 0.0 && m.causticRoughness <= 0.1;
|
|
9
|
+
}
|
|
10
|
+
fn isCausticT(m: OpenPbrResolvedMaterial) -> bool {
|
|
11
|
+
return isCausticSpecular(m) && m.transmissionWeight == 1.0 && m.causticRoughness == 0.0 && !m.thinWalled && !m.causticNormalMapped && m.alpha>=1.0;
|
|
12
|
+
}
|
|
13
|
+
fn isCausticR(m:OpenPbrResolvedMaterial)->bool{
|
|
14
|
+
return isCausticSpecular(m)&&m.causticRoughness==0.0&&!m.causticNormalMapped&&m.alpha>=1.0;
|
|
15
|
+
}
|
|
16
|
+
fn causticHitOwned(path: Path, xd: bool, vl: bool) -> bool {
|
|
17
|
+
let r1 = ${mnee} && xd && path.causticMneeReceiver && path.causticK == 1u && path.causticSingleT;
|
|
18
|
+
let r2 = ${lightTracing} && vl && path.causticK > 0u && path.causticReceiverPrimary;
|
|
19
|
+
let r3=${photonMapping}&&path.causticPhotonReceiver&&path.causticK>0u;
|
|
20
|
+
return path.causticHasReceiver && (r1 || r2 || r3);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
var<private> causticHot:array<vec3f,15>;
|
|
24
|
+
fn causticHotRecord(path:Path,emission:vec3f,kind:u32){
|
|
25
|
+
if(!${hot}){return;}
|
|
26
|
+
let value=max(max(path.beta.x*emission.x,path.beta.y*emission.y),path.beta.z*emission.z);
|
|
27
|
+
if(value<=100.0){return;}
|
|
28
|
+
causticHot[9][kind]+=1.0;
|
|
29
|
+
causticHot[0]+=vec3f(1.0,f32(samplingBounce),f32(path.causticK));
|
|
30
|
+
causticHot[1]+=vec3f(select(0.0,1.0,path.causticHasReceiver),select(0.0,1.0,path.causticSingleT),select(0.0,1.0,path.causticReceiverPrimary));
|
|
31
|
+
causticHot[2]+=vec3f(select(0.0,1.0,path.causticMneeReceiver),select(0.0,1.0,path.causticPhotonReceiver),value);
|
|
32
|
+
if(samplingBounce>=3u&&samplingBounce<=8u){causticHot[samplingBounce]+=vec3f(1.0,f32(path.causticK),value);}
|
|
33
|
+
}
|
|
34
|
+
fn causticEstimateRecord(value:vec3f,kind:u32){
|
|
35
|
+
if(!${hot}){return;}
|
|
36
|
+
let peak=max(max(value.x,value.y),value.z);if(peak>100.0){causticHot[10u+kind]+=vec3f(1.0,f32(samplingBounce),peak);}
|
|
37
|
+
}
|
|
38
|
+
fn causticEmitterRecord(si:SurfaceInteraction,path:Path,weight:f32,emission:vec3f){
|
|
39
|
+
if(!${hot}){return;}
|
|
40
|
+
let value=path.beta*weight*emission;if(max(max(value.x,value.y),value.z)<=100.0){return;}
|
|
41
|
+
let material=materialsBuffer[si.materialIndex];
|
|
42
|
+
causticHot[12]+=vec3f(1.0+dot(si.faceNormal,-path.ray.d),select(0.0,1.0,path.fromEye),material.doubleSided);
|
|
43
|
+
causticHot[13]+=vec3f(weight,material.matType,rtUniform.lightWeightTotal);
|
|
44
|
+
causticHot[14]+=vec3f(path.scatteringPdf,dot(material.emission,luminance),max(max(path.beta.x,path.beta.y),path.beta.z));
|
|
45
|
+
}
|
|
46
|
+
fn causticAdvance(path: ptr<function, Path>, m: OpenPbrResolvedMaterial, transmission: bool, surface: bool) {
|
|
47
|
+
if (surface && isCausticSpecular(m)) {
|
|
48
|
+
(*path).causticK++;
|
|
49
|
+
(*path).causticSingleT = (*path).causticK == 1u && ((isCausticT(m) && transmission)||(isCausticR(m)&&!transmission));
|
|
50
|
+
} else {
|
|
51
|
+
(*path).causticK = 0u;
|
|
52
|
+
(*path).causticSingleT = false;
|
|
53
|
+
(*path).causticPhotonReceiver=surface&&samplingBounce<=${photonMaxDepth}u&&m.materialType!=SHADOW_CATCHER;
|
|
54
|
+
(*path).causticHasReceiver = m.materialType != SHADOW_CATCHER;
|
|
55
|
+
(*path).causticMneeReceiver = surface && samplingBounce<=${mneeMaxDepth}u &&
|
|
56
|
+
m.baseWeight*(1.0-m.baseMetalness)*(1.0-m.transmissionWeight)>0.0 && m.subsurfaceWeight==0.0;
|
|
57
|
+
(*path).causticReceiverPrimary = (*path).fromEye && surface;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=caustics.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"caustics.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/caustics.wgsl.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,+EAA+E;AAC/E,MAAM,UAAU,oBAAoB,CAAC,IAAa,EAAE,YAAqB,EAAC,aAAa,GAAC,KAAK,EAAC,YAAY,GAAC,EAAE,EAAC,GAAG,GAAC,KAAK,EAAC,cAAc,GAAC,EAAE;IACvI,OAAO,UAAU,CAAC;;;;;;;;;;;;;WAaP,IAAI;WACJ,YAAY;SACd,aAAa;;;;;;MAMjB,GAAG;;;;;;;;;;MAUH,GAAG;;;;MAIH,GAAG;;;;;;;;;;;;;;yDAcmD,cAAc;;2DAEZ,YAAY;;;;;CAK1E,CAAC;AACF,CAAC","sourcesContent":["// Smooth classification is independent of the sampled lobe. The single-vertex\n// marker records either an eligible delta transmission or a smooth reflection.\nexport function causticPartitionWGSL(mnee: boolean, lightTracing: boolean,photonMapping=false,mneeMaxDepth=20,hot=false,photonMaxDepth=20) {\n return /* wgsl */ `\nfn causticDim(slot:u32)->u32{return 1048576u+samplingBounce*4096u+slot;}\nfn isCausticSpecular(m: OpenPbrResolvedMaterial) -> bool {\n return m.baseWeight * (1.0 - m.baseMetalness) * (1.0 - m.transmissionWeight) <= 1e-6 &&\n m.subsurfaceWeight <= 0.0 && m.fuzzWeight <= 0.0 && m.coatWeight <= 0.0 && m.causticRoughness <= 0.1;\n}\nfn isCausticT(m: OpenPbrResolvedMaterial) -> bool {\n return isCausticSpecular(m) && m.transmissionWeight == 1.0 && m.causticRoughness == 0.0 && !m.thinWalled && !m.causticNormalMapped && m.alpha>=1.0;\n}\nfn isCausticR(m:OpenPbrResolvedMaterial)->bool{\n return isCausticSpecular(m)&&m.causticRoughness==0.0&&!m.causticNormalMapped&&m.alpha>=1.0;\n}\nfn causticHitOwned(path: Path, mneeLight: bool, tracingLight: bool) -> bool {\n let r1 = ${mnee} && mneeLight && path.causticMneeReceiver && path.causticK == 1u && path.causticSingleT;\n let r2 = ${lightTracing} && tracingLight && path.causticK > 0u && path.causticReceiverPrimary;\n let r3=${photonMapping}&&path.causticPhotonReceiver&&path.causticK>0u;\n return path.causticHasReceiver && (r1 || r2 || r3);\n}\n// Private evidence images count only unsuppressed PT contributions above 100 after MIS.\nvar<private> causticHot:array<vec3f,15>;\nfn causticHotRecord(path:Path,emission:vec3f,kind:u32){\n if(!${hot}){return;}\n let value=max(max(path.beta.x*emission.x,path.beta.y*emission.y),path.beta.z*emission.z);\n if(value<=100.0){return;}\n causticHot[9][kind]+=1.0;\n causticHot[0]+=vec3f(1.0,f32(samplingBounce),f32(path.causticK));\n causticHot[1]+=vec3f(select(0.0,1.0,path.causticHasReceiver),select(0.0,1.0,path.causticSingleT),select(0.0,1.0,path.causticReceiverPrimary));\n causticHot[2]+=vec3f(select(0.0,1.0,path.causticMneeReceiver),select(0.0,1.0,path.causticPhotonReceiver),value);\n if(samplingBounce>=3u&&samplingBounce<=8u){causticHot[samplingBounce]+=vec3f(1.0,f32(path.causticK),value);}\n}\nfn causticEstimateRecord(value:vec3f,kind:u32){\n if(!${hot}){return;}\n let peak=max(max(value.x,value.y),value.z);if(peak>100.0){causticHot[10u+kind]+=vec3f(1.0,f32(samplingBounce),peak);}\n}\nfn causticEmitterRecord(si:SurfaceInteraction,path:Path,weight:f32,emission:vec3f){\n if(!${hot}){return;}\n let value=path.beta*weight*emission;if(max(max(value.x,value.y),value.z)<=100.0){return;}\n let material=materialsBuffer[si.materialIndex];\n causticHot[12]+=vec3f(1.0+dot(si.faceNormal,-path.ray.d),select(0.0,1.0,path.fromEye),material.doubleSided);\n causticHot[13]+=vec3f(weight,material.matType,rtUniform.lightWeightTotal);\n causticHot[14]+=vec3f(path.scatteringPdf,dot(material.emission,luminance),max(max(path.beta.x,path.beta.y),path.beta.z));\n}\nfn causticAdvance(path: ptr<function, Path>, m: OpenPbrResolvedMaterial, transmission: bool, surface: bool) {\n if (surface && isCausticSpecular(m)) {\n (*path).causticK++;\n (*path).causticSingleT = (*path).causticK == 1u && ((isCausticT(m) && transmission)||(isCausticR(m)&&!transmission));\n } else {\n (*path).causticK = 0u;\n (*path).causticSingleT = false;\n (*path).causticPhotonReceiver=surface&&samplingBounce<=${photonMaxDepth}u&&m.materialType!=SHADOW_CATCHER;\n (*path).causticHasReceiver = m.materialType != SHADOW_CATCHER;\n (*path).causticMneeReceiver = surface && samplingBounce<=${mneeMaxDepth}u &&\n m.baseWeight*(1.0-m.baseMetalness)*(1.0-m.transmissionWeight)>0.0 && m.subsurfaceWeight==0.0;\n (*path).causticReceiverPrimary = (*path).fromEye && surface;\n }\n}\n`;\n}\n"]}
|
|
@@ -11,12 +11,12 @@ const ROUGHNESS_MIN = 0.001;
|
|
|
11
11
|
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
fn
|
|
14
|
+
fn sO(position: vec3f, geometricNormal: vec3f, direction: vec3f) -> vec3f {
|
|
15
15
|
let normal = select(-geometricNormal, geometricNormal, dot(geometricNormal, direction) >= 0.0);
|
|
16
|
-
let
|
|
16
|
+
let rb = vec3i(256.0 * normal);
|
|
17
17
|
let bits = bitcast<vec3i>(position);
|
|
18
|
-
let
|
|
19
|
-
return select(
|
|
18
|
+
let ye = bitcast<vec3f>(bits + select(rb, -rb, position < vec3f(0.0)));
|
|
19
|
+
return select(ye, position + normal / 65536.0, abs(position) < vec3f(1.0 / 32.0));
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
`;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: "\n\nfn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {\n // #ifdef OES_texture_float_linear\n // return texture(map, uv);\n // #else\n let size = vec2f(textureDimensions(tex, 0));\n\n let uv2f = _uv * size - vec2f(0.5);\n let uvFloor = floor(uv2f);\n let f = fract(uv2f);\n let uv2i = vec2i(uvFloor);\n let maximum = vec2i(size) - vec2i(1);\n\n // TODO use textureGather\n let s1 = textureLoad(tex, clamp(uv2i + vec2i(0, 0), vec2i(0), maximum), 0);\n let s2 = textureLoad(tex, clamp(uv2i + vec2i(1, 0), vec2i(0), maximum), 0);\n let s3 = textureLoad(tex, clamp(uv2i + vec2i(0, 1), vec2i(0), maximum), 0);\n let s4 = textureLoad(tex, clamp(uv2i + vec2i(1, 1), vec2i(0), maximum), 0);\n\n return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);\n // #endif\n}\n\nfn cartesianToEquirect(pointOnSphere: vec3f) -> vec2f {\n var phi = atan2(-pointOnSphere.z, -pointOnSphere.x);\n if (phi < 0.0) {\n phi += TWOPI;\n }\n let theta = acos(clamp(pointOnSphere.y, -1.0, 1.0));\n return vec2f(phi * 0.5 * INVPI, theta * INVPI);\n}\n\nfn environmentOrientation() -> mat3x3f {\n return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);\n}\n\nfn environmentUv(worldDirection: vec3f) -> vec2f {\n return cartesianToEquirect(transpose(environmentOrientation()) * worldDirection);\n}\n\nfn getEnvmapV(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.y + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(0, mid), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n *vOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(0, *vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;\n\n (*pdf).y = s0.y;\n\n return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);\n}\n\nfn getEnvmapU(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.x + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(1 + mid, vOffset), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let uOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(1 + uOffset, vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(1 + uOffset + 1, vOffset), 0).xy;\n\n (*pdf).x = s0.y;\n\n return (f32(uOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);\n}\n\n// Perform two binary searches to find light direction.\nfn sampleEnvmap(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {\n var partialPdf: vec2f;\n var vOffset: i32;\n\n (*uv).y = getEnvmapV(random.x, &vOffset, &partialPdf);\n (*uv).x = getEnvmapU(random.y, vOffset, &partialPdf);\n\n let phi = (*uv).x * TWOPI;\n let theta = (*uv).y * PI;\n let cosTheta = cos(theta);\n let sinTheta = sin(theta);\n let cosPhi = cos(phi);\n let sinPhi = sin(phi);\n\n let dir = vec3f(-sinTheta * cosPhi, cosTheta, -sinTheta * sinPhi);\n\n *pdf = partialPdf
|
|
1
|
+
declare const _default: "\n\nfn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {\n // #ifdef OES_texture_float_linear\n // return texture(map, uv);\n // #else\n let size = vec2f(textureDimensions(tex, 0));\n\n let uv2f = _uv * size - vec2f(0.5);\n let uvFloor = floor(uv2f);\n let f = fract(uv2f);\n let uv2i = vec2i(uvFloor);\n let maximum = vec2i(size) - vec2i(1);\n\n // TODO use textureGather\n let s1 = textureLoad(tex, clamp(uv2i + vec2i(0, 0), vec2i(0), maximum), 0);\n let s2 = textureLoad(tex, clamp(uv2i + vec2i(1, 0), vec2i(0), maximum), 0);\n let s3 = textureLoad(tex, clamp(uv2i + vec2i(0, 1), vec2i(0), maximum), 0);\n let s4 = textureLoad(tex, clamp(uv2i + vec2i(1, 1), vec2i(0), maximum), 0);\n\n return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);\n // #endif\n}\n\nfn cartesianToEquirect(pointOnSphere: vec3f) -> vec2f {\n var phi = atan2(-pointOnSphere.z, -pointOnSphere.x);\n if (phi < 0.0) {\n phi += TWOPI;\n }\n let theta = acos(clamp(pointOnSphere.y, -1.0, 1.0));\n return vec2f(phi * 0.5 * INVPI, theta * INVPI);\n}\n\nfn environmentOrientation() -> mat3x3f {\n return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);\n}\n\nfn environmentUv(worldDirection: vec3f) -> vec2f {\n return cartesianToEquirect(transpose(environmentOrientation()) * worldDirection);\n}\n\nfn getEnvmapV(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.y + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(0, mid), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n *vOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(0, *vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;\n\n (*pdf).y = s0.y;\n\n return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);\n}\n\nfn getEnvmapU(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.x + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(1 + mid, vOffset), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let uOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(1 + uOffset, vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(1 + uOffset + 1, vOffset), 0).xy;\n\n (*pdf).x = s0.y;\n\n return (f32(uOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);\n}\n\n// The lat-long Jacobian is undefined at either pole. In f32, sin(PI) can\n// also be negative, which makes MIS amplify a BSDF hit instead of weighting it.\nfn envMapSolidAnglePdf(partialPdf: vec2f, v: f32) -> f32 {\n if (!(v > 0.0 && v < 1.0)) { return 0.0; }\n let sinTheta = sin(min(v, 1.0 - v) * PI);\n return partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);\n}\n\n// Perform two binary searches to find light direction.\nfn sampleEnvmap(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {\n var partialPdf: vec2f;\n var vOffset: i32;\n\n (*uv).y = getEnvmapV(random.x, &vOffset, &partialPdf);\n (*uv).x = getEnvmapU(random.y, vOffset, &partialPdf);\n\n let phi = (*uv).x * TWOPI;\n let theta = (*uv).y * PI;\n let cosTheta = cos(theta);\n let sinTheta = sin(theta);\n let cosPhi = cos(phi);\n let sinPhi = sin(phi);\n\n let dir = vec3f(-sinTheta * cosPhi, cosTheta, -sinTheta * sinPhi);\n\n *pdf = envMapSolidAnglePdf(partialPdf, (*uv).y);\n\n return environmentOrientation() * dir;\n}\n\nfn envMapPdf(_uv: vec2f) -> f32 {\n let size = vec2f(textureDimensions(envMap, 0));\n\n let _uv2 = clamp(vec2i(_uv * size), vec2i(0), vec2i(size) - vec2i(1));\n\n let partialX = textureLoad(envMapDistribution, vec2i(1 + _uv2.x, _uv2.y), 0).y;\n let partialY = textureLoad(envMapDistribution, vec2i(0, _uv2.y), 0).y;\n\n return envMapSolidAnglePdf(vec2f(partialX, partialY), _uv.y);\n}\n\n\n";
|
|
2
2
|
export default _default;
|
|
@@ -11,23 +11,23 @@ fn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {
|
|
|
11
11
|
|
|
12
12
|
let size = vec2f(textureDimensions(tex, 0));
|
|
13
13
|
|
|
14
|
-
let
|
|
15
|
-
let
|
|
16
|
-
let f = fract(
|
|
17
|
-
let
|
|
14
|
+
let uv2f = _uv * size - vec2f(0.5);
|
|
15
|
+
let yj = floor(uv2f);
|
|
16
|
+
let f = fract(uv2f);
|
|
17
|
+
let yi = vec2i(yj);
|
|
18
18
|
let maximum = vec2i(size) - vec2i(1);
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
let s1 = textureLoad(tex, clamp(
|
|
22
|
-
let s2 = textureLoad(tex, clamp(
|
|
23
|
-
let s3 = textureLoad(tex, clamp(
|
|
24
|
-
let s4 = textureLoad(tex, clamp(
|
|
21
|
+
let s1 = textureLoad(tex, clamp(yi + vec2i(0, 0), vec2i(0), maximum), 0);
|
|
22
|
+
let s2 = textureLoad(tex, clamp(yi + vec2i(1, 0), vec2i(0), maximum), 0);
|
|
23
|
+
let s3 = textureLoad(tex, clamp(yi + vec2i(0, 1), vec2i(0), maximum), 0);
|
|
24
|
+
let s4 = textureLoad(tex, clamp(yi + vec2i(1, 1), vec2i(0), maximum), 0);
|
|
25
25
|
|
|
26
26
|
return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);
|
|
27
27
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
fn
|
|
30
|
+
fn eF(gh: vec3f) -> vec2f {
|
|
31
31
|
var phi = atan2(-gh.z, -gh.x);
|
|
32
32
|
if (phi < 0.0) {
|
|
33
33
|
phi += TWOPI;
|
|
@@ -36,15 +36,15 @@ let theta = acos(clamp(gh.y, -1.0, 1.0));
|
|
|
36
36
|
return vec2f(phi * 0.5 * INVPI, theta * INVPI);
|
|
37
37
|
}
|
|
38
38
|
|
|
39
|
-
fn
|
|
39
|
+
fn jS() -> mat3x3f {
|
|
40
40
|
return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
fn
|
|
44
|
-
return
|
|
43
|
+
fn cT(nD: vec3f) -> vec2f {
|
|
44
|
+
return eF(transpose(jS()) * nD);
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
fn
|
|
47
|
+
fn rv(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {
|
|
48
48
|
let size = vec2i(textureDimensions(envMap, 0));
|
|
49
49
|
|
|
50
50
|
var left = 0;
|
|
@@ -70,7 +70,7 @@ let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;
|
|
|
70
70
|
return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);
|
|
71
71
|
}
|
|
72
72
|
|
|
73
|
-
fn
|
|
73
|
+
fn ru(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {
|
|
74
74
|
let size = vec2i(textureDimensions(envMap, 0));
|
|
75
75
|
|
|
76
76
|
var left = 0;
|
|
@@ -84,51 +84,57 @@ left = mid + 1;
|
|
|
84
84
|
right = mid;
|
|
85
85
|
}
|
|
86
86
|
}
|
|
87
|
-
let
|
|
87
|
+
let pw = left - 1;
|
|
88
88
|
|
|
89
89
|
|
|
90
90
|
|
|
91
|
-
let s0 = textureLoad(envMapDistribution, vec2i(1 +
|
|
92
|
-
let s1 = textureLoad(envMapDistribution, vec2i(1 +
|
|
91
|
+
let s0 = textureLoad(envMapDistribution, vec2i(1 + pw, vOffset), 0).xy;
|
|
92
|
+
let s1 = textureLoad(envMapDistribution, vec2i(1 + pw + 1, vOffset), 0).xy;
|
|
93
93
|
|
|
94
94
|
(*pdf).x = s0.y;
|
|
95
95
|
|
|
96
|
-
return (f32(
|
|
96
|
+
return (f32(pw) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
|
|
100
|
-
|
|
101
|
-
|
|
100
|
+
|
|
101
|
+
fn envMapSolidAnglePdf(partialPdf: vec2f, v: f32) -> f32 {
|
|
102
|
+
if (!(v > 0.0 && v < 1.0)) { return 0.0; }
|
|
103
|
+
let sinTheta = sin(min(v, 1.0 - v) * PI);
|
|
104
|
+
return partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
fn pn(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {
|
|
109
|
+
var partialPdf: vec2f;
|
|
102
110
|
var vOffset: i32;
|
|
103
111
|
|
|
104
|
-
(*uv).y =
|
|
105
|
-
(*uv).x =
|
|
112
|
+
(*uv).y = rv(random.x, &vOffset, &partialPdf);
|
|
113
|
+
(*uv).x = ru(random.y, vOffset, &partialPdf);
|
|
106
114
|
|
|
107
115
|
let phi = (*uv).x * TWOPI;
|
|
108
116
|
let theta = (*uv).y * PI;
|
|
109
|
-
let
|
|
117
|
+
let ct = cos(theta);
|
|
110
118
|
let sinTheta = sin(theta);
|
|
111
|
-
let
|
|
112
|
-
let
|
|
119
|
+
let vZ = cos(phi);
|
|
120
|
+
let wr = sin(phi);
|
|
113
121
|
|
|
114
|
-
let dir = vec3f(-sinTheta *
|
|
122
|
+
let dir = vec3f(-sinTheta * vZ, ct, -sinTheta * wr);
|
|
115
123
|
|
|
116
|
-
*pdf =
|
|
124
|
+
*pdf = envMapSolidAnglePdf(partialPdf, (*uv).y);
|
|
117
125
|
|
|
118
|
-
return
|
|
126
|
+
return jS() * dir;
|
|
119
127
|
}
|
|
120
128
|
|
|
121
|
-
fn
|
|
129
|
+
fn envMapPdf(_uv: vec2f) -> f32 {
|
|
122
130
|
let size = vec2f(textureDimensions(envMap, 0));
|
|
123
131
|
|
|
124
|
-
let
|
|
125
|
-
|
|
126
|
-
let vX = vec2i(_uv * size);
|
|
132
|
+
let yn = clamp(vec2i(_uv * size), vec2i(0), vec2i(size) - vec2i(1));
|
|
127
133
|
|
|
128
|
-
let
|
|
129
|
-
let
|
|
134
|
+
let ue = textureLoad(envMapDistribution, vec2i(1 + yn.x, yn.y), 0).y;
|
|
135
|
+
let uf = textureLoad(envMapDistribution, vec2i(0, yn.y), 0).y;
|
|
130
136
|
|
|
131
|
-
return
|
|
137
|
+
return envMapSolidAnglePdf(vec2f(ue, uf), _uv.y);
|
|
132
138
|
}
|
|
133
139
|
|
|
134
140
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"envMap.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/envMap.wgsl.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,sFAAsF;AACtF,uHAAuH;AAEvH,eAAe,UAAU,CAAC
|
|
1
|
+
{"version":3,"file":"envMap.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/envMap.wgsl.ts"],"names":[],"mappings":"AAAA,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,sFAAsF;AACtF,uHAAuH;AAEvH,eAAe,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuIzB,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// Sample the environment map using a cumulative distribution function as described in\n// http://www.pbr-book.org/3ed-2018/Light_Transport_I_Surface_Reflection/Sampling_Light_Sources.html#InfiniteAreaLights\n\nexport default /* wgsl */ `\n\nfn textureLinear(tex: texture_2d<f32>, _uv: vec2f) -> vec4f {\n // #ifdef OES_texture_float_linear\n // return texture(map, uv);\n // #else\n let size = vec2f(textureDimensions(tex, 0));\n\n let uv2f = _uv * size - vec2f(0.5);\n let uvFloor = floor(uv2f);\n let f = fract(uv2f);\n let uv2i = vec2i(uvFloor);\n let maximum = vec2i(size) - vec2i(1);\n\n // TODO use textureGather\n let s1 = textureLoad(tex, clamp(uv2i + vec2i(0, 0), vec2i(0), maximum), 0);\n let s2 = textureLoad(tex, clamp(uv2i + vec2i(1, 0), vec2i(0), maximum), 0);\n let s3 = textureLoad(tex, clamp(uv2i + vec2i(0, 1), vec2i(0), maximum), 0);\n let s4 = textureLoad(tex, clamp(uv2i + vec2i(1, 1), vec2i(0), maximum), 0);\n\n return mix(mix(s1, s2, f.x), mix(s3, s4, f.x), f.y);\n // #endif\n}\n\nfn cartesianToEquirect(pointOnSphere: vec3f) -> vec2f {\n var phi = atan2(-pointOnSphere.z, -pointOnSphere.x);\n if (phi < 0.0) {\n phi += TWOPI;\n }\n let theta = acos(clamp(pointOnSphere.y, -1.0, 1.0));\n return vec2f(phi * 0.5 * INVPI, theta * INVPI);\n}\n\nfn environmentOrientation() -> mat3x3f {\n return mat3x3f(rtUniform.environmentRotation[0].xyz, rtUniform.environmentRotation[1].xyz, rtUniform.environmentRotation[2].xyz);\n}\n\nfn environmentUv(worldDirection: vec3f) -> vec2f {\n return cartesianToEquirect(transpose(environmentOrientation()) * worldDirection);\n}\n\nfn getEnvmapV(u: f32, vOffset: ptr<function, i32>, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.y + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(0, mid), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n *vOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(0, *vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(0, *vOffset + 1), 0).xy;\n\n (*pdf).y = s0.y;\n\n return (f32(*vOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.y);\n}\n\nfn getEnvmapU(u: f32, vOffset: i32, pdf: ptr<function, vec2f>) -> f32 {\n let size = vec2i(textureDimensions(envMap, 0));\n\n var left = 0;\n var right = size.x + 1; // cdf length is the length of the env map + 1\n while (left < right) {\n let mid = (left + right) >> 1;\n let s = textureLoad(envMapDistribution, vec2i(1 + mid, vOffset), 0).x;\n if (s <= u) {\n left = mid + 1;\n } else {\n right = mid;\n }\n }\n let uOffset = left - 1;\n\n // x channel is cumulative distribution of env map luminance\n // y channel is partial probability density of env map luminance\n let s0 = textureLoad(envMapDistribution, vec2i(1 + uOffset, vOffset), 0).xy;\n let s1 = textureLoad(envMapDistribution, vec2i(1 + uOffset + 1, vOffset), 0).xy;\n\n (*pdf).x = s0.y;\n\n return (f32(uOffset) + (u - s0.x) / (s1.x - s0.x)) / f32(size.x);\n}\n\n// The lat-long Jacobian is undefined at either pole. In f32, sin(PI) can\n// also be negative, which makes MIS amplify a BSDF hit instead of weighting it.\nfn envMapSolidAnglePdf(partialPdf: vec2f, v: f32) -> f32 {\n if (!(v > 0.0 && v < 1.0)) { return 0.0; }\n let sinTheta = sin(min(v, 1.0 - v) * PI);\n return partialPdf.x * partialPdf.y * INVPI2 / (2.0 * sinTheta);\n}\n\n// Perform two binary searches to find light direction.\nfn sampleEnvmap(random: vec2f, uv: ptr<function, vec2f>, pdf: ptr<function, f32>) -> vec3f {\n var partialPdf: vec2f;\n var vOffset: i32;\n\n (*uv).y = getEnvmapV(random.x, &vOffset, &partialPdf);\n (*uv).x = getEnvmapU(random.y, vOffset, &partialPdf);\n\n let phi = (*uv).x * TWOPI;\n let theta = (*uv).y * PI;\n let cosTheta = cos(theta);\n let sinTheta = sin(theta);\n let cosPhi = cos(phi);\n let sinPhi = sin(phi);\n\n let dir = vec3f(-sinTheta * cosPhi, cosTheta, -sinTheta * sinPhi);\n\n *pdf = envMapSolidAnglePdf(partialPdf, (*uv).y);\n\n return environmentOrientation() * dir;\n}\n\nfn envMapPdf(_uv: vec2f) -> f32 {\n let size = vec2f(textureDimensions(envMap, 0));\n\n let _uv2 = clamp(vec2i(_uv * size), vec2i(0), vec2i(size) - vec2i(1));\n\n let partialX = textureLoad(envMapDistribution, vec2i(1 + _uv2.x, _uv2.y), 0).y;\n let partialY = textureLoad(envMapDistribution, vec2i(0, _uv2.y), 0).y;\n\n return envMapSolidAnglePdf(vec2f(partialX, partialY), _uv.y);\n}\n\n\n`;\n"]}
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
-
export
|
|
1
|
+
export declare function createSceneHitQueryWgsl(hasAnisotropyDirections?: boolean): string;
|
|
2
|
+
export declare function createSceneIntersectionsWgsl({ hasDisplacement, hasAnisotropyDirections, hasCoatNormals, blasLayoutMask, closestName, shadowName, bevelName, closestHitHook }: {
|
|
2
3
|
hasDisplacement: boolean;
|
|
3
4
|
hasAnisotropyDirections?: boolean;
|
|
4
5
|
hasCoatNormals?: boolean;
|
|
5
6
|
blasLayoutMask?: number;
|
|
7
|
+
closestName?: string;
|
|
8
|
+
shadowName?: string;
|
|
9
|
+
bevelName?: string;
|
|
10
|
+
closestHitHook?: string;
|
|
11
|
+
}): string;
|
|
12
|
+
export default function getIntersectCode({ hasDisplacement, hasAnisotropyDirections, hasCoatNormals, blasLayoutMask, sceneIntersections }: {
|
|
13
|
+
hasDisplacement: boolean;
|
|
14
|
+
hasAnisotropyDirections?: boolean;
|
|
15
|
+
hasCoatNormals?: boolean;
|
|
16
|
+
blasLayoutMask?: number;
|
|
17
|
+
sceneIntersections?: string;
|
|
6
18
|
}): string;
|