@meimu/mutracer 0.1.3 → 0.1.5
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 +4155 -4052
- package/docs/api.md +13 -10
- package/docs/materials.md +17 -26
- package/docs/threejs.md +35 -9
- package/docs/viewer.md +36 -3
- package/lib/Engine.js +18 -1
- package/lib/Engine.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/MaterialTable.d.ts +1 -0
- package/lib/renderer/MaterialTable.js +10 -4
- package/lib/renderer/MaterialTable.js.map +1 -1
- package/lib/renderer/WGPUBloomPass.js +18 -18
- package/lib/renderer/WGPUFullQuadPass.js +6 -6
- package/lib/renderer/WGPUJNLMDenoiser.js +69 -69
- package/lib/renderer/WGPURayTraceOutput.js +14 -14
- package/lib/renderer/WGPURayTracePass.d.ts +2 -0
- package/lib/renderer/WGPURayTracePass.js +17 -9
- package/lib/renderer/WGPURayTracePass.js.map +1 -1
- package/lib/renderer/WGPURenderingPipeline.js +15 -15
- package/lib/renderer/WebGLJNLMDenoiser.js +69 -69
- package/lib/renderer/WebGLRayTraceOutputPass.js +4 -4
- package/lib/renderer/WebGLRayTracePass.d.ts +1 -0
- package/lib/renderer/WebGLRayTracePass.js +8 -1
- package/lib/renderer/WebGLRayTracePass.js.map +1 -1
- package/lib/renderer/envMapCreation.d.ts +5 -1
- package/lib/renderer/envMapCreation.js +42 -5
- package/lib/renderer/envMapCreation.js.map +1 -1
- package/lib/renderer/geometryUpdates.js +1 -1
- package/lib/renderer/geometryUpdates.js.map +1 -1
- package/lib/renderer/glsl/chunks/cameraRay.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/envMap.glsl.js +66 -54
- package/lib/renderer/glsl/chunks/envMap.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/intersect.glsl.js +323 -315
- package/lib/renderer/glsl/chunks/intersect.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js +154 -121
- package/lib/renderer/glsl/chunks/materialBuffer.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js +434 -434
- package/lib/renderer/glsl/chunks/openPbrBsdf.glsl.js.map +1 -1
- 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 +42 -41
- package/lib/renderer/glsl/chunks/rayTraceCore.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleLight.glsl.js +69 -69
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js +84 -84
- package/lib/renderer/glsl/chunks/sampleMaterial.glsl.js.map +1 -1
- package/lib/renderer/glsl/chunks/sampleShadowCatcher.glsl.js +12 -12
- package/lib/renderer/glsl/chunks/sampling.glsl.js +75 -75
- package/lib/renderer/glsl/chunks/sobol.glsl.js +61 -61
- 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 +5 -5
- package/lib/renderer/glsl/depthQuery.frag.js.map +1 -1
- package/lib/renderer/glsl/normalizeRayTraceOutput.frag.js +8 -8
- package/lib/renderer/glsl/rayTrace.frag.js +133 -133
- package/lib/renderer/glsl/rayTrace.frag.js.map +1 -1
- package/lib/renderer/glsl/shadowCatcher.frag.js +9 -9
- package/lib/renderer/glsl/shadowCatcher.frag.js.map +1 -1
- package/lib/renderer/glsl/webglPipeline.frag.js +52 -52
- package/lib/renderer/lightsUtil.js +6 -4
- package/lib/renderer/lightsUtil.js.map +1 -1
- package/lib/renderer/materialChanges.js +1 -1
- package/lib/renderer/materialChanges.js.map +1 -1
- package/lib/renderer/materialComparison.generated.js +36 -18
- package/lib/renderer/materialComparison.generated.js.map +1 -1
- package/lib/renderer/prepareMeshBVH.js +2 -2
- package/lib/renderer/prepareMeshBVH.js.map +1 -1
- package/lib/renderer/sceneChangeDetector.js +4 -1
- package/lib/renderer/sceneChangeDetector.js.map +1 -1
- package/lib/renderer/sceneLightChanges.js +3 -2
- package/lib/renderer/sceneLightChanges.js.map +1 -1
- package/lib/renderer/scratchSampling.js +18 -18
- package/lib/renderer/wgsl/chunks/common.wgsl.js +4 -4
- package/lib/renderer/wgsl/chunks/envMap.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js +39 -31
- package/lib/renderer/wgsl/chunks/envMap.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js +476 -470
- package/lib/renderer/wgsl/chunks/intersect.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/intersectionAlpha.wgsl.js +8 -8
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js +95 -60
- package/lib/renderer/wgsl/chunks/materialBuffer.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/openPbrBsdf.wgsl.js +469 -469
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/chunks/pdm_displacement.wgsl.js +117 -120
- 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 +25 -22
- package/lib/renderer/wgsl/chunks/rayTraceCore.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/chunks/sampleLight.wgsl.js +127 -127
- package/lib/renderer/wgsl/chunks/sampleMaterial.wgsl.js +136 -136
- package/lib/renderer/wgsl/chunks/sampleShadowCatcher.wgsl.js +6 -6
- package/lib/renderer/wgsl/chunks/sampling.wgsl.js +73 -73
- package/lib/renderer/wgsl/chunks/sobol.wgsl.js +62 -62
- package/lib/renderer/wgsl/chunks/uvProjection.wgsl.js +11 -11
- package/lib/renderer/wgsl/compose.frag.wgsl.js +105 -105
- package/lib/renderer/wgsl/customDenoise.wgsl.js +10 -10
- package/lib/renderer/wgsl/depthQuery.wgsl.d.ts +1 -1
- package/lib/renderer/wgsl/depthQuery.wgsl.js +5 -5
- package/lib/renderer/wgsl/depthQuery.wgsl.js.map +1 -1
- package/lib/renderer/wgsl/offlineAdaptive.compute.js +28 -28
- package/lib/renderer/wgsl/rayTrace.compute.js +251 -248
- package/lib/renderer/wgsl/rayTrace.compute.js.map +1 -1
- package/lib/scene/EnvironmentLight.d.ts +9 -3
- package/lib/scene/EnvironmentLight.js +9 -2
- package/lib/scene/EnvironmentLight.js.map +1 -1
- package/lib/scene/OpenPBRMaterial.d.ts +1 -1
- package/lib/scene/OpenPBRMaterial.js +1 -1
- package/lib/scene/OpenPBRMaterial.js.map +1 -1
- package/lib/scene/Scene.d.ts +4 -0
- package/lib/scene/Scene.js.map +1 -1
- package/lib/scene/SpotLight.d.ts +2 -2
- package/lib/scene/SpotLight.js +1 -1
- package/lib/scene/SpotLight.js.map +1 -1
- package/lib/scene/Texture.d.ts +17 -6
- package/lib/scene/Texture.js +13 -4
- package/lib/scene/Texture.js.map +1 -1
- package/lib/util/fromTHREE.js +151 -29
- 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 +1 -1
|
@@ -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 ua = id.x + (size.y - 1u - id.y) * size.x;
|
|
31
|
+
let n = normalBuffer[ua].a;
|
|
32
|
+
let moments = accumulation[ua].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 lu = 0.0;
|
|
57
|
+
var jc = 0.0;
|
|
58
|
+
var mY = 0.0;
|
|
59
|
+
var iX = 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
|
+
mY += value.x;
|
|
65
|
+
iX += value.x * value.x;
|
|
66
66
|
if (value.y >= 0.0) {
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
lu += value.y;
|
|
68
|
+
jc += 1.0;
|
|
69
69
|
}
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
var variance: f32;
|
|
73
73
|
if (center.y >= 0.0) {
|
|
74
|
-
variance =
|
|
74
|
+
variance = lu / jc;
|
|
75
75
|
} else {
|
|
76
|
-
let
|
|
77
|
-
variance = max(
|
|
76
|
+
let lt = mY / 9.0;
|
|
77
|
+
variance = max(iX / 9.0 - lt * lt, 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 hg(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 lw(q: vec2i, bs: vec4f, gT: vec3f) -> f32 {
|
|
131
131
|
let albedo = textureLoad(albedoTex, q, 0);
|
|
132
132
|
|
|
133
133
|
|
|
134
|
-
let
|
|
135
|
-
let
|
|
136
|
-
let
|
|
137
|
-
let
|
|
134
|
+
let pf = max((albedo.rgb + bs.rgb) * 0.5, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
135
|
+
let ld = (albedo.rgb - bs.rgb) / pf;
|
|
136
|
+
let iU = albedo.a - bs.a;
|
|
137
|
+
let lp = textureLoad(normalTex, q, 0).rgb - gT;
|
|
138
138
|
return max(
|
|
139
|
-
dot(
|
|
140
|
-
+
|
|
141
|
-
dot(
|
|
139
|
+
dot(ld, ld) * INV_ALBEDO_BANDWIDTH2
|
|
140
|
+
+ iU * iU * INV_COVERAGE_BANDWIDTH2,
|
|
141
|
+
dot(lp, lp) * INV_NORMAL_BANDWIDTH2
|
|
142
142
|
);
|
|
143
143
|
}
|
|
144
144
|
|
|
@@ -153,36 +153,36 @@ let p = vec2i(id.xy);
|
|
|
153
153
|
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
|
-
let
|
|
157
|
-
let
|
|
158
|
-
let index =
|
|
156
|
+
let fD = textureLoad(normalTex, p, 0);
|
|
157
|
+
let gT = fD.rgb;
|
|
158
|
+
let index = hg(p);
|
|
159
159
|
|
|
160
160
|
|
|
161
|
-
if (
|
|
161
|
+
if (fD.a <= 0.0 && textureLoad(shadowCatcherTex, p, 0).r <= 0.0) {
|
|
162
162
|
outColor[index] = color[index];
|
|
163
163
|
outGuide[index] = guide[index];
|
|
164
164
|
return;
|
|
165
165
|
}
|
|
166
166
|
|
|
167
|
-
var
|
|
167
|
+
var lf: 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
|
+
lf[k] = guide[hg(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
|
|
181
|
-
var
|
|
182
|
-
var
|
|
183
|
-
var
|
|
184
|
-
var
|
|
185
|
-
var
|
|
178
|
+
let gW = max(bs.rgb, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
179
|
+
var mp = vec3f(0.0);
|
|
180
|
+
var gy = vec3f(0.0);
|
|
181
|
+
var hs = vec3f(0.0);
|
|
182
|
+
var ps = 0.0;
|
|
183
|
+
var gA = 0.0;
|
|
184
|
+
var nU = 0.0;
|
|
185
|
+
var kM = 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,63 +191,63 @@ 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 = lw(q, bs, gT);
|
|
195
195
|
if (features > 16.0) { continue; }
|
|
196
196
|
|
|
197
|
-
var
|
|
197
|
+
var fY = 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
|
-
|
|
201
|
+
let a = lf[k];
|
|
202
|
+
let b = guide[hg(q + vec2i(dx, dy) * step)];
|
|
203
|
+
let qU = a.x - b.x;
|
|
204
|
+
fY += (qU * qU
|
|
205
205
|
- VARIANCE_CANCELLATION * (a.y + min(a.y, b.y)))
|
|
206
206
|
/ (1e-10 + k2 * (a.y + b.y));
|
|
207
207
|
k++;
|
|
208
208
|
}
|
|
209
209
|
}
|
|
210
|
-
|
|
210
|
+
fY /= f32(PATCH_SIZE);
|
|
211
211
|
|
|
212
|
-
let weight = exp(-max(max(
|
|
213
|
-
let index =
|
|
212
|
+
let weight = exp(-max(max(fY, 0.0), features));
|
|
213
|
+
let index = hg(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) / gW;
|
|
218
218
|
let value = premultiplied(c);
|
|
219
219
|
sum += value * weight;
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
220
|
+
mp += a * weight;
|
|
221
|
+
gy += a * a * weight;
|
|
222
|
+
hs += a * value.rgb * weight;
|
|
223
|
+
ps += g.x * weight;
|
|
224
|
+
gA += g.y * weight * weight;
|
|
225
|
+
nU += weight;
|
|
226
|
+
kM = max(kM, weight);
|
|
227
227
|
}
|
|
228
228
|
}
|
|
229
229
|
|
|
230
230
|
|
|
231
231
|
|
|
232
232
|
let center = color[index];
|
|
233
|
-
let
|
|
234
|
-
let
|
|
235
|
-
let totalWeight =
|
|
236
|
-
let
|
|
237
|
-
let mean = (sum +
|
|
233
|
+
let le = guide[index];
|
|
234
|
+
let dG = max(kM, CENTER_WEIGHT_MIN);
|
|
235
|
+
let totalWeight = nU + dG;
|
|
236
|
+
let tM = premultiplied(center);
|
|
237
|
+
let mean = (sum + tM * dG) / totalWeight;
|
|
238
238
|
|
|
239
239
|
|
|
240
|
-
let ez =
|
|
241
|
-
let
|
|
242
|
-
let
|
|
240
|
+
let ez = mp / totalWeight;
|
|
241
|
+
let lA = max(gy / totalWeight - ez * ez, vec3f(0.0));
|
|
242
|
+
let qu = hs / 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 qE = bs.rgb + ez * gW;
|
|
247
|
+
let oz = mean.rgb * gW / max(qE, vec3f(${JNLM_ALBEDO_FLOOR}));
|
|
248
|
+
let vB = clamp(qu / (lA + vec3f(${JNLM_ALBEDO_REGULARIZATION})), vec3f(0.0), oz);
|
|
249
|
+
let rD = mean.rgb - vB * ez;
|
|
250
|
+
let filtered = vec4f(max(rD, 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
|
+
(ps + le.x * dG) / totalWeight,
|
|
259
|
+
(gA + le.y * dG * dG)
|
|
260
260
|
/ (totalWeight * totalWeight)
|
|
261
261
|
);
|
|
262
262
|
}
|
|
@@ -16,33 +16,33 @@ ${shadowCatcherAccumulationWGSL}
|
|
|
16
16
|
override outputWidth: f32;
|
|
17
17
|
override outputHeight: f32;
|
|
18
18
|
|
|
19
|
-
struct
|
|
19
|
+
struct pd {
|
|
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)
|
|
26
|
+
fn main(@builtin(position) fH: vec4f) -> pd {
|
|
27
27
|
let size = vec2u(u32(outputWidth), u32(outputHeight));
|
|
28
|
-
let
|
|
29
|
-
var idx =
|
|
28
|
+
let fQ = vec2u(u32(fH.x), size.y - u32(fH.y) - 1u);
|
|
29
|
+
var idx = fQ.x + fQ.y * size.x;
|
|
30
30
|
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
|
|
34
34
|
if (sampleCount < 1.0 && normalBuffer[idx].a <= 0.0) {
|
|
35
|
-
let
|
|
36
|
-
let
|
|
37
|
-
((
|
|
38
|
-
((size - vec2u(1u)) /
|
|
35
|
+
let vc = max(sampleTileGrid, vec2u(1u));
|
|
36
|
+
let uM = min(
|
|
37
|
+
((fQ + vc / 2u) / vc) * vc,
|
|
38
|
+
((size - vec2u(1u)) / vc) * vc
|
|
39
39
|
);
|
|
40
|
-
let
|
|
41
|
-
if (normalBuffer[
|
|
42
|
-
idx =
|
|
40
|
+
let sH = uM.x + uM.y * size.x;
|
|
41
|
+
if (normalBuffer[sH].a > 0.0) {
|
|
42
|
+
idx = sH;
|
|
43
43
|
}
|
|
44
44
|
}
|
|
45
|
-
var output:
|
|
45
|
+
var output: pd;
|
|
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,12 +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 iV = max(hit - shadow.mask.b, 0.0);
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
output.foreground = vec4f(
|
|
69
69
|
(color.rgb - shadow.background.rgb)
|
|
70
|
-
/ select(total,
|
|
70
|
+
/ select(total, iV, iV > 0.0),
|
|
71
71
|
clamp((color.a - shadow.mask.g) / total, 0.0, 1.0)
|
|
72
72
|
);
|
|
73
73
|
output.catcherBackground = shadow.background / total;
|
|
@@ -57,6 +57,8 @@ export declare function makeRayTraceUniform(): {
|
|
|
57
57
|
sequenceSeed: Uint32Array<ArrayBuffer>;
|
|
58
58
|
zSobolLogSPP: Uint32Array<ArrayBuffer>;
|
|
59
59
|
sampleSequenceOffset: Uint32Array<ArrayBuffer>;
|
|
60
|
+
environmentRotation: Float32Array<ArrayBuffer>;
|
|
61
|
+
backgroundMapTransform: Float32Array<ArrayBuffer>;
|
|
60
62
|
};
|
|
61
63
|
};
|
|
62
64
|
export declare function packAnalyticsLightsToBuffer(lights: AnalyticLight[], texturesIndices: number[], selectionPmfs: number[], iesProfileTexelOffsets?: ArrayLike<number>): Float32Array<ArrayBuffer>;
|
|
@@ -24,7 +24,7 @@ import { WGPU_SCENE_FEATURE_BITS, wgpuSceneFeatureFlags } from './WGPUSceneFeatu
|
|
|
24
24
|
import { mat4 } from '../math.js';
|
|
25
25
|
import MaterialTable, { DEFAULT_MAX_TEXTURE_ARRAY_BYTES, materialUsesMedium } from './MaterialTable.js';
|
|
26
26
|
import { numberArraysEqual } from './util.js';
|
|
27
|
-
import { generateBackgroundMapFromSceneBackground } from './envMapCreation.js';
|
|
27
|
+
import { generateBackgroundMapFromSceneBackground, environmentRotation, backgroundMapTransform } from './envMapCreation.js';
|
|
28
28
|
import rayTraceCompute, { WORKGROUP_SIZE } from './wgsl/rayTrace.compute.js';
|
|
29
29
|
import { CONSTANT_DIRECTIONAL_LIGHT, CONSTANT_RECT_LIGHT, CONSTANT_SPHERE_LIGHT, CONSTANT_SPOT_LIGHT } from './lightsUtil.js';
|
|
30
30
|
import { envMapDistribution, environmentMapSourcesMatch } from './envMapDistribution.js';
|
|
@@ -89,7 +89,7 @@ export function isWebGPUPipelineSpecializationFailure(...errors) {
|
|
|
89
89
|
/** CPU-side views over the `RayTraceUniform` WGSL struct. */
|
|
90
90
|
export function makeRayTraceUniform() {
|
|
91
91
|
// Created from https://webgpufundamentals.org/webgpu/lessons/resources/wgsl-offset-computer.html
|
|
92
|
-
const RayTraceUniformValues = new ArrayBuffer(
|
|
92
|
+
const RayTraceUniformValues = new ArrayBuffer(256);
|
|
93
93
|
const RayTraceUniformViews = {
|
|
94
94
|
outputSize: new Float32Array(RayTraceUniformValues, 0, 2),
|
|
95
95
|
sampleCount: new Float32Array(RayTraceUniformValues, 8, 1),
|
|
@@ -119,11 +119,15 @@ export function makeRayTraceUniform() {
|
|
|
119
119
|
sceneFeatureFlags: new Uint32Array(RayTraceUniformValues, 152, 1),
|
|
120
120
|
sequenceSeed: new Uint32Array(RayTraceUniformValues, 156, 1),
|
|
121
121
|
zSobolLogSPP: new Uint32Array(RayTraceUniformValues, 160, 1),
|
|
122
|
-
sampleSequenceOffset: new Uint32Array(RayTraceUniformValues, 164, 1)
|
|
122
|
+
sampleSequenceOffset: new Uint32Array(RayTraceUniformValues, 164, 1),
|
|
123
|
+
environmentRotation: new Float32Array(RayTraceUniformValues, 176, 16),
|
|
124
|
+
backgroundMapTransform: new Float32Array(RayTraceUniformValues, 240, 4)
|
|
123
125
|
};
|
|
124
126
|
// Fixed runtime trip bounds discourage thin-film loop unrolling. Keep 4 for
|
|
125
127
|
// 2 polarizations/substrates and 3 channels, independent of BSDF budgets.
|
|
126
128
|
RayTraceUniformViews.loopUnrollGuard[0] = 4;
|
|
129
|
+
RayTraceUniformViews.environmentRotation.set(environmentRotation([]));
|
|
130
|
+
RayTraceUniformViews.backgroundMapTransform.set(backgroundMapTransform());
|
|
127
131
|
RayTraceUniformViews.bevel[0] = 1;
|
|
128
132
|
RayTraceUniformViews.dispersionWavelengths[0] = 3;
|
|
129
133
|
return {
|
|
@@ -179,7 +183,7 @@ export function packAnalyticsLightsToBuffer(lights, texturesIndices, selectionPm
|
|
|
179
183
|
data[(off + 2) * 4 + 3] = light.radius;
|
|
180
184
|
packVec3(off + 3, [
|
|
181
185
|
Math.cos((light.outerAngle * Math.PI) / 180),
|
|
182
|
-
Math.
|
|
186
|
+
Math.cos((Math.min(light.innerAngle, light.outerAngle) * Math.PI) / 180),
|
|
183
187
|
0
|
|
184
188
|
]);
|
|
185
189
|
}
|
|
@@ -792,8 +796,6 @@ class WGPURayTracePass {
|
|
|
792
796
|
...MATERIAL_TEXTURE_DEFINES,
|
|
793
797
|
'USE_ANISOTROPY_DIRECTIONS',
|
|
794
798
|
'USE_COAT_NORMAL_FRAMES',
|
|
795
|
-
'COLOR_OFF',
|
|
796
|
-
'USE_VERTEX_COLOR',
|
|
797
799
|
'HAS_ALPHA_BLEND',
|
|
798
800
|
'HAS_ALPHA_MASK'
|
|
799
801
|
];
|
|
@@ -1621,6 +1623,7 @@ ${rayTraceCompute({
|
|
|
1621
1623
|
return true;
|
|
1622
1624
|
}
|
|
1623
1625
|
setBackground(background) {
|
|
1626
|
+
this._rtUniform.views.backgroundMapTransform.set(backgroundMapTransform(background));
|
|
1624
1627
|
this._constants.USE_BACKGROUND = !!background;
|
|
1625
1628
|
const backgroundImage = background && !Array.isArray(background)
|
|
1626
1629
|
? generateBackgroundMapFromSceneBackground(background)
|
|
@@ -1913,6 +1916,9 @@ ${rayTraceCompute({
|
|
|
1913
1916
|
// Retain the atlas uniform capacity when a stage/material is removed.
|
|
1914
1917
|
// Shrinking the array would rebuild every pipeline again on the next edit.
|
|
1915
1918
|
const NUM_MAPS = Math.max(Math.ceil(+materialData.defines.NUM_MAPS / 10) * 10, Number(this._constants.NUM_MAPS ?? 0), 20);
|
|
1919
|
+
// Either layer's map requires independent normals, including a smooth
|
|
1920
|
+
// coat over a mapped base. Unmapped materials retain the shared path.
|
|
1921
|
+
const USE_COAT_NORMAL_FRAMES = materials.some(m => m.coatWeight > 0 && (!!m.normalMap || !!m.coatNormalMap));
|
|
1916
1922
|
Object.assign(this._constants, {
|
|
1917
1923
|
// Match the atlas UV selector. Keep the second set when any texture
|
|
1918
1924
|
// needs it; material/texture edits already rebuild these constants.
|
|
@@ -1921,9 +1927,8 @@ ${rayTraceCompute({
|
|
|
1921
1927
|
// triangle UV differentials rather than this vertex tangent.
|
|
1922
1928
|
USE_TANGENT: mergedGeometry.tangent != null &&
|
|
1923
1929
|
materials.some(material => material.specularAnisotropy > 0 || material.coatAnisotropy > 0 || (!!material.coatNormalMap && material.coatWeight > 0)),
|
|
1924
|
-
USE_COAT_NORMAL_FRAMES
|
|
1925
|
-
USE_ANISOTROPY_DIRECTIONS: materials.some(m => (!!m.
|
|
1926
|
-
m.specularAnisotropy > 0 && (m.specularAnisotropyModel === 'gltf' || !!m.anisotropyMap || m.specularAnisotropyRotation !== 0) ||
|
|
1930
|
+
USE_COAT_NORMAL_FRAMES,
|
|
1931
|
+
USE_ANISOTROPY_DIRECTIONS: USE_COAT_NORMAL_FRAMES || materials.some(m => m.specularAnisotropy > 0 && (m.specularAnisotropyModel === 'gltf' || !!m.anisotropyMap || m.specularAnisotropyRotation !== 0) ||
|
|
1927
1932
|
m.coatAnisotropy > 0 && m.coatAnisotropyRotation !== 0),
|
|
1928
1933
|
HAS_MEDIUM,
|
|
1929
1934
|
HAS_SHADOW_CATCHER: this._hasShadowCatcher,
|
|
@@ -2119,6 +2124,8 @@ ${rayTraceCompute({
|
|
|
2119
2124
|
for (let i = 0; i < mapUvChannel.length; i++) {
|
|
2120
2125
|
mapInfoData[numMaps * 8 + i * 4] = mapUvChannel[i];
|
|
2121
2126
|
mapInfoData[numMaps * 8 + i * 4 + 1] = mapColorLinear[i];
|
|
2127
|
+
mapInfoData[numMaps * 8 + i * 4 + 2] = materialData.bufferData.mapWrap[i * 2];
|
|
2128
|
+
mapInfoData[numMaps * 8 + i * 4 + 3] = materialData.bufferData.mapWrap[i * 2 + 1];
|
|
2122
2129
|
}
|
|
2123
2130
|
let mapInfoUniform = this._mapInfoUniform;
|
|
2124
2131
|
if (!mapInfoUniform || mapInfoUniform.size !== mapInfoData.byteLength) {
|
|
@@ -2186,6 +2193,7 @@ ${rayTraceCompute({
|
|
|
2186
2193
|
const analyticLights = allAnalyticLights.slice(0, FIXED_LIGHT_COUNT);
|
|
2187
2194
|
const numAnalyticLights = analyticLights.length;
|
|
2188
2195
|
const envImage = this._sceneEnvironment.update(lights);
|
|
2196
|
+
this._rtUniform.views.environmentRotation.set(environmentRotation(lights));
|
|
2189
2197
|
this._rtUniform.views.lightsCount[0] = numAnalyticLights;
|
|
2190
2198
|
this._setEnvMap(envImage);
|
|
2191
2199
|
const lightTexturesChanged = this._rectLightTextures.update(analyticLights);
|