@pascal-app/viewer 1.0.6 → 1.1.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 +54 -21
- package/dist/components/viewer/daylight-atmosphere.d.ts +9 -0
- package/dist/components/viewer/daylight-atmosphere.d.ts.map +1 -0
- package/dist/components/viewer/daylight-atmosphere.js +315 -0
- package/dist/components/viewer/drone-controller.d.ts +15 -0
- package/dist/components/viewer/drone-controller.d.ts.map +1 -0
- package/dist/components/viewer/drone-controller.js +194 -0
- package/dist/components/viewer/glb-interactive.d.ts +4 -18
- package/dist/components/viewer/glb-interactive.d.ts.map +1 -1
- package/dist/components/viewer/glb-interactive.js +32 -268
- package/dist/components/viewer/glb-replace-instances.d.ts +6 -3
- package/dist/components/viewer/glb-replace-instances.d.ts.map +1 -1
- package/dist/components/viewer/glb-replace-instances.js +5 -4
- package/dist/components/viewer/glb-scene-motion.d.ts +8 -0
- package/dist/components/viewer/glb-scene-motion.d.ts.map +1 -0
- package/dist/components/viewer/glb-scene-motion.js +57 -0
- package/dist/components/viewer/glb-scene.d.ts +5 -1
- package/dist/components/viewer/glb-scene.d.ts.map +1 -1
- package/dist/components/viewer/glb-scene.js +290 -49
- package/dist/components/viewer/glb-selection-callout.d.ts +17 -0
- package/dist/components/viewer/glb-selection-callout.d.ts.map +1 -0
- package/dist/components/viewer/glb-selection-callout.js +54 -0
- package/dist/components/viewer/glb-walkthrough-controller.d.ts.map +1 -1
- package/dist/components/viewer/glb-walkthrough-controller.js +6 -3
- package/dist/components/viewer/index.d.ts +5 -0
- package/dist/components/viewer/index.d.ts.map +1 -1
- package/dist/components/viewer/index.js +38 -10
- package/dist/components/viewer/lights.d.ts.map +1 -1
- package/dist/components/viewer/lights.js +192 -5
- package/dist/components/viewer/post-processing.d.ts.map +1 -1
- package/dist/components/viewer/post-processing.js +150 -94
- package/dist/components/viewer/registered-systems.d.ts.map +1 -1
- package/dist/components/viewer/registered-systems.js +2 -2
- package/dist/components/viewer/scene-environment.js +4 -5
- package/dist/components/viewer/selection-callout.d.ts +51 -0
- package/dist/components/viewer/selection-callout.d.ts.map +1 -0
- package/dist/components/viewer/selection-callout.js +197 -0
- package/dist/components/viewer/unsupported-gpu-fallback.d.ts.map +1 -1
- package/dist/components/viewer/unsupported-gpu-fallback.js +21 -1
- package/dist/components/viewer/use-daylight-rooms.d.ts +13 -0
- package/dist/components/viewer/use-daylight-rooms.d.ts.map +1 -0
- package/dist/components/viewer/use-daylight-rooms.js +278 -0
- package/dist/components/viewer/viewer-camera.d.ts.map +1 -1
- package/dist/components/viewer/viewer-camera.js +12 -1
- package/dist/hooks/use-gltf-ktx2.d.ts.map +1 -1
- package/dist/hooks/use-gltf-ktx2.js +2 -1
- package/dist/index.d.ts +26 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +28 -8
- package/dist/lib/asset-url.d.ts +0 -1
- package/dist/lib/asset-url.d.ts.map +1 -1
- package/dist/lib/asset-url.js +3 -3
- package/dist/lib/daylight/ground.d.ts +21 -0
- package/dist/lib/daylight/ground.d.ts.map +1 -0
- package/dist/lib/daylight/ground.js +53 -0
- package/dist/lib/daylight/location.d.ts +32 -0
- package/dist/lib/daylight/location.d.ts.map +1 -0
- package/dist/lib/daylight/location.js +74 -0
- package/dist/lib/daylight/look.d.ts +33 -0
- package/dist/lib/daylight/look.d.ts.map +1 -0
- package/dist/lib/daylight/look.js +13 -0
- package/dist/lib/daylight/material-hooks.d.ts +2 -0
- package/dist/lib/daylight/material-hooks.d.ts.map +1 -0
- package/dist/lib/daylight/material-hooks.js +150 -0
- package/dist/lib/daylight/room-context.d.ts +12 -0
- package/dist/lib/daylight/room-context.d.ts.map +1 -0
- package/dist/lib/daylight/room-context.js +54 -0
- package/dist/lib/daylight/room-map.d.ts +124 -0
- package/dist/lib/daylight/room-map.d.ts.map +1 -0
- package/dist/lib/daylight/room-map.js +630 -0
- package/dist/lib/daylight/room-scene.d.ts +56 -0
- package/dist/lib/daylight/room-scene.d.ts.map +1 -0
- package/dist/lib/daylight/room-scene.js +391 -0
- package/dist/lib/daylight/rooms.d.ts +292 -0
- package/dist/lib/daylight/rooms.d.ts.map +1 -0
- package/dist/lib/daylight/rooms.js +1268 -0
- package/dist/lib/daylight/runtime.d.ts +33 -0
- package/dist/lib/daylight/runtime.d.ts.map +1 -0
- package/dist/lib/daylight/runtime.js +42 -0
- package/dist/lib/daylight/sky.d.ts +26 -0
- package/dist/lib/daylight/sky.d.ts.map +1 -0
- package/dist/lib/daylight/sky.js +217 -0
- package/dist/lib/daylight/solar.d.ts +46 -0
- package/dist/lib/daylight/solar.d.ts.map +1 -0
- package/dist/lib/daylight/solar.js +156 -0
- package/dist/lib/device-tier.d.ts +29 -0
- package/dist/lib/device-tier.d.ts.map +1 -0
- package/dist/lib/device-tier.js +71 -0
- package/dist/lib/dispose-object3d.d.ts.map +1 -1
- package/dist/lib/dispose-object3d.js +4 -2
- package/dist/lib/drone-flight.d.ts +44 -0
- package/dist/lib/drone-flight.d.ts.map +1 -0
- package/dist/lib/drone-flight.js +121 -0
- package/dist/lib/editor-highlight.d.ts +16 -0
- package/dist/lib/editor-highlight.d.ts.map +1 -0
- package/dist/lib/editor-highlight.js +33 -0
- package/dist/lib/foundation-materials.d.ts.map +1 -1
- package/dist/lib/foundation-materials.js +2 -4
- package/dist/lib/glb-merge.d.ts +23 -0
- package/dist/lib/glb-merge.d.ts.map +1 -0
- package/dist/lib/glb-merge.js +184 -0
- package/dist/lib/hardware-geometry.d.ts +21 -0
- package/dist/lib/hardware-geometry.d.ts.map +1 -0
- package/dist/lib/hardware-geometry.js +283 -0
- package/dist/lib/ktx2-loader.d.ts.map +1 -1
- package/dist/lib/ktx2-loader.js +2 -1
- package/dist/lib/layer-pass.d.ts +2 -0
- package/dist/lib/layer-pass.d.ts.map +1 -1
- package/dist/lib/layer-pass.js +20 -0
- package/dist/lib/materials.d.ts.map +1 -1
- package/dist/lib/materials.js +50 -23
- package/dist/lib/measurement-label.d.ts +4 -0
- package/dist/lib/measurement-label.d.ts.map +1 -0
- package/dist/lib/measurement-label.js +54 -0
- package/dist/lib/measurement-presentation.d.ts +5 -0
- package/dist/lib/measurement-presentation.d.ts.map +1 -0
- package/dist/lib/measurement-presentation.js +8 -0
- package/dist/lib/merged-outline-node.d.ts.map +1 -1
- package/dist/lib/merged-outline-node.js +7 -1
- package/dist/lib/occlusion-culler.d.ts +34 -0
- package/dist/lib/occlusion-culler.d.ts.map +1 -0
- package/dist/lib/occlusion-culler.js +698 -0
- package/dist/lib/pointer-events.d.ts.map +1 -1
- package/dist/lib/pointer-events.js +3 -3
- package/dist/lib/post-processing-resources.d.ts +4 -0
- package/dist/lib/post-processing-resources.d.ts.map +1 -1
- package/dist/lib/post-processing-resources.js +5 -0
- package/dist/lib/readback-rows.d.ts +14 -0
- package/dist/lib/readback-rows.d.ts.map +1 -0
- package/dist/lib/readback-rows.js +31 -0
- package/dist/lib/reveal-pose.d.ts.map +1 -1
- package/dist/lib/reveal-pose.js +3 -0
- package/dist/lib/scene-matrices.d.ts +12 -0
- package/dist/lib/scene-matrices.d.ts.map +1 -0
- package/dist/lib/scene-matrices.js +287 -0
- package/dist/lib/scene-pass-mrt.d.ts +5 -2
- package/dist/lib/scene-pass-mrt.d.ts.map +1 -1
- package/dist/lib/scene-pass-mrt.js +7 -2
- package/dist/lib/scene-themes.d.ts +0 -2
- package/dist/lib/scene-themes.d.ts.map +1 -1
- package/dist/lib/scene-themes.js +0 -2
- package/dist/lib/scene-visibility.d.ts +2 -0
- package/dist/lib/scene-visibility.d.ts.map +1 -1
- package/dist/lib/scene-visibility.js +12 -3
- package/dist/lib/site-surfaces.d.ts +1 -8
- package/dist/lib/site-surfaces.d.ts.map +1 -1
- package/dist/lib/site-surfaces.js +0 -19
- package/dist/lib/snapshot-pipeline.d.ts.map +1 -1
- package/dist/lib/snapshot-pipeline.js +24 -40
- package/dist/lib/texture-reference.d.ts.map +1 -1
- package/dist/lib/texture-reference.js +13 -10
- package/dist/lib/underground-ambiance.d.ts +0 -2
- package/dist/lib/underground-ambiance.d.ts.map +1 -1
- package/dist/lib/underground-ambiance.js +0 -2
- package/dist/lib/viewer-config.d.ts +21 -0
- package/dist/lib/viewer-config.d.ts.map +1 -0
- package/dist/lib/viewer-config.js +21 -0
- package/dist/lib/viewer-preference-storage.d.ts +7 -0
- package/dist/lib/viewer-preference-storage.d.ts.map +1 -0
- package/dist/lib/viewer-preference-storage.js +23 -0
- package/dist/store/use-item-light-pool.d.ts +3 -6
- package/dist/store/use-item-light-pool.d.ts.map +1 -1
- package/dist/store/use-item-light-pool.js +12 -0
- package/dist/store/use-viewer.d.ts +62 -59
- package/dist/store/use-viewer.d.ts.map +1 -1
- package/dist/store/use-viewer.js +106 -19
- package/dist/systems/ceiling/ceiling-system.d.ts +5 -0
- package/dist/systems/ceiling/ceiling-system.d.ts.map +1 -1
- package/dist/systems/ceiling/ceiling-system.js +11 -1
- package/dist/systems/door/door-system.d.ts.map +1 -1
- package/dist/systems/door/door-system.js +501 -145
- package/dist/systems/door/leaf-profile.d.ts +11 -0
- package/dist/systems/door/leaf-profile.d.ts.map +1 -0
- package/dist/systems/door/leaf-profile.js +140 -0
- package/dist/systems/elevator/elevator-interaction-system.d.ts +16 -2
- package/dist/systems/elevator/elevator-interaction-system.d.ts.map +1 -1
- package/dist/systems/elevator/elevator-interaction-system.js +41 -8
- package/dist/systems/geometry/geometry-status.d.ts +8 -0
- package/dist/systems/geometry/geometry-status.d.ts.map +1 -0
- package/dist/systems/geometry/geometry-status.js +24 -0
- package/dist/systems/interactive/callout-actions.d.ts +72 -0
- package/dist/systems/interactive/callout-actions.d.ts.map +1 -0
- package/dist/systems/interactive/callout-actions.js +212 -0
- package/dist/systems/interactive/interactive-system.d.ts +5 -1
- package/dist/systems/interactive/interactive-system.d.ts.map +1 -1
- package/dist/systems/interactive/interactive-system.js +44 -121
- package/dist/systems/interactive/opening-settled.d.ts +16 -0
- package/dist/systems/interactive/opening-settled.d.ts.map +1 -0
- package/dist/systems/interactive/opening-settled.js +53 -0
- package/dist/systems/item-light/item-light-system.d.ts.map +1 -1
- package/dist/systems/item-light/item-light-system.js +22 -214
- package/dist/systems/item-light/pooled-lights.d.ts +70 -0
- package/dist/systems/item-light/pooled-lights.d.ts.map +1 -0
- package/dist/systems/item-light/pooled-lights.js +449 -0
- package/dist/systems/level/level-system.d.ts.map +1 -1
- package/dist/systems/level/level-system.js +19 -1
- package/dist/systems/roof/roof-material-slots.d.ts +14 -0
- package/dist/systems/roof/roof-material-slots.d.ts.map +1 -0
- package/dist/systems/roof/roof-material-slots.js +13 -0
- package/dist/systems/roof/roof-materials.d.ts +25 -2
- package/dist/systems/roof/roof-materials.d.ts.map +1 -1
- package/dist/systems/roof/roof-materials.js +85 -26
- package/dist/systems/roof/roof-system.d.ts +34 -1
- package/dist/systems/roof/roof-system.d.ts.map +1 -1
- package/dist/systems/roof/roof-system.js +582 -168
- package/dist/systems/wall/opening-casing-geometry.d.ts +14 -0
- package/dist/systems/wall/opening-casing-geometry.d.ts.map +1 -0
- package/dist/systems/wall/opening-casing-geometry.js +102 -0
- package/dist/systems/wall/opening-cutout-geometry.d.ts +9 -0
- package/dist/systems/wall/opening-cutout-geometry.d.ts.map +1 -1
- package/dist/systems/wall/opening-cutout-geometry.js +7 -3
- package/dist/systems/wall/wall-materials.d.ts.map +1 -1
- package/dist/systems/wall/wall-materials.js +28 -35
- package/dist/systems/wall/wall-system.d.ts +11 -0
- package/dist/systems/wall/wall-system.d.ts.map +1 -1
- package/dist/systems/wall/wall-system.js +86 -25
- package/dist/systems/wall/wall-t-junctions.d.ts +15 -0
- package/dist/systems/wall/wall-t-junctions.d.ts.map +1 -0
- package/dist/systems/wall/wall-t-junctions.js +149 -0
- package/dist/systems/window/window-animation-system.d.ts +3 -12
- package/dist/systems/window/window-animation-system.d.ts.map +1 -1
- package/dist/systems/window/window-animation-system.js +37 -122
- package/dist/systems/window/window-pose.d.ts +31 -0
- package/dist/systems/window/window-pose.d.ts.map +1 -0
- package/dist/systems/window/window-pose.js +152 -0
- package/dist/systems/window/window-roller-shutter.d.ts +8 -0
- package/dist/systems/window/window-roller-shutter.d.ts.map +1 -0
- package/dist/systems/window/window-roller-shutter.js +64 -0
- package/dist/systems/window/window-system.d.ts +2 -11
- package/dist/systems/window/window-system.d.ts.map +1 -1
- package/dist/systems/window/window-system.js +470 -303
- package/package.json +6 -6
- package/dist/systems/interactive/control-widget.d.ts +0 -10
- package/dist/systems/interactive/control-widget.d.ts.map +0 -1
- package/dist/systems/interactive/control-widget.js +0 -35
- package/dist/systems/interactive/procedural-controls.d.ts +0 -13
- package/dist/systems/interactive/procedural-controls.d.ts.map +0 -1
- package/dist/systems/interactive/procedural-controls.js +0 -17
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { abs, cameraPosition, clamp, diffuseColor, diffuseRoughness, dot, float, hash, length, materialEmissive, max, mix, normalize, normalWorld, positionWorld, pow, smoothstep, vec3, vec4, } from 'three/tsl';
|
|
2
|
+
import { MeshBasicNodeMaterial, PhysicalLightingModel, MeshStandardNodeMaterial as StandardNodeMaterial, } from 'three/webgpu';
|
|
3
|
+
import { isHighlight } from '../editor-highlight';
|
|
4
|
+
import { SCENE_LAYER } from '../layers';
|
|
5
|
+
import { daylightRooms } from './rooms';
|
|
6
|
+
import { daylightUniforms, isDaylightRenderer } from './runtime';
|
|
7
|
+
/** sRGB 40 / 243 in linear: lo + c·(hi − lo). */
|
|
8
|
+
const ALBEDO_LO = 0.0212;
|
|
9
|
+
const ALBEDO_HI = 0.896;
|
|
10
|
+
function hooked(material, builder) {
|
|
11
|
+
// Physical materials own their lighting model; glass and other transparent surfaces keep theirs.
|
|
12
|
+
return (!material.isMeshPhysicalNodeMaterial &&
|
|
13
|
+
!material.transparent &&
|
|
14
|
+
isDaylightRenderer(builder.renderer));
|
|
15
|
+
}
|
|
16
|
+
function matte(material) {
|
|
17
|
+
return (material.metalness ?? 0) < 0.2 && (material.roughness ?? 1) >= 0.55;
|
|
18
|
+
}
|
|
19
|
+
function emitter(material) {
|
|
20
|
+
return (!material.emissiveNode &&
|
|
21
|
+
!isHighlight(material) &&
|
|
22
|
+
!!material.emissive &&
|
|
23
|
+
material.emissive.getHex() !== 0 &&
|
|
24
|
+
material.emissiveIntensity > 0);
|
|
25
|
+
}
|
|
26
|
+
/** Window/door glass (its slot, live or baked), item glass by material name, or flagged glass. */
|
|
27
|
+
function glass(material, object) {
|
|
28
|
+
if (!material.transparent || material.isMeshPhysicalNodeMaterial)
|
|
29
|
+
return false;
|
|
30
|
+
return (object?.userData?.slotId === 'glass' ||
|
|
31
|
+
material.userData.isGlass === true ||
|
|
32
|
+
/glass/i.test(material.name));
|
|
33
|
+
}
|
|
34
|
+
/** The enhanced viewer's glass: tint, near-mirror roughness, distance/Fresnel opacity, night glow. */
|
|
35
|
+
function tunedGlassNodes() {
|
|
36
|
+
const u = daylightUniforms;
|
|
37
|
+
const V = normalize(cameraPosition.sub(positionWorld));
|
|
38
|
+
const N = normalWorld;
|
|
39
|
+
const fresnel = pow(float(1).sub(abs(dot(N, V))), 5);
|
|
40
|
+
// /next trick: glass gets more opaque + reflective with distance and grazing angle, so façades
|
|
41
|
+
// read as glazing from the street while interiors stay visible up close.
|
|
42
|
+
const far = smoothstep(6, 30, length(cameraPosition.sub(positionWorld)));
|
|
43
|
+
// Night: warm radiance from the lit room behind the pane (strongest from outside / far away).
|
|
44
|
+
const behind = daylightRooms.roomAtNode(positionWorld.sub(N.mul(0.35)));
|
|
45
|
+
const front = daylightRooms.roomAtNode(positionWorld.add(N.mul(0.35)));
|
|
46
|
+
const room = max(behind, front);
|
|
47
|
+
// Pane tint = the room's actual lamp colour (18% towards white), dark when its lamps are off.
|
|
48
|
+
const lampRad = daylightRooms.roomGlowNode(room);
|
|
49
|
+
const tint = mix(lampRad, vec3(lampRad.dot(vec3(0.33))), 0.18);
|
|
50
|
+
// Per-room variation, like a game city: not every window equally bright.
|
|
51
|
+
const variation = mix(0.55, 1.0, hash(float(room).add(7.13)));
|
|
52
|
+
const strength = u.windowGlow
|
|
53
|
+
.mul(u.glowComp)
|
|
54
|
+
.mul(float(1).add(u.windowEmit.mul(1.8)))
|
|
55
|
+
.mul(variation)
|
|
56
|
+
.mul(mix(1.0, 0.35, fresnel))
|
|
57
|
+
.mul(mix(0.25, 1.0, u.cameraOutside))
|
|
58
|
+
.mul(mix(0.4, 1, far));
|
|
59
|
+
return {
|
|
60
|
+
colorNode: u.glassTint,
|
|
61
|
+
roughnessNode: float(0.04),
|
|
62
|
+
metalnessNode: float(0),
|
|
63
|
+
opacityNode: clamp(u.glassOpacity.add(far.mul(0.18)).add(fresnel.mul(0.7)), 0, 0.72),
|
|
64
|
+
emissiveNode: tint.mul(strength).mul(0.9),
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
let installed = false;
|
|
68
|
+
export function installDaylightMaterialHooks() {
|
|
69
|
+
if (installed)
|
|
70
|
+
return;
|
|
71
|
+
installed = true;
|
|
72
|
+
const proto = StandardNodeMaterial.prototype;
|
|
73
|
+
const setup = proto.setup;
|
|
74
|
+
proto.setup = function (builder) {
|
|
75
|
+
if (!isDaylightRenderer(builder.renderer) || !glass(this, builder.object))
|
|
76
|
+
return setup.call(this, builder);
|
|
77
|
+
// Build-time only: the tuned glass joins this compile without touching the material.
|
|
78
|
+
const own = this;
|
|
79
|
+
const nodes = tunedGlassNodes();
|
|
80
|
+
const saved = Object.fromEntries(Object.keys(nodes).map((key) => [key, own[key]]));
|
|
81
|
+
Object.assign(own, nodes);
|
|
82
|
+
try {
|
|
83
|
+
return setup.call(this, builder);
|
|
84
|
+
}
|
|
85
|
+
finally {
|
|
86
|
+
Object.assign(own, saved);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
const setupDiffuseColor = proto.setupDiffuseColor;
|
|
90
|
+
proto.setupDiffuseColor = function (builder) {
|
|
91
|
+
setupDiffuseColor.call(this, builder);
|
|
92
|
+
if (!hooked(this, builder))
|
|
93
|
+
return;
|
|
94
|
+
const rgb = diffuseColor.rgb;
|
|
95
|
+
const clamped = rgb.mul(ALBEDO_HI - ALBEDO_LO).add(ALBEDO_LO);
|
|
96
|
+
diffuseColor.assign(vec4(mix(rgb, clamped, daylightUniforms.albedoClamp), diffuseColor.a));
|
|
97
|
+
};
|
|
98
|
+
const setupVariants = proto.setupVariants;
|
|
99
|
+
proto.setupVariants = function (builder) {
|
|
100
|
+
setupVariants.call(this, builder);
|
|
101
|
+
if (hooked(this, builder) && matte(this))
|
|
102
|
+
diffuseRoughness.assign(daylightUniforms.eon);
|
|
103
|
+
};
|
|
104
|
+
const setupLightingModel = proto.setupLightingModel;
|
|
105
|
+
proto.setupLightingModel = function (builder) {
|
|
106
|
+
if (!hooked(this, builder) || !matte(this))
|
|
107
|
+
return setupLightingModel.call(this, builder);
|
|
108
|
+
// The eighth flag enables EON rough diffuse (fed by `diffuseRoughness` above).
|
|
109
|
+
return new PhysicalLightingModel(false, false, false, false, false, false, false, true);
|
|
110
|
+
};
|
|
111
|
+
const setupLighting = proto.setupLighting;
|
|
112
|
+
proto.setupLighting = function (builder) {
|
|
113
|
+
if (hooked(this, builder) && !this.emissiveNode && isHighlight(this)) {
|
|
114
|
+
// Editor highlights: the tint keeps its on-screen strength whatever the exposure.
|
|
115
|
+
this.emissiveNode = materialEmissive.mul(daylightUniforms.emitterExpInv);
|
|
116
|
+
try {
|
|
117
|
+
return setupLighting.call(this, builder);
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
this.emissiveNode = null;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
if (!hooked(this, builder) || !emitter(this))
|
|
124
|
+
return setupLighting.call(this, builder);
|
|
125
|
+
// Build-time only: the emission joins this compile without touching the material.
|
|
126
|
+
// Glowing surfaces (screens, signs; lamps get their own materials): brighter at night, kept
|
|
127
|
+
// out of the night exposure lift.
|
|
128
|
+
const u = daylightUniforms;
|
|
129
|
+
this.emissiveNode = materialEmissive.mul(float(1).add(u.lampLevel.mul(u.emissiveBoost).mul(u.glowComp)));
|
|
130
|
+
try {
|
|
131
|
+
return setupLighting.call(this, builder);
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
this.emissiveNode = null;
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
// Unlit scene surfaces: undo the metered exposure (zones and editor overlays are compensated in
|
|
138
|
+
// the post-processing, on their own layers; the sky capture is radiance and keeps it).
|
|
139
|
+
const basic = MeshBasicNodeMaterial.prototype;
|
|
140
|
+
const setupBasicLighting = basic.setupLighting;
|
|
141
|
+
basic.setupLighting = function (builder) {
|
|
142
|
+
const light = setupBasicLighting.call(this, builder);
|
|
143
|
+
const object = builder.object;
|
|
144
|
+
if (!isDaylightRenderer(builder.renderer) ||
|
|
145
|
+
this.userData.daylightSky === true ||
|
|
146
|
+
!object?.layers?.isEnabled(SCENE_LAYER))
|
|
147
|
+
return light;
|
|
148
|
+
return light.mul(daylightUniforms.emitterExpInv);
|
|
149
|
+
};
|
|
150
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
type N = any;
|
|
2
|
+
/**
|
|
3
|
+
* The daylight look's scene-pass lighting hooks: room light enters the material lighting as
|
|
4
|
+
* indirect irradiance (`getGI`, × albedo, × contact AO), the room enclosure dims the sky IBL
|
|
5
|
+
* (`getAO`), and outside surfaces receive the window spill and exterior lamps at night.
|
|
6
|
+
*
|
|
7
|
+
* Materials flagged `userData.noRooms` (the grounds) skip the room system: the dilated room
|
|
8
|
+
* map reaches ~20 cm past the walls and would light a strip of lawn.
|
|
9
|
+
*/
|
|
10
|
+
export declare function daylightRoomContext(): N;
|
|
11
|
+
export {};
|
|
12
|
+
//# sourceMappingURL=room-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"room-context.d.ts","sourceRoot":"","sources":["../../../src/lib/daylight/room-context.ts"],"names":[],"mappings":"AAaA,KAAK,CAAC,GAAG,GAAG,CAAA;AAKZ;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,IAAI,CAAC,CAqCvC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { context, diffuseColor, Fn, If, max, normalWorld, positionWorld, uniform, vec3, } from 'three/tsl';
|
|
2
|
+
import { daylightRooms } from './rooms';
|
|
3
|
+
/** Window spill only: receivers darker than this albedo are lit as if they had it (decal-style). */
|
|
4
|
+
const spillAlbedoFloor = uniform(0.35);
|
|
5
|
+
/**
|
|
6
|
+
* The daylight look's scene-pass lighting hooks: room light enters the material lighting as
|
|
7
|
+
* indirect irradiance (`getGI`, × albedo, × contact AO), the room enclosure dims the sky IBL
|
|
8
|
+
* (`getAO`), and outside surfaces receive the window spill and exterior lamps at night.
|
|
9
|
+
*
|
|
10
|
+
* Materials flagged `userData.noRooms` (the grounds) skip the room system: the dilated room
|
|
11
|
+
* map reaches ~20 cm past the walls and would light a strip of lawn.
|
|
12
|
+
*/
|
|
13
|
+
export function daylightRoomContext() {
|
|
14
|
+
const rooms = daylightRooms;
|
|
15
|
+
const room = rooms.probeRoomNode();
|
|
16
|
+
const roomNode = rooms.lightingNode(room);
|
|
17
|
+
const enclosure = roomNode.w;
|
|
18
|
+
const outsideMask = rooms.exteriorMaskNode(room);
|
|
19
|
+
// GI is later × albedo, so near-black paving would swallow the pools: lift dark receivers for
|
|
20
|
+
// the spill term only (like a light decal).
|
|
21
|
+
const lum = diffuseColor.rgb.dot(vec3(0.2126, 0.7152, 0.0722)).max(1e-3);
|
|
22
|
+
const albedoLift = lum.max(spillAlbedoFloor).div(lum);
|
|
23
|
+
const spill = rooms.exteriorSpillNode(positionWorld, normalWorld).mul(albedoLift);
|
|
24
|
+
const exteriorLamps = rooms.exteriorLampsNode(positionWorld, normalWorld);
|
|
25
|
+
// Inside a room the outside terms are masked to nothing anyway: skip their loops there.
|
|
26
|
+
const outsideLight = Fn(() => {
|
|
27
|
+
const light = vec3(0).toVar();
|
|
28
|
+
If(outsideMask.greaterThan(0), () => {
|
|
29
|
+
light.assign(spill.add(exteriorLamps).mul(outsideMask));
|
|
30
|
+
});
|
|
31
|
+
return light;
|
|
32
|
+
})();
|
|
33
|
+
return context({
|
|
34
|
+
getAO: (input, { material }) => {
|
|
35
|
+
if (material.transparent === true)
|
|
36
|
+
return input;
|
|
37
|
+
if (material.userData.noRooms)
|
|
38
|
+
return input;
|
|
39
|
+
return input !== null ? input.mul(enclosure) : enclosure;
|
|
40
|
+
},
|
|
41
|
+
getGI: (input, { material }) => {
|
|
42
|
+
if (material.transparent === true)
|
|
43
|
+
return input;
|
|
44
|
+
// The lighting model multiplies GI by the AO term again: undo it so room light keeps only
|
|
45
|
+
// the contact AO, and outside terms aren't dimmed by an enclosure they don't sit in.
|
|
46
|
+
let gi;
|
|
47
|
+
if (material.userData.noRooms)
|
|
48
|
+
gi = spill.add(exteriorLamps);
|
|
49
|
+
else
|
|
50
|
+
gi = outsideLight.add(roomNode.xyz).div(max(enclosure, 1e-3));
|
|
51
|
+
return input !== null ? input.add(gi) : gi;
|
|
52
|
+
},
|
|
53
|
+
});
|
|
54
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which room a point is in, at any scale: a sparse, tiled room-id map.
|
|
3
|
+
*
|
|
4
|
+
* Every level keeps its own map of 10 cm cells, cut into square tiles. A tile entirely inside one
|
|
5
|
+
* room (or outside every room) is a single value; only tiles a room edge crosses keep their cells,
|
|
6
|
+
* packed into one shared atlas. A level's rooms are grouped into clusters, each with its own tile
|
|
7
|
+
* rect, so open ground between distant rooms costs nothing. Memory then follows the length of the
|
|
8
|
+
* walls, not the site's area, and no texture grows with the number of floors. Tiles are built one
|
|
9
|
+
* at a time, so neither does the build.
|
|
10
|
+
*
|
|
11
|
+
* A point finds its level by height within its own building (a coarse directory lists the
|
|
12
|
+
* buildings near it), so neighbouring buildings with different floor heights, or a 40-storey
|
|
13
|
+
* tower, each keep their floors. Within a building, levels sorted by height stay sorted when they
|
|
14
|
+
* explode apart, so the search runs on live heights.
|
|
15
|
+
*/
|
|
16
|
+
type N = any;
|
|
17
|
+
export declare const CELL = 0.1;
|
|
18
|
+
/** Cells per tile side. */
|
|
19
|
+
export declare const TILE = 16;
|
|
20
|
+
/** Room ids are stored as two bytes (id + 1). */
|
|
21
|
+
export declare const MAX_ROOMS = 65535;
|
|
22
|
+
/** WebGPU guarantees 8192 texels a side; the renderer asks for no more. */
|
|
23
|
+
export declare const DEFAULT_TEXTURE_LIMIT = 8192;
|
|
24
|
+
export type MapLevel = {
|
|
25
|
+
/** World Y of the level's floor, assembled (not exploded). */
|
|
26
|
+
y: number;
|
|
27
|
+
/** Index of the level's building; levels of one building stack. */
|
|
28
|
+
building: number;
|
|
29
|
+
};
|
|
30
|
+
export type MapRoom = {
|
|
31
|
+
level: number;
|
|
32
|
+
/** World XZ. */
|
|
33
|
+
polygon: [number, number][];
|
|
34
|
+
holes?: [number, number][][];
|
|
35
|
+
};
|
|
36
|
+
/** One tile while it is being built, inside its row's dilated cells (with a margin all round). */
|
|
37
|
+
export type TileCells = {
|
|
38
|
+
level: number;
|
|
39
|
+
/** Site cell index of `cells[0]`. */
|
|
40
|
+
ci0: number;
|
|
41
|
+
cj0: number;
|
|
42
|
+
/** World XZ of `cells[0]`'s lower corner. */
|
|
43
|
+
x0: number;
|
|
44
|
+
z0: number;
|
|
45
|
+
/** Cells per buffer row. */
|
|
46
|
+
stride: number;
|
|
47
|
+
/** The tile's first cell in the buffer. */
|
|
48
|
+
i0: number;
|
|
49
|
+
j0: number;
|
|
50
|
+
/** Room index + 1 per cell, 0 outside. */
|
|
51
|
+
cells: Uint16Array;
|
|
52
|
+
/** Every cell of the tile itself holds the same value (no edge inside). */
|
|
53
|
+
uniform: boolean;
|
|
54
|
+
};
|
|
55
|
+
export declare class RoomMap {
|
|
56
|
+
/** The device's largest 2D texture side; set before `build`. */
|
|
57
|
+
textureLimit: number;
|
|
58
|
+
private levels;
|
|
59
|
+
/** Level indices sorted by building, then height: the order the GPU searches in. */
|
|
60
|
+
private order;
|
|
61
|
+
private position;
|
|
62
|
+
/** Per building: its range in `order`. */
|
|
63
|
+
private buildingRange;
|
|
64
|
+
private originX;
|
|
65
|
+
private originZ;
|
|
66
|
+
private dirTiles;
|
|
67
|
+
private dirW;
|
|
68
|
+
private dirH;
|
|
69
|
+
/** Per directory cell: the buildings whose rooms reach it. */
|
|
70
|
+
private dirLists;
|
|
71
|
+
private atlas;
|
|
72
|
+
private atlasTilesW;
|
|
73
|
+
private atlasTiles;
|
|
74
|
+
private indexBytes;
|
|
75
|
+
private warnedOverflow;
|
|
76
|
+
readonly u: {
|
|
77
|
+
origin: N;
|
|
78
|
+
dirTiles: import("three/webgpu").UniformNode<"int", number>;
|
|
79
|
+
dirW: import("three/webgpu").UniformNode<"int", number>;
|
|
80
|
+
dirH: import("three/webgpu").UniformNode<"int", number>;
|
|
81
|
+
/** One building: its level range is the only candidate (no directory reads). */
|
|
82
|
+
single: import("three/webgpu").UniformNode<"int", number>;
|
|
83
|
+
singleCount: import("three/webgpu").UniformNode<"int", number>;
|
|
84
|
+
/** Binary-search steps for the tallest building. */
|
|
85
|
+
searchSteps: import("three/webgpu").UniformNode<"int", number>;
|
|
86
|
+
atlasTilesW: import("three/webgpu").UniformNode<"int", number>;
|
|
87
|
+
indexW: import("three/webgpu").UniformNode<"int", number>;
|
|
88
|
+
index: N;
|
|
89
|
+
levels: N;
|
|
90
|
+
atlas: N;
|
|
91
|
+
};
|
|
92
|
+
private levelData;
|
|
93
|
+
/** Rebuild from rooms. `onTile` sees every built tile (the doorway search walks room edges). */
|
|
94
|
+
build(levels: MapLevel[], rooms: MapRoom[], onTile?: (tile: TileCells) => void): void;
|
|
95
|
+
/** CPU lookup in assembled space (same rule as the shader). */
|
|
96
|
+
roomAt(x: number, y: number, z: number): number;
|
|
97
|
+
/** A level's room at a point; clusters' rects can overlap (a wing around a courtyard pavilion). */
|
|
98
|
+
private levelRoomAt;
|
|
99
|
+
/** The level stacked right above `level` in its building, or −1. */
|
|
100
|
+
levelAbove(level: number): number;
|
|
101
|
+
/** Index the GPU uses for `level` (rooms store it). */
|
|
102
|
+
gpuLevel(level: number): number;
|
|
103
|
+
/**
|
|
104
|
+
* Live presentation per level (input order): explode offset, whether it is shown, and whether
|
|
105
|
+
* the levels over it are hidden (its rooms open to the sky from above).
|
|
106
|
+
*/
|
|
107
|
+
setPresentation(offsets: number[], shown: boolean[], focused: boolean[]): void;
|
|
108
|
+
memoryBytes(): number;
|
|
109
|
+
get stats(): {
|
|
110
|
+
atlasTiles: number;
|
|
111
|
+
dirW: number;
|
|
112
|
+
dirH: number;
|
|
113
|
+
};
|
|
114
|
+
private upload;
|
|
115
|
+
private indexTexel;
|
|
116
|
+
/** [liveY, clusterStart, clusterCount, 0] of the level at GPU position `pos`. */
|
|
117
|
+
levelTexel0(pos: N): N;
|
|
118
|
+
/** [0, 0, offset, flags] of the level at GPU position `pos`. */
|
|
119
|
+
levelTexel1(pos: N): N;
|
|
120
|
+
/** Room index (−1 outside) at a world-space position (live heights). */
|
|
121
|
+
roomAtNode: import("three/tsl").FnNode<[any], import("three/webgpu").VarNode<"int", import("three/webgpu").ConstNode<"int", number>>>;
|
|
122
|
+
}
|
|
123
|
+
export {};
|
|
124
|
+
//# sourceMappingURL=room-map.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"room-map.d.ts","sourceRoot":"","sources":["../../../src/lib/daylight/room-map.ts"],"names":[],"mappings":"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"}
|