@preference-sl/pref-viewer 2.17.0-beta.3 → 2.17.0-beta.4
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/README.md +19 -2
- package/package.json +1 -1
- package/src/babylonjs-controller.js +13 -6
package/README.md
CHANGED
|
@@ -88,8 +88,8 @@ viewer.setOptions({
|
|
|
88
88
|
intensity: 1,
|
|
89
89
|
shadows: true,
|
|
90
90
|
},
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
render: {
|
|
92
|
+
lightingTimeOfDay: 0.5,
|
|
93
93
|
},
|
|
94
94
|
});
|
|
95
95
|
```
|
|
@@ -501,6 +501,23 @@ Render settings are persisted in `localStorage` under the `pref-viewer/render-se
|
|
|
501
501
|
|
|
502
502
|
The showroom daylight background uses a shared linear HDR color calibrated with exposure and ACES tone mapping for the current light studio gray target, `#d9d9d9`, in a scene-less view. Both the static look and time-of-day cycle use this same daylight value; the cycle retains its dark night endpoint. Scene geometry can cover the background. The internal `BabylonJSController.config.look.showroom.backgroundDay` value is not a public background-color option and must be recalibrated if tone mapping or exposure changes.
|
|
503
503
|
|
|
504
|
+
## Environment map and scene lights
|
|
505
|
+
|
|
506
|
+
`options.ibl.url` accepts two formats, chosen by the URL's extension (query and hash ignored):
|
|
507
|
+
|
|
508
|
+
| Extension | Loaded as | Notes |
|
|
509
|
+
| --- | --- | --- |
|
|
510
|
+
| `.env` | Prefiltered Babylon environment (`CubeTexture.CreateFromPrefilteredData`) | No prefiltering in the browser; a 4K environment is typically under 1 MB. |
|
|
511
|
+
| anything else | Radiance HDR (`HDRCubeTexture`) | Prefiltered on load, which costs time and memory for large files. |
|
|
512
|
+
|
|
513
|
+
Either file is downloaded once, cached in IndexedDB, and reused across reloads.
|
|
514
|
+
|
|
515
|
+
Directional and spot lights that come with the scene glTF (`KHR_lights_punctual`) cast shadows when `render.shadowsEnabled` is `true` and `ibl.shadows` is off, alongside the built-in light's. Every scene and model mesh casts unless its node sets `extras.castShadows: false`, and receives unless it sets `extras.receiveShadows: false`. A light's shadow darkness comes from its node's `extras.shadowDarkness`, from `0` (black) to `1` (no shadow), and is `0.5` when absent:
|
|
516
|
+
|
|
517
|
+
```json
|
|
518
|
+
{ "name": "Sun", "rotation": [-0.5, 0, 0, 0.866], "extras": { "shadowDarkness": 0.15 }, "extensions": { "KHR_lights_punctual": { "light": 0 } } }
|
|
519
|
+
```
|
|
520
|
+
|
|
504
521
|
## Runtime styles
|
|
505
522
|
|
|
506
523
|
Runtime styles can be passed through the `styles` attribute, the `styles` property setter, `setStyles(styles)`, or `loadConfig({ styles })`.
|
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ArcRotateCamera, AssetContainer, BRDFTextureTools, Camera, Color3, Color4, DefaultRenderingPipeline, DirectionalLight, Engine, FreeCamera, HDRCubeTexture, HemisphericLight, IblShadowsRenderPipeline, ImageProcessingConfiguration, LoadAssetContainerAsync, Material, Matrix, MeshBuilder, PBRMaterial, PointerEventTypes, PointLight, RenderTargetTexture, Scene, ShadowGenerator, SpotLight, SSAORenderingPipeline, Texture, Tools, UniversalCamera, Vector3, WebXRDefaultExperience, WebXRFeatureName, WebXRSessionManager, WebXRState, WhenTextureReadyAsync } from "@babylonjs/core";
|
|
1
|
+
import { ArcRotateCamera, AssetContainer, BRDFTextureTools, Camera, Color3, Color4, CubeTexture, DefaultRenderingPipeline, DirectionalLight, Engine, FreeCamera, HDRCubeTexture, HemisphericLight, IblShadowsRenderPipeline, ImageProcessingConfiguration, LoadAssetContainerAsync, Material, Matrix, MeshBuilder, PBRMaterial, PointerEventTypes, PointLight, RenderTargetTexture, Scene, ShadowGenerator, SpotLight, SSAORenderingPipeline, Texture, Tools, UniversalCamera, Vector3, WebXRDefaultExperience, WebXRFeatureName, WebXRSessionManager, WebXRState, WhenTextureReadyAsync } from "@babylonjs/core";
|
|
2
2
|
import { DracoCompression } from "@babylonjs/core/Meshes/Compression/dracoCompression.js";
|
|
3
3
|
import "@babylonjs/loaders";
|
|
4
4
|
import "@babylonjs/loaders/glTF/2.0/Extensions/KHR_draco_mesh_compression.js";
|
|
@@ -1334,7 +1334,7 @@ export default class BabylonJSController {
|
|
|
1334
1334
|
* @returns {Promise<boolean>} Returns true if the environment texture was changed, false if it was already up to date or failed to load.
|
|
1335
1335
|
* @description
|
|
1336
1336
|
* Lifecycle implemented here:
|
|
1337
|
-
* 1. If `options.ibl.cachedUrl` exists, create `HDRCubeTexture` from it.
|
|
1337
|
+
* 1. If `options.ibl.cachedUrl` exists, create `HDRCubeTexture` from it (a prefiltered `CubeTexture` when `options.ibl.url` is a `.env`).
|
|
1338
1338
|
* 2. Wait for readiness, clone it into `#hdrTexture` for reuse.
|
|
1339
1339
|
* 3. Call `options.ibl.consumeCachedUrl(true)` to revoke temporary object URLs and clear `cachedUrl`.
|
|
1340
1340
|
* 4. On following reloads, if `options.ibl.valid === true` and no `cachedUrl` is present, use `#hdrTexture.clone()`.
|
|
@@ -1348,8 +1348,13 @@ export default class BabylonJSController {
|
|
|
1348
1348
|
let hdrTexture = null;
|
|
1349
1349
|
if (this.#options.ibl?.cachedUrl) {
|
|
1350
1350
|
const hdrTextureURI = this.#options.ibl.cachedUrl;
|
|
1351
|
-
|
|
1352
|
-
|
|
1351
|
+
if (/\.env$/i.test(String(this.#options.ibl.url ?? "").split(/[?#]/)[0])) {
|
|
1352
|
+
// The cached file is a blob: URL with no extension, so the loader is told it is a .env.
|
|
1353
|
+
hdrTexture = CubeTexture.CreateFromPrefilteredData(hdrTextureURI, this.#scene, ".env");
|
|
1354
|
+
} else {
|
|
1355
|
+
const envTextureSize = BabylonJSController.config.quality.environmentTextureSize || 1024;
|
|
1356
|
+
hdrTexture = new HDRCubeTexture(hdrTextureURI, this.#scene, envTextureSize, false, false, false, true, undefined, undefined, false, true, true);
|
|
1357
|
+
}
|
|
1353
1358
|
} else if (this.#hdrTexture && this.#options.ibl?.valid === true) {
|
|
1354
1359
|
hdrTexture = this.#hdrTexture.clone();
|
|
1355
1360
|
} else {
|
|
@@ -1586,7 +1591,7 @@ export default class BabylonJSController {
|
|
|
1586
1591
|
return generator.getLight()?.name === "PrefViewerDirLight";
|
|
1587
1592
|
});
|
|
1588
1593
|
|
|
1589
|
-
this.#containers.environment?.
|
|
1594
|
+
this.#containers.environment?.assetContainer?.lights.forEach((light) => {
|
|
1590
1595
|
// Only shadows for DirectionalLight and SpotLight types
|
|
1591
1596
|
if (!(light instanceof DirectionalLight || light instanceof SpotLight)) {
|
|
1592
1597
|
return;
|
|
@@ -1595,7 +1600,9 @@ export default class BabylonJSController {
|
|
|
1595
1600
|
const shadowGenerator = new ShadowGenerator(1024, light);
|
|
1596
1601
|
shadowGenerator.useBlurExponentialShadowMap = true;
|
|
1597
1602
|
shadowGenerator.blurKernel = 16;
|
|
1598
|
-
|
|
1603
|
+
// KHR_lights_punctual parents the light to its glTF node, which carries the node's extras.
|
|
1604
|
+
const extrasShadowDarkness = light.parent?.metadata?.gltf?.extras?.shadowDarkness;
|
|
1605
|
+
shadowGenerator.darkness = typeof extrasShadowDarkness === "number" && Number.isFinite(extrasShadowDarkness) ? Math.min(Math.max(extrasShadowDarkness, 0), 1) : 0.5;
|
|
1599
1606
|
shadowGenerator.bias = 0.0005;
|
|
1600
1607
|
shadowGenerator.normalBias = 0.02;
|
|
1601
1608
|
shadowGenerator.getShadowMap().refreshRate = RenderTargetTexture.REFRESHRATE_RENDER_ONCE;
|