@meimu/mutracer 0.1.1 → 0.1.3
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/dist/assets/bvh.worker.js +1 -1
- package/dist/mutracer.umd.js +3525 -3484
- package/docs/materials.md +27 -7
- package/docs/threejs.md +13 -2
- package/docs/viewer.md +53 -0
- package/lib/oidn.d.ts +1 -1
- package/lib/oidnBundledWeights.cdn.d.ts +2 -2
- package/lib/renderer/MaterialTable.d.ts +1 -0
- package/lib/renderer/MaterialTable.js +2 -1
- package/lib/renderer/MaterialTable.js.map +1 -1
- package/lib/renderer/WGPUBloomPass.js +18 -18
- package/lib/renderer/WGPUFullQuadPass.js +3 -3
- package/lib/renderer/WGPUJNLMDenoiser.js +62 -62
- package/lib/renderer/WGPURayTraceOutput.js +14 -12
- package/lib/renderer/WGPURayTraceOutput.js.map +1 -1
- package/lib/renderer/WGPURayTracePass.js +2 -2
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +20 -18
- package/lib/renderer/WGPURenderingPipeline.js.map +1 -1
- package/lib/renderer/WebGLJNLMDenoiser.js +61 -61
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.js +3 -1
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +9 -9
- package/lib/renderer/glsl/chunks/envMap.glsl.js +45 -45
- package/lib/renderer/glsl/chunks/intersect.glsl.js +262 -262
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +111 -111
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +436 -436
- package/lib/renderer/glsl/chunks/rand.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/random.glsl.js +3 -3
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js +32 -32
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +54 -54
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +71 -71
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/sampling.glsl.js +64 -64
- package/lib/renderer/glsl/chunks/sobol.glsl.js +49 -49
- package/lib/renderer/glsl/chunks/textureLinear.glsl.js +5 -5
- package/lib/renderer/glsl/chunks/uvProjection.glsl.js +5 -5
- package/lib/renderer/glsl/depthQuery.frag.js +2 -2
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
- package/lib/renderer/glsl/rayTrace.frag.js +128 -128
- package/lib/renderer/glsl/shadowCatcher.frag.js +12 -12
- package/lib/renderer/glsl/webglPipeline.frag.js +49 -49
- package/lib/renderer/lightsUtil.js +1 -1
- package/lib/renderer/lightsUtil.js.map +1 -1
- package/lib/renderer/materialComparison.generated.js +5 -0
- package/lib/renderer/materialComparison.generated.js.map +1 -1
- package/lib/renderer/materialLayout.js +2 -1
- package/lib/renderer/materialLayout.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.d.ts +4 -2
- package/lib/renderer/prepareMeshBVH.js +44 -20
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/scratchSampling.js +6 -6
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +29 -29
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +376 -379
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +5 -5
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +51 -51
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +453 -453
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +122 -117
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/rand.wgsl.js +3 -3
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js +13 -13
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +94 -94
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +119 -119
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +5 -5
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +62 -62
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.d.ts +3 -3
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js +2 -2
- package/lib/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +53 -53
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +5 -5
- package/lib/renderer/wgsl/compose.frag.wgsl.d.ts +2 -2
- package/lib/renderer/wgsl/compose.frag.wgsl.js +120 -92
- package/lib/renderer/wgsl/compose.frag.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.js +3 -3
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +26 -26
- package/lib/renderer/wgsl/rayTrace.compute.js +220 -211
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/OpenPBRMaterial.d.ts +4 -2
- package/lib/scene/OpenPBRMaterial.js +4 -2
- package/lib/scene/OpenPBRMaterial.js.map +1 -1
- package/lib/scene/openPbrSchema.d.ts +7 -2
- package/lib/scene/openPbrSchema.js +2 -1
- package/lib/scene/openPbrSchema.js.map +1 -1
- package/lib/util/fromTHREE.d.ts +1 -0
- package/lib/util/fromTHREE.js +24 -6
- 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 -4
|
@@ -4,28 +4,28 @@ export default /*wgsl*/ `
|
|
|
4
4
|
|
|
5
5
|
|
|
6
6
|
fn aQ(view: vec3f, alpha: vec2f, samplePoint: vec2f) -> vec3f {
|
|
7
|
-
let
|
|
8
|
-
let
|
|
9
|
-
let
|
|
10
|
-
let
|
|
11
|
-
let
|
|
12
|
-
let
|
|
13
|
-
let
|
|
14
|
-
let fi = sqrt(max(0.0,
|
|
7
|
+
let rc = vec3f(alpha, 1.0);
|
|
8
|
+
let gf = normalize(rc * view);
|
|
9
|
+
let ua = min(gf.z, 1.0);
|
|
10
|
+
let qH = 1.0 + ua;
|
|
11
|
+
let qX = (1.0 - samplePoint.y) * qH;
|
|
12
|
+
let rJ = samplePoint.y * qH;
|
|
13
|
+
let sA = qX + (1.0 - ua);
|
|
14
|
+
let fi = sqrt(max(0.0, sA * rJ));
|
|
15
15
|
let br = TWOPI * samplePoint.x;
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
let lw = vec3f(
|
|
17
|
+
gf.x + fi * cos(br),
|
|
18
|
+
gf.y + fi * sin(br),
|
|
19
|
+
qX
|
|
20
20
|
);
|
|
21
|
-
return normalize(
|
|
21
|
+
return normalize(rc * lw);
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
fn
|
|
24
|
+
fn gG(od: vec3f, alpha: vec2f) -> f32 {
|
|
25
25
|
let hm = vec3f(
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
od.x / alpha.x,
|
|
27
|
+
od.y / alpha.y,
|
|
28
|
+
od.z
|
|
29
29
|
);
|
|
30
30
|
let ap = dot(hm, hm);
|
|
31
31
|
return 1.0 / (
|
|
@@ -38,10 +38,10 @@ let eE = abs(direction.z);
|
|
|
38
38
|
if (eE <= 1e-8) {
|
|
39
39
|
return 0.0;
|
|
40
40
|
}
|
|
41
|
-
let
|
|
42
|
-
let
|
|
41
|
+
let hY = alpha * direction.xy;
|
|
42
|
+
let lA = dot(hY, hY)
|
|
43
43
|
/ (eE * eE);
|
|
44
|
-
return 2.0 / (1.0 + sqrt(1.0 +
|
|
44
|
+
return 2.0 / (1.0 + sqrt(1.0 + lA));
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
fn aE(au: f32) -> f32 {
|
|
@@ -49,25 +49,25 @@ let dg = clamp(1.0 - au, 0.0, 1.0);
|
|
|
49
49
|
return pow(dg, 5.0);
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
fn
|
|
52
|
+
fn cu(L: f32, cJ: f32) -> f32 {
|
|
53
53
|
let iu = clamp(abs(L), 0.0, 1.0);
|
|
54
|
-
let
|
|
54
|
+
let ke = cJ * cJ
|
|
55
55
|
* max(0.0, 1.0 - iu * iu);
|
|
56
|
-
if (
|
|
56
|
+
if (ke >= 1.0) {
|
|
57
57
|
return 1.0;
|
|
58
58
|
}
|
|
59
59
|
|
|
60
|
-
let
|
|
61
|
-
let ba = (iu - cJ *
|
|
62
|
-
/ max(iu + cJ *
|
|
63
|
-
let
|
|
64
|
-
/ max(cJ * iu +
|
|
60
|
+
let lK = sqrt(max(0.0, 1.0 - ke));
|
|
61
|
+
let ba = (iu - cJ * lK)
|
|
62
|
+
/ max(iu + cJ * lK, 1e-8);
|
|
63
|
+
let pw = (cJ * iu - lK)
|
|
64
|
+
/ max(cJ * iu + lK, 1e-8);
|
|
65
65
|
return 0.5 * (
|
|
66
|
-
ba * ba +
|
|
66
|
+
ba * ba + pw * pw
|
|
67
67
|
);
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
fn
|
|
70
|
+
fn gd(samplePoint: vec2f) -> vec2f {
|
|
71
71
|
let offset = 2.0 * samplePoint - vec2f(1.0);
|
|
72
72
|
if (offset.x == 0.0 && offset.y == 0.0) {
|
|
73
73
|
return vec2f(0.0);
|
|
@@ -87,39 +87,39 @@ return radius * vec2f(cos(angle), sin(angle));
|
|
|
87
87
|
}
|
|
88
88
|
|
|
89
89
|
fn bi(samplePoint: vec2f) -> vec3f {
|
|
90
|
-
let
|
|
90
|
+
let kx = gd(samplePoint);
|
|
91
91
|
return vec3f(
|
|
92
|
-
|
|
93
|
-
sqrt(max(0.0, 1.0 - dot(
|
|
92
|
+
kx,
|
|
93
|
+
sqrt(max(0.0, 1.0 - dot(kx, kx)))
|
|
94
94
|
);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
|
-
fn
|
|
98
|
-
let scale = max(
|
|
97
|
+
fn aG(pi: f32, nD: f32) -> f32 {
|
|
98
|
+
let scale = max(pi, nD);
|
|
99
99
|
if (scale <= 0.0) {
|
|
100
100
|
return 0.0;
|
|
101
101
|
}
|
|
102
|
-
let normalized = vec2f(
|
|
103
|
-
let
|
|
104
|
-
return
|
|
102
|
+
let normalized = vec2f(pi, nD) / scale;
|
|
103
|
+
let oG = normalized * normalized;
|
|
104
|
+
return oG.x / (oG.x + oG.y);
|
|
105
105
|
}
|
|
106
106
|
|
|
107
|
-
fn
|
|
107
|
+
fn aL(
|
|
108
108
|
normal: vec3f,
|
|
109
109
|
tangent: ptr<function, vec3f>,
|
|
110
110
|
bitangent: ptr<function, vec3f>
|
|
111
111
|
) {
|
|
112
|
-
let
|
|
113
|
-
let dW = -1.0 / (
|
|
112
|
+
let ie = select(-1.0, 1.0, normal.z >= 0.0);
|
|
113
|
+
let dW = -1.0 / (ie + normal.z);
|
|
114
114
|
let xy = normal.x * normal.y * dW;
|
|
115
115
|
*tangent = vec3f(
|
|
116
|
-
1.0 +
|
|
117
|
-
|
|
118
|
-
-
|
|
116
|
+
1.0 + ie * normal.x * normal.x * dW,
|
|
117
|
+
ie * xy,
|
|
118
|
+
-ie * normal.x
|
|
119
119
|
);
|
|
120
120
|
*bitangent = vec3f(
|
|
121
121
|
xy,
|
|
122
|
-
|
|
122
|
+
ie + normal.y * normal.y * dW,
|
|
123
123
|
-normal.y
|
|
124
124
|
);
|
|
125
125
|
}
|
|
@@ -139,30 +139,30 @@ return vec3f(0.0, 0.0, rgb.b);
|
|
|
139
139
|
|
|
140
140
|
fn eK(
|
|
141
141
|
wavelength: f32,
|
|
142
|
-
|
|
142
|
+
hb: f32,
|
|
143
143
|
hk: f32,
|
|
144
|
-
|
|
144
|
+
qk: f32
|
|
145
145
|
) -> f32 {
|
|
146
146
|
if (wavelength == 0.0 || hk <= 0.0) {
|
|
147
|
-
return
|
|
147
|
+
return hb;
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
let FRAUNHOFER_C = 656.3;
|
|
151
151
|
let FRAUNHOFER_D = 587.6;
|
|
152
152
|
let FRAUNHOFER_F = 486.1;
|
|
153
|
-
let
|
|
153
|
+
let jK = 1.0 / (
|
|
154
154
|
1.0 / (FRAUNHOFER_F * FRAUNHOFER_F)
|
|
155
155
|
- 1.0 / (FRAUNHOFER_C * FRAUNHOFER_C)
|
|
156
156
|
);
|
|
157
|
-
let
|
|
158
|
-
let
|
|
159
|
-
let
|
|
160
|
-
-
|
|
161
|
-
return
|
|
157
|
+
let mT = max(qk / hk, 1e-6);
|
|
158
|
+
let qI = (hb - 1.0) * jK / mT;
|
|
159
|
+
let td = hb
|
|
160
|
+
- qI / (FRAUNHOFER_D * FRAUNHOFER_D);
|
|
161
|
+
return td + qI / (wavelength * wavelength);
|
|
162
162
|
}
|
|
163
163
|
|
|
164
164
|
fn fl(
|
|
165
|
-
|
|
165
|
+
gu: vec3f,
|
|
166
166
|
anisotropy: f32,
|
|
167
167
|
samplePoint: vec2f
|
|
168
168
|
) -> vec3f {
|
|
@@ -171,21 +171,21 @@ if (abs(anisotropy) < 0.001) {
|
|
|
171
171
|
au = 1.0 - 2.0 * samplePoint.y;
|
|
172
172
|
}
|
|
173
173
|
else {
|
|
174
|
-
let
|
|
174
|
+
let iV = (1.0 - anisotropy * anisotropy)
|
|
175
175
|
/ (1.0 + anisotropy - 2.0 * anisotropy * samplePoint.y);
|
|
176
176
|
au = (
|
|
177
|
-
|
|
177
|
+
iV * iV - 1.0 - anisotropy * anisotropy
|
|
178
178
|
) / (2.0 * anisotropy);
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
-
let
|
|
181
|
+
let tW = sqrt(max(0.0, 1.0 - au * au));
|
|
182
182
|
let br = TWOPI * samplePoint.x;
|
|
183
183
|
var tangent: vec3f;
|
|
184
184
|
var bitangent: vec3f;
|
|
185
|
-
|
|
186
|
-
return tangent * (
|
|
187
|
-
+ bitangent * (
|
|
188
|
-
+
|
|
185
|
+
aL(gu, &tangent, &bitangent);
|
|
186
|
+
return tangent * (tW * cos(br))
|
|
187
|
+
+ bitangent * (tW * sin(br))
|
|
188
|
+
+ gu * au;
|
|
189
189
|
}
|
|
190
190
|
|
|
191
191
|
fn bD(au: f32, anisotropy: f32) -> f32 {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Per-pixel auxiliary accumulation: the shadow-catcher mask, its premultiplied
|
|
3
|
-
* primary background contribution
|
|
4
|
-
* denoiser's variance estimate.
|
|
3
|
+
* primary background contribution (including opaque flat primary misses), and
|
|
4
|
+
* luminance moments for the built-in denoiser's variance estimate.
|
|
5
5
|
*/
|
|
6
6
|
export declare const SHADOW_CATCHER_ACCUMULATION_BYTES = 48;
|
|
7
|
-
declare const _default: "\nstruct ShadowCatcherAccumulation {\n //
|
|
7
|
+
declare const _default: "\nstruct ShadowCatcherAccumulation {\n // Catcher coverage, separated background alpha, catcher background hits, shadow opacity.\n mask: vec4f,\n background: vec4f,\n // Sum of the denoising guide value and of its square (x, y).\n moments: vec4f,\n}\n";
|
|
8
8
|
export default _default;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Per-pixel auxiliary accumulation: the shadow-catcher mask, its premultiplied
|
|
3
|
-
* primary background contribution
|
|
4
|
-
* denoiser's variance estimate.
|
|
3
|
+
* primary background contribution (including opaque flat primary misses), and
|
|
4
|
+
* luminance moments for the built-in denoiser's variance estimate.
|
|
5
5
|
*/
|
|
6
6
|
export const SHADOW_CATCHER_ACCUMULATION_BYTES = 48;
|
|
7
7
|
export default /* wgsl */ `
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadowCatcherAccumulation.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAEpD,eAAe,UAAU,CAAC;;;;;;;;CAQzB,CAAC","sourcesContent":["/**\n * Per-pixel auxiliary accumulation: the shadow-catcher mask, its premultiplied\n * primary background contribution, and luminance moments for the built-in
|
|
1
|
+
{"version":3,"file":"shadowCatcherAccumulation.wgsl.js","sourceRoot":"","sources":["../../../../src/renderer/wgsl/chunks/shadowCatcherAccumulation.wgsl.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,EAAE,CAAC;AAEpD,eAAe,UAAU,CAAC;;;;;;;;CAQzB,CAAC","sourcesContent":["/**\n * Per-pixel auxiliary accumulation: the shadow-catcher mask, its premultiplied\n * primary background contribution (including opaque flat primary misses), and\n * luminance moments for the built-in denoiser's variance estimate.\n */\nexport const SHADOW_CATCHER_ACCUMULATION_BYTES = 48;\n\nexport default /* wgsl */ `\nstruct ShadowCatcherAccumulation {\n // Catcher coverage, separated background alpha, catcher background hits, shadow opacity.\n mask: vec4f,\n background: vec4f,\n // Sum of the denoising guide value and of its square (x, y).\n moments: vec4f,\n}\n`;\n"]}
|
|
@@ -18,10 +18,10 @@ const BOUNCE_STRIDE = 64u;
|
|
|
18
18
|
|
|
19
19
|
var<private> bc: vec2u;
|
|
20
20
|
var<private> bd: u32;
|
|
21
|
-
var<private>
|
|
21
|
+
var<private> cF: u32 = 0u;
|
|
22
22
|
var<private> em: u32 = 0u;
|
|
23
|
-
fn eg(
|
|
24
|
-
var x =
|
|
23
|
+
fn eg(kk: u32) -> u32 {
|
|
24
|
+
var x = kk;
|
|
25
25
|
x ^= x >> 16u; x *= 0x7feb352du;
|
|
26
26
|
x ^= x >> 15u; x *= 0x846ca68bu;
|
|
27
27
|
return x ^ (x >> 16u);
|
|
@@ -29,28 +29,28 @@ return x ^ (x >> 16u);
|
|
|
29
29
|
fn aq(a: u32, b: u32) -> u32 {
|
|
30
30
|
return eg(a ^ eg(b + 0x9e3779b9u));
|
|
31
31
|
}
|
|
32
|
-
fn iA(
|
|
33
|
-
var x =
|
|
32
|
+
fn iA(kk: u32, ic: u32) -> u32 {
|
|
33
|
+
var x = kk + ic;
|
|
34
34
|
x ^= x * 0x6c50b47cu; x ^= x * 0xb82f1e52u;
|
|
35
35
|
x ^= x * 0xc7afe638u; x ^= x * 0x8d22f6e6u;
|
|
36
36
|
return x;
|
|
37
37
|
}
|
|
38
|
-
fn
|
|
39
|
-
return reverseBits(iA(reverseBits(x),
|
|
38
|
+
fn sC(x: u32, ic: u32) -> u32 {
|
|
39
|
+
return reverseBits(iA(reverseBits(x), ic));
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
fn
|
|
43
|
-
var r = reverseBits(
|
|
42
|
+
fn rb(kk: u32) -> u32 {
|
|
43
|
+
var r = reverseBits(kk);
|
|
44
44
|
${sobolD1Steps.map(([shift, mask]) => `r ^= (r << ${shift}u) & 0x${mask.toString(16)}u;`).join("\n ")}
|
|
45
45
|
return r;
|
|
46
46
|
}
|
|
47
|
-
fn
|
|
48
|
-
let i =
|
|
49
|
-
let x = reverseBits(iA(i, aq(
|
|
50
|
-
let y =
|
|
47
|
+
fn vI(index: u32, ic: u32) -> vec2f {
|
|
48
|
+
let i = sC(index, aq(ic, 0u));
|
|
49
|
+
let x = reverseBits(iA(i, aq(ic, 1u)));
|
|
50
|
+
let y = sC(rb(i), aq(ic, 2u));
|
|
51
51
|
return vec2f(f32(x >> 8u), f32(y >> 8u)) * (1.0 / 16777216.0);
|
|
52
52
|
}
|
|
53
|
-
fn
|
|
53
|
+
fn tp(p: vec2u) -> u32 {
|
|
54
54
|
var v = p & vec2u(255u);
|
|
55
55
|
v = (v | (v << vec2u(4u))) & vec2u(0x0f0fu);
|
|
56
56
|
v = (v | (v << vec2u(2u))) & vec2u(0x3333u);
|
|
@@ -58,42 +58,42 @@ v = (v | (v << vec2u(1u))) & vec2u(0x5555u);
|
|
|
58
58
|
return v.x | (v.y << 1u);
|
|
59
59
|
}
|
|
60
60
|
${zSobolPackedPermutations.map((v, i) => `const Z_PERM_${i} = ${v}u;`).join("\n")}
|
|
61
|
-
fn
|
|
62
|
-
let group =
|
|
61
|
+
fn km(tu: u32) -> u32 {
|
|
62
|
+
let group = tu >> 2u;
|
|
63
63
|
var word = Z_PERM_5;
|
|
64
64
|
${[0, 1, 2, 3, 4].map(i => `word = select(word, Z_PERM_${i}, group == ${i}u);`).join("\n ")}
|
|
65
|
-
return (word >> ((
|
|
65
|
+
return (word >> ((tu & 3u) * 8u)) & 255u;
|
|
66
66
|
}
|
|
67
|
-
fn
|
|
67
|
+
fn pO(kE: u32, dim: u32, logSPP: u32) -> u32 {
|
|
68
68
|
let odd = logSPP & 1u;
|
|
69
|
-
let
|
|
69
|
+
let uf = 8u + ((logSPP + 1u) >> 1u);
|
|
70
70
|
var result = 0u;
|
|
71
|
-
for (var digit = i32(
|
|
71
|
+
for (var digit = i32(uf) - 1; digit >= i32(odd); digit--) {
|
|
72
72
|
let shift = 2u*u32(digit) - odd;
|
|
73
73
|
|
|
74
|
-
var
|
|
75
|
-
if (shift < 30u) {
|
|
76
|
-
let
|
|
77
|
-
let d = (
|
|
78
|
-
result |= ((
|
|
74
|
+
var sj = 0u;
|
|
75
|
+
if (shift < 30u) { sj = kE >> (shift + 2u); }
|
|
76
|
+
let tu = (eg(sj ^ (0x55555555u * dim)) >> 24u) % 24u;
|
|
77
|
+
let d = (kE >> shift) & 3u;
|
|
78
|
+
result |= ((km(tu) >> (2u*d)) & 3u) << shift;
|
|
79
79
|
}
|
|
80
80
|
if (odd != 0u) {
|
|
81
|
-
result |= (
|
|
81
|
+
result |= (kE & 1u) ^ (eg((kE >> 1u) ^ (0x55555555u * dim)) & 1u);
|
|
82
82
|
}
|
|
83
83
|
return result;
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
|
|
87
87
|
|
|
88
|
-
fn
|
|
89
|
-
return CAMERA_BEVEL_BASE + u32(BEVEL_SAMPLES) +
|
|
88
|
+
fn cw(slot: u32) -> u32 {
|
|
89
|
+
return CAMERA_BEVEL_BASE + u32(BEVEL_SAMPLES) + cF * BOUNCE_STRIDE + slot;
|
|
90
90
|
}
|
|
91
|
-
fn
|
|
91
|
+
fn qV(candidate: u32, slot: u32) -> u32 {
|
|
92
92
|
if (candidate == 0u) {
|
|
93
|
-
if (slot == 2u) { return
|
|
94
|
-
return
|
|
93
|
+
if (slot == 2u) { return cw(8u); }
|
|
94
|
+
return cw(slot);
|
|
95
95
|
}
|
|
96
|
-
return
|
|
96
|
+
return cw(9u + (candidate - 1u) * 3u + slot);
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
|
|
@@ -102,41 +102,41 @@ var<private> hi: u32;
|
|
|
102
102
|
var<private> fv: bool = false;
|
|
103
103
|
var<private> df: bool = false;
|
|
104
104
|
var<private> dE: u32;
|
|
105
|
-
var<private>
|
|
105
|
+
var<private> gq: u32;
|
|
106
106
|
var<private> eN: vec2f;
|
|
107
107
|
fn dw(dim: u32) {
|
|
108
108
|
|
|
109
|
-
let
|
|
110
|
-
let key = vec4u(dim, bd,
|
|
109
|
+
let jW = bc.x + bc.y * u32(rtUniform.outputSize.x);
|
|
110
|
+
let key = vec4u(dim, bd, jW, rtUniform.sequenceSeed);
|
|
111
111
|
if (fv && all(hh == key) && hi == rtUniform.zSobolLogSPP) { return; }
|
|
112
112
|
hh = key; hi = rtUniform.zSobolLogSPP;
|
|
113
113
|
fv = true; df = false;
|
|
114
|
-
var
|
|
114
|
+
var ic = aq(aq(jW, dim), rtUniform.sequenceSeed);
|
|
115
115
|
var index = bd;
|
|
116
116
|
if (SAMPLING_PATTERN == 1) {
|
|
117
117
|
var logSPP = rtUniform.zSobolLogSPP;
|
|
118
118
|
if (index == 0u) { logSPP = 0u; }
|
|
119
119
|
else { index -= 1u; }
|
|
120
120
|
|
|
121
|
-
var
|
|
121
|
+
var iW = index >> logSPP;
|
|
122
122
|
let mask = (1u << logSPP) - 1u;
|
|
123
|
-
let
|
|
124
|
-
index =
|
|
123
|
+
let kE = (tp(bc) << logSPP) | (index & mask);
|
|
124
|
+
index = pO(kE, dim, logSPP);
|
|
125
125
|
let tile = bc >> vec2u(8u);
|
|
126
|
-
|
|
126
|
+
ic = aq(aq(dim, rtUniform.sequenceSeed), aq(tile.x, tile.y));
|
|
127
127
|
|
|
128
|
-
if (bd != 0u) {
|
|
129
|
-
|
|
128
|
+
if (bd != 0u) { iW += 1u; }
|
|
129
|
+
ic = aq(ic, iW);
|
|
130
130
|
}
|
|
131
|
-
dE =
|
|
132
|
-
|
|
133
|
-
let x = reverseBits(iA(dE, aq(
|
|
131
|
+
dE = sC(index, aq(ic, 0u));
|
|
132
|
+
gq = ic;
|
|
133
|
+
let x = reverseBits(iA(dE, aq(ic, 1u)));
|
|
134
134
|
eN.x = f32(x >> 8u) * (1.0 / 16777216.0);
|
|
135
135
|
}
|
|
136
|
-
fn
|
|
136
|
+
fn kJ(dim: u32) -> vec2f {
|
|
137
137
|
dw(dim);
|
|
138
138
|
if (!df) {
|
|
139
|
-
let y =
|
|
139
|
+
let y = sC(rb(dE), aq(gq, 2u));
|
|
140
140
|
eN.y = f32(y >> 8u) * (1.0 / 16777216.0);
|
|
141
141
|
df = true;
|
|
142
142
|
}
|
|
@@ -152,18 +152,18 @@ if (SAMPLING_PATTERN == 2) {
|
|
|
152
152
|
let x = dz(dim); let y = dz(dim);
|
|
153
153
|
return vec2f(x,y);
|
|
154
154
|
}
|
|
155
|
-
return
|
|
155
|
+
return kJ(dim);
|
|
156
156
|
}
|
|
157
157
|
|
|
158
158
|
fn eo(slot: u32) -> f32 {
|
|
159
|
-
let dim = aq(aq(
|
|
159
|
+
let dim = aq(aq(cF, slot), em) | 0x80000000u;
|
|
160
160
|
em += 1u;
|
|
161
161
|
if (SAMPLING_PATTERN == 2) { return EPS + (1.0 - 2.0*EPS)*rand(); }
|
|
162
162
|
|
|
163
|
-
let
|
|
164
|
-
let
|
|
165
|
-
let i =
|
|
166
|
-
let x = reverseBits(iA(i, aq(
|
|
163
|
+
let jW = bc.x + bc.y * u32(rtUniform.outputSize.x);
|
|
164
|
+
let ic = aq(aq(jW, dim), rtUniform.sequenceSeed);
|
|
165
|
+
let i = sC(bd, aq(ic, 0u));
|
|
166
|
+
let x = reverseBits(iA(i, aq(ic, 1u)));
|
|
167
167
|
return EPS + (1.0 - 2.0*EPS) * (f32(x >> 8u) * (1.0 / 16777216.0));
|
|
168
168
|
}
|
|
169
169
|
`;
|
|
@@ -7,7 +7,7 @@ let theta = atan2(n.x, n.z) / (2.0 * PI) + 0.5;
|
|
|
7
7
|
let phi = acos(n.y) / PI;
|
|
8
8
|
return vec2f(theta, 1.0 - phi);
|
|
9
9
|
}
|
|
10
|
-
fn
|
|
10
|
+
fn iM(pos: vec3f, normal: vec3f) -> vec2f {
|
|
11
11
|
let dm = abs(normal);
|
|
12
12
|
var uv = vec2f(0.0);
|
|
13
13
|
if (dm.x > dm.y && dm.x > dm.z) {
|
|
@@ -23,18 +23,18 @@ return uv;
|
|
|
23
23
|
|
|
24
24
|
|
|
25
25
|
|
|
26
|
-
fn
|
|
26
|
+
fn hz(pos: vec3f, normal: vec3f) -> vec2f {
|
|
27
27
|
let theta = atan2(pos.z, pos.x) / (2.0 * PI) + 0.5;
|
|
28
28
|
return vec2f(theta, pos.y);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
fn
|
|
31
|
+
fn gC(fh: i32, pos: vec3f, normal: vec3f) -> vec2f {
|
|
32
32
|
if (fh == ${uvProjectionConstants.triplanar}) {
|
|
33
|
-
return
|
|
33
|
+
return iM(pos, normal);
|
|
34
34
|
} else if (fh == ${uvProjectionConstants.spherical}) {
|
|
35
35
|
return sphericalProjection(pos);
|
|
36
36
|
} else if (fh == ${uvProjectionConstants.cylindrical}) {
|
|
37
|
-
return
|
|
37
|
+
return hz(pos, normal);
|
|
38
38
|
}
|
|
39
39
|
return vec2f(0.0);
|
|
40
40
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const linearToSrgbDefine = "\nfn linearToSrgb(color: vec3f) -> vec3f {\n let linear = max(color, vec3f(0.0));\n let low = linear * 12.92;\n let high = 1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055;\n return select(high, low, linear <= vec3f(0.0031308));\n}\n";
|
|
2
2
|
export declare const composeDefine = "\n\nfn linearToneMapping(color: vec3f) -> vec3f {\n return clamp(color, vec3f(0.0), vec3f(1.0));\n}\nfn reinhardToneMapping(color: vec3f) -> vec3f {\n return clamp(color / (vec3f(1.0) + color), vec3f(0.0), vec3f(1.0));\n}\nfn cineonToneMapping(inputColor: vec3f) -> vec3f {\n let color = max(vec3f(0.0), inputColor - 0.004);\n return pow((color * (6.2 * color + 0.5)) /\n (color * (6.2 * color + 1.7) + 0.06), vec3f(2.2));\n}\nfn rrtAndOdtFit(value: vec3f) -> vec3f {\n let numerator = value * (value + 0.0245786) - 0.000090537;\n let denominator = value * (0.983729 * value + 0.4329510) + 0.238081;\n return numerator / denominator;\n}\nfn acesToneMapping(inputColor: vec3f) -> vec3f {\n let inputMatrix = mat3x3f(\n vec3f(0.59719, 0.07600, 0.02840),\n vec3f(0.35458, 0.90834, 0.13383),\n vec3f(0.04823, 0.01566, 0.83777)\n );\n let outputMatrix = mat3x3f(\n vec3f(1.60475, -0.10208, -0.00327),\n vec3f(-0.53108, 1.10813, -0.07276),\n vec3f(-0.07367, -0.00605, 1.07602)\n );\n let color = inputMatrix * (inputColor / 0.6);\n return clamp(outputMatrix * rrtAndOdtFit(color), vec3f(0.0), vec3f(1.0));\n}\nfn agxDefaultContrastApprox(value: vec3f) -> vec3f {\n let value2 = value * value;\n let value4 = value2 * value2;\n return 15.5 * value4 * value2 - 40.14 * value4 * value\n + 31.96 * value4 - 6.868 * value2 * value\n + 0.4298 * value2 + 0.1191 * value - 0.00232;\n}\nfn agxToneMapping(inputColor: vec3f) -> vec3f {\n let linearRec2020ToLinearSrgb = mat3x3f(\n vec3f(1.6605, -0.1246, -0.0182),\n vec3f(-0.5876, 1.1329, -0.1006),\n vec3f(-0.0728, -0.0083, 1.1187)\n );\n let linearSrgbToLinearRec2020 = mat3x3f(\n vec3f(0.6274, 0.0691, 0.0164),\n vec3f(0.3293, 0.9195, 0.0880),\n vec3f(0.0433, 0.0113, 0.8956)\n );\n let insetMatrix = mat3x3f(\n vec3f(0.856627153315983, 0.137318972929847, 0.11189821299995),\n vec3f(0.0951212405381588, 0.761241990602591, 0.0767994186031903),\n vec3f(0.0482516061458583, 0.101439036467562, 0.811302368396859)\n );\n let outsetMatrix = mat3x3f(\n vec3f(1.1271005818144368, -0.1413297634984383, -0.14132976349843826),\n vec3f(-0.11060664309660323, 1.157823702216272, -0.11060664309660294),\n vec3f(-0.016493938717834573, -0.016493938717834257, 1.2519364065950405)\n );\n var color = insetMatrix * (linearSrgbToLinearRec2020 * inputColor);\n color = clamp((log2(max(color, vec3f(1e-10))) + 12.47393) / 16.5, vec3f(0.0), vec3f(1.0));\n color = outsetMatrix * agxDefaultContrastApprox(color);\n color = pow(max(color, vec3f(0.0)), vec3f(2.2));\n return clamp(linearRec2020ToLinearSrgb * color, vec3f(0.0), vec3f(1.0));\n}\nfn applyToneMapping(color: vec3f) -> vec3f {\n let toneMappingMode = i32(toneMappingParams.x);\n if (toneMappingMode == 1) { return acesToneMapping(color); }\n if (toneMappingMode == 2) { return cineonToneMapping(color); }\n if (toneMappingMode == 3) { return reinhardToneMapping(color); }\n if (toneMappingMode == 4) { return linearToneMapping(color); }\n return agxToneMapping(color);\n}\n\nfn linearToSrgb(color: vec3f) -> vec3f {\n let linear = max(color, vec3f(0.0));\n let low = linear * 12.92;\n let high = 1.055 * pow(linear, vec3f(1.0 / 2.4)) - 0.055;\n return select(high, low, linear <= vec3f(0.0031308));\n}\n\nfn gradeColor(inputColor: vec3f) -> vec3f {\n let contrast = colorGradingParams.x;\n let saturation = colorGradingParams.y;\n let temperature = colorGradingParams.z;\n let tint = colorGradingParams.w;\n let balance = vec3f(\n 1.0 + temperature * 0.16 + tint * 0.04,\n 1.0 - tint * 0.12,\n 1.0 - temperature * 0.16 + tint * 0.04\n );\n var color = max(inputColor * balance, vec3f(0.0));\n color = max((color - 0.18) * contrast + 0.18, vec3f(0.0));\n let luminance = dot(color, vec3f(0.2126, 0.7152, 0.0722));\n return max(mix(vec3f(luminance), color, saturation), vec3f(0.0));\n}\n";
|
|
3
|
-
export declare const composeMain = "\n\nvar finalColor = load_colorTex(uv, 0);\nvar bloomTexel = vec4(0.0);\nif (bloomIntensity > 0.0) {\n bloomTexel = load_bloomTex(uv, 0) * bloomIntensity;\n finalColor = vec4f(finalColor.rgb + bloomTexel.rgb, finalColor.a);\n}\n\nvar gradedColor = gradeColor(finalColor.rgb * exposure);\nlet vignetteEdge = smoothstep(0.2, 0.72, distance(vec2f(uv) / vec2f(colorTexRegion()), vec2f(0.5)));\ngradedColor *= 1.0 - toneMappingParams.y * vignetteEdge;\nlet hdrOutput = hdrOutputEnabled > 0.5;\nif (!hdrOutput) {\n gradedColor = applyToneMapping(gradedColor);\n}\nlet encodedDisplay = select(\n pow(max(gradedColor, vec3f(0.0)), vec3f(1.0 / 2.2)),\n linearToSrgb(gradedColor),\n hdrOutput\n);\nvar displayColor = encodedDisplay;\nif (flatBackgroundColor.a > 0.5) {\n let surfaceCoverage = clamp(\n load_flatBackgroundMaskTex(uv, 0).a,\n 0.0,\n 1.0\n );\n let flatBackgroundDisplay = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0)));\n displayColor = mix(flatBackgroundDisplay, encodedDisplay, surfaceCoverage);\n if (bloomIntensity > 0.0) {\n var unbloomedColor = gradeColor(\n max(finalColor.rgb - bloomTexel.rgb, vec3f(0.0))\n * exposure\n );\n unbloomedColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) {\n unbloomedColor = applyToneMapping(unbloomedColor);\n }\n let encodedUnbloomed = select(\n pow(max(unbloomedColor, vec3f(0.0)), vec3f(1.0 / 2.2)),\n linearToSrgb(unbloomedColor),\n hdrOutput\n );\n displayColor += max(encodedDisplay - encodedUnbloomed, vec3f(0.0))\n * (1.0 - surfaceCoverage);\n }\n}\nfinalColor = vec4f(displayColor, finalColor.a);\nif (bloomIntensity > 0.0) {\n finalColor.a = max(finalColor.a, min(dot(bloomTexel.rgb, vec3f(0.2125, 0.7154, 0.0721)), 1.0));\n}\n\nif (shadowCatcherEnabled > 0.5) {\n let shadowCatcher = load_shadowCatcherTex(uv, 0);\n let coverage = clamp(shadowCatcher.r, 0.0, 1.0);\n let opacity = max(clamp(shadowCatcher.a / max(coverage, 0.000001), 0.0, 1.0) - (1.0 - shadowCatcherAlpha), 0.0);\n if (coverage > 0.0) {\n let foreground = load_foregroundTex(uv, 0);\n let background = load_catcherBackgroundTex(uv, 0);\n var foregroundColor = gradeColor((foreground.rgb + bloomTexel.rgb) * exposure);\n var backgroundColor = gradeColor((background.rgb / max(background.a, 0.000001) + bloomTexel.rgb) * exposure);\n foregroundColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n backgroundColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) {\n foregroundColor = applyToneMapping(foregroundColor);\n backgroundColor = applyToneMapping(backgroundColor);\n }\n foregroundColor = select(pow(max(foregroundColor, vec3f(0.0)), vec3f(1.0 / 2.2)), linearToSrgb(foregroundColor), hdrOutput);\n backgroundColor = select(pow(max(backgroundColor, vec3f(0.0)), vec3f(1.0 / 2.2)), linearToSrgb(backgroundColor), hdrOutput);\n if (flatBackgroundColor.a > 0.5) {\n var unbloomedBackground = gradeColor(background.rgb / max(background.a, 0.000001) * exposure);\n unbloomedBackground *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) { unbloomedBackground = applyToneMapping(unbloomedBackground); }\n let encodedUnbloomedBackground = select(pow(max(unbloomedBackground, vec3f(0.0)), vec3f(1.0 / 2.2)), linearToSrgb(unbloomedBackground), hdrOutput);\n let bloomSpill = select(vec3f(0.0), max(backgroundColor - encodedUnbloomedBackground, vec3f(0.0)), bloomIntensity > 0.0);\n backgroundColor = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0))) + bloomSpill;\n }\n // Foreground and catcher are disjoint primary samples, not overlapping\n // alpha layers. Shadow only the catcher background before averaging.\n let shadowAlpha = coverage * opacity;\n let bloomAlpha = clamp(dot(bloomTexel.rgb, vec3f(0.2125, 0.7154, 0.0721)), 0.0, 1.0);\n let foregroundAlpha = max(foreground.a, bloomAlpha * (1.0 - coverage));\n let backgroundAlpha = max(background.a, bloomAlpha * coverage);\n let
|
|
4
|
-
export declare const compositeDenoiseOutputMain = "\nlet encoded = max(finalColor.rgb, vec3f(0.0));\nlet displayLinear = select(\n pow(encoded, vec3f(2.2)),\n select(pow((encoded + 0.055) / 1.055, vec3f(2.4)), encoded / 12.92,\n encoded <= vec3f(0.04045)),\n hdrOutput\n);\noutput.denoiseColor = vec4f(displayLinear, finalColor.a);\n";
|
|
3
|
+
export declare const composeMain = "\n\nvar finalColor = load_colorTex(uv, 0);\nvar bloomTexel = vec4(0.0);\nif (bloomIntensity > 0.0) {\n bloomTexel = load_bloomTex(uv, 0) * bloomIntensity;\n finalColor = vec4f(finalColor.rgb + bloomTexel.rgb, finalColor.a);\n}\n\nvar gradedColor = gradeColor(finalColor.rgb * exposure);\nlet vignetteEdge = smoothstep(0.2, 0.72, distance(vec2f(uv) / vec2f(colorTexRegion()), vec2f(0.5)));\ngradedColor *= 1.0 - toneMappingParams.y * vignetteEdge;\nlet hdrOutput = hdrOutputEnabled > 0.5;\nif (!hdrOutput) {\n gradedColor = applyToneMapping(gradedColor);\n}\nlet encodedDisplay = select(\n pow(max(gradedColor, vec3f(0.0)), vec3f(1.0 / 2.2)),\n linearToSrgb(gradedColor),\n hdrOutput\n);\nvar displayColor = encodedDisplay;\nif (flatBackgroundColor.a > 0.5) {\n let surfaceCoverage = clamp(\n load_flatBackgroundMaskTex(uv, 0).a,\n 0.0,\n 1.0\n );\n let flatBackgroundDisplay = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0)));\n displayColor = mix(flatBackgroundDisplay, encodedDisplay, surfaceCoverage);\n if (bloomIntensity > 0.0) {\n var unbloomedColor = gradeColor(\n max(finalColor.rgb - bloomTexel.rgb, vec3f(0.0))\n * exposure\n );\n unbloomedColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) {\n unbloomedColor = applyToneMapping(unbloomedColor);\n }\n let encodedUnbloomed = select(\n pow(max(unbloomedColor, vec3f(0.0)), vec3f(1.0 / 2.2)),\n linearToSrgb(unbloomedColor),\n hdrOutput\n );\n displayColor += max(encodedDisplay - encodedUnbloomed, vec3f(0.0))\n * (1.0 - surfaceCoverage);\n }\n}\nfinalColor = vec4f(displayColor, finalColor.a);\nif (bloomIntensity > 0.0) {\n finalColor.a = max(finalColor.a, min(dot(bloomTexel.rgb, vec3f(0.2125, 0.7154, 0.0721)), 1.0));\n}\n\nif (shadowCatcherEnabled > 0.5) {\n let shadowCatcher = load_shadowCatcherTex(uv, 0);\n let coverage = clamp(shadowCatcher.r, 0.0, 1.0);\n let opacity = max(clamp(shadowCatcher.a / max(coverage, 0.000001), 0.0, 1.0) - (1.0 - shadowCatcherAlpha), 0.0);\n if (coverage > 0.0 || flatBackgroundColor.a > 0.5) {\n let foreground = load_foregroundTex(uv, 0);\n let background = load_catcherBackgroundTex(uv, 0);\n // An opaque flat backdrop also owns primary misses outside the receiver.\n // Its alpha contains catcher coverage plus miss coverage; only the catcher\n // fraction receives shadow. These weights come from the accumulation,\n // independently of the quantized denoising/albedo guide.\n let flatMissCoverage = select(0.0, clamp(background.a - coverage, 0.0, 1.0 - coverage), flatBackgroundColor.a > 0.5);\n var foregroundColor = gradeColor((foreground.rgb + bloomTexel.rgb) * exposure);\n var backgroundColor = gradeColor((background.rgb / max(background.a, 0.000001) + bloomTexel.rgb) * exposure);\n foregroundColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n backgroundColor *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) {\n foregroundColor = applyToneMapping(foregroundColor);\n backgroundColor = applyToneMapping(backgroundColor);\n }\n foregroundColor = select(pow(max(foregroundColor, vec3f(0.0)), vec3f(1.0 / 2.2)), linearToSrgb(foregroundColor), hdrOutput);\n backgroundColor = select(pow(max(backgroundColor, vec3f(0.0)), vec3f(1.0 / 2.2)), linearToSrgb(backgroundColor), hdrOutput);\n if (flatBackgroundColor.a > 0.5) {\n var unbloomedBackground = gradeColor(background.rgb / max(background.a, 0.000001) * exposure);\n unbloomedBackground *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) { unbloomedBackground = applyToneMapping(unbloomedBackground); }\n let encodedUnbloomedBackground = select(pow(max(unbloomedBackground, vec3f(0.0)), vec3f(1.0 / 2.2)), linearToSrgb(unbloomedBackground), hdrOutput);\n let bloomSpill = select(vec3f(0.0), max(backgroundColor - encodedUnbloomedBackground, vec3f(0.0)), bloomIntensity > 0.0);\n backgroundColor = linearToSrgb(max(flatBackgroundColor.rgb, vec3f(0.0))) + bloomSpill;\n }\n // Foreground and catcher are disjoint primary samples, not overlapping\n // alpha layers. Shadow only the catcher background before averaging.\n let shadowAlpha = coverage * opacity;\n let bloomAlpha = clamp(dot(bloomTexel.rgb, vec3f(0.2125, 0.7154, 0.0721)), 0.0, 1.0);\n let foregroundAlpha = max(foreground.a, bloomAlpha * (1.0 - coverage - flatMissCoverage));\n let backgroundAlpha = max(background.a, bloomAlpha * coverage);\n let visibleBackgroundAlpha = (backgroundAlpha - flatMissCoverage) * (1.0 - opacity) + flatMissCoverage;\n let alpha = foregroundAlpha + visibleBackgroundAlpha + shadowAlpha;\n let premultiplied = foregroundColor * foregroundAlpha\n + backgroundColor * visibleBackgroundAlpha\n + shadowCatcherColor * shadowAlpha;\n finalColor = vec4f(premultiplied / max(alpha, 0.000001), alpha);\n }\n}\n\noutput.color = finalColor;\n\n// output.color = load_bloomTex(uv, 0) * bloomIntensity;\n";
|
|
4
|
+
export declare const compositeDenoiseOutputMain = "\nlet encoded = max(finalColor.rgb, vec3f(0.0));\nlet displayLinear = select(\n pow(encoded, vec3f(2.2)),\n select(pow((encoded + 0.055) / 1.055, vec3f(2.4)), encoded / 12.92,\n encoded <= vec3f(0.04045)),\n hdrOutput\n);\noutput.denoiseColor = vec4f(displayLinear, finalColor.a);\n\n// The receiver is invisible: its visible texture is the displayed background,\n// not the neutral reflectance used for its lighting estimate. Match the beauty\n// reconstruction filter, including mixed foreground/receiver primary samples.\n// Exclude the stochastic shadow and bloom so neither is preserved as texture.\nlet rawAlbedo = load_flatBackgroundMaskTex(uv, 0);\nvar compositeAlbedo = rawAlbedo.rgb;\nif (shadowCatcherEnabled > 0.5 && flatBackgroundColor.a < 0.5) {\n let coverage = clamp(load_shadowCatcherTex(uv, 0).r, 0.0, 1.0);\n let background = load_catcherBackgroundTex(uv, 0);\n if (coverage > 0.0 && background.a > 0.0) {\n var backgroundAlbedo = gradeColor(background.rgb / background.a * exposure);\n backgroundAlbedo *= 1.0 - toneMappingParams.y * vignetteEdge;\n if (!hdrOutput) { backgroundAlbedo = applyToneMapping(backgroundAlbedo); }\n // Background alpha already includes primary catcher coverage. Retain the\n // neutral receiver for its transparent part, without counting coverage twice\n // or adding the stochastic shadow opacity to the texture guide.\n let backgroundWeight = clamp(background.a, 0.0, coverage);\n compositeAlbedo += backgroundWeight * (clamp(backgroundAlbedo, vec3f(0.0), vec3f(1.0)) - vec3f(1.0));\n }\n}\noutput.denoiseAlbedo = vec4f(clamp(compositeAlbedo, vec3f(0.0), vec3f(1.0)), rawAlbedo.a);\n";
|
|
5
5
|
export declare const compositeDenoiseDisplayMain = "\nlet denoised = load_colorTex(uv, 0);\n// Keep the original primary coverage, including transparency. OIDN only\n// filters RGB; filtering coverage separately reintroduces silhouette seams.\n// The built-in filter weights color and coverage together and may replace it.\nlet alpha = select(load_composedTex(uv, 0).a, clamp(denoised.a, 0.0, 1.0), denoisedAlpha > 0.5);\nlet linear = max(denoised.rgb, vec3f(0.0));\nlet encoded = select(pow(linear, vec3f(1.0 / 2.2)), linearToSrgb(linear), hdrOutputEnabled > 0.5);\noutput.color = vec4f(select(vec3f(0.0), encoded, alpha > 0.0), alpha);\n";
|