UNPKG

@openhps/core

Version:

Open Hybrid Positioning System - Core component

101 lines (95 loc) 3.48 kB
import { uniform } from '../core/UniformNode.js'; import { renderGroup } from '../core/UniformGroupNode.js'; import { Vector3 } from '../../math/Vector3.js'; import { cameraViewMatrix } from './Camera.js'; import { positionWorld } from './Position.js'; let uniformsLib; function getLightData(light) { uniformsLib = uniformsLib || new WeakMap(); let uniforms = uniformsLib.get(light); if (uniforms === undefined) uniformsLib.set(light, uniforms = {}); return uniforms; } /** * TSL function for getting a shadow matrix uniform node for the given light. * * @tsl * @function * @param {Light} light -The light source. * @returns {UniformNode<mat4>} The shadow matrix uniform node. */ export function lightShadowMatrix(light) { const data = getLightData(light); return data.shadowMatrix || (data.shadowMatrix = uniform('mat4').setGroup(renderGroup).onRenderUpdate(() => { if (light.castShadow !== true) { light.shadow.updateMatrices(light); } return light.shadow.matrix; })); } /** * TSL function for getting projected uv coordinates for the given light. * Relevant when using maps with spot lights. * * @tsl * @function * @param {Light} light -The light source. * @param {Node<vec3>} [position=positionWorld] -The position to project. * @returns {Node<vec3>} The projected uvs. */ export function lightProjectionUV(light, position = positionWorld) { const spotLightCoord = lightShadowMatrix(light).mul(position); const projectionUV = spotLightCoord.xyz.div(spotLightCoord.w); return projectionUV; } /** * TSL function for getting the position in world space for the given light. * * @tsl * @function * @param {Light} light -The light source. * @returns {UniformNode<vec3>} The light's position in world space. */ export function lightPosition(light) { const data = getLightData(light); return data.position || (data.position = uniform(new Vector3()).setGroup(renderGroup).onRenderUpdate((_, self) => self.value.setFromMatrixPosition(light.matrixWorld))); } /** * TSL function for getting the light target position in world space for the given light. * * @tsl * @function * @param {Light} light -The light source. * @returns {UniformNode<vec3>} The light target position in world space. */ export function lightTargetPosition(light) { const data = getLightData(light); return data.targetPosition || (data.targetPosition = uniform(new Vector3()).setGroup(renderGroup).onRenderUpdate((_, self) => self.value.setFromMatrixPosition(light.target.matrixWorld))); } /** * TSL function for getting the position in view space for the given light. * * @tsl * @function * @param {Light} light - The light source. * @returns {UniformNode<vec3>} The light's position in view space. */ export function lightViewPosition(light) { const data = getLightData(light); return data.viewPosition || (data.viewPosition = uniform(new Vector3()).setGroup(renderGroup).onRenderUpdate(({ camera }, self) => { self.value = self.value || new Vector3(); self.value.setFromMatrixPosition(light.matrixWorld); self.value.applyMatrix4(camera.matrixWorldInverse); })); } /** * TSL function for getting the light target direction for the given light. * * @tsl * @function * @param {Light} light -The light source. * @returns {Node<vec3>} The light's target direction. */ export const lightTargetDirection = light => cameraViewMatrix.transformDirection(lightPosition(light).sub(lightTargetPosition(light)));