@preference-sl/pref-viewer 2.12.0-beta.5 → 2.12.0-beta.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/package.json +1 -1
- package/src/babylonjs-controller.js +63 -15
- package/src/file-storage.js +3 -3
package/package.json
CHANGED
|
@@ -313,18 +313,27 @@ export default class BabylonJSController {
|
|
|
313
313
|
}
|
|
314
314
|
|
|
315
315
|
// 1) Stronger ambient fill
|
|
316
|
-
this.#hemiLight =
|
|
317
|
-
this.#hemiLight
|
|
316
|
+
this.#hemiLight = this.#scene.getLightByName("PrefViewerHemiLight");
|
|
317
|
+
if (!this.#hemiLight) {
|
|
318
|
+
this.#hemiLight = new HemisphericLight("PrefViewerHemiLight", new Vector3(-10, 10, -10), this.#scene);
|
|
319
|
+
this.#hemiLight.intensity = 0.6;
|
|
320
|
+
}
|
|
318
321
|
|
|
319
322
|
// 2) Directional light from the front-right, angled slightly down
|
|
320
|
-
this.#dirLight =
|
|
321
|
-
this.#dirLight
|
|
322
|
-
|
|
323
|
+
this.#dirLight = this.#scene.getLightByName("PrefViewerDirLight");
|
|
324
|
+
if (!this.#dirLight) {
|
|
325
|
+
this.#dirLight = new DirectionalLight("PrefViewerDirLight", new Vector3(-10, 10, -10), this.#scene);
|
|
326
|
+
this.#dirLight.position = new Vector3(5, 4, 5); // light is IN FRONT + ABOVE + to the RIGHT
|
|
327
|
+
this.#dirLight.intensity = 0.6;
|
|
328
|
+
}
|
|
323
329
|
|
|
324
330
|
// 3) Camera‐attached headlight
|
|
325
|
-
this.#cameraLight =
|
|
326
|
-
this.#cameraLight
|
|
327
|
-
|
|
331
|
+
this.#cameraLight = this.#scene.getLightByName("PrefViewerCameraLight");
|
|
332
|
+
if (!this.#cameraLight) {
|
|
333
|
+
this.#cameraLight = new PointLight("PrefViewerCameraLight", this.#camera.position, this.#scene);
|
|
334
|
+
this.#cameraLight.parent = this.#camera;
|
|
335
|
+
this.#cameraLight.intensity = 0.3;
|
|
336
|
+
}
|
|
328
337
|
}
|
|
329
338
|
|
|
330
339
|
/**
|
|
@@ -375,6 +384,13 @@ export default class BabylonJSController {
|
|
|
375
384
|
ssaoPipeline.radius = 0.0001;
|
|
376
385
|
ssaoPipeline.totalStrength = 1;
|
|
377
386
|
ssaoPipeline.base = 0.6;
|
|
387
|
+
|
|
388
|
+
// Configure SSAO to calculate only once instead of every frame for better performance
|
|
389
|
+
if (ssaoPipeline._ssaoPostProcess) {
|
|
390
|
+
ssaoPipeline._ssaoPostProcess.autoClear = false;
|
|
391
|
+
ssaoPipeline._ssaoPostProcess.samples = 1;
|
|
392
|
+
}
|
|
393
|
+
|
|
378
394
|
this.#scene.postProcessRenderPipelineManager.update();
|
|
379
395
|
return true;
|
|
380
396
|
} else {
|
|
@@ -447,6 +463,14 @@ export default class BabylonJSController {
|
|
|
447
463
|
defaultPipeline.grain.animated = false;
|
|
448
464
|
defaultPipeline.grain.intensity = 3;
|
|
449
465
|
|
|
466
|
+
// Configure post-processes to calculate only once instead of every frame for better performance
|
|
467
|
+
if (defaultPipeline.fxaa?._postProcess) {
|
|
468
|
+
defaultPipeline.fxaa._postProcess.autoClear = false;
|
|
469
|
+
}
|
|
470
|
+
if (defaultPipeline.grain?._postProcess) {
|
|
471
|
+
defaultPipeline.grain._postProcess.autoClear = false;
|
|
472
|
+
}
|
|
473
|
+
|
|
450
474
|
this.#scene.postProcessRenderPipelineManager.update();
|
|
451
475
|
return true;
|
|
452
476
|
} else {
|
|
@@ -503,8 +527,8 @@ export default class BabylonJSController {
|
|
|
503
527
|
}
|
|
504
528
|
|
|
505
529
|
const pipelineOptions = {
|
|
506
|
-
resolutionExp:
|
|
507
|
-
sampleDirections: 4, // More sample directions for smoother shadows
|
|
530
|
+
resolutionExp: 1, // Higher resolution for better shadow quality (recomended 8)
|
|
531
|
+
sampleDirections: 4, // More sample directions for smoother shadows (recomended 4)
|
|
508
532
|
ssShadowsEnabled: true,
|
|
509
533
|
shadowRemanence: 0.85,
|
|
510
534
|
triPlanarVoxelization: true,
|
|
@@ -533,8 +557,15 @@ export default class BabylonJSController {
|
|
|
533
557
|
|
|
534
558
|
Object.assign(iblShadowsRenderPipeline, pipelineProps);
|
|
535
559
|
|
|
560
|
+
if (iblShadowsRenderPipeline._ssaoPostProcess) {
|
|
561
|
+
iblShadowsRenderPipeline._ssaoPostProcess.autoClear = false;
|
|
562
|
+
iblShadowsRenderPipeline._ssaoPostProcess.samples = 1;
|
|
563
|
+
}
|
|
564
|
+
|
|
536
565
|
this.#scene.meshes.forEach((mesh) => {
|
|
537
|
-
|
|
566
|
+
const isRootMesh = mesh.id.startsWith("__root__");
|
|
567
|
+
const isHDRIMesh = mesh.name?.toLowerCase() === "hdri";
|
|
568
|
+
if (isRootMesh || isHDRIMesh) {
|
|
538
569
|
return false;
|
|
539
570
|
}
|
|
540
571
|
iblShadowsRenderPipeline.addShadowCastingMesh(mesh);
|
|
@@ -566,6 +597,9 @@ export default class BabylonJSController {
|
|
|
566
597
|
*/
|
|
567
598
|
#initializeDefaultLightShadows() {
|
|
568
599
|
this.#shadowGen = [];
|
|
600
|
+
if (!this.#dirLight) {
|
|
601
|
+
return;
|
|
602
|
+
}
|
|
569
603
|
this.#dirLight.autoUpdateExtends = false;
|
|
570
604
|
const shadowGenerator = new ShadowGenerator(1024, this.#dirLight);
|
|
571
605
|
shadowGenerator.useBlurExponentialShadowMap = true;
|
|
@@ -578,7 +612,7 @@ export default class BabylonJSController {
|
|
|
578
612
|
if (mesh.id.startsWith("__root__")) {
|
|
579
613
|
return false;
|
|
580
614
|
}
|
|
581
|
-
if (mesh.name !== "hdri") {
|
|
615
|
+
if (mesh.name?.toLowerCase() !== "hdri") {
|
|
582
616
|
shadowGenerator.addShadowCaster(mesh, true);
|
|
583
617
|
}
|
|
584
618
|
mesh.receiveShadows = true;
|
|
@@ -618,7 +652,7 @@ export default class BabylonJSController {
|
|
|
618
652
|
if (mesh.id.startsWith("__root__")) {
|
|
619
653
|
return false;
|
|
620
654
|
}
|
|
621
|
-
if (mesh.name !== "hdri") {
|
|
655
|
+
if (mesh.name?.toLowerCase() !== "hdri") {
|
|
622
656
|
shadowGenerator.addShadowCaster(mesh, true);
|
|
623
657
|
}
|
|
624
658
|
});
|
|
@@ -1180,7 +1214,14 @@ export default class BabylonJSController {
|
|
|
1180
1214
|
},
|
|
1181
1215
|
};
|
|
1182
1216
|
|
|
1183
|
-
|
|
1217
|
+
let assetContainer = null;
|
|
1218
|
+
|
|
1219
|
+
try {
|
|
1220
|
+
assetContainer = await LoadAssetContainerAsync(sourceData.source, this.#scene, options);
|
|
1221
|
+
return [container, assetContainer];
|
|
1222
|
+
} catch (error) {
|
|
1223
|
+
return [container, assetContainer];
|
|
1224
|
+
}
|
|
1184
1225
|
}
|
|
1185
1226
|
|
|
1186
1227
|
/**
|
|
@@ -1341,6 +1382,13 @@ export default class BabylonJSController {
|
|
|
1341
1382
|
}
|
|
1342
1383
|
}
|
|
1343
1384
|
|
|
1385
|
+
/**
|
|
1386
|
+
* Configures realistic glass material properties for all materials whose names include "Glass".
|
|
1387
|
+
* @private
|
|
1388
|
+
* @param {AssetContainer} [assetContainer] - The asset container with materials to process. If undefined, uses the model container.
|
|
1389
|
+
* @returns {void}
|
|
1390
|
+
* @note This method assumes that glass materials are named with the substring "Glass".
|
|
1391
|
+
*/
|
|
1344
1392
|
#forceReflectionsInModelGlasses(assetContainer) {
|
|
1345
1393
|
if (assetContainer === undefined) {
|
|
1346
1394
|
assetContainer = this.#containers.model.assetContainer;
|
|
@@ -1350,7 +1398,7 @@ export default class BabylonJSController {
|
|
|
1350
1398
|
}
|
|
1351
1399
|
assetContainer.materials?.forEach(material => {
|
|
1352
1400
|
if (material && material.name && material.name.includes("Glass")) {
|
|
1353
|
-
material.metallic =
|
|
1401
|
+
material.metallic = 0.25;
|
|
1354
1402
|
material.environmentIntensity = 1.0;
|
|
1355
1403
|
}
|
|
1356
1404
|
});
|
package/src/file-storage.js
CHANGED
|
@@ -169,7 +169,7 @@ export class FileStorage {
|
|
|
169
169
|
let file = undefined;
|
|
170
170
|
return new Promise((resolve) => {
|
|
171
171
|
const xhr = new XMLHttpRequest();
|
|
172
|
-
xhr.open("GET", uri, true);
|
|
172
|
+
xhr.open("GET", encodeURI(uri), true);
|
|
173
173
|
xhr.responseType = "blob";
|
|
174
174
|
xhr.onload = () => {
|
|
175
175
|
if (xhr.status === 200) {
|
|
@@ -205,7 +205,7 @@ export class FileStorage {
|
|
|
205
205
|
let timeStamp = null;
|
|
206
206
|
return new Promise((resolve) => {
|
|
207
207
|
const xhr = new XMLHttpRequest();
|
|
208
|
-
xhr.open("HEAD", uri, true);
|
|
208
|
+
xhr.open("HEAD", encodeURI(uri), true);
|
|
209
209
|
xhr.responseType = "blob";
|
|
210
210
|
xhr.onload = () => {
|
|
211
211
|
if (xhr.status === 200) {
|
|
@@ -238,7 +238,7 @@ export class FileStorage {
|
|
|
238
238
|
let size = 0;
|
|
239
239
|
return new Promise((resolve) => {
|
|
240
240
|
const xhr = new XMLHttpRequest();
|
|
241
|
-
xhr.open("HEAD", uri, true);
|
|
241
|
+
xhr.open("HEAD", encodeURI(uri), true);
|
|
242
242
|
xhr.responseType = "blob";
|
|
243
243
|
xhr.onload = () => {
|
|
244
244
|
if (xhr.status === 200) {
|