@meimu/mutracer 0.0.0-stage → 0.1.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/LICENSE +21 -0
- package/LICENSES/Apache-2.0.txt +202 -0
- package/LICENSES/GLSL-PathTracer-MIT.txt +21 -0
- package/LICENSES/GlMatrix-MIT.txt +19 -0
- package/LICENSES/KinoBloom-MIT.txt +21 -0
- package/LICENSES/OIDNWeb-MIT.txt +21 -0
- package/LICENSES/Octicons-MIT.txt +21 -0
- package/LICENSES/RayTracingRenderer-MIT.txt +21 -0
- package/LICENSES/TinyBVH-MIT.txt +21 -0
- package/LICENSES/WebGPUUtils-MIT.txt +21 -0
- package/LICENSES/ZetaRay-MIT.txt +21 -0
- package/README.md +195 -2
- package/THIRD_PARTY_NOTICES.md +160 -0
- package/dist/assets/bvh.worker.js +1 -0
- package/dist/mutracer.umd.js +14352 -0
- package/docs/api.md +394 -0
- package/docs/bvh.md +141 -0
- package/docs/denoising.md +301 -0
- package/docs/getting-started.md +308 -0
- package/docs/materials.md +281 -0
- package/docs/performance.md +85 -0
- package/docs/post-processing.md +87 -0
- package/docs/progressive-rendering.md +144 -0
- package/docs/sampling.md +40 -0
- package/docs/threejs.md +273 -0
- package/docs/todo.md +61 -0
- package/docs/updates.md +208 -0
- package/lib/Display.d.ts +72 -0
- package/lib/Display.js +121 -0
- package/lib/Display.js.map +1 -0
- package/lib/Engine.d.ts +161 -0
- package/lib/Engine.js +681 -0
- package/lib/Engine.js.map +1 -0
- package/lib/Render.d.ts +256 -0
- package/lib/Render.js +671 -0
- package/lib/Render.js.map +1 -0
- package/lib/RenderLoop.d.ts +76 -0
- package/lib/RenderLoop.js +204 -0
- package/lib/RenderLoop.js.map +1 -0
- package/lib/Sync.d.ts +19 -0
- package/lib/Sync.js +19 -0
- package/lib/Sync.js.map +1 -0
- package/lib/constants.d.ts +2 -0
- package/lib/constants.js +3 -0
- package/lib/constants.js.map +1 -0
- package/lib/main.d.ts +56 -0
- package/lib/main.js +43 -0
- package/lib/main.js.map +1 -0
- package/lib/math.d.ts +23 -0
- package/lib/math.js +56 -0
- package/lib/math.js.map +1 -0
- package/lib/oidn.d.ts +45 -0
- package/lib/oidn.js +42 -0
- package/lib/oidn.js.map +1 -0
- package/lib/oidnBundledWeights.cdn.d.ts +2 -0
- package/lib/oidnBundledWeights.cdn.js +5 -0
- package/lib/oidnBundledWeights.cdn.js.map +1 -0
- package/lib/oidnBundledWeights.d.ts +2 -0
- package/lib/oidnBundledWeights.js +4 -0
- package/lib/oidnBundledWeights.js.map +1 -0
- package/lib/renderer/DisplayPostProcess.d.ts +14 -0
- package/lib/renderer/DisplayPostProcess.js +41 -0
- package/lib/renderer/DisplayPostProcess.js.map +1 -0
- package/lib/renderer/MaterialTable.d.ts +119 -0
- package/lib/renderer/MaterialTable.js +550 -0
- package/lib/renderer/MaterialTable.js.map +1 -0
- package/lib/renderer/OfflineAdaptiveSampling.d.ts +47 -0
- package/lib/renderer/OfflineAdaptiveSampling.js +36 -0
- package/lib/renderer/OfflineAdaptiveSampling.js.map +1 -0
- package/lib/renderer/RenderingPipeline.d.ts +232 -0
- package/lib/renderer/RenderingPipeline.js +18 -0
- package/lib/renderer/RenderingPipeline.js.map +1 -0
- package/lib/renderer/ScratchPool.d.ts +13 -0
- package/lib/renderer/ScratchPool.js +21 -0
- package/lib/renderer/ScratchPool.js.map +1 -0
- package/lib/renderer/TileRender.d.ts +44 -0
- package/lib/renderer/TileRender.js +283 -0
- package/lib/renderer/TileRender.js.map +1 -0
- package/lib/renderer/WGPUBloomPass.d.ts +17 -0
- package/lib/renderer/WGPUBloomPass.js +243 -0
- package/lib/renderer/WGPUBloomPass.js.map +1 -0
- package/lib/renderer/WGPUCanvasSurface.d.ts +21 -0
- package/lib/renderer/WGPUCanvasSurface.js +48 -0
- package/lib/renderer/WGPUCanvasSurface.js.map +1 -0
- package/lib/renderer/WGPUComputePass.d.ts +73 -0
- package/lib/renderer/WGPUComputePass.js +317 -0
- package/lib/renderer/WGPUComputePass.js.map +1 -0
- package/lib/renderer/WGPUFullQuadPass.d.ts +73 -0
- package/lib/renderer/WGPUFullQuadPass.js +389 -0
- package/lib/renderer/WGPUFullQuadPass.js.map +1 -0
- package/lib/renderer/WGPUHDRPeakMeter.d.ts +19 -0
- package/lib/renderer/WGPUHDRPeakMeter.js +112 -0
- package/lib/renderer/WGPUHDRPeakMeter.js.map +1 -0
- package/lib/renderer/WGPUJNLMDenoiser.d.ts +61 -0
- package/lib/renderer/WGPUJNLMDenoiser.js +412 -0
- package/lib/renderer/WGPUJNLMDenoiser.js.map +1 -0
- package/lib/renderer/WGPURayTraceOutput.d.ts +44 -0
- package/lib/renderer/WGPURayTraceOutput.js +368 -0
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -0
- package/lib/renderer/WGPURayTracePass.d.ts +284 -0
- package/lib/renderer/WGPURayTracePass.js +2323 -0
- package/lib/renderer/WGPURayTracePass.js.map +1 -0
- package/lib/renderer/WGPURenderingPipeline.d.ts +9 -0
- package/lib/renderer/WGPURenderingPipeline.js +1446 -0
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -0
- package/lib/renderer/WGPUSceneFeatures.d.ts +3 -0
- package/lib/renderer/WGPUSceneFeatures.js +20 -0
- package/lib/renderer/WGPUSceneFeatures.js.map +1 -0
- package/lib/renderer/WGPUScratchBuffer.d.ts +9 -0
- package/lib/renderer/WGPUScratchBuffer.js +21 -0
- package/lib/renderer/WGPUScratchBuffer.js.map +1 -0
- package/lib/renderer/WGPUScratchTexture.d.ts +10 -0
- package/lib/renderer/WGPUScratchTexture.js +27 -0
- package/lib/renderer/WGPUScratchTexture.js.map +1 -0
- package/lib/renderer/WGPUShaderCache.d.ts +26 -0
- package/lib/renderer/WGPUShaderCache.js +103 -0
- package/lib/renderer/WGPUShaderCache.js.map +1 -0
- package/lib/renderer/WebGLBloomPass.d.ts +18 -0
- package/lib/renderer/WebGLBloomPass.js +113 -0
- package/lib/renderer/WebGLBloomPass.js.map +1 -0
- package/lib/renderer/WebGLFullQuadPass.d.ts +65 -0
- package/lib/renderer/WebGLFullQuadPass.js +208 -0
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -0
- package/lib/renderer/WebGLJNLMDenoiser.d.ts +32 -0
- package/lib/renderer/WebGLJNLMDenoiser.js +328 -0
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -0
- package/lib/renderer/WebGLRayTraceOutputPass.d.ts +20 -0
- package/lib/renderer/WebGLRayTraceOutputPass.js +106 -0
- package/lib/renderer/WebGLRayTraceOutputPass.js.map +1 -0
- package/lib/renderer/WebGLRayTracePass.d.ts +142 -0
- package/lib/renderer/WebGLRayTracePass.js +845 -0
- package/lib/renderer/WebGLRayTracePass.js.map +1 -0
- package/lib/renderer/WebGLReadback.d.ts +4 -0
- package/lib/renderer/WebGLReadback.js +75 -0
- package/lib/renderer/WebGLReadback.js.map +1 -0
- package/lib/renderer/WebGLRenderingPipeline.d.ts +4 -0
- package/lib/renderer/WebGLRenderingPipeline.js +510 -0
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -0
- package/lib/renderer/WebGLScratchCopy.d.ts +10 -0
- package/lib/renderer/WebGLScratchCopy.js +27 -0
- package/lib/renderer/WebGLScratchCopy.js.map +1 -0
- package/lib/renderer/accumulationTarget.d.ts +26 -0
- package/lib/renderer/accumulationTarget.js +2 -0
- package/lib/renderer/accumulationTarget.js.map +1 -0
- package/lib/renderer/binnedSahBvh.d.ts +31 -0
- package/lib/renderer/binnedSahBvh.js +263 -0
- package/lib/renderer/binnedSahBvh.js.map +1 -0
- package/lib/renderer/bvh.worker.d.ts +1 -0
- package/lib/renderer/bvh.worker.js +16 -0
- package/lib/renderer/bvh.worker.js.map +1 -0
- package/lib/renderer/bvhAccel.d.ts +81 -0
- package/lib/renderer/bvhAccel.js +621 -0
- package/lib/renderer/bvhAccel.js.map +1 -0
- package/lib/renderer/bvhWorkerBuild.d.ts +12 -0
- package/lib/renderer/bvhWorkerBuild.js +17 -0
- package/lib/renderer/bvhWorkerBuild.js.map +1 -0
- package/lib/renderer/bvhWorkerClient.d.ts +57 -0
- package/lib/renderer/bvhWorkerClient.js +166 -0
- package/lib/renderer/bvhWorkerClient.js.map +1 -0
- package/lib/renderer/cameraLens.d.ts +5 -0
- package/lib/renderer/cameraLens.js +15 -0
- package/lib/renderer/cameraLens.js.map +1 -0
- package/lib/renderer/cameraSnapshot.d.ts +3 -0
- package/lib/renderer/cameraSnapshot.js +7 -0
- package/lib/renderer/cameraSnapshot.js.map +1 -0
- package/lib/renderer/committedScene.d.ts +13 -0
- package/lib/renderer/committedScene.js +121 -0
- package/lib/renderer/committedScene.js.map +1 -0
- package/lib/renderer/dataTextureUtil.d.ts +32 -0
- package/lib/renderer/dataTextureUtil.js +46 -0
- package/lib/renderer/dataTextureUtil.js.map +1 -0
- package/lib/renderer/denoiser.d.ts +65 -0
- package/lib/renderer/denoiser.js +2 -0
- package/lib/renderer/denoiser.js.map +1 -0
- package/lib/renderer/depthQuery.d.ts +14 -0
- package/lib/renderer/depthQuery.js +14 -0
- package/lib/renderer/depthQuery.js.map +1 -0
- package/lib/renderer/deviceRequirements.d.ts +23 -0
- package/lib/renderer/deviceRequirements.js +50 -0
- package/lib/renderer/deviceRequirements.js.map +1 -0
- package/lib/renderer/envMapCreation.d.ts +10 -0
- package/lib/renderer/envMapCreation.js +96 -0
- package/lib/renderer/envMapCreation.js.map +1 -0
- package/lib/renderer/envMapDistribution.d.ts +9 -0
- package/lib/renderer/envMapDistribution.js +107 -0
- package/lib/renderer/envMapDistribution.js.map +1 -0
- package/lib/renderer/float16.d.ts +1 -0
- package/lib/renderer/float16.js +19 -0
- package/lib/renderer/float16.js.map +1 -0
- package/lib/renderer/geometryBvh.d.ts +11 -0
- package/lib/renderer/geometryBvh.js +24 -0
- package/lib/renderer/geometryBvh.js.map +1 -0
- package/lib/renderer/geometryUpdates.d.ts +28 -0
- package/lib/renderer/geometryUpdates.js +131 -0
- package/lib/renderer/geometryUpdates.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +37 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/common.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/common.glsl.js +17 -0
- package/lib/renderer/glsl/chunks/common.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js +192 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/intersect.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/intersect.glsl.js +1091 -0
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +371 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +1767 -0
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/rand.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/rand.glsl.js +26 -0
- package/lib/renderer/glsl/chunks/rand.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/random.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/random.glsl.js +27 -0
- package/lib/renderer/glsl/chunks/random.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +287 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sampleLight.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +254 -0
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +279 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +48 -0
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sampling.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sampling.glsl.js +194 -0
- package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/sobol.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/sobol.glsl.js +170 -0
- package/lib/renderer/glsl/chunks/sobol.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +27 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/uvProjection.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +72 -0
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js.map +1 -0
- package/lib/renderer/glsl/depthQuery.frag.d.ts +3 -0
- package/lib/renderer/glsl/depthQuery.frag.js +55 -0
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -0
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.d.ts +6 -0
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +46 -0
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js.map +1 -0
- package/lib/renderer/glsl/rayTrace.frag.d.ts +2 -0
- package/lib/renderer/glsl/rayTrace.frag.js +619 -0
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -0
- package/lib/renderer/glsl/shadowCatcher.frag.d.ts +3 -0
- package/lib/renderer/glsl/shadowCatcher.frag.js +119 -0
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -0
- package/lib/renderer/glsl/webglPipeline.frag.d.ts +4 -0
- package/lib/renderer/glsl/webglPipeline.frag.js +208 -0
- package/lib/renderer/glsl/webglPipeline.frag.js.map +1 -0
- package/lib/renderer/gpuMemory.d.ts +2 -0
- package/lib/renderer/gpuMemory.js +10 -0
- package/lib/renderer/gpuMemory.js.map +1 -0
- package/lib/renderer/halton.d.ts +1 -0
- package/lib/renderer/halton.js +15 -0
- package/lib/renderer/halton.js.map +1 -0
- package/lib/renderer/jnlm.d.ts +85 -0
- package/lib/renderer/jnlm.js +87 -0
- package/lib/renderer/jnlm.js.map +1 -0
- package/lib/renderer/lightSampling.d.ts +75 -0
- package/lib/renderer/lightSampling.js +305 -0
- package/lib/renderer/lightSampling.js.map +1 -0
- package/lib/renderer/lightsUtil.d.ts +26 -0
- package/lib/renderer/lightsUtil.js +154 -0
- package/lib/renderer/lightsUtil.js.map +1 -0
- package/lib/renderer/materialChanges.d.ts +13 -0
- package/lib/renderer/materialChanges.js +59 -0
- package/lib/renderer/materialChanges.js.map +1 -0
- package/lib/renderer/materialComparison.generated.d.ts +5 -0
- package/lib/renderer/materialComparison.generated.js +655 -0
- package/lib/renderer/materialComparison.generated.js.map +1 -0
- package/lib/renderer/materialConstants.d.ts +6 -0
- package/lib/renderer/materialConstants.js +3 -0
- package/lib/renderer/materialConstants.js.map +1 -0
- package/lib/renderer/materialEmission.d.ts +9 -0
- package/lib/renderer/materialEmission.js +21 -0
- package/lib/renderer/materialEmission.js.map +1 -0
- package/lib/renderer/materialIndices.d.ts +7 -0
- package/lib/renderer/materialIndices.js +34 -0
- package/lib/renderer/materialIndices.js.map +1 -0
- package/lib/renderer/materialLayout.d.ts +102 -0
- package/lib/renderer/materialLayout.js +189 -0
- package/lib/renderer/materialLayout.js.map +1 -0
- package/lib/renderer/materialTextureSlots.d.ts +537 -0
- package/lib/renderer/materialTextureSlots.js +219 -0
- package/lib/renderer/materialTextureSlots.js.map +1 -0
- package/lib/renderer/mergeMeshesToGeometry.d.ts +8 -0
- package/lib/renderer/mergeMeshesToGeometry.js +236 -0
- package/lib/renderer/mergeMeshesToGeometry.js.map +1 -0
- package/lib/renderer/meshInstances.d.ts +23 -0
- package/lib/renderer/meshInstances.js +66 -0
- package/lib/renderer/meshInstances.js.map +1 -0
- package/lib/renderer/meshMembership.d.ts +10 -0
- package/lib/renderer/meshMembership.js +72 -0
- package/lib/renderer/meshMembership.js.map +1 -0
- package/lib/renderer/oidnNetwork.d.ts +20 -0
- package/lib/renderer/oidnNetwork.js +123 -0
- package/lib/renderer/oidnNetwork.js.map +1 -0
- package/lib/renderer/openPbrEnergyLut.d.ts +32 -0
- package/lib/renderer/openPbrEnergyLut.js +965 -0
- package/lib/renderer/openPbrEnergyLut.js.map +1 -0
- package/lib/renderer/pathLimits.d.ts +4 -0
- package/lib/renderer/pathLimits.js +7 -0
- package/lib/renderer/pathLimits.js.map +1 -0
- package/lib/renderer/prepareMeshBVH.d.ts +110 -0
- package/lib/renderer/prepareMeshBVH.js +857 -0
- package/lib/renderer/prepareMeshBVH.js.map +1 -0
- package/lib/renderer/progressiveScheduler.d.ts +11 -0
- package/lib/renderer/progressiveScheduler.js +19 -0
- package/lib/renderer/progressiveScheduler.js.map +1 -0
- package/lib/renderer/renderPipeline.d.ts +57 -0
- package/lib/renderer/renderPipeline.js +49 -0
- package/lib/renderer/renderPipeline.js.map +1 -0
- package/lib/renderer/sampling.d.ts +10 -0
- package/lib/renderer/sampling.js +28 -0
- package/lib/renderer/sampling.js.map +1 -0
- package/lib/renderer/sceneChangeDetector.d.ts +29 -0
- package/lib/renderer/sceneChangeDetector.js +232 -0
- package/lib/renderer/sceneChangeDetector.js.map +1 -0
- package/lib/renderer/sceneLightChanges.d.ts +14 -0
- package/lib/renderer/sceneLightChanges.js +34 -0
- package/lib/renderer/sceneLightChanges.js.map +1 -0
- package/lib/renderer/scratchSampling.d.ts +3 -0
- package/lib/renderer/scratchSampling.js +39 -0
- package/lib/renderer/scratchSampling.js.map +1 -0
- package/lib/renderer/shader.d.ts +37 -0
- package/lib/renderer/shader.js +41 -0
- package/lib/renderer/shader.js.map +1 -0
- package/lib/renderer/staticBvhPreparation.d.ts +24 -0
- package/lib/renderer/staticBvhPreparation.js +116 -0
- package/lib/renderer/staticBvhPreparation.js.map +1 -0
- package/lib/renderer/textureRegion.d.ts +8 -0
- package/lib/renderer/textureRegion.js +9 -0
- package/lib/renderer/textureRegion.js.map +1 -0
- package/lib/renderer/texturesFromMaterials.d.ts +6 -0
- package/lib/renderer/texturesFromMaterials.js +37 -0
- package/lib/renderer/texturesFromMaterials.js.map +1 -0
- package/lib/renderer/util.d.ts +17 -0
- package/lib/renderer/util.js +56 -0
- package/lib/renderer/util.js.map +1 -0
- package/lib/renderer/webgl.d.ts +131 -0
- package/lib/renderer/webgl.js +586 -0
- package/lib/renderer/webgl.js.map +1 -0
- package/lib/renderer/webglShaders.d.ts +4 -0
- package/lib/renderer/webglShaders.js +41 -0
- package/lib/renderer/webglShaders.js.map +1 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js +23 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +128 -0
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -0
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +1441 -0
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +8 -0
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +85 -0
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +7 -0
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +315 -0
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.d.ts +3 -0
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +1737 -0
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +352 -0
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/rand.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +25 -0
- package/lib/renderer/wgsl/chunks/rand.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/random.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/chunks/random.wgsl.js +2 -0
- package/lib/renderer/wgsl/chunks/random.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +5 -0
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +328 -0
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +400 -0
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +3 -0
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +439 -0
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +40 -0
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +198 -0
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +8 -0
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +16 -0
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/sobol.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +170 -0
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +42 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +5 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js +218 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/customDenoise.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/customDenoise.wgsl.js +28 -0
- package/lib/renderer/wgsl/customDenoise.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +3 -0
- package/lib/renderer/wgsl/depthQuery.wgsl.js +34 -0
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/offlineAdaptive.compute.d.ts +2 -0
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +108 -0
- package/lib/renderer/wgsl/offlineAdaptive.compute.js.map +1 -0
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +16 -0
- package/lib/renderer/wgsl/rayTrace.compute.js +923 -0
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -0
- package/lib/scene/AmbientLight.d.ts +17 -0
- package/lib/scene/AmbientLight.js +15 -0
- package/lib/scene/AmbientLight.js.map +1 -0
- package/lib/scene/Camera.d.ts +78 -0
- package/lib/scene/Camera.js +111 -0
- package/lib/scene/Camera.js.map +1 -0
- package/lib/scene/DirectionalLight.d.ts +18 -0
- package/lib/scene/DirectionalLight.js +17 -0
- package/lib/scene/DirectionalLight.js.map +1 -0
- package/lib/scene/EnvironmentLight.d.ts +14 -0
- package/lib/scene/EnvironmentLight.js +14 -0
- package/lib/scene/EnvironmentLight.js.map +1 -0
- package/lib/scene/Geometry.d.ts +87 -0
- package/lib/scene/Geometry.js +108 -0
- package/lib/scene/Geometry.js.map +1 -0
- package/lib/scene/IESProfile.d.ts +19 -0
- package/lib/scene/IESProfile.js +165 -0
- package/lib/scene/IESProfile.js.map +1 -0
- package/lib/scene/InstancedMesh.d.ts +43 -0
- package/lib/scene/InstancedMesh.js +79 -0
- package/lib/scene/InstancedMesh.js.map +1 -0
- package/lib/scene/Mesh.d.ts +14 -0
- package/lib/scene/Mesh.js +17 -0
- package/lib/scene/Mesh.js.map +1 -0
- package/lib/scene/OpenPBRMaterial.d.ts +224 -0
- package/lib/scene/OpenPBRMaterial.js +240 -0
- package/lib/scene/OpenPBRMaterial.js.map +1 -0
- package/lib/scene/RectLight.d.ts +31 -0
- package/lib/scene/RectLight.js +26 -0
- package/lib/scene/RectLight.js.map +1 -0
- package/lib/scene/Scene.d.ts +55 -0
- package/lib/scene/Scene.js +2 -0
- package/lib/scene/Scene.js.map +1 -0
- package/lib/scene/SceneNode.d.ts +16 -0
- package/lib/scene/SceneNode.js +33 -0
- package/lib/scene/SceneNode.js.map +1 -0
- package/lib/scene/SphereLight.d.ts +22 -0
- package/lib/scene/SphereLight.js +20 -0
- package/lib/scene/SphereLight.js.map +1 -0
- package/lib/scene/SpotLight.d.ts +35 -0
- package/lib/scene/SpotLight.js +29 -0
- package/lib/scene/SpotLight.js.map +1 -0
- package/lib/scene/Texture.d.ts +38 -0
- package/lib/scene/Texture.js +37 -0
- package/lib/scene/Texture.js.map +1 -0
- package/lib/scene/anisotropyParameters.d.ts +1 -0
- package/lib/scene/anisotropyParameters.js +13 -0
- package/lib/scene/anisotropyParameters.js.map +1 -0
- package/lib/scene/geometryChanges.d.ts +5 -0
- package/lib/scene/geometryChanges.js +18 -0
- package/lib/scene/geometryChanges.js.map +1 -0
- package/lib/scene/materialTextureNames.d.ts +2 -0
- package/lib/scene/materialTextureNames.js +9 -0
- package/lib/scene/materialTextureNames.js.map +1 -0
- package/lib/scene/openPbrSchema.d.ts +400 -0
- package/lib/scene/openPbrSchema.js +149 -0
- package/lib/scene/openPbrSchema.js.map +1 -0
- package/lib/scene/thinFilmParameters.d.ts +4 -0
- package/lib/scene/thinFilmParameters.js +12 -0
- package/lib/scene/thinFilmParameters.js.map +1 -0
- package/lib/settings/display.d.ts +118 -0
- package/lib/settings/display.js +34 -0
- package/lib/settings/display.js.map +1 -0
- package/lib/settings/engine.d.ts +37 -0
- package/lib/settings/engine.js +26 -0
- package/lib/settings/engine.js.map +1 -0
- package/lib/settings/render.d.ts +178 -0
- package/lib/settings/render.js +36 -0
- package/lib/settings/render.js.map +1 -0
- package/lib/tinybvh/LICENSE +21 -0
- package/lib/tinybvh/TinyBvhBuilder.d.ts +17 -0
- package/lib/tinybvh/TinyBvhBuilder.js +211 -0
- package/lib/tinybvh/TinyBvhBuilder.js.map +1 -0
- package/lib/tinybvh/tinybvh.wasm +0 -0
- package/lib/types.d.ts +13 -0
- package/lib/types.js +2 -0
- package/lib/types.js.map +1 -0
- package/lib/util/canvas.d.ts +2 -0
- package/lib/util/canvas.js +13 -0
- package/lib/util/canvas.js.map +1 -0
- package/lib/util/commonGeometry.d.ts +15 -0
- package/lib/util/commonGeometry.js +240 -0
- package/lib/util/commonGeometry.js.map +1 -0
- package/lib/util/events.d.ts +7 -0
- package/lib/util/events.js +23 -0
- package/lib/util/events.js.map +1 -0
- package/lib/util/frame.d.ts +2 -0
- package/lib/util/frame.js +10 -0
- package/lib/util/frame.js.map +1 -0
- package/lib/util/fromTHREE.d.ts +100 -0
- package/lib/util/fromTHREE.js +1063 -0
- package/lib/util/fromTHREE.js.map +1 -0
- package/lib/util/geometry.d.ts +13 -0
- package/lib/util/geometry.js +292 -0
- package/lib/util/geometry.js.map +1 -0
- package/lib/util/loadRGBE.d.ts +7 -0
- package/lib/util/loadRGBE.js +168 -0
- package/lib/util/loadRGBE.js.map +1 -0
- package/lib/util/math.d.ts +8 -0
- package/lib/util/math.js +64 -0
- package/lib/util/math.js.map +1 -0
- package/lib/util/mesh.d.ts +7 -0
- package/lib/util/mesh.js +20 -0
- package/lib/util/mesh.js.map +1 -0
- package/lib/util/threeDeformation.d.ts +20 -0
- package/lib/util/threeDeformation.js +218 -0
- package/lib/util/threeDeformation.js.map +1 -0
- package/lib/version.d.ts +2 -0
- package/lib/version.js +3 -0
- package/lib/version.js.map +1 -0
- package/llms.txt +62 -0
- package/oidn/weights/LICENSE.txt +202 -0
- package/oidn/weights/README.md +43 -0
- package/oidn/weights/rt_hdr_alb_nrm.tza +0 -0
- package/oidn/weights/rt_hdr_alb_nrm_small.tza +0 -0
- package/package.json +124 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intersect.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/intersect.wgsl.ts"],"names":[],"mappings":"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","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\nimport { uvProjectionConstants } from '../../MaterialTable.js';\nimport { INSTANCE_VEC4_STRIDE } from '../../bvhAccel.js';\nimport pdm_displacementWgsl from './pdm_displacement.wgsl.js';\nimport { createIntersectionAlphaWgsl } from './intersectionAlpha.wgsl.js';\n\nconst displacementWgsl = pdm_displacementWgsl;\n\nconst flatIntersectCode = function () {\n return /* wgsl */ `\nlet hit = intersectTriangle(o, d, tri, maxDim, shear, tMax);\nif (hit.t > 0.0) {\n let e1 = tri.p1 - tri.p0;\n let e2 = tri.p2 - tri.p0;\n hitNormal = normalize(cross(e1, e2));\n let sideMaterialIndex = i32(unpackMaterialIndex(bitcast<i32>(insData.z)).x);\n let materialDoubleSided = materialsBuffer[sideMaterialIndex].doubleSided > 0.5;\n if (!doubleSided && !materialDoubleSided && dot(hitNormal, d) > 0.0) {\n hitNormal = vec3f(0.0);\n continue;\n }\n\n tMax = hit.t;\n isHit = true;\n isHitCurrent = true;\n hitPosition = o + tMax * d;\n hitBarycentric = hit.barycentric;\n}\n`;\n};\n\nfunction getPDMDisplacmentCode(anyHit: boolean) {\n return /*wgsl */ `\n let microTriangle = intersectDisplacement(\n o, d, tMax,\n tri.p0, tri.p1, tri.p2,\n n0, n1, n2,\n uv0, uv1, uv2,\n displacementMapIndex,\n getMapSize(displacementMapIndex),\n minH, maxH,\n hScale,\n matData.displacementStepSize,\n i32(matData.displacementUvProjection),\n displacementUvProjectionScale,\n ${anyHit ? 'true' : 'false'},\n isRefractionRay\n );\n`;\n}\n\nconst displacementIntersectCode = function (anyHit: boolean, hasAnisotropyDirections: boolean) {\n return /* wgsl */ `\n\nlet hScale = insData.w;\nlet minMaxH = bitcast<i32>(r3.w);\nif (abs(hScale) > 0.0 && minMaxH > 0) {\n // Scale normal by displacement scale\n let n0 = normalize(attrBuffers[index.x * ATTR_STRIDE + NORMAL_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n let n1 = normalize(attrBuffers[index.y * ATTR_STRIDE + NORMAL_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n let n2 = normalize(attrBuffers[index.z * ATTR_STRIDE + NORMAL_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n\n let minH = f32(minMaxH >> 8) / 255.0;\n let maxH = f32(minMaxH & 0xff) / 255.0;\n\n let pA = tri.p0 + n0 * hScale * minH;\n let pB = tri.p1 + n1 * hScale * minH;\n let pC = tri.p2 + n2 * hScale * minH;\n let pD = tri.p0 + n0 * hScale * maxH;\n let pE = tri.p1 + n1 * hScale * maxH;\n let pF = tri.p2 + n2 * hScale * maxH;\n // TODO not support material blending\n let materialIndex = i32(unpackMaterialIndex(bitcast<i32>(insData.z)).x);\n let matData = materialsBuffer[materialIndex];\n let displacementUvProjectionScale = vec2f(matData.displacementUvProjectionScale);\n let displacementMapIndex = i32(matData.displacementMapIndex);\n\n // TODO duplicate reading of normal and uv\n var uv0 = attrBuffers[index.x * ATTR_STRIDE + UV_OFF].xy;\n var uv1 = attrBuffers[index.y * ATTR_STRIDE + UV_OFF].xy;\n var uv2 = attrBuffers[index.z * ATTR_STRIDE + UV_OFF].xy;\n\n ${getPDMDisplacmentCode(anyHit)}\n\n if (microTriangle.t < tMax) {\n hitNormal = microTriangle.normal;\n // TODO support double sided to improve non watertight triangles.\n\n tMax = microTriangle.t;\n // TODO barycentric is for micro triangle\n hitBarycentric = microTriangle.barycentric;\n hitPosition = o + tMax * d;\n\n isHitMicroTriangle = true;\n isHit = true;\n isHitCurrent = true;\n }\n}\nelse {\n ${flatIntersectCode()}\n}\n`;\n};\n\nconst cwbvhTraversalWgsl = /* wgsl */ `\nfn unpackCwbvhBytes(value: u32) -> vec4f {\n return vec4f(\n f32(value & 0xffu),\n f32((value >> 8u) & 0xffu),\n f32((value >> 16u) & 0xffu),\n f32(value >> 24u)\n );\n}\n\n// CWBVH calls these helpers only with nonzero 8/24-bit masks. Every such\n// integer is exactly representable as f32, whose unbiased IEEE-754 exponent\n// gives the highest set bit. This avoids both the full-width firstLeadingBit\n// polyfill on some shader backends and a serial bit-spread/popcount chain.\n// Do not use this conversion for full 32-bit masks: rounding near a power of\n// two can change their highest bit. Zero is also outside this contract.\nfn cwbvhHighestBitIndex8(value: u32) -> u32 {\n return (bitcast<u32>(f32(value)) >> 23u) - 127u;\n}\n\nfn cwbvhHighestBitIndex24(value: u32) -> u32 {\n return (bitcast<u32>(f32(value)) >> 23u) - 127u;\n}\n\nfn intersectCwbvhInterior(\n node: i32,\n bufferOffset: i32,\n n0: vec4f,\n o: vec3f,\n invD: vec3f,\n tMax: f32\n) -> u32 {\n let i = node + bufferOffset;\n let n2 = bvhBuffer[i + 2];\n let n3 = bvhBuffer[i + 3];\n let n4 = bvhBuffer[i + 4];\n let header = bitcast<u32>(n0.w);\n let exponentX = bitcast<i32>((header & 0xffu) << 24u) >> 24;\n let exponentY = bitcast<i32>(((header >> 8u) & 0xffu) << 24u) >> 24;\n let exponentZ = bitcast<i32>(((header >> 16u) & 0xffu) << 24u) >> 24;\n let quantizationScale = vec3f(\n bitcast<f32>(u32(exponentX + 127) << 23u),\n bitcast<f32>(u32(exponentY + 127) << 23u),\n bitcast<f32>(u32(exponentZ + 127) << 23u)\n );\n let padding = depthSlabPadding(invD, o);\n let originTerm = (n0.xyz - o) * invD;\n let adjustedInvD = quantizationScale * invD;\n let minX0 = unpackCwbvhBytes(bitcast<u32>(n2.x));\n let minX1 = unpackCwbvhBytes(bitcast<u32>(n2.y));\n let minY0 = unpackCwbvhBytes(bitcast<u32>(n2.z));\n let minY1 = unpackCwbvhBytes(bitcast<u32>(n2.w));\n let minZ0 = unpackCwbvhBytes(bitcast<u32>(n3.x));\n let minZ1 = unpackCwbvhBytes(bitcast<u32>(n3.y));\n let maxX0 = unpackCwbvhBytes(bitcast<u32>(n3.z));\n let maxX1 = unpackCwbvhBytes(bitcast<u32>(n3.w));\n let maxY0 = unpackCwbvhBytes(bitcast<u32>(n4.x));\n let maxY1 = unpackCwbvhBytes(bitcast<u32>(n4.y));\n let maxZ0 = unpackCwbvhBytes(bitcast<u32>(n4.z));\n let maxZ1 = unpackCwbvhBytes(bitcast<u32>(n4.w));\n\n let minTx0 = minX0 * adjustedInvD.x + originTerm.x;\n let minTy0 = minY0 * adjustedInvD.y + originTerm.y;\n let minTz0 = minZ0 * adjustedInvD.z + originTerm.z;\n let maxTx0 = maxX0 * adjustedInvD.x + originTerm.x;\n let maxTy0 = maxY0 * adjustedInvD.y + originTerm.y;\n let maxTz0 = maxZ0 * adjustedInvD.z + originTerm.z;\n let near0 = max(\n max((min(minTx0, maxTx0) - vec4f(padding.x)), (min(minTy0, maxTy0) - vec4f(padding.y))),\n (min(minTz0, maxTz0) - vec4f(padding.z))\n );\n let far0 = min(\n min((max(minTx0, maxTx0) + vec4f(padding.x)), (max(minTy0, maxTy0) + vec4f(padding.y))),\n (max(minTz0, maxTz0) + vec4f(padding.z))\n );\n\n let minTx1 = minX1 * adjustedInvD.x + originTerm.x;\n let minTy1 = minY1 * adjustedInvD.y + originTerm.y;\n let minTz1 = minZ1 * adjustedInvD.z + originTerm.z;\n let maxTx1 = maxX1 * adjustedInvD.x + originTerm.x;\n let maxTy1 = maxY1 * adjustedInvD.y + originTerm.y;\n let maxTz1 = maxZ1 * adjustedInvD.z + originTerm.z;\n let near1 = max(\n max((min(minTx1, maxTx1) - vec4f(padding.x)), (min(minTy1, maxTy1) - vec4f(padding.y))),\n (min(minTz1, maxTz1) - vec4f(padding.z))\n );\n let far1 = min(\n min((max(minTx1, maxTx1) + vec4f(padding.x)), (max(minTy1, maxTy1) + vec4f(padding.y))),\n (max(minTz1, maxTz1) + vec4f(padding.z))\n );\n\n let hits0 = (near0 <= min(far0, vec4f(tMax))) & (far0 > vec4f(0.0));\n let hits1 = (near1 <= min(far1, vec4f(tMax))) & (far1 > vec4f(0.0));\n return select(0u, 1u, hits0.x)\n | select(0u, 2u, hits0.y)\n | select(0u, 4u, hits0.z)\n | select(0u, 8u, hits0.w)\n | select(0u, 16u, hits1.x)\n | select(0u, 32u, hits1.y)\n | select(0u, 64u, hits1.z)\n | select(0u, 128u, hits1.w);\n}\n\n`;\n\nfunction getBVHTraverseCode(\n handleHitCode: string,\n hasDisplacement: boolean,\n anyHit: boolean,\n blasLayoutMask: number,\n hasAnisotropyDirections: boolean,\n skipTriangleCode = ''\n) {\n const intersectTriangles = /* wgsl */ `\n let insData = instancesBuffer[insIdx * ${INSTANCE_VEC4_STRIDE}];\n let vertexOffset = vec3i(bitcast<i32>(insData.y));\n for (var k = 0; k < primitiveCount; k++) {\n let triangleIndex = primitiveOffset + k;\n ${skipTriangleCode}\n if (bounces > 0 && triangleIndex == currentTriangleIndex) {\n continue;\n }\n \n let r3 = bvhBuffer[triangleIndex];\n let index = bitcast<vec3i>(r3.xyz) + vertexOffset;\n var tri = Triangle(\n attrBuffers[index.x * ATTR_STRIDE + POSITION_OFF]${hasAnisotropyDirections ? '.xyz' : ''},\n attrBuffers[index.y * ATTR_STRIDE + POSITION_OFF]${hasAnisotropyDirections ? '.xyz' : ''},\n attrBuffers[index.z * ATTR_STRIDE + POSITION_OFF]${hasAnisotropyDirections ? '.xyz' : ''}\n );\n var isHitCurrent = false;\n\n ${hasDisplacement\n ? displacementIntersectCode(anyHit, hasAnisotropyDirections)\n : flatIntersectCode()}\n if (isHitCurrent) {\n ${handleHitCode}\n }\n }\n`;\n return /* wgsl */ `\nvar d = ray.d;\nvar o = ray.o;\nvar tlasStack: array<i32, TLAS_STACK_SIZE>;\nvar tlasTop = -1;\nvar invD = traversalInverse(d);\nvar isHitMicroTriangle = false;\nvar isHit = false;\nvar hitPosition: vec3f;\nvar hitNormal: vec3f;\nvar hitBarycentric: vec3f;\n\n\nif (intersectBox(o, bvhBuffer[0].xyz, bvhBuffer[1].xyz, invD, tMax) > 0.0) {\n tlasTop = 0;\n tlasStack[0] = 0;\n}\nwhile (tlasTop >= 0) {\n let tlasNode = tlasStack[tlasTop];\n tlasTop--;\n o = ray.o;\n d = ray.d;\n invD = traversalInverse(d);\n\n let tlasR1 = bvhBuffer[tlasNode];\n let tlasPointerOrPrimitiveCount = bitcast<i32>(tlasR1.w);\n if (tlasPointerOrPrimitiveCount >= 0) {\n let left = tlasNode + 2;\n let right = tlasPointerOrPrimitiveCount;\n let d0 = intersectBox(\n o,\n bvhBuffer[left].xyz,\n bvhBuffer[left + 1].xyz,\n invD,\n tMax\n );\n let d1 = intersectBox(\n o,\n bvhBuffer[right].xyz,\n bvhBuffer[right + 1].xyz,\n invD,\n tMax\n );\n\n if (d0 > d1) {\n if (d0 > 0.0) { tlasTop++; tlasStack[tlasTop] = left; }\n if (d1 > 0.0) { tlasTop++; tlasStack[tlasTop] = right; }\n }\n else {\n if (d1 > 0.0) { tlasTop++; tlasStack[tlasTop] = right; }\n if (d0 > 0.0) { tlasTop++; tlasStack[tlasTop] = left; }\n }\n }\n else {\n let tlasPrimitiveCount = -tlasPointerOrPrimitiveCount;\n // The previous unified LIFO stack visited leaf instances in reverse order.\n // Preserve that order for alpha-tested any-hit rays and deterministic RNG.\n for (\n var instanceOffset = tlasPrimitiveCount - 1;\n instanceOffset >= 0;\n instanceOffset--\n ) {\n let instanceRecord = bvhBuffer[tlasNode + 2 + instanceOffset];\n let insIdx = bitcast<i32>(instanceRecord.x);\n let blasRoot = bitcast<i32>(instanceRecord.y);\n let insData = instancesBuffer[insIdx * ${INSTANCE_VEC4_STRIDE}];\n let w2l = mat4x4<f32>(\n instancesBuffer[insIdx * ${INSTANCE_VEC4_STRIDE} + 1],\n instancesBuffer[insIdx * ${INSTANCE_VEC4_STRIDE} + 2],\n instancesBuffer[insIdx * ${INSTANCE_VEC4_STRIDE} + 3],\n instancesBuffer[insIdx * ${INSTANCE_VEC4_STRIDE} + 4]\n );\n o = (w2l * vec4f(ray.o, 1.0)).xyz;\n d = (w2l * vec4f(ray.d, 0.0)).xyz;\n invD = traversalInverse(d);\n maxDim = maxDimension(abs(d));\n shear = getShear(d, maxDim);\n\n let encodedBlasOffset = bitcast<u32>(insData.x);\n let blasLayout = encodedBlasOffset >> 30u;\n let blasOffset = i32(encodedBlasOffset & 0x3fffffffu);\n let bufferOff = rtUniform.blasOffset;\n\n ${(blasLayoutMask & 8) !== 0 ? /* wgsl */ `\n if (blasLayout == 3u) {\n // TinyBVH's official CWBVH traversal keeps compact node groups on the\n // stack. The upper 8 bits identify intersected interior slots and the\n // lower 8 bits preserve the node's interior-slot mask for popcount\n // addressing. Triangle leaves are merged into a separate 24-bit mask.\n var cwbvhStack: array<vec2u, BLAS_STACK_SIZE>;\n var cwbvhTop = -1;\n var cwbvhVisits = 0u;\n var nodeGroupBase = 0u;\n // A synthetic slot-7 hit selects relative node zero for the root.\n var nodeGroupMask = 0x80000000u;\n let octant = select(0u, 4u, d.x < 0.0)\n | select(0u, 2u, d.y < 0.0)\n | select(0u, 1u, d.z < 0.0);\n let octantInverse = 7u - octant;\n\n // Keep a statically visible trip bound. DXC can otherwise miscompile\n // the dynamic stack-top loop into a non-terminating shader on D3D12.\n // Validated scene rays stay far below this conservative safety cap.\n while (cwbvhVisits < 4096u) {\n cwbvhVisits++;\n \n let internalMask = nodeGroupMask & 0xffu;\n let childBitIndex =\n cwbvhHighestBitIndex8(nodeGroupMask >> 24u) + 24u;\n nodeGroupMask &= ~(1u << childBitIndex);\n if ((nodeGroupMask & 0xff000000u) != 0u) {\n cwbvhTop++;\n \n cwbvhStack[cwbvhTop] = vec2u(nodeGroupBase, nodeGroupMask);\n }\n\n let slot = (childBitIndex - 24u) ^ octantInverse;\n let precedingMask = (1u << slot) - 1u;\n let relativeIndex = countOneBits(internalMask & precedingMask);\n let childNodeIndex = nodeGroupBase + relativeIndex;\n let node = blasOffset + i32(childNodeIndex * 5u);\n let compressed0 = bvhBuffer[node + bufferOff];\n let slotHits = intersectCwbvhInterior(\n node, bufferOff, compressed0, o, invD, tMax\n );\n // Empty child hits need neither metadata nor leaf processing. Clear\n // the current group so the common tail restores pending siblings.\n nodeGroupMask = 0u;\n if (slotHits != 0u) {\n let compressed1 = bvhBuffer[node + bufferOff + 1];\n let nodeInternalMask = bitcast<u32>(compressed0.w) >> 24u;\n var hitMask = 0u;\n var remainingSlotHits = slotHits;\n while (remainingSlotHits != 0u) {\n let childSlot = cwbvhHighestBitIndex8(remainingSlotHits);\n remainingSlotHits &= ~(1u << childSlot);\n let metaWord = select(\n bitcast<u32>(compressed1.z),\n bitcast<u32>(compressed1.w),\n childSlot >= 4u\n );\n let childMeta =\n (metaWord >> ((childSlot & 3u) * 8u)) & 0xffu;\n let localOffset = childMeta & 0x1fu;\n let bitIndex = select(\n localOffset,\n localOffset ^ octantInverse,\n localOffset >= 24u\n );\n let childBits = (childMeta >> 5u) & 0x7u;\n hitMask |= childBits << bitIndex;\n }\n\n nodeGroupBase = bitcast<u32>(compressed1.x);\n nodeGroupMask = (hitMask & 0xff000000u) | nodeInternalMask;\n let triangleBase = bitcast<u32>(compressed1.y);\n var triangleMask = hitMask & 0x00ffffffu;\n while (triangleMask != 0u) {\n let triangleBitIndex = cwbvhHighestBitIndex24(triangleMask);\n triangleMask &= ~(1u << triangleBitIndex);\n let primitiveCount = 1;\n let primitiveOffset = bufferOff + blasOffset\n + i32(triangleBase + triangleBitIndex);\n ${intersectTriangles}\n }\n }\n\n if ((nodeGroupMask & 0xff000000u) != 0u) { continue; }\n if (cwbvhTop >= 0) {\n let restoredGroup = cwbvhStack[cwbvhTop];\n nodeGroupBase = restoredGroup.x;\n nodeGroupMask = restoredGroup.y;\n cwbvhTop--;\n }\n else { break; }\n }\n }\n ` : ''}\n\n var blasStack: array<i32, BLAS_STACK_SIZE>;\n var blasTop = -1;\n if (blasLayout != 3u) {\n blasTop = 0;\n \n blasStack[0] = blasRoot;\n }\n\n while (blasTop >= 0) {\n \n let node = blasStack[blasTop];\n blasTop--;\n var primitiveCount = 0;\n var primitiveOffset = 0;\n\n ${(blasLayoutMask & 4) !== 0 ? /* wgsl */ `\n if (blasLayout == 2u) {\n let i = node + bufferOff;\n let gpu0 = bvhBuffer[i];\n let gpu1 = bvhBuffer[i + 1];\n let gpu2 = bvhBuffer[i + 2];\n let gpu3 = bvhBuffer[i + 3];\n primitiveCount = i32(bitcast<u32>(gpu2.w));\n if (primitiveCount > 0) {\n primitiveOffset = bufferOff + blasOffset\n + i32(bitcast<u32>(gpu3.w));\n }\n else {\n let left = blasOffset + i32(bitcast<u32>(gpu0.w) * 4u);\n let right = blasOffset + i32(bitcast<u32>(gpu1.w) * 4u);\n let leftDistance = intersectBox(\n o, gpu0.xyz, gpu1.xyz, invD, tMax\n );\n let rightDistance = intersectBox(\n o, gpu2.xyz, gpu3.xyz, invD, tMax\n );\n if (leftDistance > rightDistance) {\n if (leftDistance > 0.0) {\n blasTop++; blasStack[blasTop] = left;\n }\n if (rightDistance > 0.0) {\n blasTop++; blasStack[blasTop] = right;\n }\n }\n else {\n if (rightDistance > 0.0) {\n blasTop++; blasStack[blasTop] = right;\n }\n if (leftDistance > 0.0) {\n blasTop++; blasStack[blasTop] = left;\n }\n }\n }\n }\n ` : ''}\n ${(blasLayoutMask & 2) !== 0 ? /* wgsl */ `\n if (blasLayout == 1u) {\n let nodeInfo = bitcast<u32>(node);\n if ((nodeInfo & 0x80000000u) != 0u) {\n primitiveCount = i32((nodeInfo >> 23u) & 0xffu);\n primitiveOffset = bufferOff + blasOffset\n + i32(nodeInfo & 0x007fffffu);\n }\n else {\n let i = node + bufferOff;\n let wide0 = bvhBuffer[i];\n let wide1 = bvhBuffer[i + 1];\n let wide2 = bvhBuffer[i + 2];\n let wide3 = bvhBuffer[i + 3];\n let nodeMin = wide0.xyz;\n let nodeExtent = vec3f(wide0.w, wide1.x, wide1.y);\n let childInfos = array<u32, 4>(\n bitcast<u32>(wide1.z), bitcast<u32>(wide1.w),\n bitcast<u32>(wide2.x), bitcast<u32>(wide2.y)\n );\n let childMinX = unpack4x8unorm(bitcast<u32>(wide2.z));\n let childMinY = unpack4x8unorm(bitcast<u32>(wide2.w));\n let childMinZ = unpack4x8unorm(bitcast<u32>(wide3.x));\n let childMaxX = unpack4x8unorm(bitcast<u32>(wide3.y));\n let childMaxY = unpack4x8unorm(bitcast<u32>(wide3.z));\n let childMaxZ = unpack4x8unorm(bitcast<u32>(wide3.w));\n let tx0 = (nodeMin.x + childMinX * nodeExtent.x - o.x) * invD.x;\n let tx1 = (nodeMin.x + childMaxX * nodeExtent.x - o.x) * invD.x;\n let ty0 = (nodeMin.y + childMinY * nodeExtent.y - o.y) * invD.y;\n let ty1 = (nodeMin.y + childMaxY * nodeExtent.y - o.y) * invD.y;\n let tz0 = (nodeMin.z + childMinZ * nodeExtent.z - o.z) * invD.z;\n let tz1 = (nodeMin.z + childMaxZ * nodeExtent.z - o.z) * invD.z;\n let padding = depthSlabPadding(invD, o);\n let tNear = max(\n max((min(tx0, tx1) - vec4f(padding.x)), (min(ty0, ty1) - vec4f(padding.y))),\n (min(tz0, tz1) - vec4f(padding.z))\n );\n let tFar = min(\n min((max(tx0, tx1) + vec4f(padding.x)), (max(ty0, ty1) + vec4f(padding.y))),\n (max(tz0, tz1) + vec4f(padding.z))\n );\n var distance = select(tFar, tNear, tNear > vec4f(0.0));\n distance = select(\n distance,\n vec4f(-1.0),\n tNear > min(tFar, vec4f(tMax))\n );\n var childDistances = array<f32, 4>(\n distance.x,\n distance.y,\n distance.z,\n distance.w\n );\n\n // Push far-to-near so that the closest child is popped first.\n for (var order = 0; order < 4; order++) {\n var farthestDistance = -1.0;\n var farthestChild = -1;\n for (var child = 0; child < 4; child++) {\n if (\n childInfos[child] != 0u &&\n childDistances[child] > farthestDistance\n ) {\n farthestDistance = childDistances[child];\n farthestChild = child;\n }\n }\n if (farthestChild >= 0 && farthestDistance > 0.0) {\n let childInfo = childInfos[farthestChild];\n var childAddress = bitcast<i32>(childInfo);\n if ((childInfo & 0x80000000u) == 0u) {\n childAddress += blasOffset;\n }\n blasTop++;\n blasStack[blasTop] = childAddress;\n childDistances[farthestChild] = -1.0;\n }\n }\n }\n }\n ` : ''}\n ${(blasLayoutMask & 1) !== 0 ? /* wgsl */ `\n if (blasLayout == 0u) {\n let i = node + bufferOff;\n let r1 = bvhBuffer[i];\n let pointerToRightOrNumPrims = bitcast<i32>(r1.w);\n\n if (pointerToRightOrNumPrims >= 0) {\n let left = node + 2;\n let right = pointerToRightOrNumPrims + blasOffset;\n let d0 = intersectBox(\n o,\n bvhBuffer[left + bufferOff].xyz,\n bvhBuffer[left + 1 + bufferOff].xyz,\n invD,\n tMax\n );\n let d1 = intersectBox(\n o,\n bvhBuffer[right + bufferOff].xyz,\n bvhBuffer[right + 1 + bufferOff].xyz,\n invD,\n tMax\n );\n\n if (d0 > d1) {\n if (d0 > 0.0) {\n blasTop++; blasStack[blasTop] = left;\n \n }\n if (d1 > 0.0) {\n blasTop++; blasStack[blasTop] = right;\n \n }\n }\n else {\n if (d1 > 0.0) {\n blasTop++; blasStack[blasTop] = right;\n \n }\n if (d0 > 0.0) {\n blasTop++; blasStack[blasTop] = left;\n \n }\n }\n }\n else {\n primitiveCount = -pointerToRightOrNumPrims;\n primitiveOffset = i + 2;\n }\n }\n ` : ''}\n if (primitiveCount > 0) {\n ${intersectTriangles}\n }\n }\n }\n }\n}\n\n`;\n}\nexport default function getIntersectCode({\n hasDisplacement,\n hasAnisotropyDirections = true,\n hasCoatNormals = false,\n blasLayoutMask = 1\n}: {\n hasDisplacement: boolean;\n hasAnisotropyDirections?: boolean;\n hasCoatNormals?: boolean;\n blasLayoutMask?: number;\n}) {\n return /*wgsl*/ `\n\n${hasDisplacement ? displacementWgsl : ''}\n${(blasLayoutMask & 8) !== 0 ? cwbvhTraversalWgsl : ''}\n\nstruct Triangle {\n p0: vec3f,\n p1: vec3f,\n p2: vec3f,\n};\n\nfn intersectSphere(rad: f32, pos: vec3f, r: Ray) -> f32 {\n let op: vec3f = pos - r.o;\n let eps: f32 = 0.001;\n let b: f32 = dot(op, r.d);\n var det: f32 = b * b - dot(op, op) + rad * rad;\n if (det < 0.0) {\n return INF;\n }\n\n det = sqrt(det);\n let t1: f32 = b - det;\n if (t1 > eps) {\n return t1;\n }\n\n let t2: f32 = b + det;\n if (t2 > eps) {\n return t2;\n }\n\n return INF;\n}\n\nfn intersectRect(pos: vec3f, u: vec3f, v: vec3f, n: vec3f, r: Ray) -> f32 {\n let dt: f32 = dot(r.d, n);\n let t: f32 = (dot(n, pos) - dot(n, r.o)) / dt;\n\n if (t > EPS) {\n let p: vec3f = r.o + r.d * t;\n let vi: vec3f = p - pos;\n let a1: f32 = dot(u / dot(u, u), vi);\n if (a1 >= 0.0 && a1 <= 1.0) {\n let a2: f32 = dot(v / dot(v, v), vi);\n if (a2 >= 0.0 && a2 <= 1.0) {\n return t;\n }\n }\n }\n\n return INF;\n}\n\nfn sphereSolidAnglePdf(origin: vec3f, center: vec3f, radius: f32) -> f32 {\n let centerDistance = distance(origin, center);\n if (centerDistance <= radius) { return INV4PI; }\n let sinThetaMaxSquared = min(1.0, radius * radius / (centerDistance * centerDistance));\n let cosThetaMax = sqrt(max(0.0, 1.0 - sinThetaMaxSquared));\n return 1.0 / max(TWOPI * (1.0 - cosThetaMax), 1e-8);\n}\n\nfn intersectLight(r: Ray, light: Light, lightSample: ptr<function, LightSampleRec>) -> f32 {\n // Analytic continuation hits use the same conditional light density as NEE.\n // Initialize every field because this record is reused across the light loop.\n var d: f32 = INF;\n (*lightSample).direction = r.d;\n (*lightSample).normal = -r.d;\n (*lightSample).dist = INF;\n (*lightSample).pdf = 0.0;\n (*lightSample).emission = vec3f(0.0);\n (*lightSample).isDelta = false;\n var u = light.u;\n var v = light.v;\n var lightType = i32(light.litType);\n\n if (lightType == RECT_LIGHT) {\n // Adjust the position from center to start corner\n var pos = light.position - u * 0.5 - v * 0.5;\n var normal = normalize(cross(u, v));\n if (dot(normal, r.d) > 0.0) { // Hide backfacing quad light\n return INF;\n }\n\n d = intersectRect(pos, u, v, normal, r);\n if (d < 0.0) {\n d = INF;\n }\n else {\n var cosTheta: f32 = dot(-r.d, normal);\n let spread = light.radiusOrSpread;\n if (cosTheta >= cos(spread * PI / 2.0)) {\n (*lightSample).direction = r.d;\n (*lightSample).normal = normal;\n (*lightSample).dist = d;\n (*lightSample).pdf = (d * d) / (light.area * cosTheta);\n (*lightSample).emission = light.emission;\n (*lightSample).isDelta = false;\n }\n else {\n d = INF;\n }\n }\n }\n\n else if (lightType == SPHERE_LIGHT) {\n if (light.radiusOrSpread <= 0.0) {\n let toPoint = light.position - r.o;\n let projection = dot(toPoint, r.d);\n let perpendicular = toPoint - projection * r.d;\n if (projection <= EPS || dot(perpendicular, perpendicular) > 1e-8) {\n return INF;\n }\n d = projection;\n (*lightSample).direction = r.d;\n (*lightSample).normal = -r.d;\n (*lightSample).dist = d;\n (*lightSample).pdf = 1.0;\n (*lightSample).isDelta = true;\n }\n else {\n d = intersectSphere(light.radiusOrSpread, light.position, r);\n (*lightSample).isDelta = false;\n if (d > 0.0 && d != INF) {\n (*lightSample).direction = r.d;\n (*lightSample).dist = d;\n (*lightSample).normal = normalize(\n r.o + r.d * d - light.position\n );\n (*lightSample).pdf = sphereSolidAnglePdf(\n r.o,\n light.position,\n light.radiusOrSpread\n );\n }\n }\n if (d < 0.0) {\n d = INF;\n }\n else {\n (*lightSample).direction = r.d;\n (*lightSample).dist = d;\n (*lightSample).emission = select(\n light.emission,\n light.emission / max(d * d, 1e-8),\n light.radiusOrSpread <= 0.0\n );\n }\n }\n\n else if (lightType == SPOT_LIGHT) {\n if (light.radiusOrSpread <= 0.0) {\n let toPoint = light.position - r.o;\n let projection = dot(toPoint, r.d);\n let perpendicular = toPoint - projection * r.d;\n if (projection <= EPS || dot(perpendicular, perpendicular) > 1e-8) {\n return INF;\n }\n d = projection;\n (*lightSample).direction = r.d;\n (*lightSample).normal = -r.d;\n (*lightSample).dist = d;\n (*lightSample).pdf = 1.0;\n (*lightSample).isDelta = true;\n }\n else {\n d = intersectSphere(light.radiusOrSpread, light.position, r);\n (*lightSample).isDelta = false;\n }\n if (d != INF) {\n let hitPt = r.o + d * r.d;\n let multiplier = evaluateSpotEmissionMultiplier(light, normalize(r.o - hitPt));\n if (multiplier <= 0.0) { return INF; }\n if (light.radiusOrSpread > 0.0) {\n (*lightSample).direction = r.d;\n (*lightSample).dist = d;\n (*lightSample).normal = normalize(\n r.o + r.d * d - light.position\n );\n (*lightSample).pdf = sphereSolidAnglePdf(r.o, light.position, light.radiusOrSpread);\n }\n (*lightSample).emission = light.emission * multiplier * select(\n 1.0,\n 1.0 / max(d * d, 1e-8),\n light.radiusOrSpread <= 0.0\n );\n }\n }\n\n else if (lightType != RECT_LIGHT && lightType != SPHERE_LIGHT && lightType != SPOT_LIGHT) {\n // Unsupported light\n d = INF;\n }\n\n return d;\n}\n\nfn randomPickMaterial(m0: vec3i, m1: vec3i, m2: vec3i, bary: vec3f) -> i32 {\n let m00 = unpackMaterialIndex(m0.x);\n let m01 = unpackMaterialIndex(m0.y);\n let m02 = unpackMaterialIndex(m0.z);\n let m10 = unpackMaterialIndex(m1.x);\n let m11 = unpackMaterialIndex(m1.y);\n let m12 = unpackMaterialIndex(m1.z);\n let m20 = unpackMaterialIndex(m2.x);\n let m21 = unpackMaterialIndex(m2.y);\n let m22 = unpackMaterialIndex(m2.z);\n var w00 = m00.y * bary.x;\n var w01 = m01.y * bary.x;\n var w02 = m02.y * bary.x;\n var w10 = m10.y * bary.y;\n var w11 = m11.y * bary.y;\n var w12 = m12.y * bary.y;\n var w20 = m20.y * bary.z;\n var w21 = m21.y * bary.z;\n var w22 = m22.y * bary.z;\n\n var wTotal = w00 + w01 + w02 + w10 + w11 + w12 + w20 + w21 + w22;\n // Accumulate weights\n w00 = w00 / wTotal;\n w01 = w01 / wTotal + w00;\n w02 = w02 / wTotal + w01;\n w10 = w10 / wTotal + w02;\n w11 = w11 / wTotal + w10;\n w12 = w12 / wTotal + w11;\n w20 = w20 / wTotal + w12;\n w21 = w21 / wTotal + w20;\n w22 = w22 / wTotal + w21;\n\n let rand = hashedSample(0u);\n var mIdx: f32;\n if (rand < w00) {\n mIdx = m00.x;\n } else if (rand < w01) {\n mIdx = m01.x;\n } else if (rand < w02) {\n mIdx = m02.x;\n } else if (rand < w10) {\n mIdx = m10.x;\n } else if (rand < w11) {\n mIdx = m11.x;\n } else if (rand < w12) {\n mIdx = m12.x;\n } else if (rand < w20) {\n mIdx = m20.x;\n } else if (rand < w21) {\n mIdx = m21.x;\n } else {\n mIdx = m22.x;\n }\n return i32(mIdx);\n}\n\nfn resolveSurfaceMaterialIndex(\n fallbackMaterialIndex: i32,\n index: vec3i,\n bary: vec3f\n) -> i32 {\n let m0 = vec3i(attrBuffers[index.x * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n let m1 = vec3i(attrBuffers[index.y * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n let m2 = vec3i(attrBuffers[index.z * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n if (m0.x > 0 || m1.x > 0 || m2.x > 0) {\n return randomPickMaterial(m0, m1, m2, bary);\n }\n return fallbackMaterialIndex;\n}\n\n\n\n${hasAnisotropyDirections ? /* wgsl */ `\nfn anisotropy_axes(normal: vec3f, dp1: vec3f, dp2: vec3f, duv1: vec2f, duv2: vec2f, input: vec4f) -> mat2x3f {\n let determinant = duv1.x * duv2.y - duv1.y * duv2.x;\n var t = input.xyz;\n var b = vec3f(0.0);\n // Internal W=2 marks an authored XYZ tangent whose sign is derived from UVs.\n var sign = select(input.w, 0.0, abs(input.w) > 1.5);\n if (abs(determinant) > 1e-12) {\n let dt = (dp1 * duv2.y - dp2 * duv1.y) / determinant;\n let db = (dp2 * duv1.x - dp1 * duv2.x) / determinant;\n if (dot(t, t) < 1e-8) { t = dt; }\n if (sign == 0.0) { sign = select(1.0, -1.0, dot(cross(normal, dt), db) < 0.0); }\n }\n t -= normal * dot(normal, t);\n if (dot(t, t) < 1e-8) {\n let signZ = select(-1.0, 1.0, normal.z >= 0.0);\n let factor = -1.0 / (signZ + normal.z);\n let xy = normal.x * normal.y * factor;\n t = vec3f(1.0 + signZ * normal.x * normal.x * factor, signZ * xy, -signZ * normal.x);\n b = vec3f(xy, signZ + normal.y * normal.y * factor, -normal.y);\n }\n else { t = normalize(t); b = normalize(cross(normal, t)); }\n return mat2x3f(t, b * select(1.0, -1.0, sign < 0.0));\n}\n\n` : /* wgsl */ ``}\nfn fetchAttributes(\n si: ptr<function, SurfaceInteraction>,\n tri: Triangle,\n bary: vec3f,\n index: vec3i,\n isHitMicroTriangle: bool,\n resolvedMaterialIndex: i32\n) {\n (*si).hit = true;\n // Get projected uv\n let material = materialsBuffer[(*si).materialIndex];\n let uvProjection = i32(material.uvProjection);\n\n let i0 = index.x;\n let i1 = index.y;\n let i2 = index.z;\n let isSphericalProj = uvProjection == ${uvProjectionConstants.spherical};\n\n var normal: vec3f = (*si).normal;\n var normalForSphericalProj: vec3f;\n var n0 = vec3f(0.0);\n var n1 = vec3f(0.0);\n var n2 = vec3f(0.0);\n // Otherwise use the normal from the microtriangle\n // The exception is spherical projection, we need the original normal to project the uv. Or the case like earth has wrong normal.\n if (!isHitMicroTriangle || isSphericalProj) {\n n0 = attrBuffers[i0 * ATTR_STRIDE + NORMAL_OFF]${hasAnisotropyDirections ? '.xyz' : ''};\n n1 = attrBuffers[i1 * ATTR_STRIDE + NORMAL_OFF]${hasAnisotropyDirections ? '.xyz' : ''};\n n2 = attrBuffers[i2 * ATTR_STRIDE + NORMAL_OFF]${hasAnisotropyDirections ? '.xyz' : ''};\n normalForSphericalProj = normalize(bary.x * n0 + bary.y * n1 + bary.z * n2);\n if (!isHitMicroTriangle) {\n normal = normalForSphericalProj;\n }\n }\n\n var uv: vec2f;\n var uv0: vec2f;\n var uv1: vec2f;\n var uv2: vec2f;\n var secondaryUv = vec2f(0.0);\n if (USE_UV) {\n uv0 = attrBuffers[i0 * ATTR_STRIDE + UV_OFF].xy;\n uv1 = attrBuffers[i1 * ATTR_STRIDE + UV_OFF].xy;\n uv2 = attrBuffers[i2 * ATTR_STRIDE + UV_OFF].xy;\n uv = bary.x * uv0 + bary.y * uv1 + bary.z * uv2;\n if (USE_UV1) {\n let secondaryUv0 = attrBuffers[i0 * ATTR_STRIDE + UV1_OFF].xy;\n let secondaryUv1 = attrBuffers[i1 * ATTR_STRIDE + UV1_OFF].xy;\n let secondaryUv2 = attrBuffers[i2 * ATTR_STRIDE + UV1_OFF].xy;\n secondaryUv = bary.x * secondaryUv0\n + bary.y * secondaryUv1\n + bary.z * secondaryUv2;\n }\n }\n\n if (USE_TANGENT) {\n let t0 = attrBuffers[i0 * ATTR_STRIDE + TANGENT_OFF]${hasAnisotropyDirections ? '.xyz' : ''};\n let t1 = attrBuffers[i1 * ATTR_STRIDE + TANGENT_OFF]${hasAnisotropyDirections ? '.xyz' : ''};\n let t2 = attrBuffers[i2 * ATTR_STRIDE + TANGENT_OFF]${hasAnisotropyDirections ? '.xyz' : ''};\n (*si).tangent = normalize(bary.x * t0 + bary.y * t1 + bary.z * t2);\n }\n\n if (resolvedMaterialIndex >= 0) {\n (*si).materialIndex = resolvedMaterialIndex;\n }\n else {\n (*si).materialIndex = resolveSurfaceMaterialIndex(\n (*si).materialIndex,\n index,\n bary\n );\n }\n\n if (uvProjection > 0) {\n // NOTE: position and normal are not transformed to world space yet.\n uv = projectUV(uvProjection, (*si).position, select(normal, normalForSphericalProj, isSphericalProj));\n secondaryUv = uv;\n }\n\n uv = uv * material.uvScale;\n secondaryUv = secondaryUv * material.uvScale;\n\n // Force repeating UVs for triplanar mapping\n if (uvProjection == ${uvProjectionConstants.triplanar}) {\n uv = fract(uv);\n }\n\n${hasAnisotropyDirections ? /* wgsl */ `\n${hasCoatNormals ? /* wgsl */ ` (*si).coatNormal = normal;` : ''}\n let directionMaterial = materialsBuffer[(*si).materialIndex];\n if (directionMaterial.anisotropyMapIndex >= 0.0 || directionMaterial.specularAnisotropyRotation != 0.0 || directionMaterial.coatAnisotropyRotation != 0.0${hasCoatNormals ? \" || (USE_COAT_NORMAL_MAPS && directionMaterial.coatNormalMapIndex >= 0.0)\" : \"\"}) {\n let dp1 = tri.p0 - tri.p2;\n let dp2 = tri.p1 - tri.p2;\n var inputTangent = vec4f(0.0);\n if (USE_TANGENT) {\n inputTangent = bary.x * attrBuffers[i0 * ATTR_STRIDE + TANGENT_OFF]\n + bary.y * attrBuffers[i1 * ATTR_STRIDE + TANGENT_OFF]\n + bary.z * attrBuffers[i2 * ATTR_STRIDE + TANGENT_OFF];\n }\n let geometryAxes = anisotropy_axes(normal, dp1, dp2, uv0-uv2, uv1-uv2, inputTangent);\n (*si).geometryTangent = geometryAxes[0];\n (*si).geometryBitangent = geometryAxes[1];\n var directionAxes = geometryAxes;\n if (USE_UV1 && directionMaterial.anisotropyMapIndex >= 0.0 && mapInfo[i32(directionMaterial.anisotropyMapIndex) + NUM_MAPS * 2].x > 0.5) {\n let a = attrBuffers[i0 * ATTR_STRIDE + UV1_OFF].xy;\n let b = attrBuffers[i1 * ATTR_STRIDE + UV1_OFF].xy;\n let c = attrBuffers[i2 * ATTR_STRIDE + UV1_OFF].xy;\n directionAxes = anisotropy_axes(normal, dp1, dp2, a-c, b-c, select(inputTangent, vec4f(0.0), inputTangent.w == 0.0));\n }\n (*si).directionTangent = directionAxes[0];\n (*si).directionBitangent = directionAxes[1];\n${hasCoatNormals ? /* wgsl */ `\n if (USE_COAT_NORMAL_MAPS && directionMaterial.coatNormalMapIndex >= 0.0) {\n let coatIndex = i32(directionMaterial.coatNormalMapIndex);\n var coatAxes = geometryAxes;\n if (USE_UV1 && mapInfo[coatIndex + NUM_MAPS * 2].x > 0.5) {\n let a = attrBuffers[i0 * ATTR_STRIDE + UV1_OFF].xy;\n let b = attrBuffers[i1 * ATTR_STRIDE + UV1_OFF].xy;\n let c = attrBuffers[i2 * ATTR_STRIDE + UV1_OFF].xy;\n coatAxes = anisotropy_axes(normal, dp1, dp2, a-c, b-c,\n select(inputTangent, vec4f(0.0), inputTangent.w == 0.0));\n }\n // Procedural projection overrides both UV sets. UV0 has already applied\n // triplanar wrapping, so use it for either texture channel in that case.\n let decoded = sampleMap(coatIndex, getMapUvSet(coatIndex, uv,\n select(secondaryUv, uv, uvProjection > 0))).rgb * 2.0 - 1.0;\n let mapped = coatAxes[0] * decoded.x * directionMaterial.coatNormalScale.x\n + coatAxes[1] * decoded.y * directionMaterial.coatNormalScale.y + normal * decoded.z;\n if (dot(mapped, mapped) > 1e-12) { (*si).coatNormal = normalize(mapped); }\n }\n` : ''}\n }\n\n` : /* wgsl */ ``}\n (*si).normal = normal;\n (*si).vertexNormal = normal;\n (*si).shadowOffset = vec3f(0.0);\n if (!isHitMicroTriangle) {\n // Smooth-limit geometry offset for direct-light shadow rays. This follows\n // the Cycles shadow terminator construction while keeping the result in\n // local space until the instance transform is available.\n let geometricNormal = normalize(cross(tri.p1 - tri.p0, tri.p2 - tri.p0));\n let smoothNormal = bary.x * n0 + bary.y * n1 + bary.z * n2;\n let a = dot(n2 - n0, tri.p0 - tri.p2);\n let b = dot(n2 - n1, tri.p1 - tri.p2);\n let c = dot(n1 - n0, tri.p1 - tri.p0);\n var h = a * bary.x * (bary.x - 1.0)\n + (a + b + c) * bary.x * bary.y\n + b * bary.y * (bary.y - 1.0);\n if (dot(smoothNormal, geometricNormal) > 0.0) {\n var h0 = max(max(dot(tri.p1 - tri.p0, n0), dot(tri.p2 - tri.p0, n0)), 0.0);\n var h1 = max(max(dot(tri.p0 - tri.p1, n1), dot(tri.p2 - tri.p1, n1)), 0.0);\n var h2 = max(max(dot(tri.p0 - tri.p2, n2), dot(tri.p1 - tri.p2, n2)), 0.0);\n h0 = max(dot(tri.p0 - (*si).position, n0) + h0, 0.0);\n h1 = max(dot(tri.p1 - (*si).position, n1) + h1, 0.0);\n h2 = max(dot(tri.p2 - (*si).position, n2) + h2, 0.0);\n h = max(min(min(h0, h1), h2), h * 0.5);\n }\n else {\n var h0 = max(max(dot(tri.p0 - tri.p1, n0), dot(tri.p0 - tri.p2, n0)), 0.0);\n var h1 = max(max(dot(tri.p1 - tri.p0, n1), dot(tri.p1 - tri.p2, n1)), 0.0);\n var h2 = max(max(dot(tri.p2 - tri.p0, n2), dot(tri.p2 - tri.p1, n2)), 0.0);\n h0 = max(dot((*si).position - tri.p0, n0) + h0, 0.0);\n h1 = max(dot((*si).position - tri.p1, n1) + h1, 0.0);\n h2 = max(dot((*si).position - tri.p2, n2) + h2, 0.0);\n h = min(-min(min(h0, h1), h2), h * 0.5);\n }\n (*si).shadowOffset = smoothNormal * h;\n }\n (*si).uv = uv;\n (*si).uv1 = secondaryUv;\n if (USE_NORMAL_MAPS) {\n let dp1 = tri.p0 - tri.p2;\n let dp2 = tri.p1 - tri.p2;\n let duv1 = uv0 - uv2;\n let duv2 = uv1 - uv2;\n (*si).normal = getMatNormal(\n (*si).materialIndex, uv, normal, dp1, dp2, duv1, duv2\n );\n }\n}\n\nstruct TriangleIntersect {\n t: f32,\n barycentric: vec3f,\n};\n\n\n// Triangle-ray intersection\n// Faster than the classic Möller–Trumbore intersection algorithm\n// http://www.pbr-book.org/3ed-2018/Shapes/Triangle_Meshes.html#TriangleIntersection\nfn intersectTriangle(o: vec3f, d: vec3f, tri: Triangle, maxDim: i32, shear: vec3f, tMax: f32) -> TriangleIntersect {\n var ti: TriangleIntersect;\n\n // translate vertices based on ray origin\n var p0t = tri.p0 - o;\n var p1t = tri.p1 - o;\n var p2t = tri.p2 - o;\n\n // permute components of triangle vertices\n if (maxDim == 0) {\n p0t = p0t.yzx;\n p1t = p1t.yzx;\n p2t = p2t.yzx;\n } else if (maxDim == 1) {\n p0t = p0t.zxy;\n p1t = p1t.zxy;\n p2t = p2t.zxy;\n }\n\n // apply shear transformation to translated vertex positions\n // TODO swizzled assignment is not supported in wgsl\n p0t = vec3f(p0t.xy + shear.xy * p0t.z, p0t.z);\n p1t = vec3f(p1t.xy + shear.xy * p1t.z, p1t.z);\n p2t = vec3f(p2t.xy + shear.xy * p2t.z, p2t.z);\n\n // compute edge function coefficients\n var e = vec3f(\n p1t.x * p2t.y - p1t.y * p2t.x,\n p2t.x * p0t.y - p2t.y * p0t.x,\n p0t.x * p1t.y - p0t.y * p1t.x\n );\n\n if (DEPTH_QUERY_MODE) {\n // Exact grid rays can land on shared edges. Roundoff in the two edge\n // products must not turn the edge into a crack between both triangles.\n let edgeScale = abs(vec3f(p1t.x * p2t.y, p2t.x * p0t.y, p0t.x * p1t.y))\n + abs(vec3f(p1t.y * p2t.x, p2t.y * p0t.x, p0t.y * p1t.x));\n e = select(e, vec3f(0.0), abs(e) <= edgeScale * 1e-6);\n }\n\n // check if intersection is inside triangle\n if (any(e < vec3f(0)) && any(e > vec3f(0))) {\n return ti;\n }\n\n let det = e.x + e.y + e.z;\n if (DEPTH_QUERY_MODE && det == 0.0) { return ti; }\n\n p0t.z *= shear.z;\n p1t.z *= shear.z;\n p2t.z *= shear.z;\n let tScaled = (e.x * p0t.z + e.y * p1t.z + e.z * p2t.z);\n\n // check if closer intersection already exists\n if (abs(tScaled) > abs(tMax * det)) {\n return ti;\n }\n\n let invDet = 1. / det;\n ti.t = tScaled * invDet;\n ti.barycentric = e * invDet;\n\n return ti;\n}\n\n// Pinhole depth queries can lie exactly on a grid vertex or a flat slab.\n// Specialize conservative slabs for that entry point; beauty retains its\n// original traversal arithmetic and random streams.\noverride DEPTH_QUERY_MODE: bool = false;\n\nfn traversalInverse(d: vec3f) -> vec3f {\n if (!DEPTH_QUERY_MODE) { return 1.0 / d; }\n return 1.0 / select(d, select(vec3f(1e-20), vec3f(-1e-20), d < vec3f(0.0)), abs(d) < vec3f(1e-20));\n}\n\nfn depthSlabPadding(invD: vec3f, o: vec3f) -> vec3f {\n if (!DEPTH_QUERY_MODE) { return vec3f(0.0); }\n return abs(invD) * max(vec3f(1.0), abs(o)) * 1e-6;\n}\n\n// Branchless ray/box intersection\n// https://tavianator.com/fast-branchless-raybounding-box-intersections/\nfn intersectBox(o: vec3f, bmin: vec3f, bmax: vec3f, invD: vec3f, tMax: f32) -> f32 {\n let tBot = (bmin - o) * invD;\n let tTop = (bmax - o) * invD;\n let padding = depthSlabPadding(invD, o);\n let tNear = min(tBot, tTop) - padding;\n let tFar = max(tBot, tTop) + padding;\n let t0 = max(tNear.x, max(tNear.y, tNear.z));\n let t1 = min(tFar.x, min(tFar.y, tFar.z));\n return select(select(t1, t0, t0 > 0.0), -1.0, (t0 > t1 || t0 > tMax));\n}\n\nfn maxDimension(v: vec3f) -> i32 {\n return select(select(2, 1, v.y > v.z), select(2, 0, v.x > v.z), v.x > v.y);\n}\n\nfn getShear(d: vec3f, maxDim: i32) -> vec3f {\n // Permute space so that the z dimension is the one where the absolute value of the ray's direction is largest.\n // Then create a shear transformation that aligns ray direction with the +z axis\n if (maxDim == 0) {\n return vec3f(-d.y, -d.z, 1.0) / d.x;\n } else if (maxDim == 1) {\n return vec3f(-d.z, -d.x, 1.0) / d.y;\n } else {\n return vec3f(-d.x, -d.y, 1.0) / d.z;\n }\n}\n\nfn completeSurfaceInteraction(\n si: ptr<function, SurfaceInteraction>,\n hitTri: Triangle,\n hitBarycentric: vec3f,\n hitIndex: vec3i,\n isHitMicroTriangle: bool,\n hitInsIdx: i32,\n hitNormal: vec3f,\n hitPosition: vec3f,\n resolvedMaterialIndex: i32\n) {\n (*si).instanceIndex = hitInsIdx;\n (*si).barycentrics = hitBarycentric.xy;\n (*si).normal = hitNormal;\n (*si).position = hitPosition;\n (*si).materialIndex = i32(unpackMaterialIndex(\n bitcast<i32>(instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE}].z)\n ).x);\n // NOTE: Must be called before transforming normal/position to world space.\n // UV projection depends on the local position.\n fetchAttributes(\n si,\n hitTri,\n hitBarycentric,\n hitIndex,\n isHitMicroTriangle,\n resolvedMaterialIndex\n );\n\n let l2w = mat4x4<f32>(\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 5],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 6],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 7],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 8]\n );\n let w2l = mat4x4<f32>(\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 1],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 2],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 3],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 4]\n );\n let normalTransform = transpose(mat3x3<f32>(\n w2l[0].xyz,\n w2l[1].xyz,\n w2l[2].xyz\n ));\n\n (*si).faceNormal = normalize(normalTransform * hitNormal);\n (*si).vertexNormal = normalize(normalTransform * (*si).vertexNormal);\n (*si).normal = normalize(normalTransform * (*si).normal);\n${hasCoatNormals ? /* wgsl */ ` (*si).coatNormal = normalize(normalTransform * (*si).coatNormal);` : ''}\n if (USE_TANGENT && dot((*si).tangent, (*si).tangent) > 0.0) {\n (*si).tangent = normalize((l2w * vec4f((*si).tangent, 0.0)).xyz);\n }\n${hasAnisotropyDirections ? /* wgsl */ `\n (*si).directionTangent = (l2w * vec4f((*si).directionTangent, 0.0)).xyz;\n (*si).directionBitangent = (l2w * vec4f((*si).directionBitangent, 0.0)).xyz;\n (*si).geometryTangent = (l2w * vec4f((*si).geometryTangent, 0.0)).xyz;\n (*si).geometryBitangent = (l2w * vec4f((*si).geometryBitangent, 0.0)).xyz;\n` : /* wgsl */ ``}\n (*si).shadowOffset = (l2w * vec4f((*si).shadowOffset, 0.0)).xyz;\n (*si).position = (l2w * vec4((*si).position, 1.0)).xyz;\n}\n\n\n${createIntersectionAlphaWgsl(hasAnisotropyDirections)}\n\n\n\n// Traverse BVH, find closest triangle intersection, and return surface information\nfn intersectScene(ray: Ray, si: ptr<function, SurfaceInteraction>, bounces: i32, doubleSided: bool, isRefractionRay: bool) {\n\n (*si).hit = false;\n\n if (rtUniform.isEmpty > 0) {\n return;\n }\n\n var tMax = RAY_MAX_DISTANCE;\n var maxDim: i32;\n var shear: vec3f;\n\n var hitIndex: vec3i;\n var hitTri: Triangle;\n var hitInsIdx: i32;\n var currentTriangleIndex: i32 = (*si).triangleIndex;\n\n ${getBVHTraverseCode(\n `\n(*si).triangleIndex = triangleIndex;\nhitTri = tri;\nhitIndex = index;\nhitInsIdx = insIdx;\n `,\n hasDisplacement,\n false,\n blasLayoutMask,\n hasAnisotropyDirections\n )}\n\n if (isHit) {\n completeSurfaceInteraction(\n si,\n hitTri,\n hitBarycentric,\n hitIndex,\n isHitMicroTriangle,\n hitInsIdx,\n hitNormal,\n hitPosition,\n -1\n );\n }\n}\n\n// Local intersection helper for shader bevel.\nfn intersectSceneBevel(ray: Ray, si: ptr<function, SurfaceInteraction>, instanceIndex: i32, maxDistance: f32) {\n (*si).hit = false;\n\n if (rtUniform.isEmpty > 0) {\n return;\n }\n\n let bounces = 0;\n let doubleSided = true;\n let isRefractionRay = false;\n var tMax = maxDistance;\n var maxDim: i32;\n var shear: vec3f;\n var hitIndex: vec3i;\n var hitTri: Triangle;\n var hitInsIdx: i32;\n var currentTriangleIndex: i32 = -1;\n\n ${getBVHTraverseCode(\n `\n(*si).triangleIndex = triangleIndex;\nhitTri = tri;\nhitIndex = index;\nhitInsIdx = insIdx;\n `,\n hasDisplacement,\n false,\n blasLayoutMask,\n hasAnisotropyDirections,\n `\n if (insIdx != instanceIndex) {\n continue;\n }\n `\n )}\n\n if (isHit) {\n (*si).instanceIndex = hitInsIdx;\n (*si).normal = hitNormal;\n (*si).position = hitPosition;\n (*si).materialIndex = i32(unpackMaterialIndex(bitcast<i32>(instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE}].z)).x);\n fetchAttributes(\n si,\n hitTri,\n hitBarycentric,\n hitIndex,\n isHitMicroTriangle,\n -1\n );\n\n let l2w = mat4x4<f32>(\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 5],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 6],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 7],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 8]\n );\n let w2l = mat4x4<f32>(\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 1],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 2],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 3],\n instancesBuffer[hitInsIdx * ${INSTANCE_VEC4_STRIDE} + 4]\n );\n let normalTransform = transpose(mat3x3<f32>(\n w2l[0].xyz,\n w2l[1].xyz,\n w2l[2].xyz\n ));\n (*si).faceNormal = normalize(normalTransform * hitNormal);\n (*si).vertexNormal = normalize(normalTransform * (*si).vertexNormal);\n (*si).normal = normalize(normalTransform * (*si).normal);\n${hasCoatNormals ? /* wgsl */ ` (*si).coatNormal = normalize(normalTransform * (*si).coatNormal);` : ''}\n if (USE_TANGENT && dot((*si).tangent, (*si).tangent) > 0.0) {\n (*si).tangent = normalize((l2w * vec4f((*si).tangent, 0.0)).xyz);\n }\n${hasAnisotropyDirections ? /* wgsl */ `\n (*si).directionTangent = (l2w * vec4f((*si).directionTangent, 0.0)).xyz;\n (*si).directionBitangent = (l2w * vec4f((*si).directionBitangent, 0.0)).xyz;\n (*si).geometryTangent = (l2w * vec4f((*si).geometryTangent, 0.0)).xyz;\n (*si).geometryBitangent = (l2w * vec4f((*si).geometryBitangent, 0.0)).xyz;\n` : /* wgsl */ ``}\n (*si).shadowOffset = (l2w * vec4f((*si).shadowOffset, 0.0)).xyz;\n (*si).position = (l2w * vec4((*si).position, 1.0)).xyz;\n }\n}\n\nfn intersectSceneShadow(ray: Ray, lightDistance: f32, currTriangleIndex: i32) -> bool {\n if (rtUniform.isEmpty > 0) {\n return false;\n }\n\n let doubleSided = true;\n let shadowRayTMax = min(max(lightDistance, 0.0), RAY_MAX_DISTANCE);\n var tMax = shadowRayTMax;\n var maxDim: i32;\n var shear: vec3f;\n\n let bounces = 1;\n var isRefractionRay = false;\n var currentTriangleIndex: i32 = currTriangleIndex;\n\n ${getBVHTraverseCode(\n /*wgsl */ `\n// Traversal is already clipped to the sampled light. Affine instance\n// transforms preserve the ray parameter because local directions are not\n// renormalized, so no local-to-world hit transform or distance() is needed.\nvar isOccluded = true;\n\nif (isOccluded) {\n if (HAS_ALPHA) {\n let materialIndex = i32(unpackMaterialIndex(bitcast<i32>(insData.z)).x);\n if (!intersectionAlphaPasses(\n materialIndex,\n index,\n hitBarycentric,\n hitPosition,\n hitNormal\n )) {\n // Continue looking for an opaque hit, but never traverse beyond the light.\n tMax = shadowRayTMax;\n isOccluded = false;\n }\n }\n}\nif (isOccluded) {\n return true;\n}\n `,\n hasDisplacement,\n true,\n blasLayoutMask,\n hasAnisotropyDirections\n )}\n\n return false;\n}\n\n`;\n}\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Material coverage shared by software BVH traversal and native RayQuery
|
|
3
|
+
* candidate filtering. The caller supplies local-space hit data so UV
|
|
4
|
+
* projection and stochastic glTF BLEND semantics stay backend-independent.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createIntersectionAlphaWgsl(hasAnisotropyDirections?: boolean): string;
|
|
7
|
+
declare const _default: string;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { mapAlphaUsageConstants } from '../../materialConstants.js';
|
|
2
|
+
import { uvProjectionConstants } from '../../MaterialTable.js';
|
|
3
|
+
import { materialAlphaModeConstants } from '../../../scene/OpenPBRMaterial.js';
|
|
4
|
+
/**
|
|
5
|
+
* Material coverage shared by software BVH traversal and native RayQuery
|
|
6
|
+
* candidate filtering. The caller supplies local-space hit data so UV
|
|
7
|
+
* projection and stochastic glTF BLEND semantics stay backend-independent.
|
|
8
|
+
*/
|
|
9
|
+
export function createIntersectionAlphaWgsl(hasAnisotropyDirections = true) {
|
|
10
|
+
return /* wgsl */ `
|
|
11
|
+
fn nl(
|
|
12
|
+
ph: i32,
|
|
13
|
+
index: vec3i,
|
|
14
|
+
aB: vec3f,
|
|
15
|
+
eU: vec3f,
|
|
16
|
+
eC: vec3f
|
|
17
|
+
) -> bool {
|
|
18
|
+
var materialIndex = ph;
|
|
19
|
+
let m0 = vec3i(attrBuffers[index.x * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});
|
|
20
|
+
let m1 = vec3i(attrBuffers[index.y * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});
|
|
21
|
+
let m2 = vec3i(attrBuffers[index.z * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});
|
|
22
|
+
|
|
23
|
+
if (m0.x > 0 || m1.x > 0 || m2.x > 0) {
|
|
24
|
+
materialIndex = fj(m0, m1, m2, aB);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let ma = materialsBuffer[materialIndex];
|
|
28
|
+
var alpha = ma.alpha;
|
|
29
|
+
if (USE_DIFFUSE_MAPS &&
|
|
30
|
+
ma.mapAlphaUsage == ${mapAlphaUsageConstants.alpha}) {
|
|
31
|
+
let diffuseMapIndex = i32(ma.diffuseMapIndex);
|
|
32
|
+
if (diffuseMapIndex >= 0) {
|
|
33
|
+
let uvProjection = i32(ma.uvProjection);
|
|
34
|
+
let uv0 = attrBuffers[index.x * ATTR_STRIDE + UV_OFF].xy;
|
|
35
|
+
let uv1 = attrBuffers[index.y * ATTR_STRIDE + UV_OFF].xy;
|
|
36
|
+
let uv2 = attrBuffers[index.z * ATTR_STRIDE + UV_OFF].xy;
|
|
37
|
+
var uv = aB.x * uv0 +
|
|
38
|
+
aB.y * uv1 + aB.z * uv2;
|
|
39
|
+
if (uvProjection > 0) {
|
|
40
|
+
uv = gz(uvProjection, eU, eC);
|
|
41
|
+
}
|
|
42
|
+
uv *= ma.uvScale;
|
|
43
|
+
if (uvProjection == ${uvProjectionConstants.triplanar}) {
|
|
44
|
+
uv = fract(uv);
|
|
45
|
+
}
|
|
46
|
+
alpha *= sampleMap(diffuseMapIndex, uv).a;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
if (USE_ALPHA_MAPS) {
|
|
51
|
+
let alphaMapIndex = i32(ma.alphaMapIndex);
|
|
52
|
+
if (alphaMapIndex >= 0) {
|
|
53
|
+
let uvProjection = i32(ma.uvProjection);
|
|
54
|
+
let uv0 = attrBuffers[index.x * ATTR_STRIDE + UV_OFF].xy;
|
|
55
|
+
let uv1 = attrBuffers[index.y * ATTR_STRIDE + UV_OFF].xy;
|
|
56
|
+
let uv2 = attrBuffers[index.z * ATTR_STRIDE + UV_OFF].xy;
|
|
57
|
+
var uv = aB.x * uv0 +
|
|
58
|
+
aB.y * uv1 + aB.z * uv2;
|
|
59
|
+
if (uvProjection > 0) {
|
|
60
|
+
uv = gz(uvProjection, eU, eC);
|
|
61
|
+
}
|
|
62
|
+
uv *= ma.uvScale;
|
|
63
|
+
if (uvProjection == ${uvProjectionConstants.triplanar}) {
|
|
64
|
+
uv = fract(uv);
|
|
65
|
+
}
|
|
66
|
+
alpha *= sampleMap(alphaMapIndex, uv).g;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
let alphaMode = i32(ma.alphaMode);
|
|
71
|
+
if (alphaMode == ${materialAlphaModeConstants.opaque}) {
|
|
72
|
+
alpha = 1.0;
|
|
73
|
+
}
|
|
74
|
+
else if (alphaMode == ${materialAlphaModeConstants.mask}) {
|
|
75
|
+
alpha = select(0.0, 1.0, alpha >= ma.alphaCutoff);
|
|
76
|
+
}
|
|
77
|
+
if (alphaMode == ${materialAlphaModeConstants.blend}) {
|
|
78
|
+
return eo(1u) <= alpha;
|
|
79
|
+
}
|
|
80
|
+
return alpha >= 1.0;
|
|
81
|
+
}
|
|
82
|
+
`;
|
|
83
|
+
}
|
|
84
|
+
export default createIntersectionAlphaWgsl();
|
|
85
|
+
//# sourceMappingURL=intersectionAlpha.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"intersectionAlpha.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/intersectionAlpha.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EACL,0BAA0B,EAC3B,MAAM,mCAAmC,CAAC;AAE3C;;;;GAIG;AACH,MAAM,UAAU,2BAA2B,CAAC,uBAAuB,GAAG,IAAI;IACxE,OAAO,UAAU,CAAC;;;;;;;;;uEASqD,uBAAuB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;uEACrC,uBAAuB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;uEACrC,uBAAuB,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;;;;;;;;;sBASlF,sBAAsB,CAAC,KAAK;;;;;;;;;;;;;sBAa5B,qBAAqB,CAAC,SAAS;;;;;;;;;;;;;;;;;;;;sBAoB/B,qBAAqB,CAAC,SAAS;;;;;;;;mBAQtC,0BAA0B,CAAC,MAAM;;;wBAG5B,0BAA0B,CAAC,IAAI;;;mBAGpC,0BAA0B,CAAC,KAAK;;;;;CAKpD,CAAC;AAGF,CAAC;AACD,eAAe,2BAA2B,EAAE,CAAC","sourcesContent":["import { mapAlphaUsageConstants } from '../../materialConstants.js';\nimport { uvProjectionConstants } from '../../MaterialTable.js';\nimport {\n materialAlphaModeConstants\n} from '../../../scene/OpenPBRMaterial.js';\n\n/**\n * Material coverage shared by software BVH traversal and native RayQuery\n * candidate filtering. The caller supplies local-space hit data so UV\n * projection and stochastic glTF BLEND semantics stay backend-independent.\n */\nexport function createIntersectionAlphaWgsl(hasAnisotropyDirections = true) {\n return /* wgsl */ `\nfn intersectionAlphaPasses(\n initialMaterialIndex: i32,\n index: vec3i,\n hitBarycentric: vec3f,\n hitPosition: vec3f,\n hitNormal: vec3f\n) -> bool {\n var materialIndex = initialMaterialIndex;\n let m0 = vec3i(attrBuffers[index.x * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n let m1 = vec3i(attrBuffers[index.y * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n let m2 = vec3i(attrBuffers[index.z * ATTR_STRIDE + MATERIALINDEX_OFF]${hasAnisotropyDirections ? '.xyz' : ''});\n\n if (m0.x > 0 || m1.x > 0 || m2.x > 0) {\n materialIndex = randomPickMaterial(m0, m1, m2, hitBarycentric);\n }\n\n let ma = materialsBuffer[materialIndex];\n var alpha = ma.alpha;\n if (USE_DIFFUSE_MAPS &&\n ma.mapAlphaUsage == ${mapAlphaUsageConstants.alpha}) {\n let diffuseMapIndex = i32(ma.diffuseMapIndex);\n if (diffuseMapIndex >= 0) {\n let uvProjection = i32(ma.uvProjection);\n let uv0 = attrBuffers[index.x * ATTR_STRIDE + UV_OFF].xy;\n let uv1 = attrBuffers[index.y * ATTR_STRIDE + UV_OFF].xy;\n let uv2 = attrBuffers[index.z * ATTR_STRIDE + UV_OFF].xy;\n var uv = hitBarycentric.x * uv0 +\n hitBarycentric.y * uv1 + hitBarycentric.z * uv2;\n if (uvProjection > 0) {\n uv = projectUV(uvProjection, hitPosition, hitNormal);\n }\n uv *= ma.uvScale;\n if (uvProjection == ${uvProjectionConstants.triplanar}) {\n uv = fract(uv);\n }\n alpha *= sampleMap(diffuseMapIndex, uv).a;\n }\n }\n\n if (USE_ALPHA_MAPS) {\n let alphaMapIndex = i32(ma.alphaMapIndex);\n if (alphaMapIndex >= 0) {\n let uvProjection = i32(ma.uvProjection);\n let uv0 = attrBuffers[index.x * ATTR_STRIDE + UV_OFF].xy;\n let uv1 = attrBuffers[index.y * ATTR_STRIDE + UV_OFF].xy;\n let uv2 = attrBuffers[index.z * ATTR_STRIDE + UV_OFF].xy;\n var uv = hitBarycentric.x * uv0 +\n hitBarycentric.y * uv1 + hitBarycentric.z * uv2;\n if (uvProjection > 0) {\n uv = projectUV(uvProjection, hitPosition, hitNormal);\n }\n uv *= ma.uvScale;\n if (uvProjection == ${uvProjectionConstants.triplanar}) {\n uv = fract(uv);\n }\n alpha *= sampleMap(alphaMapIndex, uv).g;\n }\n }\n\n let alphaMode = i32(ma.alphaMode);\n if (alphaMode == ${materialAlphaModeConstants.opaque}) {\n alpha = 1.0;\n }\n else if (alphaMode == ${materialAlphaModeConstants.mask}) {\n alpha = select(0.0, 1.0, alpha >= ma.alphaCutoff);\n }\n if (alphaMode == ${materialAlphaModeConstants.blend}) {\n return hashedSample(1u) <= alpha;\n }\n return alpha >= 1.0;\n}\n`;\n\n\n}\nexport default createIntersectionAlphaWgsl();\n"]}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare function createMaterialBufferWgsl({ hasAnisotropyDirections, hasCoatNormals, hasSceneAlpha }?: {
|
|
2
|
+
hasSceneAlpha?: boolean;
|
|
3
|
+
hasAnisotropyDirections?: boolean;
|
|
4
|
+
hasCoatNormals?: boolean;
|
|
5
|
+
}): string;
|
|
6
|
+
declare const materialBufferWgsl: string;
|
|
7
|
+
export default materialBufferWgsl;
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
import { simpleTextureSample, thinFilmTextureSample } from '../../materialTextureSlots.js';
|
|
2
|
+
import { INSTANCE_VEC4_STRIDE } from '../../bvhAccel.js';
|
|
3
|
+
import { mapAlphaUsageConstants } from '../../materialConstants.js';
|
|
4
|
+
// Portions adapted from ray-tracing-renderer@0.10.15
|
|
5
|
+
// (https://github.com/hoverinc/ray-tracing-renderer).
|
|
6
|
+
// Copyright (c) 2019 HOVER, MIT license; see LICENSES/RayTracingRenderer-MIT.txt.
|
|
7
|
+
import { materialAlphaModeConstants } from '../../../scene/OpenPBRMaterial.js';
|
|
8
|
+
export function createMaterialBufferWgsl({ hasAnisotropyDirections = true, hasCoatNormals = false, hasSceneAlpha = true } = {}) {
|
|
9
|
+
const alphaModeAssignment = hasSceneAlpha
|
|
10
|
+
? '(*ma).alphaMode = i32(matData.alphaMode);'
|
|
11
|
+
: '';
|
|
12
|
+
const alphaModeResolution = hasSceneAlpha
|
|
13
|
+
? /* wgsl */ `
|
|
14
|
+
if ((*ma).alphaMode == ${materialAlphaModeConstants.opaque}) {
|
|
15
|
+
(*ma).alpha = 1.0;
|
|
16
|
+
}
|
|
17
|
+
else if ((*ma).alphaMode == ${materialAlphaModeConstants.mask}) {
|
|
18
|
+
(*ma).alpha = select(0.0, 1.0, (*ma).alpha >= matData.alphaCutoff);
|
|
19
|
+
}`
|
|
20
|
+
: '(*ma).alpha = 1.0;';
|
|
21
|
+
return /* wgsl */ `
|
|
22
|
+
|
|
23
|
+
${hasAnisotropyDirections ? /* wgsl */ `fn fb(roughness: f32, strength: f32) -> vec2f {
|
|
24
|
+
if (strength == 0.0) { return vec2f(roughness, 0.0); }
|
|
25
|
+
let u = roughness * roughness;
|
|
26
|
+
let a = u + (1.0 - u) * strength * strength;
|
|
27
|
+
if (a == 0.0) { return vec2f(0.0); }
|
|
28
|
+
return vec2f(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));
|
|
29
|
+
}
|
|
30
|
+
` : /* wgsl */ ``}
|
|
31
|
+
|
|
32
|
+
fn oy(c: vec3f) -> vec3f {
|
|
33
|
+
return mix(pow(c * 0.9478672986 + 0.0521327014, vec3f(2.4)), c * 0.0773993808, vec3f(c < vec3f(0.04045)));
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
fn decodeMapColor(idx: i32, c: vec3f) -> vec3f {
|
|
37
|
+
if (mapInfo[idx + NUM_MAPS * 2].y > 0.5) { return c; }
|
|
38
|
+
return oy(c);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
fn ae(val: i32) -> vec2f {
|
|
42
|
+
return vec2f(f32(val >> 8), f32(val & 0xff) / 255.0);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
fn nX(idx: i32) -> vec2f {
|
|
46
|
+
return mapInfo[idx].xy;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
fn pf(idx: i32) -> i32 {
|
|
50
|
+
return i32(floor(mapInfo[idx].z));
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
fn nW(idx: i32) -> vec2f {
|
|
54
|
+
return vec2f(fract(mapInfo[idx].z), mapInfo[idx].w);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
fn sb(idx: i32, uv: vec2f) -> vec2f {
|
|
58
|
+
let transform = mapInfo[idx + NUM_MAPS];
|
|
59
|
+
let qv = fract(uv * transform.xy + transform.zw);
|
|
60
|
+
let je = 1.0 / vec2f(textureDimensions(map).xy);
|
|
61
|
+
let dZ = nW(idx);
|
|
62
|
+
let ke = nX(idx) + je;
|
|
63
|
+
let oB = dZ - 0.5 * je;
|
|
64
|
+
let lo = dZ + ke - je;
|
|
65
|
+
return clamp(
|
|
66
|
+
oB + qv * ke,
|
|
67
|
+
dZ,
|
|
68
|
+
lo
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
fn getMapUvSet(idx: i32, uv: vec2f, uv1: vec2f) -> vec2f {
|
|
73
|
+
return select(uv, uv1, mapInfo[idx + NUM_MAPS * 2].x > 0.5);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
fn sampleMap(idx: i32, uv: vec2f) -> vec4f {
|
|
77
|
+
return textureSampleLevel(map, mapSampler, sb(idx, uv), pf(idx), 0.0);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
fn lB(materialIndex: i32, uv: vec2f, uv1: vec2f) -> vec3f {
|
|
82
|
+
let matData = materialsBuffer[materialIndex];
|
|
83
|
+
var emission = matData.emission;
|
|
84
|
+
if (USE_EMISSIVE_MAPS) {
|
|
85
|
+
let emissiveMapIndex = i32(matData.emissiveMapIndex);
|
|
86
|
+
if (emissiveMapIndex >= 0) {
|
|
87
|
+
emission *= decodeMapColor(emissiveMapIndex, sampleMap(
|
|
88
|
+
emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)
|
|
89
|
+
).rgb);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (USE_COAT_WEIGHT_MAPS && matData.matType == 0.0) {
|
|
93
|
+
let coatWeightMapIndex = i32(matData.coatWeightMapIndex);
|
|
94
|
+
if (coatWeightMapIndex >= 0) {
|
|
95
|
+
let coatWeight = clamp(matData.coatWeight, 0.0, 1.0) * sampleMap(
|
|
96
|
+
coatWeightMapIndex, getMapUvSet(coatWeightMapIndex, uv, uv1)
|
|
97
|
+
).r;
|
|
98
|
+
emission *= mix(vec3f(1.0), sqrt(max(matData.coatColor, vec3f(0.0))), coatWeight);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return emission;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
fn aJ(roughness: f32, anisotropy: f32) -> vec2f {
|
|
106
|
+
let alpha = roughness * roughness;
|
|
107
|
+
let oT = ROUGHNESS_MIN * ROUGHNESS_MIN;
|
|
108
|
+
if (anisotropy == 0.0) { return vec2f(max(oT, alpha)); }
|
|
109
|
+
let dg = 1.0 - anisotropy;
|
|
110
|
+
let rU = alpha * sqrt(2.0 / (1.0 + dg * dg));
|
|
111
|
+
return max(vec2f(oT), vec2f(rU, dg * rU));
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
fn kx(instanceIndex: i32) -> vec3f {
|
|
115
|
+
if (instanceIndex < 0) { return vec3f(1.0); }
|
|
116
|
+
return instancesBuffer[instanceIndex * ${INSTANCE_VEC4_STRIDE} + 9].xyz;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
fn eT(
|
|
120
|
+
ma: ptr<function, J>,
|
|
121
|
+
materialIndex: i32,
|
|
122
|
+
uv: vec2f,
|
|
123
|
+
uv1: vec2f,
|
|
124
|
+
instanceIndex: i32
|
|
125
|
+
) {
|
|
126
|
+
let matData = materialsBuffer[materialIndex];
|
|
127
|
+
|
|
128
|
+
(*ma).baseColor = matData.color;
|
|
129
|
+
(*ma).materialType = i32(matData.matType);
|
|
130
|
+
(*ma).specularRoughness = matData.roughness;
|
|
131
|
+
(*ma).baseMetalness = matData.metallic;
|
|
132
|
+
(*ma).specularAnisotropy = clamp(matData.anisotropy, 0.0, 1.0);
|
|
133
|
+
(*ma).emission = lB(materialIndex, uv, uv1);
|
|
134
|
+
(*ma).inside = false;
|
|
135
|
+
(*ma).specularIor = matData.ior;
|
|
136
|
+
(*ma).transmissionWeight = matData.transmission;
|
|
137
|
+
(*ma).thinWalled = matData.thin > 0.5;
|
|
138
|
+
(*ma).bevel = matData.bevel;
|
|
139
|
+
(*ma).transmissionDispersionScale = matData.dispersion;
|
|
140
|
+
(*ma).dispersionAbbeNumber = max(matData.dispersionAbbeNumber, 1e-6);
|
|
141
|
+
(*ma).mediumExtinction = max(matData.mediumExtinction, vec3f(0.0));
|
|
142
|
+
(*ma).mediumScattering = max(matData.mediumScattering, vec3f(0.0));
|
|
143
|
+
(*ma).mediumAnisotropy = clamp(matData.mediumAnisotropy, -1.0, 1.0);
|
|
144
|
+
(*ma).mediumType = select(0, 1, max(max((*ma).mediumExtinction.x, (*ma).mediumExtinction.y), (*ma).mediumExtinction.z) > 0.0);
|
|
145
|
+
(*ma).alpha = matData.alpha;
|
|
146
|
+
${alphaModeAssignment}
|
|
147
|
+
|
|
148
|
+
(*ma).thinFilmThickness = matData.thinFilmThickness * 1000.0;
|
|
149
|
+
(*ma).thinFilmIor = matData.thinFilmIor;
|
|
150
|
+
(*ma).thinFilmWeight = select(0.0, clamp(matData.thinFilmWeight, 0.0, 1.0), HAS_THIN_FILM);
|
|
151
|
+
(*ma).baseWeight = clamp(matData.baseWeight, 0.0, 1.0);
|
|
152
|
+
(*ma).diffuseRoughness = clamp(matData.baseDiffuseRoughness, 0.0, 1.0);
|
|
153
|
+
(*ma).specularWeight = max(matData.specularWeight, 0.0);
|
|
154
|
+
(*ma).specularColor = max(matData.specularColor, vec3f(0.0));
|
|
155
|
+
(*ma).subsurfaceWeight = select(0.0, clamp(matData.subsurfaceWeight, 0.0, 1.0), HAS_SUBSURFACE);
|
|
156
|
+
(*ma).subsurfaceColor = max(matData.subsurfaceColor, vec3f(0.0));
|
|
157
|
+
(*ma).transmissionColor = max(matData.transmissionColor, vec3f(0.0));
|
|
158
|
+
(*ma).fuzzWeight = select(0.0, clamp(matData.fuzzWeight, 0.0, 1.0), HAS_FUZZ);
|
|
159
|
+
(*ma).fuzzColor = max(matData.fuzzColor, vec3f(0.0));
|
|
160
|
+
(*ma).fuzzRoughness = clamp(matData.fuzzRoughness, 0.0, 1.0);
|
|
161
|
+
(*ma).coatWeight = select(0.0, clamp(matData.coatWeight, 0.0, 1.0), HAS_COAT);
|
|
162
|
+
(*ma).coatColor = max(matData.coatColor, vec3f(0.0));
|
|
163
|
+
(*ma).coatRoughness = clamp(matData.coatRoughness, ROUGHNESS_MIN, 1.0);
|
|
164
|
+
(*ma).coatAnisotropy = clamp(matData.coatAnisotropy, 0.0, 1.0);
|
|
165
|
+
(*ma).coatIor = max(matData.coatIor, 1.0);
|
|
166
|
+
(*ma).coatDarkening = clamp(matData.coatDarkening, 0.0, 1.0);
|
|
167
|
+
|
|
168
|
+
if (USE_DIFFUSE_MAPS) {
|
|
169
|
+
let diffuseMapIndex = i32(matData.diffuseMapIndex);
|
|
170
|
+
if (diffuseMapIndex >= 0) {
|
|
171
|
+
|
|
172
|
+
let nN = sampleMap(
|
|
173
|
+
diffuseMapIndex, getMapUvSet(diffuseMapIndex, uv, uv1)
|
|
174
|
+
);
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
(*ma).baseColor *= decodeMapColor(diffuseMapIndex, nN.rgb);
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.transmission}) {
|
|
181
|
+
(*ma).transmissionWeight = 1.0 - nN.a;
|
|
182
|
+
}
|
|
183
|
+
else if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.alpha}) {
|
|
184
|
+
(*ma).alpha *= nN.a;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
${simpleTextureSample('alphaMap', 'wgsl')}
|
|
190
|
+
|
|
191
|
+
${alphaModeResolution}
|
|
192
|
+
|
|
193
|
+
${simpleTextureSample('transmissionMap', 'wgsl')}
|
|
194
|
+
|
|
195
|
+
if (USE_METALLIC_ROUGHNESS_MAPS) {
|
|
196
|
+
|
|
197
|
+
let mrtMapIndex = i32(matData.mrtMapIndex);
|
|
198
|
+
if (mrtMapIndex >= 0) {
|
|
199
|
+
let fK = sampleMap(
|
|
200
|
+
mrtMapIndex, getMapUvSet(mrtMapIndex, uv, uv1)
|
|
201
|
+
);
|
|
202
|
+
(*ma).baseMetalness *= fK.b;
|
|
203
|
+
(*ma).specularRoughness *= fK.g;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
${simpleTextureSample('roughnessMap', 'wgsl')}
|
|
208
|
+
|
|
209
|
+
${simpleTextureSample('metalnessMap', 'wgsl')}
|
|
210
|
+
|
|
211
|
+
${thinFilmTextureSample('wgsl')}
|
|
212
|
+
|
|
213
|
+
${simpleTextureSample('coatWeightMap', 'wgsl')}
|
|
214
|
+
|
|
215
|
+
${hasCoatNormals ? /* wgsl */ `
|
|
216
|
+
(*ma).coatNormalEnabled = USE_COAT_NORMAL_MAPS && matData.coatNormalMapIndex >= 0.0 && (*ma).coatWeight > 0.0;
|
|
217
|
+
` : ''}
|
|
218
|
+
|
|
219
|
+
${simpleTextureSample('coatRoughnessMap', 'wgsl')}
|
|
220
|
+
|
|
221
|
+
${simpleTextureSample('fuzzColorMap', 'wgsl')}
|
|
222
|
+
|
|
223
|
+
${simpleTextureSample('fuzzRoughnessMap', 'wgsl')}
|
|
224
|
+
|
|
225
|
+
${simpleTextureSample('specularWeightMap', 'wgsl')}
|
|
226
|
+
|
|
227
|
+
${simpleTextureSample('specularColorMap', 'wgsl')}
|
|
228
|
+
|
|
229
|
+
${hasAnisotropyDirections ? /* wgsl */ `
|
|
230
|
+
(*ma).anisotropyDirection = vec2f(1.0, 0.0);
|
|
231
|
+
(*ma).anisotropyDirectionEnabled = matData.specularAnisotropyRotation != 0.0;
|
|
232
|
+
(*ma).coatAnisotropyRotation = matData.coatAnisotropyRotation;
|
|
233
|
+
if (USE_ANISOTROPY_MAPS && matData.anisotropyMapIndex >= 0.0) {
|
|
234
|
+
let index = i32(matData.anisotropyMapIndex);
|
|
235
|
+
let iW = sampleMap(index, getMapUvSet(index, uv, uv1));
|
|
236
|
+
(*ma).specularAnisotropy *= iW.b;
|
|
237
|
+
let direction = iW.rg * 2.0 - 1.0;
|
|
238
|
+
if (dot(direction, direction) > 1e-4) { (*ma).anisotropyDirection = normalize(direction); }
|
|
239
|
+
(*ma).anisotropyDirectionEnabled = true;
|
|
240
|
+
}
|
|
241
|
+
if (matData.specularAnisotropyModel > 0.5 && (*ma).specularAnisotropy > 0.0) {
|
|
242
|
+
let sp = fb(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);
|
|
243
|
+
(*ma).specularRoughness = sp.x;
|
|
244
|
+
(*ma).specularAnisotropy = sp.y;
|
|
245
|
+
}
|
|
246
|
+
if ((*ma).anisotropyDirectionEnabled) {
|
|
247
|
+
let theta = matData.specularAnisotropyRotation;
|
|
248
|
+
let d = (*ma).anisotropyDirection;
|
|
249
|
+
(*ma).anisotropyDirection = vec2f(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
` : /* wgsl */ ``}
|
|
253
|
+
|
|
254
|
+
|
|
255
|
+
if ((*ma).coatWeight > 0.0 && (*ma).coatRoughness > 0.0) {
|
|
256
|
+
let hJ = (*ma).specularRoughness * (*ma).specularRoughness;
|
|
257
|
+
let hK = (*ma).coatRoughness * (*ma).coatRoughness;
|
|
258
|
+
(*ma).specularRoughness = mix((*ma).specularRoughness,
|
|
259
|
+
pow(min(1.0, hJ * hJ + 2.0 * hK * hK), 0.25), (*ma).coatWeight);
|
|
260
|
+
}
|
|
261
|
+
let instanceColor = kx(instanceIndex);
|
|
262
|
+
(*ma).baseColor *= instanceColor;
|
|
263
|
+
if ((*ma).materialType == UNLIT) { (*ma).emission *= instanceColor; }
|
|
264
|
+
|
|
265
|
+
(*ma).specularRoughness = clamp((*ma).specularRoughness, ROUGHNESS_MIN, 1.0);
|
|
266
|
+
(*ma).baseMetalness = clamp((*ma).baseMetalness, 0.0, 1.0);
|
|
267
|
+
let specularAlpha = aJ((*ma).specularRoughness, (*ma).specularAnisotropy);
|
|
268
|
+
(*ma).alphaX = specularAlpha.x;
|
|
269
|
+
(*ma).alphaY = specularAlpha.y;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
fn nY(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, nP: vec2f, nQ: vec2f) -> vec3f {
|
|
273
|
+
let matData = materialsBuffer[materialIndex];
|
|
274
|
+
let normalMapIndex = i32(matData.normalMapIndex);
|
|
275
|
+
if (normalMapIndex >= 0) {
|
|
276
|
+
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
let qJ = cross(dp2, normal);
|
|
280
|
+
let qI = cross(normal, dp1);
|
|
281
|
+
var dpdu = qJ * nP.x + qI * nQ.x;
|
|
282
|
+
var rZ = qJ * nP.y + qI * nQ.y;
|
|
283
|
+
let dS = max(dot(dpdu, dpdu), dot(rZ, rZ));
|
|
284
|
+
if (dS > 1e-12) {
|
|
285
|
+
let sh = inverseSqrt(dS);
|
|
286
|
+
dpdu *= sh;
|
|
287
|
+
rZ *= sh;
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
let mZ = select(
|
|
293
|
+
vec3f(0.0, 1.0, 0.0),
|
|
294
|
+
vec3f(0.0, 0.0, 1.0),
|
|
295
|
+
abs(normal.z) < 0.999
|
|
296
|
+
);
|
|
297
|
+
dpdu = normalize(cross(mZ, normal));
|
|
298
|
+
rZ = cross(normal, dpdu);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
var n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;
|
|
302
|
+
n = normalize(vec3(n.xy * matData.normalMapScale, n.z));
|
|
303
|
+
|
|
304
|
+
let tbn = mat3x3(dpdu, rZ, normal);
|
|
305
|
+
|
|
306
|
+
return normalize(tbn * n);
|
|
307
|
+
} else {
|
|
308
|
+
return normal;
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
`;
|
|
312
|
+
}
|
|
313
|
+
const materialBufferWgsl = createMaterialBufferWgsl();
|
|
314
|
+
export default materialBufferWgsl;
|
|
315
|
+
//# sourceMappingURL=materialBuffer.wgsl.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"materialBuffer.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/materialBuffer.wgsl.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AAC3F,OAAO,EAAE,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,EAAE,sBAAsB,EAAE,MAAM,4BAA4B,CAAC;AACpE,qDAAqD;AACrD,sDAAsD;AACtD,kFAAkF;AAElF,OAAO,EACL,0BAA0B,EAC3B,MAAM,mCAAmC,CAAC;AAE3C,MAAM,UAAU,wBAAwB,CAAC,EACvC,uBAAuB,GAAG,IAAI,EAC9B,cAAc,GAAG,KAAK,EACtB,aAAa,GAAG,IAAI,KAKlB,EAAE;IACJ,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,2CAA2C;QAC7C,CAAC,CAAC,EAAE,CAAC;IACP,MAAM,mBAAmB,GAAG,aAAa;QACvC,CAAC,CAAC,UAAU,CAAC;yBACU,0BAA0B,CAAC,MAAM;;;8BAG5B,0BAA0B,CAAC,IAAI;;EAE3D;QACA,CAAC,CAAC,oBAAoB,CAAC;IAEzB,OAAO,UAAU,CAAC;;EAElB,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;CAOtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCAsF0B,oBAAoB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8B3D,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAkCc,sBAAsB,CAAC,YAAY;;;oCAG9B,sBAAsB,CAAC,KAAK;;;;;;EAMlE,mBAAmB,CAAC,UAAU,EAAE,MAAM,CAAC;;EAEvC,mBAAmB;;EAEnB,mBAAmB,CAAC,iBAAiB,EAAE,MAAM,CAAC;;;;;;;;;;;;;;EAc9C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,qBAAqB,CAAC,MAAM,CAAC;;EAE7B,mBAAmB,CAAC,eAAe,EAAE,MAAM,CAAC;;EAE9C,cAAc,CAAC,CAAC,CAAC,UAAU,CAAC;;CAE7B,CAAC,CAAC,CAAC,EAAE;;EAEF,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAE/C,mBAAmB,CAAC,cAAc,EAAE,MAAM,CAAC;;EAE3C,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAE/C,mBAAmB,CAAC,mBAAmB,EAAE,MAAM,CAAC;;EAEhD,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC;;EAEjD,uBAAuB,CAAC,CAAC,CAAC,UAAU,CAAC;;;;;;;;;;;;;;;;;;;;;;;CAuBtC,CAAC,CAAC,CAAC,UAAU,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2DhB,CAAC;AACF,CAAC;AAED,MAAM,kBAAkB,GAAG,wBAAwB,EAAE,CAAC;AAEtD,eAAe,kBAAkB,CAAC","sourcesContent":["import { simpleTextureSample, thinFilmTextureSample } from '../../materialTextureSlots.js';\nimport { INSTANCE_VEC4_STRIDE } from '../../bvhAccel.js';\nimport { mapAlphaUsageConstants } from '../../materialConstants.js';\n// 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\nimport {\n materialAlphaModeConstants\n} from '../../../scene/OpenPBRMaterial.js';\n\nexport function createMaterialBufferWgsl({\n hasAnisotropyDirections = true,\n hasCoatNormals = false,\n hasSceneAlpha = true\n}: {\n hasSceneAlpha?: boolean;\n hasAnisotropyDirections?: boolean;\n hasCoatNormals?: boolean;\n} = {}) {\n const alphaModeAssignment = hasSceneAlpha\n ? '(*ma).alphaMode = i32(matData.alphaMode);'\n : '';\n const alphaModeResolution = hasSceneAlpha\n ? /* wgsl */ `\n if ((*ma).alphaMode == ${materialAlphaModeConstants.opaque}) {\n (*ma).alpha = 1.0;\n }\n else if ((*ma).alphaMode == ${materialAlphaModeConstants.mask}) {\n (*ma).alpha = select(0.0, 1.0, (*ma).alpha >= matData.alphaCutoff);\n }`\n : '(*ma).alpha = 1.0;';\n\n return /* wgsl */ `\n\n${hasAnisotropyDirections ? /* wgsl */ `fn gltf_anisotropy_to_openpbr(roughness: f32, strength: f32) -> vec2f {\n if (strength == 0.0) { return vec2f(roughness, 0.0); }\n let u = roughness * roughness;\n let a = u + (1.0 - u) * strength * strength;\n if (a == 0.0) { return vec2f(0.0); }\n return vec2f(pow((a*a + u*u) * 0.5, 0.25), clamp(1.0 - u/a, 0.0, 1.0));\n}\n` : /* wgsl */ ``}\n\nfn sRGBToLinear(c: vec3f) -> vec3f {\n return mix(pow(c * 0.9478672986 + 0.0521327014, vec3f(2.4)), c * 0.0773993808, vec3f(c < vec3f(0.04045)));\n}\n\nfn decodeMapColor(idx: i32, c: vec3f) -> vec3f {\n if (mapInfo[idx + NUM_MAPS * 2].y > 0.5) { return c; }\n return sRGBToLinear(c);\n}\n\nfn unpackMaterialIndex(val: i32) -> vec2f {\n return vec2f(f32(val >> 8), f32(val & 0xff) / 255.0);\n}\n\nfn getMapSize(idx: i32) -> vec2f {\n return mapInfo[idx].xy;\n}\n\nfn getMapLayer(idx: i32) -> i32 {\n return i32(floor(mapInfo[idx].z));\n}\n\nfn getMapOffset(idx: i32) -> vec2f {\n return vec2f(fract(mapInfo[idx].z), mapInfo[idx].w);\n}\n\nfn getMapUV(idx: i32, uv: vec2f) -> vec2f {\n let transform = mapInfo[idx + NUM_MAPS];\n let repeatedUv = fract(uv * transform.xy + transform.zw);\n let atlasTexel = 1.0 / vec2f(textureDimensions(map).xy);\n let firstTexelCenter = getMapOffset(idx);\n let sourceExtent = getMapSize(idx) + atlasTexel;\n let sourceOrigin = firstTexelCenter - 0.5 * atlasTexel;\n let lastTexelCenter = firstTexelCenter + sourceExtent - atlasTexel;\n return clamp(\n sourceOrigin + repeatedUv * sourceExtent,\n firstTexelCenter,\n lastTexelCenter\n );\n}\n\nfn getMapUvSet(idx: i32, uv: vec2f, uv1: vec2f) -> vec2f {\n return select(uv, uv1, mapInfo[idx + NUM_MAPS * 2].x > 0.5);\n}\n\nfn sampleMap(idx: i32, uv: vec2f) -> vec4f {\n return textureSampleLevel(map, mapSampler, getMapUV(idx, uv), getMapLayer(idx), 0.0);\n}\n\n\nfn getMaterialEmission(materialIndex: i32, uv: vec2f, uv1: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n var emission = matData.emission;\n if (USE_EMISSIVE_MAPS) {\n let emissiveMapIndex = i32(matData.emissiveMapIndex);\n if (emissiveMapIndex >= 0) {\n emission *= decodeMapColor(emissiveMapIndex, sampleMap(\n emissiveMapIndex, getMapUvSet(emissiveMapIndex, uv, uv1)\n ).rgb);\n }\n }\n if (USE_COAT_WEIGHT_MAPS && matData.matType == 0.0) {\n let coatWeightMapIndex = i32(matData.coatWeightMapIndex);\n if (coatWeightMapIndex >= 0) {\n let coatWeight = clamp(matData.coatWeight, 0.0, 1.0) * sampleMap(\n coatWeightMapIndex, getMapUvSet(coatWeightMapIndex, uv, uv1)\n ).r;\n emission *= mix(vec3f(1.0), sqrt(max(matData.coatColor, vec3f(0.0))), coatWeight);\n }\n }\n return emission;\n}\n\n// OpenPBR 1.1.1: RMS-preserving GGX anisotropy, shared by base and coat.\nfn openpbr_roughness_to_alpha(roughness: f32, anisotropy: f32) -> vec2f {\n let alpha = roughness * roughness;\n let alphaMin = ROUGHNESS_MIN * ROUGHNESS_MIN;\n if (anisotropy == 0.0) { return vec2f(max(alphaMin, alpha)); }\n let complement = 1.0 - anisotropy;\n let alphaT = alpha * sqrt(2.0 / (1.0 + complement * complement));\n return max(vec2f(alphaMin), vec2f(alphaT, complement * alphaT));\n}\n\nfn getInstanceColor(instanceIndex: i32) -> vec3f {\n if (instanceIndex < 0) { return vec3f(1.0); }\n return instancesBuffer[instanceIndex * ${INSTANCE_VEC4_STRIDE} + 9].xyz;\n}\n\nfn getMaterial(\n ma: ptr<function, OpenPbrResolvedMaterial>,\n materialIndex: i32,\n uv: vec2f,\n uv1: vec2f,\n instanceIndex: i32\n) {\n let matData = materialsBuffer[materialIndex];\n\n (*ma).baseColor = matData.color;\n (*ma).materialType = i32(matData.matType);\n (*ma).specularRoughness = matData.roughness;\n (*ma).baseMetalness = matData.metallic;\n (*ma).specularAnisotropy = clamp(matData.anisotropy, 0.0, 1.0);\n (*ma).emission = getMaterialEmission(materialIndex, uv, uv1);\n (*ma).inside = false;\n (*ma).specularIor = matData.ior;\n (*ma).transmissionWeight = matData.transmission;\n (*ma).thinWalled = matData.thin > 0.5;\n (*ma).bevel = matData.bevel;\n (*ma).transmissionDispersionScale = matData.dispersion;\n (*ma).dispersionAbbeNumber = max(matData.dispersionAbbeNumber, 1e-6);\n (*ma).mediumExtinction = max(matData.mediumExtinction, vec3f(0.0));\n (*ma).mediumScattering = max(matData.mediumScattering, vec3f(0.0));\n (*ma).mediumAnisotropy = clamp(matData.mediumAnisotropy, -1.0, 1.0);\n (*ma).mediumType = select(0, 1, max(max((*ma).mediumExtinction.x, (*ma).mediumExtinction.y), (*ma).mediumExtinction.z) > 0.0);\n (*ma).alpha = matData.alpha;\n ${alphaModeAssignment}\n\n (*ma).thinFilmThickness = matData.thinFilmThickness * 1000.0;\n (*ma).thinFilmIor = matData.thinFilmIor;\n (*ma).thinFilmWeight = select(0.0, clamp(matData.thinFilmWeight, 0.0, 1.0), HAS_THIN_FILM);\n (*ma).baseWeight = clamp(matData.baseWeight, 0.0, 1.0);\n (*ma).diffuseRoughness = clamp(matData.baseDiffuseRoughness, 0.0, 1.0);\n (*ma).specularWeight = max(matData.specularWeight, 0.0);\n (*ma).specularColor = max(matData.specularColor, vec3f(0.0));\n (*ma).subsurfaceWeight = select(0.0, clamp(matData.subsurfaceWeight, 0.0, 1.0), HAS_SUBSURFACE);\n (*ma).subsurfaceColor = max(matData.subsurfaceColor, vec3f(0.0));\n (*ma).transmissionColor = max(matData.transmissionColor, vec3f(0.0));\n (*ma).fuzzWeight = select(0.0, clamp(matData.fuzzWeight, 0.0, 1.0), HAS_FUZZ);\n (*ma).fuzzColor = max(matData.fuzzColor, vec3f(0.0));\n (*ma).fuzzRoughness = clamp(matData.fuzzRoughness, 0.0, 1.0);\n (*ma).coatWeight = select(0.0, clamp(matData.coatWeight, 0.0, 1.0), HAS_COAT);\n (*ma).coatColor = max(matData.coatColor, vec3f(0.0));\n (*ma).coatRoughness = clamp(matData.coatRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).coatAnisotropy = clamp(matData.coatAnisotropy, 0.0, 1.0);\n (*ma).coatIor = max(matData.coatIor, 1.0);\n (*ma).coatDarkening = clamp(matData.coatDarkening, 0.0, 1.0);\n\n if (USE_DIFFUSE_MAPS) {\n let diffuseMapIndex = i32(matData.diffuseMapIndex);\n if (diffuseMapIndex >= 0) {\n // TODO textureSample is not supported in compute shader.\n let diffuse = sampleMap(\n diffuseMapIndex, getMapUvSet(diffuseMapIndex, uv, uv1)\n );\n // Material factors from THREE / glTF are already linear. Only color\n // textures need decoding from their stored sRGB values.\n (*ma).baseColor *= decodeMapColor(diffuseMapIndex, diffuse.rgb);\n\n // Map alpha to transmission\n if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.transmission}) {\n (*ma).transmissionWeight = 1.0 - diffuse.a;\n }\n else if (matData.mapAlphaUsage == ${mapAlphaUsageConstants.alpha}) {\n (*ma).alpha *= diffuse.a;\n }\n }\n }\n\n ${simpleTextureSample('alphaMap', 'wgsl')}\n\n ${alphaModeResolution}\n\n ${simpleTextureSample('transmissionMap', 'wgsl')}\n\n if (USE_METALLIC_ROUGHNESS_MAPS) {\n // Metallic roughness transmission map index\n let mrtMapIndex = i32(matData.mrtMapIndex);\n if (mrtMapIndex >= 0) {\n let metallicRoughness = sampleMap(\n mrtMapIndex, getMapUvSet(mrtMapIndex, uv, uv1)\n );\n (*ma).baseMetalness *= metallicRoughness.b;\n (*ma).specularRoughness *= metallicRoughness.g;\n }\n }\n\n ${simpleTextureSample('roughnessMap', 'wgsl')}\n\n ${simpleTextureSample('metalnessMap', 'wgsl')}\n\n ${thinFilmTextureSample('wgsl')}\n\n ${simpleTextureSample('coatWeightMap', 'wgsl')}\n\n${hasCoatNormals ? /* wgsl */ `\n (*ma).coatNormalEnabled = USE_COAT_NORMAL_MAPS && matData.coatNormalMapIndex >= 0.0 && (*ma).coatWeight > 0.0;\n` : ''}\n\n ${simpleTextureSample('coatRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzColorMap', 'wgsl')}\n\n ${simpleTextureSample('fuzzRoughnessMap', 'wgsl')}\n\n ${simpleTextureSample('specularWeightMap', 'wgsl')}\n\n ${simpleTextureSample('specularColorMap', 'wgsl')}\n\n${hasAnisotropyDirections ? /* wgsl */ `\n (*ma).anisotropyDirection = vec2f(1.0, 0.0);\n (*ma).anisotropyDirectionEnabled = matData.specularAnisotropyRotation != 0.0;\n (*ma).coatAnisotropyRotation = matData.coatAnisotropyRotation;\n if (USE_ANISOTROPY_MAPS && matData.anisotropyMapIndex >= 0.0) {\n let index = i32(matData.anisotropyMapIndex);\n let texel = sampleMap(index, getMapUvSet(index, uv, uv1));\n (*ma).specularAnisotropy *= texel.b;\n let direction = texel.rg * 2.0 - 1.0;\n if (dot(direction, direction) > 1e-4) { (*ma).anisotropyDirection = normalize(direction); }\n (*ma).anisotropyDirectionEnabled = true;\n }\n if (matData.specularAnisotropyModel > 0.5 && (*ma).specularAnisotropy > 0.0) {\n let native = gltf_anisotropy_to_openpbr(clamp((*ma).specularRoughness, 0.0, 1.0), (*ma).specularAnisotropy);\n (*ma).specularRoughness = native.x;\n (*ma).specularAnisotropy = native.y;\n }\n if ((*ma).anisotropyDirectionEnabled) {\n let theta = matData.specularAnisotropyRotation;\n let d = (*ma).anisotropyDirection;\n (*ma).anisotropyDirection = vec2f(cos(theta)*d.x - sin(theta)*d.y, sin(theta)*d.x + cos(theta)*d.y);\n }\n\n` : /* wgsl */ ``}\n // OpenPBR 1.1.1: coat refraction broadens all base microfacet lobes.\n // Keep the zero-coat / smooth-coat paths byte-identical.\n if ((*ma).coatWeight > 0.0 && (*ma).coatRoughness > 0.0) {\n let baseRoughness2 = (*ma).specularRoughness * (*ma).specularRoughness;\n let coatRoughness2 = (*ma).coatRoughness * (*ma).coatRoughness;\n (*ma).specularRoughness = mix((*ma).specularRoughness,\n pow(min(1.0, baseRoughness2 * baseRoughness2 + 2.0 * coatRoughness2 * coatRoughness2), 0.25), (*ma).coatWeight);\n }\n let instanceColor = getInstanceColor(instanceIndex);\n (*ma).baseColor *= instanceColor;\n if ((*ma).materialType == UNLIT) { (*ma).emission *= instanceColor; }\n\n (*ma).specularRoughness = clamp((*ma).specularRoughness, ROUGHNESS_MIN, 1.0);\n (*ma).baseMetalness = clamp((*ma).baseMetalness, 0.0, 1.0);\n let specularAlpha = openpbr_roughness_to_alpha((*ma).specularRoughness, (*ma).specularAnisotropy);\n (*ma).alphaX = specularAlpha.x;\n (*ma).alphaY = specularAlpha.y;\n}\n\nfn getMatNormal(materialIndex: i32, uv: vec2f, normal: vec3f, dp1: vec3f, dp2: vec3f, duv1: vec2f, duv2: vec2f) -> vec3f {\n let matData = materialsBuffer[materialIndex];\n let normalMapIndex = i32(matData.normalMapIndex);\n if (normalMapIndex >= 0) {\n // http://www.thetenthplanet.de/archives/1180\n // TODO use tangent attribute\n // Compute co-tangent and co-bitangent vectors\n let dp2perp = cross(dp2, normal);\n let dp1perp = cross(normal, dp1);\n var dpdu = dp2perp * duv1.x + dp1perp * duv2.x;\n var dpdv = dp2perp * duv1.y + dp1perp * duv2.y;\n let gradientLengthSquared = max(dot(dpdu, dpdu), dot(dpdv, dpdv));\n if (gradientLengthSquared > 1e-12) {\n let invmax = inverseSqrt(gradientLengthSquared);\n dpdu *= invmax;\n dpdv *= invmax;\n }\n else {\n // Generated/triplanar UVs have no per-vertex UV derivatives. Build a\n // stable fallback basis instead of normalizing two zero vectors.\n let referenceAxis = select(\n vec3f(0.0, 1.0, 0.0),\n vec3f(0.0, 0.0, 1.0),\n abs(normal.z) < 0.999\n );\n dpdu = normalize(cross(referenceAxis, normal));\n dpdv = cross(normal, dpdu);\n }\n\n var n = 2.0 * sampleMap(normalMapIndex, uv).rgb - 1.0;\n n = normalize(vec3(n.xy * matData.normalMapScale, n.z));\n\n let tbn = mat3x3(dpdu, dpdv, normal);\n\n return normalize(tbn * n);\n } else {\n return normal;\n }\n}\n`;\n}\n\nconst materialBufferWgsl = createMaterialBufferWgsl();\n\nexport default materialBufferWgsl;\n"]}
|