@meimu/mutracer 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -0
- package/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +8949 -7915
- package/docs/api.md +42 -21
- package/docs/caustics.md +80 -0
- package/docs/materials.md +5 -4
- package/docs/progressive-rendering.md +50 -9
- package/docs/technical/continuous-spectrum.md +93 -0
- package/docs/updates.md +3 -1
- package/docs/viewer-checklist.md +65 -0
- package/docs/viewer.md +7 -5
- package/lib/Display.js +1 -1
- package/lib/Display.js.map +1 -1
- package/lib/Engine.d.ts +2 -0
- package/lib/Engine.js +47 -12
- package/lib/Engine.js.map +1 -1
- package/lib/Render.d.ts +61 -13
- package/lib/Render.js +169 -19
- package/lib/Render.js.map +1 -1
- package/lib/RenderLoop.d.ts +7 -3
- package/lib/RenderLoop.js +68 -44
- package/lib/RenderLoop.js.map +1 -1
- package/lib/main.d.ts +1 -1
- package/lib/main.js.map +1 -1
- package/lib/oidn.d.ts +1 -1
- package/lib/oidnBundledWeights.cdn.d.ts +2 -2
- package/lib/renderer/GPUTraceQueue.d.ts +2 -1
- package/lib/renderer/GPUTraceQueue.js +3 -1
- package/lib/renderer/GPUTraceQueue.js.map +1 -1
- package/lib/renderer/RenderingPipeline.d.ts +4 -0
- package/lib/renderer/RenderingPipeline.js.map +1 -1
- package/lib/renderer/WGPUCausticLightPass.d.ts +48 -0
- package/lib/renderer/WGPUCausticLightPass.js +217 -0
- package/lib/renderer/WGPUCausticLightPass.js.map +1 -0
- package/lib/renderer/WGPUEnvMapDistribution.js +18 -18
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPUPhotonMap.d.ts +37 -0
- package/lib/renderer/WGPUPhotonMap.js +191 -0
- package/lib/renderer/WGPUPhotonMap.js.map +1 -0
- package/lib/renderer/WGPURayTraceOutput.d.ts +13 -1
- package/lib/renderer/WGPURayTraceOutput.js +122 -28
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.d.ts +48 -17
- package/lib/renderer/WGPURayTracePass.js +538 -340
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +83 -47
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLFullQuadPass.d.ts +2 -1
- package/lib/renderer/WebGLFullQuadPass.js +4 -0
- package/lib/renderer/WebGLFullQuadPass.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +66 -66
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +6 -1
- package/lib/renderer/WebGLRayTracePass.js +43 -6
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/WebGLRenderingPipeline.js +10 -14
- package/lib/renderer/WebGLRenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLSkyBaker.js +60 -60
- package/lib/renderer/accumulationTarget.d.ts +2 -1
- package/lib/renderer/accumulationTarget.js.map +1 -1
- package/lib/renderer/causticDiagnostics.d.ts +31 -0
- package/lib/renderer/causticDiagnostics.js +5 -0
- package/lib/renderer/causticDiagnostics.js.map +1 -0
- package/lib/renderer/causticEmission.d.ts +10 -0
- package/lib/renderer/causticEmission.js +40 -0
- package/lib/renderer/causticEmission.js.map +1 -0
- package/lib/renderer/causticUniform.d.ts +12 -0
- package/lib/renderer/causticUniform.js +22 -0
- package/lib/renderer/causticUniform.js.map +1 -0
- package/lib/renderer/caustics.d.ts +16 -0
- package/lib/renderer/caustics.js +93 -0
- package/lib/renderer/caustics.js.map +1 -0
- package/lib/renderer/glsl/aovDisplay.frag.js +5 -5
- package/lib/renderer/glsl/aovReflectance.glsl.js +53 -53
- package/lib/renderer/glsl/aovReflectanceSamples.glsl.js +1 -1
- package/lib/renderer/glsl/aovTrace.frag.js +33 -33
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -9
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.d.ts +2 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js +35 -0
- package/lib/renderer/glsl/chunks/emissiveLight.glsl.js.map +1 -0
- package/lib/renderer/glsl/chunks/envMap.glsl.js +73 -73
- package/lib/renderer/glsl/chunks/intersect.glsl.js +426 -428
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +156 -153
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +771 -771
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +6 -6
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +68 -63
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +94 -76
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.d.ts +1 -0
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +140 -117
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +14 -14
- package/lib/renderer/glsl/chunks/sampling.glsl.js +89 -92
- package/lib/renderer/glsl/chunks/sampling.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sobol.glsl.js +79 -79
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +11 -11
- package/lib/renderer/glsl/depthQuery.frag.js +2 -2
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +10 -10
- package/lib/renderer/glsl/rayTrace.frag.d.ts +1 -1
- package/lib/renderer/glsl/rayTrace.frag.js +260 -237
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +26 -26
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +59 -59
- package/lib/renderer/lightSampling.d.ts +3 -2
- package/lib/renderer/lightSampling.js +14 -8
- package/lib/renderer/lightSampling.js.map +1 -1
- package/lib/renderer/progressiveScheduler.js +4 -3
- package/lib/renderer/progressiveScheduler.js.map +1 -1
- package/lib/renderer/renderPipeline.d.ts +1 -0
- package/lib/renderer/renderPipeline.js.map +1 -1
- package/lib/renderer/researchTransport.d.ts +31 -0
- package/lib/renderer/researchTransport.js +5 -0
- package/lib/renderer/researchTransport.js.map +1 -0
- package/lib/renderer/sceneLayoutSchema.d.ts +1 -0
- package/lib/renderer/sceneLayoutSchema.js +2 -2
- package/lib/renderer/sceneLayoutSchema.js.map +1 -1
- package/lib/renderer/scratchSampling.js +6 -6
- package/lib/renderer/spectrum.d.ts +21 -0
- package/lib/renderer/spectrum.js +154 -0
- package/lib/renderer/spectrum.js.map +1 -0
- package/lib/renderer/webglLightSampling.d.ts +39 -0
- package/lib/renderer/webglLightSampling.js +15 -0
- package/lib/renderer/webglLightSampling.js.map +1 -0
- package/lib/renderer/wgpuBindlessSource.js +3 -3
- package/lib/renderer/wgpuShaderSource.d.ts +7 -0
- package/lib/renderer/wgpuShaderSource.js +2 -0
- package/lib/renderer/wgpuShaderSource.js.map +1 -1
- package/lib/renderer/wgsl/aovDisplay.wgsl.js +9 -9
- package/lib/renderer/wgsl/aovReflectance.wgsl.js +55 -55
- package/lib/renderer/wgsl/aovReflectanceSamples.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovResolve.wgsl.js +2 -2
- package/lib/renderer/wgsl/aovSnapshot.wgsl.js +1 -1
- package/lib/renderer/wgsl/aovTrace.wgsl.js +33 -33
- package/lib/renderer/wgsl/bloom.wgsl.js +18 -18
- package/lib/renderer/wgsl/causticLight.compute.d.ts +6 -0
- package/lib/renderer/wgsl/causticLight.compute.js +537 -0
- package/lib/renderer/wgsl/causticLight.compute.js.map +1 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js +102 -0
- package/lib/renderer/wgsl/chunks/background.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js +12 -0
- package/lib/renderer/wgsl/chunks/causticAdjoint.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.d.ts +2 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js +16 -0
- package/lib/renderer/wgsl/chunks/causticAtomic.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.d.ts +1 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js +62 -0
- package/lib/renderer/wgsl/chunks/caustics.wgsl.js.map +1 -0
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +37 -37
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +598 -592
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +14 -14
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +75 -73
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +794 -794
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +139 -139
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.d.ts +2 -1
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +35 -25
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +142 -138
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +204 -187
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +11 -11
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +89 -93
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +83 -83
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/compose.frag.wgsl.js +98 -98
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.js +2 -2
- package/lib/renderer/wgsl/jnlm.compute.js +74 -74
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +25 -25
- package/lib/renderer/wgsl/oidnAuxiliary.wgsl.js +3 -3
- package/lib/renderer/wgsl/photonMap.compute.d.ts +29 -0
- package/lib/renderer/wgsl/photonMap.compute.js +352 -0
- package/lib/renderer/wgsl/photonMap.compute.js.map +1 -0
- package/lib/renderer/wgsl/proceduralSky.compute.js +64 -64
- package/lib/renderer/wgsl/rayTrace.compute.d.ts +9 -1
- package/lib/renderer/wgsl/rayTrace.compute.js +448 -522
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/MaterialState.d.ts +2 -2
- package/lib/scene/MaterialState.js +2 -2
- package/lib/scene/MaterialState.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 +2 -2
- 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/llms.txt +2 -1
- package/package.json +3 -3
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
import { photonQuerySource } from './photonMap.compute.js';
|
|
2
|
+
import backgroundWgsl from './chunks/background.wgsl.js';
|
|
3
|
+
import { researchTransport } from '../researchTransport.js';
|
|
4
|
+
import { causticPartitionWGSL } from './chunks/caustics.wgsl.js';
|
|
1
5
|
import { MAX_PATH_EVENTS } from '../pathLimits.js';
|
|
2
6
|
import shadowCatcherAccumulationWGSL from './chunks/shadowCatcherAccumulation.wgsl.js';
|
|
3
7
|
import reflectanceWGSL from './aovReflectance.wgsl.js';
|
|
@@ -18,12 +22,18 @@ import { createSampleMaterialWgsl } from './chunks/sampleMaterial.wgsl.js';
|
|
|
18
22
|
import sampleLightWgsl from './chunks/sampleLight.wgsl.js';
|
|
19
23
|
import { createOpenPbrBsdfWgsl } from './chunks/openPbrBsdf.wgsl.js';
|
|
20
24
|
import samplingWgsl from './chunks/sampling.wgsl.js';
|
|
25
|
+
import { spectrumWgsl } from '../spectrum.js';
|
|
21
26
|
import sampleShadowCatcherWgsl from './chunks/sampleShadowCatcher.wgsl.js';
|
|
22
27
|
import envMapWgsl from './chunks/envMap.wgsl.js';
|
|
23
28
|
import uvProjectionWgsl from './chunks/uvProjection.wgsl.js';
|
|
24
29
|
export const WORKGROUP_SIZE = 8;
|
|
25
30
|
/** Generates the WebGPU megakernel path tracing compute shader. */
|
|
26
|
-
export default function rayTraceCompute(
|
|
31
|
+
export default function rayTraceCompute(options, sceneIntersections = '', pathDiagnostic = false, inputHooks) {
|
|
32
|
+
const research = researchTransport()?.compute(options);
|
|
33
|
+
const enabled = research?.enabled ?? false;
|
|
34
|
+
const partitionDepth = research?.maxDepth ?? 20;
|
|
35
|
+
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;
|
|
27
37
|
hasAnisotropyDirections ||= hasCoatNormals;
|
|
28
38
|
const deterministicPrimaryAlpha = hasAlpha;
|
|
29
39
|
const hasShadowCatcher = sceneCapabilities === undefined || (sceneCapabilities & WGPU_SCENE_FEATURE_BITS.HAS_SHADOW_CATCHER) !== 0;
|
|
@@ -44,10 +54,10 @@ si.barycentrics = vec2f(0.0);
|
|
|
44
54
|
|
|
45
55
|
(*outAux).albedo = vec3f(1.0);
|
|
46
56
|
(*outAux).normal = select(si.normal, -si.normal, dot(si.normal, ray.d) > 0.0);
|
|
47
|
-
var
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
(*outAux).shadowCounts = sampleShadowCatcher(si, 0, &
|
|
57
|
+
var path: Path;
|
|
58
|
+
path.ray = ray;
|
|
59
|
+
path.fromEye = true;
|
|
60
|
+
(*outAux).shadowCounts = sampleShadowCatcher(si, 0, &path);
|
|
51
61
|
|
|
52
62
|
|
|
53
63
|
return vec4f(1.0);
|
|
@@ -55,7 +65,7 @@ return vec4f(1.0);
|
|
|
55
65
|
else {
|
|
56
66
|
if (HAS_BEVEL && rtUniform.bevel != 0) {
|
|
57
67
|
if (ma.bevel > 0.0) {
|
|
58
|
-
si.normal =
|
|
68
|
+
si.normal = mT(si, ma.bevel);
|
|
59
69
|
}
|
|
60
70
|
}
|
|
61
71
|
|
|
@@ -83,11 +93,12 @@ si.albedoSampled = ma.transmissionWeight > 0.5;
|
|
|
83
93
|
|
|
84
94
|
${commonWgsl}
|
|
85
95
|
|
|
86
|
-
${rayTraceCoreWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals, lightCapabilities })}
|
|
96
|
+
${rayTraceCoreWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals, lightCapabilities, caustics: enabled || lightTracing || photonMapping })}
|
|
87
97
|
|
|
88
98
|
${uvProjectionWgsl}
|
|
89
99
|
|
|
90
100
|
${createMaterialBufferWgsl({ hasSceneAlpha, hasAnisotropyDirections, hasCoatNormals,
|
|
101
|
+
caustics: enabled || lightTracing || photonMapping,
|
|
91
102
|
hasTransmission: (materialCapabilities & MATERIAL_SHADER_CAPABILITIES.transmission) !== 0,
|
|
92
103
|
hasMetalness: (materialCapabilities & MATERIAL_SHADER_CAPABILITIES.metal) !== 0 })}
|
|
93
104
|
|
|
@@ -97,57 +108,62 @@ ${randomWgsl}
|
|
|
97
108
|
${envMapWgsl}
|
|
98
109
|
|
|
99
110
|
${samplingWgsl}
|
|
111
|
+
${spectrumWgsl}
|
|
100
112
|
${createOpenPbrBsdfWgsl(hasAnisotropyDirections, hasCoatNormals)}
|
|
101
113
|
${sampleLightWgsl}${inputHooks?.declarations ?? ''}
|
|
102
114
|
|
|
103
115
|
|
|
104
|
-
var<private>
|
|
116
|
+
var<private> vp: u32 = 0u;
|
|
105
117
|
|
|
106
118
|
|
|
107
119
|
|
|
108
|
-
fn
|
|
120
|
+
fn ke() -> u32 {
|
|
109
121
|
return u32(max(rtUniform.directLightCandidates, 1));
|
|
110
122
|
}
|
|
111
123
|
|
|
112
124
|
|
|
113
125
|
|
|
114
126
|
|
|
115
|
-
fn
|
|
127
|
+
fn qp(yQ: u32) -> f32 {
|
|
116
128
|
|
|
117
129
|
|
|
118
130
|
|
|
119
131
|
|
|
120
132
|
if (SAMPLING_PATTERN == 2) { _ = rand(); }
|
|
121
|
-
let
|
|
122
|
-
let key =
|
|
123
|
-
let dimension =
|
|
124
|
-
return f32(
|
|
133
|
+
let kl = aI.x + aI.y * u32(rtUniform.outputSize.x);
|
|
134
|
+
let key = ak(ak(kl, aC), rtUniform.sequenceSeed);
|
|
135
|
+
let dimension = ak(samplingBounce, yQ) ^ 0xa511e9b3u;
|
|
136
|
+
return f32(cB(key ^ dimension) >> 8u) * (1.0 / 16777216.0);
|
|
125
137
|
}
|
|
126
138
|
|
|
127
139
|
|
|
128
140
|
|
|
129
|
-
fn
|
|
130
|
-
let candidateCount =
|
|
141
|
+
fn uY(lightPdf: f32, scatteringPdf: f32) -> f32 {
|
|
142
|
+
let candidateCount = ke();
|
|
131
143
|
if (candidateCount <= 1u) {
|
|
132
|
-
return
|
|
144
|
+
return aF(lightPdf, scatteringPdf);
|
|
133
145
|
}
|
|
134
|
-
let
|
|
135
|
-
return
|
|
136
|
-
max(
|
|
146
|
+
let weightedLightPdf = f32(candidateCount) * lightPdf;
|
|
147
|
+
return weightedLightPdf /
|
|
148
|
+
max(weightedLightPdf + scatteringPdf, 1e-20);
|
|
137
149
|
}
|
|
138
150
|
|
|
139
151
|
|
|
140
|
-
fn
|
|
141
|
-
let candidateCount =
|
|
152
|
+
fn fV(scatteringPdf: f32, lightPdf: f32) -> f32 {
|
|
153
|
+
let candidateCount = ke();
|
|
142
154
|
if (candidateCount <= 1u) {
|
|
143
|
-
return
|
|
155
|
+
return aF(scatteringPdf, lightPdf);
|
|
144
156
|
}
|
|
145
|
-
let
|
|
157
|
+
let weightedLightPdf = f32(candidateCount) * lightPdf;
|
|
146
158
|
return scatteringPdf /
|
|
147
|
-
max(scatteringPdf +
|
|
159
|
+
max(scatteringPdf + weightedLightPdf, 1e-20);
|
|
148
160
|
}
|
|
149
161
|
|
|
150
|
-
${
|
|
162
|
+
${enabled || lightTracing || photonMapping ? causticPartitionWGSL(enabled, lightTracing, photonMapping, partitionDepth, debugGroup >= 30, photonMaxDepth) : ''}${research?.declarations ?? ''}${photonMapping ? `const CAUSTIC_LIGHT_TRACING=${lightTracing};
|
|
163
|
+
const CAUSTIC_MNEE=${enabled};
|
|
164
|
+
const CAUSTIC_MNEE_MAX_DEPTH=${partitionDepth}u;
|
|
165
|
+
const CAUSTIC_PHOTON_MAX_DEPTH=${photonMaxDepth}u;
|
|
166
|
+
` + photonQuerySource(debugGroup, !lightTracing && (options.photonDirectSubset ?? true)) : ''}${createSampleMaterialWgsl(hasAnisotropyDirections, hasCoatNormals, enabled || lightTracing || photonMapping, research?.contribution, photonMapping)}
|
|
151
167
|
${sampleShadowCatcherWgsl}
|
|
152
168
|
|
|
153
169
|
|
|
@@ -159,24 +175,24 @@ ${shadowCatcherAccumulationWGSL}
|
|
|
159
175
|
@group(3) @binding(3) var<storage, read_write> outShadowCatcher: array<ShadowCatcherAccumulation>;
|
|
160
176
|
|
|
161
177
|
|
|
162
|
-
fn
|
|
163
|
-
|
|
178
|
+
fn hH(
|
|
179
|
+
gf: u32,
|
|
164
180
|
radiance: vec3f,
|
|
165
181
|
normal: vec3f
|
|
166
182
|
) {
|
|
167
183
|
if (rtUniform.varianceMoments != 0) {
|
|
168
184
|
let value = dot(radiance, luminance);
|
|
169
|
-
outNormal[
|
|
185
|
+
outNormal[gf] += vec4f(value * value, 0.0, 0.0, 1.0);
|
|
170
186
|
}
|
|
171
187
|
else {
|
|
172
|
-
outNormal[
|
|
188
|
+
outNormal[gf] += vec4f(normal, 1.0);
|
|
173
189
|
}
|
|
174
190
|
}
|
|
175
191
|
|
|
176
192
|
|
|
177
193
|
|
|
178
|
-
fn
|
|
179
|
-
outShadowCatcher[
|
|
194
|
+
fn iP(gf: u32, value: f32) {
|
|
195
|
+
outShadowCatcher[gf].moments += vec4f(value, value * value, 0.0, 0.0);
|
|
180
196
|
}
|
|
181
197
|
|
|
182
198
|
|
|
@@ -190,123 +206,23 @@ isBlank: bool,
|
|
|
190
206
|
shadowCounts: vec2f,
|
|
191
207
|
}
|
|
192
208
|
|
|
193
|
-
fn
|
|
194
|
-
let
|
|
195
|
-
if (ge < 0.00001) {
|
|
196
|
-
return -radius;
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
let iX = radius * point.y / ge;
|
|
200
|
-
let iL = -1.5 * height;
|
|
201
|
-
var eH: f32;
|
|
202
|
-
if (iX >= 0.0) {
|
|
203
|
-
eH = radius;
|
|
204
|
-
}
|
|
205
|
-
else if (iX < iL) {
|
|
206
|
-
eH = -height * ge / point.y;
|
|
207
|
-
}
|
|
208
|
-
else {
|
|
209
|
-
let cL = 1.0
|
|
210
|
-
- iX * iX / (3.0 * iL * iL);
|
|
211
|
-
eH = radius * cL;
|
|
212
|
-
}
|
|
213
|
-
return ge - eH;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
fn fd(origin: vec3f, direction: vec3f) -> vec3f {
|
|
217
|
-
if (!USE_GROUNDED_BACKGROUND) {
|
|
218
|
-
return direction;
|
|
219
|
-
}
|
|
220
|
-
let params = rtUniform.groundedBackgroundParams;
|
|
221
|
-
let cf = normalize(direction);
|
|
222
|
-
let center = vec3f(
|
|
223
|
-
rtUniform.groundedBackgroundCenter.x,
|
|
224
|
-
params.z + params.x,
|
|
225
|
-
rtUniform.groundedBackgroundCenter.y
|
|
226
|
-
);
|
|
227
|
-
let bI = origin - center;
|
|
228
|
-
let eT = dot(bI, cf);
|
|
229
|
-
let br = eT * eT
|
|
230
|
-
- dot(bI, bI) + params.y * params.y;
|
|
231
|
-
if (
|
|
232
|
-
br <= 0.0
|
|
233
|
-
|| dK(bI, params.x, params.y) > 0.0
|
|
234
|
-
) {
|
|
235
|
-
return direction;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
var cM = -eT + sqrt(br);
|
|
239
|
-
if (cM <= 0.0) {
|
|
240
|
-
return direction;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
let oK = bI + cf * cM;
|
|
244
|
-
if (oK.y >= 0.0) {
|
|
245
|
-
return normalize(oK);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
if (cf.y < -0.00001 && params.y > 1.5 * params.x) {
|
|
249
|
-
let ir = (-params.x - bI.y) / cf.y;
|
|
250
|
-
let oB = bI + cf * ir;
|
|
251
|
-
let pe = (2.0 / 3.0)
|
|
252
|
-
* sqrt(params.y * params.y - 2.25 * params.x * params.x);
|
|
253
|
-
if (ir > 0.0 && length(oB.xz) <= pe) {
|
|
254
|
-
return normalize(oB);
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
var cV = 0.0;
|
|
259
|
-
for (var i = 0; i < 14; i++) {
|
|
260
|
-
let fB = (cV + cM) * 0.5;
|
|
261
|
-
let qy = bI + cf * fB;
|
|
262
|
-
if (dK(qy, params.x, params.y) > 0.0) {
|
|
263
|
-
cM = fB;
|
|
264
|
-
}
|
|
265
|
-
else {
|
|
266
|
-
cV = fB;
|
|
267
|
-
}
|
|
268
|
-
}
|
|
269
|
-
let hit = bI + cf * ((cV + cM) * 0.5);
|
|
270
|
-
return normalize(hit);
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
fn hX(ray: Ray) -> vec4f {
|
|
274
|
-
var bg = vec4f(0.0);
|
|
275
|
-
if (USE_BACKGROUND_MAP) {
|
|
276
|
-
let d = fd(ray.o, ray.d);
|
|
277
|
-
let t = rtUniform.backgroundMapTransform;
|
|
278
|
-
let qZ = vec3f(t.x * d.x - t.y * d.z, d.y, t.y * d.x + t.x * d.z);
|
|
279
|
-
let rotation = rtUniform.backgroundMapRotation;
|
|
280
|
-
let hn = transpose(mat3x3f(rotation[0].xyz, rotation[1].xyz, rotation[2].xyz)) * qZ;
|
|
281
|
-
let bc = textureLinear(backgroundMap, eV(hn));
|
|
282
|
-
bg = vec4f(bc.rgb * t.z, bc.a);
|
|
283
|
-
}
|
|
284
|
-
else if (USE_BACKGROUND) {
|
|
285
|
-
bg = rtUniform.backgroundColor;
|
|
286
|
-
}
|
|
287
|
-
else if (USE_ENVMAP) {
|
|
288
|
-
bg = textureLinear(envMap, dm(ray.d));
|
|
289
|
-
}
|
|
290
|
-
return bg;
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
fn di(ray: Ray, wavelength: f32) -> vec4f {
|
|
294
|
-
let bg = hX(ray);
|
|
209
|
+
${backgroundWgsl}fn cP(ray: Ray, channel: i32) -> vec4f {
|
|
210
|
+
let bg = ft(ray);
|
|
295
211
|
if (SPECTRAL) {
|
|
296
|
-
return vec4f(
|
|
212
|
+
return vec4f(sampling_spectral_rgb_filter(bg.rgb, channel), bg.a);
|
|
297
213
|
}
|
|
298
214
|
return bg;
|
|
299
215
|
}
|
|
300
216
|
|
|
301
217
|
|
|
302
218
|
|
|
303
|
-
fn
|
|
304
|
-
*
|
|
305
|
-
|
|
219
|
+
fn nO(uv: vec2f, path: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>, eV: ptr<function, bool>) {
|
|
220
|
+
*eV = false;
|
|
221
|
+
samplingBounce = u32(max(*depth, 0));
|
|
306
222
|
let matType = (*ma).materialType;
|
|
307
223
|
let isShadowCatcher = ${hasShadowCatcher ? /* wgsl */ `matType == SHADOW_CATCHER` : /* wgsl */ `false`};
|
|
308
224
|
if (isShadowCatcher) {
|
|
309
|
-
if ((*
|
|
225
|
+
if ((*path).fromEye) {
|
|
310
226
|
(*si).hit = false;
|
|
311
227
|
}
|
|
312
228
|
else {
|
|
@@ -314,37 +230,37 @@ else {
|
|
|
314
230
|
|
|
315
231
|
|
|
316
232
|
if (USE_ENVMAP) {
|
|
317
|
-
if ((*
|
|
233
|
+
if ((*path).isNextRefraction) {
|
|
318
234
|
|
|
319
235
|
|
|
320
|
-
let bg =
|
|
321
|
-
(*
|
|
322
|
-
(*si).
|
|
236
|
+
let bg = cP(
|
|
237
|
+
(*path).ray,
|
|
238
|
+
(*si).spectralChannel
|
|
323
239
|
);
|
|
324
|
-
let
|
|
325
|
-
|
|
326
|
-
1.0, (*
|
|
327
|
-
(*
|
|
328
|
-
(*
|
|
240
|
+
let cM = select(fV((*path).scatteringPdf,
|
|
241
|
+
envMapPdf(cT((*path).ray.d)) * rtUniform.envLightPmf),
|
|
242
|
+
1.0, (*path).scatteringIsDelta);
|
|
243
|
+
(*path).li += cM * (*path).beta * bg.rgb * bg.a;
|
|
244
|
+
(*path).alpha = max((*path).alpha, bg.a);
|
|
329
245
|
}
|
|
330
246
|
else {
|
|
331
|
-
let
|
|
332
|
-
var emission = textureLinear(envMap,
|
|
247
|
+
let vC = cT((*path).ray.d);
|
|
248
|
+
var emission = textureLinear(envMap, vC).rgb;
|
|
333
249
|
if (SPECTRAL) {
|
|
334
|
-
emission =
|
|
250
|
+
emission = sampling_spectral_rgb_filter(emission, (*si).spectralChannel);
|
|
335
251
|
}
|
|
336
|
-
(*
|
|
337
|
-
|
|
252
|
+
(*path).li += (*path).beta * emission *
|
|
253
|
+
fV((*path).scatteringPdf, envMapPdf(vC));
|
|
338
254
|
}
|
|
339
255
|
}
|
|
340
256
|
else {
|
|
341
|
-
let bg =
|
|
342
|
-
(*
|
|
343
|
-
(*si).
|
|
257
|
+
let bg = cP(
|
|
258
|
+
(*path).ray,
|
|
259
|
+
(*si).spectralChannel
|
|
344
260
|
);
|
|
345
|
-
(*
|
|
261
|
+
(*path).li += (*path).beta * bg.rgb * bg.a;
|
|
346
262
|
}
|
|
347
|
-
(*
|
|
263
|
+
(*path).abort = true;
|
|
348
264
|
return;
|
|
349
265
|
}
|
|
350
266
|
}
|
|
@@ -352,40 +268,40 @@ if (!(*si).hit) {
|
|
|
352
268
|
|
|
353
269
|
|
|
354
270
|
|
|
355
|
-
let bg =
|
|
356
|
-
(*
|
|
357
|
-
(*si).
|
|
271
|
+
let bg = cP(
|
|
272
|
+
(*path).ray,
|
|
273
|
+
(*si).spectralChannel
|
|
358
274
|
);
|
|
359
|
-
if ((*
|
|
275
|
+
if ((*path).fromEye) {
|
|
360
276
|
|
|
361
|
-
(*
|
|
362
|
-
(*
|
|
277
|
+
(*path).li = (*path).beta * bg.rgb * bg.a;
|
|
278
|
+
(*path).alpha = bg.a;
|
|
363
279
|
|
|
364
280
|
(*outAux).isBlank = bg.a < 0.001 ||
|
|
365
281
|
(USE_BACKGROUND && !USE_BACKGROUND_MAP);
|
|
366
282
|
}
|
|
367
283
|
else {
|
|
368
|
-
let cam =
|
|
369
|
-
let
|
|
284
|
+
let cam = eT(uv);
|
|
285
|
+
let nt = dot(cam.d, (*path).ray.d) > 0.0;
|
|
370
286
|
if (rtUniform.transmissiveOutputAlphaMin < 1.0) {
|
|
371
|
-
if (
|
|
372
|
-
(*
|
|
287
|
+
if (nt) {
|
|
288
|
+
(*path).alpha = max((*path).alpha, bg.a);
|
|
373
289
|
} else {
|
|
374
|
-
(*
|
|
290
|
+
(*path).alpha = 1.0;
|
|
375
291
|
}
|
|
376
292
|
}
|
|
377
293
|
if (!USE_ENVMAP) {
|
|
378
294
|
|
|
379
295
|
|
|
380
|
-
if (
|
|
296
|
+
if (nt) {
|
|
381
297
|
|
|
382
298
|
|
|
383
|
-
(*
|
|
384
|
-
|
|
299
|
+
(*path).li += (*path).beta *
|
|
300
|
+
fV((*path).scatteringPdf, 1.0) * bg.rgb;
|
|
385
301
|
}
|
|
386
302
|
}
|
|
387
303
|
}
|
|
388
|
-
(*
|
|
304
|
+
(*path).abort = true;
|
|
389
305
|
return;
|
|
390
306
|
}
|
|
391
307
|
|
|
@@ -396,28 +312,28 @@ let alpha = clamp((*ma).alpha, 0.0, 1.0);
|
|
|
396
312
|
if (alpha < 1.0) {
|
|
397
313
|
|
|
398
314
|
|
|
399
|
-
if (alpha <= 0.0 ||
|
|
400
|
-
(*
|
|
315
|
+
if (alpha <= 0.0 || ek(3u) > alpha) {
|
|
316
|
+
(*eV) = true;
|
|
401
317
|
}
|
|
402
318
|
}
|
|
403
|
-
if (!(*
|
|
319
|
+
if (!(*eV) && rtUniform.transmissiveOutputAlphaMin < 1.0) {
|
|
404
320
|
|
|
405
321
|
|
|
406
322
|
let outputAlpha = max(1.0 - (*ma).transmissionWeight, 1.0 - pow(1.0 - rtUniform.transmissiveOutputAlphaMin, f32(*depth)));
|
|
407
|
-
(*
|
|
323
|
+
(*path).alpha = max(outputAlpha, (*path).alpha);
|
|
408
324
|
}
|
|
409
|
-
if (!(*
|
|
410
|
-
|
|
411
|
-
|
|
325
|
+
if (!(*eV)) {
|
|
326
|
+
vp = u32(max(*depth, 0));
|
|
327
|
+
mx(si, ma, path);
|
|
412
328
|
}
|
|
413
329
|
else {
|
|
414
330
|
|
|
415
331
|
|
|
416
|
-
(*
|
|
332
|
+
(*path).ray.o = (*si).position + (*path).ray.d * EPS;
|
|
417
333
|
}
|
|
418
334
|
}
|
|
419
335
|
|
|
420
|
-
if (!(*si).albedoSampled && !(*
|
|
336
|
+
if (!(*si).albedoSampled && !(*eV)) {
|
|
421
337
|
|
|
422
338
|
if ((matType == STANDARD || matType == UNLIT)) {
|
|
423
339
|
if (!((*ma).transmissionWeight > 0.5 ||
|
|
@@ -442,34 +358,34 @@ if (*depth > 4) {
|
|
|
442
358
|
|
|
443
359
|
|
|
444
360
|
if (USE_RR) {
|
|
445
|
-
if (*depth >= RR_MAX && !(*
|
|
446
|
-
let
|
|
361
|
+
if (*depth >= RR_MAX && !(*eV)) {
|
|
362
|
+
let pl = (*path).beta;
|
|
447
363
|
|
|
448
|
-
let
|
|
449
|
-
let q: f32 = max(0.0, 1.0 -
|
|
450
|
-
if (
|
|
364
|
+
let pc = max(max(pl.x, pl.y), pl.z);
|
|
365
|
+
let q: f32 = max(0.0, 1.0 - pc);
|
|
366
|
+
if (sample1D(bE(RUSSIAN_ROULETTE)) < q) {
|
|
451
367
|
|
|
452
368
|
|
|
453
|
-
(*
|
|
454
|
-
(*
|
|
369
|
+
(*path).alpha = 1.0;
|
|
370
|
+
(*path).abort = true;
|
|
455
371
|
}
|
|
456
372
|
else {
|
|
457
|
-
(*
|
|
373
|
+
(*path).beta /= 1.0 - q;
|
|
458
374
|
}
|
|
459
375
|
}
|
|
460
376
|
}
|
|
461
|
-
if ((*
|
|
377
|
+
if ((*path).abort) {
|
|
462
378
|
return;
|
|
463
379
|
}
|
|
464
380
|
|
|
465
381
|
|
|
466
382
|
}
|
|
467
383
|
|
|
468
|
-
fn
|
|
384
|
+
fn jQ(path: ptr<function, Path>, depth: ptr<function, i32>, si: ptr<function, SurfaceInteraction>, ma: ptr<function, OpenPbrResolvedMaterial>, aJ: bool) {
|
|
469
385
|
if (SPECTRAL) {
|
|
470
386
|
|
|
471
387
|
if ((*ma).transmissionWeight > 0.001) {
|
|
472
|
-
(*ma).specularIor =
|
|
388
|
+
(*ma).specularIor = sampling_cauchy_ior(
|
|
473
389
|
(*si).wavelength,
|
|
474
390
|
(*ma).specularIor,
|
|
475
391
|
(*ma).transmissionDispersionScale,
|
|
@@ -484,298 +400,299 @@ return;
|
|
|
484
400
|
|
|
485
401
|
|
|
486
402
|
var lightSample: LightSampleRec;
|
|
487
|
-
let
|
|
403
|
+
let ht = ek(3u) < (*ma).alpha;
|
|
488
404
|
for (var i = 0; i < rtUniform.lightsCount; i++) {
|
|
489
405
|
|
|
490
406
|
let light: Light = analyticLights[i];
|
|
491
|
-
let d =
|
|
407
|
+
let d = mX((*path).ray, light, &lightSample);
|
|
492
408
|
lightSample.pdf *= light.selectionPmf;
|
|
493
|
-
let
|
|
494
|
-
if (d != INF && !(
|
|
495
|
-
let
|
|
409
|
+
let lH = (*si).hit && d > distance((*si).position, (*path).ray.o);
|
|
410
|
+
if (d != INF && !(lH && ht)) {
|
|
411
|
+
let misWeight = fV((*path).scatteringPdf, lightSample.pdf);
|
|
496
412
|
if (SPECTRAL) {
|
|
497
|
-
lightSample.emission =
|
|
413
|
+
lightSample.emission = sampling_spectral_rgb_filter(lightSample.emission, (*si).spectralChannel);
|
|
498
414
|
}
|
|
499
|
-
(*
|
|
500
|
-
(*
|
|
501
|
-
(*
|
|
415
|
+
${enabled || lightTracing || photonMapping ? 'if (!causticHitOwned(*path, true, true)) { causticHotRecord(*path,misWeight*lightSample.emission,2u); ' : ''}(*path).li += misWeight * (*path).beta * lightSample.emission;${enabled || lightTracing || photonMapping ? ' }' : ''}
|
|
416
|
+
(*path).alpha = 1.0;
|
|
417
|
+
(*path).abort = true;
|
|
502
418
|
}
|
|
503
419
|
}
|
|
504
420
|
|
|
505
421
|
if (USE_ENVMAP) {
|
|
506
|
-
if (!((*si).hit &&
|
|
507
|
-
if
|
|
422
|
+
if (!((*si).hit && ht)) {${lightTracing || photonMapping ? /* wgsl */ `
|
|
423
|
+
if(causticHitOwned(*path,false,true)){(*path).abort=true;return;}` : ''}
|
|
424
|
+
if ((*path).isNextRefraction) {
|
|
508
425
|
|
|
509
426
|
|
|
510
427
|
|
|
511
|
-
let bg =
|
|
512
|
-
(*
|
|
513
|
-
(*si).
|
|
428
|
+
let bg = cP(
|
|
429
|
+
(*path).ray,
|
|
430
|
+
(*si).spectralChannel
|
|
514
431
|
);
|
|
515
|
-
let
|
|
516
|
-
|
|
517
|
-
1.0, (*
|
|
518
|
-
(*
|
|
519
|
-
(*
|
|
520
|
-
(*
|
|
432
|
+
let cM = select(fV((*path).scatteringPdf,
|
|
433
|
+
envMapPdf(cT((*path).ray.d)) * rtUniform.envLightPmf),
|
|
434
|
+
1.0, (*path).scatteringIsDelta);
|
|
435
|
+
(*path).li += cM * (*path).beta * bg.rgb * bg.a;
|
|
436
|
+
(*path).alpha = max((*path).alpha, bg.a);
|
|
437
|
+
(*path).abort = true;
|
|
521
438
|
return;
|
|
522
439
|
}
|
|
523
|
-
let _uv =
|
|
440
|
+
let _uv = cT((*path).ray.d);
|
|
524
441
|
var emission = textureLinear(envMap, _uv).rgb;
|
|
525
|
-
let
|
|
526
|
-
(*
|
|
527
|
-
|
|
442
|
+
let misWeight = fV(
|
|
443
|
+
(*path).scatteringPdf,
|
|
444
|
+
envMapPdf(_uv) * rtUniform.envLightPmf
|
|
528
445
|
);
|
|
529
446
|
if (SPECTRAL) {
|
|
530
|
-
emission =
|
|
447
|
+
emission = sampling_spectral_rgb_filter(emission, (*si).spectralChannel);
|
|
531
448
|
}
|
|
532
449
|
|
|
533
450
|
if (!USE_BACKGROUND) {
|
|
534
|
-
(*
|
|
451
|
+
(*path).alpha = 1.0;
|
|
535
452
|
}
|
|
536
|
-
(*
|
|
537
|
-
(*
|
|
453
|
+
(*path).li += (*path).beta * emission * misWeight;
|
|
454
|
+
(*path).abort = true;
|
|
538
455
|
}
|
|
539
456
|
}
|
|
540
457
|
|
|
541
458
|
*depth = *depth + 1;
|
|
542
459
|
}
|
|
543
460
|
|
|
544
|
-
fn
|
|
461
|
+
fn eT(coord: vec2f) -> Ray {
|
|
545
462
|
let origin = cameraUniform.viewProjectionInv * vec4f(coord * 2.0 - 1.0, -1.0, 1.0);
|
|
546
463
|
let center = cameraUniform.viewProjectionInv * vec4f(coord * 2.0 - 1.0, 1.0, 1.0);
|
|
547
464
|
var cam: Ray;
|
|
548
|
-
|
|
465
|
+
initRay(&cam, origin.xyz / origin.w, normalize(center.xyz * origin.w - origin.xyz * center.w));
|
|
549
466
|
|
|
550
467
|
return cam;
|
|
551
468
|
}
|
|
552
469
|
|
|
553
470
|
|
|
554
|
-
fn
|
|
471
|
+
fn kK(radius: f32, xi: f32) -> vec2f {
|
|
555
472
|
var x = 0.25;
|
|
556
|
-
for (var
|
|
473
|
+
for (var iteration = 0; iteration < 10; iteration++) {
|
|
557
474
|
let x2 = x * x;
|
|
558
475
|
let x3 = x2 * x;
|
|
559
|
-
let
|
|
476
|
+
let la = 1.0 - x;
|
|
560
477
|
let value = 10.0 * x2 - 20.0 * x3 + 15.0 * x2 * x2 -
|
|
561
478
|
4.0 * x2 * x3 - xi;
|
|
562
|
-
let
|
|
563
|
-
if (abs(value) < 1e-6 ||
|
|
564
|
-
x = clamp(x - value /
|
|
479
|
+
let mJ = 20.0 * x * la * la * la;
|
|
480
|
+
if (abs(value) < 1e-6 || mJ == 0.0) { break; }
|
|
481
|
+
x = clamp(x - value / mJ, 0.0, 1.0);
|
|
565
482
|
}
|
|
566
|
-
let
|
|
567
|
-
return vec2f(
|
|
483
|
+
let jr = x * radius;
|
|
484
|
+
return vec2f(jr, sqrt(max(radius * radius - jr * jr, 0.0)));
|
|
568
485
|
}
|
|
569
486
|
|
|
570
|
-
fn
|
|
571
|
-
if (
|
|
572
|
-
let
|
|
573
|
-
return
|
|
487
|
+
fn bevelCubicPdf(radius: f32, gu: f32) -> f32 {
|
|
488
|
+
if (gu >= radius) { return 0.0; }
|
|
489
|
+
let falloff = radius - gu;
|
|
490
|
+
return falloff * falloff * falloff;
|
|
574
491
|
}
|
|
575
492
|
|
|
576
493
|
|
|
577
|
-
fn
|
|
494
|
+
fn mT(source: SurfaceInteraction, radius: f32) -> vec3f {
|
|
578
495
|
var geometricNormal = source.faceNormal;
|
|
579
496
|
if (dot(geometricNormal, source.vertexNormal) < 0.0) {
|
|
580
497
|
geometricNormal = -geometricNormal;
|
|
581
498
|
}
|
|
582
499
|
var tangent: vec3f;
|
|
583
500
|
var bitangent: vec3f;
|
|
584
|
-
|
|
585
|
-
var
|
|
586
|
-
|
|
587
|
-
for (var
|
|
588
|
-
let
|
|
589
|
-
var
|
|
590
|
-
let
|
|
591
|
-
var
|
|
592
|
-
var
|
|
593
|
-
var
|
|
594
|
-
var
|
|
595
|
-
var
|
|
596
|
-
var
|
|
597
|
-
if (
|
|
598
|
-
|
|
599
|
-
}
|
|
600
|
-
else if (
|
|
601
|
-
let
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
501
|
+
sampling_orthonormal_basis(geometricNormal, &tangent, &bitangent);
|
|
502
|
+
var iE = vec3f(0.0);
|
|
503
|
+
|
|
504
|
+
for (var ih = 0; ih < BEVEL_SAMPLES; ih++) {
|
|
505
|
+
let qa = sample2D(CAMERA_BEVEL_BASE + u32(ih));
|
|
506
|
+
var cr = qa.x;
|
|
507
|
+
let pj = qa.y;
|
|
508
|
+
var cZ = geometricNormal;
|
|
509
|
+
var fI = tangent;
|
|
510
|
+
var eh = bitangent;
|
|
511
|
+
var ge = 0.5;
|
|
512
|
+
var hW = 0.25;
|
|
513
|
+
var gC = 0.25;
|
|
514
|
+
if (cr < 0.5) {
|
|
515
|
+
cr *= 2.0;
|
|
516
|
+
}
|
|
517
|
+
else if (cr < 0.75) {
|
|
518
|
+
let nr = cZ;
|
|
519
|
+
cZ = fI;
|
|
520
|
+
fI = nr;
|
|
521
|
+
ge = 0.25;
|
|
522
|
+
hW = 0.5;
|
|
523
|
+
cr = (cr - 0.5) * 4.0;
|
|
607
524
|
}
|
|
608
525
|
else {
|
|
609
|
-
let
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
}
|
|
616
|
-
|
|
617
|
-
let
|
|
618
|
-
let phi = TWOPI *
|
|
619
|
-
let
|
|
620
|
-
(cos(phi) *
|
|
526
|
+
let nr = cZ;
|
|
527
|
+
cZ = eh;
|
|
528
|
+
eh = nr;
|
|
529
|
+
ge = 0.25;
|
|
530
|
+
gC = 0.5;
|
|
531
|
+
cr = (cr - 0.75) * 4.0;
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
let gQ = kK(radius, pj);
|
|
535
|
+
let phi = TWOPI * cr;
|
|
536
|
+
let rr = gQ.x *
|
|
537
|
+
(cos(phi) * fI + sin(phi) * eh);
|
|
621
538
|
var ray: Ray;
|
|
622
|
-
|
|
539
|
+
initRay(
|
|
623
540
|
&ray,
|
|
624
|
-
source.position +
|
|
625
|
-
-
|
|
541
|
+
source.position + cZ * gQ.y + rr,
|
|
542
|
+
-cZ
|
|
626
543
|
);
|
|
627
544
|
var hit: SurfaceInteraction;
|
|
628
545
|
intersectSceneBevel(
|
|
629
546
|
ray,
|
|
630
547
|
&hit,
|
|
631
548
|
source.instanceIndex,
|
|
632
|
-
max(2.0 *
|
|
549
|
+
max(2.0 * gQ.y, EPS)
|
|
633
550
|
);
|
|
634
551
|
if (!hit.hit) { continue; }
|
|
635
552
|
|
|
636
|
-
let
|
|
637
|
-
let
|
|
638
|
-
let
|
|
639
|
-
var weight =
|
|
640
|
-
|
|
641
|
-
|
|
553
|
+
let lc = ge * abs(dot(cZ, hit.faceNormal));
|
|
554
|
+
let nj = hW * abs(dot(fI, hit.faceNormal));
|
|
555
|
+
let kj = gC * abs(dot(eh, hit.faceNormal));
|
|
556
|
+
var weight = lc / max(
|
|
557
|
+
lc * lc + nj * nj +
|
|
558
|
+
kj * kj,
|
|
642
559
|
1e-8
|
|
643
560
|
);
|
|
644
|
-
weight *=
|
|
645
|
-
max(
|
|
646
|
-
|
|
561
|
+
weight *= bevelCubicPdf(radius, distance(hit.position, source.position)) /
|
|
562
|
+
max(bevelCubicPdf(radius, gQ.x), 1e-8);
|
|
563
|
+
iE += weight * hit.vertexNormal;
|
|
647
564
|
}
|
|
648
565
|
|
|
649
|
-
if (dot(
|
|
650
|
-
let
|
|
651
|
-
let result = source.normal +
|
|
566
|
+
if (dot(iE, iE) <= 1e-12) { return source.normal; }
|
|
567
|
+
let jM = normalize(iE);
|
|
568
|
+
let result = source.normal + jM - source.vertexNormal;
|
|
652
569
|
if (dot(result, result) > 1e-12) { return normalize(result); }
|
|
653
570
|
return source.normal;
|
|
654
571
|
}
|
|
655
572
|
|
|
656
|
-
fn
|
|
657
|
-
var
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
573
|
+
fn cG(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>, sc: bool) -> vec4f {
|
|
574
|
+
var path: Path;
|
|
575
|
+
path.ray = ray;
|
|
576
|
+
path.li = vec3f(0.0);
|
|
577
|
+
path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
578
|
+
path.beta = vec3f(1.0);
|
|
579
|
+
path.fromEye = true;
|
|
580
|
+
path.scatteringPdf = 0.0;
|
|
581
|
+
path.scatteringIsDelta = false;
|
|
582
|
+
path.isNextRefraction = false;
|
|
583
|
+
path.abort = false;
|
|
667
584
|
|
|
668
585
|
let bounceLimit = max(rtUniform.bounces, 0);
|
|
669
|
-
let
|
|
586
|
+
let eZ = min(bounceLimit * 3, ${MAX_PATH_EVENTS});
|
|
670
587
|
var depth = 0;
|
|
671
588
|
var aJ = false;
|
|
672
|
-
var
|
|
589
|
+
var bH = false;
|
|
673
590
|
|
|
674
591
|
|
|
675
592
|
|
|
676
593
|
|
|
677
|
-
for (var event = 0; event <=
|
|
678
|
-
if ((event != 0) |
|
|
679
|
-
intersectScene(
|
|
680
|
-
|
|
594
|
+
for (var event = 0; event <= eZ; event++) {
|
|
595
|
+
if ((event != 0) | sc) {
|
|
596
|
+
intersectScene(path.ray, si, depth, event != 0, path.isNextRefraction);
|
|
597
|
+
getMaterial(ma, (*si).materialIndex, (*si).uv, (*si).uv1, (*si).instanceIndex, (*si).vertexColor);
|
|
681
598
|
}
|
|
682
599
|
if (event == 0) {
|
|
683
|
-
if (
|
|
600
|
+
if (sc & (*si).hit & ((*ma).materialType == STANDARD)) {
|
|
684
601
|
(*outAux).albedo = select((*ma).baseColor, vec3f(1.0), (*ma).transmissionWeight > 0.5);
|
|
685
602
|
(*outAux).normal = select((*si).normal, -(*si).normal,
|
|
686
603
|
dot((*si).normal, (*si).position - cameraUniform.viewInv[3].xyz) > 0.0);
|
|
687
604
|
(*si).albedoSampled = (*ma).transmissionWeight > 0.5;
|
|
688
605
|
}
|
|
689
|
-
|
|
606
|
+
bH = ((*ma).transmissionWeight < 0.001) & ((*ma).subsurfaceWeight < 0.001) & ((*ma).alpha > 0.99);
|
|
690
607
|
} else {
|
|
691
|
-
|
|
608
|
+
jQ(&path, &depth, si, ma, aJ);
|
|
692
609
|
}
|
|
693
|
-
if (
|
|
694
|
-
if (
|
|
695
|
-
|
|
696
|
-
if (
|
|
610
|
+
if (bH & (event > bounceLimit)) { path.abort = true; }
|
|
611
|
+
if (path.abort | (event >= eZ)) { break; }
|
|
612
|
+
nO(uv, &path, &depth, si, ma, outAux, &aJ);
|
|
613
|
+
if (path.abort) { break; }
|
|
697
614
|
}
|
|
698
615
|
|
|
699
|
-
return vec4f(
|
|
616
|
+
return vec4f(path.li, path.alpha);
|
|
700
617
|
}
|
|
701
618
|
|
|
702
|
-
fn
|
|
619
|
+
fn iC(uv: vec2f, si: ptr<function, SurfaceInteraction>, ray: Ray, ma: ptr<function, OpenPbrResolvedMaterial>, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
703
620
|
${deterministicPrimaryAlpha ? /* wgsl */ `let coverage = clamp((*ma).alpha, 0.0, 1.0);
|
|
704
621
|
|
|
705
622
|
|
|
706
623
|
|
|
707
624
|
|
|
708
625
|
let split = (*si).hit & (((*ma).materialType == STANDARD) | ((*ma).materialType == UNLIT)) & (coverage < 1.0);
|
|
709
|
-
var
|
|
626
|
+
var st = ray;
|
|
710
627
|
var tr = *si;
|
|
711
628
|
var tq = *ma;
|
|
712
|
-
var
|
|
629
|
+
var iw = *outAux;
|
|
713
630
|
if (split) {
|
|
714
|
-
|
|
631
|
+
st.o = (*si).position + ray.d * (EPS * 0.02);
|
|
715
632
|
tr.albedoSampled = false;
|
|
716
633
|
}
|
|
717
634
|
var back: vec4f;
|
|
718
|
-
var
|
|
635
|
+
var eg: RayTraceAuxiliary;
|
|
719
636
|
|
|
720
637
|
|
|
721
|
-
let
|
|
722
|
-
for (var
|
|
723
|
-
let result =
|
|
724
|
-
if (!split | (coverage <= 0.0)) { *outAux =
|
|
725
|
-
if (
|
|
726
|
-
back = result;
|
|
638
|
+
let vq = select(1u, rtUniform.loopUnrollGuard >> 1u, split & (coverage > 0.0));
|
|
639
|
+
for (var uM = 0u; uM < vq; uM++) {
|
|
640
|
+
let result = cG(uv, &tr, st, &tq, &iw, split & (uM == 0u));
|
|
641
|
+
if (!split | (coverage <= 0.0)) { *outAux = iw; return result; }
|
|
642
|
+
if (uM == 0u) {
|
|
643
|
+
back = result; eg = iw;
|
|
727
644
|
tr = *si; tq = *ma; tq.alpha = 1.0;
|
|
728
|
-
|
|
645
|
+
st = ray; iw = *outAux;
|
|
729
646
|
} else {
|
|
730
|
-
(*outAux).albedo = mix(
|
|
731
|
-
let
|
|
732
|
-
(*outAux).normal = select(vec3f(0.0), normalize(
|
|
733
|
-
(*outAux).isBlank =
|
|
734
|
-
(*outAux).isShadowCatcher =
|
|
735
|
-
(*outAux).shadowCounts = mix(
|
|
647
|
+
(*outAux).albedo = mix(eg.albedo, iw.albedo, coverage);
|
|
648
|
+
let cS = mix(eg.normal, iw.normal, coverage);
|
|
649
|
+
(*outAux).normal = select(vec3f(0.0), normalize(cS), dot(cS, cS) > 1e-12);
|
|
650
|
+
(*outAux).isBlank = eg.isBlank & iw.isBlank;
|
|
651
|
+
(*outAux).isShadowCatcher = eg.isShadowCatcher & iw.isShadowCatcher;
|
|
652
|
+
(*outAux).shadowCounts = mix(eg.shadowCounts, iw.shadowCounts, coverage);
|
|
736
653
|
return mix(back, result, coverage);
|
|
737
654
|
}
|
|
738
655
|
}
|
|
739
|
-
return vec4f(0.0);` : /* wgsl */ `return
|
|
656
|
+
return vec4f(0.0);` : /* wgsl */ `return cG(uv, si, ray, ma, outAux, false);`}
|
|
740
657
|
}
|
|
741
658
|
|
|
742
659
|
|
|
743
660
|
|
|
744
|
-
${spectral === false && deterministicPrimaryAlpha ? /* wgsl */ `fn
|
|
661
|
+
${spectral === false && deterministicPrimaryAlpha ? /* wgsl */ `fn hR(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
745
662
|
${primaryVariables}
|
|
746
|
-
var
|
|
747
|
-
var
|
|
748
|
-
var
|
|
749
|
-
var
|
|
663
|
+
var oy: SurfaceInteraction;
|
|
664
|
+
var ox: OpenPbrResolvedMaterial;
|
|
665
|
+
var uh: RayTraceAuxiliary;
|
|
666
|
+
var iH = false;
|
|
750
667
|
var query = true;
|
|
751
668
|
var split = false;
|
|
752
669
|
var coverage = 1.0;
|
|
753
670
|
var front = false;
|
|
754
671
|
var back: vec4f;
|
|
755
|
-
var
|
|
756
|
-
var
|
|
757
|
-
|
|
758
|
-
|
|
672
|
+
var eg: RayTraceAuxiliary;
|
|
673
|
+
var path: Path; path.ray = ray;
|
|
674
|
+
path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
675
|
+
path.beta = vec3f(1.0); path.fromEye = true;
|
|
759
676
|
let bounceLimit = max(rtUniform.bounces, 0);
|
|
760
|
-
let
|
|
677
|
+
let eZ = min(bounceLimit * 3, ${MAX_PATH_EVENTS});
|
|
761
678
|
var event = 0; var depth = 0; var aJ = false;
|
|
762
|
-
var
|
|
679
|
+
var bH = false;
|
|
763
680
|
|
|
764
681
|
|
|
765
682
|
for (var step = 0; step < (${MAX_PATH_EVENTS} + 1) * 2 + 2; step++) {
|
|
766
683
|
if (query) {
|
|
767
|
-
intersectScene(
|
|
768
|
-
|
|
684
|
+
intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
|
|
685
|
+
getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
769
686
|
}
|
|
770
687
|
query = true;
|
|
771
|
-
if (!
|
|
688
|
+
if (!iH) {
|
|
772
689
|
${primaryGuides}
|
|
773
|
-
|
|
774
|
-
|
|
690
|
+
oy = si; ox = ma; uh = *outAux;
|
|
691
|
+
iH = true;
|
|
775
692
|
coverage = clamp(ma.alpha, 0.0, 1.0);
|
|
776
693
|
split = si.hit & ((ma.materialType == STANDARD) | (ma.materialType == UNLIT)) & (coverage < 1.0);
|
|
777
694
|
if (split) {
|
|
778
|
-
|
|
695
|
+
path.ray.o = si.position + ray.d * (EPS * 0.02);
|
|
779
696
|
si.albedoSampled = false;
|
|
780
697
|
continue;
|
|
781
698
|
}
|
|
@@ -788,146 +705,150 @@ si.albedoSampled = ma.transmissionWeight > 0.5;
|
|
|
788
705
|
}
|
|
789
706
|
}
|
|
790
707
|
if (event == 0) {
|
|
791
|
-
|
|
708
|
+
bH = (ma.transmissionWeight < 0.001) & (ma.subsurfaceWeight < 0.001) & (ma.alpha > 0.99);
|
|
792
709
|
} else {
|
|
793
|
-
|
|
710
|
+
jQ(&path, &depth, &si, &ma, aJ);
|
|
794
711
|
}
|
|
795
|
-
if (
|
|
796
|
-
if (!
|
|
797
|
-
|
|
712
|
+
if (bH & (event > bounceLimit)) { path.abort = true; }
|
|
713
|
+
if (!path.abort & (event < eZ)) {
|
|
714
|
+
nO(uv, &path, &depth, &si, &ma, outAux, &aJ);
|
|
798
715
|
}
|
|
799
|
-
if (
|
|
800
|
-
let result = vec4f(
|
|
716
|
+
if (path.abort | (event >= eZ)) {
|
|
717
|
+
let result = vec4f(path.li, path.alpha);
|
|
801
718
|
if (!split | (coverage <= 0.0)) { return result; }
|
|
802
719
|
if (front) {
|
|
803
|
-
(*outAux).albedo = mix(
|
|
804
|
-
let
|
|
805
|
-
(*outAux).normal = select(vec3f(0.0), normalize(
|
|
806
|
-
(*outAux).isBlank =
|
|
807
|
-
(*outAux).isShadowCatcher =
|
|
808
|
-
(*outAux).shadowCounts = mix(
|
|
720
|
+
(*outAux).albedo = mix(eg.albedo, (*outAux).albedo, coverage);
|
|
721
|
+
let cS = mix(eg.normal, (*outAux).normal, coverage);
|
|
722
|
+
(*outAux).normal = select(vec3f(0.0), normalize(cS), dot(cS, cS) > 1e-12);
|
|
723
|
+
(*outAux).isBlank = eg.isBlank & (*outAux).isBlank;
|
|
724
|
+
(*outAux).isShadowCatcher = eg.isShadowCatcher & (*outAux).isShadowCatcher;
|
|
725
|
+
(*outAux).shadowCounts = mix(eg.shadowCounts, (*outAux).shadowCounts, coverage);
|
|
809
726
|
return mix(back, result, coverage);
|
|
810
727
|
}
|
|
811
|
-
back = result;
|
|
728
|
+
back = result; eg = *outAux;
|
|
812
729
|
front = true; query = false; event = 0; depth = 0; aJ = false;
|
|
813
|
-
si =
|
|
814
|
-
|
|
815
|
-
|
|
730
|
+
si = oy; ma = ox; ma.alpha = 1.0; *outAux = uh;
|
|
731
|
+
path = Path(); path.ray = ray; path.beta = vec3f(1.0); path.fromEye = true;
|
|
732
|
+
path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
816
733
|
} else { event++; }
|
|
817
734
|
}
|
|
818
735
|
return vec4f(0.0);
|
|
819
736
|
}
|
|
820
|
-
` : spectral === false && !deterministicPrimaryAlpha ? /* wgsl */ `fn
|
|
737
|
+
` : spectral === false && !deterministicPrimaryAlpha ? /* wgsl */ `fn hR(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
821
738
|
${primaryVariables}
|
|
822
|
-
var
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
739
|
+
var path: Path;
|
|
740
|
+
path.ray = ray;
|
|
741
|
+
path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
742
|
+
path.beta = vec3f(1.0);
|
|
743
|
+
path.fromEye = true;
|
|
827
744
|
let bounceLimit = max(rtUniform.bounces, 0);
|
|
828
|
-
let
|
|
829
|
-
var
|
|
745
|
+
let eZ = min(bounceLimit * 3, ${MAX_PATH_EVENTS});
|
|
746
|
+
var bH = false;
|
|
830
747
|
var depth = 0;
|
|
831
748
|
var aJ = false;
|
|
832
749
|
|
|
833
750
|
|
|
834
751
|
|
|
835
|
-
for (var event = 0; event <=
|
|
836
|
-
intersectScene(
|
|
837
|
-
|
|
752
|
+
for (var event = 0; event <= eZ; event++) {
|
|
753
|
+
intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
|
|
754
|
+
getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
838
755
|
if (event == 0) {
|
|
839
756
|
${primaryGuides}
|
|
840
|
-
|
|
757
|
+
bH = ma.transmissionWeight < 0.001 && ma.subsurfaceWeight < 0.001 && ma.alpha > 0.99;
|
|
841
758
|
} else {
|
|
842
|
-
|
|
759
|
+
jQ(&path, &depth, &si, &ma, aJ);
|
|
843
760
|
}
|
|
844
|
-
if (
|
|
845
|
-
if (
|
|
846
|
-
|
|
847
|
-
if (
|
|
761
|
+
if (bH && event > bounceLimit) { path.abort = true; }
|
|
762
|
+
if (path.abort || event >= eZ) { break; }
|
|
763
|
+
nO(uv, &path, &depth, &si, &ma, outAux, &aJ);
|
|
764
|
+
if (path.abort) { break; }
|
|
848
765
|
}
|
|
849
|
-
return vec4f(
|
|
766
|
+
return vec4f(path.li, path.alpha);
|
|
850
767
|
}
|
|
851
768
|
` : spectral === true && !deterministicPrimaryAlpha ? /* wgsl */ `
|
|
852
|
-
fn
|
|
769
|
+
fn hR(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
853
770
|
${primaryVariables}
|
|
854
|
-
var
|
|
855
|
-
var
|
|
856
|
-
var
|
|
857
|
-
var
|
|
771
|
+
var oy: SurfaceInteraction;
|
|
772
|
+
var ox: OpenPbrResolvedMaterial;
|
|
773
|
+
var iH = false;
|
|
774
|
+
var path: Path; path.ray = ray;
|
|
858
775
|
let bounceLimit = max(rtUniform.bounces, 0);
|
|
859
|
-
let
|
|
776
|
+
let eZ = min(bounceLimit * 3, ${MAX_PATH_EVENTS});
|
|
860
777
|
var depth = 0; var event = 0; var aJ = false;
|
|
861
|
-
var
|
|
862
|
-
var
|
|
863
|
-
let
|
|
864
|
-
var
|
|
865
|
-
var
|
|
866
|
-
var
|
|
867
|
-
var
|
|
868
|
-
var
|
|
869
|
-
|
|
778
|
+
var bH = false;
|
|
779
|
+
var mc = 0;
|
|
780
|
+
let bi = rtUniform.dispersionWavelengths == 1;
|
|
781
|
+
var ew = false;
|
|
782
|
+
var eG = 0;
|
|
783
|
+
var aZ = 0.0;
|
|
784
|
+
var he: vec4u;
|
|
785
|
+
var ey = 0u;
|
|
786
|
+
var aU: RayTraceAuxiliary;
|
|
870
787
|
var color = vec3f(0.0); var alpha = 0.0;
|
|
871
|
-
var
|
|
872
|
-
var
|
|
873
|
-
var
|
|
788
|
+
var dw = vec3f(0.0);
|
|
789
|
+
var dz = vec3f(0.0);
|
|
790
|
+
var mz = true;
|
|
874
791
|
|
|
875
792
|
|
|
876
793
|
|
|
877
|
-
let
|
|
878
|
-
for (var step = 0; step <
|
|
879
|
-
if (!
|
|
880
|
-
intersectScene(
|
|
881
|
-
|
|
794
|
+
let xf = min((${MAX_PATH_EVENTS} + 1) * 3, i32(rtUniform.loopUnrollGuard * ${Math.ceil((MAX_PATH_EVENTS + 1) * 3 / 4)}u));
|
|
795
|
+
for (var step = 0; step < xf; step++) {
|
|
796
|
+
if (!iH | ((event != 0) & !path.abort)) {
|
|
797
|
+
intersectScene(path.ray, &si, depth, event != 0, path.isNextRefraction);
|
|
798
|
+
getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
882
799
|
}
|
|
883
800
|
if (event == 0) {
|
|
884
|
-
if (!
|
|
801
|
+
if (!iH) {
|
|
885
802
|
${primaryGuides}
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
if (
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
|
|
898
|
-
|
|
899
|
-
|
|
900
|
-
si.wavelength =
|
|
901
|
-
|
|
803
|
+
oy = si; ox = ma; iH = true;
|
|
804
|
+
ew = si.hit & (ma.transmissionWeight > 0.001) & (ma.transmissionDispersionScale > 0.001);
|
|
805
|
+
aZ = sample1D(CAMERA_WAVELENGTH);
|
|
806
|
+
if (bi) {
|
|
807
|
+
eG = min(i32(floor(aZ * 3.0)), 2);
|
|
808
|
+
aZ = fract(aZ * 3.0);
|
|
809
|
+
}
|
|
810
|
+
he = s0; ey = ca;
|
|
811
|
+
}
|
|
812
|
+
si = oy; ma = ox; aU = *outAux;
|
|
813
|
+
if (!bi) {
|
|
814
|
+
s0 = he; ca = ey; samplingBounce = 0u;
|
|
815
|
+
aU.isBlank = false; aU.isShadowCatcher = false;
|
|
816
|
+
}
|
|
817
|
+
si.wavelength = 0.0; si.spectralChannel = 0;
|
|
818
|
+
if (!bi | ew) {
|
|
819
|
+
let channel = select(mc, eG, bi);
|
|
820
|
+
si.spectralChannel = channel + 1;
|
|
821
|
+
si.wavelength = cU(u32(channel), aZ);
|
|
822
|
+
ma.specularIor = sampling_cauchy_ior(si.wavelength, ma.specularIor,
|
|
902
823
|
ma.transmissionDispersionScale, ma.dispersionAbbeNumber);
|
|
903
824
|
}
|
|
904
|
-
|
|
905
|
-
|
|
825
|
+
path = Path(); path.ray = ray; path.beta = vec3f(1.0); path.fromEye = true;
|
|
826
|
+
path.alpha = select(1.0, 0.0, rtUniform.transmissiveOutputAlphaMin < 1.0);
|
|
906
827
|
depth = 0; aJ = false;
|
|
907
|
-
|
|
908
|
-
} else if (!
|
|
909
|
-
|
|
910
|
-
}
|
|
911
|
-
if (
|
|
912
|
-
if (!
|
|
913
|
-
|
|
914
|
-
}
|
|
915
|
-
if (
|
|
916
|
-
let result = vec4f(
|
|
917
|
-
if (
|
|
918
|
-
*outAux =
|
|
919
|
-
let scale = select(1.0, 3.0,
|
|
828
|
+
bH = (ma.transmissionWeight < 0.001) & (ma.subsurfaceWeight < 0.001) & (ma.alpha > 0.99);
|
|
829
|
+
} else if (!path.abort) {
|
|
830
|
+
jQ(&path, &depth, &si, &ma, aJ);
|
|
831
|
+
}
|
|
832
|
+
if (bH & (event > bounceLimit)) { path.abort = true; }
|
|
833
|
+
if (!path.abort & (event < eZ)) {
|
|
834
|
+
nO(uv, &path, &depth, &si, &ma, &aU, &aJ);
|
|
835
|
+
}
|
|
836
|
+
if (path.abort | (event >= eZ)) {
|
|
837
|
+
let result = vec4f(path.li, path.alpha);
|
|
838
|
+
if (bi) {
|
|
839
|
+
*outAux = aU;
|
|
840
|
+
let scale = select(1.0, 3.0, ew);
|
|
920
841
|
return vec4f(result.rgb * scale, result.a);
|
|
921
842
|
}
|
|
922
843
|
color += result.rgb; alpha = max(alpha, result.a);
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
if (
|
|
928
|
-
(*outAux).albedo =
|
|
929
|
-
(*outAux).normal =
|
|
930
|
-
(*outAux).isBlank =
|
|
844
|
+
dw += aU.albedo;
|
|
845
|
+
dz += aU.normal;
|
|
846
|
+
mz = mz & aU.isBlank;
|
|
847
|
+
mc++;
|
|
848
|
+
if (mc >= 3) {
|
|
849
|
+
(*outAux).albedo = dw / 3.0;
|
|
850
|
+
(*outAux).normal = dz / 3.0;
|
|
851
|
+
(*outAux).isBlank = mz;
|
|
931
852
|
return vec4f(color, alpha);
|
|
932
853
|
}
|
|
933
854
|
event = 0;
|
|
@@ -935,91 +856,95 @@ event = 0;
|
|
|
935
856
|
}
|
|
936
857
|
return vec4f(0.0);
|
|
937
858
|
}
|
|
938
|
-
` : /* wgsl */ `fn
|
|
859
|
+
` : /* wgsl */ `fn hR(uv: vec2f, ray: Ray, outAux: ptr<function, RayTraceAuxiliary>) -> vec4f {
|
|
939
860
|
${primaryVariables}
|
|
940
861
|
intersectScene(ray, &si, 0, false, false);
|
|
941
|
-
|
|
862
|
+
getMaterial(&ma, si.materialIndex, si.uv, si.uv1, si.instanceIndex, si.vertexColor);
|
|
942
863
|
${primaryGuides}
|
|
943
864
|
if (SPECTRAL) {
|
|
944
865
|
|
|
945
866
|
|
|
946
867
|
|
|
947
868
|
|
|
948
|
-
|
|
949
|
-
var vl = vec3f(0.0);
|
|
869
|
+
var vu = vec3f(0.0);
|
|
950
870
|
var alpha = 0.0;
|
|
951
|
-
var
|
|
952
|
-
var
|
|
953
|
-
var
|
|
871
|
+
var dw = vec3f(0.0);
|
|
872
|
+
var dz = vec3f(0.0);
|
|
873
|
+
var mz = true;
|
|
954
874
|
var si2 = si;
|
|
955
875
|
var ma2 = ma;
|
|
956
|
-
|
|
957
|
-
let
|
|
958
|
-
let
|
|
959
|
-
let
|
|
876
|
+
var aZ = sample1D(CAMERA_WAVELENGTH);
|
|
877
|
+
let he = s0;
|
|
878
|
+
let ey = ca;
|
|
879
|
+
let bi = rtUniform.dispersionWavelengths == 1;
|
|
880
|
+
let ew = si.hit &&
|
|
960
881
|
ma.transmissionWeight > 0.001 &&
|
|
961
882
|
ma.transmissionDispersionScale > 0.001;
|
|
962
|
-
let tm = select(3, 1,
|
|
963
|
-
var
|
|
964
|
-
if (
|
|
883
|
+
let tm = select(3, 1, bi);
|
|
884
|
+
var eG = 0;
|
|
885
|
+
if (bi) {
|
|
965
886
|
|
|
966
887
|
|
|
967
|
-
|
|
888
|
+
eG = min(i32(floor(aZ * 3.0)), 2);
|
|
889
|
+
aZ = fract(aZ * 3.0);
|
|
968
890
|
}
|
|
969
891
|
for (var i = 0; i < tm; i++) {
|
|
970
892
|
|
|
971
893
|
|
|
972
894
|
|
|
973
|
-
if (!
|
|
974
|
-
s0 =
|
|
975
|
-
|
|
976
|
-
|
|
895
|
+
if (!bi) {
|
|
896
|
+
s0 = he;
|
|
897
|
+
ca = ey;
|
|
898
|
+
samplingBounce = 0u;
|
|
977
899
|
}
|
|
978
900
|
si.wavelength = 0.0;
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
901
|
+
si.spectralChannel = 0;
|
|
902
|
+
if (!bi || ew) {
|
|
903
|
+
let channel = select(i, eG, bi);
|
|
904
|
+
si.spectralChannel = channel + 1;
|
|
905
|
+
si.wavelength = cU(u32(channel), aZ);
|
|
906
|
+
ma.specularIor = sampling_cauchy_ior(
|
|
982
907
|
si.wavelength,
|
|
983
908
|
ma.specularIor,
|
|
984
909
|
ma.transmissionDispersionScale,
|
|
985
910
|
ma.dispersionAbbeNumber
|
|
986
911
|
);
|
|
987
912
|
}
|
|
988
|
-
var
|
|
989
|
-
if (
|
|
990
|
-
|
|
913
|
+
var aU: RayTraceAuxiliary;
|
|
914
|
+
if (bi) {
|
|
915
|
+
aU = *outAux;
|
|
991
916
|
} else {
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
}
|
|
997
|
-
let res =
|
|
998
|
-
if (
|
|
999
|
-
*outAux =
|
|
1000
|
-
let scale = select(1.0, 3.0,
|
|
917
|
+
aU.albedo = (*outAux).albedo;
|
|
918
|
+
aU.normal = (*outAux).normal;
|
|
919
|
+
aU.isBlank = false;
|
|
920
|
+
aU.isShadowCatcher = false;
|
|
921
|
+
}
|
|
922
|
+
let res = iC(uv, &si, ray, &ma, &aU);
|
|
923
|
+
if (bi) {
|
|
924
|
+
*outAux = aU;
|
|
925
|
+
let scale = select(1.0, 3.0, ew);
|
|
1001
926
|
return vec4f(res.rgb * scale, res.a);
|
|
1002
927
|
}
|
|
1003
|
-
|
|
928
|
+
vu += res.rgb;
|
|
1004
929
|
alpha = max(alpha, res.a);
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
930
|
+
dw += aU.albedo;
|
|
931
|
+
dz += aU.normal;
|
|
932
|
+
mz = mz && aU.isBlank;
|
|
1008
933
|
si = si2;
|
|
1009
934
|
ma = ma2;
|
|
1010
935
|
}
|
|
1011
|
-
(*outAux).albedo =
|
|
1012
|
-
(*outAux).normal =
|
|
1013
|
-
(*outAux).isBlank =
|
|
1014
|
-
return vec4f(
|
|
936
|
+
(*outAux).albedo = dw / 3.0;
|
|
937
|
+
(*outAux).normal = dz / 3.0;
|
|
938
|
+
(*outAux).isBlank = mz;
|
|
939
|
+
return vec4f(vu, alpha);
|
|
1015
940
|
}
|
|
1016
941
|
else {
|
|
1017
|
-
return
|
|
942
|
+
return iC(uv, &si, ray, &ma, outAux);
|
|
1018
943
|
}
|
|
1019
944
|
}
|
|
1020
945
|
`}
|
|
1021
946
|
|
|
1022
|
-
fn
|
|
947
|
+
fn kq(ip: vec2f) -> vec2f {
|
|
1023
948
|
let p = 2.0 * ip - 1.0;
|
|
1024
949
|
let greater = abs(p.x) > abs(p.y);
|
|
1025
950
|
let r = select(p.y, p.x, greater);
|
|
@@ -1028,7 +953,7 @@ return r * vec2f(cos(theta), sin(theta));
|
|
|
1028
953
|
}
|
|
1029
954
|
|
|
1030
955
|
|
|
1031
|
-
@compute @workgroup_size(${
|
|
956
|
+
@compute @workgroup_size(${workgroupSize}, ${workgroupSize}, 1)
|
|
1032
957
|
fn main(@builtin(global_invocation_id) globalId: vec3u) {
|
|
1033
958
|
let outputSize = rtUniform.outputSize;
|
|
1034
959
|
let scaleOffset = rtUniform.scaleOffset;
|
|
@@ -1058,24 +983,24 @@ return;
|
|
|
1058
983
|
|
|
1059
984
|
let uv = (vec2<f32>(f32(coord.x), f32(coord.y)) + vec2f(0.5)) / outputSize;
|
|
1060
985
|
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
986
|
+
aI = coord;
|
|
987
|
+
aC = u32(outNormal[idx].a) + rtUniform.sampleSequenceOffset;
|
|
988
|
+
samplingBounce = 0u; ca = 0u;
|
|
1064
989
|
if (${inputHooks?.uniformJitter ? 'false' : 'SAMPLING_PATTERN == 0 || SAMPLING_PATTERN == 1'}) {
|
|
1065
|
-
jitter = (
|
|
990
|
+
jitter = (sample2D(CAMERA_PIXEL) - 0.5) / outputSize;
|
|
1066
991
|
}
|
|
1067
|
-
|
|
1068
|
-
var cam =
|
|
992
|
+
fi(coord, i32(aC ^ cB(rtUniform.sequenceSeed)));
|
|
993
|
+
var cam = eT(uv + jitter);
|
|
1069
994
|
|
|
1070
995
|
if (cameraUniform.apertureRadius > 0.0) {
|
|
1071
996
|
|
|
1072
997
|
let eye = cameraUniform.viewInv[3].xyz;
|
|
1073
998
|
let forward = -normalize(cameraUniform.viewInv[2].xyz);
|
|
1074
|
-
let
|
|
1075
|
-
let
|
|
1076
|
-
let origin = (cameraUniform.viewInv * vec4f(
|
|
1077
|
-
let dir = normalize(
|
|
1078
|
-
|
|
999
|
+
let ju = eye + cam.d * (cameraUniform.focusDistance / dot(cam.d, forward));
|
|
1000
|
+
let sH = cameraUniform.apertureRadius * kq(sample2D(CAMERA_LENS));
|
|
1001
|
+
let origin = (cameraUniform.viewInv * vec4f(sH, 0.0, 1.0)).xyz;
|
|
1002
|
+
let dir = normalize(ju - origin);
|
|
1003
|
+
initRay(&cam, origin, dir);
|
|
1079
1004
|
}
|
|
1080
1005
|
|
|
1081
1006
|
var outAux: RayTraceAuxiliary;
|
|
@@ -1083,39 +1008,40 @@ outAux.albedo = vec3f(0.0);
|
|
|
1083
1008
|
outAux.normal = vec3f(0.0);
|
|
1084
1009
|
outAux.isBlank = false;
|
|
1085
1010
|
outAux.isShadowCatcher = false;
|
|
1086
|
-
${pathDiagnostic ? ' mtPathBegin(coord);\n' : ''}${inputHooks?.begin ?? ''} var
|
|
1011
|
+
${pathDiagnostic ? ' mtPathBegin(coord);\n' : ''}${inputHooks?.begin ?? ''} var liAndAlpha = hR(uv + jitter, cam, &outAux);
|
|
1087
1012
|
${inputHooks?.unclampedColor ?? ''}
|
|
1088
|
-
|
|
1013
|
+
${(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
|
+
` : ''}
|
|
1089
1015
|
|
|
1090
1016
|
if (rtUniform.clamping > 0.0) {
|
|
1091
1017
|
let clamping = rtUniform.clamping;
|
|
1092
|
-
|
|
1018
|
+
liAndAlpha = vec4(clamp(liAndAlpha.rgb, -vec3f(clamping), vec3f(clamping)), liAndAlpha.a);
|
|
1093
1019
|
}
|
|
1094
|
-
if (!(
|
|
1095
|
-
|
|
1020
|
+
if (!(liAndAlpha.x < INF && liAndAlpha.x > -EPS)) {
|
|
1021
|
+
liAndAlpha = vec4f(0.0, 0.0, 0.0, 1.0);
|
|
1096
1022
|
}
|
|
1097
1023
|
|
|
1098
1024
|
if (outAux.isShadowCatcher) {
|
|
1099
1025
|
|
|
1100
1026
|
|
|
1101
|
-
let
|
|
1102
|
-
let
|
|
1103
|
-
let
|
|
1027
|
+
let aW = ft(cam);
|
|
1028
|
+
let qX = select(0.0, 1.0, aW.a >= 0.01);
|
|
1029
|
+
let jC = vec4f(aW.rgb * aW.a, aW.a);
|
|
1104
1030
|
|
|
1105
1031
|
|
|
1106
1032
|
|
|
1107
|
-
outShadowCatcher[idx].mask += vec4f(1.0,
|
|
1033
|
+
outShadowCatcher[idx].mask += vec4f(1.0, aW.a, qX, 0.0);
|
|
1108
1034
|
outShadowCatcher[idx].moments += vec4f(0.0, 0.0, outAux.shadowCounts);
|
|
1109
|
-
outShadowCatcher[idx].background +=
|
|
1110
|
-
outColor[idx] +=
|
|
1111
|
-
outAlbedo[idx] += vec4f(outAux.albedo,
|
|
1112
|
-
|
|
1035
|
+
outShadowCatcher[idx].background += jC;
|
|
1036
|
+
outColor[idx] += jC;
|
|
1037
|
+
outAlbedo[idx] += vec4f(outAux.albedo, qX);
|
|
1038
|
+
hH(idx, aW.rgb, outAux.normal);
|
|
1113
1039
|
|
|
1114
1040
|
|
|
1115
1041
|
let counts = outAux.shadowCounts;
|
|
1116
1042
|
let visibility = 1.0 - select(0.0, counts.x / counts.y, counts.y > 0.0);
|
|
1117
|
-
|
|
1118
|
-
1.0, dot(
|
|
1043
|
+
iP(idx, visibility * select(
|
|
1044
|
+
1.0, dot(aW.rgb, luminance), aW.a >= 0.01
|
|
1119
1045
|
));
|
|
1120
1046
|
}
|
|
1121
1047
|
else {
|
|
@@ -1125,13 +1051,13 @@ if (HAS_SHADOW_CATCHER && outAux.isBlank && USE_BACKGROUND && !USE_BACKGROUND_MA
|
|
|
1125
1051
|
|
|
1126
1052
|
|
|
1127
1053
|
|
|
1128
|
-
outShadowCatcher[idx].background +=
|
|
1129
|
-
outShadowCatcher[idx].mask.g +=
|
|
1054
|
+
outShadowCatcher[idx].background += liAndAlpha;
|
|
1055
|
+
outShadowCatcher[idx].mask.g += liAndAlpha.a;
|
|
1130
1056
|
}
|
|
1131
|
-
outColor[idx] +=
|
|
1057
|
+
outColor[idx] += liAndAlpha;
|
|
1132
1058
|
outAlbedo[idx] += vec4f(outAux.albedo, select(1.0, 0.0, outAux.isBlank));
|
|
1133
|
-
|
|
1134
|
-
|
|
1059
|
+
hH(idx, liAndAlpha.rgb, outAux.normal);
|
|
1060
|
+
iP(idx, dot(liAndAlpha.rgb, luminance));
|
|
1135
1061
|
}
|
|
1136
1062
|
${pathDiagnostic ? ' mtPathEnd(outAux.normal, outAux.albedo);\n' : ''}${inputHooks?.end ?? ''}}
|
|
1137
1063
|
`;
|