@plasius/gpu-lighting 0.2.5 → 0.2.6

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/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,374 @@ 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 lightingWavefrontTerminalHitTypes = Object.freeze([
1070
+ "emissive",
1071
+ "environment",
1072
+ "miss"
1073
+ ]);
1074
+ var lightingWavefrontContinuationHitTypes = Object.freeze([
1075
+ "surface",
1076
+ "transparent"
1077
+ ]);
1078
+ var lightingWavefrontPassOrder = Object.freeze([
1079
+ "accumulateTerminalRadiance",
1080
+ "scatterContinuations"
1081
+ ]);
1082
+ var lightingRequiredRendererWavefrontPassOrder = Object.freeze([
1083
+ "generatePrimaryRays",
1084
+ "intersectActiveQueue",
1085
+ "resolveSurfaceRecords",
1086
+ "accumulateTerminalRadiance",
1087
+ "scatterContinuations",
1088
+ "compactAndSwapQueues"
1089
+ ]);
1090
+ function createLightingWavefrontField(name, type, description) {
1091
+ return Object.freeze({
1092
+ name,
1093
+ type,
1094
+ description
1095
+ });
1096
+ }
1097
+ function createLightingWavefrontRecordContract(recordName, fields) {
1098
+ return Object.freeze({
1099
+ schemaVersion: lightingWavefrontSchemaVersion,
1100
+ recordName,
1101
+ fields: Object.freeze(fields)
1102
+ });
1103
+ }
1104
+ var lightingWavefrontBufferContracts = Object.freeze({
1105
+ ray: createLightingWavefrontRecordContract(
1106
+ "RayRecord",
1107
+ [
1108
+ createLightingWavefrontField("rayId", "u32", "Stable ray identifier."),
1109
+ createLightingWavefrontField("parentRayId", "u32", "Parent ray identifier."),
1110
+ createLightingWavefrontField("sourcePixelId", "u32", "Source pixel/sample owner."),
1111
+ createLightingWavefrontField("sampleId", "u32", "Per-pixel sample slot."),
1112
+ createLightingWavefrontField("bounce", "u32", "Current bounce depth."),
1113
+ createLightingWavefrontField("origin", "vec3<f32>", "Ray origin."),
1114
+ createLightingWavefrontField("direction", "vec3<f32>", "Normalized ray direction."),
1115
+ createLightingWavefrontField("throughput", "vec3<f32>", "Accumulated path throughput."),
1116
+ createLightingWavefrontField("mediumRefId", "u32", "Current medium reference."),
1117
+ createLightingWavefrontField("flags", "u32", "Renderer-owned ray flags.")
1118
+ ]
1119
+ ),
1120
+ hit: createLightingWavefrontRecordContract(
1121
+ "HitRecord",
1122
+ [
1123
+ createLightingWavefrontField("rayId", "u32", "Stable ray identifier."),
1124
+ createLightingWavefrontField("sourcePixelId", "u32", "Source pixel/sample owner."),
1125
+ createLightingWavefrontField("hitType", "u32", "Surface, emissive, environment, transparent, or miss."),
1126
+ createLightingWavefrontField("distance", "f32", "Nearest-hit distance."),
1127
+ createLightingWavefrontField("entityId", "u32", "Owning entity identifier."),
1128
+ createLightingWavefrontField("instanceId", "u32", "Owning instance identifier."),
1129
+ createLightingWavefrontField("primitiveId", "u32", "Primitive identifier."),
1130
+ createLightingWavefrontField("materialId", "u32", "Resolved material identifier."),
1131
+ createLightingWavefrontField("barycentrics", "vec3<f32>", "Triangle barycentrics."),
1132
+ createLightingWavefrontField("uv", "vec2<f32>", "Resolved UV coordinates."),
1133
+ createLightingWavefrontField("geometricNormal", "vec3<f32>", "Geometric surface normal."),
1134
+ createLightingWavefrontField("shadingNormal", "vec3<f32>", "Interpolated shading normal."),
1135
+ createLightingWavefrontField("frontFace", "u32", "Front-face classification.")
1136
+ ]
1137
+ ),
1138
+ surface: createLightingWavefrontRecordContract(
1139
+ "SurfaceRecord",
1140
+ [
1141
+ createLightingWavefrontField("rayId", "u32", "Stable ray identifier."),
1142
+ createLightingWavefrontField("entityId", "u32", "Owning entity identifier."),
1143
+ createLightingWavefrontField("materialRefId", "u32", "Renderer material reference id."),
1144
+ createLightingWavefrontField("mediumRefId", "u32", "Renderer medium reference id."),
1145
+ createLightingWavefrontField("geometricNormal", "vec3<f32>", "Geometric surface normal."),
1146
+ createLightingWavefrontField("shadingNormal", "vec3<f32>", "Interpolated shading normal."),
1147
+ createLightingWavefrontField("uv", "vec2<f32>", "Resolved UV coordinates."),
1148
+ createLightingWavefrontField("tangentFrame", "mat3x3<f32>", "Resolved tangent frame.")
1149
+ ]
1150
+ ),
1151
+ materialReference: createLightingWavefrontRecordContract(
1152
+ "MaterialReferenceRecord",
1153
+ [
1154
+ createLightingWavefrontField("materialRefId", "u32", "Lighting-visible material reference id."),
1155
+ createLightingWavefrontField("materialId", "u32", "Source material identifier."),
1156
+ createLightingWavefrontField("shadingModel", "u32", "Renderer shading-model discriminator."),
1157
+ createLightingWavefrontField("textureSetId", "u32", "Resolved texture-set identifier."),
1158
+ createLightingWavefrontField("flags", "u32", "Renderer material flags.")
1159
+ ]
1160
+ ),
1161
+ mediumReference: createLightingWavefrontRecordContract(
1162
+ "MediumReferenceRecord",
1163
+ [
1164
+ createLightingWavefrontField("mediumRefId", "u32", "Lighting-visible medium reference id."),
1165
+ createLightingWavefrontField("mediumId", "u32", "Source medium identifier."),
1166
+ createLightingWavefrontField("phaseModel", "u32", "Phase-function discriminator."),
1167
+ createLightingWavefrontField("absorption", "vec3<f32>", "Medium absorption coefficients."),
1168
+ createLightingWavefrontField("scattering", "vec3<f32>", "Medium scattering coefficients.")
1169
+ ]
1170
+ ),
1171
+ accumulation: createLightingWavefrontRecordContract(
1172
+ "AccumulationRecord",
1173
+ [
1174
+ createLightingWavefrontField("sourcePixelId", "u32", "Source pixel/sample owner."),
1175
+ createLightingWavefrontField("sampleCount", "u32", "Accumulated sample count."),
1176
+ createLightingWavefrontField("radiance", "vec3<f32>", "Accumulated radiance."),
1177
+ createLightingWavefrontField("throughput", "vec3<f32>", "Last surviving throughput."),
1178
+ createLightingWavefrontField("resetEpoch", "u32", "Renderer accumulation reset epoch.")
1179
+ ]
1180
+ )
1181
+ });
1182
+ var lightingWavefrontTerminationPolicy = Object.freeze({
1183
+ terminalHitTypes: lightingWavefrontTerminalHitTypes,
1184
+ continuationHitTypes: lightingWavefrontContinuationHitTypes,
1185
+ emissive: Object.freeze({
1186
+ action: "accumulate-and-stop",
1187
+ contributesRadiance: true
1188
+ }),
1189
+ environment: Object.freeze({
1190
+ action: "accumulate-and-stop",
1191
+ contributesRadiance: true
1192
+ }),
1193
+ miss: Object.freeze({
1194
+ action: "accumulate-environment-or-dark-stop",
1195
+ contributesRadiance: true
1196
+ })
1197
+ });
1198
+ var defaultWavefrontDarkRadiance = Object.freeze([1e-4, 1e-4, 1e-4]);
1199
+ var wavefrontEventKinds = Object.freeze([
1200
+ "diffuse",
1201
+ "reflection",
1202
+ "refraction",
1203
+ "transparency",
1204
+ "terminate"
1205
+ ]);
1206
+ function normalizeWavefrontHitType(value) {
1207
+ return lightingWavefrontHitTypes.includes(value) ? value : "surface";
1208
+ }
1209
+ function normalizeWavefrontEventKind(value) {
1210
+ return wavefrontEventKinds.includes(value) ? value : null;
1211
+ }
1212
+ function normalizeVec3(value, fallback = [0, 0, 0]) {
1213
+ if (!Array.isArray(value) || value.length < 3) {
1214
+ return [...fallback];
1215
+ }
1216
+ return [
1217
+ Number.isFinite(value[0]) ? value[0] : fallback[0],
1218
+ Number.isFinite(value[1]) ? value[1] : fallback[1],
1219
+ Number.isFinite(value[2]) ? value[2] : fallback[2]
1220
+ ];
1221
+ }
1222
+ function clampUnit(value, fallback = 0) {
1223
+ return Math.max(0, Math.min(1, readFinite(value, fallback)));
1224
+ }
1225
+ function saturateVec3(value) {
1226
+ return value.map((component) => Math.max(0, component));
1227
+ }
1228
+ function scaleVec3(value, scalar) {
1229
+ return value.map((component) => component * scalar);
1230
+ }
1231
+ function addVec3(left, right) {
1232
+ return left.map((component, index) => component + right[index]);
1233
+ }
1234
+ function multiplyVec3(left, right) {
1235
+ return left.map((component, index) => component * right[index]);
1236
+ }
1237
+ function dotVec3(left, right) {
1238
+ return left[0] * right[0] + left[1] * right[1] + left[2] * right[2];
1239
+ }
1240
+ function lengthVec3(value) {
1241
+ return Math.hypot(value[0], value[1], value[2]);
1242
+ }
1243
+ function normalizeDirection(value, fallback = [0, 1, 0]) {
1244
+ const vector = normalizeVec3(value, fallback);
1245
+ const length = lengthVec3(vector);
1246
+ if (!Number.isFinite(length) || length <= 1e-6) {
1247
+ return [...fallback];
1248
+ }
1249
+ return vector.map((component) => component / length);
1250
+ }
1251
+ function mixVec3(left, right, factor) {
1252
+ return left.map(
1253
+ (component, index) => component * (1 - factor) + right[index] * factor
1254
+ );
1255
+ }
1256
+ function reflectDirection(direction, normal) {
1257
+ const scale = 2 * dotVec3(direction, normal);
1258
+ return normalizeDirection(
1259
+ [
1260
+ direction[0] - scale * normal[0],
1261
+ direction[1] - scale * normal[1],
1262
+ direction[2] - scale * normal[2]
1263
+ ],
1264
+ normal
1265
+ );
1266
+ }
1267
+ function refractDirection(direction, normal, etaRatio) {
1268
+ const cosTheta = Math.min(-dotVec3(direction, normal), 1);
1269
+ const rOutPerp = scaleVec3(addVec3(direction, scaleVec3(normal, cosTheta)), etaRatio);
1270
+ const rOutPerpLengthSquared = dotVec3(rOutPerp, rOutPerp);
1271
+ const parallelFactor = 1 - rOutPerpLengthSquared;
1272
+ if (parallelFactor <= 0) {
1273
+ return null;
1274
+ }
1275
+ const rOutParallel = scaleVec3(normal, -Math.sqrt(parallelFactor));
1276
+ return normalizeDirection(addVec3(rOutPerp, rOutParallel), direction);
1277
+ }
1278
+ function createWavefrontLightingPlan(options = {}) {
1279
+ const maxDepth = Math.max(1, Math.trunc(readFinite(options.maxDepth, 4)));
1280
+ const queueCapacity = Math.max(
1281
+ 1,
1282
+ Math.trunc(readFinite(options.queueCapacity, 4096))
1283
+ );
1284
+ const explicitLightSampling = Boolean(options.explicitLightSampling);
1285
+ const accumulationResetEpoch = Math.max(
1286
+ 0,
1287
+ Math.trunc(readFinite(options.accumulationResetEpoch, 0))
1288
+ );
1289
+ return Object.freeze({
1290
+ schemaVersion: lightingWavefrontSchemaVersion,
1291
+ maxDepth,
1292
+ queueCapacity,
1293
+ explicitLightSampling,
1294
+ accumulationResetEpoch,
1295
+ queueLayout: Object.freeze({
1296
+ strategy: lightingWavefrontQueuePairStrategy,
1297
+ compactAfterScatter: true,
1298
+ queues: Object.freeze([
1299
+ Object.freeze({ name: "active", role: "current-bounce" }),
1300
+ Object.freeze({ name: "next", role: "next-bounce" })
1301
+ ])
1302
+ }),
1303
+ bufferContracts: lightingWavefrontBufferContracts,
1304
+ terminationPolicy: lightingWavefrontTerminationPolicy,
1305
+ requiredRendererPassOrder: lightingRequiredRendererWavefrontPassOrder,
1306
+ lightingPasses: Object.freeze([
1307
+ Object.freeze({
1308
+ key: "accumulateTerminalRadiance",
1309
+ stage: "accumulateTerminalRadiance",
1310
+ reads: Object.freeze([
1311
+ "ray",
1312
+ "hit",
1313
+ "surface",
1314
+ "materialReference",
1315
+ "mediumReference"
1316
+ ]),
1317
+ writes: Object.freeze(["accumulation"]),
1318
+ terminalHitTypes: lightingWavefrontTerminalHitTypes
1319
+ }),
1320
+ Object.freeze({
1321
+ key: "scatterContinuations",
1322
+ stage: "scatterContinuations",
1323
+ reads: Object.freeze([
1324
+ "ray",
1325
+ "hit",
1326
+ "surface",
1327
+ "materialReference",
1328
+ "mediumReference"
1329
+ ]),
1330
+ writes: Object.freeze(["ray"]),
1331
+ continuationHitTypes: lightingWavefrontContinuationHitTypes,
1332
+ explicitLightSampling
1333
+ })
1334
+ ])
1335
+ });
1336
+ }
1337
+ function evaluateWavefrontTerminalRadiance(options = {}) {
1338
+ const hitType = normalizeWavefrontHitType(options.hitType);
1339
+ const throughput = saturateVec3(normalizeVec3(options.throughput, [1, 1, 1]));
1340
+ const emission = saturateVec3(normalizeVec3(options.emission, [0, 0, 0]));
1341
+ const environmentRadiance = saturateVec3(
1342
+ normalizeVec3(options.environmentRadiance, [0, 0, 0])
1343
+ );
1344
+ const missRadiance = saturateVec3(
1345
+ normalizeVec3(options.missRadiance, defaultWavefrontDarkRadiance)
1346
+ );
1347
+ const environmentLuminance = colorLuminance(environmentRadiance);
1348
+ let source = "none";
1349
+ let rawRadiance = [0, 0, 0];
1350
+ if (hitType === "emissive") {
1351
+ source = "emissive";
1352
+ rawRadiance = emission;
1353
+ } else if (hitType === "environment") {
1354
+ source = "environment";
1355
+ rawRadiance = environmentRadiance;
1356
+ } else if (hitType === "miss") {
1357
+ source = environmentLuminance > 1e-6 ? "environment" : "dark";
1358
+ rawRadiance = environmentLuminance > 1e-6 ? environmentRadiance : missRadiance;
1359
+ }
1360
+ const radiance = multiplyVec3(throughput, rawRadiance);
1361
+ const terminated = lightingWavefrontTerminalHitTypes.includes(hitType);
1362
+ return Object.freeze({
1363
+ hitType,
1364
+ source,
1365
+ terminated,
1366
+ radiance: Object.freeze(radiance),
1367
+ nearDarkSample: source === "dark" && colorLuminance(radiance) <= colorLuminance(defaultWavefrontDarkRadiance)
1368
+ });
1369
+ }
1370
+ function evaluateWavefrontContinuationEvent(options = {}) {
1371
+ const hitType = normalizeWavefrontHitType(options.hitType);
1372
+ const bounceIndex = Math.max(0, Math.trunc(readFinite(options.bounceIndex, 0)));
1373
+ const maxDepth = Math.max(1, Math.trunc(readFinite(options.maxDepth, 4)));
1374
+ const throughput = saturateVec3(normalizeVec3(options.throughput, [1, 1, 1]));
1375
+ const albedo = saturateVec3(normalizeVec3(options.albedo, [0.8, 0.8, 0.8]));
1376
+ const transmission = saturateVec3(
1377
+ normalizeVec3(options.transmission, [0, 0, 0])
1378
+ );
1379
+ const shadingNormal = normalizeDirection(options.shadingNormal, [0, 1, 0]);
1380
+ const viewDirection = normalizeDirection(options.viewDirection, [0, 0, 1]);
1381
+ const incomingDirection = normalizeDirection(
1382
+ scaleVec3(viewDirection, -1),
1383
+ [0, 0, -1]
1384
+ );
1385
+ const frontFace = options.frontFace !== false;
1386
+ const orientedNormal = frontFace ? shadingNormal : scaleVec3(shadingNormal, -1);
1387
+ const metalness = clampUnit(options.metalness, 0);
1388
+ const roughness = clampUnit(options.roughness, 0.5);
1389
+ const opacity = clampUnit(options.opacity, 1);
1390
+ const refractiveIndex = Math.max(1, readFinite(options.refractiveIndex ?? options.ior, 1.45));
1391
+ const transmissionStrength = Math.max(...transmission);
1392
+ let eventKind = normalizeWavefrontEventKind(options.eventKind) ?? (hitType === "transparent" || opacity < 0.999 ? "transparency" : transmissionStrength > 1e-3 ? "refraction" : metalness >= 0.5 || roughness <= 0.2 ? "reflection" : "diffuse");
1393
+ let nextDirection = incomingDirection;
1394
+ let attenuation;
1395
+ if (!lightingWavefrontContinuationHitTypes.includes(hitType) || bounceIndex >= maxDepth - 1) {
1396
+ eventKind = "terminate";
1397
+ attenuation = [0, 0, 0];
1398
+ } else if (eventKind === "reflection") {
1399
+ nextDirection = reflectDirection(incomingDirection, orientedNormal);
1400
+ attenuation = mixVec3([0.04, 0.04, 0.04], albedo, metalness);
1401
+ } else if (eventKind === "refraction") {
1402
+ const etaRatio = frontFace ? 1 / refractiveIndex : refractiveIndex;
1403
+ nextDirection = refractDirection(incomingDirection, orientedNormal, etaRatio) ?? reflectDirection(incomingDirection, orientedNormal);
1404
+ attenuation = transmissionStrength > 1e-3 ? transmission : [1, 1, 1];
1405
+ } else if (eventKind === "transparency") {
1406
+ nextDirection = incomingDirection;
1407
+ const transparencyWeight = Math.max(1 - opacity, transmissionStrength, 0.05);
1408
+ attenuation = transmissionStrength > 1e-3 ? transmission : [transparencyWeight, transparencyWeight, transparencyWeight];
1409
+ } else {
1410
+ nextDirection = normalizeDirection(
1411
+ addVec3(orientedNormal, albedo.map((component) => component - 0.5)),
1412
+ orientedNormal
1413
+ );
1414
+ attenuation = scaleVec3(albedo, Math.max(0.05, 1 - metalness));
1415
+ }
1416
+ const nextThroughput = multiplyVec3(throughput, saturateVec3(attenuation));
1417
+ const continueTracing = eventKind !== "terminate" && colorLuminance(nextThroughput) > 1e-4;
1418
+ return Object.freeze({
1419
+ hitType,
1420
+ eventKind,
1421
+ continueTracing,
1422
+ nextDirection: Object.freeze(nextDirection),
1423
+ attenuation: Object.freeze(saturateVec3(attenuation)),
1424
+ nextThroughput: Object.freeze(nextThroughput),
1425
+ explicitLightSamplingEnabled: Boolean(options.explicitLightSampling)
1426
+ });
1427
+ }
1052
1428
  var lightingImportanceLevels = Object.freeze([
1053
1429
  "low",
1054
1430
  "medium",
@@ -1614,6 +1990,91 @@ var lightingWorkerSpecPresets = {
1614
1990
  }
1615
1991
  }
1616
1992
  },
