UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

264 lines (242 loc) 7.84 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.LightShadow = void 0; var _Matrix = require("../math/Matrix4.js"); var _Vector = require("../math/Vector2.js"); var _Vector2 = require("../math/Vector3.js"); var _Vector3 = require("../math/Vector4.js"); var _Frustum = require("../math/Frustum.js"); const _projScreenMatrix = /*@__PURE__*/new _Matrix.Matrix4(); const _lightPositionWorld = /*@__PURE__*/new _Vector2.Vector3(); const _lookTarget = /*@__PURE__*/new _Vector2.Vector3(); /** * Abstract base class for light shadow classes. These classes * represent the shadow configuration for different light types. * * @abstract */ class LightShadow { /** * Constructs a new light shadow. * * @param {Camera} camera - The light's view of the world. */ constructor(camera) { /** * The light's view of the world. * * @type {Camera} */ this.camera = camera; /** * The intensity of the shadow. The default is `1`. * Valid values are in the range `[0, 1]`. * * @type {number} * @default 1 */ this.intensity = 1; /** * Shadow map bias, how much to add or subtract from the normalized depth * when deciding whether a surface is in shadow. * * The default is `0`. Very tiny adjustments here (in the order of `0.0001`) * may help reduce artifacts in shadows. * * @type {number} * @default 0 */ this.bias = 0; /** * Defines how much the position used to query the shadow map is offset along * the object normal. The default is `0`. Increasing this value can be used to * reduce shadow acne especially in large scenes where light shines onto * geometry at a shallow angle. The cost is that shadows may appear distorted. * * @type {number} * @default 0 */ this.normalBias = 0; /** * Setting this to values greater than 1 will blur the edges of the shadow. * High values will cause unwanted banding effects in the shadows - a greater * map size will allow for a higher value to be used here before these effects * become visible. * * The property has no effect when the shadow map type is `PCFSoftShadowMap` and * and it is recommended to increase softness by decreasing the shadow map size instead. * * The property has no effect when the shadow map type is `BasicShadowMap`. * * @type {number} * @default 1 */ this.radius = 1; /** * The amount of samples to use when blurring a VSM shadow map. * * @type {number} * @default 8 */ this.blurSamples = 8; /** * Defines the width and height of the shadow map. Higher values give better quality * shadows at the cost of computation time. Values must be powers of two. * * @type {Vector2} * @default (512,512) */ this.mapSize = new _Vector.Vector2(512, 512); /** * The depth map generated using the internal camera; a location beyond a * pixel's depth is in shadow. Computed internally during rendering. * * @type {?RenderTarget} * @default null */ this.map = null; /** * The distribution map generated using the internal camera; an occlusion is * calculated based on the distribution of depths. Computed internally during * rendering. * * @type {?RenderTarget} * @default null */ this.mapPass = null; /** * Model to shadow camera space, to compute location and depth in shadow map. * This is computed internally during rendering. * * @type {Matrix4} */ this.matrix = new _Matrix.Matrix4(); /** * Enables automatic updates of the light's shadow. If you do not require dynamic * lighting / shadows, you may set this to `false`. * * @type {boolean} * @default true */ this.autoUpdate = true; /** * When set to `true`, shadow maps will be updated in the next `render` call. * If you have set {@link LightShadow#autoUpdate} to `false`, you will need to * set this property to `true` and then make a render call to update the light's shadow. * * @type {boolean} * @default false */ this.needsUpdate = false; this._frustum = new _Frustum.Frustum(); this._frameExtents = new _Vector.Vector2(1, 1); this._viewportCount = 1; this._viewports = [new _Vector3.Vector4(0, 0, 1, 1)]; } /** * Used internally by the renderer to get the number of viewports that need * to be rendered for this shadow. * * @return {number} The viewport count. */ getViewportCount() { return this._viewportCount; } /** * Gets the shadow cameras frustum. Used internally by the renderer to cull objects. * * @return {Frustum} The shadow camera frustum. */ getFrustum() { return this._frustum; } /** * 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. */ updateMatrices(light) { const shadowCamera = this.camera; const shadowMatrix = this.matrix; _lightPositionWorld.setFromMatrixPosition(light.matrixWorld); shadowCamera.position.copy(_lightPositionWorld); _lookTarget.setFromMatrixPosition(light.target.matrixWorld); shadowCamera.lookAt(_lookTarget); shadowCamera.updateMatrixWorld(); _projScreenMatrix.multiplyMatrices(shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse); this._frustum.setFromProjectionMatrix(_projScreenMatrix); shadowMatrix.set(0.5, 0.0, 0.0, 0.5, 0.0, 0.5, 0.0, 0.5, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0, 1.0); shadowMatrix.multiply(_projScreenMatrix); } /** * Returns a viewport definition for the given viewport index. * * @param {number} viewportIndex - The viewport index. * @return {Vector4} The viewport. */ getViewport(viewportIndex) { return this._viewports[viewportIndex]; } /** * Returns the frame extends. * * @return {Vector2} The frame extends. */ getFrameExtents() { return this._frameExtents; } /** * Frees the GPU-related resources allocated by this instance. Call this * method whenever this instance is no longer used in your app. */ dispose() { if (this.map) { this.map.dispose(); } if (this.mapPass) { this.mapPass.dispose(); } } /** * Copies the values of the given light shadow instance to this instance. * * @param {LightShadow} source - The light shadow to copy. * @return {LightShadow} A reference to this light shadow instance. */ copy(source) { this.camera = source.camera.clone(); this.intensity = source.intensity; this.bias = source.bias; this.radius = source.radius; this.mapSize.copy(source.mapSize); return this; } /** * Returns a new light shadow instance with copied values from this instance. * * @return {LightShadow} A clone of this instance. */ clone() { return new this.constructor().copy(this); } /** * Serializes the light shadow into JSON. * * @return {Object} A JSON object representing the serialized light shadow. * @see {@link ObjectLoader#parse} */ toJSON() { const object = {}; if (this.intensity !== 1) object.intensity = this.intensity; if (this.bias !== 0) object.bias = this.bias; if (this.normalBias !== 0) object.normalBias = this.normalBias; if (this.radius !== 1) object.radius = this.radius; if (this.mapSize.x !== 512 || this.mapSize.y !== 512) object.mapSize = this.mapSize.toArray(); object.camera = this.camera.toJSON(false).object; delete object.camera.matrix; return object; } } exports.LightShadow = LightShadow;