@pascal-app/viewer 0.9.1 → 0.9.2
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/components/error-boundary.d.ts +6 -0
- package/dist/components/error-boundary.d.ts.map +1 -1
- package/dist/components/error-boundary.js +6 -0
- package/dist/components/renderers/node-renderer.d.ts +5 -1
- package/dist/components/renderers/node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/node-renderer.js +5 -2
- package/dist/components/renderers/parametric-node-renderer.d.ts.map +1 -1
- package/dist/components/renderers/parametric-node-renderer.js +7 -4
- package/dist/components/viewer/bvh-ecctrl.d.ts +77 -0
- package/dist/components/viewer/bvh-ecctrl.d.ts.map +1 -0
- package/dist/components/viewer/bvh-ecctrl.js +552 -0
- package/dist/components/viewer/frame-limiter.d.ts.map +1 -1
- package/dist/components/viewer/frame-limiter.js +39 -4
- package/dist/components/viewer/glb-interactive.d.ts +41 -0
- package/dist/components/viewer/glb-interactive.d.ts.map +1 -0
- package/dist/components/viewer/glb-interactive.js +394 -0
- package/dist/components/viewer/glb-reference-nodes.d.ts +29 -0
- package/dist/components/viewer/glb-reference-nodes.d.ts.map +1 -0
- package/dist/components/viewer/glb-reference-nodes.js +80 -0
- package/dist/components/viewer/glb-replace-instances.d.ts +18 -0
- package/dist/components/viewer/glb-replace-instances.d.ts.map +1 -0
- package/dist/components/viewer/glb-replace-instances.js +61 -0
- package/dist/components/viewer/glb-scene.d.ts +54 -0
- package/dist/components/viewer/glb-scene.d.ts.map +1 -0
- package/dist/components/viewer/glb-scene.js +920 -0
- package/dist/components/viewer/glb-walkthrough-controller.d.ts +12 -0
- package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -0
- package/dist/components/viewer/glb-walkthrough-controller.js +357 -0
- package/dist/components/viewer/index.d.ts +19 -2
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +104 -12
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +36 -5
- package/dist/components/viewer/perf-monitor.d.ts.map +1 -1
- package/dist/components/viewer/perf-monitor.js +17 -2
- package/dist/components/viewer/post-processing.d.ts +7 -1
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +179 -24
- package/dist/components/viewer/registered-systems.d.ts.map +1 -1
- package/dist/components/viewer/registered-systems.js +6 -4
- package/dist/components/viewer/scene-bvh.d.ts +2 -1
- package/dist/components/viewer/scene-bvh.d.ts.map +1 -1
- package/dist/components/viewer/scene-bvh.js +3 -0
- package/dist/components/viewer/scene-bvh.test.d.ts +2 -0
- package/dist/components/viewer/scene-bvh.test.d.ts.map +1 -0
- package/dist/components/viewer/scene-bvh.test.js +13 -0
- package/dist/components/viewer/scene-environment.d.ts +2 -0
- package/dist/components/viewer/scene-environment.d.ts.map +1 -0
- package/dist/components/viewer/scene-environment.js +79 -0
- package/dist/components/viewer/selection-manager.d.ts.map +1 -1
- package/dist/components/viewer/selection-manager.js +18 -10
- package/dist/components/viewer/walkthrough-controls.d.ts +1 -0
- package/dist/components/viewer/walkthrough-controls.d.ts.map +1 -1
- package/dist/components/viewer/walkthrough-controls.js +20 -0
- package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.js +3 -22
- package/dist/hooks/use-node-events.d.ts +1 -1
- package/dist/hooks/use-node-events.d.ts.map +1 -1
- package/dist/hooks/use-node-events.js +22 -14
- package/dist/index.d.ts +19 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +22 -8
- package/dist/lib/backdrop.d.ts +33 -0
- package/dist/lib/backdrop.d.ts.map +1 -0
- package/dist/lib/backdrop.js +92 -0
- package/dist/lib/box-uv.d.ts +13 -0
- package/dist/lib/box-uv.d.ts.map +1 -0
- package/dist/lib/box-uv.js +32 -0
- package/dist/lib/csg-utils.d.ts +3 -9
- package/dist/lib/csg-utils.d.ts.map +1 -1
- package/dist/lib/csg-utils.js +65 -5
- package/dist/lib/csg-utils.test.d.ts +2 -0
- package/dist/lib/csg-utils.test.d.ts.map +1 -0
- package/dist/lib/csg-utils.test.js +45 -0
- package/dist/lib/edge-style.d.ts +1 -0
- package/dist/lib/edge-style.d.ts.map +1 -1
- package/dist/lib/edge-style.js +26 -6
- package/dist/lib/ink-edges.d.ts +1 -1
- package/dist/lib/ink-edges.d.ts.map +1 -1
- package/dist/lib/ink-edges.js +13 -7
- package/dist/lib/ktx2-loader.d.ts +43 -0
- package/dist/lib/ktx2-loader.d.ts.map +1 -0
- package/dist/lib/ktx2-loader.js +136 -0
- package/dist/lib/layers.d.ts +10 -0
- package/dist/lib/layers.d.ts.map +1 -1
- package/dist/lib/layers.js +10 -0
- package/dist/lib/materials.d.ts +14 -1
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +103 -26
- package/dist/lib/scene-themes.d.ts +1 -0
- package/dist/lib/scene-themes.d.ts.map +1 -1
- package/dist/lib/scene-themes.js +25 -16
- package/dist/lib/shadow-only.d.ts +4 -0
- package/dist/lib/shadow-only.d.ts.map +1 -0
- package/dist/lib/shadow-only.js +36 -0
- package/dist/lib/tsl-compat.d.ts +12 -0
- package/dist/lib/tsl-compat.d.ts.map +1 -0
- package/dist/lib/tsl-compat.js +13 -0
- package/dist/store/use-viewer.d.ts +60 -18
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +175 -3
- package/dist/store/use-viewer.test.d.ts +2 -0
- package/dist/store/use-viewer.test.d.ts.map +1 -0
- package/dist/store/use-viewer.test.js +42 -0
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +4 -1
- package/dist/systems/door/door-animation.test.d.ts +2 -0
- package/dist/systems/door/door-animation.test.d.ts.map +1 -0
- package/dist/systems/door/door-animation.test.js +51 -0
- package/dist/systems/door/door-floor-alignment.test.d.ts +2 -0
- package/dist/systems/door/door-floor-alignment.test.d.ts.map +1 -0
- package/dist/systems/door/door-floor-alignment.test.js +50 -0
- package/dist/systems/door/door-system.d.ts +24 -0
- package/dist/systems/door/door-system.d.ts.map +1 -1
- package/dist/systems/door/door-system.js +494 -161
- package/dist/systems/fence/fence-system.d.ts +17 -0
- package/dist/systems/fence/fence-system.d.ts.map +1 -1
- package/dist/systems/fence/fence-system.js +221 -53
- package/dist/systems/geometry/geometry-system.d.ts +7 -0
- package/dist/systems/geometry/geometry-system.d.ts.map +1 -1
- package/dist/systems/geometry/geometry-system.js +95 -26
- package/dist/systems/geometry/geometry-system.test.d.ts +2 -0
- package/dist/systems/geometry/geometry-system.test.d.ts.map +1 -0
- package/dist/systems/geometry/geometry-system.test.js +30 -0
- package/dist/systems/interactive/control-widget.d.ts +10 -0
- package/dist/systems/interactive/control-widget.d.ts.map +1 -0
- package/dist/systems/interactive/control-widget.js +35 -0
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +55 -56
- package/dist/systems/item/item-system.d.ts.map +1 -1
- package/dist/systems/item/item-system.js +20 -6
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +28 -4
- package/dist/systems/level/level-utils.d.ts +0 -3
- package/dist/systems/level/level-utils.d.ts.map +1 -1
- package/dist/systems/level/level-utils.js +2 -41
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +29 -8
- package/dist/systems/roof/roof-system.d.ts +21 -8
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +1079 -221
- package/dist/systems/slab/slab-system.d.ts +5 -3
- package/dist/systems/slab/slab-system.d.ts.map +1 -1
- package/dist/systems/slab/slab-system.js +41 -23
- package/dist/systems/slab/slab-system.test.js +3 -2
- package/dist/systems/stair/stair-system.js +6 -3
- package/dist/systems/wall/opening-cutout-geometry.d.ts +31 -0
- package/dist/systems/wall/opening-cutout-geometry.d.ts.map +1 -0
- package/dist/systems/wall/opening-cutout-geometry.js +167 -0
- package/dist/systems/wall/opening-cutout-geometry.test.d.ts +2 -0
- package/dist/systems/wall/opening-cutout-geometry.test.d.ts.map +1 -0
- package/dist/systems/wall/opening-cutout-geometry.test.js +172 -0
- package/dist/systems/wall/wall-cutout.d.ts.map +1 -1
- package/dist/systems/wall/wall-cutout.js +46 -17
- package/dist/systems/wall/wall-materials.d.ts +11 -7
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +244 -35
- package/dist/systems/wall/wall-opening-cutout.test.d.ts +2 -0
- package/dist/systems/wall/wall-opening-cutout.test.d.ts.map +1 -0
- package/dist/systems/wall/wall-opening-cutout.test.js +59 -0
- package/dist/systems/wall/wall-support-extension.test.d.ts +2 -0
- package/dist/systems/wall/wall-support-extension.test.d.ts.map +1 -0
- package/dist/systems/wall/wall-support-extension.test.js +48 -0
- package/dist/systems/wall/wall-system.d.ts +2 -2
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +329 -174
- package/dist/systems/window/window-animation-system.d.ts +12 -0
- package/dist/systems/window/window-animation-system.d.ts.map +1 -1
- package/dist/systems/window/window-animation-system.js +16 -5
- package/dist/systems/window/window-system.d.ts +7 -0
- package/dist/systems/window/window-system.d.ts.map +1 -1
- package/dist/systems/window/window-system.js +240 -14
- package/package.json +4 -4
- package/dist/components/viewer/ground-occluder.d.ts +0 -2
- package/dist/components/viewer/ground-occluder.d.ts.map +0 -1
- package/dist/components/viewer/ground-occluder.js +0 -67
package/dist/lib/materials.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type MaterialPresetPayload, type MaterialSchema, type SurfaceRole } from '@pascal-app/core';
|
|
1
|
+
import { type MaterialPresetPayload, type MaterialSchema, type SceneMaterial, type SceneMaterialId, type SurfaceRole } from '@pascal-app/core';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
3
|
import { MeshLambertNodeMaterial } from 'three/webgpu';
|
|
4
4
|
export type RenderShading = 'solid' | 'rendered';
|
|
@@ -14,6 +14,19 @@ export declare function applyMaterialPresetToMaterials(materialInput: THREE.Mate
|
|
|
14
14
|
export declare function createMaterialFromPreset(preset: MaterialPresetPayload, shading?: RenderShading): THREE.Material;
|
|
15
15
|
export declare function createMaterialFromPresetRef(materialPreset?: string, shading?: RenderShading): THREE.Material | null;
|
|
16
16
|
export declare function createMaterial(material?: MaterialSchema, shading?: RenderShading): THREE.Material;
|
|
17
|
+
/**
|
|
18
|
+
* Resolve a MaterialRef ('library:<id>' | 'scene:<id>') to a three.js material.
|
|
19
|
+
* Returns null for an unknown / dangling ref so callers fall back to the
|
|
20
|
+
* slot's default (authored material, then themed default). Never throws.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveMaterialRef(ref: string | undefined, sceneMaterials: Record<SceneMaterialId, SceneMaterial> | undefined, shading?: RenderShading): THREE.Material | null;
|
|
23
|
+
/**
|
|
24
|
+
* Resolve a node kind's declared slot default — either a catalog `library:<id>`
|
|
25
|
+
* finish or a flat `#rrggbb` colour — to a renderable material. Shared by the
|
|
26
|
+
* procedural kinds whose colored-mode unpainted appearance comes from a
|
|
27
|
+
* declarative default (slab, wall).
|
|
28
|
+
*/
|
|
29
|
+
export declare function resolveSlotDefaultMaterial(slotDefault: string, shading?: RenderShading, roughness?: number): THREE.Material;
|
|
17
30
|
export declare function createDefaultMaterial(color?: string, roughness?: number, shading?: RenderShading, side?: THREE.Side): THREE.Material;
|
|
18
31
|
export declare function createSurfaceRoleMaterial(role: SurfaceRole, preset: ColorPreset, side?: THREE.Side, sceneThemeId?: string): THREE.Material;
|
|
19
32
|
export declare function baseMaterial(shading?: RenderShading): THREE.Material;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/lib/materials.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,qBAAqB,EAE1B,KAAK,cAAc,
|
|
1
|
+
{"version":3,"file":"materials.d.ts","sourceRoot":"","sources":["../../src/lib/materials.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/materials.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { getMaterialPresetByRef, resolveMaterial, } from '@pascal-app/core';
|
|
1
|
+
import { getMaterialPresetByRef, parseMaterialRef, resolveMaterial, } from '@pascal-app/core';
|
|
2
2
|
import * as THREE from 'three';
|
|
3
|
+
import { float, mix, positionViewDirection, transformedNormalView } from 'three/tsl';
|
|
3
4
|
import { MeshLambertNodeMaterial, MeshStandardNodeMaterial } from 'three/webgpu';
|
|
4
5
|
import { resolveCdnUrl } from './asset-url';
|
|
6
|
+
import { isKtx2Url, ktx2Loader, whenKtx2Ready } from './ktx2-loader';
|
|
5
7
|
import { getSceneTheme } from './scene-themes';
|
|
6
8
|
export const CLAY_PALETTE = {
|
|
7
9
|
wall: '#dcd6c7',
|
|
@@ -12,14 +14,16 @@ export const CLAY_PALETTE = {
|
|
|
12
14
|
glazing: '#c8d4dc',
|
|
13
15
|
furnishing: '#d2ccbe',
|
|
14
16
|
};
|
|
17
|
+
// Albedos are clamped to ≈0.83 linear (max channel #eb): real white paint
|
|
18
|
+
// reflects ~80%, and pure-white albedo kills GI/shadow contrast.
|
|
15
19
|
export const WHITE_PALETTE = {
|
|
16
|
-
wall: '#
|
|
17
|
-
floor: '#
|
|
18
|
-
ceiling: '#
|
|
20
|
+
wall: '#ebeae6',
|
|
21
|
+
floor: '#e7e4dd',
|
|
22
|
+
ceiling: '#ebeae6',
|
|
19
23
|
roof: '#dedbd2',
|
|
20
|
-
joinery: '#
|
|
24
|
+
joinery: '#e5e2d9',
|
|
21
25
|
glazing: '#dbe8ee',
|
|
22
|
-
furnishing: '#
|
|
26
|
+
furnishing: '#e9e7e1',
|
|
23
27
|
};
|
|
24
28
|
export const MONO_PALETTE = {
|
|
25
29
|
wall: '#c8c8c8',
|
|
@@ -49,7 +53,7 @@ export function resolveSurfaceColor(role, preset, sceneThemeId) {
|
|
|
49
53
|
// The active scene theme may tint individual roles (e.g. Mediterranean's blue
|
|
50
54
|
// roof); fall back to the chosen colour preset's palette when it doesn't.
|
|
51
55
|
const tints = sceneThemeId ? getSceneTheme(sceneThemeId).clayTints : undefined;
|
|
52
|
-
return tints?.[role] ?? PRESET_PALETTES[preset][role];
|
|
56
|
+
return tints?.[role] ?? (PRESET_PALETTES[preset] ?? CLAY_PALETTE)[role];
|
|
53
57
|
}
|
|
54
58
|
// DoubleSide on any NodeMaterial inside the MRT scenePass (SSGI's output /
|
|
55
59
|
// diffuseColor / normal targets) causes WebGPU to create a render pipeline
|
|
@@ -62,10 +66,14 @@ export const glassMaterial = new MeshLambertNodeMaterial({
|
|
|
62
66
|
opacity: 0.35,
|
|
63
67
|
side: THREE.FrontSide,
|
|
64
68
|
});
|
|
69
|
+
glassMaterial.userData.__pascalCachedMaterial = true;
|
|
70
|
+
function resolveNodeMaterialSide(side) {
|
|
71
|
+
return side === THREE.DoubleSide ? THREE.FrontSide : side;
|
|
72
|
+
}
|
|
65
73
|
const sideMap = {
|
|
66
74
|
front: THREE.FrontSide,
|
|
67
75
|
back: THREE.BackSide,
|
|
68
|
-
double: THREE.
|
|
76
|
+
double: THREE.FrontSide,
|
|
69
77
|
};
|
|
70
78
|
const materialCache = new Map();
|
|
71
79
|
const defaultMaterialCache = new Map();
|
|
@@ -73,6 +81,13 @@ const surfaceRoleMaterialCache = new Map();
|
|
|
73
81
|
const textureCache = new Map();
|
|
74
82
|
const textureLoadPromises = new Map();
|
|
75
83
|
const textureLoader = new THREE.TextureLoader();
|
|
84
|
+
// `.ktx2` finish maps transcode through the shared KTX2 loader (support is
|
|
85
|
+
// detected once at viewer init); everything else loads as a normal image.
|
|
86
|
+
function pickTextureLoader(url) {
|
|
87
|
+
// KTX2Loader's load/loadAsync are call-compatible with TextureLoader (url →
|
|
88
|
+
// Texture / Promise<Texture>); cast for typing.
|
|
89
|
+
return isKtx2Url(url) ? ktx2Loader : textureLoader;
|
|
90
|
+
}
|
|
76
91
|
const wrapMap = {
|
|
77
92
|
Repeat: THREE.RepeatWrapping,
|
|
78
93
|
ClampToEdge: THREE.ClampToEdgeWrapping,
|
|
@@ -116,7 +131,7 @@ function getTexture(material) {
|
|
|
116
131
|
const cached = textureCache.get(cacheKey);
|
|
117
132
|
if (cached)
|
|
118
133
|
return cached;
|
|
119
|
-
const texture =
|
|
134
|
+
const texture = pickTextureLoader(textureConfig.url).load(textureConfig.url);
|
|
120
135
|
texture.wrapS = THREE.RepeatWrapping;
|
|
121
136
|
texture.wrapT = THREE.RepeatWrapping;
|
|
122
137
|
const repeatX = textureConfig.repeat?.[0] ?? textureConfig.scale ?? 1;
|
|
@@ -162,7 +177,7 @@ function getPresetTexture(path, props, slot) {
|
|
|
162
177
|
const cached = textureCache.get(cacheKey);
|
|
163
178
|
if (cached)
|
|
164
179
|
return cached;
|
|
165
|
-
const texture =
|
|
180
|
+
const texture = pickTextureLoader(resolvedPath).load(resolvedPath);
|
|
166
181
|
applyTextureProperties(texture, props, slot);
|
|
167
182
|
setTextureCacheKey(texture, cacheKey);
|
|
168
183
|
textureCache.set(cacheKey, texture);
|
|
@@ -195,8 +210,14 @@ async function loadPresetTexture(path, props, slot) {
|
|
|
195
210
|
const existingPromise = textureLoadPromises.get(cacheKey);
|
|
196
211
|
if (existingPromise)
|
|
197
212
|
return existingPromise;
|
|
198
|
-
|
|
199
|
-
|
|
213
|
+
// `.ktx2` loads wait for `detectSupport` (KTX2Loader.load throws before it) —
|
|
214
|
+
// materials can be created while a capture canvas's renderer is still
|
|
215
|
+
// initializing, and failing here would cache the material permanently
|
|
216
|
+
// texture-less (white).
|
|
217
|
+
const load = isKtx2Url(resolvedPath)
|
|
218
|
+
? whenKtx2Ready().then(() => ktx2Loader.loadAsync(resolvedPath))
|
|
219
|
+
: textureLoader.loadAsync(resolvedPath);
|
|
220
|
+
const promise = load
|
|
200
221
|
.then((texture) => {
|
|
201
222
|
applyTextureProperties(texture, props, slot);
|
|
202
223
|
setTextureCacheKey(texture, cacheKey);
|
|
@@ -257,15 +278,35 @@ function applyMaterialMapProperties(material, mapProperties) {
|
|
|
257
278
|
}
|
|
258
279
|
material.transparent = mapProperties.transparent;
|
|
259
280
|
material.opacity = mapProperties.opacity;
|
|
260
|
-
material.side =
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
: THREE.DoubleSide;
|
|
281
|
+
material.side = resolveNodeMaterialSide(mapProperties.side === 0
|
|
282
|
+
? THREE.FrontSide
|
|
283
|
+
: mapProperties.side === 1
|
|
284
|
+
? THREE.BackSide
|
|
285
|
+
: THREE.DoubleSide);
|
|
266
286
|
applyTexturePropertiesToMaterial(material, mapProperties);
|
|
267
287
|
material.needsUpdate = true;
|
|
268
288
|
}
|
|
289
|
+
// Glass-like transparency threshold: any standard material authored as
|
|
290
|
+
// `transparent` with opacity below this gets the fresnel treatment.
|
|
291
|
+
const GLASS_OPACITY_THRESHOLD = 0.6;
|
|
292
|
+
/**
|
|
293
|
+
* Fresnel-driven opacity for glass: nearly the authored opacity head-on,
|
|
294
|
+
* increasingly opaque (showing the environment reflection) at grazing angles.
|
|
295
|
+
* This is what makes glass read as a surface instead of a flat blue tint.
|
|
296
|
+
*/
|
|
297
|
+
function applyGlassFresnel(material) {
|
|
298
|
+
const facing = transformedNormalView.dot(positionViewDirection).clamp(0, 1);
|
|
299
|
+
const fresnel = facing.oneMinus().pow(3);
|
|
300
|
+
material.opacityNode = mix(float(material.opacity), float(0.92), fresnel);
|
|
301
|
+
material.envMapIntensity = 1.4;
|
|
302
|
+
}
|
|
303
|
+
function maybeApplyGlassFresnel(material) {
|
|
304
|
+
if (material instanceof MeshStandardNodeMaterial &&
|
|
305
|
+
material.transparent &&
|
|
306
|
+
material.opacity < GLASS_OPACITY_THRESHOLD) {
|
|
307
|
+
applyGlassFresnel(material);
|
|
308
|
+
}
|
|
309
|
+
}
|
|
269
310
|
function applyMaterialPresetTextures(material, preset) {
|
|
270
311
|
const { maps, mapProperties } = preset;
|
|
271
312
|
queueTextureAssignment(material, 'map', maps.albedoMap, mapProperties);
|
|
@@ -302,6 +343,8 @@ export function createMaterialFromPreset(preset, shading = 'rendered') {
|
|
|
302
343
|
}
|
|
303
344
|
const material = shading === 'solid' ? new MeshLambertNodeMaterial() : new MeshStandardNodeMaterial();
|
|
304
345
|
applyMaterialPresetToMaterials(material, preset);
|
|
346
|
+
maybeApplyGlassFresnel(material);
|
|
347
|
+
material.userData.__pascalCachedMaterial = true;
|
|
305
348
|
materialCache.set(cacheKey, material);
|
|
306
349
|
return material;
|
|
307
350
|
}
|
|
@@ -333,21 +376,53 @@ export function createMaterial(material, shading = 'rendered') {
|
|
|
333
376
|
roughness: props.roughness,
|
|
334
377
|
metalness: props.metalness,
|
|
335
378
|
});
|
|
379
|
+
maybeApplyGlassFresnel(threeMaterial);
|
|
380
|
+
threeMaterial.userData.__pascalCachedMaterial = true;
|
|
336
381
|
materialCache.set(cacheKey, threeMaterial);
|
|
337
382
|
return threeMaterial;
|
|
338
383
|
}
|
|
384
|
+
/**
|
|
385
|
+
* Resolve a MaterialRef ('library:<id>' | 'scene:<id>') to a three.js material.
|
|
386
|
+
* Returns null for an unknown / dangling ref so callers fall back to the
|
|
387
|
+
* slot's default (authored material, then themed default). Never throws.
|
|
388
|
+
*/
|
|
389
|
+
export function resolveMaterialRef(ref, sceneMaterials, shading = 'rendered') {
|
|
390
|
+
const parsed = parseMaterialRef(ref);
|
|
391
|
+
if (!parsed)
|
|
392
|
+
return null;
|
|
393
|
+
if (parsed.kind === 'library')
|
|
394
|
+
return createMaterialFromPresetRef(ref, shading);
|
|
395
|
+
const sceneMaterial = sceneMaterials?.[parsed.id];
|
|
396
|
+
if (!sceneMaterial)
|
|
397
|
+
return null;
|
|
398
|
+
return createMaterial(sceneMaterial.material, shading);
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Resolve a node kind's declared slot default — either a catalog `library:<id>`
|
|
402
|
+
* finish or a flat `#rrggbb` colour — to a renderable material. Shared by the
|
|
403
|
+
* procedural kinds whose colored-mode unpainted appearance comes from a
|
|
404
|
+
* declarative default (slab, wall).
|
|
405
|
+
*/
|
|
406
|
+
export function resolveSlotDefaultMaterial(slotDefault, shading = 'rendered', roughness = 0.9) {
|
|
407
|
+
if (parseMaterialRef(slotDefault)?.kind === 'library') {
|
|
408
|
+
return (createMaterialFromPresetRef(slotDefault, shading) ??
|
|
409
|
+
createDefaultMaterial('#ffffff', roughness, shading));
|
|
410
|
+
}
|
|
411
|
+
return createDefaultMaterial(slotDefault, roughness, shading);
|
|
412
|
+
}
|
|
339
413
|
export function createDefaultMaterial(color = '#ffffff', roughness = 0.9, shading = 'rendered', side = THREE.FrontSide) {
|
|
414
|
+
const resolvedSide = resolveNodeMaterialSide(side);
|
|
340
415
|
if (shading === 'solid') {
|
|
341
416
|
return new MeshLambertNodeMaterial({
|
|
342
417
|
color,
|
|
343
|
-
side,
|
|
418
|
+
side: resolvedSide,
|
|
344
419
|
});
|
|
345
420
|
}
|
|
346
421
|
return new MeshStandardNodeMaterial({
|
|
347
422
|
color,
|
|
348
423
|
roughness,
|
|
349
424
|
metalness: 0,
|
|
350
|
-
side,
|
|
425
|
+
side: resolvedSide,
|
|
351
426
|
});
|
|
352
427
|
}
|
|
353
428
|
function cachedDefaultMaterial(key, color, roughness, shading, side = THREE.FrontSide) {
|
|
@@ -356,6 +431,7 @@ function cachedDefaultMaterial(key, color, roughness, shading, side = THREE.Fron
|
|
|
356
431
|
if (cached)
|
|
357
432
|
return cached;
|
|
358
433
|
const material = createDefaultMaterial(color, roughness, shading, side);
|
|
434
|
+
material.userData.__pascalCachedMaterial = true;
|
|
359
435
|
defaultMaterialCache.set(cacheKey, material);
|
|
360
436
|
return material;
|
|
361
437
|
}
|
|
@@ -368,7 +444,7 @@ export function createSurfaceRoleMaterial(role, preset, side = THREE.FrontSide,
|
|
|
368
444
|
// on both gable faces on the first frame). Callers that need both sides
|
|
369
445
|
// visible (e.g. dormer back gable) must rotate the host mesh 180° so the
|
|
370
446
|
// FrontSide faces the viewer.
|
|
371
|
-
const resolvedSide = role === 'glazing' ? THREE.FrontSide : side;
|
|
447
|
+
const resolvedSide = role === 'glazing' ? THREE.FrontSide : resolveNodeMaterialSide(side ?? THREE.FrontSide);
|
|
372
448
|
const cacheKey = `${role}-${preset}-${resolvedSide}-${sceneThemeId ?? 'base'}`;
|
|
373
449
|
const cached = surfaceRoleMaterialCache.get(cacheKey);
|
|
374
450
|
if (cached)
|
|
@@ -390,10 +466,10 @@ export function createSurfaceRoleMaterial(role, preset, side = THREE.FrontSide,
|
|
|
390
466
|
return material;
|
|
391
467
|
}
|
|
392
468
|
export function baseMaterial(shading = 'rendered') {
|
|
393
|
-
return cachedDefaultMaterial('base', '#
|
|
469
|
+
return cachedDefaultMaterial('base', '#e9e7e3', 0.5, shading);
|
|
394
470
|
}
|
|
395
471
|
export function DEFAULT_WALL_MATERIAL(shading = 'rendered') {
|
|
396
|
-
return cachedDefaultMaterial('wall', '#
|
|
472
|
+
return cachedDefaultMaterial('wall', '#e9e6e0', 0.9, shading);
|
|
397
473
|
}
|
|
398
474
|
export function DEFAULT_SLAB_MATERIAL(shading = 'rendered') {
|
|
399
475
|
return cachedDefaultMaterial('slab', '#e5e5e5', 0.8, shading);
|
|
@@ -424,20 +500,21 @@ export function DEFAULT_WINDOW_MATERIAL(shading = 'rendered') {
|
|
|
424
500
|
roughness: 0.1,
|
|
425
501
|
metalness: 0.1,
|
|
426
502
|
});
|
|
503
|
+
maybeApplyGlassFresnel(material);
|
|
427
504
|
defaultMaterialCache.set(cacheKey, material);
|
|
428
505
|
return material;
|
|
429
506
|
}
|
|
430
507
|
export function DEFAULT_CEILING_MATERIAL(shading = 'rendered') {
|
|
431
|
-
return cachedDefaultMaterial('ceiling', '#
|
|
508
|
+
return cachedDefaultMaterial('ceiling', '#ebebd3', 0.95, shading);
|
|
432
509
|
}
|
|
433
510
|
export function DEFAULT_ROOF_MATERIAL(shading = 'rendered') {
|
|
434
511
|
return cachedDefaultMaterial('roof', '#808080', 0.85, shading);
|
|
435
512
|
}
|
|
436
513
|
export function DEFAULT_SHELF_MATERIAL(shading = 'rendered') {
|
|
437
|
-
return cachedDefaultMaterial('shelf', '#
|
|
514
|
+
return cachedDefaultMaterial('shelf', '#e9e6e0', 0.9, shading);
|
|
438
515
|
}
|
|
439
516
|
export function DEFAULT_STAIR_MATERIAL(shading = 'rendered') {
|
|
440
|
-
return cachedDefaultMaterial('stair', '#
|
|
517
|
+
return cachedDefaultMaterial('stair', '#e9e6e0', 0.9, shading);
|
|
441
518
|
}
|
|
442
519
|
export function disposeMaterial(material) {
|
|
443
520
|
material.dispose();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene-themes.d.ts","sourceRoot":"","sources":["../../src/lib/scene-themes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IAIZ,UAAU,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;IAIlB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,MAAM,EAAE,KAAK,CAAC;QACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;QAClC,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,MAAM,CAAA;QACjB,UAAU,CAAC,EAAE,OAAO,CAAA;KACrB,CAAC,CAAA;IACF,mBAAmB,EAAE,MAAM,CAAA;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;CACjD,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,UAAU,
|
|
1
|
+
{"version":3,"file":"scene-themes.d.ts","sourceRoot":"","sources":["../../src/lib/scene-themes.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAEnD,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAA;IACV,IAAI,EAAE,MAAM,CAAA;IAIZ,UAAU,EAAE,OAAO,GAAG,MAAM,CAAA;IAC5B,UAAU,EAAE,MAAM,CAAA;IAIlB,aAAa,CAAC,EAAE,MAAM,CAAA;IAItB,MAAM,EAAE,MAAM,CAAA;IACd,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IAC7C,IAAI,CAAC,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAA;IACzD,MAAM,EAAE,KAAK,CAAC;QACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;QAClC,KAAK,EAAE,MAAM,CAAA;QACb,SAAS,EAAE,MAAM,CAAA;QACjB,UAAU,CAAC,EAAE,OAAO,CAAA;KACrB,CAAC,CAAA;IACF,mBAAmB,EAAE,MAAM,CAAA;IAC3B,SAAS,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;CACjD,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,UAAU,EAoMpC,CAAA;AAED,eAAO,MAAM,eAAe,UAAwC,CAAA;AAIpE,wBAAgB,aAAa,CAAC,EAAE,EAAE,MAAM,GAAG,UAAU,CAEpD"}
|
package/dist/lib/scene-themes.js
CHANGED
|
@@ -3,13 +3,14 @@ export const SCENE_THEMES = [
|
|
|
3
3
|
id: 'studio',
|
|
4
4
|
name: 'Studio',
|
|
5
5
|
appearance: 'light',
|
|
6
|
-
background: '#
|
|
7
|
-
|
|
6
|
+
background: '#fbfbfa',
|
|
7
|
+
backgroundSky: '#b6cfe7',
|
|
8
|
+
ground: '#e9e7e2',
|
|
8
9
|
ambient: { color: '#ffffff', intensity: 0.15 },
|
|
9
|
-
hemi: { sky: '#ffffff', ground: '#aaa49a', intensity: 0.
|
|
10
|
+
hemi: { sky: '#ffffff', ground: '#aaa49a', intensity: 0.45 },
|
|
10
11
|
lights: [
|
|
11
12
|
{ position: [10, 10, 10], color: '#ffffff', intensity: 4, castShadow: true },
|
|
12
|
-
{ position: [-10, 10, -10], color: '#ffffff', intensity: 0.
|
|
13
|
+
{ position: [-10, 10, -10], color: '#ffffff', intensity: 0.6 },
|
|
13
14
|
],
|
|
14
15
|
toneMappingExposure: 0.9,
|
|
15
16
|
clayTints: {
|
|
@@ -25,6 +26,7 @@ export const SCENE_THEMES = [
|
|
|
25
26
|
name: 'Paper',
|
|
26
27
|
appearance: 'light',
|
|
27
28
|
background: '#ede9df',
|
|
29
|
+
backgroundSky: '#c0d2e4',
|
|
28
30
|
ground: '#e7e1d3',
|
|
29
31
|
ambient: { color: '#fff9eb', intensity: 0.55 },
|
|
30
32
|
hemi: { sky: '#fff5d9', ground: '#c2b89c', intensity: 0.35 },
|
|
@@ -46,6 +48,7 @@ export const SCENE_THEMES = [
|
|
|
46
48
|
name: 'Sunset',
|
|
47
49
|
appearance: 'light',
|
|
48
50
|
background: '#f6e8d4',
|
|
51
|
+
backgroundSky: '#b5bede',
|
|
49
52
|
ground: '#ecd9bf',
|
|
50
53
|
ambient: { color: '#ffd9a8', intensity: 0.45 },
|
|
51
54
|
hemi: { sky: '#ffd9a8', ground: '#5b4634', intensity: 0.4 },
|
|
@@ -67,11 +70,12 @@ export const SCENE_THEMES = [
|
|
|
67
70
|
name: 'Overcast',
|
|
68
71
|
appearance: 'light',
|
|
69
72
|
background: '#e6e7e6',
|
|
73
|
+
backgroundSky: '#c3ccd6',
|
|
70
74
|
ground: '#dadcd9',
|
|
71
75
|
ambient: { color: '#eef0ef', intensity: 1.1 },
|
|
72
76
|
hemi: { sky: '#f4f5f3', ground: '#bcbfbb', intensity: 0.9 },
|
|
73
77
|
lights: [{ position: [12, 28, 10], color: '#f4f5f3', intensity: 0.8, castShadow: true }],
|
|
74
|
-
toneMappingExposure: 0.
|
|
78
|
+
toneMappingExposure: 0.9,
|
|
75
79
|
clayTints: {
|
|
76
80
|
wall: '#dedfdc',
|
|
77
81
|
floor: '#cdcec9',
|
|
@@ -85,6 +89,7 @@ export const SCENE_THEMES = [
|
|
|
85
89
|
name: 'Blueprint',
|
|
86
90
|
appearance: 'light',
|
|
87
91
|
background: '#dde6ef',
|
|
92
|
+
backgroundSky: '#a5c4e2',
|
|
88
93
|
ground: '#c9d6e6',
|
|
89
94
|
ambient: { color: '#cfdcec', intensity: 0.7 },
|
|
90
95
|
hemi: { sky: '#dfeaf6', ground: '#5b6b80', intensity: 0.55 },
|
|
@@ -92,7 +97,7 @@ export const SCENE_THEMES = [
|
|
|
92
97
|
{ position: [16, 24, 12], color: '#e6efff', intensity: 1.8, castShadow: true },
|
|
93
98
|
{ position: [-12, 10, -8], color: '#9fb6d8', intensity: 0.4 },
|
|
94
99
|
],
|
|
95
|
-
toneMappingExposure: 0.
|
|
100
|
+
toneMappingExposure: 0.9,
|
|
96
101
|
clayTints: {
|
|
97
102
|
wall: '#9fb6d2',
|
|
98
103
|
floor: '#8ba2c2',
|
|
@@ -106,6 +111,7 @@ export const SCENE_THEMES = [
|
|
|
106
111
|
name: 'Mediterranean',
|
|
107
112
|
appearance: 'light',
|
|
108
113
|
background: '#bdd6e8',
|
|
114
|
+
backgroundSky: '#8ab4d6',
|
|
109
115
|
ground: '#ddd2bb',
|
|
110
116
|
ambient: { color: '#d6e6f3', intensity: 0.5 },
|
|
111
117
|
hemi: { sky: '#a8c8e2', ground: '#d8c9a4', intensity: 0.6 },
|
|
@@ -127,14 +133,15 @@ export const SCENE_THEMES = [
|
|
|
127
133
|
name: 'Twilight',
|
|
128
134
|
appearance: 'dark',
|
|
129
135
|
background: '#3a3550',
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
136
|
+
backgroundSky: '#272338',
|
|
137
|
+
ground: '#67618a',
|
|
138
|
+
ambient: { color: '#a89cc8', intensity: 0.55 },
|
|
139
|
+
hemi: { sky: '#d8a8c0', ground: '#3a3450', intensity: 0.7 },
|
|
133
140
|
lights: [
|
|
134
141
|
{ position: [-14, 22, -10], color: '#a4b6e8', intensity: 1.4, castShadow: true },
|
|
135
142
|
{ position: [14, 6, 8], color: '#ffb070', intensity: 0.9 },
|
|
136
143
|
],
|
|
137
|
-
toneMappingExposure:
|
|
144
|
+
toneMappingExposure: 0.9,
|
|
138
145
|
clayTints: {
|
|
139
146
|
wall: '#c5b9cf',
|
|
140
147
|
floor: '#ad9fbb',
|
|
@@ -148,12 +155,13 @@ export const SCENE_THEMES = [
|
|
|
148
155
|
name: 'Night',
|
|
149
156
|
appearance: 'dark',
|
|
150
157
|
background: '#1f2433',
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
158
|
+
backgroundSky: '#12161f',
|
|
159
|
+
ground: '#4a5470',
|
|
160
|
+
ambient: { color: '#a0b0ff', intensity: 0.25 },
|
|
161
|
+
hemi: { sky: '#3a4666', ground: '#232a3d', intensity: 0.55 },
|
|
154
162
|
lights: [
|
|
155
|
-
{ position: [10, 10, 10], color: '#e0e5ff', intensity:
|
|
156
|
-
{ position: [-10, 10, -10], color: '#8090ff', intensity: 0.
|
|
163
|
+
{ position: [10, 10, 10], color: '#e0e5ff', intensity: 1.2, castShadow: true },
|
|
164
|
+
{ position: [-10, 10, -10], color: '#8090ff', intensity: 0.3 },
|
|
157
165
|
],
|
|
158
166
|
toneMappingExposure: 0.9,
|
|
159
167
|
clayTints: {
|
|
@@ -169,6 +177,7 @@ export const SCENE_THEMES = [
|
|
|
169
177
|
name: 'Verdant',
|
|
170
178
|
appearance: 'light',
|
|
171
179
|
background: '#d6e4d2',
|
|
180
|
+
backgroundSky: '#aecde0',
|
|
172
181
|
ground: '#c7d6b4',
|
|
173
182
|
ambient: { color: '#e3efdd', intensity: 0.5 },
|
|
174
183
|
hemi: { sky: '#cfe6cf', ground: '#8ea06f', intensity: 0.65 },
|
|
@@ -176,7 +185,7 @@ export const SCENE_THEMES = [
|
|
|
176
185
|
{ position: [16, 22, 12], color: '#fff6d8', intensity: 3, castShadow: true },
|
|
177
186
|
{ position: [-12, 10, -8], color: '#bfe0c2', intensity: 0.5 },
|
|
178
187
|
],
|
|
179
|
-
toneMappingExposure: 0.
|
|
188
|
+
toneMappingExposure: 0.9,
|
|
180
189
|
clayTints: {
|
|
181
190
|
wall: '#eef0e6',
|
|
182
191
|
floor: '#d8ddc6',
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shadow-only.d.ts","sourceRoot":"","sources":["../../src/lib/shadow-only.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAuBrC,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CASpD;AAED,wBAAgB,eAAe,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI,CAOpD"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { SCENE_LAYER, SHADOW_ONLY_LAYER } from './layers';
|
|
2
|
+
/**
|
|
3
|
+
* Shadow-caster-only hiding: removes an object (and its descendants) from the
|
|
4
|
+
* color passes while keeping it in the shadow map, so a hidden roof or level
|
|
5
|
+
* still shadows the interior and sun enters through windows correctly.
|
|
6
|
+
*
|
|
7
|
+
* Uses layer masks instead of `visible = false` for two reasons: `visible`
|
|
8
|
+
* cascades (and, critically, prunes the object from the shadow pass too),
|
|
9
|
+
* while layers are tested per-object against the rendering camera — the main
|
|
10
|
+
* camera never enables {@link SHADOW_ONLY_LAYER}, but every shadow-casting
|
|
11
|
+
* light's shadow camera does (see `lights.tsx`).
|
|
12
|
+
*
|
|
13
|
+
* The original `layers.mask` is stashed under a private Symbol so
|
|
14
|
+
* {@link clearShadowOnly} restores the exact prior state. Both calls are
|
|
15
|
+
* idempotent and cheap to reapply.
|
|
16
|
+
*/
|
|
17
|
+
const ORIGINAL_LAYERS = Symbol('pascal:shadow-only:original-layers');
|
|
18
|
+
export function applyShadowOnly(root) {
|
|
19
|
+
root.traverse((obj) => {
|
|
20
|
+
const carrier = obj;
|
|
21
|
+
if (carrier[ORIGINAL_LAYERS] === undefined) {
|
|
22
|
+
carrier[ORIGINAL_LAYERS] = obj.layers.mask;
|
|
23
|
+
}
|
|
24
|
+
obj.layers.disable(SCENE_LAYER);
|
|
25
|
+
obj.layers.enable(SHADOW_ONLY_LAYER);
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
export function clearShadowOnly(root) {
|
|
29
|
+
root.traverse((obj) => {
|
|
30
|
+
const carrier = obj;
|
|
31
|
+
if (carrier[ORIGINAL_LAYERS] === undefined)
|
|
32
|
+
return;
|
|
33
|
+
obj.layers.mask = carrier[ORIGINAL_LAYERS];
|
|
34
|
+
delete carrier[ORIGINAL_LAYERS];
|
|
35
|
+
});
|
|
36
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* three runs at 0.185 but @types/three is pinned at 0.184: the 0.185 typings
|
|
3
|
+
* make tsgo's type inference allocate unboundedly (microsoft/typescript-go
|
|
4
|
+
* #2125 class) and OOM the machine. r185 renamed directionToColor /
|
|
5
|
+
* colorToDirection to packNormalToRGB / unpackRGBToNormal — re-export the new
|
|
6
|
+
* runtime names under the old names' signatures. Delete this file (and the
|
|
7
|
+
* @types/three pin) once tsgo handles the 0.185 types; the `typeof` references
|
|
8
|
+
* to the removed old names will fail the build as a reminder.
|
|
9
|
+
*/
|
|
10
|
+
export declare const packNormalToRGB: (node: import("three/webgpu").Node) => import("three/webgpu").Node<"vec3">;
|
|
11
|
+
export declare const unpackRGBToNormal: (node: import("three/webgpu").Node) => import("three/webgpu").Node<"vec3">;
|
|
12
|
+
//# sourceMappingURL=tsl-compat.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tsl-compat.d.ts","sourceRoot":"","sources":["../../src/lib/tsl-compat.ts"],"names":[],"mappings":"AAEA;;;;;;;;GAQG;AACH,eAAO,MAAM,eAAe,4EACV,CAAA;AAClB,eAAO,MAAM,iBAAiB,4EAEX,CAAA"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import * as TSL from 'three/tsl';
|
|
2
|
+
/**
|
|
3
|
+
* three runs at 0.185 but @types/three is pinned at 0.184: the 0.185 typings
|
|
4
|
+
* make tsgo's type inference allocate unboundedly (microsoft/typescript-go
|
|
5
|
+
* #2125 class) and OOM the machine. r185 renamed directionToColor /
|
|
6
|
+
* colorToDirection to packNormalToRGB / unpackRGBToNormal — re-export the new
|
|
7
|
+
* runtime names under the old names' signatures. Delete this file (and the
|
|
8
|
+
* @types/three pin) once tsgo handles the 0.185 types; the `typeof` references
|
|
9
|
+
* to the removed old names will fail the build as a reminder.
|
|
10
|
+
*/
|
|
11
|
+
export const packNormalToRGB = TSL
|
|
12
|
+
.packNormalToRGB;
|
|
13
|
+
export const unpackRGBToNormal = TSL.unpackRGBToNormal;
|