@openhps/core
Version:
Open Hybrid Positioning System - Core component
89 lines (85 loc) • 3.04 kB
JavaScript
import { LightShadow } from './LightShadow.js';
import { PerspectiveCamera } from '../cameras/PerspectiveCamera.js';
import { Matrix4 } from '../math/Matrix4.js';
import { Vector2 } from '../math/Vector2.js';
import { Vector3 } from '../math/Vector3.js';
import { Vector4 } from '../math/Vector4.js';
const _projScreenMatrix = /*@__PURE__*/new Matrix4();
const _lightPositionWorld = /*@__PURE__*/new Vector3();
const _lookTarget = /*@__PURE__*/new Vector3();
/**
* Represents the shadow configuration of point lights.
*
* @augments LightShadow
*/
class PointLightShadow extends LightShadow {
/**
* Constructs a new point light shadow.
*/
constructor() {
super(new PerspectiveCamera(90, 1, 0.5, 500));
/**
* This flag can be used for type testing.
*
* @type {boolean}
* @readonly
* @default true
*/
this.isPointLightShadow = true;
this._frameExtents = new Vector2(4, 2);
this._viewportCount = 6;
this._viewports = [
// These viewports map a cube-map onto a 2D texture with the
// following orientation:
//
// xzXZ
// y Y
//
// X - Positive x direction
// x - Negative x direction
// Y - Positive y direction
// y - Negative y direction
// Z - Positive z direction
// z - Negative z direction
// positive X
new Vector4(2, 1, 1, 1),
// negative X
new Vector4(0, 1, 1, 1),
// positive Z
new Vector4(3, 1, 1, 1),
// negative Z
new Vector4(1, 1, 1, 1),
// positive Y
new Vector4(3, 0, 1, 1),
// negative Y
new Vector4(1, 0, 1, 1)];
this._cubeDirections = [new Vector3(1, 0, 0), new Vector3(-1, 0, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1), new Vector3(0, 1, 0), new Vector3(0, -1, 0)];
this._cubeUps = [new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 1, 0), new Vector3(0, 0, 1), new Vector3(0, 0, -1)];
}
/**
* Update the matrices for the camera and shadow, used internally by the renderer.
*
* @param {Light} light - The light for which the shadow is being rendered.
* @param {number} [viewportIndex=0] - The viewport index.
*/
updateMatrices(light, viewportIndex = 0) {
const camera = this.camera;
const shadowMatrix = this.matrix;
const far = light.distance || camera.far;
if (far !== camera.far) {
camera.far = far;
camera.updateProjectionMatrix();
}
_lightPositionWorld.setFromMatrixPosition(light.matrixWorld);
camera.position.copy(_lightPositionWorld);
_lookTarget.copy(camera.position);
_lookTarget.add(this._cubeDirections[viewportIndex]);
camera.up.copy(this._cubeUps[viewportIndex]);
camera.lookAt(_lookTarget);
camera.updateMatrixWorld();
shadowMatrix.makeTranslation(-_lightPositionWorld.x, -_lightPositionWorld.y, -_lightPositionWorld.z);
_projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);
this._frustum.setFromProjectionMatrix(_projScreenMatrix);
}
}
export { PointLightShadow };