@preference-sl/pref-viewer 2.17.2-beta.1 → 2.18.0-beta.0
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
CHANGED
|
@@ -521,6 +521,8 @@ Render settings are persisted in `localStorage` under the `pref-viewer/render-se
|
|
|
521
521
|
|
|
522
522
|
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.
|
|
523
523
|
|
|
524
|
+
The model's transmissive glass (`KHR_materials_transmission`, as authored by the SDK) also carries a base color alpha of `0.15`, which would multiply its reflection away and leave it flat grey. The viewer sets that alpha to `1` and `metallicF0Factor` to `3` (`BabylonJSController.config.look.glass`, internal like the showroom look) so the environment reflection reads while the glass stays see-through through transmission. Glass in the environment glTF is unaffected: it is simplified to alpha blending instead.
|
|
525
|
+
|
|
524
526
|
## Environment map and scene lights
|
|
525
527
|
|
|
526
528
|
`options.ibl.url` accepts two formats, chosen by the URL's extension (query and hash ignored):
|
package/package.json
CHANGED
|
@@ -216,6 +216,14 @@ export default class BabylonJSController {
|
|
|
216
216
|
// Re-solve these if exposure, contrast or the tonemapping curve change.
|
|
217
217
|
backgroundDay: [1.424, 1.424, 1.424],
|
|
218
218
|
},
|
|
219
|
+
// The model's physical glass (KHR_materials_transmission). The SDK also authors it with a
|
|
220
|
+
// baseColor alpha of 0.15, which multiplies the reflection away; the viewer sets the alpha
|
|
221
|
+
// to 1 and raises the dielectric F0 (MaterialUtils.tunePhysicalGlassMaterial) so the
|
|
222
|
+
// environment reads on the glass while transmission keeps it see-through.
|
|
223
|
+
glass: {
|
|
224
|
+
alpha: 1,
|
|
225
|
+
metallicF0Factor: 3,
|
|
226
|
+
},
|
|
219
227
|
},
|
|
220
228
|
pointerPicking: {
|
|
221
229
|
movePickIntervalMs: 50, // Cap expensive scene.pick calls to ~20 Hz while moving the pointer
|
|
@@ -2863,6 +2871,21 @@ export default class BabylonJSController {
|
|
|
2863
2871
|
assetContainer.lights = [];
|
|
2864
2872
|
}
|
|
2865
2873
|
|
|
2874
|
+
/**
|
|
2875
|
+
* Gives the model container's physical glass (KHR_materials_transmission) a visible reflection.
|
|
2876
|
+
* Model container only: environment glass is simplified instead (see
|
|
2877
|
+
* #assetContainer_simplifyTransmissiveMaterials), so it is never tuned here.
|
|
2878
|
+
* @private
|
|
2879
|
+
* @param {AssetContainer} assetContainer - Model container whose glass materials should be tuned.
|
|
2880
|
+
* @returns {void}
|
|
2881
|
+
*/
|
|
2882
|
+
#assetContainer_tuneModelGlass(assetContainer) {
|
|
2883
|
+
const look = BabylonJSController.config.look.glass;
|
|
2884
|
+
assetContainer.materials?.forEach((mat) => {
|
|
2885
|
+
MaterialUtils.tunePhysicalGlassMaterial(mat, look);
|
|
2886
|
+
});
|
|
2887
|
+
}
|
|
2888
|
+
|
|
2866
2889
|
/**
|
|
2867
2890
|
* Strips KHR_materials_transmission, KHR_materials_ior and KHR_materials_volume from
|
|
2868
2891
|
* environment-container (scene) materials, converting them to simple alpha blending.
|
|
@@ -3078,6 +3101,7 @@ export default class BabylonJSController {
|
|
|
3078
3101
|
if (container.state.name === "model") {
|
|
3079
3102
|
this.#assetContainer_deleteLights(assetContainer);
|
|
3080
3103
|
this.#assetContainer_stopAnimations(assetContainer);
|
|
3104
|
+
this.#assetContainer_tuneModelGlass(assetContainer);
|
|
3081
3105
|
newModelMetadata = { ...(container.state.update.metadata ?? {}) };
|
|
3082
3106
|
}
|
|
3083
3107
|
if (container.state.name === "model" || container.state.name === "environment") {
|
|
@@ -3396,7 +3420,8 @@ export default class BabylonJSController {
|
|
|
3396
3420
|
getViewport: () => ({ width: this.#canvas.clientWidth, height: this.#canvas.clientHeight }),
|
|
3397
3421
|
getCulture: this.#viewCubeConfig.getCulture,
|
|
3398
3422
|
onLayout: this.#viewCubeConfig.onLayout,
|
|
3399
|
-
|
|
3423
|
+
// A cube drag is pointer interaction like a main-canvas drag: keep the loop continuous for the same window.
|
|
3424
|
+
requestRender: (options) => this.#requestRender({ frames: 2, continuousMs: options?.interaction ? BabylonJSController.config.render.interactionMs : 0 }),
|
|
3400
3425
|
});
|
|
3401
3426
|
}
|
|
3402
3427
|
|
|
@@ -139,7 +139,7 @@ export default class BabylonJSViewCubeController {
|
|
|
139
139
|
* @param {function(import("@babylonjs/core").Camera|null|undefined): boolean} host.isLocked - Reports whether navigation is forbidden for the supplied camera, including unavailable cameras or active XR.
|
|
140
140
|
* @param {function(): (ViewCubeBounds|null)} host.getBounds - Returns current model-only world bounds and their eight corners; null when geometry is unusable. Excludes the environment.
|
|
141
141
|
* @param {function(): {width: number, height: number}} host.getViewport - Returns the current scene viewport dimensions in CSS pixels.
|
|
142
|
-
* @param {function(): void} host.requestRender - Requests rendering through the host scheduler after accepted navigation.
|
|
142
|
+
* @param {function(Object=): void} host.requestRender - Requests rendering through the host scheduler after accepted navigation; `{ interaction: true }` marks a pointer drag step, for which the host keeps rendering continuously as it does for its own canvas drags.
|
|
143
143
|
* @param {function(): string} [host.getCulture] - Returns the current localization culture; omitted callbacks use the translator's default culture.
|
|
144
144
|
* @param {function(number, number): void} [host.onLayout] - Receives the measured cube viewport height and scene viewport height, in CSS pixels; zero cube height clears the menu offset, and disposal reports (0, 0).
|
|
145
145
|
* @param {function(ViewCubeRendererOptions): BabylonJSViewCubeRenderer} [host.createRenderer] - Renderer factory, mainly for tests; defaults to a BabylonJSViewCubeRenderer with its own Engine.
|
|
@@ -581,7 +581,9 @@ export default class BabylonJSViewCubeController {
|
|
|
581
581
|
const direction = directionFromAngles(applyDragDelta(angles, dAlpha, dBeta));
|
|
582
582
|
this.#writePose(camera, pose.target.add(new Vector3(direction.x, direction.y, direction.z).scale(pose.distance)), pose.target, pose.distance);
|
|
583
583
|
}
|
|
584
|
-
|
|
584
|
+
// A drag is pointer interaction: the host keeps its loop continuous for its interaction window, as it does for a
|
|
585
|
+
// main-canvas drag. A plain one-frame request would let its idle throttle pace the drag (seen at ~8 fps).
|
|
586
|
+
this.#host.requestRender({ interaction: true });
|
|
585
587
|
}
|
|
586
588
|
|
|
587
589
|
/**
|
package/src/material-utils.js
CHANGED
|
@@ -47,6 +47,36 @@ export default class MaterialUtils {
|
|
|
47
47
|
return Boolean(mat?.subSurface?.isRefractionEnabled || mat?.subSurface?.isTranslucencyEnabled);
|
|
48
48
|
}
|
|
49
49
|
|
|
50
|
+
/**
|
|
51
|
+
* Gives the model's physical glass a visible reflection.
|
|
52
|
+
*
|
|
53
|
+
* The SDK authors window glass with KHR_materials_transmission AND a baseColor alpha of 0.15 in
|
|
54
|
+
* alpha-blend. Babylon's transmission extension turns on `transparencyAsCoverage` for the whole
|
|
55
|
+
* GLB, which makes `useSpecularOverAlpha` / `useRadianceOverAlpha` false, so the ~4 % Fresnel
|
|
56
|
+
* reflection is multiplied by that alpha and the glass reads as flat grey. Setting the alpha to
|
|
57
|
+
* 1, raising the dielectric F0 and re-enabling the over-alpha reflections lets the environment
|
|
58
|
+
* show up on the glass while transmission keeps it see-through.
|
|
59
|
+
*
|
|
60
|
+
* Only physical glass (see `isPrefViewerPhysicalGlassMaterial`) is touched; `transparencyMode`
|
|
61
|
+
* and `subSurface` are left as authored so the glass stays in the transparent pass.
|
|
62
|
+
* @public
|
|
63
|
+
* @static
|
|
64
|
+
* @param {import("@babylonjs/core").PBRMaterial|null|undefined} mat - Material to tune.
|
|
65
|
+
* @param {{ alpha?: number, metallicF0Factor?: number }} [look] - Glass look; defaults to alpha 1 and F0 factor 3.
|
|
66
|
+
* @returns {boolean} True when the material was physical glass and has been changed.
|
|
67
|
+
*/
|
|
68
|
+
static tunePhysicalGlassMaterial(mat, look = {}) {
|
|
69
|
+
if (!MaterialUtils.isPrefViewerPhysicalGlassMaterial(mat)) {
|
|
70
|
+
return false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
mat.alpha = look?.alpha ?? 1;
|
|
74
|
+
mat.metallicF0Factor = look?.metallicF0Factor ?? 3;
|
|
75
|
+
mat.useSpecularOverAlpha = true;
|
|
76
|
+
mat.useRadianceOverAlpha = true;
|
|
77
|
+
return true;
|
|
78
|
+
}
|
|
79
|
+
|
|
50
80
|
/**
|
|
51
81
|
* Returns true when a material should be placed in the transparent rendering group (renderingGroupId=1).
|
|
52
82
|
*
|