UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

89 lines (85 loc) 3.04 kB
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 };