@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
|
@@ -27,9 +27,9 @@ ${shadowCatcherAccumulationWGSL}
|
|
|
27
27
|
fn main(@builtin(global_invocation_id) id: vec3u) {
|
|
28
28
|
let size = params.size;
|
|
29
29
|
if (id.x >= size.x || id.y >= size.y) { return; }
|
|
30
|
-
let
|
|
31
|
-
let n = normalBuffer[
|
|
32
|
-
let moments = accumulation[
|
|
30
|
+
let tT = id.x + (size.y - 1u - id.y) * size.x;
|
|
31
|
+
let n = normalBuffer[tT].a;
|
|
32
|
+
let moments = accumulation[tT].moments;
|
|
33
33
|
let mean = moments.x / max(n, 1.0);
|
|
34
34
|
|
|
35
35
|
var variance = -1.0;
|
|
@@ -53,28 +53,28 @@ fn main(@builtin(global_invocation_id) id: vec3u) {
|
|
|
53
53
|
let size = params.size;
|
|
54
54
|
if (id.x >= size.x || id.y >= size.y) { return; }
|
|
55
55
|
let center = rawGuide[id.x + id.y * size.x];
|
|
56
|
-
var
|
|
57
|
-
var
|
|
58
|
-
var
|
|
59
|
-
var
|
|
56
|
+
var lk = 0.0;
|
|
57
|
+
var iY = 0.0;
|
|
58
|
+
var mO = 0.0;
|
|
59
|
+
var iS = 0.0;
|
|
60
60
|
for (var dy = -1; dy <= 1; dy++) {
|
|
61
61
|
for (var dx = -1; dx <= 1; dx++) {
|
|
62
62
|
let q = clamp(vec2i(id.xy) + vec2i(dx, dy), vec2i(0), vec2i(size) - 1);
|
|
63
63
|
let value = rawGuide[u32(q.x) + u32(q.y) * size.x];
|
|
64
|
-
|
|
65
|
-
|
|
64
|
+
mO += value.x;
|
|
65
|
+
iS += value.x * value.x;
|
|
66
66
|
if (value.y >= 0.0) {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
lk += value.y;
|
|
68
|
+
iY += 1.0;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
var variance: f32;
|
|
73
73
|
if (center.y >= 0.0) {
|
|
74
|
-
variance =
|
|
74
|
+
variance = lk / iY;
|
|
75
75
|
} else {
|
|
76
|
-
let
|
|
77
|
-
variance = max(
|
|
76
|
+
let lj = mO / 9.0;
|
|
77
|
+
variance = max(iS / 9.0 - lj * lj, 0.0) * 9.0 / 8.0;
|
|
78
78
|
}
|
|
79
79
|
guide[id.x + id.y * size.x] = vec2f(center.x, variance);
|
|
80
80
|
}
|
|
@@ -122,23 +122,23 @@ const INV_NORMAL_BANDWIDTH2 = ${(1 / normalBandwidth ** 2).toFixed(6)};
|
|
|
122
122
|
|
|
123
123
|
const CENTER_WEIGHT_MIN = 0.01;
|
|
124
124
|
|
|
125
|
-
fn
|
|
125
|
+
fn ha(p: vec2i) -> u32 {
|
|
126
126
|
let q = clamp(p, vec2i(0), vec2i(params.size) - 1);
|
|
127
127
|
return u32(q.x) + u32(q.y) * params.size.x;
|
|
128
128
|
}
|
|
129
129
|
|
|
130
|
-
fn
|
|
130
|
+
fn ln(q: vec2i, bs: vec4f, gO: vec3f) -> f32 {
|
|
131
131
|
let albedo = textureLoad(albedoTex, q, 0);
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
let
|
|
135
|
-
let
|
|
136
|
-
let
|
|
137
|
-
let
|
|
134
|
+
let oW = max((albedo.rgb + bs.rgb) * 0.5, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
135
|
+
let kU = (albedo.rgb - bs.rgb) / oW;
|
|
136
|
+
let iP = albedo.a - bs.a;
|
|
137
|
+
let le = textureLoad(normalTex, q, 0).rgb - gO;
|
|
138
138
|
return max(
|
|
139
|
-
dot(
|
|
140
|
-
+
|
|
141
|
-
dot(
|
|
139
|
+
dot(kU, kU) * INV_ALBEDO_BANDWIDTH2
|
|
140
|
+
+ iP * iP * INV_COVERAGE_BANDWIDTH2,
|
|
141
|
+
dot(le, le) * INV_NORMAL_BANDWIDTH2
|
|
142
142
|
);
|
|
143
143
|
}
|
|
144
144
|
|
|
@@ -154,8 +154,8 @@ if (p.x >= size.x || p.y >= size.y) { return; }
|
|
|
154
154
|
let step = i32(params.dilation);
|
|
155
155
|
let bs = textureLoad(albedoTex, p, 0);
|
|
156
156
|
let fw = textureLoad(normalTex, p, 0);
|
|
157
|
-
let
|
|
158
|
-
let index =
|
|
157
|
+
let gO = fw.rgb;
|
|
158
|
+
let index = ha(p);
|
|
159
159
|
|
|
160
160
|
|
|
161
161
|
if (fw.a <= 0.0 && textureLoad(shadowCatcherTex, p, 0).r <= 0.0) {
|
|
@@ -164,25 +164,25 @@ outGuide[index] = guide[index];
|
|
|
164
164
|
return;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
var
|
|
167
|
+
var kW: array<vec2f, PATCH_SIZE>;
|
|
168
168
|
var k = 0;
|
|
169
169
|
for (var dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
|
|
170
170
|
for (var dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
|
|
171
|
-
|
|
171
|
+
kW[k] = guide[ha(p + vec2i(dx, dy) * step)];
|
|
172
172
|
k++;
|
|
173
173
|
}
|
|
174
174
|
}
|
|
175
175
|
let k2 = params.colorSensitivity * params.colorSensitivity;
|
|
176
176
|
|
|
177
177
|
var sum = vec4f(0.0);
|
|
178
|
-
let
|
|
179
|
-
var
|
|
180
|
-
var
|
|
178
|
+
let gR = max(bs.rgb, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
179
|
+
var mf = vec3f(0.0);
|
|
180
|
+
var gt = vec3f(0.0);
|
|
181
181
|
var hn = vec3f(0.0);
|
|
182
|
-
var
|
|
183
|
-
var
|
|
184
|
-
var
|
|
185
|
-
var
|
|
182
|
+
var pk = 0.0;
|
|
183
|
+
var gv = 0.0;
|
|
184
|
+
var nK = 0.0;
|
|
185
|
+
var kD = 0.0;
|
|
186
186
|
for (var sy = -SEARCH_RADIUS; sy <= SEARCH_RADIUS; sy++) {
|
|
187
187
|
for (var sx = -SEARCH_RADIUS; sx <= SEARCH_RADIUS; sx++) {
|
|
188
188
|
let q = p + vec2i(sx, sy) * step;
|
|
@@ -191,17 +191,17 @@ if (
|
|
|
191
191
|
q.x < 0 || q.y < 0 || q.x >= size.x || q.y >= size.y
|
|
192
192
|
) { continue; }
|
|
193
193
|
|
|
194
|
-
let features =
|
|
194
|
+
let features = ln(q, bs, gO);
|
|
195
195
|
if (features > 16.0) { continue; }
|
|
196
196
|
|
|
197
197
|
var fT = 0.0;
|
|
198
198
|
k = 0;
|
|
199
199
|
for (var dy = -PATCH_RADIUS; dy <= PATCH_RADIUS; dy++) {
|
|
200
200
|
for (var dx = -PATCH_RADIUS; dx <= PATCH_RADIUS; dx++) {
|
|
201
|
-
let a =
|
|
202
|
-
let b = guide[
|
|
203
|
-
let
|
|
204
|
-
fT += (
|
|
201
|
+
let a = kW[k];
|
|
202
|
+
let b = guide[ha(q + vec2i(dx, dy) * step)];
|
|
203
|
+
let qL = a.x - b.x;
|
|
204
|
+
fT += (qL * qL
|
|
205
205
|
- VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))
|
|
206
206
|
/ (1e-10 + k2 * (a.y + b.y));
|
|
207
207
|
k++;
|
|
@@ -210,44 +210,44 @@ k++;
|
|
|
210
210
|
fT /= f32(PATCH_SIZE);
|
|
211
211
|
|
|
212
212
|
let weight = exp(-max(max(fT, 0.0), features));
|
|
213
|
-
let index =
|
|
213
|
+
let index = ha(q);
|
|
214
214
|
let c = color[index];
|
|
215
215
|
let g = guide[index];
|
|
216
216
|
|
|
217
|
-
let a = (textureLoad(albedoTex, q, 0).rgb - bs.rgb) /
|
|
217
|
+
let a = (textureLoad(albedoTex, q, 0).rgb - bs.rgb) / gR;
|
|
218
218
|
let value = premultiplied(c);
|
|
219
219
|
sum += value * weight;
|
|
220
|
-
|
|
221
|
-
|
|
220
|
+
mf += a * weight;
|
|
221
|
+
gt += a * a * weight;
|
|
222
222
|
hn += a * value.rgb * weight;
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
223
|
+
pk += g.x * weight;
|
|
224
|
+
gv += g.y * weight * weight;
|
|
225
|
+
nK += weight;
|
|
226
|
+
kD = max(kD, weight);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
|
|
231
231
|
|
|
232
232
|
let center = color[index];
|
|
233
|
-
let
|
|
234
|
-
let dF = max(
|
|
235
|
-
let totalWeight =
|
|
236
|
-
let
|
|
237
|
-
let mean = (sum +
|
|
233
|
+
let kV = guide[index];
|
|
234
|
+
let dF = max(kD, CENTER_WEIGHT_MIN);
|
|
235
|
+
let totalWeight = nK + dF;
|
|
236
|
+
let tF = premultiplied(center);
|
|
237
|
+
let mean = (sum + tF * dF) / totalWeight;
|
|
238
238
|
|
|
239
239
|
|
|
240
|
-
let ez =
|
|
241
|
-
let
|
|
242
|
-
let
|
|
240
|
+
let ez = mf / totalWeight;
|
|
241
|
+
let lo = max(gt / totalWeight - ez * ez, vec3f(0.0));
|
|
242
|
+
let qm = hn / totalWeight - ez * mean.rgb;
|
|
243
243
|
|
|
244
244
|
|
|
245
245
|
|
|
246
|
-
let
|
|
247
|
-
let
|
|
248
|
-
let
|
|
249
|
-
let
|
|
250
|
-
let filtered = vec4f(max(
|
|
246
|
+
let qw = bs.rgb + ez * gR;
|
|
247
|
+
let oq = mean.rgb * gR / max(qw, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
248
|
+
let vs = clamp(qm / (lo + vec3f(${JNLM_ALBEDO_REGULARIZATION})), vec3f(0.0), oq);
|
|
249
|
+
let rs = mean.rgb - vs * ez;
|
|
250
|
+
let filtered = vec4f(max(rs, vec3f(0.0)), max(mean.a, 0.0));
|
|
251
251
|
let rgb = select(
|
|
252
252
|
center.rgb,
|
|
253
253
|
filtered.rgb / max(filtered.a, 1e-6),
|
|
@@ -255,8 +255,8 @@ filtered.a > 1e-6
|
|
|
255
255
|
);
|
|
256
256
|
outColor[index] = vec4f(rgb, filtered.a);
|
|
257
257
|
outGuide[index] = vec2f(
|
|
258
|
-
(
|
|
259
|
-
(
|
|
258
|
+
(pk + kV.x * dF) / totalWeight,
|
|
259
|
+
(gv + kV.y * dF * dF)
|
|
260
260
|
/ (totalWeight * totalWeight)
|
|
261
261
|
);
|
|
262
262
|
}
|
|
@@ -16,14 +16,14 @@ ${shadowCatcherAccumulationWGSL}
|
|
|
16
16
|
override outputWidth: f32;
|
|
17
17
|
override outputHeight: f32;
|
|
18
18
|
|
|
19
|
-
struct
|
|
19
|
+
struct oU {
|
|
20
20
|
${layers ? `@location(0) foreground: vec4f,
|
|
21
21
|
@location(1) catcherBackground: vec4f` : `@location(0) color: vec4f,
|
|
22
22
|
@location(1) normal: vec4f,
|
|
23
23
|
@location(2) albedo: vec4f${catcher ? ',\n @location(3) shadowCatcher: vec4f' : ''}`}
|
|
24
24
|
}
|
|
25
25
|
@fragment
|
|
26
|
-
fn main(@builtin(position) fD: vec4f) ->
|
|
26
|
+
fn main(@builtin(position) fD: vec4f) -> oU {
|
|
27
27
|
let size = vec2u(u32(outputWidth), u32(outputHeight));
|
|
28
28
|
let fM = vec2u(u32(fD.x), size.y - u32(fD.y) - 1u);
|
|
29
29
|
var idx = fM.x + fM.y * size.x;
|
|
@@ -32,17 +32,17 @@ var idx = fM.x + fM.y * size.x;
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
if (sampleCount < 1.0 && normalBuffer[idx].a <= 0.0) {
|
|
35
|
-
let
|
|
36
|
-
let
|
|
37
|
-
((fM +
|
|
38
|
-
((size - vec2u(1u)) /
|
|
35
|
+
let uV = max(sampleTileGrid, vec2u(1u));
|
|
36
|
+
let uF = min(
|
|
37
|
+
((fM + uV / 2u) / uV) * uV,
|
|
38
|
+
((size - vec2u(1u)) / uV) * uV
|
|
39
39
|
);
|
|
40
|
-
let
|
|
41
|
-
if (normalBuffer[
|
|
42
|
-
idx =
|
|
40
|
+
let sz = uF.x + uF.y * size.x;
|
|
41
|
+
if (normalBuffer[sz].a > 0.0) {
|
|
42
|
+
idx = sz;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
var output:
|
|
45
|
+
var output: oU;
|
|
46
46
|
if (normalBuffer[idx].a <= 0.0) {
|
|
47
47
|
${layers ? `output.foreground = vec4f(0.0);
|
|
48
48
|
output.catcherBackground = vec4f(0.0);` : `output.color = vec4f(0.0);
|
|
@@ -62,10 +62,12 @@ let hit = albedo.a;
|
|
|
62
62
|
let total = max(normal.a, 1.0);
|
|
63
63
|
${layers ? `
|
|
64
64
|
let shadow = shadowCatcherBuffer[idx];
|
|
65
|
-
let
|
|
65
|
+
let iQ = max(hit - shadow.mask.b, 0.0);
|
|
66
|
+
|
|
67
|
+
|
|
66
68
|
output.foreground = vec4f(
|
|
67
69
|
(color.rgb - shadow.background.rgb)
|
|
68
|
-
/ select(total,
|
|
70
|
+
/ select(total, iQ, iQ > 0.0),
|
|
69
71
|
clamp((color.a - shadow.mask.g) / total, 0.0, 1.0)
|
|
70
72
|
);
|
|
71
73
|
output.catcherBackground = shadow.background / total;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WGPURayTraceOutput.js","sourceRoot":"","sources":["../../src/renderer/WGPURayTraceOutput.ts"],"names":[],"mappings":"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","sourcesContent":["import { getTargetShaderCache } from './WGPUShaderCache.js';\nimport { textureBytes } from './gpuMemory.js';\nimport shadowCatcherAccumulationWGSL from './wgsl/chunks/shadowCatcherAccumulation.wgsl.js';\nimport { fullScreenQuadVertexShaderWGSL } from './WGPUFullQuadPass.js';\n\nexport function createNormalizeRayTraceOutputWGSL(layers = false, catcher = true) {\n return /* wgsl */ `\n@group(0) @binding(0) var<storage, read> colorBuffer: array<vec4f>;\n@group(0) @binding(1) var<storage, read> normalBuffer: array<vec4f>;\n@group(0) @binding(2) var<storage, read> albedoBuffer: array<vec4f>;\n${shadowCatcherAccumulationWGSL}\n@group(0) @binding(3) var<storage, read> shadowCatcherBuffer: array<ShadowCatcherAccumulation>;\n\n@group(1) @binding(0) var<uniform> sampleCount: f32;\n@group(1) @binding(1) var<uniform> sampleTileGrid: vec2u;\n\noverride outputWidth: f32;\noverride outputHeight: f32;\n\nstruct FSOutput {\n ${layers ? `@location(0) foreground: vec4f,\n @location(1) catcherBackground: vec4f` : `@location(0) color: vec4f,\n @location(1) normal: vec4f,\n @location(2) albedo: vec4f${catcher ? ',\\n @location(3) shadowCatcher: vec4f' : ''}`}\n}\n@fragment\nfn main(@builtin(position) coord: vec4f) -> FSOutput {\n let size = vec2u(u32(outputWidth), u32(outputHeight));\n let pixel = vec2u(u32(coord.x), size.y - u32(coord.y) - 1u);\n var idx = pixel.x + pixel.y * size.x;\n // Tiles are interleaved pixel grids, not contiguous rectangles. The first\n // tile samples (0, 0) of every grid cell across the current camera image.\n // Reconstruct only pixels not yet sampled, until the first sweep completes;\n // never write these display estimates back into the accumulated ray buffers.\n if (sampleCount < 1.0 && normalBuffer[idx].a <= 0.0) {\n let grid = max(sampleTileGrid, vec2u(1u));\n let nearest = min(\n ((pixel + grid / 2u) / grid) * grid,\n ((size - vec2u(1u)) / grid) * grid\n );\n let nearestIdx = nearest.x + nearest.y * size.x;\n if (normalBuffer[nearestIdx].a > 0.0) {\n idx = nearestIdx;\n }\n }\n var output: FSOutput;\n if (normalBuffer[idx].a <= 0.0) {\n ${layers ? `output.foreground = vec4f(0.0);\n output.catcherBackground = vec4f(0.0);` : `output.color = vec4f(0.0);\n output.normal = vec4f(0.0);\n output.albedo = vec4f(0.0);\n ${catcher ? 'output.shadowCatcher = vec4f(0.0);' : ''}`}\n return output;\n }\n let color = colorBuffer[idx];\n let normal = normalBuffer[idx];\n let albedo = albedoBuffer[idx];\n let hit = albedo.a;\n // The CPU count covers completed sweeps and is still zero during the first\n // interleaved sample. Use the actual per-pixel count, including for misses.\n // Empty pixels must remain finite: NaN alpha can poison float HDR output\n // even when its canvas uses opaque compositing.\n let total = max(normal.a, 1.0);\n ${layers ? `\n let shadow = shadowCatcherBuffer[idx];\n let foregroundHit = max(hit - shadow.mask.b, 0.0);\n output.foreground = vec4f(\n (color.rgb - shadow.background.rgb)\n / select(total, foregroundHit, foregroundHit > 0.0),\n clamp((color.a - shadow.mask.g) / total, 0.0, 1.0)\n );\n output.catcherBackground = shadow.background / total;\n ` : `output.color = vec4f(\n // average the color by hit count.\n // So the antialised edge color will be correct when having transparent background\n color.rgb / select(total, hit, hit > 0.0),\n color.a / total\n );\n\n output.normal = vec4f(0.0);\n // Normalize to 0 - 1\n if (dot(normal.rgb, normal.rgb) > 0.1) {\n output.normal = vec4f(normal.rgb / total * 0.5 + 0.5, 1.0);\n }\n output.albedo = vec4f(albedo.rgb / total, clamp(hit / total, 0.0, 1.0));\n ${catcher ? 'output.shadowCatcher = shadowCatcherBuffer[idx].mask / total;' : ''}\n `}\n return output;\n}\n`;\n}\n\ntype RayTraceOutput = 'color' | 'normal' | 'albedo' | 'shadowCatcher'\n | 'foreground' | 'catcherBackground';\ntype RayTraceBuffers = {\n color: GPUBuffer;\n normal: GPUBuffer;\n albedo: GPUBuffer;\n shadowCatcher: GPUBuffer;\n shadowCatcherOffset?: number;\n};\n\nexport class WGPURayTraceOutputPass {\n private _device: GPUDevice;\n\n private _pipeline!: GPURenderPipeline;\n private _layersPipeline!: GPURenderPipeline;\n private _foregroundTexture!: GPUTexture;\n private _catcherBackgroundTexture!: GPUTexture;\n private _colorTexture!: GPUTexture;\n private _normalTexture!: GPUTexture;\n private _albedoTexture!: GPUTexture;\n private _shadowCatcherTexture!: GPUTexture;\n private _uniformBindGroup!: GPUBindGroup;\n\n private _uniformsBuffers;\n\n private _width = 1;\n private _height = 1;\n\n private _hasCatcher = false;\n private _needsUpdatePipeline = true;\n\n constructor(device: GPUDevice, private readonly zeroTexture?: GPUTexture) {\n this._device = device;\n this._uniformsBuffers = {\n sampleCount: device.createBuffer({\n size: 4,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n }),\n sampleTileGrid: device.createBuffer({\n size: 8,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n })\n };\n }\n\n private readonly _retainedOutputs = new Set<GPUTexture>();\n retainOutput(texture: GPUTexture) {\n const owned = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n if (owned.some(label => this.getOutput(label) === texture)) this._retainedOutputs.add(texture);\n }\n releaseOutput(texture: GPUTexture) {\n if (!this._retainedOutputs.delete(texture)) return;\n const owned = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n if (!owned.some(label => this.getOutput(label) === texture)) {\n void this._device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => texture.destroy());\n }\n }\n\n getOutput(label: RayTraceOutput): GPUTexture {\n\n return this[`_${label}Texture`] ?? this.zeroTexture!;\n }\n\n private _createTextures() {\n const { _device: device, _width: width, _height: height } = this;\n const textureDescriptor: GPUTextureDescriptor = {\n size: {\n width,\n height,\n depthOrArrayLayers: 1\n },\n format: 'rgba8unorm',\n usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING |\n GPUTextureUsage.COPY_SRC\n };\n this._destroyTextures();\n this._colorTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Color',\n format: 'rgba16float',\n usage:\n GPUTextureUsage.RENDER_ATTACHMENT |\n GPUTextureUsage.TEXTURE_BINDING |\n GPUTextureUsage.COPY_SRC\n });\n this._normalTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Normal',\n usage: textureDescriptor.usage | GPUTextureUsage.COPY_SRC\n });\n this._albedoTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Albedo'\n });\n if (this._hasCatcher) {\n this._foregroundTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Foreground',\n format: 'rgba16float'\n });\n this._catcherBackgroundTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Catcher Background',\n format: 'rgba16float'\n });\n this._shadowCatcherTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Shadow Catcher',\n format: 'rgba16float'\n });\n } else {\n this._foregroundTexture = this._catcherBackgroundTexture = this._shadowCatcherTexture = undefined!;\n }\n }\n\n private _updateBindGroups() {\n const device = this._device;\n this._uniformBindGroup = device.createBindGroup({\n layout: this._pipeline.getBindGroupLayout(1),\n entries: [\n {\n binding: 0,\n resource: {\n buffer: this._uniformsBuffers.sampleCount\n }\n },\n {\n binding: 1,\n resource: {\n buffer: this._uniformsBuffers.sampleTileGrid\n }\n }\n ]\n });\n }\n\n private _updatePipeline() {\n if (!this._needsUpdatePipeline) {\n return;\n }\n this._needsUpdatePipeline = false;\n const device = this._device;\n\n this._pipeline = getTargetShaderCache(device).createRenderPipeline({\n label: 'rayTraceOutput',\n layout: 'auto',\n vertex: {\n module: getTargetShaderCache(device).createShaderModule({\n code: fullScreenQuadVertexShaderWGSL\n }),\n entryPoint: 'main'\n },\n fragment: {\n module: getTargetShaderCache(device).createShaderModule({\n code: createNormalizeRayTraceOutputWGSL(false, this._hasCatcher)\n }),\n entryPoint: 'main',\n targets: [\n {\n format: 'rgba16float'\n },\n {\n format: 'rgba8unorm'\n },\n {\n format: 'rgba8unorm'\n },\n ...(this._hasCatcher ? [{format: 'rgba16float' as const}] : [])\n ],\n constants: {\n outputWidth: this._width,\n outputHeight: this._height\n }\n }\n });\n\n if (this._hasCatcher) this._layersPipeline = getTargetShaderCache(device).createRenderPipeline({\n label: 'rayTraceLayers',\n layout: 'auto',\n vertex: {\n module: getTargetShaderCache(device).createShaderModule({ code: fullScreenQuadVertexShaderWGSL }),\n entryPoint: 'main'\n },\n fragment: {\n module: getTargetShaderCache(device).createShaderModule({ code: createNormalizeRayTraceOutputWGSL(true) }),\n entryPoint: 'main',\n targets: [{ format: 'rgba16float' }, { format: 'rgba16float' }],\n constants: { outputWidth: this._width, outputHeight: this._height }\n }\n });\n this._updateBindGroups();\n }\n\n setSize(width: number, height: number) {\n if (\n this._width !== width ||\n this._height !== height ||\n !this._colorTexture\n ) {\n this._width = width;\n this._height = height;\n this._createTextures();\n this._needsUpdatePipeline = true;\n }\n }\n\n setSampleCount(sampleCount: number) {\n this._device.queue.writeBuffer(\n this._uniformsBuffers.sampleCount,\n 0,\n new Float32Array([sampleCount])\n );\n }\n\n setSampleTileGrid(columns: number, rows: number) {\n this._device.queue.writeBuffer(\n this._uniformsBuffers.sampleTileGrid,\n 0,\n new Uint32Array([columns, rows])\n );\n }\n\n createPass(\n encoder: GPUCommandEncoder,\n inputBuffers: RayTraceBuffers,\n separateCatcher = false\n ) {\n if (this._hasCatcher !== separateCatcher) {\n this._hasCatcher = separateCatcher; this._createTextures(); this._needsUpdatePipeline = true;\n }\n this._updatePipeline();\n this._createOutputPass(encoder, inputBuffers, false);\n if (separateCatcher) this._createOutputPass(encoder, inputBuffers, true);\n }\n\n private _createOutputPass(\n encoder: GPUCommandEncoder,\n inputBuffers: RayTraceBuffers,\n layers: boolean\n ) {\n const pipeline = layers ? this._layersPipeline : this._pipeline;\n const textures = layers\n ? [this._foregroundTexture, this._catcherBackgroundTexture]\n : [this._colorTexture, this._normalTexture, this._albedoTexture, ...(this._hasCatcher ? [this._shadowCatcherTexture] : [])];\n const pass = encoder.beginRenderPass({\n colorAttachments: textures.map((texture) => ({\n view: texture.createView(),\n loadValue: { r: 0, g: 0, b: 0, a: 0 },\n storeOp: 'store',\n loadOp: 'clear'\n }))\n });\n pass.setPipeline(pipeline);\n\n pass.setBindGroup(\n 0,\n this._device.createBindGroup({\n label: 'rayTraceOutput',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n inputBuffers.color,\n inputBuffers.normal,\n inputBuffers.albedo,\n inputBuffers.shadowCatcher\n ].map((buffer, idx) => ({\n binding: idx,\n resource: {\n buffer,\n ...(idx === 3 ? { offset: inputBuffers.shadowCatcherOffset ?? 0 } : {})\n }\n })).filter(entry => entry.binding < 3 || this._hasCatcher || layers)\n })\n );\n pass.setBindGroup(1, layers ? this._device.createBindGroup({\n layout: pipeline.getBindGroupLayout(1),\n entries: Object.values(this._uniformsBuffers).map((buffer, binding) => ({\n binding, resource: { buffer }\n }))\n }) : this._uniformBindGroup);\n\n pass.draw(6, 1, 0, 0);\n pass.end();\n\n }\n\n private _destroyTextures() {\n if (!this._colorTexture) return;\n\n // These textures are also OIDN inputs. A resolution or preview-mode\n // change can replace them immediately after a denoising command buffer\n // was submitted. Keep the old resources alive until all work submitted so\n // far has completed; destroying them synchronously can make Dawn validate\n // the pending submit against an already-destroyed texture.\n const textures = [\n this._colorTexture,\n this._normalTexture,\n this._albedoTexture,\n this._shadowCatcherTexture,\n this._foregroundTexture,\n this._catcherBackgroundTexture\n ].filter((texture): texture is GPUTexture => !!texture && !this._retainedOutputs.has(texture));\n void this._device.queue\n .onSubmittedWorkDone()\n .catch(() => undefined)\n .then(() => textures.forEach((texture) => texture.destroy()));\n }\n\n getMemoryBytes() {\n const textures = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n return Object.values(this._uniformsBuffers).reduce((sum, buffer) => sum + buffer.size, 0)\n + Array.from(new Set([...textures.map(label => this[`_${label}Texture`]), ...this._retainedOutputs]))\n .reduce((sum, texture) => sum + textureBytes(texture), 0);\n }\n\n dispose() {\n const retained = Array.from(this._retainedOutputs);\n void this._device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => retained.forEach(texture => texture.destroy()));\n this._destroyTextures();\n this._retainedOutputs.clear();\n Object.keys(this._uniformsBuffers).forEach((key) => {\n (this._uniformsBuffers as any)[key].destroy();\n });\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"WGPURayTraceOutput.js","sourceRoot":"","sources":["../../src/renderer/WGPURayTraceOutput.ts"],"names":[],"mappings":"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","sourcesContent":["import { getTargetShaderCache } from './WGPUShaderCache.js';\nimport { textureBytes } from './gpuMemory.js';\nimport shadowCatcherAccumulationWGSL from './wgsl/chunks/shadowCatcherAccumulation.wgsl.js';\nimport { fullScreenQuadVertexShaderWGSL } from './WGPUFullQuadPass.js';\n\nexport function createNormalizeRayTraceOutputWGSL(layers = false, catcher = true) {\n return /* wgsl */ `\n@group(0) @binding(0) var<storage, read> colorBuffer: array<vec4f>;\n@group(0) @binding(1) var<storage, read> normalBuffer: array<vec4f>;\n@group(0) @binding(2) var<storage, read> albedoBuffer: array<vec4f>;\n${shadowCatcherAccumulationWGSL}\n@group(0) @binding(3) var<storage, read> shadowCatcherBuffer: array<ShadowCatcherAccumulation>;\n\n@group(1) @binding(0) var<uniform> sampleCount: f32;\n@group(1) @binding(1) var<uniform> sampleTileGrid: vec2u;\n\noverride outputWidth: f32;\noverride outputHeight: f32;\n\nstruct FSOutput {\n ${layers ? `@location(0) foreground: vec4f,\n @location(1) catcherBackground: vec4f` : `@location(0) color: vec4f,\n @location(1) normal: vec4f,\n @location(2) albedo: vec4f${catcher ? ',\\n @location(3) shadowCatcher: vec4f' : ''}`}\n}\n@fragment\nfn main(@builtin(position) coord: vec4f) -> FSOutput {\n let size = vec2u(u32(outputWidth), u32(outputHeight));\n let pixel = vec2u(u32(coord.x), size.y - u32(coord.y) - 1u);\n var idx = pixel.x + pixel.y * size.x;\n // Tiles are interleaved pixel grids, not contiguous rectangles. The first\n // tile samples (0, 0) of every grid cell across the current camera image.\n // Reconstruct only pixels not yet sampled, until the first sweep completes;\n // never write these display estimates back into the accumulated ray buffers.\n if (sampleCount < 1.0 && normalBuffer[idx].a <= 0.0) {\n let grid = max(sampleTileGrid, vec2u(1u));\n let nearest = min(\n ((pixel + grid / 2u) / grid) * grid,\n ((size - vec2u(1u)) / grid) * grid\n );\n let nearestIdx = nearest.x + nearest.y * size.x;\n if (normalBuffer[nearestIdx].a > 0.0) {\n idx = nearestIdx;\n }\n }\n var output: FSOutput;\n if (normalBuffer[idx].a <= 0.0) {\n ${layers ? `output.foreground = vec4f(0.0);\n output.catcherBackground = vec4f(0.0);` : `output.color = vec4f(0.0);\n output.normal = vec4f(0.0);\n output.albedo = vec4f(0.0);\n ${catcher ? 'output.shadowCatcher = vec4f(0.0);' : ''}`}\n return output;\n }\n let color = colorBuffer[idx];\n let normal = normalBuffer[idx];\n let albedo = albedoBuffer[idx];\n let hit = albedo.a;\n // The CPU count covers completed sweeps and is still zero during the first\n // interleaved sample. Use the actual per-pixel count, including for misses.\n // Empty pixels must remain finite: NaN alpha can poison float HDR output\n // even when its canvas uses opaque compositing.\n let total = max(normal.a, 1.0);\n ${layers ? `\n let shadow = shadowCatcherBuffer[idx];\n let foregroundHit = max(hit - shadow.mask.b, 0.0);\n // Separated background includes flat primary misses as well as catcher\n // samples. Neither belongs in the hit-normalized geometry color/alpha.\n output.foreground = vec4f(\n (color.rgb - shadow.background.rgb)\n / select(total, foregroundHit, foregroundHit > 0.0),\n clamp((color.a - shadow.mask.g) / total, 0.0, 1.0)\n );\n output.catcherBackground = shadow.background / total;\n ` : `output.color = vec4f(\n // average the color by hit count.\n // So the antialised edge color will be correct when having transparent background\n color.rgb / select(total, hit, hit > 0.0),\n color.a / total\n );\n\n output.normal = vec4f(0.0);\n // Normalize to 0 - 1\n if (dot(normal.rgb, normal.rgb) > 0.1) {\n output.normal = vec4f(normal.rgb / total * 0.5 + 0.5, 1.0);\n }\n output.albedo = vec4f(albedo.rgb / total, clamp(hit / total, 0.0, 1.0));\n ${catcher ? 'output.shadowCatcher = shadowCatcherBuffer[idx].mask / total;' : ''}\n `}\n return output;\n}\n`;\n}\n\ntype RayTraceOutput = 'color' | 'normal' | 'albedo' | 'shadowCatcher'\n | 'foreground' | 'catcherBackground';\ntype RayTraceBuffers = {\n color: GPUBuffer;\n normal: GPUBuffer;\n albedo: GPUBuffer;\n shadowCatcher: GPUBuffer;\n shadowCatcherOffset?: number;\n};\n\nexport class WGPURayTraceOutputPass {\n private _device: GPUDevice;\n\n private _pipeline!: GPURenderPipeline;\n private _layersPipeline!: GPURenderPipeline;\n private _foregroundTexture!: GPUTexture;\n private _catcherBackgroundTexture!: GPUTexture;\n private _colorTexture!: GPUTexture;\n private _normalTexture!: GPUTexture;\n private _albedoTexture!: GPUTexture;\n private _shadowCatcherTexture!: GPUTexture;\n private _uniformBindGroup!: GPUBindGroup;\n\n private _uniformsBuffers;\n\n private _width = 1;\n private _height = 1;\n\n private _hasCatcher = false;\n private _needsUpdatePipeline = true;\n\n constructor(device: GPUDevice, private readonly zeroTexture?: GPUTexture) {\n this._device = device;\n this._uniformsBuffers = {\n sampleCount: device.createBuffer({\n size: 4,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n }),\n sampleTileGrid: device.createBuffer({\n size: 8,\n usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST\n })\n };\n }\n\n private readonly _retainedOutputs = new Set<GPUTexture>();\n retainOutput(texture: GPUTexture) {\n const owned = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n if (owned.some(label => this.getOutput(label) === texture)) this._retainedOutputs.add(texture);\n }\n releaseOutput(texture: GPUTexture) {\n if (!this._retainedOutputs.delete(texture)) return;\n const owned = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n if (!owned.some(label => this.getOutput(label) === texture)) {\n void this._device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => texture.destroy());\n }\n }\n\n getOutput(label: RayTraceOutput): GPUTexture {\n\n return this[`_${label}Texture`] ?? this.zeroTexture!;\n }\n\n private _createTextures() {\n const { _device: device, _width: width, _height: height } = this;\n const textureDescriptor: GPUTextureDescriptor = {\n size: {\n width,\n height,\n depthOrArrayLayers: 1\n },\n format: 'rgba8unorm',\n usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING |\n GPUTextureUsage.COPY_SRC\n };\n this._destroyTextures();\n this._colorTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Color',\n format: 'rgba16float',\n usage:\n GPUTextureUsage.RENDER_ATTACHMENT |\n GPUTextureUsage.TEXTURE_BINDING |\n GPUTextureUsage.COPY_SRC\n });\n this._normalTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Normal',\n usage: textureDescriptor.usage | GPUTextureUsage.COPY_SRC\n });\n this._albedoTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Albedo'\n });\n if (this._hasCatcher) {\n this._foregroundTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Foreground',\n format: 'rgba16float'\n });\n this._catcherBackgroundTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Catcher Background',\n format: 'rgba16float'\n });\n this._shadowCatcherTexture = device.createTexture({\n ...textureDescriptor,\n label: 'Ray Trace Shadow Catcher',\n format: 'rgba16float'\n });\n } else {\n this._foregroundTexture = this._catcherBackgroundTexture = this._shadowCatcherTexture = undefined!;\n }\n }\n\n private _updateBindGroups() {\n const device = this._device;\n this._uniformBindGroup = device.createBindGroup({\n layout: this._pipeline.getBindGroupLayout(1),\n entries: [\n {\n binding: 0,\n resource: {\n buffer: this._uniformsBuffers.sampleCount\n }\n },\n {\n binding: 1,\n resource: {\n buffer: this._uniformsBuffers.sampleTileGrid\n }\n }\n ]\n });\n }\n\n private _updatePipeline() {\n if (!this._needsUpdatePipeline) {\n return;\n }\n this._needsUpdatePipeline = false;\n const device = this._device;\n\n this._pipeline = getTargetShaderCache(device).createRenderPipeline({\n label: 'rayTraceOutput',\n layout: 'auto',\n vertex: {\n module: getTargetShaderCache(device).createShaderModule({\n code: fullScreenQuadVertexShaderWGSL\n }),\n entryPoint: 'main'\n },\n fragment: {\n module: getTargetShaderCache(device).createShaderModule({\n code: createNormalizeRayTraceOutputWGSL(false, this._hasCatcher)\n }),\n entryPoint: 'main',\n targets: [\n {\n format: 'rgba16float'\n },\n {\n format: 'rgba8unorm'\n },\n {\n format: 'rgba8unorm'\n },\n ...(this._hasCatcher ? [{format: 'rgba16float' as const}] : [])\n ],\n constants: {\n outputWidth: this._width,\n outputHeight: this._height\n }\n }\n });\n\n if (this._hasCatcher) this._layersPipeline = getTargetShaderCache(device).createRenderPipeline({\n label: 'rayTraceLayers',\n layout: 'auto',\n vertex: {\n module: getTargetShaderCache(device).createShaderModule({ code: fullScreenQuadVertexShaderWGSL }),\n entryPoint: 'main'\n },\n fragment: {\n module: getTargetShaderCache(device).createShaderModule({ code: createNormalizeRayTraceOutputWGSL(true) }),\n entryPoint: 'main',\n targets: [{ format: 'rgba16float' }, { format: 'rgba16float' }],\n constants: { outputWidth: this._width, outputHeight: this._height }\n }\n });\n this._updateBindGroups();\n }\n\n setSize(width: number, height: number) {\n if (\n this._width !== width ||\n this._height !== height ||\n !this._colorTexture\n ) {\n this._width = width;\n this._height = height;\n this._createTextures();\n this._needsUpdatePipeline = true;\n }\n }\n\n setSampleCount(sampleCount: number) {\n this._device.queue.writeBuffer(\n this._uniformsBuffers.sampleCount,\n 0,\n new Float32Array([sampleCount])\n );\n }\n\n setSampleTileGrid(columns: number, rows: number) {\n this._device.queue.writeBuffer(\n this._uniformsBuffers.sampleTileGrid,\n 0,\n new Uint32Array([columns, rows])\n );\n }\n\n createPass(\n encoder: GPUCommandEncoder,\n inputBuffers: RayTraceBuffers,\n separateCatcher = false\n ) {\n if (this._hasCatcher !== separateCatcher) {\n this._hasCatcher = separateCatcher; this._createTextures(); this._needsUpdatePipeline = true;\n }\n this._updatePipeline();\n this._createOutputPass(encoder, inputBuffers, false);\n if (separateCatcher) this._createOutputPass(encoder, inputBuffers, true);\n }\n\n private _createOutputPass(\n encoder: GPUCommandEncoder,\n inputBuffers: RayTraceBuffers,\n layers: boolean\n ) {\n const pipeline = layers ? this._layersPipeline : this._pipeline;\n const textures = layers\n ? [this._foregroundTexture, this._catcherBackgroundTexture]\n : [this._colorTexture, this._normalTexture, this._albedoTexture, ...(this._hasCatcher ? [this._shadowCatcherTexture] : [])];\n const pass = encoder.beginRenderPass({\n colorAttachments: textures.map((texture) => ({\n view: texture.createView(),\n loadValue: { r: 0, g: 0, b: 0, a: 0 },\n storeOp: 'store',\n loadOp: 'clear'\n }))\n });\n pass.setPipeline(pipeline);\n\n pass.setBindGroup(\n 0,\n this._device.createBindGroup({\n label: 'rayTraceOutput',\n layout: pipeline.getBindGroupLayout(0),\n entries: [\n inputBuffers.color,\n inputBuffers.normal,\n inputBuffers.albedo,\n inputBuffers.shadowCatcher\n ].map((buffer, idx) => ({\n binding: idx,\n resource: {\n buffer,\n ...(idx === 3 ? { offset: inputBuffers.shadowCatcherOffset ?? 0 } : {})\n }\n })).filter(entry => entry.binding < 3 || this._hasCatcher || layers)\n })\n );\n pass.setBindGroup(1, layers ? this._device.createBindGroup({\n layout: pipeline.getBindGroupLayout(1),\n entries: Object.values(this._uniformsBuffers).map((buffer, binding) => ({\n binding, resource: { buffer }\n }))\n }) : this._uniformBindGroup);\n\n pass.draw(6, 1, 0, 0);\n pass.end();\n\n }\n\n private _destroyTextures() {\n if (!this._colorTexture) return;\n\n // These textures are also OIDN inputs. A resolution or preview-mode\n // change can replace them immediately after a denoising command buffer\n // was submitted. Keep the old resources alive until all work submitted so\n // far has completed; destroying them synchronously can make Dawn validate\n // the pending submit against an already-destroyed texture.\n const textures = [\n this._colorTexture,\n this._normalTexture,\n this._albedoTexture,\n this._shadowCatcherTexture,\n this._foregroundTexture,\n this._catcherBackgroundTexture\n ].filter((texture): texture is GPUTexture => !!texture && !this._retainedOutputs.has(texture));\n void this._device.queue\n .onSubmittedWorkDone()\n .catch(() => undefined)\n .then(() => textures.forEach((texture) => texture.destroy()));\n }\n\n getMemoryBytes() {\n const textures = ['color', 'normal', 'albedo', 'shadowCatcher', 'foreground', 'catcherBackground'] as const;\n return Object.values(this._uniformsBuffers).reduce((sum, buffer) => sum + buffer.size, 0)\n + Array.from(new Set([...textures.map(label => this[`_${label}Texture`]), ...this._retainedOutputs]))\n .reduce((sum, texture) => sum + textureBytes(texture), 0);\n }\n\n dispose() {\n const retained = Array.from(this._retainedOutputs);\n void this._device.queue.onSubmittedWorkDone().catch(() => undefined).then(() => retained.forEach(texture => texture.destroy()));\n this._destroyTextures();\n this._retainedOutputs.clear();\n Object.keys(this._uniformsBuffers).forEach((key) => {\n (this._uniformsBuffers as any)[key].destroy();\n });\n }\n}\n"]}
|
|
@@ -188,7 +188,7 @@ export function packAnalyticsLightsToBuffer(lights, texturesIndices, selectionPm
|
|
|
188
188
|
}
|
|
189
189
|
data[(off + 3) * 4 + 3] = light.type === 'SpotLight'
|
|
190
190
|
? iesProfileTexelOffsets[i] ?? -1
|
|
191
|
-
: texturesIndices[i];
|
|
191
|
+
: texturesIndices[i] ?? -1;
|
|
192
192
|
data[(off + 4) * 4] = selectionPmfs[i] ?? 0;
|
|
193
193
|
packVec3(off + 5, getRigidLightFrame(light).x);
|
|
194
194
|
}
|
|
@@ -1802,7 +1802,7 @@ ${rayTraceCompute({
|
|
|
1802
1802
|
for (const geometry of this._geometriesNeedRefit) {
|
|
1803
1803
|
const usesDisplacement = meshes.some((mesh) => mesh.geometry === geometry &&
|
|
1804
1804
|
!!mesh.materials[0]?.displacementMap &&
|
|
1805
|
-
|
|
1805
|
+
(mesh.materials[0].displacementScale !== 0 || mesh.materials[0].displacementBias !== 0));
|
|
1806
1806
|
if (usesDisplacement || geometryTopologyChanged(this._preparedMeshData, geometry) || !getGeometryBvh(geometry) || !refitBLAS(getGeometryBvh(geometry), geometry)) {
|
|
1807
1807
|
setGeometryBvh(geometry, undefined);
|
|
1808
1808
|
}
|