@plasius/gpu-lighting 0.2.5 → 0.2.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +35 -3
- package/README.md +98 -0
- package/dist/index.cjs +837 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +817 -0
- package/dist/index.js.map +1 -1
- package/dist/techniques/techniques/wavefront/accumulate-terminal-radiance.job.wgsl +61 -0
- package/dist/techniques/techniques/wavefront/prelude.wgsl +237 -0
- package/dist/techniques/techniques/wavefront/scatter-continuations.job.wgsl +136 -0
- package/package.json +2 -1
- package/src/index.js +889 -0
- package/src/techniques/wavefront/accumulate-terminal-radiance.job.wgsl +61 -0
- package/src/techniques/wavefront/prelude.wgsl +237 -0
- package/src/techniques/wavefront/scatter-continuations.job.wgsl +136 -0
package/dist/index.js
CHANGED
|
@@ -41,6 +41,14 @@ var techniqueSpecs = {
|
|
|
41
41
|
denoise: "denoise.job.wgsl"
|
|
42
42
|
}
|
|
43
43
|
},
|
|
44
|
+
wavefront: {
|
|
45
|
+
description: "Renderer-aligned wavefront lighting jobs for terminal radiance and continuation scattering.",
|
|
46
|
+
prelude: "prelude.wgsl",
|
|
47
|
+
jobs: {
|
|
48
|
+
accumulateTerminalRadiance: "accumulate-terminal-radiance.job.wgsl",
|
|
49
|
+
scatterContinuations: "scatter-continuations.job.wgsl"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
44
52
|
volumetrics: {
|
|
45
53
|
description: "Froxel volumetric lighting for fog, shafts, and participating media shadows.",
|
|
46
54
|
prelude: "prelude.wgsl",
|
|
@@ -1049,6 +1057,684 @@ function createWavefrontEnvironmentLightingOptions(options = {}) {
|
|
|
1049
1057
|
lightingEnvironment: config
|
|
1050
1058
|
});
|
|
1051
1059
|
}
|
|
1060
|
+
var lightingWavefrontSchemaVersion = 1;
|
|
1061
|
+
var lightingWavefrontQueuePairStrategy = "ping-pong-active-next";
|
|
1062
|
+
var lightingWavefrontHitTypes = Object.freeze([
|
|
1063
|
+
"surface",
|
|
1064
|
+
"emissive",
|
|
1065
|
+
"environment",
|
|
1066
|
+
"transparent",
|
|
1067
|
+
"miss"
|
|
1068
|
+
]);
|
|
1069
|
+
var lightingWavefrontRayKinds = Object.freeze([
|
|
1070
|
+
"path",
|
|
1071
|
+
"visibility-probe"
|
|
1072
|
+
]);
|
|
1073
|
+
var lightingWavefrontVisibilityProbeModes = Object.freeze([
|
|
1074
|
+
"disabled",
|
|
1075
|
+
"mis-balanced",
|
|
1076
|
+
"exclusive-emissive"
|
|
1077
|
+
]);
|
|
1078
|
+
var lightingWavefrontTerminalHitTypes = Object.freeze([
|
|
1079
|
+
"emissive",
|
|
1080
|
+
"environment",
|
|
1081
|
+
"miss"
|
|
1082
|
+
]);
|
|
1083
|
+
var lightingWavefrontContinuationHitTypes = Object.freeze([
|
|
1084
|
+
"surface",
|
|
1085
|
+
"transparent"
|
|
1086
|
+
]);
|
|
1087
|
+
var lightingWavefrontPassOrder = Object.freeze([
|
|
1088
|
+
"accumulateTerminalRadiance",
|
|
1089
|
+
"scatterContinuations"
|
|
1090
|
+
]);
|
|
1091
|
+
var lightingRequiredRendererWavefrontPassOrder = Object.freeze([
|
|
1092
|
+
"generatePrimaryRays",
|
|
1093
|
+
"intersectActiveQueue",
|
|
1094
|
+
"resolveSurfaceRecords",
|
|
1095
|
+
"accumulateTerminalRadiance",
|
|
1096
|
+
"scatterContinuations",
|
|
1097
|
+
"compactAndSwapQueues"
|
|
1098
|
+
]);
|
|
1099
|
+
function createLightingWavefrontField(name, type, description) {
|
|
1100
|
+
return Object.freeze({
|
|
1101
|
+
name,
|
|
1102
|
+
type,
|
|
1103
|
+
description
|
|
1104
|
+
});
|
|
1105
|
+
}
|
|
1106
|
+
function createLightingWavefrontRecordContract(recordName, fields) {
|
|
1107
|
+
return Object.freeze({
|
|
1108
|
+
schemaVersion: lightingWavefrontSchemaVersion,
|
|
1109
|
+
recordName,
|
|
1110
|
+
fields: Object.freeze(fields)
|
|
1111
|
+
});
|
|
1112
|
+
}
|
|
1113
|
+
var lightingWavefrontBufferContracts = Object.freeze({
|
|
1114
|
+
ray: createLightingWavefrontRecordContract(
|
|
1115
|
+
"RayRecord",
|
|
1116
|
+
[
|
|
1117
|
+
createLightingWavefrontField("rayId", "u32", "Stable ray identifier."),
|
|
1118
|
+
createLightingWavefrontField("parentRayId", "u32", "Parent ray identifier."),
|
|
1119
|
+
createLightingWavefrontField("sourcePixelId", "u32", "Source pixel/sample owner."),
|
|
1120
|
+
createLightingWavefrontField("sampleId", "u32", "Per-pixel sample slot."),
|
|
1121
|
+
createLightingWavefrontField("bounce", "u32", "Current bounce depth."),
|
|
1122
|
+
createLightingWavefrontField("mediumRefId", "u32", "Current medium reference."),
|
|
1123
|
+
createLightingWavefrontField(
|
|
1124
|
+
"mediumStackDepth",
|
|
1125
|
+
"u32",
|
|
1126
|
+
"Depth of the bounded nested medium stack."
|
|
1127
|
+
),
|
|
1128
|
+
createLightingWavefrontField(
|
|
1129
|
+
"flags",
|
|
1130
|
+
"u32",
|
|
1131
|
+
"Renderer-owned ray flags. Low bits may encode ray kind metadata."
|
|
1132
|
+
),
|
|
1133
|
+
createLightingWavefrontField(
|
|
1134
|
+
"mediumStack0",
|
|
1135
|
+
"vec4<u32>",
|
|
1136
|
+
"Lower half of the bounded nested medium stack."
|
|
1137
|
+
),
|
|
1138
|
+
createLightingWavefrontField(
|
|
1139
|
+
"mediumStack1",
|
|
1140
|
+
"vec4<u32>",
|
|
1141
|
+
"Upper half of the bounded nested medium stack."
|
|
1142
|
+
),
|
|
1143
|
+
createLightingWavefrontField(
|
|
1144
|
+
"spectralState",
|
|
1145
|
+
"vec4<f32>",
|
|
1146
|
+
"Spectral transport payload for wavelength-driven reference validation."
|
|
1147
|
+
),
|
|
1148
|
+
createLightingWavefrontField("origin", "vec3<f32>", "Ray origin."),
|
|
1149
|
+
createLightingWavefrontField("direction", "vec3<f32>", "Normalized ray direction."),
|
|
1150
|
+
createLightingWavefrontField("throughput", "vec3<f32>", "Accumulated path throughput.")
|
|
1151
|
+
]
|
|
1152
|
+
),
|
|
1153
|
+
hit: createLightingWavefrontRecordContract(
|
|
1154
|
+
"HitRecord",
|
|
1155
|
+
[
|
|
1156
|
+
createLightingWavefrontField("rayId", "u32", "Stable ray identifier."),
|
|
1157
|
+
createLightingWavefrontField("sourcePixelId", "u32", "Source pixel/sample owner."),
|
|
1158
|
+
createLightingWavefrontField("hitType", "u32", "Surface, emissive, environment, transparent, or miss."),
|
|
1159
|
+
createLightingWavefrontField("distance", "f32", "Nearest-hit distance."),
|
|
1160
|
+
createLightingWavefrontField("entityId", "u32", "Owning entity identifier."),
|
|
1161
|
+
createLightingWavefrontField("instanceId", "u32", "Owning instance identifier."),
|
|
1162
|
+
createLightingWavefrontField("primitiveId", "u32", "Primitive identifier."),
|
|
1163
|
+
createLightingWavefrontField("materialId", "u32", "Resolved material identifier."),
|
|
1164
|
+
createLightingWavefrontField("barycentrics", "vec3<f32>", "Triangle barycentrics."),
|
|
1165
|
+
createLightingWavefrontField("uv", "vec2<f32>", "Resolved UV coordinates."),
|
|
1166
|
+
createLightingWavefrontField("geometricNormal", "vec3<f32>", "Geometric surface normal."),
|
|
1167
|
+
createLightingWavefrontField("shadingNormal", "vec3<f32>", "Interpolated shading normal."),
|
|
1168
|
+
createLightingWavefrontField("frontFace", "u32", "Front-face classification.")
|
|
1169
|
+
]
|
|
1170
|
+
),
|
|
1171
|
+
surface: createLightingWavefrontRecordContract(
|
|
1172
|
+
"SurfaceRecord",
|
|
1173
|
+
[
|
|
1174
|
+
createLightingWavefrontField("rayId", "u32", "Stable ray identifier."),
|
|
1175
|
+
createLightingWavefrontField("entityId", "u32", "Owning entity identifier."),
|
|
1176
|
+
createLightingWavefrontField("materialRefId", "u32", "Renderer material reference id."),
|
|
1177
|
+
createLightingWavefrontField("mediumRefId", "u32", "Renderer medium reference id."),
|
|
1178
|
+
createLightingWavefrontField("geometricNormal", "vec3<f32>", "Geometric surface normal."),
|
|
1179
|
+
createLightingWavefrontField("shadingNormal", "vec3<f32>", "Interpolated shading normal."),
|
|
1180
|
+
createLightingWavefrontField("uv", "vec2<f32>", "Resolved UV coordinates."),
|
|
1181
|
+
createLightingWavefrontField("tangentFrame", "mat3x3<f32>", "Resolved tangent frame.")
|
|
1182
|
+
]
|
|
1183
|
+
),
|
|
1184
|
+
materialReference: createLightingWavefrontRecordContract(
|
|
1185
|
+
"MaterialReferenceRecord",
|
|
1186
|
+
[
|
|
1187
|
+
createLightingWavefrontField("materialRefId", "u32", "Lighting-visible material reference id."),
|
|
1188
|
+
createLightingWavefrontField("materialId", "u32", "Source material identifier."),
|
|
1189
|
+
createLightingWavefrontField("shadingModel", "u32", "Renderer shading-model discriminator."),
|
|
1190
|
+
createLightingWavefrontField("textureSetId", "u32", "Resolved texture-set identifier."),
|
|
1191
|
+
createLightingWavefrontField("flags", "u32", "Renderer material flags.")
|
|
1192
|
+
]
|
|
1193
|
+
),
|
|
1194
|
+
mediumReference: createLightingWavefrontRecordContract(
|
|
1195
|
+
"MediumReferenceRecord",
|
|
1196
|
+
[
|
|
1197
|
+
createLightingWavefrontField("mediumRefId", "u32", "Lighting-visible medium reference id."),
|
|
1198
|
+
createLightingWavefrontField("mediumId", "u32", "Source medium identifier."),
|
|
1199
|
+
createLightingWavefrontField("phaseModel", "u32", "Phase-function discriminator."),
|
|
1200
|
+
createLightingWavefrontField("absorption", "vec3<f32>", "Medium absorption coefficients."),
|
|
1201
|
+
createLightingWavefrontField("scattering", "vec3<f32>", "Medium scattering coefficients.")
|
|
1202
|
+
]
|
|
1203
|
+
),
|
|
1204
|
+
accumulation: createLightingWavefrontRecordContract(
|
|
1205
|
+
"AccumulationRecord",
|
|
1206
|
+
[
|
|
1207
|
+
createLightingWavefrontField("sourcePixelId", "u32", "Source pixel/sample owner."),
|
|
1208
|
+
createLightingWavefrontField("sampleCount", "u32", "Accumulated sample count."),
|
|
1209
|
+
createLightingWavefrontField("radiance", "vec3<f32>", "Accumulated radiance."),
|
|
1210
|
+
createLightingWavefrontField("throughput", "vec3<f32>", "Last surviving throughput."),
|
|
1211
|
+
createLightingWavefrontField("resetEpoch", "u32", "Renderer accumulation reset epoch.")
|
|
1212
|
+
]
|
|
1213
|
+
)
|
|
1214
|
+
});
|
|
1215
|
+
var lightingWavefrontTerminationPolicy = Object.freeze({
|
|
1216
|
+
terminalHitTypes: lightingWavefrontTerminalHitTypes,
|
|
1217
|
+
continuationHitTypes: lightingWavefrontContinuationHitTypes,
|
|
1218
|
+
emissive: Object.freeze({
|
|
1219
|
+
action: "accumulate-and-stop",
|
|
1220
|
+
contributesRadiance: true
|
|
1221
|
+
}),
|
|
1222
|
+
environment: Object.freeze({
|
|
1223
|
+
action: "accumulate-and-stop",
|
|
1224
|
+
contributesRadiance: true
|
|
1225
|
+
}),
|
|
1226
|
+
miss: Object.freeze({
|
|
1227
|
+
action: "accumulate-environment-or-dark-stop",
|
|
1228
|
+
contributesRadiance: true
|
|
1229
|
+
})
|
|
1230
|
+
});
|
|
1231
|
+
var defaultWavefrontDarkRadiance = Object.freeze([1e-4, 1e-4, 1e-4]);
|
|
1232
|
+
var wavefrontEventKinds = Object.freeze([
|
|
1233
|
+
"diffuse",
|
|
1234
|
+
"reflection",
|
|
1235
|
+
"refraction",
|
|
1236
|
+
"transparency",
|
|
1237
|
+
"terminate"
|
|
1238
|
+
]);
|
|
1239
|
+
var wavefrontRayKindFlagMask = 3;
|
|
1240
|
+
var wavefrontRayKindFlagValues = Object.freeze({
|
|
1241
|
+
path: 0,
|
|
1242
|
+
"visibility-probe": 1
|
|
1243
|
+
});
|
|
1244
|
+
function normalizeWavefrontRayKind(value) {
|
|
1245
|
+
return lightingWavefrontRayKinds.includes(value) ? value : "path";
|
|
1246
|
+
}
|
|
1247
|
+
function normalizeWavefrontVisibilityProbeMode(value) {
|
|
1248
|
+
return lightingWavefrontVisibilityProbeModes.includes(value) ? value : "disabled";
|
|
1249
|
+
}
|
|
1250
|
+
function normalizeWavefrontHitType(value) {
|
|
1251
|
+
return lightingWavefrontHitTypes.includes(value) ? value : "surface";
|
|
1252
|
+
}
|
|
1253
|
+
function normalizeWavefrontEventKind(value) {
|
|
1254
|
+
return wavefrontEventKinds.includes(value) ? value : null;
|
|
1255
|
+
}
|
|
1256
|
+
function normalizeVec3(value, fallback = [0, 0, 0]) {
|
|
1257
|
+
if (!Array.isArray(value) || value.length < 3) {
|
|
1258
|
+
return [...fallback];
|
|
1259
|
+
}
|
|
1260
|
+
return [
|
|
1261
|
+
Number.isFinite(value[0]) ? value[0] : fallback[0],
|
|
1262
|
+
Number.isFinite(value[1]) ? value[1] : fallback[1],
|
|
1263
|
+
Number.isFinite(value[2]) ? value[2] : fallback[2]
|
|
1264
|
+
];
|
|
1265
|
+
}
|
|
1266
|
+
function clampUnit(value, fallback = 0) {
|
|
1267
|
+
return Math.max(0, Math.min(1, readFinite(value, fallback)));
|
|
1268
|
+
}
|
|
1269
|
+
function saturateVec3(value) {
|
|
1270
|
+
return value.map((component) => Math.max(0, component));
|
|
1271
|
+
}
|
|
1272
|
+
function scaleVec3(value, scalar) {
|
|
1273
|
+
return value.map((component) => component * scalar);
|
|
1274
|
+
}
|
|
1275
|
+
function addVec3(left, right) {
|
|
1276
|
+
return left.map((component, index) => component + right[index]);
|
|
1277
|
+
}
|
|
1278
|
+
function multiplyVec3(left, right) {
|
|
1279
|
+
return left.map((component, index) => component * right[index]);
|
|
1280
|
+
}
|
|
1281
|
+
function dotVec3(left, right) {
|
|
1282
|
+
return left[0] * right[0] + left[1] * right[1] + left[2] * right[2];
|
|
1283
|
+
}
|
|
1284
|
+
function lengthVec3(value) {
|
|
1285
|
+
return Math.hypot(value[0], value[1], value[2]);
|
|
1286
|
+
}
|
|
1287
|
+
function normalizeDirection(value, fallback = [0, 1, 0]) {
|
|
1288
|
+
const vector = normalizeVec3(value, fallback);
|
|
1289
|
+
const length = lengthVec3(vector);
|
|
1290
|
+
if (!Number.isFinite(length) || length <= 1e-6) {
|
|
1291
|
+
return [...fallback];
|
|
1292
|
+
}
|
|
1293
|
+
return vector.map((component) => component / length);
|
|
1294
|
+
}
|
|
1295
|
+
function mixVec3(left, right, factor) {
|
|
1296
|
+
return left.map(
|
|
1297
|
+
(component, index) => component * (1 - factor) + right[index] * factor
|
|
1298
|
+
);
|
|
1299
|
+
}
|
|
1300
|
+
function reflectDirection(direction, normal) {
|
|
1301
|
+
const scale = 2 * dotVec3(direction, normal);
|
|
1302
|
+
return normalizeDirection(
|
|
1303
|
+
[
|
|
1304
|
+
direction[0] - scale * normal[0],
|
|
1305
|
+
direction[1] - scale * normal[1],
|
|
1306
|
+
direction[2] - scale * normal[2]
|
|
1307
|
+
],
|
|
1308
|
+
normal
|
|
1309
|
+
);
|
|
1310
|
+
}
|
|
1311
|
+
function refractDirection(direction, normal, etaRatio) {
|
|
1312
|
+
const cosTheta = Math.min(-dotVec3(direction, normal), 1);
|
|
1313
|
+
const rOutPerp = scaleVec3(addVec3(direction, scaleVec3(normal, cosTheta)), etaRatio);
|
|
1314
|
+
const rOutPerpLengthSquared = dotVec3(rOutPerp, rOutPerp);
|
|
1315
|
+
const parallelFactor = 1 - rOutPerpLengthSquared;
|
|
1316
|
+
if (parallelFactor <= 0) {
|
|
1317
|
+
return null;
|
|
1318
|
+
}
|
|
1319
|
+
const rOutParallel = scaleVec3(normal, -Math.sqrt(parallelFactor));
|
|
1320
|
+
return normalizeDirection(addVec3(rOutPerp, rOutParallel), direction);
|
|
1321
|
+
}
|
|
1322
|
+
function normalizeMediumRefId(value) {
|
|
1323
|
+
const mediumRefId = Math.max(0, Math.trunc(readFinite(value, 0)));
|
|
1324
|
+
return Number.isFinite(mediumRefId) ? mediumRefId : 0;
|
|
1325
|
+
}
|
|
1326
|
+
function normalizeMediumStack(value) {
|
|
1327
|
+
if (!Array.isArray(value)) {
|
|
1328
|
+
return [];
|
|
1329
|
+
}
|
|
1330
|
+
return value.map((entry) => normalizeMediumRefId(entry)).filter((entry, index, stack) => entry > 0 && stack.indexOf(entry) === index).slice(0, 4);
|
|
1331
|
+
}
|
|
1332
|
+
function createWavefrontMediumStatePayload(currentMediumRefId, stack) {
|
|
1333
|
+
const normalizedStack = normalizeMediumStack(stack);
|
|
1334
|
+
const stackSlots = [0, 0, 0, 0];
|
|
1335
|
+
normalizedStack.forEach((entry, index) => {
|
|
1336
|
+
stackSlots[index] = entry;
|
|
1337
|
+
});
|
|
1338
|
+
return Object.freeze({
|
|
1339
|
+
currentMediumRefId,
|
|
1340
|
+
stackDepth: normalizedStack.length,
|
|
1341
|
+
stack: Object.freeze(normalizedStack),
|
|
1342
|
+
stackSlots: Object.freeze(stackSlots)
|
|
1343
|
+
});
|
|
1344
|
+
}
|
|
1345
|
+
function evaluateWavefrontMediumState(options = {}) {
|
|
1346
|
+
const currentMediumRefId = normalizeMediumRefId(
|
|
1347
|
+
options.currentMediumRefId ?? options.mediumRefId
|
|
1348
|
+
);
|
|
1349
|
+
const surfaceMediumRefId = normalizeMediumRefId(options.surfaceMediumRefId);
|
|
1350
|
+
const stack = normalizeMediumStack(options.mediumStack);
|
|
1351
|
+
const frontFace = options.frontFace !== false;
|
|
1352
|
+
const eventKind = normalizeWavefrontEventKind(options.eventKind) ?? "transparency";
|
|
1353
|
+
if (surfaceMediumRefId === 0 || eventKind !== "refraction" && eventKind !== "transparency") {
|
|
1354
|
+
return Object.freeze({
|
|
1355
|
+
...createWavefrontMediumStatePayload(currentMediumRefId, stack),
|
|
1356
|
+
enteredMediumRefId: 0,
|
|
1357
|
+
exitedMediumRefId: 0
|
|
1358
|
+
});
|
|
1359
|
+
}
|
|
1360
|
+
let nextStack = [...stack];
|
|
1361
|
+
let nextMediumRefId = currentMediumRefId;
|
|
1362
|
+
let enteredMediumRefId = 0;
|
|
1363
|
+
let exitedMediumRefId = 0;
|
|
1364
|
+
const stackTop = nextStack.at(-1) ?? 0;
|
|
1365
|
+
if (frontFace) {
|
|
1366
|
+
if (stackTop !== surfaceMediumRefId) {
|
|
1367
|
+
nextStack.push(surfaceMediumRefId);
|
|
1368
|
+
nextStack = nextStack.slice(-4);
|
|
1369
|
+
}
|
|
1370
|
+
nextMediumRefId = surfaceMediumRefId;
|
|
1371
|
+
enteredMediumRefId = surfaceMediumRefId;
|
|
1372
|
+
} else if (stackTop === surfaceMediumRefId) {
|
|
1373
|
+
nextStack.pop();
|
|
1374
|
+
nextMediumRefId = nextStack.at(-1) ?? 0;
|
|
1375
|
+
exitedMediumRefId = surfaceMediumRefId;
|
|
1376
|
+
}
|
|
1377
|
+
return Object.freeze({
|
|
1378
|
+
...createWavefrontMediumStatePayload(nextMediumRefId, nextStack),
|
|
1379
|
+
enteredMediumRefId,
|
|
1380
|
+
exitedMediumRefId
|
|
1381
|
+
});
|
|
1382
|
+
}
|
|
1383
|
+
function encodeWavefrontRayFlags(flags, rayKind) {
|
|
1384
|
+
const normalizedFlags = Math.max(0, Math.trunc(readFinite(flags, 0)));
|
|
1385
|
+
const rayKindValue = wavefrontRayKindFlagValues[rayKind];
|
|
1386
|
+
return normalizedFlags & ~wavefrontRayKindFlagMask | rayKindValue;
|
|
1387
|
+
}
|
|
1388
|
+
function createWavefrontRayPayload(options = {}) {
|
|
1389
|
+
const rayKind = normalizeWavefrontRayKind(options.rayKind);
|
|
1390
|
+
const mediumState = evaluateWavefrontMediumState({
|
|
1391
|
+
currentMediumRefId: options.mediumRefId,
|
|
1392
|
+
mediumStack: options.mediumStack
|
|
1393
|
+
});
|
|
1394
|
+
const spectralState = Object.freeze(
|
|
1395
|
+
normalizeVec3(options.spectralState, [550, 1, 0]).concat(
|
|
1396
|
+
readFinite(options.spectralWeight, 0)
|
|
1397
|
+
)
|
|
1398
|
+
);
|
|
1399
|
+
const mediumStack0 = Object.freeze([
|
|
1400
|
+
mediumState.stackSlots[0],
|
|
1401
|
+
mediumState.stackSlots[1],
|
|
1402
|
+
mediumState.stackSlots[2],
|
|
1403
|
+
mediumState.stackSlots[3]
|
|
1404
|
+
]);
|
|
1405
|
+
const mediumStack1 = Object.freeze([0, 0, 0, 0]);
|
|
1406
|
+
return Object.freeze({
|
|
1407
|
+
rayId: Math.max(0, Math.trunc(readFinite(options.rayId, 0))),
|
|
1408
|
+
parentRayId: Math.max(0, Math.trunc(readFinite(options.parentRayId, 0))),
|
|
1409
|
+
sourcePixelId: Math.max(0, Math.trunc(readFinite(options.sourcePixelId, 0))),
|
|
1410
|
+
sampleId: Math.max(0, Math.trunc(readFinite(options.sampleId, 0))),
|
|
1411
|
+
bounce: Math.max(0, Math.trunc(readFinite(options.bounce, 0))),
|
|
1412
|
+
origin: Object.freeze(normalizeVec3(options.origin, [0, 0, 0])),
|
|
1413
|
+
direction: Object.freeze(normalizeDirection(options.direction, [0, 0, -1])),
|
|
1414
|
+
throughput: Object.freeze(
|
|
1415
|
+
saturateVec3(normalizeVec3(options.throughput, [1, 1, 1]))
|
|
1416
|
+
),
|
|
1417
|
+
mediumRefId: mediumState.currentMediumRefId,
|
|
1418
|
+
mediumStackDepth: mediumState.stackDepth,
|
|
1419
|
+
mediumStack: mediumState.stack,
|
|
1420
|
+
mediumStackSlots: mediumState.stackSlots,
|
|
1421
|
+
mediumStack0,
|
|
1422
|
+
mediumStack1,
|
|
1423
|
+
spectralState,
|
|
1424
|
+
rayKind,
|
|
1425
|
+
flags: encodeWavefrontRayFlags(options.flags, rayKind)
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
function createWavefrontVisibilityProbeRay(options = {}) {
|
|
1429
|
+
return createWavefrontRayPayload({
|
|
1430
|
+
...options,
|
|
1431
|
+
rayKind: "visibility-probe"
|
|
1432
|
+
});
|
|
1433
|
+
}
|
|
1434
|
+
function createWavefrontLightingPlan(options = {}) {
|
|
1435
|
+
const maxDepth = Math.max(1, Math.trunc(readFinite(options.maxDepth, 4)));
|
|
1436
|
+
const queueCapacity = Math.max(
|
|
1437
|
+
1,
|
|
1438
|
+
Math.trunc(readFinite(options.queueCapacity, 4096))
|
|
1439
|
+
);
|
|
1440
|
+
const explicitLightSampling = Boolean(options.explicitLightSampling);
|
|
1441
|
+
const visibilityProbeMode = normalizeWavefrontVisibilityProbeMode(
|
|
1442
|
+
options.visibilityProbeMode ?? (explicitLightSampling ? "mis-balanced" : "disabled")
|
|
1443
|
+
);
|
|
1444
|
+
const accumulationResetEpoch = Math.max(
|
|
1445
|
+
0,
|
|
1446
|
+
Math.trunc(readFinite(options.accumulationResetEpoch, 0))
|
|
1447
|
+
);
|
|
1448
|
+
return Object.freeze({
|
|
1449
|
+
schemaVersion: lightingWavefrontSchemaVersion,
|
|
1450
|
+
maxDepth,
|
|
1451
|
+
queueCapacity,
|
|
1452
|
+
explicitLightSampling,
|
|
1453
|
+
visibilityProbeMode,
|
|
1454
|
+
rayKinds: lightingWavefrontRayKinds,
|
|
1455
|
+
accumulationResetEpoch,
|
|
1456
|
+
queueLayout: Object.freeze({
|
|
1457
|
+
strategy: lightingWavefrontQueuePairStrategy,
|
|
1458
|
+
compactAfterScatter: true,
|
|
1459
|
+
queues: Object.freeze([
|
|
1460
|
+
Object.freeze({ name: "active", role: "current-bounce" }),
|
|
1461
|
+
Object.freeze({ name: "next", role: "next-bounce" })
|
|
1462
|
+
])
|
|
1463
|
+
}),
|
|
1464
|
+
bufferContracts: lightingWavefrontBufferContracts,
|
|
1465
|
+
terminationPolicy: lightingWavefrontTerminationPolicy,
|
|
1466
|
+
requiredRendererPassOrder: lightingRequiredRendererWavefrontPassOrder,
|
|
1467
|
+
lightingPasses: Object.freeze([
|
|
1468
|
+
Object.freeze({
|
|
1469
|
+
key: "accumulateTerminalRadiance",
|
|
1470
|
+
stage: "accumulateTerminalRadiance",
|
|
1471
|
+
reads: Object.freeze([
|
|
1472
|
+
"ray",
|
|
1473
|
+
"hit",
|
|
1474
|
+
"surface",
|
|
1475
|
+
"materialReference",
|
|
1476
|
+
"mediumReference"
|
|
1477
|
+
]),
|
|
1478
|
+
writes: Object.freeze(["accumulation"]),
|
|
1479
|
+
terminalHitTypes: lightingWavefrontTerminalHitTypes
|
|
1480
|
+
}),
|
|
1481
|
+
Object.freeze({
|
|
1482
|
+
key: "scatterContinuations",
|
|
1483
|
+
stage: "scatterContinuations",
|
|
1484
|
+
reads: Object.freeze([
|
|
1485
|
+
"ray",
|
|
1486
|
+
"hit",
|
|
1487
|
+
"surface",
|
|
1488
|
+
"materialReference",
|
|
1489
|
+
"mediumReference"
|
|
1490
|
+
]),
|
|
1491
|
+
writes: Object.freeze(["ray"]),
|
|
1492
|
+
continuationHitTypes: lightingWavefrontContinuationHitTypes,
|
|
1493
|
+
explicitLightSampling,
|
|
1494
|
+
visibilityProbeMode
|
|
1495
|
+
})
|
|
1496
|
+
])
|
|
1497
|
+
});
|
|
1498
|
+
}
|
|
1499
|
+
function evaluateWavefrontTerminalRadiance(options = {}) {
|
|
1500
|
+
const hitType = normalizeWavefrontHitType(options.hitType);
|
|
1501
|
+
const throughput = saturateVec3(normalizeVec3(options.throughput, [1, 1, 1]));
|
|
1502
|
+
const emission = saturateVec3(normalizeVec3(options.emission, [0, 0, 0]));
|
|
1503
|
+
const environmentRadiance = saturateVec3(
|
|
1504
|
+
normalizeVec3(options.environmentRadiance, [0, 0, 0])
|
|
1505
|
+
);
|
|
1506
|
+
const missRadiance = saturateVec3(
|
|
1507
|
+
normalizeVec3(options.missRadiance, defaultWavefrontDarkRadiance)
|
|
1508
|
+
);
|
|
1509
|
+
const environmentLuminance = colorLuminance(environmentRadiance);
|
|
1510
|
+
let source = "none";
|
|
1511
|
+
let rawRadiance = [0, 0, 0];
|
|
1512
|
+
if (hitType === "emissive") {
|
|
1513
|
+
source = "emissive";
|
|
1514
|
+
rawRadiance = emission;
|
|
1515
|
+
} else if (hitType === "environment") {
|
|
1516
|
+
source = "environment";
|
|
1517
|
+
rawRadiance = environmentRadiance;
|
|
1518
|
+
} else if (hitType === "miss") {
|
|
1519
|
+
source = environmentLuminance > 1e-6 ? "environment" : "dark";
|
|
1520
|
+
rawRadiance = environmentLuminance > 1e-6 ? environmentRadiance : missRadiance;
|
|
1521
|
+
}
|
|
1522
|
+
const radiance = multiplyVec3(throughput, rawRadiance);
|
|
1523
|
+
const terminated = lightingWavefrontTerminalHitTypes.includes(hitType);
|
|
1524
|
+
return Object.freeze({
|
|
1525
|
+
hitType,
|
|
1526
|
+
source,
|
|
1527
|
+
terminated,
|
|
1528
|
+
radiance: Object.freeze(radiance),
|
|
1529
|
+
nearDarkSample: source === "dark" && colorLuminance(radiance) <= colorLuminance(defaultWavefrontDarkRadiance)
|
|
1530
|
+
});
|
|
1531
|
+
}
|
|
1532
|
+
function evaluateWavefrontContinuationEvent(options = {}) {
|
|
1533
|
+
const hitType = normalizeWavefrontHitType(options.hitType);
|
|
1534
|
+
const bounceIndex = Math.max(0, Math.trunc(readFinite(options.bounceIndex, 0)));
|
|
1535
|
+
const maxDepth = Math.max(1, Math.trunc(readFinite(options.maxDepth, 4)));
|
|
1536
|
+
const throughput = saturateVec3(normalizeVec3(options.throughput, [1, 1, 1]));
|
|
1537
|
+
const albedo = saturateVec3(normalizeVec3(options.albedo, [0.8, 0.8, 0.8]));
|
|
1538
|
+
const transmission = saturateVec3(
|
|
1539
|
+
normalizeVec3(options.transmission, [0, 0, 0])
|
|
1540
|
+
);
|
|
1541
|
+
const shadingNormal = normalizeDirection(options.shadingNormal, [0, 1, 0]);
|
|
1542
|
+
const viewDirection = normalizeDirection(options.viewDirection, [0, 0, 1]);
|
|
1543
|
+
const incomingDirection = normalizeDirection(
|
|
1544
|
+
scaleVec3(viewDirection, -1),
|
|
1545
|
+
[0, 0, -1]
|
|
1546
|
+
);
|
|
1547
|
+
const frontFace = options.frontFace !== false;
|
|
1548
|
+
const orientedNormal = frontFace ? shadingNormal : scaleVec3(shadingNormal, -1);
|
|
1549
|
+
const metalness = clampUnit(options.metalness, 0);
|
|
1550
|
+
const roughness = clampUnit(options.roughness, 0.5);
|
|
1551
|
+
const opacity = clampUnit(options.opacity, 1);
|
|
1552
|
+
const refractiveIndex = Math.max(1, readFinite(options.refractiveIndex ?? options.ior, 1.45));
|
|
1553
|
+
const transmissionStrength = Math.max(...transmission);
|
|
1554
|
+
const requestedEventKind = normalizeWavefrontEventKind(options.eventKind) ?? (hitType === "transparent" || opacity < 0.999 ? "transparency" : transmissionStrength > 1e-3 ? "refraction" : metalness >= 0.5 || roughness <= 0.2 ? "reflection" : "diffuse");
|
|
1555
|
+
let eventKind = requestedEventKind;
|
|
1556
|
+
let totalInternalReflection = false;
|
|
1557
|
+
let nextDirection = incomingDirection;
|
|
1558
|
+
let attenuation;
|
|
1559
|
+
if (!lightingWavefrontContinuationHitTypes.includes(hitType) || bounceIndex >= maxDepth - 1) {
|
|
1560
|
+
eventKind = "terminate";
|
|
1561
|
+
attenuation = [0, 0, 0];
|
|
1562
|
+
} else if (eventKind === "reflection") {
|
|
1563
|
+
nextDirection = reflectDirection(incomingDirection, orientedNormal);
|
|
1564
|
+
attenuation = mixVec3([0.04, 0.04, 0.04], albedo, metalness);
|
|
1565
|
+
} else if (eventKind === "refraction") {
|
|
1566
|
+
const etaRatio = frontFace ? 1 / refractiveIndex : refractiveIndex;
|
|
1567
|
+
const refractedDirection = refractDirection(
|
|
1568
|
+
incomingDirection,
|
|
1569
|
+
orientedNormal,
|
|
1570
|
+
etaRatio
|
|
1571
|
+
);
|
|
1572
|
+
if (refractedDirection) {
|
|
1573
|
+
nextDirection = refractedDirection;
|
|
1574
|
+
attenuation = transmissionStrength > 1e-3 ? transmission : [1, 1, 1];
|
|
1575
|
+
} else {
|
|
1576
|
+
totalInternalReflection = true;
|
|
1577
|
+
eventKind = "reflection";
|
|
1578
|
+
nextDirection = reflectDirection(incomingDirection, orientedNormal);
|
|
1579
|
+
attenuation = mixVec3([0.04, 0.04, 0.04], albedo, metalness);
|
|
1580
|
+
}
|
|
1581
|
+
} else if (eventKind === "transparency") {
|
|
1582
|
+
nextDirection = incomingDirection;
|
|
1583
|
+
const transparencyWeight = Math.max(1 - opacity, transmissionStrength, 0.05);
|
|
1584
|
+
attenuation = transmissionStrength > 1e-3 ? transmission : [transparencyWeight, transparencyWeight, transparencyWeight];
|
|
1585
|
+
} else {
|
|
1586
|
+
nextDirection = normalizeDirection(
|
|
1587
|
+
addVec3(orientedNormal, albedo.map((component) => component - 0.5)),
|
|
1588
|
+
orientedNormal
|
|
1589
|
+
);
|
|
1590
|
+
attenuation = scaleVec3(albedo, Math.max(0.05, 1 - metalness));
|
|
1591
|
+
}
|
|
1592
|
+
const nextThroughput = multiplyVec3(throughput, saturateVec3(attenuation));
|
|
1593
|
+
const continueTracing = eventKind !== "terminate" && colorLuminance(nextThroughput) > 1e-4;
|
|
1594
|
+
const mediumState = evaluateWavefrontMediumState({
|
|
1595
|
+
currentMediumRefId: options.currentMediumRefId ?? options.mediumRefId,
|
|
1596
|
+
surfaceMediumRefId: options.surfaceMediumRefId,
|
|
1597
|
+
mediumStack: options.mediumStack,
|
|
1598
|
+
frontFace,
|
|
1599
|
+
eventKind
|
|
1600
|
+
});
|
|
1601
|
+
return Object.freeze({
|
|
1602
|
+
hitType,
|
|
1603
|
+
requestedEventKind,
|
|
1604
|
+
eventKind,
|
|
1605
|
+
continueTracing,
|
|
1606
|
+
totalInternalReflection,
|
|
1607
|
+
nextDirection: Object.freeze(nextDirection),
|
|
1608
|
+
attenuation: Object.freeze(saturateVec3(attenuation)),
|
|
1609
|
+
nextThroughput: Object.freeze(nextThroughput),
|
|
1610
|
+
mediumState,
|
|
1611
|
+
explicitLightSamplingEnabled: Boolean(options.explicitLightSampling)
|
|
1612
|
+
});
|
|
1613
|
+
}
|
|
1614
|
+
function evaluateWavefrontVisibilityProbe(options = {}) {
|
|
1615
|
+
const probeMode = normalizeWavefrontVisibilityProbeMode(
|
|
1616
|
+
options.probeMode ?? (options.explicitLightSampling ? "mis-balanced" : "disabled")
|
|
1617
|
+
);
|
|
1618
|
+
const probeRay = createWavefrontVisibilityProbeRay({
|
|
1619
|
+
...options.probeRay,
|
|
1620
|
+
throughput: options.throughput ?? options.probeRay?.throughput,
|
|
1621
|
+
direction: options.direction ?? options.probeRay?.direction,
|
|
1622
|
+
mediumRefId: options.currentMediumRefId ?? options.probeRay?.mediumRefId,
|
|
1623
|
+
mediumStack: options.mediumStack ?? options.probeRay?.mediumStack
|
|
1624
|
+
});
|
|
1625
|
+
const transparentSegments = Array.isArray(options.transparentSegments) ? options.transparentSegments : [];
|
|
1626
|
+
const transmittance = transparentSegments.reduce(
|
|
1627
|
+
(current, segment) => multiplyVec3(current, saturateVec3(normalizeVec3(segment, [1, 1, 1]))),
|
|
1628
|
+
[1, 1, 1]
|
|
1629
|
+
);
|
|
1630
|
+
const emissiveRadiance = saturateVec3(
|
|
1631
|
+
normalizeVec3(options.emissiveRadiance, [0, 0, 0])
|
|
1632
|
+
);
|
|
1633
|
+
const environmentRadiance = saturateVec3(
|
|
1634
|
+
normalizeVec3(options.environmentRadiance, [0, 0, 0])
|
|
1635
|
+
);
|
|
1636
|
+
const activeEmissiveRadiance = saturateVec3(
|
|
1637
|
+
normalizeVec3(options.activeEmissiveRadiance, [0, 0, 0])
|
|
1638
|
+
);
|
|
1639
|
+
const prefersEnvironment = Boolean(options.prefersEnvironment);
|
|
1640
|
+
const sourceRadiance = prefersEnvironment || colorLuminance(emissiveRadiance) <= 1e-6 ? environmentRadiance : emissiveRadiance;
|
|
1641
|
+
const rawContribution = multiplyVec3(
|
|
1642
|
+
probeRay.throughput,
|
|
1643
|
+
multiplyVec3(sourceRadiance, transmittance)
|
|
1644
|
+
);
|
|
1645
|
+
const activeEmissiveVisible = colorLuminance(activeEmissiveRadiance) > 1e-6;
|
|
1646
|
+
const misWeight = probeMode === "mis-balanced" && activeEmissiveVisible ? 0.5 : 1;
|
|
1647
|
+
const contribution = probeMode === "exclusive-emissive" && activeEmissiveVisible ? [0, 0, 0] : scaleVec3(rawContribution, misWeight);
|
|
1648
|
+
return Object.freeze({
|
|
1649
|
+
probeMode,
|
|
1650
|
+
probeRay,
|
|
1651
|
+
transmittance: Object.freeze(transmittance),
|
|
1652
|
+
misWeight,
|
|
1653
|
+
doubleCountPrevented: activeEmissiveVisible && probeMode !== "disabled",
|
|
1654
|
+
contribution: Object.freeze(contribution)
|
|
1655
|
+
});
|
|
1656
|
+
}
|
|
1657
|
+
function evaluateWavefrontMaterialReference(options = {}) {
|
|
1658
|
+
const material = Object.freeze({
|
|
1659
|
+
albedo: Object.freeze(
|
|
1660
|
+
saturateVec3(normalizeVec3(options.albedo, [0.8, 0.8, 0.8]))
|
|
1661
|
+
),
|
|
1662
|
+
emission: Object.freeze(
|
|
1663
|
+
saturateVec3(normalizeVec3(options.emission, [0, 0, 0]))
|
|
1664
|
+
),
|
|
1665
|
+
roughness: clampUnit(options.roughness, 0.5),
|
|
1666
|
+
metalness: clampUnit(options.metalness, 0),
|
|
1667
|
+
opacity: clampUnit(options.opacity, 1),
|
|
1668
|
+
transmission: Object.freeze(
|
|
1669
|
+
saturateVec3(normalizeVec3(options.transmission, [0, 0, 0]))
|
|
1670
|
+
),
|
|
1671
|
+
refractiveIndex: Math.max(
|
|
1672
|
+
1,
|
|
1673
|
+
readFinite(options.refractiveIndex ?? options.ior, 1.45)
|
|
1674
|
+
)
|
|
1675
|
+
});
|
|
1676
|
+
const continuation = evaluateWavefrontContinuationEvent({
|
|
1677
|
+
...options,
|
|
1678
|
+
albedo: material.albedo,
|
|
1679
|
+
roughness: material.roughness,
|
|
1680
|
+
metalness: material.metalness,
|
|
1681
|
+
opacity: material.opacity,
|
|
1682
|
+
transmission: material.transmission,
|
|
1683
|
+
refractiveIndex: material.refractiveIndex
|
|
1684
|
+
});
|
|
1685
|
+
const terminal = evaluateWavefrontTerminalRadiance({
|
|
1686
|
+
...options,
|
|
1687
|
+
emission: material.emission
|
|
1688
|
+
});
|
|
1689
|
+
return Object.freeze({
|
|
1690
|
+
material,
|
|
1691
|
+
terminal,
|
|
1692
|
+
continuation,
|
|
1693
|
+
throughputUpdate: continuation.nextThroughput
|
|
1694
|
+
});
|
|
1695
|
+
}
|
|
1696
|
+
function createWavefrontReferenceFixture(options = {}) {
|
|
1697
|
+
const tolerance = Math.max(1e-4, readFinite(options.tolerance, 5e-4));
|
|
1698
|
+
const ray = createWavefrontRayPayload({
|
|
1699
|
+
rayId: options.rayId,
|
|
1700
|
+
parentRayId: options.parentRayId,
|
|
1701
|
+
sourcePixelId: options.sourcePixelId,
|
|
1702
|
+
sampleId: options.sampleId,
|
|
1703
|
+
bounce: options.bounceIndex ?? options.bounce,
|
|
1704
|
+
origin: options.origin,
|
|
1705
|
+
direction: options.direction ?? scaleVec3(options.viewDirection ?? [0, 0, 1], -1),
|
|
1706
|
+
throughput: options.throughput,
|
|
1707
|
+
mediumRefId: options.currentMediumRefId ?? options.mediumRefId,
|
|
1708
|
+
mediumStack: options.mediumStack
|
|
1709
|
+
});
|
|
1710
|
+
const reference = evaluateWavefrontMaterialReference(options);
|
|
1711
|
+
const visibilityProbe = options.visibilityProbe === void 0 ? null : evaluateWavefrontVisibilityProbe({
|
|
1712
|
+
...options.visibilityProbe,
|
|
1713
|
+
throughput: options.visibilityProbe.throughput ?? ray.throughput
|
|
1714
|
+
});
|
|
1715
|
+
const accumulationRadiance = addVec3(
|
|
1716
|
+
reference.terminal.radiance,
|
|
1717
|
+
visibilityProbe?.contribution ?? [0, 0, 0]
|
|
1718
|
+
);
|
|
1719
|
+
return Object.freeze({
|
|
1720
|
+
tolerance,
|
|
1721
|
+
ray,
|
|
1722
|
+
material: reference.material,
|
|
1723
|
+
continuation: reference.continuation,
|
|
1724
|
+
terminal: reference.terminal,
|
|
1725
|
+
visibilityProbe,
|
|
1726
|
+
accumulation: Object.freeze({
|
|
1727
|
+
sourcePixelId: ray.sourcePixelId,
|
|
1728
|
+
sampleCount: reference.terminal.terminated ? 1 : 0,
|
|
1729
|
+
radiance: Object.freeze(accumulationRadiance),
|
|
1730
|
+
throughput: reference.continuation.nextThroughput,
|
|
1731
|
+
resetEpoch: Math.max(
|
|
1732
|
+
0,
|
|
1733
|
+
Math.trunc(readFinite(options.accumulationResetEpoch, 0))
|
|
1734
|
+
)
|
|
1735
|
+
})
|
|
1736
|
+
});
|
|
1737
|
+
}
|
|
1052
1738
|
var lightingImportanceLevels = Object.freeze([
|
|
1053
1739
|
"low",
|
|
1054
1740
|
"medium",
|
|
@@ -1614,6 +2300,91 @@ var lightingWorkerSpecPresets = {
|
|
|
1614
2300
|
}
|
|
1615
2301
|
}
|
|
1616
2302
|
},
|
|
2303
|
+
wavefront: {
|
|
2304
|
+
suggestedAllocationIds: [
|
|
2305
|
+
"lighting.wavefront.active-queue",
|
|
2306
|
+
"lighting.wavefront.next-queue",
|
|
2307
|
+
"lighting.wavefront.accumulation"
|
|
2308
|
+
],
|
|
2309
|
+
jobs: {
|
|
2310
|
+
accumulateTerminalRadiance: {
|
|
2311
|
+
domain: "lighting",
|
|
2312
|
+
importance: "critical",
|
|
2313
|
+
levels: buildWorkerBudgetLevels(
|
|
2314
|
+
"lighting.wavefront.accumulateTerminalRadiance",
|
|
2315
|
+
lightingWorkerQueueClass,
|
|
2316
|
+
{
|
|
2317
|
+
low: {
|
|
2318
|
+
estimatedCostMs: 0.7,
|
|
2319
|
+
maxDispatchesPerFrame: 1,
|
|
2320
|
+
maxJobsPerDispatch: 32,
|
|
2321
|
+
cadenceDivisor: 2,
|
|
2322
|
+
workgroupScale: 0.5,
|
|
2323
|
+
maxQueueDepth: 96
|
|
2324
|
+
},
|
|
2325
|
+
medium: {
|
|
2326
|
+
estimatedCostMs: 1.2,
|
|
2327
|
+
maxDispatchesPerFrame: 1,
|
|
2328
|
+
maxJobsPerDispatch: 64,
|
|
2329
|
+
cadenceDivisor: 1,
|
|
2330
|
+
workgroupScale: 0.75,
|
|
2331
|
+
maxQueueDepth: 192
|
|
2332
|
+
},
|
|
2333
|
+
high: {
|
|
2334
|
+
estimatedCostMs: 1.8,
|
|
2335
|
+
maxDispatchesPerFrame: 2,
|
|
2336
|
+
maxJobsPerDispatch: 128,
|
|
2337
|
+
cadenceDivisor: 1,
|
|
2338
|
+
workgroupScale: 1,
|
|
2339
|
+
maxQueueDepth: 256
|
|
2340
|
+
}
|
|
2341
|
+
}
|
|
2342
|
+
),
|
|
2343
|
+
suggestedAllocationIds: [
|
|
2344
|
+
"lighting.wavefront.accumulation",
|
|
2345
|
+
"lighting.wavefront.active-queue"
|
|
2346
|
+
]
|
|
2347
|
+
},
|
|
2348
|
+
scatterContinuations: {
|
|
2349
|
+
domain: "lighting",
|
|
2350
|
+
importance: "critical",
|
|
2351
|
+
levels: buildWorkerBudgetLevels(
|
|
2352
|
+
"lighting.wavefront.scatterContinuations",
|
|
2353
|
+
lightingWorkerQueueClass,
|
|
2354
|
+
{
|
|
2355
|
+
low: {
|
|
2356
|
+
estimatedCostMs: 0.8,
|
|
2357
|
+
maxDispatchesPerFrame: 1,
|
|
2358
|
+
maxJobsPerDispatch: 32,
|
|
2359
|
+
cadenceDivisor: 2,
|
|
2360
|
+
workgroupScale: 0.5,
|
|
2361
|
+
maxQueueDepth: 96
|
|
2362
|
+
},
|
|
2363
|
+
medium: {
|
|
2364
|
+
estimatedCostMs: 1.4,
|
|
2365
|
+
maxDispatchesPerFrame: 1,
|
|
2366
|
+
maxJobsPerDispatch: 64,
|
|
2367
|
+
cadenceDivisor: 1,
|
|
2368
|
+
workgroupScale: 0.75,
|
|
2369
|
+
maxQueueDepth: 192
|
|
2370
|
+
},
|
|
2371
|
+
high: {
|
|
2372
|
+
estimatedCostMs: 2.1,
|
|
2373
|
+
maxDispatchesPerFrame: 2,
|
|
2374
|
+
maxJobsPerDispatch: 128,
|
|
2375
|
+
cadenceDivisor: 1,
|
|
2376
|
+
workgroupScale: 1,
|
|
2377
|
+
maxQueueDepth: 256
|
|
2378
|
+
}
|
|
2379
|
+
}
|
|
2380
|
+
),
|
|
2381
|
+
suggestedAllocationIds: [
|
|
2382
|
+
"lighting.wavefront.active-queue",
|
|
2383
|
+
"lighting.wavefront.next-queue"
|
|
2384
|
+
]
|
|
2385
|
+
}
|
|
2386
|
+
}
|
|
2387
|
+
},
|
|
1617
2388
|
volumetrics: {
|
|
1618
2389
|
suggestedAllocationIds: [
|
|
1619
2390
|
"lighting.volumetrics.froxel-grid",
|
|
@@ -1823,6 +2594,13 @@ var lightingWorkerDagSpecs = {
|
|
|
1823
2594
|
accumulate: { priority: 3, dependencies: ["pathTrace"] },
|
|
1824
2595
|
denoise: { priority: 2, dependencies: ["accumulate"] }
|
|
1825
2596
|
},
|
|
2597
|
+
wavefront: {
|
|
2598
|
+
accumulateTerminalRadiance: { priority: 3, dependencies: [] },
|
|
2599
|
+
scatterContinuations: {
|
|
2600
|
+
priority: 2,
|
|
2601
|
+
dependencies: ["accumulateTerminalRadiance"]
|
|
2602
|
+
}
|
|
2603
|
+
},
|
|
1826
2604
|
volumetrics: {
|
|
1827
2605
|
volumetricShadow: { priority: 3, dependencies: [] },
|
|
1828
2606
|
froxelIntegrate: { priority: 2, dependencies: ["volumetricShadow"] }
|
|
@@ -1856,6 +2634,16 @@ function resolveLightingQualityDimensions(techniqueName, jobKey) {
|
|
|
1856
2634
|
"pathtracer.pathTrace": { rayTracing: 1, lightingSamples: 1 },
|
|
1857
2635
|
"pathtracer.accumulate": { temporalReuse: 1, updateCadence: 0.4 },
|
|
1858
2636
|
"pathtracer.denoise": { temporalReuse: 1, shading: 0.4 },
|
|
2637
|
+
"wavefront.accumulateTerminalRadiance": {
|
|
2638
|
+
rayTracing: 1,
|
|
2639
|
+
lightingSamples: 1,
|
|
2640
|
+
temporalReuse: 0.4
|
|
2641
|
+
},
|
|
2642
|
+
"wavefront.scatterContinuations": {
|
|
2643
|
+
rayTracing: 1,
|
|
2644
|
+
shading: 0.7,
|
|
2645
|
+
updateCadence: 0.5
|
|
2646
|
+
},
|
|
1859
2647
|
"volumetrics.froxelIntegrate": {
|
|
1860
2648
|
lightingSamples: 0.6,
|
|
1861
2649
|
shading: 0.4,
|
|
@@ -1900,6 +2688,15 @@ function resolveLightingImportanceSignals(techniqueName, jobKey) {
|
|
|
1900
2688
|
},
|
|
1901
2689
|
"pathtracer.accumulate": { visible: true },
|
|
1902
2690
|
"pathtracer.denoise": { visible: true },
|
|
2691
|
+
"wavefront.accumulateTerminalRadiance": {
|
|
2692
|
+
visible: true,
|
|
2693
|
+
shadowSignificance: "high",
|
|
2694
|
+
reflectionSignificance: "high"
|
|
2695
|
+
},
|
|
2696
|
+
"wavefront.scatterContinuations": {
|
|
2697
|
+
visible: true,
|
|
2698
|
+
reflectionSignificance: "high"
|
|
2699
|
+
},
|
|
1903
2700
|
"volumetrics.froxelIntegrate": { visible: true },
|
|
1904
2701
|
"volumetrics.volumetricShadow": { visible: true, shadowSignificance: "high" },
|
|
1905
2702
|
"hdri.irradianceConvolution": { visible: false },
|
|
@@ -2169,9 +2966,18 @@ export {
|
|
|
2169
2966
|
createLightingBandPlan,
|
|
2170
2967
|
createLightingProfileModeLadder,
|
|
2171
2968
|
createWavefrontEnvironmentLightingOptions,
|
|
2969
|
+
createWavefrontLightingPlan,
|
|
2970
|
+
createWavefrontRayPayload,
|
|
2971
|
+
createWavefrontReferenceFixture,
|
|
2972
|
+
createWavefrontVisibilityProbeRay,
|
|
2172
2973
|
defaultAdaptiveLightingProfilePolicy,
|
|
2173
2974
|
defaultLightingProfile,
|
|
2174
2975
|
defaultLightingTechnique,
|
|
2976
|
+
evaluateWavefrontContinuationEvent,
|
|
2977
|
+
evaluateWavefrontMaterialReference,
|
|
2978
|
+
evaluateWavefrontMediumState,
|
|
2979
|
+
evaluateWavefrontTerminalRadiance,
|
|
2980
|
+
evaluateWavefrontVisibilityProbe,
|
|
2175
2981
|
getLightingProfile,
|
|
2176
2982
|
getLightingProfileWorkerManifest,
|
|
2177
2983
|
getLightingTechnique,
|
|
@@ -2190,8 +2996,19 @@ export {
|
|
|
2190
2996
|
lightingProfileModeOrder,
|
|
2191
2997
|
lightingProfileNames,
|
|
2192
2998
|
lightingProfiles,
|
|
2999
|
+
lightingRequiredRendererWavefrontPassOrder,
|
|
2193
3000
|
lightingTechniqueNames,
|
|
2194
3001
|
lightingTechniques,
|
|
3002
|
+
lightingWavefrontBufferContracts,
|
|
3003
|
+
lightingWavefrontContinuationHitTypes,
|
|
3004
|
+
lightingWavefrontHitTypes,
|
|
3005
|
+
lightingWavefrontPassOrder,
|
|
3006
|
+
lightingWavefrontQueuePairStrategy,
|
|
3007
|
+
lightingWavefrontRayKinds,
|
|
3008
|
+
lightingWavefrontSchemaVersion,
|
|
3009
|
+
lightingWavefrontTerminalHitTypes,
|
|
3010
|
+
lightingWavefrontTerminationPolicy,
|
|
3011
|
+
lightingWavefrontVisibilityProbeModes,
|
|
2195
3012
|
lightingWorkerManifests,
|
|
2196
3013
|
lightingWorkerQueueClass,
|
|
2197
3014
|
loadLightingJobs,
|