UNPKG

three

Version:

JavaScript 3D library

102 lines (74 loc) 2.12 kB
import { Mesh, NodeMaterial, SphereGeometry } from 'three'; import { float, Fn, getShIrradianceAt, normalWorld, uniformArray, uniform, vec4 } from 'three/tsl'; /** * Renders a sphere to visualize a light probe in the scene. * * This helper can only be used with {@link WebGPURenderer}. * When using {@link WebGLRenderer}, import from `LightProbeHelper.js`. * * ```js * const helper = new LightProbeHelper( lightProbe ); * scene.add( helper ); * ``` * * @private * @augments Mesh */ class LightProbeHelper extends Mesh { /** * Constructs a new light probe helper. * * @param {LightProbe} lightProbe - The light probe to visualize. * @param {number} [size=1] - The size of the helper. */ constructor( lightProbe, size = 1 ) { const sh = uniformArray( lightProbe.sh.coefficients ); const intensity = uniform( lightProbe.intensity ); const RECIPROCAL_PI = float( 1 / Math.PI ); const fragmentNode = Fn( () => { const irradiance = getShIrradianceAt( normalWorld, sh ); const outgoingLight = RECIPROCAL_PI.mul( irradiance ).mul( intensity ); return vec4( outgoingLight, 1.0 ); } )(); const material = new NodeMaterial(); material.fragmentNode = fragmentNode; const geometry = new SphereGeometry( 1, 32, 16 ); super( geometry, material ); /** * The light probe to visualize. * * @type {LightProbe} */ this.lightProbe = lightProbe; /** * The size of the helper. * * @type {number} * @default 1 */ this.size = size; this.type = 'LightProbeHelper'; this._intensity = intensity; this._sh = sh; this.onBeforeRender(); } /** * Frees the GPU-related resources allocated by this instance. Call this * method whenever this instance is no longer used in your app. */ dispose() { this.geometry.dispose(); this.material.dispose(); } onBeforeRender() { this.position.copy( this.lightProbe.position ); this.scale.set( 1, 1, 1 ).multiplyScalar( this.size ); this._intensity.value = this.lightProbe.intensity; this._sh.array = this.lightProbe.sh.coefficients; } } export { LightProbeHelper };