@meimu/mutracer 0.3.0 → 0.3.1
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/CHANGELOG.md +222 -0
- package/LICENSES/FidelityFX-FSR.txt +19 -0
- package/LICENSES/pbrt-v4-Apache-2.0.txt +202 -0
- package/THIRD_PARTY_NOTICES.md +18 -4
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +6260 -5580
- package/docs/api.md +45 -18
- package/docs/materials.md +4 -2
- package/docs/performance.md +7 -0
- package/docs/post-processing.md +62 -9
- package/docs/progressive-rendering.md +3 -0
- package/docs/sampling.md +4 -0
- package/docs/technical/acceleration.md +52 -0
- package/docs/technical/aovs.md +79 -0
- package/docs/technical/caustics.md +109 -0
- package/docs/technical/continuous-spectrum.md +29 -0
- package/docs/technical/display-upscale.md +82 -0
- package/docs/technical/openpbr.md +99 -0
- package/docs/technical/pbrt-import.md +168 -0
- package/docs/technical/tiling.md +74 -0
- package/docs/technical/webgl.md +53 -0
- package/docs/viewer.md +11 -1
- package/lib/Display.d.ts +19 -5
- package/lib/Display.js +10 -7
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -1
- package/lib/Engine.js +30 -2
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +20 -11
- package/lib/Render.js +32 -7
- package/lib/Render.js.map +1 -1
- package/lib/main.d.ts +3 -1
- package/lib/main.js +1 -0
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/renderer/AovPrimitiveCache.js +39 -8
- package/lib/renderer/AovPrimitiveCache.js.map +1 -1
- package/lib/renderer/DisplayPostProcess.d.ts +8 -3
- package/lib/renderer/DisplayPostProcess.js +51 -18
- package/lib/renderer/DisplayPostProcess.js.map +1 -1
- package/lib/renderer/MaterialData.js +7 -2
- package/lib/renderer/MaterialData.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +7 -1
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/TileRender.d.ts +2 -2
- package/lib/renderer/TileRender.js +128 -7
- package/lib/renderer/TileRender.js.map +1 -1
- package/lib/renderer/WGPUAov.d.ts +6 -1
- package/lib/renderer/WGPUAov.js +108 -14
- package/lib/renderer/WGPUAov.js.map +1 -1
- package/lib/renderer/WGPUCanvasSurface.js +12 -1
- package/lib/renderer/WGPUCanvasSurface.js.map +1 -1
- package/lib/renderer/WGPUEnvMapDistribution.js +19 -19
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPURayTraceOutput.js +12 -12
- package/lib/renderer/WGPURayTracePass.d.ts +17 -4
- package/lib/renderer/WGPURayTracePass.js +194 -71
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +46 -40
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLAov.js +3 -3
- package/lib/renderer/WebGLAov.js.map +1 -1
- package/lib/renderer/WebGLFullQuadPass.d.ts +1 -1
- package/lib/renderer/WebGLFullQuadPass.js +8 -2
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
- package/lib/renderer/WebGLJNLMDenoiser.js.map +1 -1
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +14 -10
- package/lib/renderer/WebGLRayTracePass.js +115 -111
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +10 -3
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +57 -57
- package/lib/renderer/aov.d.ts +13 -1
- package/lib/renderer/aov.js +21 -2
- package/lib/renderer/aov.js.map +1 -1
- package/lib/renderer/aovDisplay.js +2 -2
- package/lib/renderer/aovDisplay.js.map +1 -1
- package/lib/renderer/binnedSahBvh.d.ts +2 -1
- package/lib/renderer/binnedSahBvh.js +24 -17
- package/lib/renderer/binnedSahBvh.js.map +1 -1
- package/lib/renderer/bvhAccel.d.ts +3 -1
- package/lib/renderer/bvhAccel.js +36 -6
- package/lib/renderer/bvhAccel.js.map +1 -1
- package/lib/renderer/cameraUniform.d.ts +1 -1
- package/lib/renderer/cameraUniform.js +6 -2
- package/lib/renderer/cameraUniform.js.map +1 -1
- package/lib/renderer/compactVertices.d.ts +14 -0
- package/lib/renderer/compactVertices.js +124 -0
- package/lib/renderer/compactVertices.js.map +1 -0
- package/lib/renderer/easu.d.ts +11 -0
- package/lib/renderer/easu.js +156 -0
- package/lib/renderer/easu.js.map +1 -0
- package/lib/renderer/geometryUpdateState.d.ts +1 -0
- package/lib/renderer/geometryUpdateState.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +3 -2
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
- package/lib/renderer/glsl/aovReflectance.glsl.js +35 -35
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +44 -36
- package/lib/renderer/glsl/aovTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js +16 -0
- package/lib/renderer/glsl/chunks/cameraProjection.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/cameraRay.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -16
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +8 -8
- package/lib/renderer/glsl/chunks/envMap.glsl.js +67 -67
- package/lib/renderer/glsl/chunks/intersect.glsl.js +390 -375
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +120 -120
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +562 -562
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +4 -4
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +37 -35
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +70 -74
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +107 -88
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +11 -11
- package/lib/renderer/glsl/chunks/sampling.glsl.js +77 -77
- package/lib/renderer/glsl/chunks/sobol.glsl.js +70 -70
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.d.ts +6 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js +47 -0
- package/lib/renderer/glsl/chunks/spectralPrefix.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
- package/lib/renderer/glsl/depthQuery.frag.js +12 -6
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
- package/lib/renderer/glsl/rayTrace.frag.js +233 -170
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +10 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +58 -58
- package/lib/renderer/gpuMemory.js +1 -1
- package/lib/renderer/gpuMemory.js.map +1 -1
- package/lib/renderer/openPbrEnergyLut.d.ts +2 -1
- package/lib/renderer/openPbrEnergyLut.js +18 -1
- package/lib/renderer/openPbrEnergyLut.js.map +1 -1
- package/lib/renderer/pathLimits.d.ts +5 -4
- package/lib/renderer/pathLimits.js +6 -5
- package/lib/renderer/pathLimits.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.d.ts +2 -0
- package/lib/renderer/prepareMeshBVH.js +5 -3
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/progressiveScheduler.js +1 -1
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +4 -0
- package/lib/renderer/renderPipeline.js +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/researchTransport.d.ts +1 -1
- package/lib/renderer/researchTransport.js.map +1 -1
- package/lib/renderer/sceneAssembly.d.ts +1 -1
- package/lib/renderer/sceneAssembly.js +4 -3
- package/lib/renderer/sceneAssembly.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.d.ts +1 -1
- package/lib/renderer/sceneChangeDetector.js +3 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
- package/lib/renderer/sceneLayoutSchema.js +2 -2
- package/lib/renderer/sceneLayoutSchema.js.map +1 -1
- package/lib/renderer/scenePreparation.d.ts +3 -2
- package/lib/renderer/scenePreparation.js +18 -2
- package/lib/renderer/scenePreparation.js.map +1 -1
- package/lib/renderer/scratchSampling.js +6 -6
- package/lib/renderer/spectrum.js +2 -2
- package/lib/renderer/staticBvhPreparation.d.ts +9 -0
- package/lib/renderer/staticBvhPreparation.js +8 -2
- package/lib/renderer/staticBvhPreparation.js.map +1 -1
- package/lib/renderer/surfaceHit.d.ts +10 -0
- package/lib/renderer/surfaceHit.js +22 -0
- package/lib/renderer/surfaceHit.js.map +1 -0
- package/lib/renderer/tangentRequirements.d.ts +2 -0
- package/lib/renderer/tangentRequirements.js +7 -0
- package/lib/renderer/tangentRequirements.js.map +1 -0
- package/lib/renderer/textureAtlas.d.ts +4 -0
- package/lib/renderer/textureAtlas.js +48 -2
- package/lib/renderer/textureAtlas.js.map +1 -1
- package/lib/renderer/webgl.js +4 -0
- package/lib/renderer/webgl.js.map +1 -1
- package/lib/renderer/webglVertexAttributes.d.ts +17 -0
- package/lib/renderer/webglVertexAttributes.js +44 -0
- package/lib/renderer/webglVertexAttributes.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.js +2 -2
- package/lib/renderer/wgpuMaterialConstants.js +4 -3
- package/lib/renderer/wgpuMaterialConstants.js.map +1 -1
- package/lib/renderer/wgpuSceneUniform.js +2 -2
- package/lib/renderer/wgpuSceneUniform.js.map +1 -1
- package/lib/renderer/wgpuShaderSource.d.ts +15 -0
- package/lib/renderer/wgpuShaderSource.js +1 -1
- package/lib/renderer/wgpuShaderSource.js.map +1 -1
- package/lib/renderer/wgsl/aovCompact.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js +26 -0
- package/lib/renderer/wgsl/aovCompact.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +39 -39
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovResolve.wgsl.d.ts +4 -0
- package/lib/renderer/wgsl/aovResolve.wgsl.js +21 -2
- package/lib/renderer/wgsl/aovResolve.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +2 -2
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/aovTrace.wgsl.js +31 -31
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js +56 -0
- package/lib/renderer/wgsl/aovTraceDisplay.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
- package/lib/renderer/wgsl/causticLight.compute.d.ts +1 -1
- package/lib/renderer/wgsl/causticLight.compute.js +121 -119
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -1
- package/lib/renderer/wgsl/chunks/background.wgsl.js +46 -46
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +30 -30
- package/lib/renderer/wgsl/chunks/intersect.wgsl.d.ts +6 -2
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +550 -542
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +18 -16
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +70 -69
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +593 -593
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +118 -118
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +4 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +32 -26
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +114 -114
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +159 -137
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +74 -74
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.d.ts +6 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js +66 -0
- package/lib/renderer/wgsl/chunks/spectralPrefix.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js +61 -0
- package/lib/renderer/wgsl/chunks/vertexAttributes.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/compose.frag.wgsl.js +99 -97
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/depthQuery.wgsl.js +11 -2
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/easu.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/easu.wgsl.js +80 -0
- package/lib/renderer/wgsl/easu.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.d.ts +21 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js +230 -0
- package/lib/renderer/wgsl/easuDetail.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/jnlm.compute.js +74 -74
- package/lib/renderer/wgsl/jnlm.compute.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
- package/lib/renderer/wgsl/photonMap.compute.js +89 -89
- package/lib/renderer/wgsl/proceduralSky.compute.js +61 -61
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +14 -0
- package/lib/renderer/wgsl/rayTrace.compute.js +395 -333
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/Scene.js.map +1 -1
- package/lib/settings/render.d.ts +11 -0
- package/lib/settings/render.js +1 -0
- package/lib/settings/render.js.map +1 -1
- package/lib/util/fromTHREE.js +21 -14
- package/lib/util/fromTHREE.js.map +1 -1
- package/lib/version.d.ts +1 -1
- package/lib/version.js +1 -1
- package/lib/version.js.map +1 -1
- package/package.json +5 -2
- package/lib/oidnBundledWeights.cdn.d.ts +0 -2
- package/lib/oidnBundledWeights.cdn.js +0 -5
- package/lib/oidnBundledWeights.cdn.js.map +0 -1
- package/lib/renderer/bvh.worker.d.ts +0 -1
- package/lib/renderer/bvh.worker.js +0 -16
- package/lib/renderer/bvh.worker.js.map +0 -1
- package/lib/renderer/bvhWorkerBuild.d.ts +0 -13
- package/lib/renderer/bvhWorkerBuild.js +0 -17
- package/lib/renderer/bvhWorkerBuild.js.map +0 -1
- package/lib/renderer/lightCore.d.ts +0 -12
- package/lib/renderer/lightCore.js +0 -13
- package/lib/renderer/lightCore.js.map +0 -1
- package/lib/renderer/materialCore.d.ts +0 -8
- package/lib/renderer/materialCore.js +0 -9
- package/lib/renderer/materialCore.js.map +0 -1
- package/lib/scene/PixelTexture.d.ts +0 -6
- package/lib/scene/PixelTexture.js +0 -10
- package/lib/scene/PixelTexture.js.map +0 -1
- package/lib/util/studioLighting.d.ts +0 -18
- package/lib/util/studioLighting.js +0 -36
- package/lib/util/studioLighting.js.map +0 -1
|
@@ -1,11 +1,13 @@
|
|
|
1
|
+
import { spectralPrefixWgsl, prefixCheckpoint, prefixSave, prefixRestore, prefixRandomBindings } from './chunks/spectralPrefix.wgsl.js';
|
|
1
2
|
import { photonQuerySource } from './photonMap.compute.js';
|
|
2
3
|
import backgroundWgsl from './chunks/background.wgsl.js';
|
|
3
4
|
import { researchTransport } from '../researchTransport.js';
|
|
4
5
|
import { causticPartitionWGSL } from './chunks/caustics.wgsl.js';
|
|
5
|
-
import {
|
|
6
|
+
import { MAX_PATH_EVENTS_WEBGL } from '../pathLimits.js';
|
|
6
7
|
import shadowCatcherAccumulationWGSL from './chunks/shadowCatcherAccumulation.wgsl.js';
|
|
7
8
|
import reflectanceWGSL from './aovReflectance.wgsl.js';
|
|
8
9
|
import aovTraceWGSL from './aovTrace.wgsl.js';
|
|
10
|
+
import aovTraceDisplayWGSL from './aovTraceDisplay.wgsl.js';
|
|
9
11
|
import depthQueryWGSL from './depthQuery.wgsl.js';
|
|
10
12
|
// Portions adapted from ray-tracing-renderer@0.10.15
|
|
11
13
|
// (https://github.com/hoverinc/ray-tracing-renderer).
|
|
@@ -29,14 +31,28 @@ import uvProjectionWgsl from './chunks/uvProjection.wgsl.js';
|
|
|
29
31
|
export const WORKGROUP_SIZE = 8;
|
|
30
32
|
/** Generates the WebGPU megakernel path tracing compute shader. */
|
|
31
33
|
export default function rayTraceCompute(options, sceneIntersections = '', pathDiagnostic = false, inputHooks) {
|
|
34
|
+
const maxPathEvents = options.maxPathEvents ?? MAX_PATH_EVENTS_WEBGL;
|
|
32
35
|
const research = researchTransport()?.compute(options);
|
|
33
36
|
const enabled = research?.enabled ?? false;
|
|
34
37
|
const partitionDepth = research?.maxDepth ?? 20;
|
|
35
38
|
const debugGroup = research?.debugGroup ?? options.debugGroup ?? -1;
|
|
36
|
-
let { hasDisplacement, workgroupSize = WORKGROUP_SIZE, lightTracing = false, photonMapping = false, photonMaxDepth = 20, hasAnisotropyDirections = false, hasCoatNormals = false, hasAlpha = true, hasSceneAlpha = true, blasLayoutMask = 1, spectral, sceneCapabilities, dynamicEnvironment = false, materialCapabilities = ALL_MATERIAL_SHADER_CAPABILITIES, lightCapabilities } = options;
|
|
39
|
+
let { compactVertices = false, hasDisplacement, workgroupSize = WORKGROUP_SIZE, lightTracing = false, photonMapping = false, photonMaxDepth = 20, hasAnisotropyDirections = false, hasCoatNormals = false, hasAlpha = true, hasSceneAlpha = true, blasLayoutMask = 1, spectral, sceneCapabilities, dynamicEnvironment = false, materialCapabilities = ALL_MATERIAL_SHADER_CAPABILITIES, lightCapabilities } = options;
|
|
37
40
|
hasAnisotropyDirections ||= hasCoatNormals;
|
|
38
41
|
const deterministicPrimaryAlpha = hasAlpha;
|
|
39
42
|
const hasShadowCatcher = sceneCapabilities === undefined || (sceneCapabilities & WGPU_SCENE_FEATURE_BITS.HAS_SHADOW_CATCHER) !== 0;
|
|
43
|
+
// MNEE can refract a wavelength-dependent connection at an ordinary receiver,
|
|
44
|
+
// before the camera path reaches any Cauchy boundary. Preserve its independent
|
|
45
|
+
// wavelength paths until a connection-solver checkpoint is available.
|
|
46
|
+
const sharePrefix = options.shareSpectralPrefix ?? false;
|
|
47
|
+
const surfacePrefix = {
|
|
48
|
+
path: ['Path', 'path'], si: ['SurfaceInteraction', '*si'], ma: ['OpenPbrResolvedMaterial', '*ma'],
|
|
49
|
+
aux: ['RayTraceAuxiliary', '*outAux'], depth: ['i32', 'depth'], event: ['i32', 'event'],
|
|
50
|
+
ignored: ['bool', 'sampleIgnored'], opaque: ['bool', 'isNotTransparent'], ...prefixRandomBindings
|
|
51
|
+
};
|
|
52
|
+
const flatPrefix = {
|
|
53
|
+
...surfacePrefix, si: ['SurfaceInteraction', 'si'], ma: ['OpenPbrResolvedMaterial', 'ma'],
|
|
54
|
+
aux: ['RayTraceAuxiliary', 'wavelengthAux']
|
|
55
|
+
};
|
|
40
56
|
const primaryVariables = /* wgsl */ `
|
|
41
57
|
var si: SurfaceInteraction;
|
|
42
58
|
var ma: OpenPbrResolvedMaterial;
|
|
@@ -65,7 +81,7 @@ return vec4f(1.0);
|
|
|
65
81
|
else {
|
|
66
82
|
if (HAS_BEVEL && rtUniform.bevel != 0) {
|
|
67
83
|
if (ma.bevel > 0.0) {
|
|
68
|
-
si.normal =
|
|
84
|
+
si.normal = kB(si, ma.bevel);
|
|
69
85
|
}
|
|
70
86
|
}
|
|
71
87
|
|
|
@@ -93,16 +109,16 @@ si.albedoSampled = ma.transmissionWeight > 0.5;
|
|
|
93
109
|
|
|
94
110
|
${commonWgsl}
|
|
95
111
|
|
|
96
|
-
${rayTraceCoreWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals, lightCapabilities, caustics: enabled || lightTracing || photonMapping })}
|
|
112
|
+
${rayTraceCoreWgsl({ independentTextures: options.independentTextures, compactVertices, cameraProjectionInverse: options.cameraProjectionInverse, hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals, lightCapabilities, caustics: enabled || lightTracing || photonMapping })}
|
|
97
113
|
|
|
98
114
|
${uvProjectionWgsl}
|
|
99
115
|
|
|
100
|
-
${createMaterialBufferWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals,
|
|
116
|
+
${createMaterialBufferWgsl({ independentTextures: options.independentTextures, hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals,
|
|
101
117
|
caustics: enabled || lightTracing || photonMapping,
|
|
102
118
|
hasTransmission: (materialCapabilities & MATERIAL_SHADER_CAPABILITIES.transmission) !== 0,
|
|
103
119
|
hasMetalness: (materialCapabilities & MATERIAL_SHADER_CAPABILITIES.metal) !== 0 })}
|
|
104
120
|
|
|
105
|
-
${createIntersectionWgsl({ hasDisplacement, blasLayoutMask, hasAnisotropyDirections, hasCoatNormals, sceneIntersections })}
|
|
121
|
+
${createIntersectionWgsl({ compactVertices, perInstanceBounds: options.perInstanceBounds, hasDisplacement, blasLayoutMask, hasAnisotropyDirections, hasCoatNormals, sceneIntersections })}
|
|
106
122
|
${randWgsl}
|
|
107
123
|
${randomWgsl}
|
|
108
124
|
${envMapWgsl}
|
|
@@ -113,35 +129,35 @@ ${createOpenPbrBsdfWgsl(hasAnisotropyDirections, hasCoatNormals)}
|
|
|
113
129
|
${sampleLightWgsl}${inputHooks?.declarations ?? ''}
|
|
114
130
|
|
|
115
131
|
|
|
116
|
-
var<private>
|
|
132
|
+
var<private> bounceIndex: u32 = 0u;
|
|
117
133
|
|
|
118
134
|
|
|
119
135
|
|
|
120
|
-
fn
|
|
136
|
+
fn kL() -> u32 {
|
|
121
137
|
return u32(max(rtUniform.directLightCandidates, 1));
|
|
122
138
|
}
|
|
123
139
|
|
|
124
140
|
|
|
125
141
|
|
|
126
142
|
|
|
127
|
-
fn
|
|
143
|
+
fn rA(AT: u32) -> f32 {
|
|
128
144
|
|
|
129
145
|
|
|
130
146
|
|
|
131
147
|
|
|
132
148
|
if (SAMPLING_PATTERN == 2) { _ = rand(); }
|
|
133
|
-
let
|
|
134
|
-
let key = ak(ak(
|
|
135
|
-
let dimension = ak(samplingBounce,
|
|
136
|
-
return f32(
|
|
149
|
+
let kT = aJ.x + aJ.y * u32(rtUniform.outputSize.x);
|
|
150
|
+
let key = ak(ak(kT, aC), rtUniform.sequenceSeed);
|
|
151
|
+
let dimension = ak(samplingBounce, AT) ^ 0xa511e9b3u;
|
|
152
|
+
return f32(cD(key ^ dimension) >> 8u) * (1.0 / 16777216.0);
|
|
137
153
|
}
|
|
138
154
|
|
|
139
155
|
|
|
140
156
|
|
|
141
|
-
fn
|
|
142
|
-
let candidateCount =
|
|
157
|
+
fn wM(lightPdf: f32, scatteringPdf: f32) -> f32 {
|
|
158
|
+
let candidateCount = kL();
|
|
143
159
|
if (candidateCount <= 1u) {
|
|
144
|
-
return
|
|
160
|
+
return aG(lightPdf, scatteringPdf);
|
|
145
161
|
}
|
|
146
162
|
let weightedLightPdf = f32(candidateCount) * lightPdf;
|
|
147
163
|
return weightedLightPdf /
|
|
@@ -149,10 +165,10 @@ max(weightedLightPdf + scatteringPdf, 1e-20);
|
|
|
149
165
|
}
|
|
150
166
|
|
|
151
167
|
|
|
152
|
-
fn
|
|
153
|
-
let candidateCount =
|
|
168
|
+
fn gm(scatteringPdf: f32, lightPdf: f32) -> f32 {
|
|
169
|
+
let candidateCount = kL();
|
|
154
170
|
if (candidateCount <= 1u) {
|
|
155
|
-
return
|
|
171
|
+
return aG(scatteringPdf, lightPdf);
|
|
156
172
|
}
|
|
157
173
|
let weightedLightPdf = f32(candidateCount) * lightPdf;
|
|
158
174
|
return scatteringPdf /
|
|
@@ -163,7 +179,7 @@ ${enabled || lightTracing || photonMapping ? causticPartitionWGSL(enabled, light
|
|
|
163
179
|
const CAUSTIC_MNEE=${enabled};
|
|
164
180
|
const CAUSTIC_MNEE_MAX_DEPTH=${partitionDepth}u;
|
|
165
181
|
const CAUSTIC_PHOTON_MAX_DEPTH=${photonMaxDepth}u;
|
|
166
|
-
` + photonQuerySource(debugGroup, !lightTracing && (options.photonDirectSubset ?? true)) : ''}${createSampleMaterialWgsl(hasAnisotropyDirections, hasCoatNormals, enabled || lightTracing || photonMapping, research?.contribution, photonMapping)}
|
|
182
|
+
` + photonQuerySource(debugGroup, !lightTracing && (options.photonDirectSubset ?? true)) : ''}${createSampleMaterialWgsl(hasAnisotropyDirections, hasCoatNormals, enabled || lightTracing || photonMapping, research?.contribution, photonMapping, options.channelIndependentRis)}
|
|
167
183
|
${sampleShadowCatcherWgsl}
|
|
168
184
|
|
|
169
185
|
|
|
@@ -175,24 +191,24 @@ ${shadowCatcherAccumulationWGSL}
|
|
|
175
191
|
@group(3) @binding(3) var<storage, read_write> outShadowCatcher: array<ShadowCatcherAccumulation>;
|
|
176
192
|
|
|
177
193
|
|
|
178
|
-
fn
|
|
179
|
-
|
|
194
|
+
fn ij(
|
|
195
|
+
gx: u32,
|
|
180
196
|
radiance: vec3f,
|
|
181
197
|
normal: vec3f
|
|
182
198
|
) {
|
|
183
199
|
if (rtUniform.varianceMoments != 0) {
|
|
184
200
|
let value = dot(radiance, luminance);
|
|
185
|
-
outNormal[
|
|
201
|
+
outNormal[gx] += vec4f(value * value, 0.0, 0.0, 1.0);
|
|
186
202
|
}
|
|
187
203
|
else {
|
|
188
|
-
outNormal[
|
|
204
|
+
outNormal[gx] += vec4f(normal, 1.0);
|
|
189
205
|
}
|
|
190
206
|
}
|
|
191
207
|
|
|
192
208
|
|
|
193
209
|
|
|
194
|
-
fn
|
|
195
|
-
outShadowCatcher[
|
|
210
|
+
fn ju(gx: u32, value: f32) {
|
|
211
|
+
outShadowCatcher[gx].moments += vec4f(value, value * value, 0.0, 0.0);
|
|
196
212
|
}
|
|
197
213
|
|
|
198
214
|
|
|
@@ -206,8 +222,8 @@ isBlank: bool,
|
|
|
206
222
|
shadowCounts: vec2f,
|
|
207
223
|
}
|
|
208
224
|
|
|
209
|
-
${backgroundWgsl}fn
|
|
210
|
-
let bg =
|
|
225
|
+
${backgroundWgsl}fn cS(ray: Ray, channel: i32) -> vec4f {
|
|
226
|
+
let bg = fI(ray);
|
|
211
227
|
if (SPECTRAL) {
|
|
212
228
|
return vec4f(sampling_spectral_rgb_filter(bg.rgb, channel), bg.a);
|
|
213
229
|
}
|
|
@@ -216,8 +232,8 @@ return bg;
|
|
|
216
232
|
|
|
217
233
|
|
|
218
234
|
|
|
219
|
-
fn
|
|
220
|
-
*
|
|
235
|
+
fn mD(uv: vec2f, path: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>, fg: ptr<function, bool>) {
|
|
236
|
+
*fg = false;
|
|
221
237
|
samplingBounce = u32(max(*depth, 0));
|
|
222
238
|
let matType = (*ma).materialType;
|
|
223
239
|
let isShadowCatcher = ${hasShadowCatcher ? /* wgsl */ `matType == SHADOW_CATCHER` : /* wgsl */ `false`};
|
|
@@ -233,28 +249,28 @@ if (USE_ENVMAP) {
|
|
|
233
249
|
if ((*path).isNextRefraction) {
|
|
234
250
|
|
|
235
251
|
|
|
236
|
-
let bg =
|
|
252
|
+
let bg = cS(
|
|
237
253
|
(*path).ray,
|
|
238
254
|
(*si).spectralChannel
|
|
239
255
|
);
|
|
240
|
-
let
|
|
241
|
-
envMapPdf(
|
|
256
|
+
let cP = select(gm((*path).scatteringPdf,
|
|
257
|
+
envMapPdf(cU((*path).ray.d)) * rtUniform.envLightPmf),
|
|
242
258
|
1.0, (*path).scatteringIsDelta);
|
|
243
|
-
(*path).li +=
|
|
259
|
+
(*path).li += cP * (*path).beta * bg.rgb * bg.a;
|
|
244
260
|
(*path).alpha = max((*path).alpha, bg.a);
|
|
245
261
|
}
|
|
246
262
|
else {
|
|
247
|
-
let
|
|
248
|
-
var emission = textureLinear(envMap,
|
|
263
|
+
let xp = cU((*path).ray.d);
|
|
264
|
+
var emission = textureLinear(envMap, xp).rgb;
|
|
249
265
|
if (SPECTRAL) {
|
|
250
266
|
emission = sampling_spectral_rgb_filter(emission, (*si).spectralChannel);
|
|
251
267
|
}
|
|
252
268
|
(*path).li += (*path).beta * emission *
|
|
253
|
-
|
|
269
|
+
gm((*path).scatteringPdf, envMapPdf(xp));
|
|
254
270
|
}
|
|
255
271
|
}
|
|
256
272
|
else {
|
|
257
|
-
let bg =
|
|
273
|
+
let bg = cS(
|
|
258
274
|
(*path).ray,
|
|
259
275
|
(*si).spectralChannel
|
|
260
276
|
);
|
|
@@ -268,7 +284,7 @@ if (!(*si).hit) {
|
|
|
268
284
|
|
|
269
285
|
|
|
270
286
|
|
|
271
|
-
let bg =
|
|
287
|
+
let bg = cS(
|
|
272
288
|
(*path).ray,
|
|
273
289
|
(*si).spectralChannel
|
|
274
290
|
);
|
|
@@ -281,10 +297,10 @@ if ((*path).fromEye) {
|
|
|
281
297
|
(USE_BACKGROUND && !USE_BACKGROUND_MAP);
|
|
282
298
|
}
|
|
283
299
|
else {
|
|
284
|
-
let cam =
|
|
285
|
-
let
|
|
300
|
+
let cam = cV(uv);
|
|
301
|
+
let ou = dot(cam.d, (*path).ray.d) > 0.0;
|
|
286
302
|
if (rtUniform.transmissiveOutputAlphaMin < 1.0) {
|
|
287
|
-
if (
|
|
303
|
+
if (ou) {
|
|
288
304
|
(*path).alpha = max((*path).alpha, bg.a);
|
|
289
305
|
} else {
|
|
290
306
|
(*path).alpha = 1.0;
|
|
@@ -293,11 +309,11 @@ if (nt) {
|
|
|
293
309
|
if (!USE_ENVMAP) {
|
|
294
310
|
|
|
295
311
|
|
|
296
|
-
if (
|
|
312
|
+
if (ou) {
|
|
297
313
|
|
|
298
314
|
|
|
299
315
|
(*path).li += (*path).beta *
|
|
300
|
-
|
|
316
|
+
gm((*path).scatteringPdf, 1.0) * bg.rgb;
|
|
301
317
|
}
|
|
302
318
|
}
|
|
303
319
|
}
|
|
@@ -312,19 +328,19 @@ let alpha = clamp((*ma).alpha, 0.0, 1.0);
|
|
|
312
328
|
if (alpha < 1.0) {
|
|
313
329
|
|
|
314
330
|
|
|
315
|
-
if (alpha <= 0.0 ||
|
|
316
|
-
(*
|
|
331
|
+
if (alpha <= 0.0 || cm(3u) > alpha) {
|
|
332
|
+
(*fg) = true;
|
|
317
333
|
}
|
|
318
334
|
}
|
|
319
|
-
if (!(*
|
|
335
|
+
if (!(*fg) && rtUniform.transmissiveOutputAlphaMin < 1.0) {
|
|
320
336
|
|
|
321
337
|
|
|
322
338
|
let outputAlpha = max(1.0 - (*ma).transmissionWeight, 1.0 - pow(1.0 - rtUniform.transmissiveOutputAlphaMin, f32(*depth)));
|
|
323
339
|
(*path).alpha = max(outputAlpha, (*path).alpha);
|
|
324
340
|
}
|
|
325
|
-
if (!(*
|
|
326
|
-
|
|
327
|
-
|
|
341
|
+
if (!(*fg)) {
|
|
342
|
+
bounceIndex = u32(max(*depth, 0));
|
|
343
|
+
nB(si, ma, path);
|
|
328
344
|
}
|
|
329
345
|
else {
|
|
330
346
|
|
|
@@ -333,7 +349,7 @@ else {
|
|
|
333
349
|
}
|
|
334
350
|
}
|
|
335
351
|
|
|
336
|
-
if (!(*si).albedoSampled && !(*
|
|
352
|
+
if (!(*si).albedoSampled && !(*fg)) {
|
|
337
353
|
|
|
338
354
|
if ((matType == STANDARD || matType == UNLIT)) {
|
|
339
355
|
if (!((*ma).transmissionWeight > 0.5 ||
|
|
@@ -358,12 +374,12 @@ if (*depth > 4) {
|
|
|
358
374
|
|
|
359
375
|
|
|
360
376
|
if (USE_RR) {
|
|
361
|
-
if (*depth >= RR_MAX && !(*
|
|
362
|
-
let
|
|
377
|
+
if (*depth >= select(2, RR_MAX, (*path).scatteringMediumEntered) && !(*fg)) {
|
|
378
|
+
let qv = (*path).beta;
|
|
363
379
|
|
|
364
|
-
let
|
|
365
|
-
let q: f32 = max(0.0, 1.0 -
|
|
366
|
-
if (sample1D(
|
|
380
|
+
let ql = max(max(qv.x, qv.y), qv.z);
|
|
381
|
+
let q: f32 = max(0.0, 1.0 - ql);
|
|
382
|
+
if (sample1D(aX(RUSSIAN_ROULETTE)) < q) {
|
|
367
383
|
|
|
368
384
|
|
|
369
385
|
(*path).alpha = 1.0;
|
|
@@ -381,7 +397,7 @@ return;
|
|
|
381
397
|
|
|
382
398
|
}
|
|
383
399
|
|
|
384
|
-
fn
|
|
400
|
+
fn gN(path: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, sampleIgnored: bool) {
|
|
385
401
|
if (SPECTRAL) {
|
|
386
402
|
|
|
387
403
|
if ((*ma).transmissionWeight > 0.001) {
|
|
@@ -394,21 +410,21 @@ if ((*ma).transmissionWeight > 0.001) {
|
|
|
394
410
|
}
|
|
395
411
|
}
|
|
396
412
|
|
|
397
|
-
if (
|
|
413
|
+
if (sampleIgnored) {
|
|
398
414
|
return;
|
|
399
415
|
}
|
|
400
416
|
|
|
401
417
|
|
|
402
418
|
var lightSample: LightSampleRec;
|
|
403
|
-
let
|
|
419
|
+
let hN = cm(3u) < (*ma).alpha;
|
|
404
420
|
for (var i = 0; i < rtUniform.lightsCount; i++) {
|
|
405
421
|
|
|
406
422
|
let light: Light = analyticLights[i];
|
|
407
|
-
let d =
|
|
423
|
+
let d = iB((*path).ray, light, &lightSample);
|
|
408
424
|
lightSample.pdf *= light.selectionPmf;
|
|
409
|
-
let
|
|
410
|
-
if (d != INF && !(
|
|
411
|
-
let misWeight =
|
|
425
|
+
let mz = (*si).hit && d > distance((*si).position, (*path).ray.o);
|
|
426
|
+
if (d != INF && !(mz && hN)) {
|
|
427
|
+
let misWeight = gm((*path).scatteringPdf, lightSample.pdf);
|
|
412
428
|
if (SPECTRAL) {
|
|
413
429
|
lightSample.emission = sampling_spectral_rgb_filter(lightSample.emission, (*si).spectralChannel);
|
|
414
430
|
}
|
|
@@ -419,27 +435,27 @@ ${enabled || lightTracing || photonMapping ? 'if (!causticHitOwned(*path, true,
|
|
|
419
435
|
}
|
|
420
436
|
|
|
421
437
|
if (USE_ENVMAP) {
|
|
422
|
-
if (!((*si).hit &&
|
|
438
|
+
if (!((*si).hit && hN)) {${lightTracing || photonMapping ? /* wgsl */ `
|
|
423
439
|
if(causticHitOwned(*path,false,true)){(*path).abort=true;return;}` : ''}
|
|
424
440
|
if ((*path).isNextRefraction) {
|
|
425
441
|
|
|
426
442
|
|
|
427
443
|
|
|
428
|
-
let bg =
|
|
444
|
+
let bg = cS(
|
|
429
445
|
(*path).ray,
|
|
430
446
|
(*si).spectralChannel
|
|
431
447
|
);
|
|
432
|
-
let
|
|
433
|
-
envMapPdf(
|
|
448
|
+
let cP = select(gm((*path).scatteringPdf,
|
|
449
|
+
envMapPdf(cU((*path).ray.d)) * rtUniform.envLightPmf),
|
|
434
450
|
1.0, (*path).scatteringIsDelta);
|
|
435
|
-
(*path).li +=
|
|
451
|
+
(*path).li += cP * (*path).beta * bg.rgb * bg.a;
|
|
436
452
|
(*path).alpha = max((*path).alpha, bg.a);
|
|
437
453
|
(*path).abort = true;
|
|
438
454
|
return;
|
|
439
455
|
}
|
|
440
|
-
let _uv =
|
|
456
|
+
let _uv = cU((*path).ray.d);
|
|
441
457
|
var emission = textureLinear(envMap, _uv).rgb;
|
|
442
|
-
let misWeight =
|
|
458
|
+
let misWeight = gm(
|
|
443
459
|
(*path).scatteringPdf,
|
|
444
460
|
envMapPdf(_uv) * rtUniform.envLightPmf
|
|
445
461
|
);
|
|
@@ -458,40 +474,52 @@ if (!USE_BACKGROUND) {
|
|
|
458
474
|
*depth = *depth + 1;
|
|
459
475
|
}
|
|
460
476
|
|
|
461
|
-
|
|
477
|
+
${options.cameraProjectionInverse ? /* wgsl */ `
|
|
478
|
+
fn cV(coord: vec2f) -> Ray {
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
let origin = cameraUniform.projectionInv * vec4f(coord * 2.0 - 1.0, -1.0, 1.0);
|
|
482
|
+
let center = cameraUniform.projectionInv * vec4f(coord * 2.0 - 1.0, 1.0, 1.0);
|
|
483
|
+
let direction = center.xyz * origin.w - origin.xyz * center.w;
|
|
484
|
+
var cam: Ray;
|
|
485
|
+
initRay(&cam, (cameraUniform.viewInv * vec4f(origin.xyz / origin.w, 1.0)).xyz,
|
|
486
|
+
normalize((cameraUniform.viewInv * vec4f(direction, 0.0)).xyz));
|
|
487
|
+
return cam;
|
|
488
|
+
}
|
|
489
|
+
` : /* wgsl */ `fn cV(coord: vec2f) -> Ray {
|
|
462
490
|
let origin = cameraUniform.viewProjectionInv * vec4f(coord * 2.0 - 1.0, -1.0, 1.0);
|
|
463
491
|
let center = cameraUniform.viewProjectionInv * vec4f(coord * 2.0 - 1.0, 1.0, 1.0);
|
|
464
492
|
var cam: Ray;
|
|
465
493
|
initRay(&cam, origin.xyz / origin.w, normalize(center.xyz * origin.w - origin.xyz * center.w));
|
|
466
494
|
|
|
467
495
|
return cam;
|
|
468
|
-
}
|
|
496
|
+
}`}
|
|
469
497
|
|
|
470
498
|
|
|
471
|
-
fn
|
|
499
|
+
fn lD(radius: f32, xi: f32) -> vec2f {
|
|
472
500
|
var x = 0.25;
|
|
473
501
|
for (var iteration = 0; iteration < 10; iteration++) {
|
|
474
502
|
let x2 = x * x;
|
|
475
503
|
let x3 = x2 * x;
|
|
476
|
-
let
|
|
504
|
+
let lU = 1.0 - x;
|
|
477
505
|
let value = 10.0 * x2 - 20.0 * x3 + 15.0 * x2 * x2 -
|
|
478
506
|
4.0 * x2 * x3 - xi;
|
|
479
|
-
let
|
|
480
|
-
if (abs(value) < 1e-6 ||
|
|
481
|
-
x = clamp(x - value /
|
|
507
|
+
let nL = 20.0 * x * lU * lU * lU;
|
|
508
|
+
if (abs(value) < 1e-6 || nL == 0.0) { break; }
|
|
509
|
+
x = clamp(x - value / nL, 0.0, 1.0);
|
|
482
510
|
}
|
|
483
|
-
let
|
|
484
|
-
return vec2f(
|
|
511
|
+
let jW = x * radius;
|
|
512
|
+
return vec2f(jW, sqrt(max(radius * radius - jW * jW, 0.0)));
|
|
485
513
|
}
|
|
486
514
|
|
|
487
|
-
fn bevelCubicPdf(radius: f32,
|
|
488
|
-
if (
|
|
489
|
-
let falloff = radius -
|
|
515
|
+
fn bevelCubicPdf(radius: f32, gO: f32) -> f32 {
|
|
516
|
+
if (gO >= radius) { return 0.0; }
|
|
517
|
+
let falloff = radius - gO;
|
|
490
518
|
return falloff * falloff * falloff;
|
|
491
519
|
}
|
|
492
520
|
|
|
493
521
|
|
|
494
|
-
fn
|
|
522
|
+
fn kB(source: SurfaceInteraction, radius: f32) -> vec3f {
|
|
495
523
|
var geometricNormal = source.faceNormal;
|
|
496
524
|
if (dot(geometricNormal, source.vertexNormal) < 0.0) {
|
|
497
525
|
geometricNormal = -geometricNormal;
|
|
@@ -499,78 +527,78 @@ geometricNormal = -geometricNormal;
|
|
|
499
527
|
var tangent: vec3f;
|
|
500
528
|
var bitangent: vec3f;
|
|
501
529
|
sampling_orthonormal_basis(geometricNormal, &tangent, &bitangent);
|
|
502
|
-
var
|
|
503
|
-
|
|
504
|
-
for (var
|
|
505
|
-
let
|
|
506
|
-
var
|
|
507
|
-
let
|
|
508
|
-
var
|
|
509
|
-
var
|
|
510
|
-
var
|
|
511
|
-
var
|
|
512
|
-
var
|
|
513
|
-
var
|
|
514
|
-
if (
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
else if (
|
|
518
|
-
let
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
530
|
+
var jd = vec3f(0.0);
|
|
531
|
+
|
|
532
|
+
for (var iN = 0; iN < BEVEL_SAMPLES; iN++) {
|
|
533
|
+
let rh = sample2D(CAMERA_BEVEL_BASE + u32(iN));
|
|
534
|
+
var cu = rh.x;
|
|
535
|
+
let qt = rh.y;
|
|
536
|
+
var dc = geometricNormal;
|
|
537
|
+
var fU = tangent;
|
|
538
|
+
var eo = bitangent;
|
|
539
|
+
var gw = 0.5;
|
|
540
|
+
var iH = 0.25;
|
|
541
|
+
var gV = 0.25;
|
|
542
|
+
if (cu < 0.5) {
|
|
543
|
+
cu *= 2.0;
|
|
544
|
+
}
|
|
545
|
+
else if (cu < 0.75) {
|
|
546
|
+
let os = dc;
|
|
547
|
+
dc = fU;
|
|
548
|
+
fU = os;
|
|
549
|
+
gw = 0.25;
|
|
550
|
+
iH = 0.5;
|
|
551
|
+
cu = (cu - 0.5) * 4.0;
|
|
524
552
|
}
|
|
525
553
|
else {
|
|
526
|
-
let
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
}
|
|
533
|
-
|
|
534
|
-
let
|
|
535
|
-
let phi = TWOPI *
|
|
536
|
-
let
|
|
537
|
-
(cos(phi) *
|
|
554
|
+
let os = dc;
|
|
555
|
+
dc = eo;
|
|
556
|
+
eo = os;
|
|
557
|
+
gw = 0.25;
|
|
558
|
+
gV = 0.5;
|
|
559
|
+
cu = (cu - 0.75) * 4.0;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
let hm = lD(radius, qt);
|
|
563
|
+
let phi = TWOPI * cu;
|
|
564
|
+
let sI = hm.x *
|
|
565
|
+
(cos(phi) * fU + sin(phi) * eo);
|
|
538
566
|
var ray: Ray;
|
|
539
567
|
initRay(
|
|
540
568
|
&ray,
|
|
541
|
-
source.position +
|
|
542
|
-
-
|
|
569
|
+
source.position + dc * hm.y + sI,
|
|
570
|
+
-dc
|
|
543
571
|
);
|
|
544
572
|
var hit: SurfaceInteraction;
|
|
545
573
|
intersectSceneBevel(
|
|
546
574
|
ray,
|
|
547
575
|
&hit,
|
|
548
576
|
source.instanceIndex,
|
|
549
|
-
max(2.0 *
|
|
577
|
+
max(2.0 * hm.y, EPS)
|
|
550
578
|
);
|
|
551
579
|
if (!hit.hit) { continue; }
|
|
552
580
|
|
|
553
|
-
let
|
|
554
|
-
let
|
|
555
|
-
let
|
|
556
|
-
var weight =
|
|
557
|
-
|
|
558
|
-
|
|
581
|
+
let lV = gw * abs(dot(dc, hit.faceNormal));
|
|
582
|
+
let oi = iH * abs(dot(fU, hit.faceNormal));
|
|
583
|
+
let kR = gV * abs(dot(eo, hit.faceNormal));
|
|
584
|
+
var weight = lV / max(
|
|
585
|
+
lV * lV + oi * oi +
|
|
586
|
+
kR * kR,
|
|
559
587
|
1e-8
|
|
560
588
|
);
|
|
561
589
|
weight *= bevelCubicPdf(radius, distance(hit.position, source.position)) /
|
|
562
|
-
max(bevelCubicPdf(radius,
|
|
563
|
-
|
|
590
|
+
max(bevelCubicPdf(radius, hm.x), 1e-8);
|
|
591
|
+
jd += weight * hit.vertexNormal;
|
|
564
592
|
}
|
|
565
593
|
|
|
566
|
-
if (dot(
|
|
567
|
-
let
|
|
568
|
-
let result = source.normal +
|
|
594
|
+
if (dot(jd, jd) <= 1e-12) { return source.normal; }
|
|
595
|
+
let kt = normalize(jd);
|
|
596
|
+
let result = source.normal + kt - source.vertexNormal;
|
|
569
597
|
if (dot(result, result) > 1e-12) { return normalize(result); }
|
|
570
598
|
return source.normal;
|
|
571
599
|
}
|
|
572
600
|
|
|
573
|
-
fn
|
|
601
|
+
${sharePrefix ? spectralPrefixWgsl(!enabled) + prefixCheckpoint('spSurface', surfacePrefix) + prefixCheckpoint('spFlat', flatPrefix) : ''}fn cJ(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>, initialQuery: bool) -> vec4f {
|
|
574
602
|
var path: Path;
|
|
575
603
|
path.ray = ray;
|
|
576
604
|
path.li = vec3f(0.0);
|
|
@@ -583,112 +611,124 @@ path.isNextRefraction = false;
|
|
|
583
611
|
path.abort = false;
|
|
584
612
|
|
|
585
613
|
let bounceLimit = max(rtUniform.bounces, 0);
|
|
586
|
-
let
|
|
614
|
+
let fj = min(bounceLimit * 3, ${maxPathEvents});
|
|
587
615
|
var depth = 0;
|
|
588
|
-
var
|
|
589
|
-
var
|
|
590
|
-
|
|
616
|
+
var sampleIgnored = false;
|
|
617
|
+
var isNotTransparent = false;
|
|
618
|
+
${sharePrefix ? /* wgsl */ ` let spSlot = qz; qz++;
|
|
619
|
+
if (spActive && spChannel > 1 && eB[spSlot].ready) { return rN(spSlot, outAux); }
|
|
620
|
+
var spEvent = 0; var spResume = false;
|
|
621
|
+
if (spActive && spChannel > 1 && fC == spSlot) {
|
|
622
|
+
var event = 0;
|
|
623
|
+
${prefixRestore('spSurface', surfacePrefix)}
|
|
624
|
+
spEvent = event; spResume = true; qA(&path, si);
|
|
625
|
+
} else if (sd) { (*si).spectralChannel = select(spChannel, 0, spActive); (*si).wavelength = lg; }
|
|
626
|
+
` : ''}
|
|
591
627
|
|
|
592
628
|
|
|
593
629
|
|
|
594
|
-
for (var event = 0; event <=
|
|
595
|
-
if ((event != 0) |
|
|
630
|
+
for (var event = ${sharePrefix ? 'spEvent' : '0'}; event <= fj; event++) {
|
|
631
|
+
if (${sharePrefix ? '!spResume && ((event != 0) | initialQuery)' : '(event != 0) | initialQuery'}) {
|
|
596
632
|
intersectScene(path.ray, si, depth, event != 0, path.isNextRefraction);
|
|
597
633
|
getMaterial(ma, (*si).materialIndex, (*si).uv, (*si).uv1, (*si).instanceIndex, (*si).vertexColor);
|
|
598
634
|
}
|
|
599
635
|
if (event == 0) {
|
|
600
|
-
if (
|
|
636
|
+
if (initialQuery & (*si).hit & ((*ma).materialType == STANDARD)) {
|
|
601
637
|
(*outAux).albedo = select((*ma).baseColor, vec3f(1.0), (*ma).transmissionWeight > 0.5);
|
|
602
638
|
(*outAux).normal = select((*si).normal, -(*si).normal,
|
|
603
639
|
dot((*si).normal, (*si).position - cameraUniform.viewInv[3].xyz) > 0.0);
|
|
604
640
|
(*si).albedoSampled = (*ma).transmissionWeight > 0.5;
|
|
605
641
|
}
|
|
606
|
-
|
|
607
|
-
} else {
|
|
608
|
-
|
|
609
|
-
}
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
642
|
+
isNotTransparent = ((*ma).transmissionWeight < 0.001) & ((*ma).subsurfaceWeight < 0.001) & ((*ma).alpha > 0.99);
|
|
643
|
+
} else {${sharePrefix ? /* wgsl */ `
|
|
644
|
+
if (spActive && (*ma).transmissionWeight > 0.001 && gf(*ma)) {
|
|
645
|
+
${prefixSave('spSurface', surfacePrefix)}
|
|
646
|
+
fC = spSlot; qA(&path, si);
|
|
647
|
+
}` : ''}
|
|
648
|
+
gN(&path, &depth, si, ma, sampleIgnored);
|
|
649
|
+
}
|
|
650
|
+
${sharePrefix ? ' spResume = false;\n' : ''} if (isNotTransparent & (event > bounceLimit)) { path.abort = true; }
|
|
651
|
+
if (path.abort | (event >= fj)) { break; }
|
|
652
|
+
mD(uv, &path, &depth, si, ma, outAux, &sampleIgnored);
|
|
613
653
|
if (path.abort) { break; }
|
|
614
654
|
}
|
|
615
655
|
|
|
616
|
-
return vec4f(path.li, path.alpha);
|
|
656
|
+
return ${sharePrefix ? 'spFinish(spSlot, vec4f(path.li, path.alpha), *outAux)' : 'vec4f(path.li, path.alpha)'};
|
|
617
657
|
}
|
|
618
658
|
|
|
619
|
-
fn
|
|
659
|
+
fn jb(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
620
660
|
${deterministicPrimaryAlpha ? /* wgsl */ `let coverage = clamp((*ma).alpha, 0.0, 1.0);
|
|
621
661
|
|
|
622
662
|
|
|
623
663
|
|
|
624
664
|
|
|
625
665
|
let split = (*si).hit & (((*ma).materialType == STANDARD) | ((*ma).materialType == UNLIT)) & (coverage < 1.0);
|
|
626
|
-
var
|
|
627
|
-
var
|
|
628
|
-
var
|
|
629
|
-
var
|
|
666
|
+
var tT = ray;
|
|
667
|
+
var uW = *si;
|
|
668
|
+
var uV = *ma;
|
|
669
|
+
var iX = *outAux;
|
|
630
670
|
if (split) {
|
|
631
|
-
|
|
632
|
-
|
|
671
|
+
tT.o = (*si).position + ray.d * (EPS * 0.02);
|
|
672
|
+
uW.albedoSampled = false;
|
|
633
673
|
}
|
|
634
674
|
var back: vec4f;
|
|
635
|
-
var
|
|
675
|
+
var backAux: RayTraceAuxiliary;
|
|
636
676
|
|
|
637
677
|
|
|
638
|
-
let
|
|
639
|
-
for (var
|
|
640
|
-
let result =
|
|
641
|
-
if (!split | (coverage <= 0.0)) { *outAux =
|
|
642
|
-
if (
|
|
643
|
-
back = result;
|
|
644
|
-
|
|
645
|
-
|
|
678
|
+
let xh = select(1u, rtUniform.loopUnrollGuard >> 1u, split & (coverage > 0.0));
|
|
679
|
+
for (var wv = 0u; wv < xh; wv++) {
|
|
680
|
+
let result = cJ(uv, &uW, tT, &uV, &iX, split & (wv == 0u));
|
|
681
|
+
if (!split | (coverage <= 0.0)) { *outAux = iX; return result; }
|
|
682
|
+
if (wv == 0u) {
|
|
683
|
+
back = result; backAux = iX;
|
|
684
|
+
uW = *si; uV = *ma; uV.alpha = 1.0;
|
|
685
|
+
tT = ray; iX = *outAux;
|
|
646
686
|
} else {
|
|
647
|
-
(*outAux).albedo = mix(
|
|
648
|
-
let
|
|
649
|
-
(*outAux).normal = select(vec3f(0.0), normalize(
|
|
650
|
-
(*outAux).isBlank =
|
|
651
|
-
(*outAux).isShadowCatcher =
|
|
652
|
-
(*outAux).shadowCounts = mix(
|
|
687
|
+
(*outAux).albedo = mix(backAux.albedo, iX.albedo, coverage);
|
|
688
|
+
let aS = mix(backAux.normal, iX.normal, coverage);
|
|
689
|
+
(*outAux).normal = select(vec3f(0.0), normalize(aS), dot(aS, aS) > 1e-12);
|
|
690
|
+
(*outAux).isBlank = backAux.isBlank & iX.isBlank;
|
|
691
|
+
(*outAux).isShadowCatcher = backAux.isShadowCatcher & iX.isShadowCatcher;
|
|
692
|
+
(*outAux).shadowCounts = mix(backAux.shadowCounts, iX.shadowCounts, coverage);
|
|
653
693
|
return mix(back, result, coverage);
|
|
654
694
|
}
|
|
655
695
|
}
|
|
656
|
-
return vec4f(0.0);` : /* wgsl */ `return
|
|
696
|
+
return vec4f(0.0);` : /* wgsl */ `return cJ(uv, si, ray, ma, outAux, false);`}
|
|
657
697
|
}
|
|
658
698
|
|
|
659
699
|
|
|
660
700
|
|
|
661
|
-
${spectral === false && deterministicPrimaryAlpha ? /* wgsl */ `fn
|
|
701
|
+
${spectral === false && deterministicPrimaryAlpha ? /* wgsl */ `fn hq(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
662
702
|
${primaryVariables}
|
|
663
|
-
var
|
|
664
|
-
var
|
|
665
|
-
var
|
|
666
|
-
var
|
|
703
|
+
var primarySi: SurfaceInteraction;
|
|
704
|
+
var primaryMa: OpenPbrResolvedMaterial;
|
|
705
|
+
var vR: RayTraceAuxiliary;
|
|
706
|
+
var jg = false;
|
|
667
707
|
var query = true;
|
|
668
708
|
var split = false;
|
|
669
709
|
var coverage = 1.0;
|
|
670
710
|
var front = false;
|
|
671
711
|
var back: vec4f;
|
|
672
|
-
var
|
|
712
|
+
var backAux: RayTraceAuxiliary;
|
|
673
713
|
var path: Path; path.ray = ray;
|
|
674
714
|
path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
675
715
|
path.beta = vec3f(1.0); path.fromEye = true;
|
|
676
716
|
let bounceLimit = max(rtUniform.bounces, 0);
|
|
677
|
-
let
|
|
678
|
-
var event = 0; var depth = 0; var
|
|
679
|
-
var
|
|
717
|
+
let fj = min(bounceLimit * 3, ${maxPathEvents});
|
|
718
|
+
var event = 0; var depth = 0; var sampleIgnored = false;
|
|
719
|
+
var isNotTransparent = false;
|
|
680
720
|
|
|
681
721
|
|
|
682
|
-
for (var step = 0; step < (${
|
|
722
|
+
for (var step = 0; step < (${maxPathEvents} + 1) * 2 + 2; step++) {
|
|
683
723
|
if (query) {
|
|
684
724
|
intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
|
|
685
725
|
getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
686
726
|
}
|
|
687
727
|
query = true;
|
|
688
|
-
if (!
|
|
728
|
+
if (!jg) {
|
|
689
729
|
${primaryGuides}
|
|
690
|
-
|
|
691
|
-
|
|
730
|
+
primarySi = si; primaryMa = ma; vR = *outAux;
|
|
731
|
+
jg = true;
|
|
692
732
|
coverage = clamp(ma.alpha, 0.0, 1.0);
|
|
693
733
|
split = si.hit & ((ma.materialType == STANDARD) | (ma.materialType == UNLIT)) & (coverage < 1.0);
|
|
694
734
|
if (split) {
|
|
@@ -705,36 +745,36 @@ si.albedoSampled = ma.transmissionWeight > 0.5;
|
|
|
705
745
|
}
|
|
706
746
|
}
|
|
707
747
|
if (event == 0) {
|
|
708
|
-
|
|
748
|
+
isNotTransparent = (ma.transmissionWeight < 0.001) & (ma.subsurfaceWeight < 0.001) & (ma.alpha > 0.99);
|
|
709
749
|
} else {
|
|
710
|
-
|
|
750
|
+
gN(&path, &depth, &si, &ma, sampleIgnored);
|
|
711
751
|
}
|
|
712
|
-
if (
|
|
713
|
-
if (!path.abort & (event <
|
|
714
|
-
|
|
752
|
+
if (isNotTransparent & (event > bounceLimit)) { path.abort = true; }
|
|
753
|
+
if (!path.abort & (event < fj)) {
|
|
754
|
+
mD(uv, &path, &depth, &si, &ma, outAux, &sampleIgnored);
|
|
715
755
|
}
|
|
716
|
-
if (path.abort | (event >=
|
|
756
|
+
if (path.abort | (event >= fj)) {
|
|
717
757
|
let result = vec4f(path.li, path.alpha);
|
|
718
758
|
if (!split | (coverage <= 0.0)) { return result; }
|
|
719
759
|
if (front) {
|
|
720
|
-
(*outAux).albedo = mix(
|
|
721
|
-
let
|
|
722
|
-
(*outAux).normal = select(vec3f(0.0), normalize(
|
|
723
|
-
(*outAux).isBlank =
|
|
724
|
-
(*outAux).isShadowCatcher =
|
|
725
|
-
(*outAux).shadowCounts = mix(
|
|
760
|
+
(*outAux).albedo = mix(backAux.albedo, (*outAux).albedo, coverage);
|
|
761
|
+
let aS = mix(backAux.normal, (*outAux).normal, coverage);
|
|
762
|
+
(*outAux).normal = select(vec3f(0.0), normalize(aS), dot(aS, aS) > 1e-12);
|
|
763
|
+
(*outAux).isBlank = backAux.isBlank & (*outAux).isBlank;
|
|
764
|
+
(*outAux).isShadowCatcher = backAux.isShadowCatcher & (*outAux).isShadowCatcher;
|
|
765
|
+
(*outAux).shadowCounts = mix(backAux.shadowCounts, (*outAux).shadowCounts, coverage);
|
|
726
766
|
return mix(back, result, coverage);
|
|
727
767
|
}
|
|
728
|
-
back = result;
|
|
729
|
-
front = true; query = false; event = 0; depth = 0;
|
|
730
|
-
si =
|
|
768
|
+
back = result; backAux = *outAux;
|
|
769
|
+
front = true; query = false; event = 0; depth = 0; sampleIgnored = false;
|
|
770
|
+
si = primarySi; ma = primaryMa; ma.alpha = 1.0; *outAux = vR;
|
|
731
771
|
path = Path(); path.ray = ray; path.beta = vec3f(1.0); path.fromEye = true;
|
|
732
772
|
path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
733
773
|
} else { event++; }
|
|
734
774
|
}
|
|
735
775
|
return vec4f(0.0);
|
|
736
776
|
}
|
|
737
|
-
` : spectral === false && !deterministicPrimaryAlpha ? /* wgsl */ `fn
|
|
777
|
+
` : spectral === false && !deterministicPrimaryAlpha ? /* wgsl */ `fn hq(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
738
778
|
${primaryVariables}
|
|
739
779
|
var path: Path;
|
|
740
780
|
path.ray = ray;
|
|
@@ -742,113 +782,133 @@ path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
|
742
782
|
path.beta = vec3f(1.0);
|
|
743
783
|
path.fromEye = true;
|
|
744
784
|
let bounceLimit = max(rtUniform.bounces, 0);
|
|
745
|
-
let
|
|
746
|
-
var
|
|
785
|
+
let fj = min(bounceLimit * 3, ${maxPathEvents});
|
|
786
|
+
var isNotTransparent = false;
|
|
747
787
|
var depth = 0;
|
|
748
|
-
var
|
|
788
|
+
var sampleIgnored = false;
|
|
749
789
|
|
|
750
790
|
|
|
751
791
|
|
|
752
|
-
for (var event = 0; event <=
|
|
792
|
+
for (var event = 0; event <= fj; event++) {
|
|
753
793
|
intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
|
|
754
794
|
getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
755
795
|
if (event == 0) {
|
|
756
796
|
${primaryGuides}
|
|
757
|
-
|
|
797
|
+
isNotTransparent = ma.transmissionWeight < 0.001 && ma.subsurfaceWeight < 0.001 && ma.alpha > 0.99;
|
|
758
798
|
} else {
|
|
759
|
-
|
|
799
|
+
gN(&path, &depth, &si, &ma, sampleIgnored);
|
|
760
800
|
}
|
|
761
|
-
if (
|
|
762
|
-
if (path.abort || event >=
|
|
763
|
-
|
|
801
|
+
if (isNotTransparent && event > bounceLimit) { path.abort = true; }
|
|
802
|
+
if (path.abort || event >= fj) { break; }
|
|
803
|
+
mD(uv, &path, &depth, &si, &ma, outAux, &sampleIgnored);
|
|
764
804
|
if (path.abort) { break; }
|
|
765
805
|
}
|
|
766
806
|
return vec4f(path.li, path.alpha);
|
|
767
807
|
}
|
|
768
808
|
` : spectral === true && !deterministicPrimaryAlpha ? /* wgsl */ `
|
|
769
|
-
fn
|
|
809
|
+
fn hq(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
770
810
|
${primaryVariables}
|
|
771
|
-
var
|
|
772
|
-
var
|
|
773
|
-
var
|
|
811
|
+
var primarySi: SurfaceInteraction;
|
|
812
|
+
var primaryMa: OpenPbrResolvedMaterial;
|
|
813
|
+
var jg = false;
|
|
774
814
|
var path: Path; path.ray = ray;
|
|
775
815
|
let bounceLimit = max(rtUniform.bounces, 0);
|
|
776
|
-
let
|
|
777
|
-
var depth = 0; var event = 0; var
|
|
778
|
-
var
|
|
779
|
-
var
|
|
780
|
-
let
|
|
781
|
-
var
|
|
782
|
-
var
|
|
783
|
-
var
|
|
784
|
-
var
|
|
785
|
-
var
|
|
786
|
-
var
|
|
816
|
+
let fj = min(bounceLimit * 3, ${maxPathEvents});
|
|
817
|
+
var depth = 0; var event = 0; var sampleIgnored = false;
|
|
818
|
+
var isNotTransparent = false;
|
|
819
|
+
var jR = 0;
|
|
820
|
+
let bj = rtUniform.dispersionWavelengths == 1;
|
|
821
|
+
var eG = false;
|
|
822
|
+
var eQ = 0;
|
|
823
|
+
var aE = 0.0;
|
|
824
|
+
var wavelengthRngState: vec4u;
|
|
825
|
+
var eH = 0u;
|
|
826
|
+
var wavelengthAux: RayTraceAuxiliary;
|
|
787
827
|
var color = vec3f(0.0); var alpha = 0.0;
|
|
788
|
-
var
|
|
789
|
-
var
|
|
790
|
-
var
|
|
828
|
+
var dD = vec3f(0.0);
|
|
829
|
+
var dE = vec3f(0.0);
|
|
830
|
+
var ik = true;
|
|
791
831
|
|
|
792
832
|
|
|
793
833
|
|
|
794
|
-
let
|
|
795
|
-
for (var step = 0; step <
|
|
796
|
-
if (!
|
|
834
|
+
let zh = min((${maxPathEvents} + 1) * 3, i32(rtUniform.loopUnrollGuard * ${Math.ceil((maxPathEvents + 1) * 3 / 4)}u));
|
|
835
|
+
for (var step = 0; step < zh; step++) {
|
|
836
|
+
if (!jg | ((event != 0) & !path.abort)) {
|
|
797
837
|
intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
|
|
798
838
|
getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
799
839
|
}
|
|
800
840
|
if (event == 0) {
|
|
801
|
-
if (!
|
|
841
|
+
if (!jg) {
|
|
802
842
|
${primaryGuides}
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
if (
|
|
807
|
-
|
|
808
|
-
|
|
843
|
+
primarySi = si; primaryMa = ma; jg = true;
|
|
844
|
+
eG = si.hit & (ma.transmissionWeight > 0.001) & (ma.transmissionDispersionScale > 0.001);
|
|
845
|
+
aE = sample1D(CAMERA_WAVELENGTH);
|
|
846
|
+
if (bj) {
|
|
847
|
+
eQ = min(i32(floor(aE * 3.0)), 2);
|
|
848
|
+
aE = fract(aE * 3.0);
|
|
809
849
|
}
|
|
810
|
-
|
|
850
|
+
wavelengthRngState = s0; eH = hashedCounter;
|
|
811
851
|
}
|
|
812
|
-
si =
|
|
813
|
-
if (!
|
|
814
|
-
s0 =
|
|
815
|
-
|
|
852
|
+
si = primarySi; ma = primaryMa; wavelengthAux = *outAux;
|
|
853
|
+
if (!bj) {
|
|
854
|
+
s0 = wavelengthRngState; hashedCounter = eH; samplingBounce = 0u;
|
|
855
|
+
wavelengthAux.isBlank = false; wavelengthAux.isShadowCatcher = false;
|
|
816
856
|
}
|
|
817
857
|
si.wavelength = 0.0; si.spectralChannel = 0;
|
|
818
|
-
if (!
|
|
819
|
-
let channel = select(
|
|
858
|
+
if (!bj | eG) {
|
|
859
|
+
let channel = select(jR, eQ, bj);
|
|
820
860
|
si.spectralChannel = channel + 1;
|
|
821
|
-
si.wavelength =
|
|
822
|
-
|
|
861
|
+
si.wavelength = ce(u32(channel), aE);
|
|
862
|
+
${sharePrefix ? /* wgsl */ ` wY(channel + 1, si.wavelength, gf(ma));
|
|
863
|
+
if (spActive) { si.spectralChannel = 0; }
|
|
864
|
+
` : ''} ma.specularIor = sampling_cauchy_ior(si.wavelength, ma.specularIor,
|
|
823
865
|
ma.transmissionDispersionScale, ma.dispersionAbbeNumber);
|
|
824
866
|
}
|
|
825
867
|
path = Path(); path.ray = ray; path.beta = vec3f(1.0); path.fromEye = true;
|
|
826
868
|
path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
827
|
-
depth = 0;
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
869
|
+
depth = 0; sampleIgnored = false;
|
|
870
|
+
isNotTransparent = (ma.transmissionWeight < 0.001) & (ma.subsurfaceWeight < 0.001) & (ma.alpha > 0.99);
|
|
871
|
+
${sharePrefix ? /* wgsl */ ` if (spActive && jR > 0 && fC == 0) {
|
|
872
|
+
${prefixRestore('spFlat', flatPrefix)}
|
|
873
|
+
qA(&path, &si);
|
|
874
|
+
}
|
|
875
|
+
}
|
|
876
|
+
if (event > 0 && !path.abort) {
|
|
877
|
+
if (spActive && ma.transmissionWeight > 0.001 && gf(ma)) {
|
|
878
|
+
${prefixSave('spFlat', flatPrefix)}
|
|
879
|
+
fC = 0; qA(&path, &si);
|
|
880
|
+
}
|
|
881
|
+
gN(&path, &depth, &si, &ma, sampleIgnored);
|
|
882
|
+
}` : /* wgsl */ ` } else if (!path.abort) {
|
|
883
|
+
gN(&path, &depth, &si, &ma, sampleIgnored);
|
|
884
|
+
}`}
|
|
885
|
+
if (isNotTransparent & (event > bounceLimit)) { path.abort = true; }
|
|
886
|
+
if (!path.abort & (event < fj)) {
|
|
887
|
+
mD(uv, &path, &depth, &si, &ma, &wavelengthAux, &sampleIgnored);
|
|
888
|
+
}
|
|
889
|
+
if (path.abort | (event >= fj)) {
|
|
837
890
|
let result = vec4f(path.li, path.alpha);
|
|
838
|
-
if (
|
|
839
|
-
*outAux =
|
|
840
|
-
let scale = select(1.0, 3.0,
|
|
891
|
+
if (bj) {
|
|
892
|
+
*outAux = wavelengthAux;
|
|
893
|
+
let scale = select(1.0, 3.0, eG);
|
|
841
894
|
return vec4f(result.rgb * scale, result.a);
|
|
842
895
|
}
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
896
|
+
${sharePrefix ? /* wgsl */ ` if (spActive) {
|
|
897
|
+
(*outAux).isBlank = wavelengthAux.isBlank;
|
|
898
|
+
|
|
899
|
+
(*outAux).albedo = (wavelengthAux.albedo + wavelengthAux.albedo + wavelengthAux.albedo) / 3.0;
|
|
900
|
+
(*outAux).normal = (wavelengthAux.normal + wavelengthAux.normal + wavelengthAux.normal) / 3.0;
|
|
901
|
+
return result;
|
|
902
|
+
}
|
|
903
|
+
` : ''} color += result.rgb; alpha = max(alpha, result.a);
|
|
904
|
+
dD += wavelengthAux.albedo;
|
|
905
|
+
dE += wavelengthAux.normal;
|
|
906
|
+
ik = ik & wavelengthAux.isBlank;
|
|
907
|
+
jR++;
|
|
908
|
+
if (jR >= 3) {
|
|
909
|
+
(*outAux).albedo = dD / 3.0;
|
|
910
|
+
(*outAux).normal = dE / 3.0;
|
|
911
|
+
(*outAux).isBlank = ik;
|
|
852
912
|
return vec4f(color, alpha);
|
|
853
913
|
}
|
|
854
914
|
event = 0;
|
|
@@ -856,7 +916,7 @@ event = 0;
|
|
|
856
916
|
}
|
|
857
917
|
return vec4f(0.0);
|
|
858
918
|
}
|
|
859
|
-
` : /* wgsl */ `fn
|
|
919
|
+
` : /* wgsl */ `fn hq(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
860
920
|
${primaryVariables}
|
|
861
921
|
intersectScene(ray, &si, 0, false, false);
|
|
862
922
|
getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
@@ -866,85 +926,87 @@ if (SPECTRAL) {
|
|
|
866
926
|
|
|
867
927
|
|
|
868
928
|
|
|
869
|
-
var
|
|
929
|
+
var xl = vec3f(0.0);
|
|
870
930
|
var alpha = 0.0;
|
|
871
|
-
var
|
|
872
|
-
var
|
|
873
|
-
var
|
|
931
|
+
var dD = vec3f(0.0);
|
|
932
|
+
var dE = vec3f(0.0);
|
|
933
|
+
var ik = true;
|
|
874
934
|
var si2 = si;
|
|
875
935
|
var ma2 = ma;
|
|
876
|
-
var
|
|
877
|
-
let
|
|
878
|
-
let
|
|
879
|
-
let
|
|
880
|
-
let
|
|
936
|
+
var aE = sample1D(CAMERA_WAVELENGTH);
|
|
937
|
+
let wavelengthRngState = s0;
|
|
938
|
+
let eH = hashedCounter;
|
|
939
|
+
let bj = rtUniform.dispersionWavelengths == 1;
|
|
940
|
+
let eG = si.hit &&
|
|
881
941
|
ma.transmissionWeight > 0.001 &&
|
|
882
942
|
ma.transmissionDispersionScale > 0.001;
|
|
883
|
-
let
|
|
884
|
-
var
|
|
885
|
-
if (
|
|
943
|
+
let uR = select(3, 1, bj);
|
|
944
|
+
var eQ = 0;
|
|
945
|
+
if (bj) {
|
|
886
946
|
|
|
887
947
|
|
|
888
|
-
|
|
889
|
-
|
|
948
|
+
eQ = min(i32(floor(aE * 3.0)), 2);
|
|
949
|
+
aE = fract(aE * 3.0);
|
|
890
950
|
}
|
|
891
|
-
for (var i = 0; i <
|
|
951
|
+
for (var i = 0; i < uR; i++) {
|
|
892
952
|
|
|
893
953
|
|
|
894
954
|
|
|
895
|
-
if (!
|
|
896
|
-
s0 =
|
|
897
|
-
|
|
955
|
+
if (!bj) {
|
|
956
|
+
s0 = wavelengthRngState;
|
|
957
|
+
hashedCounter = eH;
|
|
898
958
|
samplingBounce = 0u;
|
|
899
959
|
}
|
|
900
960
|
si.wavelength = 0.0;
|
|
901
961
|
si.spectralChannel = 0;
|
|
902
|
-
if (!
|
|
903
|
-
let channel = select(i,
|
|
962
|
+
if (!bj || eG) {
|
|
963
|
+
let channel = select(i, eQ, bj);
|
|
904
964
|
si.spectralChannel = channel + 1;
|
|
905
|
-
si.wavelength =
|
|
906
|
-
|
|
965
|
+
si.wavelength = ce(u32(channel), aE);
|
|
966
|
+
${sharePrefix ? /* wgsl */ ` wY(channel + 1, si.wavelength, gf(ma));
|
|
967
|
+
if (spActive) { si.spectralChannel = 0; }
|
|
968
|
+
` : ''} ma.specularIor = sampling_cauchy_ior(
|
|
907
969
|
si.wavelength,
|
|
908
970
|
ma.specularIor,
|
|
909
971
|
ma.transmissionDispersionScale,
|
|
910
972
|
ma.dispersionAbbeNumber
|
|
911
973
|
);
|
|
912
974
|
}
|
|
913
|
-
var
|
|
914
|
-
if (
|
|
915
|
-
|
|
975
|
+
var wavelengthAux: RayTraceAuxiliary;
|
|
976
|
+
if (bj) {
|
|
977
|
+
wavelengthAux = *outAux;
|
|
916
978
|
} else {
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
}
|
|
922
|
-
let res =
|
|
923
|
-
if (
|
|
924
|
-
*outAux =
|
|
925
|
-
let scale = select(1.0, 3.0,
|
|
979
|
+
wavelengthAux.albedo = (*outAux).albedo;
|
|
980
|
+
wavelengthAux.normal = (*outAux).normal;
|
|
981
|
+
wavelengthAux.isBlank = false;
|
|
982
|
+
wavelengthAux.isShadowCatcher = false;
|
|
983
|
+
}
|
|
984
|
+
let res = jb(uv, &si, ray, &ma, &wavelengthAux);
|
|
985
|
+
if (bj) {
|
|
986
|
+
*outAux = wavelengthAux;
|
|
987
|
+
let scale = select(1.0, 3.0, eG);
|
|
926
988
|
return vec4f(res.rgb * scale, res.a);
|
|
927
989
|
}
|
|
928
|
-
|
|
990
|
+
xl += res.rgb;
|
|
929
991
|
alpha = max(alpha, res.a);
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
992
|
+
dD += wavelengthAux.albedo;
|
|
993
|
+
dE += wavelengthAux.normal;
|
|
994
|
+
ik = ik && wavelengthAux.isBlank;
|
|
933
995
|
si = si2;
|
|
934
996
|
ma = ma2;
|
|
935
997
|
}
|
|
936
|
-
(*outAux).albedo =
|
|
937
|
-
(*outAux).normal =
|
|
938
|
-
(*outAux).isBlank =
|
|
939
|
-
return vec4f(
|
|
998
|
+
(*outAux).albedo = dD / 3.0;
|
|
999
|
+
(*outAux).normal = dE / 3.0;
|
|
1000
|
+
(*outAux).isBlank = ik;
|
|
1001
|
+
return vec4f(xl, alpha);
|
|
940
1002
|
}
|
|
941
1003
|
else {
|
|
942
|
-
return
|
|
1004
|
+
return jb(uv, &si, ray, &ma, outAux);
|
|
943
1005
|
}
|
|
944
1006
|
}
|
|
945
1007
|
`}
|
|
946
1008
|
|
|
947
|
-
fn
|
|
1009
|
+
fn kX(ip: vec2f) -> vec2f {
|
|
948
1010
|
let p = 2.0 * ip - 1.0;
|
|
949
1011
|
let greater = abs(p.x) > abs(p.y);
|
|
950
1012
|
let r = select(p.y, p.x, greater);
|
|
@@ -983,23 +1045,23 @@ return;
|
|
|
983
1045
|
|
|
984
1046
|
let uv = (vec2<f32>(f32(coord.x), f32(coord.y)) + vec2f(0.5)) / outputSize;
|
|
985
1047
|
|
|
986
|
-
|
|
1048
|
+
aJ = coord;
|
|
987
1049
|
aC = u32(outNormal[idx].a) + rtUniform.sampleSequenceOffset;
|
|
988
|
-
samplingBounce = 0u;
|
|
1050
|
+
samplingBounce = 0u; hashedCounter = 0u;
|
|
989
1051
|
if (${inputHooks?.uniformJitter ? 'false' : 'SAMPLING_PATTERN == 0 || SAMPLING_PATTERN == 1'}) {
|
|
990
1052
|
jitter = (sample2D(CAMERA_PIXEL) - 0.5) / outputSize;
|
|
991
1053
|
}
|
|
992
|
-
|
|
993
|
-
var cam =
|
|
1054
|
+
fA(coord, i32(aC ^ cD(rtUniform.sequenceSeed)));
|
|
1055
|
+
var cam = cV(uv + jitter);
|
|
994
1056
|
|
|
995
1057
|
if (cameraUniform.apertureRadius > 0.0) {
|
|
996
1058
|
|
|
997
1059
|
let eye = cameraUniform.viewInv[3].xyz;
|
|
998
1060
|
let forward = -normalize(cameraUniform.viewInv[2].xyz);
|
|
999
|
-
let
|
|
1000
|
-
let
|
|
1001
|
-
let origin = (cameraUniform.viewInv * vec4f(
|
|
1002
|
-
let dir = normalize(
|
|
1061
|
+
let jY = eye + cam.d * (cameraUniform.focusDistance / dot(cam.d, forward));
|
|
1062
|
+
let uh = cameraUniform.apertureRadius * kX(sample2D(CAMERA_LENS));
|
|
1063
|
+
let origin = (cameraUniform.viewInv * vec4f(uh, 0.0, 1.0)).xyz;
|
|
1064
|
+
let dir = normalize(jY - origin);
|
|
1003
1065
|
initRay(&cam, origin, dir);
|
|
1004
1066
|
}
|
|
1005
1067
|
|
|
@@ -1008,7 +1070,7 @@ outAux.albedo = vec3f(0.0);
|
|
|
1008
1070
|
outAux.normal = vec3f(0.0);
|
|
1009
1071
|
outAux.isBlank = false;
|
|
1010
1072
|
outAux.isShadowCatcher = false;
|
|
1011
|
-
${pathDiagnostic ? ' mtPathBegin(coord);\n' : ''}${inputHooks?.begin ?? ''} var liAndAlpha =
|
|
1073
|
+
${pathDiagnostic ? ' mtPathBegin(coord);\n' : ''}${inputHooks?.begin ?? ''} var liAndAlpha = hq(uv + jitter, cam, &outAux);
|
|
1012
1074
|
${inputHooks?.unclampedColor ?? ''}
|
|
1013
1075
|
${(enabled || lightTracing || photonMapping) && debugGroup >= 0 ? /* wgsl */ ` liAndAlpha=${debugGroup >= 50 ? `vec4f(photonQueryStats,1.0)` : debugGroup >= 30 ? `vec4f(causticHot[${debugGroup - 30}],1.0)` : research?.debugOutput ?? 'liAndAlpha'};
|
|
1014
1076
|
` : ''}
|
|
@@ -1024,23 +1086,23 @@ liAndAlpha = vec4f(0.0, 0.0, 0.0, 1.0);
|
|
|
1024
1086
|
if (outAux.isShadowCatcher) {
|
|
1025
1087
|
|
|
1026
1088
|
|
|
1027
|
-
let aW =
|
|
1028
|
-
let
|
|
1029
|
-
let
|
|
1089
|
+
let aW = fI(cam);
|
|
1090
|
+
let sn = select(0.0, 1.0, aW.a >= 0.01);
|
|
1091
|
+
let kg = vec4f(aW.rgb * aW.a, aW.a);
|
|
1030
1092
|
|
|
1031
1093
|
|
|
1032
1094
|
|
|
1033
|
-
outShadowCatcher[idx].mask += vec4f(1.0, aW.a,
|
|
1095
|
+
outShadowCatcher[idx].mask += vec4f(1.0, aW.a, sn, 0.0);
|
|
1034
1096
|
outShadowCatcher[idx].moments += vec4f(0.0, 0.0, outAux.shadowCounts);
|
|
1035
|
-
outShadowCatcher[idx].background +=
|
|
1036
|
-
outColor[idx] +=
|
|
1037
|
-
outAlbedo[idx] += vec4f(outAux.albedo,
|
|
1038
|
-
|
|
1097
|
+
outShadowCatcher[idx].background += kg;
|
|
1098
|
+
outColor[idx] += kg;
|
|
1099
|
+
outAlbedo[idx] += vec4f(outAux.albedo, sn);
|
|
1100
|
+
ij(idx, aW.rgb, outAux.normal);
|
|
1039
1101
|
|
|
1040
1102
|
|
|
1041
1103
|
let counts = outAux.shadowCounts;
|
|
1042
1104
|
let visibility = 1.0 - select(0.0, counts.x / counts.y, counts.y > 0.0);
|
|
1043
|
-
|
|
1105
|
+
ju(idx, visibility * select(
|
|
1044
1106
|
1.0, dot(aW.rgb, luminance), aW.a >= 0.01
|
|
1045
1107
|
));
|
|
1046
1108
|
}
|
|
@@ -1056,8 +1118,8 @@ outShadowCatcher[idx].mask.g += liAndAlpha.a;
|
|
|
1056
1118
|
}
|
|
1057
1119
|
outColor[idx] += liAndAlpha;
|
|
1058
1120
|
outAlbedo[idx] += vec4f(outAux.albedo, select(1.0, 0.0, outAux.isBlank));
|
|
1059
|
-
|
|
1060
|
-
|
|
1121
|
+
ij(idx, liAndAlpha.rgb, outAux.normal);
|
|
1122
|
+
ju(idx, dot(liAndAlpha.rgb, luminance));
|
|
1061
1123
|
}
|
|
1062
1124
|
${pathDiagnostic ? ' mtPathEnd(outAux.normal, outAux.albedo);\n' : ''}${inputHooks?.end ?? ''}}
|
|
1063
1125
|
`;
|
|
@@ -1065,7 +1127,7 @@ ${pathDiagnostic ? ' mtPathEnd(outAux.normal, outAux.albedo);\n' : ''}${inputHo
|
|
|
1065
1127
|
// It has no effect on the beauty entry point or its bindings.
|
|
1066
1128
|
// Gate optional material layers on scene-level feature flags so drivers can
|
|
1067
1129
|
// skip the unused BSDF lobes.
|
|
1068
|
-
let specializedSource = source + depthQueryWGSL + reflectanceWGSL + aovTraceWGSL;
|
|
1130
|
+
let specializedSource = source + depthQueryWGSL + reflectanceWGSL + (options.displayAovStorage ? aovTraceDisplayWGSL : aovTraceWGSL);
|
|
1069
1131
|
const backgroundBits = {
|
|
1070
1132
|
USE_BACKGROUND: 1,
|
|
1071
1133
|
USE_BACKGROUND_MAP: 2,
|