1993
+ wavefront: {
1994
+ suggestedAllocationIds: [
1995
+ "lighting.wavefront.active-queue",
1996
+ "lighting.wavefront.next-queue",
1997
+ "lighting.wavefront.accumulation"
1998
+ ],
1999
+ jobs: {
2000
+ accumulateTerminalRadiance: {
2001
+ domain: "lighting",
2002
+ importance: "critical",
2003
+ levels: buildWorkerBudgetLevels(
2004
+ "lighting.wavefront.accumulateTerminalRadiance",
2005
+ lightingWorkerQueueClass,
2006
+ {
2007
+ low: {
2008
+ estimatedCostMs: 0.7,
2009
+ maxDispatchesPerFrame: 1,
2010
+ maxJobsPerDispatch: 32,
2011
+ cadenceDivisor: 2,
2012
+ workgroupScale: 0.5,
2013
+ maxQueueDepth: 96
2014
+ },
2015
+ medium: {
2016
+ estimatedCostMs: 1.2,
2017
+ maxDispatchesPerFrame: 1,
2018
+ maxJobsPerDispatch: 64,
2019
+ cadenceDivisor: 1,
2020
+ workgroupScale: 0.75,
2021
+ maxQueueDepth: 192
2022
+ },
2023
+ high: {
2024
+ estimatedCostMs: 1.8,
2025
+ maxDispatchesPerFrame: 2,
2026
+ maxJobsPerDispatch: 128,
2027
+ cadenceDivisor: 1,
2028
+ workgroupScale: 1,
2029
+ maxQueueDepth: 256
2030
+ }
2031
+ }
2032
+ ),
2033
+ suggestedAllocationIds: [
2034
+ "lighting.wavefront.accumulation",
2035
+ "lighting.wavefront.active-queue"
2036
+ ]
2037
+ },
2038
+ scatterContinuations: {
2039
+ domain: "lighting",
2040
+ importance: "critical",
2041
+ levels: buildWorkerBudgetLevels(
2042
+ "lighting.wavefront.scatterContinuations",
2043
+ lightingWorkerQueueClass,
2044
+ {
2045
+ low: {
2046
+ estimatedCostMs: 0.8,
2047
+ maxDispatchesPerFrame: 1,
2048
+ maxJobsPerDispatch: 32,
2049
+ cadenceDivisor: 2,
2050
+ workgroupScale: 0.5,
2051
+ maxQueueDepth: 96
2052
+ },
2053
+ medium: {
2054
+ estimatedCostMs: 1.4,
2055
+ maxDispatchesPerFrame: 1,
2056
+ maxJobsPerDispatch: 64,
2057
+ cadenceDivisor: 1,
2058
+ workgroupScale: 0.75,
2059
+ maxQueueDepth: 192
2060
+ },
2061
+ high: {
2062
+ estimatedCostMs: 2.1,
2063
+ maxDispatchesPerFrame: 2,
2064
+ maxJobsPerDispatch: 128,
2065
+ cadenceDivisor: 1,
2066
+ workgroupScale: 1,
2067
+ maxQueueDepth: 256
2068
+ }
2069
+ }
2070
+ ),
2071
+ suggestedAllocationIds: [
2072
+ "lighting.wavefront.active-queue",
2073
+ "lighting.wavefront.next-queue"
2074
+ ]
2075
+ }
2076
+ }
2077
+ },
1617
2078
  volumetrics: {
1618
2079
  suggestedAllocationIds: [
1619
2080
  "lighting.volumetrics.froxel-grid",
@@ -1823,6 +2284,13 @@ var lightingWorkerDagSpecs = {
1823
2284
  accumulate: { priority: 3, dependencies: ["pathTrace"] },
1824
2285
  denoise: { priority: 2, dependencies: ["accumulate"] }
1825
2286
  },
2287
+ wavefront: {
2288
+ accumulateTerminalRadiance: { priority: 3, dependencies: [] },
2289
+ scatterContinuations: {
2290
+ priority: 2,
2291
+ dependencies: ["accumulateTerminalRadiance"]
2292
+ }
2293
+ },
1826
2294
  volumetrics: {
1827
2295
  volumetricShadow: { priority: 3, dependencies: [] },
1828
2296
  froxelIntegrate: { priority: 2, dependencies: ["volumetricShadow"] }
@@ -1856,6 +2324,16 @@ function resolveLightingQualityDimensions(techniqueName, jobKey) {
1856
2324
  "pathtracer.pathTrace": { rayTracing: 1, lightingSamples: 1 },
1857
2325
  "pathtracer.accumulate": { temporalReuse: 1, updateCadence: 0.4 },
1858
2326
  "pathtracer.denoise": { temporalReuse: 1, shading: 0.4 },
2327
+ "wavefront.accumulateTerminalRadiance": {
2328
+ rayTracing: 1,
2329
+ lightingSamples: 1,
2330
+ temporalReuse: 0.4
2331
+ },
2332
+ "wavefront.scatterContinuations": {
2333
+ rayTracing: 1,
2334
+ shading: 0.7,
2335
+ updateCadence: 0.5
2336
+ },
1859
2337
  "volumetrics.froxelIntegrate": {
1860
2338
  lightingSamples: 0.6,
1861
2339
  shading: 0.4,
@@ -1900,6 +2378,15 @@ function resolveLightingImportanceSignals(techniqueName, jobKey) {
1900
2378
  },
1901
2379
  "pathtracer.accumulate": { visible: true },
1902
2380
  "pathtracer.denoise": { visible: true },
2381
+ "wavefront.accumulateTerminalRadiance": {
2382
+ visible: true,
2383
+ shadowSignificance: "high",
2384
+ reflectionSignificance: "high"
2385
+ },
2386
+ "wavefront.scatterContinuations": {
2387
+ visible: true,
2388
+ reflectionSignificance: "high"
2389
+ },
1903
2390
  "volumetrics.froxelIntegrate": { visible: true },
1904
2391
  "volumetrics.volumetricShadow": { visible: true, shadowSignificance: "high" },
1905
2392
  "hdri.irradianceConvolution": { visible: false },
@@ -2169,9 +2656,12 @@ export {
2169
2656
  createLightingBandPlan,
2170
2657
  createLightingProfileModeLadder,
2171
2658
  createWavefrontEnvironmentLightingOptions,
2659
+ createWavefrontLightingPlan,
2172
2660
  defaultAdaptiveLightingProfilePolicy,
2173
2661
  defaultLightingProfile,
2174
2662
  defaultLightingTechnique,
2663
+ evaluateWavefrontContinuationEvent,
2664
+ evaluateWavefrontTerminalRadiance,
2175
2665
  getLightingProfile,
2176
2666
  getLightingProfileWorkerManifest,
2177
2667
  getLightingTechnique,
@@ -2190,8 +2680,17 @@ export {
2190
2680
  lightingProfileModeOrder,
2191
2681
  lightingProfileNames,
2192
2682
  lightingProfiles,
2683
+ lightingRequiredRendererWavefrontPassOrder,
2193
2684
  lightingTechniqueNames,
2194
2685
  lightingTechniques,
2686
+ lightingWavefrontBufferContracts,
2687
+ lightingWavefrontContinuationHitTypes,
2688
+ lightingWavefrontHitTypes,
2689
+ lightingWavefrontPassOrder,
2690
+ lightingWavefrontQueuePairStrategy,
2691
+ lightingWavefrontSchemaVersion,
2692
+ lightingWavefrontTerminalHitTypes,
2693
+ lightingWavefrontTerminationPolicy,
2195
2694
  lightingWorkerManifests,
2196
2695
  lightingWorkerQueueClass,
2197
2696
  loadLightingJobs,