@flighthq/camera 0.2.1-next.585.c7219b8 → 0.2.1-next.640.ec2ea9a
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/shadowCamera.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { AabbLike, Camera3D, Vector3Like } from '@flighthq/types';
|
|
2
2
|
export declare function configureDirectionalShadowCamera3D(camera: Camera3D, lightDirection: Readonly<Vector3Like>, sceneBounds: Readonly<AabbLike>): void;
|
|
3
|
+
export declare function configureDirectionalShadowCamera3DTightFit(camera: Camera3D, lightDirection: Readonly<Vector3Like>, worldBounds: Readonly<AabbLike>, padding?: number): void;
|
|
3
4
|
//# sourceMappingURL=shadowCamera.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadowCamera.d.ts","sourceRoot":"","sources":["../src/shadowCamera.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAavE,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAC9B,IAAI,CA8BN"}
|
|
1
|
+
{"version":3,"file":"shadowCamera.d.ts","sourceRoot":"","sources":["../src/shadowCamera.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAavE,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,GAC9B,IAAI,CA8BN;AAWD,wBAAgB,0CAA0C,CACxD,MAAM,EAAE,QAAQ,EAChB,cAAc,EAAE,QAAQ,CAAC,WAAW,CAAC,EACrC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,EAC/B,OAAO,SAAI,GACV,IAAI,CAgEN"}
|
package/dist/shadowCamera.js
CHANGED
|
@@ -36,6 +36,77 @@ export function configureDirectionalShadowCamera3D(camera, lightDirection, scene
|
|
|
36
36
|
camera.far = radius * 3; // distance + radius
|
|
37
37
|
camera.projection = createOrthographicProjection({ halfHeight: radius, halfWidth: radius });
|
|
38
38
|
}
|
|
39
|
+
// Configures a directional-light shadow camera with a tight light-space fit of `worldBounds`.
|
|
40
|
+
// Unlike configureDirectionalShadowCamera3D's rotation-stable bounding sphere, this transforms all
|
|
41
|
+
// eight world-AABB corners into the light view and independently fits the orthographic X/Y extents,
|
|
42
|
+
// preserving substantially more texel density for a large static architectural scene. `padding`
|
|
43
|
+
// multiplies every fitted half-extent (default 1); callers can raise it to absorb animated pose
|
|
44
|
+
// excursions outside bind-pose aggregate bounds.
|
|
45
|
+
//
|
|
46
|
+
// A tight fit of static whole-scene world bounds is stable. Re-fitting per-frame visible bounds
|
|
47
|
+
// requires texel snapping to avoid shimmering and is intentionally a separate, caller-composed pass.
|
|
48
|
+
export function configureDirectionalShadowCamera3DTightFit(camera, lightDirection, worldBounds, padding = 1) {
|
|
49
|
+
const min = worldBounds.min;
|
|
50
|
+
const max = worldBounds.max;
|
|
51
|
+
const hasBounds = min.x <= max.x && min.y <= max.y && min.z <= max.z;
|
|
52
|
+
const cx = hasBounds ? (min.x + max.x) * 0.5 : 0;
|
|
53
|
+
const cy = hasBounds ? (min.y + max.y) * 0.5 : 0;
|
|
54
|
+
const cz = hasBounds ? (min.z + max.z) * 0.5 : 0;
|
|
55
|
+
const ex = hasBounds ? (max.x - min.x) * 0.5 : 1;
|
|
56
|
+
const ey = hasBounds ? (max.y - min.y) * 0.5 : 1;
|
|
57
|
+
const ez = hasBounds ? (max.z - min.z) * 0.5 : 1;
|
|
58
|
+
const radius = Math.max(Math.hypot(ex, ey, ez), 1e-4);
|
|
59
|
+
const extentScale = padding > 0 ? padding : 1;
|
|
60
|
+
let dx = lightDirection.x;
|
|
61
|
+
let dy = lightDirection.y;
|
|
62
|
+
let dz = lightDirection.z;
|
|
63
|
+
const directionLength = Math.hypot(dx, dy, dz);
|
|
64
|
+
if (directionLength > 0) {
|
|
65
|
+
dx /= directionLength;
|
|
66
|
+
dy /= directionLength;
|
|
67
|
+
dz /= directionLength;
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
dx = 0;
|
|
71
|
+
dy = -1;
|
|
72
|
+
dz = 0;
|
|
73
|
+
}
|
|
74
|
+
// Pull back far enough that even padded depth extents remain in front of the camera. Translation
|
|
75
|
+
// along the view direction does not change the tight X/Y fit.
|
|
76
|
+
const distance = Math.max(radius * 2 * extentScale, 1);
|
|
77
|
+
_eye.x = cx - dx * distance;
|
|
78
|
+
_eye.y = cy - dy * distance;
|
|
79
|
+
_eye.z = cz - dz * distance;
|
|
80
|
+
_target.x = cx;
|
|
81
|
+
_target.y = cy;
|
|
82
|
+
_target.z = cz;
|
|
83
|
+
setCamera3DViewMatrix4FromLookAt(camera, _eye, _target, Math.abs(dy) > 0.99 ? _upZ : _upY);
|
|
84
|
+
const view = camera.view.m;
|
|
85
|
+
let halfWidth = 0;
|
|
86
|
+
let halfHeight = 0;
|
|
87
|
+
let minViewZ = Number.POSITIVE_INFINITY;
|
|
88
|
+
let maxViewZ = Number.NEGATIVE_INFINITY;
|
|
89
|
+
for (let corner = 0; corner < 8; corner++) {
|
|
90
|
+
const x = (corner & 1) === 0 ? cx - ex : cx + ex;
|
|
91
|
+
const y = (corner & 2) === 0 ? cy - ey : cy + ey;
|
|
92
|
+
const z = (corner & 4) === 0 ? cz - ez : cz + ez;
|
|
93
|
+
const viewX = view[0] * x + view[4] * y + view[8] * z + view[12];
|
|
94
|
+
const viewY = view[1] * x + view[5] * y + view[9] * z + view[13];
|
|
95
|
+
const viewZ = view[2] * x + view[6] * y + view[10] * z + view[14];
|
|
96
|
+
halfWidth = Math.max(halfWidth, Math.abs(viewX));
|
|
97
|
+
halfHeight = Math.max(halfHeight, Math.abs(viewY));
|
|
98
|
+
minViewZ = Math.min(minViewZ, viewZ);
|
|
99
|
+
maxViewZ = Math.max(maxViewZ, viewZ);
|
|
100
|
+
}
|
|
101
|
+
const depthCenter = (minViewZ + maxViewZ) * 0.5;
|
|
102
|
+
const halfDepth = Math.max((maxViewZ - minViewZ) * 0.5 * extentScale, 1e-4);
|
|
103
|
+
camera.near = Math.max(-depthCenter - halfDepth, 1e-4);
|
|
104
|
+
camera.far = Math.max(-depthCenter + halfDepth, camera.near + 1e-4);
|
|
105
|
+
camera.projection = createOrthographicProjection({
|
|
106
|
+
halfHeight: Math.max(halfHeight * extentScale, 1e-4),
|
|
107
|
+
halfWidth: Math.max(halfWidth * extentScale, 1e-4),
|
|
108
|
+
});
|
|
109
|
+
}
|
|
39
110
|
const _eye = { x: 0, y: 0, z: 0 };
|
|
40
111
|
const _target = { x: 0, y: 0, z: 0 };
|
|
41
112
|
const _upY = { x: 0, y: 1, z: 0 };
|
package/dist/shadowCamera.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shadowCamera.js","sourceRoot":"","sources":["../src/shadowCamera.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"shadowCamera.js","sourceRoot":"","sources":["../src/shadowCamera.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flighthq/camera",
|
|
3
|
-
"version": "0.2.1-next.
|
|
3
|
+
"version": "0.2.1-next.640.ec2ea9a",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/flighthq/flight.git",
|
|
@@ -32,9 +32,9 @@
|
|
|
32
32
|
"clean:dist": "tsx ../../scripts/clean-package-dist.ts"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@flighthq/entity": "0.2.1-next.
|
|
36
|
-
"@flighthq/geometry": "0.2.1-next.
|
|
37
|
-
"@flighthq/types": "0.2.1-next.
|
|
35
|
+
"@flighthq/entity": "0.2.1-next.640.ec2ea9a",
|
|
36
|
+
"@flighthq/geometry": "0.2.1-next.640.ec2ea9a",
|
|
37
|
+
"@flighthq/types": "0.2.1-next.640.ec2ea9a"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"typescript": "^5.3.0"
|
package/src/shadowCamera.test.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { OrthographicProjection } from '@flighthq/types';
|
|
|
3
3
|
|
|
4
4
|
import { createCamera3D } from './camera';
|
|
5
5
|
import { createPerspectiveProjection } from './projection';
|
|
6
|
-
import { configureDirectionalShadowCamera3D } from './shadowCamera';
|
|
6
|
+
import { configureDirectionalShadowCamera3D, configureDirectionalShadowCamera3DTightFit } from './shadowCamera';
|
|
7
7
|
|
|
8
8
|
function bounds() {
|
|
9
9
|
return createAabb(-1, -1, -1, 1, 1, 1);
|
|
@@ -43,3 +43,56 @@ describe('configureDirectionalShadowCamera3D', () => {
|
|
|
43
43
|
expect(camera.view.m[14]).toBeCloseTo(-distance);
|
|
44
44
|
});
|
|
45
45
|
});
|
|
46
|
+
|
|
47
|
+
describe('configureDirectionalShadowCamera3DTightFit', () => {
|
|
48
|
+
it('fits light-space orthographic extents more tightly than the rotation-stable sphere fit', () => {
|
|
49
|
+
const sphereCamera = createCamera3D({
|
|
50
|
+
far: 100,
|
|
51
|
+
near: 0.1,
|
|
52
|
+
projection: createPerspectiveProjection({ aspect: 1, fovY: 1 }),
|
|
53
|
+
});
|
|
54
|
+
const tightCamera = createCamera3D({
|
|
55
|
+
far: 100,
|
|
56
|
+
near: 0.1,
|
|
57
|
+
projection: createPerspectiveProjection({ aspect: 1, fovY: 1 }),
|
|
58
|
+
});
|
|
59
|
+
const sceneBounds = createAabb(-10, -1, -2, 10, 1, 2);
|
|
60
|
+
configureDirectionalShadowCamera3D(sphereCamera, { x: 0, y: -1, z: 0 }, sceneBounds);
|
|
61
|
+
configureDirectionalShadowCamera3DTightFit(tightCamera, { x: 0, y: -1, z: 0 }, sceneBounds);
|
|
62
|
+
|
|
63
|
+
const sphere = sphereCamera.projection as OrthographicProjection;
|
|
64
|
+
const tight = tightCamera.projection as OrthographicProjection;
|
|
65
|
+
expect(tight.halfWidth).toBeCloseTo(10);
|
|
66
|
+
expect(tight.halfHeight).toBeCloseTo(2);
|
|
67
|
+
expect(tight.halfWidth).toBeLessThan(sphere.halfWidth);
|
|
68
|
+
expect(tight.halfHeight).toBeLessThan(sphere.halfHeight);
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
it('multiplies fitted extents by padding', () => {
|
|
72
|
+
const camera = createCamera3D({
|
|
73
|
+
far: 100,
|
|
74
|
+
near: 0.1,
|
|
75
|
+
projection: createPerspectiveProjection({ aspect: 1, fovY: 1 }),
|
|
76
|
+
});
|
|
77
|
+
configureDirectionalShadowCamera3DTightFit(camera, { x: 0, y: -1, z: 0 }, bounds(), 1.5);
|
|
78
|
+
const projection = camera.projection as OrthographicProjection;
|
|
79
|
+
expect(projection.halfWidth).toBeCloseTo(1.5);
|
|
80
|
+
expect(projection.halfHeight).toBeCloseTo(1.5);
|
|
81
|
+
expect(camera.near).toBeGreaterThan(0);
|
|
82
|
+
expect(camera.far).toBeGreaterThan(camera.near);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it('falls back to a valid unit fit for empty bounds and a zero direction', () => {
|
|
86
|
+
const camera = createCamera3D({
|
|
87
|
+
far: 100,
|
|
88
|
+
near: 0.1,
|
|
89
|
+
projection: createPerspectiveProjection({ aspect: 1, fovY: 1 }),
|
|
90
|
+
});
|
|
91
|
+
configureDirectionalShadowCamera3DTightFit(camera, { x: 0, y: 0, z: 0 }, createAabb());
|
|
92
|
+
const projection = camera.projection as OrthographicProjection;
|
|
93
|
+
expect(projection.halfWidth).toBeGreaterThan(0);
|
|
94
|
+
expect(projection.halfHeight).toBeGreaterThan(0);
|
|
95
|
+
expect(camera.near).toBeGreaterThan(0);
|
|
96
|
+
expect(camera.far).toBeGreaterThan(camera.near);
|
|
97
|
+
});
|
|
98
|
+
});
|