@plasius/gpu-lighting 0.1.7 → 0.1.9
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 +41 -0
- package/README.md +18 -0
- package/dist/index.cjs +206 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +204 -0
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.js +220 -0
package/src/index.js
CHANGED
|
@@ -127,10 +127,151 @@ export const lightingProfiles = Object.freeze(
|
|
|
127
127
|
export const lightingProfileNames = Object.freeze(Object.keys(lightingProfiles));
|
|
128
128
|
|
|
129
129
|
export const defaultLightingProfile = "realtime";
|
|
130
|
+
export const lightingDistanceBands = Object.freeze([
|
|
131
|
+
"near",
|
|
132
|
+
"mid",
|
|
133
|
+
"far",
|
|
134
|
+
"horizon",
|
|
135
|
+
]);
|
|
130
136
|
|
|
131
137
|
export const lightingWorkerQueueClass = "lighting";
|
|
132
138
|
export const lightingDebugOwner = "lighting";
|
|
133
139
|
|
|
140
|
+
const lightingImportanceLevels = Object.freeze([
|
|
141
|
+
"low",
|
|
142
|
+
"medium",
|
|
143
|
+
"high",
|
|
144
|
+
"critical",
|
|
145
|
+
]);
|
|
146
|
+
|
|
147
|
+
const lightingBandPolicySpecs = Object.freeze({
|
|
148
|
+
near: Object.freeze({
|
|
149
|
+
primaryShadowSource: "ray-traced-primary",
|
|
150
|
+
assistShadowSources: Object.freeze(["visibility-raster", "shadow-map-assist"]),
|
|
151
|
+
temporalReuse: "balanced",
|
|
152
|
+
updateCadenceDivisor: 1,
|
|
153
|
+
liveObjectShadows: true,
|
|
154
|
+
impressionOnly: false,
|
|
155
|
+
}),
|
|
156
|
+
mid: Object.freeze({
|
|
157
|
+
primaryShadowSource: "selective-raster-and-proxy",
|
|
158
|
+
assistShadowSources: Object.freeze([
|
|
159
|
+
"regional-shadow-map",
|
|
160
|
+
"proxy-caster",
|
|
161
|
+
"temporal-history",
|
|
162
|
+
]),
|
|
163
|
+
temporalReuse: "aggressive",
|
|
164
|
+
updateCadenceDivisor: 2,
|
|
165
|
+
liveObjectShadows: true,
|
|
166
|
+
impressionOnly: false,
|
|
167
|
+
}),
|
|
168
|
+
far: Object.freeze({
|
|
169
|
+
primaryShadowSource: "merged-proxy-casters",
|
|
170
|
+
assistShadowSources: Object.freeze([
|
|
171
|
+
"coarse-directional",
|
|
172
|
+
"semi-static-occlusion",
|
|
173
|
+
]),
|
|
174
|
+
temporalReuse: "high",
|
|
175
|
+
updateCadenceDivisor: 8,
|
|
176
|
+
liveObjectShadows: false,
|
|
177
|
+
impressionOnly: false,
|
|
178
|
+
}),
|
|
179
|
+
horizon: Object.freeze({
|
|
180
|
+
primaryShadowSource: "baked-impression",
|
|
181
|
+
assistShadowSources: Object.freeze(["atmospheric-gradient", "skyline-darkening"]),
|
|
182
|
+
temporalReuse: "baked",
|
|
183
|
+
updateCadenceDivisor: 60,
|
|
184
|
+
liveObjectShadows: false,
|
|
185
|
+
impressionOnly: true,
|
|
186
|
+
}),
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
function assertLightingImportance(name, value) {
|
|
190
|
+
if (!lightingImportanceLevels.includes(value)) {
|
|
191
|
+
throw new Error(
|
|
192
|
+
`${name} must be one of: ${lightingImportanceLevels.join(", ")}.`
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
return value;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function resolveBandParticipation(profileName, band, importance) {
|
|
199
|
+
const referenceProfile = profileName === "reference";
|
|
200
|
+
const premiumImportance =
|
|
201
|
+
importance === "critical" || importance === "high";
|
|
202
|
+
|
|
203
|
+
if (band === "near") {
|
|
204
|
+
return Object.freeze({
|
|
205
|
+
directShadows: premiumImportance ? "premium" : "selective",
|
|
206
|
+
reflections: premiumImportance ? "premium" : "selective",
|
|
207
|
+
globalIllumination:
|
|
208
|
+
referenceProfile || importance === "critical" ? "premium" : "selective",
|
|
209
|
+
});
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
if (band === "mid") {
|
|
213
|
+
return Object.freeze({
|
|
214
|
+
directShadows: premiumImportance ? "selective" : "proxy",
|
|
215
|
+
reflections:
|
|
216
|
+
referenceProfile && premiumImportance ? "selective" : "proxy",
|
|
217
|
+
globalIllumination:
|
|
218
|
+
referenceProfile && importance === "critical" ? "selective" : "disabled",
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
if (band === "far") {
|
|
223
|
+
return Object.freeze({
|
|
224
|
+
directShadows: "proxy",
|
|
225
|
+
reflections:
|
|
226
|
+
referenceProfile && importance === "critical" ? "proxy" : "disabled",
|
|
227
|
+
globalIllumination: "disabled",
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
return Object.freeze({
|
|
232
|
+
directShadows: "disabled",
|
|
233
|
+
reflections: "disabled",
|
|
234
|
+
globalIllumination: "disabled",
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function createLightingBandPlan(options = {}) {
|
|
239
|
+
const profileName = options.profile ?? defaultLightingProfile;
|
|
240
|
+
const profile = getLightingProfile(profileName);
|
|
241
|
+
const importance = assertLightingImportance(
|
|
242
|
+
"importance",
|
|
243
|
+
options.importance ?? "high"
|
|
244
|
+
);
|
|
245
|
+
|
|
246
|
+
const bands = Object.freeze(
|
|
247
|
+
lightingDistanceBands.map((band) =>
|
|
248
|
+
Object.freeze({
|
|
249
|
+
band,
|
|
250
|
+
profile: profile.name,
|
|
251
|
+
importance,
|
|
252
|
+
primaryShadowSource: lightingBandPolicySpecs[band].primaryShadowSource,
|
|
253
|
+
assistShadowSources: Object.freeze([
|
|
254
|
+
...lightingBandPolicySpecs[band].assistShadowSources,
|
|
255
|
+
]),
|
|
256
|
+
rtParticipation: resolveBandParticipation(profile.name, band, importance),
|
|
257
|
+
temporalReuse: lightingBandPolicySpecs[band].temporalReuse,
|
|
258
|
+
updateCadenceDivisor: lightingBandPolicySpecs[band].updateCadenceDivisor,
|
|
259
|
+
liveObjectShadows: lightingBandPolicySpecs[band].liveObjectShadows,
|
|
260
|
+
impressionOnly: lightingBandPolicySpecs[band].impressionOnly,
|
|
261
|
+
})
|
|
262
|
+
)
|
|
263
|
+
);
|
|
264
|
+
|
|
265
|
+
return Object.freeze({
|
|
266
|
+
schemaVersion: 1,
|
|
267
|
+
owner: lightingDebugOwner,
|
|
268
|
+
profile: profile.name,
|
|
269
|
+
importance,
|
|
270
|
+
techniques: Object.freeze([...profile.techniques]),
|
|
271
|
+
bands,
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
|
|
134
275
|
function buildWorkerBudgetLevels(jobType, queueClass, presets) {
|
|
135
276
|
return Object.freeze([
|
|
136
277
|
Object.freeze({
|
|
@@ -713,6 +854,80 @@ const lightingWorkerDagSpecs = {
|
|
|
713
854
|
},
|
|
714
855
|
};
|
|
715
856
|
|
|
857
|
+
function resolveLightingQualityDimensions(techniqueName, jobKey) {
|
|
858
|
+
const key = `${techniqueName}.${jobKey}`;
|
|
859
|
+
return Object.freeze(
|
|
860
|
+
{
|
|
861
|
+
"hybrid.directLighting": { shadows: 1, lightingSamples: 0.7 },
|
|
862
|
+
"hybrid.screenTrace": { rayTracing: 1, temporalReuse: 0.4 },
|
|
863
|
+
"hybrid.radianceCache": {
|
|
864
|
+
lightingSamples: 0.8,
|
|
865
|
+
updateCadence: 0.7,
|
|
866
|
+
temporalReuse: 1,
|
|
867
|
+
},
|
|
868
|
+
"hybrid.finalGather": { lightingSamples: 1, rayTracing: 0.6 },
|
|
869
|
+
"hybrid.reflectionResolve": {
|
|
870
|
+
rayTracing: 0.5,
|
|
871
|
+
temporalReuse: 1,
|
|
872
|
+
shading: 0.3,
|
|
873
|
+
},
|
|
874
|
+
"pathtracer.pathTrace": { rayTracing: 1, lightingSamples: 1 },
|
|
875
|
+
"pathtracer.accumulate": { temporalReuse: 1, updateCadence: 0.4 },
|
|
876
|
+
"pathtracer.denoise": { temporalReuse: 1, shading: 0.4 },
|
|
877
|
+
"volumetrics.froxelIntegrate": {
|
|
878
|
+
lightingSamples: 0.6,
|
|
879
|
+
shading: 0.4,
|
|
880
|
+
updateCadence: 0.3,
|
|
881
|
+
},
|
|
882
|
+
"volumetrics.volumetricShadow": { shadows: 0.8, updateCadence: 0.5 },
|
|
883
|
+
"hdri.irradianceConvolution": {
|
|
884
|
+
lightingSamples: 0.4,
|
|
885
|
+
temporalReuse: 1,
|
|
886
|
+
updateCadence: 1,
|
|
887
|
+
},
|
|
888
|
+
"hdri.specularPrefilter": {
|
|
889
|
+
lightingSamples: 0.5,
|
|
890
|
+
temporalReuse: 1,
|
|
891
|
+
updateCadence: 1,
|
|
892
|
+
},
|
|
893
|
+
"hdri.brdfLut": {
|
|
894
|
+
shading: 0.4,
|
|
895
|
+
temporalReuse: 1,
|
|
896
|
+
updateCadence: 1,
|
|
897
|
+
},
|
|
898
|
+
}[key] ?? {}
|
|
899
|
+
);
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
function resolveLightingImportanceSignals(techniqueName, jobKey) {
|
|
903
|
+
const key = `${techniqueName}.${jobKey}`;
|
|
904
|
+
return Object.freeze(
|
|
905
|
+
{
|
|
906
|
+
"hybrid.directLighting": { visible: true, shadowSignificance: "high" },
|
|
907
|
+
"hybrid.screenTrace": { visible: true, reflectionSignificance: "high" },
|
|
908
|
+
"hybrid.radianceCache": { visible: true },
|
|
909
|
+
"hybrid.finalGather": {
|
|
910
|
+
visible: true,
|
|
911
|
+
shadowSignificance: "critical",
|
|
912
|
+
reflectionSignificance: "high",
|
|
913
|
+
},
|
|
914
|
+
"hybrid.reflectionResolve": { visible: true, reflectionSignificance: "high" },
|
|
915
|
+
"pathtracer.pathTrace": {
|
|
916
|
+
visible: true,
|
|
917
|
+
shadowSignificance: "high",
|
|
918
|
+
reflectionSignificance: "high",
|
|
919
|
+
},
|
|
920
|
+
"pathtracer.accumulate": { visible: true },
|
|
921
|
+
"pathtracer.denoise": { visible: true },
|
|
922
|
+
"volumetrics.froxelIntegrate": { visible: true },
|
|
923
|
+
"volumetrics.volumetricShadow": { visible: true, shadowSignificance: "high" },
|
|
924
|
+
"hdri.irradianceConvolution": { visible: false },
|
|
925
|
+
"hdri.specularPrefilter": { visible: false, reflectionSignificance: "medium" },
|
|
926
|
+
"hdri.brdfLut": { visible: false },
|
|
927
|
+
}[key] ?? {}
|
|
928
|
+
);
|
|
929
|
+
}
|
|
930
|
+
|
|
716
931
|
function buildWorkerManifestJob(techniqueName, job) {
|
|
717
932
|
const spec = lightingWorkerSpecPresets[techniqueName].jobs[job.key];
|
|
718
933
|
const dag = lightingWorkerDagSpecs[techniqueName][job.key];
|
|
@@ -737,6 +952,8 @@ function buildWorkerManifestJob(techniqueName, job) {
|
|
|
737
952
|
domain: spec.domain,
|
|
738
953
|
authority: "visual",
|
|
739
954
|
importance: spec.importance,
|
|
955
|
+
qualityDimensions: resolveLightingQualityDimensions(techniqueName, job.key),
|
|
956
|
+
importanceSignals: resolveLightingImportanceSignals(techniqueName, job.key),
|
|
740
957
|
levels: spec.levels,
|
|
741
958
|
}),
|
|
742
959
|
debug: Object.freeze({
|
|
@@ -830,6 +1047,7 @@ export function getLightingProfileWorkerManifest(
|
|
|
830
1047
|
const techniques = profile.techniques.map((techniqueName) =>
|
|
831
1048
|
getLightingTechniqueWorkerManifest(techniqueName)
|
|
832
1049
|
);
|
|
1050
|
+
const lightingBandPlan = createLightingBandPlan({ profile: profile.name });
|
|
833
1051
|
|
|
834
1052
|
return Object.freeze({
|
|
835
1053
|
schemaVersion: 1,
|
|
@@ -838,6 +1056,7 @@ export function getLightingProfileWorkerManifest(
|
|
|
838
1056
|
description: profile.description,
|
|
839
1057
|
schedulerMode: "dag",
|
|
840
1058
|
techniques: Object.freeze(techniques),
|
|
1059
|
+
lightingBands: lightingBandPlan.bands,
|
|
841
1060
|
jobs: Object.freeze(techniques.flatMap((technique) => technique.jobs)),
|
|
842
1061
|
});
|
|
843
1062
|
}
|
|
@@ -1011,6 +1230,7 @@ export async function loadLightingProfileWorkerPlan(
|
|
|
1011
1230
|
return {
|
|
1012
1231
|
profile,
|
|
1013
1232
|
techniques,
|
|
1233
|
+
lightingBandPlan: createLightingBandPlan({ profile: profile.name }),
|
|
1014
1234
|
workerManifest: getLightingProfileWorkerManifest(profile.name),
|
|
1015
1235
|
};
|
|
1016
1236
|
}
|