@meimu/mutracer 0.1.4 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSES/Classroom-CC0.txt +121 -0
- package/README.md +7 -7
- package/THIRD_PARTY_NOTICES.md +13 -8
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +10421 -8363
- package/docs/api.md +202 -11
- package/docs/denoising.md +30 -15
- package/docs/materials.md +18 -27
- package/docs/performance.md +5 -2
- package/docs/progressive-rendering.md +32 -1
- package/docs/threejs.md +19 -10
- package/docs/updates.md +44 -2
- package/docs/viewer.md +41 -3
- package/lib/Display.d.ts +13 -2
- package/lib/Display.js +27 -6
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -0
- package/lib/Engine.js +52 -25
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +44 -9
- package/lib/Render.js +115 -17
- package/lib/Render.js.map +1 -1
- package/lib/RenderLoop.d.ts +7 -1
- package/lib/RenderLoop.js +94 -13
- 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 +10 -0
- package/lib/renderer/GPUTraceQueue.js +31 -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 +32 -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/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/WGPURayTraceOutput.js +26 -17
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.d.ts +36 -40
- package/lib/renderer/WGPURayTracePass.js +399 -548
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.d.ts +5 -3
- package/lib/renderer/WGPURenderingPipeline.js +239 -60
- 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 +5 -3
- package/lib/renderer/WebGLFullQuadPass.js +18 -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 +12 -2
- package/lib/renderer/WebGLRayTracePass.js +83 -7
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +116 -8
- 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 +5 -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/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/envMap.glsl.js +80 -74
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/intersect.glsl.js +437 -435
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +146 -145
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +821 -821
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
- 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.js +51 -51
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +80 -80
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +108 -108
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +20 -17
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampling.glsl.js +93 -93
- 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.js +191 -191
- package/lib/renderer/glsl/shadowCatcher.frag.js +25 -20
- 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 +20 -17
- package/lib/renderer/lightSampling.js +123 -56
- 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 +3 -0
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +3 -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/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 +118 -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/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/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 +15 -0
- package/lib/renderer/wgpuShaderSource.js +31 -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/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 +43 -37
- 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 +743 -706
- 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 +3 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +86 -83
- 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 +139 -139
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +42 -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 -148
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +239 -232
- 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 +26 -13
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +91 -91
- 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/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 +17 -1
- package/lib/renderer/wgsl/rayTrace.compute.js +612 -393
- 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 +7 -169
- 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 +25 -3
- package/lib/settings/render.js +3 -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 +18 -5
- 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 +4 -0
- package/package.json +31 -5
- package/lib/renderer/texturesFromMaterials.d.ts +0 -6
- package/lib/renderer/texturesFromMaterials.js.map +0 -1
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import shadowCatcherAccumulationWGSL from './chunks/shadowCatcherAccumulation.wgsl.js';
|
|
2
|
+
import { linearToSrgbDefine } from './compose.frag.wgsl.js';
|
|
3
|
+
import { JNLM_DEFAULT_COLOR_SENSITIVITY, JNLM_DEFAULT_SHAPE, JNLM_ALBEDO_FLOOR, JNLM_ALBEDO_REGULARIZATION, JNLM_COVERAGE_BANDWIDTH, jnlmPassDilation } from '../jnlm.js';
|
|
4
|
+
function guideBinding(guides, binding, name) {
|
|
5
|
+
return guides === 'textures'
|
|
6
|
+
? `@group(0) @binding(${binding}) var ${name}: texture_2d<f32>;`
|
|
7
|
+
: `@group(0) @binding(${binding}) var<storage, read> ${name}: array<vec4f>;`;
|
|
8
|
+
}
|
|
9
|
+
function loadGuide(guides, name, position) {
|
|
10
|
+
return guides === 'textures' ? `textureLoad(${name}, ${position}, 0)` : `${name}[gv(${position})]`;
|
|
11
|
+
}
|
|
12
|
+
// Shared uniform packing also fixes sensitivity and dilation for native callers.
|
|
13
|
+
export function packJNLMParameters(width, height, strength, pass) {
|
|
14
|
+
const bytes = new ArrayBuffer(16);
|
|
15
|
+
new Uint32Array(bytes, 0, 2).set([width, height]);
|
|
16
|
+
new Float32Array(bytes, 8, 2).set([
|
|
17
|
+
JNLM_DEFAULT_COLOR_SENSITIVITY * Math.max(strength, 1e-3), jnlmPassDilation(pass)
|
|
18
|
+
]);
|
|
19
|
+
return bytes;
|
|
20
|
+
}
|
|
21
|
+
export const JNLM_WORKGROUP_SIZE = 8;
|
|
22
|
+
const paramsWGSL = /* wgsl */ `
|
|
23
|
+
struct JNLMParams {
|
|
24
|
+
size: vec2u,
|
|
25
|
+
colorSensitivity: f32,
|
|
26
|
+
|
|
27
|
+
dilation: f32,
|
|
28
|
+
}
|
|
29
|
+
@group(0) @binding(0) var<uniform> params: JNLMParams;
|
|
30
|
+
`;
|
|
31
|
+
/**
|
|
32
|
+
* Pass 1: the guide mean and the variance of that mean from the accumulated
|
|
33
|
+
* moments. Ray buffers are stored bottom-up; guides use texture rows.
|
|
34
|
+
*/
|
|
35
|
+
export const jnlmGuideWGSL = /* wgsl */ `
|
|
36
|
+
${paramsWGSL}
|
|
37
|
+
${shadowCatcherAccumulationWGSL}
|
|
38
|
+
@group(0) @binding(1) var<storage, read> accumulation: array<ShadowCatcherAccumulation>;
|
|
39
|
+
@group(0) @binding(2) var<storage, read> normalBuffer: array<vec4f>;
|
|
40
|
+
@group(0) @binding(3) var<storage, read_write> rawGuide: array<vec2f>;
|
|
41
|
+
|
|
42
|
+
@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)
|
|
43
|
+
fn main(@builtin(global_invocation_id) id: vec3u) {
|
|
44
|
+
let size = params.size;
|
|
45
|
+
if (id.x >= size.x || id.y >= size.y) { return; }
|
|
46
|
+
let qE = id.x + (size.y - 1u - id.y) * size.x;
|
|
47
|
+
let n = normalBuffer[qE].a;
|
|
48
|
+
let moments = accumulation[qE].moments;
|
|
49
|
+
let mean = moments.x / max(n, 1.0);
|
|
50
|
+
|
|
51
|
+
var variance = -1.0;
|
|
52
|
+
if (n >= 2.0) {
|
|
53
|
+
variance = max(moments.y - n * mean * mean, 0.0) / (n * (n - 1.0));
|
|
54
|
+
}
|
|
55
|
+
rawGuide[id.x + id.y * size.x] = vec2f(mean, variance);
|
|
56
|
+
}
|
|
57
|
+
`;
|
|
58
|
+
/**
|
|
59
|
+
* Pass 2: smooth the noisy per-pixel variance over 3 x 3 pixels. Pixels with
|
|
60
|
+
* a single sample take the spatial variance of their neighborhood instead.
|
|
61
|
+
*/
|
|
62
|
+
export const jnlmVarianceWGSL = /* wgsl */ `
|
|
63
|
+
${paramsWGSL}
|
|
64
|
+
@group(0) @binding(1) var<storage, read> rawGuide: array<vec2f>;
|
|
65
|
+
@group(0) @binding(2) var<storage, read_write> guide: array<vec2f>;
|
|
66
|
+
|
|
67
|
+
@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)
|
|
68
|
+
fn main(@builtin(global_invocation_id) id: vec3u) {
|
|
69
|
+
let size = params.size;
|
|
70
|
+
if (id.x >= size.x || id.y >= size.y) { return; }
|
|
71
|
+
let center = rawGuide[id.x + id.y * size.x];
|
|
72
|
+
var mf = 0.0;
|
|
73
|
+
var jx = 0.0;
|
|
74
|
+
var nW = 0.0;
|
|
75
|
+
var jp = 0.0;
|
|
76
|
+
for (var dy = -1; dy <= 1; dy++) {
|
|
77
|
+
for (var dx = -1; dx <= 1; dx++) {
|
|
78
|
+
let q = clamp(vec2i(id.xy) + vec2i(dx, dy), vec2i(0), vec2i(size) - 1);
|
|
79
|
+
let value = rawGuide[u32(q.x) + u32(q.y) * size.x];
|
|
80
|
+
nW += value.x;
|
|
81
|
+
jp += value.x * value.x;
|
|
82
|
+
if (value.y >= 0.0) {
|
|
83
|
+
mf += value.y;
|
|
84
|
+
jx += 1.0;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
var variance: f32;
|
|
89
|
+
if (center.y >= 0.0) {
|
|
90
|
+
variance = mf / jx;
|
|
91
|
+
} else {
|
|
92
|
+
let me = nW / 9.0;
|
|
93
|
+
variance = max(jp / 9.0 - me * me, 0.0) * 9.0 / 8.0;
|
|
94
|
+
}
|
|
95
|
+
guide[id.x + id.y * size.x] = vec2f(center.x, variance);
|
|
96
|
+
}
|
|
97
|
+
`;
|
|
98
|
+
/** Copies the composed image into the filter's color buffer. */
|
|
99
|
+
export function createJNLMLoadColorWGSL(guides = 'textures') {
|
|
100
|
+
return /* wgsl */ `
|
|
101
|
+
${paramsWGSL}
|
|
102
|
+
@group(0) @binding(1) var colorTex: texture_2d<f32>;
|
|
103
|
+
@group(0) @binding(2) var<storage, read_write> outColor: array<vec4f>;
|
|
104
|
+
${guides === 'buffers' ? `${shadowCatcherAccumulationWGSL}
|
|
105
|
+
@group(0) @binding(3) var<storage, read> normalAccumulation: array<vec4f>;
|
|
106
|
+
@group(0) @binding(4) var<storage, read_write> normal: array<vec4f>;
|
|
107
|
+
@group(0) @binding(5) var<storage, read> shadowAccumulation: array<ShadowCatcherAccumulation>;
|
|
108
|
+
@group(0) @binding(6) var<storage, read_write> shadow: array<vec4f>;
|
|
109
|
+
@group(0) @binding(7) var albedoTex: texture_2d<f32>;
|
|
110
|
+
@group(0) @binding(8) var<storage, read_write> albedo: array<vec4f>;` : ''}
|
|
111
|
+
|
|
112
|
+
@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)
|
|
113
|
+
fn main(@builtin(global_invocation_id) id: vec3u) {
|
|
114
|
+
if (id.x >= params.size.x || id.y >= params.size.y) { return; }
|
|
115
|
+
outColor[id.x + id.y * params.size.x] = textureLoad(colorTex, vec2i(id.xy), 0);
|
|
116
|
+
${guides === 'buffers' ? ` let index = id.x + id.y * params.size.x;
|
|
117
|
+
let qE = id.x + (params.size.y - 1u - id.y) * params.size.x;
|
|
118
|
+
let n = normalAccumulation[qE];
|
|
119
|
+
let samples = max(n.a, 1.0);
|
|
120
|
+
normal[index] = vec4f(n.rgb / samples * 0.5 + 0.5, select(0.0, 1.0, dot(n.rgb, n.rgb) > 0.1));
|
|
121
|
+
shadow[index] = shadowAccumulation[qE].mask / samples;
|
|
122
|
+
albedo[index] = textureLoad(albedoTex, vec2i(id.xy), 0);` : ''}
|
|
123
|
+
}
|
|
124
|
+
`;
|
|
125
|
+
}
|
|
126
|
+
export const jnlmLoadColorWGSL = createJNLMLoadColorWGSL();
|
|
127
|
+
/**
|
|
128
|
+
* Pass 3: the joint NL-means filter of the composed image. It also filters
|
|
129
|
+
* the guide with the same weights, with the variance of the weighted mean,
|
|
130
|
+
* for a following pass. The albedo regression corrects color only, keeping
|
|
131
|
+
* uncertain fitted texture responses out of the matching guide.
|
|
132
|
+
*/
|
|
133
|
+
export function createJNLMFilterWGSL({ searchRadius, patchRadius, albedoBandwidth, normalBandwidth } = JNLM_DEFAULT_SHAPE, guides = 'textures') {
|
|
134
|
+
const patchSize = (2 * patchRadius + 1) ** 2;
|
|
135
|
+
return /* wgsl */ `
|
|
136
|
+
${paramsWGSL}
|
|
137
|
+
@group(0) @binding(1) var<storage, read> guide: array<vec2f>;
|
|
138
|
+
@group(0) @binding(2) var<storage, read> color: array<vec4f>;
|
|
139
|
+
${guideBinding(guides, 3, 'albedoTex')}
|
|
140
|
+
${guideBinding(guides, 4, 'normalTex')}
|
|
141
|
+
@group(0) @binding(5) var<storage, read_write> outColor: array<vec4f>;
|
|
142
|
+
@group(0) @binding(6) var<storage, read_write> outGuide: array<vec2f>;
|
|
143
|
+
${guideBinding(guides, 7, 'shadowCatcherTex')}
|
|
144
|
+
|
|
145
|
+
const SEARCH_RADIUS = ${searchRadius};
|
|
146
|
+
const PATCH_RADIUS = ${patchRadius};
|
|
147
|
+
const PATCH_SIZE = ${patchSize};
|
|
148
|
+
|
|
149
|
+
const VARIANCE_CANCELLATION = 1.0;
|
|
150
|
+
|
|
151
|
+
const INV_ALBEDO_BANDWIDTH2 = ${(1 / albedoBandwidth ** 2).toFixed(6)};
|
|
152
|
+
const INV_COVERAGE_BANDWIDTH2 = ${(1 / JNLM_COVERAGE_BANDWIDTH ** 2).toFixed(6)};
|
|
153
|
+
const INV_NORMAL_BANDWIDTH2 = ${(1 / normalBandwidth ** 2).toFixed(6)};
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
const CENTER_WEIGHT_MIN = 0.01;
|
|
157
|
+
|
|
158
|
+
fn gv(p: vec2i) -> u32 {
|
|
159
|
+
let q = clamp(p, vec2i(0), vec2i(params.size) - 1);
|
|
160
|
+
return u32(q.x) + u32(q.y) * params.size.x;
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
fn mi(q: vec2i, bC: vec4f, hg: vec3f) -> f32 {
|
|
164
|
+
let albedo = ${loadGuide(guides, 'albedoTex', 'q')};
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
let qd = max((albedo.rgb + bC.rgb) * 0.5, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
168
|
+
let lN = (albedo.rgb - bC.rgb) / qd;
|
|
169
|
+
let jk = albedo.a - bC.a;
|
|
170
|
+
let lX = ${loadGuide(guides, 'normalTex', 'q')}.rgb - hg;
|
|
171
|
+
return max(
|
|
172
|
+
dot(lN, lN) * INV_ALBEDO_BANDWIDTH2
|
|
173
|
+
+ jk * jk * INV_COVERAGE_BANDWIDTH2,
|
|
174
|
+
dot(lX, lX) * INV_NORMAL_BANDWIDTH2
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
fn premultiplied(c: vec4f) -> vec4f {
|
|
179
|
+
return vec4f(c.rgb * c.a, c.a);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)
|
|
183
|
+
fn main(@builtin(global_invocation_id) id: vec3u) {
|
|
184
|
+
let size = vec2i(params.size);
|
|
185
|
+
let p = vec2i(id.xy);
|
|
186
|
+
if (p.x >= size.x || p.y >= size.y) { return; }
|
|
187
|
+
let step = i32(params.dilation);
|
|
188
|
+
let bC = ${loadGuide(guides, 'albedoTex', 'p')};
|
|
189
|
+
let fR = ${loadGuide(guides, 'normalTex', 'p')};
|
|
190
|
+
let hg = fR.rgb;
|
|
191
|
+
let index = gv(p);
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
if (fR.a <= 0.0 && ${loadGuide(guides, 'shadowCatcherTex', 'p')}.r <= 0.0) {
|
|
195
|
+
outColor[index] = color[index];
|
|
196
|
+
outGuide[index] = guide[index];
|
|
197
|
+
return;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
var lP: array<vec2f, PATCH_SIZE>;
|
|
201
|
+
var k = 0;
|
|
202
|
+
for (var dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
|
|
203
|
+
for (var dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
|
|
204
|
+
lP[k] = guide[gv(p + vec2i(dx, dy) * step)];
|
|
205
|
+
k++;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
let k2 = params.colorSensitivity * params.colorSensitivity;
|
|
209
|
+
|
|
210
|
+
var sum = vec4f(0.0);
|
|
211
|
+
let hk = max(bC.rgb, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
212
|
+
var ng = vec3f(0.0);
|
|
213
|
+
var gN = vec3f(0.0);
|
|
214
|
+
var hG = vec3f(0.0);
|
|
215
|
+
var qp = 0.0;
|
|
216
|
+
var gP = 0.0;
|
|
217
|
+
var oP = 0.0;
|
|
218
|
+
var lt = 0.0;
|
|
219
|
+
for (var sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {
|
|
220
|
+
for (var sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {
|
|
221
|
+
let q = p + vec2i(sx, sy) * step;
|
|
222
|
+
if (
|
|
223
|
+
(sx == 0 && sy == 0) ||
|
|
224
|
+
q.x < 0 || q.y < 0 || q.x >= size.x || q.y >= size.y
|
|
225
|
+
) { continue; }
|
|
226
|
+
|
|
227
|
+
let features = mi(q, bC, hg);
|
|
228
|
+
if (features > 16.0) { continue; }
|
|
229
|
+
|
|
230
|
+
var gk = 0.0;
|
|
231
|
+
k = 0;
|
|
232
|
+
for (var dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
|
|
233
|
+
for (var dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
|
|
234
|
+
let a = lP[k];
|
|
235
|
+
let b = guide[gv(q + vec2i(dx, dy) * step)];
|
|
236
|
+
let rZ = a.x - b.x;
|
|
237
|
+
gk += (rZ * rZ
|
|
238
|
+
- VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))
|
|
239
|
+
/ (1e-10 + k2 * (a.y + b.y));
|
|
240
|
+
k++;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
gk /= f32(PATCH_SIZE);
|
|
244
|
+
|
|
245
|
+
let weight = exp(-max(max(gk, 0.0), features));
|
|
246
|
+
let index = gv(q);
|
|
247
|
+
let c = color[index];
|
|
248
|
+
let g = guide[index];
|
|
249
|
+
|
|
250
|
+
let a = (${loadGuide(guides, 'albedoTex', 'q')}.rgb - bC.rgb) / hk;
|
|
251
|
+
let value = premultiplied(c);
|
|
252
|
+
sum += value * weight;
|
|
253
|
+
ng += a * weight;
|
|
254
|
+
gN += a * a * weight;
|
|
255
|
+
hG += a * value.rgb * weight;
|
|
256
|
+
qp += g.x * weight;
|
|
257
|
+
gP += g.y * weight * weight;
|
|
258
|
+
oP += weight;
|
|
259
|
+
lt = max(lt, weight);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
|
|
264
|
+
|
|
265
|
+
let center = color[index];
|
|
266
|
+
let lO = guide[index];
|
|
267
|
+
let dR = max(lt, CENTER_WEIGHT_MIN);
|
|
268
|
+
let totalWeight = oP + dR;
|
|
269
|
+
let vj = premultiplied(center);
|
|
270
|
+
let mean = (sum + vj * dR) / totalWeight;
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
let eI = ng / totalWeight;
|
|
274
|
+
let mj = max(gN / totalWeight - eI * eI, vec3f(0.0));
|
|
275
|
+
let rv = hG / totalWeight - eI * mean.rgb;
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
let rI = bC.rgb + eI * hk;
|
|
280
|
+
let po = mean.rgb * hk / max(rI, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
281
|
+
let xg = clamp(rv / (mj + vec3f(${JNLM_ALBEDO_REGULARIZATION})), vec3f(0.0), po);
|
|
282
|
+
let sD = mean.rgb - xg * eI;
|
|
283
|
+
let filtered = vec4f(max(sD, vec3f(0.0)), max(mean.a, 0.0));
|
|
284
|
+
let rgb = select(
|
|
285
|
+
center.rgb,
|
|
286
|
+
filtered.rgb / max(filtered.a, 1e-6),
|
|
287
|
+
filtered.a > 1e-6
|
|
288
|
+
);
|
|
289
|
+
outColor[index] = vec4f(rgb, filtered.a);
|
|
290
|
+
outGuide[index] = vec2f(
|
|
291
|
+
(qp + lO.x * dR) / totalWeight,
|
|
292
|
+
(gP + lO.y * dR * dR)
|
|
293
|
+
/ (totalWeight * totalWeight)
|
|
294
|
+
);
|
|
295
|
+
}
|
|
296
|
+
`;
|
|
297
|
+
}
|
|
298
|
+
// Compute presentation for hosts that consume the filtered buffer directly.
|
|
299
|
+
// Use the same sRGB transfer as browser display composition.
|
|
300
|
+
export const jnlmEncodeWGSL = /* wgsl */ `
|
|
301
|
+
struct OutputParams { size: vec2u, premultiply: u32, reserved: u32 }
|
|
302
|
+
@group(0) @binding(0) var<uniform> params: OutputParams;
|
|
303
|
+
@group(0) @binding(1) var<storage, read> color: array<vec4f>;
|
|
304
|
+
@group(0) @binding(2) var output: texture_storage_2d<rgba8unorm, write>;
|
|
305
|
+
${linearToSrgbDefine}
|
|
306
|
+
@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)
|
|
307
|
+
fn main(@builtin(global_invocation_id) id: vec3u) {
|
|
308
|
+
if (any(id.xy >= params.size)) { return; }
|
|
309
|
+
let c = color[id.y * params.size.x + id.x];
|
|
310
|
+
var rgb = linearToSrgb(c.rgb);
|
|
311
|
+
if (params.premultiply != 0u) { rgb *= c.a; }
|
|
312
|
+
textureStore(output, id.xy, vec4f(rgb, c.a));
|
|
313
|
+
}
|
|
314
|
+
`;
|
|
315
|
+
//# sourceMappingURL=jnlm.compute.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jnlm.compute.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/jnlm.compute.ts"],"names":[],"mappings":"AAAA,OAAO,6BAA6B,MAAM,4CAA4C,CAAC;AACvF,OAAO,EAAC,kBAAkB,EAAC,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EACL,8BAA8B,EAAE,kBAAkB,EAAE,iBAAiB,EACrE,0BAA0B,EAAE,uBAAuB,EAAE,gBAAgB,EAEtE,MAAM,YAAY,CAAC;AAIpB,SAAS,YAAY,CAAC,MAAyB,EAAE,OAAe,EAAE,IAAY;IAC5E,OAAO,MAAM,KAAK,UAAU;QAC1B,CAAC,CAAC,sBAAsB,OAAO,SAAS,IAAI,oBAAoB;QAChE,CAAC,CAAC,sBAAsB,OAAO,wBAAwB,IAAI,iBAAiB,CAAC;AACjF,CAAC;AACD,SAAS,SAAS,CAAC,MAAyB,EAAE,IAAY,EAAE,QAAgB;IAC1E,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,eAAe,IAAI,KAAK,QAAQ,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,OAAe,QAAQ,IAAI,CAAC;AAC7G,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,kBAAkB,CAAC,KAAa,EAAE,MAAc,EAAE,QAAgB,EAAE,IAAY;IAC9F,MAAM,KAAK,GAAG,IAAI,WAAW,CAAC,EAAE,CAAC,CAAC;IAClC,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;IAClD,IAAI,YAAY,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;QAChC,8BAA8B,GAAG,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,EAAE,gBAAgB,CAAC,IAAI,CAAC;KAClF,CAAC,CAAC;IACH,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC;AAErC,MAAM,UAAU,GAAG,UAAU,CAAC;;;;;;;;CAQ7B,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,UAAU,CAAC;EACtC,UAAU;EACV,6BAA6B;;;;;2BAKJ,mBAAmB,KAAK,mBAAmB;;;;;;;;;;;;;;;CAerE,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,UAAU,CAAC;EACzC,UAAU;;;;2BAIe,mBAAmB,KAAK,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BrE,CAAC;AAEF,gEAAgE;AAChE,MAAM,UAAU,uBAAuB,CAAC,SAA4B,UAAU;IAC5E,OAAO,UAAU,CAAC;EAClB,UAAU;;;EAGV,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,GAAG,6BAA6B;;;;;;qEAMY,CAAC,CAAC,CAAC,EAAE;;2BAE/C,mBAAmB,KAAK,mBAAmB;;;;EAIpE,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC;;;;;;yDAMkC,CAAC,CAAC,CAAC,EAAE;;CAE/D,CAAC;AACF,CAAC;AACD,MAAM,CAAC,MAAM,iBAAiB,GAAG,uBAAuB,EAAE,CAAC;AAE3D;;;;;GAKG;AACH,MAAM,UAAU,oBAAoB,CAAC,EACnC,YAAY,EAAE,WAAW,EAAE,eAAe,EAAE,eAAe,KACxC,kBAAkB,EAAE,SAA4B,UAAU;IAC7E,MAAM,SAAS,GAAG,CAAC,CAAC,GAAG,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC;IAC7C,OAAO,UAAU,CAAC;EAClB,UAAU;;;EAGV,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC;EACpC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,WAAW,CAAC;;;EAGpC,YAAY,CAAC,MAAM,EAAE,CAAC,EAAE,kBAAkB,CAAC;;wBAErB,YAAY;uBACb,WAAW;qBACb,SAAS;;;;gCAIE,CAAC,CAAC,GAAG,eAAe,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;kCACnC,CAAC,CAAC,GAAG,uBAAuB,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;gCAC/C,CAAC,CAAC,GAAG,eAAe,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;;;;;;;;;;;eAWpD,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC;;;kDAGmB,iBAAiB;;;WAGlE,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC;;;;;;;;;;;;2BAY9B,mBAAmB,KAAK,mBAAmB;;;;;;WAM/C,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC;WAC9B,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC;;;;;qBAKzB,SAAS,CAAC,MAAM,EAAE,kBAAkB,EAAE,GAAG,CAAC;;;;;;;;;;;;;;;;;6BAiB7B,iBAAiB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;WAuCnD,SAAS,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCA8BmB,iBAAiB;kCAC5B,0BAA0B;;;;;;;;;;;;;;;CAerF,CAAC;AACF,CAAC;AAED,4EAA4E;AAC5E,6DAA6D;AAC7D,MAAM,CAAC,MAAM,cAAc,GAAG,UAAU,CAAC;;;;;EAKvC,kBAAkB;2BACO,mBAAmB,KAAK,mBAAmB;;;;;;;;CAQrE,CAAC","sourcesContent":["import shadowCatcherAccumulationWGSL from './chunks/shadowCatcherAccumulation.wgsl.js';\nimport {linearToSrgbDefine} from './compose.frag.wgsl.js';\nimport {\n JNLM_DEFAULT_COLOR_SENSITIVITY, JNLM_DEFAULT_SHAPE, JNLM_ALBEDO_FLOOR,\n JNLM_ALBEDO_REGULARIZATION, JNLM_COVERAGE_BANDWIDTH, jnlmPassDilation,\n type JNLMFilterShape\n} from '../jnlm.js';\n\n// Web textures and native normalized guide buffers use the same filter body.\nexport type JNLMGuideBindings = 'textures' | 'buffers';\nfunction guideBinding(guides: JNLMGuideBindings, binding: number, name: string): string {\n return guides === 'textures'\n ? `@group(0) @binding(${binding}) var ${name}: texture_2d<f32>;`\n : `@group(0) @binding(${binding}) var<storage, read> ${name}: array<vec4f>;`;\n}\nfunction loadGuide(guides: JNLMGuideBindings, name: string, position: string): string {\n return guides === 'textures' ? `textureLoad(${name}, ${position}, 0)` : `${name}[pixelIndex(${position})]`;\n}\n\n// Shared uniform packing also fixes sensitivity and dilation for native callers.\nexport function packJNLMParameters(width: number, height: number, strength: number, pass: number): ArrayBuffer {\n const bytes = new ArrayBuffer(16);\n new Uint32Array(bytes, 0, 2).set([width, height]);\n new Float32Array(bytes, 8, 2).set([\n JNLM_DEFAULT_COLOR_SENSITIVITY * Math.max(strength, 1e-3), jnlmPassDilation(pass)\n ]);\n return bytes;\n}\n\nexport const JNLM_WORKGROUP_SIZE = 8;\n\nconst paramsWGSL = /* wgsl */ `\nstruct JNLMParams {\n size: vec2u,\n colorSensitivity: f32,\n // Pixel spacing of the search window and patches in this pass.\n dilation: f32,\n}\n@group(0) @binding(0) var<uniform> params: JNLMParams;\n`;\n\n/**\n * Pass 1: the guide mean and the variance of that mean from the accumulated\n * moments. Ray buffers are stored bottom-up; guides use texture rows.\n */\nexport const jnlmGuideWGSL = /* wgsl */ `\n${paramsWGSL}\n${shadowCatcherAccumulationWGSL}\n@group(0) @binding(1) var<storage, read> accumulation: array<ShadowCatcherAccumulation>;\n@group(0) @binding(2) var<storage, read> normalBuffer: array<vec4f>;\n@group(0) @binding(3) var<storage, read_write> rawGuide: array<vec2f>;\n\n@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)\nfn main(@builtin(global_invocation_id) id: vec3u) {\n let size = params.size;\n if (id.x >= size.x || id.y >= size.y) { return; }\n let rayIndex = id.x + (size.y - 1u - id.y) * size.x;\n let n = normalBuffer[rayIndex].a;\n let moments = accumulation[rayIndex].moments;\n let mean = moments.x / max(n, 1.0);\n // Variance of the mean, or -1 when one sample cannot estimate it.\n var variance = -1.0;\n if (n >= 2.0) {\n variance = max(moments.y - n * mean * mean, 0.0) / (n * (n - 1.0));\n }\n rawGuide[id.x + id.y * size.x] = vec2f(mean, variance);\n}\n`;\n\n/**\n * Pass 2: smooth the noisy per-pixel variance over 3 x 3 pixels. Pixels with\n * a single sample take the spatial variance of their neighborhood instead.\n */\nexport const jnlmVarianceWGSL = /* wgsl */ `\n${paramsWGSL}\n@group(0) @binding(1) var<storage, read> rawGuide: array<vec2f>;\n@group(0) @binding(2) var<storage, read_write> guide: array<vec2f>;\n\n@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)\nfn main(@builtin(global_invocation_id) id: vec3u) {\n let size = params.size;\n if (id.x >= size.x || id.y >= size.y) { return; }\n let center = rawGuide[id.x + id.y * size.x];\n var varianceSum = 0.0;\n var varianceCount = 0.0;\n var meanSum = 0.0;\n var meanSquareSum = 0.0;\n for (var dy = -1; dy <= 1; dy++) {\n for (var dx = -1; dx <= 1; dx++) {\n let q = clamp(vec2i(id.xy) + vec2i(dx, dy), vec2i(0), vec2i(size) - 1);\n let value = rawGuide[u32(q.x) + u32(q.y) * size.x];\n meanSum += value.x;\n meanSquareSum += value.x * value.x;\n if (value.y >= 0.0) {\n varianceSum += value.y;\n varianceCount += 1.0;\n }\n }\n }\n var variance: f32;\n if (center.y >= 0.0) {\n variance = varianceSum / varianceCount;\n } else {\n let spatialMean = meanSum / 9.0;\n variance = max(meanSquareSum / 9.0 - spatialMean * spatialMean, 0.0) * 9.0 / 8.0;\n }\n guide[id.x + id.y * size.x] = vec2f(center.x, variance);\n}\n`;\n\n/** Copies the composed image into the filter's color buffer. */\nexport function createJNLMLoadColorWGSL(guides: JNLMGuideBindings = 'textures'): string {\n return /* wgsl */ `\n${paramsWGSL}\n@group(0) @binding(1) var colorTex: texture_2d<f32>;\n@group(0) @binding(2) var<storage, read_write> outColor: array<vec4f>;\n${guides === 'buffers' ? `${shadowCatcherAccumulationWGSL}\n@group(0) @binding(3) var<storage, read> normalAccumulation: array<vec4f>;\n@group(0) @binding(4) var<storage, read_write> normal: array<vec4f>;\n@group(0) @binding(5) var<storage, read> shadowAccumulation: array<ShadowCatcherAccumulation>;\n@group(0) @binding(6) var<storage, read_write> shadow: array<vec4f>;\n@group(0) @binding(7) var albedoTex: texture_2d<f32>;\n@group(0) @binding(8) var<storage, read_write> albedo: array<vec4f>;` : ''}\n\n@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)\nfn main(@builtin(global_invocation_id) id: vec3u) {\n if (id.x >= params.size.x || id.y >= params.size.y) { return; }\n outColor[id.x + id.y * params.size.x] = textureLoad(colorTex, vec2i(id.xy), 0);\n${guides === 'buffers' ? ` let index = id.x + id.y * params.size.x;\n let rayIndex = id.x + (params.size.y - 1u - id.y) * params.size.x;\n let n = normalAccumulation[rayIndex];\n let samples = max(n.a, 1.0);\n normal[index] = vec4f(n.rgb / samples * 0.5 + 0.5, select(0.0, 1.0, dot(n.rgb, n.rgb) > 0.1));\n shadow[index] = shadowAccumulation[rayIndex].mask / samples;\n albedo[index] = textureLoad(albedoTex, vec2i(id.xy), 0);` : ''}\n}\n`;\n}\nexport const jnlmLoadColorWGSL = createJNLMLoadColorWGSL();\n\n/**\n * Pass 3: the joint NL-means filter of the composed image. It also filters\n * the guide with the same weights, with the variance of the weighted mean,\n * for a following pass. The albedo regression corrects color only, keeping\n * uncertain fitted texture responses out of the matching guide.\n */\nexport function createJNLMFilterWGSL({\n searchRadius, patchRadius, albedoBandwidth, normalBandwidth\n}: JNLMFilterShape = JNLM_DEFAULT_SHAPE, guides: JNLMGuideBindings = 'textures') {\n const patchSize = (2 * patchRadius + 1) ** 2;\n return /* wgsl */ `\n${paramsWGSL}\n@group(0) @binding(1) var<storage, read> guide: array<vec2f>;\n@group(0) @binding(2) var<storage, read> color: array<vec4f>;\n${guideBinding(guides, 3, 'albedoTex')}\n${guideBinding(guides, 4, 'normalTex')}\n@group(0) @binding(5) var<storage, read_write> outColor: array<vec4f>;\n@group(0) @binding(6) var<storage, read_write> outGuide: array<vec2f>;\n${guideBinding(guides, 7, 'shadowCatcherTex')}\n\nconst SEARCH_RADIUS = ${searchRadius};\nconst PATCH_RADIUS = ${patchRadius};\nconst PATCH_SIZE = ${patchSize};\n// Variance cancellation strength alpha of the paper.\nconst VARIANCE_CANCELLATION = 1.0;\n// Inverse squared feature bandwidths. Normals are encoded as n * 0.5 + 0.5.\nconst INV_ALBEDO_BANDWIDTH2 = ${(1 / albedoBandwidth ** 2).toFixed(6)};\nconst INV_COVERAGE_BANDWIDTH2 = ${(1 / JNLM_COVERAGE_BANDWIDTH ** 2).toFixed(6)};\nconst INV_NORMAL_BANDWIDTH2 = ${(1 / normalBandwidth ** 2).toFixed(6)};\n// Lower bound of the center weight, so a pixel unlike all of its neighbors\n// (a thin highlight) is kept rather than replaced by them.\nconst CENTER_WEIGHT_MIN = 0.01;\n\nfn pixelIndex(p: vec2i) -> u32 {\n let q = clamp(p, vec2i(0), vec2i(params.size) - 1);\n return u32(q.x) + u32(q.y) * params.size.x;\n}\n\nfn featureDistance(q: vec2i, centerAlbedo: vec4f, centerNormal: vec3f) -> f32 {\n let albedo = ${loadGuide(guides, 'albedoTex', 'q')};\n // Absolute differences in linear albedo erase low-contrast dark textures.\n // Measure RGB contrast relative to both pixels; keep coverage absolute.\n let albedoScale = max((albedo.rgb + centerAlbedo.rgb) * 0.5, vec3f(${JNLM_ALBEDO_FLOOR}));\n let albedoDelta = (albedo.rgb - centerAlbedo.rgb) / albedoScale;\n let coverageDelta = albedo.a - centerAlbedo.a;\n let normalDelta = ${loadGuide(guides, 'normalTex', 'q')}.rgb - centerNormal;\n return max(\n dot(albedoDelta, albedoDelta) * INV_ALBEDO_BANDWIDTH2\n + coverageDelta * coverageDelta * INV_COVERAGE_BANDWIDTH2,\n dot(normalDelta, normalDelta) * INV_NORMAL_BANDWIDTH2\n );\n}\n\nfn premultiplied(c: vec4f) -> vec4f {\n return vec4f(c.rgb * c.a, c.a);\n}\n\n@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)\nfn main(@builtin(global_invocation_id) id: vec3u) {\n let size = vec2i(params.size);\n let p = vec2i(id.xy);\n if (p.x >= size.x || p.y >= size.y) { return; }\n let step = i32(params.dilation);\n let centerAlbedo = ${loadGuide(guides, 'albedoTex', 'p')};\n let centerNormalTexel = ${loadGuide(guides, 'normalTex', 'p')};\n let centerNormal = centerNormalTexel.rgb;\n let index = pixelIndex(p);\n // Primary misses show the background directly. It has no features that\n // protect its detail and no noise beyond antialiasing, so keep it.\n if (centerNormalTexel.a <= 0.0 && ${loadGuide(guides, 'shadowCatcherTex', 'p')}.r <= 0.0) {\n outColor[index] = color[index];\n outGuide[index] = guide[index];\n return;\n }\n\n var centerPatch: array<vec2f, PATCH_SIZE>;\n var k = 0;\n for (var dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (var dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n centerPatch[k] = guide[pixelIndex(p + vec2i(dx, dy) * step)];\n k++;\n }\n }\n let k2 = params.colorSensitivity * params.colorSensitivity;\n\n var sum = vec4f(0.0);\n let featureScale = max(centerAlbedo.rgb, vec3f(${JNLM_ALBEDO_FLOOR}));\n var featureSum = vec3f(0.0);\n var featureSquareSum = vec3f(0.0);\n var featureColorSum = vec3f(0.0);\n var guideSum = 0.0;\n var guideVarianceSum = 0.0;\n var weightSum = 0.0;\n var maxWeight = 0.0;\n for (var sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {\n for (var sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {\n let q = p + vec2i(sx, sy) * step;\n if (\n (sx == 0 && sy == 0) ||\n q.x < 0 || q.y < 0 || q.x >= size.x || q.y >= size.y\n ) { continue; }\n\n let features = featureDistance(q, centerAlbedo, centerNormal);\n if (features > 16.0) { continue; }\n\n var colorDistance = 0.0;\n k = 0;\n for (var dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {\n for (var dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {\n let a = centerPatch[k];\n let b = guide[pixelIndex(q + vec2i(dx, dy) * step)];\n let delta = a.x - b.x;\n colorDistance += (delta * delta\n - VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))\n / (1e-10 + k2 * (a.y + b.y));\n k++;\n }\n }\n colorDistance /= f32(PATCH_SIZE);\n\n let weight = exp(-max(max(colorDistance, 0.0), features));\n let index = pixelIndex(q);\n let c = color[index];\n let g = guide[index];\n // Filter premultiplied color so coverage and color stay consistent.\n let a = (${loadGuide(guides, 'albedoTex', 'q')}.rgb - centerAlbedo.rgb) / featureScale;\n let value = premultiplied(c);\n sum += value * weight;\n featureSum += a * weight;\n featureSquareSum += a * a * weight;\n featureColorSum += a * value.rgb * weight;\n guideSum += g.x * weight;\n guideVarianceSum += g.y * weight * weight;\n weightSum += weight;\n maxWeight = max(maxWeight, weight);\n }\n }\n\n // Weight the center like its most similar neighbor (Buades et al. 2005)\n // instead of 1, so isolated outliers are not kept unfiltered.\n let center = color[index];\n let centerGuide = guide[index];\n let centerWeight = max(maxWeight, CENTER_WEIGHT_MIN);\n let totalWeight = weightSum + centerWeight;\n let centerValue = premultiplied(center);\n let mean = (sum + centerValue * centerWeight) / totalWeight;\n // Fit each color channel against relative albedo with the same JNLM weights.\n // Centering at this pixel avoids cancellation when the feature is constant.\n let meanFeature = featureSum / totalWeight;\n let featureVariance = max(featureSquareSum / totalWeight - meanFeature * meanFeature, vec3f(0.0));\n let covariance = featureColorSum / totalWeight - meanFeature * mean.rgb;\n // A 1% contrast ridge stabilizes flat guides. Bound the response between no\n // texture dependence and multiplicative albedo modulation; specular color\n // with an unrelated albedo falls back to the weighted mean.\n let meanAlbedo = centerAlbedo.rgb + meanFeature * featureScale;\n let maximumSlope = mean.rgb * featureScale / max(meanAlbedo, vec3f(${JNLM_ALBEDO_FLOOR}));\n let slope = clamp(covariance / (featureVariance + vec3f(${JNLM_ALBEDO_REGULARIZATION})), vec3f(0.0), maximumSlope);\n let corrected = mean.rgb - slope * meanFeature;\n let filtered = vec4f(max(corrected, vec3f(0.0)), max(mean.a, 0.0));\n let rgb = select(\n center.rgb,\n filtered.rgb / max(filtered.a, 1e-6),\n filtered.a > 1e-6\n );\n outColor[index] = vec4f(rgb, filtered.a);\n outGuide[index] = vec2f(\n (guideSum + centerGuide.x * centerWeight) / totalWeight,\n (guideVarianceSum + centerGuide.y * centerWeight * centerWeight)\n / (totalWeight * totalWeight)\n );\n}\n`;\n}\n\n// Compute presentation for hosts that consume the filtered buffer directly.\n// Use the same sRGB transfer as browser display composition.\nexport const jnlmEncodeWGSL = /* wgsl */ `\nstruct OutputParams { size: vec2u, premultiply: u32, reserved: u32 }\n@group(0) @binding(0) var<uniform> params: OutputParams;\n@group(0) @binding(1) var<storage, read> color: array<vec4f>;\n@group(0) @binding(2) var output: texture_storage_2d<rgba8unorm, write>;\n${linearToSrgbDefine}\n@compute @workgroup_size(${JNLM_WORKGROUP_SIZE}, ${JNLM_WORKGROUP_SIZE}, 1)\nfn main(@builtin(global_invocation_id) id: vec3u) {\n if (any(id.xy >= params.size)) { return; }\n let c = color[id.y * params.size.x + id.x];\n var rgb = linearToSrgb(c.rgb);\n if (params.premultiply != 0u) { rgb *= c.a; }\n textureStore(output, id.xy, vec4f(rgb, c.a));\n}\n`;\n"]}
|
|
@@ -27,8 +27,8 @@ _padding: f32,
|
|
|
27
27
|
const LUMINANCE = vec3f(0.2126, 0.7152, 0.0722);
|
|
28
28
|
|
|
29
29
|
@compute @workgroup_size(64)
|
|
30
|
-
fn main(@builtin(global_invocation_id)
|
|
31
|
-
let tile =
|
|
30
|
+
fn main(@builtin(global_invocation_id) vQ: vec3u) {
|
|
31
|
+
let tile = vQ.x;
|
|
32
32
|
let tileCount = params.columns * params.rows;
|
|
33
33
|
if (tile >= tileCount) {
|
|
34
34
|
return;
|
|
@@ -36,18 +36,18 @@ return;
|
|
|
36
36
|
|
|
37
37
|
let tileX = tile % params.columns;
|
|
38
38
|
let tileY = tile / params.columns;
|
|
39
|
-
let
|
|
40
|
-
let
|
|
41
|
-
let
|
|
42
|
-
let
|
|
43
|
-
var
|
|
44
|
-
var
|
|
39
|
+
let vY = tileX * params.tileSize;
|
|
40
|
+
let vZ = tileY * params.tileSize;
|
|
41
|
+
let ye = min(vY + params.tileSize, params.width);
|
|
42
|
+
let yf = min(vZ + params.tileSize, params.height);
|
|
43
|
+
var nW = 0.0;
|
|
44
|
+
var jB = 0.0;
|
|
45
45
|
var count = 0u;
|
|
46
46
|
|
|
47
|
-
for (var y =
|
|
48
|
-
for (var x =
|
|
49
|
-
let
|
|
50
|
-
let offset =
|
|
47
|
+
for (var y = vZ; y < yf; y++) {
|
|
48
|
+
for (var x = vY; x < ye; x++) {
|
|
49
|
+
let pixel = y * params.width + x;
|
|
50
|
+
let offset = pixel * 4u;
|
|
51
51
|
let samples = pilotMoments[offset + 3u];
|
|
52
52
|
if (samples <= 0.0) {
|
|
53
53
|
continue;
|
|
@@ -60,28 +60,28 @@ pilotColor[offset + 2u]
|
|
|
60
60
|
),
|
|
61
61
|
LUMINANCE
|
|
62
62
|
) / samples;
|
|
63
|
-
let
|
|
64
|
-
let
|
|
65
|
-
var variance =
|
|
63
|
+
let va = pilotMoments[offset] / samples;
|
|
64
|
+
let qg = max(va - mean * mean, 0.0);
|
|
65
|
+
var variance = qg;
|
|
66
66
|
if (samples > 1.0) {
|
|
67
|
-
variance =
|
|
67
|
+
variance = qg * samples / (samples - 1.0);
|
|
68
68
|
}
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
nW += mean;
|
|
70
|
+
jB = max(jB, variance);
|
|
71
71
|
count += 1u;
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
|
|
75
|
-
let mean =
|
|
76
|
-
var
|
|
75
|
+
let mean = nW / f32(max(count, 1u));
|
|
76
|
+
var pT = 0.0;
|
|
77
77
|
if (params.hasPrevious != 0u) {
|
|
78
|
-
|
|
78
|
+
pT = previousVariance[tile];
|
|
79
79
|
}
|
|
80
|
-
let
|
|
81
|
-
let
|
|
80
|
+
let tu = max(jB, pT);
|
|
81
|
+
let uD = params.absoluteError + params.relativeError * abs(mean);
|
|
82
82
|
let required = ceil(
|
|
83
|
-
params.confidence * params.confidence *
|
|
84
|
-
max(
|
|
83
|
+
params.confidence * params.confidence * tu /
|
|
84
|
+
max(uD * uD, 1e-16)
|
|
85
85
|
);
|
|
86
86
|
let targetSamples = u32(min(
|
|
87
87
|
f32(params.maxSamples),
|
|
@@ -91,11 +91,11 @@ max(f32(params.minSamples), required)
|
|
|
91
91
|
tileMeans[tile] = mean;
|
|
92
92
|
|
|
93
93
|
|
|
94
|
-
tileVariances[tile] =
|
|
94
|
+
tileVariances[tile] = jB;
|
|
95
95
|
tileTargets[tile] = targetSamples;
|
|
96
96
|
|
|
97
|
-
for (var y =
|
|
98
|
-
for (var x =
|
|
97
|
+
for (var y = vZ; y < yf; y++) {
|
|
98
|
+
for (var x = vY; x < ye; x++) {
|
|
99
99
|
textureStore(
|
|
100
100
|
targetTexture,
|
|
101
101
|
vec2i(i32(x), i32(y)),
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const oidnAuxiliaryDefine = "\nfn oidnEncodeAlbedo(value: vec3f) -> vec3f {\n let linear = clamp(value, vec3f(0.0), vec3f(1.0));\n return select(1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055,\n 12.92 * linear, linear <= vec3f(0.0031308));\n}\nfn oidnDecodeAlbedo(value: vec3f) -> vec3f {\n let encoded = clamp(value, vec3f(0.0), vec3f(1.0));\n return select(pow((encoded + 0.055) / 1.055, vec3f(2.4)),\n encoded / 12.92, encoded <= vec3f(0.04045));\n}\nfn oidnSanitizeNormal(value: vec3f) -> vec3f {\n return clamp(value, vec3f(0.0), vec3f(1.0));\n}\n";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// OIDN's LDR auxiliary networks use sRGB albedo and normals in [0,1].
|
|
2
|
+
export const oidnAuxiliaryDefine = /* wgsl */ `
|
|
3
|
+
fn sT(value: vec3f) -> vec3f {
|
|
4
|
+
let linear = clamp(value, vec3f(0.0), vec3f(1.0));
|
|
5
|
+
return select(1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055,
|
|
6
|
+
12.92 * linear, linear <= vec3f(0.0031308));
|
|
7
|
+
}
|
|
8
|
+
fn sS(value: vec3f) -> vec3f {
|
|
9
|
+
let encoded = clamp(value, vec3f(0.0), vec3f(1.0));
|
|
10
|
+
return select(pow((encoded + 0.055) / 1.055, vec3f(2.4)),
|
|
11
|
+
encoded / 12.92, encoded <= vec3f(0.04045));
|
|
12
|
+
}
|
|
13
|
+
fn rL(value: vec3f) -> vec3f {
|
|
14
|
+
return clamp(value, vec3f(0.0), vec3f(1.0));
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
//# sourceMappingURL=oidnAuxiliary.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oidnAuxiliary.wgsl.js","sourceRoot":"","sources":["../../../src/renderer/wgsl/oidnAuxiliary.wgsl.ts"],"names":[],"mappings":"AAAA,sEAAsE;AACtE,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;;;;;;;;;;;;;;CAc7C,CAAC","sourcesContent":["// OIDN's LDR auxiliary networks use sRGB albedo and normals in [0,1].\nexport const oidnAuxiliaryDefine = /* wgsl */ `\nfn oidnEncodeAlbedo(value: vec3f) -> vec3f {\n let linear = clamp(value, vec3f(0.0), vec3f(1.0));\n return select(1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055,\n 12.92 * linear, linear <= vec3f(0.0031308));\n}\nfn oidnDecodeAlbedo(value: vec3f) -> vec3f {\n let encoded = clamp(value, vec3f(0.0), vec3f(1.0));\n return select(pow((encoded + 0.055) / 1.055, vec3f(2.4)),\n encoded / 12.92, encoded <= vec3f(0.04045));\n}\nfn oidnSanitizeNormal(value: vec3f) -> vec3f {\n return clamp(value, vec3f(0.0), vec3f(1.0));\n}\n`;\n"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const proceduralSkyWGSL: string;
|
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
import { TURBIDITY, GROUND_ALBEDO, ILLUMINANCE, REFERENCE_ILLUMINANCE } from '../skyModel.js';
|
|
2
|
+
// Same atmosphere, quadrature and pass order as WebGLSkyBaker. Distances in km.
|
|
3
|
+
export const proceduralSkyWGSL = /* wgsl */ `
|
|
4
|
+
struct Params { sun: vec4f, sunWorld: vec4f, size: vec4f, scale: vec4f, ambient: vec4f }
|
|
5
|
+
@group(0) @binding(0) var<uniform> params: Params;
|
|
6
|
+
@group(0) @binding(1) var transmittanceTable: texture_2d<f32>;
|
|
7
|
+
@group(0) @binding(2) var multipleTable: texture_2d<f32>;
|
|
8
|
+
@group(0) @binding(3) var skyTable: texture_2d<f32>;
|
|
9
|
+
@group(0) @binding(4) var irradianceTable: texture_2d<f32>;
|
|
10
|
+
@group(0) @binding(5) var output: texture_storage_2d<rgba32float, write>;
|
|
11
|
+
const PI = 3.14159265358979;
|
|
12
|
+
const R_GROUND = 6360.0;
|
|
13
|
+
const R_TOP = 6460.0;
|
|
14
|
+
const CAMERA_ALTITUDE = 0.2;
|
|
15
|
+
const RAYLEIGH = vec3f(5.802e-3, 13.558e-3, 33.1e-3);
|
|
16
|
+
const MIE_SCATTERING = 3.996e-3;
|
|
17
|
+
const MIE_EXTINCTION = 4.44e-3;
|
|
18
|
+
const MIE_G = 0.8;
|
|
19
|
+
const OZONE = vec3f(0.65e-3, 1.881e-3, 0.085e-3);
|
|
20
|
+
const ALBEDO = vec3f(${GROUND_ALBEDO.join(', ')});
|
|
21
|
+
const T_SIZE = vec2u(256, 64);
|
|
22
|
+
const MS_ALTITUDES = 32u;
|
|
23
|
+
const SV_SIZE = vec2u(96, 192);
|
|
24
|
+
|
|
25
|
+
fn br(r: f32, mu: f32, radius: f32) -> f32 { return (radius - r) * (radius + r) + r * r * mu * mu; }
|
|
26
|
+
fn np(r: f32, mu: f32) -> bool { return mu < 0.0 && br(r, mu, R_GROUND) >= 0.0; }
|
|
27
|
+
fn ll(r: f32, mu: f32) -> f32 { return max(-r * mu - sqrt(max(br(r, mu, R_GROUND), 0.0)), 0.0); }
|
|
28
|
+
fn jm(r: f32, mu: f32) -> f32 { return max(-r * mu + sqrt(max(br(r, mu, R_TOP), 0.0)), 0.0); }
|
|
29
|
+
fn oz(r: f32) -> vec3f {
|
|
30
|
+
let h = max(r - R_GROUND, 0.0);
|
|
31
|
+
return vec3f(exp(-h / 8.0), exp(-h / 1.2) * ${TURBIDITY}, max(0.0, 1.0 - abs(h - 25.0) / 15.0));
|
|
32
|
+
}
|
|
33
|
+
fn extinction(d: vec3f) -> vec3f { return RAYLEIGH * d.x + MIE_EXTINCTION * d.y + OZONE * d.z; }
|
|
34
|
+
fn mP(x: f32) -> f32 { return x * x * (R_TOP - R_GROUND); }
|
|
35
|
+
fn hR(h: f32) -> f32 { return sqrt(clamp(h / (R_TOP - R_GROUND), 0.0, 1.0)); }
|
|
36
|
+
fn fh(table: texture_2d<f32>, p: vec2f) -> vec3f {
|
|
37
|
+
let size = vec2i(textureDimensions(table));
|
|
38
|
+
let q = clamp(p, vec2f(0.0), vec2f(size - 1));
|
|
39
|
+
let i = min(vec2i(floor(q)), max(size - 2, vec2i(0)));
|
|
40
|
+
let f = clamp(q - vec2f(i), vec2f(0.0), vec2f(1.0));
|
|
41
|
+
let j = min(i + 1, size - 1);
|
|
42
|
+
let a = textureLoad(table, i, 0).rgb;
|
|
43
|
+
let b = textureLoad(table, vec2i(j.x, i.y), 0).rgb;
|
|
44
|
+
let c = textureLoad(table, vec2i(i.x, j.y), 0).rgb;
|
|
45
|
+
let d = textureLoad(table, j, 0).rgb;
|
|
46
|
+
return mix(mix(a, b, f.x), mix(c, d, f.x), f.y);
|
|
47
|
+
}
|
|
48
|
+
fn fO(r: f32, mu: f32) -> vec3f {
|
|
49
|
+
return fh(transmittanceTable, vec2f((clamp(mu, -1.0, 1.0) + 1.0) * 0.5 * f32(T_SIZE.x - 1u), hR(r - R_GROUND) * f32(T_SIZE.y - 1u)));
|
|
50
|
+
}
|
|
51
|
+
fn mW(nu: f32) -> f32 {
|
|
52
|
+
let g2 = MIE_G * MIE_G;
|
|
53
|
+
return 3.0 / (8.0 * PI) * ((1.0 - g2) * (1.0 + nu * nu)) / ((2.0 + g2) * pow(1.0 + g2 - 2.0 * MIE_G * nu, 1.5));
|
|
54
|
+
}
|
|
55
|
+
struct xJ { radiance: vec3f, throughput: vec3f }
|
|
56
|
+
fn vt(origin: vec3f, dir: vec3f, steps: u32, full: bool, uw: vec3f) -> xJ {
|
|
57
|
+
let r = length(origin);
|
|
58
|
+
let mu = dot(origin, dir) / r;
|
|
59
|
+
let ground = np(r, mu);
|
|
60
|
+
var len = jm(r, mu);
|
|
61
|
+
if (ground) { len = ll(r, mu); }
|
|
62
|
+
let nu = dot(dir, params.sun.xyz);
|
|
63
|
+
var jv = 1.0 / (4.0 * PI);
|
|
64
|
+
var sn = jv;
|
|
65
|
+
if (full) { jv = 3.0 / (16.0 * PI) * (1.0 + nu * nu); sn = mW(nu); }
|
|
66
|
+
var result = xJ(vec3f(0.0), vec3f(0.0));
|
|
67
|
+
var view = vec3f(1.0);
|
|
68
|
+
var previous = 0.0;
|
|
69
|
+
for (var i = 0u; i < steps; i++) {
|
|
70
|
+
let s = f32(i + 1u) / f32(steps);
|
|
71
|
+
let next = len * s * s;
|
|
72
|
+
let dt = next - previous;
|
|
73
|
+
let p = origin + dir * (0.5 * (previous + next));
|
|
74
|
+
previous = next;
|
|
75
|
+
let pr = length(p);
|
|
76
|
+
let d = oz(pr);
|
|
77
|
+
let e = extinction(d);
|
|
78
|
+
let vb = fO(pr, dot(p, params.sun.xyz) / pr);
|
|
79
|
+
let nG = RAYLEIGH * d.x;
|
|
80
|
+
let nF = MIE_SCATTERING * d.y;
|
|
81
|
+
var ms = vec3f(0.0);
|
|
82
|
+
if (full) { ms = fh(multipleTable, vec2f(hR(pr - R_GROUND) * f32(MS_ALTITUDES - 1u), 0.0)); }
|
|
83
|
+
let source = vb * (nG * jv + nF * sn) + (nG + nF) * ms;
|
|
84
|
+
let st = exp(-e * dt);
|
|
85
|
+
let weight = (1.0 - st) / max(e, vec3f(1e-9));
|
|
86
|
+
result.radiance += view * source * weight;
|
|
87
|
+
result.throughput += view * (nG + nF) * weight;
|
|
88
|
+
view *= st;
|
|
89
|
+
}
|
|
90
|
+
if (ground) {
|
|
91
|
+
let p = origin + dir * len;
|
|
92
|
+
let pr = length(p);
|
|
93
|
+
let tC = dot(p, params.sun.xyz) / pr;
|
|
94
|
+
let irradiance = fO(pr, tC) * max(tC, 0.0) + uw;
|
|
95
|
+
result.radiance += view * ALBEDO / PI * irradiance;
|
|
96
|
+
}
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
fn qk(row: f32) -> f32 {
|
|
100
|
+
let x = row / f32(SV_SIZE.y - 1u) * 2.0 - 1.0;
|
|
101
|
+
return sign(x) * x * x * (PI / 2.0);
|
|
102
|
+
}
|
|
103
|
+
fn ik(e: f32) -> f32 {
|
|
104
|
+
let x = sign(e) * sqrt(abs(e) / (PI / 2.0));
|
|
105
|
+
return clamp((x + 1.0) * 0.5, 0.0, 1.0) * f32(SV_SIZE.y - 1u);
|
|
106
|
+
}
|
|
107
|
+
@compute @workgroup_size(8, 8)
|
|
108
|
+
fn transmittance(@builtin(global_invocation_id) id: vec3u) {
|
|
109
|
+
if (any(id.xy >= T_SIZE)) { return; }
|
|
110
|
+
let mu = f32(id.x) / f32(T_SIZE.x - 1u) * 2.0 - 1.0;
|
|
111
|
+
let r = R_GROUND + mP(f32(id.y) / f32(T_SIZE.y - 1u));
|
|
112
|
+
if (np(r, mu)) { textureStore(output, vec2i(id.xy), vec4f(0.0, 0.0, 0.0, 1.0)); return; }
|
|
113
|
+
let len = jm(r, mu);
|
|
114
|
+
var depth = vec3f(0.0);
|
|
115
|
+
for (var i = 0u; i < 48u; i++) {
|
|
116
|
+
let t = (f32(i) + 0.5) / 48.0 * len;
|
|
117
|
+
depth += extinction(oz(sqrt(t * t + 2.0 * r * mu * t + r * r))) * (len / 48.0);
|
|
118
|
+
}
|
|
119
|
+
textureStore(output, vec2i(id.xy), vec4f(exp(-depth), 1.0));
|
|
120
|
+
}
|
|
121
|
+
@compute @workgroup_size(8, 8)
|
|
122
|
+
fn multiple(@builtin(global_invocation_id) id: vec3u) {
|
|
123
|
+
if (id.x >= MS_ALTITUDES || id.y > 0u) { return; }
|
|
124
|
+
let r = R_GROUND + mP(f32(id.x) / f32(MS_ALTITUDES - 1u));
|
|
125
|
+
var second = vec3f(0.0);
|
|
126
|
+
var qK = vec3f(0.0);
|
|
127
|
+
for (var i = 0u; i < 64u; i++) {
|
|
128
|
+
let mu = 1.0 - 2.0 * (f32(i) + 0.5) / 64.0;
|
|
129
|
+
let phi = f32(i) * PI * (3.0 - sqrt(5.0));
|
|
130
|
+
let s = sqrt(1.0 - mu * mu);
|
|
131
|
+
let result = vt(vec3f(0.0, r, 0.0), vec3f(s * cos(phi), mu, s * sin(phi)), 20u, false, vec3f(0.0));
|
|
132
|
+
second += result.radiance / 64.0;
|
|
133
|
+
qK += result.throughput / 64.0;
|
|
134
|
+
}
|
|
135
|
+
textureStore(output, vec2i(id.xy), vec4f(second / (1.0 - qK), 1.0));
|
|
136
|
+
}
|
|
137
|
+
@compute @workgroup_size(8, 8)
|
|
138
|
+
fn skyView(@builtin(global_invocation_id) id: vec3u) {
|
|
139
|
+
if (any(id.xy >= SV_SIZE)) { return; }
|
|
140
|
+
let e = qk(f32(id.y));
|
|
141
|
+
let phi = f32(id.x) / f32(SV_SIZE.x - 1u) * PI;
|
|
142
|
+
var sky = vec3f(0.0);
|
|
143
|
+
if (params.size.w > 0.0) { sky = textureLoad(irradianceTable, vec2i(0), 0).rgb; }
|
|
144
|
+
let result = vt(vec3f(0.0, R_GROUND + CAMERA_ALTITUDE, 0.0), vec3f(cos(e) * cos(phi), sin(e), cos(e) * sin(phi)), 40u, true, sky);
|
|
145
|
+
textureStore(output, vec2i(id.xy), vec4f(result.radiance, 1.0));
|
|
146
|
+
}
|
|
147
|
+
@compute @workgroup_size(8, 8)
|
|
148
|
+
fn irradiance(@builtin(global_invocation_id) id: vec3u) {
|
|
149
|
+
if (id.x >= 2u || id.y > 0u) { return; }
|
|
150
|
+
var sky = vec3f(0.0);
|
|
151
|
+
for (var i = 0u; i < 128u; i++) {
|
|
152
|
+
let e = (f32(i) + 0.5) / 128.0 * (PI / 2.0);
|
|
153
|
+
let weight = 2.0 * sin(e) * cos(e) * (PI / 2.0 / 128.0) * (PI / 48.0);
|
|
154
|
+
for (var j = 0u; j < 48u; j++) {
|
|
155
|
+
let phi = (f32(j) + 0.5) / 48.0 * PI;
|
|
156
|
+
sky += fh(skyTable, vec2f(phi / PI * f32(SV_SIZE.x - 1u), ik(e))) * weight;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
if (id.x == 0u) { textureStore(output, vec2i(id.xy), vec4f(sky, 1.0)); return; }
|
|
160
|
+
let vb = fO(R_GROUND + CAMERA_ALTITUDE, params.sun.y);
|
|
161
|
+
let xc = vec3f(0.2126, 0.7152, 0.0722);
|
|
162
|
+
let horizontal = dot(sky, xc) + dot(vb, xc) * max(params.sun.y, 0.0);
|
|
163
|
+
let scale = ${ILLUMINANCE} / sqrt(max(horizontal, ${REFERENCE_ILLUMINANCE} * 1e-3) * ${REFERENCE_ILLUMINANCE});
|
|
164
|
+
textureStore(output, vec2i(id.xy), vec4f(vb, scale));
|
|
165
|
+
}
|
|
166
|
+
fn hn(dk: vec2f) -> vec3f {
|
|
167
|
+
let theta = dk.y / params.size.y * PI;
|
|
168
|
+
let phi = dk.x / params.size.x * 2.0 * PI;
|
|
169
|
+
return vec3f(-sin(theta) * cos(phi), cos(theta), -sin(theta) * sin(phi));
|
|
170
|
+
}
|
|
171
|
+
@compute @workgroup_size(8, 8)
|
|
172
|
+
fn map(@builtin(global_invocation_id) id: vec3u) {
|
|
173
|
+
if (any(id.xy >= vec2u(params.size.xy))) { return; }
|
|
174
|
+
let dk = vec2f(id.xy) + 0.5;
|
|
175
|
+
let dir = hn(dk);
|
|
176
|
+
let th = abs(atan2(dir.z, dir.x) - params.sun.w);
|
|
177
|
+
let wr = th - floor(th / (2.0 * PI)) * (2.0 * PI);
|
|
178
|
+
let ek = min(wr, 2.0 * PI - wr);
|
|
179
|
+
let e = asin(clamp(dir.y, -1.0, 1.0));
|
|
180
|
+
var radiance = fh(skyTable, vec2f(ek / PI * f32(SV_SIZE.x - 1u), ik(e)));
|
|
181
|
+
let sun = textureLoad(irradianceTable, vec2i(1, 0), 0);
|
|
182
|
+
let radius = params.sunWorld.w;
|
|
183
|
+
let rP = PI / params.size.y;
|
|
184
|
+
if (acos(clamp(dot(dir, params.sunWorld.xyz), -1.0, 1.0)) < radius + 3.0 * rP / max(sqrt(1.0 - dir.y * dir.y), 0.05)) {
|
|
185
|
+
var coverage = 0.0;
|
|
186
|
+
for (var y = 0u; y < 6u; y++) { for (var x = 0u; x < 6u; x++) {
|
|
187
|
+
let d = hn(dk - 0.5 + (vec2f(f32(x), f32(y)) + 0.5) / 6.0);
|
|
188
|
+
let angle = 2.0 * asin(min(length(d - params.sunWorld.xyz) * 0.5, 1.0));
|
|
189
|
+
let t = angle / radius;
|
|
190
|
+
if (t < 1.0) { coverage += 1.0 - 0.6 * (1.0 - sqrt(1.0 - t * t)); }
|
|
191
|
+
} }
|
|
192
|
+
let rO = 2.0 * PI * (1.0 - cos(radius));
|
|
193
|
+
radiance += coverage / 36.0 / (rO * (1.0 - 0.6 / 3.0)) * sun.rgb;
|
|
194
|
+
}
|
|
195
|
+
textureStore(output, vec2i(id.xy), vec4f(radiance * sun.a * params.scale.xyz + params.ambient.xyz, 1.0));
|
|
196
|
+
}
|
|
197
|
+
`;
|
|
198
|
+
//# sourceMappingURL=proceduralSky.compute.js.map
|