diff --git a/build/three.cjs b/build/three.cjs index 9103baf3972206..28df5820edc50d 100644 --- a/build/three.cjs +++ b/build/three.cjs @@ -9713,17 +9713,68 @@ class WebGL3DRenderTarget extends WebGLRenderTarget { } /** - * Represents an axis-aligned bounding box (AABB) in 3D space. + * Represents a 4x4 matrix. + * + * The most common use of a 4x4 matrix in 3D computer graphics is as a transformation matrix. + * For an introduction to transformation matrices as used in WebGL, check out [this tutorial](https://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices) + * + * This allows a 3D vector representing a point in 3D space to undergo + * transformations such as translation, rotation, shear, scale, reflection, + * orthogonal or perspective projection and so on, by being multiplied by the + * matrix. This is known as `applying` the matrix to the vector. + * + * A Note on Row-Major and Column-Major Ordering: + * + * The constructor and {@link Matrix3#set} method take arguments in + * [row-major](https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order) + * order, while internally they are stored in the {@link Matrix3#elements} array in column-major order. + * This means that calling: + * ```js + * const m = new THREE.Matrix4(); + * m.set( 11, 12, 13, 14, + * 21, 22, 23, 24, + * 31, 32, 33, 34, + * 41, 42, 43, 44 ); + * ``` + * will result in the elements array containing: + * ```js + * m.elements = [ 11, 21, 31, 41, + * 12, 22, 32, 42, + * 13, 23, 33, 43, + * 14, 24, 34, 44 ]; + * ``` + * and internally all calculations are performed using column-major ordering. + * However, as the actual ordering makes no difference mathematically and + * most people are used to thinking about matrices in row-major order, the + * three.js documentation shows matrices in row-major order. Just bear in + * mind that if you are reading the source code, you'll have to take the + * transpose of any matrices outlined here to make sense of the calculations. */ -class Box3 { +class Matrix4 { /** - * Constructs a new bounding box. + * Constructs a new 4x4 matrix. The arguments are supposed to be + * in row-major order. If no arguments are provided, the constructor + * initializes the matrix as an identity matrix. * - * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box. - * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box. + * @param {number} [n11] - 1-1 matrix element. + * @param {number} [n12] - 1-2 matrix element. + * @param {number} [n13] - 1-3 matrix element. + * @param {number} [n14] - 1-4 matrix element. + * @param {number} [n21] - 2-1 matrix element. + * @param {number} [n22] - 2-2 matrix element. + * @param {number} [n23] - 2-3 matrix element. + * @param {number} [n24] - 2-4 matrix element. + * @param {number} [n31] - 3-1 matrix element. + * @param {number} [n32] - 3-2 matrix element. + * @param {number} [n33] - 3-3 matrix element. + * @param {number} [n34] - 3-4 matrix element. + * @param {number} [n41] - 4-1 matrix element. + * @param {number} [n42] - 4-2 matrix element. + * @param {number} [n43] - 4-3 matrix element. + * @param {number} [n44] - 4-4 matrix element. */ - constructor( min = new Vector3( + Infinity, + Infinity, + Infinity ), max = new Vector3( - Infinity, - Infinity, - Infinity ) ) { + constructor( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { /** * This flag can be used for type testing. @@ -9732,7910 +9783,4987 @@ class Box3 { * @readonly * @default true */ - this.isBox3 = true; + Matrix4.prototype.isMatrix4 = true; /** - * The lower boundary of the box. + * A column-major list of matrix values. * - * @type {Vector3} + * @type {Array} */ - this.min = min; + this.elements = [ - /** - * The upper boundary of the box. - * - * @type {Vector3} - */ - this.max = max; + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - } + ]; - /** - * Sets the lower and upper boundaries of this box. - * Please note that this method only copies the values from the given objects. - * - * @param {Vector3} min - The lower boundary of the box. - * @param {Vector3} max - The upper boundary of the box. - * @return {Box3} A reference to this bounding box. - */ - set( min, max ) { + if ( n11 !== undefined ) { - this.min.copy( min ); - this.max.copy( max ); + this.set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ); - return this; + } } /** - * Sets the upper and lower bounds of this box so it encloses the position data - * in the given array. + * Sets the elements of the matrix.The arguments are supposed to be + * in row-major order. * - * @param {Array} array - An array holding 3D position data. - * @return {Box3} A reference to this bounding box. + * @param {number} [n11] - 1-1 matrix element. + * @param {number} [n12] - 1-2 matrix element. + * @param {number} [n13] - 1-3 matrix element. + * @param {number} [n14] - 1-4 matrix element. + * @param {number} [n21] - 2-1 matrix element. + * @param {number} [n22] - 2-2 matrix element. + * @param {number} [n23] - 2-3 matrix element. + * @param {number} [n24] - 2-4 matrix element. + * @param {number} [n31] - 3-1 matrix element. + * @param {number} [n32] - 3-2 matrix element. + * @param {number} [n33] - 3-3 matrix element. + * @param {number} [n34] - 3-4 matrix element. + * @param {number} [n41] - 4-1 matrix element. + * @param {number} [n42] - 4-2 matrix element. + * @param {number} [n43] - 4-3 matrix element. + * @param {number} [n44] - 4-4 matrix element. + * @return {Matrix4} A reference to this matrix. */ - setFromArray( array ) { - - this.makeEmpty(); - - for ( let i = 0, il = array.length; i < il; i += 3 ) { + set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { - this.expandByPoint( _vector$b.fromArray( array, i ) ); + const te = this.elements; - } + te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; + te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; + te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; + te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; return this; } /** - * Sets the upper and lower bounds of this box so it encloses the position data - * in the given buffer attribute. + * Sets this matrix to the 4x4 identity matrix. * - * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data. - * @return {Box3} A reference to this bounding box. + * @return {Matrix4} A reference to this matrix. */ - setFromBufferAttribute( attribute ) { - - this.makeEmpty(); + identity() { - for ( let i = 0, il = attribute.count; i < il; i ++ ) { + this.set( - this.expandByPoint( _vector$b.fromBufferAttribute( attribute, i ) ); + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - } + ); return this; } /** - * Sets the upper and lower bounds of this box so it encloses the position data - * in the given array. + * Returns a matrix with copied values from this instance. * - * @param {Array} points - An array holding 3D position data as instances of {@link Vector3}. - * @return {Box3} A reference to this bounding box. + * @return {Matrix4} A clone of this instance. */ - setFromPoints( points ) { - - this.makeEmpty(); - - for ( let i = 0, il = points.length; i < il; i ++ ) { - - this.expandByPoint( points[ i ] ); - - } + clone() { - return this; + return new Matrix4().fromArray( this.elements ); } /** - * Centers this box on the given center vector and sets this box's width, height and - * depth to the given size values. + * Copies the values of the given matrix to this instance. * - * @param {Vector3} center - The center of the box. - * @param {Vector3} size - The x, y and z dimensions of the box. - * @return {Box3} A reference to this bounding box. + * @param {Matrix4} m - The matrix to copy. + * @return {Matrix4} A reference to this matrix. */ - setFromCenterAndSize( center, size ) { + copy( m ) { - const halfSize = _vector$b.copy( size ).multiplyScalar( 0.5 ); + const te = this.elements; + const me = m.elements; - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; + te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; + te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; + te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; return this; } /** - * Computes the world-axis-aligned bounding box for the given 3D object - * (including its children), accounting for the object's, and children's, - * world transforms. The function may result in a larger box than strictly necessary. + * Copies the translation component of the given matrix + * into this matrix's translation component. * - * @param {Object3D} object - The 3D object to compute the bounding box for. - * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest - * world-axis-aligned bounding box at the expense of more computation. - * @return {Box3} A reference to this bounding box. + * @param {Matrix4} m - The matrix to copy the translation component. + * @return {Matrix4} A reference to this matrix. */ - setFromObject( object, precise = false ) { + copyPosition( m ) { - this.makeEmpty(); + const te = this.elements, me = m.elements; - return this.expandByObject( object, precise ); + te[ 12 ] = me[ 12 ]; + te[ 13 ] = me[ 13 ]; + te[ 14 ] = me[ 14 ]; + + return this; } /** - * Returns a new box with copied values from this instance. + * Set the upper 3x3 elements of this matrix to the values of given 3x3 matrix. * - * @return {Box3} A clone of this instance. + * @param {Matrix3} m - The 3x3 matrix. + * @return {Matrix4} A reference to this matrix. */ - clone() { + setFromMatrix3( m ) { - return new this.constructor().copy( this ); + const me = m.elements; - } + this.set( - /** - * Copies the values of the given box to this instance. - * - * @param {Box3} box - The box to copy. - * @return {Box3} A reference to this bounding box. - */ - copy( box ) { + me[ 0 ], me[ 3 ], me[ 6 ], 0, + me[ 1 ], me[ 4 ], me[ 7 ], 0, + me[ 2 ], me[ 5 ], me[ 8 ], 0, + 0, 0, 0, 1 - this.min.copy( box.min ); - this.max.copy( box.max ); + ); return this; } /** - * Makes this box empty which means in encloses a zero space in 3D. + * Extracts the basis of this matrix into the three axis vectors provided. * - * @return {Box3} A reference to this bounding box. + * @param {Vector3} xAxis - The basis's x axis. + * @param {Vector3} yAxis - The basis's y axis. + * @param {Vector3} zAxis - The basis's z axis. + * @return {Matrix4} A reference to this matrix. */ - makeEmpty() { + extractBasis( xAxis, yAxis, zAxis ) { - this.min.x = this.min.y = this.min.z = + Infinity; - this.max.x = this.max.y = this.max.z = - Infinity; + if ( this.determinant() === 0 ) { - return this; + xAxis.set( 1, 0, 0 ); + yAxis.set( 0, 1, 0 ); + zAxis.set( 0, 0, 1 ); - } + return this; - /** - * Returns true if this box includes zero points within its bounds. - * Note that a box with equal lower and upper bounds still includes one - * point, the one both bounds share. - * - * @return {boolean} Whether this box is empty or not. - */ - isEmpty() { + } - // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + xAxis.setFromMatrixColumn( this, 0 ); + yAxis.setFromMatrixColumn( this, 1 ); + zAxis.setFromMatrixColumn( this, 2 ); - return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); + return this; } /** - * Returns the center point of this box. + * Sets the given basis vectors to this matrix. * - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The center point. + * @param {Vector3} xAxis - The basis's x axis. + * @param {Vector3} yAxis - The basis's y axis. + * @param {Vector3} zAxis - The basis's z axis. + * @return {Matrix4} A reference to this matrix. */ - getCenter( target ) { - - return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); - - } + makeBasis( xAxis, yAxis, zAxis ) { - /** - * Returns the dimensions of this box. - * - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The size. - */ - getSize( target ) { + this.set( + xAxis.x, yAxis.x, zAxis.x, 0, + xAxis.y, yAxis.y, zAxis.y, 0, + xAxis.z, yAxis.z, zAxis.z, 0, + 0, 0, 0, 1 + ); - return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); + return this; } /** - * Expands the boundaries of this box to include the given point. + * Extracts the rotation component of the given matrix + * into this matrix's rotation component. * - * @param {Vector3} point - The point that should be included by the bounding box. - * @return {Box3} A reference to this bounding box. + * Note: This method does not support reflection matrices. + * + * @param {Matrix4} m - The matrix. + * @return {Matrix4} A reference to this matrix. */ - expandByPoint( point ) { + extractRotation( m ) { - this.min.min( point ); - this.max.max( point ); + if ( m.determinant() === 0 ) { - return this; + return this.identity(); - } + } - /** - * Expands this box equilaterally by the given vector. The width of this - * box will be expanded by the x component of the vector in both - * directions. The height of this box will be expanded by the y component of - * the vector in both directions. The depth of this box will be - * expanded by the z component of the vector in both directions. - * - * @param {Vector3} vector - The vector that should expand the bounding box. - * @return {Box3} A reference to this bounding box. - */ - expandByVector( vector ) { + const te = this.elements; + const me = m.elements; - this.min.sub( vector ); - this.max.add( vector ); + const scaleX = 1 / _v1$7.setFromMatrixColumn( m, 0 ).length(); + const scaleY = 1 / _v1$7.setFromMatrixColumn( m, 1 ).length(); + const scaleZ = 1 / _v1$7.setFromMatrixColumn( m, 2 ).length(); - return this; + te[ 0 ] = me[ 0 ] * scaleX; + te[ 1 ] = me[ 1 ] * scaleX; + te[ 2 ] = me[ 2 ] * scaleX; + te[ 3 ] = 0; - } + te[ 4 ] = me[ 4 ] * scaleY; + te[ 5 ] = me[ 5 ] * scaleY; + te[ 6 ] = me[ 6 ] * scaleY; + te[ 7 ] = 0; - /** - * Expands each dimension of the box by the given scalar. If negative, the - * dimensions of the box will be contracted. - * - * @param {number} scalar - The scalar value that should expand the bounding box. - * @return {Box3} A reference to this bounding box. - */ - expandByScalar( scalar ) { + te[ 8 ] = me[ 8 ] * scaleZ; + te[ 9 ] = me[ 9 ] * scaleZ; + te[ 10 ] = me[ 10 ] * scaleZ; + te[ 11 ] = 0; - this.min.addScalar( - scalar ); - this.max.addScalar( scalar ); + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; return this; } /** - * Expands the boundaries of this box to include the given 3D object and - * its children, accounting for the object's, and children's, world - * transforms. The function may result in a larger box than strictly - * necessary (unless the precise parameter is set to true). + * Sets the rotation component (the upper left 3x3 matrix) of this matrix to + * the rotation specified by the given Euler angles. The rest of + * the matrix is set to the identity. Depending on the {@link Euler#order}, + * there are six possible outcomes. See [this page](https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix) + * for a complete list. * - * @param {Object3D} object - The 3D object that should expand the bounding box. - * @param {boolean} precise - If set to `true`, the method expands the bounding box - * as little as necessary at the expense of more computation. - * @return {Box3} A reference to this bounding box. + * @param {Euler} euler - The Euler angles. + * @return {Matrix4} A reference to this matrix. */ - expandByObject( object, precise = false ) { - - // Computes the world-axis-aligned bounding box of an object (including its children), - // accounting for both the object's, and children's, world transforms + makeRotationFromEuler( euler ) { - object.updateWorldMatrix( false, false ); + const te = this.elements; - const geometry = object.geometry; + const x = euler.x, y = euler.y, z = euler.z; + const a = Math.cos( x ), b = Math.sin( x ); + const c = Math.cos( y ), d = Math.sin( y ); + const e = Math.cos( z ), f = Math.sin( z ); - if ( geometry !== undefined ) { + if ( euler.order === 'XYZ' ) { - const positionAttribute = geometry.getAttribute( 'position' ); + const ae = a * e, af = a * f, be = b * e, bf = b * f; - // precise AABB computation based on vertex data requires at least a position attribute. - // instancing isn't supported so far and uses the normal (conservative) code path. + te[ 0 ] = c * e; + te[ 4 ] = - c * f; + te[ 8 ] = d; - if ( precise === true && positionAttribute !== undefined && object.isInstancedMesh !== true ) { + te[ 1 ] = af + be * d; + te[ 5 ] = ae - bf * d; + te[ 9 ] = - b * c; - for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) { + te[ 2 ] = bf - ae * d; + te[ 6 ] = be + af * d; + te[ 10 ] = a * c; - if ( object.isMesh === true ) { + } else if ( euler.order === 'YXZ' ) { - object.getVertexPosition( i, _vector$b ); + const ce = c * e, cf = c * f, de = d * e, df = d * f; - } else { + te[ 0 ] = ce + df * b; + te[ 4 ] = de * b - cf; + te[ 8 ] = a * d; - _vector$b.fromBufferAttribute( positionAttribute, i ); + te[ 1 ] = a * f; + te[ 5 ] = a * e; + te[ 9 ] = - b; - } + te[ 2 ] = cf * b - de; + te[ 6 ] = df + ce * b; + te[ 10 ] = a * c; - _vector$b.applyMatrix4( object.matrixWorld ); - this.expandByPoint( _vector$b ); + } else if ( euler.order === 'ZXY' ) { - } + const ce = c * e, cf = c * f, de = d * e, df = d * f; - } else { + te[ 0 ] = ce - df * b; + te[ 4 ] = - a * f; + te[ 8 ] = de + cf * b; - if ( object.boundingBox !== undefined ) { + te[ 1 ] = cf + de * b; + te[ 5 ] = a * e; + te[ 9 ] = df - ce * b; - // object-level bounding box + te[ 2 ] = - a * d; + te[ 6 ] = b; + te[ 10 ] = a * c; - if ( object.boundingBox === null ) { + } else if ( euler.order === 'ZYX' ) { - object.computeBoundingBox(); + const ae = a * e, af = a * f, be = b * e, bf = b * f; - } + te[ 0 ] = c * e; + te[ 4 ] = be * d - af; + te[ 8 ] = ae * d + bf; - _box$4.copy( object.boundingBox ); + te[ 1 ] = c * f; + te[ 5 ] = bf * d + ae; + te[ 9 ] = af * d - be; + te[ 2 ] = - d; + te[ 6 ] = b * c; + te[ 10 ] = a * c; - } else { + } else if ( euler.order === 'YZX' ) { - // geometry-level bounding box + const ac = a * c, ad = a * d, bc = b * c, bd = b * d; - if ( geometry.boundingBox === null ) { + te[ 0 ] = c * e; + te[ 4 ] = bd - ac * f; + te[ 8 ] = bc * f + ad; - geometry.computeBoundingBox(); + te[ 1 ] = f; + te[ 5 ] = a * e; + te[ 9 ] = - b * e; - } + te[ 2 ] = - d * e; + te[ 6 ] = ad * f + bc; + te[ 10 ] = ac - bd * f; - _box$4.copy( geometry.boundingBox ); + } else if ( euler.order === 'XZY' ) { - } + const ac = a * c, ad = a * d, bc = b * c, bd = b * d; - _box$4.applyMatrix4( object.matrixWorld ); + te[ 0 ] = c * e; + te[ 4 ] = - f; + te[ 8 ] = d * e; - this.union( _box$4 ); + te[ 1 ] = ac * f + bd; + te[ 5 ] = a * e; + te[ 9 ] = ad * f - bc; - } + te[ 2 ] = bc * f - ad; + te[ 6 ] = b * e; + te[ 10 ] = bd * f + ac; } - const children = object.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - this.expandByObject( children[ i ], precise ); + // bottom row + te[ 3 ] = 0; + te[ 7 ] = 0; + te[ 11 ] = 0; - } + // last column + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; return this; } /** - * Returns `true` if the given point lies within or on the boundaries of this box. + * Sets the rotation component of this matrix to the rotation specified by + * the given Quaternion as outlined [here](https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion) + * The rest of the matrix is set to the identity. * - * @param {Vector3} point - The point to test. - * @return {boolean} Whether the bounding box contains the given point or not. + * @param {Quaternion} q - The Quaternion. + * @return {Matrix4} A reference to this matrix. */ - containsPoint( point ) { + makeRotationFromQuaternion( q ) { - return point.x >= this.min.x && point.x <= this.max.x && - point.y >= this.min.y && point.y <= this.max.y && - point.z >= this.min.z && point.z <= this.max.z; + return this.compose( _zero, q, _one ); } /** - * Returns `true` if this bounding box includes the entirety of the given bounding box. - * If this box and the given one are identical, this function also returns `true`. + * Sets the rotation component of the transformation matrix, looking from `eye` towards + * `target`, and oriented by the up-direction. * - * @param {Box3} box - The bounding box to test. - * @return {boolean} Whether the bounding box contains the given bounding box or not. + * @param {Vector3} eye - The eye vector. + * @param {Vector3} target - The target vector. + * @param {Vector3} up - The up vector. + * @return {Matrix4} A reference to this matrix. */ - containsBox( box ) { + lookAt( eye, target, up ) { - return this.min.x <= box.min.x && box.max.x <= this.max.x && - this.min.y <= box.min.y && box.max.y <= this.max.y && - this.min.z <= box.min.z && box.max.z <= this.max.z; + const te = this.elements; + + _z.subVectors( eye, target ); + + if ( _z.lengthSq() === 0 ) { + + // eye and target are in the same position + + _z.z = 1; + + } + + _z.normalize(); + _x.crossVectors( up, _z ); + + if ( _x.lengthSq() === 0 ) { + + // up and z are parallel + + if ( Math.abs( up.z ) === 1 ) { + + _z.x += 0.0001; + + } else { + + _z.z += 0.0001; + + } + + _z.normalize(); + _x.crossVectors( up, _z ); + + } + + _x.normalize(); + _y.crossVectors( _z, _x ); + + te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; + te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; + te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; + + return this; } /** - * Returns a point as a proportion of this box's width, height and depth. + * Post-multiplies this matrix by the given 4x4 matrix. * - * @param {Vector3} point - A point in 3D space. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} A point as a proportion of this box's width, height and depth. + * @param {Matrix4} m - The matrix to multiply with. + * @return {Matrix4} A reference to this matrix. */ - getParameter( point, target ) { + multiply( m ) { - // This can potentially have a divide by zero if the box - // has a size dimension of 0. + return this.multiplyMatrices( this, m ); - return target.set( - ( point.x - this.min.x ) / ( this.max.x - this.min.x ), - ( point.y - this.min.y ) / ( this.max.y - this.min.y ), - ( point.z - this.min.z ) / ( this.max.z - this.min.z ) - ); + } + + /** + * Pre-multiplies this matrix by the given 4x4 matrix. + * + * @param {Matrix4} m - The matrix to multiply with. + * @return {Matrix4} A reference to this matrix. + */ + premultiply( m ) { + + return this.multiplyMatrices( m, this ); } /** - * Returns `true` if the given bounding box intersects with this bounding box. + * Multiples the given 4x4 matrices and stores the result + * in this matrix. * - * @param {Box3} box - The bounding box to test. - * @return {boolean} Whether the given bounding box intersects with this bounding box. + * @param {Matrix4} a - The first matrix. + * @param {Matrix4} b - The second matrix. + * @return {Matrix4} A reference to this matrix. */ - intersectsBox( box ) { + multiplyMatrices( a, b ) { - // using 6 splitting planes to rule out intersections. - return box.max.x >= this.min.x && box.min.x <= this.max.x && - box.max.y >= this.min.y && box.min.y <= this.max.y && - box.max.z >= this.min.z && box.min.z <= this.max.z; + const ae = a.elements; + const be = b.elements; + const te = this.elements; + + const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; + const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; + const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; + const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; + + const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; + const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; + const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; + const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; + + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; + te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; + te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; + te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; + + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; + te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; + te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; + te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; + + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; + te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; + te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; + te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; + + te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; + te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; + te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; + te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; + + return this; } /** - * Returns `true` if the given bounding sphere intersects with this bounding box. + * Multiplies every component of the matrix by the given scalar. * - * @param {Sphere} sphere - The bounding sphere to test. - * @return {boolean} Whether the given bounding sphere intersects with this bounding box. + * @param {number} s - The scalar. + * @return {Matrix4} A reference to this matrix. */ - intersectsSphere( sphere ) { + multiplyScalar( s ) { - // Find the point on the AABB closest to the sphere center. - this.clampPoint( sphere.center, _vector$b ); + const te = this.elements; - // If that point is inside the sphere, the AABB and sphere intersect. - return _vector$b.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); + te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; + te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; + te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; + te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; + + return this; } /** - * Returns `true` if the given plane intersects with this bounding box. + * Computes and returns the determinant of this matrix. * - * @param {Plane} plane - The plane to test. - * @return {boolean} Whether the given plane intersects with this bounding box. + * Based on the method outlined [here](http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html). + * + * @return {number} The determinant. */ - intersectsPlane( plane ) { + determinant() { - // We compute the minimum and maximum dot product values. If those values - // are on the same side (back or front) of the plane, then there is no intersection. + const te = this.elements; - let min, max; + const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; + const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; + const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; + const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - if ( plane.normal.x > 0 ) { + const t11 = n23 * n34 - n24 * n33; + const t12 = n22 * n34 - n24 * n32; + const t13 = n22 * n33 - n23 * n32; - min = plane.normal.x * this.min.x; - max = plane.normal.x * this.max.x; + const t21 = n21 * n34 - n24 * n31; + const t22 = n21 * n33 - n23 * n31; + const t23 = n21 * n32 - n22 * n31; - } else { + return n11 * ( n42 * t11 - n43 * t12 + n44 * t13 ) - + n12 * ( n41 * t11 - n43 * t21 + n44 * t22 ) + + n13 * ( n41 * t12 - n42 * t21 + n44 * t23 ) - + n14 * ( n41 * t13 - n42 * t22 + n43 * t23 ); - min = plane.normal.x * this.max.x; - max = plane.normal.x * this.min.x; + } - } + /** + * Transposes this matrix in place. + * + * @return {Matrix4} A reference to this matrix. + */ + transpose() { - if ( plane.normal.y > 0 ) { + const te = this.elements; + let tmp; - min += plane.normal.y * this.min.y; - max += plane.normal.y * this.max.y; + tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; + tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; + tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; - } else { + tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; + tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; + tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; - min += plane.normal.y * this.max.y; - max += plane.normal.y * this.min.y; + return this; - } + } - if ( plane.normal.z > 0 ) { + /** + * Sets the position component for this matrix from the given vector, + * without affecting the rest of the matrix. + * + * @param {number|Vector3} x - The x component of the vector or alternatively the vector object. + * @param {number} y - The y component of the vector. + * @param {number} z - The z component of the vector. + * @return {Matrix4} A reference to this matrix. + */ + setPosition( x, y, z ) { - min += plane.normal.z * this.min.z; - max += plane.normal.z * this.max.z; + const te = this.elements; + + if ( x.isVector3 ) { + + te[ 12 ] = x.x; + te[ 13 ] = x.y; + te[ 14 ] = x.z; } else { - min += plane.normal.z * this.max.z; - max += plane.normal.z * this.min.z; + te[ 12 ] = x; + te[ 13 ] = y; + te[ 14 ] = z; } - return ( min <= - plane.constant && max >= - plane.constant ); + return this; } /** - * Returns `true` if the given triangle intersects with this bounding box. + * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution). + * You can not invert with a determinant of zero. If you attempt this, the method produces + * a zero matrix instead. * - * @param {Triangle} triangle - The triangle to test. - * @return {boolean} Whether the given triangle intersects with this bounding box. + * @return {Matrix4} A reference to this matrix. */ - intersectsTriangle( triangle ) { - - if ( this.isEmpty() ) { - - return false; - - } + invert() { - // compute box center and extents - this.getCenter( _center ); - _extents.subVectors( this.max, _center ); + // based on https://github.com/toji/gl-matrix + const te = this.elements, - // translate triangle to aabb origin - _v0$3.subVectors( triangle.a, _center ); - _v1$7.subVectors( triangle.b, _center ); - _v2$4.subVectors( triangle.c, _center ); + n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n41 = te[ 3 ], + n12 = te[ 4 ], n22 = te[ 5 ], n32 = te[ 6 ], n42 = te[ 7 ], + n13 = te[ 8 ], n23 = te[ 9 ], n33 = te[ 10 ], n43 = te[ 11 ], + n14 = te[ 12 ], n24 = te[ 13 ], n34 = te[ 14 ], n44 = te[ 15 ], - // compute edge vectors for triangle - _f0.subVectors( _v1$7, _v0$3 ); - _f1.subVectors( _v2$4, _v1$7 ); - _f2.subVectors( _v0$3, _v2$4 ); + t1 = n11 * n22 - n21 * n12, + t2 = n11 * n32 - n31 * n12, + t3 = n11 * n42 - n41 * n12, + t4 = n21 * n32 - n31 * n22, + t5 = n21 * n42 - n41 * n22, + t6 = n31 * n42 - n41 * n32, + t7 = n13 * n24 - n23 * n14, + t8 = n13 * n34 - n33 * n14, + t9 = n13 * n44 - n43 * n14, + t10 = n23 * n34 - n33 * n24, + t11 = n23 * n44 - n43 * n24, + t12 = n33 * n44 - n43 * n34; - // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb - // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation - // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) - let axes = [ - 0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y, - _f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x, - - _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0 - ]; - if ( ! satForAxes( axes, _v0$3, _v1$7, _v2$4, _extents ) ) { + const det = t1 * t12 - t2 * t11 + t3 * t10 + t4 * t9 - t5 * t8 + t6 * t7; - return false; + if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); - } + const detInv = 1 / det; - // test 3 face normals from the aabb - axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; - if ( ! satForAxes( axes, _v0$3, _v1$7, _v2$4, _extents ) ) { + te[ 0 ] = ( n22 * t12 - n32 * t11 + n42 * t10 ) * detInv; + te[ 1 ] = ( n31 * t11 - n21 * t12 - n41 * t10 ) * detInv; + te[ 2 ] = ( n24 * t6 - n34 * t5 + n44 * t4 ) * detInv; + te[ 3 ] = ( n33 * t5 - n23 * t6 - n43 * t4 ) * detInv; - return false; + te[ 4 ] = ( n32 * t9 - n12 * t12 - n42 * t8 ) * detInv; + te[ 5 ] = ( n11 * t12 - n31 * t9 + n41 * t8 ) * detInv; + te[ 6 ] = ( n34 * t3 - n14 * t6 - n44 * t2 ) * detInv; + te[ 7 ] = ( n13 * t6 - n33 * t3 + n43 * t2 ) * detInv; - } + te[ 8 ] = ( n12 * t11 - n22 * t9 + n42 * t7 ) * detInv; + te[ 9 ] = ( n21 * t9 - n11 * t11 - n41 * t7 ) * detInv; + te[ 10 ] = ( n14 * t5 - n24 * t3 + n44 * t1 ) * detInv; + te[ 11 ] = ( n23 * t3 - n13 * t5 - n43 * t1 ) * detInv; - // finally testing the face normal of the triangle - // use already existing triangle edge vectors here - _triangleNormal.crossVectors( _f0, _f1 ); - axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ]; + te[ 12 ] = ( n22 * t8 - n12 * t10 - n32 * t7 ) * detInv; + te[ 13 ] = ( n11 * t10 - n21 * t8 + n31 * t7 ) * detInv; + te[ 14 ] = ( n24 * t2 - n14 * t4 - n34 * t1 ) * detInv; + te[ 15 ] = ( n13 * t4 - n23 * t2 + n33 * t1 ) * detInv; - return satForAxes( axes, _v0$3, _v1$7, _v2$4, _extents ); + return this; } /** - * Clamps the given point within the bounds of this box. + * Multiplies the columns of this matrix by the given vector. * - * @param {Vector3} point - The point to clamp. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The clamped point. + * @param {Vector3} v - The scale vector. + * @return {Matrix4} A reference to this matrix. */ - clampPoint( point, target ) { + scale( v ) { - return target.copy( point ).clamp( this.min, this.max ); + const te = this.elements; + const x = v.x, y = v.y, z = v.z; + + te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; + te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; + te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; + te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; + + return this; } /** - * Returns the euclidean distance from any edge of this box to the specified point. If - * the given point lies inside of this box, the distance will be `0`. + * Gets the maximum scale value of the three axes. * - * @param {Vector3} point - The point to compute the distance to. - * @return {number} The euclidean distance. + * @return {number} The maximum scale. */ - distanceToPoint( point ) { + getMaxScaleOnAxis() { - return this.clampPoint( point, _vector$b ).distanceTo( point ); + const te = this.elements; + + const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; + const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; + const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; + + return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); } /** - * Returns a bounding sphere that encloses this bounding box. + * Sets this matrix as a translation transform from the given vector. * - * @param {Sphere} target - The target sphere that is used to store the method's result. - * @return {Sphere} The bounding sphere that encloses this bounding box. + * @param {number|Vector3} x - The amount to translate in the X axis or alternatively a translation vector. + * @param {number} y - The amount to translate in the Y axis. + * @param {number} z - The amount to translate in the z axis. + * @return {Matrix4} A reference to this matrix. */ - getBoundingSphere( target ) { + makeTranslation( x, y, z ) { - if ( this.isEmpty() ) { + if ( x.isVector3 ) { - target.makeEmpty(); + this.set( + + 1, 0, 0, x.x, + 0, 1, 0, x.y, + 0, 0, 1, x.z, + 0, 0, 0, 1 + + ); } else { - this.getCenter( target.center ); + this.set( - target.radius = this.getSize( _vector$b ).length() * 0.5; + 1, 0, 0, x, + 0, 1, 0, y, + 0, 0, 1, z, + 0, 0, 0, 1 + + ); } - return target; + return this; } /** - * Computes the intersection of this bounding box and the given one, setting the upper - * bound of this box to the lesser of the two boxes' upper bounds and the - * lower bound of this box to the greater of the two boxes' lower bounds. If - * there's no overlap, makes this box empty. + * Sets this matrix as a rotational transformation around the X axis by + * the given angle. * - * @param {Box3} box - The bounding box to intersect with. - * @return {Box3} A reference to this bounding box. + * @param {number} theta - The rotation in radians. + * @return {Matrix4} A reference to this matrix. */ - intersect( box ) { + makeRotationX( theta ) { - this.min.max( box.min ); - this.max.min( box.max ); + const c = Math.cos( theta ), s = Math.sin( theta ); - // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. - if ( this.isEmpty() ) this.makeEmpty(); + this.set( + + 1, 0, 0, 0, + 0, c, - s, 0, + 0, s, c, 0, + 0, 0, 0, 1 + + ); return this; } /** - * Computes the union of this box and another and the given one, setting the upper - * bound of this box to the greater of the two boxes' upper bounds and the - * lower bound of this box to the lesser of the two boxes' lower bounds. + * Sets this matrix as a rotational transformation around the Y axis by + * the given angle. * - * @param {Box3} box - The bounding box that will be unioned with this instance. - * @return {Box3} A reference to this bounding box. + * @param {number} theta - The rotation in radians. + * @return {Matrix4} A reference to this matrix. */ - union( box ) { + makeRotationY( theta ) { - this.min.min( box.min ); - this.max.max( box.max ); + const c = Math.cos( theta ), s = Math.sin( theta ); + + this.set( + + c, 0, s, 0, + 0, 1, 0, 0, + - s, 0, c, 0, + 0, 0, 0, 1 + + ); return this; } /** - * Transforms this bounding box by the given 4x4 transformation matrix. + * Sets this matrix as a rotational transformation around the Z axis by + * the given angle. * - * @param {Matrix4} matrix - The transformation matrix. - * @return {Box3} A reference to this bounding box. + * @param {number} theta - The rotation in radians. + * @return {Matrix4} A reference to this matrix. */ - applyMatrix4( matrix ) { + makeRotationZ( theta ) { - // transform of empty box is an empty box. - if ( this.isEmpty() ) return this; + const c = Math.cos( theta ), s = Math.sin( theta ); - // NOTE: I am using a binary pattern to specify all 2^3 combinations below - _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 - _points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 - _points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 - _points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 - _points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 - _points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 - _points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 - _points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 + this.set( - this.setFromPoints( _points ); + c, - s, 0, 0, + s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + + ); return this; } /** - * Adds the given offset to both the upper and lower bounds of this bounding box, - * effectively moving it in 3D space. + * Sets this matrix as a rotational transformation around the given axis by + * the given angle. * - * @param {Vector3} offset - The offset that should be used to translate the bounding box. - * @return {Box3} A reference to this bounding box. + * This is a somewhat controversial but mathematically sound alternative to + * rotating via Quaternions. See the discussion [here](https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199). + * + * @param {Vector3} axis - The normalized rotation axis. + * @param {number} angle - The rotation in radians. + * @return {Matrix4} A reference to this matrix. */ - translate( offset ) { + makeRotationAxis( axis, angle ) { - this.min.add( offset ); - this.max.add( offset ); + // Based on http://www.gamedev.net/reference/articles/article1199.asp + + const c = Math.cos( angle ); + const s = Math.sin( angle ); + const t = 1 - c; + const x = axis.x, y = axis.y, z = axis.z; + const tx = t * x, ty = t * y; + + this.set( + + tx * x + c, tx * y - s * z, tx * z + s * y, 0, + tx * y + s * z, ty * y + c, ty * z - s * x, 0, + tx * z - s * y, ty * z + s * x, t * z * z + c, 0, + 0, 0, 0, 1 + + ); return this; } /** - * Returns `true` if this bounding box is equal with the given one. + * Sets this matrix as a scale transformation. * - * @param {Box3} box - The box to test for equality. - * @return {boolean} Whether this bounding box is equal with the given one. + * @param {number} x - The amount to scale in the X axis. + * @param {number} y - The amount to scale in the Y axis. + * @param {number} z - The amount to scale in the Z axis. + * @return {Matrix4} A reference to this matrix. */ - equals( box ) { + makeScale( x, y, z ) { - return box.min.equals( this.min ) && box.max.equals( this.max ); + this.set( + + x, 0, 0, 0, + 0, y, 0, 0, + 0, 0, z, 0, + 0, 0, 0, 1 + + ); + + return this; } /** - * Returns a serialized structure of the bounding box. + * Sets this matrix as a shear transformation. * - * @return {Object} Serialized structure with fields representing the object state. + * @param {number} xy - The amount to shear X by Y. + * @param {number} xz - The amount to shear X by Z. + * @param {number} yx - The amount to shear Y by X. + * @param {number} yz - The amount to shear Y by Z. + * @param {number} zx - The amount to shear Z by X. + * @param {number} zy - The amount to shear Z by Y. + * @return {Matrix4} A reference to this matrix. */ - toJSON() { + makeShear( xy, xz, yx, yz, zx, zy ) { - return { - min: this.min.toArray(), - max: this.max.toArray() - }; + this.set( + + 1, yx, zx, 0, + xy, 1, zy, 0, + xz, yz, 1, 0, + 0, 0, 0, 1 + + ); + + return this; } /** - * Returns a serialized structure of the bounding box. + * Sets this matrix to the transformation composed of the given position, + * rotation (Quaternion) and scale. * - * @param {Object} json - The serialized json to set the box from. - * @return {Box3} A reference to this bounding box. + * @param {Vector3} position - The position vector. + * @param {Quaternion} quaternion - The rotation as a Quaternion. + * @param {Vector3} scale - The scale vector. + * @return {Matrix4} A reference to this matrix. */ - fromJSON( json ) { + compose( position, quaternion, scale ) { - this.min.fromArray( json.min ); - this.max.fromArray( json.max ); - return this; + const te = this.elements; - } + const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; + const x2 = x + x, y2 = y + y, z2 = z + z; + const xx = x * x2, xy = x * y2, xz = x * z2; + const yy = y * y2, yz = y * z2, zz = z * z2; + const wx = w * x2, wy = w * y2, wz = w * z2; -} + const sx = scale.x, sy = scale.y, sz = scale.z; -const _points = [ - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3() -]; + te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; + te[ 1 ] = ( xy + wz ) * sx; + te[ 2 ] = ( xz - wy ) * sx; + te[ 3 ] = 0; -const _vector$b = /*@__PURE__*/ new Vector3(); + te[ 4 ] = ( xy - wz ) * sy; + te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; + te[ 6 ] = ( yz + wx ) * sy; + te[ 7 ] = 0; -const _box$4 = /*@__PURE__*/ new Box3(); + te[ 8 ] = ( xz + wy ) * sz; + te[ 9 ] = ( yz - wx ) * sz; + te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; + te[ 11 ] = 0; -// triangle centered vertices + te[ 12 ] = position.x; + te[ 13 ] = position.y; + te[ 14 ] = position.z; + te[ 15 ] = 1; -const _v0$3 = /*@__PURE__*/ new Vector3(); -const _v1$7 = /*@__PURE__*/ new Vector3(); -const _v2$4 = /*@__PURE__*/ new Vector3(); + return this; -// triangle edge vectors + } -const _f0 = /*@__PURE__*/ new Vector3(); -const _f1 = /*@__PURE__*/ new Vector3(); -const _f2 = /*@__PURE__*/ new Vector3(); + /** + * Decomposes this matrix into its position, rotation and scale components + * and provides the result in the given objects. + * + * Note: Not all matrices are decomposable in this way. For example, if an + * object has a non-uniformly scaled parent, then the object's world matrix + * may not be decomposable, and this method may not be appropriate. + * + * @param {Vector3} position - The position vector. + * @param {Quaternion} quaternion - The rotation as a Quaternion. + * @param {Vector3} scale - The scale vector. + * @return {Matrix4} A reference to this matrix. + */ + decompose( position, quaternion, scale ) { -const _center = /*@__PURE__*/ new Vector3(); -const _extents = /*@__PURE__*/ new Vector3(); -const _triangleNormal = /*@__PURE__*/ new Vector3(); -const _testAxis = /*@__PURE__*/ new Vector3(); + const te = this.elements; -function satForAxes( axes, v0, v1, v2, extents ) { + position.x = te[ 12 ]; + position.y = te[ 13 ]; + position.z = te[ 14 ]; - for ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) { + const det = this.determinant(); - _testAxis.fromArray( axes, i ); - // project the aabb onto the separating axis - const r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z ); - // project all 3 vertices of the triangle onto the separating axis - const p0 = v0.dot( _testAxis ); - const p1 = v1.dot( _testAxis ); - const p2 = v2.dot( _testAxis ); - // actual test, basically see if either of the most extreme of the triangle points intersects r - if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { + if ( det === 0 ) { - // points of the projected triangle are outside the projected half-length of the aabb - // the axis is separating and we can exit - return false; + scale.set( 1, 1, 1 ); + quaternion.identity(); + + return this; } - } + let sx = _v1$7.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); + const sy = _v1$7.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); + const sz = _v1$7.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); - return true; + // if determinant is negative, we need to invert one scale + if ( det < 0 ) sx = - sx; -} + // scale the rotation part + _m1$4.copy( this ); -const _box$3 = /*@__PURE__*/ new Box3(); -const _v1$6 = /*@__PURE__*/ new Vector3(); -const _v2$3 = /*@__PURE__*/ new Vector3(); + const invSX = 1 / sx; + const invSY = 1 / sy; + const invSZ = 1 / sz; -/** - * An analytical 3D sphere defined by a center and radius. This class is mainly - * used as a Bounding Sphere for 3D objects. - */ -class Sphere { + _m1$4.elements[ 0 ] *= invSX; + _m1$4.elements[ 1 ] *= invSX; + _m1$4.elements[ 2 ] *= invSX; - /** - * Constructs a new sphere. - * - * @param {Vector3} [center=(0,0,0)] - The center of the sphere - * @param {number} [radius=-1] - The radius of the sphere. - */ - constructor( center = new Vector3(), radius = -1 ) { + _m1$4.elements[ 4 ] *= invSY; + _m1$4.elements[ 5 ] *= invSY; + _m1$4.elements[ 6 ] *= invSY; - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isSphere = true; + _m1$4.elements[ 8 ] *= invSZ; + _m1$4.elements[ 9 ] *= invSZ; + _m1$4.elements[ 10 ] *= invSZ; - /** - * The center of the sphere - * - * @type {Vector3} - */ - this.center = center; + quaternion.setFromRotationMatrix( _m1$4 ); - /** - * The radius of the sphere. - * - * @type {number} - */ - this.radius = radius; + scale.x = sx; + scale.y = sy; + scale.z = sz; + + return this; } /** - * Sets the sphere's components by copying the given values. - * - * @param {Vector3} center - The center. - * @param {number} radius - The radius. - * @return {Sphere} A reference to this sphere. + * Creates a perspective projection matrix. This is used internally by + * {@link PerspectiveCamera#updateProjectionMatrix}. + + * @param {number} left - Left boundary of the viewing frustum at the near plane. + * @param {number} right - Right boundary of the viewing frustum at the near plane. + * @param {number} top - Top boundary of the viewing frustum at the near plane. + * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. + * @param {number} near - The distance from the camera to the near plane. + * @param {number} far - The distance from the camera to the far plane. + * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. + * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. + * @return {Matrix4} A reference to this matrix. */ - set( center, radius ) { + makePerspective( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) { - this.center.copy( center ); - this.radius = radius; + const te = this.elements; + + const x = 2 * near / ( right - left ); + const y = 2 * near / ( top - bottom ); + + const a = ( right + left ) / ( right - left ); + const b = ( top + bottom ) / ( top - bottom ); + + let c, d; + + if ( reversedDepth ) { + + c = near / ( far - near ); + d = ( far * near ) / ( far - near ); + + } else { + + if ( coordinateSystem === WebGLCoordinateSystem ) { + + c = - ( far + near ) / ( far - near ); + d = ( -2 * far * near ) / ( far - near ); + + } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + + c = - far / ( far - near ); + d = ( - far * near ) / ( far - near ); + + } else { + + throw new Error( 'THREE.Matrix4.makePerspective(): Invalid coordinate system: ' + coordinateSystem ); + + } + + } + + te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; + te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = -1; te[ 15 ] = 0; return this; } /** - * Computes the minimum bounding sphere for list of points. - * If the optional center point is given, it is used as the sphere's - * center. Otherwise, the center of the axis-aligned bounding box - * encompassing the points is calculated. - * - * @param {Array} points - A list of points in 3D space. - * @param {Vector3} [optionalCenter] - The center of the sphere. - * @return {Sphere} A reference to this sphere. + * Creates a orthographic projection matrix. This is used internally by + * {@link OrthographicCamera#updateProjectionMatrix}. + + * @param {number} left - Left boundary of the viewing frustum at the near plane. + * @param {number} right - Right boundary of the viewing frustum at the near plane. + * @param {number} top - Top boundary of the viewing frustum at the near plane. + * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. + * @param {number} near - The distance from the camera to the near plane. + * @param {number} far - The distance from the camera to the far plane. + * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. + * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. + * @return {Matrix4} A reference to this matrix. */ - setFromPoints( points, optionalCenter ) { + makeOrthographic( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) { - const center = this.center; + const te = this.elements; - if ( optionalCenter !== undefined ) { + const x = 2 / ( right - left ); + const y = 2 / ( top - bottom ); - center.copy( optionalCenter ); + const a = - ( right + left ) / ( right - left ); + const b = - ( top + bottom ) / ( top - bottom ); + + let c, d; + + if ( reversedDepth ) { + + c = 1 / ( far - near ); + d = far / ( far - near ); } else { - _box$3.setFromPoints( points ).getCenter( center ); + if ( coordinateSystem === WebGLCoordinateSystem ) { - } + c = -2 / ( far - near ); + d = - ( far + near ) / ( far - near ); - let maxRadiusSq = 0; + } else if ( coordinateSystem === WebGPUCoordinateSystem ) { - for ( let i = 0, il = points.length; i < il; i ++ ) { + c = -1 / ( far - near ); + d = - near / ( far - near ); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); + } else { + + throw new Error( 'THREE.Matrix4.makeOrthographic(): Invalid coordinate system: ' + coordinateSystem ); + + } } - this.radius = Math.sqrt( maxRadiusSq ); + te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = a; + te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = 0; te[ 13 ] = b; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; return this; } /** - * Copies the values of the given sphere to this instance. + * Returns `true` if this matrix is equal with the given one. * - * @param {Sphere} sphere - The sphere to copy. - * @return {Sphere} A reference to this sphere. + * @param {Matrix4} matrix - The matrix to test for equality. + * @return {boolean} Whether this matrix is equal with the given one. */ - copy( sphere ) { + equals( matrix ) { - this.center.copy( sphere.center ); - this.radius = sphere.radius; + const te = this.elements; + const me = matrix.elements; - return this; + for ( let i = 0; i < 16; i ++ ) { - } + if ( te[ i ] !== me[ i ] ) return false; - /** - * Returns `true` if the sphere is empty (the radius set to a negative number). - * - * Spheres with a radius of `0` contain only their center point and are not - * considered to be empty. - * - * @return {boolean} Whether this sphere is empty or not. - */ - isEmpty() { + } - return ( this.radius < 0 ); + return true; } /** - * Makes this sphere empty which means in encloses a zero space in 3D. + * Sets the elements of the matrix from the given array. * - * @return {Sphere} A reference to this sphere. + * @param {Array} array - The matrix elements in column-major order. + * @param {number} [offset=0] - Index of the first element in the array. + * @return {Matrix4} A reference to this matrix. */ - makeEmpty() { + fromArray( array, offset = 0 ) { - this.center.set( 0, 0, 0 ); - this.radius = -1; + for ( let i = 0; i < 16; i ++ ) { + + this.elements[ i ] = array[ i + offset ]; + + } return this; } /** - * Returns `true` if this sphere contains the given point inclusive of - * the surface of the sphere. + * Writes the elements of this matrix to the given array. If no array is provided, + * the method returns a new instance. * - * @param {Vector3} point - The point to check. - * @return {boolean} Whether this sphere contains the given point or not. + * @param {Array} [array=[]] - The target array holding the matrix elements in column-major order. + * @param {number} [offset=0] - Index of the first element in the array. + * @return {Array} The matrix elements in column-major order. */ - containsPoint( point ) { + toArray( array = [], offset = 0 ) { - return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); + const te = this.elements; + + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + array[ offset + 3 ] = te[ 3 ]; + + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + + array[ offset + 8 ] = te[ 8 ]; + array[ offset + 9 ] = te[ 9 ]; + array[ offset + 10 ] = te[ 10 ]; + array[ offset + 11 ] = te[ 11 ]; + + array[ offset + 12 ] = te[ 12 ]; + array[ offset + 13 ] = te[ 13 ]; + array[ offset + 14 ] = te[ 14 ]; + array[ offset + 15 ] = te[ 15 ]; + + return array; } +} + +const _v1$7 = /*@__PURE__*/ new Vector3(); +const _m1$4 = /*@__PURE__*/ new Matrix4(); +const _zero = /*@__PURE__*/ new Vector3( 0, 0, 0 ); +const _one = /*@__PURE__*/ new Vector3( 1, 1, 1 ); +const _x = /*@__PURE__*/ new Vector3(); +const _y = /*@__PURE__*/ new Vector3(); +const _z = /*@__PURE__*/ new Vector3(); + +const _matrix$2 = /*@__PURE__*/ new Matrix4(); +const _quaternion$4 = /*@__PURE__*/ new Quaternion(); + +/** + * A class representing Euler angles. + * + * Euler angles describe a rotational transformation by rotating an object on + * its various axes in specified amounts per axis, and a specified axis + * order. + * + * Iterating through an instance will yield its components (x, y, z, + * order) in the corresponding order. + * + * ```js + * const a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); + * const b = new THREE.Vector3( 1, 0, 1 ); + * b.applyEuler(a); + * ``` + */ +class Euler { + /** - * Returns the closest distance from the boundary of the sphere to the - * given point. If the sphere contains the point, the distance will - * be negative. + * Constructs a new euler instance. * - * @param {Vector3} point - The point to compute the distance to. - * @return {number} The distance to the point. + * @param {number} [x=0] - The angle of the x axis in radians. + * @param {number} [y=0] - The angle of the y axis in radians. + * @param {number} [z=0] - The angle of the z axis in radians. + * @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied. */ - distanceToPoint( point ) { + constructor( x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER ) { - return ( point.distanceTo( this.center ) - this.radius ); + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isEuler = true; + + this._x = x; + this._y = y; + this._z = z; + this._order = order; } /** - * Returns `true` if this sphere intersects with the given one. + * The angle of the x axis in radians. * - * @param {Sphere} sphere - The sphere to test. - * @return {boolean} Whether this sphere intersects with the given one or not. + * @type {number} + * @default 0 */ - intersectsSphere( sphere ) { + get x() { - const radiusSum = this.radius + sphere.radius; + return this._x; - return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); + } + + set x( value ) { + + this._x = value; + this._onChangeCallback(); } /** - * Returns `true` if this sphere intersects with the given box. + * The angle of the y axis in radians. * - * @param {Box3} box - The box to test. - * @return {boolean} Whether this sphere intersects with the given box or not. + * @type {number} + * @default 0 */ - intersectsBox( box ) { + get y() { - return box.intersectsSphere( this ); + return this._y; } - /** - * Returns `true` if this sphere intersects with the given plane. - * - * @param {Plane} plane - The plane to test. - * @return {boolean} Whether this sphere intersects with the given plane or not. - */ - intersectsPlane( plane ) { + set y( value ) { - return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; + this._y = value; + this._onChangeCallback(); } /** - * Clamps a point within the sphere. If the point is outside the sphere, it - * will clamp it to the closest point on the edge of the sphere. Points - * already inside the sphere will not be affected. + * The angle of the z axis in radians. * - * @param {Vector3} point - The plane to clamp. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The clamped point. + * @type {number} + * @default 0 */ - clampPoint( point, target ) { - - const deltaLengthSq = this.center.distanceToSquared( point ); - - target.copy( point ); + get z() { - if ( deltaLengthSq > ( this.radius * this.radius ) ) { + return this._z; - target.sub( this.center ).normalize(); - target.multiplyScalar( this.radius ).add( this.center ); + } - } + set z( value ) { - return target; + this._z = value; + this._onChangeCallback(); } /** - * Returns a bounding box that encloses this sphere. + * A string representing the order that the rotations are applied. * - * @param {Box3} target - The target box that is used to store the method's result. - * @return {Box3} The bounding box that encloses this sphere. + * @type {string} + * @default 'XYZ' */ - getBoundingBox( target ) { + get order() { - if ( this.isEmpty() ) { - - // Empty sphere produces empty bounding box - target.makeEmpty(); - return target; + return this._order; - } + } - target.set( this.center, this.center ); - target.expandByScalar( this.radius ); + set order( value ) { - return target; + this._order = value; + this._onChangeCallback(); } /** - * Transforms this sphere with the given 4x4 transformation matrix. + * Sets the Euler components. * - * @param {Matrix4} matrix - The transformation matrix. - * @return {Sphere} A reference to this sphere. + * @param {number} x - The angle of the x axis in radians. + * @param {number} y - The angle of the y axis in radians. + * @param {number} z - The angle of the z axis in radians. + * @param {string} [order] - A string representing the order that the rotations are applied. + * @return {Euler} A reference to this Euler instance. */ - applyMatrix4( matrix ) { + set( x, y, z, order = this._order ) { - this.center.applyMatrix4( matrix ); - this.radius = this.radius * matrix.getMaxScaleOnAxis(); + this._x = x; + this._y = y; + this._z = z; + this._order = order; + + this._onChangeCallback(); return this; } /** - * Translates the sphere's center by the given offset. + * Returns a new Euler instance with copied values from this instance. * - * @param {Vector3} offset - The offset. - * @return {Sphere} A reference to this sphere. + * @return {Euler} A clone of this instance. */ - translate( offset ) { + clone() { - this.center.add( offset ); + return new this.constructor( this._x, this._y, this._z, this._order ); + + } + + /** + * Copies the values of the given Euler instance to this instance. + * + * @param {Euler} euler - The Euler instance to copy. + * @return {Euler} A reference to this Euler instance. + */ + copy( euler ) { + + this._x = euler._x; + this._y = euler._y; + this._z = euler._z; + this._order = euler._order; + + this._onChangeCallback(); return this; } /** - * Expands the boundaries of this sphere to include the given point. + * Sets the angles of this Euler instance from a pure rotation matrix. * - * @param {Vector3} point - The point to include. - * @return {Sphere} A reference to this sphere. + * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled). + * @param {string} [order] - A string representing the order that the rotations are applied. + * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. + * @return {Euler} A reference to this Euler instance. */ - expandByPoint( point ) { + setFromRotationMatrix( m, order = this._order, update = true ) { - if ( this.isEmpty() ) { + const te = m.elements; + const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; + const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; + const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - this.center.copy( point ); + switch ( order ) { - this.radius = 0; + case 'XYZ': - return this; + this._y = Math.asin( clamp( m13, -1, 1 ) ); - } + if ( Math.abs( m13 ) < 0.9999999 ) { - _v1$6.subVectors( point, this.center ); + this._x = Math.atan2( - m23, m33 ); + this._z = Math.atan2( - m12, m11 ); - const lengthSq = _v1$6.lengthSq(); + } else { - if ( lengthSq > ( this.radius * this.radius ) ) { + this._x = Math.atan2( m32, m22 ); + this._z = 0; - // calculate the minimal sphere + } - const length = Math.sqrt( lengthSq ); + break; - const delta = ( length - this.radius ) * 0.5; + case 'YXZ': - this.center.addScaledVector( _v1$6, delta / length ); + this._x = Math.asin( - clamp( m23, -1, 1 ) ); - this.radius += delta; + if ( Math.abs( m23 ) < 0.9999999 ) { - } + this._y = Math.atan2( m13, m33 ); + this._z = Math.atan2( m21, m22 ); - return this; + } else { - } + this._y = Math.atan2( - m31, m11 ); + this._z = 0; - /** - * Expands this sphere to enclose both the original sphere and the given sphere. - * - * @param {Sphere} sphere - The sphere to include. - * @return {Sphere} A reference to this sphere. - */ - union( sphere ) { + } - if ( sphere.isEmpty() ) { + break; - return this; + case 'ZXY': - } + this._x = Math.asin( clamp( m32, -1, 1 ) ); - if ( this.isEmpty() ) { + if ( Math.abs( m32 ) < 0.9999999 ) { - this.copy( sphere ); + this._y = Math.atan2( - m31, m33 ); + this._z = Math.atan2( - m12, m22 ); - return this; + } else { - } + this._y = 0; + this._z = Math.atan2( m21, m11 ); - if ( this.center.equals( sphere.center ) === true ) { + } - this.radius = Math.max( this.radius, sphere.radius ); + break; - } else { + case 'ZYX': + + this._y = Math.asin( - clamp( m31, -1, 1 ) ); + + if ( Math.abs( m31 ) < 0.9999999 ) { + + this._x = Math.atan2( m32, m33 ); + this._z = Math.atan2( m21, m11 ); + + } else { + + this._x = 0; + this._z = Math.atan2( - m12, m22 ); + + } + + break; + + case 'YZX': + + this._z = Math.asin( clamp( m21, -1, 1 ) ); + + if ( Math.abs( m21 ) < 0.9999999 ) { + + this._x = Math.atan2( - m23, m22 ); + this._y = Math.atan2( - m31, m11 ); - _v2$3.subVectors( sphere.center, this.center ).setLength( sphere.radius ); + } else { + + this._x = 0; + this._y = Math.atan2( m13, m33 ); + + } + + break; + + case 'XZY': + + this._z = Math.asin( - clamp( m12, -1, 1 ) ); + + if ( Math.abs( m12 ) < 0.9999999 ) { + + this._x = Math.atan2( m32, m22 ); + this._y = Math.atan2( m13, m11 ); + + } else { + + this._x = Math.atan2( - m23, m33 ); + this._y = 0; + + } - this.expandByPoint( _v1$6.copy( sphere.center ).add( _v2$3 ) ); + break; + + default: - this.expandByPoint( _v1$6.copy( sphere.center ).sub( _v2$3 ) ); + warn( 'Euler: .setFromRotationMatrix() encountered an unknown order: ' + order ); } + this._order = order; + + if ( update === true ) this._onChangeCallback(); + return this; } /** - * Returns `true` if this sphere is equal with the given one. + * Sets the angles of this Euler instance from a normalized quaternion. * - * @param {Sphere} sphere - The sphere to test for equality. - * @return {boolean} Whether this bounding sphere is equal with the given one. + * @param {Quaternion} q - A normalized Quaternion. + * @param {string} [order] - A string representing the order that the rotations are applied. + * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. + * @return {Euler} A reference to this Euler instance. */ - equals( sphere ) { + setFromQuaternion( q, order, update ) { - return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); + _matrix$2.makeRotationFromQuaternion( q ); + + return this.setFromRotationMatrix( _matrix$2, order, update ); } /** - * Returns a new sphere with copied values from this instance. + * Sets the angles of this Euler instance from the given vector. * - * @return {Sphere} A clone of this instance. + * @param {Vector3} v - The vector. + * @param {string} [order] - A string representing the order that the rotations are applied. + * @return {Euler} A reference to this Euler instance. */ - clone() { + setFromVector3( v, order = this._order ) { - return new this.constructor().copy( this ); + return this.set( v.x, v.y, v.z, order ); } /** - * Returns a serialized structure of the bounding sphere. + * Resets the euler angle with a new order by creating a quaternion from this + * euler angle and then setting this euler angle with the quaternion and the + * new order. * - * @return {Object} Serialized structure with fields representing the object state. + * Warning: This discards revolution information. + * + * @param {string} [newOrder] - A string representing the new order that the rotations are applied. + * @return {Euler} A reference to this Euler instance. */ - toJSON() { + reorder( newOrder ) { - return { - radius: this.radius, - center: this.center.toArray() - }; + _quaternion$4.setFromEuler( this ); + + return this.setFromQuaternion( _quaternion$4, newOrder ); } /** - * Returns a serialized structure of the bounding sphere. + * Returns `true` if this Euler instance is equal with the given one. * - * @param {Object} json - The serialized json to set the sphere from. - * @return {Sphere} A reference to this bounding sphere. + * @param {Euler} euler - The Euler instance to test for equality. + * @return {boolean} Whether this Euler instance is equal with the given one. */ - fromJSON( json ) { + equals( euler ) { - this.radius = json.radius; - this.center.fromArray( json.center ); - return this; + return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); } -} - -const _vector$a = /*@__PURE__*/ new Vector3(); -const _segCenter = /*@__PURE__*/ new Vector3(); -const _segDir = /*@__PURE__*/ new Vector3(); -const _diff = /*@__PURE__*/ new Vector3(); - -const _edge1 = /*@__PURE__*/ new Vector3(); -const _edge2 = /*@__PURE__*/ new Vector3(); -const _normal$1 = /*@__PURE__*/ new Vector3(); - -/** - * A ray that emits from an origin in a certain direction. The class is used by - * {@link Raycaster} to assist with raycasting. Raycasting is used for - * mouse picking (working out what objects in the 3D space the mouse is over) - * amongst other things. - */ -class Ray { - /** - * Constructs a new ray. + * Sets this Euler instance's components to values from the given array. The first three + * entries of the array are assign to the x,y and z components. An optional fourth entry + * defines the Euler order. * - * @param {Vector3} [origin=(0,0,0)] - The origin of the ray. - * @param {Vector3} [direction=(0,0,-1)] - The (normalized) direction of the ray. + * @param {Array} array - An array holding the Euler component values. + * @return {Euler} A reference to this Euler instance. */ - constructor( origin = new Vector3(), direction = new Vector3( 0, 0, -1 ) ) { + fromArray( array ) { - /** - * The origin of the ray. - * - * @type {Vector3} - */ - this.origin = origin; + this._x = array[ 0 ]; + this._y = array[ 1 ]; + this._z = array[ 2 ]; + if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; - /** - * The (normalized) direction of the ray. - * - * @type {Vector3} - */ - this.direction = direction; + this._onChangeCallback(); + + return this; } /** - * Sets the ray's components by copying the given values. + * Writes the components of this Euler instance to the given array. If no array is provided, + * the method returns a new instance. * - * @param {Vector3} origin - The origin. - * @param {Vector3} direction - The direction. - * @return {Ray} A reference to this ray. + * @param {Array} [array=[]] - The target array holding the Euler components. + * @param {number} [offset=0] - Index of the first element in the array. + * @return {Array} The Euler components. */ - set( origin, direction ) { + toArray( array = [], offset = 0 ) { - this.origin.copy( origin ); - this.direction.copy( direction ); + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._order; - return this; + return array; } - /** - * Copies the values of the given ray to this instance. - * - * @param {Ray} ray - The ray to copy. - * @return {Ray} A reference to this ray. - */ - copy( ray ) { + _onChange( callback ) { - this.origin.copy( ray.origin ); - this.direction.copy( ray.direction ); + this._onChangeCallback = callback; return this; } - /** - * Returns a vector that is located at a given distance along this ray. - * - * @param {number} t - The distance along the ray to retrieve a position for. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} A position on the ray. - */ - at( t, target ) { + _onChangeCallback() {} - return target.copy( this.origin ).addScaledVector( this.direction, t ); + *[ Symbol.iterator ]() { + + yield this._x; + yield this._y; + yield this._z; + yield this._order; } +} + +/** + * The default Euler angle order. + * + * @static + * @type {string} + * @default 'XYZ' + */ +Euler.DEFAULT_ORDER = 'XYZ'; + +/** + * A layers object assigns an 3D object to 1 or more of 32 + * layers numbered `0` to `31` - internally the layers are stored as a + * bit mask], and by default all 3D objects are a member of layer `0`. + * + * This can be used to control visibility - an object must share a layer with + * a camera to be visible when that camera's view is + * rendered. + * + * All classes that inherit from {@link Object3D} have an `layers` property which + * is an instance of this class. + */ +class Layers { + /** - * Adjusts the direction of the ray to point at the given vector in world space. - * - * @param {Vector3} v - The target position. - * @return {Ray} A reference to this ray. + * Constructs a new layers instance, with membership + * initially set to layer `0`. */ - lookAt( v ) { - - this.direction.copy( v ).sub( this.origin ).normalize(); + constructor() { - return this; + /** + * A bit mask storing which of the 32 layers this layers object is currently + * a member of. + * + * @type {number} + */ + this.mask = 1 | 0; } /** - * Shift the origin of this ray along its direction by the given distance. + * Sets membership to the given layer, and remove membership all other layers. * - * @param {number} t - The distance along the ray to interpolate. - * @return {Ray} A reference to this ray. + * @param {number} layer - The layer to set. */ - recast( t ) { - - this.origin.copy( this.at( t, _vector$a ) ); + set( layer ) { - return this; + this.mask = ( 1 << layer | 0 ) >>> 0; } /** - * Returns the point along this ray that is closest to the given point. + * Adds membership of the given layer. * - * @param {Vector3} point - A point in 3D space to get the closet location on the ray for. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The closest point on this ray. + * @param {number} layer - The layer to enable. */ - closestPointToPoint( point, target ) { - - target.subVectors( point, this.origin ); - - const directionDistance = target.dot( this.direction ); + enable( layer ) { - if ( directionDistance < 0 ) { + this.mask |= 1 << layer | 0; - return target.copy( this.origin ); + } - } + /** + * Adds membership to all layers. + */ + enableAll() { - return target.copy( this.origin ).addScaledVector( this.direction, directionDistance ); + this.mask = 0xffffffff | 0; } /** - * Returns the distance of the closest approach between this ray and the given point. + * Toggles the membership of the given layer. * - * @param {Vector3} point - A point in 3D space to compute the distance to. - * @return {number} The distance. + * @param {number} layer - The layer to toggle. */ - distanceToPoint( point ) { + toggle( layer ) { - return Math.sqrt( this.distanceSqToPoint( point ) ); + this.mask ^= 1 << layer | 0; } /** - * Returns the squared distance of the closest approach between this ray and the given point. + * Removes membership of the given layer. * - * @param {Vector3} point - A point in 3D space to compute the distance to. - * @return {number} The squared distance. + * @param {number} layer - The layer to enable. */ - distanceSqToPoint( point ) { + disable( layer ) { - const directionDistance = _vector$a.subVectors( point, this.origin ).dot( this.direction ); + this.mask &= ~ ( 1 << layer | 0 ); - // point behind the ray + } - if ( directionDistance < 0 ) { + /** + * Removes the membership from all layers. + */ + disableAll() { - return this.origin.distanceToSquared( point ); + this.mask = 0; - } + } - _vector$a.copy( this.origin ).addScaledVector( this.direction, directionDistance ); + /** + * Returns `true` if this and the given layers object have at least one + * layer in common. + * + * @param {Layers} layers - The layers to test. + * @return {boolean } Whether this and the given layers object have at least one layer in common or not. + */ + test( layers ) { - return _vector$a.distanceToSquared( point ); + return ( this.mask & layers.mask ) !== 0; } /** - * Returns the squared distance between this ray and the given line segment. + * Returns `true` if the given layer is enabled. * - * @param {Vector3} v0 - The start point of the line segment. - * @param {Vector3} v1 - The end point of the line segment. - * @param {Vector3} [optionalPointOnRay] - When provided, it receives the point on this ray that is closest to the segment. - * @param {Vector3} [optionalPointOnSegment] - When provided, it receives the point on the line segment that is closest to this ray. - * @return {number} The squared distance. + * @param {number} layer - The layer to test. + * @return {boolean } Whether the given layer is enabled or not. */ - distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { - - // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h - // It returns the min distance between the ray and the segment - // defined by v0 and v1 - // It can also set two optional targets : - // - The closest point on the ray - // - The closest point on the segment + isEnabled( layer ) { - _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); - _segDir.copy( v1 ).sub( v0 ).normalize(); - _diff.copy( this.origin ).sub( _segCenter ); + return ( this.mask & ( 1 << layer | 0 ) ) !== 0; - const segExtent = v0.distanceTo( v1 ) * 0.5; - const a01 = - this.direction.dot( _segDir ); - const b0 = _diff.dot( this.direction ); - const b1 = - _diff.dot( _segDir ); - const c = _diff.lengthSq(); - const det = Math.abs( 1 - a01 * a01 ); - let s0, s1, sqrDist, extDet; + } - if ( det > 0 ) { +} - // The ray and segment are not parallel. +let _object3DId = 0; - s0 = a01 * b1 - b0; - s1 = a01 * b0 - b1; - extDet = segExtent * det; +const _v1$6 = /*@__PURE__*/ new Vector3(); +const _q1 = /*@__PURE__*/ new Quaternion(); +const _m1$3 = /*@__PURE__*/ new Matrix4(); +const _target = /*@__PURE__*/ new Vector3(); - if ( s0 >= 0 ) { +const _position$4 = /*@__PURE__*/ new Vector3(); +const _scale$3 = /*@__PURE__*/ new Vector3(); +const _quaternion$3 = /*@__PURE__*/ new Quaternion(); - if ( s1 >= - extDet ) { +const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 ); +const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 ); +const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 ); - if ( s1 <= extDet ) { +/** + * Fires when the object has been added to its parent object. + * + * @event Object3D#added + * @type {Object} + */ +const _addedEvent = { type: 'added' }; - // region 0 - // Minimum at interior points of ray and segment. - - const invDet = 1 / det; - s0 *= invDet; - s1 *= invDet; - sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; - - } else { - - // region 1 +/** + * Fires when the object has been removed from its parent object. + * + * @event Object3D#removed + * @type {Object} + */ +const _removedEvent = { type: 'removed' }; - s1 = segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; +/** + * Fires when a new child object has been added. + * + * @event Object3D#childadded + * @type {Object} + */ +const _childaddedEvent = { type: 'childadded', child: null }; - } +/** + * Fires when a child object has been removed. + * + * @event Object3D#childremoved + * @type {Object} + */ +const _childremovedEvent = { type: 'childremoved', child: null }; - } else { +/** + * This is the base class for most objects in three.js and provides a set of + * properties and methods for manipulating objects in 3D space. + * + * @augments EventDispatcher + */ +class Object3D extends EventDispatcher { - // region 5 + /** + * Constructs a new 3D object. + */ + constructor() { - s1 = - segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + super(); - } + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isObject3D = true; - } else { + /** + * The ID of the 3D object. + * + * @name Object3D#id + * @type {number} + * @readonly + */ + Object.defineProperty( this, 'id', { value: _object3DId ++ } ); - if ( s1 <= - extDet ) { + /** + * The UUID of the 3D object. + * + * @type {string} + * @readonly + */ + this.uuid = generateUUID(); - // region 4 + /** + * The name of the 3D object. + * + * @type {string} + */ + this.name = ''; - s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + /** + * The type property is used for detecting the object type + * in context of serialization/deserialization. + * + * @type {string} + * @readonly + */ + this.type = 'Object3D'; - } else if ( s1 <= extDet ) { + /** + * A reference to the parent object. + * + * @type {?Object3D} + * @default null + */ + this.parent = null; - // region 3 + /** + * An array holding the child 3D objects of this instance. + * + * @type {Array} + */ + this.children = []; - s0 = 0; - s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = s1 * ( s1 + 2 * b1 ) + c; + /** + * Defines the `up` direction of the 3D object which influences + * the orientation via methods like {@link Object3D#lookAt}. + * + * The default values for all 3D objects is defined by `Object3D.DEFAULT_UP`. + * + * @type {Vector3} + */ + this.up = Object3D.DEFAULT_UP.clone(); - } else { + const position = new Vector3(); + const rotation = new Euler(); + const quaternion = new Quaternion(); + const scale = new Vector3( 1, 1, 1 ); - // region 2 + function onRotationChange() { - s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + quaternion.setFromEuler( rotation, false ); - } + } - } + function onQuaternionChange() { - } else { + rotation.setFromQuaternion( quaternion, undefined, false ); - // Ray and segment are parallel. + } - s1 = ( a01 > 0 ) ? - segExtent : segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + rotation._onChange( onRotationChange ); + quaternion._onChange( onQuaternionChange ); - } + Object.defineProperties( this, { + /** + * Represents the object's local position. + * + * @name Object3D#position + * @type {Vector3} + * @default (0,0,0) + */ + position: { + configurable: true, + enumerable: true, + value: position + }, + /** + * Represents the object's local rotation as Euler angles, in radians. + * + * @name Object3D#rotation + * @type {Euler} + * @default (0,0,0) + */ + rotation: { + configurable: true, + enumerable: true, + value: rotation + }, + /** + * Represents the object's local rotation as Quaternions. + * + * @name Object3D#quaternion + * @type {Quaternion} + */ + quaternion: { + configurable: true, + enumerable: true, + value: quaternion + }, + /** + * Represents the object's local scale. + * + * @name Object3D#scale + * @type {Vector3} + * @default (1,1,1) + */ + scale: { + configurable: true, + enumerable: true, + value: scale + }, + /** + * Represents the object's model-view matrix. + * + * @name Object3D#modelViewMatrix + * @type {Matrix4} + */ + modelViewMatrix: { + value: new Matrix4() + }, + /** + * Represents the object's normal matrix. + * + * @name Object3D#normalMatrix + * @type {Matrix3} + */ + normalMatrix: { + value: new Matrix3() + } + } ); - if ( optionalPointOnRay ) { + /** + * Represents the object's transformation matrix in local space. + * + * @type {Matrix4} + */ + this.matrix = new Matrix4(); - optionalPointOnRay.copy( this.origin ).addScaledVector( this.direction, s0 ); + /** + * Represents the object's transformation matrix in world space. + * If the 3D object has no parent, then it's identical to the local transformation matrix + * + * @type {Matrix4} + */ + this.matrixWorld = new Matrix4(); - } + /** + * When set to `true`, the engine automatically computes the local matrix from position, + * rotation and scale every frame. If set to `false`, the app is responsible for recomputing + * the local matrix by calling `updateMatrix()`. + * + * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_AUTO_UPDATE`. + * + * @type {boolean} + * @default true + */ + this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE; - if ( optionalPointOnSegment ) { + /** + * When set to `true`, the engine automatically computes the world matrix from the current local + * matrix and the object's transformation hierarchy. If set to `false`, the app is responsible for + * recomputing the world matrix by directly updating the `matrixWorld` property. + * + * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE`. + * + * @type {boolean} + * @default true + */ + this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer - optionalPointOnSegment.copy( _segCenter ).addScaledVector( _segDir, s1 ); + /** + * When set to `true`, it calculates the world matrix in that frame and resets this property + * to `false`. + * + * @type {boolean} + * @default false + */ + this.matrixWorldNeedsUpdate = false; - } + /** + * The layer membership of the 3D object. The 3D object is only visible if it has + * at least one layer in common with the camera in use. This property can also be + * used to filter out unwanted objects in ray-intersection tests when using {@link Raycaster}. + * + * @type {Layers} + */ + this.layers = new Layers(); - return sqrDist; + /** + * When set to `true`, the 3D object gets rendered. + * + * @type {boolean} + * @default true + */ + this.visible = true; - } + /** + * When set to `true`, the 3D object gets rendered into shadow maps. + * + * @type {boolean} + * @default false + */ + this.castShadow = false; - /** - * Intersects this ray with the given sphere, returning the intersection - * point or `null` if there is no intersection. - * - * @param {Sphere} sphere - The sphere to intersect. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The intersection point. - */ - intersectSphere( sphere, target ) { + /** + * When set to `true`, the 3D object is affected by shadows in the scene. + * + * @type {boolean} + * @default false + */ + this.receiveShadow = false; - _vector$a.subVectors( sphere.center, this.origin ); - const tca = _vector$a.dot( this.direction ); - const d2 = _vector$a.dot( _vector$a ) - tca * tca; - const radius2 = sphere.radius * sphere.radius; + /** + * When set to `true`, the 3D object is honored by view frustum culling. + * + * @type {boolean} + * @default true + */ + this.frustumCulled = true; - if ( d2 > radius2 ) return null; + /** + * This value allows the default rendering order of scene graph objects to be + * overridden although opaque and transparent objects remain sorted independently. + * When this property is set for an instance of {@link Group},all descendants + * objects will be sorted and rendered together. Sorting is from lowest to highest + * render order. + * + * @type {number} + * @default 0 + */ + this.renderOrder = 0; - const thc = Math.sqrt( radius2 - d2 ); + /** + * An array holding the animation clips of the 3D object. + * + * @type {Array} + */ + this.animations = []; - // t0 = first intersect point - entrance on front of sphere - const t0 = tca - thc; + /** + * Custom depth material to be used when rendering to the depth map. Can only be used + * in context of meshes. When shadow-casting with a {@link DirectionalLight} or {@link SpotLight}, + * if you are modifying vertex positions in the vertex shader you must specify a custom depth + * material for proper shadows. + * + * Only relevant in context of {@link WebGLRenderer}. + * + * @type {(Material|undefined)} + * @default undefined + */ + this.customDepthMaterial = undefined; - // t1 = second intersect point - exit point on back of sphere - const t1 = tca + thc; + /** + * Same as {@link Object3D#customDepthMaterial}, but used with {@link PointLight}. + * + * Only relevant in context of {@link WebGLRenderer}. + * + * @type {(Material|undefined)} + * @default undefined + */ + this.customDistanceMaterial = undefined; - // test to see if t1 is behind the ray - if so, return null - if ( t1 < 0 ) return null; + /** + * Whether the 3D object is supposed to be static or not. If set to `true`, it means + * the 3D object is not going to be changed after the initial renderer. This includes + * geometry and material settings. A static 3D object can be processed by the renderer + * slightly faster since certain state checks can be bypassed. + * + * Only relevant in context of {@link WebGPURenderer}. + * + * @type {boolean} + * @default false + */ + this.static = false; - // test to see if t0 is behind the ray: - // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, - // in order to always return an intersect point that is in front of the ray. - if ( t0 < 0 ) return this.at( t1, target ); + /** + * An object that can be used to store custom data about the 3D object. It + * should not hold references to functions as these will not be cloned. + * + * @type {Object} + */ + this.userData = {}; - // else t0 is in front of the ray, so return the first collision point scaled by t0 - return this.at( t0, target ); + /** + * The pivot point for rotation and scale transformations. + * When set, rotation and scale are applied around this point + * instead of the object's origin. + * + * @type {?Vector3} + * @default null + */ + this.pivot = null; } /** - * Returns `true` if this ray intersects with the given sphere. + * A callback that is executed immediately before a 3D object is rendered to a shadow map. * - * @param {Sphere} sphere - The sphere to intersect. - * @return {boolean} Whether this ray intersects with the given sphere or not. + * @param {Renderer|WebGLRenderer} renderer - The renderer. + * @param {Object3D} object - The 3D object. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {Camera} shadowCamera - The shadow camera. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Material} depthMaterial - The depth material. + * @param {Object} group - The geometry group data. */ - intersectsSphere( sphere ) { + onBeforeShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {} - if ( sphere.radius < 0 ) return false; // handle empty spheres, see #31187 + /** + * A callback that is executed immediately after a 3D object is rendered to a shadow map. + * + * @param {Renderer|WebGLRenderer} renderer - The renderer. + * @param {Object3D} object - The 3D object. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {Camera} shadowCamera - The shadow camera. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Material} depthMaterial - The depth material. + * @param {Object} group - The geometry group data. + */ + onAfterShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {} - return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); + /** + * A callback that is executed immediately before a 3D object is rendered. + * + * @param {Renderer|WebGLRenderer} renderer - The renderer. + * @param {Object3D} object - The 3D object. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Material} material - The 3D object's material. + * @param {Object} group - The geometry group data. + */ + onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {} - } + /** + * A callback that is executed immediately after a 3D object is rendered. + * + * @param {Renderer|WebGLRenderer} renderer - The renderer. + * @param {Object3D} object - The 3D object. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Material} material - The 3D object's material. + * @param {Object} group - The geometry group data. + */ + onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {} /** - * Computes the distance from the ray's origin to the given plane. Returns `null` if the ray - * does not intersect with the plane. + * Applies the given transformation matrix to the object and updates the object's position, + * rotation and scale. * - * @param {Plane} plane - The plane to compute the distance to. - * @return {?number} Whether this ray intersects with the given sphere or not. + * @param {Matrix4} matrix - The transformation matrix. */ - distanceToPlane( plane ) { + applyMatrix4( matrix ) { - const denominator = plane.normal.dot( this.direction ); + if ( this.matrixAutoUpdate ) this.updateMatrix(); - if ( denominator === 0 ) { + this.matrix.premultiply( matrix ); - // line is coplanar, return origin - if ( plane.distanceToPoint( this.origin ) === 0 ) { + this.matrix.decompose( this.position, this.quaternion, this.scale ); - return 0; + } - } + /** + * Applies a rotation represented by given the quaternion to the 3D object. + * + * @param {Quaternion} q - The quaternion. + * @return {Object3D} A reference to this instance. + */ + applyQuaternion( q ) { - // Null is preferable to undefined since undefined means.... it is undefined + this.quaternion.premultiply( q ); - return null; + return this; - } + } - const t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + /** + * Sets the given rotation represented as an axis/angle couple to the 3D object. + * + * @param {Vector3} axis - The (normalized) axis vector. + * @param {number} angle - The angle in radians. + */ + setRotationFromAxisAngle( axis, angle ) { - // Return if the ray never intersects the plane + // assumes axis is normalized - return t >= 0 ? t : null; + this.quaternion.setFromAxisAngle( axis, angle ); } /** - * Intersects this ray with the given plane, returning the intersection - * point or `null` if there is no intersection. + * Sets the given rotation represented as Euler angles to the 3D object. * - * @param {Plane} plane - The plane to intersect. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The intersection point. + * @param {Euler} euler - The Euler angles. */ - intersectPlane( plane, target ) { + setRotationFromEuler( euler ) { - const t = this.distanceToPlane( plane ); + this.quaternion.setFromEuler( euler, true ); - if ( t === null ) { + } - return null; + /** + * Sets the given rotation represented as rotation matrix to the 3D object. + * + * @param {Matrix4} m - Although a 4x4 matrix is expected, the upper 3x3 portion must be + * a pure rotation matrix (i.e, unscaled). + */ + setRotationFromMatrix( m ) { - } + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - return this.at( t, target ); + this.quaternion.setFromRotationMatrix( m ); } /** - * Returns `true` if this ray intersects with the given plane. + * Sets the given rotation represented as a Quaternion to the 3D object. * - * @param {Plane} plane - The plane to intersect. - * @return {boolean} Whether this ray intersects with the given plane or not. + * @param {Quaternion} q - The Quaternion */ - intersectsPlane( plane ) { + setRotationFromQuaternion( q ) { - // check if the ray lies on the plane first + // assumes q is normalized - const distToPoint = plane.distanceToPoint( this.origin ); + this.quaternion.copy( q ); - if ( distToPoint === 0 ) { + } - return true; + /** + * Rotates the 3D object along an axis in local space. + * + * @param {Vector3} axis - The (normalized) axis vector. + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. + */ + rotateOnAxis( axis, angle ) { - } + // rotate object on axis in object space + // axis is assumed to be normalized - const denominator = plane.normal.dot( this.direction ); + _q1.setFromAxisAngle( axis, angle ); - if ( denominator * distToPoint < 0 ) { + this.quaternion.multiply( _q1 ); - return true; + return this; - } + } - // ray origin is behind the plane (and is pointing behind it) + /** + * Rotates the 3D object along an axis in world space. + * + * @param {Vector3} axis - The (normalized) axis vector. + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. + */ + rotateOnWorldAxis( axis, angle ) { - return false; + // rotate object on axis in world space + // axis is assumed to be normalized + // method assumes no rotated parent + + _q1.setFromAxisAngle( axis, angle ); + + this.quaternion.premultiply( _q1 ); + + return this; } /** - * Intersects this ray with the given bounding box, returning the intersection - * point or `null` if there is no intersection. + * Rotates the 3D object around its X axis in local space. * - * @param {Box3} box - The box to intersect. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The intersection point. + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. */ - intersectBox( box, target ) { - - let tmin, tmax, tymin, tymax, tzmin, tzmax; + rotateX( angle ) { - const invdirx = 1 / this.direction.x, - invdiry = 1 / this.direction.y, - invdirz = 1 / this.direction.z; + return this.rotateOnAxis( _xAxis, angle ); - const origin = this.origin; + } - if ( invdirx >= 0 ) { + /** + * Rotates the 3D object around its Y axis in local space. + * + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. + */ + rotateY( angle ) { - tmin = ( box.min.x - origin.x ) * invdirx; - tmax = ( box.max.x - origin.x ) * invdirx; + return this.rotateOnAxis( _yAxis, angle ); - } else { + } - tmin = ( box.max.x - origin.x ) * invdirx; - tmax = ( box.min.x - origin.x ) * invdirx; + /** + * Rotates the 3D object around its Z axis in local space. + * + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. + */ + rotateZ( angle ) { - } + return this.rotateOnAxis( _zAxis, angle ); - if ( invdiry >= 0 ) { + } - tymin = ( box.min.y - origin.y ) * invdiry; - tymax = ( box.max.y - origin.y ) * invdiry; + /** + * Translate the 3D object by a distance along the given axis in local space. + * + * @param {Vector3} axis - The (normalized) axis vector. + * @param {number} distance - The distance in world units. + * @return {Object3D} A reference to this instance. + */ + translateOnAxis( axis, distance ) { - } else { + // translate object by distance along axis in object space + // axis is assumed to be normalized - tymin = ( box.max.y - origin.y ) * invdiry; - tymax = ( box.min.y - origin.y ) * invdiry; + _v1$6.copy( axis ).applyQuaternion( this.quaternion ); - } + this.position.add( _v1$6.multiplyScalar( distance ) ); - if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + return this; - if ( tymin > tmin || isNaN( tmin ) ) tmin = tymin; + } - if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax; + /** + * Translate the 3D object by a distance along its X-axis in local space. + * + * @param {number} distance - The distance in world units. + * @return {Object3D} A reference to this instance. + */ + translateX( distance ) { - if ( invdirz >= 0 ) { + return this.translateOnAxis( _xAxis, distance ); - tzmin = ( box.min.z - origin.z ) * invdirz; - tzmax = ( box.max.z - origin.z ) * invdirz; + } - } else { + /** + * Translate the 3D object by a distance along its Y-axis in local space. + * + * @param {number} distance - The distance in world units. + * @return {Object3D} A reference to this instance. + */ + translateY( distance ) { - tzmin = ( box.max.z - origin.z ) * invdirz; - tzmax = ( box.min.z - origin.z ) * invdirz; + return this.translateOnAxis( _yAxis, distance ); - } + } - if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; + /** + * Translate the 3D object by a distance along its Z-axis in local space. + * + * @param {number} distance - The distance in world units. + * @return {Object3D} A reference to this instance. + */ + translateZ( distance ) { - if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; + return this.translateOnAxis( _zAxis, distance ); - if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; + } - //return point closest to the ray (positive side) + /** + * Converts the given vector from this 3D object's local space to world space. + * + * @param {Vector3} vector - The vector to convert. + * @return {Vector3} The converted vector. + */ + localToWorld( vector ) { - if ( tmax < 0 ) return null; + this.updateWorldMatrix( true, false ); - return this.at( tmin >= 0 ? tmin : tmax, target ); + return vector.applyMatrix4( this.matrixWorld ); } /** - * Returns `true` if this ray intersects with the given box. + * Converts the given vector from this 3D object's world space to local space. * - * @param {Box3} box - The box to intersect. - * @return {boolean} Whether this ray intersects with the given box or not. + * @param {Vector3} vector - The vector to convert. + * @return {Vector3} The converted vector. */ - intersectsBox( box ) { + worldToLocal( vector ) { - return this.intersectBox( box, _vector$a ) !== null; + this.updateWorldMatrix( true, false ); + + return vector.applyMatrix4( _m1$3.copy( this.matrixWorld ).invert() ); } /** - * Intersects this ray with the given triangle, returning the intersection - * point or `null` if there is no intersection. + * Rotates the object to face a point in world space. * - * @param {Vector3} a - The first vertex of the triangle. - * @param {Vector3} b - The second vertex of the triangle. - * @param {Vector3} c - The third vertex of the triangle. - * @param {boolean} backfaceCulling - Whether to use backface culling or not. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The intersection point. + * This method does not support objects having non-uniformly-scaled parent(s). + * + * @param {number|Vector3} x - The x coordinate in world space. Alternatively, a vector representing a position in world space + * @param {number} [y] - The y coordinate in world space. + * @param {number} [z] - The z coordinate in world space. */ - intersectTriangle( a, b, c, backfaceCulling, target ) { + lookAt( x, y, z ) { - // Compute the offset origin, edges, and normal. + // This method does not support objects having non-uniformly-scaled parent(s) - // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h + if ( x.isVector3 ) { - _edge1.subVectors( b, a ); - _edge2.subVectors( c, a ); - _normal$1.crossVectors( _edge1, _edge2 ); + _target.copy( x ); - // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, - // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by - // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) - // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) - // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) - let DdN = this.direction.dot( _normal$1 ); - let sign; + } else { - if ( DdN > 0 ) { + _target.set( x, y, z ); - if ( backfaceCulling ) return null; - sign = 1; + } - } else if ( DdN < 0 ) { + const parent = this.parent; - sign = -1; - DdN = - DdN; + this.updateWorldMatrix( true, false ); + + _position$4.setFromMatrixPosition( this.matrixWorld ); + + if ( this.isCamera || this.isLight ) { + + _m1$3.lookAt( _position$4, _target, this.up ); } else { - return null; + _m1$3.lookAt( _target, _position$4, this.up ); } - _diff.subVectors( this.origin, a ); - const DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) ); + this.quaternion.setFromRotationMatrix( _m1$3 ); - // b1 < 0, no intersection - if ( DdQxE2 < 0 ) { + if ( parent ) { - return null; + _m1$3.extractRotation( parent.matrixWorld ); + _q1.setFromRotationMatrix( _m1$3 ); + this.quaternion.premultiply( _q1.invert() ); } - const DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); + } - // b2 < 0, no intersection - if ( DdE1xQ < 0 ) { + /** + * Adds the given 3D object as a child to this 3D object. An arbitrary number of + * objects may be added. Any current parent on an object passed in here will be + * removed, since an object can have at most one parent. + * + * @fires Object3D#added + * @fires Object3D#childadded + * @param {Object3D} object - The 3D object to add. + * @return {Object3D} A reference to this instance. + */ + add( object ) { - return null; + if ( arguments.length > 1 ) { - } + for ( let i = 0; i < arguments.length; i ++ ) { - // b1+b2 > 1, no intersection - if ( DdQxE2 + DdE1xQ > DdN ) { + this.add( arguments[ i ] ); - return null; + } - } + return this; - // Line intersects triangle, check if ray does. - const QdN = - sign * _diff.dot( _normal$1 ); + } - // t < 0, no intersection - if ( QdN < 0 ) { + if ( object === this ) { - return null; + error( 'Object3D.add: object can\'t be added as a child of itself.', object ); + return this; } - // Ray intersects triangle. - return this.at( QdN / DdN, target ); + if ( object && object.isObject3D ) { - } + object.removeFromParent(); + object.parent = this; + this.children.push( object ); - /** - * Transforms this ray with the given 4x4 transformation matrix. - * - * @param {Matrix4} matrix4 - The transformation matrix. - * @return {Ray} A reference to this ray. - */ - applyMatrix4( matrix4 ) { + object.dispatchEvent( _addedEvent ); - this.origin.applyMatrix4( matrix4 ); - this.direction.transformDirection( matrix4 ); + _childaddedEvent.child = object; + this.dispatchEvent( _childaddedEvent ); + _childaddedEvent.child = null; - return this; + } else { - } + error( 'Object3D.add: object not an instance of THREE.Object3D.', object ); - /** - * Returns `true` if this ray is equal with the given one. - * - * @param {Ray} ray - The ray to test for equality. - * @return {boolean} Whether this ray is equal with the given one. - */ - equals( ray ) { + } - return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); + return this; } /** - * Returns a new ray with copied values from this instance. + * Removes the given 3D object as child from this 3D object. + * An arbitrary number of objects may be removed. * - * @return {Ray} A clone of this instance. + * @fires Object3D#removed + * @fires Object3D#childremoved + * @param {Object3D} object - The 3D object to remove. + * @return {Object3D} A reference to this instance. */ - clone() { + remove( object ) { - return new this.constructor().copy( this ); + if ( arguments.length > 1 ) { - } + for ( let i = 0; i < arguments.length; i ++ ) { -} + this.remove( arguments[ i ] ); -/** - * Represents a 4x4 matrix. - * - * The most common use of a 4x4 matrix in 3D computer graphics is as a transformation matrix. - * For an introduction to transformation matrices as used in WebGL, check out [this tutorial](https://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices) - * - * This allows a 3D vector representing a point in 3D space to undergo - * transformations such as translation, rotation, shear, scale, reflection, - * orthogonal or perspective projection and so on, by being multiplied by the - * matrix. This is known as `applying` the matrix to the vector. - * - * A Note on Row-Major and Column-Major Ordering: - * - * The constructor and {@link Matrix3#set} method take arguments in - * [row-major](https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order) - * order, while internally they are stored in the {@link Matrix3#elements} array in column-major order. - * This means that calling: - * ```js - * const m = new THREE.Matrix4(); - * m.set( 11, 12, 13, 14, - * 21, 22, 23, 24, - * 31, 32, 33, 34, - * 41, 42, 43, 44 ); - * ``` - * will result in the elements array containing: - * ```js - * m.elements = [ 11, 21, 31, 41, - * 12, 22, 32, 42, - * 13, 23, 33, 43, - * 14, 24, 34, 44 ]; - * ``` - * and internally all calculations are performed using column-major ordering. - * However, as the actual ordering makes no difference mathematically and - * most people are used to thinking about matrices in row-major order, the - * three.js documentation shows matrices in row-major order. Just bear in - * mind that if you are reading the source code, you'll have to take the - * transpose of any matrices outlined here to make sense of the calculations. - */ -class Matrix4 { + } - /** - * Constructs a new 4x4 matrix. The arguments are supposed to be - * in row-major order. If no arguments are provided, the constructor - * initializes the matrix as an identity matrix. - * - * @param {number} [n11] - 1-1 matrix element. - * @param {number} [n12] - 1-2 matrix element. - * @param {number} [n13] - 1-3 matrix element. - * @param {number} [n14] - 1-4 matrix element. - * @param {number} [n21] - 2-1 matrix element. - * @param {number} [n22] - 2-2 matrix element. - * @param {number} [n23] - 2-3 matrix element. - * @param {number} [n24] - 2-4 matrix element. - * @param {number} [n31] - 3-1 matrix element. - * @param {number} [n32] - 3-2 matrix element. - * @param {number} [n33] - 3-3 matrix element. - * @param {number} [n34] - 3-4 matrix element. - * @param {number} [n41] - 4-1 matrix element. - * @param {number} [n42] - 4-2 matrix element. - * @param {number} [n43] - 4-3 matrix element. - * @param {number} [n44] - 4-4 matrix element. - */ - constructor( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { + return this; - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - Matrix4.prototype.isMatrix4 = true; + } - /** - * A column-major list of matrix values. - * - * @type {Array} - */ - this.elements = [ + const index = this.children.indexOf( object ); - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + if ( index !== -1 ) { - ]; + object.parent = null; + this.children.splice( index, 1 ); - if ( n11 !== undefined ) { + object.dispatchEvent( _removedEvent ); - this.set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ); + _childremovedEvent.child = object; + this.dispatchEvent( _childremovedEvent ); + _childremovedEvent.child = null; } - } - - /** - * Sets the elements of the matrix.The arguments are supposed to be - * in row-major order. - * - * @param {number} [n11] - 1-1 matrix element. - * @param {number} [n12] - 1-2 matrix element. - * @param {number} [n13] - 1-3 matrix element. - * @param {number} [n14] - 1-4 matrix element. - * @param {number} [n21] - 2-1 matrix element. - * @param {number} [n22] - 2-2 matrix element. - * @param {number} [n23] - 2-3 matrix element. - * @param {number} [n24] - 2-4 matrix element. - * @param {number} [n31] - 3-1 matrix element. - * @param {number} [n32] - 3-2 matrix element. - * @param {number} [n33] - 3-3 matrix element. - * @param {number} [n34] - 3-4 matrix element. - * @param {number} [n41] - 4-1 matrix element. - * @param {number} [n42] - 4-2 matrix element. - * @param {number} [n43] - 4-3 matrix element. - * @param {number} [n44] - 4-4 matrix element. - * @return {Matrix4} A reference to this matrix. - */ - set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { - - const te = this.elements; - - te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; - te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; - te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; - te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; - return this; } /** - * Sets this matrix to the 4x4 identity matrix. + * Removes this 3D object from its current parent. * - * @return {Matrix4} A reference to this matrix. + * @fires Object3D#removed + * @fires Object3D#childremoved + * @return {Object3D} A reference to this instance. */ - identity() { + removeFromParent() { - this.set( + const parent = this.parent; - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + if ( parent !== null ) { - ); + parent.remove( this ); + + } return this; } /** - * Returns a matrix with copied values from this instance. + * Removes all child objects. * - * @return {Matrix4} A clone of this instance. + * @fires Object3D#removed + * @fires Object3D#childremoved + * @return {Object3D} A reference to this instance. */ - clone() { + clear() { - return new Matrix4().fromArray( this.elements ); + return this.remove( ... this.children ); } /** - * Copies the values of the given matrix to this instance. + * Adds the given 3D object as a child of this 3D object, while maintaining the object's world + * transform. This method does not support scene graphs having non-uniformly-scaled nodes(s). * - * @param {Matrix4} m - The matrix to copy. - * @return {Matrix4} A reference to this matrix. + * @fires Object3D#added + * @fires Object3D#childadded + * @param {Object3D} object - The 3D object to attach. + * @return {Object3D} A reference to this instance. */ - copy( m ) { + attach( object ) { - const te = this.elements; - const me = m.elements; + // adds object as a child of this, while maintaining the object's world transform - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; - te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; - te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; - te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; + // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) - return this; + this.updateWorldMatrix( true, false ); - } + _m1$3.copy( this.matrixWorld ).invert(); - /** - * Copies the translation component of the given matrix - * into this matrix's translation component. - * - * @param {Matrix4} m - The matrix to copy the translation component. - * @return {Matrix4} A reference to this matrix. - */ - copyPosition( m ) { + if ( object.parent !== null ) { - const te = this.elements, me = m.elements; + object.parent.updateWorldMatrix( true, false ); - te[ 12 ] = me[ 12 ]; - te[ 13 ] = me[ 13 ]; - te[ 14 ] = me[ 14 ]; + _m1$3.multiply( object.parent.matrixWorld ); - return this; + } - } - - /** - * Set the upper 3x3 elements of this matrix to the values of given 3x3 matrix. - * - * @param {Matrix3} m - The 3x3 matrix. - * @return {Matrix4} A reference to this matrix. - */ - setFromMatrix3( m ) { + object.applyMatrix4( _m1$3 ); - const me = m.elements; + object.removeFromParent(); + object.parent = this; + this.children.push( object ); - this.set( + object.updateWorldMatrix( false, true ); - me[ 0 ], me[ 3 ], me[ 6 ], 0, - me[ 1 ], me[ 4 ], me[ 7 ], 0, - me[ 2 ], me[ 5 ], me[ 8 ], 0, - 0, 0, 0, 1 + object.dispatchEvent( _addedEvent ); - ); + _childaddedEvent.child = object; + this.dispatchEvent( _childaddedEvent ); + _childaddedEvent.child = null; return this; } /** - * Extracts the basis of this matrix into the three axis vectors provided. + * Searches through the 3D object and its children, starting with the 3D object + * itself, and returns the first with a matching ID. * - * @param {Vector3} xAxis - The basis's x axis. - * @param {Vector3} yAxis - The basis's y axis. - * @param {Vector3} zAxis - The basis's z axis. - * @return {Matrix4} A reference to this matrix. + * @param {number} id - The id. + * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. */ - extractBasis( xAxis, yAxis, zAxis ) { - - if ( this.determinant() === 0 ) { - - xAxis.set( 1, 0, 0 ); - yAxis.set( 0, 1, 0 ); - zAxis.set( 0, 0, 1 ); + getObjectById( id ) { - return this; + return this.getObjectByProperty( 'id', id ); - } + } - xAxis.setFromMatrixColumn( this, 0 ); - yAxis.setFromMatrixColumn( this, 1 ); - zAxis.setFromMatrixColumn( this, 2 ); + /** + * Searches through the 3D object and its children, starting with the 3D object + * itself, and returns the first with a matching name. + * + * @param {string} name - The name. + * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. + */ + getObjectByName( name ) { - return this; + return this.getObjectByProperty( 'name', name ); } /** - * Sets the given basis vectors to this matrix. + * Searches through the 3D object and its children, starting with the 3D object + * itself, and returns the first with a matching property value. * - * @param {Vector3} xAxis - The basis's x axis. - * @param {Vector3} yAxis - The basis's y axis. - * @param {Vector3} zAxis - The basis's z axis. - * @return {Matrix4} A reference to this matrix. + * @param {string} name - The name of the property. + * @param {any} value - The value. + * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. */ - makeBasis( xAxis, yAxis, zAxis ) { + getObjectByProperty( name, value ) { - this.set( - xAxis.x, yAxis.x, zAxis.x, 0, - xAxis.y, yAxis.y, zAxis.y, 0, - xAxis.z, yAxis.z, zAxis.z, 0, - 0, 0, 0, 1 - ); + if ( this[ name ] === value ) return this; - return this; + for ( let i = 0, l = this.children.length; i < l; i ++ ) { + + const child = this.children[ i ]; + const object = child.getObjectByProperty( name, value ); + + if ( object !== undefined ) { + + return object; + + } + + } + + return undefined; } /** - * Extracts the rotation component of the given matrix - * into this matrix's rotation component. - * - * Note: This method does not support reflection matrices. + * Searches through the 3D object and its children, starting with the 3D object + * itself, and returns all 3D objects with a matching property value. * - * @param {Matrix4} m - The matrix. - * @return {Matrix4} A reference to this matrix. + * @param {string} name - The name of the property. + * @param {any} value - The value. + * @param {Array} result - The method stores the result in this array. + * @return {Array} The found 3D objects. */ - extractRotation( m ) { + getObjectsByProperty( name, value, result = [] ) { - if ( m.determinant() === 0 ) { + if ( this[ name ] === value ) result.push( this ); - return this.identity(); + const children = this.children; - } + for ( let i = 0, l = children.length; i < l; i ++ ) { - const te = this.elements; - const me = m.elements; + children[ i ].getObjectsByProperty( name, value, result ); - const scaleX = 1 / _v1$5.setFromMatrixColumn( m, 0 ).length(); - const scaleY = 1 / _v1$5.setFromMatrixColumn( m, 1 ).length(); - const scaleZ = 1 / _v1$5.setFromMatrixColumn( m, 2 ).length(); + } - te[ 0 ] = me[ 0 ] * scaleX; - te[ 1 ] = me[ 1 ] * scaleX; - te[ 2 ] = me[ 2 ] * scaleX; - te[ 3 ] = 0; + return result; - te[ 4 ] = me[ 4 ] * scaleY; - te[ 5 ] = me[ 5 ] * scaleY; - te[ 6 ] = me[ 6 ] * scaleY; - te[ 7 ] = 0; + } - te[ 8 ] = me[ 8 ] * scaleZ; - te[ 9 ] = me[ 9 ] * scaleZ; - te[ 10 ] = me[ 10 ] * scaleZ; - te[ 11 ] = 0; + /** + * Returns a vector representing the position of the 3D object in world space. + * + * @param {Vector3} target - The target vector the result is stored to. + * @return {Vector3} The 3D object's position in world space. + */ + getWorldPosition( target ) { - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + this.updateWorldMatrix( true, false ); - return this; + return target.setFromMatrixPosition( this.matrixWorld ); } /** - * Sets the rotation component (the upper left 3x3 matrix) of this matrix to - * the rotation specified by the given Euler angles. The rest of - * the matrix is set to the identity. Depending on the {@link Euler#order}, - * there are six possible outcomes. See [this page](https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix) - * for a complete list. + * Returns a Quaternion representing the position of the 3D object in world space. * - * @param {Euler} euler - The Euler angles. - * @return {Matrix4} A reference to this matrix. + * @param {Quaternion} target - The target Quaternion the result is stored to. + * @return {Quaternion} The 3D object's rotation in world space. */ - makeRotationFromEuler( euler ) { + getWorldQuaternion( target ) { - const te = this.elements; + this.updateWorldMatrix( true, false ); - const x = euler.x, y = euler.y, z = euler.z; - const a = Math.cos( x ), b = Math.sin( x ); - const c = Math.cos( y ), d = Math.sin( y ); - const e = Math.cos( z ), f = Math.sin( z ); + this.matrixWorld.decompose( _position$4, target, _scale$3 ); - if ( euler.order === 'XYZ' ) { + return target; - const ae = a * e, af = a * f, be = b * e, bf = b * f; + } - te[ 0 ] = c * e; - te[ 4 ] = - c * f; - te[ 8 ] = d; + /** + * Returns a vector representing the scale of the 3D object in world space. + * + * @param {Vector3} target - The target vector the result is stored to. + * @return {Vector3} The 3D object's scale in world space. + */ + getWorldScale( target ) { - te[ 1 ] = af + be * d; - te[ 5 ] = ae - bf * d; - te[ 9 ] = - b * c; + this.updateWorldMatrix( true, false ); - te[ 2 ] = bf - ae * d; - te[ 6 ] = be + af * d; - te[ 10 ] = a * c; + this.matrixWorld.decompose( _position$4, _quaternion$3, target ); - } else if ( euler.order === 'YXZ' ) { + return target; - const ce = c * e, cf = c * f, de = d * e, df = d * f; + } - te[ 0 ] = ce + df * b; - te[ 4 ] = de * b - cf; - te[ 8 ] = a * d; + /** + * Returns a vector representing the ("look") direction of the 3D object in world space. + * + * @param {Vector3} target - The target vector the result is stored to. + * @return {Vector3} The 3D object's direction in world space. + */ + getWorldDirection( target ) { - te[ 1 ] = a * f; - te[ 5 ] = a * e; - te[ 9 ] = - b; + this.updateWorldMatrix( true, false ); - te[ 2 ] = cf * b - de; - te[ 6 ] = df + ce * b; - te[ 10 ] = a * c; + const e = this.matrixWorld.elements; - } else if ( euler.order === 'ZXY' ) { + return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); - const ce = c * e, cf = c * f, de = d * e, df = d * f; + } - te[ 0 ] = ce - df * b; - te[ 4 ] = - a * f; - te[ 8 ] = de + cf * b; + /** + * Abstract method to get intersections between a casted ray and this + * 3D object. Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points} + * implement this method in order to use raycasting. + * + * @abstract + * @param {Raycaster} raycaster - The raycaster. + * @param {Array} intersects - An array holding the result of the method. + */ + raycast( /* raycaster, intersects */ ) {} - te[ 1 ] = cf + de * b; - te[ 5 ] = a * e; - te[ 9 ] = df - ce * b; + /** + * Executes the callback on this 3D object and all descendants. + * + * Note: Modifying the scene graph inside the callback is discouraged. + * + * @param {Function} callback - A callback function that allows to process the current 3D object. + */ + traverse( callback ) { - te[ 2 ] = - a * d; - te[ 6 ] = b; - te[ 10 ] = a * c; + callback( this ); - } else if ( euler.order === 'ZYX' ) { + const children = this.children; - const ae = a * e, af = a * f, be = b * e, bf = b * f; + for ( let i = 0, l = children.length; i < l; i ++ ) { - te[ 0 ] = c * e; - te[ 4 ] = be * d - af; - te[ 8 ] = ae * d + bf; + children[ i ].traverse( callback ); - te[ 1 ] = c * f; - te[ 5 ] = bf * d + ae; - te[ 9 ] = af * d - be; + } - te[ 2 ] = - d; - te[ 6 ] = b * c; - te[ 10 ] = a * c; + } - } else if ( euler.order === 'YZX' ) { + /** + * Like {@link Object3D#traverse}, but the callback will only be executed for visible 3D objects. + * Descendants of invisible 3D objects are not traversed. + * + * Note: Modifying the scene graph inside the callback is discouraged. + * + * @param {Function} callback - A callback function that allows to process the current 3D object. + */ + traverseVisible( callback ) { - const ac = a * c, ad = a * d, bc = b * c, bd = b * d; + if ( this.visible === false ) return; - te[ 0 ] = c * e; - te[ 4 ] = bd - ac * f; - te[ 8 ] = bc * f + ad; + callback( this ); - te[ 1 ] = f; - te[ 5 ] = a * e; - te[ 9 ] = - b * e; + const children = this.children; - te[ 2 ] = - d * e; - te[ 6 ] = ad * f + bc; - te[ 10 ] = ac - bd * f; + for ( let i = 0, l = children.length; i < l; i ++ ) { - } else if ( euler.order === 'XZY' ) { + children[ i ].traverseVisible( callback ); - const ac = a * c, ad = a * d, bc = b * c, bd = b * d; + } - te[ 0 ] = c * e; - te[ 4 ] = - f; - te[ 8 ] = d * e; + } - te[ 1 ] = ac * f + bd; - te[ 5 ] = a * e; - te[ 9 ] = ad * f - bc; + /** + * Like {@link Object3D#traverse}, but the callback will only be executed for all ancestors. + * + * Note: Modifying the scene graph inside the callback is discouraged. + * + * @param {Function} callback - A callback function that allows to process the current 3D object. + */ + traverseAncestors( callback ) { - te[ 2 ] = bc * f - ad; - te[ 6 ] = b * e; - te[ 10 ] = bd * f + ac; + const parent = this.parent; - } + if ( parent !== null ) { - // bottom row - te[ 3 ] = 0; - te[ 7 ] = 0; - te[ 11 ] = 0; + callback( parent ); - // last column - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + parent.traverseAncestors( callback ); - return this; + } } /** - * Sets the rotation component of this matrix to the rotation specified by - * the given Quaternion as outlined [here](https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion) - * The rest of the matrix is set to the identity. - * - * @param {Quaternion} q - The Quaternion. - * @return {Matrix4} A reference to this matrix. + * Updates the transformation matrix in local space by computing it from the current + * position, rotation and scale values. */ - makeRotationFromQuaternion( q ) { + updateMatrix() { - return this.compose( _zero, q, _one ); + this.matrix.compose( this.position, this.quaternion, this.scale ); + + const pivot = this.pivot; + + if ( pivot !== null ) { + + const px = pivot.x, py = pivot.y, pz = pivot.z; + const te = this.matrix.elements; + + te[ 12 ] += px - te[ 0 ] * px - te[ 4 ] * py - te[ 8 ] * pz; + te[ 13 ] += py - te[ 1 ] * px - te[ 5 ] * py - te[ 9 ] * pz; + te[ 14 ] += pz - te[ 2 ] * px - te[ 6 ] * py - te[ 10 ] * pz; + + } + + this.matrixWorldNeedsUpdate = true; } /** - * Sets the rotation component of the transformation matrix, looking from `eye` towards - * `target`, and oriented by the up-direction. + * Updates the transformation matrix in world space of this 3D objects and its descendants. * - * @param {Vector3} eye - The eye vector. - * @param {Vector3} target - The target vector. - * @param {Vector3} up - The up vector. - * @return {Matrix4} A reference to this matrix. + * To ensure correct results, this method also recomputes the 3D object's transformation matrix in + * local space. The computation of the local and world matrix can be controlled with the + * {@link Object3D#matrixAutoUpdate} and {@link Object3D#matrixWorldAutoUpdate} flags which are both + * `true` by default. Set these flags to `false` if you need more control over the update matrix process. + * + * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even + * when {@link Object3D#matrixWorldNeedsUpdate} is `false`. */ - lookAt( eye, target, up ) { - - const te = this.elements; + updateMatrixWorld( force ) { - _z.subVectors( eye, target ); + if ( this.matrixAutoUpdate ) this.updateMatrix(); - if ( _z.lengthSq() === 0 ) { + if ( this.matrixWorldNeedsUpdate || force ) { - // eye and target are in the same position + if ( this.matrixWorldAutoUpdate === true ) { - _z.z = 1; + if ( this.parent === null ) { - } + this.matrixWorld.copy( this.matrix ); - _z.normalize(); - _x.crossVectors( up, _z ); + } else { - if ( _x.lengthSq() === 0 ) { + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - // up and z are parallel + } - if ( Math.abs( up.z ) === 1 ) { + } - _z.x += 0.0001; + this.matrixWorldNeedsUpdate = false; - } else { + force = true; - _z.z += 0.0001; + } - } + // make sure descendants are updated if required - _z.normalize(); - _x.crossVectors( up, _z ); + const children = this.children; - } + for ( let i = 0, l = children.length; i < l; i ++ ) { - _x.normalize(); - _y.crossVectors( _z, _x ); + const child = children[ i ]; - te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; - te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; - te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; + child.updateMatrixWorld( force ); - return this; + } } /** - * Post-multiplies this matrix by the given 4x4 matrix. + * An alternative version of {@link Object3D#updateMatrixWorld} with more control over the + * update of ancestor and descendant nodes. * - * @param {Matrix4} m - The matrix to multiply with. - * @return {Matrix4} A reference to this matrix. + * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not. + * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not. */ - multiply( m ) { + updateWorldMatrix( updateParents, updateChildren ) { - return this.multiplyMatrices( this, m ); + const parent = this.parent; - } + if ( updateParents === true && parent !== null ) { - /** - * Pre-multiplies this matrix by the given 4x4 matrix. - * - * @param {Matrix4} m - The matrix to multiply with. - * @return {Matrix4} A reference to this matrix. - */ - premultiply( m ) { + parent.updateWorldMatrix( true, false ); - return this.multiplyMatrices( m, this ); + } - } + if ( this.matrixAutoUpdate ) this.updateMatrix(); - /** - * Multiples the given 4x4 matrices and stores the result - * in this matrix. - * - * @param {Matrix4} a - The first matrix. - * @param {Matrix4} b - The second matrix. - * @return {Matrix4} A reference to this matrix. - */ - multiplyMatrices( a, b ) { + if ( this.matrixWorldAutoUpdate === true ) { - const ae = a.elements; - const be = b.elements; - const te = this.elements; + if ( this.parent === null ) { - const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; - const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; - const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; - const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; + this.matrixWorld.copy( this.matrix ); - const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; - const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; - const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; - const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; + } else { - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; - te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; - te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; - te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; - te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; - te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; - te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; + } - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; - te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; - te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; - te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; + } - te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; - te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; - te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; - te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; + // make sure descendants are updated - return this; + if ( updateChildren === true ) { - } + const children = this.children; - /** - * Multiplies every component of the matrix by the given scalar. - * - * @param {number} s - The scalar. - * @return {Matrix4} A reference to this matrix. - */ - multiplyScalar( s ) { + for ( let i = 0, l = children.length; i < l; i ++ ) { - const te = this.elements; + const child = children[ i ]; - te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; - te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; - te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; - te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; + child.updateWorldMatrix( false, true ); - return this; + } + + } } /** - * Computes and returns the determinant of this matrix. - * - * Based on the method outlined [here](http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html). + * Serializes the 3D object into JSON. * - * @return {number} The determinant. + * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized 3D object. + * @see {@link ObjectLoader#parse} */ - determinant() { + toJSON( meta ) { - const te = this.elements; + // meta is a string when called from JSON.stringify + const isRootObject = ( meta === undefined || typeof meta === 'string' ); - const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; - const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; - const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; - const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - - const t11 = n23 * n34 - n24 * n33; - const t12 = n22 * n34 - n24 * n32; - const t13 = n22 * n33 - n23 * n32; + const output = {}; - const t21 = n21 * n34 - n24 * n31; - const t22 = n21 * n33 - n23 * n31; - const t23 = n21 * n32 - n22 * n31; + // meta is a hash used to collect geometries, materials. + // not providing it implies that this is the root object + // being serialized. + if ( isRootObject ) { - return n11 * ( n42 * t11 - n43 * t12 + n44 * t13 ) - - n12 * ( n41 * t11 - n43 * t21 + n44 * t22 ) + - n13 * ( n41 * t12 - n42 * t21 + n44 * t23 ) - - n14 * ( n41 * t13 - n42 * t22 + n43 * t23 ); + // initialize meta obj + meta = { + geometries: {}, + materials: {}, + textures: {}, + images: {}, + shapes: {}, + skeletons: {}, + animations: {}, + nodes: {} + }; - } + output.metadata = { + version: 4.7, + type: 'Object', + generator: 'Object3D.toJSON' + }; - /** - * Transposes this matrix in place. - * - * @return {Matrix4} A reference to this matrix. - */ - transpose() { + } - const te = this.elements; - let tmp; + // standard Object3D serialization - tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; - tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; - tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; + const object = {}; - tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; - tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; - tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; + object.uuid = this.uuid; + object.type = this.type; - return this; + if ( this.name !== '' ) object.name = this.name; + if ( this.castShadow === true ) object.castShadow = true; + if ( this.receiveShadow === true ) object.receiveShadow = true; + if ( this.visible === false ) object.visible = false; + if ( this.frustumCulled === false ) object.frustumCulled = false; + if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; + if ( this.static !== false ) object.static = this.static; + if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData; - } + object.layers = this.layers.mask; + object.matrix = this.matrix.toArray(); + object.up = this.up.toArray(); - /** - * Sets the position component for this matrix from the given vector, - * without affecting the rest of the matrix. - * - * @param {number|Vector3} x - The x component of the vector or alternatively the vector object. - * @param {number} y - The y component of the vector. - * @param {number} z - The z component of the vector. - * @return {Matrix4} A reference to this matrix. - */ - setPosition( x, y, z ) { + if ( this.pivot !== null ) object.pivot = this.pivot.toArray(); - const te = this.elements; + if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; - if ( x.isVector3 ) { + if ( this.morphTargetDictionary !== undefined ) object.morphTargetDictionary = Object.assign( {}, this.morphTargetDictionary ); + if ( this.morphTargetInfluences !== undefined ) object.morphTargetInfluences = this.morphTargetInfluences.slice(); - te[ 12 ] = x.x; - te[ 13 ] = x.y; - te[ 14 ] = x.z; + // object specific properties - } else { + if ( this.isInstancedMesh ) { - te[ 12 ] = x; - te[ 13 ] = y; - te[ 14 ] = z; + object.type = 'InstancedMesh'; + object.count = this.count; + object.instanceMatrix = this.instanceMatrix.toJSON(); + if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON(); } - return this; - - } + if ( this.isBatchedMesh ) { - /** - * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution). - * You can not invert with a determinant of zero. If you attempt this, the method produces - * a zero matrix instead. - * - * @return {Matrix4} A reference to this matrix. - */ - invert() { + object.type = 'BatchedMesh'; + object.perObjectFrustumCulled = this.perObjectFrustumCulled; + object.sortObjects = this.sortObjects; - // based on https://github.com/toji/gl-matrix - const te = this.elements, + object.drawRanges = this._drawRanges; + object.reservedRanges = this._reservedRanges; - n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n41 = te[ 3 ], - n12 = te[ 4 ], n22 = te[ 5 ], n32 = te[ 6 ], n42 = te[ 7 ], - n13 = te[ 8 ], n23 = te[ 9 ], n33 = te[ 10 ], n43 = te[ 11 ], - n14 = te[ 12 ], n24 = te[ 13 ], n34 = te[ 14 ], n44 = te[ 15 ], + object.geometryInfo = this._geometryInfo.map( info => ( { + ...info, + boundingBox: info.boundingBox ? info.boundingBox.toJSON() : undefined, + boundingSphere: info.boundingSphere ? info.boundingSphere.toJSON() : undefined + } ) ); + object.instanceInfo = this._instanceInfo.map( info => ( { ...info } ) ); - t1 = n11 * n22 - n21 * n12, - t2 = n11 * n32 - n31 * n12, - t3 = n11 * n42 - n41 * n12, - t4 = n21 * n32 - n31 * n22, - t5 = n21 * n42 - n41 * n22, - t6 = n31 * n42 - n41 * n32, - t7 = n13 * n24 - n23 * n14, - t8 = n13 * n34 - n33 * n14, - t9 = n13 * n44 - n43 * n14, - t10 = n23 * n34 - n33 * n24, - t11 = n23 * n44 - n43 * n24, - t12 = n33 * n44 - n43 * n34; + object.availableInstanceIds = this._availableInstanceIds.slice(); + object.availableGeometryIds = this._availableGeometryIds.slice(); - const det = t1 * t12 - t2 * t11 + t3 * t10 + t4 * t9 - t5 * t8 + t6 * t7; + object.nextIndexStart = this._nextIndexStart; + object.nextVertexStart = this._nextVertexStart; + object.geometryCount = this._geometryCount; - if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + object.maxInstanceCount = this._maxInstanceCount; + object.maxVertexCount = this._maxVertexCount; + object.maxIndexCount = this._maxIndexCount; - const detInv = 1 / det; + object.geometryInitialized = this._geometryInitialized; - te[ 0 ] = ( n22 * t12 - n32 * t11 + n42 * t10 ) * detInv; - te[ 1 ] = ( n31 * t11 - n21 * t12 - n41 * t10 ) * detInv; - te[ 2 ] = ( n24 * t6 - n34 * t5 + n44 * t4 ) * detInv; - te[ 3 ] = ( n33 * t5 - n23 * t6 - n43 * t4 ) * detInv; + object.matricesTexture = this._matricesTexture.toJSON( meta ); - te[ 4 ] = ( n32 * t9 - n12 * t12 - n42 * t8 ) * detInv; - te[ 5 ] = ( n11 * t12 - n31 * t9 + n41 * t8 ) * detInv; - te[ 6 ] = ( n34 * t3 - n14 * t6 - n44 * t2 ) * detInv; - te[ 7 ] = ( n13 * t6 - n33 * t3 + n43 * t2 ) * detInv; + object.indirectTexture = this._indirectTexture.toJSON( meta ); - te[ 8 ] = ( n12 * t11 - n22 * t9 + n42 * t7 ) * detInv; - te[ 9 ] = ( n21 * t9 - n11 * t11 - n41 * t7 ) * detInv; - te[ 10 ] = ( n14 * t5 - n24 * t3 + n44 * t1 ) * detInv; - te[ 11 ] = ( n23 * t3 - n13 * t5 - n43 * t1 ) * detInv; + if ( this._colorsTexture !== null ) { - te[ 12 ] = ( n22 * t8 - n12 * t10 - n32 * t7 ) * detInv; - te[ 13 ] = ( n11 * t10 - n21 * t8 + n31 * t7 ) * detInv; - te[ 14 ] = ( n24 * t2 - n14 * t4 - n34 * t1 ) * detInv; - te[ 15 ] = ( n13 * t4 - n23 * t2 + n33 * t1 ) * detInv; + object.colorsTexture = this._colorsTexture.toJSON( meta ); - return this; + } - } + if ( this.boundingSphere !== null ) { - /** - * Multiplies the columns of this matrix by the given vector. - * - * @param {Vector3} v - The scale vector. - * @return {Matrix4} A reference to this matrix. - */ - scale( v ) { + object.boundingSphere = this.boundingSphere.toJSON(); - const te = this.elements; - const x = v.x, y = v.y, z = v.z; + } - te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; - te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; - te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; - te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; + if ( this.boundingBox !== null ) { - return this; + object.boundingBox = this.boundingBox.toJSON(); - } + } - /** - * Gets the maximum scale value of the three axes. - * - * @return {number} The maximum scale. - */ - getMaxScaleOnAxis() { + } - const te = this.elements; + // - const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; - const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; - const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; + function serialize( library, element ) { - return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); + if ( library[ element.uuid ] === undefined ) { - } + library[ element.uuid ] = element.toJSON( meta ); - /** - * Sets this matrix as a translation transform from the given vector. - * - * @param {number|Vector3} x - The amount to translate in the X axis or alternatively a translation vector. - * @param {number} y - The amount to translate in the Y axis. - * @param {number} z - The amount to translate in the z axis. - * @return {Matrix4} A reference to this matrix. - */ - makeTranslation( x, y, z ) { + } - if ( x.isVector3 ) { + return element.uuid; - this.set( + } - 1, 0, 0, x.x, - 0, 1, 0, x.y, - 0, 0, 1, x.z, - 0, 0, 0, 1 + if ( this.isScene ) { - ); + if ( this.background ) { - } else { + if ( this.background.isColor ) { - this.set( + object.background = this.background.toJSON(); - 1, 0, 0, x, - 0, 1, 0, y, - 0, 0, 1, z, - 0, 0, 0, 1 + } else if ( this.background.isTexture ) { - ); + object.background = this.background.toJSON( meta ).uuid; - } + } - return this; + } - } + if ( this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true ) { - /** - * Sets this matrix as a rotational transformation around the X axis by - * the given angle. - * - * @param {number} theta - The rotation in radians. - * @return {Matrix4} A reference to this matrix. - */ - makeRotationX( theta ) { + object.environment = this.environment.toJSON( meta ).uuid; - const c = Math.cos( theta ), s = Math.sin( theta ); + } - this.set( + } else if ( this.isMesh || this.isLine || this.isPoints ) { - 1, 0, 0, 0, - 0, c, - s, 0, - 0, s, c, 0, - 0, 0, 0, 1 + object.geometry = serialize( meta.geometries, this.geometry ); - ); + const parameters = this.geometry.parameters; - return this; + if ( parameters !== undefined && parameters.shapes !== undefined ) { - } + const shapes = parameters.shapes; - /** - * Sets this matrix as a rotational transformation around the Y axis by - * the given angle. - * - * @param {number} theta - The rotation in radians. - * @return {Matrix4} A reference to this matrix. - */ - makeRotationY( theta ) { + if ( Array.isArray( shapes ) ) { - const c = Math.cos( theta ), s = Math.sin( theta ); + for ( let i = 0, l = shapes.length; i < l; i ++ ) { - this.set( + const shape = shapes[ i ]; - c, 0, s, 0, - 0, 1, 0, 0, - - s, 0, c, 0, - 0, 0, 0, 1 + serialize( meta.shapes, shape ); - ); + } - return this; + } else { - } + serialize( meta.shapes, shapes ); - /** - * Sets this matrix as a rotational transformation around the Z axis by - * the given angle. - * - * @param {number} theta - The rotation in radians. - * @return {Matrix4} A reference to this matrix. - */ - makeRotationZ( theta ) { + } - const c = Math.cos( theta ), s = Math.sin( theta ); + } - this.set( + } - c, - s, 0, 0, - s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + if ( this.isSkinnedMesh ) { - ); + object.bindMode = this.bindMode; + object.bindMatrix = this.bindMatrix.toArray(); - return this; + if ( this.skeleton !== undefined ) { - } + serialize( meta.skeletons, this.skeleton ); - /** - * Sets this matrix as a rotational transformation around the given axis by - * the given angle. - * - * This is a somewhat controversial but mathematically sound alternative to - * rotating via Quaternions. See the discussion [here](https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199). - * - * @param {Vector3} axis - The normalized rotation axis. - * @param {number} angle - The rotation in radians. - * @return {Matrix4} A reference to this matrix. - */ - makeRotationAxis( axis, angle ) { + object.skeleton = this.skeleton.uuid; - // Based on http://www.gamedev.net/reference/articles/article1199.asp + } - const c = Math.cos( angle ); - const s = Math.sin( angle ); - const t = 1 - c; - const x = axis.x, y = axis.y, z = axis.z; - const tx = t * x, ty = t * y; + } - this.set( + if ( this.material !== undefined ) { - tx * x + c, tx * y - s * z, tx * z + s * y, 0, - tx * y + s * z, ty * y + c, ty * z - s * x, 0, - tx * z - s * y, ty * z + s * x, t * z * z + c, 0, - 0, 0, 0, 1 + if ( Array.isArray( this.material ) ) { - ); + const uuids = []; - return this; + for ( let i = 0, l = this.material.length; i < l; i ++ ) { - } + uuids.push( serialize( meta.materials, this.material[ i ] ) ); - /** - * Sets this matrix as a scale transformation. - * - * @param {number} x - The amount to scale in the X axis. - * @param {number} y - The amount to scale in the Y axis. - * @param {number} z - The amount to scale in the Z axis. - * @return {Matrix4} A reference to this matrix. - */ - makeScale( x, y, z ) { + } - this.set( + object.material = uuids; - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - 0, 0, 0, 1 + } else { - ); + object.material = serialize( meta.materials, this.material ); - return this; + } - } + } - /** - * Sets this matrix as a shear transformation. - * - * @param {number} xy - The amount to shear X by Y. - * @param {number} xz - The amount to shear X by Z. - * @param {number} yx - The amount to shear Y by X. - * @param {number} yz - The amount to shear Y by Z. - * @param {number} zx - The amount to shear Z by X. - * @param {number} zy - The amount to shear Z by Y. - * @return {Matrix4} A reference to this matrix. - */ - makeShear( xy, xz, yx, yz, zx, zy ) { + // - this.set( + if ( this.children.length > 0 ) { - 1, yx, zx, 0, - xy, 1, zy, 0, - xz, yz, 1, 0, - 0, 0, 0, 1 + object.children = []; - ); + for ( let i = 0; i < this.children.length; i ++ ) { - return this; + object.children.push( this.children[ i ].toJSON( meta ).object ); - } + } - /** - * Sets this matrix to the transformation composed of the given position, - * rotation (Quaternion) and scale. - * - * @param {Vector3} position - The position vector. - * @param {Quaternion} quaternion - The rotation as a Quaternion. - * @param {Vector3} scale - The scale vector. - * @return {Matrix4} A reference to this matrix. - */ - compose( position, quaternion, scale ) { + } - const te = this.elements; + // - const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; - const x2 = x + x, y2 = y + y, z2 = z + z; - const xx = x * x2, xy = x * y2, xz = x * z2; - const yy = y * y2, yz = y * z2, zz = z * z2; - const wx = w * x2, wy = w * y2, wz = w * z2; + if ( this.animations.length > 0 ) { - const sx = scale.x, sy = scale.y, sz = scale.z; + object.animations = []; - te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; - te[ 1 ] = ( xy + wz ) * sx; - te[ 2 ] = ( xz - wy ) * sx; - te[ 3 ] = 0; + for ( let i = 0; i < this.animations.length; i ++ ) { - te[ 4 ] = ( xy - wz ) * sy; - te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; - te[ 6 ] = ( yz + wx ) * sy; - te[ 7 ] = 0; + const animation = this.animations[ i ]; - te[ 8 ] = ( xz + wy ) * sz; - te[ 9 ] = ( yz - wx ) * sz; - te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; - te[ 11 ] = 0; + object.animations.push( serialize( meta.animations, animation ) ); - te[ 12 ] = position.x; - te[ 13 ] = position.y; - te[ 14 ] = position.z; - te[ 15 ] = 1; + } - return this; + } - } + if ( isRootObject ) { - /** - * Decomposes this matrix into its position, rotation and scale components - * and provides the result in the given objects. - * - * Note: Not all matrices are decomposable in this way. For example, if an - * object has a non-uniformly scaled parent, then the object's world matrix - * may not be decomposable, and this method may not be appropriate. - * - * @param {Vector3} position - The position vector. - * @param {Quaternion} quaternion - The rotation as a Quaternion. - * @param {Vector3} scale - The scale vector. - * @return {Matrix4} A reference to this matrix. - */ - decompose( position, quaternion, scale ) { + const geometries = extractFromCache( meta.geometries ); + const materials = extractFromCache( meta.materials ); + const textures = extractFromCache( meta.textures ); + const images = extractFromCache( meta.images ); + const shapes = extractFromCache( meta.shapes ); + const skeletons = extractFromCache( meta.skeletons ); + const animations = extractFromCache( meta.animations ); + const nodes = extractFromCache( meta.nodes ); - const te = this.elements; + if ( geometries.length > 0 ) output.geometries = geometries; + if ( materials.length > 0 ) output.materials = materials; + if ( textures.length > 0 ) output.textures = textures; + if ( images.length > 0 ) output.images = images; + if ( shapes.length > 0 ) output.shapes = shapes; + if ( skeletons.length > 0 ) output.skeletons = skeletons; + if ( animations.length > 0 ) output.animations = animations; + if ( nodes.length > 0 ) output.nodes = nodes; - position.x = te[ 12 ]; - position.y = te[ 13 ]; - position.z = te[ 14 ]; + } - const det = this.determinant(); + output.object = object; - if ( det === 0 ) { + return output; - scale.set( 1, 1, 1 ); - quaternion.identity(); + // extract data from the cache hash + // remove metadata on each item + // and return as array + function extractFromCache( cache ) { - return this; + const values = []; + for ( const key in cache ) { - } + const data = cache[ key ]; + delete data.metadata; + values.push( data ); - let sx = _v1$5.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); - const sy = _v1$5.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); - const sz = _v1$5.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); + } - // if determinant is negative, we need to invert one scale - if ( det < 0 ) sx = - sx; + return values; - // scale the rotation part - _m1$4.copy( this ); + } - const invSX = 1 / sx; - const invSY = 1 / sy; - const invSZ = 1 / sz; + } - _m1$4.elements[ 0 ] *= invSX; - _m1$4.elements[ 1 ] *= invSX; - _m1$4.elements[ 2 ] *= invSX; + /** + * Returns a new 3D object with copied values from this instance. + * + * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are also cloned. + * @return {Object3D} A clone of this instance. + */ + clone( recursive ) { - _m1$4.elements[ 4 ] *= invSY; - _m1$4.elements[ 5 ] *= invSY; - _m1$4.elements[ 6 ] *= invSY; + return new this.constructor().copy( this, recursive ); - _m1$4.elements[ 8 ] *= invSZ; - _m1$4.elements[ 9 ] *= invSZ; - _m1$4.elements[ 10 ] *= invSZ; + } - quaternion.setFromRotationMatrix( _m1$4 ); + /** + * Copies the values of the given 3D object to this instance. + * + * @param {Object3D} source - The 3D object to copy. + * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are cloned. + * @return {Object3D} A reference to this instance. + */ + copy( source, recursive = true ) { - scale.x = sx; - scale.y = sy; - scale.z = sz; + this.name = source.name; - return this; + this.up.copy( source.up ); - } + this.position.copy( source.position ); + this.rotation.order = source.rotation.order; + this.quaternion.copy( source.quaternion ); + this.scale.copy( source.scale ); - /** - * Creates a perspective projection matrix. This is used internally by - * {@link PerspectiveCamera#updateProjectionMatrix}. + if ( source.pivot !== null ) { - * @param {number} left - Left boundary of the viewing frustum at the near plane. - * @param {number} right - Right boundary of the viewing frustum at the near plane. - * @param {number} top - Top boundary of the viewing frustum at the near plane. - * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. - * @param {number} near - The distance from the camera to the near plane. - * @param {number} far - The distance from the camera to the far plane. - * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. - * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. - * @return {Matrix4} A reference to this matrix. - */ - makePerspective( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) { + this.pivot = source.pivot.clone(); - const te = this.elements; + } - const x = 2 * near / ( right - left ); - const y = 2 * near / ( top - bottom ); + this.matrix.copy( source.matrix ); + this.matrixWorld.copy( source.matrixWorld ); - const a = ( right + left ) / ( right - left ); - const b = ( top + bottom ) / ( top - bottom ); + this.matrixAutoUpdate = source.matrixAutoUpdate; - let c, d; + this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; + this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - if ( reversedDepth ) { + this.layers.mask = source.layers.mask; + this.visible = source.visible; - c = near / ( far - near ); - d = ( far * near ) / ( far - near ); + this.castShadow = source.castShadow; + this.receiveShadow = source.receiveShadow; - } else { + this.frustumCulled = source.frustumCulled; + this.renderOrder = source.renderOrder; - if ( coordinateSystem === WebGLCoordinateSystem ) { + this.static = source.static; - c = - ( far + near ) / ( far - near ); - d = ( -2 * far * near ) / ( far - near ); + this.animations = source.animations.slice(); - } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - c = - far / ( far - near ); - d = ( - far * near ) / ( far - near ); + if ( recursive === true ) { - } else { + for ( let i = 0; i < source.children.length; i ++ ) { - throw new Error( 'THREE.Matrix4.makePerspective(): Invalid coordinate system: ' + coordinateSystem ); + const child = source.children[ i ]; + this.add( child.clone() ); } } - te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; - te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = -1; te[ 15 ] = 0; - return this; } - /** - * Creates a orthographic projection matrix. This is used internally by - * {@link OrthographicCamera#updateProjectionMatrix}. - - * @param {number} left - Left boundary of the viewing frustum at the near plane. - * @param {number} right - Right boundary of the viewing frustum at the near plane. - * @param {number} top - Top boundary of the viewing frustum at the near plane. - * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. - * @param {number} near - The distance from the camera to the near plane. - * @param {number} far - The distance from the camera to the far plane. - * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. - * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. - * @return {Matrix4} A reference to this matrix. - */ - makeOrthographic( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) { - - const te = this.elements; +} - const x = 2 / ( right - left ); - const y = 2 / ( top - bottom ); +/** + * The default up direction for objects, also used as the default + * position for {@link DirectionalLight} and {@link HemisphereLight}. + * + * @static + * @type {Vector3} + * @default (0,1,0) + */ +Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 ); - const a = - ( right + left ) / ( right - left ); - const b = - ( top + bottom ) / ( top - bottom ); +/** + * The default setting for {@link Object3D#matrixAutoUpdate} for + * newly created 3D objects. + * + * @static + * @type {boolean} + * @default true + */ +Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; - let c, d; +/** + * The default setting for {@link Object3D#matrixWorldAutoUpdate} for + * newly created 3D objects. + * + * @static + * @type {boolean} + * @default true + */ +Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; - if ( reversedDepth ) { +/** + * This is almost identical to an {@link Object3D}. Its purpose is to + * make working with groups of objects syntactically clearer. + * + * ```js + * // Create a group and add the two cubes. + * // These cubes can now be rotated / scaled etc as a group. + * const group = new THREE.Group(); + * + * group.add( meshA ); + * group.add( meshB ); + * + * scene.add( group ); + * ``` + * + * @augments Object3D + */ +class Group extends Object3D { - c = 1 / ( far - near ); - d = far / ( far - near ); + constructor() { - } else { + super(); - if ( coordinateSystem === WebGLCoordinateSystem ) { + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isGroup = true; - c = -2 / ( far - near ); - d = - ( far + near ) / ( far - near ); + this.type = 'Group'; - } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + } - c = -1 / ( far - near ); - d = - near / ( far - near ); +} - } else { +const _moveEvent = { type: 'move' }; - throw new Error( 'THREE.Matrix4.makeOrthographic(): Invalid coordinate system: ' + coordinateSystem ); +/** + * Class for representing a XR controller with its + * different coordinate systems. + * + * @private + */ +class WebXRController { - } + /** + * Constructs a new XR controller. + */ + constructor() { - } + /** + * A group representing the target ray space + * of the XR controller. + * + * @private + * @type {?Group} + * @default null + */ + this._targetRay = null; - te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = a; - te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = 0; te[ 13 ] = b; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; + /** + * A group representing the grip space + * of the XR controller. + * + * @private + * @type {?Group} + * @default null + */ + this._grip = null; - return this; + /** + * A group representing the hand space + * of the XR controller. + * + * @private + * @type {?Group} + * @default null + */ + this._hand = null; } /** - * Returns `true` if this matrix is equal with the given one. + * Returns a group representing the hand space of the XR controller. * - * @param {Matrix4} matrix - The matrix to test for equality. - * @return {boolean} Whether this matrix is equal with the given one. + * @return {Group} A group representing the hand space of the XR controller. */ - equals( matrix ) { + getHandSpace() { - const te = this.elements; - const me = matrix.elements; + if ( this._hand === null ) { - for ( let i = 0; i < 16; i ++ ) { + this._hand = new Group(); + this._hand.matrixAutoUpdate = false; + this._hand.visible = false; - if ( te[ i ] !== me[ i ] ) return false; + this._hand.joints = {}; + this._hand.inputState = { pinching: false }; } - return true; + return this._hand; } /** - * Sets the elements of the matrix from the given array. + * Returns a group representing the target ray space of the XR controller. * - * @param {Array} array - The matrix elements in column-major order. - * @param {number} [offset=0] - Index of the first element in the array. - * @return {Matrix4} A reference to this matrix. + * @return {Group} A group representing the target ray space of the XR controller. */ - fromArray( array, offset = 0 ) { + getTargetRaySpace() { - for ( let i = 0; i < 16; i ++ ) { + if ( this._targetRay === null ) { - this.elements[ i ] = array[ i + offset ]; + this._targetRay = new Group(); + this._targetRay.matrixAutoUpdate = false; + this._targetRay.visible = false; + this._targetRay.hasLinearVelocity = false; + this._targetRay.linearVelocity = new Vector3(); + this._targetRay.hasAngularVelocity = false; + this._targetRay.angularVelocity = new Vector3(); } - return this; + return this._targetRay; } /** - * Writes the elements of this matrix to the given array. If no array is provided, - * the method returns a new instance. + * Returns a group representing the grip space of the XR controller. * - * @param {Array} [array=[]] - The target array holding the matrix elements in column-major order. - * @param {number} [offset=0] - Index of the first element in the array. - * @return {Array} The matrix elements in column-major order. + * @return {Group} A group representing the grip space of the XR controller. */ - toArray( array = [], offset = 0 ) { - - const te = this.elements; - - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - array[ offset + 3 ] = te[ 3 ]; + getGripSpace() { - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; + if ( this._grip === null ) { - array[ offset + 8 ] = te[ 8 ]; - array[ offset + 9 ] = te[ 9 ]; - array[ offset + 10 ] = te[ 10 ]; - array[ offset + 11 ] = te[ 11 ]; + this._grip = new Group(); + this._grip.matrixAutoUpdate = false; + this._grip.visible = false; + this._grip.hasLinearVelocity = false; + this._grip.linearVelocity = new Vector3(); + this._grip.hasAngularVelocity = false; + this._grip.angularVelocity = new Vector3(); - array[ offset + 12 ] = te[ 12 ]; - array[ offset + 13 ] = te[ 13 ]; - array[ offset + 14 ] = te[ 14 ]; - array[ offset + 15 ] = te[ 15 ]; + } - return array; + return this._grip; } -} - -const _v1$5 = /*@__PURE__*/ new Vector3(); -const _m1$4 = /*@__PURE__*/ new Matrix4(); -const _zero = /*@__PURE__*/ new Vector3( 0, 0, 0 ); -const _one = /*@__PURE__*/ new Vector3( 1, 1, 1 ); -const _x = /*@__PURE__*/ new Vector3(); -const _y = /*@__PURE__*/ new Vector3(); -const _z = /*@__PURE__*/ new Vector3(); - -const _matrix$2 = /*@__PURE__*/ new Matrix4(); -const _quaternion$4 = /*@__PURE__*/ new Quaternion(); - -/** - * A class representing Euler angles. - * - * Euler angles describe a rotational transformation by rotating an object on - * its various axes in specified amounts per axis, and a specified axis - * order. - * - * Iterating through an instance will yield its components (x, y, z, - * order) in the corresponding order. - * - * ```js - * const a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); - * const b = new THREE.Vector3( 1, 0, 1 ); - * b.applyEuler(a); - * ``` - */ -class Euler { - /** - * Constructs a new euler instance. + * Dispatches the given event to the groups representing + * the different coordinate spaces of the XR controller. * - * @param {number} [x=0] - The angle of the x axis in radians. - * @param {number} [y=0] - The angle of the y axis in radians. - * @param {number} [z=0] - The angle of the z axis in radians. - * @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied. + * @param {Object} event - The event to dispatch. + * @return {WebXRController} A reference to this instance. */ - constructor( x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER ) { + dispatchEvent( event ) { - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isEuler = true; + if ( this._targetRay !== null ) { - this._x = x; - this._y = y; - this._z = z; - this._order = order; + this._targetRay.dispatchEvent( event ); - } + } - /** - * The angle of the x axis in radians. - * - * @type {number} - * @default 0 - */ - get x() { + if ( this._grip !== null ) { - return this._x; + this._grip.dispatchEvent( event ); - } + } - set x( value ) { + if ( this._hand !== null ) { - this._x = value; - this._onChangeCallback(); + this._hand.dispatchEvent( event ); + + } + + return this; } /** - * The angle of the y axis in radians. + * Connects the controller with the given XR input source. * - * @type {number} - * @default 0 + * @param {XRInputSource} inputSource - The input source. + * @return {WebXRController} A reference to this instance. */ - get y() { + connect( inputSource ) { - return this._y; + if ( inputSource && inputSource.hand ) { - } + const hand = this._hand; - set y( value ) { + if ( hand ) { - this._y = value; - this._onChangeCallback(); + for ( const inputjoint of inputSource.hand.values() ) { - } + // Initialize hand with joints when connected + this._getHandJoint( hand, inputjoint ); - /** - * The angle of the z axis in radians. - * - * @type {number} - * @default 0 - */ - get z() { + } - return this._z; + } - } + } - set z( value ) { + this.dispatchEvent( { type: 'connected', data: inputSource } ); - this._z = value; - this._onChangeCallback(); + return this; } /** - * A string representing the order that the rotations are applied. + * Disconnects the controller from the given XR input source. * - * @type {string} - * @default 'XYZ' + * @param {XRInputSource} inputSource - The input source. + * @return {WebXRController} A reference to this instance. */ - get order() { + disconnect( inputSource ) { - return this._order; + this.dispatchEvent( { type: 'disconnected', data: inputSource } ); - } + if ( this._targetRay !== null ) { - set order( value ) { + this._targetRay.visible = false; - this._order = value; - this._onChangeCallback(); + } - } + if ( this._grip !== null ) { - /** - * Sets the Euler components. - * - * @param {number} x - The angle of the x axis in radians. - * @param {number} y - The angle of the y axis in radians. - * @param {number} z - The angle of the z axis in radians. - * @param {string} [order] - A string representing the order that the rotations are applied. - * @return {Euler} A reference to this Euler instance. - */ - set( x, y, z, order = this._order ) { + this._grip.visible = false; - this._x = x; - this._y = y; - this._z = z; - this._order = order; + } - this._onChangeCallback(); + if ( this._hand !== null ) { + + this._hand.visible = false; + + } return this; } /** - * Returns a new Euler instance with copied values from this instance. + * Updates the controller with the given input source, XR frame and reference space. + * This updates the transformations of the groups that represent the different + * coordinate systems of the controller. * - * @return {Euler} A clone of this instance. + * @param {XRInputSource} inputSource - The input source. + * @param {XRFrame} frame - The XR frame. + * @param {XRReferenceSpace} referenceSpace - The reference space. + * @return {WebXRController} A reference to this instance. */ - clone() { + update( inputSource, frame, referenceSpace ) { - return new this.constructor( this._x, this._y, this._z, this._order ); + let inputPose = null; + let gripPose = null; + let handPose = null; - } + const targetRay = this._targetRay; + const grip = this._grip; + const hand = this._hand; - /** - * Copies the values of the given Euler instance to this instance. - * - * @param {Euler} euler - The Euler instance to copy. - * @return {Euler} A reference to this Euler instance. - */ - copy( euler ) { + if ( inputSource && frame.session.visibilityState !== 'visible-blurred' ) { - this._x = euler._x; - this._y = euler._y; - this._z = euler._z; - this._order = euler._order; + if ( hand && inputSource.hand ) { - this._onChangeCallback(); + handPose = true; - return this; + for ( const inputjoint of inputSource.hand.values() ) { - } + // Update the joints groups with the XRJoint poses + const jointPose = frame.getJointPose( inputjoint, referenceSpace ); - /** - * Sets the angles of this Euler instance from a pure rotation matrix. - * - * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled). - * @param {string} [order] - A string representing the order that the rotations are applied. - * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. - * @return {Euler} A reference to this Euler instance. - */ - setFromRotationMatrix( m, order = this._order, update = true ) { + // The transform of this joint will be updated with the joint pose on each frame + const joint = this._getHandJoint( hand, inputjoint ); - const te = m.elements; - const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; - const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; - const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; + if ( jointPose !== null ) { - switch ( order ) { + joint.matrix.fromArray( jointPose.transform.matrix ); + joint.matrix.decompose( joint.position, joint.rotation, joint.scale ); + joint.matrixWorldNeedsUpdate = true; + joint.jointRadius = jointPose.radius; - case 'XYZ': + } - this._y = Math.asin( clamp( m13, -1, 1 ) ); + joint.visible = jointPose !== null; - if ( Math.abs( m13 ) < 0.9999999 ) { + } - this._x = Math.atan2( - m23, m33 ); - this._z = Math.atan2( - m12, m11 ); + // Custom events - } else { + // Check pinchz + const indexTip = hand.joints[ 'index-finger-tip' ]; + const thumbTip = hand.joints[ 'thumb-tip' ]; + const distance = indexTip.position.distanceTo( thumbTip.position ); - this._x = Math.atan2( m32, m22 ); - this._z = 0; + const distanceToPinch = 0.02; + const threshold = 0.005; + + if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) { + + hand.inputState.pinching = false; + this.dispatchEvent( { + type: 'pinchend', + handedness: inputSource.handedness, + target: this + } ); + + } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) { + + hand.inputState.pinching = true; + this.dispatchEvent( { + type: 'pinchstart', + handedness: inputSource.handedness, + target: this + } ); } - break; + } else { - case 'YXZ': + if ( grip !== null && inputSource.gripSpace ) { - this._x = Math.asin( - clamp( m23, -1, 1 ) ); + gripPose = frame.getPose( inputSource.gripSpace, referenceSpace ); - if ( Math.abs( m23 ) < 0.9999999 ) { + if ( gripPose !== null ) { - this._y = Math.atan2( m13, m33 ); - this._z = Math.atan2( m21, m22 ); + grip.matrix.fromArray( gripPose.transform.matrix ); + grip.matrix.decompose( grip.position, grip.rotation, grip.scale ); + grip.matrixWorldNeedsUpdate = true; - } else { + if ( gripPose.linearVelocity ) { - this._y = Math.atan2( - m31, m11 ); - this._z = 0; + grip.hasLinearVelocity = true; + grip.linearVelocity.copy( gripPose.linearVelocity ); - } + } else { - break; + grip.hasLinearVelocity = false; - case 'ZXY': + } - this._x = Math.asin( clamp( m32, -1, 1 ) ); + if ( gripPose.angularVelocity ) { - if ( Math.abs( m32 ) < 0.9999999 ) { + grip.hasAngularVelocity = true; + grip.angularVelocity.copy( gripPose.angularVelocity ); - this._y = Math.atan2( - m31, m33 ); - this._z = Math.atan2( - m12, m22 ); + } else { - } else { + grip.hasAngularVelocity = false; - this._y = 0; - this._z = Math.atan2( m21, m11 ); + } + + } } - break; + } - case 'ZYX': + if ( targetRay !== null ) { - this._y = Math.asin( - clamp( m31, -1, 1 ) ); + inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); - if ( Math.abs( m31 ) < 0.9999999 ) { + // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it + if ( inputPose === null && gripPose !== null ) { - this._x = Math.atan2( m32, m33 ); - this._z = Math.atan2( m21, m11 ); + inputPose = gripPose; - } else { + } - this._x = 0; - this._z = Math.atan2( - m12, m22 ); + if ( inputPose !== null ) { - } + targetRay.matrix.fromArray( inputPose.transform.matrix ); + targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale ); + targetRay.matrixWorldNeedsUpdate = true; - break; + if ( inputPose.linearVelocity ) { - case 'YZX': + targetRay.hasLinearVelocity = true; + targetRay.linearVelocity.copy( inputPose.linearVelocity ); - this._z = Math.asin( clamp( m21, -1, 1 ) ); + } else { - if ( Math.abs( m21 ) < 0.9999999 ) { + targetRay.hasLinearVelocity = false; - this._x = Math.atan2( - m23, m22 ); - this._y = Math.atan2( - m31, m11 ); + } - } else { + if ( inputPose.angularVelocity ) { - this._x = 0; - this._y = Math.atan2( m13, m33 ); + targetRay.hasAngularVelocity = true; + targetRay.angularVelocity.copy( inputPose.angularVelocity ); - } + } else { - break; + targetRay.hasAngularVelocity = false; - case 'XZY': + } - this._z = Math.asin( - clamp( m12, -1, 1 ) ); + this.dispatchEvent( _moveEvent ); - if ( Math.abs( m12 ) < 0.9999999 ) { + } - this._x = Math.atan2( m32, m22 ); - this._y = Math.atan2( m13, m11 ); + } - } else { - this._x = Math.atan2( - m23, m33 ); - this._y = 0; + } - } + if ( targetRay !== null ) { - break; + targetRay.visible = ( inputPose !== null ); - default: + } - warn( 'Euler: .setFromRotationMatrix() encountered an unknown order: ' + order ); + if ( grip !== null ) { + + grip.visible = ( gripPose !== null ); } - this._order = order; + if ( hand !== null ) { - if ( update === true ) this._onChangeCallback(); + hand.visible = ( handPose !== null ); + + } return this; } /** - * Sets the angles of this Euler instance from a normalized quaternion. + * Returns a group representing the hand joint for the given input joint. * - * @param {Quaternion} q - A normalized Quaternion. - * @param {string} [order] - A string representing the order that the rotations are applied. - * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. - * @return {Euler} A reference to this Euler instance. + * @private + * @param {Group} hand - The group representing the hand space. + * @param {XRJointSpace} inputjoint - The hand joint data. + * @return {Group} A group representing the hand joint for the given input joint. */ - setFromQuaternion( q, order, update ) { + _getHandJoint( hand, inputjoint ) { - _matrix$2.makeRotationFromQuaternion( q ); + if ( hand.joints[ inputjoint.jointName ] === undefined ) { - return this.setFromRotationMatrix( _matrix$2, order, update ); + const joint = new Group(); + joint.matrixAutoUpdate = false; + joint.visible = false; + hand.joints[ inputjoint.jointName ] = joint; - } + hand.add( joint ); - /** - * Sets the angles of this Euler instance from the given vector. - * - * @param {Vector3} v - The vector. - * @param {string} [order] - A string representing the order that the rotations are applied. - * @return {Euler} A reference to this Euler instance. - */ - setFromVector3( v, order = this._order ) { + } - return this.set( v.x, v.y, v.z, order ); + return hand.joints[ inputjoint.jointName ]; } - /** - * Resets the euler angle with a new order by creating a quaternion from this - * euler angle and then setting this euler angle with the quaternion and the - * new order. - * - * Warning: This discards revolution information. - * - * @param {string} [newOrder] - A string representing the new order that the rotations are applied. - * @return {Euler} A reference to this Euler instance. - */ - reorder( newOrder ) { +} - _quaternion$4.setFromEuler( this ); +const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, + 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, + 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, + 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, + 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, + 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, + 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, + 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, + 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, + 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, + 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, + 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, + 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, + 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, + 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, + 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, + 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, + 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, + 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, + 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, + 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, + 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, + 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, + 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; - return this.setFromQuaternion( _quaternion$4, newOrder ); +const _hslA = { h: 0, s: 0, l: 0 }; +const _hslB = { h: 0, s: 0, l: 0 }; - } +function hue2rgb( p, q, t ) { - /** - * Returns `true` if this Euler instance is equal with the given one. - * - * @param {Euler} euler - The Euler instance to test for equality. - * @return {boolean} Whether this Euler instance is equal with the given one. - */ - equals( euler ) { + if ( t < 0 ) t += 1; + if ( t > 1 ) t -= 1; + if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; + if ( t < 1 / 2 ) return q; + if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); + return p; - return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); +} - } +/** + * A Color instance is represented by RGB components in the linear working + * color space, which defaults to `LinearSRGBColorSpace`. Inputs + * conventionally using `SRGBColorSpace` (such as hexadecimals and CSS + * strings) are converted to the working color space automatically. + * + * ```js + * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace + * const color = new THREE.Color().setHex( 0x112233 ); + * ``` + * Source color spaces may be specified explicitly, to ensure correct conversions. + * ```js + * // assumed already LinearSRGBColorSpace; no conversion + * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 ); + * + * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace + * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace ); + * ``` + * If THREE.ColorManagement is disabled, no conversions occur. For details, + * see Color management. Iterating through a Color instance will yield + * its components (r, g, b) in the corresponding order. A Color can be initialised + * in any of the following ways: + * ```js + * //empty constructor - will default white + * const color1 = new THREE.Color(); + * + * //Hexadecimal color (recommended) + * const color2 = new THREE.Color( 0xff0000 ); + * + * //RGB string + * const color3 = new THREE.Color("rgb(255, 0, 0)"); + * const color4 = new THREE.Color("rgb(100%, 0%, 0%)"); + * + * //X11 color name - all 140 color names are supported. + * //Note the lack of CamelCase in the name + * const color5 = new THREE.Color( 'skyblue' ); + * //HSL string + * const color6 = new THREE.Color("hsl(0, 100%, 50%)"); + * + * //Separate RGB values between 0 and 1 + * const color7 = new THREE.Color( 1, 0, 0 ); + * ``` + */ +class Color { /** - * Sets this Euler instance's components to values from the given array. The first three - * entries of the array are assign to the x,y and z components. An optional fourth entry - * defines the Euler order. + * Constructs a new color. * - * @param {Array} array - An array holding the Euler component values. - * @return {Euler} A reference to this Euler instance. + * Note that standard method of specifying color in three.js is with a hexadecimal triplet, + * and that method is used throughout the rest of the documentation. + * + * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are + * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. + * @param {number} [g] - The green component. + * @param {number} [b] - The blue component. */ - fromArray( array ) { + constructor( r, g, b ) { - this._x = array[ 0 ]; - this._y = array[ 1 ]; - this._z = array[ 2 ]; - if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isColor = true; - this._onChangeCallback(); + /** + * The red component. + * + * @type {number} + * @default 1 + */ + this.r = 1; - return this; + /** + * The green component. + * + * @type {number} + * @default 1 + */ + this.g = 1; + + /** + * The blue component. + * + * @type {number} + * @default 1 + */ + this.b = 1; + + return this.set( r, g, b ); } /** - * Writes the components of this Euler instance to the given array. If no array is provided, - * the method returns a new instance. + * Sets the colors's components from the given values. * - * @param {Array} [array=[]] - The target array holding the Euler components. - * @param {number} [offset=0] - Index of the first element in the array. - * @return {Array} The Euler components. + * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are + * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. + * @param {number} [g] - The green component. + * @param {number} [b] - The blue component. + * @return {Color} A reference to this color. */ - toArray( array = [], offset = 0 ) { - - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._order; - - return array; + set( r, g, b ) { - } + if ( g === undefined && b === undefined ) { - _onChange( callback ) { + // r is THREE.Color, hex or string - this._onChangeCallback = callback; + const value = r; - return this; + if ( value && value.isColor ) { - } + this.copy( value ); - _onChangeCallback() {} + } else if ( typeof value === 'number' ) { - *[ Symbol.iterator ]() { + this.setHex( value ); - yield this._x; - yield this._y; - yield this._z; - yield this._order; + } else if ( typeof value === 'string' ) { - } + this.setStyle( value ); -} + } -/** - * The default Euler angle order. - * - * @static - * @type {string} - * @default 'XYZ' - */ -Euler.DEFAULT_ORDER = 'XYZ'; + } else { -/** - * A layers object assigns an 3D object to 1 or more of 32 - * layers numbered `0` to `31` - internally the layers are stored as a - * bit mask], and by default all 3D objects are a member of layer `0`. - * - * This can be used to control visibility - an object must share a layer with - * a camera to be visible when that camera's view is - * rendered. - * - * All classes that inherit from {@link Object3D} have an `layers` property which - * is an instance of this class. - */ -class Layers { + this.setRGB( r, g, b ); - /** - * Constructs a new layers instance, with membership - * initially set to layer `0`. - */ - constructor() { + } - /** - * A bit mask storing which of the 32 layers this layers object is currently - * a member of. - * - * @type {number} - */ - this.mask = 1 | 0; + return this; } /** - * Sets membership to the given layer, and remove membership all other layers. + * Sets the colors's components to the given scalar value. * - * @param {number} layer - The layer to set. + * @param {number} scalar - The scalar value. + * @return {Color} A reference to this color. */ - set( layer ) { + setScalar( scalar ) { - this.mask = ( 1 << layer | 0 ) >>> 0; + this.r = scalar; + this.g = scalar; + this.b = scalar; + + return this; } /** - * Adds membership of the given layer. + * Sets this color from a hexadecimal value. * - * @param {number} layer - The layer to enable. + * @param {number} hex - The hexadecimal value. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {Color} A reference to this color. */ - enable( layer ) { + setHex( hex, colorSpace = SRGBColorSpace ) { - this.mask |= 1 << layer | 0; + hex = Math.floor( hex ); - } + this.r = ( hex >> 16 & 255 ) / 255; + this.g = ( hex >> 8 & 255 ) / 255; + this.b = ( hex & 255 ) / 255; - /** - * Adds membership to all layers. - */ - enableAll() { + ColorManagement.colorSpaceToWorking( this, colorSpace ); - this.mask = 0xffffffff | 0; + return this; } /** - * Toggles the membership of the given layer. + * Sets this color from RGB values. * - * @param {number} layer - The layer to toggle. + * @param {number} r - Red channel value between `0.0` and `1.0`. + * @param {number} g - Green channel value between `0.0` and `1.0`. + * @param {number} b - Blue channel value between `0.0` and `1.0`. + * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. + * @return {Color} A reference to this color. */ - toggle( layer ) { + setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) { - this.mask ^= 1 << layer | 0; + this.r = r; + this.g = g; + this.b = b; + + ColorManagement.colorSpaceToWorking( this, colorSpace ); + + return this; } /** - * Removes membership of the given layer. + * Sets this color from RGB values. * - * @param {number} layer - The layer to enable. + * @param {number} h - Hue value between `0.0` and `1.0`. + * @param {number} s - Saturation value between `0.0` and `1.0`. + * @param {number} l - Lightness value between `0.0` and `1.0`. + * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. + * @return {Color} A reference to this color. */ - disable( layer ) { + setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) { - this.mask &= ~ ( 1 << layer | 0 ); + // h,s,l ranges are in 0.0 - 1.0 + h = euclideanModulo( h, 1 ); + s = clamp( s, 0, 1 ); + l = clamp( l, 0, 1 ); - } + if ( s === 0 ) { - /** - * Removes the membership from all layers. - */ - disableAll() { + this.r = this.g = this.b = l; - this.mask = 0; + } else { - } + const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); + const q = ( 2 * l ) - p; - /** - * Returns `true` if this and the given layers object have at least one - * layer in common. - * - * @param {Layers} layers - The layers to test. - * @return {boolean } Whether this and the given layers object have at least one layer in common or not. - */ - test( layers ) { - - return ( this.mask & layers.mask ) !== 0; - - } - - /** - * Returns `true` if the given layer is enabled. - * - * @param {number} layer - The layer to test. - * @return {boolean } Whether the given layer is enabled or not. - */ - isEnabled( layer ) { - - return ( this.mask & ( 1 << layer | 0 ) ) !== 0; - - } - -} - -let _object3DId = 0; - -const _v1$4 = /*@__PURE__*/ new Vector3(); -const _q1 = /*@__PURE__*/ new Quaternion(); -const _m1$3 = /*@__PURE__*/ new Matrix4(); -const _target = /*@__PURE__*/ new Vector3(); - -const _position$4 = /*@__PURE__*/ new Vector3(); -const _scale$3 = /*@__PURE__*/ new Vector3(); -const _quaternion$3 = /*@__PURE__*/ new Quaternion(); - -const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 ); -const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 ); -const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 ); - -/** - * Fires when the object has been added to its parent object. - * - * @event Object3D#added - * @type {Object} - */ -const _addedEvent = { type: 'added' }; - -/** - * Fires when the object has been removed from its parent object. - * - * @event Object3D#removed - * @type {Object} - */ -const _removedEvent = { type: 'removed' }; - -/** - * Fires when a new child object has been added. - * - * @event Object3D#childadded - * @type {Object} - */ -const _childaddedEvent = { type: 'childadded', child: null }; - -/** - * Fires when a child object has been removed. - * - * @event Object3D#childremoved - * @type {Object} - */ -const _childremovedEvent = { type: 'childremoved', child: null }; - -/** - * This is the base class for most objects in three.js and provides a set of - * properties and methods for manipulating objects in 3D space. - * - * @augments EventDispatcher - */ -class Object3D extends EventDispatcher { - - /** - * Constructs a new 3D object. - */ - constructor() { - - super(); - - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isObject3D = true; - - /** - * The ID of the 3D object. - * - * @name Object3D#id - * @type {number} - * @readonly - */ - Object.defineProperty( this, 'id', { value: _object3DId ++ } ); - - /** - * The UUID of the 3D object. - * - * @type {string} - * @readonly - */ - this.uuid = generateUUID(); - - /** - * The name of the 3D object. - * - * @type {string} - */ - this.name = ''; - - /** - * The type property is used for detecting the object type - * in context of serialization/deserialization. - * - * @type {string} - * @readonly - */ - this.type = 'Object3D'; - - /** - * A reference to the parent object. - * - * @type {?Object3D} - * @default null - */ - this.parent = null; - - /** - * An array holding the child 3D objects of this instance. - * - * @type {Array} - */ - this.children = []; - - /** - * Defines the `up` direction of the 3D object which influences - * the orientation via methods like {@link Object3D#lookAt}. - * - * The default values for all 3D objects is defined by `Object3D.DEFAULT_UP`. - * - * @type {Vector3} - */ - this.up = Object3D.DEFAULT_UP.clone(); - - const position = new Vector3(); - const rotation = new Euler(); - const quaternion = new Quaternion(); - const scale = new Vector3( 1, 1, 1 ); - - function onRotationChange() { - - quaternion.setFromEuler( rotation, false ); - - } - - function onQuaternionChange() { - - rotation.setFromQuaternion( quaternion, undefined, false ); - - } - - rotation._onChange( onRotationChange ); - quaternion._onChange( onQuaternionChange ); - - Object.defineProperties( this, { - /** - * Represents the object's local position. - * - * @name Object3D#position - * @type {Vector3} - * @default (0,0,0) - */ - position: { - configurable: true, - enumerable: true, - value: position - }, - /** - * Represents the object's local rotation as Euler angles, in radians. - * - * @name Object3D#rotation - * @type {Euler} - * @default (0,0,0) - */ - rotation: { - configurable: true, - enumerable: true, - value: rotation - }, - /** - * Represents the object's local rotation as Quaternions. - * - * @name Object3D#quaternion - * @type {Quaternion} - */ - quaternion: { - configurable: true, - enumerable: true, - value: quaternion - }, - /** - * Represents the object's local scale. - * - * @name Object3D#scale - * @type {Vector3} - * @default (1,1,1) - */ - scale: { - configurable: true, - enumerable: true, - value: scale - }, - /** - * Represents the object's model-view matrix. - * - * @name Object3D#modelViewMatrix - * @type {Matrix4} - */ - modelViewMatrix: { - value: new Matrix4() - }, - /** - * Represents the object's normal matrix. - * - * @name Object3D#normalMatrix - * @type {Matrix3} - */ - normalMatrix: { - value: new Matrix3() - } - } ); - - /** - * Represents the object's transformation matrix in local space. - * - * @type {Matrix4} - */ - this.matrix = new Matrix4(); - - /** - * Represents the object's transformation matrix in world space. - * If the 3D object has no parent, then it's identical to the local transformation matrix - * - * @type {Matrix4} - */ - this.matrixWorld = new Matrix4(); - - /** - * When set to `true`, the engine automatically computes the local matrix from position, - * rotation and scale every frame. - * - * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_AUTO_UPDATE`. - * - * @type {boolean} - * @default true - */ - this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE; - - /** - * When set to `true`, the engine automatically computes the world matrix from the current local - * matrix and the object's transformation hierarchy. - * - * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE`. - * - * @type {boolean} - * @default true - */ - this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer - - /** - * When set to `true`, it calculates the world matrix in that frame and resets this property - * to `false`. - * - * @type {boolean} - * @default false - */ - this.matrixWorldNeedsUpdate = false; - - /** - * The layer membership of the 3D object. The 3D object is only visible if it has - * at least one layer in common with the camera in use. This property can also be - * used to filter out unwanted objects in ray-intersection tests when using {@link Raycaster}. - * - * @type {Layers} - */ - this.layers = new Layers(); - - /** - * When set to `true`, the 3D object gets rendered. - * - * @type {boolean} - * @default true - */ - this.visible = true; - - /** - * When set to `true`, the 3D object gets rendered into shadow maps. - * - * @type {boolean} - * @default false - */ - this.castShadow = false; - - /** - * When set to `true`, the 3D object is affected by shadows in the scene. - * - * @type {boolean} - * @default false - */ - this.receiveShadow = false; - - /** - * When set to `true`, the 3D object is honored by view frustum culling. - * - * @type {boolean} - * @default true - */ - this.frustumCulled = true; - - /** - * This value allows the default rendering order of scene graph objects to be - * overridden although opaque and transparent objects remain sorted independently. - * When this property is set for an instance of {@link Group},all descendants - * objects will be sorted and rendered together. Sorting is from lowest to highest - * render order. - * - * @type {number} - * @default 0 - */ - this.renderOrder = 0; - - /** - * An array holding the animation clips of the 3D object. - * - * @type {Array} - */ - this.animations = []; - - /** - * Custom depth material to be used when rendering to the depth map. Can only be used - * in context of meshes. When shadow-casting with a {@link DirectionalLight} or {@link SpotLight}, - * if you are modifying vertex positions in the vertex shader you must specify a custom depth - * material for proper shadows. - * - * Only relevant in context of {@link WebGLRenderer}. - * - * @type {(Material|undefined)} - * @default undefined - */ - this.customDepthMaterial = undefined; - - /** - * Same as {@link Object3D#customDepthMaterial}, but used with {@link PointLight}. - * - * Only relevant in context of {@link WebGLRenderer}. - * - * @type {(Material|undefined)} - * @default undefined - */ - this.customDistanceMaterial = undefined; - - /** - * Whether the 3D object is supposed to be static or not. If set to `true`, it means - * the 3D object is not going to be changed after the initial renderer. This includes - * geometry and material settings. A static 3D object can be processed by the renderer - * slightly faster since certain state checks can be bypassed. - * - * Only relevant in context of {@link WebGPURenderer}. - * - * @type {boolean} - * @default false - */ - this.static = false; - - /** - * An object that can be used to store custom data about the 3D object. It - * should not hold references to functions as these will not be cloned. - * - * @type {Object} - */ - this.userData = {}; - - /** - * The pivot point for rotation and scale transformations. - * When set, rotation and scale are applied around this point - * instead of the object's origin. - * - * @type {?Vector3} - * @default null - */ - this.pivot = null; - - } - - /** - * A callback that is executed immediately before a 3D object is rendered to a shadow map. - * - * @param {Renderer|WebGLRenderer} renderer - The renderer. - * @param {Object3D} object - The 3D object. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {Camera} shadowCamera - The shadow camera. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Material} depthMaterial - The depth material. - * @param {Object} group - The geometry group data. - */ - onBeforeShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {} - - /** - * A callback that is executed immediately after a 3D object is rendered to a shadow map. - * - * @param {Renderer|WebGLRenderer} renderer - The renderer. - * @param {Object3D} object - The 3D object. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {Camera} shadowCamera - The shadow camera. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Material} depthMaterial - The depth material. - * @param {Object} group - The geometry group data. - */ - onAfterShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {} - - /** - * A callback that is executed immediately before a 3D object is rendered. - * - * @param {Renderer|WebGLRenderer} renderer - The renderer. - * @param {Object3D} object - The 3D object. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Material} material - The 3D object's material. - * @param {Object} group - The geometry group data. - */ - onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {} - - /** - * A callback that is executed immediately after a 3D object is rendered. - * - * @param {Renderer|WebGLRenderer} renderer - The renderer. - * @param {Object3D} object - The 3D object. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Material} material - The 3D object's material. - * @param {Object} group - The geometry group data. - */ - onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {} - - /** - * Applies the given transformation matrix to the object and updates the object's position, - * rotation and scale. - * - * @param {Matrix4} matrix - The transformation matrix. - */ - applyMatrix4( matrix ) { - - if ( this.matrixAutoUpdate ) this.updateMatrix(); - - this.matrix.premultiply( matrix ); - - this.matrix.decompose( this.position, this.quaternion, this.scale ); - - } - - /** - * Applies a rotation represented by given the quaternion to the 3D object. - * - * @param {Quaternion} q - The quaternion. - * @return {Object3D} A reference to this instance. - */ - applyQuaternion( q ) { - - this.quaternion.premultiply( q ); - - return this; - - } - - /** - * Sets the given rotation represented as an axis/angle couple to the 3D object. - * - * @param {Vector3} axis - The (normalized) axis vector. - * @param {number} angle - The angle in radians. - */ - setRotationFromAxisAngle( axis, angle ) { - - // assumes axis is normalized - - this.quaternion.setFromAxisAngle( axis, angle ); - - } - - /** - * Sets the given rotation represented as Euler angles to the 3D object. - * - * @param {Euler} euler - The Euler angles. - */ - setRotationFromEuler( euler ) { - - this.quaternion.setFromEuler( euler, true ); - - } - - /** - * Sets the given rotation represented as rotation matrix to the 3D object. - * - * @param {Matrix4} m - Although a 4x4 matrix is expected, the upper 3x3 portion must be - * a pure rotation matrix (i.e, unscaled). - */ - setRotationFromMatrix( m ) { - - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - - this.quaternion.setFromRotationMatrix( m ); - - } - - /** - * Sets the given rotation represented as a Quaternion to the 3D object. - * - * @param {Quaternion} q - The Quaternion - */ - setRotationFromQuaternion( q ) { - - // assumes q is normalized - - this.quaternion.copy( q ); - - } - - /** - * Rotates the 3D object along an axis in local space. - * - * @param {Vector3} axis - The (normalized) axis vector. - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. - */ - rotateOnAxis( axis, angle ) { - - // rotate object on axis in object space - // axis is assumed to be normalized - - _q1.setFromAxisAngle( axis, angle ); - - this.quaternion.multiply( _q1 ); - - return this; - - } - - /** - * Rotates the 3D object along an axis in world space. - * - * @param {Vector3} axis - The (normalized) axis vector. - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. - */ - rotateOnWorldAxis( axis, angle ) { - - // rotate object on axis in world space - // axis is assumed to be normalized - // method assumes no rotated parent - - _q1.setFromAxisAngle( axis, angle ); - - this.quaternion.premultiply( _q1 ); - - return this; - - } - - /** - * Rotates the 3D object around its X axis in local space. - * - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. - */ - rotateX( angle ) { - - return this.rotateOnAxis( _xAxis, angle ); - - } - - /** - * Rotates the 3D object around its Y axis in local space. - * - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. - */ - rotateY( angle ) { - - return this.rotateOnAxis( _yAxis, angle ); - - } - - /** - * Rotates the 3D object around its Z axis in local space. - * - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. - */ - rotateZ( angle ) { - - return this.rotateOnAxis( _zAxis, angle ); - - } - - /** - * Translate the 3D object by a distance along the given axis in local space. - * - * @param {Vector3} axis - The (normalized) axis vector. - * @param {number} distance - The distance in world units. - * @return {Object3D} A reference to this instance. - */ - translateOnAxis( axis, distance ) { - - // translate object by distance along axis in object space - // axis is assumed to be normalized - - _v1$4.copy( axis ).applyQuaternion( this.quaternion ); - - this.position.add( _v1$4.multiplyScalar( distance ) ); - - return this; - - } - - /** - * Translate the 3D object by a distance along its X-axis in local space. - * - * @param {number} distance - The distance in world units. - * @return {Object3D} A reference to this instance. - */ - translateX( distance ) { - - return this.translateOnAxis( _xAxis, distance ); - - } - - /** - * Translate the 3D object by a distance along its Y-axis in local space. - * - * @param {number} distance - The distance in world units. - * @return {Object3D} A reference to this instance. - */ - translateY( distance ) { - - return this.translateOnAxis( _yAxis, distance ); - - } - - /** - * Translate the 3D object by a distance along its Z-axis in local space. - * - * @param {number} distance - The distance in world units. - * @return {Object3D} A reference to this instance. - */ - translateZ( distance ) { - - return this.translateOnAxis( _zAxis, distance ); - - } - - /** - * Converts the given vector from this 3D object's local space to world space. - * - * @param {Vector3} vector - The vector to convert. - * @return {Vector3} The converted vector. - */ - localToWorld( vector ) { - - this.updateWorldMatrix( true, false ); - - return vector.applyMatrix4( this.matrixWorld ); - - } - - /** - * Converts the given vector from this 3D object's world space to local space. - * - * @param {Vector3} vector - The vector to convert. - * @return {Vector3} The converted vector. - */ - worldToLocal( vector ) { - - this.updateWorldMatrix( true, false ); - - return vector.applyMatrix4( _m1$3.copy( this.matrixWorld ).invert() ); - - } - - /** - * Rotates the object to face a point in world space. - * - * This method does not support objects having non-uniformly-scaled parent(s). - * - * @param {number|Vector3} x - The x coordinate in world space. Alternatively, a vector representing a position in world space - * @param {number} [y] - The y coordinate in world space. - * @param {number} [z] - The z coordinate in world space. - */ - lookAt( x, y, z ) { - - // This method does not support objects having non-uniformly-scaled parent(s) - - if ( x.isVector3 ) { - - _target.copy( x ); - - } else { - - _target.set( x, y, z ); - - } - - const parent = this.parent; - - this.updateWorldMatrix( true, false ); - - _position$4.setFromMatrixPosition( this.matrixWorld ); - - if ( this.isCamera || this.isLight ) { - - _m1$3.lookAt( _position$4, _target, this.up ); - - } else { - - _m1$3.lookAt( _target, _position$4, this.up ); - - } - - this.quaternion.setFromRotationMatrix( _m1$3 ); - - if ( parent ) { - - _m1$3.extractRotation( parent.matrixWorld ); - _q1.setFromRotationMatrix( _m1$3 ); - this.quaternion.premultiply( _q1.invert() ); - - } - - } - - /** - * Adds the given 3D object as a child to this 3D object. An arbitrary number of - * objects may be added. Any current parent on an object passed in here will be - * removed, since an object can have at most one parent. - * - * @fires Object3D#added - * @fires Object3D#childadded - * @param {Object3D} object - The 3D object to add. - * @return {Object3D} A reference to this instance. - */ - add( object ) { - - if ( arguments.length > 1 ) { - - for ( let i = 0; i < arguments.length; i ++ ) { - - this.add( arguments[ i ] ); - - } - - return this; - - } - - if ( object === this ) { - - error( 'Object3D.add: object can\'t be added as a child of itself.', object ); - return this; - - } - - if ( object && object.isObject3D ) { - - object.removeFromParent(); - object.parent = this; - this.children.push( object ); - - object.dispatchEvent( _addedEvent ); - - _childaddedEvent.child = object; - this.dispatchEvent( _childaddedEvent ); - _childaddedEvent.child = null; - - } else { - - error( 'Object3D.add: object not an instance of THREE.Object3D.', object ); - - } - - return this; - - } - - /** - * Removes the given 3D object as child from this 3D object. - * An arbitrary number of objects may be removed. - * - * @fires Object3D#removed - * @fires Object3D#childremoved - * @param {Object3D} object - The 3D object to remove. - * @return {Object3D} A reference to this instance. - */ - remove( object ) { - - if ( arguments.length > 1 ) { - - for ( let i = 0; i < arguments.length; i ++ ) { - - this.remove( arguments[ i ] ); - - } - - return this; - - } - - const index = this.children.indexOf( object ); - - if ( index !== -1 ) { - - object.parent = null; - this.children.splice( index, 1 ); - - object.dispatchEvent( _removedEvent ); - - _childremovedEvent.child = object; - this.dispatchEvent( _childremovedEvent ); - _childremovedEvent.child = null; - - } - - return this; - - } - - /** - * Removes this 3D object from its current parent. - * - * @fires Object3D#removed - * @fires Object3D#childremoved - * @return {Object3D} A reference to this instance. - */ - removeFromParent() { - - const parent = this.parent; - - if ( parent !== null ) { - - parent.remove( this ); - - } - - return this; - - } - - /** - * Removes all child objects. - * - * @fires Object3D#removed - * @fires Object3D#childremoved - * @return {Object3D} A reference to this instance. - */ - clear() { - - return this.remove( ... this.children ); - - } - - /** - * Adds the given 3D object as a child of this 3D object, while maintaining the object's world - * transform. This method does not support scene graphs having non-uniformly-scaled nodes(s). - * - * @fires Object3D#added - * @fires Object3D#childadded - * @param {Object3D} object - The 3D object to attach. - * @return {Object3D} A reference to this instance. - */ - attach( object ) { - - // adds object as a child of this, while maintaining the object's world transform - - // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) - - this.updateWorldMatrix( true, false ); - - _m1$3.copy( this.matrixWorld ).invert(); - - if ( object.parent !== null ) { - - object.parent.updateWorldMatrix( true, false ); - - _m1$3.multiply( object.parent.matrixWorld ); - - } - - object.applyMatrix4( _m1$3 ); - - object.removeFromParent(); - object.parent = this; - this.children.push( object ); - - object.updateWorldMatrix( false, true ); - - object.dispatchEvent( _addedEvent ); - - _childaddedEvent.child = object; - this.dispatchEvent( _childaddedEvent ); - _childaddedEvent.child = null; - - return this; - - } - - /** - * Searches through the 3D object and its children, starting with the 3D object - * itself, and returns the first with a matching ID. - * - * @param {number} id - The id. - * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. - */ - getObjectById( id ) { - - return this.getObjectByProperty( 'id', id ); - - } - - /** - * Searches through the 3D object and its children, starting with the 3D object - * itself, and returns the first with a matching name. - * - * @param {string} name - The name. - * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. - */ - getObjectByName( name ) { - - return this.getObjectByProperty( 'name', name ); - - } - - /** - * Searches through the 3D object and its children, starting with the 3D object - * itself, and returns the first with a matching property value. - * - * @param {string} name - The name of the property. - * @param {any} value - The value. - * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. - */ - getObjectByProperty( name, value ) { - - if ( this[ name ] === value ) return this; - - for ( let i = 0, l = this.children.length; i < l; i ++ ) { - - const child = this.children[ i ]; - const object = child.getObjectByProperty( name, value ); - - if ( object !== undefined ) { - - return object; - - } - - } - - return undefined; - - } - - /** - * Searches through the 3D object and its children, starting with the 3D object - * itself, and returns all 3D objects with a matching property value. - * - * @param {string} name - The name of the property. - * @param {any} value - The value. - * @param {Array} result - The method stores the result in this array. - * @return {Array} The found 3D objects. - */ - getObjectsByProperty( name, value, result = [] ) { - - if ( this[ name ] === value ) result.push( this ); - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - children[ i ].getObjectsByProperty( name, value, result ); - - } - - return result; - - } - - /** - * Returns a vector representing the position of the 3D object in world space. - * - * @param {Vector3} target - The target vector the result is stored to. - * @return {Vector3} The 3D object's position in world space. - */ - getWorldPosition( target ) { - - this.updateWorldMatrix( true, false ); - - return target.setFromMatrixPosition( this.matrixWorld ); - - } - - /** - * Returns a Quaternion representing the position of the 3D object in world space. - * - * @param {Quaternion} target - The target Quaternion the result is stored to. - * @return {Quaternion} The 3D object's rotation in world space. - */ - getWorldQuaternion( target ) { - - this.updateWorldMatrix( true, false ); - - this.matrixWorld.decompose( _position$4, target, _scale$3 ); - - return target; - - } - - /** - * Returns a vector representing the scale of the 3D object in world space. - * - * @param {Vector3} target - The target vector the result is stored to. - * @return {Vector3} The 3D object's scale in world space. - */ - getWorldScale( target ) { - - this.updateWorldMatrix( true, false ); - - this.matrixWorld.decompose( _position$4, _quaternion$3, target ); - - return target; - - } - - /** - * Returns a vector representing the ("look") direction of the 3D object in world space. - * - * @param {Vector3} target - The target vector the result is stored to. - * @return {Vector3} The 3D object's direction in world space. - */ - getWorldDirection( target ) { - - this.updateWorldMatrix( true, false ); - - const e = this.matrixWorld.elements; - - return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); - - } - - /** - * Abstract method to get intersections between a casted ray and this - * 3D object. Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points} - * implement this method in order to use raycasting. - * - * @abstract - * @param {Raycaster} raycaster - The raycaster. - * @param {Array} intersects - An array holding the result of the method. - */ - raycast( /* raycaster, intersects */ ) {} - - /** - * Executes the callback on this 3D object and all descendants. - * - * Note: Modifying the scene graph inside the callback is discouraged. - * - * @param {Function} callback - A callback function that allows to process the current 3D object. - */ - traverse( callback ) { - - callback( this ); - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - children[ i ].traverse( callback ); - - } - - } - - /** - * Like {@link Object3D#traverse}, but the callback will only be executed for visible 3D objects. - * Descendants of invisible 3D objects are not traversed. - * - * Note: Modifying the scene graph inside the callback is discouraged. - * - * @param {Function} callback - A callback function that allows to process the current 3D object. - */ - traverseVisible( callback ) { - - if ( this.visible === false ) return; - - callback( this ); - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - children[ i ].traverseVisible( callback ); - - } - - } - - /** - * Like {@link Object3D#traverse}, but the callback will only be executed for all ancestors. - * - * Note: Modifying the scene graph inside the callback is discouraged. - * - * @param {Function} callback - A callback function that allows to process the current 3D object. - */ - traverseAncestors( callback ) { - - const parent = this.parent; - - if ( parent !== null ) { - - callback( parent ); - - parent.traverseAncestors( callback ); - - } - - } - - /** - * Updates the transformation matrix in local space by computing it from the current - * position, rotation and scale values. - */ - updateMatrix() { - - this.matrix.compose( this.position, this.quaternion, this.scale ); - - const pivot = this.pivot; - - if ( pivot !== null ) { - - const px = pivot.x, py = pivot.y, pz = pivot.z; - const te = this.matrix.elements; - - te[ 12 ] += px - te[ 0 ] * px - te[ 4 ] * py - te[ 8 ] * pz; - te[ 13 ] += py - te[ 1 ] * px - te[ 5 ] * py - te[ 9 ] * pz; - te[ 14 ] += pz - te[ 2 ] * px - te[ 6 ] * py - te[ 10 ] * pz; - - } - - this.matrixWorldNeedsUpdate = true; - - } - - /** - * Updates the transformation matrix in world space of this 3D objects and its descendants. - * - * To ensure correct results, this method also recomputes the 3D object's transformation matrix in - * local space. The computation of the local and world matrix can be controlled with the - * {@link Object3D#matrixAutoUpdate} and {@link Object3D#matrixWorldAutoUpdate} flags which are both - * `true` by default. Set these flags to `false` if you need more control over the update matrix process. - * - * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even - * when {@link Object3D#matrixWorldAutoUpdate} is set to `false`. - */ - updateMatrixWorld( force ) { - - if ( this.matrixAutoUpdate ) this.updateMatrix(); - - if ( this.matrixWorldNeedsUpdate || force ) { - - if ( this.matrixWorldAutoUpdate === true ) { - - if ( this.parent === null ) { - - this.matrixWorld.copy( this.matrix ); - - } else { - - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - - } - - } - - this.matrixWorldNeedsUpdate = false; - - force = true; - - } - - // make sure descendants are updated if required - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - const child = children[ i ]; - - child.updateMatrixWorld( force ); - - } - - } - - /** - * An alternative version of {@link Object3D#updateMatrixWorld} with more control over the - * update of ancestor and descendant nodes. - * - * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not. - * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not. - */ - updateWorldMatrix( updateParents, updateChildren ) { - - const parent = this.parent; - - if ( updateParents === true && parent !== null ) { - - parent.updateWorldMatrix( true, false ); - - } - - if ( this.matrixAutoUpdate ) this.updateMatrix(); - - if ( this.matrixWorldAutoUpdate === true ) { - - if ( this.parent === null ) { - - this.matrixWorld.copy( this.matrix ); - - } else { - - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - - } - - } - - // make sure descendants are updated - - if ( updateChildren === true ) { - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - const child = children[ i ]; - - child.updateWorldMatrix( false, true ); - - } - - } - - } - - /** - * Serializes the 3D object into JSON. - * - * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized 3D object. - * @see {@link ObjectLoader#parse} - */ - toJSON( meta ) { - - // meta is a string when called from JSON.stringify - const isRootObject = ( meta === undefined || typeof meta === 'string' ); - - const output = {}; - - // meta is a hash used to collect geometries, materials. - // not providing it implies that this is the root object - // being serialized. - if ( isRootObject ) { - - // initialize meta obj - meta = { - geometries: {}, - materials: {}, - textures: {}, - images: {}, - shapes: {}, - skeletons: {}, - animations: {}, - nodes: {} - }; - - output.metadata = { - version: 4.7, - type: 'Object', - generator: 'Object3D.toJSON' - }; - - } - - // standard Object3D serialization - - const object = {}; - - object.uuid = this.uuid; - object.type = this.type; - - if ( this.name !== '' ) object.name = this.name; - if ( this.castShadow === true ) object.castShadow = true; - if ( this.receiveShadow === true ) object.receiveShadow = true; - if ( this.visible === false ) object.visible = false; - if ( this.frustumCulled === false ) object.frustumCulled = false; - if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; - if ( this.static !== false ) object.static = this.static; - if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData; - - object.layers = this.layers.mask; - object.matrix = this.matrix.toArray(); - object.up = this.up.toArray(); - - if ( this.pivot !== null ) object.pivot = this.pivot.toArray(); - - if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; - - if ( this.morphTargetDictionary !== undefined ) object.morphTargetDictionary = Object.assign( {}, this.morphTargetDictionary ); - if ( this.morphTargetInfluences !== undefined ) object.morphTargetInfluences = this.morphTargetInfluences.slice(); - - // object specific properties - - if ( this.isInstancedMesh ) { - - object.type = 'InstancedMesh'; - object.count = this.count; - object.instanceMatrix = this.instanceMatrix.toJSON(); - if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON(); - - } - - if ( this.isBatchedMesh ) { - - object.type = 'BatchedMesh'; - object.perObjectFrustumCulled = this.perObjectFrustumCulled; - object.sortObjects = this.sortObjects; - - object.drawRanges = this._drawRanges; - object.reservedRanges = this._reservedRanges; - - object.geometryInfo = this._geometryInfo.map( info => ( { - ...info, - boundingBox: info.boundingBox ? info.boundingBox.toJSON() : undefined, - boundingSphere: info.boundingSphere ? info.boundingSphere.toJSON() : undefined - } ) ); - object.instanceInfo = this._instanceInfo.map( info => ( { ...info } ) ); - - object.availableInstanceIds = this._availableInstanceIds.slice(); - object.availableGeometryIds = this._availableGeometryIds.slice(); - - object.nextIndexStart = this._nextIndexStart; - object.nextVertexStart = this._nextVertexStart; - object.geometryCount = this._geometryCount; - - object.maxInstanceCount = this._maxInstanceCount; - object.maxVertexCount = this._maxVertexCount; - object.maxIndexCount = this._maxIndexCount; - - object.geometryInitialized = this._geometryInitialized; - - object.matricesTexture = this._matricesTexture.toJSON( meta ); - - object.indirectTexture = this._indirectTexture.toJSON( meta ); - - if ( this._colorsTexture !== null ) { - - object.colorsTexture = this._colorsTexture.toJSON( meta ); - - } - - if ( this.boundingSphere !== null ) { - - object.boundingSphere = this.boundingSphere.toJSON(); - - } - - if ( this.boundingBox !== null ) { - - object.boundingBox = this.boundingBox.toJSON(); - - } - - } - - // - - function serialize( library, element ) { - - if ( library[ element.uuid ] === undefined ) { - - library[ element.uuid ] = element.toJSON( meta ); - - } - - return element.uuid; - - } - - if ( this.isScene ) { - - if ( this.background ) { - - if ( this.background.isColor ) { - - object.background = this.background.toJSON(); - - } else if ( this.background.isTexture ) { - - object.background = this.background.toJSON( meta ).uuid; - - } - - } - - if ( this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true ) { - - object.environment = this.environment.toJSON( meta ).uuid; - - } - - } else if ( this.isMesh || this.isLine || this.isPoints ) { - - object.geometry = serialize( meta.geometries, this.geometry ); - - const parameters = this.geometry.parameters; - - if ( parameters !== undefined && parameters.shapes !== undefined ) { - - const shapes = parameters.shapes; - - if ( Array.isArray( shapes ) ) { - - for ( let i = 0, l = shapes.length; i < l; i ++ ) { - - const shape = shapes[ i ]; - - serialize( meta.shapes, shape ); - - } - - } else { - - serialize( meta.shapes, shapes ); - - } - - } - - } - - if ( this.isSkinnedMesh ) { - - object.bindMode = this.bindMode; - object.bindMatrix = this.bindMatrix.toArray(); - - if ( this.skeleton !== undefined ) { - - serialize( meta.skeletons, this.skeleton ); - - object.skeleton = this.skeleton.uuid; - - } - - } - - if ( this.material !== undefined ) { - - if ( Array.isArray( this.material ) ) { - - const uuids = []; - - for ( let i = 0, l = this.material.length; i < l; i ++ ) { - - uuids.push( serialize( meta.materials, this.material[ i ] ) ); - - } - - object.material = uuids; - - } else { - - object.material = serialize( meta.materials, this.material ); - - } - - } - - // - - if ( this.children.length > 0 ) { - - object.children = []; - - for ( let i = 0; i < this.children.length; i ++ ) { - - object.children.push( this.children[ i ].toJSON( meta ).object ); - - } - - } - - // - - if ( this.animations.length > 0 ) { - - object.animations = []; - - for ( let i = 0; i < this.animations.length; i ++ ) { - - const animation = this.animations[ i ]; - - object.animations.push( serialize( meta.animations, animation ) ); - - } - - } - - if ( isRootObject ) { - - const geometries = extractFromCache( meta.geometries ); - const materials = extractFromCache( meta.materials ); - const textures = extractFromCache( meta.textures ); - const images = extractFromCache( meta.images ); - const shapes = extractFromCache( meta.shapes ); - const skeletons = extractFromCache( meta.skeletons ); - const animations = extractFromCache( meta.animations ); - const nodes = extractFromCache( meta.nodes ); - - if ( geometries.length > 0 ) output.geometries = geometries; - if ( materials.length > 0 ) output.materials = materials; - if ( textures.length > 0 ) output.textures = textures; - if ( images.length > 0 ) output.images = images; - if ( shapes.length > 0 ) output.shapes = shapes; - if ( skeletons.length > 0 ) output.skeletons = skeletons; - if ( animations.length > 0 ) output.animations = animations; - if ( nodes.length > 0 ) output.nodes = nodes; - - } - - output.object = object; - - return output; - - // extract data from the cache hash - // remove metadata on each item - // and return as array - function extractFromCache( cache ) { - - const values = []; - for ( const key in cache ) { - - const data = cache[ key ]; - delete data.metadata; - values.push( data ); - - } - - return values; - - } - - } - - /** - * Returns a new 3D object with copied values from this instance. - * - * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are also cloned. - * @return {Object3D} A clone of this instance. - */ - clone( recursive ) { - - return new this.constructor().copy( this, recursive ); - - } - - /** - * Copies the values of the given 3D object to this instance. - * - * @param {Object3D} source - The 3D object to copy. - * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are cloned. - * @return {Object3D} A reference to this instance. - */ - copy( source, recursive = true ) { - - this.name = source.name; - - this.up.copy( source.up ); - - this.position.copy( source.position ); - this.rotation.order = source.rotation.order; - this.quaternion.copy( source.quaternion ); - this.scale.copy( source.scale ); - - if ( source.pivot !== null ) { - - this.pivot = source.pivot.clone(); - - } - - this.matrix.copy( source.matrix ); - this.matrixWorld.copy( source.matrixWorld ); - - this.matrixAutoUpdate = source.matrixAutoUpdate; - - this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; - this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - - this.layers.mask = source.layers.mask; - this.visible = source.visible; - - this.castShadow = source.castShadow; - this.receiveShadow = source.receiveShadow; - - this.frustumCulled = source.frustumCulled; - this.renderOrder = source.renderOrder; - - this.static = source.static; - - this.animations = source.animations.slice(); - - this.userData = JSON.parse( JSON.stringify( source.userData ) ); - - if ( recursive === true ) { - - for ( let i = 0; i < source.children.length; i ++ ) { - - const child = source.children[ i ]; - this.add( child.clone() ); - - } - - } - - return this; - - } - -} - -/** - * The default up direction for objects, also used as the default - * position for {@link DirectionalLight} and {@link HemisphereLight}. - * - * @static - * @type {Vector3} - * @default (0,1,0) - */ -Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 ); - -/** - * The default setting for {@link Object3D#matrixAutoUpdate} for - * newly created 3D objects. - * - * @static - * @type {boolean} - * @default true - */ -Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; - -/** - * The default setting for {@link Object3D#matrixWorldAutoUpdate} for - * newly created 3D objects. - * - * @static - * @type {boolean} - * @default true - */ -Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; - -const _v0$2 = /*@__PURE__*/ new Vector3(); -const _v1$3 = /*@__PURE__*/ new Vector3(); -const _v2$2 = /*@__PURE__*/ new Vector3(); -const _v3$2 = /*@__PURE__*/ new Vector3(); - -const _vab = /*@__PURE__*/ new Vector3(); -const _vac = /*@__PURE__*/ new Vector3(); -const _vbc = /*@__PURE__*/ new Vector3(); -const _vap = /*@__PURE__*/ new Vector3(); -const _vbp = /*@__PURE__*/ new Vector3(); -const _vcp = /*@__PURE__*/ new Vector3(); - -const _v40 = /*@__PURE__*/ new Vector4(); -const _v41 = /*@__PURE__*/ new Vector4(); -const _v42 = /*@__PURE__*/ new Vector4(); - -/** - * A geometric triangle as defined by three vectors representing its three corners. - */ -class Triangle { - - /** - * Constructs a new triangle. - * - * @param {Vector3} [a=(0,0,0)] - The first corner of the triangle. - * @param {Vector3} [b=(0,0,0)] - The second corner of the triangle. - * @param {Vector3} [c=(0,0,0)] - The third corner of the triangle. - */ - constructor( a = new Vector3(), b = new Vector3(), c = new Vector3() ) { - - /** - * The first corner of the triangle. - * - * @type {Vector3} - */ - this.a = a; - - /** - * The second corner of the triangle. - * - * @type {Vector3} - */ - this.b = b; - - /** - * The third corner of the triangle. - * - * @type {Vector3} - */ - this.c = c; - - } - - /** - * Computes the normal vector of a triangle. - * - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The triangle's normal. - */ - static getNormal( a, b, c, target ) { - - target.subVectors( c, b ); - _v0$2.subVectors( a, b ); - target.cross( _v0$2 ); - - const targetLengthSq = target.lengthSq(); - if ( targetLengthSq > 0 ) { - - return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); - - } - - return target.set( 0, 0, 0 ); - - } - - /** - * Computes a barycentric coordinates from the given vector. - * Returns `null` if the triangle is degenerate. - * - * @param {Vector3} point - A point in 3D space. - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The barycentric coordinates for the given point - */ - static getBarycoord( point, a, b, c, target ) { - - // based on: http://www.blackpawn.com/texts/pointinpoly/default.html - - _v0$2.subVectors( c, a ); - _v1$3.subVectors( b, a ); - _v2$2.subVectors( point, a ); - - const dot00 = _v0$2.dot( _v0$2 ); - const dot01 = _v0$2.dot( _v1$3 ); - const dot02 = _v0$2.dot( _v2$2 ); - const dot11 = _v1$3.dot( _v1$3 ); - const dot12 = _v1$3.dot( _v2$2 ); - - const denom = ( dot00 * dot11 - dot01 * dot01 ); - - // collinear or singular triangle - if ( denom === 0 ) { - - target.set( 0, 0, 0 ); - return null; - - } - - const invDenom = 1 / denom; - const u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; - const v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; - - // barycentric coordinates must always sum to 1 - return target.set( 1 - u - v, v, u ); - - } - - /** - * Returns `true` if the given point, when projected onto the plane of the - * triangle, lies within the triangle. - * - * @param {Vector3} point - The point in 3D space to test. - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @return {boolean} Whether the given point, when projected onto the plane of the - * triangle, lies within the triangle or not. - */ - static containsPoint( point, a, b, c ) { - - // if the triangle is degenerate then we can't contain a point - if ( this.getBarycoord( point, a, b, c, _v3$2 ) === null ) { - - return false; - - } - - return ( _v3$2.x >= 0 ) && ( _v3$2.y >= 0 ) && ( ( _v3$2.x + _v3$2.y ) <= 1 ); - - } - - /** - * Computes the value barycentrically interpolated for the given point on the - * triangle. Returns `null` if the triangle is degenerate. - * - * @param {Vector3} point - Position of interpolated point. - * @param {Vector3} p1 - The first corner of the triangle. - * @param {Vector3} p2 - The second corner of the triangle. - * @param {Vector3} p3 - The third corner of the triangle. - * @param {Vector3} v1 - Value to interpolate of first vertex. - * @param {Vector3} v2 - Value to interpolate of second vertex. - * @param {Vector3} v3 - Value to interpolate of third vertex. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The interpolated value. - */ - static getInterpolation( point, p1, p2, p3, v1, v2, v3, target ) { - - if ( this.getBarycoord( point, p1, p2, p3, _v3$2 ) === null ) { - - target.x = 0; - target.y = 0; - if ( 'z' in target ) target.z = 0; - if ( 'w' in target ) target.w = 0; - return null; - - } - - target.setScalar( 0 ); - target.addScaledVector( v1, _v3$2.x ); - target.addScaledVector( v2, _v3$2.y ); - target.addScaledVector( v3, _v3$2.z ); - - return target; - - } - - /** - * Computes the value barycentrically interpolated for the given attribute and indices. - * - * @param {BufferAttribute} attr - The attribute to interpolate. - * @param {number} i1 - Index of first vertex. - * @param {number} i2 - Index of second vertex. - * @param {number} i3 - Index of third vertex. - * @param {Vector3} barycoord - The barycoordinate value to use to interpolate. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The interpolated attribute value. - */ - static getInterpolatedAttribute( attr, i1, i2, i3, barycoord, target ) { - - _v40.setScalar( 0 ); - _v41.setScalar( 0 ); - _v42.setScalar( 0 ); - - _v40.fromBufferAttribute( attr, i1 ); - _v41.fromBufferAttribute( attr, i2 ); - _v42.fromBufferAttribute( attr, i3 ); - - target.setScalar( 0 ); - target.addScaledVector( _v40, barycoord.x ); - target.addScaledVector( _v41, barycoord.y ); - target.addScaledVector( _v42, barycoord.z ); - - return target; - - } - - /** - * Returns `true` if the triangle is oriented towards the given direction. - * - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @param {Vector3} direction - The (normalized) direction vector. - * @return {boolean} Whether the triangle is oriented towards the given direction or not. - */ - static isFrontFacing( a, b, c, direction ) { - - _v0$2.subVectors( c, b ); - _v1$3.subVectors( a, b ); - - // strictly front facing - return ( _v0$2.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false; - - } - - /** - * Sets the triangle's vertices by copying the given values. - * - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @return {Triangle} A reference to this triangle. - */ - set( a, b, c ) { - - this.a.copy( a ); - this.b.copy( b ); - this.c.copy( c ); - - return this; - - } - - /** - * Sets the triangle's vertices by copying the given array values. - * - * @param {Array} points - An array with 3D points. - * @param {number} i0 - The array index representing the first corner of the triangle. - * @param {number} i1 - The array index representing the second corner of the triangle. - * @param {number} i2 - The array index representing the third corner of the triangle. - * @return {Triangle} A reference to this triangle. - */ - setFromPointsAndIndices( points, i0, i1, i2 ) { - - this.a.copy( points[ i0 ] ); - this.b.copy( points[ i1 ] ); - this.c.copy( points[ i2 ] ); - - return this; - - } - - /** - * Sets the triangle's vertices by copying the given attribute values. - * - * @param {BufferAttribute} attribute - A buffer attribute with 3D points data. - * @param {number} i0 - The attribute index representing the first corner of the triangle. - * @param {number} i1 - The attribute index representing the second corner of the triangle. - * @param {number} i2 - The attribute index representing the third corner of the triangle. - * @return {Triangle} A reference to this triangle. - */ - setFromAttributeAndIndices( attribute, i0, i1, i2 ) { - - this.a.fromBufferAttribute( attribute, i0 ); - this.b.fromBufferAttribute( attribute, i1 ); - this.c.fromBufferAttribute( attribute, i2 ); - - return this; - - } - - /** - * Returns a new triangle with copied values from this instance. - * - * @return {Triangle} A clone of this instance. - */ - clone() { - - return new this.constructor().copy( this ); - - } - - /** - * Copies the values of the given triangle to this instance. - * - * @param {Triangle} triangle - The triangle to copy. - * @return {Triangle} A reference to this triangle. - */ - copy( triangle ) { - - this.a.copy( triangle.a ); - this.b.copy( triangle.b ); - this.c.copy( triangle.c ); - - return this; - - } - - /** - * Computes the area of the triangle. - * - * @return {number} The triangle's area. - */ - getArea() { - - _v0$2.subVectors( this.c, this.b ); - _v1$3.subVectors( this.a, this.b ); - - return _v0$2.cross( _v1$3 ).length() * 0.5; - - } - - /** - * Computes the midpoint of the triangle. - * - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The triangle's midpoint. - */ - getMidpoint( target ) { - - return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); - - } - - /** - * Computes the normal of the triangle. - * - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The triangle's normal. - */ - getNormal( target ) { - - return Triangle.getNormal( this.a, this.b, this.c, target ); - - } - - /** - * Computes a plane the triangle lies within. - * - * @param {Plane} target - The target vector that is used to store the method's result. - * @return {Plane} The plane the triangle lies within. - */ - getPlane( target ) { - - return target.setFromCoplanarPoints( this.a, this.b, this.c ); - - } - - /** - * Computes a barycentric coordinates from the given vector. - * Returns `null` if the triangle is degenerate. - * - * @param {Vector3} point - A point in 3D space. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The barycentric coordinates for the given point - */ - getBarycoord( point, target ) { - - return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); - - } - - /** - * Computes the value barycentrically interpolated for the given point on the - * triangle. Returns `null` if the triangle is degenerate. - * - * @param {Vector3} point - Position of interpolated point. - * @param {Vector3} v1 - Value to interpolate of first vertex. - * @param {Vector3} v2 - Value to interpolate of second vertex. - * @param {Vector3} v3 - Value to interpolate of third vertex. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The interpolated value. - */ - getInterpolation( point, v1, v2, v3, target ) { - - return Triangle.getInterpolation( point, this.a, this.b, this.c, v1, v2, v3, target ); - - } - - /** - * Returns `true` if the given point, when projected onto the plane of the - * triangle, lies within the triangle. - * - * @param {Vector3} point - The point in 3D space to test. - * @return {boolean} Whether the given point, when projected onto the plane of the - * triangle, lies within the triangle or not. - */ - containsPoint( point ) { - - return Triangle.containsPoint( point, this.a, this.b, this.c ); - - } - - /** - * Returns `true` if the triangle is oriented towards the given direction. - * - * @param {Vector3} direction - The (normalized) direction vector. - * @return {boolean} Whether the triangle is oriented towards the given direction or not. - */ - isFrontFacing( direction ) { - - return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); - - } - - /** - * Returns `true` if this triangle intersects with the given box. - * - * @param {Box3} box - The box to intersect. - * @return {boolean} Whether this triangle intersects with the given box or not. - */ - intersectsBox( box ) { - - return box.intersectsTriangle( this ); - - } - - /** - * Returns the closest point on the triangle to the given point. - * - * @param {Vector3} p - The point to compute the closest point for. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The closest point on the triangle. - */ - closestPointToPoint( p, target ) { - - const a = this.a, b = this.b, c = this.c; - let v, w; - - // algorithm thanks to Real-Time Collision Detection by Christer Ericson, - // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., - // under the accompanying license; see chapter 5.1.5 for detailed explanation. - // basically, we're distinguishing which of the voronoi regions of the triangle - // the point lies in with the minimum amount of redundant computation. - - _vab.subVectors( b, a ); - _vac.subVectors( c, a ); - _vap.subVectors( p, a ); - const d1 = _vab.dot( _vap ); - const d2 = _vac.dot( _vap ); - if ( d1 <= 0 && d2 <= 0 ) { - - // vertex region of A; barycentric coords (1, 0, 0) - return target.copy( a ); - - } - - _vbp.subVectors( p, b ); - const d3 = _vab.dot( _vbp ); - const d4 = _vac.dot( _vbp ); - if ( d3 >= 0 && d4 <= d3 ) { - - // vertex region of B; barycentric coords (0, 1, 0) - return target.copy( b ); - - } - - const vc = d1 * d4 - d3 * d2; - if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { - - v = d1 / ( d1 - d3 ); - // edge region of AB; barycentric coords (1-v, v, 0) - return target.copy( a ).addScaledVector( _vab, v ); - - } - - _vcp.subVectors( p, c ); - const d5 = _vab.dot( _vcp ); - const d6 = _vac.dot( _vcp ); - if ( d6 >= 0 && d5 <= d6 ) { - - // vertex region of C; barycentric coords (0, 0, 1) - return target.copy( c ); - - } - - const vb = d5 * d2 - d1 * d6; - if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { - - w = d2 / ( d2 - d6 ); - // edge region of AC; barycentric coords (1-w, 0, w) - return target.copy( a ).addScaledVector( _vac, w ); - - } - - const va = d3 * d6 - d5 * d4; - if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { - - _vbc.subVectors( c, b ); - w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); - // edge region of BC; barycentric coords (0, 1-w, w) - return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC - - } - - // face region - const denom = 1 / ( va + vb + vc ); - // u = va * denom - v = vb * denom; - w = vc * denom; - - return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w ); - - } - - /** - * Returns `true` if this triangle is equal with the given one. - * - * @param {Triangle} triangle - The triangle to test for equality. - * @return {boolean} Whether this triangle is equal with the given one. - */ - equals( triangle ) { - - return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); - - } - -} - -const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, - 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, - 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, - 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, - 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, - 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, - 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, - 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, - 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, - 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, - 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, - 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, - 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, - 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, - 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, - 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, - 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, - 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, - 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, - 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, - 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, - 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, - 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, - 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; - -const _hslA = { h: 0, s: 0, l: 0 }; -const _hslB = { h: 0, s: 0, l: 0 }; - -function hue2rgb( p, q, t ) { - - if ( t < 0 ) t += 1; - if ( t > 1 ) t -= 1; - if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; - if ( t < 1 / 2 ) return q; - if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); - return p; - -} - -/** - * A Color instance is represented by RGB components in the linear working - * color space, which defaults to `LinearSRGBColorSpace`. Inputs - * conventionally using `SRGBColorSpace` (such as hexadecimals and CSS - * strings) are converted to the working color space automatically. - * - * ```js - * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace - * const color = new THREE.Color().setHex( 0x112233 ); - * ``` - * Source color spaces may be specified explicitly, to ensure correct conversions. - * ```js - * // assumed already LinearSRGBColorSpace; no conversion - * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 ); - * - * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace - * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace ); - * ``` - * If THREE.ColorManagement is disabled, no conversions occur. For details, - * see Color management. Iterating through a Color instance will yield - * its components (r, g, b) in the corresponding order. A Color can be initialised - * in any of the following ways: - * ```js - * //empty constructor - will default white - * const color1 = new THREE.Color(); - * - * //Hexadecimal color (recommended) - * const color2 = new THREE.Color( 0xff0000 ); - * - * //RGB string - * const color3 = new THREE.Color("rgb(255, 0, 0)"); - * const color4 = new THREE.Color("rgb(100%, 0%, 0%)"); - * - * //X11 color name - all 140 color names are supported. - * //Note the lack of CamelCase in the name - * const color5 = new THREE.Color( 'skyblue' ); - * //HSL string - * const color6 = new THREE.Color("hsl(0, 100%, 50%)"); - * - * //Separate RGB values between 0 and 1 - * const color7 = new THREE.Color( 1, 0, 0 ); - * ``` - */ -class Color { - - /** - * Constructs a new color. - * - * Note that standard method of specifying color in three.js is with a hexadecimal triplet, - * and that method is used throughout the rest of the documentation. - * - * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are - * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. - * @param {number} [g] - The green component. - * @param {number} [b] - The blue component. - */ - constructor( r, g, b ) { - - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isColor = true; - - /** - * The red component. - * - * @type {number} - * @default 1 - */ - this.r = 1; - - /** - * The green component. - * - * @type {number} - * @default 1 - */ - this.g = 1; - - /** - * The blue component. - * - * @type {number} - * @default 1 - */ - this.b = 1; - - return this.set( r, g, b ); - - } - - /** - * Sets the colors's components from the given values. - * - * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are - * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. - * @param {number} [g] - The green component. - * @param {number} [b] - The blue component. - * @return {Color} A reference to this color. - */ - set( r, g, b ) { - - if ( g === undefined && b === undefined ) { - - // r is THREE.Color, hex or string - - const value = r; - - if ( value && value.isColor ) { - - this.copy( value ); - - } else if ( typeof value === 'number' ) { - - this.setHex( value ); - - } else if ( typeof value === 'string' ) { - - this.setStyle( value ); - - } - - } else { - - this.setRGB( r, g, b ); - - } - - return this; - - } - - /** - * Sets the colors's components to the given scalar value. - * - * @param {number} scalar - The scalar value. - * @return {Color} A reference to this color. - */ - setScalar( scalar ) { - - this.r = scalar; - this.g = scalar; - this.b = scalar; - - return this; - - } - - /** - * Sets this color from a hexadecimal value. - * - * @param {number} hex - The hexadecimal value. - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {Color} A reference to this color. - */ - setHex( hex, colorSpace = SRGBColorSpace ) { - - hex = Math.floor( hex ); - - this.r = ( hex >> 16 & 255 ) / 255; - this.g = ( hex >> 8 & 255 ) / 255; - this.b = ( hex & 255 ) / 255; - - ColorManagement.colorSpaceToWorking( this, colorSpace ); - - return this; - - } - - /** - * Sets this color from RGB values. - * - * @param {number} r - Red channel value between `0.0` and `1.0`. - * @param {number} g - Green channel value between `0.0` and `1.0`. - * @param {number} b - Blue channel value between `0.0` and `1.0`. - * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. - * @return {Color} A reference to this color. - */ - setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) { - - this.r = r; - this.g = g; - this.b = b; - - ColorManagement.colorSpaceToWorking( this, colorSpace ); - - return this; - - } - - /** - * Sets this color from RGB values. - * - * @param {number} h - Hue value between `0.0` and `1.0`. - * @param {number} s - Saturation value between `0.0` and `1.0`. - * @param {number} l - Lightness value between `0.0` and `1.0`. - * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. - * @return {Color} A reference to this color. - */ - setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) { - - // h,s,l ranges are in 0.0 - 1.0 - h = euclideanModulo( h, 1 ); - s = clamp( s, 0, 1 ); - l = clamp( l, 0, 1 ); - - if ( s === 0 ) { - - this.r = this.g = this.b = l; - - } else { - - const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); - const q = ( 2 * l ) - p; - - this.r = hue2rgb( q, p, h + 1 / 3 ); - this.g = hue2rgb( q, p, h ); - this.b = hue2rgb( q, p, h - 1 / 3 ); - - } - - ColorManagement.colorSpaceToWorking( this, colorSpace ); - - return this; - - } - - /** - * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`, - * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or - * any [X11 color name](https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart) - - * all 140 color names are supported). - * - * @param {string} style - Color as a CSS-style string. - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {Color} A reference to this color. - */ - setStyle( style, colorSpace = SRGBColorSpace ) { - - function handleAlpha( string ) { - - if ( string === undefined ) return; - - if ( parseFloat( string ) < 1 ) { - - warn( 'Color: Alpha component of ' + style + ' will be ignored.' ); - - } - - } - - - let m; - - if ( m = /^(\w+)\(([^\)]*)\)/.exec( style ) ) { - - // rgb / hsl - - let color; - const name = m[ 1 ]; - const components = m[ 2 ]; - - switch ( name ) { - - case 'rgb': - case 'rgba': - - if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - - // rgb(255,0,0) rgba(255,0,0,0.5) - - handleAlpha( color[ 4 ] ); - - return this.setRGB( - Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255, - Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255, - Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255, - colorSpace - ); - - } - - if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - - // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) - - handleAlpha( color[ 4 ] ); - - return this.setRGB( - Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100, - Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100, - Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100, - colorSpace - ); - - } - - break; - - case 'hsl': - case 'hsla': - - if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - - // hsl(120,50%,50%) hsla(120,50%,50%,0.5) - - handleAlpha( color[ 4 ] ); - - return this.setHSL( - parseFloat( color[ 1 ] ) / 360, - parseFloat( color[ 2 ] ) / 100, - parseFloat( color[ 3 ] ) / 100, - colorSpace - ); - - } - - break; - - default: - - warn( 'Color: Unknown color model ' + style ); - - } - - } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) { - - // hex color - - const hex = m[ 1 ]; - const size = hex.length; - - if ( size === 3 ) { - - // #ff0 - return this.setRGB( - parseInt( hex.charAt( 0 ), 16 ) / 15, - parseInt( hex.charAt( 1 ), 16 ) / 15, - parseInt( hex.charAt( 2 ), 16 ) / 15, - colorSpace - ); - - } else if ( size === 6 ) { - - // #ff0000 - return this.setHex( parseInt( hex, 16 ), colorSpace ); - - } else { - - warn( 'Color: Invalid hex color ' + style ); - - } - - } else if ( style && style.length > 0 ) { - - return this.setColorName( style, colorSpace ); - - } - - return this; - - } - - /** - * Sets this color from a color name. Faster than {@link Color#setStyle} if - * you don't need the other CSS-style formats. - * - * For convenience, the list of names is exposed in `Color.NAMES` as a hash. - * ```js - * Color.NAMES.aliceblue // returns 0xF0F8FF - * ``` - * - * @param {string} style - The color name. - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {Color} A reference to this color. - */ - setColorName( style, colorSpace = SRGBColorSpace ) { - - // color keywords - const hex = _colorKeywords[ style.toLowerCase() ]; - - if ( hex !== undefined ) { - - // red - this.setHex( hex, colorSpace ); - - } else { - - // unknown color - warn( 'Color: Unknown color ' + style ); - - } - - return this; - - } - - /** - * Returns a new color with copied values from this instance. - * - * @return {Color} A clone of this instance. - */ - clone() { - - return new this.constructor( this.r, this.g, this.b ); - - } - - /** - * Copies the values of the given color to this instance. - * - * @param {Color} color - The color to copy. - * @return {Color} A reference to this color. - */ - copy( color ) { - - this.r = color.r; - this.g = color.g; - this.b = color.b; - - return this; - - } - - /** - * Copies the given color into this color, and then converts this color from - * `SRGBColorSpace` to `LinearSRGBColorSpace`. - * - * @param {Color} color - The color to copy/convert. - * @return {Color} A reference to this color. - */ - copySRGBToLinear( color ) { - - this.r = SRGBToLinear( color.r ); - this.g = SRGBToLinear( color.g ); - this.b = SRGBToLinear( color.b ); - - return this; - - } - - /** - * Copies the given color into this color, and then converts this color from - * `LinearSRGBColorSpace` to `SRGBColorSpace`. - * - * @param {Color} color - The color to copy/convert. - * @return {Color} A reference to this color. - */ - copyLinearToSRGB( color ) { - - this.r = LinearToSRGB( color.r ); - this.g = LinearToSRGB( color.g ); - this.b = LinearToSRGB( color.b ); - - return this; - - } - - /** - * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. - * - * @return {Color} A reference to this color. - */ - convertSRGBToLinear() { - - this.copySRGBToLinear( this ); - - return this; - - } - - /** - * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. - * - * @return {Color} A reference to this color. - */ - convertLinearToSRGB() { - - this.copyLinearToSRGB( this ); - - return this; - - } - - /** - * Returns the hexadecimal value of this color. - * - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {number} The hexadecimal value. - */ - getHex( colorSpace = SRGBColorSpace ) { - - ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - - return Math.round( clamp( _color.r * 255, 0, 255 ) ) * 65536 + Math.round( clamp( _color.g * 255, 0, 255 ) ) * 256 + Math.round( clamp( _color.b * 255, 0, 255 ) ); - - } - - /** - * Returns the hexadecimal value of this color as a string (for example, 'FFFFFF'). - * - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {string} The hexadecimal value as a string. - */ - getHexString( colorSpace = SRGBColorSpace ) { - - return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( -6 ); - - } - - /** - * Converts the colors RGB values into the HSL format and stores them into the - * given target object. - * - * @param {{h:number,s:number,l:number}} target - The target object that is used to store the method's result. - * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. - * @return {{h:number,s:number,l:number}} The HSL representation of this color. - */ - getHSL( target, colorSpace = ColorManagement.workingColorSpace ) { - - // h,s,l ranges are in 0.0 - 1.0 - - ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - - const r = _color.r, g = _color.g, b = _color.b; - - const max = Math.max( r, g, b ); - const min = Math.min( r, g, b ); - - let hue, saturation; - const lightness = ( min + max ) / 2.0; - - if ( min === max ) { - - hue = 0; - saturation = 0; - - } else { - - const delta = max - min; - - saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); - - switch ( max ) { - - case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; - case g: hue = ( b - r ) / delta + 2; break; - case b: hue = ( r - g ) / delta + 4; break; - - } - - hue /= 6; - - } - - target.h = hue; - target.s = saturation; - target.l = lightness; - - return target; - - } - - /** - * Returns the RGB values of this color and stores them into the given target object. - * - * @param {Color} target - The target color that is used to store the method's result. - * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. - * @return {Color} The RGB representation of this color. - */ - getRGB( target, colorSpace = ColorManagement.workingColorSpace ) { - - ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - - target.r = _color.r; - target.g = _color.g; - target.b = _color.b; - - return target; - - } - - /** - * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`. - * - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {string} The CSS representation of this color. - */ - getStyle( colorSpace = SRGBColorSpace ) { - - ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - - const r = _color.r, g = _color.g, b = _color.b; - - if ( colorSpace !== SRGBColorSpace ) { - - // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/). - return `color(${ colorSpace } ${ r.toFixed( 3 ) } ${ g.toFixed( 3 ) } ${ b.toFixed( 3 ) })`; + this.r = hue2rgb( q, p, h + 1 / 3 ); + this.g = hue2rgb( q, p, h ); + this.b = hue2rgb( q, p, h - 1 / 3 ); } - return `rgb(${ Math.round( r * 255 ) },${ Math.round( g * 255 ) },${ Math.round( b * 255 ) })`; - - } - - /** - * Adds the given HSL values to this color's values. - * Internally, this converts the color's RGB values to HSL, adds HSL - * and then converts the color back to RGB. - * - * @param {number} h - Hue value between `0.0` and `1.0`. - * @param {number} s - Saturation value between `0.0` and `1.0`. - * @param {number} l - Lightness value between `0.0` and `1.0`. - * @return {Color} A reference to this color. - */ - offsetHSL( h, s, l ) { - - this.getHSL( _hslA ); - - return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l ); - - } - - /** - * Adds the RGB values of the given color to the RGB values of this color. - * - * @param {Color} color - The color to add. - * @return {Color} A reference to this color. - */ - add( color ) { - - this.r += color.r; - this.g += color.g; - this.b += color.b; - - return this; - - } - - /** - * Adds the RGB values of the given colors and stores the result in this instance. - * - * @param {Color} color1 - The first color. - * @param {Color} color2 - The second color. - * @return {Color} A reference to this color. - */ - addColors( color1, color2 ) { - - this.r = color1.r + color2.r; - this.g = color1.g + color2.g; - this.b = color1.b + color2.b; - - return this; - - } - - /** - * Adds the given scalar value to the RGB values of this color. - * - * @param {number} s - The scalar to add. - * @return {Color} A reference to this color. - */ - addScalar( s ) { - - this.r += s; - this.g += s; - this.b += s; - - return this; - - } - - /** - * Subtracts the RGB values of the given color from the RGB values of this color. - * - * @param {Color} color - The color to subtract. - * @return {Color} A reference to this color. - */ - sub( color ) { - - this.r = Math.max( 0, this.r - color.r ); - this.g = Math.max( 0, this.g - color.g ); - this.b = Math.max( 0, this.b - color.b ); - - return this; - - } - - /** - * Multiplies the RGB values of the given color with the RGB values of this color. - * - * @param {Color} color - The color to multiply. - * @return {Color} A reference to this color. - */ - multiply( color ) { - - this.r *= color.r; - this.g *= color.g; - this.b *= color.b; - - return this; - - } - - /** - * Multiplies the given scalar value with the RGB values of this color. - * - * @param {number} s - The scalar to multiply. - * @return {Color} A reference to this color. - */ - multiplyScalar( s ) { - - this.r *= s; - this.g *= s; - this.b *= s; - - return this; - - } - - /** - * Linearly interpolates this color's RGB values toward the RGB values of the - * given color. The alpha argument can be thought of as the ratio between - * the two colors, where `0.0` is this color and `1.0` is the first argument. - * - * @param {Color} color - The color to converge on. - * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. - * @return {Color} A reference to this color. - */ - lerp( color, alpha ) { - - this.r += ( color.r - this.r ) * alpha; - this.g += ( color.g - this.g ) * alpha; - this.b += ( color.b - this.b ) * alpha; - - return this; - - } - - /** - * Linearly interpolates between the given colors and stores the result in this instance. - * The alpha argument can be thought of as the ratio between the two colors, where `0.0` - * is the first and `1.0` is the second color. - * - * @param {Color} color1 - The first color. - * @param {Color} color2 - The second color. - * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. - * @return {Color} A reference to this color. - */ - lerpColors( color1, color2, alpha ) { - - this.r = color1.r + ( color2.r - color1.r ) * alpha; - this.g = color1.g + ( color2.g - color1.g ) * alpha; - this.b = color1.b + ( color2.b - color1.b ) * alpha; - - return this; - - } - - /** - * Linearly interpolates this color's HSL values toward the HSL values of the - * given color. It differs from {@link Color#lerp} by not interpolating straight - * from one color to the other, but instead going through all the hues in between - * those two colors. The alpha argument can be thought of as the ratio between - * the two colors, where 0.0 is this color and 1.0 is the first argument. - * - * @param {Color} color - The color to converge on. - * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. - * @return {Color} A reference to this color. - */ - lerpHSL( color, alpha ) { - - this.getHSL( _hslA ); - color.getHSL( _hslB ); - - const h = lerp( _hslA.h, _hslB.h, alpha ); - const s = lerp( _hslA.s, _hslB.s, alpha ); - const l = lerp( _hslA.l, _hslB.l, alpha ); - - this.setHSL( h, s, l ); - - return this; - - } - - /** - * Sets the color's RGB components from the given 3D vector. - * - * @param {Vector3} v - The vector to set. - * @return {Color} A reference to this color. - */ - setFromVector3( v ) { - - this.r = v.x; - this.g = v.y; - this.b = v.z; - - return this; - - } - - /** - * Transforms this color with the given 3x3 matrix. - * - * @param {Matrix3} m - The matrix. - * @return {Color} A reference to this color. - */ - applyMatrix3( m ) { - - const r = this.r, g = this.g, b = this.b; - const e = m.elements; - - this.r = e[ 0 ] * r + e[ 3 ] * g + e[ 6 ] * b; - this.g = e[ 1 ] * r + e[ 4 ] * g + e[ 7 ] * b; - this.b = e[ 2 ] * r + e[ 5 ] * g + e[ 8 ] * b; - - return this; - - } - - /** - * Returns `true` if this color is equal with the given one. - * - * @param {Color} c - The color to test for equality. - * @return {boolean} Whether this bounding color is equal with the given one. - */ - equals( c ) { - - return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); - - } - - /** - * Sets this color's RGB components from the given array. - * - * @param {Array} array - An array holding the RGB values. - * @param {number} [offset=0] - The offset into the array. - * @return {Color} A reference to this color. - */ - fromArray( array, offset = 0 ) { - - this.r = array[ offset ]; - this.g = array[ offset + 1 ]; - this.b = array[ offset + 2 ]; + ColorManagement.colorSpaceToWorking( this, colorSpace ); return this; } /** - * Writes the RGB components of this color to the given array. If no array is provided, - * the method returns a new instance. - * - * @param {Array} [array=[]] - The target array holding the color components. - * @param {number} [offset=0] - Index of the first element in the array. - * @return {Array} The color components. - */ - toArray( array = [], offset = 0 ) { - - array[ offset ] = this.r; - array[ offset + 1 ] = this.g; - array[ offset + 2 ] = this.b; - - return array; - - } - - /** - * Sets the components of this color from the given buffer attribute. + * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`, + * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or + * any [X11 color name](https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart) - + * all 140 color names are supported). * - * @param {BufferAttribute} attribute - The buffer attribute holding color data. - * @param {number} index - The index into the attribute. + * @param {string} style - Color as a CSS-style string. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. * @return {Color} A reference to this color. */ - fromBufferAttribute( attribute, index ) { - - this.r = attribute.getX( index ); - this.g = attribute.getY( index ); - this.b = attribute.getZ( index ); - - return this; - - } - - /** - * This methods defines the serialization result of this class. Returns the color - * as a hexadecimal value. - * - * @return {number} The hexadecimal value. - */ - toJSON() { - - return this.getHex(); - - } - - *[ Symbol.iterator ]() { - - yield this.r; - yield this.g; - yield this.b; - - } - -} - -const _color = /*@__PURE__*/ new Color(); - -/** - * A dictionary with X11 color names. - * - * Note that multiple words such as Dark Orange become the string 'darkorange'. - * - * @static - * @type {Object} - */ -Color.NAMES = _colorKeywords; - -let _materialId = 0; - -/** - * Abstract base class for materials. - * - * Materials define the appearance of renderable 3D objects. - * - * @abstract - * @augments EventDispatcher - */ -class Material extends EventDispatcher { - - /** - * Constructs a new material. - */ - constructor() { - - super(); - - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isMaterial = true; - - /** - * The ID of the material. - * - * @name Material#id - * @type {number} - * @readonly - */ - Object.defineProperty( this, 'id', { value: _materialId ++ } ); - - /** - * The UUID of the material. - * - * @type {string} - * @readonly - */ - this.uuid = generateUUID(); - - /** - * The name of the material. - * - * @type {string} - */ - this.name = ''; - - /** - * The type property is used for detecting the object type - * in context of serialization/deserialization. - * - * @type {string} - * @readonly - */ - this.type = 'Material'; - - /** - * Defines the blending type of the material. - * - * It must be set to `CustomBlending` if custom blending properties like - * {@link Material#blendSrc}, {@link Material#blendDst} or {@link Material#blendEquation} - * should have any effect. - * - * @type {(NoBlending|NormalBlending|AdditiveBlending|SubtractiveBlending|MultiplyBlending|CustomBlending)} - * @default NormalBlending - */ - this.blending = NormalBlending; - - /** - * Defines which side of faces will be rendered - front, back or both. - * - * @type {(FrontSide|BackSide|DoubleSide)} - * @default FrontSide - */ - this.side = FrontSide; - - /** - * If set to `true`, vertex colors should be used. - * - * The engine supports RGB and RGBA vertex colors depending on whether a three (RGB) or - * four (RGBA) component color buffer attribute is used. - * - * @type {boolean} - * @default false - */ - this.vertexColors = false; - - /** - * Defines how transparent the material is. - * A value of `0.0` indicates fully transparent, `1.0` is fully opaque. - * - * If the {@link Material#transparent} is not set to `true`, - * the material will remain fully opaque and this value will only affect its color. - * - * @type {number} - * @default 1 - */ - this.opacity = 1; - - /** - * Defines whether this material is transparent. This has an effect on - * rendering as transparent objects need special treatment and are rendered - * after non-transparent objects. - * - * When set to true, the extent to which the material is transparent is - * controlled by {@link Material#opacity}. - * - * @type {boolean} - * @default false - */ - this.transparent = false; + setStyle( style, colorSpace = SRGBColorSpace ) { - /** - * Enables alpha hashed transparency, an alternative to {@link Material#transparent} or - * {@link Material#alphaTest}. The material will not be rendered if opacity is lower than - * a random threshold. Randomization introduces some grain or noise, but approximates alpha - * blending without the associated problems of sorting. Using TAA can reduce the resulting noise. - * - * @type {boolean} - * @default false - */ - this.alphaHash = false; + function handleAlpha( string ) { - /** - * Defines the blending source factor. - * - * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} - * @default SrcAlphaFactor - */ - this.blendSrc = SrcAlphaFactor; + if ( string === undefined ) return; - /** - * Defines the blending destination factor. - * - * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} - * @default OneMinusSrcAlphaFactor - */ - this.blendDst = OneMinusSrcAlphaFactor; + if ( parseFloat( string ) < 1 ) { - /** - * Defines the blending equation. - * - * @type {(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)} - * @default AddEquation - */ - this.blendEquation = AddEquation; + warn( 'Color: Alpha component of ' + style + ' will be ignored.' ); - /** - * Defines the blending source alpha factor. - * - * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} - * @default null - */ - this.blendSrcAlpha = null; + } - /** - * Defines the blending destination alpha factor. - * - * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} - * @default null - */ - this.blendDstAlpha = null; + } - /** - * Defines the blending equation of the alpha channel. - * - * @type {?(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)} - * @default null - */ - this.blendEquationAlpha = null; - /** - * Represents the RGB values of the constant blend color. - * - * This property has only an effect when using custom blending with `ConstantColor` or `OneMinusConstantColor`. - * - * @type {Color} - * @default (0,0,0) - */ - this.blendColor = new Color( 0, 0, 0 ); + let m; - /** - * Represents the alpha value of the constant blend color. - * - * This property has only an effect when using custom blending with `ConstantAlpha` or `OneMinusConstantAlpha`. - * - * @type {number} - * @default 0 - */ - this.blendAlpha = 0; + if ( m = /^(\w+)\(([^\)]*)\)/.exec( style ) ) { - /** - * Defines the depth function. - * - * @type {(NeverDepth|AlwaysDepth|LessDepth|LessEqualDepth|EqualDepth|GreaterEqualDepth|GreaterDepth|NotEqualDepth)} - * @default LessEqualDepth - */ - this.depthFunc = LessEqualDepth; + // rgb / hsl - /** - * Whether to have depth test enabled when rendering this material. - * When the depth test is disabled, the depth write will also be implicitly disabled. - * - * @type {boolean} - * @default true - */ - this.depthTest = true; + let color; + const name = m[ 1 ]; + const components = m[ 2 ]; - /** - * Whether rendering this material has any effect on the depth buffer. - * - * When drawing 2D overlays it can be useful to disable the depth writing in - * order to layer several things together without creating z-index artifacts. - * - * @type {boolean} - * @default true - */ - this.depthWrite = true; + switch ( name ) { - /** - * The bit mask to use when writing to the stencil buffer. - * - * @type {number} - * @default 0xff - */ - this.stencilWriteMask = 0xff; + case 'rgb': + case 'rgba': - /** - * The stencil comparison function to use. - * - * @type {NeverStencilFunc|LessStencilFunc|EqualStencilFunc|LessEqualStencilFunc|GreaterStencilFunc|NotEqualStencilFunc|GreaterEqualStencilFunc|AlwaysStencilFunc} - * @default AlwaysStencilFunc - */ - this.stencilFunc = AlwaysStencilFunc; + if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - /** - * The value to use when performing stencil comparisons or stencil operations. - * - * @type {number} - * @default 0 - */ - this.stencilRef = 0; + // rgb(255,0,0) rgba(255,0,0,0.5) - /** - * The bit mask to use when comparing against the stencil buffer. - * - * @type {number} - * @default 0xff - */ - this.stencilFuncMask = 0xff; + handleAlpha( color[ 4 ] ); - /** - * Which stencil operation to perform when the comparison function returns `false`. - * - * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} - * @default KeepStencilOp - */ - this.stencilFail = KeepStencilOp; + return this.setRGB( + Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255, + Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255, + Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255, + colorSpace + ); - /** - * Which stencil operation to perform when the comparison function returns - * `true` but the depth test fails. - * - * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} - * @default KeepStencilOp - */ - this.stencilZFail = KeepStencilOp; + } - /** - * Which stencil operation to perform when the comparison function returns - * `true` and the depth test passes. - * - * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} - * @default KeepStencilOp - */ - this.stencilZPass = KeepStencilOp; + if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - /** - * Whether stencil operations are performed against the stencil buffer. In - * order to perform writes or comparisons against the stencil buffer this - * value must be `true`. - * - * @type {boolean} - * @default false - */ - this.stencilWrite = false; + // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) - /** - * User-defined clipping planes specified as THREE.Plane objects in world - * space. These planes apply to the objects this material is attached to. - * Points in space whose signed distance to the plane is negative are clipped - * (not rendered). This requires {@link WebGLRenderer#localClippingEnabled} to - * be `true`. - * - * @type {?Array} - * @default null - */ - this.clippingPlanes = null; + handleAlpha( color[ 4 ] ); - /** - * Changes the behavior of clipping planes so that only their intersection is - * clipped, rather than their union. - * - * @type {boolean} - * @default false - */ - this.clipIntersection = false; + return this.setRGB( + Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100, + Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100, + Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100, + colorSpace + ); - /** - * Defines whether to clip shadows according to the clipping planes specified - * on this material. - * - * @type {boolean} - * @default false - */ - this.clipShadows = false; + } - /** - * Defines which side of faces cast shadows. If `null`, the side casting shadows - * is determined as follows: - * - * - When {@link Material#side} is set to `FrontSide`, the back side cast shadows. - * - When {@link Material#side} is set to `BackSide`, the front side cast shadows. - * - When {@link Material#side} is set to `DoubleSide`, both sides cast shadows. - * - * @type {?(FrontSide|BackSide|DoubleSide)} - * @default null - */ - this.shadowSide = null; + break; - /** - * Whether to render the material's color. - * - * This can be used in conjunction with {@link Object3D#renderOder} to create invisible - * objects that occlude other objects. - * - * @type {boolean} - * @default true - */ - this.colorWrite = true; + case 'hsl': + case 'hsla': - /** - * Override the renderer's default precision for this material. - * - * @type {?('highp'|'mediump'|'lowp')} - * @default null - */ - this.precision = null; + if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - /** - * Whether to use polygon offset or not. When enabled, each fragment's depth value will - * be offset after it is interpolated from the depth values of the appropriate vertices. - * The offset is added before the depth test is performed and before the value is written - * into the depth buffer. - * - * Can be useful for rendering hidden-line images, for applying decals to surfaces, and for - * rendering solids with highlighted edges. - * - * @type {boolean} - * @default false - */ - this.polygonOffset = false; + // hsl(120,50%,50%) hsla(120,50%,50%,0.5) - /** - * Specifies a scale factor that is used to create a variable depth offset for each polygon. - * - * @type {number} - * @default 0 - */ - this.polygonOffsetFactor = 0; + handleAlpha( color[ 4 ] ); - /** - * Is multiplied by an implementation-specific value to create a constant depth offset. - * - * @type {number} - * @default 0 - */ - this.polygonOffsetUnits = 0; + return this.setHSL( + parseFloat( color[ 1 ] ) / 360, + parseFloat( color[ 2 ] ) / 100, + parseFloat( color[ 3 ] ) / 100, + colorSpace + ); - /** - * Whether to apply dithering to the color to remove the appearance of banding. - * - * @type {boolean} - * @default false - */ - this.dithering = false; + } - /** - * Whether alpha to coverage should be enabled or not. Can only be used with MSAA-enabled contexts - * (meaning when the renderer was created with *antialias* parameter set to `true`). Enabling this - * will smooth aliasing on clip plane edges and alphaTest-clipped edges. - * - * @type {boolean} - * @default false - */ - this.alphaToCoverage = false; + break; - /** - * Whether to premultiply the alpha (transparency) value. - * - * @type {boolean} - * @default false - */ - this.premultipliedAlpha = false; + default: - /** - * Whether double-sided, transparent objects should be rendered with a single pass or not. - * - * The engine renders double-sided, transparent objects with two draw calls (back faces first, - * then front faces) to mitigate transparency artifacts. There are scenarios however where this - * approach produces no quality gains but still doubles draw calls e.g. when rendering flat - * vegetation like grass sprites. In these cases, set the `forceSinglePass` flag to `true` to - * disable the two pass rendering to avoid performance issues. - * - * @type {boolean} - * @default false - */ - this.forceSinglePass = false; + warn( 'Color: Unknown color model ' + style ); - /** - * Whether it's possible to override the material with {@link Scene#overrideMaterial} or not. - * - * @type {boolean} - * @default true - */ - this.allowOverride = true; + } - /** - * Defines whether 3D objects using this material are visible. - * - * @type {boolean} - * @default true - */ - this.visible = true; + } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) { - /** - * Defines whether this material is tone mapped according to the renderer's tone mapping setting. - * - * It is ignored when rendering to a render target or using post processing or when using - * `WebGPURenderer`. In all these cases, all materials are honored by tone mapping. - * - * @type {boolean} - * @default true - */ - this.toneMapped = true; + // hex color - /** - * An object that can be used to store custom data about the Material. It - * should not hold references to functions as these will not be cloned. - * - * @type {Object} - */ - this.userData = {}; + const hex = m[ 1 ]; + const size = hex.length; - /** - * This starts at `0` and counts how many times {@link Material#needsUpdate} is set to `true`. - * - * @type {number} - * @readonly - * @default 0 - */ - this.version = 0; + if ( size === 3 ) { - this._alphaTest = 0; + // #ff0 + return this.setRGB( + parseInt( hex.charAt( 0 ), 16 ) / 15, + parseInt( hex.charAt( 1 ), 16 ) / 15, + parseInt( hex.charAt( 2 ), 16 ) / 15, + colorSpace + ); - } + } else if ( size === 6 ) { - /** - * Sets the alpha value to be used when running an alpha test. The material - * will not be rendered if the opacity is lower than this value. - * - * @type {number} - * @readonly - * @default 0 - */ - get alphaTest() { + // #ff0000 + return this.setHex( parseInt( hex, 16 ), colorSpace ); - return this._alphaTest; + } else { - } + warn( 'Color: Invalid hex color ' + style ); - set alphaTest( value ) { + } - if ( this._alphaTest > 0 !== value > 0 ) { + } else if ( style && style.length > 0 ) { - this.version ++; + return this.setColorName( style, colorSpace ); } - this._alphaTest = value; + return this; } /** - * An optional callback that is executed immediately before the material is used to render a 3D object. + * Sets this color from a color name. Faster than {@link Color#setStyle} if + * you don't need the other CSS-style formats. * - * This method can only be used when rendering with {@link WebGLRenderer}. + * For convenience, the list of names is exposed in `Color.NAMES` as a hash. + * ```js + * Color.NAMES.aliceblue // returns 0xF0F8FF + * ``` * - * @param {WebGLRenderer} renderer - The renderer. - * @param {Scene} scene - The scene. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Object3D} object - The 3D object. - * @param {Object} group - The geometry group data. + * @param {string} style - The color name. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {Color} A reference to this color. */ - onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {} + setColorName( style, colorSpace = SRGBColorSpace ) { - /** - * An optional callback that is executed immediately before the shader - * program is compiled. This function is called with the shader source code - * as a parameter. Useful for the modification of built-in materials. - * - * This method can only be used when rendering with {@link WebGLRenderer}. The - * recommended approach when customizing materials is to use `WebGPURenderer` with the new - * Node Material system and [TSL](https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language). - * - * @param {{vertexShader:string,fragmentShader:string,uniforms:Object}} shaderobject - The object holds the uniforms and the vertex and fragment shader source. - * @param {WebGLRenderer} renderer - A reference to the renderer. - */ - onBeforeCompile( /* shaderobject, renderer */ ) {} + // color keywords + const hex = _colorKeywords[ style.toLowerCase() ]; - /** - * In case {@link Material#onBeforeCompile} is used, this callback can be used to identify - * values of settings used in `onBeforeCompile()`, so three.js can reuse a cached - * shader or recompile the shader for this material as needed. - * - * This method can only be used when rendering with {@link WebGLRenderer}. - * - * @return {string} The custom program cache key. - */ - customProgramCacheKey() { + if ( hex !== undefined ) { - return this.onBeforeCompile.toString(); + // red + this.setHex( hex, colorSpace ); + + } else { + + // unknown color + warn( 'Color: Unknown color ' + style ); + + } + + return this; } /** - * This method can be used to set default values from parameter objects. - * It is a generic implementation so it can be used with different types - * of materials. + * Returns a new color with copied values from this instance. * - * @param {Object} [values] - The material values to set. + * @return {Color} A clone of this instance. */ - setValues( values ) { - - if ( values === undefined ) return; + clone() { - for ( const key in values ) { + return new this.constructor( this.r, this.g, this.b ); - const newValue = values[ key ]; + } - if ( newValue === undefined ) { + /** + * Copies the values of the given color to this instance. + * + * @param {Color} color - The color to copy. + * @return {Color} A reference to this color. + */ + copy( color ) { - warn( `Material: parameter '${ key }' has value of undefined.` ); - continue; + this.r = color.r; + this.g = color.g; + this.b = color.b; - } + return this; - const currentValue = this[ key ]; + } - if ( currentValue === undefined ) { + /** + * Copies the given color into this color, and then converts this color from + * `SRGBColorSpace` to `LinearSRGBColorSpace`. + * + * @param {Color} color - The color to copy/convert. + * @return {Color} A reference to this color. + */ + copySRGBToLinear( color ) { - warn( `Material: '${ key }' is not a property of THREE.${ this.type }.` ); - continue; + this.r = SRGBToLinear( color.r ); + this.g = SRGBToLinear( color.g ); + this.b = SRGBToLinear( color.b ); - } + return this; - if ( currentValue && currentValue.isColor ) { + } - currentValue.set( newValue ); + /** + * Copies the given color into this color, and then converts this color from + * `LinearSRGBColorSpace` to `SRGBColorSpace`. + * + * @param {Color} color - The color to copy/convert. + * @return {Color} A reference to this color. + */ + copyLinearToSRGB( color ) { - } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { + this.r = LinearToSRGB( color.r ); + this.g = LinearToSRGB( color.g ); + this.b = LinearToSRGB( color.b ); - currentValue.copy( newValue ); + return this; - } else { + } - this[ key ] = newValue; + /** + * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. + * + * @return {Color} A reference to this color. + */ + convertSRGBToLinear() { - } + this.copySRGBToLinear( this ); - } + return this; } /** - * Serializes the material into JSON. + * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. * - * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized material. - * @see {@link ObjectLoader#parse} + * @return {Color} A reference to this color. */ - toJSON( meta ) { + convertLinearToSRGB() { - const isRootObject = ( meta === undefined || typeof meta === 'string' ); + this.copyLinearToSRGB( this ); - if ( isRootObject ) { + return this; - meta = { - textures: {}, - images: {} - }; + } - } + /** + * Returns the hexadecimal value of this color. + * + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {number} The hexadecimal value. + */ + getHex( colorSpace = SRGBColorSpace ) { - const data = { - metadata: { - version: 4.7, - type: 'Material', - generator: 'Material.toJSON' - } - }; + ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - // standard Material serialization - data.uuid = this.uuid; - data.type = this.type; + return Math.round( clamp( _color.r * 255, 0, 255 ) ) * 65536 + Math.round( clamp( _color.g * 255, 0, 255 ) ) * 256 + Math.round( clamp( _color.b * 255, 0, 255 ) ); - if ( this.name !== '' ) data.name = this.name; + } - if ( this.color && this.color.isColor ) data.color = this.color.getHex(); + /** + * Returns the hexadecimal value of this color as a string (for example, 'FFFFFF'). + * + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {string} The hexadecimal value as a string. + */ + getHexString( colorSpace = SRGBColorSpace ) { - if ( this.roughness !== undefined ) data.roughness = this.roughness; - if ( this.metalness !== undefined ) data.metalness = this.metalness; + return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( -6 ); - if ( this.sheen !== undefined ) data.sheen = this.sheen; - if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex(); - if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness; - if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); - if ( this.emissiveIntensity !== undefined && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; + } - if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); - if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity; - if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex(); - if ( this.shininess !== undefined ) data.shininess = this.shininess; - if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; - if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; + /** + * Converts the colors RGB values into the HSL format and stores them into the + * given target object. + * + * @param {{h:number,s:number,l:number}} target - The target object that is used to store the method's result. + * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. + * @return {{h:number,s:number,l:number}} The HSL representation of this color. + */ + getHSL( target, colorSpace = ColorManagement.workingColorSpace ) { - if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { + // h,s,l ranges are in 0.0 - 1.0 - data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; + ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - } + const r = _color.r, g = _color.g, b = _color.b; - if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { + const max = Math.max( r, g, b ); + const min = Math.min( r, g, b ); - data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; + let hue, saturation; + const lightness = ( min + max ) / 2.0; - } + if ( min === max ) { - if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { + hue = 0; + saturation = 0; - data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; - data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); + } else { - } + const delta = max - min; - if ( this.sheenColorMap && this.sheenColorMap.isTexture ) { + saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); - data.sheenColorMap = this.sheenColorMap.toJSON( meta ).uuid; + switch ( max ) { - } + case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; + case g: hue = ( b - r ) / delta + 2; break; + case b: hue = ( r - g ) / delta + 4; break; - if ( this.sheenRoughnessMap && this.sheenRoughnessMap.isTexture ) { + } - data.sheenRoughnessMap = this.sheenRoughnessMap.toJSON( meta ).uuid; + hue /= 6; } - if ( this.dispersion !== undefined ) data.dispersion = this.dispersion; - - if ( this.iridescence !== undefined ) data.iridescence = this.iridescence; - if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR; - if ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange; - - if ( this.iridescenceMap && this.iridescenceMap.isTexture ) { + target.h = hue; + target.s = saturation; + target.l = lightness; - data.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid; + return target; - } + } - if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) { + /** + * Returns the RGB values of this color and stores them into the given target object. + * + * @param {Color} target - The target color that is used to store the method's result. + * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. + * @return {Color} The RGB representation of this color. + */ + getRGB( target, colorSpace = ColorManagement.workingColorSpace ) { - data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid; + ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - } + target.r = _color.r; + target.g = _color.g; + target.b = _color.b; - if ( this.anisotropy !== undefined ) data.anisotropy = this.anisotropy; - if ( this.anisotropyRotation !== undefined ) data.anisotropyRotation = this.anisotropyRotation; + return target; - if ( this.anisotropyMap && this.anisotropyMap.isTexture ) { + } - data.anisotropyMap = this.anisotropyMap.toJSON( meta ).uuid; + /** + * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`. + * + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {string} The CSS representation of this color. + */ + getStyle( colorSpace = SRGBColorSpace ) { - } + ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; - if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; - if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; + const r = _color.r, g = _color.g, b = _color.b; - if ( this.lightMap && this.lightMap.isTexture ) { + if ( colorSpace !== SRGBColorSpace ) { - data.lightMap = this.lightMap.toJSON( meta ).uuid; - data.lightMapIntensity = this.lightMapIntensity; + // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/). + return `color(${ colorSpace } ${ r.toFixed( 3 ) } ${ g.toFixed( 3 ) } ${ b.toFixed( 3 ) })`; } - if ( this.aoMap && this.aoMap.isTexture ) { - - data.aoMap = this.aoMap.toJSON( meta ).uuid; - data.aoMapIntensity = this.aoMapIntensity; + return `rgb(${ Math.round( r * 255 ) },${ Math.round( g * 255 ) },${ Math.round( b * 255 ) })`; - } + } - if ( this.bumpMap && this.bumpMap.isTexture ) { + /** + * Adds the given HSL values to this color's values. + * Internally, this converts the color's RGB values to HSL, adds HSL + * and then converts the color back to RGB. + * + * @param {number} h - Hue value between `0.0` and `1.0`. + * @param {number} s - Saturation value between `0.0` and `1.0`. + * @param {number} l - Lightness value between `0.0` and `1.0`. + * @return {Color} A reference to this color. + */ + offsetHSL( h, s, l ) { - data.bumpMap = this.bumpMap.toJSON( meta ).uuid; - data.bumpScale = this.bumpScale; + this.getHSL( _hslA ); - } + return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l ); - if ( this.normalMap && this.normalMap.isTexture ) { + } - data.normalMap = this.normalMap.toJSON( meta ).uuid; - data.normalMapType = this.normalMapType; - data.normalScale = this.normalScale.toArray(); + /** + * Adds the RGB values of the given color to the RGB values of this color. + * + * @param {Color} color - The color to add. + * @return {Color} A reference to this color. + */ + add( color ) { - } + this.r += color.r; + this.g += color.g; + this.b += color.b; - if ( this.displacementMap && this.displacementMap.isTexture ) { + return this; - data.displacementMap = this.displacementMap.toJSON( meta ).uuid; - data.displacementScale = this.displacementScale; - data.displacementBias = this.displacementBias; + } - } + /** + * Adds the RGB values of the given colors and stores the result in this instance. + * + * @param {Color} color1 - The first color. + * @param {Color} color2 - The second color. + * @return {Color} A reference to this color. + */ + addColors( color1, color2 ) { - if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; - if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; + this.r = color1.r + color2.r; + this.g = color1.g + color2.g; + this.b = color1.b + color2.b; - if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; - if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; - if ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid; - if ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid; + return this; - if ( this.envMap && this.envMap.isTexture ) { + } - data.envMap = this.envMap.toJSON( meta ).uuid; + /** + * Adds the given scalar value to the RGB values of this color. + * + * @param {number} s - The scalar to add. + * @return {Color} A reference to this color. + */ + addScalar( s ) { - if ( this.combine !== undefined ) data.combine = this.combine; + this.r += s; + this.g += s; + this.b += s; - } + return this; - if ( this.envMapRotation !== undefined ) data.envMapRotation = this.envMapRotation.toArray(); - if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; - if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity; - if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio; + } - if ( this.gradientMap && this.gradientMap.isTexture ) { + /** + * Subtracts the RGB values of the given color from the RGB values of this color. + * + * @param {Color} color - The color to subtract. + * @return {Color} A reference to this color. + */ + sub( color ) { - data.gradientMap = this.gradientMap.toJSON( meta ).uuid; + this.r = Math.max( 0, this.r - color.r ); + this.g = Math.max( 0, this.g - color.g ); + this.b = Math.max( 0, this.b - color.b ); - } + return this; - if ( this.transmission !== undefined ) data.transmission = this.transmission; - if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid; - if ( this.thickness !== undefined ) data.thickness = this.thickness; - if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid; - if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance; - if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex(); + } - if ( this.size !== undefined ) data.size = this.size; - if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide; - if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; + /** + * Multiplies the RGB values of the given color with the RGB values of this color. + * + * @param {Color} color - The color to multiply. + * @return {Color} A reference to this color. + */ + multiply( color ) { - if ( this.blending !== NormalBlending ) data.blending = this.blending; - if ( this.side !== FrontSide ) data.side = this.side; - if ( this.vertexColors === true ) data.vertexColors = true; + this.r *= color.r; + this.g *= color.g; + this.b *= color.b; - if ( this.opacity < 1 ) data.opacity = this.opacity; - if ( this.transparent === true ) data.transparent = true; + return this; - if ( this.blendSrc !== SrcAlphaFactor ) data.blendSrc = this.blendSrc; - if ( this.blendDst !== OneMinusSrcAlphaFactor ) data.blendDst = this.blendDst; - if ( this.blendEquation !== AddEquation ) data.blendEquation = this.blendEquation; - if ( this.blendSrcAlpha !== null ) data.blendSrcAlpha = this.blendSrcAlpha; - if ( this.blendDstAlpha !== null ) data.blendDstAlpha = this.blendDstAlpha; - if ( this.blendEquationAlpha !== null ) data.blendEquationAlpha = this.blendEquationAlpha; - if ( this.blendColor && this.blendColor.isColor ) data.blendColor = this.blendColor.getHex(); - if ( this.blendAlpha !== 0 ) data.blendAlpha = this.blendAlpha; + } - if ( this.depthFunc !== LessEqualDepth ) data.depthFunc = this.depthFunc; - if ( this.depthTest === false ) data.depthTest = this.depthTest; - if ( this.depthWrite === false ) data.depthWrite = this.depthWrite; - if ( this.colorWrite === false ) data.colorWrite = this.colorWrite; + /** + * Multiplies the given scalar value with the RGB values of this color. + * + * @param {number} s - The scalar to multiply. + * @return {Color} A reference to this color. + */ + multiplyScalar( s ) { - if ( this.stencilWriteMask !== 0xff ) data.stencilWriteMask = this.stencilWriteMask; - if ( this.stencilFunc !== AlwaysStencilFunc ) data.stencilFunc = this.stencilFunc; - if ( this.stencilRef !== 0 ) data.stencilRef = this.stencilRef; - if ( this.stencilFuncMask !== 0xff ) data.stencilFuncMask = this.stencilFuncMask; - if ( this.stencilFail !== KeepStencilOp ) data.stencilFail = this.stencilFail; - if ( this.stencilZFail !== KeepStencilOp ) data.stencilZFail = this.stencilZFail; - if ( this.stencilZPass !== KeepStencilOp ) data.stencilZPass = this.stencilZPass; - if ( this.stencilWrite === true ) data.stencilWrite = this.stencilWrite; + this.r *= s; + this.g *= s; + this.b *= s; - // rotation (SpriteMaterial) - if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation; + return this; - if ( this.polygonOffset === true ) data.polygonOffset = true; - if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; - if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; + } - if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth; - if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; - if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; - if ( this.scale !== undefined ) data.scale = this.scale; + /** + * Linearly interpolates this color's RGB values toward the RGB values of the + * given color. The alpha argument can be thought of as the ratio between + * the two colors, where `0.0` is this color and `1.0` is the first argument. + * + * @param {Color} color - The color to converge on. + * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. + * @return {Color} A reference to this color. + */ + lerp( color, alpha ) { - if ( this.dithering === true ) data.dithering = true; + this.r += ( color.r - this.r ) * alpha; + this.g += ( color.g - this.g ) * alpha; + this.b += ( color.b - this.b ) * alpha; - if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; - if ( this.alphaHash === true ) data.alphaHash = true; - if ( this.alphaToCoverage === true ) data.alphaToCoverage = true; - if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true; - if ( this.forceSinglePass === true ) data.forceSinglePass = true; - if ( this.allowOverride === false ) data.allowOverride = false; + return this; - if ( this.wireframe === true ) data.wireframe = true; - if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; - if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; - if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; + } - if ( this.flatShading === true ) data.flatShading = true; + /** + * Linearly interpolates between the given colors and stores the result in this instance. + * The alpha argument can be thought of as the ratio between the two colors, where `0.0` + * is the first and `1.0` is the second color. + * + * @param {Color} color1 - The first color. + * @param {Color} color2 - The second color. + * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. + * @return {Color} A reference to this color. + */ + lerpColors( color1, color2, alpha ) { - if ( this.visible === false ) data.visible = false; + this.r = color1.r + ( color2.r - color1.r ) * alpha; + this.g = color1.g + ( color2.g - color1.g ) * alpha; + this.b = color1.b + ( color2.b - color1.b ) * alpha; - if ( this.toneMapped === false ) data.toneMapped = false; + return this; - if ( this.fog === false ) data.fog = false; + } - if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; + /** + * Linearly interpolates this color's HSL values toward the HSL values of the + * given color. It differs from {@link Color#lerp} by not interpolating straight + * from one color to the other, but instead going through all the hues in between + * those two colors. The alpha argument can be thought of as the ratio between + * the two colors, where 0.0 is this color and 1.0 is the first argument. + * + * @param {Color} color - The color to converge on. + * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. + * @return {Color} A reference to this color. + */ + lerpHSL( color, alpha ) { - // TODO: Copied from Object3D.toJSON + this.getHSL( _hslA ); + color.getHSL( _hslB ); - function extractFromCache( cache ) { + const h = lerp( _hslA.h, _hslB.h, alpha ); + const s = lerp( _hslA.s, _hslB.s, alpha ); + const l = lerp( _hslA.l, _hslB.l, alpha ); - const values = []; + this.setHSL( h, s, l ); - for ( const key in cache ) { + return this; - const data = cache[ key ]; - delete data.metadata; - values.push( data ); + } - } + /** + * Sets the color's RGB components from the given 3D vector. + * + * @param {Vector3} v - The vector to set. + * @return {Color} A reference to this color. + */ + setFromVector3( v ) { - return values; + this.r = v.x; + this.g = v.y; + this.b = v.z; - } + return this; - if ( isRootObject ) { + } - const textures = extractFromCache( meta.textures ); - const images = extractFromCache( meta.images ); + /** + * Transforms this color with the given 3x3 matrix. + * + * @param {Matrix3} m - The matrix. + * @return {Color} A reference to this color. + */ + applyMatrix3( m ) { - if ( textures.length > 0 ) data.textures = textures; - if ( images.length > 0 ) data.images = images; + const r = this.r, g = this.g, b = this.b; + const e = m.elements; - } + this.r = e[ 0 ] * r + e[ 3 ] * g + e[ 6 ] * b; + this.g = e[ 1 ] * r + e[ 4 ] * g + e[ 7 ] * b; + this.b = e[ 2 ] * r + e[ 5 ] * g + e[ 8 ] * b; - return data; + return this; } /** - * Returns a new material with copied values from this instance. + * Returns `true` if this color is equal with the given one. * - * @return {Material} A clone of this instance. + * @param {Color} c - The color to test for equality. + * @return {boolean} Whether this bounding color is equal with the given one. */ - clone() { + equals( c ) { - return new this.constructor().copy( this ); + return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); } /** - * Copies the values of the given material to this instance. + * Sets this color's RGB components from the given array. * - * @param {Material} source - The material to copy. - * @return {Material} A reference to this instance. + * @param {Array} array - An array holding the RGB values. + * @param {number} [offset=0] - The offset into the array. + * @return {Color} A reference to this color. */ - copy( source ) { + fromArray( array, offset = 0 ) { - this.name = source.name; + this.r = array[ offset ]; + this.g = array[ offset + 1 ]; + this.b = array[ offset + 2 ]; - this.blending = source.blending; - this.side = source.side; - this.vertexColors = source.vertexColors; + return this; - this.opacity = source.opacity; - this.transparent = source.transparent; + } - this.blendSrc = source.blendSrc; - this.blendDst = source.blendDst; - this.blendEquation = source.blendEquation; - this.blendSrcAlpha = source.blendSrcAlpha; - this.blendDstAlpha = source.blendDstAlpha; - this.blendEquationAlpha = source.blendEquationAlpha; - this.blendColor.copy( source.blendColor ); - this.blendAlpha = source.blendAlpha; + /** + * Writes the RGB components of this color to the given array. If no array is provided, + * the method returns a new instance. + * + * @param {Array} [array=[]] - The target array holding the color components. + * @param {number} [offset=0] - Index of the first element in the array. + * @return {Array} The color components. + */ + toArray( array = [], offset = 0 ) { - this.depthFunc = source.depthFunc; - this.depthTest = source.depthTest; - this.depthWrite = source.depthWrite; + array[ offset ] = this.r; + array[ offset + 1 ] = this.g; + array[ offset + 2 ] = this.b; - this.stencilWriteMask = source.stencilWriteMask; - this.stencilFunc = source.stencilFunc; - this.stencilRef = source.stencilRef; - this.stencilFuncMask = source.stencilFuncMask; - this.stencilFail = source.stencilFail; - this.stencilZFail = source.stencilZFail; - this.stencilZPass = source.stencilZPass; - this.stencilWrite = source.stencilWrite; + return array; + + } - const srcPlanes = source.clippingPlanes; - let dstPlanes = null; + /** + * Sets the components of this color from the given buffer attribute. + * + * @param {BufferAttribute} attribute - The buffer attribute holding color data. + * @param {number} index - The index into the attribute. + * @return {Color} A reference to this color. + */ + fromBufferAttribute( attribute, index ) { - if ( srcPlanes !== null ) { + this.r = attribute.getX( index ); + this.g = attribute.getY( index ); + this.b = attribute.getZ( index ); - const n = srcPlanes.length; - dstPlanes = new Array( n ); + return this; - for ( let i = 0; i !== n; ++ i ) { + } - dstPlanes[ i ] = srcPlanes[ i ].clone(); + /** + * This methods defines the serialization result of this class. Returns the color + * as a hexadecimal value. + * + * @return {number} The hexadecimal value. + */ + toJSON() { - } + return this.getHex(); - } + } - this.clippingPlanes = dstPlanes; - this.clipIntersection = source.clipIntersection; - this.clipShadows = source.clipShadows; + *[ Symbol.iterator ]() { - this.shadowSide = source.shadowSide; + yield this.r; + yield this.g; + yield this.b; - this.colorWrite = source.colorWrite; + } - this.precision = source.precision; +} - this.polygonOffset = source.polygonOffset; - this.polygonOffsetFactor = source.polygonOffsetFactor; - this.polygonOffsetUnits = source.polygonOffsetUnits; +const _color = /*@__PURE__*/ new Color(); - this.dithering = source.dithering; +/** + * A dictionary with X11 color names. + * + * Note that multiple words such as Dark Orange become the string 'darkorange'. + * + * @static + * @type {Object} + */ +Color.NAMES = _colorKeywords; - this.alphaTest = source.alphaTest; - this.alphaHash = source.alphaHash; - this.alphaToCoverage = source.alphaToCoverage; - this.premultipliedAlpha = source.premultipliedAlpha; - this.forceSinglePass = source.forceSinglePass; - this.allowOverride = source.allowOverride; +/** + * This class can be used to define an exponential squared fog, + * which gives a clear view near the camera and a faster than exponentially + * densening fog farther from the camera. + * + * ```js + * const scene = new THREE.Scene(); + * scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 ); + * ``` + */ +class FogExp2 { - this.visible = source.visible; + /** + * Constructs a new fog. + * + * @param {number|Color} color - The fog's color. + * @param {number} [density=0.00025] - Defines how fast the fog will grow dense. + */ + constructor( color, density = 0.00025 ) { - this.toneMapped = source.toneMapped; + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isFogExp2 = true; - this.userData = JSON.parse( JSON.stringify( source.userData ) ); + /** + * The name of the fog. + * + * @type {string} + */ + this.name = ''; - return this; + /** + * The fog's color. + * + * @type {Color} + */ + this.color = new Color( color ); + + /** + * Defines how fast the fog will grow dense. + * + * @type {number} + * @default 0.00025 + */ + this.density = density; } /** - * Frees the GPU-related resources allocated by this instance. Call this - * method whenever this instance is no longer used in your app. + * Returns a new fog with copied values from this instance. * - * @fires Material#dispose + * @return {FogExp2} A clone of this instance. */ - dispose() { + clone() { - /** - * Fires when the material has been disposed of. - * - * @event Material#dispose - * @type {Object} - */ - this.dispatchEvent( { type: 'dispose' } ); + return new FogExp2( this.color, this.density ); } /** - * Setting this property to `true` indicates the engine the material - * needs to be recompiled. + * Serializes the fog into JSON. * - * @type {boolean} - * @default false - * @param {boolean} value + * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized fog */ - set needsUpdate( value ) { + toJSON( /* meta */ ) { - if ( value === true ) this.version ++; + return { + type: 'FogExp2', + name: this.name, + color: this.color.getHex(), + density: this.density + }; } } /** - * A material for drawing geometries in a simple shaded (flat or wireframe) way. - * - * This material is not affected by lights. + * This class can be used to define a linear fog that grows linearly denser + * with the distance. * - * @augments Material - * @demo scenes/material-browser.html#MeshBasicMaterial + * ```js + * const scene = new THREE.Scene(); + * scene.fog = new THREE.Fog( 0xcccccc, 10, 15 ); + * ``` */ -class MeshBasicMaterial extends Material { +class Fog { /** - * Constructs a new mesh basic material. + * Constructs a new fog. * - * @param {Object} [parameters] - An object with one or more properties - * defining the material's appearance. Any property of the material - * (including any property from inherited materials) can be passed - * in here. Color values can be passed any type of value accepted - * by {@link Color#set}. + * @param {number|Color} color - The fog's color. + * @param {number} [near=1] - The minimum distance to start applying fog. + * @param {number} [far=1000] - The maximum distance at which fog stops being calculated and applied. */ - constructor( parameters ) { - - super(); + constructor( color, near = 1, far = 1000 ) { /** * This flag can be used for type testing. @@ -17644,1496 +14772,1810 @@ class MeshBasicMaterial extends Material { * @readonly * @default true */ - this.isMeshBasicMaterial = true; - - this.type = 'MeshBasicMaterial'; - - /** - * Color of the material. - * - * @type {Color} - * @default (1,1,1) - */ - this.color = new Color( 0xffffff ); // diffuse + this.isFog = true; /** - * The color map. May optionally include an alpha channel, typically combined - * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map - * color is modulated by the diffuse `color`. + * The name of the fog. * - * @type {?Texture} - * @default null + * @type {string} */ - this.map = null; + this.name = ''; /** - * The light map. Requires a second set of UVs. + * The fog's color. * - * @type {?Texture} - * @default null + * @type {Color} */ - this.lightMap = null; + this.color = new Color( color ); /** - * Intensity of the baked light. + * The minimum distance to start applying fog. Objects that are less than + * `near` units from the active camera won't be affected by fog. * * @type {number} * @default 1 */ - this.lightMapIntensity = 1.0; + this.near = near; /** - * The red channel of this texture is used as the ambient occlusion map. - * Requires a second set of UVs. + * The maximum distance at which fog stops being calculated and applied. + * Objects that are more than `far` units away from the active camera won't + * be affected by fog. * - * @type {?Texture} - * @default null + * @type {number} + * @default 1000 */ - this.aoMap = null; + this.far = far; + + } + + /** + * Returns a new fog with copied values from this instance. + * + * @return {Fog} A clone of this instance. + */ + clone() { + + return new Fog( this.color, this.near, this.far ); + + } + + /** + * Serializes the fog into JSON. + * + * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized fog + */ + toJSON( /* meta */ ) { + + return { + type: 'Fog', + name: this.name, + color: this.color.getHex(), + near: this.near, + far: this.far + }; + + } + +} + +/** + * Scenes allow you to set up what is to be rendered and where by three.js. + * This is where you place 3D objects like meshes, lines or lights. + * + * @augments Object3D + */ +class Scene extends Object3D { + + /** + * Constructs a new scene. + */ + constructor() { + + super(); /** - * Intensity of the ambient occlusion effect. Range is `[0,1]`, where `0` - * disables ambient occlusion. Where intensity is `1` and the AO map's - * red channel is also `1`, ambient light is fully occluded on a surface. + * This flag can be used for type testing. * - * @type {number} - * @default 1 + * @type {boolean} + * @readonly + * @default true */ - this.aoMapIntensity = 1.0; + this.isScene = true; + + this.type = 'Scene'; /** - * Specular map used by the material. + * Defines the background of the scene. Valid inputs are: * - * @type {?Texture} + * - A color for defining a uniform colored background. + * - A texture for defining a (flat) textured background. + * - Cube textures or equirectangular textures for defining a skybox. + * + * @type {?(Color|Texture)} * @default null */ - this.specularMap = null; + this.background = null; /** - * The alpha map is a grayscale texture that controls the opacity across the - * surface (black: fully transparent; white: fully opaque). - * - * Only the color of the texture is used, ignoring the alpha channel if one - * exists. For RGB and RGBA textures, the renderer will use the green channel - * when sampling this texture due to the extra bit of precision provided for - * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and - * luminance/alpha textures will also still work as expected. + * Sets the environment map for all physical materials in the scene. However, + * it's not possible to overwrite an existing texture assigned to the `envMap` + * material property. * * @type {?Texture} * @default null */ - this.alphaMap = null; + this.environment = null; /** - * The environment map. + * A fog instance defining the type of fog that affects everything + * rendered in the scene. * - * @type {?Texture} + * @type {?(Fog|FogExp2)} * @default null */ - this.envMap = null; + this.fog = null; /** - * The rotation of the environment map in radians. + * Sets the blurriness of the background. Only influences environment maps + * assigned to {@link Scene#background}. Valid input is a float between `0` + * and `1`. * - * @type {Euler} - * @default (0,0,0) + * @type {number} + * @default 0 */ - this.envMapRotation = new Euler(); + this.backgroundBlurriness = 0; /** - * How to combine the result of the surface's color with the environment map, if any. - * - * When set to `MixOperation`, the {@link MeshBasicMaterial#reflectivity} is used to - * blend between the two colors. + * Attenuates the color of the background. Only applies to background textures. * - * @type {(MultiplyOperation|MixOperation|AddOperation)} - * @default MultiplyOperation + * @type {number} + * @default 1 */ - this.combine = MultiplyOperation; + this.backgroundIntensity = 1; /** - * How much the environment map affects the surface. - * The valid range is between `0` (no reflections) and `1` (full reflections). + * The rotation of the background in radians. Only influences environment maps + * assigned to {@link Scene#background}. * - * @type {number} - * @default 1 + * @type {Euler} + * @default (0,0,0) */ - this.reflectivity = 1; + this.backgroundRotation = new Euler(); /** - * The index of refraction (IOR) of air (approximately 1) divided by the - * index of refraction of the material. It is used with environment mapping - * modes {@link CubeRefractionMapping} and {@link EquirectangularRefractionMapping}. - * The refraction ratio should not exceed `1`. + * Attenuates the color of the environment. Only influences environment maps + * assigned to {@link Scene#environment}. * * @type {number} - * @default 0.98 + * @default 1 */ - this.refractionRatio = 0.98; + this.environmentIntensity = 1; /** - * Renders the geometry as a wireframe. + * The rotation of the environment map in radians. Only influences physical materials + * in the scene when {@link Scene#environment} is used. * - * @type {boolean} - * @default false + * @type {Euler} + * @default (0,0,0) */ - this.wireframe = false; + this.environmentRotation = new Euler(); /** - * Controls the thickness of the wireframe. - * - * Can only be used with {@link SVGRenderer}. + * Forces everything in the scene to be rendered with the defined material. It is possible + * to exclude materials from override by setting {@link Material#allowOverride} to `false`. * - * @type {number} - * @default 1 + * @type {?Material} + * @default null */ - this.wireframeLinewidth = 1; + this.overrideMaterial = null; + + if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); + + } + + } + + copy( source, recursive ) { + + super.copy( source, recursive ); + + if ( source.background !== null ) this.background = source.background.clone(); + if ( source.environment !== null ) this.environment = source.environment.clone(); + if ( source.fog !== null ) this.fog = source.fog.clone(); + + this.backgroundBlurriness = source.backgroundBlurriness; + this.backgroundIntensity = source.backgroundIntensity; + this.backgroundRotation.copy( source.backgroundRotation ); + + this.environmentIntensity = source.environmentIntensity; + this.environmentRotation.copy( source.environmentRotation ); + + if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); + + this.matrixAutoUpdate = source.matrixAutoUpdate; + + return this; + + } + + toJSON( meta ) { + + const data = super.toJSON( meta ); + + if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); + + if ( this.backgroundBlurriness > 0 ) data.object.backgroundBlurriness = this.backgroundBlurriness; + if ( this.backgroundIntensity !== 1 ) data.object.backgroundIntensity = this.backgroundIntensity; + data.object.backgroundRotation = this.backgroundRotation.toArray(); + + if ( this.environmentIntensity !== 1 ) data.object.environmentIntensity = this.environmentIntensity; + data.object.environmentRotation = this.environmentRotation.toArray(); + + return data; + + } + +} + +const _v0$3 = /*@__PURE__*/ new Vector3(); +const _v1$5 = /*@__PURE__*/ new Vector3(); +const _v2$4 = /*@__PURE__*/ new Vector3(); +const _v3$2 = /*@__PURE__*/ new Vector3(); + +const _vab = /*@__PURE__*/ new Vector3(); +const _vac = /*@__PURE__*/ new Vector3(); +const _vbc = /*@__PURE__*/ new Vector3(); +const _vap = /*@__PURE__*/ new Vector3(); +const _vbp = /*@__PURE__*/ new Vector3(); +const _vcp = /*@__PURE__*/ new Vector3(); + +const _v40 = /*@__PURE__*/ new Vector4(); +const _v41 = /*@__PURE__*/ new Vector4(); +const _v42 = /*@__PURE__*/ new Vector4(); + +/** + * A geometric triangle as defined by three vectors representing its three corners. + */ +class Triangle { + + /** + * Constructs a new triangle. + * + * @param {Vector3} [a=(0,0,0)] - The first corner of the triangle. + * @param {Vector3} [b=(0,0,0)] - The second corner of the triangle. + * @param {Vector3} [c=(0,0,0)] - The third corner of the triangle. + */ + constructor( a = new Vector3(), b = new Vector3(), c = new Vector3() ) { /** - * Defines appearance of wireframe ends. - * - * Can only be used with {@link SVGRenderer}. + * The first corner of the triangle. * - * @type {('round'|'bevel'|'miter')} - * @default 'round' + * @type {Vector3} */ - this.wireframeLinecap = 'round'; + this.a = a; /** - * Defines appearance of wireframe joints. - * - * Can only be used with {@link SVGRenderer}. + * The second corner of the triangle. * - * @type {('round'|'bevel'|'miter')} - * @default 'round' + * @type {Vector3} */ - this.wireframeLinejoin = 'round'; + this.b = b; /** - * Whether the material is affected by fog or not. + * The third corner of the triangle. * - * @type {boolean} - * @default true + * @type {Vector3} */ - this.fog = true; + this.c = c; + + } + + /** + * Computes the normal vector of a triangle. + * + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The triangle's normal. + */ + static getNormal( a, b, c, target ) { + + target.subVectors( c, b ); + _v0$3.subVectors( a, b ); + target.cross( _v0$3 ); + + const targetLengthSq = target.lengthSq(); + if ( targetLengthSq > 0 ) { + + return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); + + } + + return target.set( 0, 0, 0 ); + + } + + /** + * Computes a barycentric coordinates from the given vector. + * Returns `null` if the triangle is degenerate. + * + * @param {Vector3} point - A point in 3D space. + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The barycentric coordinates for the given point + */ + static getBarycoord( point, a, b, c, target ) { - this.setValues( parameters ); + // based on: http://www.blackpawn.com/texts/pointinpoly/default.html - } + _v0$3.subVectors( c, a ); + _v1$5.subVectors( b, a ); + _v2$4.subVectors( point, a ); - copy( source ) { + const dot00 = _v0$3.dot( _v0$3 ); + const dot01 = _v0$3.dot( _v1$5 ); + const dot02 = _v0$3.dot( _v2$4 ); + const dot11 = _v1$5.dot( _v1$5 ); + const dot12 = _v1$5.dot( _v2$4 ); - super.copy( source ); + const denom = ( dot00 * dot11 - dot01 * dot01 ); - this.color.copy( source.color ); + // collinear or singular triangle + if ( denom === 0 ) { - this.map = source.map; + target.set( 0, 0, 0 ); + return null; - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; + } - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; + const invDenom = 1 / denom; + const u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; + const v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; - this.specularMap = source.specularMap; + // barycentric coordinates must always sum to 1 + return target.set( 1 - u - v, v, u ); - this.alphaMap = source.alphaMap; + } - this.envMap = source.envMap; - this.envMapRotation.copy( source.envMapRotation ); - this.combine = source.combine; - this.reflectivity = source.reflectivity; - this.refractionRatio = source.refractionRatio; + /** + * Returns `true` if the given point, when projected onto the plane of the + * triangle, lies within the triangle. + * + * @param {Vector3} point - The point in 3D space to test. + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @return {boolean} Whether the given point, when projected onto the plane of the + * triangle, lies within the triangle or not. + */ + static containsPoint( point, a, b, c ) { - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; + // if the triangle is degenerate then we can't contain a point + if ( this.getBarycoord( point, a, b, c, _v3$2 ) === null ) { - this.fog = source.fog; + return false; - return this; + } - } + return ( _v3$2.x >= 0 ) && ( _v3$2.y >= 0 ) && ( ( _v3$2.x + _v3$2.y ) <= 1 ); -} + } -// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf + /** + * Computes the value barycentrically interpolated for the given point on the + * triangle. Returns `null` if the triangle is degenerate. + * + * @param {Vector3} point - Position of interpolated point. + * @param {Vector3} p1 - The first corner of the triangle. + * @param {Vector3} p2 - The second corner of the triangle. + * @param {Vector3} p3 - The third corner of the triangle. + * @param {Vector3} v1 - Value to interpolate of first vertex. + * @param {Vector3} v2 - Value to interpolate of second vertex. + * @param {Vector3} v3 - Value to interpolate of third vertex. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The interpolated value. + */ + static getInterpolation( point, p1, p2, p3, v1, v2, v3, target ) { -const _tables = /*@__PURE__*/ _generateTables(); + if ( this.getBarycoord( point, p1, p2, p3, _v3$2 ) === null ) { -function _generateTables() { + target.x = 0; + target.y = 0; + if ( 'z' in target ) target.z = 0; + if ( 'w' in target ) target.w = 0; + return null; - // float32 to float16 helpers + } - const buffer = new ArrayBuffer( 4 ); - const floatView = new Float32Array( buffer ); - const uint32View = new Uint32Array( buffer ); + target.setScalar( 0 ); + target.addScaledVector( v1, _v3$2.x ); + target.addScaledVector( v2, _v3$2.y ); + target.addScaledVector( v3, _v3$2.z ); - const baseTable = new Uint32Array( 512 ); - const shiftTable = new Uint32Array( 512 ); + return target; - for ( let i = 0; i < 256; ++ i ) { + } - const e = i - 127; + /** + * Computes the value barycentrically interpolated for the given attribute and indices. + * + * @param {BufferAttribute} attr - The attribute to interpolate. + * @param {number} i1 - Index of first vertex. + * @param {number} i2 - Index of second vertex. + * @param {number} i3 - Index of third vertex. + * @param {Vector3} barycoord - The barycoordinate value to use to interpolate. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The interpolated attribute value. + */ + static getInterpolatedAttribute( attr, i1, i2, i3, barycoord, target ) { - // very small number (0, -0) + _v40.setScalar( 0 ); + _v41.setScalar( 0 ); + _v42.setScalar( 0 ); - if ( e < -27 ) { + _v40.fromBufferAttribute( attr, i1 ); + _v41.fromBufferAttribute( attr, i2 ); + _v42.fromBufferAttribute( attr, i3 ); - baseTable[ i ] = 0x0000; - baseTable[ i | 0x100 ] = 0x8000; - shiftTable[ i ] = 24; - shiftTable[ i | 0x100 ] = 24; + target.setScalar( 0 ); + target.addScaledVector( _v40, barycoord.x ); + target.addScaledVector( _v41, barycoord.y ); + target.addScaledVector( _v42, barycoord.z ); - // small number (denorm) + return target; - } else if ( e < -14 ) { + } - baseTable[ i ] = 0x0400 >> ( - e - 14 ); - baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000; - shiftTable[ i ] = - e - 1; - shiftTable[ i | 0x100 ] = - e - 1; + /** + * Returns `true` if the triangle is oriented towards the given direction. + * + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @param {Vector3} direction - The (normalized) direction vector. + * @return {boolean} Whether the triangle is oriented towards the given direction or not. + */ + static isFrontFacing( a, b, c, direction ) { - // normal number + _v0$3.subVectors( c, b ); + _v1$5.subVectors( a, b ); - } else if ( e <= 15 ) { + // strictly front facing + return ( _v0$3.cross( _v1$5 ).dot( direction ) < 0 ) ? true : false; - baseTable[ i ] = ( e + 15 ) << 10; - baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000; - shiftTable[ i ] = 13; - shiftTable[ i | 0x100 ] = 13; + } - // large number (Infinity, -Infinity) + /** + * Sets the triangle's vertices by copying the given values. + * + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @return {Triangle} A reference to this triangle. + */ + set( a, b, c ) { - } else if ( e < 128 ) { + this.a.copy( a ); + this.b.copy( b ); + this.c.copy( c ); - baseTable[ i ] = 0x7c00; - baseTable[ i | 0x100 ] = 0xfc00; - shiftTable[ i ] = 24; - shiftTable[ i | 0x100 ] = 24; + return this; - // stay (NaN, Infinity, -Infinity) + } - } else { + /** + * Sets the triangle's vertices by copying the given array values. + * + * @param {Array} points - An array with 3D points. + * @param {number} i0 - The array index representing the first corner of the triangle. + * @param {number} i1 - The array index representing the second corner of the triangle. + * @param {number} i2 - The array index representing the third corner of the triangle. + * @return {Triangle} A reference to this triangle. + */ + setFromPointsAndIndices( points, i0, i1, i2 ) { - baseTable[ i ] = 0x7c00; - baseTable[ i | 0x100 ] = 0xfc00; - shiftTable[ i ] = 13; - shiftTable[ i | 0x100 ] = 13; + this.a.copy( points[ i0 ] ); + this.b.copy( points[ i1 ] ); + this.c.copy( points[ i2 ] ); - } + return this; } - // float16 to float32 helpers + /** + * Sets the triangle's vertices by copying the given attribute values. + * + * @param {BufferAttribute} attribute - A buffer attribute with 3D points data. + * @param {number} i0 - The attribute index representing the first corner of the triangle. + * @param {number} i1 - The attribute index representing the second corner of the triangle. + * @param {number} i2 - The attribute index representing the third corner of the triangle. + * @return {Triangle} A reference to this triangle. + */ + setFromAttributeAndIndices( attribute, i0, i1, i2 ) { - const mantissaTable = new Uint32Array( 2048 ); - const exponentTable = new Uint32Array( 64 ); - const offsetTable = new Uint32Array( 64 ); + this.a.fromBufferAttribute( attribute, i0 ); + this.b.fromBufferAttribute( attribute, i1 ); + this.c.fromBufferAttribute( attribute, i2 ); - for ( let i = 1; i < 1024; ++ i ) { + return this; - let m = i << 13; // zero pad mantissa bits - let e = 0; // zero exponent + } - // normalized - while ( ( m & 0x00800000 ) === 0 ) { + /** + * Returns a new triangle with copied values from this instance. + * + * @return {Triangle} A clone of this instance. + */ + clone() { - m <<= 1; - e -= 0x00800000; // decrement exponent + return new this.constructor().copy( this ); - } + } - m &= -8388609; // clear leading 1 bit - e += 0x38800000; // adjust bias + /** + * Copies the values of the given triangle to this instance. + * + * @param {Triangle} triangle - The triangle to copy. + * @return {Triangle} A reference to this triangle. + */ + copy( triangle ) { - mantissaTable[ i ] = m | e; + this.a.copy( triangle.a ); + this.b.copy( triangle.b ); + this.c.copy( triangle.c ); + + return this; } - for ( let i = 1024; i < 2048; ++ i ) { + /** + * Computes the area of the triangle. + * + * @return {number} The triangle's area. + */ + getArea() { - mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 ); + _v0$3.subVectors( this.c, this.b ); + _v1$5.subVectors( this.a, this.b ); + + return _v0$3.cross( _v1$5 ).length() * 0.5; } - for ( let i = 1; i < 31; ++ i ) { + /** + * Computes the midpoint of the triangle. + * + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The triangle's midpoint. + */ + getMidpoint( target ) { - exponentTable[ i ] = i << 23; + return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); } - exponentTable[ 31 ] = 0x47800000; - exponentTable[ 32 ] = 0x80000000; - - for ( let i = 33; i < 63; ++ i ) { + /** + * Computes the normal of the triangle. + * + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The triangle's normal. + */ + getNormal( target ) { - exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 ); + return Triangle.getNormal( this.a, this.b, this.c, target ); } - exponentTable[ 63 ] = 0xc7800000; + /** + * Computes a plane the triangle lies within. + * + * @param {Plane} target - The target vector that is used to store the method's result. + * @return {Plane} The plane the triangle lies within. + */ + getPlane( target ) { - for ( let i = 1; i < 64; ++ i ) { + return target.setFromCoplanarPoints( this.a, this.b, this.c ); - if ( i !== 32 ) { + } - offsetTable[ i ] = 1024; + /** + * Computes a barycentric coordinates from the given vector. + * Returns `null` if the triangle is degenerate. + * + * @param {Vector3} point - A point in 3D space. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The barycentric coordinates for the given point + */ + getBarycoord( point, target ) { - } + return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); } - return { - floatView: floatView, - uint32View: uint32View, - baseTable: baseTable, - shiftTable: shiftTable, - mantissaTable: mantissaTable, - exponentTable: exponentTable, - offsetTable: offsetTable - }; - -} - -/** - * Returns a half precision floating point value (FP16) from the given single - * precision floating point value (FP32). - * - * @param {number} val - A single precision floating point value. - * @return {number} The FP16 value. - */ -function toHalfFloat( val ) { + /** + * Computes the value barycentrically interpolated for the given point on the + * triangle. Returns `null` if the triangle is degenerate. + * + * @param {Vector3} point - Position of interpolated point. + * @param {Vector3} v1 - Value to interpolate of first vertex. + * @param {Vector3} v2 - Value to interpolate of second vertex. + * @param {Vector3} v3 - Value to interpolate of third vertex. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The interpolated value. + */ + getInterpolation( point, v1, v2, v3, target ) { - if ( Math.abs( val ) > 65504 ) warn( 'DataUtils.toHalfFloat(): Value out of range.' ); + return Triangle.getInterpolation( point, this.a, this.b, this.c, v1, v2, v3, target ); - val = clamp( val, -65504, 65504 ); + } - _tables.floatView[ 0 ] = val; - const f = _tables.uint32View[ 0 ]; - const e = ( f >> 23 ) & 0x1ff; - return _tables.baseTable[ e ] + ( ( f & 0x007fffff ) >> _tables.shiftTable[ e ] ); + /** + * Returns `true` if the given point, when projected onto the plane of the + * triangle, lies within the triangle. + * + * @param {Vector3} point - The point in 3D space to test. + * @return {boolean} Whether the given point, when projected onto the plane of the + * triangle, lies within the triangle or not. + */ + containsPoint( point ) { -} + return Triangle.containsPoint( point, this.a, this.b, this.c ); -/** - * Returns a single precision floating point value (FP32) from the given half - * precision floating point value (FP16). - * - * @param {number} val - A half precision floating point value. - * @return {number} The FP32 value. - */ -function fromHalfFloat( val ) { + } - const m = val >> 10; - _tables.uint32View[ 0 ] = _tables.mantissaTable[ _tables.offsetTable[ m ] + ( val & 0x3ff ) ] + _tables.exponentTable[ m ]; - return _tables.floatView[ 0 ]; + /** + * Returns `true` if the triangle is oriented towards the given direction. + * + * @param {Vector3} direction - The (normalized) direction vector. + * @return {boolean} Whether the triangle is oriented towards the given direction or not. + */ + isFrontFacing( direction ) { -} + return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); -/** - * A class containing utility functions for data. - * - * @hideconstructor - */ -class DataUtils { + } /** - * Returns a half precision floating point value (FP16) from the given single - * precision floating point value (FP32). + * Returns `true` if this triangle intersects with the given box. * - * @param {number} val - A single precision floating point value. - * @return {number} The FP16 value. + * @param {Box3} box - The box to intersect. + * @return {boolean} Whether this triangle intersects with the given box or not. */ - static toHalfFloat( val ) { + intersectsBox( box ) { - return toHalfFloat( val ); + return box.intersectsTriangle( this ); } /** - * Returns a single precision floating point value (FP32) from the given half - * precision floating point value (FP16). + * Returns the closest point on the triangle to the given point. * - * @param {number} val - A half precision floating point value. - * @return {number} The FP32 value. + * @param {Vector3} p - The point to compute the closest point for. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The closest point on the triangle. */ - static fromHalfFloat( val ) { + closestPointToPoint( p, target ) { - return fromHalfFloat( val ); + const a = this.a, b = this.b, c = this.c; + let v, w; - } + // algorithm thanks to Real-Time Collision Detection by Christer Ericson, + // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., + // under the accompanying license; see chapter 5.1.5 for detailed explanation. + // basically, we're distinguishing which of the voronoi regions of the triangle + // the point lies in with the minimum amount of redundant computation. -} + _vab.subVectors( b, a ); + _vac.subVectors( c, a ); + _vap.subVectors( p, a ); + const d1 = _vab.dot( _vap ); + const d2 = _vac.dot( _vap ); + if ( d1 <= 0 && d2 <= 0 ) { -const _vector$9 = /*@__PURE__*/ new Vector3(); -const _vector2$1 = /*@__PURE__*/ new Vector2(); + // vertex region of A; barycentric coords (1, 0, 0) + return target.copy( a ); -let _id$3 = 0; + } -/** - * This class stores data for an attribute (such as vertex positions, face - * indices, normals, colors, UVs, and any custom attributes ) associated with - * a geometry, which allows for more efficient passing of data to the GPU. - * - * When working with vector-like data, the `fromBufferAttribute( attribute, index )` - * helper methods on vector and color class might be helpful. E.g. {@link Vector3#fromBufferAttribute}. - */ -class BufferAttribute { + _vbp.subVectors( p, b ); + const d3 = _vab.dot( _vbp ); + const d4 = _vac.dot( _vbp ); + if ( d3 >= 0 && d4 <= d3 ) { - /** - * Constructs a new buffer attribute. - * - * @param {TypedArray} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized = false ) { + // vertex region of B; barycentric coords (0, 1, 0) + return target.copy( b ); - if ( Array.isArray( array ) ) { + } - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + const vc = d1 * d4 - d3 * d2; + if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { + + v = d1 / ( d1 - d3 ); + // edge region of AB; barycentric coords (1-v, v, 0) + return target.copy( a ).addScaledVector( _vab, v ); } - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isBufferAttribute = true; + _vcp.subVectors( p, c ); + const d5 = _vab.dot( _vcp ); + const d6 = _vac.dot( _vcp ); + if ( d6 >= 0 && d5 <= d6 ) { - /** - * The ID of the buffer attribute. - * - * @name BufferAttribute#id - * @type {number} - * @readonly - */ - Object.defineProperty( this, 'id', { value: _id$3 ++ } ); + // vertex region of C; barycentric coords (0, 0, 1) + return target.copy( c ); - /** - * The name of the buffer attribute. - * - * @type {string} - */ - this.name = ''; + } + + const vb = d5 * d2 - d1 * d6; + if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { + + w = d2 / ( d2 - d6 ); + // edge region of AC; barycentric coords (1-w, 0, w) + return target.copy( a ).addScaledVector( _vac, w ); + + } + + const va = d3 * d6 - d5 * d4; + if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { + + _vbc.subVectors( c, b ); + w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); + // edge region of BC; barycentric coords (0, 1-w, w) + return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC + + } + + // face region + const denom = 1 / ( va + vb + vc ); + // u = va * denom + v = vb * denom; + w = vc * denom; + + return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w ); + + } + + /** + * Returns `true` if this triangle is equal with the given one. + * + * @param {Triangle} triangle - The triangle to test for equality. + * @return {boolean} Whether this triangle is equal with the given one. + */ + equals( triangle ) { - /** - * The array holding the attribute data. It should have `itemSize * numVertices` - * elements, where `numVertices` is the number of vertices in the associated geometry. - * - * @type {TypedArray} - */ - this.array = array; + return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); - /** - * The number of values of the array that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a position, - * normal, or color), then the value should be `3`. - * - * @type {number} - */ - this.itemSize = itemSize; + } - /** - * Represents the number of items this buffer attribute stores. It is internally computed - * by dividing the `array` length by the `itemSize`. - * - * @type {number} - * @readonly - */ - this.count = array !== undefined ? array.length / itemSize : 0; +} - /** - * Applies to integer data only. Indicates how the underlying data in the buffer maps to - * the values in the GLSL code. For instance, if `array` is an instance of `UInt16Array`, - * and `normalized` is `true`, the values `0 - +65535` in the array data will be mapped to - * `0.0f - +1.0f` in the GLSL attribute. If `normalized` is `false`, the values will be converted - * to floats unmodified, i.e. `65535` becomes `65535.0f`. - * - * @type {boolean} - */ - this.normalized = normalized; +/** + * Represents an axis-aligned bounding box (AABB) in 3D space. + */ +class Box3 { - /** - * Defines the intended usage pattern of the data store for optimization purposes. - * - * Note: After the initial use of a buffer, its usage cannot be changed. Instead, - * instantiate a new one and set the desired usage before the next render. - * - * @type {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} - * @default StaticDrawUsage - */ - this.usage = StaticDrawUsage; + /** + * Constructs a new bounding box. + * + * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box. + * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box. + */ + constructor( min = new Vector3( + Infinity, + Infinity, + Infinity ), max = new Vector3( - Infinity, - Infinity, - Infinity ) ) { /** - * This can be used to only update some components of stored vectors (for example, just the - * component related to color). Use the `addUpdateRange()` function to add ranges to this array. + * This flag can be used for type testing. * - * @type {Array} + * @type {boolean} + * @readonly + * @default true */ - this.updateRanges = []; + this.isBox3 = true; /** - * Configures the bound GPU type for use in shaders. - * - * Note: this only has an effect for integer arrays and is not configurable for float arrays. - * For lower precision float types, use `Float16BufferAttribute`. + * The lower boundary of the box. * - * @type {(FloatType|IntType)} - * @default FloatType + * @type {Vector3} */ - this.gpuType = FloatType; + this.min = min; /** - * A version number, incremented every time the `needsUpdate` is set to `true`. + * The upper boundary of the box. * - * @type {number} + * @type {Vector3} */ - this.version = 0; + this.max = max; } /** - * A callback function that is executed after the renderer has transferred the attribute - * array data to the GPU. + * Sets the lower and upper boundaries of this box. + * Please note that this method only copies the values from the given objects. + * + * @param {Vector3} min - The lower boundary of the box. + * @param {Vector3} max - The upper boundary of the box. + * @return {Box3} A reference to this bounding box. */ - onUploadCallback() {} + set( min, max ) { + + this.min.copy( min ); + this.max.copy( max ); + + return this; + + } /** - * Flag to indicate that this attribute has changed and should be re-sent to - * the GPU. Set this to `true` when you modify the value of the array. + * Sets the upper and lower bounds of this box so it encloses the position data + * in the given array. * - * @type {number} - * @default false - * @param {boolean} value + * @param {Array} array - An array holding 3D position data. + * @return {Box3} A reference to this bounding box. */ - set needsUpdate( value ) { + setFromArray( array ) { - if ( value === true ) this.version ++; + this.makeEmpty(); + + for ( let i = 0, il = array.length; i < il; i += 3 ) { + + this.expandByPoint( _vector$b.fromArray( array, i ) ); + + } + + return this; } /** - * Sets the usage of this buffer attribute. + * Sets the upper and lower bounds of this box so it encloses the position data + * in the given buffer attribute. * - * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. - * @return {BufferAttribute} A reference to this buffer attribute. + * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data. + * @return {Box3} A reference to this bounding box. */ - setUsage( value ) { + setFromBufferAttribute( attribute ) { - this.usage = value; + this.makeEmpty(); + + for ( let i = 0, il = attribute.count; i < il; i ++ ) { + + this.expandByPoint( _vector$b.fromBufferAttribute( attribute, i ) ); + + } return this; } /** - * Adds a range of data in the data array to be updated on the GPU. + * Sets the upper and lower bounds of this box so it encloses the position data + * in the given array. * - * @param {number} start - Position at which to start update. - * @param {number} count - The number of components to update. + * @param {Array} points - An array holding 3D position data as instances of {@link Vector3}. + * @return {Box3} A reference to this bounding box. */ - addUpdateRange( start, count ) { + setFromPoints( points ) { - this.updateRanges.push( { start, count } ); + this.makeEmpty(); + + for ( let i = 0, il = points.length; i < il; i ++ ) { + + this.expandByPoint( points[ i ] ); + + } + + return this; } /** - * Clears the update ranges. + * Centers this box on the given center vector and sets this box's width, height and + * depth to the given size values. + * + * @param {Vector3} center - The center of the box. + * @param {Vector3} size - The x, y and z dimensions of the box. + * @return {Box3} A reference to this bounding box. */ - clearUpdateRanges() { + setFromCenterAndSize( center, size ) { - this.updateRanges.length = 0; + const halfSize = _vector$b.copy( size ).multiplyScalar( 0.5 ); + + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); + + return this; } /** - * Copies the values of the given buffer attribute to this instance. + * Computes the world-axis-aligned bounding box for the given 3D object + * (including its children), accounting for the object's, and children's, + * world transforms. The function may result in a larger box than strictly necessary. * - * @param {BufferAttribute} source - The buffer attribute to copy. - * @return {BufferAttribute} A reference to this instance. + * @param {Object3D} object - The 3D object to compute the bounding box for. + * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest + * world-axis-aligned bounding box at the expense of more computation. + * @return {Box3} A reference to this bounding box. */ - copy( source ) { - - this.name = source.name; - this.array = new source.array.constructor( source.array ); - this.itemSize = source.itemSize; - this.count = source.count; - this.normalized = source.normalized; + setFromObject( object, precise = false ) { - this.usage = source.usage; - this.gpuType = source.gpuType; + this.makeEmpty(); - return this; + return this.expandByObject( object, precise ); } /** - * Copies a vector from the given buffer attribute to this one. The start - * and destination position in the attribute buffers are represented by the - * given indices. + * Returns a new box with copied values from this instance. * - * @param {number} index1 - The destination index into this buffer attribute. - * @param {BufferAttribute} attribute - The buffer attribute to copy from. - * @param {number} index2 - The source index into the given buffer attribute. - * @return {BufferAttribute} A reference to this instance. + * @return {Box3} A clone of this instance. */ - copyAt( index1, attribute, index2 ) { + clone() { - index1 *= this.itemSize; - index2 *= attribute.itemSize; + return new this.constructor().copy( this ); - for ( let i = 0, l = this.itemSize; i < l; i ++ ) { + } - this.array[ index1 + i ] = attribute.array[ index2 + i ]; + /** + * Copies the values of the given box to this instance. + * + * @param {Box3} box - The box to copy. + * @return {Box3} A reference to this bounding box. + */ + copy( box ) { - } + this.min.copy( box.min ); + this.max.copy( box.max ); return this; } /** - * Copies the given array data into this buffer attribute. + * Makes this box empty which means in encloses a zero space in 3D. * - * @param {(TypedArray|Array)} array - The array to copy. - * @return {BufferAttribute} A reference to this instance. + * @return {Box3} A reference to this bounding box. */ - copyArray( array ) { + makeEmpty() { - this.array.set( array ); + this.min.x = this.min.y = this.min.z = + Infinity; + this.max.x = this.max.y = this.max.z = - Infinity; return this; } /** - * Applies the given 3x3 matrix to the given attribute. Works with - * item size `2` and `3`. + * Returns true if this box includes zero points within its bounds. + * Note that a box with equal lower and upper bounds still includes one + * point, the one both bounds share. * - * @param {Matrix3} m - The matrix to apply. - * @return {BufferAttribute} A reference to this instance. + * @return {boolean} Whether this box is empty or not. */ - applyMatrix3( m ) { + isEmpty() { - if ( this.itemSize === 2 ) { + // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes - for ( let i = 0, l = this.count; i < l; i ++ ) { + return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); - _vector2$1.fromBufferAttribute( this, i ); - _vector2$1.applyMatrix3( m ); + } - this.setXY( i, _vector2$1.x, _vector2$1.y ); + /** + * Returns the center point of this box. + * + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The center point. + */ + getCenter( target ) { - } + return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); - } else if ( this.itemSize === 3 ) { + } - for ( let i = 0, l = this.count; i < l; i ++ ) { + /** + * Returns the dimensions of this box. + * + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The size. + */ + getSize( target ) { - _vector$9.fromBufferAttribute( this, i ); - _vector$9.applyMatrix3( m ); + return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); - this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); + } - } + /** + * Expands the boundaries of this box to include the given point. + * + * @param {Vector3} point - The point that should be included by the bounding box. + * @return {Box3} A reference to this bounding box. + */ + expandByPoint( point ) { - } + this.min.min( point ); + this.max.max( point ); return this; } /** - * Applies the given 4x4 matrix to the given attribute. Only works with - * item size `3`. + * Expands this box equilaterally by the given vector. The width of this + * box will be expanded by the x component of the vector in both + * directions. The height of this box will be expanded by the y component of + * the vector in both directions. The depth of this box will be + * expanded by the z component of the vector in both directions. * - * @param {Matrix4} m - The matrix to apply. - * @return {BufferAttribute} A reference to this instance. + * @param {Vector3} vector - The vector that should expand the bounding box. + * @return {Box3} A reference to this bounding box. */ - applyMatrix4( m ) { + expandByVector( vector ) { - for ( let i = 0, l = this.count; i < l; i ++ ) { + this.min.sub( vector ); + this.max.add( vector ); - _vector$9.fromBufferAttribute( this, i ); + return this; - _vector$9.applyMatrix4( m ); + } - this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); + /** + * Expands each dimension of the box by the given scalar. If negative, the + * dimensions of the box will be contracted. + * + * @param {number} scalar - The scalar value that should expand the bounding box. + * @return {Box3} A reference to this bounding box. + */ + expandByScalar( scalar ) { - } + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); return this; } /** - * Applies the given 3x3 normal matrix to the given attribute. Only works with - * item size `3`. + * Expands the boundaries of this box to include the given 3D object and + * its children, accounting for the object's, and children's, world + * transforms. The function may result in a larger box than strictly + * necessary (unless the precise parameter is set to true). * - * @param {Matrix3} m - The normal matrix to apply. - * @return {BufferAttribute} A reference to this instance. + * @param {Object3D} object - The 3D object that should expand the bounding box. + * @param {boolean} precise - If set to `true`, the method expands the bounding box + * as little as necessary at the expense of more computation. + * @return {Box3} A reference to this bounding box. */ - applyNormalMatrix( m ) { + expandByObject( object, precise = false ) { - for ( let i = 0, l = this.count; i < l; i ++ ) { + // Computes the world-axis-aligned bounding box of an object (including its children), + // accounting for both the object's, and children's, world transforms - _vector$9.fromBufferAttribute( this, i ); + object.updateWorldMatrix( false, false ); - _vector$9.applyNormalMatrix( m ); + const geometry = object.geometry; - this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); + if ( geometry !== undefined ) { - } + const positionAttribute = geometry.getAttribute( 'position' ); - return this; + // precise AABB computation based on vertex data requires at least a position attribute. + // instancing isn't supported so far and uses the normal (conservative) code path. - } + if ( precise === true && positionAttribute !== undefined && object.isInstancedMesh !== true ) { - /** - * Applies the given 4x4 matrix to the given attribute. Only works with - * item size `3` and with direction vectors. - * - * @param {Matrix4} m - The matrix to apply. - * @return {BufferAttribute} A reference to this instance. - */ - transformDirection( m ) { + for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) { - for ( let i = 0, l = this.count; i < l; i ++ ) { + if ( object.isMesh === true ) { - _vector$9.fromBufferAttribute( this, i ); + object.getVertexPosition( i, _vector$b ); - _vector$9.transformDirection( m ); + } else { - this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); + _vector$b.fromBufferAttribute( positionAttribute, i ); - } + } - return this; + _vector$b.applyMatrix4( object.matrixWorld ); + this.expandByPoint( _vector$b ); - } + } - /** - * Sets the given array data in the buffer attribute. - * - * @param {(TypedArray|Array)} value - The array data to set. - * @param {number} [offset=0] - The offset in this buffer attribute's array. - * @return {BufferAttribute} A reference to this instance. - */ - set( value, offset = 0 ) { + } else { - // Matching BufferAttribute constructor, do not normalize the array. - this.array.set( value, offset ); + if ( object.boundingBox !== undefined ) { - return this; + // object-level bounding box - } + if ( object.boundingBox === null ) { - /** - * Returns the given component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} component - The component index. - * @return {number} The returned value. - */ - getComponent( index, component ) { + object.computeBoundingBox(); - let value = this.array[ index * this.itemSize + component ]; + } - if ( this.normalized ) value = denormalize( value, this.array ); + _box$4.copy( object.boundingBox ); - return value; - } + } else { - /** - * Sets the given value to the given component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} component - The component index. - * @param {number} value - The value to set. - * @return {BufferAttribute} A reference to this instance. - */ - setComponent( index, component, value ) { + // geometry-level bounding box - if ( this.normalized ) value = normalize( value, this.array ); + if ( geometry.boundingBox === null ) { - this.array[ index * this.itemSize + component ] = value; + geometry.computeBoundingBox(); - return this; + } - } + _box$4.copy( geometry.boundingBox ); - /** - * Returns the x component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @return {number} The x component. - */ - getX( index ) { + } - let x = this.array[ index * this.itemSize ]; + _box$4.applyMatrix4( object.matrixWorld ); - if ( this.normalized ) x = denormalize( x, this.array ); + this.union( _box$4 ); - return x; + } - } + } - /** - * Sets the x component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value to set. - * @return {BufferAttribute} A reference to this instance. - */ - setX( index, x ) { + const children = object.children; - if ( this.normalized ) x = normalize( x, this.array ); + for ( let i = 0, l = children.length; i < l; i ++ ) { - this.array[ index * this.itemSize ] = x; + this.expandByObject( children[ i ], precise ); + + } return this; } /** - * Returns the y component of the vector at the given index. + * Returns `true` if the given point lies within or on the boundaries of this box. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The y component. + * @param {Vector3} point - The point to test. + * @return {boolean} Whether the bounding box contains the given point or not. */ - getY( index ) { - - let y = this.array[ index * this.itemSize + 1 ]; - - if ( this.normalized ) y = denormalize( y, this.array ); + containsPoint( point ) { - return y; + return point.x >= this.min.x && point.x <= this.max.x && + point.y >= this.min.y && point.y <= this.max.y && + point.z >= this.min.z && point.z <= this.max.z; } /** - * Sets the y component of the vector at the given index. + * Returns `true` if this bounding box includes the entirety of the given bounding box. + * If this box and the given one are identical, this function also returns `true`. * - * @param {number} index - The index into the buffer attribute. - * @param {number} y - The value to set. - * @return {BufferAttribute} A reference to this instance. + * @param {Box3} box - The bounding box to test. + * @return {boolean} Whether the bounding box contains the given bounding box or not. */ - setY( index, y ) { - - if ( this.normalized ) y = normalize( y, this.array ); - - this.array[ index * this.itemSize + 1 ] = y; + containsBox( box ) { - return this; + return this.min.x <= box.min.x && box.max.x <= this.max.x && + this.min.y <= box.min.y && box.max.y <= this.max.y && + this.min.z <= box.min.z && box.max.z <= this.max.z; } /** - * Returns the z component of the vector at the given index. + * Returns a point as a proportion of this box's width, height and depth. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The z component. + * @param {Vector3} point - A point in 3D space. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} A point as a proportion of this box's width, height and depth. */ - getZ( index ) { - - let z = this.array[ index * this.itemSize + 2 ]; + getParameter( point, target ) { - if ( this.normalized ) z = denormalize( z, this.array ); + // This can potentially have a divide by zero if the box + // has a size dimension of 0. - return z; + return target.set( + ( point.x - this.min.x ) / ( this.max.x - this.min.x ), + ( point.y - this.min.y ) / ( this.max.y - this.min.y ), + ( point.z - this.min.z ) / ( this.max.z - this.min.z ) + ); } /** - * Sets the z component of the vector at the given index. + * Returns `true` if the given bounding box intersects with this bounding box. * - * @param {number} index - The index into the buffer attribute. - * @param {number} z - The value to set. - * @return {BufferAttribute} A reference to this instance. - */ - setZ( index, z ) { - - if ( this.normalized ) z = normalize( z, this.array ); - - this.array[ index * this.itemSize + 2 ] = z; + * @param {Box3} box - The bounding box to test. + * @return {boolean} Whether the given bounding box intersects with this bounding box. + */ + intersectsBox( box ) { - return this; + // using 6 splitting planes to rule out intersections. + return box.max.x >= this.min.x && box.min.x <= this.max.x && + box.max.y >= this.min.y && box.min.y <= this.max.y && + box.max.z >= this.min.z && box.min.z <= this.max.z; } /** - * Returns the w component of the vector at the given index. + * Returns `true` if the given bounding sphere intersects with this bounding box. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The w component. + * @param {Sphere} sphere - The bounding sphere to test. + * @return {boolean} Whether the given bounding sphere intersects with this bounding box. */ - getW( index ) { - - let w = this.array[ index * this.itemSize + 3 ]; + intersectsSphere( sphere ) { - if ( this.normalized ) w = denormalize( w, this.array ); + // Find the point on the AABB closest to the sphere center. + this.clampPoint( sphere.center, _vector$b ); - return w; + // If that point is inside the sphere, the AABB and sphere intersect. + return _vector$b.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); } /** - * Sets the w component of the vector at the given index. + * Returns `true` if the given plane intersects with this bounding box. * - * @param {number} index - The index into the buffer attribute. - * @param {number} w - The value to set. - * @return {BufferAttribute} A reference to this instance. + * @param {Plane} plane - The plane to test. + * @return {boolean} Whether the given plane intersects with this bounding box. */ - setW( index, w ) { + intersectsPlane( plane ) { - if ( this.normalized ) w = normalize( w, this.array ); + // We compute the minimum and maximum dot product values. If those values + // are on the same side (back or front) of the plane, then there is no intersection. - this.array[ index * this.itemSize + 3 ] = w; + let min, max; - return this; + if ( plane.normal.x > 0 ) { - } + min = plane.normal.x * this.min.x; + max = plane.normal.x * this.max.x; - /** - * Sets the x and y component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @return {BufferAttribute} A reference to this instance. - */ - setXY( index, x, y ) { + } else { - index *= this.itemSize; + min = plane.normal.x * this.max.x; + max = plane.normal.x * this.min.x; - if ( this.normalized ) { + } - x = normalize( x, this.array ); - y = normalize( y, this.array ); + if ( plane.normal.y > 0 ) { + + min += plane.normal.y * this.min.y; + max += plane.normal.y * this.max.y; + + } else { + + min += plane.normal.y * this.max.y; + max += plane.normal.y * this.min.y; } - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; + if ( plane.normal.z > 0 ) { - return this; + min += plane.normal.z * this.min.z; + max += plane.normal.z * this.max.z; + + } else { + + min += plane.normal.z * this.max.z; + max += plane.normal.z * this.min.z; + + } + + return ( min <= - plane.constant && max >= - plane.constant ); } /** - * Sets the x, y and z component of the vector at the given index. + * Returns `true` if the given triangle intersects with this bounding box. * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @param {number} z - The value for the z component to set. - * @return {BufferAttribute} A reference to this instance. + * @param {Triangle} triangle - The triangle to test. + * @return {boolean} Whether the given triangle intersects with this bounding box. */ - setXYZ( index, x, y, z ) { - - index *= this.itemSize; + intersectsTriangle( triangle ) { - if ( this.normalized ) { + if ( this.isEmpty() ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); + return false; } - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; + // compute box center and extents + this.getCenter( _center ); + _extents.subVectors( this.max, _center ); - return this; + // translate triangle to aabb origin + _v0$2.subVectors( triangle.a, _center ); + _v1$4.subVectors( triangle.b, _center ); + _v2$3.subVectors( triangle.c, _center ); - } + // compute edge vectors for triangle + _f0.subVectors( _v1$4, _v0$2 ); + _f1.subVectors( _v2$3, _v1$4 ); + _f2.subVectors( _v0$2, _v2$3 ); - /** - * Sets the x, y, z and w component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @param {number} z - The value for the z component to set. - * @param {number} w - The value for the w component to set. - * @return {BufferAttribute} A reference to this instance. - */ - setXYZW( index, x, y, z, w ) { + // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb + // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation + // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) + let axes = [ + 0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y, + _f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x, + - _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0 + ]; + if ( ! satForAxes( axes, _v0$2, _v1$4, _v2$3, _extents ) ) { - index *= this.itemSize; + return false; - if ( this.normalized ) { + } - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - w = normalize( w, this.array ); + // test 3 face normals from the aabb + axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; + if ( ! satForAxes( axes, _v0$2, _v1$4, _v2$3, _extents ) ) { + + return false; } - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; - this.array[ index + 3 ] = w; + // finally testing the face normal of the triangle + // use already existing triangle edge vectors here + _triangleNormal.crossVectors( _f0, _f1 ); + axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ]; - return this; + return satForAxes( axes, _v0$2, _v1$4, _v2$3, _extents ); } /** - * Sets the given callback function that is executed after the Renderer has transferred - * the attribute array data to the GPU. Can be used to perform clean-up operations after - * the upload when attribute data are not needed anymore on the CPU side. + * Clamps the given point within the bounds of this box. * - * @param {Function} callback - The `onUpload()` callback. - * @return {BufferAttribute} A reference to this instance. + * @param {Vector3} point - The point to clamp. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The clamped point. */ - onUpload( callback ) { - - this.onUploadCallback = callback; + clampPoint( point, target ) { - return this; + return target.copy( point ).clamp( this.min, this.max ); } /** - * Returns a new buffer attribute with copied values from this instance. + * Returns the euclidean distance from any edge of this box to the specified point. If + * the given point lies inside of this box, the distance will be `0`. * - * @return {BufferAttribute} A clone of this instance. + * @param {Vector3} point - The point to compute the distance to. + * @return {number} The euclidean distance. */ - clone() { + distanceToPoint( point ) { - return new this.constructor( this.array, this.itemSize ).copy( this ); + return this.clampPoint( point, _vector$b ).distanceTo( point ); } /** - * Serializes the buffer attribute into JSON. + * Returns a bounding sphere that encloses this bounding box. * - * @return {Object} A JSON object representing the serialized buffer attribute. + * @param {Sphere} target - The target sphere that is used to store the method's result. + * @return {Sphere} The bounding sphere that encloses this bounding box. */ - toJSON() { + getBoundingSphere( target ) { - const data = { - itemSize: this.itemSize, - type: this.array.constructor.name, - array: Array.from( this.array ), - normalized: this.normalized - }; + if ( this.isEmpty() ) { - if ( this.name !== '' ) data.name = this.name; - if ( this.usage !== StaticDrawUsage ) data.usage = this.usage; + target.makeEmpty(); - return data; + } else { - } + this.getCenter( target.center ); -} + target.radius = this.getSize( _vector$b ).length() * 0.5; -/** - * Convenient class that can be used when creating a `Int8` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Int8BufferAttribute extends BufferAttribute { + } + + return target; + + } /** - * Constructs a new buffer attribute. + * Computes the intersection of this bounding box and the given one, setting the upper + * bound of this box to the lesser of the two boxes' upper bounds and the + * lower bound of this box to the greater of the two boxes' lower bounds. If + * there's no overlap, makes this box empty. * - * @param {(Array|Int8Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {Box3} box - The bounding box to intersect with. + * @return {Box3} A reference to this bounding box. */ - constructor( array, itemSize, normalized ) { + intersect( box ) { - super( new Int8Array( array ), itemSize, normalized ); + this.min.max( box.min ); + this.max.min( box.max ); - } + // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. + if ( this.isEmpty() ) this.makeEmpty(); -} + return this; -/** - * Convenient class that can be used when creating a `UInt8` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Uint8BufferAttribute extends BufferAttribute { + } /** - * Constructs a new buffer attribute. + * Computes the union of this box and another and the given one, setting the upper + * bound of this box to the greater of the two boxes' upper bounds and the + * lower bound of this box to the lesser of the two boxes' lower bounds. * - * @param {(Array|Uint8Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {Box3} box - The bounding box that will be unioned with this instance. + * @return {Box3} A reference to this bounding box. */ - constructor( array, itemSize, normalized ) { - - super( new Uint8Array( array ), itemSize, normalized ); + union( box ) { - } + this.min.min( box.min ); + this.max.max( box.max ); -} + return this; -/** - * Convenient class that can be used when creating a `UInt8Clamped` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Uint8ClampedBufferAttribute extends BufferAttribute { + } /** - * Constructs a new buffer attribute. + * Transforms this bounding box by the given 4x4 transformation matrix. * - * @param {(Array|Uint8ClampedArray)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {Matrix4} matrix - The transformation matrix. + * @return {Box3} A reference to this bounding box. */ - constructor( array, itemSize, normalized ) { + applyMatrix4( matrix ) { - super( new Uint8ClampedArray( array ), itemSize, normalized ); + // transform of empty box is an empty box. + if ( this.isEmpty() ) return this; - } + // NOTE: I am using a binary pattern to specify all 2^3 combinations below + _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 + _points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 + _points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 + _points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 + _points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 + _points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 + _points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 + _points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 -} + this.setFromPoints( _points ); -/** - * Convenient class that can be used when creating a `Int16` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Int16BufferAttribute extends BufferAttribute { + return this; + + } /** - * Constructs a new buffer attribute. + * Adds the given offset to both the upper and lower bounds of this bounding box, + * effectively moving it in 3D space. * - * @param {(Array|Int16Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {Vector3} offset - The offset that should be used to translate the bounding box. + * @return {Box3} A reference to this bounding box. */ - constructor( array, itemSize, normalized ) { - - super( new Int16Array( array ), itemSize, normalized ); + translate( offset ) { - } + this.min.add( offset ); + this.max.add( offset ); -} + return this; -/** - * Convenient class that can be used when creating a `UInt16` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Uint16BufferAttribute extends BufferAttribute { + } /** - * Constructs a new buffer attribute. + * Returns `true` if this bounding box is equal with the given one. * - * @param {(Array|Uint16Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {Box3} box - The box to test for equality. + * @return {boolean} Whether this bounding box is equal with the given one. */ - constructor( array, itemSize, normalized ) { + equals( box ) { - super( new Uint16Array( array ), itemSize, normalized ); + return box.min.equals( this.min ) && box.max.equals( this.max ); } -} - -/** - * Convenient class that can be used when creating a `Int32` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Int32BufferAttribute extends BufferAttribute { - /** - * Constructs a new buffer attribute. + * Returns a serialized structure of the bounding box. * - * @param {(Array|Int32Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @return {Object} Serialized structure with fields representing the object state. */ - constructor( array, itemSize, normalized ) { + toJSON() { - super( new Int32Array( array ), itemSize, normalized ); + return { + min: this.min.toArray(), + max: this.max.toArray() + }; } -} - -/** - * Convenient class that can be used when creating a `UInt32` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Uint32BufferAttribute extends BufferAttribute { - /** - * Constructs a new buffer attribute. + * Returns a serialized structure of the bounding box. * - * @param {(Array|Uint32Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {Object} json - The serialized json to set the box from. + * @return {Box3} A reference to this bounding box. */ - constructor( array, itemSize, normalized ) { + fromJSON( json ) { - super( new Uint32Array( array ), itemSize, normalized ); + this.min.fromArray( json.min ); + this.max.fromArray( json.max ); + return this; } } -/** - * Convenient class that can be used when creating a `Float16` buffer attribute with - * a plain `Array` instance. - * - * This class automatically converts to and from FP16 via `Uint16Array` since `Float16Array` - * browser support is still problematic. - * - * @augments BufferAttribute - */ -class Float16BufferAttribute extends BufferAttribute { +const _points = [ + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3() +]; - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Uint16Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { +const _vector$b = /*@__PURE__*/ new Vector3(); - super( new Uint16Array( array ), itemSize, normalized ); +const _box$4 = /*@__PURE__*/ new Box3(); - this.isFloat16BufferAttribute = true; +// triangle centered vertices - } +const _v0$2 = /*@__PURE__*/ new Vector3(); +const _v1$4 = /*@__PURE__*/ new Vector3(); +const _v2$3 = /*@__PURE__*/ new Vector3(); - getX( index ) { +// triangle edge vectors - let x = fromHalfFloat( this.array[ index * this.itemSize ] ); +const _f0 = /*@__PURE__*/ new Vector3(); +const _f1 = /*@__PURE__*/ new Vector3(); +const _f2 = /*@__PURE__*/ new Vector3(); - if ( this.normalized ) x = denormalize( x, this.array ); +const _center = /*@__PURE__*/ new Vector3(); +const _extents = /*@__PURE__*/ new Vector3(); +const _triangleNormal = /*@__PURE__*/ new Vector3(); +const _testAxis = /*@__PURE__*/ new Vector3(); - return x; +function satForAxes( axes, v0, v1, v2, extents ) { + + for ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) { + + _testAxis.fromArray( axes, i ); + // project the aabb onto the separating axis + const r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z ); + // project all 3 vertices of the triangle onto the separating axis + const p0 = v0.dot( _testAxis ); + const p1 = v1.dot( _testAxis ); + const p2 = v2.dot( _testAxis ); + // actual test, basically see if either of the most extreme of the triangle points intersects r + if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { + + // points of the projected triangle are outside the projected half-length of the aabb + // the axis is separating and we can exit + return false; + + } } - setX( index, x ) { + return true; - if ( this.normalized ) x = normalize( x, this.array ); +} - this.array[ index * this.itemSize ] = toHalfFloat( x ); +// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf - return this; +const _tables = /*@__PURE__*/ _generateTables(); - } +function _generateTables() { - getY( index ) { + // float32 to float16 helpers - let y = fromHalfFloat( this.array[ index * this.itemSize + 1 ] ); + const buffer = new ArrayBuffer( 4 ); + const floatView = new Float32Array( buffer ); + const uint32View = new Uint32Array( buffer ); - if ( this.normalized ) y = denormalize( y, this.array ); + const baseTable = new Uint32Array( 512 ); + const shiftTable = new Uint32Array( 512 ); - return y; + for ( let i = 0; i < 256; ++ i ) { - } + const e = i - 127; - setY( index, y ) { + // very small number (0, -0) - if ( this.normalized ) y = normalize( y, this.array ); + if ( e < -27 ) { - this.array[ index * this.itemSize + 1 ] = toHalfFloat( y ); + baseTable[ i ] = 0x0000; + baseTable[ i | 0x100 ] = 0x8000; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; - return this; + // small number (denorm) - } + } else if ( e < -14 ) { - getZ( index ) { + baseTable[ i ] = 0x0400 >> ( - e - 14 ); + baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000; + shiftTable[ i ] = - e - 1; + shiftTable[ i | 0x100 ] = - e - 1; - let z = fromHalfFloat( this.array[ index * this.itemSize + 2 ] ); + // normal number + + } else if ( e <= 15 ) { + + baseTable[ i ] = ( e + 15 ) << 10; + baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000; + shiftTable[ i ] = 13; + shiftTable[ i | 0x100 ] = 13; + + // large number (Infinity, -Infinity) + + } else if ( e < 128 ) { + + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; + + // stay (NaN, Infinity, -Infinity) + + } else { - if ( this.normalized ) z = denormalize( z, this.array ); + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 13; + shiftTable[ i | 0x100 ] = 13; - return z; + } } - setZ( index, z ) { + // float16 to float32 helpers - if ( this.normalized ) z = normalize( z, this.array ); + const mantissaTable = new Uint32Array( 2048 ); + const exponentTable = new Uint32Array( 64 ); + const offsetTable = new Uint32Array( 64 ); - this.array[ index * this.itemSize + 2 ] = toHalfFloat( z ); + for ( let i = 1; i < 1024; ++ i ) { - return this; + let m = i << 13; // zero pad mantissa bits + let e = 0; // zero exponent - } + // normalized + while ( ( m & 0x00800000 ) === 0 ) { - getW( index ) { + m <<= 1; + e -= 0x00800000; // decrement exponent - let w = fromHalfFloat( this.array[ index * this.itemSize + 3 ] ); + } - if ( this.normalized ) w = denormalize( w, this.array ); + m &= -8388609; // clear leading 1 bit + e += 0x38800000; // adjust bias - return w; + mantissaTable[ i ] = m | e; } - setW( index, w ) { - - if ( this.normalized ) w = normalize( w, this.array ); - - this.array[ index * this.itemSize + 3 ] = toHalfFloat( w ); + for ( let i = 1024; i < 2048; ++ i ) { - return this; + mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 ); } - setXY( index, x, y ) { - - index *= this.itemSize; + for ( let i = 1; i < 31; ++ i ) { - if ( this.normalized ) { + exponentTable[ i ] = i << 23; - x = normalize( x, this.array ); - y = normalize( y, this.array ); + } - } + exponentTable[ 31 ] = 0x47800000; + exponentTable[ 32 ] = 0x80000000; - this.array[ index + 0 ] = toHalfFloat( x ); - this.array[ index + 1 ] = toHalfFloat( y ); + for ( let i = 33; i < 63; ++ i ) { - return this; + exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 ); } - setXYZ( index, x, y, z ) { + exponentTable[ 63 ] = 0xc7800000; - index *= this.itemSize; + for ( let i = 1; i < 64; ++ i ) { - if ( this.normalized ) { + if ( i !== 32 ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); + offsetTable[ i ] = 1024; } - this.array[ index + 0 ] = toHalfFloat( x ); - this.array[ index + 1 ] = toHalfFloat( y ); - this.array[ index + 2 ] = toHalfFloat( z ); - - return this; - } - setXYZW( index, x, y, z, w ) { + return { + floatView: floatView, + uint32View: uint32View, + baseTable: baseTable, + shiftTable: shiftTable, + mantissaTable: mantissaTable, + exponentTable: exponentTable, + offsetTable: offsetTable + }; - index *= this.itemSize; +} - if ( this.normalized ) { +/** + * Returns a half precision floating point value (FP16) from the given single + * precision floating point value (FP32). + * + * @param {number} val - A single precision floating point value. + * @return {number} The FP16 value. + */ +function toHalfFloat( val ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - w = normalize( w, this.array ); + if ( Math.abs( val ) > 65504 ) warn( 'DataUtils.toHalfFloat(): Value out of range.' ); - } + val = clamp( val, -65504, 65504 ); - this.array[ index + 0 ] = toHalfFloat( x ); - this.array[ index + 1 ] = toHalfFloat( y ); - this.array[ index + 2 ] = toHalfFloat( z ); - this.array[ index + 3 ] = toHalfFloat( w ); + _tables.floatView[ 0 ] = val; + const f = _tables.uint32View[ 0 ]; + const e = ( f >> 23 ) & 0x1ff; + return _tables.baseTable[ e ] + ( ( f & 0x007fffff ) >> _tables.shiftTable[ e ] ); - return this; +} - } +/** + * Returns a single precision floating point value (FP32) from the given half + * precision floating point value (FP16). + * + * @param {number} val - A half precision floating point value. + * @return {number} The FP32 value. + */ +function fromHalfFloat( val ) { + + const m = val >> 10; + _tables.uint32View[ 0 ] = _tables.mantissaTable[ _tables.offsetTable[ m ] + ( val & 0x3ff ) ] + _tables.exponentTable[ m ]; + return _tables.floatView[ 0 ]; } /** - * Convenient class that can be used when creating a `Float32` buffer attribute with - * a plain `Array` instance. + * A class containing utility functions for data. * - * @augments BufferAttribute + * @hideconstructor */ -class Float32BufferAttribute extends BufferAttribute { +class DataUtils { /** - * Constructs a new buffer attribute. + * Returns a half precision floating point value (FP16) from the given single + * precision floating point value (FP32). * - * @param {(Array|Float32Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {number} val - A single precision floating point value. + * @return {number} The FP16 value. */ - constructor( array, itemSize, normalized ) { + static toHalfFloat( val ) { - super( new Float32Array( array ), itemSize, normalized ); + return toHalfFloat( val ); + + } + + /** + * Returns a single precision floating point value (FP32) from the given half + * precision floating point value (FP16). + * + * @param {number} val - A half precision floating point value. + * @return {number} The FP32 value. + */ + static fromHalfFloat( val ) { + + return fromHalfFloat( val ); } } -let _id$2 = 0; +const _vector$a = /*@__PURE__*/ new Vector3(); +const _vector2$1 = /*@__PURE__*/ new Vector2(); -const _m1$2 = /*@__PURE__*/ new Matrix4(); -const _obj = /*@__PURE__*/ new Object3D(); -const _offset = /*@__PURE__*/ new Vector3(); -const _box$2 = /*@__PURE__*/ new Box3(); -const _boxMorphTargets = /*@__PURE__*/ new Box3(); -const _vector$8 = /*@__PURE__*/ new Vector3(); +let _id$3 = 0; /** - * A representation of mesh, line, or point geometry. Includes vertex - * positions, face indices, normals, colors, UVs, and custom attributes - * within buffers, reducing the cost of passing all this data to the GPU. - * - * ```js - * const geometry = new THREE.BufferGeometry(); - * // create a simple square shape. We duplicate the top left and bottom right - * // vertices because each vertex needs to appear once per triangle. - * const vertices = new Float32Array( [ - * -1.0, -1.0, 1.0, // v0 - * 1.0, -1.0, 1.0, // v1 - * 1.0, 1.0, 1.0, // v2 - * - * 1.0, 1.0, 1.0, // v3 - * -1.0, 1.0, 1.0, // v4 - * -1.0, -1.0, 1.0 // v5 - * ] ); - * // itemSize = 3 because there are 3 values (components) per vertex - * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); - * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); - * const mesh = new THREE.Mesh( geometry, material ); - * ``` + * This class stores data for an attribute (such as vertex positions, face + * indices, normals, colors, UVs, and any custom attributes ) associated with + * a geometry, which allows for more efficient passing of data to the GPU. * - * @augments EventDispatcher + * When working with vector-like data, the `fromBufferAttribute( attribute, index )` + * helper methods on vector and color class might be helpful. E.g. {@link Vector3#fromBufferAttribute}. */ -class BufferGeometry extends EventDispatcher { +class BufferAttribute { /** - * Constructs a new geometry. + * Constructs a new buffer attribute. + * + * @param {TypedArray} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - constructor() { + constructor( array, itemSize, normalized = false ) { - super(); + if ( Array.isArray( array ) ) { + + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + + } /** * This flag can be used for type testing. @@ -19142,1549 +16584,2204 @@ class BufferGeometry extends EventDispatcher { * @readonly * @default true */ - this.isBufferGeometry = true; + this.isBufferAttribute = true; /** - * The ID of the geometry. + * The ID of the buffer attribute. * - * @name BufferGeometry#id + * @name BufferAttribute#id * @type {number} * @readonly */ - Object.defineProperty( this, 'id', { value: _id$2 ++ } ); - - /** - * The UUID of the geometry. - * - * @type {string} - * @readonly - */ - this.uuid = generateUUID(); + Object.defineProperty( this, 'id', { value: _id$3 ++ } ); /** - * The name of the geometry. + * The name of the buffer attribute. * * @type {string} */ this.name = ''; - this.type = 'BufferGeometry'; /** - * Allows for vertices to be re-used across multiple triangles; this is - * called using "indexed triangles". Each triangle is associated with the - * indices of three vertices. This attribute therefore stores the index of - * each vertex for each triangular face. If this attribute is not set, the - * renderer assumes that each three contiguous positions represent a single triangle. + * The array holding the attribute data. It should have `itemSize * numVertices` + * elements, where `numVertices` is the number of vertices in the associated geometry. * - * @type {?BufferAttribute} - * @default null + * @type {TypedArray} */ - this.index = null; + this.array = array; /** - * A (storage) buffer attribute which was generated with a compute shader and - * now defines indirect draw calls. - * - * Can only be used with {@link WebGPURenderer} and a WebGPU backend. + * The number of values of the array that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a position, + * normal, or color), then the value should be `3`. * - * @type {?BufferAttribute} - * @default null + * @type {number} */ - this.indirect = null; + this.itemSize = itemSize; /** - * The offset, in bytes, into the indirect drawing buffer where the value data begins. If an array is provided, multiple indirect draw calls will be made for each offset. - * - * Can only be used with {@link WebGPURenderer} and a WebGPU backend. + * Represents the number of items this buffer attribute stores. It is internally computed + * by dividing the `array` length by the `itemSize`. * - * @type {number|Array} - * @default 0 + * @type {number} + * @readonly */ - this.indirectOffset = 0; + this.count = array !== undefined ? array.length / itemSize : 0; /** - * This dictionary has as id the name of the attribute to be set and as value - * the buffer attribute to set it to. Rather than accessing this property directly, - * use `setAttribute()` and `getAttribute()` to access attributes of this geometry. + * Applies to integer data only. Indicates how the underlying data in the buffer maps to + * the values in the GLSL code. For instance, if `array` is an instance of `UInt16Array`, + * and `normalized` is `true`, the values `0 - +65535` in the array data will be mapped to + * `0.0f - +1.0f` in the GLSL attribute. If `normalized` is `false`, the values will be converted + * to floats unmodified, i.e. `65535` becomes `65535.0f`. * - * @type {Object} + * @type {boolean} */ - this.attributes = {}; + this.normalized = normalized; /** - * This dictionary holds the morph targets of the geometry. + * Defines the intended usage pattern of the data store for optimization purposes. * - * Note: Once the geometry has been rendered, the morph attribute data cannot - * be changed. You will have to call `dispose()`, and create a new geometry instance. + * Note: After the initial use of a buffer, its usage cannot be changed. Instead, + * instantiate a new one and set the desired usage before the next render. * - * @type {Object} + * @type {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} + * @default StaticDrawUsage */ - this.morphAttributes = {}; + this.usage = StaticDrawUsage; /** - * Used to control the morph target behavior; when set to `true`, the morph - * target data is treated as relative offsets, rather than as absolute - * positions/normals. + * This can be used to only update some components of stored vectors (for example, just the + * component related to color). Use the `addUpdateRange()` function to add ranges to this array. * - * @type {boolean} - * @default false + * @type {Array} */ - this.morphTargetsRelative = false; + this.updateRanges = []; /** - * Split the geometry into groups, each of which will be rendered in a - * separate draw call. This allows an array of materials to be used with the geometry. - * - * Use `addGroup()` and `clearGroups()` to edit groups, rather than modifying this array directly. + * Configures the bound GPU type for use in shaders. * - * Every vertex and index must belong to exactly one group — groups must not share vertices or - * indices, and must not leave vertices or indices unused. + * Note: this only has an effect for integer arrays and is not configurable for float arrays. + * For lower precision float types, use `Float16BufferAttribute`. * - * @type {Array} + * @type {(FloatType|IntType)} + * @default FloatType */ - this.groups = []; + this.gpuType = FloatType; /** - * Bounding box for the geometry which can be calculated with `computeBoundingBox()`. + * A version number, incremented every time the `needsUpdate` is set to `true`. * - * @type {?Box3} - * @default null + * @type {number} */ - this.boundingBox = null; + this.version = 0; - /** - * Bounding sphere for the geometry which can be calculated with `computeBoundingSphere()`. - * - * @type {?Sphere} - * @default null - */ - this.boundingSphere = null; + } - /** - * Determines the part of the geometry to render. This should not be set directly, - * instead use `setDrawRange()`. - * - * @type {{start:number,count:number}} - */ - this.drawRange = { start: 0, count: Infinity }; + /** + * A callback function that is executed after the renderer has transferred the attribute + * array data to the GPU. + */ + onUploadCallback() {} + + /** + * Flag to indicate that this attribute has changed and should be re-sent to + * the GPU. Set this to `true` when you modify the value of the array. + * + * @type {number} + * @default false + * @param {boolean} value + */ + set needsUpdate( value ) { + + if ( value === true ) this.version ++; + + } + + /** + * Sets the usage of this buffer attribute. + * + * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. + * @return {BufferAttribute} A reference to this buffer attribute. + */ + setUsage( value ) { + + this.usage = value; + + return this; + + } + + /** + * Adds a range of data in the data array to be updated on the GPU. + * + * @param {number} start - Position at which to start update. + * @param {number} count - The number of components to update. + */ + addUpdateRange( start, count ) { + + this.updateRanges.push( { start, count } ); + + } + + /** + * Clears the update ranges. + */ + clearUpdateRanges() { + + this.updateRanges.length = 0; + + } + + /** + * Copies the values of the given buffer attribute to this instance. + * + * @param {BufferAttribute} source - The buffer attribute to copy. + * @return {BufferAttribute} A reference to this instance. + */ + copy( source ) { + + this.name = source.name; + this.array = new source.array.constructor( source.array ); + this.itemSize = source.itemSize; + this.count = source.count; + this.normalized = source.normalized; + + this.usage = source.usage; + this.gpuType = source.gpuType; + + return this; + + } + + /** + * Copies a vector from the given buffer attribute to this one. The start + * and destination position in the attribute buffers are represented by the + * given indices. + * + * @param {number} index1 - The destination index into this buffer attribute. + * @param {BufferAttribute} attribute - The buffer attribute to copy from. + * @param {number} index2 - The source index into the given buffer attribute. + * @return {BufferAttribute} A reference to this instance. + */ + copyAt( index1, attribute, index2 ) { + + index1 *= this.itemSize; + index2 *= attribute.itemSize; + + for ( let i = 0, l = this.itemSize; i < l; i ++ ) { + + this.array[ index1 + i ] = attribute.array[ index2 + i ]; + + } + + return this; + + } + + /** + * Copies the given array data into this buffer attribute. + * + * @param {(TypedArray|Array)} array - The array to copy. + * @return {BufferAttribute} A reference to this instance. + */ + copyArray( array ) { + + this.array.set( array ); + + return this; + + } + + /** + * Applies the given 3x3 matrix to the given attribute. Works with + * item size `2` and `3`. + * + * @param {Matrix3} m - The matrix to apply. + * @return {BufferAttribute} A reference to this instance. + */ + applyMatrix3( m ) { + + if ( this.itemSize === 2 ) { + + for ( let i = 0, l = this.count; i < l; i ++ ) { + + _vector2$1.fromBufferAttribute( this, i ); + _vector2$1.applyMatrix3( m ); + + this.setXY( i, _vector2$1.x, _vector2$1.y ); + + } + + } else if ( this.itemSize === 3 ) { + + for ( let i = 0, l = this.count; i < l; i ++ ) { + + _vector$a.fromBufferAttribute( this, i ); + _vector$a.applyMatrix3( m ); + + this.setXYZ( i, _vector$a.x, _vector$a.y, _vector$a.z ); + + } + + } + + return this; + + } + + /** + * Applies the given 4x4 matrix to the given attribute. Only works with + * item size `3`. + * + * @param {Matrix4} m - The matrix to apply. + * @return {BufferAttribute} A reference to this instance. + */ + applyMatrix4( m ) { + + for ( let i = 0, l = this.count; i < l; i ++ ) { + + _vector$a.fromBufferAttribute( this, i ); + + _vector$a.applyMatrix4( m ); + + this.setXYZ( i, _vector$a.x, _vector$a.y, _vector$a.z ); + + } + + return this; + + } + + /** + * Applies the given 3x3 normal matrix to the given attribute. Only works with + * item size `3`. + * + * @param {Matrix3} m - The normal matrix to apply. + * @return {BufferAttribute} A reference to this instance. + */ + applyNormalMatrix( m ) { + + for ( let i = 0, l = this.count; i < l; i ++ ) { - /** - * An object that can be used to store custom data about the geometry. - * It should not hold references to functions as these will not be cloned. - * - * @type {Object} - */ - this.userData = {}; + _vector$a.fromBufferAttribute( this, i ); + + _vector$a.applyNormalMatrix( m ); + + this.setXYZ( i, _vector$a.x, _vector$a.y, _vector$a.z ); + + } + + return this; } /** - * Returns the index of this geometry. + * Applies the given 4x4 matrix to the given attribute. Only works with + * item size `3` and with direction vectors. * - * @return {?BufferAttribute} The index. Returns `null` if no index is defined. + * @param {Matrix4} m - The matrix to apply. + * @return {BufferAttribute} A reference to this instance. */ - getIndex() { + transformDirection( m ) { - return this.index; + for ( let i = 0, l = this.count; i < l; i ++ ) { + + _vector$a.fromBufferAttribute( this, i ); + + _vector$a.transformDirection( m ); + + this.setXYZ( i, _vector$a.x, _vector$a.y, _vector$a.z ); + + } + + return this; } /** - * Sets the given index to this geometry. + * Sets the given array data in the buffer attribute. * - * @param {Array|BufferAttribute} index - The index to set. - * @return {BufferGeometry} A reference to this instance. + * @param {(TypedArray|Array)} value - The array data to set. + * @param {number} [offset=0] - The offset in this buffer attribute's array. + * @return {BufferAttribute} A reference to this instance. */ - setIndex( index ) { + set( value, offset = 0 ) { - if ( Array.isArray( index ) ) { + // Matching BufferAttribute constructor, do not normalize the array. + this.array.set( value, offset ); - this.index = new ( arrayNeedsUint32( index ) ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); + return this; - } else { + } - this.index = index; + /** + * Returns the given component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} component - The component index. + * @return {number} The returned value. + */ + getComponent( index, component ) { - } + let value = this.array[ index * this.itemSize + component ]; - return this; + if ( this.normalized ) value = denormalize( value, this.array ); + + return value; } /** - * Sets the given indirect attribute to this geometry. + * Sets the given value to the given component of the vector at the given index. * - * @param {BufferAttribute} indirect - The attribute holding indirect draw calls. - * @param {number|Array} [indirectOffset=0] - The offset, in bytes, into the indirect drawing buffer where the value data begins. If an array is provided, multiple indirect draw calls will be made for each offset. - * @return {BufferGeometry} A reference to this instance. + * @param {number} index - The index into the buffer attribute. + * @param {number} component - The component index. + * @param {number} value - The value to set. + * @return {BufferAttribute} A reference to this instance. */ - setIndirect( indirect, indirectOffset = 0 ) { + setComponent( index, component, value ) { - this.indirect = indirect; - this.indirectOffset = indirectOffset; + if ( this.normalized ) value = normalize( value, this.array ); + + this.array[ index * this.itemSize + component ] = value; return this; } /** - * Returns the indirect attribute of this geometry. + * Returns the x component of the vector at the given index. * - * @return {?BufferAttribute} The indirect attribute. Returns `null` if no indirect attribute is defined. + * @param {number} index - The index into the buffer attribute. + * @return {number} The x component. */ - getIndirect() { + getX( index ) { - return this.indirect; + let x = this.array[ index * this.itemSize ]; + + if ( this.normalized ) x = denormalize( x, this.array ); + + return x; } /** - * Returns the buffer attribute for the given name. + * Sets the x component of the vector at the given index. * - * @param {string} name - The attribute name. - * @return {BufferAttribute|InterleavedBufferAttribute|undefined} The buffer attribute. - * Returns `undefined` if not attribute has been found. + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value to set. + * @return {BufferAttribute} A reference to this instance. */ - getAttribute( name ) { + setX( index, x ) { - return this.attributes[ name ]; + if ( this.normalized ) x = normalize( x, this.array ); + + this.array[ index * this.itemSize ] = x; + + return this; } /** - * Sets the given attribute for the given name. + * Returns the y component of the vector at the given index. * - * @param {string} name - The attribute name. - * @param {BufferAttribute|InterleavedBufferAttribute} attribute - The attribute to set. - * @return {BufferGeometry} A reference to this instance. + * @param {number} index - The index into the buffer attribute. + * @return {number} The y component. */ - setAttribute( name, attribute ) { + getY( index ) { - this.attributes[ name ] = attribute; + let y = this.array[ index * this.itemSize + 1 ]; - return this; + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; } /** - * Deletes the attribute for the given name. + * Sets the y component of the vector at the given index. * - * @param {string} name - The attribute name to delete. - * @return {BufferGeometry} A reference to this instance. + * @param {number} index - The index into the buffer attribute. + * @param {number} y - The value to set. + * @return {BufferAttribute} A reference to this instance. */ - deleteAttribute( name ) { + setY( index, y ) { - delete this.attributes[ name ]; + if ( this.normalized ) y = normalize( y, this.array ); + + this.array[ index * this.itemSize + 1 ] = y; return this; } /** - * Returns `true` if this geometry has an attribute for the given name. + * Returns the z component of the vector at the given index. * - * @param {string} name - The attribute name. - * @return {boolean} Whether this geometry has an attribute for the given name or not. + * @param {number} index - The index into the buffer attribute. + * @return {number} The z component. */ - hasAttribute( name ) { + getZ( index ) { - return this.attributes[ name ] !== undefined; + let z = this.array[ index * this.itemSize + 2 ]; + + if ( this.normalized ) z = denormalize( z, this.array ); + + return z; } /** - * Adds a group to this geometry. + * Sets the z component of the vector at the given index. * - * @param {number} start - The first element in this draw call. That is the first - * vertex for non-indexed geometry, otherwise the first triangle index. - * @param {number} count - Specifies how many vertices (or indices) are part of this group. - * @param {number} [materialIndex=0] - The material array index to use. + * @param {number} index - The index into the buffer attribute. + * @param {number} z - The value to set. + * @return {BufferAttribute} A reference to this instance. */ - addGroup( start, count, materialIndex = 0 ) { + setZ( index, z ) { - this.groups.push( { + if ( this.normalized ) z = normalize( z, this.array ); - start: start, - count: count, - materialIndex: materialIndex + this.array[ index * this.itemSize + 2 ] = z; - } ); + return this; } /** - * Clears all groups. + * Returns the w component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The w component. */ - clearGroups() { + getW( index ) { - this.groups = []; + let w = this.array[ index * this.itemSize + 3 ]; + + if ( this.normalized ) w = denormalize( w, this.array ); + + return w; } /** - * Sets the draw range for this geometry. + * Sets the w component of the vector at the given index. * - * @param {number} start - The first vertex for non-indexed geometry, otherwise the first triangle index. - * @param {number} count - For non-indexed BufferGeometry, `count` is the number of vertices to render. - * For indexed BufferGeometry, `count` is the number of indices to render. + * @param {number} index - The index into the buffer attribute. + * @param {number} w - The value to set. + * @return {BufferAttribute} A reference to this instance. */ - setDrawRange( start, count ) { + setW( index, w ) { - this.drawRange.start = start; - this.drawRange.count = count; + if ( this.normalized ) w = normalize( w, this.array ); + + this.array[ index * this.itemSize + 3 ] = w; + + return this; } /** - * Applies the given 4x4 transformation matrix to the geometry. + * Sets the x and y component of the vector at the given index. * - * @param {Matrix4} matrix - The matrix to apply. - * @return {BufferGeometry} A reference to this instance. + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @return {BufferAttribute} A reference to this instance. */ - applyMatrix4( matrix ) { - - const position = this.attributes.position; + setXY( index, x, y ) { - if ( position !== undefined ) { + index *= this.itemSize; - position.applyMatrix4( matrix ); + if ( this.normalized ) { - position.needsUpdate = true; + x = normalize( x, this.array ); + y = normalize( y, this.array ); } - const normal = this.attributes.normal; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; - if ( normal !== undefined ) { + return this; - const normalMatrix = new Matrix3().getNormalMatrix( matrix ); + } - normal.applyNormalMatrix( normalMatrix ); + /** + * Sets the x, y and z component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @param {number} z - The value for the z component to set. + * @return {BufferAttribute} A reference to this instance. + */ + setXYZ( index, x, y, z ) { - normal.needsUpdate = true; + index *= this.itemSize; + + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); } - const tangent = this.attributes.tangent; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; - if ( tangent !== undefined ) { + return this; - tangent.transformDirection( matrix ); + } - tangent.needsUpdate = true; + /** + * Sets the x, y, z and w component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @param {number} z - The value for the z component to set. + * @param {number} w - The value for the w component to set. + * @return {BufferAttribute} A reference to this instance. + */ + setXYZW( index, x, y, z, w ) { - } + index *= this.itemSize; - if ( this.boundingBox !== null ) { + if ( this.normalized ) { - this.computeBoundingBox(); + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); } - if ( this.boundingSphere !== null ) { + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; + this.array[ index + 3 ] = w; - this.computeBoundingSphere(); + return this; - } + } + + /** + * Sets the given callback function that is executed after the Renderer has transferred + * the attribute array data to the GPU. Can be used to perform clean-up operations after + * the upload when attribute data are not needed anymore on the CPU side. + * + * @param {Function} callback - The `onUpload()` callback. + * @return {BufferAttribute} A reference to this instance. + */ + onUpload( callback ) { + + this.onUploadCallback = callback; return this; } /** - * Applies the rotation represented by the Quaternion to the geometry. + * Returns a new buffer attribute with copied values from this instance. * - * @param {Quaternion} q - The Quaternion to apply. - * @return {BufferGeometry} A reference to this instance. + * @return {BufferAttribute} A clone of this instance. */ - applyQuaternion( q ) { + clone() { - _m1$2.makeRotationFromQuaternion( q ); + return new this.constructor( this.array, this.itemSize ).copy( this ); - this.applyMatrix4( _m1$2 ); + } - return this; + /** + * Serializes the buffer attribute into JSON. + * + * @return {Object} A JSON object representing the serialized buffer attribute. + */ + toJSON() { + + const data = { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: Array.from( this.array ), + normalized: this.normalized + }; + + if ( this.name !== '' ) data.name = this.name; + if ( this.usage !== StaticDrawUsage ) data.usage = this.usage; + + return data; } +} + +/** + * Convenient class that can be used when creating a `Int8` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Int8BufferAttribute extends BufferAttribute { + /** - * Rotates the geometry about the X axis. This is typically done as a one time - * operation, and not during a loop. Use {@link Object3D#rotation} for typical - * real-time mesh rotation. + * Constructs a new buffer attribute. * - * @param {number} angle - The angle in radians. - * @return {BufferGeometry} A reference to this instance. + * @param {(Array|Int8Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - rotateX( angle ) { + constructor( array, itemSize, normalized ) { - // rotate geometry around world x-axis + super( new Int8Array( array ), itemSize, normalized ); - _m1$2.makeRotationX( angle ); + } - this.applyMatrix4( _m1$2 ); +} - return this; +/** + * Convenient class that can be used when creating a `UInt8` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Uint8BufferAttribute extends BufferAttribute { + + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Uint8Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { + + super( new Uint8Array( array ), itemSize, normalized ); } +} + +/** + * Convenient class that can be used when creating a `UInt8Clamped` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Uint8ClampedBufferAttribute extends BufferAttribute { + /** - * Rotates the geometry about the Y axis. This is typically done as a one time - * operation, and not during a loop. Use {@link Object3D#rotation} for typical - * real-time mesh rotation. + * Constructs a new buffer attribute. * - * @param {number} angle - The angle in radians. - * @return {BufferGeometry} A reference to this instance. + * @param {(Array|Uint8ClampedArray)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - rotateY( angle ) { + constructor( array, itemSize, normalized ) { - // rotate geometry around world y-axis + super( new Uint8ClampedArray( array ), itemSize, normalized ); - _m1$2.makeRotationY( angle ); + } - this.applyMatrix4( _m1$2 ); +} - return this; +/** + * Convenient class that can be used when creating a `Int16` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Int16BufferAttribute extends BufferAttribute { + + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Int16Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { + + super( new Int16Array( array ), itemSize, normalized ); } +} + +/** + * Convenient class that can be used when creating a `UInt16` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Uint16BufferAttribute extends BufferAttribute { + /** - * Rotates the geometry about the Z axis. This is typically done as a one time - * operation, and not during a loop. Use {@link Object3D#rotation} for typical - * real-time mesh rotation. + * Constructs a new buffer attribute. * - * @param {number} angle - The angle in radians. - * @return {BufferGeometry} A reference to this instance. + * @param {(Array|Uint16Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - rotateZ( angle ) { + constructor( array, itemSize, normalized ) { - // rotate geometry around world z-axis + super( new Uint16Array( array ), itemSize, normalized ); - _m1$2.makeRotationZ( angle ); + } - this.applyMatrix4( _m1$2 ); +} - return this; +/** + * Convenient class that can be used when creating a `Int32` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Int32BufferAttribute extends BufferAttribute { + + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Int32Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { + + super( new Int32Array( array ), itemSize, normalized ); } +} + +/** + * Convenient class that can be used when creating a `UInt32` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Uint32BufferAttribute extends BufferAttribute { + /** - * Translates the geometry. This is typically done as a one time - * operation, and not during a loop. Use {@link Object3D#position} for typical - * real-time mesh rotation. + * Constructs a new buffer attribute. * - * @param {number} x - The x offset. - * @param {number} y - The y offset. - * @param {number} z - The z offset. - * @return {BufferGeometry} A reference to this instance. + * @param {(Array|Uint32Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - translate( x, y, z ) { + constructor( array, itemSize, normalized ) { + + super( new Uint32Array( array ), itemSize, normalized ); + + } + +} + +/** + * Convenient class that can be used when creating a `Float16` buffer attribute with + * a plain `Array` instance. + * + * This class automatically converts to and from FP16 via `Uint16Array` since `Float16Array` + * browser support is still problematic. + * + * @augments BufferAttribute + */ +class Float16BufferAttribute extends BufferAttribute { + + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Uint16Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { + + super( new Uint16Array( array ), itemSize, normalized ); + + this.isFloat16BufferAttribute = true; - // translate geometry + } - _m1$2.makeTranslation( x, y, z ); + getX( index ) { - this.applyMatrix4( _m1$2 ); + let x = fromHalfFloat( this.array[ index * this.itemSize ] ); - return this; + if ( this.normalized ) x = denormalize( x, this.array ); - } + return x; - /** - * Scales the geometry. This is typically done as a one time - * operation, and not during a loop. Use {@link Object3D#scale} for typical - * real-time mesh rotation. - * - * @param {number} x - The x scale. - * @param {number} y - The y scale. - * @param {number} z - The z scale. - * @return {BufferGeometry} A reference to this instance. - */ - scale( x, y, z ) { + } - // scale geometry + setX( index, x ) { - _m1$2.makeScale( x, y, z ); + if ( this.normalized ) x = normalize( x, this.array ); - this.applyMatrix4( _m1$2 ); + this.array[ index * this.itemSize ] = toHalfFloat( x ); return this; } - /** - * Rotates the geometry to face a point in 3D space. This is typically done as a one time - * operation, and not during a loop. Use {@link Object3D#lookAt} for typical - * real-time mesh rotation. - * - * @param {Vector3} vector - The target point. - * @return {BufferGeometry} A reference to this instance. - */ - lookAt( vector ) { - - _obj.lookAt( vector ); + getY( index ) { - _obj.updateMatrix(); + let y = fromHalfFloat( this.array[ index * this.itemSize + 1 ] ); - this.applyMatrix4( _obj.matrix ); + if ( this.normalized ) y = denormalize( y, this.array ); - return this; + return y; } - /** - * Center the geometry based on its bounding box. - * - * @return {BufferGeometry} A reference to this instance. - */ - center() { - - this.computeBoundingBox(); + setY( index, y ) { - this.boundingBox.getCenter( _offset ).negate(); + if ( this.normalized ) y = normalize( y, this.array ); - this.translate( _offset.x, _offset.y, _offset.z ); + this.array[ index * this.itemSize + 1 ] = toHalfFloat( y ); return this; } - /** - * Defines a geometry by creating a `position` attribute based on the given array of points. The array - * can hold 2D or 3D vectors. When using two-dimensional data, the `z` coordinate for all vertices is - * set to `0`. - * - * If the method is used with an existing `position` attribute, the vertex data are overwritten with the - * data from the array. The length of the array must match the vertex count. - * - * @param {Array|Array} points - The points. - * @return {BufferGeometry} A reference to this instance. - */ - setFromPoints( points ) { + getZ( index ) { - const positionAttribute = this.getAttribute( 'position' ); + let z = fromHalfFloat( this.array[ index * this.itemSize + 2 ] ); - if ( positionAttribute === undefined ) { + if ( this.normalized ) z = denormalize( z, this.array ); - const position = []; + return z; - for ( let i = 0, l = points.length; i < l; i ++ ) { + } - const point = points[ i ]; - position.push( point.x, point.y, point.z || 0 ); + setZ( index, z ) { - } + if ( this.normalized ) z = normalize( z, this.array ); - this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); + this.array[ index * this.itemSize + 2 ] = toHalfFloat( z ); - } else { + return this; - const l = Math.min( points.length, positionAttribute.count ); // make sure data do not exceed buffer size + } - for ( let i = 0; i < l; i ++ ) { + getW( index ) { - const point = points[ i ]; - positionAttribute.setXYZ( i, point.x, point.y, point.z || 0 ); + let w = fromHalfFloat( this.array[ index * this.itemSize + 3 ] ); - } + if ( this.normalized ) w = denormalize( w, this.array ); - if ( points.length > positionAttribute.count ) { + return w; - warn( 'BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry.' ); + } - } + setW( index, w ) { - positionAttribute.needsUpdate = true; + if ( this.normalized ) w = normalize( w, this.array ); - } + this.array[ index * this.itemSize + 3 ] = toHalfFloat( w ); return this; } - /** - * Computes the bounding box of the geometry, and updates the `boundingBox` member. - * The bounding box is not computed by the engine; it must be computed by your app. - * You may need to recompute the bounding box if the geometry vertices are modified. - */ - computeBoundingBox() { + setXY( index, x, y ) { - if ( this.boundingBox === null ) { + index *= this.itemSize; - this.boundingBox = new Box3(); + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); } - const position = this.attributes.position; - const morphAttributesPosition = this.morphAttributes.position; + this.array[ index + 0 ] = toHalfFloat( x ); + this.array[ index + 1 ] = toHalfFloat( y ); - if ( position && position.isGLBufferAttribute ) { + return this; - error( 'BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.', this ); + } - this.boundingBox.set( - new Vector3( - Infinity, - Infinity, - Infinity ), - new Vector3( + Infinity, + Infinity, + Infinity ) - ); + setXYZ( index, x, y, z ) { - return; + index *= this.itemSize; + + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); } - if ( position !== undefined ) { + this.array[ index + 0 ] = toHalfFloat( x ); + this.array[ index + 1 ] = toHalfFloat( y ); + this.array[ index + 2 ] = toHalfFloat( z ); - this.boundingBox.setFromBufferAttribute( position ); + return this; - // process morph attributes if present + } - if ( morphAttributesPosition ) { + setXYZW( index, x, y, z, w ) { - for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + index *= this.itemSize; - const morphAttribute = morphAttributesPosition[ i ]; - _box$2.setFromBufferAttribute( morphAttribute ); + if ( this.normalized ) { - if ( this.morphTargetsRelative ) { + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); - _vector$8.addVectors( this.boundingBox.min, _box$2.min ); - this.boundingBox.expandByPoint( _vector$8 ); + } - _vector$8.addVectors( this.boundingBox.max, _box$2.max ); - this.boundingBox.expandByPoint( _vector$8 ); + this.array[ index + 0 ] = toHalfFloat( x ); + this.array[ index + 1 ] = toHalfFloat( y ); + this.array[ index + 2 ] = toHalfFloat( z ); + this.array[ index + 3 ] = toHalfFloat( w ); - } else { + return this; - this.boundingBox.expandByPoint( _box$2.min ); - this.boundingBox.expandByPoint( _box$2.max ); + } - } +} - } +/** + * Convenient class that can be used when creating a `Float32` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Float32BufferAttribute extends BufferAttribute { - } + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Float32Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { - } else { + super( new Float32Array( array ), itemSize, normalized ); - this.boundingBox.makeEmpty(); + } - } +} - if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { +const _box$3 = /*@__PURE__*/ new Box3(); +const _v1$3 = /*@__PURE__*/ new Vector3(); +const _v2$2 = /*@__PURE__*/ new Vector3(); - error( 'BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); +/** + * An analytical 3D sphere defined by a center and radius. This class is mainly + * used as a Bounding Sphere for 3D objects. + */ +class Sphere { - } + /** + * Constructs a new sphere. + * + * @param {Vector3} [center=(0,0,0)] - The center of the sphere + * @param {number} [radius=-1] - The radius of the sphere. + */ + constructor( center = new Vector3(), radius = -1 ) { + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isSphere = true; + + /** + * The center of the sphere + * + * @type {Vector3} + */ + this.center = center; + + /** + * The radius of the sphere. + * + * @type {number} + */ + this.radius = radius; } /** - * Computes the bounding sphere of the geometry, and updates the `boundingSphere` member. - * The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. - * You may need to recompute the bounding sphere if the geometry vertices are modified. + * Sets the sphere's components by copying the given values. + * + * @param {Vector3} center - The center. + * @param {number} radius - The radius. + * @return {Sphere} A reference to this sphere. */ - computeBoundingSphere() { + set( center, radius ) { - if ( this.boundingSphere === null ) { + this.center.copy( center ); + this.radius = radius; - this.boundingSphere = new Sphere(); + return this; - } + } - const position = this.attributes.position; - const morphAttributesPosition = this.morphAttributes.position; + /** + * Computes the minimum bounding sphere for list of points. + * If the optional center point is given, it is used as the sphere's + * center. Otherwise, the center of the axis-aligned bounding box + * encompassing the points is calculated. + * + * @param {Array} points - A list of points in 3D space. + * @param {Vector3} [optionalCenter] - The center of the sphere. + * @return {Sphere} A reference to this sphere. + */ + setFromPoints( points, optionalCenter ) { - if ( position && position.isGLBufferAttribute ) { + const center = this.center; - error( 'BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere.', this ); + if ( optionalCenter !== undefined ) { - this.boundingSphere.set( new Vector3(), Infinity ); + center.copy( optionalCenter ); - return; + } else { - } + _box$3.setFromPoints( points ).getCenter( center ); - if ( position ) { + } - // first, find the center of the bounding sphere + let maxRadiusSq = 0; - const center = this.boundingSphere.center; + for ( let i = 0, il = points.length; i < il; i ++ ) { - _box$2.setFromBufferAttribute( position ); + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); - // process morph attributes if present + } - if ( morphAttributesPosition ) { + this.radius = Math.sqrt( maxRadiusSq ); - for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + return this; - const morphAttribute = morphAttributesPosition[ i ]; - _boxMorphTargets.setFromBufferAttribute( morphAttribute ); + } - if ( this.morphTargetsRelative ) { + /** + * Copies the values of the given sphere to this instance. + * + * @param {Sphere} sphere - The sphere to copy. + * @return {Sphere} A reference to this sphere. + */ + copy( sphere ) { - _vector$8.addVectors( _box$2.min, _boxMorphTargets.min ); - _box$2.expandByPoint( _vector$8 ); + this.center.copy( sphere.center ); + this.radius = sphere.radius; - _vector$8.addVectors( _box$2.max, _boxMorphTargets.max ); - _box$2.expandByPoint( _vector$8 ); + return this; - } else { + } - _box$2.expandByPoint( _boxMorphTargets.min ); - _box$2.expandByPoint( _boxMorphTargets.max ); + /** + * Returns `true` if the sphere is empty (the radius set to a negative number). + * + * Spheres with a radius of `0` contain only their center point and are not + * considered to be empty. + * + * @return {boolean} Whether this sphere is empty or not. + */ + isEmpty() { - } + return ( this.radius < 0 ); - } + } - } + /** + * Makes this sphere empty which means in encloses a zero space in 3D. + * + * @return {Sphere} A reference to this sphere. + */ + makeEmpty() { - _box$2.getCenter( center ); + this.center.set( 0, 0, 0 ); + this.radius = -1; - // second, try to find a boundingSphere with a radius smaller than the - // boundingSphere of the boundingBox: sqrt(3) smaller in the best case + return this; - let maxRadiusSq = 0; + } - for ( let i = 0, il = position.count; i < il; i ++ ) { + /** + * Returns `true` if this sphere contains the given point inclusive of + * the surface of the sphere. + * + * @param {Vector3} point - The point to check. + * @return {boolean} Whether this sphere contains the given point or not. + */ + containsPoint( point ) { - _vector$8.fromBufferAttribute( position, i ); + return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) ); + } - } + /** + * Returns the closest distance from the boundary of the sphere to the + * given point. If the sphere contains the point, the distance will + * be negative. + * + * @param {Vector3} point - The point to compute the distance to. + * @return {number} The distance to the point. + */ + distanceToPoint( point ) { - // process morph attributes if present + return ( point.distanceTo( this.center ) - this.radius ); - if ( morphAttributesPosition ) { + } - for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { + /** + * Returns `true` if this sphere intersects with the given one. + * + * @param {Sphere} sphere - The sphere to test. + * @return {boolean} Whether this sphere intersects with the given one or not. + */ + intersectsSphere( sphere ) { - const morphAttribute = morphAttributesPosition[ i ]; - const morphTargetsRelative = this.morphTargetsRelative; + const radiusSum = this.radius + sphere.radius; - for ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) { + return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); - _vector$8.fromBufferAttribute( morphAttribute, j ); + } - if ( morphTargetsRelative ) { + /** + * Returns `true` if this sphere intersects with the given box. + * + * @param {Box3} box - The box to test. + * @return {boolean} Whether this sphere intersects with the given box or not. + */ + intersectsBox( box ) { - _offset.fromBufferAttribute( position, j ); - _vector$8.add( _offset ); + return box.intersectsSphere( this ); - } + } - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) ); + /** + * Returns `true` if this sphere intersects with the given plane. + * + * @param {Plane} plane - The plane to test. + * @return {boolean} Whether this sphere intersects with the given plane or not. + */ + intersectsPlane( plane ) { - } + return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; - } + } - } + /** + * Clamps a point within the sphere. If the point is outside the sphere, it + * will clamp it to the closest point on the edge of the sphere. Points + * already inside the sphere will not be affected. + * + * @param {Vector3} point - The plane to clamp. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The clamped point. + */ + clampPoint( point, target ) { - this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); + const deltaLengthSq = this.center.distanceToSquared( point ); - if ( isNaN( this.boundingSphere.radius ) ) { + target.copy( point ); - error( 'BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); + if ( deltaLengthSq > ( this.radius * this.radius ) ) { - } + target.sub( this.center ).normalize(); + target.multiplyScalar( this.radius ).add( this.center ); } + return target; + } /** - * Calculates and adds a tangent attribute to this geometry. + * Returns a bounding box that encloses this sphere. * - * The computation is only supported for indexed geometries and if position, normal, and uv attributes - * are defined. When using a tangent space normal map, prefer the MikkTSpace algorithm provided by - * {@link BufferGeometryUtils#computeMikkTSpaceTangents} instead. + * @param {Box3} target - The target box that is used to store the method's result. + * @return {Box3} The bounding box that encloses this sphere. */ - computeTangents() { + getBoundingBox( target ) { - const index = this.index; - const attributes = this.attributes; + if ( this.isEmpty() ) { - // based on http://www.terathon.com/code/tangent.html - // (per vertex tangents) + // Empty sphere produces empty bounding box + target.makeEmpty(); + return target; - if ( index === null || - attributes.position === undefined || - attributes.normal === undefined || - attributes.uv === undefined ) { + } - error( 'BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)' ); - return; + target.set( this.center, this.center ); + target.expandByScalar( this.radius ); - } + return target; - const positionAttribute = attributes.position; - const normalAttribute = attributes.normal; - const uvAttribute = attributes.uv; + } - if ( this.hasAttribute( 'tangent' ) === false ) { + /** + * Transforms this sphere with the given 4x4 transformation matrix. + * + * @param {Matrix4} matrix - The transformation matrix. + * @return {Sphere} A reference to this sphere. + */ + applyMatrix4( matrix ) { - this.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * positionAttribute.count ), 4 ) ); + this.center.applyMatrix4( matrix ); + this.radius = this.radius * matrix.getMaxScaleOnAxis(); - } + return this; - const tangentAttribute = this.getAttribute( 'tangent' ); + } - const tan1 = [], tan2 = []; + /** + * Translates the sphere's center by the given offset. + * + * @param {Vector3} offset - The offset. + * @return {Sphere} A reference to this sphere. + */ + translate( offset ) { - for ( let i = 0; i < positionAttribute.count; i ++ ) { + this.center.add( offset ); - tan1[ i ] = new Vector3(); - tan2[ i ] = new Vector3(); + return this; - } + } - const vA = new Vector3(), - vB = new Vector3(), - vC = new Vector3(), + /** + * Expands the boundaries of this sphere to include the given point. + * + * @param {Vector3} point - The point to include. + * @return {Sphere} A reference to this sphere. + */ + expandByPoint( point ) { - uvA = new Vector2(), - uvB = new Vector2(), - uvC = new Vector2(), + if ( this.isEmpty() ) { - sdir = new Vector3(), - tdir = new Vector3(); + this.center.copy( point ); - function handleTriangle( a, b, c ) { + this.radius = 0; - vA.fromBufferAttribute( positionAttribute, a ); - vB.fromBufferAttribute( positionAttribute, b ); - vC.fromBufferAttribute( positionAttribute, c ); + return this; - uvA.fromBufferAttribute( uvAttribute, a ); - uvB.fromBufferAttribute( uvAttribute, b ); - uvC.fromBufferAttribute( uvAttribute, c ); + } - vB.sub( vA ); - vC.sub( vA ); + _v1$3.subVectors( point, this.center ); - uvB.sub( uvA ); - uvC.sub( uvA ); + const lengthSq = _v1$3.lengthSq(); - const r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y ); + if ( lengthSq > ( this.radius * this.radius ) ) { - // silently ignore degenerate uv triangles having coincident or colinear vertices + // calculate the minimal sphere - if ( ! isFinite( r ) ) return; + const length = Math.sqrt( lengthSq ); - sdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r ); - tdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r ); + const delta = ( length - this.radius ) * 0.5; - tan1[ a ].add( sdir ); - tan1[ b ].add( sdir ); - tan1[ c ].add( sdir ); + this.center.addScaledVector( _v1$3, delta / length ); - tan2[ a ].add( tdir ); - tan2[ b ].add( tdir ); - tan2[ c ].add( tdir ); + this.radius += delta; } - let groups = this.groups; - - if ( groups.length === 0 ) { + return this; - groups = [ { - start: 0, - count: index.count - } ]; + } - } + /** + * Expands this sphere to enclose both the original sphere and the given sphere. + * + * @param {Sphere} sphere - The sphere to include. + * @return {Sphere} A reference to this sphere. + */ + union( sphere ) { - for ( let i = 0, il = groups.length; i < il; ++ i ) { + if ( sphere.isEmpty() ) { - const group = groups[ i ]; + return this; - const start = group.start; - const count = group.count; + } - for ( let j = start, jl = start + count; j < jl; j += 3 ) { + if ( this.isEmpty() ) { - handleTriangle( - index.getX( j + 0 ), - index.getX( j + 1 ), - index.getX( j + 2 ) - ); + this.copy( sphere ); - } + return this; } - const tmp = new Vector3(), tmp2 = new Vector3(); - const n = new Vector3(), n2 = new Vector3(); + if ( this.center.equals( sphere.center ) === true ) { - function handleVertex( v ) { + this.radius = Math.max( this.radius, sphere.radius ); - n.fromBufferAttribute( normalAttribute, v ); - n2.copy( n ); + } else { - const t = tan1[ v ]; + _v2$2.subVectors( sphere.center, this.center ).setLength( sphere.radius ); - // Gram-Schmidt orthogonalize + this.expandByPoint( _v1$3.copy( sphere.center ).add( _v2$2 ) ); - tmp.copy( t ); - tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); + this.expandByPoint( _v1$3.copy( sphere.center ).sub( _v2$2 ) ); - // Calculate handedness + } - tmp2.crossVectors( n2, t ); - const test = tmp2.dot( tan2[ v ] ); - const w = ( test < 0.0 ) ? -1 : 1.0; + return this; - tangentAttribute.setXYZW( v, tmp.x, tmp.y, tmp.z, w ); + } - } + /** + * Returns `true` if this sphere is equal with the given one. + * + * @param {Sphere} sphere - The sphere to test for equality. + * @return {boolean} Whether this bounding sphere is equal with the given one. + */ + equals( sphere ) { - for ( let i = 0, il = groups.length; i < il; ++ i ) { + return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); - const group = groups[ i ]; + } - const start = group.start; - const count = group.count; + /** + * Returns a new sphere with copied values from this instance. + * + * @return {Sphere} A clone of this instance. + */ + clone() { - for ( let j = start, jl = start + count; j < jl; j += 3 ) { + return new this.constructor().copy( this ); - handleVertex( index.getX( j + 0 ) ); - handleVertex( index.getX( j + 1 ) ); - handleVertex( index.getX( j + 2 ) ); + } - } + /** + * Returns a serialized structure of the bounding sphere. + * + * @return {Object} Serialized structure with fields representing the object state. + */ + toJSON() { - } + return { + radius: this.radius, + center: this.center.toArray() + }; } /** - * Computes vertex normals for the given vertex data. For indexed geometries, the method sets - * each vertex normal to be the average of the face normals of the faces that share that vertex. - * For non-indexed geometries, vertices are not shared, and the method sets each vertex normal - * to be the same as the face normal. + * Returns a serialized structure of the bounding sphere. + * + * @param {Object} json - The serialized json to set the sphere from. + * @return {Sphere} A reference to this bounding sphere. */ - computeVertexNormals() { + fromJSON( json ) { - const index = this.index; - const positionAttribute = this.getAttribute( 'position' ); + this.radius = json.radius; + this.center.fromArray( json.center ); + return this; - if ( positionAttribute !== undefined ) { + } - let normalAttribute = this.getAttribute( 'normal' ); +} - if ( normalAttribute === undefined ) { +let _id$2 = 0; - normalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 ); - this.setAttribute( 'normal', normalAttribute ); +const _m1$2 = /*@__PURE__*/ new Matrix4(); +const _obj = /*@__PURE__*/ new Object3D(); +const _offset = /*@__PURE__*/ new Vector3(); +const _box$2 = /*@__PURE__*/ new Box3(); +const _boxMorphTargets = /*@__PURE__*/ new Box3(); +const _vector$9 = /*@__PURE__*/ new Vector3(); - } else { +/** + * A representation of mesh, line, or point geometry. Includes vertex + * positions, face indices, normals, colors, UVs, and custom attributes + * within buffers, reducing the cost of passing all this data to the GPU. + * + * ```js + * const geometry = new THREE.BufferGeometry(); + * // create a simple square shape. We duplicate the top left and bottom right + * // vertices because each vertex needs to appear once per triangle. + * const vertices = new Float32Array( [ + * -1.0, -1.0, 1.0, // v0 + * 1.0, -1.0, 1.0, // v1 + * 1.0, 1.0, 1.0, // v2 + * + * 1.0, 1.0, 1.0, // v3 + * -1.0, 1.0, 1.0, // v4 + * -1.0, -1.0, 1.0 // v5 + * ] ); + * // itemSize = 3 because there are 3 values (components) per vertex + * geometry.setAttribute( 'position', new THREE.BufferAttribute( vertices, 3 ) ); + * const material = new THREE.MeshBasicMaterial( { color: 0xff0000 } ); + * const mesh = new THREE.Mesh( geometry, material ); + * ``` + * + * @augments EventDispatcher + */ +class BufferGeometry extends EventDispatcher { - // reset existing normals to zero + /** + * Constructs a new geometry. + */ + constructor() { - for ( let i = 0, il = normalAttribute.count; i < il; i ++ ) { + super(); - normalAttribute.setXYZ( i, 0, 0, 0 ); + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isBufferGeometry = true; - } + /** + * The ID of the geometry. + * + * @name BufferGeometry#id + * @type {number} + * @readonly + */ + Object.defineProperty( this, 'id', { value: _id$2 ++ } ); - } + /** + * The UUID of the geometry. + * + * @type {string} + * @readonly + */ + this.uuid = generateUUID(); - const pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); - const nA = new Vector3(), nB = new Vector3(), nC = new Vector3(); - const cb = new Vector3(), ab = new Vector3(); + /** + * The name of the geometry. + * + * @type {string} + */ + this.name = ''; + this.type = 'BufferGeometry'; - // indexed elements + /** + * Allows for vertices to be re-used across multiple triangles; this is + * called using "indexed triangles". Each triangle is associated with the + * indices of three vertices. This attribute therefore stores the index of + * each vertex for each triangular face. If this attribute is not set, the + * renderer assumes that each three contiguous positions represent a single triangle. + * + * @type {?BufferAttribute} + * @default null + */ + this.index = null; - if ( index ) { + /** + * A (storage) buffer attribute which was generated with a compute shader and + * now defines indirect draw calls. + * + * Can only be used with {@link WebGPURenderer} and a WebGPU backend. + * + * @type {?BufferAttribute} + * @default null + */ + this.indirect = null; - for ( let i = 0, il = index.count; i < il; i += 3 ) { + /** + * The offset, in bytes, into the indirect drawing buffer where the value data begins. If an array is provided, multiple indirect draw calls will be made for each offset. + * + * Can only be used with {@link WebGPURenderer} and a WebGPU backend. + * + * @type {number|Array} + * @default 0 + */ + this.indirectOffset = 0; - const vA = index.getX( i + 0 ); - const vB = index.getX( i + 1 ); - const vC = index.getX( i + 2 ); + /** + * This dictionary has as id the name of the attribute to be set and as value + * the buffer attribute to set it to. Rather than accessing this property directly, + * use `setAttribute()` and `getAttribute()` to access attributes of this geometry. + * + * @type {Object} + */ + this.attributes = {}; - pA.fromBufferAttribute( positionAttribute, vA ); - pB.fromBufferAttribute( positionAttribute, vB ); - pC.fromBufferAttribute( positionAttribute, vC ); + /** + * This dictionary holds the morph targets of the geometry. + * + * Note: Once the geometry has been rendered, the morph attribute data cannot + * be changed. You will have to call `dispose()`, and create a new geometry instance. + * + * @type {Object} + */ + this.morphAttributes = {}; - cb.subVectors( pC, pB ); - ab.subVectors( pA, pB ); - cb.cross( ab ); + /** + * Used to control the morph target behavior; when set to `true`, the morph + * target data is treated as relative offsets, rather than as absolute + * positions/normals. + * + * @type {boolean} + * @default false + */ + this.morphTargetsRelative = false; - nA.fromBufferAttribute( normalAttribute, vA ); - nB.fromBufferAttribute( normalAttribute, vB ); - nC.fromBufferAttribute( normalAttribute, vC ); + /** + * Split the geometry into groups, each of which will be rendered in a + * separate draw call. This allows an array of materials to be used with the geometry. + * + * Use `addGroup()` and `clearGroups()` to edit groups, rather than modifying this array directly. + * + * Every vertex and index must belong to exactly one group — groups must not share vertices or + * indices, and must not leave vertices or indices unused. + * + * @type {Array} + */ + this.groups = []; - nA.add( cb ); - nB.add( cb ); - nC.add( cb ); + /** + * Bounding box for the geometry which can be calculated with `computeBoundingBox()`. + * + * @type {?Box3} + * @default null + */ + this.boundingBox = null; - normalAttribute.setXYZ( vA, nA.x, nA.y, nA.z ); - normalAttribute.setXYZ( vB, nB.x, nB.y, nB.z ); - normalAttribute.setXYZ( vC, nC.x, nC.y, nC.z ); + /** + * Bounding sphere for the geometry which can be calculated with `computeBoundingSphere()`. + * + * @type {?Sphere} + * @default null + */ + this.boundingSphere = null; - } + /** + * Determines the part of the geometry to render. This should not be set directly, + * instead use `setDrawRange()`. + * + * @type {{start:number,count:number}} + */ + this.drawRange = { start: 0, count: Infinity }; - } else { + /** + * An object that can be used to store custom data about the geometry. + * It should not hold references to functions as these will not be cloned. + * + * @type {Object} + */ + this.userData = {}; - // non-indexed elements (unconnected triangle soup) + } - for ( let i = 0, il = positionAttribute.count; i < il; i += 3 ) { + /** + * Returns the index of this geometry. + * + * @return {?BufferAttribute} The index. Returns `null` if no index is defined. + */ + getIndex() { - pA.fromBufferAttribute( positionAttribute, i + 0 ); - pB.fromBufferAttribute( positionAttribute, i + 1 ); - pC.fromBufferAttribute( positionAttribute, i + 2 ); + return this.index; - cb.subVectors( pC, pB ); - ab.subVectors( pA, pB ); - cb.cross( ab ); + } - normalAttribute.setXYZ( i + 0, cb.x, cb.y, cb.z ); - normalAttribute.setXYZ( i + 1, cb.x, cb.y, cb.z ); - normalAttribute.setXYZ( i + 2, cb.x, cb.y, cb.z ); + /** + * Sets the given index to this geometry. + * + * @param {Array|BufferAttribute} index - The index to set. + * @return {BufferGeometry} A reference to this instance. + */ + setIndex( index ) { - } + if ( Array.isArray( index ) ) { - } + this.index = new ( arrayNeedsUint32( index ) ? Uint32BufferAttribute : Uint16BufferAttribute )( index, 1 ); - this.normalizeNormals(); + } else { - normalAttribute.needsUpdate = true; + this.index = index; } + return this; + } /** - * Ensures every normal vector in a geometry will have a magnitude of `1`. This will - * correct lighting on the geometry surfaces. + * Sets the given indirect attribute to this geometry. + * + * @param {BufferAttribute} indirect - The attribute holding indirect draw calls. + * @param {number|Array} [indirectOffset=0] - The offset, in bytes, into the indirect drawing buffer where the value data begins. If an array is provided, multiple indirect draw calls will be made for each offset. + * @return {BufferGeometry} A reference to this instance. */ - normalizeNormals() { - - const normals = this.attributes.normal; + setIndirect( indirect, indirectOffset = 0 ) { - for ( let i = 0, il = normals.count; i < il; i ++ ) { + this.indirect = indirect; + this.indirectOffset = indirectOffset; - _vector$8.fromBufferAttribute( normals, i ); + return this; - _vector$8.normalize(); + } - normals.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); + /** + * Returns the indirect attribute of this geometry. + * + * @return {?BufferAttribute} The indirect attribute. Returns `null` if no indirect attribute is defined. + */ + getIndirect() { - } + return this.indirect; } /** - * Return a new non-index version of this indexed geometry. If the geometry - * is already non-indexed, the method is a NOOP. + * Returns the buffer attribute for the given name. * - * @return {BufferGeometry} The non-indexed version of this indexed geometry. + * @param {string} name - The attribute name. + * @return {BufferAttribute|InterleavedBufferAttribute|undefined} The buffer attribute. + * Returns `undefined` if not attribute has been found. */ - toNonIndexed() { + getAttribute( name ) { - function convertBufferAttribute( attribute, indices ) { + return this.attributes[ name ]; - const array = attribute.array; - const itemSize = attribute.itemSize; - const normalized = attribute.normalized; + } - const array2 = new array.constructor( indices.length * itemSize ); + /** + * Sets the given attribute for the given name. + * + * @param {string} name - The attribute name. + * @param {BufferAttribute|InterleavedBufferAttribute} attribute - The attribute to set. + * @return {BufferGeometry} A reference to this instance. + */ + setAttribute( name, attribute ) { - let index = 0, index2 = 0; + this.attributes[ name ] = attribute; - for ( let i = 0, l = indices.length; i < l; i ++ ) { + return this; - if ( attribute.isInterleavedBufferAttribute ) { + } - index = indices[ i ] * attribute.data.stride + attribute.offset; + /** + * Deletes the attribute for the given name. + * + * @param {string} name - The attribute name to delete. + * @return {BufferGeometry} A reference to this instance. + */ + deleteAttribute( name ) { - } else { + delete this.attributes[ name ]; - index = indices[ i ] * itemSize; + return this; - } + } - for ( let j = 0; j < itemSize; j ++ ) { + /** + * Returns `true` if this geometry has an attribute for the given name. + * + * @param {string} name - The attribute name. + * @return {boolean} Whether this geometry has an attribute for the given name or not. + */ + hasAttribute( name ) { - array2[ index2 ++ ] = array[ index ++ ]; + return this.attributes[ name ] !== undefined; - } + } - } + /** + * Adds a group to this geometry. + * + * @param {number} start - The first element in this draw call. That is the first + * vertex for non-indexed geometry, otherwise the first triangle index. + * @param {number} count - Specifies how many vertices (or indices) are part of this group. + * @param {number} [materialIndex=0] - The material array index to use. + */ + addGroup( start, count, materialIndex = 0 ) { - return new BufferAttribute( array2, itemSize, normalized ); + this.groups.push( { - } + start: start, + count: count, + materialIndex: materialIndex - // + } ); - if ( this.index === null ) { + } - warn( 'BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.' ); - return this; + /** + * Clears all groups. + */ + clearGroups() { - } + this.groups = []; - const geometry2 = new BufferGeometry(); + } - const indices = this.index.array; - const attributes = this.attributes; + /** + * Sets the draw range for this geometry. + * + * @param {number} start - The first vertex for non-indexed geometry, otherwise the first triangle index. + * @param {number} count - For non-indexed BufferGeometry, `count` is the number of vertices to render. + * For indexed BufferGeometry, `count` is the number of indices to render. + */ + setDrawRange( start, count ) { - // attributes + this.drawRange.start = start; + this.drawRange.count = count; - for ( const name in attributes ) { + } - const attribute = attributes[ name ]; + /** + * Applies the given 4x4 transformation matrix to the geometry. + * + * @param {Matrix4} matrix - The matrix to apply. + * @return {BufferGeometry} A reference to this instance. + */ + applyMatrix4( matrix ) { - const newAttribute = convertBufferAttribute( attribute, indices ); + const position = this.attributes.position; - geometry2.setAttribute( name, newAttribute ); + if ( position !== undefined ) { + + position.applyMatrix4( matrix ); + + position.needsUpdate = true; } - // morph attributes + const normal = this.attributes.normal; - const morphAttributes = this.morphAttributes; + if ( normal !== undefined ) { - for ( const name in morphAttributes ) { + const normalMatrix = new Matrix3().getNormalMatrix( matrix ); - const morphArray = []; - const morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes + normal.applyNormalMatrix( normalMatrix ); - for ( let i = 0, il = morphAttribute.length; i < il; i ++ ) { + normal.needsUpdate = true; - const attribute = morphAttribute[ i ]; + } - const newAttribute = convertBufferAttribute( attribute, indices ); + const tangent = this.attributes.tangent; - morphArray.push( newAttribute ); + if ( tangent !== undefined ) { - } + tangent.transformDirection( matrix ); - geometry2.morphAttributes[ name ] = morphArray; + tangent.needsUpdate = true; } - geometry2.morphTargetsRelative = this.morphTargetsRelative; + if ( this.boundingBox !== null ) { - // groups + this.computeBoundingBox(); - const groups = this.groups; + } - for ( let i = 0, l = groups.length; i < l; i ++ ) { + if ( this.boundingSphere !== null ) { - const group = groups[ i ]; - geometry2.addGroup( group.start, group.count, group.materialIndex ); + this.computeBoundingSphere(); } - return geometry2; + return this; } /** - * Serializes the geometry into JSON. + * Applies the rotation represented by the Quaternion to the geometry. * - * @return {Object} A JSON object representing the serialized geometry. + * @param {Quaternion} q - The Quaternion to apply. + * @return {BufferGeometry} A reference to this instance. */ - toJSON() { - - const data = { - metadata: { - version: 4.7, - type: 'BufferGeometry', - generator: 'BufferGeometry.toJSON' - } - }; - - // standard BufferGeometry serialization - - data.uuid = this.uuid; - data.type = this.type; - if ( this.name !== '' ) data.name = this.name; - if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; - - if ( this.parameters !== undefined ) { - - const parameters = this.parameters; - - for ( const key in parameters ) { - - if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; + applyQuaternion( q ) { - } + _m1$2.makeRotationFromQuaternion( q ); - return data; + this.applyMatrix4( _m1$2 ); - } + return this; - // for simplicity the code assumes attributes are not shared across geometries, see #15811 + } - data.data = { attributes: {} }; + /** + * Rotates the geometry about the X axis. This is typically done as a one time + * operation, and not during a loop. Use {@link Object3D#rotation} for typical + * real-time mesh rotation. + * + * @param {number} angle - The angle in radians. + * @return {BufferGeometry} A reference to this instance. + */ + rotateX( angle ) { - const index = this.index; + // rotate geometry around world x-axis - if ( index !== null ) { + _m1$2.makeRotationX( angle ); - data.data.index = { - type: index.array.constructor.name, - array: Array.prototype.slice.call( index.array ) - }; + this.applyMatrix4( _m1$2 ); - } + return this; - const attributes = this.attributes; + } - for ( const key in attributes ) { + /** + * Rotates the geometry about the Y axis. This is typically done as a one time + * operation, and not during a loop. Use {@link Object3D#rotation} for typical + * real-time mesh rotation. + * + * @param {number} angle - The angle in radians. + * @return {BufferGeometry} A reference to this instance. + */ + rotateY( angle ) { - const attribute = attributes[ key ]; + // rotate geometry around world y-axis - data.data.attributes[ key ] = attribute.toJSON( data.data ); + _m1$2.makeRotationY( angle ); - } + this.applyMatrix4( _m1$2 ); - const morphAttributes = {}; - let hasMorphAttributes = false; + return this; - for ( const key in this.morphAttributes ) { + } - const attributeArray = this.morphAttributes[ key ]; + /** + * Rotates the geometry about the Z axis. This is typically done as a one time + * operation, and not during a loop. Use {@link Object3D#rotation} for typical + * real-time mesh rotation. + * + * @param {number} angle - The angle in radians. + * @return {BufferGeometry} A reference to this instance. + */ + rotateZ( angle ) { - const array = []; + // rotate geometry around world z-axis - for ( let i = 0, il = attributeArray.length; i < il; i ++ ) { + _m1$2.makeRotationZ( angle ); - const attribute = attributeArray[ i ]; + this.applyMatrix4( _m1$2 ); - array.push( attribute.toJSON( data.data ) ); + return this; - } + } - if ( array.length > 0 ) { + /** + * Translates the geometry. This is typically done as a one time + * operation, and not during a loop. Use {@link Object3D#position} for typical + * real-time mesh rotation. + * + * @param {number} x - The x offset. + * @param {number} y - The y offset. + * @param {number} z - The z offset. + * @return {BufferGeometry} A reference to this instance. + */ + translate( x, y, z ) { - morphAttributes[ key ] = array; + // translate geometry - hasMorphAttributes = true; + _m1$2.makeTranslation( x, y, z ); - } + this.applyMatrix4( _m1$2 ); - } + return this; - if ( hasMorphAttributes ) { + } - data.data.morphAttributes = morphAttributes; - data.data.morphTargetsRelative = this.morphTargetsRelative; + /** + * Scales the geometry. This is typically done as a one time + * operation, and not during a loop. Use {@link Object3D#scale} for typical + * real-time mesh rotation. + * + * @param {number} x - The x scale. + * @param {number} y - The y scale. + * @param {number} z - The z scale. + * @return {BufferGeometry} A reference to this instance. + */ + scale( x, y, z ) { - } + // scale geometry - const groups = this.groups; + _m1$2.makeScale( x, y, z ); - if ( groups.length > 0 ) { + this.applyMatrix4( _m1$2 ); - data.data.groups = JSON.parse( JSON.stringify( groups ) ); + return this; - } + } - const boundingSphere = this.boundingSphere; + /** + * Rotates the geometry to face a point in 3D space. This is typically done as a one time + * operation, and not during a loop. Use {@link Object3D#lookAt} for typical + * real-time mesh rotation. + * + * @param {Vector3} vector - The target point. + * @return {BufferGeometry} A reference to this instance. + */ + lookAt( vector ) { - if ( boundingSphere !== null ) { + _obj.lookAt( vector ); - data.data.boundingSphere = boundingSphere.toJSON(); + _obj.updateMatrix(); - } + this.applyMatrix4( _obj.matrix ); - return data; + return this; } /** - * Returns a new geometry with copied values from this instance. + * Center the geometry based on its bounding box. * - * @return {BufferGeometry} A clone of this instance. + * @return {BufferGeometry} A reference to this instance. */ - clone() { + center() { - return new this.constructor().copy( this ); + this.computeBoundingBox(); + + this.boundingBox.getCenter( _offset ).negate(); + + this.translate( _offset.x, _offset.y, _offset.z ); + + return this; } /** - * Copies the values of the given geometry to this instance. + * Defines a geometry by creating a `position` attribute based on the given array of points. The array + * can hold 2D or 3D vectors. When using two-dimensional data, the `z` coordinate for all vertices is + * set to `0`. * - * @param {BufferGeometry} source - The geometry to copy. + * If the method is used with an existing `position` attribute, the vertex data are overwritten with the + * data from the array. The length of the array must match the vertex count. + * + * @param {Array|Array} points - The points. * @return {BufferGeometry} A reference to this instance. */ - copy( source ) { + setFromPoints( points ) { - // reset + const positionAttribute = this.getAttribute( 'position' ); - this.index = null; - this.attributes = {}; - this.morphAttributes = {}; - this.groups = []; - this.boundingBox = null; - this.boundingSphere = null; + if ( positionAttribute === undefined ) { - // used for storing cloned, shared data + const position = []; - const data = {}; + for ( let i = 0, l = points.length; i < l; i ++ ) { - // name + const point = points[ i ]; + position.push( point.x, point.y, point.z || 0 ); - this.name = source.name; + } - // index + this.setAttribute( 'position', new Float32BufferAttribute( position, 3 ) ); - const index = source.index; + } else { - if ( index !== null ) { + const l = Math.min( points.length, positionAttribute.count ); // make sure data do not exceed buffer size - this.setIndex( index.clone() ); + for ( let i = 0; i < l; i ++ ) { - } + const point = points[ i ]; + positionAttribute.setXYZ( i, point.x, point.y, point.z || 0 ); - // attributes + } - const attributes = source.attributes; + if ( points.length > positionAttribute.count ) { - for ( const name in attributes ) { + warn( 'BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry.' ); - const attribute = attributes[ name ]; - this.setAttribute( name, attribute.clone( data ) ); + } + + positionAttribute.needsUpdate = true; } - // morph attributes + return this; - const morphAttributes = source.morphAttributes; + } - for ( const name in morphAttributes ) { + /** + * Computes the bounding box of the geometry, and updates the `boundingBox` member. + * The bounding box is not computed by the engine; it must be computed by your app. + * You may need to recompute the bounding box if the geometry vertices are modified. + */ + computeBoundingBox() { - const array = []; - const morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes + if ( this.boundingBox === null ) { - for ( let i = 0, l = morphAttribute.length; i < l; i ++ ) { + this.boundingBox = new Box3(); - array.push( morphAttribute[ i ].clone( data ) ); + } - } + const position = this.attributes.position; + const morphAttributesPosition = this.morphAttributes.position; - this.morphAttributes[ name ] = array; + if ( position && position.isGLBufferAttribute ) { - } + error( 'BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.', this ); - this.morphTargetsRelative = source.morphTargetsRelative; + this.boundingBox.set( + new Vector3( - Infinity, - Infinity, - Infinity ), + new Vector3( + Infinity, + Infinity, + Infinity ) + ); - // groups + return; - const groups = source.groups; + } - for ( let i = 0, l = groups.length; i < l; i ++ ) { + if ( position !== undefined ) { - const group = groups[ i ]; - this.addGroup( group.start, group.count, group.materialIndex ); + this.boundingBox.setFromBufferAttribute( position ); - } + // process morph attributes if present - // bounding box + if ( morphAttributesPosition ) { - const boundingBox = source.boundingBox; + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - if ( boundingBox !== null ) { + const morphAttribute = morphAttributesPosition[ i ]; + _box$2.setFromBufferAttribute( morphAttribute ); - this.boundingBox = boundingBox.clone(); + if ( this.morphTargetsRelative ) { - } + _vector$9.addVectors( this.boundingBox.min, _box$2.min ); + this.boundingBox.expandByPoint( _vector$9 ); - // bounding sphere + _vector$9.addVectors( this.boundingBox.max, _box$2.max ); + this.boundingBox.expandByPoint( _vector$9 ); - const boundingSphere = source.boundingSphere; + } else { - if ( boundingSphere !== null ) { + this.boundingBox.expandByPoint( _box$2.min ); + this.boundingBox.expandByPoint( _box$2.max ); - this.boundingSphere = boundingSphere.clone(); + } - } + } - // draw range + } - this.drawRange.start = source.drawRange.start; - this.drawRange.count = source.drawRange.count; + } else { - // user data + this.boundingBox.makeEmpty(); - this.userData = source.userData; + } - return this; + if ( isNaN( this.boundingBox.min.x ) || isNaN( this.boundingBox.min.y ) || isNaN( this.boundingBox.min.z ) ) { + + error( 'BufferGeometry.computeBoundingBox(): Computed min/max have NaN values. The "position" attribute is likely to have NaN values.', this ); + + } } /** - * Frees the GPU-related resources allocated by this instance. Call this - * method whenever this instance is no longer used in your app. - * - * @fires BufferGeometry#dispose + * Computes the bounding sphere of the geometry, and updates the `boundingSphere` member. + * The engine automatically computes the bounding sphere when it is needed, e.g., for ray casting or view frustum culling. + * You may need to recompute the bounding sphere if the geometry vertices are modified. */ - dispose() { + computeBoundingSphere() { - this.dispatchEvent( { type: 'dispose' } ); + if ( this.boundingSphere === null ) { - } + this.boundingSphere = new Sphere(); -} + } -const _inverseMatrix$3 = /*@__PURE__*/ new Matrix4(); -const _ray$3 = /*@__PURE__*/ new Ray(); -const _sphere$6 = /*@__PURE__*/ new Sphere(); -const _sphereHitAt = /*@__PURE__*/ new Vector3(); + const position = this.attributes.position; + const morphAttributesPosition = this.morphAttributes.position; -const _vA$1 = /*@__PURE__*/ new Vector3(); -const _vB$1 = /*@__PURE__*/ new Vector3(); -const _vC$1 = /*@__PURE__*/ new Vector3(); + if ( position && position.isGLBufferAttribute ) { -const _tempA = /*@__PURE__*/ new Vector3(); -const _morphA = /*@__PURE__*/ new Vector3(); + error( 'BufferGeometry.computeBoundingSphere(): GLBufferAttribute requires a manual bounding sphere.', this ); -const _intersectionPoint = /*@__PURE__*/ new Vector3(); -const _intersectionPointWorld = /*@__PURE__*/ new Vector3(); + this.boundingSphere.set( new Vector3(), Infinity ); -/** - * Class representing triangular polygon mesh based objects. - * - * ```js - * const geometry = new THREE.BoxGeometry( 1, 1, 1 ); - * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); - * const mesh = new THREE.Mesh( geometry, material ); - * scene.add( mesh ); - * ``` - * - * @augments Object3D - */ -class Mesh extends Object3D { + return; - /** - * Constructs a new mesh. - * - * @param {BufferGeometry} [geometry] - The mesh geometry. - * @param {Material|Array} [material] - The mesh material. - */ - constructor( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) { + } - super(); + if ( position ) { - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isMesh = true; + // first, find the center of the bounding sphere - this.type = 'Mesh'; + const center = this.boundingSphere.center; - /** - * The mesh geometry. - * - * @type {BufferGeometry} - */ - this.geometry = geometry; + _box$2.setFromBufferAttribute( position ); - /** - * The mesh material. - * - * @type {Material|Array} - * @default MeshBasicMaterial - */ - this.material = material; + // process morph attributes if present - /** - * A dictionary representing the morph targets in the geometry. The key is the - * morph targets name, the value its attribute index. This member is `undefined` - * by default and only set when morph targets are detected in the geometry. - * - * @type {Object|undefined} - * @default undefined - */ - this.morphTargetDictionary = undefined; + if ( morphAttributesPosition ) { - /** - * An array of weights typically in the range `[0,1]` that specify how much of the morph - * is applied. This member is `undefined` by default and only set when morph targets are - * detected in the geometry. - * - * @type {Array|undefined} - * @default undefined - */ - this.morphTargetInfluences = undefined; + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - /** - * The number of instances of this mesh. - * Can only be used with {@link WebGPURenderer}. - * - * @type {number} - * @default 1 - */ - this.count = 1; + const morphAttribute = morphAttributesPosition[ i ]; + _boxMorphTargets.setFromBufferAttribute( morphAttribute ); - this.updateMorphTargets(); + if ( this.morphTargetsRelative ) { - } + _vector$9.addVectors( _box$2.min, _boxMorphTargets.min ); + _box$2.expandByPoint( _vector$9 ); - copy( source, recursive ) { + _vector$9.addVectors( _box$2.max, _boxMorphTargets.max ); + _box$2.expandByPoint( _vector$9 ); - super.copy( source, recursive ); + } else { - if ( source.morphTargetInfluences !== undefined ) { + _box$2.expandByPoint( _boxMorphTargets.min ); + _box$2.expandByPoint( _boxMorphTargets.max ); - this.morphTargetInfluences = source.morphTargetInfluences.slice(); + } - } + } - if ( source.morphTargetDictionary !== undefined ) { + } - this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); + _box$2.getCenter( center ); - } + // second, try to find a boundingSphere with a radius smaller than the + // boundingSphere of the boundingBox: sqrt(3) smaller in the best case - this.material = Array.isArray( source.material ) ? source.material.slice() : source.material; - this.geometry = source.geometry; + let maxRadiusSq = 0; - return this; + for ( let i = 0, il = position.count; i < il; i ++ ) { - } + _vector$9.fromBufferAttribute( position, i ); - /** - * Sets the values of {@link Mesh#morphTargetDictionary} and {@link Mesh#morphTargetInfluences} - * to make sure existing morph targets can influence this 3D object. - */ - updateMorphTargets() { + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$9 ) ); - const geometry = this.geometry; + } - const morphAttributes = geometry.morphAttributes; - const keys = Object.keys( morphAttributes ); + // process morph attributes if present - if ( keys.length > 0 ) { + if ( morphAttributesPosition ) { - const morphAttribute = morphAttributes[ keys[ 0 ] ]; + for ( let i = 0, il = morphAttributesPosition.length; i < il; i ++ ) { - if ( morphAttribute !== undefined ) { + const morphAttribute = morphAttributesPosition[ i ]; + const morphTargetsRelative = this.morphTargetsRelative; - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + for ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) { - for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) { + _vector$9.fromBufferAttribute( morphAttribute, j ); - const name = morphAttribute[ m ].name || String( m ); + if ( morphTargetsRelative ) { - this.morphTargetInfluences.push( 0 ); - this.morphTargetDictionary[ name ] = m; + _offset.fromBufferAttribute( position, j ); + _vector$9.add( _offset ); + + } + + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$9 ) ); + + } + + } + + } + + this.boundingSphere.radius = Math.sqrt( maxRadiusSq ); - } + if ( isNaN( this.boundingSphere.radius ) ) { + + error( 'BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.', this ); } @@ -20693,725 +18790,663 @@ class Mesh extends Object3D { } /** - * Returns the local-space position of the vertex at the given index, taking into - * account the current animation state of both morph targets and skinning. + * Calculates and adds a tangent attribute to this geometry. * - * @param {number} index - The vertex index. - * @param {Vector3} target - The target object that is used to store the method's result. - * @return {Vector3} The vertex position in local space. + * The computation is only supported for indexed geometries and if position, normal, and uv attributes + * are defined. When using a tangent space normal map, prefer the MikkTSpace algorithm provided by + * {@link BufferGeometryUtils#computeMikkTSpaceTangents} instead. */ - getVertexPosition( index, target ) { + computeTangents() { - const geometry = this.geometry; - const position = geometry.attributes.position; - const morphPosition = geometry.morphAttributes.position; - const morphTargetsRelative = geometry.morphTargetsRelative; + const index = this.index; + const attributes = this.attributes; - target.fromBufferAttribute( position, index ); + // based on http://www.terathon.com/code/tangent.html + // (per vertex tangents) - const morphInfluences = this.morphTargetInfluences; + if ( index === null || + attributes.position === undefined || + attributes.normal === undefined || + attributes.uv === undefined ) { - if ( morphPosition && morphInfluences ) { + error( 'BufferGeometry: .computeTangents() failed. Missing required attributes (index, position, normal or uv)' ); + return; - _morphA.set( 0, 0, 0 ); + } - for ( let i = 0, il = morphPosition.length; i < il; i ++ ) { + const positionAttribute = attributes.position; + const normalAttribute = attributes.normal; + const uvAttribute = attributes.uv; - const influence = morphInfluences[ i ]; - const morphAttribute = morphPosition[ i ]; + if ( this.hasAttribute( 'tangent' ) === false ) { - if ( influence === 0 ) continue; + this.setAttribute( 'tangent', new BufferAttribute( new Float32Array( 4 * positionAttribute.count ), 4 ) ); - _tempA.fromBufferAttribute( morphAttribute, index ); + } - if ( morphTargetsRelative ) { + const tangentAttribute = this.getAttribute( 'tangent' ); - _morphA.addScaledVector( _tempA, influence ); + const tan1 = [], tan2 = []; - } else { + for ( let i = 0; i < positionAttribute.count; i ++ ) { - _morphA.addScaledVector( _tempA.sub( target ), influence ); + tan1[ i ] = new Vector3(); + tan2[ i ] = new Vector3(); - } + } - } + const vA = new Vector3(), + vB = new Vector3(), + vC = new Vector3(), - target.add( _morphA ); + uvA = new Vector2(), + uvB = new Vector2(), + uvC = new Vector2(), - } + sdir = new Vector3(), + tdir = new Vector3(); - return target; + function handleTriangle( a, b, c ) { - } + vA.fromBufferAttribute( positionAttribute, a ); + vB.fromBufferAttribute( positionAttribute, b ); + vC.fromBufferAttribute( positionAttribute, c ); - /** - * Computes intersection points between a casted ray and this line. - * - * @param {Raycaster} raycaster - The raycaster. - * @param {Array} intersects - The target array that holds the intersection points. - */ - raycast( raycaster, intersects ) { + uvA.fromBufferAttribute( uvAttribute, a ); + uvB.fromBufferAttribute( uvAttribute, b ); + uvC.fromBufferAttribute( uvAttribute, c ); - const geometry = this.geometry; - const material = this.material; - const matrixWorld = this.matrixWorld; + vB.sub( vA ); + vC.sub( vA ); - if ( material === undefined ) return; + uvB.sub( uvA ); + uvC.sub( uvA ); - // test with bounding sphere in world space + const r = 1.0 / ( uvB.x * uvC.y - uvC.x * uvB.y ); - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + // silently ignore degenerate uv triangles having coincident or colinear vertices - _sphere$6.copy( geometry.boundingSphere ); - _sphere$6.applyMatrix4( matrixWorld ); + if ( ! isFinite( r ) ) return; - // check distance from ray origin to bounding sphere + sdir.copy( vB ).multiplyScalar( uvC.y ).addScaledVector( vC, - uvB.y ).multiplyScalar( r ); + tdir.copy( vC ).multiplyScalar( uvB.x ).addScaledVector( vB, - uvC.x ).multiplyScalar( r ); - _ray$3.copy( raycaster.ray ).recast( raycaster.near ); + tan1[ a ].add( sdir ); + tan1[ b ].add( sdir ); + tan1[ c ].add( sdir ); - if ( _sphere$6.containsPoint( _ray$3.origin ) === false ) { + tan2[ a ].add( tdir ); + tan2[ b ].add( tdir ); + tan2[ c ].add( tdir ); - if ( _ray$3.intersectSphere( _sphere$6, _sphereHitAt ) === null ) return; + } - if ( _ray$3.origin.distanceToSquared( _sphereHitAt ) > ( raycaster.far - raycaster.near ) ** 2 ) return; + let groups = this.groups; + + if ( groups.length === 0 ) { + + groups = [ { + start: 0, + count: index.count + } ]; } - // convert ray to local space of mesh + for ( let i = 0, il = groups.length; i < il; ++ i ) { - _inverseMatrix$3.copy( matrixWorld ).invert(); - _ray$3.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$3 ); + const group = groups[ i ]; - // test with bounding box in local space + const start = group.start; + const count = group.count; - if ( geometry.boundingBox !== null ) { + for ( let j = start, jl = start + count; j < jl; j += 3 ) { - if ( _ray$3.intersectsBox( geometry.boundingBox ) === false ) return; + handleTriangle( + index.getX( j + 0 ), + index.getX( j + 1 ), + index.getX( j + 2 ) + ); - } + } - // test for intersections with geometry + } - this._computeIntersections( raycaster, intersects, _ray$3 ); + const tmp = new Vector3(), tmp2 = new Vector3(); + const n = new Vector3(), n2 = new Vector3(); - } + function handleVertex( v ) { - _computeIntersections( raycaster, intersects, rayLocalSpace ) { + n.fromBufferAttribute( normalAttribute, v ); + n2.copy( n ); - let intersection; + const t = tan1[ v ]; - const geometry = this.geometry; - const material = this.material; + // Gram-Schmidt orthogonalize - const index = geometry.index; - const position = geometry.attributes.position; - const uv = geometry.attributes.uv; - const uv1 = geometry.attributes.uv1; - const normal = geometry.attributes.normal; - const groups = geometry.groups; - const drawRange = geometry.drawRange; + tmp.copy( t ); + tmp.sub( n.multiplyScalar( n.dot( t ) ) ).normalize(); - if ( index !== null ) { + // Calculate handedness - // indexed buffer geometry + tmp2.crossVectors( n2, t ); + const test = tmp2.dot( tan2[ v ] ); + const w = ( test < 0.0 ) ? -1 : 1.0; - if ( Array.isArray( material ) ) { + tangentAttribute.setXYZW( v, tmp.x, tmp.y, tmp.z, w ); - for ( let i = 0, il = groups.length; i < il; i ++ ) { + } - const group = groups[ i ]; - const groupMaterial = material[ group.materialIndex ]; + for ( let i = 0, il = groups.length; i < il; ++ i ) { - const start = Math.max( group.start, drawRange.start ); - const end = Math.min( index.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); + const group = groups[ i ]; - for ( let j = start, jl = end; j < jl; j += 3 ) { + const start = group.start; + const count = group.count; - const a = index.getX( j ); - const b = index.getX( j + 1 ); - const c = index.getX( j + 2 ); + for ( let j = start, jl = start + count; j < jl; j += 3 ) { - intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); + handleVertex( index.getX( j + 0 ) ); + handleVertex( index.getX( j + 1 ) ); + handleVertex( index.getX( j + 2 ) ); - if ( intersection ) { + } - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; - intersects.push( intersection ); + } - } + } - } + /** + * Computes vertex normals for the given vertex data. For indexed geometries, the method sets + * each vertex normal to be the average of the face normals of the faces that share that vertex. + * For non-indexed geometries, vertices are not shared, and the method sets each vertex normal + * to be the same as the face normal. + */ + computeVertexNormals() { - } + const index = this.index; + const positionAttribute = this.getAttribute( 'position' ); - } else { + if ( positionAttribute !== undefined ) { - const start = Math.max( 0, drawRange.start ); - const end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); + let normalAttribute = this.getAttribute( 'normal' ); - for ( let i = start, il = end; i < il; i += 3 ) { + if ( normalAttribute === undefined ) { - const a = index.getX( i ); - const b = index.getX( i + 1 ); - const c = index.getX( i + 2 ); + normalAttribute = new BufferAttribute( new Float32Array( positionAttribute.count * 3 ), 3 ); + this.setAttribute( 'normal', normalAttribute ); - intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); + } else { - if ( intersection ) { + // reset existing normals to zero - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics - intersects.push( intersection ); + for ( let i = 0, il = normalAttribute.count; i < il; i ++ ) { - } + normalAttribute.setXYZ( i, 0, 0, 0 ); } } - } else if ( position !== undefined ) { - - // non-indexed buffer geometry - - if ( Array.isArray( material ) ) { - - for ( let i = 0, il = groups.length; i < il; i ++ ) { + const pA = new Vector3(), pB = new Vector3(), pC = new Vector3(); + const nA = new Vector3(), nB = new Vector3(), nC = new Vector3(); + const cb = new Vector3(), ab = new Vector3(); - const group = groups[ i ]; - const groupMaterial = material[ group.materialIndex ]; + // indexed elements - const start = Math.max( group.start, drawRange.start ); - const end = Math.min( position.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); + if ( index ) { - for ( let j = start, jl = end; j < jl; j += 3 ) { + for ( let i = 0, il = index.count; i < il; i += 3 ) { - const a = j; - const b = j + 1; - const c = j + 2; + const vA = index.getX( i + 0 ); + const vB = index.getX( i + 1 ); + const vC = index.getX( i + 2 ); - intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); + pA.fromBufferAttribute( positionAttribute, vA ); + pB.fromBufferAttribute( positionAttribute, vB ); + pC.fromBufferAttribute( positionAttribute, vC ); - if ( intersection ) { + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; - intersects.push( intersection ); + nA.fromBufferAttribute( normalAttribute, vA ); + nB.fromBufferAttribute( normalAttribute, vB ); + nC.fromBufferAttribute( normalAttribute, vC ); - } + nA.add( cb ); + nB.add( cb ); + nC.add( cb ); - } + normalAttribute.setXYZ( vA, nA.x, nA.y, nA.z ); + normalAttribute.setXYZ( vB, nB.x, nB.y, nB.z ); + normalAttribute.setXYZ( vC, nC.x, nC.y, nC.z ); } } else { - const start = Math.max( 0, drawRange.start ); - const end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); - - for ( let i = start, il = end; i < il; i += 3 ) { - - const a = i; - const b = i + 1; - const c = i + 2; + // non-indexed elements (unconnected triangle soup) - intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); + for ( let i = 0, il = positionAttribute.count; i < il; i += 3 ) { - if ( intersection ) { + pA.fromBufferAttribute( positionAttribute, i + 0 ); + pB.fromBufferAttribute( positionAttribute, i + 1 ); + pC.fromBufferAttribute( positionAttribute, i + 2 ); - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics - intersects.push( intersection ); + cb.subVectors( pC, pB ); + ab.subVectors( pA, pB ); + cb.cross( ab ); - } + normalAttribute.setXYZ( i + 0, cb.x, cb.y, cb.z ); + normalAttribute.setXYZ( i + 1, cb.x, cb.y, cb.z ); + normalAttribute.setXYZ( i + 2, cb.x, cb.y, cb.z ); } } + this.normalizeNormals(); + + normalAttribute.needsUpdate = true; + } } -} + /** + * Ensures every normal vector in a geometry will have a magnitude of `1`. This will + * correct lighting on the geometry surfaces. + */ + normalizeNormals() { -function checkIntersection$1( object, material, raycaster, ray, pA, pB, pC, point ) { + const normals = this.attributes.normal; - let intersect; + for ( let i = 0, il = normals.count; i < il; i ++ ) { - if ( material.side === BackSide ) { + _vector$9.fromBufferAttribute( normals, i ); - intersect = ray.intersectTriangle( pC, pB, pA, true, point ); + _vector$9.normalize(); - } else { + normals.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - intersect = ray.intersectTriangle( pA, pB, pC, ( material.side === FrontSide ), point ); + } } - if ( intersect === null ) return null; + /** + * Return a new non-index version of this indexed geometry. If the geometry + * is already non-indexed, the method is a NOOP. + * + * @return {BufferGeometry} The non-indexed version of this indexed geometry. + */ + toNonIndexed() { - _intersectionPointWorld.copy( point ); - _intersectionPointWorld.applyMatrix4( object.matrixWorld ); + function convertBufferAttribute( attribute, indices ) { - const distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); + const array = attribute.array; + const itemSize = attribute.itemSize; + const normalized = attribute.normalized; - if ( distance < raycaster.near || distance > raycaster.far ) return null; + const array2 = new array.constructor( indices.length * itemSize ); - return { - distance: distance, - point: _intersectionPointWorld.clone(), - object: object - }; + let index = 0, index2 = 0; -} + for ( let i = 0, l = indices.length; i < l; i ++ ) { -function checkGeometryIntersection( object, material, raycaster, ray, uv, uv1, normal, a, b, c ) { + if ( attribute.isInterleavedBufferAttribute ) { - object.getVertexPosition( a, _vA$1 ); - object.getVertexPosition( b, _vB$1 ); - object.getVertexPosition( c, _vC$1 ); + index = indices[ i ] * attribute.data.stride + attribute.offset; - const intersection = checkIntersection$1( object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint ); + } else { - if ( intersection ) { + index = indices[ i ] * itemSize; - const barycoord = new Vector3(); - Triangle.getBarycoord( _intersectionPoint, _vA$1, _vB$1, _vC$1, barycoord ); + } - if ( uv ) { + for ( let j = 0; j < itemSize; j ++ ) { - intersection.uv = Triangle.getInterpolatedAttribute( uv, a, b, c, barycoord, new Vector2() ); + array2[ index2 ++ ] = array[ index ++ ]; - } + } - if ( uv1 ) { + } - intersection.uv1 = Triangle.getInterpolatedAttribute( uv1, a, b, c, barycoord, new Vector2() ); + return new BufferAttribute( array2, itemSize, normalized ); } - if ( normal ) { + // - intersection.normal = Triangle.getInterpolatedAttribute( normal, a, b, c, barycoord, new Vector3() ); + if ( this.index === null ) { - if ( intersection.normal.dot( ray.direction ) > 0 ) { + warn( 'BufferGeometry.toNonIndexed(): BufferGeometry is already non-indexed.' ); + return this; - intersection.normal.multiplyScalar( -1 ); + } - } + const geometry2 = new BufferGeometry(); - } + const indices = this.index.array; + const attributes = this.attributes; - const face = { - a: a, - b: b, - c: c, - normal: new Vector3(), - materialIndex: 0 - }; + // attributes + + for ( const name in attributes ) { - Triangle.getNormal( _vA$1, _vB$1, _vC$1, face.normal ); + const attribute = attributes[ name ]; - intersection.face = face; - intersection.barycoord = barycoord; + const newAttribute = convertBufferAttribute( attribute, indices ); - } + geometry2.setAttribute( name, newAttribute ); - return intersection; + } -} + // morph attributes -/** - * A geometry class for a rectangular cuboid with a given width, height, and depth. - * On creation, the cuboid is centred on the origin, with each edge parallel to one - * of the axes. - * - * ```js - * const geometry = new THREE.BoxGeometry( 1, 1, 1 ); - * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); - * const cube = new THREE.Mesh( geometry, material ); - * scene.add( cube ); - * ``` - * - * @augments BufferGeometry - * @demo scenes/geometry-browser.html#BoxGeometry - */ -class BoxGeometry extends BufferGeometry { + const morphAttributes = this.morphAttributes; - /** - * Constructs a new box geometry. - * - * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis. - * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis. - * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis. - * @param {number} [widthSegments=1] - Number of segmented rectangular faces along the width of the sides. - * @param {number} [heightSegments=1] - Number of segmented rectangular faces along the height of the sides. - * @param {number} [depthSegments=1] - Number of segmented rectangular faces along the depth of the sides. - */ - constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) { + for ( const name in morphAttributes ) { - super(); + const morphArray = []; + const morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes - this.type = 'BoxGeometry'; + for ( let i = 0, il = morphAttribute.length; i < il; i ++ ) { - /** - * Holds the constructor parameters that have been - * used to generate the geometry. Any modification - * after instantiation does not change the geometry. - * - * @type {Object} - */ - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; + const attribute = morphAttribute[ i ]; - const scope = this; + const newAttribute = convertBufferAttribute( attribute, indices ); - // segments + morphArray.push( newAttribute ); - widthSegments = Math.floor( widthSegments ); - heightSegments = Math.floor( heightSegments ); - depthSegments = Math.floor( depthSegments ); + } - // buffers + geometry2.morphAttributes[ name ] = morphArray; - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; + } - // helper variables + geometry2.morphTargetsRelative = this.morphTargetsRelative; - let numberOfVertices = 0; - let groupStart = 0; + // groups - // build each side of the box geometry + const groups = this.groups; - buildPlane( 'z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0 ); // px - buildPlane( 'z', 'y', 'x', 1, -1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx - buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py - buildPlane( 'x', 'z', 'y', 1, -1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny - buildPlane( 'x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4 ); // pz - buildPlane( 'x', 'y', 'z', -1, -1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz + for ( let i = 0, l = groups.length; i < l; i ++ ) { - // build geometry + const group = groups[ i ]; + geometry2.addGroup( group.start, group.count, group.materialIndex ); - this.setIndex( indices ); - this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + } - function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { + return geometry2; - const segmentWidth = width / gridX; - const segmentHeight = height / gridY; + } - const widthHalf = width / 2; - const heightHalf = height / 2; - const depthHalf = depth / 2; + /** + * Serializes the geometry into JSON. + * + * @return {Object} A JSON object representing the serialized geometry. + */ + toJSON() { - const gridX1 = gridX + 1; - const gridY1 = gridY + 1; + const data = { + metadata: { + version: 4.7, + type: 'BufferGeometry', + generator: 'BufferGeometry.toJSON' + } + }; - let vertexCounter = 0; - let groupCount = 0; + // standard BufferGeometry serialization - const vector = new Vector3(); + data.uuid = this.uuid; + data.type = this.type; + if ( this.name !== '' ) data.name = this.name; + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; - // generate vertices, normals and uvs + if ( this.parameters !== undefined ) { - for ( let iy = 0; iy < gridY1; iy ++ ) { + const parameters = this.parameters; - const y = iy * segmentHeight - heightHalf; + for ( const key in parameters ) { - for ( let ix = 0; ix < gridX1; ix ++ ) { + if ( parameters[ key ] !== undefined ) data[ key ] = parameters[ key ]; - const x = ix * segmentWidth - widthHalf; + } - // set values to correct vector component + return data; - vector[ u ] = x * udir; - vector[ v ] = y * vdir; - vector[ w ] = depthHalf; + } - // now apply vector to vertex buffer + // for simplicity the code assumes attributes are not shared across geometries, see #15811 - vertices.push( vector.x, vector.y, vector.z ); + data.data = { attributes: {} }; - // set values to correct vector component + const index = this.index; - vector[ u ] = 0; - vector[ v ] = 0; - vector[ w ] = depth > 0 ? 1 : -1; + if ( index !== null ) { - // now apply vector to normal buffer + data.data.index = { + type: index.array.constructor.name, + array: Array.prototype.slice.call( index.array ) + }; - normals.push( vector.x, vector.y, vector.z ); + } - // uvs + const attributes = this.attributes; - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + for ( const key in attributes ) { - // counters + const attribute = attributes[ key ]; - vertexCounter += 1; + data.data.attributes[ key ] = attribute.toJSON( data.data ); - } + } - } + const morphAttributes = {}; + let hasMorphAttributes = false; - // indices + for ( const key in this.morphAttributes ) { - // 1. you need three indices to draw a single face - // 2. a single segment consists of two faces - // 3. so we need to generate six (2*3) indices per segment + const attributeArray = this.morphAttributes[ key ]; - for ( let iy = 0; iy < gridY; iy ++ ) { + const array = []; - for ( let ix = 0; ix < gridX; ix ++ ) { + for ( let i = 0, il = attributeArray.length; i < il; i ++ ) { - const a = numberOfVertices + ix + gridX1 * iy; - const b = numberOfVertices + ix + gridX1 * ( iy + 1 ); - const c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); - const d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; + const attribute = attributeArray[ i ]; - // faces + array.push( attribute.toJSON( data.data ) ); - indices.push( a, b, d ); - indices.push( b, c, d ); + } - // increase counter + if ( array.length > 0 ) { - groupCount += 6; + morphAttributes[ key ] = array; - } + hasMorphAttributes = true; } - // add a group to the geometry. this will ensure multi material support + } - scope.addGroup( groupStart, groupCount, materialIndex ); + if ( hasMorphAttributes ) { - // calculate new start value for groups + data.data.morphAttributes = morphAttributes; + data.data.morphTargetsRelative = this.morphTargetsRelative; - groupStart += groupCount; + } - // update total number of vertices + const groups = this.groups; - numberOfVertices += vertexCounter; + if ( groups.length > 0 ) { + + data.data.groups = JSON.parse( JSON.stringify( groups ) ); } - } + const boundingSphere = this.boundingSphere; - copy( source ) { + if ( boundingSphere !== null ) { - super.copy( source ); + data.data.boundingSphere = boundingSphere.toJSON(); - this.parameters = Object.assign( {}, source.parameters ); + } - return this; + return data; } /** - * Factory method for creating an instance of this class from the given - * JSON object. + * Returns a new geometry with copied values from this instance. * - * @param {Object} data - A JSON object representing the serialized geometry. - * @return {BoxGeometry} A new instance. + * @return {BufferGeometry} A clone of this instance. */ - static fromJSON( data ) { + clone() { - return new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments ); + return new this.constructor().copy( this ); } -} + /** + * Copies the values of the given geometry to this instance. + * + * @param {BufferGeometry} source - The geometry to copy. + * @return {BufferGeometry} A reference to this instance. + */ + copy( source ) { -/** - * Provides utility functions for managing uniforms. - * - * @module UniformsUtils - */ + // reset -/** - * Clones the given uniform definitions by performing a deep-copy. That means - * if the value of a uniform refers to an object like a Vector3 or Texture, - * the cloned uniform will refer to a new object reference. - * - * @param {Object} src - An object representing uniform definitions. - * @return {Object} The cloned uniforms. - */ -function cloneUniforms( src ) { + this.index = null; + this.attributes = {}; + this.morphAttributes = {}; + this.groups = []; + this.boundingBox = null; + this.boundingSphere = null; - const dst = {}; + // used for storing cloned, shared data - for ( const u in src ) { + const data = {}; - dst[ u ] = {}; + // name - for ( const p in src[ u ] ) { + this.name = source.name; - const property = src[ u ][ p ]; + // index - if ( property && ( property.isColor || - property.isMatrix3 || property.isMatrix4 || - property.isVector2 || property.isVector3 || property.isVector4 || - property.isTexture || property.isQuaternion ) ) { + const index = source.index; - if ( property.isRenderTargetTexture ) { + if ( index !== null ) { - warn( 'UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms().' ); - dst[ u ][ p ] = null; + this.setIndex( index.clone() ); - } else { + } - dst[ u ][ p ] = property.clone(); + // attributes - } + const attributes = source.attributes; - } else if ( Array.isArray( property ) ) { + for ( const name in attributes ) { - dst[ u ][ p ] = property.slice(); + const attribute = attributes[ name ]; + this.setAttribute( name, attribute.clone( data ) ); - } else { + } - dst[ u ][ p ] = property; + // morph attributes - } + const morphAttributes = source.morphAttributes; - } + for ( const name in morphAttributes ) { - } + const array = []; + const morphAttribute = morphAttributes[ name ]; // morphAttribute: array of Float32BufferAttributes - return dst; + for ( let i = 0, l = morphAttribute.length; i < l; i ++ ) { -} + array.push( morphAttribute[ i ].clone( data ) ); -/** - * Merges the given uniform definitions into a single object. Since the - * method internally uses cloneUniforms(), it performs a deep-copy when - * producing the merged uniform definitions. - * - * @param {Array} uniforms - An array of objects containing uniform definitions. - * @return {Object} The merged uniforms. - */ -function mergeUniforms( uniforms ) { + } - const merged = {}; + this.morphAttributes[ name ] = array; - for ( let u = 0; u < uniforms.length; u ++ ) { + } - const tmp = cloneUniforms( uniforms[ u ] ); + this.morphTargetsRelative = source.morphTargetsRelative; - for ( const p in tmp ) { + // groups - merged[ p ] = tmp[ p ]; + const groups = source.groups; - } + for ( let i = 0, l = groups.length; i < l; i ++ ) { - } + const group = groups[ i ]; + this.addGroup( group.start, group.count, group.materialIndex ); - return merged; + } -} + // bounding box -function cloneUniformsGroups( src ) { + const boundingBox = source.boundingBox; - const dst = []; + if ( boundingBox !== null ) { - for ( let u = 0; u < src.length; u ++ ) { + this.boundingBox = boundingBox.clone(); - dst.push( src[ u ].clone() ); + } - } + // bounding sphere - return dst; + const boundingSphere = source.boundingSphere; -} + if ( boundingSphere !== null ) { -function getUnlitUniformColorSpace( renderer ) { + this.boundingSphere = boundingSphere.clone(); - const currentRenderTarget = renderer.getRenderTarget(); + } - if ( currentRenderTarget === null ) { + // draw range - // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 - return renderer.outputColorSpace; + this.drawRange.start = source.drawRange.start; + this.drawRange.count = source.drawRange.count; - } + // user data - // https://github.com/mrdoob/three.js/issues/27868 - if ( currentRenderTarget.isXRRenderTarget === true ) { + this.userData = source.userData; - return currentRenderTarget.texture.colorSpace; + return this; } - return ColorManagement.workingColorSpace; - -} - -// Legacy + /** + * Frees the GPU-related resources allocated by this instance. Call this + * method whenever this instance is no longer used in your app. + * + * @fires BufferGeometry#dispose + */ + dispose() { -const UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; + this.dispatchEvent( { type: 'dispose' } ); -var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; + } -var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; +} /** - * A material rendered with custom shaders. A shader is a small program written in GLSL. - * that runs on the GPU. You may want to use a custom shader if you need to implement an - * effect not included with any of the built-in materials. - * - * There are the following notes to bear in mind when using a `ShaderMaterial`: - * - * - `ShaderMaterial` can only be used with {@link WebGLRenderer}. - * - Built in attributes and uniforms are passed to the shaders along with your code. If - * you don't want that, use {@link RawShaderMaterial} instead. - * - You can use the directive `#pragma unroll_loop_start` and `#pragma unroll_loop_end` - * in order to unroll a `for` loop in GLSL by the shader preprocessor. The directive has - * to be placed right above the loop. The loop formatting has to correspond to a defined standard. - * - The loop has to be [normalized](https://en.wikipedia.org/wiki/Normalized_loop). - * - The loop variable has to be *i*. - * - The value `UNROLLED_LOOP_INDEX` will be replaced with the explicitly - * value of *i* for the given iteration and can be used in preprocessor - * statements. - * - * ```js - * const material = new THREE.ShaderMaterial( { - * uniforms: { - * time: { value: 1.0 }, - * resolution: { value: new THREE.Vector2() } - * }, - * vertexShader: document.getElementById( 'vertexShader' ).textContent, - * fragmentShader: document.getElementById( 'fragmentShader' ).textContent - * } ); - * ``` + * "Interleaved" means that multiple attributes, possibly of different types, + * (e.g., position, normal, uv, color) are packed into a single array buffer. * - * @augments Material + * An introduction into interleaved arrays can be found here: [Interleaved array basics](https://blog.tojicode.com/2011/05/interleaved-array-basics.html) */ -class ShaderMaterial extends Material { +class InterleavedBuffer { /** - * Constructs a new shader material. + * Constructs a new interleaved buffer. * - * @param {Object} [parameters] - An object with one or more properties - * defining the material's appearance. Any property of the material - * (including any property from inherited materials) can be passed - * in here. Color values can be passed any type of value accepted - * by {@link Color#set}. + * @param {TypedArray} array - A typed array with a shared buffer storing attribute data. + * @param {number} stride - The number of typed-array elements per vertex. */ - constructor( parameters ) { - - super(); + constructor( array, stride ) { /** * This flag can be used for type testing. @@ -21420,366 +19455,288 @@ class ShaderMaterial extends Material { * @readonly * @default true */ - this.isShaderMaterial = true; - - this.type = 'ShaderMaterial'; - - /** - * Defines custom constants using `#define` directives within the GLSL code - * for both the vertex shader and the fragment shader; each key/value pair - * yields another directive. - * ```js - * defines: { - * FOO: 15, - * BAR: true - * } - * ``` - * Yields the lines: - * ``` - * #define FOO 15 - * #define BAR true - * ``` - * - * @type {Object} - */ - this.defines = {}; - - /** - * An object of the form: - * ```js - * { - * "uniform1": { value: 1.0 }, - * "uniform2": { value: 2 } - * } - * ``` - * specifying the uniforms to be passed to the shader code; keys are uniform - * names, values are definitions of the form - * ``` - * { - * value: 1.0 - * } - * ``` - * where `value` is the value of the uniform. Names must match the name of - * the uniform, as defined in the GLSL code. Note that uniforms are refreshed - * on every frame, so updating the value of the uniform will immediately - * update the value available to the GLSL code. - * - * @type {Object} - */ - this.uniforms = {}; + this.isInterleavedBuffer = true; /** - * An array holding uniforms groups for configuring UBOs. + * A typed array with a shared buffer storing attribute data. * - * @type {Array} + * @type {TypedArray} */ - this.uniformsGroups = []; + this.array = array; /** - * Vertex shader GLSL code. This is the actual code for the shader. + * The number of typed-array elements per vertex. * - * @type {string} + * @type {number} */ - this.vertexShader = default_vertex; + this.stride = stride; /** - * Fragment shader GLSL code. This is the actual code for the shader. + * The total number of elements in the array * - * @type {string} + * @type {number} + * @readonly */ - this.fragmentShader = default_fragment; + this.count = array !== undefined ? array.length / stride : 0; /** - * Controls line thickness or lines. + * Defines the intended usage pattern of the data store for optimization purposes. * - * WebGL and WebGPU ignore this setting and always render line primitives with a - * width of one pixel. + * Note: After the initial use of a buffer, its usage cannot be changed. Instead, + * instantiate a new one and set the desired usage before the next render. * - * @type {number} - * @default 1 + * @type {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} + * @default StaticDrawUsage */ - this.linewidth = 1; + this.usage = StaticDrawUsage; /** - * Renders the geometry as a wireframe. + * This can be used to only update some components of stored vectors (for example, just the + * component related to color). Use the `addUpdateRange()` function to add ranges to this array. * - * @type {boolean} - * @default false + * @type {Array} */ - this.wireframe = false; + this.updateRanges = []; /** - * Controls the thickness of the wireframe. - * - * WebGL and WebGPU ignore this property and always render - * 1 pixel wide lines. + * A version number, incremented every time the `needsUpdate` is set to `true`. * * @type {number} - * @default 1 - */ - this.wireframeLinewidth = 1; - - /** - * Defines whether the material color is affected by global fog settings; `true` - * to pass fog uniforms to the shader. - * - * Setting this property to `true` requires the definition of fog uniforms. It is - * recommended to use `UniformsUtils.merge()` to combine the custom shader uniforms - * with predefined fog uniforms. - * - * ```js - * const material = new ShaderMaterial( { - * uniforms: UniformsUtils.merge( [ UniformsLib[ 'fog' ], shaderUniforms ] ); - * vertexShader: vertexShader, - * fragmentShader: fragmentShader, - * fog: true - * } ); - * ``` - * - * @type {boolean} - * @default false */ - this.fog = false; + this.version = 0; /** - * Defines whether this material uses lighting; `true` to pass uniform data - * related to lighting to this shader. + * The UUID of the interleaved buffer. * - * @type {boolean} - * @default false + * @type {string} + * @readonly */ - this.lights = false; + this.uuid = generateUUID(); - /** - * Defines whether this material supports clipping; `true` to let the renderer - * pass the clippingPlanes uniform. - * - * @type {boolean} - * @default false - */ - this.clipping = false; + } - /** - * Overwritten and set to `true` by default. - * - * @type {boolean} - * @default true - */ - this.forceSinglePass = true; + /** + * A callback function that is executed after the renderer has transferred the attribute array + * data to the GPU. + */ + onUploadCallback() {} - /** - * This object allows to enable certain WebGL 2 extensions. - * - * - clipCullDistance: set to `true` to use vertex shader clipping - * - multiDraw: set to `true` to use vertex shader multi_draw / enable gl_DrawID - * - * @type {{clipCullDistance:false,multiDraw:false}} - */ - this.extensions = { - clipCullDistance: false, // set to use vertex shader clipping - multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID - }; + /** + * Flag to indicate that this attribute has changed and should be re-sent to + * the GPU. Set this to `true` when you modify the value of the array. + * + * @type {number} + * @default false + * @param {boolean} value + */ + set needsUpdate( value ) { - /** - * When the rendered geometry doesn't include these attributes but the - * material does, these default values will be passed to the shaders. This - * avoids errors when buffer data is missing. - * - * - color: [ 1, 1, 1 ] - * - uv: [ 0, 0 ] - * - uv1: [ 0, 0 ] - * - * @type {Object} - */ - this.defaultAttributeValues = { - 'color': [ 1, 1, 1 ], - 'uv': [ 0, 0 ], - 'uv1': [ 0, 0 ] - }; + if ( value === true ) this.version ++; - /** - * If set, this calls [gl.bindAttribLocation](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation) - * to bind a generic vertex index to an attribute variable. - * - * @type {string|undefined} - * @default undefined - */ - this.index0AttributeName = undefined; + } - /** - * Can be used to force a uniform update while changing uniforms in - * {@link Object3D#onBeforeRender}. - * - * @type {boolean} - * @default false - */ - this.uniformsNeedUpdate = false; + /** + * Sets the usage of this interleaved buffer. + * + * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. + * @return {InterleavedBuffer} A reference to this interleaved buffer. + */ + setUsage( value ) { - /** - * Defines the GLSL version of custom shader code. - * - * @type {?(GLSL1|GLSL3)} - * @default null - */ - this.glslVersion = null; + this.usage = value; - if ( parameters !== undefined ) { + return this; - this.setValues( parameters ); + } - } + /** + * Adds a range of data in the data array to be updated on the GPU. + * + * @param {number} start - Position at which to start update. + * @param {number} count - The number of components to update. + */ + addUpdateRange( start, count ) { + + this.updateRanges.push( { start, count } ); } - copy( source ) { + /** + * Clears the update ranges. + */ + clearUpdateRanges() { - super.copy( source ); + this.updateRanges.length = 0; - this.fragmentShader = source.fragmentShader; - this.vertexShader = source.vertexShader; + } - this.uniforms = cloneUniforms( source.uniforms ); - this.uniformsGroups = cloneUniformsGroups( source.uniformsGroups ); + /** + * Copies the values of the given interleaved buffer to this instance. + * + * @param {InterleavedBuffer} source - The interleaved buffer to copy. + * @return {InterleavedBuffer} A reference to this instance. + */ + copy( source ) { - this.defines = Object.assign( {}, source.defines ); + this.array = new source.array.constructor( source.array ); + this.count = source.count; + this.stride = source.stride; + this.usage = source.usage; - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; + return this; - this.fog = source.fog; - this.lights = source.lights; - this.clipping = source.clipping; + } - this.extensions = Object.assign( {}, source.extensions ); + /** + * Copies a vector from the given interleaved buffer to this one. The start + * and destination position in the attribute buffers are represented by the + * given indices. + * + * @param {number} index1 - The destination index into this interleaved buffer. + * @param {InterleavedBuffer} interleavedBuffer - The interleaved buffer to copy from. + * @param {number} index2 - The source index into the given interleaved buffer. + * @return {InterleavedBuffer} A reference to this instance. + */ + copyAt( index1, interleavedBuffer, index2 ) { - this.glslVersion = source.glslVersion; + index1 *= this.stride; + index2 *= interleavedBuffer.stride; - this.defaultAttributeValues = Object.assign( {}, source.defaultAttributeValues ); + for ( let i = 0, l = this.stride; i < l; i ++ ) { - this.index0AttributeName = source.index0AttributeName; + this.array[ index1 + i ] = interleavedBuffer.array[ index2 + i ]; - this.uniformsNeedUpdate = source.uniformsNeedUpdate; + } return this; } - toJSON( meta ) { + /** + * Sets the given array data in the interleaved buffer. + * + * @param {(TypedArray|Array)} value - The array data to set. + * @param {number} [offset=0] - The offset in this interleaved buffer's array. + * @return {InterleavedBuffer} A reference to this instance. + */ + set( value, offset = 0 ) { - const data = super.toJSON( meta ); + this.array.set( value, offset ); - data.glslVersion = this.glslVersion; - data.uniforms = {}; + return this; - for ( const name in this.uniforms ) { + } - const uniform = this.uniforms[ name ]; - const value = uniform.value; + /** + * Returns a new interleaved buffer with copied values from this instance. + * + * @param {Object} [data] - An object with shared array buffers that allows to retain shared structures. + * @return {InterleavedBuffer} A clone of this instance. + */ + clone( data ) { - if ( value && value.isTexture ) { + if ( data.arrayBuffers === undefined ) { - data.uniforms[ name ] = { - type: 't', - value: value.toJSON( meta ).uuid - }; + data.arrayBuffers = {}; - } else if ( value && value.isColor ) { + } - data.uniforms[ name ] = { - type: 'c', - value: value.getHex() - }; + if ( this.array.buffer._uuid === undefined ) { - } else if ( value && value.isVector2 ) { + this.array.buffer._uuid = generateUUID(); - data.uniforms[ name ] = { - type: 'v2', - value: value.toArray() - }; + } - } else if ( value && value.isVector3 ) { + if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { - data.uniforms[ name ] = { - type: 'v3', - value: value.toArray() - }; + data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer; - } else if ( value && value.isVector4 ) { + } - data.uniforms[ name ] = { - type: 'v4', - value: value.toArray() - }; + const array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] ); - } else if ( value && value.isMatrix3 ) { + const ib = new this.constructor( array, this.stride ); + ib.setUsage( this.usage ); - data.uniforms[ name ] = { - type: 'm3', - value: value.toArray() - }; + return ib; - } else if ( value && value.isMatrix4 ) { + } - data.uniforms[ name ] = { - type: 'm4', - value: value.toArray() - }; + /** + * Sets the given callback function that is executed after the Renderer has transferred + * the array data to the GPU. Can be used to perform clean-up operations after + * the upload when data are not needed anymore on the CPU side. + * + * @param {Function} callback - The `onUpload()` callback. + * @return {InterleavedBuffer} A reference to this instance. + */ + onUpload( callback ) { - } else { + this.onUploadCallback = callback; - data.uniforms[ name ] = { - value: value - }; + return this; - // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far + } - } + /** + * Serializes the interleaved buffer into JSON. + * + * @param {Object} [data] - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized interleaved buffer. + */ + toJSON( data ) { + + if ( data.arrayBuffers === undefined ) { + + data.arrayBuffers = {}; } - if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines; + // generate UUID for array buffer if necessary - data.vertexShader = this.vertexShader; - data.fragmentShader = this.fragmentShader; + if ( this.array.buffer._uuid === undefined ) { - data.lights = this.lights; - data.clipping = this.clipping; + this.array.buffer._uuid = generateUUID(); - const extensions = {}; + } - for ( const key in this.extensions ) { + if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { - if ( this.extensions[ key ] === true ) extensions[ key ] = true; + data.arrayBuffers[ this.array.buffer._uuid ] = Array.from( new Uint32Array( this.array.buffer ) ); } - if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions; + // - return data; + return { + uuid: this.uuid, + buffer: this.array.buffer._uuid, + type: this.array.constructor.name, + stride: this.stride + }; } } -const _position$3 = /*@__PURE__*/ new Vector3(); -const _quaternion$2 = /*@__PURE__*/ new Quaternion(); -const _scale$2 = /*@__PURE__*/ new Vector3(); +const _vector$8 = /*@__PURE__*/ new Vector3(); /** - * Abstract base class for cameras. This class should always be inherited - * when you build a new camera. - * - * @abstract - * @augments Object3D + * An alternative version of a buffer attribute with interleaved data. Interleaved + * attributes share a common interleaved data storage ({@link InterleavedBuffer}) and refer with + * different offsets into the buffer. */ -class Camera extends Object3D { +class InterleavedBufferAttribute { /** - * Constructs a new camera. + * Constructs a new interleaved buffer attribute. + * + * @param {InterleavedBuffer} interleavedBuffer - The buffer holding the interleaved data. + * @param {number} itemSize - The item size. + * @param {number} offset - The attribute offset into the buffer. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - constructor() { - - super(); + constructor( interleavedBuffer, itemSize, offset, normalized = false ) { /** * This flag can be used for type testing. @@ -21788,811 +19745,540 @@ class Camera extends Object3D { * @readonly * @default true */ - this.isCamera = true; - - this.type = 'Camera'; + this.isInterleavedBufferAttribute = true; /** - * The inverse of the camera's world matrix. + * The name of the buffer attribute. * - * @type {Matrix4} + * @type {string} */ - this.matrixWorldInverse = new Matrix4(); + this.name = ''; /** - * The camera's projection matrix. + * The buffer holding the interleaved data. * - * @type {Matrix4} + * @type {InterleavedBuffer} */ - this.projectionMatrix = new Matrix4(); + this.data = interleavedBuffer; /** - * The inverse of the camera's projection matrix. + * The item size, see {@link BufferAttribute#itemSize}. * - * @type {Matrix4} + * @type {number} */ - this.projectionMatrixInverse = new Matrix4(); + this.itemSize = itemSize; /** - * The coordinate system in which the camera is used. + * The attribute offset into the buffer. * - * @type {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} + * @type {number} */ - this.coordinateSystem = WebGLCoordinateSystem; + this.offset = offset; - this._reversedDepth = false; + /** + * Whether the data are normalized or not, see {@link BufferAttribute#normalized} + * + * @type {InterleavedBuffer} + */ + this.normalized = normalized; } /** - * The flag that indicates whether the camera uses a reversed depth buffer. + * The item count of this buffer attribute. * - * @type {boolean} - * @default false + * @type {number} + * @readonly */ - get reversedDepth() { + get count() { - return this._reversedDepth; + return this.data.count; } - copy( source, recursive ) { - - super.copy( source, recursive ); - - this.matrixWorldInverse.copy( source.matrixWorldInverse ); - - this.projectionMatrix.copy( source.projectionMatrix ); - this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); - - this.coordinateSystem = source.coordinateSystem; + /** + * The array holding the interleaved buffer attribute data. + * + * @type {TypedArray} + */ + get array() { - return this; + return this.data.array; } /** - * Returns a vector representing the ("look") direction of the 3D object in world space. - * - * This method is overwritten since cameras have a different forward vector compared to other - * 3D objects. A camera looks down its local, negative z-axis by default. + * Flag to indicate that this attribute has changed and should be re-sent to + * the GPU. Set this to `true` when you modify the value of the array. * - * @param {Vector3} target - The target vector the result is stored to. - * @return {Vector3} The 3D object's direction in world space. + * @type {number} + * @default false + * @param {boolean} value */ - getWorldDirection( target ) { + set needsUpdate( value ) { - return super.getWorldDirection( target ).negate(); + this.data.needsUpdate = value; } - updateMatrixWorld( force ) { - - super.updateMatrixWorld( force ); - - // exclude scale from view matrix to be glTF conform - - this.matrixWorld.decompose( _position$3, _quaternion$2, _scale$2 ); + /** + * Applies the given 4x4 matrix to the given attribute. Only works with + * item size `3`. + * + * @param {Matrix4} m - The matrix to apply. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + applyMatrix4( m ) { - if ( _scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1 ) { + for ( let i = 0, l = this.data.count; i < l; i ++ ) { - this.matrixWorldInverse.copy( this.matrixWorld ).invert(); + _vector$8.fromBufferAttribute( this, i ); - } else { + _vector$8.applyMatrix4( m ); - this.matrixWorldInverse.compose( _position$3, _quaternion$2, _scale$2.set( 1, 1, 1 ) ).invert(); + this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); } - } - - updateWorldMatrix( updateParents, updateChildren ) { - - super.updateWorldMatrix( updateParents, updateChildren ); + return this; - // exclude scale from view matrix to be glTF conform + } - this.matrixWorld.decompose( _position$3, _quaternion$2, _scale$2 ); + /** + * Applies the given 3x3 normal matrix to the given attribute. Only works with + * item size `3`. + * + * @param {Matrix3} m - The normal matrix to apply. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + applyNormalMatrix( m ) { - if ( _scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1 ) { + for ( let i = 0, l = this.count; i < l; i ++ ) { - this.matrixWorldInverse.copy( this.matrixWorld ).invert(); + _vector$8.fromBufferAttribute( this, i ); - } else { + _vector$8.applyNormalMatrix( m ); - this.matrixWorldInverse.compose( _position$3, _quaternion$2, _scale$2.set( 1, 1, 1 ) ).invert(); + this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); } - } - - clone() { - - return new this.constructor().copy( this ); + return this; } -} - -const _v3$1 = /*@__PURE__*/ new Vector3(); -const _minTarget = /*@__PURE__*/ new Vector2(); -const _maxTarget = /*@__PURE__*/ new Vector2(); - -/** - * Camera that uses [perspective projection](https://en.wikipedia.org/wiki/Perspective_(graphical)). - * - * This projection mode is designed to mimic the way the human eye sees. It - * is the most common projection mode used for rendering a 3D scene. - * - * ```js - * const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); - * scene.add( camera ); - * ``` - * - * @augments Camera - */ -class PerspectiveCamera extends Camera { - /** - * Constructs a new perspective camera. + * Applies the given 4x4 matrix to the given attribute. Only works with + * item size `3` and with direction vectors. * - * @param {number} [fov=50] - The vertical field of view. - * @param {number} [aspect=1] - The aspect ratio. - * @param {number} [near=0.1] - The camera's near plane. - * @param {number} [far=2000] - The camera's far plane. + * @param {Matrix4} m - The matrix to apply. + * @return {InterleavedBufferAttribute} A reference to this instance. */ - constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) { - - super(); - - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isPerspectiveCamera = true; + transformDirection( m ) { - this.type = 'PerspectiveCamera'; + for ( let i = 0, l = this.count; i < l; i ++ ) { - /** - * The vertical field of view, from bottom to top of view, - * in degrees. - * - * @type {number} - * @default 50 - */ - this.fov = fov; + _vector$8.fromBufferAttribute( this, i ); - /** - * The zoom factor of the camera. - * - * @type {number} - * @default 1 - */ - this.zoom = 1; + _vector$8.transformDirection( m ); - /** - * The camera's near plane. The valid range is greater than `0` - * and less than the current value of {@link PerspectiveCamera#far}. - * - * Note that, unlike for the {@link OrthographicCamera}, `0` is not a - * valid value for a perspective camera's near plane. - * - * @type {number} - * @default 0.1 - */ - this.near = near; + this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); - /** - * The camera's far plane. Must be greater than the - * current value of {@link PerspectiveCamera#near}. - * - * @type {number} - * @default 2000 - */ - this.far = far; + } - /** - * Object distance used for stereoscopy and depth-of-field effects. This - * parameter does not influence the projection matrix unless a - * {@link StereoCamera} is being used. - * - * @type {number} - * @default 10 - */ - this.focus = 10; + return this; - /** - * The aspect ratio, usually the canvas width / canvas height. - * - * @type {number} - * @default 1 - */ - this.aspect = aspect; + } - /** - * Represents the frustum window specification. This property should not be edited - * directly but via {@link PerspectiveCamera#setViewOffset} and {@link PerspectiveCamera#clearViewOffset}. - * - * @type {?Object} - * @default null - */ - this.view = null; + /** + * Returns the given component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} component - The component index. + * @return {number} The returned value. + */ + getComponent( index, component ) { - /** - * Film size used for the larger axis. Default is `35` (millimeters). This - * parameter does not influence the projection matrix unless {@link PerspectiveCamera#filmOffset} - * is set to a nonzero value. - * - * @type {number} - * @default 35 - */ - this.filmGauge = 35; + let value = this.array[ index * this.data.stride + this.offset + component ]; - /** - * Horizontal off-center offset in the same unit as {@link PerspectiveCamera#filmGauge}. - * - * @type {number} - * @default 0 - */ - this.filmOffset = 0; + if ( this.normalized ) value = denormalize( value, this.array ); - this.updateProjectionMatrix(); + return value; } - copy( source, recursive ) { - - super.copy( source, recursive ); - - this.fov = source.fov; - this.zoom = source.zoom; - - this.near = source.near; - this.far = source.far; - this.focus = source.focus; + /** + * Sets the given value to the given component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} component - The component index. + * @param {number} value - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setComponent( index, component, value ) { - this.aspect = source.aspect; - this.view = source.view === null ? null : Object.assign( {}, source.view ); + if ( this.normalized ) value = normalize( value, this.array ); - this.filmGauge = source.filmGauge; - this.filmOffset = source.filmOffset; + this.data.array[ index * this.data.stride + this.offset + component ] = value; return this; } /** - * Sets the FOV by focal length in respect to the current {@link PerspectiveCamera#filmGauge}. - * - * The default film gauge is 35, so that the focal length can be specified for - * a 35mm (full frame) camera. + * Sets the x component of the vector at the given index. * - * @param {number} focalLength - Values for focal length and film gauge must have the same unit. + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. */ - setFocalLength( focalLength ) { + setX( index, x ) { - /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ - const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; + if ( this.normalized ) x = normalize( x, this.array ); - this.fov = RAD2DEG * 2 * Math.atan( vExtentSlope ); - this.updateProjectionMatrix(); + this.data.array[ index * this.data.stride + this.offset ] = x; + + return this; } /** - * Returns the focal length from the current {@link PerspectiveCamera#fov} and - * {@link PerspectiveCamera#filmGauge}. + * Sets the y component of the vector at the given index. * - * @return {number} The computed focal length. + * @param {number} index - The index into the buffer attribute. + * @param {number} y - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. */ - getFocalLength() { + setY( index, y ) { - const vExtentSlope = Math.tan( DEG2RAD * 0.5 * this.fov ); + if ( this.normalized ) y = normalize( y, this.array ); - return 0.5 * this.getFilmHeight() / vExtentSlope; + this.data.array[ index * this.data.stride + this.offset + 1 ] = y; + + return this; } /** - * Returns the current vertical field of view angle in degrees considering {@link PerspectiveCamera#zoom}. + * Sets the z component of the vector at the given index. * - * @return {number} The effective FOV. + * @param {number} index - The index into the buffer attribute. + * @param {number} z - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. */ - getEffectiveFOV() { - - return RAD2DEG * 2 * Math.atan( - Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom ); + setZ( index, z ) { - } + if ( this.normalized ) z = normalize( z, this.array ); - /** - * Returns the width of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or - * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. - * - * @return {number} The film width. - */ - getFilmWidth() { + this.data.array[ index * this.data.stride + this.offset + 2 ] = z; - // film not completely covered in portrait format (aspect < 1) - return this.filmGauge * Math.min( this.aspect, 1 ); + return this; } /** - * Returns the height of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or - * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. + * Sets the w component of the vector at the given index. * - * @return {number} The film width. + * @param {number} index - The index into the buffer attribute. + * @param {number} w - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. */ - getFilmHeight() { + setW( index, w ) { - // film not completely covered in landscape format (aspect > 1) - return this.filmGauge / Math.max( this.aspect, 1 ); + if ( this.normalized ) w = normalize( w, this.array ); + + this.data.array[ index * this.data.stride + this.offset + 3 ] = w; + + return this; } /** - * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. - * Sets `minTarget` and `maxTarget` to the coordinates of the lower-left and upper-right corners of the view rectangle. + * Returns the x component of the vector at the given index. * - * @param {number} distance - The viewing distance. - * @param {Vector2} minTarget - The lower-left corner of the view rectangle is written into this vector. - * @param {Vector2} maxTarget - The upper-right corner of the view rectangle is written into this vector. + * @param {number} index - The index into the buffer attribute. + * @return {number} The x component. */ - getViewBounds( distance, minTarget, maxTarget ) { - - _v3$1.set( -1, -1, 0.5 ).applyMatrix4( this.projectionMatrixInverse ); + getX( index ) { - minTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z ); + let x = this.data.array[ index * this.data.stride + this.offset ]; - _v3$1.set( 1, 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse ); + if ( this.normalized ) x = denormalize( x, this.array ); - maxTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z ); + return x; } /** - * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. + * Returns the y component of the vector at the given index. * - * @param {number} distance - The viewing distance. - * @param {Vector2} target - The target vector that is used to store result where x is width and y is height. - * @returns {Vector2} The view size. + * @param {number} index - The index into the buffer attribute. + * @return {number} The y component. */ - getViewSize( distance, target ) { + getY( index ) { - this.getViewBounds( distance, _minTarget, _maxTarget ); + let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; - return target.subVectors( _maxTarget, _minTarget ); + if ( this.normalized ) y = denormalize( y, this.array ); + + return y; } /** - * Sets an offset in a larger frustum. This is useful for multi-window or - * multi-monitor/multi-machine setups. - * - * For example, if you have 3x2 monitors and each monitor is 1920x1080 and - * the monitors are in grid like this - *``` - * +---+---+---+ - * | A | B | C | - * +---+---+---+ - * | D | E | F | - * +---+---+---+ - *``` - * then for each monitor you would call it like this: - *```js - * const w = 1920; - * const h = 1080; - * const fullWidth = w * 3; - * const fullHeight = h * 2; - * - * // --A-- - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * // --B-- - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * // --C-- - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * // --D-- - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * // --E-- - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * // --F-- - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - * ``` - * - * Note there is no reason monitors have to be the same size or in a grid. + * Returns the z component of the vector at the given index. * - * @param {number} fullWidth - The full width of multiview setup. - * @param {number} fullHeight - The full height of multiview setup. - * @param {number} x - The horizontal offset of the subcamera. - * @param {number} y - The vertical offset of the subcamera. - * @param {number} width - The width of subcamera. - * @param {number} height - The height of subcamera. + * @param {number} index - The index into the buffer attribute. + * @return {number} The z component. */ - setViewOffset( fullWidth, fullHeight, x, y, width, height ) { - - this.aspect = fullWidth / fullHeight; - - if ( this.view === null ) { - - this.view = { - enabled: true, - fullWidth: 1, - fullHeight: 1, - offsetX: 0, - offsetY: 0, - width: 1, - height: 1 - }; + getZ( index ) { - } + let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; - this.view.enabled = true; - this.view.fullWidth = fullWidth; - this.view.fullHeight = fullHeight; - this.view.offsetX = x; - this.view.offsetY = y; - this.view.width = width; - this.view.height = height; + if ( this.normalized ) z = denormalize( z, this.array ); - this.updateProjectionMatrix(); + return z; } /** - * Removes the view offset from the projection matrix. + * Returns the w component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The w component. */ - clearViewOffset() { - - if ( this.view !== null ) { + getW( index ) { - this.view.enabled = false; + let w = this.data.array[ index * this.data.stride + this.offset + 3 ]; - } + if ( this.normalized ) w = denormalize( w, this.array ); - this.updateProjectionMatrix(); + return w; } /** - * Updates the camera's projection matrix. Must be called after any change of - * camera properties. + * Sets the x and y component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @return {InterleavedBufferAttribute} A reference to this instance. */ - updateProjectionMatrix() { - - const near = this.near; - let top = near * Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom; - let height = 2 * top; - let width = this.aspect * height; - let left = -0.5 * width; - const view = this.view; + setXY( index, x, y ) { - if ( this.view !== null && this.view.enabled ) { + index = index * this.data.stride + this.offset; - const fullWidth = view.fullWidth, - fullHeight = view.fullHeight; + if ( this.normalized ) { - left += view.offsetX * width / fullWidth; - top -= view.offsetY * height / fullHeight; - width *= view.width / fullWidth; - height *= view.height / fullHeight; + x = normalize( x, this.array ); + y = normalize( y, this.array ); } - const skew = this.filmOffset; - if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); - - this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far, this.coordinateSystem, this.reversedDepth ); + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; - this.projectionMatrixInverse.copy( this.projectionMatrix ).invert(); + return this; } - toJSON( meta ) { - - const data = super.toJSON( meta ); + /** + * Sets the x, y and z component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @param {number} z - The value for the z component to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setXYZ( index, x, y, z ) { - data.object.fov = this.fov; - data.object.zoom = this.zoom; + index = index * this.data.stride + this.offset; - data.object.near = this.near; - data.object.far = this.far; - data.object.focus = this.focus; + if ( this.normalized ) { - data.object.aspect = this.aspect; + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); - if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); + } - data.object.filmGauge = this.filmGauge; - data.object.filmOffset = this.filmOffset; + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; + this.data.array[ index + 2 ] = z; - return data; + return this; } -} - -const fov = -90; // negative fov is not an error -const aspect = 1; - -/** - * A special type of camera that is positioned in 3D space to render its surroundings into a - * cube render target. The render target can then be used as an environment map for rendering - * realtime reflections in your scene. - * - * ```js - * // Create cube render target - * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 256, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); - * - * // Create cube camera - * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); - * scene.add( cubeCamera ); - * - * // Create car - * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); - * const car = new THREE.Mesh( carGeometry, chromeMaterial ); - * scene.add( car ); - * - * // Update the render target cube - * car.visible = false; - * cubeCamera.position.copy( car.position ); - * cubeCamera.update( renderer, scene ); - * - * // Render the scene - * car.visible = true; - * renderer.render( scene, camera ); - * ``` - * - * @augments Object3D - */ -class CubeCamera extends Object3D { - /** - * Constructs a new cube camera. + * Sets the x, y, z and w component of the vector at the given index. * - * @param {number} near - The camera's near plane. - * @param {number} far - The camera's far plane. - * @param {WebGLCubeRenderTarget} renderTarget - The cube render target. + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @param {number} z - The value for the z component to set. + * @param {number} w - The value for the w component to set. + * @return {InterleavedBufferAttribute} A reference to this instance. */ - constructor( near, far, renderTarget ) { - - super(); - - this.type = 'CubeCamera'; - - /** - * A reference to the cube render target. - * - * @type {WebGLCubeRenderTarget} - */ - this.renderTarget = renderTarget; - - /** - * The current active coordinate system. - * - * @type {?(WebGLCoordinateSystem|WebGPUCoordinateSystem)} - * @default null - */ - this.coordinateSystem = null; - - /** - * The current active mipmap level - * - * @type {number} - * @default 0 - */ - this.activeMipmapLevel = 0; + setXYZW( index, x, y, z, w ) { - const cameraPX = new PerspectiveCamera( fov, aspect, near, far ); - cameraPX.layers = this.layers; - this.add( cameraPX ); + index = index * this.data.stride + this.offset; - const cameraNX = new PerspectiveCamera( fov, aspect, near, far ); - cameraNX.layers = this.layers; - this.add( cameraNX ); + if ( this.normalized ) { - const cameraPY = new PerspectiveCamera( fov, aspect, near, far ); - cameraPY.layers = this.layers; - this.add( cameraPY ); + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); - const cameraNY = new PerspectiveCamera( fov, aspect, near, far ); - cameraNY.layers = this.layers; - this.add( cameraNY ); + } - const cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); - cameraPZ.layers = this.layers; - this.add( cameraPZ ); + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; + this.data.array[ index + 2 ] = z; + this.data.array[ index + 3 ] = w; - const cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); - cameraNZ.layers = this.layers; - this.add( cameraNZ ); + return this; } /** - * Must be called when the coordinate system of the cube camera is changed. + * Returns a new buffer attribute with copied values from this instance. + * + * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. + * + * @param {Object} [data] - An object with interleaved buffers that allows to retain the interleaved property. + * @return {BufferAttribute|InterleavedBufferAttribute} A clone of this instance. */ - updateCoordinateSystem() { - - const coordinateSystem = this.coordinateSystem; - - const cameras = this.children.concat(); - - const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = cameras; - - for ( const camera of cameras ) this.remove( camera ); - - if ( coordinateSystem === WebGLCoordinateSystem ) { - - cameraPX.up.set( 0, 1, 0 ); - cameraPX.lookAt( 1, 0, 0 ); + clone( data ) { - cameraNX.up.set( 0, 1, 0 ); - cameraNX.lookAt( -1, 0, 0 ); + if ( data === undefined ) { - cameraPY.up.set( 0, 0, -1 ); - cameraPY.lookAt( 0, 1, 0 ); + log( 'InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' ); - cameraNY.up.set( 0, 0, 1 ); - cameraNY.lookAt( 0, -1, 0 ); + const array = []; - cameraPZ.up.set( 0, 1, 0 ); - cameraPZ.lookAt( 0, 0, 1 ); + for ( let i = 0; i < this.count; i ++ ) { - cameraNZ.up.set( 0, 1, 0 ); - cameraNZ.lookAt( 0, 0, -1 ); + const index = i * this.data.stride + this.offset; - } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + for ( let j = 0; j < this.itemSize; j ++ ) { - cameraPX.up.set( 0, -1, 0 ); - cameraPX.lookAt( -1, 0, 0 ); + array.push( this.data.array[ index + j ] ); - cameraNX.up.set( 0, -1, 0 ); - cameraNX.lookAt( 1, 0, 0 ); + } - cameraPY.up.set( 0, 0, 1 ); - cameraPY.lookAt( 0, 1, 0 ); + } - cameraNY.up.set( 0, 0, -1 ); - cameraNY.lookAt( 0, -1, 0 ); + return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized ); - cameraPZ.up.set( 0, -1, 0 ); - cameraPZ.lookAt( 0, 0, 1 ); + } else { - cameraNZ.up.set( 0, -1, 0 ); - cameraNZ.lookAt( 0, 0, -1 ); + if ( data.interleavedBuffers === undefined ) { - } else { + data.interleavedBuffers = {}; - throw new Error( 'THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: ' + coordinateSystem ); + } - } + if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) { - for ( const camera of cameras ) { + data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data ); - this.add( camera ); + } - camera.updateMatrixWorld(); + return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized ); } } /** - * Calling this method will render the given scene with the given renderer - * into the cube render target of the camera. + * Serializes the buffer attribute into JSON. * - * @param {(Renderer|WebGLRenderer)} renderer - The renderer. - * @param {Scene} scene - The scene to render. + * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. + * + * @param {Object} [data] - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized buffer attribute. */ - update( renderer, scene ) { - - if ( this.parent === null ) this.updateMatrixWorld(); - - const { renderTarget, activeMipmapLevel } = this; - - if ( this.coordinateSystem !== renderer.coordinateSystem ) { + toJSON( data ) { - this.coordinateSystem = renderer.coordinateSystem; + if ( data === undefined ) { - this.updateCoordinateSystem(); + log( 'InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' ); - } + const array = []; - const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children; + for ( let i = 0; i < this.count; i ++ ) { - const currentRenderTarget = renderer.getRenderTarget(); - const currentActiveCubeFace = renderer.getActiveCubeFace(); - const currentActiveMipmapLevel = renderer.getActiveMipmapLevel(); + const index = i * this.data.stride + this.offset; - const currentXrEnabled = renderer.xr.enabled; + for ( let j = 0; j < this.itemSize; j ++ ) { - renderer.xr.enabled = false; + array.push( this.data.array[ index + j ] ); - const generateMipmaps = renderTarget.texture.generateMipmaps; + } - renderTarget.texture.generateMipmaps = false; + } - // https://github.com/mrdoob/three.js/issues/31413#issuecomment-3095966812 - const reversedDepthBuffer = !! ( renderer.isWebGLRenderer && renderer.state.buffers.depth.getReversed() ); + // de-interleave data and save it as an ordinary buffer attribute for now - renderer.setRenderTarget( renderTarget, 0, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraPX ); + return { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: array, + normalized: this.normalized + }; - renderer.setRenderTarget( renderTarget, 1, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraNX ); + } else { - renderer.setRenderTarget( renderTarget, 2, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraPY ); + // save as true interleaved attribute - renderer.setRenderTarget( renderTarget, 3, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraNY ); + if ( data.interleavedBuffers === undefined ) { - renderer.setRenderTarget( renderTarget, 4, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraPZ ); + data.interleavedBuffers = {}; - // mipmaps are generated during the last call of render() - // at this point, all sides of the cube render target are defined + } - renderTarget.texture.generateMipmaps = generateMipmaps; + if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) { - renderer.setRenderTarget( renderTarget, 5, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraNZ ); + data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data ); - renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel ); + } - renderer.xr.enabled = currentXrEnabled; + return { + isInterleavedBufferAttribute: true, + itemSize: this.itemSize, + data: this.data.uuid, + offset: this.offset, + normalized: this.normalized + }; - renderTarget.texture.needsPMREMUpdate = true; + } } } +let _materialId = 0; + /** - * Creates a cube texture made up of six images. - * - * ```js - * const loader = new THREE.CubeTextureLoader(); - * loader.setPath( 'textures/cube/pisa/' ); - * - * const textureCube = loader.load( [ - * 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' - * ] ); + * Abstract base class for materials. * - * const material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube } ); - * ``` + * Materials define the appearance of renderable 3D objects. * - * @augments Texture + * @abstract + * @augments EventDispatcher */ -class CubeTexture extends Texture { +class Material extends EventDispatcher { /** - * Constructs a new cube texture. - * - * @param {Array} [images=[]] - An array holding a image for each side of a cube. - * @param {number} [mapping=CubeReflectionMapping] - The texture mapping. - * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. - * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. - * @param {number} [magFilter=LinearFilter] - The mag filter value. - * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value. - * @param {number} [format=RGBAFormat] - The texture format. - * @param {number} [type=UnsignedByteType] - The texture type. - * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. - * @param {string} [colorSpace=NoColorSpace] - The color space value. + * Constructs a new material. */ - constructor( images = [], mapping = CubeReflectionMapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace ) { + constructor() { - super( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace ); + super(); /** * This flag can be used for type testing. @@ -22601,692 +20287,1018 @@ class CubeTexture extends Texture { * @readonly * @default true */ - this.isCubeTexture = true; + this.isMaterial = true; /** - * If set to `true`, the texture is flipped along the vertical axis when - * uploaded to the GPU. + * The ID of the material. * - * Overwritten and set to `false` by default. + * @name Material#id + * @type {number} + * @readonly + */ + Object.defineProperty( this, 'id', { value: _materialId ++ } ); + + /** + * The UUID of the material. * - * @type {boolean} - * @default false + * @type {string} + * @readonly */ - this.flipY = false; + this.uuid = generateUUID(); - } + /** + * The name of the material. + * + * @type {string} + */ + this.name = ''; - /** - * Alias for {@link CubeTexture#image}. - * - * @type {Array} - */ - get images() { + /** + * The type property is used for detecting the object type + * in context of serialization/deserialization. + * + * @type {string} + * @readonly + */ + this.type = 'Material'; - return this.image; + /** + * Defines the blending type of the material. + * + * It must be set to `CustomBlending` if custom blending properties like + * {@link Material#blendSrc}, {@link Material#blendDst} or {@link Material#blendEquation} + * should have any effect. + * + * @type {(NoBlending|NormalBlending|AdditiveBlending|SubtractiveBlending|MultiplyBlending|CustomBlending)} + * @default NormalBlending + */ + this.blending = NormalBlending; - } + /** + * Defines which side of faces will be rendered - front, back or both. + * + * @type {(FrontSide|BackSide|DoubleSide)} + * @default FrontSide + */ + this.side = FrontSide; - set images( value ) { + /** + * If set to `true`, vertex colors should be used. + * + * The engine supports RGB and RGBA vertex colors depending on whether a three (RGB) or + * four (RGBA) component color buffer attribute is used. + * + * @type {boolean} + * @default false + */ + this.vertexColors = false; - this.image = value; + /** + * Defines how transparent the material is. + * A value of `0.0` indicates fully transparent, `1.0` is fully opaque. + * + * If the {@link Material#transparent} is not set to `true`, + * the material will remain fully opaque and this value will only affect its color. + * + * @type {number} + * @default 1 + */ + this.opacity = 1; - } + /** + * Defines whether this material is transparent. This has an effect on + * rendering as transparent objects need special treatment and are rendered + * after non-transparent objects. + * + * When set to true, the extent to which the material is transparent is + * controlled by {@link Material#opacity}. + * + * @type {boolean} + * @default false + */ + this.transparent = false; -} + /** + * Enables alpha hashed transparency, an alternative to {@link Material#transparent} or + * {@link Material#alphaTest}. The material will not be rendered if opacity is lower than + * a random threshold. Randomization introduces some grain or noise, but approximates alpha + * blending without the associated problems of sorting. Using TAA can reduce the resulting noise. + * + * @type {boolean} + * @default false + */ + this.alphaHash = false; -/** - * A cube render target used in context of {@link WebGLRenderer}. - * - * @augments WebGLRenderTarget - */ -class WebGLCubeRenderTarget extends WebGLRenderTarget { + /** + * Defines the blending source factor. + * + * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} + * @default SrcAlphaFactor + */ + this.blendSrc = SrcAlphaFactor; - /** - * Constructs a new cube render target. - * - * @param {number} [size=1] - The size of the render target. - * @param {RenderTarget~Options} [options] - The configuration object. - */ - constructor( size = 1, options = {} ) { + /** + * Defines the blending destination factor. + * + * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} + * @default OneMinusSrcAlphaFactor + */ + this.blendDst = OneMinusSrcAlphaFactor; - super( size, size, options ); + /** + * Defines the blending equation. + * + * @type {(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)} + * @default AddEquation + */ + this.blendEquation = AddEquation; /** - * This flag can be used for type testing. + * Defines the blending source alpha factor. * - * @type {boolean} - * @readonly - * @default true + * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} + * @default null */ - this.isWebGLCubeRenderTarget = true; + this.blendSrcAlpha = null; - const image = { width: size, height: size, depth: 1 }; - const images = [ image, image, image, image, image, image ]; + /** + * Defines the blending destination alpha factor. + * + * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} + * @default null + */ + this.blendDstAlpha = null; /** - * Overwritten with a different texture type. + * Defines the blending equation of the alpha channel. * - * @type {DataArrayTexture} + * @type {?(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)} + * @default null */ - this.texture = new CubeTexture( images ); - this._setTextureOptions( options ); + this.blendEquationAlpha = null; - // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) - // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, - // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. + /** + * Represents the RGB values of the constant blend color. + * + * This property has only an effect when using custom blending with `ConstantColor` or `OneMinusConstantColor`. + * + * @type {Color} + * @default (0,0,0) + */ + this.blendColor = new Color( 0, 0, 0 ); - // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped - // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture - // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). + /** + * Represents the alpha value of the constant blend color. + * + * This property has only an effect when using custom blending with `ConstantAlpha` or `OneMinusConstantAlpha`. + * + * @type {number} + * @default 0 + */ + this.blendAlpha = 0; - this.texture.isRenderTargetTexture = true; + /** + * Defines the depth function. + * + * @type {(NeverDepth|AlwaysDepth|LessDepth|LessEqualDepth|EqualDepth|GreaterEqualDepth|GreaterDepth|NotEqualDepth)} + * @default LessEqualDepth + */ + this.depthFunc = LessEqualDepth; - } + /** + * Whether to have depth test enabled when rendering this material. + * When the depth test is disabled, the depth write will also be implicitly disabled. + * + * @type {boolean} + * @default true + */ + this.depthTest = true; - /** - * Converts the given equirectangular texture to a cube map. - * - * @param {WebGLRenderer} renderer - The renderer. - * @param {Texture} texture - The equirectangular texture. - * @return {WebGLCubeRenderTarget} A reference to this cube render target. - */ - fromEquirectangularTexture( renderer, texture ) { + /** + * Whether rendering this material has any effect on the depth buffer. + * + * When drawing 2D overlays it can be useful to disable the depth writing in + * order to layer several things together without creating z-index artifacts. + * + * @type {boolean} + * @default true + */ + this.depthWrite = true; - this.texture.type = texture.type; - this.texture.colorSpace = texture.colorSpace; + /** + * The bit mask to use when writing to the stencil buffer. + * + * @type {number} + * @default 0xff + */ + this.stencilWriteMask = 0xff; - this.texture.generateMipmaps = texture.generateMipmaps; - this.texture.minFilter = texture.minFilter; - this.texture.magFilter = texture.magFilter; + /** + * The stencil comparison function to use. + * + * @type {NeverStencilFunc|LessStencilFunc|EqualStencilFunc|LessEqualStencilFunc|GreaterStencilFunc|NotEqualStencilFunc|GreaterEqualStencilFunc|AlwaysStencilFunc} + * @default AlwaysStencilFunc + */ + this.stencilFunc = AlwaysStencilFunc; - const shader = { + /** + * The value to use when performing stencil comparisons or stencil operations. + * + * @type {number} + * @default 0 + */ + this.stencilRef = 0; - uniforms: { - tEquirect: { value: null }, - }, + /** + * The bit mask to use when comparing against the stencil buffer. + * + * @type {number} + * @default 0xff + */ + this.stencilFuncMask = 0xff; - vertexShader: /* glsl */` + /** + * Which stencil operation to perform when the comparison function returns `false`. + * + * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} + * @default KeepStencilOp + */ + this.stencilFail = KeepStencilOp; - varying vec3 vWorldDirection; + /** + * Which stencil operation to perform when the comparison function returns + * `true` but the depth test fails. + * + * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} + * @default KeepStencilOp + */ + this.stencilZFail = KeepStencilOp; - vec3 transformDirection( in vec3 dir, in mat4 matrix ) { + /** + * Which stencil operation to perform when the comparison function returns + * `true` and the depth test passes. + * + * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} + * @default KeepStencilOp + */ + this.stencilZPass = KeepStencilOp; - return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); + /** + * Whether stencil operations are performed against the stencil buffer. In + * order to perform writes or comparisons against the stencil buffer this + * value must be `true`. + * + * @type {boolean} + * @default false + */ + this.stencilWrite = false; - } + /** + * User-defined clipping planes specified as THREE.Plane objects in world + * space. These planes apply to the objects this material is attached to. + * Points in space whose signed distance to the plane is negative are clipped + * (not rendered). This requires {@link WebGLRenderer#localClippingEnabled} to + * be `true`. + * + * @type {?Array} + * @default null + */ + this.clippingPlanes = null; - void main() { + /** + * Changes the behavior of clipping planes so that only their intersection is + * clipped, rather than their union. + * + * @type {boolean} + * @default false + */ + this.clipIntersection = false; - vWorldDirection = transformDirection( position, modelMatrix ); + /** + * Defines whether to clip shadows according to the clipping planes specified + * on this material. + * + * @type {boolean} + * @default false + */ + this.clipShadows = false; - #include - #include + /** + * Defines which side of faces cast shadows. If `null`, the side casting shadows + * is determined as follows: + * + * - When {@link Material#side} is set to `FrontSide`, the back side cast shadows. + * - When {@link Material#side} is set to `BackSide`, the front side cast shadows. + * - When {@link Material#side} is set to `DoubleSide`, both sides cast shadows. + * + * @type {?(FrontSide|BackSide|DoubleSide)} + * @default null + */ + this.shadowSide = null; - } - `, + /** + * Whether to render the material's color. + * + * This can be used in conjunction with {@link Object3D#renderOder} to create invisible + * objects that occlude other objects. + * + * @type {boolean} + * @default true + */ + this.colorWrite = true; - fragmentShader: /* glsl */` + /** + * Override the renderer's default precision for this material. + * + * @type {?('highp'|'mediump'|'lowp')} + * @default null + */ + this.precision = null; - uniform sampler2D tEquirect; + /** + * Whether to use polygon offset or not. When enabled, each fragment's depth value will + * be offset after it is interpolated from the depth values of the appropriate vertices. + * The offset is added before the depth test is performed and before the value is written + * into the depth buffer. + * + * Can be useful for rendering hidden-line images, for applying decals to surfaces, and for + * rendering solids with highlighted edges. + * + * @type {boolean} + * @default false + */ + this.polygonOffset = false; - varying vec3 vWorldDirection; + /** + * Specifies a scale factor that is used to create a variable depth offset for each polygon. + * + * @type {number} + * @default 0 + */ + this.polygonOffsetFactor = 0; - #include + /** + * Is multiplied by an implementation-specific value to create a constant depth offset. + * + * @type {number} + * @default 0 + */ + this.polygonOffsetUnits = 0; - void main() { + /** + * Whether to apply dithering to the color to remove the appearance of banding. + * + * @type {boolean} + * @default false + */ + this.dithering = false; - vec3 direction = normalize( vWorldDirection ); + /** + * Whether alpha to coverage should be enabled or not. Can only be used with MSAA-enabled contexts + * (meaning when the renderer was created with *antialias* parameter set to `true`). Enabling this + * will smooth aliasing on clip plane edges and alphaTest-clipped edges. + * + * @type {boolean} + * @default false + */ + this.alphaToCoverage = false; - vec2 sampleUV = equirectUv( direction ); + /** + * Whether to premultiply the alpha (transparency) value. + * + * @type {boolean} + * @default false + */ + this.premultipliedAlpha = false; - gl_FragColor = texture2D( tEquirect, sampleUV ); + /** + * Whether double-sided, transparent objects should be rendered with a single pass or not. + * + * The engine renders double-sided, transparent objects with two draw calls (back faces first, + * then front faces) to mitigate transparency artifacts. There are scenarios however where this + * approach produces no quality gains but still doubles draw calls e.g. when rendering flat + * vegetation like grass sprites. In these cases, set the `forceSinglePass` flag to `true` to + * disable the two pass rendering to avoid performance issues. + * + * @type {boolean} + * @default false + */ + this.forceSinglePass = false; - } - ` - }; + /** + * Whether it's possible to override the material with {@link Scene#overrideMaterial} or not. + * + * @type {boolean} + * @default true + */ + this.allowOverride = true; - const geometry = new BoxGeometry( 5, 5, 5 ); + /** + * Defines whether 3D objects using this material are visible. + * + * @type {boolean} + * @default true + */ + this.visible = true; + + /** + * Defines whether this material is tone mapped according to the renderer's tone mapping setting. + * + * It is ignored when rendering to a render target or using post processing or when using + * `WebGPURenderer`. In all these cases, all materials are honored by tone mapping. + * + * @type {boolean} + * @default true + */ + this.toneMapped = true; - const material = new ShaderMaterial( { + /** + * An object that can be used to store custom data about the Material. It + * should not hold references to functions as these will not be cloned. + * + * @type {Object} + */ + this.userData = {}; - name: 'CubemapFromEquirect', + /** + * This starts at `0` and counts how many times {@link Material#needsUpdate} is set to `true`. + * + * @type {number} + * @readonly + * @default 0 + */ + this.version = 0; - uniforms: cloneUniforms( shader.uniforms ), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader, - side: BackSide, - blending: NoBlending + this._alphaTest = 0; - } ); + } - material.uniforms.tEquirect.value = texture; + /** + * Sets the alpha value to be used when running an alpha test. The material + * will not be rendered if the opacity is lower than this value. + * + * @type {number} + * @readonly + * @default 0 + */ + get alphaTest() { - const mesh = new Mesh( geometry, material ); + return this._alphaTest; - const currentMinFilter = texture.minFilter; + } - // Avoid blurred poles - if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter; + set alphaTest( value ) { - const camera = new CubeCamera( 1, 10, this ); - camera.update( renderer, mesh ); + if ( this._alphaTest > 0 !== value > 0 ) { - texture.minFilter = currentMinFilter; + this.version ++; - mesh.geometry.dispose(); - mesh.material.dispose(); + } - return this; + this._alphaTest = value; } /** - * Clears this cube render target. + * An optional callback that is executed immediately before the material is used to render a 3D object. + * + * This method can only be used when rendering with {@link WebGLRenderer}. * * @param {WebGLRenderer} renderer - The renderer. - * @param {boolean} [color=true] - Whether the color buffer should be cleared or not. - * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not. - * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not. + * @param {Scene} scene - The scene. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Object3D} object - The 3D object. + * @param {Object} group - The geometry group data. */ - clear( renderer, color = true, depth = true, stencil = true ) { - - const currentRenderTarget = renderer.getRenderTarget(); - - for ( let i = 0; i < 6; i ++ ) { - - renderer.setRenderTarget( this, i ); + onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {} - renderer.clear( color, depth, stencil ); + /** + * An optional callback that is executed immediately before the shader + * program is compiled. This function is called with the shader source code + * as a parameter. Useful for the modification of built-in materials. + * + * This method can only be used when rendering with {@link WebGLRenderer}. The + * recommended approach when customizing materials is to use `WebGPURenderer` with the new + * Node Material system and [TSL](https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language). + * + * @param {{vertexShader:string,fragmentShader:string,uniforms:Object}} shaderobject - The object holds the uniforms and the vertex and fragment shader source. + * @param {WebGLRenderer} renderer - A reference to the renderer. + */ + onBeforeCompile( /* shaderobject, renderer */ ) {} - } + /** + * In case {@link Material#onBeforeCompile} is used, this callback can be used to identify + * values of settings used in `onBeforeCompile()`, so three.js can reuse a cached + * shader or recompile the shader for this material as needed. + * + * This method can only be used when rendering with {@link WebGLRenderer}. + * + * @return {string} The custom program cache key. + */ + customProgramCacheKey() { - renderer.setRenderTarget( currentRenderTarget ); + return this.onBeforeCompile.toString(); } -} - -/** - * This is almost identical to an {@link Object3D}. Its purpose is to - * make working with groups of objects syntactically clearer. - * - * ```js - * // Create a group and add the two cubes. - * // These cubes can now be rotated / scaled etc as a group. - * const group = new THREE.Group(); - * - * group.add( meshA ); - * group.add( meshB ); - * - * scene.add( group ); - * ``` - * - * @augments Object3D - */ -class Group extends Object3D { + /** + * This method can be used to set default values from parameter objects. + * It is a generic implementation so it can be used with different types + * of materials. + * + * @param {Object} [values] - The material values to set. + */ + setValues( values ) { - constructor() { + if ( values === undefined ) return; - super(); + for ( const key in values ) { - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isGroup = true; + const newValue = values[ key ]; - this.type = 'Group'; + if ( newValue === undefined ) { - } + warn( `Material: parameter '${ key }' has value of undefined.` ); + continue; -} + } -const _moveEvent = { type: 'move' }; + const currentValue = this[ key ]; -/** - * Class for representing a XR controller with its - * different coordinate systems. - * - * @private - */ -class WebXRController { + if ( currentValue === undefined ) { - /** - * Constructs a new XR controller. - */ - constructor() { + warn( `Material: '${ key }' is not a property of THREE.${ this.type }.` ); + continue; - /** - * A group representing the target ray space - * of the XR controller. - * - * @private - * @type {?Group} - * @default null - */ - this._targetRay = null; + } - /** - * A group representing the grip space - * of the XR controller. - * - * @private - * @type {?Group} - * @default null - */ - this._grip = null; + if ( currentValue && currentValue.isColor ) { - /** - * A group representing the hand space - * of the XR controller. - * - * @private - * @type {?Group} - * @default null - */ - this._hand = null; + currentValue.set( newValue ); - } + } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { - /** - * Returns a group representing the hand space of the XR controller. - * - * @return {Group} A group representing the hand space of the XR controller. - */ - getHandSpace() { + currentValue.copy( newValue ); - if ( this._hand === null ) { + } else { - this._hand = new Group(); - this._hand.matrixAutoUpdate = false; - this._hand.visible = false; + this[ key ] = newValue; - this._hand.joints = {}; - this._hand.inputState = { pinching: false }; + } } - return this._hand; - } /** - * Returns a group representing the target ray space of the XR controller. + * Serializes the material into JSON. * - * @return {Group} A group representing the target ray space of the XR controller. + * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized material. + * @see {@link ObjectLoader#parse} */ - getTargetRaySpace() { + toJSON( meta ) { - if ( this._targetRay === null ) { + const isRootObject = ( meta === undefined || typeof meta === 'string' ); - this._targetRay = new Group(); - this._targetRay.matrixAutoUpdate = false; - this._targetRay.visible = false; - this._targetRay.hasLinearVelocity = false; - this._targetRay.linearVelocity = new Vector3(); - this._targetRay.hasAngularVelocity = false; - this._targetRay.angularVelocity = new Vector3(); + if ( isRootObject ) { + + meta = { + textures: {}, + images: {} + }; } - return this._targetRay; + const data = { + metadata: { + version: 4.7, + type: 'Material', + generator: 'Material.toJSON' + } + }; - } + // standard Material serialization + data.uuid = this.uuid; + data.type = this.type; - /** - * Returns a group representing the grip space of the XR controller. - * - * @return {Group} A group representing the grip space of the XR controller. - */ - getGripSpace() { + if ( this.name !== '' ) data.name = this.name; - if ( this._grip === null ) { + if ( this.color && this.color.isColor ) data.color = this.color.getHex(); - this._grip = new Group(); - this._grip.matrixAutoUpdate = false; - this._grip.visible = false; - this._grip.hasLinearVelocity = false; - this._grip.linearVelocity = new Vector3(); - this._grip.hasAngularVelocity = false; - this._grip.angularVelocity = new Vector3(); + if ( this.roughness !== undefined ) data.roughness = this.roughness; + if ( this.metalness !== undefined ) data.metalness = this.metalness; - } + if ( this.sheen !== undefined ) data.sheen = this.sheen; + if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex(); + if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness; + if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); + if ( this.emissiveIntensity !== undefined && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; - return this._grip; + if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); + if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity; + if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex(); + if ( this.shininess !== undefined ) data.shininess = this.shininess; + if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; + if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; - } + if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { - /** - * Dispatches the given event to the groups representing - * the different coordinate spaces of the XR controller. - * - * @param {Object} event - The event to dispatch. - * @return {WebXRController} A reference to this instance. - */ - dispatchEvent( event ) { + data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; - if ( this._targetRay !== null ) { + } - this._targetRay.dispatchEvent( event ); + if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { + + data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; } - if ( this._grip !== null ) { + if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { - this._grip.dispatchEvent( event ); + data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; + data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); } - if ( this._hand !== null ) { + if ( this.sheenColorMap && this.sheenColorMap.isTexture ) { - this._hand.dispatchEvent( event ); + data.sheenColorMap = this.sheenColorMap.toJSON( meta ).uuid; } - return this; + if ( this.sheenRoughnessMap && this.sheenRoughnessMap.isTexture ) { - } + data.sheenRoughnessMap = this.sheenRoughnessMap.toJSON( meta ).uuid; - /** - * Connects the controller with the given XR input source. - * - * @param {XRInputSource} inputSource - The input source. - * @return {WebXRController} A reference to this instance. - */ - connect( inputSource ) { + } - if ( inputSource && inputSource.hand ) { + if ( this.dispersion !== undefined ) data.dispersion = this.dispersion; - const hand = this._hand; + if ( this.iridescence !== undefined ) data.iridescence = this.iridescence; + if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR; + if ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange; - if ( hand ) { + if ( this.iridescenceMap && this.iridescenceMap.isTexture ) { - for ( const inputjoint of inputSource.hand.values() ) { + data.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid; - // Initialize hand with joints when connected - this._getHandJoint( hand, inputjoint ); + } - } + if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) { - } + data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid; } - this.dispatchEvent( { type: 'connected', data: inputSource } ); + if ( this.anisotropy !== undefined ) data.anisotropy = this.anisotropy; + if ( this.anisotropyRotation !== undefined ) data.anisotropyRotation = this.anisotropyRotation; - return this; + if ( this.anisotropyMap && this.anisotropyMap.isTexture ) { - } + data.anisotropyMap = this.anisotropyMap.toJSON( meta ).uuid; - /** - * Disconnects the controller from the given XR input source. - * - * @param {XRInputSource} inputSource - The input source. - * @return {WebXRController} A reference to this instance. - */ - disconnect( inputSource ) { + } - this.dispatchEvent( { type: 'disconnected', data: inputSource } ); + if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; + if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; + if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; - if ( this._targetRay !== null ) { + if ( this.lightMap && this.lightMap.isTexture ) { - this._targetRay.visible = false; + data.lightMap = this.lightMap.toJSON( meta ).uuid; + data.lightMapIntensity = this.lightMapIntensity; } - if ( this._grip !== null ) { + if ( this.aoMap && this.aoMap.isTexture ) { - this._grip.visible = false; + data.aoMap = this.aoMap.toJSON( meta ).uuid; + data.aoMapIntensity = this.aoMapIntensity; } - if ( this._hand !== null ) { + if ( this.bumpMap && this.bumpMap.isTexture ) { - this._hand.visible = false; + data.bumpMap = this.bumpMap.toJSON( meta ).uuid; + data.bumpScale = this.bumpScale; } - return this; + if ( this.normalMap && this.normalMap.isTexture ) { - } + data.normalMap = this.normalMap.toJSON( meta ).uuid; + data.normalMapType = this.normalMapType; + data.normalScale = this.normalScale.toArray(); - /** - * Updates the controller with the given input source, XR frame and reference space. - * This updates the transformations of the groups that represent the different - * coordinate systems of the controller. - * - * @param {XRInputSource} inputSource - The input source. - * @param {XRFrame} frame - The XR frame. - * @param {XRReferenceSpace} referenceSpace - The reference space. - * @return {WebXRController} A reference to this instance. - */ - update( inputSource, frame, referenceSpace ) { + } - let inputPose = null; - let gripPose = null; - let handPose = null; + if ( this.displacementMap && this.displacementMap.isTexture ) { - const targetRay = this._targetRay; - const grip = this._grip; - const hand = this._hand; + data.displacementMap = this.displacementMap.toJSON( meta ).uuid; + data.displacementScale = this.displacementScale; + data.displacementBias = this.displacementBias; - if ( inputSource && frame.session.visibilityState !== 'visible-blurred' ) { + } - if ( hand && inputSource.hand ) { + if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; + if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; - handPose = true; + if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; + if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; + if ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid; + if ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid; - for ( const inputjoint of inputSource.hand.values() ) { + if ( this.envMap && this.envMap.isTexture ) { - // Update the joints groups with the XRJoint poses - const jointPose = frame.getJointPose( inputjoint, referenceSpace ); + data.envMap = this.envMap.toJSON( meta ).uuid; - // The transform of this joint will be updated with the joint pose on each frame - const joint = this._getHandJoint( hand, inputjoint ); + if ( this.combine !== undefined ) data.combine = this.combine; - if ( jointPose !== null ) { + } - joint.matrix.fromArray( jointPose.transform.matrix ); - joint.matrix.decompose( joint.position, joint.rotation, joint.scale ); - joint.matrixWorldNeedsUpdate = true; - joint.jointRadius = jointPose.radius; + if ( this.envMapRotation !== undefined ) data.envMapRotation = this.envMapRotation.toArray(); + if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; + if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity; + if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio; - } + if ( this.gradientMap && this.gradientMap.isTexture ) { - joint.visible = jointPose !== null; + data.gradientMap = this.gradientMap.toJSON( meta ).uuid; - } + } - // Custom events + if ( this.transmission !== undefined ) data.transmission = this.transmission; + if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid; + if ( this.thickness !== undefined ) data.thickness = this.thickness; + if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid; + if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance; + if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex(); - // Check pinchz - const indexTip = hand.joints[ 'index-finger-tip' ]; - const thumbTip = hand.joints[ 'thumb-tip' ]; - const distance = indexTip.position.distanceTo( thumbTip.position ); + if ( this.size !== undefined ) data.size = this.size; + if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide; + if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; - const distanceToPinch = 0.02; - const threshold = 0.005; + if ( this.blending !== NormalBlending ) data.blending = this.blending; + if ( this.side !== FrontSide ) data.side = this.side; + if ( this.vertexColors === true ) data.vertexColors = true; - if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) { + if ( this.opacity < 1 ) data.opacity = this.opacity; + if ( this.transparent === true ) data.transparent = true; - hand.inputState.pinching = false; - this.dispatchEvent( { - type: 'pinchend', - handedness: inputSource.handedness, - target: this - } ); + if ( this.blendSrc !== SrcAlphaFactor ) data.blendSrc = this.blendSrc; + if ( this.blendDst !== OneMinusSrcAlphaFactor ) data.blendDst = this.blendDst; + if ( this.blendEquation !== AddEquation ) data.blendEquation = this.blendEquation; + if ( this.blendSrcAlpha !== null ) data.blendSrcAlpha = this.blendSrcAlpha; + if ( this.blendDstAlpha !== null ) data.blendDstAlpha = this.blendDstAlpha; + if ( this.blendEquationAlpha !== null ) data.blendEquationAlpha = this.blendEquationAlpha; + if ( this.blendColor && this.blendColor.isColor ) data.blendColor = this.blendColor.getHex(); + if ( this.blendAlpha !== 0 ) data.blendAlpha = this.blendAlpha; - } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) { + if ( this.depthFunc !== LessEqualDepth ) data.depthFunc = this.depthFunc; + if ( this.depthTest === false ) data.depthTest = this.depthTest; + if ( this.depthWrite === false ) data.depthWrite = this.depthWrite; + if ( this.colorWrite === false ) data.colorWrite = this.colorWrite; - hand.inputState.pinching = true; - this.dispatchEvent( { - type: 'pinchstart', - handedness: inputSource.handedness, - target: this - } ); + if ( this.stencilWriteMask !== 0xff ) data.stencilWriteMask = this.stencilWriteMask; + if ( this.stencilFunc !== AlwaysStencilFunc ) data.stencilFunc = this.stencilFunc; + if ( this.stencilRef !== 0 ) data.stencilRef = this.stencilRef; + if ( this.stencilFuncMask !== 0xff ) data.stencilFuncMask = this.stencilFuncMask; + if ( this.stencilFail !== KeepStencilOp ) data.stencilFail = this.stencilFail; + if ( this.stencilZFail !== KeepStencilOp ) data.stencilZFail = this.stencilZFail; + if ( this.stencilZPass !== KeepStencilOp ) data.stencilZPass = this.stencilZPass; + if ( this.stencilWrite === true ) data.stencilWrite = this.stencilWrite; - } + // rotation (SpriteMaterial) + if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation; - } else { + if ( this.polygonOffset === true ) data.polygonOffset = true; + if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; + if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; - if ( grip !== null && inputSource.gripSpace ) { + if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth; + if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; + if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; + if ( this.scale !== undefined ) data.scale = this.scale; - gripPose = frame.getPose( inputSource.gripSpace, referenceSpace ); + if ( this.dithering === true ) data.dithering = true; + + if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; + if ( this.alphaHash === true ) data.alphaHash = true; + if ( this.alphaToCoverage === true ) data.alphaToCoverage = true; + if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true; + if ( this.forceSinglePass === true ) data.forceSinglePass = true; + if ( this.allowOverride === false ) data.allowOverride = false; + + if ( this.wireframe === true ) data.wireframe = true; + if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; + if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; + if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; - if ( gripPose !== null ) { + if ( this.flatShading === true ) data.flatShading = true; - grip.matrix.fromArray( gripPose.transform.matrix ); - grip.matrix.decompose( grip.position, grip.rotation, grip.scale ); - grip.matrixWorldNeedsUpdate = true; + if ( this.visible === false ) data.visible = false; - if ( gripPose.linearVelocity ) { + if ( this.toneMapped === false ) data.toneMapped = false; - grip.hasLinearVelocity = true; - grip.linearVelocity.copy( gripPose.linearVelocity ); + if ( this.fog === false ) data.fog = false; - } else { + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; - grip.hasLinearVelocity = false; + // TODO: Copied from Object3D.toJSON - } + function extractFromCache( cache ) { - if ( gripPose.angularVelocity ) { + const values = []; - grip.hasAngularVelocity = true; - grip.angularVelocity.copy( gripPose.angularVelocity ); + for ( const key in cache ) { - } else { + const data = cache[ key ]; + delete data.metadata; + values.push( data ); - grip.hasAngularVelocity = false; + } - } + return values; - } + } - } + if ( isRootObject ) { - } + const textures = extractFromCache( meta.textures ); + const images = extractFromCache( meta.images ); - if ( targetRay !== null ) { + if ( textures.length > 0 ) data.textures = textures; + if ( images.length > 0 ) data.images = images; - inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); + } - // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it - if ( inputPose === null && gripPose !== null ) { + return data; - inputPose = gripPose; + } - } + /** + * Returns a new material with copied values from this instance. + * + * @return {Material} A clone of this instance. + */ + clone() { - if ( inputPose !== null ) { + return new this.constructor().copy( this ); - targetRay.matrix.fromArray( inputPose.transform.matrix ); - targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale ); - targetRay.matrixWorldNeedsUpdate = true; + } - if ( inputPose.linearVelocity ) { + /** + * Copies the values of the given material to this instance. + * + * @param {Material} source - The material to copy. + * @return {Material} A reference to this instance. + */ + copy( source ) { - targetRay.hasLinearVelocity = true; - targetRay.linearVelocity.copy( inputPose.linearVelocity ); + this.name = source.name; - } else { + this.blending = source.blending; + this.side = source.side; + this.vertexColors = source.vertexColors; - targetRay.hasLinearVelocity = false; + this.opacity = source.opacity; + this.transparent = source.transparent; - } + this.blendSrc = source.blendSrc; + this.blendDst = source.blendDst; + this.blendEquation = source.blendEquation; + this.blendSrcAlpha = source.blendSrcAlpha; + this.blendDstAlpha = source.blendDstAlpha; + this.blendEquationAlpha = source.blendEquationAlpha; + this.blendColor.copy( source.blendColor ); + this.blendAlpha = source.blendAlpha; - if ( inputPose.angularVelocity ) { + this.depthFunc = source.depthFunc; + this.depthTest = source.depthTest; + this.depthWrite = source.depthWrite; - targetRay.hasAngularVelocity = true; - targetRay.angularVelocity.copy( inputPose.angularVelocity ); + this.stencilWriteMask = source.stencilWriteMask; + this.stencilFunc = source.stencilFunc; + this.stencilRef = source.stencilRef; + this.stencilFuncMask = source.stencilFuncMask; + this.stencilFail = source.stencilFail; + this.stencilZFail = source.stencilZFail; + this.stencilZPass = source.stencilZPass; + this.stencilWrite = source.stencilWrite; - } else { + const srcPlanes = source.clippingPlanes; + let dstPlanes = null; - targetRay.hasAngularVelocity = false; + if ( srcPlanes !== null ) { - } + const n = srcPlanes.length; + dstPlanes = new Array( n ); - this.dispatchEvent( _moveEvent ); + for ( let i = 0; i !== n; ++ i ) { - } + dstPlanes[ i ] = srcPlanes[ i ].clone(); } - } - if ( targetRay !== null ) { + this.clippingPlanes = dstPlanes; + this.clipIntersection = source.clipIntersection; + this.clipShadows = source.clipShadows; - targetRay.visible = ( inputPose !== null ); + this.shadowSide = source.shadowSide; - } + this.colorWrite = source.colorWrite; - if ( grip !== null ) { + this.precision = source.precision; - grip.visible = ( gripPose !== null ); + this.polygonOffset = source.polygonOffset; + this.polygonOffsetFactor = source.polygonOffsetFactor; + this.polygonOffsetUnits = source.polygonOffsetUnits; - } + this.dithering = source.dithering; - if ( hand !== null ) { + this.alphaTest = source.alphaTest; + this.alphaHash = source.alphaHash; + this.alphaToCoverage = source.alphaToCoverage; + this.premultipliedAlpha = source.premultipliedAlpha; + this.forceSinglePass = source.forceSinglePass; + this.allowOverride = source.allowOverride; - hand.visible = ( handPose !== null ); + this.visible = source.visible; - } + this.toneMapped = source.toneMapped; + + this.userData = JSON.parse( JSON.stringify( source.userData ) ); return this; } /** - * Returns a group representing the hand joint for the given input joint. + * Frees the GPU-related resources allocated by this instance. Call this + * method whenever this instance is no longer used in your app. * - * @private - * @param {Group} hand - The group representing the hand space. - * @param {XRJointSpace} inputjoint - The hand joint data. - * @return {Group} A group representing the hand joint for the given input joint. + * @fires Material#dispose */ - _getHandJoint( hand, inputjoint ) { - - if ( hand.joints[ inputjoint.jointName ] === undefined ) { + dispose() { - const joint = new Group(); - joint.matrixAutoUpdate = false; - joint.visible = false; - hand.joints[ inputjoint.jointName ] = joint; + /** + * Fires when the material has been disposed of. + * + * @event Material#dispose + * @type {Object} + */ + this.dispatchEvent( { type: 'dispose' } ); - hand.add( joint ); + } - } + /** + * Setting this property to `true` indicates the engine the material + * needs to be recompiled. + * + * @type {boolean} + * @default false + * @param {boolean} value + */ + set needsUpdate( value ) { - return hand.joints[ inputjoint.jointName ]; + if ( value === true ) this.version ++; } } /** - * This class can be used to define an exponential squared fog, - * which gives a clear view near the camera and a faster than exponentially - * densening fog farther from the camera. + * A material for rendering instances of {@link Sprite}. * * ```js - * const scene = new THREE.Scene(); - * scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 ); + * const map = new THREE.TextureLoader().load( 'textures/sprite.png' ); + * const material = new THREE.SpriteMaterial( { map: map, color: 0xffffff } ); + * + * const sprite = new THREE.Sprite( material ); + * sprite.scale.set(200, 200, 1) + * scene.add( sprite ); * ``` + * + * @augments Material */ -class FogExp2 { +class SpriteMaterial extends Material { /** - * Constructs a new fog. + * Constructs a new sprite material. * - * @param {number|Color} color - The fog's color. - * @param {number} [density=0.00025] - Defines how fast the fog will grow dense. + * @param {Object} [parameters] - An object with one or more properties + * defining the material's appearance. Any property of the material + * (including any property from inherited materials) can be passed + * in here. Color values can be passed any type of value accepted + * by {@link Color#set}. */ - constructor( color, density = 0.00025 ) { + constructor( parameters ) { + + super(); /** * This flag can be used for type testing. @@ -23295,169 +21307,145 @@ class FogExp2 { * @readonly * @default true */ - this.isFogExp2 = true; + this.isSpriteMaterial = true; - /** - * The name of the fog. - * - * @type {string} - */ - this.name = ''; + this.type = 'SpriteMaterial'; /** - * The fog's color. + * Color of the material. * * @type {Color} + * @default (1,1,1) */ - this.color = new Color( color ); + this.color = new Color( 0xffffff ); /** - * Defines how fast the fog will grow dense. + * The color map. May optionally include an alpha channel, typically combined + * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map + * color is modulated by the diffuse `color`. * - * @type {number} - * @default 0.00025 + * @type {?Texture} + * @default null */ - this.density = density; - - } - - /** - * Returns a new fog with copied values from this instance. - * - * @return {FogExp2} A clone of this instance. - */ - clone() { - - return new FogExp2( this.color, this.density ); - - } - - /** - * Serializes the fog into JSON. - * - * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized fog - */ - toJSON( /* meta */ ) { - - return { - type: 'FogExp2', - name: this.name, - color: this.color.getHex(), - density: this.density - }; - - } - -} - -/** - * This class can be used to define a linear fog that grows linearly denser - * with the distance. - * - * ```js - * const scene = new THREE.Scene(); - * scene.fog = new THREE.Fog( 0xcccccc, 10, 15 ); - * ``` - */ -class Fog { - - /** - * Constructs a new fog. - * - * @param {number|Color} color - The fog's color. - * @param {number} [near=1] - The minimum distance to start applying fog. - * @param {number} [far=1000] - The maximum distance at which fog stops being calculated and applied. - */ - constructor( color, near = 1, far = 1000 ) { + this.map = null; /** - * This flag can be used for type testing. + * The alpha map is a grayscale texture that controls the opacity across the + * surface (black: fully transparent; white: fully opaque). * - * @type {boolean} - * @readonly - * @default true + * Only the color of the texture is used, ignoring the alpha channel if one + * exists. For RGB and RGBA textures, the renderer will use the green channel + * when sampling this texture due to the extra bit of precision provided for + * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and + * luminance/alpha textures will also still work as expected. + * + * @type {?Texture} + * @default null */ - this.isFog = true; + this.alphaMap = null; /** - * The name of the fog. + * The rotation of the sprite in radians. * - * @type {string} + * @type {number} + * @default 0 */ - this.name = ''; + this.rotation = 0; /** - * The fog's color. + * Specifies whether size of the sprite is attenuated by the camera depth (perspective camera only). * - * @type {Color} + * @type {boolean} + * @default true */ - this.color = new Color( color ); + this.sizeAttenuation = true; /** - * The minimum distance to start applying fog. Objects that are less than - * `near` units from the active camera won't be affected by fog. + * Overwritten since sprite materials are transparent + * by default. * - * @type {number} - * @default 1 + * @type {boolean} + * @default true */ - this.near = near; + this.transparent = true; /** - * The maximum distance at which fog stops being calculated and applied. - * Objects that are more than `far` units away from the active camera won't - * be affected by fog. + * Whether the material is affected by fog or not. * - * @type {number} - * @default 1000 + * @type {boolean} + * @default true */ - this.far = far; + this.fog = true; + + this.setValues( parameters ); } - /** - * Returns a new fog with copied values from this instance. - * - * @return {Fog} A clone of this instance. - */ - clone() { + copy( source ) { - return new Fog( this.color, this.near, this.far ); + super.copy( source ); - } + this.color.copy( source.color ); - /** - * Serializes the fog into JSON. - * - * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized fog - */ - toJSON( /* meta */ ) { + this.map = source.map; - return { - type: 'Fog', - name: this.name, - color: this.color.getHex(), - near: this.near, - far: this.far - }; + this.alphaMap = source.alphaMap; + + this.rotation = source.rotation; + + this.sizeAttenuation = source.sizeAttenuation; + + this.fog = source.fog; + + return this; } } +let _geometry; + +const _intersectPoint = /*@__PURE__*/ new Vector3(); +const _worldScale = /*@__PURE__*/ new Vector3(); +const _mvPosition = /*@__PURE__*/ new Vector3(); + +const _alignedPosition = /*@__PURE__*/ new Vector2(); +const _rotatedPosition = /*@__PURE__*/ new Vector2(); +const _viewWorldMatrix = /*@__PURE__*/ new Matrix4(); + +const _vA$1 = /*@__PURE__*/ new Vector3(); +const _vB$1 = /*@__PURE__*/ new Vector3(); +const _vC$1 = /*@__PURE__*/ new Vector3(); + +const _uvA = /*@__PURE__*/ new Vector2(); +const _uvB = /*@__PURE__*/ new Vector2(); +const _uvC = /*@__PURE__*/ new Vector2(); + /** - * Scenes allow you to set up what is to be rendered and where by three.js. - * This is where you place 3D objects like meshes, lines or lights. + * A sprite is a plane that always faces towards the camera, generally with a + * partially transparent texture applied. + * + * Sprites do not cast shadows, setting {@link Object3D#castShadow} to `true` will + * have no effect. + * + * ```js + * const map = new THREE.TextureLoader().load( 'sprite.png' ); + * const material = new THREE.SpriteMaterial( { map: map } ); + * + * const sprite = new THREE.Sprite( material ); + * scene.add( sprite ); + * ``` * * @augments Object3D */ -class Scene extends Object3D { +class Sprite extends Object3D { /** - * Constructs a new scene. + * Constructs a new sprite. + * + * @param {(SpriteMaterial|SpriteNodeMaterial)} [material] - The sprite material. */ - constructor() { + constructor( material = new SpriteMaterial() ) { super(); @@ -23468,160 +21456,223 @@ class Scene extends Object3D { * @readonly * @default true */ - this.isScene = true; + this.isSprite = true; - this.type = 'Scene'; + this.type = 'Sprite'; + + if ( _geometry === undefined ) { + + _geometry = new BufferGeometry(); + + const float32Array = new Float32Array( [ + -0.5, -0.5, 0, 0, 0, + 0.5, -0.5, 0, 1, 0, + 0.5, 0.5, 0, 1, 1, + -0.5, 0.5, 0, 0, 1 + ] ); + + const interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); + + _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); + _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); + _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + + } /** - * Defines the background of the scene. Valid inputs are: - * - * - A color for defining a uniform colored background. - * - A texture for defining a (flat) textured background. - * - Cube textures or equirectangular textures for defining a skybox. + * The sprite geometry. * - * @type {?(Color|Texture)} - * @default null + * @type {BufferGeometry} */ - this.background = null; + this.geometry = _geometry; /** - * Sets the environment map for all physical materials in the scene. However, - * it's not possible to overwrite an existing texture assigned to the `envMap` - * material property. + * The sprite material. * - * @type {?Texture} - * @default null + * @type {(SpriteMaterial|SpriteNodeMaterial)} */ - this.environment = null; + this.material = material; /** - * A fog instance defining the type of fog that affects everything - * rendered in the scene. + * The sprite's anchor point, and the point around which the sprite rotates. + * A value of `(0.5, 0.5)` corresponds to the midpoint of the sprite. A value + * of `(0, 0)` corresponds to the lower left corner of the sprite. * - * @type {?(Fog|FogExp2)} - * @default null + * @type {Vector2} + * @default (0.5,0.5) */ - this.fog = null; + this.center = new Vector2( 0.5, 0.5 ); /** - * Sets the blurriness of the background. Only influences environment maps - * assigned to {@link Scene#background}. Valid input is a float between `0` - * and `1`. + * The number of instances of this sprite. + * Can only be used with {@link WebGPURenderer}. * * @type {number} - * @default 0 + * @default 1 */ - this.backgroundBlurriness = 0; + this.count = 1; + + } + + /** + * Computes intersection points between a casted ray and this sprite. + * + * @param {Raycaster} raycaster - The raycaster. + * @param {Array} intersects - The target array that holds the intersection points. + */ + raycast( raycaster, intersects ) { + + if ( raycaster.camera === null ) { + + error( 'Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' ); + + } + + _worldScale.setFromMatrixScale( this.matrixWorld ); + + _viewWorldMatrix.copy( raycaster.camera.matrixWorld ); + this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld ); + + _mvPosition.setFromMatrixPosition( this.modelViewMatrix ); + + if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) { + + _worldScale.multiplyScalar( - _mvPosition.z ); + + } + + const rotation = this.material.rotation; + let sin, cos; + + if ( rotation !== 0 ) { + + cos = Math.cos( rotation ); + sin = Math.sin( rotation ); - /** - * Attenuates the color of the background. Only applies to background textures. - * - * @type {number} - * @default 1 - */ - this.backgroundIntensity = 1; + } - /** - * The rotation of the background in radians. Only influences environment maps - * assigned to {@link Scene#background}. - * - * @type {Euler} - * @default (0,0,0) - */ - this.backgroundRotation = new Euler(); + const center = this.center; - /** - * Attenuates the color of the environment. Only influences environment maps - * assigned to {@link Scene#environment}. - * - * @type {number} - * @default 1 - */ - this.environmentIntensity = 1; + transformVertex( _vA$1.set( -0.5, -0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + transformVertex( _vB$1.set( 0.5, -0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + transformVertex( _vC$1.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - /** - * The rotation of the environment map in radians. Only influences physical materials - * in the scene when {@link Scene#environment} is used. - * - * @type {Euler} - * @default (0,0,0) - */ - this.environmentRotation = new Euler(); + _uvA.set( 0, 0 ); + _uvB.set( 1, 0 ); + _uvC.set( 1, 1 ); - /** - * Forces everything in the scene to be rendered with the defined material. It is possible - * to exclude materials from override by setting {@link Material#allowOverride} to `false`. - * - * @type {?Material} - * @default null - */ - this.overrideMaterial = null; + // check first triangle + let intersect = raycaster.ray.intersectTriangle( _vA$1, _vB$1, _vC$1, false, _intersectPoint ); - if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + if ( intersect === null ) { - __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); + // check second triangle + transformVertex( _vB$1.set( -0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + _uvB.set( 0, 1 ); + + intersect = raycaster.ray.intersectTriangle( _vA$1, _vC$1, _vB$1, false, _intersectPoint ); + if ( intersect === null ) { + + return; + + } } - } + const distance = raycaster.ray.origin.distanceTo( _intersectPoint ); - copy( source, recursive ) { + if ( distance < raycaster.near || distance > raycaster.far ) return; - super.copy( source, recursive ); + intersects.push( { - if ( source.background !== null ) this.background = source.background.clone(); - if ( source.environment !== null ) this.environment = source.environment.clone(); - if ( source.fog !== null ) this.fog = source.fog.clone(); + distance: distance, + point: _intersectPoint.clone(), + uv: Triangle.getInterpolation( _intersectPoint, _vA$1, _vB$1, _vC$1, _uvA, _uvB, _uvC, new Vector2() ), + face: null, + object: this - this.backgroundBlurriness = source.backgroundBlurriness; - this.backgroundIntensity = source.backgroundIntensity; - this.backgroundRotation.copy( source.backgroundRotation ); + } ); - this.environmentIntensity = source.environmentIntensity; - this.environmentRotation.copy( source.environmentRotation ); + } - if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); + copy( source, recursive ) { - this.matrixAutoUpdate = source.matrixAutoUpdate; + super.copy( source, recursive ); + + if ( source.center !== undefined ) this.center.copy( source.center ); + + this.material = source.material; return this; } - toJSON( meta ) { +} - const data = super.toJSON( meta ); +function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { - if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); + // compute position in camera space + _alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); - if ( this.backgroundBlurriness > 0 ) data.object.backgroundBlurriness = this.backgroundBlurriness; - if ( this.backgroundIntensity !== 1 ) data.object.backgroundIntensity = this.backgroundIntensity; - data.object.backgroundRotation = this.backgroundRotation.toArray(); + // to check if rotation is not zero + if ( sin !== undefined ) { - if ( this.environmentIntensity !== 1 ) data.object.environmentIntensity = this.environmentIntensity; - data.object.environmentRotation = this.environmentRotation.toArray(); + _rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y ); + _rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y ); - return data; + } else { + + _rotatedPosition.copy( _alignedPosition ); } + + vertexPosition.copy( mvPosition ); + vertexPosition.x += _rotatedPosition.x; + vertexPosition.y += _rotatedPosition.y; + + // transform to world space + vertexPosition.applyMatrix4( _viewWorldMatrix ); + } +const _v1$2 = /*@__PURE__*/ new Vector3(); +const _v2$1 = /*@__PURE__*/ new Vector3(); + /** - * "Interleaved" means that multiple attributes, possibly of different types, - * (e.g., position, normal, uv, color) are packed into a single array buffer. + * A component for providing a basic Level of Detail (LOD) mechanism. * - * An introduction into interleaved arrays can be found here: [Interleaved array basics](https://blog.tojicode.com/2011/05/interleaved-array-basics.html) + * Every LOD level is associated with an object, and rendering can be switched + * between them at the distances specified. Typically you would create, say, + * three meshes, one for far away (low detail), one for mid range (medium + * detail) and one for close up (high detail). + * + * ```js + * const lod = new THREE.LOD(); + * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + * + * //Create spheres with 3 levels of detail and create new LOD levels for them + * for( let i = 0; i < 3; i++ ) { + * + * const geometry = new THREE.IcosahedronGeometry( 10, 3 - i ); + * const mesh = new THREE.Mesh( geometry, material ); + * lod.addLevel( mesh, i * 75 ); + * + * } + * + * scene.add( lod ); + * ``` + * + * @augments Object3D */ -class InterleavedBuffer { +class LOD extends Object3D { /** - * Constructs a new interleaved buffer. - * - * @param {TypedArray} array - A typed array with a shared buffer storing attribute data. - * @param {number} stride - The number of typed-array elements per vertex. + * Constructs a new LOD. */ - constructor( array, stride ) { + constructor() { + + super(); /** * This flag can be used for type testing. @@ -23630,830 +21681,949 @@ class InterleavedBuffer { * @readonly * @default true */ - this.isInterleavedBuffer = true; - - /** - * A typed array with a shared buffer storing attribute data. - * - * @type {TypedArray} - */ - this.array = array; + this.isLOD = true; /** - * The number of typed-array elements per vertex. + * The current LOD index. * + * @private * @type {number} + * @default 0 */ - this.stride = stride; + this._currentLevel = 0; - /** - * The total number of elements in the array - * - * @type {number} - * @readonly - */ - this.count = array !== undefined ? array.length / stride : 0; + this.type = 'LOD'; - /** - * Defines the intended usage pattern of the data store for optimization purposes. - * - * Note: After the initial use of a buffer, its usage cannot be changed. Instead, - * instantiate a new one and set the desired usage before the next render. - * - * @type {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} - * @default StaticDrawUsage - */ - this.usage = StaticDrawUsage; + Object.defineProperties( this, { + /** + * This array holds the LOD levels. + * + * @name LOD#levels + * @type {Array<{object:Object3D,distance:number,hysteresis:number}>} + */ + levels: { + enumerable: true, + value: [] + } + } ); /** - * This can be used to only update some components of stored vectors (for example, just the - * component related to color). Use the `addUpdateRange()` function to add ranges to this array. + * Whether the LOD object is updated automatically by the renderer per frame + * or not. If set to `false`, you have to call {@link LOD#update} in the + * render loop by yourself. * - * @type {Array} + * @type {boolean} + * @default true */ - this.updateRanges = []; + this.autoUpdate = true; - /** - * A version number, incremented every time the `needsUpdate` is set to `true`. - * - * @type {number} - */ - this.version = 0; + } - /** - * The UUID of the interleaved buffer. - * - * @type {string} - * @readonly - */ - this.uuid = generateUUID(); + copy( source ) { - } + super.copy( source, false ); - /** - * A callback function that is executed after the renderer has transferred the attribute array - * data to the GPU. - */ - onUploadCallback() {} + const levels = source.levels; - /** - * Flag to indicate that this attribute has changed and should be re-sent to - * the GPU. Set this to `true` when you modify the value of the array. - * - * @type {number} - * @default false - * @param {boolean} value - */ - set needsUpdate( value ) { + for ( let i = 0, l = levels.length; i < l; i ++ ) { - if ( value === true ) this.version ++; + const level = levels[ i ]; - } + this.addLevel( level.object.clone(), level.distance, level.hysteresis ); - /** - * Sets the usage of this interleaved buffer. - * - * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. - * @return {InterleavedBuffer} A reference to this interleaved buffer. - */ - setUsage( value ) { + } - this.usage = value; + this.autoUpdate = source.autoUpdate; return this; } /** - * Adds a range of data in the data array to be updated on the GPU. + * Adds a mesh that will display at a certain distance and greater. Typically + * the further away the distance, the lower the detail on the mesh. * - * @param {number} start - Position at which to start update. - * @param {number} count - The number of components to update. + * @param {Object3D} object - The 3D object to display at this level. + * @param {number} [distance=0] - The distance at which to display this level of detail. + * @param {number} [hysteresis=0] - Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. + * @return {LOD} A reference to this instance. */ - addUpdateRange( start, count ) { + addLevel( object, distance = 0, hysteresis = 0 ) { - this.updateRanges.push( { start, count } ); + distance = Math.abs( distance ); - } + const levels = this.levels; - /** - * Clears the update ranges. - */ - clearUpdateRanges() { + let l; - this.updateRanges.length = 0; + for ( l = 0; l < levels.length; l ++ ) { - } + if ( distance < levels[ l ].distance ) { - /** - * Copies the values of the given interleaved buffer to this instance. - * - * @param {InterleavedBuffer} source - The interleaved buffer to copy. - * @return {InterleavedBuffer} A reference to this instance. - */ - copy( source ) { + break; - this.array = new source.array.constructor( source.array ); - this.count = source.count; - this.stride = source.stride; - this.usage = source.usage; + } + + } + + levels.splice( l, 0, { distance: distance, hysteresis: hysteresis, object: object } ); + + this.add( object ); return this; } /** - * Copies a vector from the given interleaved buffer to this one. The start - * and destination position in the attribute buffers are represented by the - * given indices. + * Removes an existing level, based on the distance from the camera. + * Returns `true` when the level has been removed. Otherwise `false`. * - * @param {number} index1 - The destination index into this interleaved buffer. - * @param {InterleavedBuffer} interleavedBuffer - The interleaved buffer to copy from. - * @param {number} index2 - The source index into the given interleaved buffer. - * @return {InterleavedBuffer} A reference to this instance. + * @param {number} distance - Distance of the level to remove. + * @return {boolean} Whether the level has been removed or not. */ - copyAt( index1, interleavedBuffer, index2 ) { + removeLevel( distance ) { - index1 *= this.stride; - index2 *= interleavedBuffer.stride; + const levels = this.levels; - for ( let i = 0, l = this.stride; i < l; i ++ ) { + for ( let i = 0; i < levels.length; i ++ ) { - this.array[ index1 + i ] = interleavedBuffer.array[ index2 + i ]; + if ( levels[ i ].distance === distance ) { + + const removedElements = levels.splice( i, 1 ); + this.remove( removedElements[ 0 ].object ); + + return true; + + } } - return this; + return false; } /** - * Sets the given array data in the interleaved buffer. + * Returns the currently active LOD level index. * - * @param {(TypedArray|Array)} value - The array data to set. - * @param {number} [offset=0] - The offset in this interleaved buffer's array. - * @return {InterleavedBuffer} A reference to this instance. + * @return {number} The current active LOD level index. */ - set( value, offset = 0 ) { - - this.array.set( value, offset ); + getCurrentLevel() { - return this; + return this._currentLevel; } /** - * Returns a new interleaved buffer with copied values from this instance. + * Returns a reference to the first 3D object that is greater than + * the given distance. * - * @param {Object} [data] - An object with shared array buffers that allows to retain shared structures. - * @return {InterleavedBuffer} A clone of this instance. + * @param {number} distance - The LOD distance. + * @return {?Object3D} The found 3D object. `null` if no 3D object has been found. */ - clone( data ) { + getObjectForDistance( distance ) { - if ( data.arrayBuffers === undefined ) { + const levels = this.levels; - data.arrayBuffers = {}; + if ( levels.length > 0 ) { - } + let i, l; - if ( this.array.buffer._uuid === undefined ) { + for ( i = 1, l = levels.length; i < l; i ++ ) { - this.array.buffer._uuid = generateUUID(); + let levelDistance = levels[ i ].distance; - } + if ( levels[ i ].object.visible ) { - if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { + levelDistance -= levelDistance * levels[ i ].hysteresis; - data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer; + } - } + if ( distance < levelDistance ) { - const array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] ); + break; - const ib = new this.constructor( array, this.stride ); - ib.setUsage( this.usage ); + } - return ib; + } + + return levels[ i - 1 ].object; + + } + + return null; } /** - * Sets the given callback function that is executed after the Renderer has transferred - * the array data to the GPU. Can be used to perform clean-up operations after - * the upload when data are not needed anymore on the CPU side. + * Computes intersection points between a casted ray and this LOD. * - * @param {Function} callback - The `onUpload()` callback. - * @return {InterleavedBuffer} A reference to this instance. + * @param {Raycaster} raycaster - The raycaster. + * @param {Array} intersects - The target array that holds the intersection points. */ - onUpload( callback ) { + raycast( raycaster, intersects ) { - this.onUploadCallback = callback; + const levels = this.levels; - return this; + if ( levels.length > 0 ) { + + _v1$2.setFromMatrixPosition( this.matrixWorld ); + + const distance = raycaster.ray.origin.distanceTo( _v1$2 ); + + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + + } } /** - * Serializes the interleaved buffer into JSON. + * Updates the LOD by computing which LOD level should be visible according + * to the current distance of the given camera. * - * @param {Object} [data] - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized interleaved buffer. + * @param {Camera} camera - The camera the scene is rendered with. */ - toJSON( data ) { + update( camera ) { - if ( data.arrayBuffers === undefined ) { + const levels = this.levels; - data.arrayBuffers = {}; + if ( levels.length > 1 ) { - } + _v1$2.setFromMatrixPosition( camera.matrixWorld ); + _v2$1.setFromMatrixPosition( this.matrixWorld ); - // generate UUID for array buffer if necessary + const distance = _v1$2.distanceTo( _v2$1 ) / camera.zoom; - if ( this.array.buffer._uuid === undefined ) { + levels[ 0 ].object.visible = true; - this.array.buffer._uuid = generateUUID(); + let i, l; - } + for ( i = 1, l = levels.length; i < l; i ++ ) { - if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { + let levelDistance = levels[ i ].distance; - data.arrayBuffers[ this.array.buffer._uuid ] = Array.from( new Uint32Array( this.array.buffer ) ); + if ( levels[ i ].object.visible ) { - } + levelDistance -= levelDistance * levels[ i ].hysteresis; - // + } - return { - uuid: this.uuid, - buffer: this.array.buffer._uuid, - type: this.array.constructor.name, - stride: this.stride - }; + if ( distance >= levelDistance ) { + + levels[ i - 1 ].object.visible = false; + levels[ i ].object.visible = true; + + } else { + + break; + + } + + } + + this._currentLevel = i - 1; + + for ( ; i < l; i ++ ) { + + levels[ i ].object.visible = false; + + } + + } } -} + toJSON( meta ) { -const _vector$7 = /*@__PURE__*/ new Vector3(); + const data = super.toJSON( meta ); -/** - * An alternative version of a buffer attribute with interleaved data. Interleaved - * attributes share a common interleaved data storage ({@link InterleavedBuffer}) and refer with - * different offsets into the buffer. - */ -class InterleavedBufferAttribute { + if ( this.autoUpdate === false ) data.object.autoUpdate = false; - /** - * Constructs a new interleaved buffer attribute. - * - * @param {InterleavedBuffer} interleavedBuffer - The buffer holding the interleaved data. - * @param {number} itemSize - The item size. - * @param {number} offset - The attribute offset into the buffer. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( interleavedBuffer, itemSize, offset, normalized = false ) { + data.object.levels = []; - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isInterleavedBufferAttribute = true; + const levels = this.levels; + + for ( let i = 0, l = levels.length; i < l; i ++ ) { + + const level = levels[ i ]; + + data.object.levels.push( { + object: level.object.uuid, + distance: level.distance, + hysteresis: level.hysteresis + } ); + + } + + return data; + + } + +} + +const _vector$7 = /*@__PURE__*/ new Vector3(); +const _segCenter = /*@__PURE__*/ new Vector3(); +const _segDir = /*@__PURE__*/ new Vector3(); +const _diff = /*@__PURE__*/ new Vector3(); - /** - * The name of the buffer attribute. - * - * @type {string} - */ - this.name = ''; +const _edge1 = /*@__PURE__*/ new Vector3(); +const _edge2 = /*@__PURE__*/ new Vector3(); +const _normal$1 = /*@__PURE__*/ new Vector3(); - /** - * The buffer holding the interleaved data. - * - * @type {InterleavedBuffer} - */ - this.data = interleavedBuffer; +/** + * A ray that emits from an origin in a certain direction. The class is used by + * {@link Raycaster} to assist with raycasting. Raycasting is used for + * mouse picking (working out what objects in the 3D space the mouse is over) + * amongst other things. + */ +class Ray { - /** - * The item size, see {@link BufferAttribute#itemSize}. - * - * @type {number} - */ - this.itemSize = itemSize; + /** + * Constructs a new ray. + * + * @param {Vector3} [origin=(0,0,0)] - The origin of the ray. + * @param {Vector3} [direction=(0,0,-1)] - The (normalized) direction of the ray. + */ + constructor( origin = new Vector3(), direction = new Vector3( 0, 0, -1 ) ) { /** - * The attribute offset into the buffer. + * The origin of the ray. * - * @type {number} + * @type {Vector3} */ - this.offset = offset; + this.origin = origin; /** - * Whether the data are normalized or not, see {@link BufferAttribute#normalized} + * The (normalized) direction of the ray. * - * @type {InterleavedBuffer} + * @type {Vector3} */ - this.normalized = normalized; + this.direction = direction; } /** - * The item count of this buffer attribute. + * Sets the ray's components by copying the given values. * - * @type {number} - * @readonly + * @param {Vector3} origin - The origin. + * @param {Vector3} direction - The direction. + * @return {Ray} A reference to this ray. */ - get count() { + set( origin, direction ) { - return this.data.count; + this.origin.copy( origin ); + this.direction.copy( direction ); + + return this; } /** - * The array holding the interleaved buffer attribute data. + * Copies the values of the given ray to this instance. * - * @type {TypedArray} + * @param {Ray} ray - The ray to copy. + * @return {Ray} A reference to this ray. */ - get array() { + copy( ray ) { - return this.data.array; + this.origin.copy( ray.origin ); + this.direction.copy( ray.direction ); + + return this; } /** - * Flag to indicate that this attribute has changed and should be re-sent to - * the GPU. Set this to `true` when you modify the value of the array. + * Returns a vector that is located at a given distance along this ray. * - * @type {number} - * @default false - * @param {boolean} value + * @param {number} t - The distance along the ray to retrieve a position for. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} A position on the ray. */ - set needsUpdate( value ) { + at( t, target ) { - this.data.needsUpdate = value; + return target.copy( this.origin ).addScaledVector( this.direction, t ); } /** - * Applies the given 4x4 matrix to the given attribute. Only works with - * item size `3`. + * Adjusts the direction of the ray to point at the given vector in world space. * - * @param {Matrix4} m - The matrix to apply. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Vector3} v - The target position. + * @return {Ray} A reference to this ray. */ - applyMatrix4( m ) { + lookAt( v ) { - for ( let i = 0, l = this.data.count; i < l; i ++ ) { + this.direction.copy( v ).sub( this.origin ).normalize(); - _vector$7.fromBufferAttribute( this, i ); + return this; - _vector$7.applyMatrix4( m ); + } - this.setXYZ( i, _vector$7.x, _vector$7.y, _vector$7.z ); + /** + * Shift the origin of this ray along its direction by the given distance. + * + * @param {number} t - The distance along the ray to interpolate. + * @return {Ray} A reference to this ray. + */ + recast( t ) { - } + this.origin.copy( this.at( t, _vector$7 ) ); return this; } /** - * Applies the given 3x3 normal matrix to the given attribute. Only works with - * item size `3`. + * Returns the point along this ray that is closest to the given point. * - * @param {Matrix3} m - The normal matrix to apply. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Vector3} point - A point in 3D space to get the closet location on the ray for. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The closest point on this ray. */ - applyNormalMatrix( m ) { + closestPointToPoint( point, target ) { - for ( let i = 0, l = this.count; i < l; i ++ ) { + target.subVectors( point, this.origin ); - _vector$7.fromBufferAttribute( this, i ); + const directionDistance = target.dot( this.direction ); - _vector$7.applyNormalMatrix( m ); + if ( directionDistance < 0 ) { - this.setXYZ( i, _vector$7.x, _vector$7.y, _vector$7.z ); + return target.copy( this.origin ); } - return this; + return target.copy( this.origin ).addScaledVector( this.direction, directionDistance ); } /** - * Applies the given 4x4 matrix to the given attribute. Only works with - * item size `3` and with direction vectors. + * Returns the distance of the closest approach between this ray and the given point. * - * @param {Matrix4} m - The matrix to apply. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Vector3} point - A point in 3D space to compute the distance to. + * @return {number} The distance. */ - transformDirection( m ) { + distanceToPoint( point ) { - for ( let i = 0, l = this.count; i < l; i ++ ) { + return Math.sqrt( this.distanceSqToPoint( point ) ); + + } + + /** + * Returns the squared distance of the closest approach between this ray and the given point. + * + * @param {Vector3} point - A point in 3D space to compute the distance to. + * @return {number} The squared distance. + */ + distanceSqToPoint( point ) { - _vector$7.fromBufferAttribute( this, i ); + const directionDistance = _vector$7.subVectors( point, this.origin ).dot( this.direction ); + + // point behind the ray - _vector$7.transformDirection( m ); + if ( directionDistance < 0 ) { - this.setXYZ( i, _vector$7.x, _vector$7.y, _vector$7.z ); + return this.origin.distanceToSquared( point ); } - return this; + _vector$7.copy( this.origin ).addScaledVector( this.direction, directionDistance ); + + return _vector$7.distanceToSquared( point ); } /** - * Returns the given component of the vector at the given index. + * Returns the squared distance between this ray and the given line segment. * - * @param {number} index - The index into the buffer attribute. - * @param {number} component - The component index. - * @return {number} The returned value. + * @param {Vector3} v0 - The start point of the line segment. + * @param {Vector3} v1 - The end point of the line segment. + * @param {Vector3} [optionalPointOnRay] - When provided, it receives the point on this ray that is closest to the segment. + * @param {Vector3} [optionalPointOnSegment] - When provided, it receives the point on the line segment that is closest to this ray. + * @return {number} The squared distance. */ - getComponent( index, component ) { + distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { - let value = this.array[ index * this.data.stride + this.offset + component ]; + // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h + // It returns the min distance between the ray and the segment + // defined by v0 and v1 + // It can also set two optional targets : + // - The closest point on the ray + // - The closest point on the segment - if ( this.normalized ) value = denormalize( value, this.array ); + _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); + _segDir.copy( v1 ).sub( v0 ).normalize(); + _diff.copy( this.origin ).sub( _segCenter ); - return value; + const segExtent = v0.distanceTo( v1 ) * 0.5; + const a01 = - this.direction.dot( _segDir ); + const b0 = _diff.dot( this.direction ); + const b1 = - _diff.dot( _segDir ); + const c = _diff.lengthSq(); + const det = Math.abs( 1 - a01 * a01 ); + let s0, s1, sqrDist, extDet; - } + if ( det > 0 ) { - /** - * Sets the given value to the given component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} component - The component index. - * @param {number} value - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setComponent( index, component, value ) { + // The ray and segment are not parallel. - if ( this.normalized ) value = normalize( value, this.array ); + s0 = a01 * b1 - b0; + s1 = a01 * b0 - b1; + extDet = segExtent * det; - this.data.array[ index * this.data.stride + this.offset + component ] = value; + if ( s0 >= 0 ) { - return this; + if ( s1 >= - extDet ) { - } + if ( s1 <= extDet ) { - /** - * Sets the x component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setX( index, x ) { + // region 0 + // Minimum at interior points of ray and segment. - if ( this.normalized ) x = normalize( x, this.array ); + const invDet = 1 / det; + s0 *= invDet; + s1 *= invDet; + sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; - this.data.array[ index * this.data.stride + this.offset ] = x; + } else { - return this; + // region 1 - } + s1 = segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - /** - * Sets the y component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} y - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setY( index, y ) { + } - if ( this.normalized ) y = normalize( y, this.array ); + } else { - this.data.array[ index * this.data.stride + this.offset + 1 ] = y; + // region 5 - return this; + s1 = - segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } + } - /** - * Sets the z component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} z - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setZ( index, z ) { + } else { - if ( this.normalized ) z = normalize( z, this.array ); + if ( s1 <= - extDet ) { - this.data.array[ index * this.data.stride + this.offset + 2 ] = z; + // region 4 - return this; + s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } + } else if ( s1 <= extDet ) { - /** - * Sets the w component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} w - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setW( index, w ) { + // region 3 - if ( this.normalized ) w = normalize( w, this.array ); + s0 = 0; + s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = s1 * ( s1 + 2 * b1 ) + c; - this.data.array[ index * this.data.stride + this.offset + 3 ] = w; + } else { - return this; + // region 2 + + s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + + } + + } + + } else { + + // Ray and segment are parallel. + + s1 = ( a01 > 0 ) ? - segExtent : segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + + } + + if ( optionalPointOnRay ) { + + optionalPointOnRay.copy( this.origin ).addScaledVector( this.direction, s0 ); + + } + + if ( optionalPointOnSegment ) { + + optionalPointOnSegment.copy( _segCenter ).addScaledVector( _segDir, s1 ); + + } + + return sqrDist; } /** - * Returns the x component of the vector at the given index. + * Intersects this ray with the given sphere, returning the intersection + * point or `null` if there is no intersection. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The x component. + * @param {Sphere} sphere - The sphere to intersect. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The intersection point. */ - getX( index ) { + intersectSphere( sphere, target ) { - let x = this.data.array[ index * this.data.stride + this.offset ]; + _vector$7.subVectors( sphere.center, this.origin ); + const tca = _vector$7.dot( this.direction ); + const d2 = _vector$7.dot( _vector$7 ) - tca * tca; + const radius2 = sphere.radius * sphere.radius; - if ( this.normalized ) x = denormalize( x, this.array ); + if ( d2 > radius2 ) return null; - return x; + const thc = Math.sqrt( radius2 - d2 ); + + // t0 = first intersect point - entrance on front of sphere + const t0 = tca - thc; + + // t1 = second intersect point - exit point on back of sphere + const t1 = tca + thc; + + // test to see if t1 is behind the ray - if so, return null + if ( t1 < 0 ) return null; + + // test to see if t0 is behind the ray: + // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, + // in order to always return an intersect point that is in front of the ray. + if ( t0 < 0 ) return this.at( t1, target ); + + // else t0 is in front of the ray, so return the first collision point scaled by t0 + return this.at( t0, target ); } /** - * Returns the y component of the vector at the given index. + * Returns `true` if this ray intersects with the given sphere. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The y component. + * @param {Sphere} sphere - The sphere to intersect. + * @return {boolean} Whether this ray intersects with the given sphere or not. */ - getY( index ) { - - let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; + intersectsSphere( sphere ) { - if ( this.normalized ) y = denormalize( y, this.array ); + if ( sphere.radius < 0 ) return false; // handle empty spheres, see #31187 - return y; + return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); } /** - * Returns the z component of the vector at the given index. + * Computes the distance from the ray's origin to the given plane. Returns `null` if the ray + * does not intersect with the plane. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The z component. + * @param {Plane} plane - The plane to compute the distance to. + * @return {?number} Whether this ray intersects with the given sphere or not. */ - getZ( index ) { + distanceToPlane( plane ) { - let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; + const denominator = plane.normal.dot( this.direction ); - if ( this.normalized ) z = denormalize( z, this.array ); + if ( denominator === 0 ) { - return z; + // line is coplanar, return origin + if ( plane.distanceToPoint( this.origin ) === 0 ) { + + return 0; + + } + + // Null is preferable to undefined since undefined means.... it is undefined + + return null; + + } + + const t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + + // Return if the ray never intersects the plane + + return t >= 0 ? t : null; } /** - * Returns the w component of the vector at the given index. + * Intersects this ray with the given plane, returning the intersection + * point or `null` if there is no intersection. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The w component. + * @param {Plane} plane - The plane to intersect. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The intersection point. */ - getW( index ) { + intersectPlane( plane, target ) { - let w = this.data.array[ index * this.data.stride + this.offset + 3 ]; + const t = this.distanceToPlane( plane ); - if ( this.normalized ) w = denormalize( w, this.array ); + if ( t === null ) { - return w; + return null; + + } + + return this.at( t, target ); } /** - * Sets the x and y component of the vector at the given index. + * Returns `true` if this ray intersects with the given plane. * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Plane} plane - The plane to intersect. + * @return {boolean} Whether this ray intersects with the given plane or not. */ - setXY( index, x, y ) { + intersectsPlane( plane ) { - index = index * this.data.stride + this.offset; + // check if the ray lies on the plane first - if ( this.normalized ) { + const distToPoint = plane.distanceToPoint( this.origin ); - x = normalize( x, this.array ); - y = normalize( y, this.array ); + if ( distToPoint === 0 ) { + + return true; } - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; + const denominator = plane.normal.dot( this.direction ); - return this; + if ( denominator * distToPoint < 0 ) { + + return true; + + } + + // ray origin is behind the plane (and is pointing behind it) + + return false; } /** - * Sets the x, y and z component of the vector at the given index. + * Intersects this ray with the given bounding box, returning the intersection + * point or `null` if there is no intersection. * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @param {number} z - The value for the z component to set. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Box3} box - The box to intersect. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The intersection point. */ - setXYZ( index, x, y, z ) { + intersectBox( box, target ) { - index = index * this.data.stride + this.offset; + let tmin, tmax, tymin, tymax, tzmin, tzmax; - if ( this.normalized ) { + const invdirx = 1 / this.direction.x, + invdiry = 1 / this.direction.y, + invdirz = 1 / this.direction.z; - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); + const origin = this.origin; + + if ( invdirx >= 0 ) { + + tmin = ( box.min.x - origin.x ) * invdirx; + tmax = ( box.max.x - origin.x ) * invdirx; + + } else { + + tmin = ( box.max.x - origin.x ) * invdirx; + tmax = ( box.min.x - origin.x ) * invdirx; } - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; - this.data.array[ index + 2 ] = z; + if ( invdiry >= 0 ) { - return this; + tymin = ( box.min.y - origin.y ) * invdiry; + tymax = ( box.max.y - origin.y ) * invdiry; - } + } else { - /** - * Sets the x, y, z and w component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @param {number} z - The value for the z component to set. - * @param {number} w - The value for the w component to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setXYZW( index, x, y, z, w ) { + tymin = ( box.max.y - origin.y ) * invdiry; + tymax = ( box.min.y - origin.y ) * invdiry; - index = index * this.data.stride + this.offset; + } + + if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + + if ( tymin > tmin || isNaN( tmin ) ) tmin = tymin; + + if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax; + + if ( invdirz >= 0 ) { + + tzmin = ( box.min.z - origin.z ) * invdirz; + tzmax = ( box.max.z - origin.z ) * invdirz; - if ( this.normalized ) { + } else { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - w = normalize( w, this.array ); + tzmin = ( box.max.z - origin.z ) * invdirz; + tzmax = ( box.min.z - origin.z ) * invdirz; } - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; - this.data.array[ index + 2 ] = z; - this.data.array[ index + 3 ] = w; + if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; - return this; + if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; + + if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; + + //return point closest to the ray (positive side) + + if ( tmax < 0 ) return null; + + return this.at( tmin >= 0 ? tmin : tmax, target ); } /** - * Returns a new buffer attribute with copied values from this instance. - * - * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. + * Returns `true` if this ray intersects with the given box. * - * @param {Object} [data] - An object with interleaved buffers that allows to retain the interleaved property. - * @return {BufferAttribute|InterleavedBufferAttribute} A clone of this instance. + * @param {Box3} box - The box to intersect. + * @return {boolean} Whether this ray intersects with the given box or not. */ - clone( data ) { - - if ( data === undefined ) { + intersectsBox( box ) { - log( 'InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' ); + return this.intersectBox( box, _vector$7 ) !== null; - const array = []; + } - for ( let i = 0; i < this.count; i ++ ) { + /** + * Intersects this ray with the given triangle, returning the intersection + * point or `null` if there is no intersection. + * + * @param {Vector3} a - The first vertex of the triangle. + * @param {Vector3} b - The second vertex of the triangle. + * @param {Vector3} c - The third vertex of the triangle. + * @param {boolean} backfaceCulling - Whether to use backface culling or not. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The intersection point. + */ + intersectTriangle( a, b, c, backfaceCulling, target ) { - const index = i * this.data.stride + this.offset; + // Compute the offset origin, edges, and normal. - for ( let j = 0; j < this.itemSize; j ++ ) { + // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h - array.push( this.data.array[ index + j ] ); + _edge1.subVectors( b, a ); + _edge2.subVectors( c, a ); + _normal$1.crossVectors( _edge1, _edge2 ); - } + // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, + // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by + // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) + // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) + // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) + let DdN = this.direction.dot( _normal$1 ); + let sign; - } + if ( DdN > 0 ) { - return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized ); + if ( backfaceCulling ) return null; + sign = 1; - } else { + } else if ( DdN < 0 ) { - if ( data.interleavedBuffers === undefined ) { + sign = -1; + DdN = - DdN; - data.interleavedBuffers = {}; + } else { - } + return null; - if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) { + } - data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data ); + _diff.subVectors( this.origin, a ); + const DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) ); - } + // b1 < 0, no intersection + if ( DdQxE2 < 0 ) { - return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized ); + return null; } - } - - /** - * Serializes the buffer attribute into JSON. - * - * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. - * - * @param {Object} [data] - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized buffer attribute. - */ - toJSON( data ) { + const DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); - if ( data === undefined ) { + // b2 < 0, no intersection + if ( DdE1xQ < 0 ) { - log( 'InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' ); + return null; - const array = []; + } - for ( let i = 0; i < this.count; i ++ ) { + // b1+b2 > 1, no intersection + if ( DdQxE2 + DdE1xQ > DdN ) { - const index = i * this.data.stride + this.offset; + return null; - for ( let j = 0; j < this.itemSize; j ++ ) { + } - array.push( this.data.array[ index + j ] ); + // Line intersects triangle, check if ray does. + const QdN = - sign * _diff.dot( _normal$1 ); - } + // t < 0, no intersection + if ( QdN < 0 ) { - } + return null; - // de-interleave data and save it as an ordinary buffer attribute for now + } - return { - itemSize: this.itemSize, - type: this.array.constructor.name, - array: array, - normalized: this.normalized - }; + // Ray intersects triangle. + return this.at( QdN / DdN, target ); - } else { + } - // save as true interleaved attribute + /** + * Transforms this ray with the given 4x4 transformation matrix. + * + * @param {Matrix4} matrix4 - The transformation matrix. + * @return {Ray} A reference to this ray. + */ + applyMatrix4( matrix4 ) { - if ( data.interleavedBuffers === undefined ) { + this.origin.applyMatrix4( matrix4 ); + this.direction.transformDirection( matrix4 ); - data.interleavedBuffers = {}; + return this; - } + } - if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) { + /** + * Returns `true` if this ray is equal with the given one. + * + * @param {Ray} ray - The ray to test for equality. + * @return {boolean} Whether this ray is equal with the given one. + */ + equals( ray ) { - data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data ); + return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); - } + } - return { - isInterleavedBufferAttribute: true, - itemSize: this.itemSize, - data: this.data.uuid, - offset: this.offset, - normalized: this.normalized - }; + /** + * Returns a new ray with copied values from this instance. + * + * @return {Ray} A clone of this instance. + */ + clone() { - } + return new this.constructor().copy( this ); } } /** - * A material for rendering instances of {@link Sprite}. - * - * ```js - * const map = new THREE.TextureLoader().load( 'textures/sprite.png' ); - * const material = new THREE.SpriteMaterial( { map: map, color: 0xffffff } ); + * A material for drawing geometries in a simple shaded (flat or wireframe) way. * - * const sprite = new THREE.Sprite( material ); - * sprite.scale.set(200, 200, 1) - * scene.add( sprite ); - * ``` + * This material is not affected by lights. * * @augments Material + * @demo scenes/material-browser.html#MeshBasicMaterial */ -class SpriteMaterial extends Material { +class MeshBasicMaterial extends Material { /** - * Constructs a new sprite material. + * Constructs a new mesh basic material. * * @param {Object} [parameters] - An object with one or more properties * defining the material's appearance. Any property of the material @@ -24472,9 +22642,9 @@ class SpriteMaterial extends Material { * @readonly * @default true */ - this.isSpriteMaterial = true; + this.isMeshBasicMaterial = true; - this.type = 'SpriteMaterial'; + this.type = 'MeshBasicMaterial'; /** * Color of the material. @@ -24482,7 +22652,7 @@ class SpriteMaterial extends Material { * @type {Color} * @default (1,1,1) */ - this.color = new Color( 0xffffff ); + this.color = new Color( 0xffffff ); // diffuse /** * The color map. May optionally include an alpha channel, typically combined @@ -24494,6 +22664,49 @@ class SpriteMaterial extends Material { */ this.map = null; + /** + * The light map. Requires a second set of UVs. + * + * @type {?Texture} + * @default null + */ + this.lightMap = null; + + /** + * Intensity of the baked light. + * + * @type {number} + * @default 1 + */ + this.lightMapIntensity = 1.0; + + /** + * The red channel of this texture is used as the ambient occlusion map. + * Requires a second set of UVs. + * + * @type {?Texture} + * @default null + */ + this.aoMap = null; + + /** + * Intensity of the ambient occlusion effect. Range is `[0,1]`, where `0` + * disables ambient occlusion. Where intensity is `1` and the AO map's + * red channel is also `1`, ambient light is fully occluded on a surface. + * + * @type {number} + * @default 1 + */ + this.aoMapIntensity = 1.0; + + /** + * Specular map used by the material. + * + * @type {?Texture} + * @default null + */ + this.specularMap = null; + /** * The alpha map is a grayscale texture that controls the opacity across the * surface (black: fully transparent; white: fully opaque). @@ -24510,29 +22723,89 @@ class SpriteMaterial extends Material { this.alphaMap = null; /** - * The rotation of the sprite in radians. + * The environment map. + * + * @type {?Texture} + * @default null + */ + this.envMap = null; + + /** + * The rotation of the environment map in radians. + * + * @type {Euler} + * @default (0,0,0) + */ + this.envMapRotation = new Euler(); + + /** + * How to combine the result of the surface's color with the environment map, if any. + * + * When set to `MixOperation`, the {@link MeshBasicMaterial#reflectivity} is used to + * blend between the two colors. + * + * @type {(MultiplyOperation|MixOperation|AddOperation)} + * @default MultiplyOperation + */ + this.combine = MultiplyOperation; + + /** + * How much the environment map affects the surface. + * The valid range is between `0` (no reflections) and `1` (full reflections). * * @type {number} - * @default 0 + * @default 1 */ - this.rotation = 0; + this.reflectivity = 1; /** - * Specifies whether size of the sprite is attenuated by the camera depth (perspective camera only). + * The index of refraction (IOR) of air (approximately 1) divided by the + * index of refraction of the material. It is used with environment mapping + * modes {@link CubeRefractionMapping} and {@link EquirectangularRefractionMapping}. + * The refraction ratio should not exceed `1`. * - * @type {boolean} - * @default true + * @type {number} + * @default 0.98 */ - this.sizeAttenuation = true; + this.refractionRatio = 0.98; /** - * Overwritten since sprite materials are transparent - * by default. + * Renders the geometry as a wireframe. * * @type {boolean} - * @default true + * @default false */ - this.transparent = true; + this.wireframe = false; + + /** + * Controls the thickness of the wireframe. + * + * Can only be used with {@link SVGRenderer}. + * + * @type {number} + * @default 1 + */ + this.wireframeLinewidth = 1; + + /** + * Defines appearance of wireframe ends. + * + * Can only be used with {@link SVGRenderer}. + * + * @type {('round'|'bevel'|'miter')} + * @default 'round' + */ + this.wireframeLinecap = 'round'; + + /** + * Defines appearance of wireframe joints. + * + * Can only be used with {@link SVGRenderer}. + * + * @type {('round'|'bevel'|'miter')} + * @default 'round' + */ + this.wireframeLinejoin = 'round'; /** * Whether the material is affected by fog or not. @@ -24554,11 +22827,26 @@ class SpriteMaterial extends Material { this.map = source.map; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.specularMap = source.specularMap; + this.alphaMap = source.alphaMap; - this.rotation = source.rotation; + this.envMap = source.envMap; + this.envMapRotation.copy( source.envMapRotation ); + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; - this.sizeAttenuation = source.sizeAttenuation; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; this.fog = source.fog; @@ -24568,49 +22856,42 @@ class SpriteMaterial extends Material { } -let _geometry; - -const _intersectPoint = /*@__PURE__*/ new Vector3(); -const _worldScale = /*@__PURE__*/ new Vector3(); -const _mvPosition = /*@__PURE__*/ new Vector3(); - -const _alignedPosition = /*@__PURE__*/ new Vector2(); -const _rotatedPosition = /*@__PURE__*/ new Vector2(); -const _viewWorldMatrix = /*@__PURE__*/ new Matrix4(); +const _inverseMatrix$3 = /*@__PURE__*/ new Matrix4(); +const _ray$3 = /*@__PURE__*/ new Ray(); +const _sphere$6 = /*@__PURE__*/ new Sphere(); +const _sphereHitAt = /*@__PURE__*/ new Vector3(); const _vA = /*@__PURE__*/ new Vector3(); const _vB = /*@__PURE__*/ new Vector3(); const _vC = /*@__PURE__*/ new Vector3(); -const _uvA = /*@__PURE__*/ new Vector2(); -const _uvB = /*@__PURE__*/ new Vector2(); -const _uvC = /*@__PURE__*/ new Vector2(); +const _tempA = /*@__PURE__*/ new Vector3(); +const _morphA = /*@__PURE__*/ new Vector3(); + +const _intersectionPoint = /*@__PURE__*/ new Vector3(); +const _intersectionPointWorld = /*@__PURE__*/ new Vector3(); /** - * A sprite is a plane that always faces towards the camera, generally with a - * partially transparent texture applied. - * - * Sprites do not cast shadows, setting {@link Object3D#castShadow} to `true` will - * have no effect. + * Class representing triangular polygon mesh based objects. * * ```js - * const map = new THREE.TextureLoader().load( 'sprite.png' ); - * const material = new THREE.SpriteMaterial( { map: map } ); - * - * const sprite = new THREE.Sprite( material ); - * scene.add( sprite ); + * const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + * const mesh = new THREE.Mesh( geometry, material ); + * scene.add( mesh ); * ``` * * @augments Object3D */ -class Sprite extends Object3D { +class Mesh extends Object3D { /** - * Constructs a new sprite. + * Constructs a new mesh. * - * @param {(SpriteMaterial|SpriteNodeMaterial)} [material] - The sprite material. + * @param {BufferGeometry} [geometry] - The mesh geometry. + * @param {Material|Array} [material] - The mesh material. */ - constructor( material = new SpriteMaterial() ) { + constructor( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) { super(); @@ -24621,55 +22902,47 @@ class Sprite extends Object3D { * @readonly * @default true */ - this.isSprite = true; - - this.type = 'Sprite'; - - if ( _geometry === undefined ) { - - _geometry = new BufferGeometry(); - - const float32Array = new Float32Array( [ - -0.5, -0.5, 0, 0, 0, - 0.5, -0.5, 0, 1, 0, - 0.5, 0.5, 0, 1, 1, - -0.5, 0.5, 0, 0, 1 - ] ); - - const interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); - - _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); - _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); - _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + this.isMesh = true; - } + this.type = 'Mesh'; /** - * The sprite geometry. + * The mesh geometry. * * @type {BufferGeometry} */ - this.geometry = _geometry; + this.geometry = geometry; /** - * The sprite material. + * The mesh material. * - * @type {(SpriteMaterial|SpriteNodeMaterial)} + * @type {Material|Array} + * @default MeshBasicMaterial */ this.material = material; /** - * The sprite's anchor point, and the point around which the sprite rotates. - * A value of `(0.5, 0.5)` corresponds to the midpoint of the sprite. A value - * of `(0, 0)` corresponds to the lower left corner of the sprite. + * A dictionary representing the morph targets in the geometry. The key is the + * morph targets name, the value its attribute index. This member is `undefined` + * by default and only set when morph targets are detected in the geometry. * - * @type {Vector2} - * @default (0.5,0.5) + * @type {Object|undefined} + * @default undefined */ - this.center = new Vector2( 0.5, 0.5 ); + this.morphTargetDictionary = undefined; /** - * The number of instances of this sprite. + * An array of weights typically in the range `[0,1]` that specify how much of the morph + * is applied. This member is `undefined` by default and only set when morph targets are + * detected in the geometry. + * + * @type {Array|undefined} + * @default undefined + */ + this.morphTargetInfluences = undefined; + + /** + * The number of instances of this mesh. * Can only be used with {@link WebGPURenderer}. * * @type {number} @@ -24677,452 +22950,394 @@ class Sprite extends Object3D { */ this.count = 1; + this.updateMorphTargets(); + } - /** - * Computes intersection points between a casted ray and this sprite. - * - * @param {Raycaster} raycaster - The raycaster. - * @param {Array} intersects - The target array that holds the intersection points. - */ - raycast( raycaster, intersects ) { + copy( source, recursive ) { - if ( raycaster.camera === null ) { + super.copy( source, recursive ); - error( 'Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' ); + if ( source.morphTargetInfluences !== undefined ) { - } + this.morphTargetInfluences = source.morphTargetInfluences.slice(); - _worldScale.setFromMatrixScale( this.matrixWorld ); + } - _viewWorldMatrix.copy( raycaster.camera.matrixWorld ); - this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld ); + if ( source.morphTargetDictionary !== undefined ) { - _mvPosition.setFromMatrixPosition( this.modelViewMatrix ); + this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); - if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) { + } - _worldScale.multiplyScalar( - _mvPosition.z ); + this.material = Array.isArray( source.material ) ? source.material.slice() : source.material; + this.geometry = source.geometry; - } + return this; - const rotation = this.material.rotation; - let sin, cos; + } - if ( rotation !== 0 ) { + /** + * Sets the values of {@link Mesh#morphTargetDictionary} and {@link Mesh#morphTargetInfluences} + * to make sure existing morph targets can influence this 3D object. + */ + updateMorphTargets() { - cos = Math.cos( rotation ); - sin = Math.sin( rotation ); + const geometry = this.geometry; - } + const morphAttributes = geometry.morphAttributes; + const keys = Object.keys( morphAttributes ); - const center = this.center; + if ( keys.length > 0 ) { - transformVertex( _vA.set( -0.5, -0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - transformVertex( _vB.set( 0.5, -0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - transformVertex( _vC.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + const morphAttribute = morphAttributes[ keys[ 0 ] ]; - _uvA.set( 0, 0 ); - _uvB.set( 1, 0 ); - _uvC.set( 1, 1 ); + if ( morphAttribute !== undefined ) { - // check first triangle - let intersect = raycaster.ray.intersectTriangle( _vA, _vB, _vC, false, _intersectPoint ); + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - if ( intersect === null ) { + for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) { - // check second triangle - transformVertex( _vB.set( -0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - _uvB.set( 0, 1 ); + const name = morphAttribute[ m ].name || String( m ); - intersect = raycaster.ray.intersectTriangle( _vA, _vC, _vB, false, _intersectPoint ); - if ( intersect === null ) { + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ name ] = m; - return; + } } } - const distance = raycaster.ray.origin.distanceTo( _intersectPoint ); + } - if ( distance < raycaster.near || distance > raycaster.far ) return; + /** + * Returns the local-space position of the vertex at the given index, taking into + * account the current animation state of both morph targets and skinning. + * + * @param {number} index - The vertex index. + * @param {Vector3} target - The target object that is used to store the method's result. + * @return {Vector3} The vertex position in local space. + */ + getVertexPosition( index, target ) { - intersects.push( { + const geometry = this.geometry; + const position = geometry.attributes.position; + const morphPosition = geometry.morphAttributes.position; + const morphTargetsRelative = geometry.morphTargetsRelative; - distance: distance, - point: _intersectPoint.clone(), - uv: Triangle.getInterpolation( _intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ), - face: null, - object: this + target.fromBufferAttribute( position, index ); - } ); + const morphInfluences = this.morphTargetInfluences; - } + if ( morphPosition && morphInfluences ) { - copy( source, recursive ) { + _morphA.set( 0, 0, 0 ); - super.copy( source, recursive ); + for ( let i = 0, il = morphPosition.length; i < il; i ++ ) { - if ( source.center !== undefined ) this.center.copy( source.center ); + const influence = morphInfluences[ i ]; + const morphAttribute = morphPosition[ i ]; - this.material = source.material; + if ( influence === 0 ) continue; - return this; + _tempA.fromBufferAttribute( morphAttribute, index ); - } + if ( morphTargetsRelative ) { -} + _morphA.addScaledVector( _tempA, influence ); -function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { + } else { - // compute position in camera space - _alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); + _morphA.addScaledVector( _tempA.sub( target ), influence ); - // to check if rotation is not zero - if ( sin !== undefined ) { + } - _rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y ); - _rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y ); + } - } else { + target.add( _morphA ); - _rotatedPosition.copy( _alignedPosition ); + } + + return target; } + /** + * Computes intersection points between a casted ray and this line. + * + * @param {Raycaster} raycaster - The raycaster. + * @param {Array} intersects - The target array that holds the intersection points. + */ + raycast( raycaster, intersects ) { - vertexPosition.copy( mvPosition ); - vertexPosition.x += _rotatedPosition.x; - vertexPosition.y += _rotatedPosition.y; + const geometry = this.geometry; + const material = this.material; + const matrixWorld = this.matrixWorld; - // transform to world space - vertexPosition.applyMatrix4( _viewWorldMatrix ); + if ( material === undefined ) return; -} + // test with bounding sphere in world space -const _v1$2 = /*@__PURE__*/ new Vector3(); -const _v2$1 = /*@__PURE__*/ new Vector3(); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); -/** - * A component for providing a basic Level of Detail (LOD) mechanism. - * - * Every LOD level is associated with an object, and rendering can be switched - * between them at the distances specified. Typically you would create, say, - * three meshes, one for far away (low detail), one for mid range (medium - * detail) and one for close up (high detail). - * - * ```js - * const lod = new THREE.LOD(); - * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); - * - * //Create spheres with 3 levels of detail and create new LOD levels for them - * for( let i = 0; i < 3; i++ ) { - * - * const geometry = new THREE.IcosahedronGeometry( 10, 3 - i ); - * const mesh = new THREE.Mesh( geometry, material ); - * lod.addLevel( mesh, i * 75 ); - * - * } - * - * scene.add( lod ); - * ``` - * - * @augments Object3D - */ -class LOD extends Object3D { + _sphere$6.copy( geometry.boundingSphere ); + _sphere$6.applyMatrix4( matrixWorld ); - /** - * Constructs a new LOD. - */ - constructor() { + // check distance from ray origin to bounding sphere - super(); + _ray$3.copy( raycaster.ray ).recast( raycaster.near ); - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isLOD = true; + if ( _sphere$6.containsPoint( _ray$3.origin ) === false ) { - /** - * The current LOD index. - * - * @private - * @type {number} - * @default 0 - */ - this._currentLevel = 0; + if ( _ray$3.intersectSphere( _sphere$6, _sphereHitAt ) === null ) return; - this.type = 'LOD'; + if ( _ray$3.origin.distanceToSquared( _sphereHitAt ) > ( raycaster.far - raycaster.near ) ** 2 ) return; - Object.defineProperties( this, { - /** - * This array holds the LOD levels. - * - * @name LOD#levels - * @type {Array<{object:Object3D,distance:number,hysteresis:number}>} - */ - levels: { - enumerable: true, - value: [] - } - } ); + } - /** - * Whether the LOD object is updated automatically by the renderer per frame - * or not. If set to `false`, you have to call {@link LOD#update} in the - * render loop by yourself. - * - * @type {boolean} - * @default true - */ - this.autoUpdate = true; + // convert ray to local space of mesh - } + _inverseMatrix$3.copy( matrixWorld ).invert(); + _ray$3.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$3 ); - copy( source ) { + // test with bounding box in local space - super.copy( source, false ); + if ( geometry.boundingBox !== null ) { - const levels = source.levels; + if ( _ray$3.intersectsBox( geometry.boundingBox ) === false ) return; - for ( let i = 0, l = levels.length; i < l; i ++ ) { + } - const level = levels[ i ]; + // test for intersections with geometry - this.addLevel( level.object.clone(), level.distance, level.hysteresis ); + this._computeIntersections( raycaster, intersects, _ray$3 ); - } + } - this.autoUpdate = source.autoUpdate; + _computeIntersections( raycaster, intersects, rayLocalSpace ) { - return this; + let intersection; - } + const geometry = this.geometry; + const material = this.material; - /** - * Adds a mesh that will display at a certain distance and greater. Typically - * the further away the distance, the lower the detail on the mesh. - * - * @param {Object3D} object - The 3D object to display at this level. - * @param {number} [distance=0] - The distance at which to display this level of detail. - * @param {number} [hysteresis=0] - Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. - * @return {LOD} A reference to this instance. - */ - addLevel( object, distance = 0, hysteresis = 0 ) { + const index = geometry.index; + const position = geometry.attributes.position; + const uv = geometry.attributes.uv; + const uv1 = geometry.attributes.uv1; + const normal = geometry.attributes.normal; + const groups = geometry.groups; + const drawRange = geometry.drawRange; - distance = Math.abs( distance ); + if ( index !== null ) { - const levels = this.levels; + // indexed buffer geometry - let l; + if ( Array.isArray( material ) ) { - for ( l = 0; l < levels.length; l ++ ) { + for ( let i = 0, il = groups.length; i < il; i ++ ) { - if ( distance < levels[ l ].distance ) { + const group = groups[ i ]; + const groupMaterial = material[ group.materialIndex ]; - break; + const start = Math.max( group.start, drawRange.start ); + const end = Math.min( index.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); - } + for ( let j = start, jl = end; j < jl; j += 3 ) { - } + const a = index.getX( j ); + const b = index.getX( j + 1 ); + const c = index.getX( j + 2 ); - levels.splice( l, 0, { distance: distance, hysteresis: hysteresis, object: object } ); + intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); - this.add( object ); + if ( intersection ) { - return this; + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - } + } - /** - * Removes an existing level, based on the distance from the camera. - * Returns `true` when the level has been removed. Otherwise `false`. - * - * @param {number} distance - Distance of the level to remove. - * @return {boolean} Whether the level has been removed or not. - */ - removeLevel( distance ) { + } - const levels = this.levels; + } - for ( let i = 0; i < levels.length; i ++ ) { + } else { - if ( levels[ i ].distance === distance ) { + const start = Math.max( 0, drawRange.start ); + const end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); - const removedElements = levels.splice( i, 1 ); - this.remove( removedElements[ 0 ].object ); + for ( let i = start, il = end; i < il; i += 3 ) { - return true; + const a = index.getX( i ); + const b = index.getX( i + 1 ); + const c = index.getX( i + 2 ); - } + intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); - } + if ( intersection ) { - return false; + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics + intersects.push( intersection ); - } + } - /** - * Returns the currently active LOD level index. - * - * @return {number} The current active LOD level index. - */ - getCurrentLevel() { + } - return this._currentLevel; + } - } + } else if ( position !== undefined ) { - /** - * Returns a reference to the first 3D object that is greater than - * the given distance. - * - * @param {number} distance - The LOD distance. - * @return {?Object3D} The found 3D object. `null` if no 3D object has been found. - */ - getObjectForDistance( distance ) { + // non-indexed buffer geometry - const levels = this.levels; + if ( Array.isArray( material ) ) { - if ( levels.length > 0 ) { + for ( let i = 0, il = groups.length; i < il; i ++ ) { - let i, l; + const group = groups[ i ]; + const groupMaterial = material[ group.materialIndex ]; - for ( i = 1, l = levels.length; i < l; i ++ ) { + const start = Math.max( group.start, drawRange.start ); + const end = Math.min( position.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); - let levelDistance = levels[ i ].distance; + for ( let j = start, jl = end; j < jl; j += 3 ) { - if ( levels[ i ].object.visible ) { + const a = j; + const b = j + 1; + const c = j + 2; - levelDistance -= levelDistance * levels[ i ].hysteresis; + intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); - } + if ( intersection ) { - if ( distance < levelDistance ) { + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - break; + } - } + } - } + } - return levels[ i - 1 ].object; + } else { - } + const start = Math.max( 0, drawRange.start ); + const end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); - return null; + for ( let i = start, il = end; i < il; i += 3 ) { - } + const a = i; + const b = i + 1; + const c = i + 2; - /** - * Computes intersection points between a casted ray and this LOD. - * - * @param {Raycaster} raycaster - The raycaster. - * @param {Array} intersects - The target array that holds the intersection points. - */ - raycast( raycaster, intersects ) { + intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); - const levels = this.levels; + if ( intersection ) { - if ( levels.length > 0 ) { + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics + intersects.push( intersection ); - _v1$2.setFromMatrixPosition( this.matrixWorld ); + } - const distance = raycaster.ray.origin.distanceTo( _v1$2 ); + } - this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + } } } - /** - * Updates the LOD by computing which LOD level should be visible according - * to the current distance of the given camera. - * - * @param {Camera} camera - The camera the scene is rendered with. - */ - update( camera ) { - - const levels = this.levels; +} - if ( levels.length > 1 ) { +function checkIntersection$1( object, material, raycaster, ray, pA, pB, pC, point ) { - _v1$2.setFromMatrixPosition( camera.matrixWorld ); - _v2$1.setFromMatrixPosition( this.matrixWorld ); + let intersect; - const distance = _v1$2.distanceTo( _v2$1 ) / camera.zoom; + if ( material.side === BackSide ) { - levels[ 0 ].object.visible = true; + intersect = ray.intersectTriangle( pC, pB, pA, true, point ); - let i, l; + } else { - for ( i = 1, l = levels.length; i < l; i ++ ) { + intersect = ray.intersectTriangle( pA, pB, pC, ( material.side === FrontSide ), point ); - let levelDistance = levels[ i ].distance; + } - if ( levels[ i ].object.visible ) { + if ( intersect === null ) return null; - levelDistance -= levelDistance * levels[ i ].hysteresis; + _intersectionPointWorld.copy( point ); + _intersectionPointWorld.applyMatrix4( object.matrixWorld ); - } + const distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); - if ( distance >= levelDistance ) { + if ( distance < raycaster.near || distance > raycaster.far ) return null; - levels[ i - 1 ].object.visible = false; - levels[ i ].object.visible = true; + return { + distance: distance, + point: _intersectionPointWorld.clone(), + object: object + }; - } else { +} - break; +function checkGeometryIntersection( object, material, raycaster, ray, uv, uv1, normal, a, b, c ) { - } + object.getVertexPosition( a, _vA ); + object.getVertexPosition( b, _vB ); + object.getVertexPosition( c, _vC ); - } + const intersection = checkIntersection$1( object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint ); - this._currentLevel = i - 1; + if ( intersection ) { - for ( ; i < l; i ++ ) { + const barycoord = new Vector3(); + Triangle.getBarycoord( _intersectionPoint, _vA, _vB, _vC, barycoord ); - levels[ i ].object.visible = false; + if ( uv ) { - } + intersection.uv = Triangle.getInterpolatedAttribute( uv, a, b, c, barycoord, new Vector2() ); } - } - - toJSON( meta ) { + if ( uv1 ) { - const data = super.toJSON( meta ); + intersection.uv1 = Triangle.getInterpolatedAttribute( uv1, a, b, c, barycoord, new Vector2() ); - if ( this.autoUpdate === false ) data.object.autoUpdate = false; + } - data.object.levels = []; + if ( normal ) { - const levels = this.levels; + intersection.normal = Triangle.getInterpolatedAttribute( normal, a, b, c, barycoord, new Vector3() ); - for ( let i = 0, l = levels.length; i < l; i ++ ) { + if ( intersection.normal.dot( ray.direction ) > 0 ) { - const level = levels[ i ]; + intersection.normal.multiplyScalar( -1 ); - data.object.levels.push( { - object: level.object.uuid, - distance: level.distance, - hysteresis: level.hysteresis - } ); + } } - return data; + const face = { + a: a, + b: b, + c: c, + normal: new Vector3(), + materialIndex: 0 + }; + + Triangle.getNormal( _vA, _vB, _vC, face.normal ); + + intersection.face = face; + intersection.barycoord = barycoord; } + return intersection; + } const _basePosition = /*@__PURE__*/ new Vector3(); @@ -29640,7 +27855,7 @@ class PointsMaterial extends Material { const _inverseMatrix = /*@__PURE__*/ new Matrix4(); const _ray = /*@__PURE__*/ new Ray(); const _sphere = /*@__PURE__*/ new Sphere(); -const _position$2 = /*@__PURE__*/ new Vector3(); +const _position$3 = /*@__PURE__*/ new Vector3(); /** * A class for displaying points or point clouds. @@ -29764,9 +27979,9 @@ class Points extends Object3D { const a = index.getX( i ); - _position$2.fromBufferAttribute( positionAttribute, a ); + _position$3.fromBufferAttribute( positionAttribute, a ); - testPoint( _position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this ); + testPoint( _position$3, a, localThresholdSq, matrixWorld, raycaster, intersects, this ); } @@ -29777,9 +27992,9 @@ class Points extends Object3D { for ( let i = start, l = end; i < l; i ++ ) { - _position$2.fromBufferAttribute( positionAttribute, i ); + _position$3.fromBufferAttribute( positionAttribute, i ); - testPoint( _position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this ); + testPoint( _position$3, i, localThresholdSq, matrixWorld, raycaster, intersects, this ); } @@ -30341,6 +28556,83 @@ class CompressedCubeTexture extends CompressedTexture { } +/** + * Creates a cube texture made up of six images. + * + * ```js + * const loader = new THREE.CubeTextureLoader(); + * loader.setPath( 'textures/cube/pisa/' ); + * + * const textureCube = loader.load( [ + * 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' + * ] ); + * + * const material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube } ); + * ``` + * + * @augments Texture + */ +class CubeTexture extends Texture { + + /** + * Constructs a new cube texture. + * + * @param {Array} [images=[]] - An array holding a image for each side of a cube. + * @param {number} [mapping=CubeReflectionMapping] - The texture mapping. + * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. + * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. + * @param {number} [magFilter=LinearFilter] - The mag filter value. + * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value. + * @param {number} [format=RGBAFormat] - The texture format. + * @param {number} [type=UnsignedByteType] - The texture type. + * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. + * @param {string} [colorSpace=NoColorSpace] - The color space value. + */ + constructor( images = [], mapping = CubeReflectionMapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace ) { + + super( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace ); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isCubeTexture = true; + + /** + * If set to `true`, the texture is flipped along the vertical axis when + * uploaded to the GPU. + * + * Overwritten and set to `false` by default. + * + * @type {boolean} + * @default false + */ + this.flipY = false; + + } + + /** + * Alias for {@link CubeTexture#image}. + * + * @type {Array} + */ + get images() { + + return this.image; + + } + + set images( value ) { + + this.image = value; + + } + +} + /** * Creates a texture from a canvas element. * @@ -30607,6 +28899,220 @@ class ExternalTexture extends Texture { } +/** + * A geometry class for a rectangular cuboid with a given width, height, and depth. + * On creation, the cuboid is centred on the origin, with each edge parallel to one + * of the axes. + * + * ```js + * const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + * const cube = new THREE.Mesh( geometry, material ); + * scene.add( cube ); + * ``` + * + * @augments BufferGeometry + * @demo scenes/geometry-browser.html#BoxGeometry + */ +class BoxGeometry extends BufferGeometry { + + /** + * Constructs a new box geometry. + * + * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis. + * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis. + * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis. + * @param {number} [widthSegments=1] - Number of segmented rectangular faces along the width of the sides. + * @param {number} [heightSegments=1] - Number of segmented rectangular faces along the height of the sides. + * @param {number} [depthSegments=1] - Number of segmented rectangular faces along the depth of the sides. + */ + constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) { + + super(); + + this.type = 'BoxGeometry'; + + /** + * Holds the constructor parameters that have been + * used to generate the geometry. Any modification + * after instantiation does not change the geometry. + * + * @type {Object} + */ + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; + + const scope = this; + + // segments + + widthSegments = Math.floor( widthSegments ); + heightSegments = Math.floor( heightSegments ); + depthSegments = Math.floor( depthSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + let numberOfVertices = 0; + let groupStart = 0; + + // build each side of the box geometry + + buildPlane( 'z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0 ); // px + buildPlane( 'z', 'y', 'x', 1, -1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx + buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py + buildPlane( 'x', 'z', 'y', 1, -1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny + buildPlane( 'x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4 ); // pz + buildPlane( 'x', 'y', 'z', -1, -1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz + + // build geometry + + this.setIndex( indices ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + + function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { + + const segmentWidth = width / gridX; + const segmentHeight = height / gridY; + + const widthHalf = width / 2; + const heightHalf = height / 2; + const depthHalf = depth / 2; + + const gridX1 = gridX + 1; + const gridY1 = gridY + 1; + + let vertexCounter = 0; + let groupCount = 0; + + const vector = new Vector3(); + + // generate vertices, normals and uvs + + for ( let iy = 0; iy < gridY1; iy ++ ) { + + const y = iy * segmentHeight - heightHalf; + + for ( let ix = 0; ix < gridX1; ix ++ ) { + + const x = ix * segmentWidth - widthHalf; + + // set values to correct vector component + + vector[ u ] = x * udir; + vector[ v ] = y * vdir; + vector[ w ] = depthHalf; + + // now apply vector to vertex buffer + + vertices.push( vector.x, vector.y, vector.z ); + + // set values to correct vector component + + vector[ u ] = 0; + vector[ v ] = 0; + vector[ w ] = depth > 0 ? 1 : -1; + + // now apply vector to normal buffer + + normals.push( vector.x, vector.y, vector.z ); + + // uvs + + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); + + // counters + + vertexCounter += 1; + + } + + } + + // indices + + // 1. you need three indices to draw a single face + // 2. a single segment consists of two faces + // 3. so we need to generate six (2*3) indices per segment + + for ( let iy = 0; iy < gridY; iy ++ ) { + + for ( let ix = 0; ix < gridX; ix ++ ) { + + const a = numberOfVertices + ix + gridX1 * iy; + const b = numberOfVertices + ix + gridX1 * ( iy + 1 ); + const c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); + const d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; + + // faces + + indices.push( a, b, d ); + indices.push( b, c, d ); + + // increase counter + + groupCount += 6; + + } + + } + + // add a group to the geometry. this will ensure multi material support + + scope.addGroup( groupStart, groupCount, materialIndex ); + + // calculate new start value for groups + + groupStart += groupCount; + + // update total number of vertices + + numberOfVertices += vertexCounter; + + } + + } + + copy( source ) { + + super.copy( source ); + + this.parameters = Object.assign( {}, source.parameters ); + + return this; + + } + + /** + * Factory method for creating an instance of this class from the given + * JSON object. + * + * @param {Object} data - A JSON object representing the serialized geometry. + * @return {BoxGeometry} A new instance. + */ + static fromJSON( data ) { + + return new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments ); + + } + +} + /** * A geometry class for representing a capsule. * @@ -38289,168 +36795,401 @@ class WireframeGeometry extends BufferGeometry { if ( geometry.index !== null ) { - // indexed BufferGeometry + // indexed BufferGeometry + + const position = geometry.attributes.position; + const indices = geometry.index; + let groups = geometry.groups; + + if ( groups.length === 0 ) { + + groups = [ { start: 0, count: indices.count, materialIndex: 0 } ]; + + } + + // create a data structure that contains all edges without duplicates + + for ( let o = 0, ol = groups.length; o < ol; ++ o ) { + + const group = groups[ o ]; + + const groupStart = group.start; + const groupCount = group.count; + + for ( let i = groupStart, l = ( groupStart + groupCount ); i < l; i += 3 ) { + + for ( let j = 0; j < 3; j ++ ) { + + const index1 = indices.getX( i + j ); + const index2 = indices.getX( i + ( j + 1 ) % 3 ); + + start.fromBufferAttribute( position, index1 ); + end.fromBufferAttribute( position, index2 ); + + if ( isUniqueEdge( start, end, edges ) === true ) { + + vertices.push( start.x, start.y, start.z ); + vertices.push( end.x, end.y, end.z ); + + } + + } + + } + + } + + } else { + + // non-indexed BufferGeometry + + const position = geometry.attributes.position; + + for ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) { + + for ( let j = 0; j < 3; j ++ ) { + + // three edges per triangle, an edge is represented as (index1, index2) + // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) + + const index1 = 3 * i + j; + const index2 = 3 * i + ( ( j + 1 ) % 3 ); + + start.fromBufferAttribute( position, index1 ); + end.fromBufferAttribute( position, index2 ); + + if ( isUniqueEdge( start, end, edges ) === true ) { + + vertices.push( start.x, start.y, start.z ); + vertices.push( end.x, end.y, end.z ); + + } + + } + + } + + } + + // build geometry + + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + + } + + } + + copy( source ) { + + super.copy( source ); + + this.parameters = Object.assign( {}, source.parameters ); + + return this; + + } + +} + +function isUniqueEdge( start, end, edges ) { + + const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`; + const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge + + if ( edges.has( hash1 ) === true || edges.has( hash2 ) === true ) { + + return false; + + } else { + + edges.add( hash1 ); + edges.add( hash2 ); + return true; + + } + +} + +var Geometries = /*#__PURE__*/Object.freeze({ + __proto__: null, + BoxGeometry: BoxGeometry, + CapsuleGeometry: CapsuleGeometry, + CircleGeometry: CircleGeometry, + ConeGeometry: ConeGeometry, + CylinderGeometry: CylinderGeometry, + DodecahedronGeometry: DodecahedronGeometry, + EdgesGeometry: EdgesGeometry, + ExtrudeGeometry: ExtrudeGeometry, + IcosahedronGeometry: IcosahedronGeometry, + LatheGeometry: LatheGeometry, + OctahedronGeometry: OctahedronGeometry, + PlaneGeometry: PlaneGeometry, + PolyhedronGeometry: PolyhedronGeometry, + RingGeometry: RingGeometry, + ShapeGeometry: ShapeGeometry, + SphereGeometry: SphereGeometry, + TetrahedronGeometry: TetrahedronGeometry, + TorusGeometry: TorusGeometry, + TorusKnotGeometry: TorusKnotGeometry, + TubeGeometry: TubeGeometry, + WireframeGeometry: WireframeGeometry +}); + +/** + * This material can receive shadows, but otherwise is completely transparent. + * + * ```js + * const geometry = new THREE.PlaneGeometry( 2000, 2000 ); + * geometry.rotateX( - Math.PI / 2 ); + * + * const material = new THREE.ShadowMaterial(); + * material.opacity = 0.2; + * + * const plane = new THREE.Mesh( geometry, material ); + * plane.position.y = -200; + * plane.receiveShadow = true; + * scene.add( plane ); + * ``` + * + * @augments Material + */ +class ShadowMaterial extends Material { + + /** + * Constructs a new shadow material. + * + * @param {Object} [parameters] - An object with one or more properties + * defining the material's appearance. Any property of the material + * (including any property from inherited materials) can be passed + * in here. Color values can be passed any type of value accepted + * by {@link Color#set}. + */ + constructor( parameters ) { + + super(); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isShadowMaterial = true; + + this.type = 'ShadowMaterial'; + + /** + * Color of the material. + * + * @type {Color} + * @default (0,0,0) + */ + this.color = new Color( 0x000000 ); + + /** + * Overwritten since shadow materials are transparent + * by default. + * + * @type {boolean} + * @default true + */ + this.transparent = true; + + /** + * Whether the material is affected by fog or not. + * + * @type {boolean} + * @default true + */ + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.fog = source.fog; + + return this; + + } + +} + +/** + * Provides utility functions for managing uniforms. + * + * @module UniformsUtils + */ + +/** + * Clones the given uniform definitions by performing a deep-copy. That means + * if the value of a uniform refers to an object like a Vector3 or Texture, + * the cloned uniform will refer to a new object reference. + * + * @param {Object} src - An object representing uniform definitions. + * @return {Object} The cloned uniforms. + */ +function cloneUniforms( src ) { + + const dst = {}; - const position = geometry.attributes.position; - const indices = geometry.index; - let groups = geometry.groups; + for ( const u in src ) { - if ( groups.length === 0 ) { + dst[ u ] = {}; - groups = [ { start: 0, count: indices.count, materialIndex: 0 } ]; + for ( const p in src[ u ] ) { - } + const property = src[ u ][ p ]; - // create a data structure that contains all edges without duplicates + if ( property && ( property.isColor || + property.isMatrix3 || property.isMatrix4 || + property.isVector2 || property.isVector3 || property.isVector4 || + property.isTexture || property.isQuaternion ) ) { - for ( let o = 0, ol = groups.length; o < ol; ++ o ) { + if ( property.isRenderTargetTexture ) { - const group = groups[ o ]; + warn( 'UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms().' ); + dst[ u ][ p ] = null; - const groupStart = group.start; - const groupCount = group.count; + } else { - for ( let i = groupStart, l = ( groupStart + groupCount ); i < l; i += 3 ) { + dst[ u ][ p ] = property.clone(); - for ( let j = 0; j < 3; j ++ ) { + } - const index1 = indices.getX( i + j ); - const index2 = indices.getX( i + ( j + 1 ) % 3 ); + } else if ( Array.isArray( property ) ) { - start.fromBufferAttribute( position, index1 ); - end.fromBufferAttribute( position, index2 ); + dst[ u ][ p ] = property.slice(); - if ( isUniqueEdge( start, end, edges ) === true ) { + } else { - vertices.push( start.x, start.y, start.z ); - vertices.push( end.x, end.y, end.z ); + dst[ u ][ p ] = property; - } + } - } + } - } + } - } + return dst; - } else { +} - // non-indexed BufferGeometry +/** + * Merges the given uniform definitions into a single object. Since the + * method internally uses cloneUniforms(), it performs a deep-copy when + * producing the merged uniform definitions. + * + * @param {Array} uniforms - An array of objects containing uniform definitions. + * @return {Object} The merged uniforms. + */ +function mergeUniforms( uniforms ) { - const position = geometry.attributes.position; + const merged = {}; - for ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) { + for ( let u = 0; u < uniforms.length; u ++ ) { - for ( let j = 0; j < 3; j ++ ) { + const tmp = cloneUniforms( uniforms[ u ] ); - // three edges per triangle, an edge is represented as (index1, index2) - // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) + for ( const p in tmp ) { - const index1 = 3 * i + j; - const index2 = 3 * i + ( ( j + 1 ) % 3 ); + merged[ p ] = tmp[ p ]; - start.fromBufferAttribute( position, index1 ); - end.fromBufferAttribute( position, index2 ); + } - if ( isUniqueEdge( start, end, edges ) === true ) { + } - vertices.push( start.x, start.y, start.z ); - vertices.push( end.x, end.y, end.z ); + return merged; - } +} - } +function cloneUniformsGroups( src ) { - } + const dst = []; - } + for ( let u = 0; u < src.length; u ++ ) { - // build geometry + dst.push( src[ u ].clone() ); - this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + } - } + return dst; - } +} - copy( source ) { +function getUnlitUniformColorSpace( renderer ) { - super.copy( source ); + const currentRenderTarget = renderer.getRenderTarget(); - this.parameters = Object.assign( {}, source.parameters ); + if ( currentRenderTarget === null ) { - return this; + // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 + return renderer.outputColorSpace; } -} - -function isUniqueEdge( start, end, edges ) { + // https://github.com/mrdoob/three.js/issues/27868 + if ( currentRenderTarget.isXRRenderTarget === true ) { - const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`; - const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge + return currentRenderTarget.texture.colorSpace; - if ( edges.has( hash1 ) === true || edges.has( hash2 ) === true ) { + } - return false; + return ColorManagement.workingColorSpace; - } else { +} - edges.add( hash1 ); - edges.add( hash2 ); - return true; +// Legacy - } +const UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; -} +var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; -var Geometries = /*#__PURE__*/Object.freeze({ - __proto__: null, - BoxGeometry: BoxGeometry, - CapsuleGeometry: CapsuleGeometry, - CircleGeometry: CircleGeometry, - ConeGeometry: ConeGeometry, - CylinderGeometry: CylinderGeometry, - DodecahedronGeometry: DodecahedronGeometry, - EdgesGeometry: EdgesGeometry, - ExtrudeGeometry: ExtrudeGeometry, - IcosahedronGeometry: IcosahedronGeometry, - LatheGeometry: LatheGeometry, - OctahedronGeometry: OctahedronGeometry, - PlaneGeometry: PlaneGeometry, - PolyhedronGeometry: PolyhedronGeometry, - RingGeometry: RingGeometry, - ShapeGeometry: ShapeGeometry, - SphereGeometry: SphereGeometry, - TetrahedronGeometry: TetrahedronGeometry, - TorusGeometry: TorusGeometry, - TorusKnotGeometry: TorusKnotGeometry, - TubeGeometry: TubeGeometry, - WireframeGeometry: WireframeGeometry -}); +var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; /** - * This material can receive shadows, but otherwise is completely transparent. + * A material rendered with custom shaders. A shader is a small program written in GLSL. + * that runs on the GPU. You may want to use a custom shader if you need to implement an + * effect not included with any of the built-in materials. * - * ```js - * const geometry = new THREE.PlaneGeometry( 2000, 2000 ); - * geometry.rotateX( - Math.PI / 2 ); + * There are the following notes to bear in mind when using a `ShaderMaterial`: * - * const material = new THREE.ShadowMaterial(); - * material.opacity = 0.2; + * - `ShaderMaterial` can only be used with {@link WebGLRenderer}. + * - Built in attributes and uniforms are passed to the shaders along with your code. If + * you don't want that, use {@link RawShaderMaterial} instead. + * - You can use the directive `#pragma unroll_loop_start` and `#pragma unroll_loop_end` + * in order to unroll a `for` loop in GLSL by the shader preprocessor. The directive has + * to be placed right above the loop. The loop formatting has to correspond to a defined standard. + * - The loop has to be [normalized](https://en.wikipedia.org/wiki/Normalized_loop). + * - The loop variable has to be *i*. + * - The value `UNROLLED_LOOP_INDEX` will be replaced with the explicitly + * value of *i* for the given iteration and can be used in preprocessor + * statements. * - * const plane = new THREE.Mesh( geometry, material ); - * plane.position.y = -200; - * plane.receiveShadow = true; - * scene.add( plane ); + * ```js + * const material = new THREE.ShaderMaterial( { + * uniforms: { + * time: { value: 1.0 }, + * resolution: { value: new THREE.Vector2() } + * }, + * vertexShader: document.getElementById( 'vertexShader' ).textContent, + * fragmentShader: document.getElementById( 'fragmentShader' ).textContent + * } ); * ``` * * @augments Material */ -class ShadowMaterial extends Material { +class ShaderMaterial extends Material { /** - * Constructs a new shadow material. + * Constructs a new shader material. * * @param {Object} [parameters] - An object with one or more properties * defining the material's appearance. Any property of the material @@ -38469,36 +37208,214 @@ class ShadowMaterial extends Material { * @readonly * @default true */ - this.isShadowMaterial = true; + this.isShaderMaterial = true; - this.type = 'ShadowMaterial'; + this.type = 'ShaderMaterial'; /** - * Color of the material. + * Defines custom constants using `#define` directives within the GLSL code + * for both the vertex shader and the fragment shader; each key/value pair + * yields another directive. + * ```js + * defines: { + * FOO: 15, + * BAR: true + * } + * ``` + * Yields the lines: + * ``` + * #define FOO 15 + * #define BAR true + * ``` * - * @type {Color} - * @default (0,0,0) + * @type {Object} */ - this.color = new Color( 0x000000 ); + this.defines = {}; /** - * Overwritten since shadow materials are transparent - * by default. + * An object of the form: + * ```js + * { + * "uniform1": { value: 1.0 }, + * "uniform2": { value: 2 } + * } + * ``` + * specifying the uniforms to be passed to the shader code; keys are uniform + * names, values are definitions of the form + * ``` + * { + * value: 1.0 + * } + * ``` + * where `value` is the value of the uniform. Names must match the name of + * the uniform, as defined in the GLSL code. Note that uniforms are refreshed + * on every frame, so updating the value of the uniform will immediately + * update the value available to the GLSL code. + * + * @type {Object} + */ + this.uniforms = {}; + + /** + * An array holding uniforms groups for configuring UBOs. + * + * @type {Array} + */ + this.uniformsGroups = []; + + /** + * Vertex shader GLSL code. This is the actual code for the shader. + * + * @type {string} + */ + this.vertexShader = default_vertex; + + /** + * Fragment shader GLSL code. This is the actual code for the shader. + * + * @type {string} + */ + this.fragmentShader = default_fragment; + + /** + * Controls line thickness or lines. + * + * WebGL and WebGPU ignore this setting and always render line primitives with a + * width of one pixel. + * + * @type {number} + * @default 1 + */ + this.linewidth = 1; + + /** + * Renders the geometry as a wireframe. * * @type {boolean} - * @default true + * @default false */ - this.transparent = true; + this.wireframe = false; /** - * Whether the material is affected by fog or not. + * Controls the thickness of the wireframe. + * + * WebGL and WebGPU ignore this property and always render + * 1 pixel wide lines. + * + * @type {number} + * @default 1 + */ + this.wireframeLinewidth = 1; + + /** + * Defines whether the material color is affected by global fog settings; `true` + * to pass fog uniforms to the shader. + * + * Setting this property to `true` requires the definition of fog uniforms. It is + * recommended to use `UniformsUtils.merge()` to combine the custom shader uniforms + * with predefined fog uniforms. + * + * ```js + * const material = new ShaderMaterial( { + * uniforms: UniformsUtils.merge( [ UniformsLib[ 'fog' ], shaderUniforms ] ); + * vertexShader: vertexShader, + * fragmentShader: fragmentShader, + * fog: true + * } ); + * ``` + * + * @type {boolean} + * @default false + */ + this.fog = false; + + /** + * Defines whether this material uses lighting; `true` to pass uniform data + * related to lighting to this shader. + * + * @type {boolean} + * @default false + */ + this.lights = false; + + /** + * Defines whether this material supports clipping; `true` to let the renderer + * pass the clippingPlanes uniform. + * + * @type {boolean} + * @default false + */ + this.clipping = false; + + /** + * Overwritten and set to `true` by default. * * @type {boolean} * @default true */ - this.fog = true; + this.forceSinglePass = true; - this.setValues( parameters ); + /** + * This object allows to enable certain WebGL 2 extensions. + * + * - clipCullDistance: set to `true` to use vertex shader clipping + * - multiDraw: set to `true` to use vertex shader multi_draw / enable gl_DrawID + * + * @type {{clipCullDistance:false,multiDraw:false}} + */ + this.extensions = { + clipCullDistance: false, // set to use vertex shader clipping + multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID + }; + + /** + * When the rendered geometry doesn't include these attributes but the + * material does, these default values will be passed to the shaders. This + * avoids errors when buffer data is missing. + * + * - color: [ 1, 1, 1 ] + * - uv: [ 0, 0 ] + * - uv1: [ 0, 0 ] + * + * @type {Object} + */ + this.defaultAttributeValues = { + 'color': [ 1, 1, 1 ], + 'uv': [ 0, 0 ], + 'uv1': [ 0, 0 ] + }; + + /** + * If set, this calls [gl.bindAttribLocation](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation) + * to bind a generic vertex index to an attribute variable. + * + * @type {string|undefined} + * @default undefined + */ + this.index0AttributeName = undefined; + + /** + * Can be used to force a uniform update while changing uniforms in + * {@link Object3D#onBeforeRender}. + * + * @type {boolean} + * @default false + */ + this.uniformsNeedUpdate = false; + + /** + * Defines the GLSL version of custom shader code. + * + * @type {?(GLSL1|GLSL3)} + * @default null + */ + this.glslVersion = null; + + if ( parameters !== undefined ) { + + this.setValues( parameters ); + + } } @@ -38506,14 +37423,130 @@ class ShadowMaterial extends Material { super.copy( source ); - this.color.copy( source.color ); + this.fragmentShader = source.fragmentShader; + this.vertexShader = source.vertexShader; + + this.uniforms = cloneUniforms( source.uniforms ); + this.uniformsGroups = cloneUniformsGroups( source.uniformsGroups ); + + this.defines = Object.assign( {}, source.defines ); + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; this.fog = source.fog; + this.lights = source.lights; + this.clipping = source.clipping; + + this.extensions = Object.assign( {}, source.extensions ); + + this.glslVersion = source.glslVersion; + + this.defaultAttributeValues = Object.assign( {}, source.defaultAttributeValues ); + + this.index0AttributeName = source.index0AttributeName; + + this.uniformsNeedUpdate = source.uniformsNeedUpdate; return this; } + toJSON( meta ) { + + const data = super.toJSON( meta ); + + data.glslVersion = this.glslVersion; + data.uniforms = {}; + + for ( const name in this.uniforms ) { + + const uniform = this.uniforms[ name ]; + const value = uniform.value; + + if ( value && value.isTexture ) { + + data.uniforms[ name ] = { + type: 't', + value: value.toJSON( meta ).uuid + }; + + } else if ( value && value.isColor ) { + + data.uniforms[ name ] = { + type: 'c', + value: value.getHex() + }; + + } else if ( value && value.isVector2 ) { + + data.uniforms[ name ] = { + type: 'v2', + value: value.toArray() + }; + + } else if ( value && value.isVector3 ) { + + data.uniforms[ name ] = { + type: 'v3', + value: value.toArray() + }; + + } else if ( value && value.isVector4 ) { + + data.uniforms[ name ] = { + type: 'v4', + value: value.toArray() + }; + + } else if ( value && value.isMatrix3 ) { + + data.uniforms[ name ] = { + type: 'm3', + value: value.toArray() + }; + + } else if ( value && value.isMatrix4 ) { + + data.uniforms[ name ] = { + type: 'm4', + value: value.toArray() + }; + + } else { + + data.uniforms[ name ] = { + value: value + }; + + // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far + + } + + } + + if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines; + + data.vertexShader = this.vertexShader; + data.fragmentShader = this.fragmentShader; + + data.lights = this.lights; + data.clipping = this.clipping; + + const extensions = {}; + + for ( const key in this.extensions ) { + + if ( this.extensions[ key ] === true ) extensions[ key ] = true; + + } + + if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions; + + return data; + + } + } /** @@ -45841,393 +44874,947 @@ class HemisphereLight extends Light { /** * Constructs a new hemisphere light. * - * @param {(number|Color|string)} [skyColor=0xffffff] - The light's sky color. - * @param {(number|Color|string)} [groundColor=0xffffff] - The light's ground color. - * @param {number} [intensity=1] - The light's strength/intensity. + * @param {(number|Color|string)} [skyColor=0xffffff] - The light's sky color. + * @param {(number|Color|string)} [groundColor=0xffffff] - The light's ground color. + * @param {number} [intensity=1] - The light's strength/intensity. + */ + constructor( skyColor, groundColor, intensity ) { + + super( skyColor, intensity ); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isHemisphereLight = true; + + this.type = 'HemisphereLight'; + + this.position.copy( Object3D.DEFAULT_UP ); + this.updateMatrix(); + + /** + * The light's ground color. + * + * @type {Color} + */ + this.groundColor = new Color( groundColor ); + + } + + copy( source, recursive ) { + + super.copy( source, recursive ); + + this.groundColor.copy( source.groundColor ); + + return this; + + } + + toJSON( meta ) { + + const data = super.toJSON( meta ); + + data.object.groundColor = this.groundColor.getHex(); + + return data; + + } + +} + +const _projScreenMatrix$1 = /*@__PURE__*/ new Matrix4(); +const _lightPositionWorld$1 = /*@__PURE__*/ new Vector3(); +const _lookTarget$1 = /*@__PURE__*/ new 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; + + /** + * A node version of `bias`. Only supported with `WebGPURenderer`. + * + * If a bias node is defined, `bias` has no effect. + * + * @type {?Node} + * @default null + */ + this.biasNode = null; + + /** + * 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 `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 Vector2( 512, 512 ); + + /** + * The type of shadow texture. The default is `UnsignedByteType`. + * + * @type {number} + * @default UnsignedByteType + */ + this.mapType = UnsignedByteType; + + /** + * 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 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(); + this._frameExtents = new Vector2( 1, 1 ); + + this._viewportCount = 1; + + this._viewports = [ + + new 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$1.setFromMatrixPosition( light.matrixWorld ); + shadowCamera.position.copy( _lightPositionWorld$1 ); + + _lookTarget$1.setFromMatrixPosition( light.target.matrixWorld ); + shadowCamera.lookAt( _lookTarget$1 ); + shadowCamera.updateMatrixWorld(); + + _projScreenMatrix$1.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); + this._frustum.setFromProjectionMatrix( _projScreenMatrix$1, shadowCamera.coordinateSystem, shadowCamera.reversedDepth ); + + if ( shadowCamera.reversedDepth ) { + + shadowMatrix.set( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + + } else { + + 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$1 ); + + } + + /** + * 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.autoUpdate = source.autoUpdate; + this.needsUpdate = source.needsUpdate; + this.normalBias = source.normalBias; + this.blurSamples = source.blurSamples; + + this.mapSize.copy( source.mapSize ); + + this.biasNode = source.biasNode; + + 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; + + } + +} + +const _position$2 = /*@__PURE__*/ new Vector3(); +const _quaternion$2 = /*@__PURE__*/ new Quaternion(); +const _scale$2 = /*@__PURE__*/ new Vector3(); + +/** + * Abstract base class for cameras. This class should always be inherited + * when you build a new camera. + * + * @abstract + * @augments Object3D + */ +class Camera extends Object3D { + + /** + * Constructs a new camera. + */ + constructor() { + + super(); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isCamera = true; + + this.type = 'Camera'; + + /** + * The inverse of the camera's world matrix. + * + * @type {Matrix4} + */ + this.matrixWorldInverse = new Matrix4(); + + /** + * The camera's projection matrix. + * + * @type {Matrix4} + */ + this.projectionMatrix = new Matrix4(); + + /** + * The inverse of the camera's projection matrix. + * + * @type {Matrix4} + */ + this.projectionMatrixInverse = new Matrix4(); + + /** + * The coordinate system in which the camera is used. + * + * @type {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} + */ + this.coordinateSystem = WebGLCoordinateSystem; + + this._reversedDepth = false; + + } + + /** + * The flag that indicates whether the camera uses a reversed depth buffer. + * + * @type {boolean} + * @default false + */ + get reversedDepth() { + + return this._reversedDepth; + + } + + copy( source, recursive ) { + + super.copy( source, recursive ); + + this.matrixWorldInverse.copy( source.matrixWorldInverse ); + + this.projectionMatrix.copy( source.projectionMatrix ); + this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); + + this.coordinateSystem = source.coordinateSystem; + + return this; + + } + + /** + * Returns a vector representing the ("look") direction of the 3D object in world space. + * + * This method is overwritten since cameras have a different forward vector compared to other + * 3D objects. A camera looks down its local, negative z-axis by default. + * + * @param {Vector3} target - The target vector the result is stored to. + * @return {Vector3} The 3D object's direction in world space. */ - constructor( skyColor, groundColor, intensity ) { + getWorldDirection( target ) { - super( skyColor, intensity ); + return super.getWorldDirection( target ).negate(); - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isHemisphereLight = true; + } - this.type = 'HemisphereLight'; + updateMatrixWorld( force ) { - this.position.copy( Object3D.DEFAULT_UP ); - this.updateMatrix(); + super.updateMatrixWorld( force ); - /** - * The light's ground color. - * - * @type {Color} - */ - this.groundColor = new Color( groundColor ); + // exclude scale from view matrix to be glTF conform - } + this.matrixWorld.decompose( _position$2, _quaternion$2, _scale$2 ); - copy( source, recursive ) { + if ( _scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1 ) { - super.copy( source, recursive ); + this.matrixWorldInverse.copy( this.matrixWorld ).invert(); - this.groundColor.copy( source.groundColor ); + } else { - return this; + this.matrixWorldInverse.compose( _position$2, _quaternion$2, _scale$2.set( 1, 1, 1 ) ).invert(); + + } } - toJSON( meta ) { + updateWorldMatrix( updateParents, updateChildren ) { - const data = super.toJSON( meta ); + super.updateWorldMatrix( updateParents, updateChildren ); - data.object.groundColor = this.groundColor.getHex(); + // exclude scale from view matrix to be glTF conform - return data; + this.matrixWorld.decompose( _position$2, _quaternion$2, _scale$2 ); + + if ( _scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1 ) { + + this.matrixWorldInverse.copy( this.matrixWorld ).invert(); + + } else { + + this.matrixWorldInverse.compose( _position$2, _quaternion$2, _scale$2.set( 1, 1, 1 ) ).invert(); + + } + + } + + clone() { + + return new this.constructor().copy( this ); } } -const _projScreenMatrix$1 = /*@__PURE__*/ new Matrix4(); -const _lightPositionWorld$1 = /*@__PURE__*/ new Vector3(); -const _lookTarget$1 = /*@__PURE__*/ new Vector3(); +const _v3$1 = /*@__PURE__*/ new Vector3(); +const _minTarget = /*@__PURE__*/ new Vector2(); +const _maxTarget = /*@__PURE__*/ new Vector2(); /** - * Abstract base class for light shadow classes. These classes - * represent the shadow configuration for different light types. + * Camera that uses [perspective projection](https://en.wikipedia.org/wiki/Perspective_(graphical)). * - * @abstract + * This projection mode is designed to mimic the way the human eye sees. It + * is the most common projection mode used for rendering a 3D scene. + * + * ```js + * const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); + * scene.add( camera ); + * ``` + * + * @augments Camera */ -class LightShadow { +class PerspectiveCamera extends Camera { /** - * Constructs a new light shadow. + * Constructs a new perspective camera. * - * @param {Camera} camera - The light's view of the world. + * @param {number} [fov=50] - The vertical field of view. + * @param {number} [aspect=1] - The aspect ratio. + * @param {number} [near=0.1] - The camera's near plane. + * @param {number} [far=2000] - The camera's far plane. */ - constructor( camera ) { + constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) { + + super(); /** - * The light's view of the world. + * This flag can be used for type testing. * - * @type {Camera} + * @type {boolean} + * @readonly + * @default true */ - this.camera = camera; + this.isPerspectiveCamera = true; + + this.type = 'PerspectiveCamera'; /** - * The intensity of the shadow. The default is `1`. - * Valid values are in the range `[0, 1]`. + * The vertical field of view, from bottom to top of view, + * in degrees. * * @type {number} - * @default 1 + * @default 50 */ - this.intensity = 1; + this.fov = fov; /** - * 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. + * The zoom factor of the camera. * * @type {number} - * @default 0 + * @default 1 */ - this.bias = 0; + this.zoom = 1; /** - * A node version of `bias`. Only supported with `WebGPURenderer`. + * The camera's near plane. The valid range is greater than `0` + * and less than the current value of {@link PerspectiveCamera#far}. * - * If a bias node is defined, `bias` has no effect. + * Note that, unlike for the {@link OrthographicCamera}, `0` is not a + * valid value for a perspective camera's near plane. * - * @type {?Node} - * @default null + * @type {number} + * @default 0.1 */ - this.biasNode = null; + this.near = near; /** - * 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. + * The camera's far plane. Must be greater than the + * current value of {@link PerspectiveCamera#near}. * * @type {number} - * @default 0 + * @default 2000 */ - this.normalBias = 0; + this.far = far; /** - * 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 `BasicShadowMap`. + * Object distance used for stereoscopy and depth-of-field effects. This + * parameter does not influence the projection matrix unless a + * {@link StereoCamera} is being used. * * @type {number} - * @default 1 + * @default 10 */ - this.radius = 1; + this.focus = 10; /** - * The amount of samples to use when blurring a VSM shadow map. + * The aspect ratio, usually the canvas width / canvas height. * * @type {number} - * @default 8 + * @default 1 */ - this.blurSamples = 8; + this.aspect = aspect; /** - * 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. + * Represents the frustum window specification. This property should not be edited + * directly but via {@link PerspectiveCamera#setViewOffset} and {@link PerspectiveCamera#clearViewOffset}. * - * @type {Vector2} - * @default (512,512) + * @type {?Object} + * @default null */ - this.mapSize = new Vector2( 512, 512 ); + this.view = null; /** - * The type of shadow texture. The default is `UnsignedByteType`. + * Film size used for the larger axis. Default is `35` (millimeters). This + * parameter does not influence the projection matrix unless {@link PerspectiveCamera#filmOffset} + * is set to a nonzero value. * * @type {number} - * @default UnsignedByteType + * @default 35 */ - this.mapType = UnsignedByteType; + this.filmGauge = 35; /** - * The depth map generated using the internal camera; a location beyond a - * pixel's depth is in shadow. Computed internally during rendering. + * Horizontal off-center offset in the same unit as {@link PerspectiveCamera#filmGauge}. * - * @type {?RenderTarget} - * @default null + * @type {number} + * @default 0 */ - this.map = null; + this.filmOffset = 0; - /** - * 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; + this.updateProjectionMatrix(); - /** - * Model to shadow camera space, to compute location and depth in shadow map. - * This is computed internally during rendering. - * - * @type {Matrix4} - */ - this.matrix = new 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; + copy( source, recursive ) { - /** - * 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; + super.copy( source, recursive ); - this._frustum = new Frustum(); - this._frameExtents = new Vector2( 1, 1 ); + this.fov = source.fov; + this.zoom = source.zoom; - this._viewportCount = 1; + this.near = source.near; + this.far = source.far; + this.focus = source.focus; - this._viewports = [ + this.aspect = source.aspect; + this.view = source.view === null ? null : Object.assign( {}, source.view ); - new Vector4( 0, 0, 1, 1 ) + this.filmGauge = source.filmGauge; + this.filmOffset = source.filmOffset; - ]; + return this; } /** - * Used internally by the renderer to get the number of viewports that need - * to be rendered for this shadow. + * Sets the FOV by focal length in respect to the current {@link PerspectiveCamera#filmGauge}. * - * @return {number} The viewport count. + * The default film gauge is 35, so that the focal length can be specified for + * a 35mm (full frame) camera. + * + * @param {number} focalLength - Values for focal length and film gauge must have the same unit. */ - getViewportCount() { + setFocalLength( focalLength ) { - return this._viewportCount; + /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ + const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; + + this.fov = RAD2DEG * 2 * Math.atan( vExtentSlope ); + this.updateProjectionMatrix(); } /** - * Gets the shadow cameras frustum. Used internally by the renderer to cull objects. + * Returns the focal length from the current {@link PerspectiveCamera#fov} and + * {@link PerspectiveCamera#filmGauge}. * - * @return {Frustum} The shadow camera frustum. + * @return {number} The computed focal length. */ - getFrustum() { + getFocalLength() { - return this._frustum; + const vExtentSlope = Math.tan( DEG2RAD * 0.5 * this.fov ); + + return 0.5 * this.getFilmHeight() / vExtentSlope; } /** - * Update the matrices for the camera and shadow, used internally by the renderer. + * Returns the current vertical field of view angle in degrees considering {@link PerspectiveCamera#zoom}. * - * @param {Light} light - The light for which the shadow is being rendered. + * @return {number} The effective FOV. */ - updateMatrices( light ) { - - const shadowCamera = this.camera; - const shadowMatrix = this.matrix; - - _lightPositionWorld$1.setFromMatrixPosition( light.matrixWorld ); - shadowCamera.position.copy( _lightPositionWorld$1 ); - - _lookTarget$1.setFromMatrixPosition( light.target.matrixWorld ); - shadowCamera.lookAt( _lookTarget$1 ); - shadowCamera.updateMatrixWorld(); + getEffectiveFOV() { - _projScreenMatrix$1.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); - this._frustum.setFromProjectionMatrix( _projScreenMatrix$1, shadowCamera.coordinateSystem, shadowCamera.reversedDepth ); + return RAD2DEG * 2 * Math.atan( + Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom ); - if ( shadowCamera.reversedDepth ) { + } - shadowMatrix.set( - 0.5, 0.0, 0.0, 0.5, - 0.0, 0.5, 0.0, 0.5, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - ); + /** + * Returns the width of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or + * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. + * + * @return {number} The film width. + */ + getFilmWidth() { - } else { + // film not completely covered in portrait format (aspect < 1) + return this.filmGauge * Math.min( this.aspect, 1 ); - 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 - ); + } - } + /** + * Returns the height of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or + * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. + * + * @return {number} The film width. + */ + getFilmHeight() { - shadowMatrix.multiply( _projScreenMatrix$1 ); + // film not completely covered in landscape format (aspect > 1) + return this.filmGauge / Math.max( this.aspect, 1 ); } /** - * Returns a viewport definition for the given viewport index. + * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. + * Sets `minTarget` and `maxTarget` to the coordinates of the lower-left and upper-right corners of the view rectangle. * - * @param {number} viewportIndex - The viewport index. - * @return {Vector4} The viewport. + * @param {number} distance - The viewing distance. + * @param {Vector2} minTarget - The lower-left corner of the view rectangle is written into this vector. + * @param {Vector2} maxTarget - The upper-right corner of the view rectangle is written into this vector. */ - getViewport( viewportIndex ) { + getViewBounds( distance, minTarget, maxTarget ) { - return this._viewports[ viewportIndex ]; + _v3$1.set( -1, -1, 0.5 ).applyMatrix4( this.projectionMatrixInverse ); + + minTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z ); + + _v3$1.set( 1, 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse ); + + maxTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z ); } /** - * Returns the frame extends. + * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. * - * @return {Vector2} The frame extends. + * @param {number} distance - The viewing distance. + * @param {Vector2} target - The target vector that is used to store result where x is width and y is height. + * @returns {Vector2} The view size. */ - getFrameExtents() { + getViewSize( distance, target ) { - return this._frameExtents; + this.getViewBounds( distance, _minTarget, _maxTarget ); + + return target.subVectors( _maxTarget, _minTarget ); } /** - * Frees the GPU-related resources allocated by this instance. Call this - * method whenever this instance is no longer used in your app. + * Sets an offset in a larger frustum. This is useful for multi-window or + * multi-monitor/multi-machine setups. + * + * For example, if you have 3x2 monitors and each monitor is 1920x1080 and + * the monitors are in grid like this + *``` + * +---+---+---+ + * | A | B | C | + * +---+---+---+ + * | D | E | F | + * +---+---+---+ + *``` + * then for each monitor you would call it like this: + *```js + * const w = 1920; + * const h = 1080; + * const fullWidth = w * 3; + * const fullHeight = h * 2; + * + * // --A-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * // --B-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * // --C-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * // --D-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * // --E-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * // --F-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); + * ``` + * + * Note there is no reason monitors have to be the same size or in a grid. + * + * @param {number} fullWidth - The full width of multiview setup. + * @param {number} fullHeight - The full height of multiview setup. + * @param {number} x - The horizontal offset of the subcamera. + * @param {number} y - The vertical offset of the subcamera. + * @param {number} width - The width of subcamera. + * @param {number} height - The height of subcamera. */ - dispose() { + setViewOffset( fullWidth, fullHeight, x, y, width, height ) { - if ( this.map ) { + this.aspect = fullWidth / fullHeight; - this.map.dispose(); + if ( this.view === null ) { + + this.view = { + enabled: true, + fullWidth: 1, + fullHeight: 1, + offsetX: 0, + offsetY: 0, + width: 1, + height: 1 + }; } - if ( this.mapPass ) { + this.view.enabled = true; + this.view.fullWidth = fullWidth; + this.view.fullHeight = fullHeight; + this.view.offsetX = x; + this.view.offsetY = y; + this.view.width = width; + this.view.height = height; - this.mapPass.dispose(); + this.updateProjectionMatrix(); + + } + + /** + * Removes the view offset from the projection matrix. + */ + clearViewOffset() { + + if ( this.view !== null ) { + + this.view.enabled = false; } + this.updateProjectionMatrix(); + } /** - * 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. + * Updates the camera's projection matrix. Must be called after any change of + * camera properties. */ - copy( source ) { + updateProjectionMatrix() { - this.camera = source.camera.clone(); + const near = this.near; + let top = near * Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom; + let height = 2 * top; + let width = this.aspect * height; + let left = -0.5 * width; + const view = this.view; - this.intensity = source.intensity; + if ( this.view !== null && this.view.enabled ) { - this.bias = source.bias; - this.radius = source.radius; + const fullWidth = view.fullWidth, + fullHeight = view.fullHeight; - this.autoUpdate = source.autoUpdate; - this.needsUpdate = source.needsUpdate; - this.normalBias = source.normalBias; - this.blurSamples = source.blurSamples; + left += view.offsetX * width / fullWidth; + top -= view.offsetY * height / fullHeight; + width *= view.width / fullWidth; + height *= view.height / fullHeight; - this.mapSize.copy( source.mapSize ); + } - this.biasNode = source.biasNode; + const skew = this.filmOffset; + if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); - return this; + this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far, this.coordinateSystem, this.reversedDepth ); + + this.projectionMatrixInverse.copy( this.projectionMatrix ).invert(); } - /** - * Returns a new light shadow instance with copied values from this instance. - * - * @return {LightShadow} A clone of this instance. - */ - clone() { + toJSON( meta ) { - return new this.constructor().copy( this ); + const data = super.toJSON( meta ); - } + data.object.fov = this.fov; + data.object.zoom = this.zoom; - /** - * Serializes the light shadow into JSON. - * - * @return {Object} A JSON object representing the serialized light shadow. - * @see {@link ObjectLoader#parse} - */ - toJSON() { + data.object.near = this.near; + data.object.far = this.far; + data.object.focus = this.focus; - const object = {}; + data.object.aspect = this.aspect; - 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(); + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); - object.camera = this.camera.toJSON( false ).object; - delete object.camera.matrix; + data.object.filmGauge = this.filmGauge; + data.object.filmOffset = this.filmOffset; - return object; + return data; } @@ -50037,6 +49624,249 @@ class StereoCamera { } +const fov = -90; // negative fov is not an error +const aspect = 1; + +/** + * A special type of camera that is positioned in 3D space to render its surroundings into a + * cube render target. The render target can then be used as an environment map for rendering + * realtime reflections in your scene. + * + * ```js + * // Create cube render target + * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 256, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); + * + * // Create cube camera + * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); + * scene.add( cubeCamera ); + * + * // Create car + * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); + * const car = new THREE.Mesh( carGeometry, chromeMaterial ); + * scene.add( car ); + * + * // Update the render target cube + * car.visible = false; + * cubeCamera.position.copy( car.position ); + * cubeCamera.update( renderer, scene ); + * + * // Render the scene + * car.visible = true; + * renderer.render( scene, camera ); + * ``` + * + * @augments Object3D + */ +class CubeCamera extends Object3D { + + /** + * Constructs a new cube camera. + * + * @param {number} near - The camera's near plane. + * @param {number} far - The camera's far plane. + * @param {WebGLCubeRenderTarget} renderTarget - The cube render target. + */ + constructor( near, far, renderTarget ) { + + super(); + + this.type = 'CubeCamera'; + + /** + * A reference to the cube render target. + * + * @type {WebGLCubeRenderTarget} + */ + this.renderTarget = renderTarget; + + /** + * The current active coordinate system. + * + * @type {?(WebGLCoordinateSystem|WebGPUCoordinateSystem)} + * @default null + */ + this.coordinateSystem = null; + + /** + * The current active mipmap level + * + * @type {number} + * @default 0 + */ + this.activeMipmapLevel = 0; + + const cameraPX = new PerspectiveCamera( fov, aspect, near, far ); + cameraPX.layers = this.layers; + this.add( cameraPX ); + + const cameraNX = new PerspectiveCamera( fov, aspect, near, far ); + cameraNX.layers = this.layers; + this.add( cameraNX ); + + const cameraPY = new PerspectiveCamera( fov, aspect, near, far ); + cameraPY.layers = this.layers; + this.add( cameraPY ); + + const cameraNY = new PerspectiveCamera( fov, aspect, near, far ); + cameraNY.layers = this.layers; + this.add( cameraNY ); + + const cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraPZ.layers = this.layers; + this.add( cameraPZ ); + + const cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraNZ.layers = this.layers; + this.add( cameraNZ ); + + } + + /** + * Must be called when the coordinate system of the cube camera is changed. + */ + updateCoordinateSystem() { + + const coordinateSystem = this.coordinateSystem; + + const cameras = this.children.concat(); + + const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = cameras; + + for ( const camera of cameras ) this.remove( camera ); + + if ( coordinateSystem === WebGLCoordinateSystem ) { + + cameraPX.up.set( 0, 1, 0 ); + cameraPX.lookAt( 1, 0, 0 ); + + cameraNX.up.set( 0, 1, 0 ); + cameraNX.lookAt( -1, 0, 0 ); + + cameraPY.up.set( 0, 0, -1 ); + cameraPY.lookAt( 0, 1, 0 ); + + cameraNY.up.set( 0, 0, 1 ); + cameraNY.lookAt( 0, -1, 0 ); + + cameraPZ.up.set( 0, 1, 0 ); + cameraPZ.lookAt( 0, 0, 1 ); + + cameraNZ.up.set( 0, 1, 0 ); + cameraNZ.lookAt( 0, 0, -1 ); + + } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + + cameraPX.up.set( 0, -1, 0 ); + cameraPX.lookAt( -1, 0, 0 ); + + cameraNX.up.set( 0, -1, 0 ); + cameraNX.lookAt( 1, 0, 0 ); + + cameraPY.up.set( 0, 0, 1 ); + cameraPY.lookAt( 0, 1, 0 ); + + cameraNY.up.set( 0, 0, -1 ); + cameraNY.lookAt( 0, -1, 0 ); + + cameraPZ.up.set( 0, -1, 0 ); + cameraPZ.lookAt( 0, 0, 1 ); + + cameraNZ.up.set( 0, -1, 0 ); + cameraNZ.lookAt( 0, 0, -1 ); + + } else { + + throw new Error( 'THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: ' + coordinateSystem ); + + } + + for ( const camera of cameras ) { + + this.add( camera ); + + camera.updateMatrixWorld(); + + } + + } + + /** + * Calling this method will render the given scene with the given renderer + * into the cube render target of the camera. + * + * @param {(Renderer|WebGLRenderer)} renderer - The renderer. + * @param {Scene} scene - The scene to render. + */ + update( renderer, scene ) { + + if ( this.parent === null ) this.updateMatrixWorld(); + + const { renderTarget, activeMipmapLevel } = this; + + if ( this.coordinateSystem !== renderer.coordinateSystem ) { + + this.coordinateSystem = renderer.coordinateSystem; + + this.updateCoordinateSystem(); + + } + + const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children; + + const currentRenderTarget = renderer.getRenderTarget(); + const currentActiveCubeFace = renderer.getActiveCubeFace(); + const currentActiveMipmapLevel = renderer.getActiveMipmapLevel(); + + const currentXrEnabled = renderer.xr.enabled; + + renderer.xr.enabled = false; + + const generateMipmaps = renderTarget.texture.generateMipmaps; + + renderTarget.texture.generateMipmaps = false; + + // https://github.com/mrdoob/three.js/issues/31413#issuecomment-3095966812 + const reversedDepthBuffer = !! ( renderer.isWebGLRenderer && renderer.state.buffers.depth.getReversed() ); + + renderer.setRenderTarget( renderTarget, 0, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraPX ); + + renderer.setRenderTarget( renderTarget, 1, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraNX ); + + renderer.setRenderTarget( renderTarget, 2, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraPY ); + + renderer.setRenderTarget( renderTarget, 3, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraNY ); + + renderer.setRenderTarget( renderTarget, 4, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraPZ ); + + // mipmaps are generated during the last call of render() + // at this point, all sides of the cube render target are defined + + renderTarget.texture.generateMipmaps = generateMipmaps; + + renderer.setRenderTarget( renderTarget, 5, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraNZ ); + + renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel ); + + renderer.xr.enabled = currentXrEnabled; + + renderTarget.texture.needsPMREMUpdate = true; + + } + +} + /** * This type of camera can be used in order to efficiently render a scene with a * predefined set of cameras. This is an important performance aspect for @@ -56898,12 +56728,10 @@ class Line3 { } - c1.copy( p1 ).add( _d1.multiplyScalar( s ) ); - c2.copy( p2 ).add( _d2.multiplyScalar( t ) ); - - c1.sub( c2 ); + c1.copy( p1 ).addScaledVector( _d1, s ); + c2.copy( p2 ).addScaledVector( _d2, t ); - return c1.dot( c1 ); + return c1.distanceToSquared( c2 ); } @@ -63311,6 +63139,178 @@ function _getCommonVertexShader() { } +/** + * A cube render target used in context of {@link WebGLRenderer}. + * + * @augments WebGLRenderTarget + */ +class WebGLCubeRenderTarget extends WebGLRenderTarget { + + /** + * Constructs a new cube render target. + * + * @param {number} [size=1] - The size of the render target. + * @param {RenderTarget~Options} [options] - The configuration object. + */ + constructor( size = 1, options = {} ) { + + super( size, size, options ); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isWebGLCubeRenderTarget = true; + + const image = { width: size, height: size, depth: 1 }; + const images = [ image, image, image, image, image, image ]; + + /** + * Overwritten with a different texture type. + * + * @type {DataArrayTexture} + */ + this.texture = new CubeTexture( images ); + this._setTextureOptions( options ); + + // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, + // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. + + // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped + // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture + // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). + + this.texture.isRenderTargetTexture = true; + + } + + /** + * Converts the given equirectangular texture to a cube map. + * + * @param {WebGLRenderer} renderer - The renderer. + * @param {Texture} texture - The equirectangular texture. + * @return {WebGLCubeRenderTarget} A reference to this cube render target. + */ + fromEquirectangularTexture( renderer, texture ) { + + this.texture.type = texture.type; + this.texture.colorSpace = texture.colorSpace; + + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; + + const shader = { + + uniforms: { + tEquirect: { value: null }, + }, + + vertexShader: /* glsl */` + + varying vec3 vWorldDirection; + + vec3 transformDirection( in vec3 dir, in mat4 matrix ) { + + return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); + + } + + void main() { + + vWorldDirection = transformDirection( position, modelMatrix ); + + #include + #include + + } + `, + + fragmentShader: /* glsl */` + + uniform sampler2D tEquirect; + + varying vec3 vWorldDirection; + + #include + + void main() { + + vec3 direction = normalize( vWorldDirection ); + + vec2 sampleUV = equirectUv( direction ); + + gl_FragColor = texture2D( tEquirect, sampleUV ); + + } + ` + }; + + const geometry = new BoxGeometry( 5, 5, 5 ); + + const material = new ShaderMaterial( { + + name: 'CubemapFromEquirect', + + uniforms: cloneUniforms( shader.uniforms ), + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader, + side: BackSide, + blending: NoBlending + + } ); + + material.uniforms.tEquirect.value = texture; + + const mesh = new Mesh( geometry, material ); + + const currentMinFilter = texture.minFilter; + + // Avoid blurred poles + if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter; + + const camera = new CubeCamera( 1, 10, this ); + camera.update( renderer, mesh ); + + texture.minFilter = currentMinFilter; + + mesh.geometry.dispose(); + mesh.material.dispose(); + + return this; + + } + + /** + * Clears this cube render target. + * + * @param {WebGLRenderer} renderer - The renderer. + * @param {boolean} [color=true] - Whether the color buffer should be cleared or not. + * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not. + * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not. + */ + clear( renderer, color = true, depth = true, stencil = true ) { + + const currentRenderTarget = renderer.getRenderTarget(); + + for ( let i = 0; i < 6; i ++ ) { + + renderer.setRenderTarget( this, i ); + + renderer.clear( color, depth, stencil ); + + } + + renderer.setRenderTarget( currentRenderTarget ); + + } + +} + function WebGLEnvironments( renderer ) { let cubeMaps = new WeakMap(); diff --git a/build/three.core.js b/build/three.core.js index 421a62228dfdab..522c09784ca5bf 100644 --- a/build/three.core.js +++ b/build/three.core.js @@ -9711,17 +9711,68 @@ class WebGL3DRenderTarget extends WebGLRenderTarget { } /** - * Represents an axis-aligned bounding box (AABB) in 3D space. + * Represents a 4x4 matrix. + * + * The most common use of a 4x4 matrix in 3D computer graphics is as a transformation matrix. + * For an introduction to transformation matrices as used in WebGL, check out [this tutorial](https://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices) + * + * This allows a 3D vector representing a point in 3D space to undergo + * transformations such as translation, rotation, shear, scale, reflection, + * orthogonal or perspective projection and so on, by being multiplied by the + * matrix. This is known as `applying` the matrix to the vector. + * + * A Note on Row-Major and Column-Major Ordering: + * + * The constructor and {@link Matrix3#set} method take arguments in + * [row-major](https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order) + * order, while internally they are stored in the {@link Matrix3#elements} array in column-major order. + * This means that calling: + * ```js + * const m = new THREE.Matrix4(); + * m.set( 11, 12, 13, 14, + * 21, 22, 23, 24, + * 31, 32, 33, 34, + * 41, 42, 43, 44 ); + * ``` + * will result in the elements array containing: + * ```js + * m.elements = [ 11, 21, 31, 41, + * 12, 22, 32, 42, + * 13, 23, 33, 43, + * 14, 24, 34, 44 ]; + * ``` + * and internally all calculations are performed using column-major ordering. + * However, as the actual ordering makes no difference mathematically and + * most people are used to thinking about matrices in row-major order, the + * three.js documentation shows matrices in row-major order. Just bear in + * mind that if you are reading the source code, you'll have to take the + * transpose of any matrices outlined here to make sense of the calculations. */ -class Box3 { +class Matrix4 { /** - * Constructs a new bounding box. + * Constructs a new 4x4 matrix. The arguments are supposed to be + * in row-major order. If no arguments are provided, the constructor + * initializes the matrix as an identity matrix. * - * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box. - * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box. + * @param {number} [n11] - 1-1 matrix element. + * @param {number} [n12] - 1-2 matrix element. + * @param {number} [n13] - 1-3 matrix element. + * @param {number} [n14] - 1-4 matrix element. + * @param {number} [n21] - 2-1 matrix element. + * @param {number} [n22] - 2-2 matrix element. + * @param {number} [n23] - 2-3 matrix element. + * @param {number} [n24] - 2-4 matrix element. + * @param {number} [n31] - 3-1 matrix element. + * @param {number} [n32] - 3-2 matrix element. + * @param {number} [n33] - 3-3 matrix element. + * @param {number} [n34] - 3-4 matrix element. + * @param {number} [n41] - 4-1 matrix element. + * @param {number} [n42] - 4-2 matrix element. + * @param {number} [n43] - 4-3 matrix element. + * @param {number} [n44] - 4-4 matrix element. */ - constructor( min = new Vector3( + Infinity, + Infinity, + Infinity ), max = new Vector3( - Infinity, - Infinity, - Infinity ) ) { + constructor( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { /** * This flag can be used for type testing. @@ -9730,6896 +9781,6799 @@ class Box3 { * @readonly * @default true */ - this.isBox3 = true; + Matrix4.prototype.isMatrix4 = true; /** - * The lower boundary of the box. + * A column-major list of matrix values. * - * @type {Vector3} + * @type {Array} */ - this.min = min; + this.elements = [ - /** - * The upper boundary of the box. - * - * @type {Vector3} - */ - this.max = max; + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - } + ]; - /** - * Sets the lower and upper boundaries of this box. - * Please note that this method only copies the values from the given objects. - * - * @param {Vector3} min - The lower boundary of the box. - * @param {Vector3} max - The upper boundary of the box. - * @return {Box3} A reference to this bounding box. - */ - set( min, max ) { + if ( n11 !== undefined ) { - this.min.copy( min ); - this.max.copy( max ); + this.set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ); - return this; + } } /** - * Sets the upper and lower bounds of this box so it encloses the position data - * in the given array. + * Sets the elements of the matrix.The arguments are supposed to be + * in row-major order. * - * @param {Array} array - An array holding 3D position data. - * @return {Box3} A reference to this bounding box. + * @param {number} [n11] - 1-1 matrix element. + * @param {number} [n12] - 1-2 matrix element. + * @param {number} [n13] - 1-3 matrix element. + * @param {number} [n14] - 1-4 matrix element. + * @param {number} [n21] - 2-1 matrix element. + * @param {number} [n22] - 2-2 matrix element. + * @param {number} [n23] - 2-3 matrix element. + * @param {number} [n24] - 2-4 matrix element. + * @param {number} [n31] - 3-1 matrix element. + * @param {number} [n32] - 3-2 matrix element. + * @param {number} [n33] - 3-3 matrix element. + * @param {number} [n34] - 3-4 matrix element. + * @param {number} [n41] - 4-1 matrix element. + * @param {number} [n42] - 4-2 matrix element. + * @param {number} [n43] - 4-3 matrix element. + * @param {number} [n44] - 4-4 matrix element. + * @return {Matrix4} A reference to this matrix. */ - setFromArray( array ) { - - this.makeEmpty(); - - for ( let i = 0, il = array.length; i < il; i += 3 ) { + set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { - this.expandByPoint( _vector$b.fromArray( array, i ) ); + const te = this.elements; - } + te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; + te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; + te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; + te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; return this; } /** - * Sets the upper and lower bounds of this box so it encloses the position data - * in the given buffer attribute. + * Sets this matrix to the 4x4 identity matrix. * - * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data. - * @return {Box3} A reference to this bounding box. + * @return {Matrix4} A reference to this matrix. */ - setFromBufferAttribute( attribute ) { - - this.makeEmpty(); + identity() { - for ( let i = 0, il = attribute.count; i < il; i ++ ) { + this.set( - this.expandByPoint( _vector$b.fromBufferAttribute( attribute, i ) ); + 1, 0, 0, 0, + 0, 1, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 - } + ); return this; } /** - * Sets the upper and lower bounds of this box so it encloses the position data - * in the given array. + * Returns a matrix with copied values from this instance. * - * @param {Array} points - An array holding 3D position data as instances of {@link Vector3}. - * @return {Box3} A reference to this bounding box. + * @return {Matrix4} A clone of this instance. */ - setFromPoints( points ) { - - this.makeEmpty(); - - for ( let i = 0, il = points.length; i < il; i ++ ) { - - this.expandByPoint( points[ i ] ); - - } + clone() { - return this; + return new Matrix4().fromArray( this.elements ); } /** - * Centers this box on the given center vector and sets this box's width, height and - * depth to the given size values. + * Copies the values of the given matrix to this instance. * - * @param {Vector3} center - The center of the box. - * @param {Vector3} size - The x, y and z dimensions of the box. - * @return {Box3} A reference to this bounding box. + * @param {Matrix4} m - The matrix to copy. + * @return {Matrix4} A reference to this matrix. */ - setFromCenterAndSize( center, size ) { + copy( m ) { - const halfSize = _vector$b.copy( size ).multiplyScalar( 0.5 ); + const te = this.elements; + const me = m.elements; - this.min.copy( center ).sub( halfSize ); - this.max.copy( center ).add( halfSize ); + te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; + te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; + te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; + te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; return this; } /** - * Computes the world-axis-aligned bounding box for the given 3D object - * (including its children), accounting for the object's, and children's, - * world transforms. The function may result in a larger box than strictly necessary. + * Copies the translation component of the given matrix + * into this matrix's translation component. * - * @param {Object3D} object - The 3D object to compute the bounding box for. - * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest - * world-axis-aligned bounding box at the expense of more computation. - * @return {Box3} A reference to this bounding box. + * @param {Matrix4} m - The matrix to copy the translation component. + * @return {Matrix4} A reference to this matrix. */ - setFromObject( object, precise = false ) { + copyPosition( m ) { - this.makeEmpty(); + const te = this.elements, me = m.elements; - return this.expandByObject( object, precise ); + te[ 12 ] = me[ 12 ]; + te[ 13 ] = me[ 13 ]; + te[ 14 ] = me[ 14 ]; + + return this; } /** - * Returns a new box with copied values from this instance. + * Set the upper 3x3 elements of this matrix to the values of given 3x3 matrix. * - * @return {Box3} A clone of this instance. + * @param {Matrix3} m - The 3x3 matrix. + * @return {Matrix4} A reference to this matrix. */ - clone() { + setFromMatrix3( m ) { - return new this.constructor().copy( this ); + const me = m.elements; - } + this.set( - /** - * Copies the values of the given box to this instance. - * - * @param {Box3} box - The box to copy. - * @return {Box3} A reference to this bounding box. - */ - copy( box ) { + me[ 0 ], me[ 3 ], me[ 6 ], 0, + me[ 1 ], me[ 4 ], me[ 7 ], 0, + me[ 2 ], me[ 5 ], me[ 8 ], 0, + 0, 0, 0, 1 - this.min.copy( box.min ); - this.max.copy( box.max ); + ); return this; } /** - * Makes this box empty which means in encloses a zero space in 3D. + * Extracts the basis of this matrix into the three axis vectors provided. * - * @return {Box3} A reference to this bounding box. + * @param {Vector3} xAxis - The basis's x axis. + * @param {Vector3} yAxis - The basis's y axis. + * @param {Vector3} zAxis - The basis's z axis. + * @return {Matrix4} A reference to this matrix. */ - makeEmpty() { + extractBasis( xAxis, yAxis, zAxis ) { - this.min.x = this.min.y = this.min.z = + Infinity; - this.max.x = this.max.y = this.max.z = - Infinity; + if ( this.determinant() === 0 ) { - return this; + xAxis.set( 1, 0, 0 ); + yAxis.set( 0, 1, 0 ); + zAxis.set( 0, 0, 1 ); - } + return this; - /** - * Returns true if this box includes zero points within its bounds. - * Note that a box with equal lower and upper bounds still includes one - * point, the one both bounds share. - * - * @return {boolean} Whether this box is empty or not. - */ - isEmpty() { + } - // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes + xAxis.setFromMatrixColumn( this, 0 ); + yAxis.setFromMatrixColumn( this, 1 ); + zAxis.setFromMatrixColumn( this, 2 ); - return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); + return this; } /** - * Returns the center point of this box. + * Sets the given basis vectors to this matrix. * - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The center point. + * @param {Vector3} xAxis - The basis's x axis. + * @param {Vector3} yAxis - The basis's y axis. + * @param {Vector3} zAxis - The basis's z axis. + * @return {Matrix4} A reference to this matrix. */ - getCenter( target ) { - - return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); - - } + makeBasis( xAxis, yAxis, zAxis ) { - /** - * Returns the dimensions of this box. - * - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The size. - */ - getSize( target ) { + this.set( + xAxis.x, yAxis.x, zAxis.x, 0, + xAxis.y, yAxis.y, zAxis.y, 0, + xAxis.z, yAxis.z, zAxis.z, 0, + 0, 0, 0, 1 + ); - return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); + return this; } /** - * Expands the boundaries of this box to include the given point. + * Extracts the rotation component of the given matrix + * into this matrix's rotation component. * - * @param {Vector3} point - The point that should be included by the bounding box. - * @return {Box3} A reference to this bounding box. + * Note: This method does not support reflection matrices. + * + * @param {Matrix4} m - The matrix. + * @return {Matrix4} A reference to this matrix. */ - expandByPoint( point ) { + extractRotation( m ) { - this.min.min( point ); - this.max.max( point ); + if ( m.determinant() === 0 ) { - return this; + return this.identity(); - } + } - /** - * Expands this box equilaterally by the given vector. The width of this - * box will be expanded by the x component of the vector in both - * directions. The height of this box will be expanded by the y component of - * the vector in both directions. The depth of this box will be - * expanded by the z component of the vector in both directions. - * - * @param {Vector3} vector - The vector that should expand the bounding box. - * @return {Box3} A reference to this bounding box. - */ - expandByVector( vector ) { + const te = this.elements; + const me = m.elements; - this.min.sub( vector ); - this.max.add( vector ); + const scaleX = 1 / _v1$7.setFromMatrixColumn( m, 0 ).length(); + const scaleY = 1 / _v1$7.setFromMatrixColumn( m, 1 ).length(); + const scaleZ = 1 / _v1$7.setFromMatrixColumn( m, 2 ).length(); - return this; + te[ 0 ] = me[ 0 ] * scaleX; + te[ 1 ] = me[ 1 ] * scaleX; + te[ 2 ] = me[ 2 ] * scaleX; + te[ 3 ] = 0; - } + te[ 4 ] = me[ 4 ] * scaleY; + te[ 5 ] = me[ 5 ] * scaleY; + te[ 6 ] = me[ 6 ] * scaleY; + te[ 7 ] = 0; - /** - * Expands each dimension of the box by the given scalar. If negative, the - * dimensions of the box will be contracted. - * - * @param {number} scalar - The scalar value that should expand the bounding box. - * @return {Box3} A reference to this bounding box. - */ - expandByScalar( scalar ) { + te[ 8 ] = me[ 8 ] * scaleZ; + te[ 9 ] = me[ 9 ] * scaleZ; + te[ 10 ] = me[ 10 ] * scaleZ; + te[ 11 ] = 0; - this.min.addScalar( - scalar ); - this.max.addScalar( scalar ); + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; return this; } /** - * Expands the boundaries of this box to include the given 3D object and - * its children, accounting for the object's, and children's, world - * transforms. The function may result in a larger box than strictly - * necessary (unless the precise parameter is set to true). + * Sets the rotation component (the upper left 3x3 matrix) of this matrix to + * the rotation specified by the given Euler angles. The rest of + * the matrix is set to the identity. Depending on the {@link Euler#order}, + * there are six possible outcomes. See [this page](https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix) + * for a complete list. * - * @param {Object3D} object - The 3D object that should expand the bounding box. - * @param {boolean} precise - If set to `true`, the method expands the bounding box - * as little as necessary at the expense of more computation. - * @return {Box3} A reference to this bounding box. + * @param {Euler} euler - The Euler angles. + * @return {Matrix4} A reference to this matrix. */ - expandByObject( object, precise = false ) { - - // Computes the world-axis-aligned bounding box of an object (including its children), - // accounting for both the object's, and children's, world transforms + makeRotationFromEuler( euler ) { - object.updateWorldMatrix( false, false ); + const te = this.elements; - const geometry = object.geometry; + const x = euler.x, y = euler.y, z = euler.z; + const a = Math.cos( x ), b = Math.sin( x ); + const c = Math.cos( y ), d = Math.sin( y ); + const e = Math.cos( z ), f = Math.sin( z ); - if ( geometry !== undefined ) { + if ( euler.order === 'XYZ' ) { - const positionAttribute = geometry.getAttribute( 'position' ); + const ae = a * e, af = a * f, be = b * e, bf = b * f; - // precise AABB computation based on vertex data requires at least a position attribute. - // instancing isn't supported so far and uses the normal (conservative) code path. + te[ 0 ] = c * e; + te[ 4 ] = - c * f; + te[ 8 ] = d; - if ( precise === true && positionAttribute !== undefined && object.isInstancedMesh !== true ) { + te[ 1 ] = af + be * d; + te[ 5 ] = ae - bf * d; + te[ 9 ] = - b * c; - for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) { + te[ 2 ] = bf - ae * d; + te[ 6 ] = be + af * d; + te[ 10 ] = a * c; - if ( object.isMesh === true ) { + } else if ( euler.order === 'YXZ' ) { - object.getVertexPosition( i, _vector$b ); + const ce = c * e, cf = c * f, de = d * e, df = d * f; - } else { + te[ 0 ] = ce + df * b; + te[ 4 ] = de * b - cf; + te[ 8 ] = a * d; - _vector$b.fromBufferAttribute( positionAttribute, i ); + te[ 1 ] = a * f; + te[ 5 ] = a * e; + te[ 9 ] = - b; - } + te[ 2 ] = cf * b - de; + te[ 6 ] = df + ce * b; + te[ 10 ] = a * c; - _vector$b.applyMatrix4( object.matrixWorld ); - this.expandByPoint( _vector$b ); + } else if ( euler.order === 'ZXY' ) { - } + const ce = c * e, cf = c * f, de = d * e, df = d * f; - } else { + te[ 0 ] = ce - df * b; + te[ 4 ] = - a * f; + te[ 8 ] = de + cf * b; - if ( object.boundingBox !== undefined ) { + te[ 1 ] = cf + de * b; + te[ 5 ] = a * e; + te[ 9 ] = df - ce * b; - // object-level bounding box + te[ 2 ] = - a * d; + te[ 6 ] = b; + te[ 10 ] = a * c; - if ( object.boundingBox === null ) { + } else if ( euler.order === 'ZYX' ) { - object.computeBoundingBox(); + const ae = a * e, af = a * f, be = b * e, bf = b * f; - } + te[ 0 ] = c * e; + te[ 4 ] = be * d - af; + te[ 8 ] = ae * d + bf; - _box$4.copy( object.boundingBox ); + te[ 1 ] = c * f; + te[ 5 ] = bf * d + ae; + te[ 9 ] = af * d - be; + te[ 2 ] = - d; + te[ 6 ] = b * c; + te[ 10 ] = a * c; - } else { + } else if ( euler.order === 'YZX' ) { - // geometry-level bounding box + const ac = a * c, ad = a * d, bc = b * c, bd = b * d; - if ( geometry.boundingBox === null ) { + te[ 0 ] = c * e; + te[ 4 ] = bd - ac * f; + te[ 8 ] = bc * f + ad; - geometry.computeBoundingBox(); + te[ 1 ] = f; + te[ 5 ] = a * e; + te[ 9 ] = - b * e; - } + te[ 2 ] = - d * e; + te[ 6 ] = ad * f + bc; + te[ 10 ] = ac - bd * f; - _box$4.copy( geometry.boundingBox ); + } else if ( euler.order === 'XZY' ) { - } + const ac = a * c, ad = a * d, bc = b * c, bd = b * d; - _box$4.applyMatrix4( object.matrixWorld ); + te[ 0 ] = c * e; + te[ 4 ] = - f; + te[ 8 ] = d * e; - this.union( _box$4 ); + te[ 1 ] = ac * f + bd; + te[ 5 ] = a * e; + te[ 9 ] = ad * f - bc; - } + te[ 2 ] = bc * f - ad; + te[ 6 ] = b * e; + te[ 10 ] = bd * f + ac; } - const children = object.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - this.expandByObject( children[ i ], precise ); + // bottom row + te[ 3 ] = 0; + te[ 7 ] = 0; + te[ 11 ] = 0; - } + // last column + te[ 12 ] = 0; + te[ 13 ] = 0; + te[ 14 ] = 0; + te[ 15 ] = 1; return this; } /** - * Returns `true` if the given point lies within or on the boundaries of this box. + * Sets the rotation component of this matrix to the rotation specified by + * the given Quaternion as outlined [here](https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion) + * The rest of the matrix is set to the identity. * - * @param {Vector3} point - The point to test. - * @return {boolean} Whether the bounding box contains the given point or not. + * @param {Quaternion} q - The Quaternion. + * @return {Matrix4} A reference to this matrix. */ - containsPoint( point ) { + makeRotationFromQuaternion( q ) { - return point.x >= this.min.x && point.x <= this.max.x && - point.y >= this.min.y && point.y <= this.max.y && - point.z >= this.min.z && point.z <= this.max.z; + return this.compose( _zero, q, _one ); } /** - * Returns `true` if this bounding box includes the entirety of the given bounding box. - * If this box and the given one are identical, this function also returns `true`. + * Sets the rotation component of the transformation matrix, looking from `eye` towards + * `target`, and oriented by the up-direction. * - * @param {Box3} box - The bounding box to test. - * @return {boolean} Whether the bounding box contains the given bounding box or not. + * @param {Vector3} eye - The eye vector. + * @param {Vector3} target - The target vector. + * @param {Vector3} up - The up vector. + * @return {Matrix4} A reference to this matrix. */ - containsBox( box ) { + lookAt( eye, target, up ) { - return this.min.x <= box.min.x && box.max.x <= this.max.x && - this.min.y <= box.min.y && box.max.y <= this.max.y && - this.min.z <= box.min.z && box.max.z <= this.max.z; + const te = this.elements; + + _z.subVectors( eye, target ); + + if ( _z.lengthSq() === 0 ) { + + // eye and target are in the same position + + _z.z = 1; + + } + + _z.normalize(); + _x.crossVectors( up, _z ); + + if ( _x.lengthSq() === 0 ) { + + // up and z are parallel + + if ( Math.abs( up.z ) === 1 ) { + + _z.x += 0.0001; + + } else { + + _z.z += 0.0001; + + } + + _z.normalize(); + _x.crossVectors( up, _z ); + + } + + _x.normalize(); + _y.crossVectors( _z, _x ); + + te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; + te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; + te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; + + return this; } /** - * Returns a point as a proportion of this box's width, height and depth. + * Post-multiplies this matrix by the given 4x4 matrix. * - * @param {Vector3} point - A point in 3D space. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} A point as a proportion of this box's width, height and depth. + * @param {Matrix4} m - The matrix to multiply with. + * @return {Matrix4} A reference to this matrix. */ - getParameter( point, target ) { + multiply( m ) { - // This can potentially have a divide by zero if the box - // has a size dimension of 0. + return this.multiplyMatrices( this, m ); - return target.set( - ( point.x - this.min.x ) / ( this.max.x - this.min.x ), - ( point.y - this.min.y ) / ( this.max.y - this.min.y ), - ( point.z - this.min.z ) / ( this.max.z - this.min.z ) - ); + } + + /** + * Pre-multiplies this matrix by the given 4x4 matrix. + * + * @param {Matrix4} m - The matrix to multiply with. + * @return {Matrix4} A reference to this matrix. + */ + premultiply( m ) { + + return this.multiplyMatrices( m, this ); } /** - * Returns `true` if the given bounding box intersects with this bounding box. + * Multiples the given 4x4 matrices and stores the result + * in this matrix. * - * @param {Box3} box - The bounding box to test. - * @return {boolean} Whether the given bounding box intersects with this bounding box. + * @param {Matrix4} a - The first matrix. + * @param {Matrix4} b - The second matrix. + * @return {Matrix4} A reference to this matrix. */ - intersectsBox( box ) { + multiplyMatrices( a, b ) { - // using 6 splitting planes to rule out intersections. - return box.max.x >= this.min.x && box.min.x <= this.max.x && - box.max.y >= this.min.y && box.min.y <= this.max.y && - box.max.z >= this.min.z && box.min.z <= this.max.z; + const ae = a.elements; + const be = b.elements; + const te = this.elements; + + const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; + const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; + const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; + const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; + + const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; + const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; + const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; + const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; + + te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; + te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; + te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; + te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; + + te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; + te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; + te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; + te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; + + te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; + te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; + te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; + te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; + + te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; + te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; + te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; + te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; + + return this; } /** - * Returns `true` if the given bounding sphere intersects with this bounding box. + * Multiplies every component of the matrix by the given scalar. * - * @param {Sphere} sphere - The bounding sphere to test. - * @return {boolean} Whether the given bounding sphere intersects with this bounding box. + * @param {number} s - The scalar. + * @return {Matrix4} A reference to this matrix. */ - intersectsSphere( sphere ) { + multiplyScalar( s ) { - // Find the point on the AABB closest to the sphere center. - this.clampPoint( sphere.center, _vector$b ); + const te = this.elements; - // If that point is inside the sphere, the AABB and sphere intersect. - return _vector$b.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); + te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; + te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; + te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; + te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; + + return this; } /** - * Returns `true` if the given plane intersects with this bounding box. + * Computes and returns the determinant of this matrix. * - * @param {Plane} plane - The plane to test. - * @return {boolean} Whether the given plane intersects with this bounding box. + * Based on the method outlined [here](http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html). + * + * @return {number} The determinant. */ - intersectsPlane( plane ) { + determinant() { - // We compute the minimum and maximum dot product values. If those values - // are on the same side (back or front) of the plane, then there is no intersection. + const te = this.elements; - let min, max; + const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; + const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; + const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; + const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - if ( plane.normal.x > 0 ) { + const t11 = n23 * n34 - n24 * n33; + const t12 = n22 * n34 - n24 * n32; + const t13 = n22 * n33 - n23 * n32; - min = plane.normal.x * this.min.x; - max = plane.normal.x * this.max.x; + const t21 = n21 * n34 - n24 * n31; + const t22 = n21 * n33 - n23 * n31; + const t23 = n21 * n32 - n22 * n31; - } else { + return n11 * ( n42 * t11 - n43 * t12 + n44 * t13 ) - + n12 * ( n41 * t11 - n43 * t21 + n44 * t22 ) + + n13 * ( n41 * t12 - n42 * t21 + n44 * t23 ) - + n14 * ( n41 * t13 - n42 * t22 + n43 * t23 ); - min = plane.normal.x * this.max.x; - max = plane.normal.x * this.min.x; + } - } + /** + * Transposes this matrix in place. + * + * @return {Matrix4} A reference to this matrix. + */ + transpose() { - if ( plane.normal.y > 0 ) { + const te = this.elements; + let tmp; - min += plane.normal.y * this.min.y; - max += plane.normal.y * this.max.y; + tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; + tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; + tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; - } else { + tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; + tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; + tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; - min += plane.normal.y * this.max.y; - max += plane.normal.y * this.min.y; + return this; - } + } - if ( plane.normal.z > 0 ) { + /** + * Sets the position component for this matrix from the given vector, + * without affecting the rest of the matrix. + * + * @param {number|Vector3} x - The x component of the vector or alternatively the vector object. + * @param {number} y - The y component of the vector. + * @param {number} z - The z component of the vector. + * @return {Matrix4} A reference to this matrix. + */ + setPosition( x, y, z ) { - min += plane.normal.z * this.min.z; - max += plane.normal.z * this.max.z; + const te = this.elements; + + if ( x.isVector3 ) { + + te[ 12 ] = x.x; + te[ 13 ] = x.y; + te[ 14 ] = x.z; } else { - min += plane.normal.z * this.max.z; - max += plane.normal.z * this.min.z; + te[ 12 ] = x; + te[ 13 ] = y; + te[ 14 ] = z; } - return ( min <= - plane.constant && max >= - plane.constant ); + return this; } /** - * Returns `true` if the given triangle intersects with this bounding box. + * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution). + * You can not invert with a determinant of zero. If you attempt this, the method produces + * a zero matrix instead. * - * @param {Triangle} triangle - The triangle to test. - * @return {boolean} Whether the given triangle intersects with this bounding box. + * @return {Matrix4} A reference to this matrix. */ - intersectsTriangle( triangle ) { - - if ( this.isEmpty() ) { - - return false; - - } + invert() { - // compute box center and extents - this.getCenter( _center ); - _extents.subVectors( this.max, _center ); + // based on https://github.com/toji/gl-matrix + const te = this.elements, - // translate triangle to aabb origin - _v0$2.subVectors( triangle.a, _center ); - _v1$7.subVectors( triangle.b, _center ); - _v2$4.subVectors( triangle.c, _center ); + n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n41 = te[ 3 ], + n12 = te[ 4 ], n22 = te[ 5 ], n32 = te[ 6 ], n42 = te[ 7 ], + n13 = te[ 8 ], n23 = te[ 9 ], n33 = te[ 10 ], n43 = te[ 11 ], + n14 = te[ 12 ], n24 = te[ 13 ], n34 = te[ 14 ], n44 = te[ 15 ], - // compute edge vectors for triangle - _f0.subVectors( _v1$7, _v0$2 ); - _f1.subVectors( _v2$4, _v1$7 ); - _f2.subVectors( _v0$2, _v2$4 ); + t1 = n11 * n22 - n21 * n12, + t2 = n11 * n32 - n31 * n12, + t3 = n11 * n42 - n41 * n12, + t4 = n21 * n32 - n31 * n22, + t5 = n21 * n42 - n41 * n22, + t6 = n31 * n42 - n41 * n32, + t7 = n13 * n24 - n23 * n14, + t8 = n13 * n34 - n33 * n14, + t9 = n13 * n44 - n43 * n14, + t10 = n23 * n34 - n33 * n24, + t11 = n23 * n44 - n43 * n24, + t12 = n33 * n44 - n43 * n34; - // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb - // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation - // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) - let axes = [ - 0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y, - _f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x, - - _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0 - ]; - if ( ! satForAxes( axes, _v0$2, _v1$7, _v2$4, _extents ) ) { + const det = t1 * t12 - t2 * t11 + t3 * t10 + t4 * t9 - t5 * t8 + t6 * t7; - return false; + if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); - } + const detInv = 1 / det; - // test 3 face normals from the aabb - axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; - if ( ! satForAxes( axes, _v0$2, _v1$7, _v2$4, _extents ) ) { + te[ 0 ] = ( n22 * t12 - n32 * t11 + n42 * t10 ) * detInv; + te[ 1 ] = ( n31 * t11 - n21 * t12 - n41 * t10 ) * detInv; + te[ 2 ] = ( n24 * t6 - n34 * t5 + n44 * t4 ) * detInv; + te[ 3 ] = ( n33 * t5 - n23 * t6 - n43 * t4 ) * detInv; - return false; + te[ 4 ] = ( n32 * t9 - n12 * t12 - n42 * t8 ) * detInv; + te[ 5 ] = ( n11 * t12 - n31 * t9 + n41 * t8 ) * detInv; + te[ 6 ] = ( n34 * t3 - n14 * t6 - n44 * t2 ) * detInv; + te[ 7 ] = ( n13 * t6 - n33 * t3 + n43 * t2 ) * detInv; - } + te[ 8 ] = ( n12 * t11 - n22 * t9 + n42 * t7 ) * detInv; + te[ 9 ] = ( n21 * t9 - n11 * t11 - n41 * t7 ) * detInv; + te[ 10 ] = ( n14 * t5 - n24 * t3 + n44 * t1 ) * detInv; + te[ 11 ] = ( n23 * t3 - n13 * t5 - n43 * t1 ) * detInv; - // finally testing the face normal of the triangle - // use already existing triangle edge vectors here - _triangleNormal.crossVectors( _f0, _f1 ); - axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ]; + te[ 12 ] = ( n22 * t8 - n12 * t10 - n32 * t7 ) * detInv; + te[ 13 ] = ( n11 * t10 - n21 * t8 + n31 * t7 ) * detInv; + te[ 14 ] = ( n24 * t2 - n14 * t4 - n34 * t1 ) * detInv; + te[ 15 ] = ( n13 * t4 - n23 * t2 + n33 * t1 ) * detInv; - return satForAxes( axes, _v0$2, _v1$7, _v2$4, _extents ); + return this; } /** - * Clamps the given point within the bounds of this box. + * Multiplies the columns of this matrix by the given vector. * - * @param {Vector3} point - The point to clamp. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The clamped point. + * @param {Vector3} v - The scale vector. + * @return {Matrix4} A reference to this matrix. */ - clampPoint( point, target ) { + scale( v ) { - return target.copy( point ).clamp( this.min, this.max ); + const te = this.elements; + const x = v.x, y = v.y, z = v.z; + + te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; + te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; + te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; + te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; + + return this; } /** - * Returns the euclidean distance from any edge of this box to the specified point. If - * the given point lies inside of this box, the distance will be `0`. + * Gets the maximum scale value of the three axes. * - * @param {Vector3} point - The point to compute the distance to. - * @return {number} The euclidean distance. + * @return {number} The maximum scale. */ - distanceToPoint( point ) { + getMaxScaleOnAxis() { - return this.clampPoint( point, _vector$b ).distanceTo( point ); + const te = this.elements; + + const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; + const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; + const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; + + return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); } /** - * Returns a bounding sphere that encloses this bounding box. + * Sets this matrix as a translation transform from the given vector. * - * @param {Sphere} target - The target sphere that is used to store the method's result. - * @return {Sphere} The bounding sphere that encloses this bounding box. + * @param {number|Vector3} x - The amount to translate in the X axis or alternatively a translation vector. + * @param {number} y - The amount to translate in the Y axis. + * @param {number} z - The amount to translate in the z axis. + * @return {Matrix4} A reference to this matrix. */ - getBoundingSphere( target ) { + makeTranslation( x, y, z ) { - if ( this.isEmpty() ) { + if ( x.isVector3 ) { - target.makeEmpty(); + this.set( + + 1, 0, 0, x.x, + 0, 1, 0, x.y, + 0, 0, 1, x.z, + 0, 0, 0, 1 + + ); } else { - this.getCenter( target.center ); + this.set( - target.radius = this.getSize( _vector$b ).length() * 0.5; + 1, 0, 0, x, + 0, 1, 0, y, + 0, 0, 1, z, + 0, 0, 0, 1 + + ); } - return target; + return this; } /** - * Computes the intersection of this bounding box and the given one, setting the upper - * bound of this box to the lesser of the two boxes' upper bounds and the - * lower bound of this box to the greater of the two boxes' lower bounds. If - * there's no overlap, makes this box empty. + * Sets this matrix as a rotational transformation around the X axis by + * the given angle. * - * @param {Box3} box - The bounding box to intersect with. - * @return {Box3} A reference to this bounding box. + * @param {number} theta - The rotation in radians. + * @return {Matrix4} A reference to this matrix. */ - intersect( box ) { + makeRotationX( theta ) { - this.min.max( box.min ); - this.max.min( box.max ); + const c = Math.cos( theta ), s = Math.sin( theta ); - // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. - if ( this.isEmpty() ) this.makeEmpty(); + this.set( + + 1, 0, 0, 0, + 0, c, - s, 0, + 0, s, c, 0, + 0, 0, 0, 1 + + ); return this; } /** - * Computes the union of this box and another and the given one, setting the upper - * bound of this box to the greater of the two boxes' upper bounds and the - * lower bound of this box to the lesser of the two boxes' lower bounds. + * Sets this matrix as a rotational transformation around the Y axis by + * the given angle. * - * @param {Box3} box - The bounding box that will be unioned with this instance. - * @return {Box3} A reference to this bounding box. + * @param {number} theta - The rotation in radians. + * @return {Matrix4} A reference to this matrix. */ - union( box ) { + makeRotationY( theta ) { - this.min.min( box.min ); - this.max.max( box.max ); + const c = Math.cos( theta ), s = Math.sin( theta ); + + this.set( + + c, 0, s, 0, + 0, 1, 0, 0, + - s, 0, c, 0, + 0, 0, 0, 1 + + ); return this; } /** - * Transforms this bounding box by the given 4x4 transformation matrix. + * Sets this matrix as a rotational transformation around the Z axis by + * the given angle. * - * @param {Matrix4} matrix - The transformation matrix. - * @return {Box3} A reference to this bounding box. + * @param {number} theta - The rotation in radians. + * @return {Matrix4} A reference to this matrix. */ - applyMatrix4( matrix ) { + makeRotationZ( theta ) { - // transform of empty box is an empty box. - if ( this.isEmpty() ) return this; + const c = Math.cos( theta ), s = Math.sin( theta ); - // NOTE: I am using a binary pattern to specify all 2^3 combinations below - _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 - _points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 - _points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 - _points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 - _points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 - _points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 - _points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 - _points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 + this.set( - this.setFromPoints( _points ); + c, - s, 0, 0, + s, c, 0, 0, + 0, 0, 1, 0, + 0, 0, 0, 1 + + ); return this; } /** - * Adds the given offset to both the upper and lower bounds of this bounding box, - * effectively moving it in 3D space. + * Sets this matrix as a rotational transformation around the given axis by + * the given angle. * - * @param {Vector3} offset - The offset that should be used to translate the bounding box. - * @return {Box3} A reference to this bounding box. + * This is a somewhat controversial but mathematically sound alternative to + * rotating via Quaternions. See the discussion [here](https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199). + * + * @param {Vector3} axis - The normalized rotation axis. + * @param {number} angle - The rotation in radians. + * @return {Matrix4} A reference to this matrix. */ - translate( offset ) { + makeRotationAxis( axis, angle ) { - this.min.add( offset ); - this.max.add( offset ); + // Based on http://www.gamedev.net/reference/articles/article1199.asp + + const c = Math.cos( angle ); + const s = Math.sin( angle ); + const t = 1 - c; + const x = axis.x, y = axis.y, z = axis.z; + const tx = t * x, ty = t * y; + + this.set( + + tx * x + c, tx * y - s * z, tx * z + s * y, 0, + tx * y + s * z, ty * y + c, ty * z - s * x, 0, + tx * z - s * y, ty * z + s * x, t * z * z + c, 0, + 0, 0, 0, 1 + + ); return this; } /** - * Returns `true` if this bounding box is equal with the given one. + * Sets this matrix as a scale transformation. * - * @param {Box3} box - The box to test for equality. - * @return {boolean} Whether this bounding box is equal with the given one. + * @param {number} x - The amount to scale in the X axis. + * @param {number} y - The amount to scale in the Y axis. + * @param {number} z - The amount to scale in the Z axis. + * @return {Matrix4} A reference to this matrix. */ - equals( box ) { + makeScale( x, y, z ) { - return box.min.equals( this.min ) && box.max.equals( this.max ); + this.set( + + x, 0, 0, 0, + 0, y, 0, 0, + 0, 0, z, 0, + 0, 0, 0, 1 + + ); + + return this; } /** - * Returns a serialized structure of the bounding box. + * Sets this matrix as a shear transformation. * - * @return {Object} Serialized structure with fields representing the object state. + * @param {number} xy - The amount to shear X by Y. + * @param {number} xz - The amount to shear X by Z. + * @param {number} yx - The amount to shear Y by X. + * @param {number} yz - The amount to shear Y by Z. + * @param {number} zx - The amount to shear Z by X. + * @param {number} zy - The amount to shear Z by Y. + * @return {Matrix4} A reference to this matrix. */ - toJSON() { + makeShear( xy, xz, yx, yz, zx, zy ) { - return { - min: this.min.toArray(), - max: this.max.toArray() - }; + this.set( + + 1, yx, zx, 0, + xy, 1, zy, 0, + xz, yz, 1, 0, + 0, 0, 0, 1 + + ); + + return this; } /** - * Returns a serialized structure of the bounding box. + * Sets this matrix to the transformation composed of the given position, + * rotation (Quaternion) and scale. * - * @param {Object} json - The serialized json to set the box from. - * @return {Box3} A reference to this bounding box. + * @param {Vector3} position - The position vector. + * @param {Quaternion} quaternion - The rotation as a Quaternion. + * @param {Vector3} scale - The scale vector. + * @return {Matrix4} A reference to this matrix. */ - fromJSON( json ) { + compose( position, quaternion, scale ) { - this.min.fromArray( json.min ); - this.max.fromArray( json.max ); - return this; + const te = this.elements; - } + const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; + const x2 = x + x, y2 = y + y, z2 = z + z; + const xx = x * x2, xy = x * y2, xz = x * z2; + const yy = y * y2, yz = y * z2, zz = z * z2; + const wx = w * x2, wy = w * y2, wz = w * z2; -} + const sx = scale.x, sy = scale.y, sz = scale.z; -const _points = [ - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3(), - /*@__PURE__*/ new Vector3() -]; + te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; + te[ 1 ] = ( xy + wz ) * sx; + te[ 2 ] = ( xz - wy ) * sx; + te[ 3 ] = 0; -const _vector$b = /*@__PURE__*/ new Vector3(); + te[ 4 ] = ( xy - wz ) * sy; + te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; + te[ 6 ] = ( yz + wx ) * sy; + te[ 7 ] = 0; -const _box$4 = /*@__PURE__*/ new Box3(); + te[ 8 ] = ( xz + wy ) * sz; + te[ 9 ] = ( yz - wx ) * sz; + te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; + te[ 11 ] = 0; -// triangle centered vertices + te[ 12 ] = position.x; + te[ 13 ] = position.y; + te[ 14 ] = position.z; + te[ 15 ] = 1; -const _v0$2 = /*@__PURE__*/ new Vector3(); -const _v1$7 = /*@__PURE__*/ new Vector3(); -const _v2$4 = /*@__PURE__*/ new Vector3(); + return this; -// triangle edge vectors + } -const _f0 = /*@__PURE__*/ new Vector3(); -const _f1 = /*@__PURE__*/ new Vector3(); -const _f2 = /*@__PURE__*/ new Vector3(); + /** + * Decomposes this matrix into its position, rotation and scale components + * and provides the result in the given objects. + * + * Note: Not all matrices are decomposable in this way. For example, if an + * object has a non-uniformly scaled parent, then the object's world matrix + * may not be decomposable, and this method may not be appropriate. + * + * @param {Vector3} position - The position vector. + * @param {Quaternion} quaternion - The rotation as a Quaternion. + * @param {Vector3} scale - The scale vector. + * @return {Matrix4} A reference to this matrix. + */ + decompose( position, quaternion, scale ) { -const _center = /*@__PURE__*/ new Vector3(); -const _extents = /*@__PURE__*/ new Vector3(); -const _triangleNormal = /*@__PURE__*/ new Vector3(); -const _testAxis = /*@__PURE__*/ new Vector3(); + const te = this.elements; -function satForAxes( axes, v0, v1, v2, extents ) { + position.x = te[ 12 ]; + position.y = te[ 13 ]; + position.z = te[ 14 ]; - for ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) { + const det = this.determinant(); - _testAxis.fromArray( axes, i ); - // project the aabb onto the separating axis - const r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z ); - // project all 3 vertices of the triangle onto the separating axis - const p0 = v0.dot( _testAxis ); - const p1 = v1.dot( _testAxis ); - const p2 = v2.dot( _testAxis ); - // actual test, basically see if either of the most extreme of the triangle points intersects r - if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { + if ( det === 0 ) { - // points of the projected triangle are outside the projected half-length of the aabb - // the axis is separating and we can exit - return false; + scale.set( 1, 1, 1 ); + quaternion.identity(); + + return this; } - } + let sx = _v1$7.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); + const sy = _v1$7.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); + const sz = _v1$7.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); - return true; + // if determinant is negative, we need to invert one scale + if ( det < 0 ) sx = - sx; -} + // scale the rotation part + _m1$2.copy( this ); -const _box$3 = /*@__PURE__*/ new Box3(); -const _v1$6 = /*@__PURE__*/ new Vector3(); -const _v2$3 = /*@__PURE__*/ new Vector3(); + const invSX = 1 / sx; + const invSY = 1 / sy; + const invSZ = 1 / sz; -/** - * An analytical 3D sphere defined by a center and radius. This class is mainly - * used as a Bounding Sphere for 3D objects. - */ -class Sphere { + _m1$2.elements[ 0 ] *= invSX; + _m1$2.elements[ 1 ] *= invSX; + _m1$2.elements[ 2 ] *= invSX; - /** - * Constructs a new sphere. - * - * @param {Vector3} [center=(0,0,0)] - The center of the sphere - * @param {number} [radius=-1] - The radius of the sphere. - */ - constructor( center = new Vector3(), radius = -1 ) { + _m1$2.elements[ 4 ] *= invSY; + _m1$2.elements[ 5 ] *= invSY; + _m1$2.elements[ 6 ] *= invSY; - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isSphere = true; + _m1$2.elements[ 8 ] *= invSZ; + _m1$2.elements[ 9 ] *= invSZ; + _m1$2.elements[ 10 ] *= invSZ; - /** - * The center of the sphere - * - * @type {Vector3} - */ - this.center = center; + quaternion.setFromRotationMatrix( _m1$2 ); - /** - * The radius of the sphere. - * - * @type {number} - */ - this.radius = radius; + scale.x = sx; + scale.y = sy; + scale.z = sz; + + return this; } /** - * Sets the sphere's components by copying the given values. - * - * @param {Vector3} center - The center. - * @param {number} radius - The radius. - * @return {Sphere} A reference to this sphere. + * Creates a perspective projection matrix. This is used internally by + * {@link PerspectiveCamera#updateProjectionMatrix}. + + * @param {number} left - Left boundary of the viewing frustum at the near plane. + * @param {number} right - Right boundary of the viewing frustum at the near plane. + * @param {number} top - Top boundary of the viewing frustum at the near plane. + * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. + * @param {number} near - The distance from the camera to the near plane. + * @param {number} far - The distance from the camera to the far plane. + * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. + * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. + * @return {Matrix4} A reference to this matrix. */ - set( center, radius ) { + makePerspective( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) { - this.center.copy( center ); - this.radius = radius; + const te = this.elements; + + const x = 2 * near / ( right - left ); + const y = 2 * near / ( top - bottom ); + + const a = ( right + left ) / ( right - left ); + const b = ( top + bottom ) / ( top - bottom ); + + let c, d; + + if ( reversedDepth ) { + + c = near / ( far - near ); + d = ( far * near ) / ( far - near ); + + } else { + + if ( coordinateSystem === WebGLCoordinateSystem ) { + + c = - ( far + near ) / ( far - near ); + d = ( -2 * far * near ) / ( far - near ); + + } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + + c = - far / ( far - near ); + d = ( - far * near ) / ( far - near ); + + } else { + + throw new Error( 'THREE.Matrix4.makePerspective(): Invalid coordinate system: ' + coordinateSystem ); + + } + + } + + te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; + te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = -1; te[ 15 ] = 0; return this; } /** - * Computes the minimum bounding sphere for list of points. - * If the optional center point is given, it is used as the sphere's - * center. Otherwise, the center of the axis-aligned bounding box - * encompassing the points is calculated. - * - * @param {Array} points - A list of points in 3D space. - * @param {Vector3} [optionalCenter] - The center of the sphere. - * @return {Sphere} A reference to this sphere. + * Creates a orthographic projection matrix. This is used internally by + * {@link OrthographicCamera#updateProjectionMatrix}. + + * @param {number} left - Left boundary of the viewing frustum at the near plane. + * @param {number} right - Right boundary of the viewing frustum at the near plane. + * @param {number} top - Top boundary of the viewing frustum at the near plane. + * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. + * @param {number} near - The distance from the camera to the near plane. + * @param {number} far - The distance from the camera to the far plane. + * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. + * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. + * @return {Matrix4} A reference to this matrix. */ - setFromPoints( points, optionalCenter ) { + makeOrthographic( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) { - const center = this.center; + const te = this.elements; - if ( optionalCenter !== undefined ) { + const x = 2 / ( right - left ); + const y = 2 / ( top - bottom ); - center.copy( optionalCenter ); + const a = - ( right + left ) / ( right - left ); + const b = - ( top + bottom ) / ( top - bottom ); + + let c, d; + + if ( reversedDepth ) { + + c = 1 / ( far - near ); + d = far / ( far - near ); } else { - _box$3.setFromPoints( points ).getCenter( center ); + if ( coordinateSystem === WebGLCoordinateSystem ) { - } + c = -2 / ( far - near ); + d = - ( far + near ) / ( far - near ); - let maxRadiusSq = 0; + } else if ( coordinateSystem === WebGPUCoordinateSystem ) { - for ( let i = 0, il = points.length; i < il; i ++ ) { + c = -1 / ( far - near ); + d = - near / ( far - near ); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); + } else { + + throw new Error( 'THREE.Matrix4.makeOrthographic(): Invalid coordinate system: ' + coordinateSystem ); + + } } - this.radius = Math.sqrt( maxRadiusSq ); + te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = a; + te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = 0; te[ 13 ] = b; + te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; + te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; return this; } /** - * Copies the values of the given sphere to this instance. + * Returns `true` if this matrix is equal with the given one. * - * @param {Sphere} sphere - The sphere to copy. - * @return {Sphere} A reference to this sphere. + * @param {Matrix4} matrix - The matrix to test for equality. + * @return {boolean} Whether this matrix is equal with the given one. */ - copy( sphere ) { + equals( matrix ) { - this.center.copy( sphere.center ); - this.radius = sphere.radius; + const te = this.elements; + const me = matrix.elements; - return this; + for ( let i = 0; i < 16; i ++ ) { - } + if ( te[ i ] !== me[ i ] ) return false; - /** - * Returns `true` if the sphere is empty (the radius set to a negative number). - * - * Spheres with a radius of `0` contain only their center point and are not - * considered to be empty. - * - * @return {boolean} Whether this sphere is empty or not. - */ - isEmpty() { + } - return ( this.radius < 0 ); + return true; } /** - * Makes this sphere empty which means in encloses a zero space in 3D. + * Sets the elements of the matrix from the given array. * - * @return {Sphere} A reference to this sphere. + * @param {Array} array - The matrix elements in column-major order. + * @param {number} [offset=0] - Index of the first element in the array. + * @return {Matrix4} A reference to this matrix. */ - makeEmpty() { + fromArray( array, offset = 0 ) { - this.center.set( 0, 0, 0 ); - this.radius = -1; + for ( let i = 0; i < 16; i ++ ) { + + this.elements[ i ] = array[ i + offset ]; + + } return this; } /** - * Returns `true` if this sphere contains the given point inclusive of - * the surface of the sphere. + * Writes the elements of this matrix to the given array. If no array is provided, + * the method returns a new instance. * - * @param {Vector3} point - The point to check. - * @return {boolean} Whether this sphere contains the given point or not. + * @param {Array} [array=[]] - The target array holding the matrix elements in column-major order. + * @param {number} [offset=0] - Index of the first element in the array. + * @return {Array} The matrix elements in column-major order. */ - containsPoint( point ) { + toArray( array = [], offset = 0 ) { - return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); + const te = this.elements; + + array[ offset ] = te[ 0 ]; + array[ offset + 1 ] = te[ 1 ]; + array[ offset + 2 ] = te[ 2 ]; + array[ offset + 3 ] = te[ 3 ]; + + array[ offset + 4 ] = te[ 4 ]; + array[ offset + 5 ] = te[ 5 ]; + array[ offset + 6 ] = te[ 6 ]; + array[ offset + 7 ] = te[ 7 ]; + + array[ offset + 8 ] = te[ 8 ]; + array[ offset + 9 ] = te[ 9 ]; + array[ offset + 10 ] = te[ 10 ]; + array[ offset + 11 ] = te[ 11 ]; + + array[ offset + 12 ] = te[ 12 ]; + array[ offset + 13 ] = te[ 13 ]; + array[ offset + 14 ] = te[ 14 ]; + array[ offset + 15 ] = te[ 15 ]; + + return array; } +} + +const _v1$7 = /*@__PURE__*/ new Vector3(); +const _m1$2 = /*@__PURE__*/ new Matrix4(); +const _zero = /*@__PURE__*/ new Vector3( 0, 0, 0 ); +const _one = /*@__PURE__*/ new Vector3( 1, 1, 1 ); +const _x = /*@__PURE__*/ new Vector3(); +const _y = /*@__PURE__*/ new Vector3(); +const _z = /*@__PURE__*/ new Vector3(); + +const _matrix$2 = /*@__PURE__*/ new Matrix4(); +const _quaternion$4 = /*@__PURE__*/ new Quaternion(); + +/** + * A class representing Euler angles. + * + * Euler angles describe a rotational transformation by rotating an object on + * its various axes in specified amounts per axis, and a specified axis + * order. + * + * Iterating through an instance will yield its components (x, y, z, + * order) in the corresponding order. + * + * ```js + * const a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); + * const b = new THREE.Vector3( 1, 0, 1 ); + * b.applyEuler(a); + * ``` + */ +class Euler { + /** - * Returns the closest distance from the boundary of the sphere to the - * given point. If the sphere contains the point, the distance will - * be negative. + * Constructs a new euler instance. * - * @param {Vector3} point - The point to compute the distance to. - * @return {number} The distance to the point. + * @param {number} [x=0] - The angle of the x axis in radians. + * @param {number} [y=0] - The angle of the y axis in radians. + * @param {number} [z=0] - The angle of the z axis in radians. + * @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied. */ - distanceToPoint( point ) { + constructor( x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER ) { - return ( point.distanceTo( this.center ) - this.radius ); + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isEuler = true; + + this._x = x; + this._y = y; + this._z = z; + this._order = order; } /** - * Returns `true` if this sphere intersects with the given one. + * The angle of the x axis in radians. * - * @param {Sphere} sphere - The sphere to test. - * @return {boolean} Whether this sphere intersects with the given one or not. + * @type {number} + * @default 0 */ - intersectsSphere( sphere ) { + get x() { - const radiusSum = this.radius + sphere.radius; + return this._x; - return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); + } + + set x( value ) { + + this._x = value; + this._onChangeCallback(); } /** - * Returns `true` if this sphere intersects with the given box. + * The angle of the y axis in radians. * - * @param {Box3} box - The box to test. - * @return {boolean} Whether this sphere intersects with the given box or not. + * @type {number} + * @default 0 */ - intersectsBox( box ) { + get y() { - return box.intersectsSphere( this ); + return this._y; } - /** - * Returns `true` if this sphere intersects with the given plane. - * - * @param {Plane} plane - The plane to test. - * @return {boolean} Whether this sphere intersects with the given plane or not. - */ - intersectsPlane( plane ) { + set y( value ) { - return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; + this._y = value; + this._onChangeCallback(); } /** - * Clamps a point within the sphere. If the point is outside the sphere, it - * will clamp it to the closest point on the edge of the sphere. Points - * already inside the sphere will not be affected. + * The angle of the z axis in radians. * - * @param {Vector3} point - The plane to clamp. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The clamped point. + * @type {number} + * @default 0 */ - clampPoint( point, target ) { - - const deltaLengthSq = this.center.distanceToSquared( point ); - - target.copy( point ); + get z() { - if ( deltaLengthSq > ( this.radius * this.radius ) ) { + return this._z; - target.sub( this.center ).normalize(); - target.multiplyScalar( this.radius ).add( this.center ); + } - } + set z( value ) { - return target; + this._z = value; + this._onChangeCallback(); } /** - * Returns a bounding box that encloses this sphere. + * A string representing the order that the rotations are applied. * - * @param {Box3} target - The target box that is used to store the method's result. - * @return {Box3} The bounding box that encloses this sphere. + * @type {string} + * @default 'XYZ' */ - getBoundingBox( target ) { + get order() { - if ( this.isEmpty() ) { - - // Empty sphere produces empty bounding box - target.makeEmpty(); - return target; + return this._order; - } + } - target.set( this.center, this.center ); - target.expandByScalar( this.radius ); + set order( value ) { - return target; + this._order = value; + this._onChangeCallback(); } /** - * Transforms this sphere with the given 4x4 transformation matrix. + * Sets the Euler components. * - * @param {Matrix4} matrix - The transformation matrix. - * @return {Sphere} A reference to this sphere. + * @param {number} x - The angle of the x axis in radians. + * @param {number} y - The angle of the y axis in radians. + * @param {number} z - The angle of the z axis in radians. + * @param {string} [order] - A string representing the order that the rotations are applied. + * @return {Euler} A reference to this Euler instance. */ - applyMatrix4( matrix ) { + set( x, y, z, order = this._order ) { - this.center.applyMatrix4( matrix ); - this.radius = this.radius * matrix.getMaxScaleOnAxis(); + this._x = x; + this._y = y; + this._z = z; + this._order = order; + + this._onChangeCallback(); return this; } /** - * Translates the sphere's center by the given offset. + * Returns a new Euler instance with copied values from this instance. * - * @param {Vector3} offset - The offset. - * @return {Sphere} A reference to this sphere. + * @return {Euler} A clone of this instance. */ - translate( offset ) { + clone() { - this.center.add( offset ); + return new this.constructor( this._x, this._y, this._z, this._order ); + + } + + /** + * Copies the values of the given Euler instance to this instance. + * + * @param {Euler} euler - The Euler instance to copy. + * @return {Euler} A reference to this Euler instance. + */ + copy( euler ) { + + this._x = euler._x; + this._y = euler._y; + this._z = euler._z; + this._order = euler._order; + + this._onChangeCallback(); return this; } /** - * Expands the boundaries of this sphere to include the given point. + * Sets the angles of this Euler instance from a pure rotation matrix. * - * @param {Vector3} point - The point to include. - * @return {Sphere} A reference to this sphere. + * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled). + * @param {string} [order] - A string representing the order that the rotations are applied. + * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. + * @return {Euler} A reference to this Euler instance. */ - expandByPoint( point ) { + setFromRotationMatrix( m, order = this._order, update = true ) { - if ( this.isEmpty() ) { + const te = m.elements; + const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; + const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; + const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; - this.center.copy( point ); + switch ( order ) { - this.radius = 0; + case 'XYZ': - return this; + this._y = Math.asin( clamp( m13, -1, 1 ) ); - } + if ( Math.abs( m13 ) < 0.9999999 ) { - _v1$6.subVectors( point, this.center ); + this._x = Math.atan2( - m23, m33 ); + this._z = Math.atan2( - m12, m11 ); - const lengthSq = _v1$6.lengthSq(); + } else { - if ( lengthSq > ( this.radius * this.radius ) ) { + this._x = Math.atan2( m32, m22 ); + this._z = 0; - // calculate the minimal sphere + } - const length = Math.sqrt( lengthSq ); + break; - const delta = ( length - this.radius ) * 0.5; + case 'YXZ': - this.center.addScaledVector( _v1$6, delta / length ); + this._x = Math.asin( - clamp( m23, -1, 1 ) ); - this.radius += delta; + if ( Math.abs( m23 ) < 0.9999999 ) { - } + this._y = Math.atan2( m13, m33 ); + this._z = Math.atan2( m21, m22 ); - return this; + } else { - } + this._y = Math.atan2( - m31, m11 ); + this._z = 0; - /** - * Expands this sphere to enclose both the original sphere and the given sphere. - * - * @param {Sphere} sphere - The sphere to include. - * @return {Sphere} A reference to this sphere. - */ - union( sphere ) { + } - if ( sphere.isEmpty() ) { + break; - return this; + case 'ZXY': - } + this._x = Math.asin( clamp( m32, -1, 1 ) ); - if ( this.isEmpty() ) { + if ( Math.abs( m32 ) < 0.9999999 ) { - this.copy( sphere ); + this._y = Math.atan2( - m31, m33 ); + this._z = Math.atan2( - m12, m22 ); - return this; + } else { - } + this._y = 0; + this._z = Math.atan2( m21, m11 ); - if ( this.center.equals( sphere.center ) === true ) { + } - this.radius = Math.max( this.radius, sphere.radius ); + break; - } else { + case 'ZYX': + + this._y = Math.asin( - clamp( m31, -1, 1 ) ); + + if ( Math.abs( m31 ) < 0.9999999 ) { + + this._x = Math.atan2( m32, m33 ); + this._z = Math.atan2( m21, m11 ); + + } else { + + this._x = 0; + this._z = Math.atan2( - m12, m22 ); + + } + + break; + + case 'YZX': + + this._z = Math.asin( clamp( m21, -1, 1 ) ); + + if ( Math.abs( m21 ) < 0.9999999 ) { + + this._x = Math.atan2( - m23, m22 ); + this._y = Math.atan2( - m31, m11 ); - _v2$3.subVectors( sphere.center, this.center ).setLength( sphere.radius ); + } else { + + this._x = 0; + this._y = Math.atan2( m13, m33 ); + + } + + break; + + case 'XZY': + + this._z = Math.asin( - clamp( m12, -1, 1 ) ); + + if ( Math.abs( m12 ) < 0.9999999 ) { + + this._x = Math.atan2( m32, m22 ); + this._y = Math.atan2( m13, m11 ); + + } else { + + this._x = Math.atan2( - m23, m33 ); + this._y = 0; + + } - this.expandByPoint( _v1$6.copy( sphere.center ).add( _v2$3 ) ); + break; + + default: - this.expandByPoint( _v1$6.copy( sphere.center ).sub( _v2$3 ) ); + warn( 'Euler: .setFromRotationMatrix() encountered an unknown order: ' + order ); } + this._order = order; + + if ( update === true ) this._onChangeCallback(); + return this; } /** - * Returns `true` if this sphere is equal with the given one. + * Sets the angles of this Euler instance from a normalized quaternion. * - * @param {Sphere} sphere - The sphere to test for equality. - * @return {boolean} Whether this bounding sphere is equal with the given one. + * @param {Quaternion} q - A normalized Quaternion. + * @param {string} [order] - A string representing the order that the rotations are applied. + * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. + * @return {Euler} A reference to this Euler instance. */ - equals( sphere ) { + setFromQuaternion( q, order, update ) { - return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); + _matrix$2.makeRotationFromQuaternion( q ); + + return this.setFromRotationMatrix( _matrix$2, order, update ); } /** - * Returns a new sphere with copied values from this instance. + * Sets the angles of this Euler instance from the given vector. * - * @return {Sphere} A clone of this instance. + * @param {Vector3} v - The vector. + * @param {string} [order] - A string representing the order that the rotations are applied. + * @return {Euler} A reference to this Euler instance. */ - clone() { + setFromVector3( v, order = this._order ) { - return new this.constructor().copy( this ); + return this.set( v.x, v.y, v.z, order ); } /** - * Returns a serialized structure of the bounding sphere. + * Resets the euler angle with a new order by creating a quaternion from this + * euler angle and then setting this euler angle with the quaternion and the + * new order. * - * @return {Object} Serialized structure with fields representing the object state. + * Warning: This discards revolution information. + * + * @param {string} [newOrder] - A string representing the new order that the rotations are applied. + * @return {Euler} A reference to this Euler instance. */ - toJSON() { + reorder( newOrder ) { - return { - radius: this.radius, - center: this.center.toArray() - }; + _quaternion$4.setFromEuler( this ); + + return this.setFromQuaternion( _quaternion$4, newOrder ); } /** - * Returns a serialized structure of the bounding sphere. + * Returns `true` if this Euler instance is equal with the given one. * - * @param {Object} json - The serialized json to set the sphere from. - * @return {Sphere} A reference to this bounding sphere. + * @param {Euler} euler - The Euler instance to test for equality. + * @return {boolean} Whether this Euler instance is equal with the given one. */ - fromJSON( json ) { + equals( euler ) { - this.radius = json.radius; - this.center.fromArray( json.center ); - return this; + return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); } -} - -const _vector$a = /*@__PURE__*/ new Vector3(); -const _segCenter = /*@__PURE__*/ new Vector3(); -const _segDir = /*@__PURE__*/ new Vector3(); -const _diff = /*@__PURE__*/ new Vector3(); - -const _edge1 = /*@__PURE__*/ new Vector3(); -const _edge2 = /*@__PURE__*/ new Vector3(); -const _normal$1 = /*@__PURE__*/ new Vector3(); - -/** - * A ray that emits from an origin in a certain direction. The class is used by - * {@link Raycaster} to assist with raycasting. Raycasting is used for - * mouse picking (working out what objects in the 3D space the mouse is over) - * amongst other things. - */ -class Ray { - /** - * Constructs a new ray. + * Sets this Euler instance's components to values from the given array. The first three + * entries of the array are assign to the x,y and z components. An optional fourth entry + * defines the Euler order. * - * @param {Vector3} [origin=(0,0,0)] - The origin of the ray. - * @param {Vector3} [direction=(0,0,-1)] - The (normalized) direction of the ray. + * @param {Array} array - An array holding the Euler component values. + * @return {Euler} A reference to this Euler instance. */ - constructor( origin = new Vector3(), direction = new Vector3( 0, 0, -1 ) ) { + fromArray( array ) { - /** - * The origin of the ray. - * - * @type {Vector3} - */ - this.origin = origin; + this._x = array[ 0 ]; + this._y = array[ 1 ]; + this._z = array[ 2 ]; + if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; - /** - * The (normalized) direction of the ray. - * - * @type {Vector3} - */ - this.direction = direction; + this._onChangeCallback(); + + return this; } /** - * Sets the ray's components by copying the given values. + * Writes the components of this Euler instance to the given array. If no array is provided, + * the method returns a new instance. * - * @param {Vector3} origin - The origin. - * @param {Vector3} direction - The direction. - * @return {Ray} A reference to this ray. + * @param {Array} [array=[]] - The target array holding the Euler components. + * @param {number} [offset=0] - Index of the first element in the array. + * @return {Array} The Euler components. */ - set( origin, direction ) { + toArray( array = [], offset = 0 ) { - this.origin.copy( origin ); - this.direction.copy( direction ); + array[ offset ] = this._x; + array[ offset + 1 ] = this._y; + array[ offset + 2 ] = this._z; + array[ offset + 3 ] = this._order; - return this; + return array; } - /** - * Copies the values of the given ray to this instance. - * - * @param {Ray} ray - The ray to copy. - * @return {Ray} A reference to this ray. - */ - copy( ray ) { + _onChange( callback ) { - this.origin.copy( ray.origin ); - this.direction.copy( ray.direction ); + this._onChangeCallback = callback; return this; } - /** - * Returns a vector that is located at a given distance along this ray. - * - * @param {number} t - The distance along the ray to retrieve a position for. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} A position on the ray. - */ - at( t, target ) { + _onChangeCallback() {} - return target.copy( this.origin ).addScaledVector( this.direction, t ); + *[ Symbol.iterator ]() { + + yield this._x; + yield this._y; + yield this._z; + yield this._order; } +} + +/** + * The default Euler angle order. + * + * @static + * @type {string} + * @default 'XYZ' + */ +Euler.DEFAULT_ORDER = 'XYZ'; + +/** + * A layers object assigns an 3D object to 1 or more of 32 + * layers numbered `0` to `31` - internally the layers are stored as a + * bit mask], and by default all 3D objects are a member of layer `0`. + * + * This can be used to control visibility - an object must share a layer with + * a camera to be visible when that camera's view is + * rendered. + * + * All classes that inherit from {@link Object3D} have an `layers` property which + * is an instance of this class. + */ +class Layers { + /** - * Adjusts the direction of the ray to point at the given vector in world space. - * - * @param {Vector3} v - The target position. - * @return {Ray} A reference to this ray. + * Constructs a new layers instance, with membership + * initially set to layer `0`. */ - lookAt( v ) { - - this.direction.copy( v ).sub( this.origin ).normalize(); + constructor() { - return this; + /** + * A bit mask storing which of the 32 layers this layers object is currently + * a member of. + * + * @type {number} + */ + this.mask = 1 | 0; } /** - * Shift the origin of this ray along its direction by the given distance. + * Sets membership to the given layer, and remove membership all other layers. * - * @param {number} t - The distance along the ray to interpolate. - * @return {Ray} A reference to this ray. + * @param {number} layer - The layer to set. */ - recast( t ) { - - this.origin.copy( this.at( t, _vector$a ) ); + set( layer ) { - return this; + this.mask = ( 1 << layer | 0 ) >>> 0; } /** - * Returns the point along this ray that is closest to the given point. + * Adds membership of the given layer. * - * @param {Vector3} point - A point in 3D space to get the closet location on the ray for. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The closest point on this ray. + * @param {number} layer - The layer to enable. */ - closestPointToPoint( point, target ) { - - target.subVectors( point, this.origin ); - - const directionDistance = target.dot( this.direction ); + enable( layer ) { - if ( directionDistance < 0 ) { + this.mask |= 1 << layer | 0; - return target.copy( this.origin ); + } - } + /** + * Adds membership to all layers. + */ + enableAll() { - return target.copy( this.origin ).addScaledVector( this.direction, directionDistance ); + this.mask = 0xffffffff | 0; } /** - * Returns the distance of the closest approach between this ray and the given point. + * Toggles the membership of the given layer. * - * @param {Vector3} point - A point in 3D space to compute the distance to. - * @return {number} The distance. + * @param {number} layer - The layer to toggle. */ - distanceToPoint( point ) { + toggle( layer ) { - return Math.sqrt( this.distanceSqToPoint( point ) ); + this.mask ^= 1 << layer | 0; } /** - * Returns the squared distance of the closest approach between this ray and the given point. + * Removes membership of the given layer. * - * @param {Vector3} point - A point in 3D space to compute the distance to. - * @return {number} The squared distance. + * @param {number} layer - The layer to enable. */ - distanceSqToPoint( point ) { + disable( layer ) { - const directionDistance = _vector$a.subVectors( point, this.origin ).dot( this.direction ); + this.mask &= ~ ( 1 << layer | 0 ); - // point behind the ray + } - if ( directionDistance < 0 ) { + /** + * Removes the membership from all layers. + */ + disableAll() { - return this.origin.distanceToSquared( point ); + this.mask = 0; - } + } - _vector$a.copy( this.origin ).addScaledVector( this.direction, directionDistance ); + /** + * Returns `true` if this and the given layers object have at least one + * layer in common. + * + * @param {Layers} layers - The layers to test. + * @return {boolean } Whether this and the given layers object have at least one layer in common or not. + */ + test( layers ) { - return _vector$a.distanceToSquared( point ); + return ( this.mask & layers.mask ) !== 0; } /** - * Returns the squared distance between this ray and the given line segment. + * Returns `true` if the given layer is enabled. * - * @param {Vector3} v0 - The start point of the line segment. - * @param {Vector3} v1 - The end point of the line segment. - * @param {Vector3} [optionalPointOnRay] - When provided, it receives the point on this ray that is closest to the segment. - * @param {Vector3} [optionalPointOnSegment] - When provided, it receives the point on the line segment that is closest to this ray. - * @return {number} The squared distance. + * @param {number} layer - The layer to test. + * @return {boolean } Whether the given layer is enabled or not. */ - distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { - - // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h - // It returns the min distance between the ray and the segment - // defined by v0 and v1 - // It can also set two optional targets : - // - The closest point on the ray - // - The closest point on the segment + isEnabled( layer ) { - _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); - _segDir.copy( v1 ).sub( v0 ).normalize(); - _diff.copy( this.origin ).sub( _segCenter ); + return ( this.mask & ( 1 << layer | 0 ) ) !== 0; - const segExtent = v0.distanceTo( v1 ) * 0.5; - const a01 = - this.direction.dot( _segDir ); - const b0 = _diff.dot( this.direction ); - const b1 = - _diff.dot( _segDir ); - const c = _diff.lengthSq(); - const det = Math.abs( 1 - a01 * a01 ); - let s0, s1, sqrDist, extDet; + } - if ( det > 0 ) { +} - // The ray and segment are not parallel. +let _object3DId = 0; - s0 = a01 * b1 - b0; - s1 = a01 * b0 - b1; - extDet = segExtent * det; +const _v1$6 = /*@__PURE__*/ new Vector3(); +const _q1 = /*@__PURE__*/ new Quaternion(); +const _m1$1 = /*@__PURE__*/ new Matrix4(); +const _target = /*@__PURE__*/ new Vector3(); - if ( s0 >= 0 ) { +const _position$4 = /*@__PURE__*/ new Vector3(); +const _scale$3 = /*@__PURE__*/ new Vector3(); +const _quaternion$3 = /*@__PURE__*/ new Quaternion(); - if ( s1 >= - extDet ) { +const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 ); +const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 ); +const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 ); - if ( s1 <= extDet ) { +/** + * Fires when the object has been added to its parent object. + * + * @event Object3D#added + * @type {Object} + */ +const _addedEvent = { type: 'added' }; - // region 0 - // Minimum at interior points of ray and segment. - - const invDet = 1 / det; - s0 *= invDet; - s1 *= invDet; - sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; - - } else { - - // region 1 +/** + * Fires when the object has been removed from its parent object. + * + * @event Object3D#removed + * @type {Object} + */ +const _removedEvent = { type: 'removed' }; - s1 = segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; +/** + * Fires when a new child object has been added. + * + * @event Object3D#childadded + * @type {Object} + */ +const _childaddedEvent = { type: 'childadded', child: null }; - } +/** + * Fires when a child object has been removed. + * + * @event Object3D#childremoved + * @type {Object} + */ +const _childremovedEvent = { type: 'childremoved', child: null }; - } else { +/** + * This is the base class for most objects in three.js and provides a set of + * properties and methods for manipulating objects in 3D space. + * + * @augments EventDispatcher + */ +class Object3D extends EventDispatcher { - // region 5 + /** + * Constructs a new 3D object. + */ + constructor() { - s1 = - segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + super(); - } + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isObject3D = true; - } else { + /** + * The ID of the 3D object. + * + * @name Object3D#id + * @type {number} + * @readonly + */ + Object.defineProperty( this, 'id', { value: _object3DId ++ } ); - if ( s1 <= - extDet ) { + /** + * The UUID of the 3D object. + * + * @type {string} + * @readonly + */ + this.uuid = generateUUID(); - // region 4 + /** + * The name of the 3D object. + * + * @type {string} + */ + this.name = ''; - s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + /** + * The type property is used for detecting the object type + * in context of serialization/deserialization. + * + * @type {string} + * @readonly + */ + this.type = 'Object3D'; - } else if ( s1 <= extDet ) { + /** + * A reference to the parent object. + * + * @type {?Object3D} + * @default null + */ + this.parent = null; - // region 3 + /** + * An array holding the child 3D objects of this instance. + * + * @type {Array} + */ + this.children = []; - s0 = 0; - s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = s1 * ( s1 + 2 * b1 ) + c; + /** + * Defines the `up` direction of the 3D object which influences + * the orientation via methods like {@link Object3D#lookAt}. + * + * The default values for all 3D objects is defined by `Object3D.DEFAULT_UP`. + * + * @type {Vector3} + */ + this.up = Object3D.DEFAULT_UP.clone(); - } else { + const position = new Vector3(); + const rotation = new Euler(); + const quaternion = new Quaternion(); + const scale = new Vector3( 1, 1, 1 ); - // region 2 + function onRotationChange() { - s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); - s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + quaternion.setFromEuler( rotation, false ); - } + } - } + function onQuaternionChange() { - } else { + rotation.setFromQuaternion( quaternion, undefined, false ); - // Ray and segment are parallel. + } - s1 = ( a01 > 0 ) ? - segExtent : segExtent; - s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); - sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + rotation._onChange( onRotationChange ); + quaternion._onChange( onQuaternionChange ); - } + Object.defineProperties( this, { + /** + * Represents the object's local position. + * + * @name Object3D#position + * @type {Vector3} + * @default (0,0,0) + */ + position: { + configurable: true, + enumerable: true, + value: position + }, + /** + * Represents the object's local rotation as Euler angles, in radians. + * + * @name Object3D#rotation + * @type {Euler} + * @default (0,0,0) + */ + rotation: { + configurable: true, + enumerable: true, + value: rotation + }, + /** + * Represents the object's local rotation as Quaternions. + * + * @name Object3D#quaternion + * @type {Quaternion} + */ + quaternion: { + configurable: true, + enumerable: true, + value: quaternion + }, + /** + * Represents the object's local scale. + * + * @name Object3D#scale + * @type {Vector3} + * @default (1,1,1) + */ + scale: { + configurable: true, + enumerable: true, + value: scale + }, + /** + * Represents the object's model-view matrix. + * + * @name Object3D#modelViewMatrix + * @type {Matrix4} + */ + modelViewMatrix: { + value: new Matrix4() + }, + /** + * Represents the object's normal matrix. + * + * @name Object3D#normalMatrix + * @type {Matrix3} + */ + normalMatrix: { + value: new Matrix3() + } + } ); - if ( optionalPointOnRay ) { + /** + * Represents the object's transformation matrix in local space. + * + * @type {Matrix4} + */ + this.matrix = new Matrix4(); - optionalPointOnRay.copy( this.origin ).addScaledVector( this.direction, s0 ); + /** + * Represents the object's transformation matrix in world space. + * If the 3D object has no parent, then it's identical to the local transformation matrix + * + * @type {Matrix4} + */ + this.matrixWorld = new Matrix4(); - } + /** + * When set to `true`, the engine automatically computes the local matrix from position, + * rotation and scale every frame. If set to `false`, the app is responsible for recomputing + * the local matrix by calling `updateMatrix()`. + * + * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_AUTO_UPDATE`. + * + * @type {boolean} + * @default true + */ + this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE; - if ( optionalPointOnSegment ) { + /** + * When set to `true`, the engine automatically computes the world matrix from the current local + * matrix and the object's transformation hierarchy. If set to `false`, the app is responsible for + * recomputing the world matrix by directly updating the `matrixWorld` property. + * + * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE`. + * + * @type {boolean} + * @default true + */ + this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer - optionalPointOnSegment.copy( _segCenter ).addScaledVector( _segDir, s1 ); + /** + * When set to `true`, it calculates the world matrix in that frame and resets this property + * to `false`. + * + * @type {boolean} + * @default false + */ + this.matrixWorldNeedsUpdate = false; - } + /** + * The layer membership of the 3D object. The 3D object is only visible if it has + * at least one layer in common with the camera in use. This property can also be + * used to filter out unwanted objects in ray-intersection tests when using {@link Raycaster}. + * + * @type {Layers} + */ + this.layers = new Layers(); - return sqrDist; + /** + * When set to `true`, the 3D object gets rendered. + * + * @type {boolean} + * @default true + */ + this.visible = true; - } + /** + * When set to `true`, the 3D object gets rendered into shadow maps. + * + * @type {boolean} + * @default false + */ + this.castShadow = false; - /** - * Intersects this ray with the given sphere, returning the intersection - * point or `null` if there is no intersection. - * - * @param {Sphere} sphere - The sphere to intersect. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The intersection point. - */ - intersectSphere( sphere, target ) { + /** + * When set to `true`, the 3D object is affected by shadows in the scene. + * + * @type {boolean} + * @default false + */ + this.receiveShadow = false; - _vector$a.subVectors( sphere.center, this.origin ); - const tca = _vector$a.dot( this.direction ); - const d2 = _vector$a.dot( _vector$a ) - tca * tca; - const radius2 = sphere.radius * sphere.radius; + /** + * When set to `true`, the 3D object is honored by view frustum culling. + * + * @type {boolean} + * @default true + */ + this.frustumCulled = true; - if ( d2 > radius2 ) return null; + /** + * This value allows the default rendering order of scene graph objects to be + * overridden although opaque and transparent objects remain sorted independently. + * When this property is set for an instance of {@link Group},all descendants + * objects will be sorted and rendered together. Sorting is from lowest to highest + * render order. + * + * @type {number} + * @default 0 + */ + this.renderOrder = 0; - const thc = Math.sqrt( radius2 - d2 ); + /** + * An array holding the animation clips of the 3D object. + * + * @type {Array} + */ + this.animations = []; - // t0 = first intersect point - entrance on front of sphere - const t0 = tca - thc; + /** + * Custom depth material to be used when rendering to the depth map. Can only be used + * in context of meshes. When shadow-casting with a {@link DirectionalLight} or {@link SpotLight}, + * if you are modifying vertex positions in the vertex shader you must specify a custom depth + * material for proper shadows. + * + * Only relevant in context of {@link WebGLRenderer}. + * + * @type {(Material|undefined)} + * @default undefined + */ + this.customDepthMaterial = undefined; - // t1 = second intersect point - exit point on back of sphere - const t1 = tca + thc; + /** + * Same as {@link Object3D#customDepthMaterial}, but used with {@link PointLight}. + * + * Only relevant in context of {@link WebGLRenderer}. + * + * @type {(Material|undefined)} + * @default undefined + */ + this.customDistanceMaterial = undefined; - // test to see if t1 is behind the ray - if so, return null - if ( t1 < 0 ) return null; + /** + * Whether the 3D object is supposed to be static or not. If set to `true`, it means + * the 3D object is not going to be changed after the initial renderer. This includes + * geometry and material settings. A static 3D object can be processed by the renderer + * slightly faster since certain state checks can be bypassed. + * + * Only relevant in context of {@link WebGPURenderer}. + * + * @type {boolean} + * @default false + */ + this.static = false; - // test to see if t0 is behind the ray: - // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, - // in order to always return an intersect point that is in front of the ray. - if ( t0 < 0 ) return this.at( t1, target ); + /** + * An object that can be used to store custom data about the 3D object. It + * should not hold references to functions as these will not be cloned. + * + * @type {Object} + */ + this.userData = {}; - // else t0 is in front of the ray, so return the first collision point scaled by t0 - return this.at( t0, target ); + /** + * The pivot point for rotation and scale transformations. + * When set, rotation and scale are applied around this point + * instead of the object's origin. + * + * @type {?Vector3} + * @default null + */ + this.pivot = null; } /** - * Returns `true` if this ray intersects with the given sphere. + * A callback that is executed immediately before a 3D object is rendered to a shadow map. * - * @param {Sphere} sphere - The sphere to intersect. - * @return {boolean} Whether this ray intersects with the given sphere or not. + * @param {Renderer|WebGLRenderer} renderer - The renderer. + * @param {Object3D} object - The 3D object. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {Camera} shadowCamera - The shadow camera. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Material} depthMaterial - The depth material. + * @param {Object} group - The geometry group data. */ - intersectsSphere( sphere ) { + onBeforeShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {} - if ( sphere.radius < 0 ) return false; // handle empty spheres, see #31187 + /** + * A callback that is executed immediately after a 3D object is rendered to a shadow map. + * + * @param {Renderer|WebGLRenderer} renderer - The renderer. + * @param {Object3D} object - The 3D object. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {Camera} shadowCamera - The shadow camera. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Material} depthMaterial - The depth material. + * @param {Object} group - The geometry group data. + */ + onAfterShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {} - return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); + /** + * A callback that is executed immediately before a 3D object is rendered. + * + * @param {Renderer|WebGLRenderer} renderer - The renderer. + * @param {Object3D} object - The 3D object. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Material} material - The 3D object's material. + * @param {Object} group - The geometry group data. + */ + onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {} - } + /** + * A callback that is executed immediately after a 3D object is rendered. + * + * @param {Renderer|WebGLRenderer} renderer - The renderer. + * @param {Object3D} object - The 3D object. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Material} material - The 3D object's material. + * @param {Object} group - The geometry group data. + */ + onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {} /** - * Computes the distance from the ray's origin to the given plane. Returns `null` if the ray - * does not intersect with the plane. + * Applies the given transformation matrix to the object and updates the object's position, + * rotation and scale. * - * @param {Plane} plane - The plane to compute the distance to. - * @return {?number} Whether this ray intersects with the given sphere or not. + * @param {Matrix4} matrix - The transformation matrix. */ - distanceToPlane( plane ) { + applyMatrix4( matrix ) { - const denominator = plane.normal.dot( this.direction ); + if ( this.matrixAutoUpdate ) this.updateMatrix(); - if ( denominator === 0 ) { + this.matrix.premultiply( matrix ); - // line is coplanar, return origin - if ( plane.distanceToPoint( this.origin ) === 0 ) { + this.matrix.decompose( this.position, this.quaternion, this.scale ); - return 0; + } - } + /** + * Applies a rotation represented by given the quaternion to the 3D object. + * + * @param {Quaternion} q - The quaternion. + * @return {Object3D} A reference to this instance. + */ + applyQuaternion( q ) { - // Null is preferable to undefined since undefined means.... it is undefined + this.quaternion.premultiply( q ); - return null; + return this; - } + } - const t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + /** + * Sets the given rotation represented as an axis/angle couple to the 3D object. + * + * @param {Vector3} axis - The (normalized) axis vector. + * @param {number} angle - The angle in radians. + */ + setRotationFromAxisAngle( axis, angle ) { - // Return if the ray never intersects the plane + // assumes axis is normalized - return t >= 0 ? t : null; + this.quaternion.setFromAxisAngle( axis, angle ); } /** - * Intersects this ray with the given plane, returning the intersection - * point or `null` if there is no intersection. + * Sets the given rotation represented as Euler angles to the 3D object. * - * @param {Plane} plane - The plane to intersect. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The intersection point. + * @param {Euler} euler - The Euler angles. */ - intersectPlane( plane, target ) { + setRotationFromEuler( euler ) { - const t = this.distanceToPlane( plane ); + this.quaternion.setFromEuler( euler, true ); - if ( t === null ) { + } - return null; + /** + * Sets the given rotation represented as rotation matrix to the 3D object. + * + * @param {Matrix4} m - Although a 4x4 matrix is expected, the upper 3x3 portion must be + * a pure rotation matrix (i.e, unscaled). + */ + setRotationFromMatrix( m ) { - } + // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) - return this.at( t, target ); + this.quaternion.setFromRotationMatrix( m ); } /** - * Returns `true` if this ray intersects with the given plane. + * Sets the given rotation represented as a Quaternion to the 3D object. * - * @param {Plane} plane - The plane to intersect. - * @return {boolean} Whether this ray intersects with the given plane or not. + * @param {Quaternion} q - The Quaternion */ - intersectsPlane( plane ) { + setRotationFromQuaternion( q ) { - // check if the ray lies on the plane first + // assumes q is normalized - const distToPoint = plane.distanceToPoint( this.origin ); + this.quaternion.copy( q ); - if ( distToPoint === 0 ) { + } - return true; + /** + * Rotates the 3D object along an axis in local space. + * + * @param {Vector3} axis - The (normalized) axis vector. + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. + */ + rotateOnAxis( axis, angle ) { - } + // rotate object on axis in object space + // axis is assumed to be normalized - const denominator = plane.normal.dot( this.direction ); + _q1.setFromAxisAngle( axis, angle ); - if ( denominator * distToPoint < 0 ) { + this.quaternion.multiply( _q1 ); - return true; + return this; - } + } - // ray origin is behind the plane (and is pointing behind it) + /** + * Rotates the 3D object along an axis in world space. + * + * @param {Vector3} axis - The (normalized) axis vector. + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. + */ + rotateOnWorldAxis( axis, angle ) { - return false; + // rotate object on axis in world space + // axis is assumed to be normalized + // method assumes no rotated parent + + _q1.setFromAxisAngle( axis, angle ); + + this.quaternion.premultiply( _q1 ); + + return this; } /** - * Intersects this ray with the given bounding box, returning the intersection - * point or `null` if there is no intersection. + * Rotates the 3D object around its X axis in local space. * - * @param {Box3} box - The box to intersect. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The intersection point. + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. */ - intersectBox( box, target ) { - - let tmin, tmax, tymin, tymax, tzmin, tzmax; + rotateX( angle ) { - const invdirx = 1 / this.direction.x, - invdiry = 1 / this.direction.y, - invdirz = 1 / this.direction.z; + return this.rotateOnAxis( _xAxis, angle ); - const origin = this.origin; + } - if ( invdirx >= 0 ) { + /** + * Rotates the 3D object around its Y axis in local space. + * + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. + */ + rotateY( angle ) { - tmin = ( box.min.x - origin.x ) * invdirx; - tmax = ( box.max.x - origin.x ) * invdirx; + return this.rotateOnAxis( _yAxis, angle ); - } else { + } - tmin = ( box.max.x - origin.x ) * invdirx; - tmax = ( box.min.x - origin.x ) * invdirx; + /** + * Rotates the 3D object around its Z axis in local space. + * + * @param {number} angle - The angle in radians. + * @return {Object3D} A reference to this instance. + */ + rotateZ( angle ) { - } + return this.rotateOnAxis( _zAxis, angle ); - if ( invdiry >= 0 ) { + } - tymin = ( box.min.y - origin.y ) * invdiry; - tymax = ( box.max.y - origin.y ) * invdiry; + /** + * Translate the 3D object by a distance along the given axis in local space. + * + * @param {Vector3} axis - The (normalized) axis vector. + * @param {number} distance - The distance in world units. + * @return {Object3D} A reference to this instance. + */ + translateOnAxis( axis, distance ) { - } else { + // translate object by distance along axis in object space + // axis is assumed to be normalized - tymin = ( box.max.y - origin.y ) * invdiry; - tymax = ( box.min.y - origin.y ) * invdiry; + _v1$6.copy( axis ).applyQuaternion( this.quaternion ); - } + this.position.add( _v1$6.multiplyScalar( distance ) ); - if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + return this; - if ( tymin > tmin || isNaN( tmin ) ) tmin = tymin; + } - if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax; + /** + * Translate the 3D object by a distance along its X-axis in local space. + * + * @param {number} distance - The distance in world units. + * @return {Object3D} A reference to this instance. + */ + translateX( distance ) { - if ( invdirz >= 0 ) { + return this.translateOnAxis( _xAxis, distance ); - tzmin = ( box.min.z - origin.z ) * invdirz; - tzmax = ( box.max.z - origin.z ) * invdirz; + } - } else { + /** + * Translate the 3D object by a distance along its Y-axis in local space. + * + * @param {number} distance - The distance in world units. + * @return {Object3D} A reference to this instance. + */ + translateY( distance ) { - tzmin = ( box.max.z - origin.z ) * invdirz; - tzmax = ( box.min.z - origin.z ) * invdirz; + return this.translateOnAxis( _yAxis, distance ); - } + } - if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; + /** + * Translate the 3D object by a distance along its Z-axis in local space. + * + * @param {number} distance - The distance in world units. + * @return {Object3D} A reference to this instance. + */ + translateZ( distance ) { - if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; + return this.translateOnAxis( _zAxis, distance ); - if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; + } - //return point closest to the ray (positive side) + /** + * Converts the given vector from this 3D object's local space to world space. + * + * @param {Vector3} vector - The vector to convert. + * @return {Vector3} The converted vector. + */ + localToWorld( vector ) { - if ( tmax < 0 ) return null; + this.updateWorldMatrix( true, false ); - return this.at( tmin >= 0 ? tmin : tmax, target ); + return vector.applyMatrix4( this.matrixWorld ); } /** - * Returns `true` if this ray intersects with the given box. + * Converts the given vector from this 3D object's world space to local space. * - * @param {Box3} box - The box to intersect. - * @return {boolean} Whether this ray intersects with the given box or not. + * @param {Vector3} vector - The vector to convert. + * @return {Vector3} The converted vector. */ - intersectsBox( box ) { + worldToLocal( vector ) { - return this.intersectBox( box, _vector$a ) !== null; + this.updateWorldMatrix( true, false ); + + return vector.applyMatrix4( _m1$1.copy( this.matrixWorld ).invert() ); } /** - * Intersects this ray with the given triangle, returning the intersection - * point or `null` if there is no intersection. + * Rotates the object to face a point in world space. * - * @param {Vector3} a - The first vertex of the triangle. - * @param {Vector3} b - The second vertex of the triangle. - * @param {Vector3} c - The third vertex of the triangle. - * @param {boolean} backfaceCulling - Whether to use backface culling or not. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The intersection point. + * This method does not support objects having non-uniformly-scaled parent(s). + * + * @param {number|Vector3} x - The x coordinate in world space. Alternatively, a vector representing a position in world space + * @param {number} [y] - The y coordinate in world space. + * @param {number} [z] - The z coordinate in world space. */ - intersectTriangle( a, b, c, backfaceCulling, target ) { + lookAt( x, y, z ) { - // Compute the offset origin, edges, and normal. + // This method does not support objects having non-uniformly-scaled parent(s) - // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h + if ( x.isVector3 ) { - _edge1.subVectors( b, a ); - _edge2.subVectors( c, a ); - _normal$1.crossVectors( _edge1, _edge2 ); + _target.copy( x ); - // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, - // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by - // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) - // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) - // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) - let DdN = this.direction.dot( _normal$1 ); - let sign; + } else { - if ( DdN > 0 ) { + _target.set( x, y, z ); - if ( backfaceCulling ) return null; - sign = 1; + } - } else if ( DdN < 0 ) { + const parent = this.parent; - sign = -1; - DdN = - DdN; + this.updateWorldMatrix( true, false ); + + _position$4.setFromMatrixPosition( this.matrixWorld ); + + if ( this.isCamera || this.isLight ) { + + _m1$1.lookAt( _position$4, _target, this.up ); } else { - return null; + _m1$1.lookAt( _target, _position$4, this.up ); } - _diff.subVectors( this.origin, a ); - const DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) ); + this.quaternion.setFromRotationMatrix( _m1$1 ); - // b1 < 0, no intersection - if ( DdQxE2 < 0 ) { + if ( parent ) { - return null; + _m1$1.extractRotation( parent.matrixWorld ); + _q1.setFromRotationMatrix( _m1$1 ); + this.quaternion.premultiply( _q1.invert() ); } - const DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); + } - // b2 < 0, no intersection - if ( DdE1xQ < 0 ) { + /** + * Adds the given 3D object as a child to this 3D object. An arbitrary number of + * objects may be added. Any current parent on an object passed in here will be + * removed, since an object can have at most one parent. + * + * @fires Object3D#added + * @fires Object3D#childadded + * @param {Object3D} object - The 3D object to add. + * @return {Object3D} A reference to this instance. + */ + add( object ) { - return null; + if ( arguments.length > 1 ) { - } + for ( let i = 0; i < arguments.length; i ++ ) { - // b1+b2 > 1, no intersection - if ( DdQxE2 + DdE1xQ > DdN ) { + this.add( arguments[ i ] ); - return null; + } - } + return this; - // Line intersects triangle, check if ray does. - const QdN = - sign * _diff.dot( _normal$1 ); + } - // t < 0, no intersection - if ( QdN < 0 ) { + if ( object === this ) { - return null; + error( 'Object3D.add: object can\'t be added as a child of itself.', object ); + return this; } - // Ray intersects triangle. - return this.at( QdN / DdN, target ); + if ( object && object.isObject3D ) { - } + object.removeFromParent(); + object.parent = this; + this.children.push( object ); - /** - * Transforms this ray with the given 4x4 transformation matrix. - * - * @param {Matrix4} matrix4 - The transformation matrix. - * @return {Ray} A reference to this ray. - */ - applyMatrix4( matrix4 ) { + object.dispatchEvent( _addedEvent ); - this.origin.applyMatrix4( matrix4 ); - this.direction.transformDirection( matrix4 ); + _childaddedEvent.child = object; + this.dispatchEvent( _childaddedEvent ); + _childaddedEvent.child = null; - return this; + } else { - } + error( 'Object3D.add: object not an instance of THREE.Object3D.', object ); - /** - * Returns `true` if this ray is equal with the given one. - * - * @param {Ray} ray - The ray to test for equality. - * @return {boolean} Whether this ray is equal with the given one. - */ - equals( ray ) { + } - return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); + return this; } /** - * Returns a new ray with copied values from this instance. + * Removes the given 3D object as child from this 3D object. + * An arbitrary number of objects may be removed. * - * @return {Ray} A clone of this instance. + * @fires Object3D#removed + * @fires Object3D#childremoved + * @param {Object3D} object - The 3D object to remove. + * @return {Object3D} A reference to this instance. */ - clone() { + remove( object ) { - return new this.constructor().copy( this ); + if ( arguments.length > 1 ) { - } + for ( let i = 0; i < arguments.length; i ++ ) { -} + this.remove( arguments[ i ] ); -/** - * Represents a 4x4 matrix. - * - * The most common use of a 4x4 matrix in 3D computer graphics is as a transformation matrix. - * For an introduction to transformation matrices as used in WebGL, check out [this tutorial](https://www.opengl-tutorial.org/beginners-tutorials/tutorial-3-matrices) - * - * This allows a 3D vector representing a point in 3D space to undergo - * transformations such as translation, rotation, shear, scale, reflection, - * orthogonal or perspective projection and so on, by being multiplied by the - * matrix. This is known as `applying` the matrix to the vector. - * - * A Note on Row-Major and Column-Major Ordering: - * - * The constructor and {@link Matrix3#set} method take arguments in - * [row-major](https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order) - * order, while internally they are stored in the {@link Matrix3#elements} array in column-major order. - * This means that calling: - * ```js - * const m = new THREE.Matrix4(); - * m.set( 11, 12, 13, 14, - * 21, 22, 23, 24, - * 31, 32, 33, 34, - * 41, 42, 43, 44 ); - * ``` - * will result in the elements array containing: - * ```js - * m.elements = [ 11, 21, 31, 41, - * 12, 22, 32, 42, - * 13, 23, 33, 43, - * 14, 24, 34, 44 ]; - * ``` - * and internally all calculations are performed using column-major ordering. - * However, as the actual ordering makes no difference mathematically and - * most people are used to thinking about matrices in row-major order, the - * three.js documentation shows matrices in row-major order. Just bear in - * mind that if you are reading the source code, you'll have to take the - * transpose of any matrices outlined here to make sense of the calculations. - */ -class Matrix4 { + } - /** - * Constructs a new 4x4 matrix. The arguments are supposed to be - * in row-major order. If no arguments are provided, the constructor - * initializes the matrix as an identity matrix. - * - * @param {number} [n11] - 1-1 matrix element. - * @param {number} [n12] - 1-2 matrix element. - * @param {number} [n13] - 1-3 matrix element. - * @param {number} [n14] - 1-4 matrix element. - * @param {number} [n21] - 2-1 matrix element. - * @param {number} [n22] - 2-2 matrix element. - * @param {number} [n23] - 2-3 matrix element. - * @param {number} [n24] - 2-4 matrix element. - * @param {number} [n31] - 3-1 matrix element. - * @param {number} [n32] - 3-2 matrix element. - * @param {number} [n33] - 3-3 matrix element. - * @param {number} [n34] - 3-4 matrix element. - * @param {number} [n41] - 4-1 matrix element. - * @param {number} [n42] - 4-2 matrix element. - * @param {number} [n43] - 4-3 matrix element. - * @param {number} [n44] - 4-4 matrix element. - */ - constructor( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { + return this; - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - Matrix4.prototype.isMatrix4 = true; + } - /** - * A column-major list of matrix values. - * - * @type {Array} - */ - this.elements = [ + const index = this.children.indexOf( object ); - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + if ( index !== -1 ) { - ]; + object.parent = null; + this.children.splice( index, 1 ); - if ( n11 !== undefined ) { + object.dispatchEvent( _removedEvent ); - this.set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ); + _childremovedEvent.child = object; + this.dispatchEvent( _childremovedEvent ); + _childremovedEvent.child = null; } - } - - /** - * Sets the elements of the matrix.The arguments are supposed to be - * in row-major order. - * - * @param {number} [n11] - 1-1 matrix element. - * @param {number} [n12] - 1-2 matrix element. - * @param {number} [n13] - 1-3 matrix element. - * @param {number} [n14] - 1-4 matrix element. - * @param {number} [n21] - 2-1 matrix element. - * @param {number} [n22] - 2-2 matrix element. - * @param {number} [n23] - 2-3 matrix element. - * @param {number} [n24] - 2-4 matrix element. - * @param {number} [n31] - 3-1 matrix element. - * @param {number} [n32] - 3-2 matrix element. - * @param {number} [n33] - 3-3 matrix element. - * @param {number} [n34] - 3-4 matrix element. - * @param {number} [n41] - 4-1 matrix element. - * @param {number} [n42] - 4-2 matrix element. - * @param {number} [n43] - 4-3 matrix element. - * @param {number} [n44] - 4-4 matrix element. - * @return {Matrix4} A reference to this matrix. - */ - set( n11, n12, n13, n14, n21, n22, n23, n24, n31, n32, n33, n34, n41, n42, n43, n44 ) { - - const te = this.elements; - - te[ 0 ] = n11; te[ 4 ] = n12; te[ 8 ] = n13; te[ 12 ] = n14; - te[ 1 ] = n21; te[ 5 ] = n22; te[ 9 ] = n23; te[ 13 ] = n24; - te[ 2 ] = n31; te[ 6 ] = n32; te[ 10 ] = n33; te[ 14 ] = n34; - te[ 3 ] = n41; te[ 7 ] = n42; te[ 11 ] = n43; te[ 15 ] = n44; - return this; } /** - * Sets this matrix to the 4x4 identity matrix. + * Removes this 3D object from its current parent. * - * @return {Matrix4} A reference to this matrix. + * @fires Object3D#removed + * @fires Object3D#childremoved + * @return {Object3D} A reference to this instance. */ - identity() { + removeFromParent() { - this.set( + const parent = this.parent; - 1, 0, 0, 0, - 0, 1, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + if ( parent !== null ) { - ); + parent.remove( this ); + + } return this; } /** - * Returns a matrix with copied values from this instance. + * Removes all child objects. * - * @return {Matrix4} A clone of this instance. + * @fires Object3D#removed + * @fires Object3D#childremoved + * @return {Object3D} A reference to this instance. */ - clone() { + clear() { - return new Matrix4().fromArray( this.elements ); + return this.remove( ... this.children ); } /** - * Copies the values of the given matrix to this instance. + * Adds the given 3D object as a child of this 3D object, while maintaining the object's world + * transform. This method does not support scene graphs having non-uniformly-scaled nodes(s). * - * @param {Matrix4} m - The matrix to copy. - * @return {Matrix4} A reference to this matrix. + * @fires Object3D#added + * @fires Object3D#childadded + * @param {Object3D} object - The 3D object to attach. + * @return {Object3D} A reference to this instance. */ - copy( m ) { + attach( object ) { - const te = this.elements; - const me = m.elements; + // adds object as a child of this, while maintaining the object's world transform - te[ 0 ] = me[ 0 ]; te[ 1 ] = me[ 1 ]; te[ 2 ] = me[ 2 ]; te[ 3 ] = me[ 3 ]; - te[ 4 ] = me[ 4 ]; te[ 5 ] = me[ 5 ]; te[ 6 ] = me[ 6 ]; te[ 7 ] = me[ 7 ]; - te[ 8 ] = me[ 8 ]; te[ 9 ] = me[ 9 ]; te[ 10 ] = me[ 10 ]; te[ 11 ] = me[ 11 ]; - te[ 12 ] = me[ 12 ]; te[ 13 ] = me[ 13 ]; te[ 14 ] = me[ 14 ]; te[ 15 ] = me[ 15 ]; + // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) - return this; + this.updateWorldMatrix( true, false ); - } + _m1$1.copy( this.matrixWorld ).invert(); - /** - * Copies the translation component of the given matrix - * into this matrix's translation component. - * - * @param {Matrix4} m - The matrix to copy the translation component. - * @return {Matrix4} A reference to this matrix. - */ - copyPosition( m ) { + if ( object.parent !== null ) { - const te = this.elements, me = m.elements; + object.parent.updateWorldMatrix( true, false ); - te[ 12 ] = me[ 12 ]; - te[ 13 ] = me[ 13 ]; - te[ 14 ] = me[ 14 ]; + _m1$1.multiply( object.parent.matrixWorld ); - return this; + } - } - - /** - * Set the upper 3x3 elements of this matrix to the values of given 3x3 matrix. - * - * @param {Matrix3} m - The 3x3 matrix. - * @return {Matrix4} A reference to this matrix. - */ - setFromMatrix3( m ) { + object.applyMatrix4( _m1$1 ); - const me = m.elements; + object.removeFromParent(); + object.parent = this; + this.children.push( object ); - this.set( + object.updateWorldMatrix( false, true ); - me[ 0 ], me[ 3 ], me[ 6 ], 0, - me[ 1 ], me[ 4 ], me[ 7 ], 0, - me[ 2 ], me[ 5 ], me[ 8 ], 0, - 0, 0, 0, 1 + object.dispatchEvent( _addedEvent ); - ); + _childaddedEvent.child = object; + this.dispatchEvent( _childaddedEvent ); + _childaddedEvent.child = null; return this; } /** - * Extracts the basis of this matrix into the three axis vectors provided. + * Searches through the 3D object and its children, starting with the 3D object + * itself, and returns the first with a matching ID. * - * @param {Vector3} xAxis - The basis's x axis. - * @param {Vector3} yAxis - The basis's y axis. - * @param {Vector3} zAxis - The basis's z axis. - * @return {Matrix4} A reference to this matrix. + * @param {number} id - The id. + * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. */ - extractBasis( xAxis, yAxis, zAxis ) { - - if ( this.determinant() === 0 ) { - - xAxis.set( 1, 0, 0 ); - yAxis.set( 0, 1, 0 ); - zAxis.set( 0, 0, 1 ); + getObjectById( id ) { - return this; + return this.getObjectByProperty( 'id', id ); - } + } - xAxis.setFromMatrixColumn( this, 0 ); - yAxis.setFromMatrixColumn( this, 1 ); - zAxis.setFromMatrixColumn( this, 2 ); + /** + * Searches through the 3D object and its children, starting with the 3D object + * itself, and returns the first with a matching name. + * + * @param {string} name - The name. + * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. + */ + getObjectByName( name ) { - return this; + return this.getObjectByProperty( 'name', name ); } /** - * Sets the given basis vectors to this matrix. + * Searches through the 3D object and its children, starting with the 3D object + * itself, and returns the first with a matching property value. * - * @param {Vector3} xAxis - The basis's x axis. - * @param {Vector3} yAxis - The basis's y axis. - * @param {Vector3} zAxis - The basis's z axis. - * @return {Matrix4} A reference to this matrix. + * @param {string} name - The name of the property. + * @param {any} value - The value. + * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. */ - makeBasis( xAxis, yAxis, zAxis ) { + getObjectByProperty( name, value ) { - this.set( - xAxis.x, yAxis.x, zAxis.x, 0, - xAxis.y, yAxis.y, zAxis.y, 0, - xAxis.z, yAxis.z, zAxis.z, 0, - 0, 0, 0, 1 - ); + if ( this[ name ] === value ) return this; - return this; + for ( let i = 0, l = this.children.length; i < l; i ++ ) { + + const child = this.children[ i ]; + const object = child.getObjectByProperty( name, value ); + + if ( object !== undefined ) { + + return object; + + } + + } + + return undefined; } /** - * Extracts the rotation component of the given matrix - * into this matrix's rotation component. - * - * Note: This method does not support reflection matrices. + * Searches through the 3D object and its children, starting with the 3D object + * itself, and returns all 3D objects with a matching property value. * - * @param {Matrix4} m - The matrix. - * @return {Matrix4} A reference to this matrix. + * @param {string} name - The name of the property. + * @param {any} value - The value. + * @param {Array} result - The method stores the result in this array. + * @return {Array} The found 3D objects. */ - extractRotation( m ) { + getObjectsByProperty( name, value, result = [] ) { - if ( m.determinant() === 0 ) { + if ( this[ name ] === value ) result.push( this ); - return this.identity(); + const children = this.children; - } + for ( let i = 0, l = children.length; i < l; i ++ ) { - const te = this.elements; - const me = m.elements; + children[ i ].getObjectsByProperty( name, value, result ); - const scaleX = 1 / _v1$5.setFromMatrixColumn( m, 0 ).length(); - const scaleY = 1 / _v1$5.setFromMatrixColumn( m, 1 ).length(); - const scaleZ = 1 / _v1$5.setFromMatrixColumn( m, 2 ).length(); + } - te[ 0 ] = me[ 0 ] * scaleX; - te[ 1 ] = me[ 1 ] * scaleX; - te[ 2 ] = me[ 2 ] * scaleX; - te[ 3 ] = 0; + return result; - te[ 4 ] = me[ 4 ] * scaleY; - te[ 5 ] = me[ 5 ] * scaleY; - te[ 6 ] = me[ 6 ] * scaleY; - te[ 7 ] = 0; + } - te[ 8 ] = me[ 8 ] * scaleZ; - te[ 9 ] = me[ 9 ] * scaleZ; - te[ 10 ] = me[ 10 ] * scaleZ; - te[ 11 ] = 0; + /** + * Returns a vector representing the position of the 3D object in world space. + * + * @param {Vector3} target - The target vector the result is stored to. + * @return {Vector3} The 3D object's position in world space. + */ + getWorldPosition( target ) { - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + this.updateWorldMatrix( true, false ); - return this; + return target.setFromMatrixPosition( this.matrixWorld ); } /** - * Sets the rotation component (the upper left 3x3 matrix) of this matrix to - * the rotation specified by the given Euler angles. The rest of - * the matrix is set to the identity. Depending on the {@link Euler#order}, - * there are six possible outcomes. See [this page](https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix) - * for a complete list. + * Returns a Quaternion representing the position of the 3D object in world space. * - * @param {Euler} euler - The Euler angles. - * @return {Matrix4} A reference to this matrix. + * @param {Quaternion} target - The target Quaternion the result is stored to. + * @return {Quaternion} The 3D object's rotation in world space. */ - makeRotationFromEuler( euler ) { + getWorldQuaternion( target ) { - const te = this.elements; + this.updateWorldMatrix( true, false ); - const x = euler.x, y = euler.y, z = euler.z; - const a = Math.cos( x ), b = Math.sin( x ); - const c = Math.cos( y ), d = Math.sin( y ); - const e = Math.cos( z ), f = Math.sin( z ); + this.matrixWorld.decompose( _position$4, target, _scale$3 ); - if ( euler.order === 'XYZ' ) { + return target; - const ae = a * e, af = a * f, be = b * e, bf = b * f; + } - te[ 0 ] = c * e; - te[ 4 ] = - c * f; - te[ 8 ] = d; + /** + * Returns a vector representing the scale of the 3D object in world space. + * + * @param {Vector3} target - The target vector the result is stored to. + * @return {Vector3} The 3D object's scale in world space. + */ + getWorldScale( target ) { - te[ 1 ] = af + be * d; - te[ 5 ] = ae - bf * d; - te[ 9 ] = - b * c; + this.updateWorldMatrix( true, false ); - te[ 2 ] = bf - ae * d; - te[ 6 ] = be + af * d; - te[ 10 ] = a * c; + this.matrixWorld.decompose( _position$4, _quaternion$3, target ); - } else if ( euler.order === 'YXZ' ) { + return target; - const ce = c * e, cf = c * f, de = d * e, df = d * f; + } - te[ 0 ] = ce + df * b; - te[ 4 ] = de * b - cf; - te[ 8 ] = a * d; + /** + * Returns a vector representing the ("look") direction of the 3D object in world space. + * + * @param {Vector3} target - The target vector the result is stored to. + * @return {Vector3} The 3D object's direction in world space. + */ + getWorldDirection( target ) { - te[ 1 ] = a * f; - te[ 5 ] = a * e; - te[ 9 ] = - b; + this.updateWorldMatrix( true, false ); - te[ 2 ] = cf * b - de; - te[ 6 ] = df + ce * b; - te[ 10 ] = a * c; + const e = this.matrixWorld.elements; - } else if ( euler.order === 'ZXY' ) { + return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); - const ce = c * e, cf = c * f, de = d * e, df = d * f; + } - te[ 0 ] = ce - df * b; - te[ 4 ] = - a * f; - te[ 8 ] = de + cf * b; + /** + * Abstract method to get intersections between a casted ray and this + * 3D object. Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points} + * implement this method in order to use raycasting. + * + * @abstract + * @param {Raycaster} raycaster - The raycaster. + * @param {Array} intersects - An array holding the result of the method. + */ + raycast( /* raycaster, intersects */ ) {} - te[ 1 ] = cf + de * b; - te[ 5 ] = a * e; - te[ 9 ] = df - ce * b; + /** + * Executes the callback on this 3D object and all descendants. + * + * Note: Modifying the scene graph inside the callback is discouraged. + * + * @param {Function} callback - A callback function that allows to process the current 3D object. + */ + traverse( callback ) { - te[ 2 ] = - a * d; - te[ 6 ] = b; - te[ 10 ] = a * c; + callback( this ); - } else if ( euler.order === 'ZYX' ) { + const children = this.children; - const ae = a * e, af = a * f, be = b * e, bf = b * f; + for ( let i = 0, l = children.length; i < l; i ++ ) { - te[ 0 ] = c * e; - te[ 4 ] = be * d - af; - te[ 8 ] = ae * d + bf; + children[ i ].traverse( callback ); - te[ 1 ] = c * f; - te[ 5 ] = bf * d + ae; - te[ 9 ] = af * d - be; + } - te[ 2 ] = - d; - te[ 6 ] = b * c; - te[ 10 ] = a * c; + } - } else if ( euler.order === 'YZX' ) { + /** + * Like {@link Object3D#traverse}, but the callback will only be executed for visible 3D objects. + * Descendants of invisible 3D objects are not traversed. + * + * Note: Modifying the scene graph inside the callback is discouraged. + * + * @param {Function} callback - A callback function that allows to process the current 3D object. + */ + traverseVisible( callback ) { - const ac = a * c, ad = a * d, bc = b * c, bd = b * d; + if ( this.visible === false ) return; - te[ 0 ] = c * e; - te[ 4 ] = bd - ac * f; - te[ 8 ] = bc * f + ad; + callback( this ); - te[ 1 ] = f; - te[ 5 ] = a * e; - te[ 9 ] = - b * e; + const children = this.children; - te[ 2 ] = - d * e; - te[ 6 ] = ad * f + bc; - te[ 10 ] = ac - bd * f; + for ( let i = 0, l = children.length; i < l; i ++ ) { - } else if ( euler.order === 'XZY' ) { + children[ i ].traverseVisible( callback ); - const ac = a * c, ad = a * d, bc = b * c, bd = b * d; + } - te[ 0 ] = c * e; - te[ 4 ] = - f; - te[ 8 ] = d * e; + } - te[ 1 ] = ac * f + bd; - te[ 5 ] = a * e; - te[ 9 ] = ad * f - bc; + /** + * Like {@link Object3D#traverse}, but the callback will only be executed for all ancestors. + * + * Note: Modifying the scene graph inside the callback is discouraged. + * + * @param {Function} callback - A callback function that allows to process the current 3D object. + */ + traverseAncestors( callback ) { - te[ 2 ] = bc * f - ad; - te[ 6 ] = b * e; - te[ 10 ] = bd * f + ac; + const parent = this.parent; - } + if ( parent !== null ) { - // bottom row - te[ 3 ] = 0; - te[ 7 ] = 0; - te[ 11 ] = 0; + callback( parent ); - // last column - te[ 12 ] = 0; - te[ 13 ] = 0; - te[ 14 ] = 0; - te[ 15 ] = 1; + parent.traverseAncestors( callback ); - return this; + } } /** - * Sets the rotation component of this matrix to the rotation specified by - * the given Quaternion as outlined [here](https://en.wikipedia.org/wiki/Rotation_matrix#Quaternion) - * The rest of the matrix is set to the identity. - * - * @param {Quaternion} q - The Quaternion. - * @return {Matrix4} A reference to this matrix. + * Updates the transformation matrix in local space by computing it from the current + * position, rotation and scale values. */ - makeRotationFromQuaternion( q ) { + updateMatrix() { - return this.compose( _zero, q, _one ); + this.matrix.compose( this.position, this.quaternion, this.scale ); + + const pivot = this.pivot; + + if ( pivot !== null ) { + + const px = pivot.x, py = pivot.y, pz = pivot.z; + const te = this.matrix.elements; + + te[ 12 ] += px - te[ 0 ] * px - te[ 4 ] * py - te[ 8 ] * pz; + te[ 13 ] += py - te[ 1 ] * px - te[ 5 ] * py - te[ 9 ] * pz; + te[ 14 ] += pz - te[ 2 ] * px - te[ 6 ] * py - te[ 10 ] * pz; + + } + + this.matrixWorldNeedsUpdate = true; } /** - * Sets the rotation component of the transformation matrix, looking from `eye` towards - * `target`, and oriented by the up-direction. + * Updates the transformation matrix in world space of this 3D objects and its descendants. * - * @param {Vector3} eye - The eye vector. - * @param {Vector3} target - The target vector. - * @param {Vector3} up - The up vector. - * @return {Matrix4} A reference to this matrix. + * To ensure correct results, this method also recomputes the 3D object's transformation matrix in + * local space. The computation of the local and world matrix can be controlled with the + * {@link Object3D#matrixAutoUpdate} and {@link Object3D#matrixWorldAutoUpdate} flags which are both + * `true` by default. Set these flags to `false` if you need more control over the update matrix process. + * + * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even + * when {@link Object3D#matrixWorldNeedsUpdate} is `false`. */ - lookAt( eye, target, up ) { - - const te = this.elements; + updateMatrixWorld( force ) { - _z.subVectors( eye, target ); + if ( this.matrixAutoUpdate ) this.updateMatrix(); - if ( _z.lengthSq() === 0 ) { + if ( this.matrixWorldNeedsUpdate || force ) { - // eye and target are in the same position + if ( this.matrixWorldAutoUpdate === true ) { - _z.z = 1; + if ( this.parent === null ) { - } + this.matrixWorld.copy( this.matrix ); - _z.normalize(); - _x.crossVectors( up, _z ); + } else { - if ( _x.lengthSq() === 0 ) { + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - // up and z are parallel + } - if ( Math.abs( up.z ) === 1 ) { + } - _z.x += 0.0001; + this.matrixWorldNeedsUpdate = false; - } else { + force = true; - _z.z += 0.0001; + } - } + // make sure descendants are updated if required - _z.normalize(); - _x.crossVectors( up, _z ); + const children = this.children; - } + for ( let i = 0, l = children.length; i < l; i ++ ) { - _x.normalize(); - _y.crossVectors( _z, _x ); + const child = children[ i ]; - te[ 0 ] = _x.x; te[ 4 ] = _y.x; te[ 8 ] = _z.x; - te[ 1 ] = _x.y; te[ 5 ] = _y.y; te[ 9 ] = _z.y; - te[ 2 ] = _x.z; te[ 6 ] = _y.z; te[ 10 ] = _z.z; + child.updateMatrixWorld( force ); - return this; + } } /** - * Post-multiplies this matrix by the given 4x4 matrix. + * An alternative version of {@link Object3D#updateMatrixWorld} with more control over the + * update of ancestor and descendant nodes. * - * @param {Matrix4} m - The matrix to multiply with. - * @return {Matrix4} A reference to this matrix. + * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not. + * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not. */ - multiply( m ) { + updateWorldMatrix( updateParents, updateChildren ) { - return this.multiplyMatrices( this, m ); + const parent = this.parent; - } + if ( updateParents === true && parent !== null ) { - /** - * Pre-multiplies this matrix by the given 4x4 matrix. - * - * @param {Matrix4} m - The matrix to multiply with. - * @return {Matrix4} A reference to this matrix. - */ - premultiply( m ) { + parent.updateWorldMatrix( true, false ); - return this.multiplyMatrices( m, this ); + } - } + if ( this.matrixAutoUpdate ) this.updateMatrix(); - /** - * Multiples the given 4x4 matrices and stores the result - * in this matrix. - * - * @param {Matrix4} a - The first matrix. - * @param {Matrix4} b - The second matrix. - * @return {Matrix4} A reference to this matrix. - */ - multiplyMatrices( a, b ) { + if ( this.matrixWorldAutoUpdate === true ) { - const ae = a.elements; - const be = b.elements; - const te = this.elements; + if ( this.parent === null ) { - const a11 = ae[ 0 ], a12 = ae[ 4 ], a13 = ae[ 8 ], a14 = ae[ 12 ]; - const a21 = ae[ 1 ], a22 = ae[ 5 ], a23 = ae[ 9 ], a24 = ae[ 13 ]; - const a31 = ae[ 2 ], a32 = ae[ 6 ], a33 = ae[ 10 ], a34 = ae[ 14 ]; - const a41 = ae[ 3 ], a42 = ae[ 7 ], a43 = ae[ 11 ], a44 = ae[ 15 ]; + this.matrixWorld.copy( this.matrix ); - const b11 = be[ 0 ], b12 = be[ 4 ], b13 = be[ 8 ], b14 = be[ 12 ]; - const b21 = be[ 1 ], b22 = be[ 5 ], b23 = be[ 9 ], b24 = be[ 13 ]; - const b31 = be[ 2 ], b32 = be[ 6 ], b33 = be[ 10 ], b34 = be[ 14 ]; - const b41 = be[ 3 ], b42 = be[ 7 ], b43 = be[ 11 ], b44 = be[ 15 ]; + } else { - te[ 0 ] = a11 * b11 + a12 * b21 + a13 * b31 + a14 * b41; - te[ 4 ] = a11 * b12 + a12 * b22 + a13 * b32 + a14 * b42; - te[ 8 ] = a11 * b13 + a12 * b23 + a13 * b33 + a14 * b43; - te[ 12 ] = a11 * b14 + a12 * b24 + a13 * b34 + a14 * b44; + this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); - te[ 1 ] = a21 * b11 + a22 * b21 + a23 * b31 + a24 * b41; - te[ 5 ] = a21 * b12 + a22 * b22 + a23 * b32 + a24 * b42; - te[ 9 ] = a21 * b13 + a22 * b23 + a23 * b33 + a24 * b43; - te[ 13 ] = a21 * b14 + a22 * b24 + a23 * b34 + a24 * b44; + } - te[ 2 ] = a31 * b11 + a32 * b21 + a33 * b31 + a34 * b41; - te[ 6 ] = a31 * b12 + a32 * b22 + a33 * b32 + a34 * b42; - te[ 10 ] = a31 * b13 + a32 * b23 + a33 * b33 + a34 * b43; - te[ 14 ] = a31 * b14 + a32 * b24 + a33 * b34 + a34 * b44; + } - te[ 3 ] = a41 * b11 + a42 * b21 + a43 * b31 + a44 * b41; - te[ 7 ] = a41 * b12 + a42 * b22 + a43 * b32 + a44 * b42; - te[ 11 ] = a41 * b13 + a42 * b23 + a43 * b33 + a44 * b43; - te[ 15 ] = a41 * b14 + a42 * b24 + a43 * b34 + a44 * b44; + // make sure descendants are updated - return this; + if ( updateChildren === true ) { - } + const children = this.children; - /** - * Multiplies every component of the matrix by the given scalar. - * - * @param {number} s - The scalar. - * @return {Matrix4} A reference to this matrix. - */ - multiplyScalar( s ) { + for ( let i = 0, l = children.length; i < l; i ++ ) { - const te = this.elements; + const child = children[ i ]; - te[ 0 ] *= s; te[ 4 ] *= s; te[ 8 ] *= s; te[ 12 ] *= s; - te[ 1 ] *= s; te[ 5 ] *= s; te[ 9 ] *= s; te[ 13 ] *= s; - te[ 2 ] *= s; te[ 6 ] *= s; te[ 10 ] *= s; te[ 14 ] *= s; - te[ 3 ] *= s; te[ 7 ] *= s; te[ 11 ] *= s; te[ 15 ] *= s; + child.updateWorldMatrix( false, true ); - return this; + } + + } } /** - * Computes and returns the determinant of this matrix. - * - * Based on the method outlined [here](http://www.euclideanspace.com/maths/algebra/matrix/functions/inverse/fourD/index.html). + * Serializes the 3D object into JSON. * - * @return {number} The determinant. + * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized 3D object. + * @see {@link ObjectLoader#parse} */ - determinant() { + toJSON( meta ) { - const te = this.elements; + // meta is a string when called from JSON.stringify + const isRootObject = ( meta === undefined || typeof meta === 'string' ); - const n11 = te[ 0 ], n12 = te[ 4 ], n13 = te[ 8 ], n14 = te[ 12 ]; - const n21 = te[ 1 ], n22 = te[ 5 ], n23 = te[ 9 ], n24 = te[ 13 ]; - const n31 = te[ 2 ], n32 = te[ 6 ], n33 = te[ 10 ], n34 = te[ 14 ]; - const n41 = te[ 3 ], n42 = te[ 7 ], n43 = te[ 11 ], n44 = te[ 15 ]; - - const t11 = n23 * n34 - n24 * n33; - const t12 = n22 * n34 - n24 * n32; - const t13 = n22 * n33 - n23 * n32; + const output = {}; - const t21 = n21 * n34 - n24 * n31; - const t22 = n21 * n33 - n23 * n31; - const t23 = n21 * n32 - n22 * n31; + // meta is a hash used to collect geometries, materials. + // not providing it implies that this is the root object + // being serialized. + if ( isRootObject ) { - return n11 * ( n42 * t11 - n43 * t12 + n44 * t13 ) - - n12 * ( n41 * t11 - n43 * t21 + n44 * t22 ) + - n13 * ( n41 * t12 - n42 * t21 + n44 * t23 ) - - n14 * ( n41 * t13 - n42 * t22 + n43 * t23 ); + // initialize meta obj + meta = { + geometries: {}, + materials: {}, + textures: {}, + images: {}, + shapes: {}, + skeletons: {}, + animations: {}, + nodes: {} + }; - } + output.metadata = { + version: 4.7, + type: 'Object', + generator: 'Object3D.toJSON' + }; - /** - * Transposes this matrix in place. - * - * @return {Matrix4} A reference to this matrix. - */ - transpose() { + } - const te = this.elements; - let tmp; + // standard Object3D serialization - tmp = te[ 1 ]; te[ 1 ] = te[ 4 ]; te[ 4 ] = tmp; - tmp = te[ 2 ]; te[ 2 ] = te[ 8 ]; te[ 8 ] = tmp; - tmp = te[ 6 ]; te[ 6 ] = te[ 9 ]; te[ 9 ] = tmp; + const object = {}; - tmp = te[ 3 ]; te[ 3 ] = te[ 12 ]; te[ 12 ] = tmp; - tmp = te[ 7 ]; te[ 7 ] = te[ 13 ]; te[ 13 ] = tmp; - tmp = te[ 11 ]; te[ 11 ] = te[ 14 ]; te[ 14 ] = tmp; + object.uuid = this.uuid; + object.type = this.type; - return this; + if ( this.name !== '' ) object.name = this.name; + if ( this.castShadow === true ) object.castShadow = true; + if ( this.receiveShadow === true ) object.receiveShadow = true; + if ( this.visible === false ) object.visible = false; + if ( this.frustumCulled === false ) object.frustumCulled = false; + if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; + if ( this.static !== false ) object.static = this.static; + if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData; - } + object.layers = this.layers.mask; + object.matrix = this.matrix.toArray(); + object.up = this.up.toArray(); - /** - * Sets the position component for this matrix from the given vector, - * without affecting the rest of the matrix. - * - * @param {number|Vector3} x - The x component of the vector or alternatively the vector object. - * @param {number} y - The y component of the vector. - * @param {number} z - The z component of the vector. - * @return {Matrix4} A reference to this matrix. - */ - setPosition( x, y, z ) { + if ( this.pivot !== null ) object.pivot = this.pivot.toArray(); - const te = this.elements; + if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; - if ( x.isVector3 ) { + if ( this.morphTargetDictionary !== undefined ) object.morphTargetDictionary = Object.assign( {}, this.morphTargetDictionary ); + if ( this.morphTargetInfluences !== undefined ) object.morphTargetInfluences = this.morphTargetInfluences.slice(); - te[ 12 ] = x.x; - te[ 13 ] = x.y; - te[ 14 ] = x.z; + // object specific properties - } else { + if ( this.isInstancedMesh ) { - te[ 12 ] = x; - te[ 13 ] = y; - te[ 14 ] = z; + object.type = 'InstancedMesh'; + object.count = this.count; + object.instanceMatrix = this.instanceMatrix.toJSON(); + if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON(); } - return this; - - } + if ( this.isBatchedMesh ) { - /** - * Inverts this matrix, using the [analytic method](https://en.wikipedia.org/wiki/Invertible_matrix#Analytic_solution). - * You can not invert with a determinant of zero. If you attempt this, the method produces - * a zero matrix instead. - * - * @return {Matrix4} A reference to this matrix. - */ - invert() { + object.type = 'BatchedMesh'; + object.perObjectFrustumCulled = this.perObjectFrustumCulled; + object.sortObjects = this.sortObjects; - // based on https://github.com/toji/gl-matrix - const te = this.elements, + object.drawRanges = this._drawRanges; + object.reservedRanges = this._reservedRanges; - n11 = te[ 0 ], n21 = te[ 1 ], n31 = te[ 2 ], n41 = te[ 3 ], - n12 = te[ 4 ], n22 = te[ 5 ], n32 = te[ 6 ], n42 = te[ 7 ], - n13 = te[ 8 ], n23 = te[ 9 ], n33 = te[ 10 ], n43 = te[ 11 ], - n14 = te[ 12 ], n24 = te[ 13 ], n34 = te[ 14 ], n44 = te[ 15 ], + object.geometryInfo = this._geometryInfo.map( info => ( { + ...info, + boundingBox: info.boundingBox ? info.boundingBox.toJSON() : undefined, + boundingSphere: info.boundingSphere ? info.boundingSphere.toJSON() : undefined + } ) ); + object.instanceInfo = this._instanceInfo.map( info => ( { ...info } ) ); - t1 = n11 * n22 - n21 * n12, - t2 = n11 * n32 - n31 * n12, - t3 = n11 * n42 - n41 * n12, - t4 = n21 * n32 - n31 * n22, - t5 = n21 * n42 - n41 * n22, - t6 = n31 * n42 - n41 * n32, - t7 = n13 * n24 - n23 * n14, - t8 = n13 * n34 - n33 * n14, - t9 = n13 * n44 - n43 * n14, - t10 = n23 * n34 - n33 * n24, - t11 = n23 * n44 - n43 * n24, - t12 = n33 * n44 - n43 * n34; + object.availableInstanceIds = this._availableInstanceIds.slice(); + object.availableGeometryIds = this._availableGeometryIds.slice(); - const det = t1 * t12 - t2 * t11 + t3 * t10 + t4 * t9 - t5 * t8 + t6 * t7; + object.nextIndexStart = this._nextIndexStart; + object.nextVertexStart = this._nextVertexStart; + object.geometryCount = this._geometryCount; - if ( det === 0 ) return this.set( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ); + object.maxInstanceCount = this._maxInstanceCount; + object.maxVertexCount = this._maxVertexCount; + object.maxIndexCount = this._maxIndexCount; - const detInv = 1 / det; + object.geometryInitialized = this._geometryInitialized; - te[ 0 ] = ( n22 * t12 - n32 * t11 + n42 * t10 ) * detInv; - te[ 1 ] = ( n31 * t11 - n21 * t12 - n41 * t10 ) * detInv; - te[ 2 ] = ( n24 * t6 - n34 * t5 + n44 * t4 ) * detInv; - te[ 3 ] = ( n33 * t5 - n23 * t6 - n43 * t4 ) * detInv; + object.matricesTexture = this._matricesTexture.toJSON( meta ); - te[ 4 ] = ( n32 * t9 - n12 * t12 - n42 * t8 ) * detInv; - te[ 5 ] = ( n11 * t12 - n31 * t9 + n41 * t8 ) * detInv; - te[ 6 ] = ( n34 * t3 - n14 * t6 - n44 * t2 ) * detInv; - te[ 7 ] = ( n13 * t6 - n33 * t3 + n43 * t2 ) * detInv; + object.indirectTexture = this._indirectTexture.toJSON( meta ); - te[ 8 ] = ( n12 * t11 - n22 * t9 + n42 * t7 ) * detInv; - te[ 9 ] = ( n21 * t9 - n11 * t11 - n41 * t7 ) * detInv; - te[ 10 ] = ( n14 * t5 - n24 * t3 + n44 * t1 ) * detInv; - te[ 11 ] = ( n23 * t3 - n13 * t5 - n43 * t1 ) * detInv; + if ( this._colorsTexture !== null ) { - te[ 12 ] = ( n22 * t8 - n12 * t10 - n32 * t7 ) * detInv; - te[ 13 ] = ( n11 * t10 - n21 * t8 + n31 * t7 ) * detInv; - te[ 14 ] = ( n24 * t2 - n14 * t4 - n34 * t1 ) * detInv; - te[ 15 ] = ( n13 * t4 - n23 * t2 + n33 * t1 ) * detInv; + object.colorsTexture = this._colorsTexture.toJSON( meta ); - return this; + } - } + if ( this.boundingSphere !== null ) { - /** - * Multiplies the columns of this matrix by the given vector. - * - * @param {Vector3} v - The scale vector. - * @return {Matrix4} A reference to this matrix. - */ - scale( v ) { + object.boundingSphere = this.boundingSphere.toJSON(); - const te = this.elements; - const x = v.x, y = v.y, z = v.z; + } - te[ 0 ] *= x; te[ 4 ] *= y; te[ 8 ] *= z; - te[ 1 ] *= x; te[ 5 ] *= y; te[ 9 ] *= z; - te[ 2 ] *= x; te[ 6 ] *= y; te[ 10 ] *= z; - te[ 3 ] *= x; te[ 7 ] *= y; te[ 11 ] *= z; + if ( this.boundingBox !== null ) { - return this; + object.boundingBox = this.boundingBox.toJSON(); - } + } - /** - * Gets the maximum scale value of the three axes. - * - * @return {number} The maximum scale. - */ - getMaxScaleOnAxis() { + } - const te = this.elements; + // - const scaleXSq = te[ 0 ] * te[ 0 ] + te[ 1 ] * te[ 1 ] + te[ 2 ] * te[ 2 ]; - const scaleYSq = te[ 4 ] * te[ 4 ] + te[ 5 ] * te[ 5 ] + te[ 6 ] * te[ 6 ]; - const scaleZSq = te[ 8 ] * te[ 8 ] + te[ 9 ] * te[ 9 ] + te[ 10 ] * te[ 10 ]; + function serialize( library, element ) { - return Math.sqrt( Math.max( scaleXSq, scaleYSq, scaleZSq ) ); + if ( library[ element.uuid ] === undefined ) { - } + library[ element.uuid ] = element.toJSON( meta ); - /** - * Sets this matrix as a translation transform from the given vector. - * - * @param {number|Vector3} x - The amount to translate in the X axis or alternatively a translation vector. - * @param {number} y - The amount to translate in the Y axis. - * @param {number} z - The amount to translate in the z axis. - * @return {Matrix4} A reference to this matrix. - */ - makeTranslation( x, y, z ) { + } - if ( x.isVector3 ) { + return element.uuid; - this.set( + } - 1, 0, 0, x.x, - 0, 1, 0, x.y, - 0, 0, 1, x.z, - 0, 0, 0, 1 + if ( this.isScene ) { - ); + if ( this.background ) { - } else { + if ( this.background.isColor ) { - this.set( + object.background = this.background.toJSON(); - 1, 0, 0, x, - 0, 1, 0, y, - 0, 0, 1, z, - 0, 0, 0, 1 + } else if ( this.background.isTexture ) { - ); + object.background = this.background.toJSON( meta ).uuid; - } + } - return this; + } - } + if ( this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true ) { - /** - * Sets this matrix as a rotational transformation around the X axis by - * the given angle. - * - * @param {number} theta - The rotation in radians. - * @return {Matrix4} A reference to this matrix. - */ - makeRotationX( theta ) { + object.environment = this.environment.toJSON( meta ).uuid; - const c = Math.cos( theta ), s = Math.sin( theta ); + } - this.set( + } else if ( this.isMesh || this.isLine || this.isPoints ) { - 1, 0, 0, 0, - 0, c, - s, 0, - 0, s, c, 0, - 0, 0, 0, 1 + object.geometry = serialize( meta.geometries, this.geometry ); - ); + const parameters = this.geometry.parameters; - return this; + if ( parameters !== undefined && parameters.shapes !== undefined ) { - } + const shapes = parameters.shapes; - /** - * Sets this matrix as a rotational transformation around the Y axis by - * the given angle. - * - * @param {number} theta - The rotation in radians. - * @return {Matrix4} A reference to this matrix. - */ - makeRotationY( theta ) { + if ( Array.isArray( shapes ) ) { - const c = Math.cos( theta ), s = Math.sin( theta ); + for ( let i = 0, l = shapes.length; i < l; i ++ ) { - this.set( + const shape = shapes[ i ]; - c, 0, s, 0, - 0, 1, 0, 0, - - s, 0, c, 0, - 0, 0, 0, 1 + serialize( meta.shapes, shape ); - ); + } - return this; + } else { - } + serialize( meta.shapes, shapes ); - /** - * Sets this matrix as a rotational transformation around the Z axis by - * the given angle. - * - * @param {number} theta - The rotation in radians. - * @return {Matrix4} A reference to this matrix. - */ - makeRotationZ( theta ) { + } - const c = Math.cos( theta ), s = Math.sin( theta ); + } - this.set( + } - c, - s, 0, 0, - s, c, 0, 0, - 0, 0, 1, 0, - 0, 0, 0, 1 + if ( this.isSkinnedMesh ) { - ); + object.bindMode = this.bindMode; + object.bindMatrix = this.bindMatrix.toArray(); - return this; + if ( this.skeleton !== undefined ) { - } + serialize( meta.skeletons, this.skeleton ); - /** - * Sets this matrix as a rotational transformation around the given axis by - * the given angle. - * - * This is a somewhat controversial but mathematically sound alternative to - * rotating via Quaternions. See the discussion [here](https://www.gamedev.net/articles/programming/math-and-physics/do-we-really-need-quaternions-r1199). - * - * @param {Vector3} axis - The normalized rotation axis. - * @param {number} angle - The rotation in radians. - * @return {Matrix4} A reference to this matrix. - */ - makeRotationAxis( axis, angle ) { + object.skeleton = this.skeleton.uuid; - // Based on http://www.gamedev.net/reference/articles/article1199.asp + } - const c = Math.cos( angle ); - const s = Math.sin( angle ); - const t = 1 - c; - const x = axis.x, y = axis.y, z = axis.z; - const tx = t * x, ty = t * y; + } - this.set( + if ( this.material !== undefined ) { - tx * x + c, tx * y - s * z, tx * z + s * y, 0, - tx * y + s * z, ty * y + c, ty * z - s * x, 0, - tx * z - s * y, ty * z + s * x, t * z * z + c, 0, - 0, 0, 0, 1 + if ( Array.isArray( this.material ) ) { - ); + const uuids = []; - return this; + for ( let i = 0, l = this.material.length; i < l; i ++ ) { - } + uuids.push( serialize( meta.materials, this.material[ i ] ) ); - /** - * Sets this matrix as a scale transformation. - * - * @param {number} x - The amount to scale in the X axis. - * @param {number} y - The amount to scale in the Y axis. - * @param {number} z - The amount to scale in the Z axis. - * @return {Matrix4} A reference to this matrix. - */ - makeScale( x, y, z ) { + } - this.set( + object.material = uuids; - x, 0, 0, 0, - 0, y, 0, 0, - 0, 0, z, 0, - 0, 0, 0, 1 + } else { - ); + object.material = serialize( meta.materials, this.material ); - return this; + } - } + } - /** - * Sets this matrix as a shear transformation. - * - * @param {number} xy - The amount to shear X by Y. - * @param {number} xz - The amount to shear X by Z. - * @param {number} yx - The amount to shear Y by X. - * @param {number} yz - The amount to shear Y by Z. - * @param {number} zx - The amount to shear Z by X. - * @param {number} zy - The amount to shear Z by Y. - * @return {Matrix4} A reference to this matrix. - */ - makeShear( xy, xz, yx, yz, zx, zy ) { + // - this.set( + if ( this.children.length > 0 ) { - 1, yx, zx, 0, - xy, 1, zy, 0, - xz, yz, 1, 0, - 0, 0, 0, 1 + object.children = []; - ); + for ( let i = 0; i < this.children.length; i ++ ) { - return this; + object.children.push( this.children[ i ].toJSON( meta ).object ); - } + } - /** - * Sets this matrix to the transformation composed of the given position, - * rotation (Quaternion) and scale. - * - * @param {Vector3} position - The position vector. - * @param {Quaternion} quaternion - The rotation as a Quaternion. - * @param {Vector3} scale - The scale vector. - * @return {Matrix4} A reference to this matrix. - */ - compose( position, quaternion, scale ) { + } - const te = this.elements; + // - const x = quaternion._x, y = quaternion._y, z = quaternion._z, w = quaternion._w; - const x2 = x + x, y2 = y + y, z2 = z + z; - const xx = x * x2, xy = x * y2, xz = x * z2; - const yy = y * y2, yz = y * z2, zz = z * z2; - const wx = w * x2, wy = w * y2, wz = w * z2; + if ( this.animations.length > 0 ) { - const sx = scale.x, sy = scale.y, sz = scale.z; + object.animations = []; - te[ 0 ] = ( 1 - ( yy + zz ) ) * sx; - te[ 1 ] = ( xy + wz ) * sx; - te[ 2 ] = ( xz - wy ) * sx; - te[ 3 ] = 0; + for ( let i = 0; i < this.animations.length; i ++ ) { - te[ 4 ] = ( xy - wz ) * sy; - te[ 5 ] = ( 1 - ( xx + zz ) ) * sy; - te[ 6 ] = ( yz + wx ) * sy; - te[ 7 ] = 0; + const animation = this.animations[ i ]; - te[ 8 ] = ( xz + wy ) * sz; - te[ 9 ] = ( yz - wx ) * sz; - te[ 10 ] = ( 1 - ( xx + yy ) ) * sz; - te[ 11 ] = 0; + object.animations.push( serialize( meta.animations, animation ) ); - te[ 12 ] = position.x; - te[ 13 ] = position.y; - te[ 14 ] = position.z; - te[ 15 ] = 1; + } - return this; + } - } + if ( isRootObject ) { - /** - * Decomposes this matrix into its position, rotation and scale components - * and provides the result in the given objects. - * - * Note: Not all matrices are decomposable in this way. For example, if an - * object has a non-uniformly scaled parent, then the object's world matrix - * may not be decomposable, and this method may not be appropriate. - * - * @param {Vector3} position - The position vector. - * @param {Quaternion} quaternion - The rotation as a Quaternion. - * @param {Vector3} scale - The scale vector. - * @return {Matrix4} A reference to this matrix. - */ - decompose( position, quaternion, scale ) { + const geometries = extractFromCache( meta.geometries ); + const materials = extractFromCache( meta.materials ); + const textures = extractFromCache( meta.textures ); + const images = extractFromCache( meta.images ); + const shapes = extractFromCache( meta.shapes ); + const skeletons = extractFromCache( meta.skeletons ); + const animations = extractFromCache( meta.animations ); + const nodes = extractFromCache( meta.nodes ); - const te = this.elements; + if ( geometries.length > 0 ) output.geometries = geometries; + if ( materials.length > 0 ) output.materials = materials; + if ( textures.length > 0 ) output.textures = textures; + if ( images.length > 0 ) output.images = images; + if ( shapes.length > 0 ) output.shapes = shapes; + if ( skeletons.length > 0 ) output.skeletons = skeletons; + if ( animations.length > 0 ) output.animations = animations; + if ( nodes.length > 0 ) output.nodes = nodes; - position.x = te[ 12 ]; - position.y = te[ 13 ]; - position.z = te[ 14 ]; + } - const det = this.determinant(); + output.object = object; - if ( det === 0 ) { + return output; - scale.set( 1, 1, 1 ); - quaternion.identity(); + // extract data from the cache hash + // remove metadata on each item + // and return as array + function extractFromCache( cache ) { - return this; + const values = []; + for ( const key in cache ) { - } + const data = cache[ key ]; + delete data.metadata; + values.push( data ); - let sx = _v1$5.set( te[ 0 ], te[ 1 ], te[ 2 ] ).length(); - const sy = _v1$5.set( te[ 4 ], te[ 5 ], te[ 6 ] ).length(); - const sz = _v1$5.set( te[ 8 ], te[ 9 ], te[ 10 ] ).length(); + } - // if determinant is negative, we need to invert one scale - if ( det < 0 ) sx = - sx; + return values; - // scale the rotation part - _m1$2.copy( this ); + } - const invSX = 1 / sx; - const invSY = 1 / sy; - const invSZ = 1 / sz; + } - _m1$2.elements[ 0 ] *= invSX; - _m1$2.elements[ 1 ] *= invSX; - _m1$2.elements[ 2 ] *= invSX; + /** + * Returns a new 3D object with copied values from this instance. + * + * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are also cloned. + * @return {Object3D} A clone of this instance. + */ + clone( recursive ) { - _m1$2.elements[ 4 ] *= invSY; - _m1$2.elements[ 5 ] *= invSY; - _m1$2.elements[ 6 ] *= invSY; + return new this.constructor().copy( this, recursive ); - _m1$2.elements[ 8 ] *= invSZ; - _m1$2.elements[ 9 ] *= invSZ; - _m1$2.elements[ 10 ] *= invSZ; + } - quaternion.setFromRotationMatrix( _m1$2 ); + /** + * Copies the values of the given 3D object to this instance. + * + * @param {Object3D} source - The 3D object to copy. + * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are cloned. + * @return {Object3D} A reference to this instance. + */ + copy( source, recursive = true ) { - scale.x = sx; - scale.y = sy; - scale.z = sz; + this.name = source.name; - return this; + this.up.copy( source.up ); - } + this.position.copy( source.position ); + this.rotation.order = source.rotation.order; + this.quaternion.copy( source.quaternion ); + this.scale.copy( source.scale ); - /** - * Creates a perspective projection matrix. This is used internally by - * {@link PerspectiveCamera#updateProjectionMatrix}. + if ( source.pivot !== null ) { - * @param {number} left - Left boundary of the viewing frustum at the near plane. - * @param {number} right - Right boundary of the viewing frustum at the near plane. - * @param {number} top - Top boundary of the viewing frustum at the near plane. - * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. - * @param {number} near - The distance from the camera to the near plane. - * @param {number} far - The distance from the camera to the far plane. - * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. - * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. - * @return {Matrix4} A reference to this matrix. - */ - makePerspective( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) { + this.pivot = source.pivot.clone(); - const te = this.elements; + } - const x = 2 * near / ( right - left ); - const y = 2 * near / ( top - bottom ); + this.matrix.copy( source.matrix ); + this.matrixWorld.copy( source.matrixWorld ); - const a = ( right + left ) / ( right - left ); - const b = ( top + bottom ) / ( top - bottom ); + this.matrixAutoUpdate = source.matrixAutoUpdate; - let c, d; + this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; + this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - if ( reversedDepth ) { + this.layers.mask = source.layers.mask; + this.visible = source.visible; - c = near / ( far - near ); - d = ( far * near ) / ( far - near ); + this.castShadow = source.castShadow; + this.receiveShadow = source.receiveShadow; - } else { + this.frustumCulled = source.frustumCulled; + this.renderOrder = source.renderOrder; - if ( coordinateSystem === WebGLCoordinateSystem ) { + this.static = source.static; - c = - ( far + near ) / ( far - near ); - d = ( -2 * far * near ) / ( far - near ); + this.animations = source.animations.slice(); - } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + this.userData = JSON.parse( JSON.stringify( source.userData ) ); - c = - far / ( far - near ); - d = ( - far * near ) / ( far - near ); + if ( recursive === true ) { - } else { + for ( let i = 0; i < source.children.length; i ++ ) { - throw new Error( 'THREE.Matrix4.makePerspective(): Invalid coordinate system: ' + coordinateSystem ); + const child = source.children[ i ]; + this.add( child.clone() ); } } - te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = a; te[ 12 ] = 0; - te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = b; te[ 13 ] = 0; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = -1; te[ 15 ] = 0; - return this; } - /** - * Creates a orthographic projection matrix. This is used internally by - * {@link OrthographicCamera#updateProjectionMatrix}. - - * @param {number} left - Left boundary of the viewing frustum at the near plane. - * @param {number} right - Right boundary of the viewing frustum at the near plane. - * @param {number} top - Top boundary of the viewing frustum at the near plane. - * @param {number} bottom - Bottom boundary of the viewing frustum at the near plane. - * @param {number} near - The distance from the camera to the near plane. - * @param {number} far - The distance from the camera to the far plane. - * @param {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} [coordinateSystem=WebGLCoordinateSystem] - The coordinate system. - * @param {boolean} [reversedDepth=false] - Whether to use a reversed depth. - * @return {Matrix4} A reference to this matrix. - */ - makeOrthographic( left, right, top, bottom, near, far, coordinateSystem = WebGLCoordinateSystem, reversedDepth = false ) { - - const te = this.elements; +} - const x = 2 / ( right - left ); - const y = 2 / ( top - bottom ); +/** + * The default up direction for objects, also used as the default + * position for {@link DirectionalLight} and {@link HemisphereLight}. + * + * @static + * @type {Vector3} + * @default (0,1,0) + */ +Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 ); - const a = - ( right + left ) / ( right - left ); - const b = - ( top + bottom ) / ( top - bottom ); +/** + * The default setting for {@link Object3D#matrixAutoUpdate} for + * newly created 3D objects. + * + * @static + * @type {boolean} + * @default true + */ +Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; - let c, d; +/** + * The default setting for {@link Object3D#matrixWorldAutoUpdate} for + * newly created 3D objects. + * + * @static + * @type {boolean} + * @default true + */ +Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; - if ( reversedDepth ) { +/** + * This is almost identical to an {@link Object3D}. Its purpose is to + * make working with groups of objects syntactically clearer. + * + * ```js + * // Create a group and add the two cubes. + * // These cubes can now be rotated / scaled etc as a group. + * const group = new THREE.Group(); + * + * group.add( meshA ); + * group.add( meshB ); + * + * scene.add( group ); + * ``` + * + * @augments Object3D + */ +class Group extends Object3D { - c = 1 / ( far - near ); - d = far / ( far - near ); + constructor() { - } else { + super(); - if ( coordinateSystem === WebGLCoordinateSystem ) { + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isGroup = true; - c = -2 / ( far - near ); - d = - ( far + near ) / ( far - near ); + this.type = 'Group'; - } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + } - c = -1 / ( far - near ); - d = - near / ( far - near ); +} - } else { +const _moveEvent = { type: 'move' }; - throw new Error( 'THREE.Matrix4.makeOrthographic(): Invalid coordinate system: ' + coordinateSystem ); +/** + * Class for representing a XR controller with its + * different coordinate systems. + * + * @private + */ +class WebXRController { - } + /** + * Constructs a new XR controller. + */ + constructor() { - } + /** + * A group representing the target ray space + * of the XR controller. + * + * @private + * @type {?Group} + * @default null + */ + this._targetRay = null; - te[ 0 ] = x; te[ 4 ] = 0; te[ 8 ] = 0; te[ 12 ] = a; - te[ 1 ] = 0; te[ 5 ] = y; te[ 9 ] = 0; te[ 13 ] = b; - te[ 2 ] = 0; te[ 6 ] = 0; te[ 10 ] = c; te[ 14 ] = d; - te[ 3 ] = 0; te[ 7 ] = 0; te[ 11 ] = 0; te[ 15 ] = 1; + /** + * A group representing the grip space + * of the XR controller. + * + * @private + * @type {?Group} + * @default null + */ + this._grip = null; - return this; + /** + * A group representing the hand space + * of the XR controller. + * + * @private + * @type {?Group} + * @default null + */ + this._hand = null; } /** - * Returns `true` if this matrix is equal with the given one. + * Returns a group representing the hand space of the XR controller. * - * @param {Matrix4} matrix - The matrix to test for equality. - * @return {boolean} Whether this matrix is equal with the given one. + * @return {Group} A group representing the hand space of the XR controller. */ - equals( matrix ) { + getHandSpace() { - const te = this.elements; - const me = matrix.elements; + if ( this._hand === null ) { - for ( let i = 0; i < 16; i ++ ) { + this._hand = new Group(); + this._hand.matrixAutoUpdate = false; + this._hand.visible = false; - if ( te[ i ] !== me[ i ] ) return false; + this._hand.joints = {}; + this._hand.inputState = { pinching: false }; } - return true; + return this._hand; } /** - * Sets the elements of the matrix from the given array. + * Returns a group representing the target ray space of the XR controller. * - * @param {Array} array - The matrix elements in column-major order. - * @param {number} [offset=0] - Index of the first element in the array. - * @return {Matrix4} A reference to this matrix. + * @return {Group} A group representing the target ray space of the XR controller. */ - fromArray( array, offset = 0 ) { + getTargetRaySpace() { - for ( let i = 0; i < 16; i ++ ) { + if ( this._targetRay === null ) { - this.elements[ i ] = array[ i + offset ]; + this._targetRay = new Group(); + this._targetRay.matrixAutoUpdate = false; + this._targetRay.visible = false; + this._targetRay.hasLinearVelocity = false; + this._targetRay.linearVelocity = new Vector3(); + this._targetRay.hasAngularVelocity = false; + this._targetRay.angularVelocity = new Vector3(); } - return this; + return this._targetRay; } /** - * Writes the elements of this matrix to the given array. If no array is provided, - * the method returns a new instance. + * Returns a group representing the grip space of the XR controller. * - * @param {Array} [array=[]] - The target array holding the matrix elements in column-major order. - * @param {number} [offset=0] - Index of the first element in the array. - * @return {Array} The matrix elements in column-major order. + * @return {Group} A group representing the grip space of the XR controller. */ - toArray( array = [], offset = 0 ) { - - const te = this.elements; - - array[ offset ] = te[ 0 ]; - array[ offset + 1 ] = te[ 1 ]; - array[ offset + 2 ] = te[ 2 ]; - array[ offset + 3 ] = te[ 3 ]; + getGripSpace() { - array[ offset + 4 ] = te[ 4 ]; - array[ offset + 5 ] = te[ 5 ]; - array[ offset + 6 ] = te[ 6 ]; - array[ offset + 7 ] = te[ 7 ]; + if ( this._grip === null ) { - array[ offset + 8 ] = te[ 8 ]; - array[ offset + 9 ] = te[ 9 ]; - array[ offset + 10 ] = te[ 10 ]; - array[ offset + 11 ] = te[ 11 ]; + this._grip = new Group(); + this._grip.matrixAutoUpdate = false; + this._grip.visible = false; + this._grip.hasLinearVelocity = false; + this._grip.linearVelocity = new Vector3(); + this._grip.hasAngularVelocity = false; + this._grip.angularVelocity = new Vector3(); - array[ offset + 12 ] = te[ 12 ]; - array[ offset + 13 ] = te[ 13 ]; - array[ offset + 14 ] = te[ 14 ]; - array[ offset + 15 ] = te[ 15 ]; + } - return array; + return this._grip; } -} - -const _v1$5 = /*@__PURE__*/ new Vector3(); -const _m1$2 = /*@__PURE__*/ new Matrix4(); -const _zero = /*@__PURE__*/ new Vector3( 0, 0, 0 ); -const _one = /*@__PURE__*/ new Vector3( 1, 1, 1 ); -const _x = /*@__PURE__*/ new Vector3(); -const _y = /*@__PURE__*/ new Vector3(); -const _z = /*@__PURE__*/ new Vector3(); - -const _matrix$2 = /*@__PURE__*/ new Matrix4(); -const _quaternion$4 = /*@__PURE__*/ new Quaternion(); - -/** - * A class representing Euler angles. - * - * Euler angles describe a rotational transformation by rotating an object on - * its various axes in specified amounts per axis, and a specified axis - * order. - * - * Iterating through an instance will yield its components (x, y, z, - * order) in the corresponding order. - * - * ```js - * const a = new THREE.Euler( 0, 1, 1.57, 'XYZ' ); - * const b = new THREE.Vector3( 1, 0, 1 ); - * b.applyEuler(a); - * ``` - */ -class Euler { - /** - * Constructs a new euler instance. + * Dispatches the given event to the groups representing + * the different coordinate spaces of the XR controller. * - * @param {number} [x=0] - The angle of the x axis in radians. - * @param {number} [y=0] - The angle of the y axis in radians. - * @param {number} [z=0] - The angle of the z axis in radians. - * @param {string} [order=Euler.DEFAULT_ORDER] - A string representing the order that the rotations are applied. + * @param {Object} event - The event to dispatch. + * @return {WebXRController} A reference to this instance. */ - constructor( x = 0, y = 0, z = 0, order = Euler.DEFAULT_ORDER ) { + dispatchEvent( event ) { - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isEuler = true; + if ( this._targetRay !== null ) { - this._x = x; - this._y = y; - this._z = z; - this._order = order; + this._targetRay.dispatchEvent( event ); - } + } - /** - * The angle of the x axis in radians. - * - * @type {number} - * @default 0 - */ - get x() { + if ( this._grip !== null ) { - return this._x; + this._grip.dispatchEvent( event ); - } + } - set x( value ) { + if ( this._hand !== null ) { - this._x = value; - this._onChangeCallback(); + this._hand.dispatchEvent( event ); + + } + + return this; } /** - * The angle of the y axis in radians. + * Connects the controller with the given XR input source. * - * @type {number} - * @default 0 + * @param {XRInputSource} inputSource - The input source. + * @return {WebXRController} A reference to this instance. */ - get y() { + connect( inputSource ) { - return this._y; + if ( inputSource && inputSource.hand ) { - } + const hand = this._hand; - set y( value ) { + if ( hand ) { - this._y = value; - this._onChangeCallback(); + for ( const inputjoint of inputSource.hand.values() ) { - } + // Initialize hand with joints when connected + this._getHandJoint( hand, inputjoint ); - /** - * The angle of the z axis in radians. - * - * @type {number} - * @default 0 - */ - get z() { + } - return this._z; + } - } + } - set z( value ) { + this.dispatchEvent( { type: 'connected', data: inputSource } ); - this._z = value; - this._onChangeCallback(); + return this; } /** - * A string representing the order that the rotations are applied. + * Disconnects the controller from the given XR input source. * - * @type {string} - * @default 'XYZ' + * @param {XRInputSource} inputSource - The input source. + * @return {WebXRController} A reference to this instance. */ - get order() { + disconnect( inputSource ) { - return this._order; + this.dispatchEvent( { type: 'disconnected', data: inputSource } ); - } + if ( this._targetRay !== null ) { - set order( value ) { + this._targetRay.visible = false; - this._order = value; - this._onChangeCallback(); + } - } + if ( this._grip !== null ) { - /** - * Sets the Euler components. - * - * @param {number} x - The angle of the x axis in radians. - * @param {number} y - The angle of the y axis in radians. - * @param {number} z - The angle of the z axis in radians. - * @param {string} [order] - A string representing the order that the rotations are applied. - * @return {Euler} A reference to this Euler instance. - */ - set( x, y, z, order = this._order ) { + this._grip.visible = false; - this._x = x; - this._y = y; - this._z = z; - this._order = order; + } - this._onChangeCallback(); + if ( this._hand !== null ) { + + this._hand.visible = false; + + } return this; } /** - * Returns a new Euler instance with copied values from this instance. + * Updates the controller with the given input source, XR frame and reference space. + * This updates the transformations of the groups that represent the different + * coordinate systems of the controller. * - * @return {Euler} A clone of this instance. + * @param {XRInputSource} inputSource - The input source. + * @param {XRFrame} frame - The XR frame. + * @param {XRReferenceSpace} referenceSpace - The reference space. + * @return {WebXRController} A reference to this instance. */ - clone() { + update( inputSource, frame, referenceSpace ) { - return new this.constructor( this._x, this._y, this._z, this._order ); + let inputPose = null; + let gripPose = null; + let handPose = null; - } + const targetRay = this._targetRay; + const grip = this._grip; + const hand = this._hand; - /** - * Copies the values of the given Euler instance to this instance. - * - * @param {Euler} euler - The Euler instance to copy. - * @return {Euler} A reference to this Euler instance. - */ - copy( euler ) { + if ( inputSource && frame.session.visibilityState !== 'visible-blurred' ) { - this._x = euler._x; - this._y = euler._y; - this._z = euler._z; - this._order = euler._order; + if ( hand && inputSource.hand ) { - this._onChangeCallback(); + handPose = true; - return this; + for ( const inputjoint of inputSource.hand.values() ) { - } + // Update the joints groups with the XRJoint poses + const jointPose = frame.getJointPose( inputjoint, referenceSpace ); - /** - * Sets the angles of this Euler instance from a pure rotation matrix. - * - * @param {Matrix4} m - A 4x4 matrix of which the upper 3x3 of matrix is a pure rotation matrix (i.e. unscaled). - * @param {string} [order] - A string representing the order that the rotations are applied. - * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. - * @return {Euler} A reference to this Euler instance. - */ - setFromRotationMatrix( m, order = this._order, update = true ) { + // The transform of this joint will be updated with the joint pose on each frame + const joint = this._getHandJoint( hand, inputjoint ); - const te = m.elements; - const m11 = te[ 0 ], m12 = te[ 4 ], m13 = te[ 8 ]; - const m21 = te[ 1 ], m22 = te[ 5 ], m23 = te[ 9 ]; - const m31 = te[ 2 ], m32 = te[ 6 ], m33 = te[ 10 ]; + if ( jointPose !== null ) { - switch ( order ) { + joint.matrix.fromArray( jointPose.transform.matrix ); + joint.matrix.decompose( joint.position, joint.rotation, joint.scale ); + joint.matrixWorldNeedsUpdate = true; + joint.jointRadius = jointPose.radius; - case 'XYZ': + } - this._y = Math.asin( clamp( m13, -1, 1 ) ); + joint.visible = jointPose !== null; - if ( Math.abs( m13 ) < 0.9999999 ) { + } - this._x = Math.atan2( - m23, m33 ); - this._z = Math.atan2( - m12, m11 ); + // Custom events - } else { + // Check pinchz + const indexTip = hand.joints[ 'index-finger-tip' ]; + const thumbTip = hand.joints[ 'thumb-tip' ]; + const distance = indexTip.position.distanceTo( thumbTip.position ); - this._x = Math.atan2( m32, m22 ); - this._z = 0; + const distanceToPinch = 0.02; + const threshold = 0.005; + + if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) { + + hand.inputState.pinching = false; + this.dispatchEvent( { + type: 'pinchend', + handedness: inputSource.handedness, + target: this + } ); + + } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) { + + hand.inputState.pinching = true; + this.dispatchEvent( { + type: 'pinchstart', + handedness: inputSource.handedness, + target: this + } ); } - break; + } else { - case 'YXZ': + if ( grip !== null && inputSource.gripSpace ) { - this._x = Math.asin( - clamp( m23, -1, 1 ) ); + gripPose = frame.getPose( inputSource.gripSpace, referenceSpace ); - if ( Math.abs( m23 ) < 0.9999999 ) { + if ( gripPose !== null ) { - this._y = Math.atan2( m13, m33 ); - this._z = Math.atan2( m21, m22 ); + grip.matrix.fromArray( gripPose.transform.matrix ); + grip.matrix.decompose( grip.position, grip.rotation, grip.scale ); + grip.matrixWorldNeedsUpdate = true; - } else { + if ( gripPose.linearVelocity ) { - this._y = Math.atan2( - m31, m11 ); - this._z = 0; + grip.hasLinearVelocity = true; + grip.linearVelocity.copy( gripPose.linearVelocity ); - } + } else { - break; + grip.hasLinearVelocity = false; - case 'ZXY': + } - this._x = Math.asin( clamp( m32, -1, 1 ) ); + if ( gripPose.angularVelocity ) { - if ( Math.abs( m32 ) < 0.9999999 ) { + grip.hasAngularVelocity = true; + grip.angularVelocity.copy( gripPose.angularVelocity ); - this._y = Math.atan2( - m31, m33 ); - this._z = Math.atan2( - m12, m22 ); + } else { - } else { + grip.hasAngularVelocity = false; - this._y = 0; - this._z = Math.atan2( m21, m11 ); + } + + } } - break; + } - case 'ZYX': + if ( targetRay !== null ) { - this._y = Math.asin( - clamp( m31, -1, 1 ) ); + inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); - if ( Math.abs( m31 ) < 0.9999999 ) { + // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it + if ( inputPose === null && gripPose !== null ) { - this._x = Math.atan2( m32, m33 ); - this._z = Math.atan2( m21, m11 ); + inputPose = gripPose; - } else { + } - this._x = 0; - this._z = Math.atan2( - m12, m22 ); + if ( inputPose !== null ) { - } + targetRay.matrix.fromArray( inputPose.transform.matrix ); + targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale ); + targetRay.matrixWorldNeedsUpdate = true; - break; + if ( inputPose.linearVelocity ) { - case 'YZX': + targetRay.hasLinearVelocity = true; + targetRay.linearVelocity.copy( inputPose.linearVelocity ); - this._z = Math.asin( clamp( m21, -1, 1 ) ); + } else { - if ( Math.abs( m21 ) < 0.9999999 ) { + targetRay.hasLinearVelocity = false; - this._x = Math.atan2( - m23, m22 ); - this._y = Math.atan2( - m31, m11 ); + } - } else { + if ( inputPose.angularVelocity ) { - this._x = 0; - this._y = Math.atan2( m13, m33 ); + targetRay.hasAngularVelocity = true; + targetRay.angularVelocity.copy( inputPose.angularVelocity ); - } + } else { - break; + targetRay.hasAngularVelocity = false; - case 'XZY': + } - this._z = Math.asin( - clamp( m12, -1, 1 ) ); + this.dispatchEvent( _moveEvent ); - if ( Math.abs( m12 ) < 0.9999999 ) { + } - this._x = Math.atan2( m32, m22 ); - this._y = Math.atan2( m13, m11 ); + } - } else { - this._x = Math.atan2( - m23, m33 ); - this._y = 0; + } - } + if ( targetRay !== null ) { - break; + targetRay.visible = ( inputPose !== null ); - default: + } - warn( 'Euler: .setFromRotationMatrix() encountered an unknown order: ' + order ); + if ( grip !== null ) { + + grip.visible = ( gripPose !== null ); } - this._order = order; + if ( hand !== null ) { - if ( update === true ) this._onChangeCallback(); + hand.visible = ( handPose !== null ); + + } return this; } /** - * Sets the angles of this Euler instance from a normalized quaternion. + * Returns a group representing the hand joint for the given input joint. * - * @param {Quaternion} q - A normalized Quaternion. - * @param {string} [order] - A string representing the order that the rotations are applied. - * @param {boolean} [update=true] - Whether the internal `onChange` callback should be executed or not. - * @return {Euler} A reference to this Euler instance. + * @private + * @param {Group} hand - The group representing the hand space. + * @param {XRJointSpace} inputjoint - The hand joint data. + * @return {Group} A group representing the hand joint for the given input joint. */ - setFromQuaternion( q, order, update ) { + _getHandJoint( hand, inputjoint ) { - _matrix$2.makeRotationFromQuaternion( q ); + if ( hand.joints[ inputjoint.jointName ] === undefined ) { - return this.setFromRotationMatrix( _matrix$2, order, update ); + const joint = new Group(); + joint.matrixAutoUpdate = false; + joint.visible = false; + hand.joints[ inputjoint.jointName ] = joint; - } + hand.add( joint ); - /** - * Sets the angles of this Euler instance from the given vector. - * - * @param {Vector3} v - The vector. - * @param {string} [order] - A string representing the order that the rotations are applied. - * @return {Euler} A reference to this Euler instance. - */ - setFromVector3( v, order = this._order ) { + } - return this.set( v.x, v.y, v.z, order ); + return hand.joints[ inputjoint.jointName ]; } - /** - * Resets the euler angle with a new order by creating a quaternion from this - * euler angle and then setting this euler angle with the quaternion and the - * new order. - * - * Warning: This discards revolution information. - * - * @param {string} [newOrder] - A string representing the new order that the rotations are applied. - * @return {Euler} A reference to this Euler instance. - */ - reorder( newOrder ) { +} - _quaternion$4.setFromEuler( this ); +const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, + 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, + 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, + 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, + 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, + 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, + 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, + 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, + 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, + 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, + 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, + 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, + 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, + 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, + 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, + 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, + 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, + 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, + 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, + 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, + 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, + 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, + 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, + 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; - return this.setFromQuaternion( _quaternion$4, newOrder ); +const _hslA = { h: 0, s: 0, l: 0 }; +const _hslB = { h: 0, s: 0, l: 0 }; - } +function hue2rgb( p, q, t ) { - /** - * Returns `true` if this Euler instance is equal with the given one. - * - * @param {Euler} euler - The Euler instance to test for equality. - * @return {boolean} Whether this Euler instance is equal with the given one. - */ - equals( euler ) { + if ( t < 0 ) t += 1; + if ( t > 1 ) t -= 1; + if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; + if ( t < 1 / 2 ) return q; + if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); + return p; - return ( euler._x === this._x ) && ( euler._y === this._y ) && ( euler._z === this._z ) && ( euler._order === this._order ); +} - } +/** + * A Color instance is represented by RGB components in the linear working + * color space, which defaults to `LinearSRGBColorSpace`. Inputs + * conventionally using `SRGBColorSpace` (such as hexadecimals and CSS + * strings) are converted to the working color space automatically. + * + * ```js + * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace + * const color = new THREE.Color().setHex( 0x112233 ); + * ``` + * Source color spaces may be specified explicitly, to ensure correct conversions. + * ```js + * // assumed already LinearSRGBColorSpace; no conversion + * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 ); + * + * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace + * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace ); + * ``` + * If THREE.ColorManagement is disabled, no conversions occur. For details, + * see Color management. Iterating through a Color instance will yield + * its components (r, g, b) in the corresponding order. A Color can be initialised + * in any of the following ways: + * ```js + * //empty constructor - will default white + * const color1 = new THREE.Color(); + * + * //Hexadecimal color (recommended) + * const color2 = new THREE.Color( 0xff0000 ); + * + * //RGB string + * const color3 = new THREE.Color("rgb(255, 0, 0)"); + * const color4 = new THREE.Color("rgb(100%, 0%, 0%)"); + * + * //X11 color name - all 140 color names are supported. + * //Note the lack of CamelCase in the name + * const color5 = new THREE.Color( 'skyblue' ); + * //HSL string + * const color6 = new THREE.Color("hsl(0, 100%, 50%)"); + * + * //Separate RGB values between 0 and 1 + * const color7 = new THREE.Color( 1, 0, 0 ); + * ``` + */ +class Color { /** - * Sets this Euler instance's components to values from the given array. The first three - * entries of the array are assign to the x,y and z components. An optional fourth entry - * defines the Euler order. + * Constructs a new color. * - * @param {Array} array - An array holding the Euler component values. - * @return {Euler} A reference to this Euler instance. + * Note that standard method of specifying color in three.js is with a hexadecimal triplet, + * and that method is used throughout the rest of the documentation. + * + * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are + * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. + * @param {number} [g] - The green component. + * @param {number} [b] - The blue component. */ - fromArray( array ) { + constructor( r, g, b ) { - this._x = array[ 0 ]; - this._y = array[ 1 ]; - this._z = array[ 2 ]; - if ( array[ 3 ] !== undefined ) this._order = array[ 3 ]; + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isColor = true; - this._onChangeCallback(); + /** + * The red component. + * + * @type {number} + * @default 1 + */ + this.r = 1; - return this; + /** + * The green component. + * + * @type {number} + * @default 1 + */ + this.g = 1; + + /** + * The blue component. + * + * @type {number} + * @default 1 + */ + this.b = 1; + + return this.set( r, g, b ); } /** - * Writes the components of this Euler instance to the given array. If no array is provided, - * the method returns a new instance. + * Sets the colors's components from the given values. * - * @param {Array} [array=[]] - The target array holding the Euler components. - * @param {number} [offset=0] - Index of the first element in the array. - * @return {Array} The Euler components. + * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are + * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. + * @param {number} [g] - The green component. + * @param {number} [b] - The blue component. + * @return {Color} A reference to this color. */ - toArray( array = [], offset = 0 ) { - - array[ offset ] = this._x; - array[ offset + 1 ] = this._y; - array[ offset + 2 ] = this._z; - array[ offset + 3 ] = this._order; - - return array; + set( r, g, b ) { - } + if ( g === undefined && b === undefined ) { - _onChange( callback ) { + // r is THREE.Color, hex or string - this._onChangeCallback = callback; + const value = r; - return this; + if ( value && value.isColor ) { - } + this.copy( value ); - _onChangeCallback() {} + } else if ( typeof value === 'number' ) { - *[ Symbol.iterator ]() { + this.setHex( value ); - yield this._x; - yield this._y; - yield this._z; - yield this._order; + } else if ( typeof value === 'string' ) { - } + this.setStyle( value ); -} + } -/** - * The default Euler angle order. - * - * @static - * @type {string} - * @default 'XYZ' - */ -Euler.DEFAULT_ORDER = 'XYZ'; + } else { -/** - * A layers object assigns an 3D object to 1 or more of 32 - * layers numbered `0` to `31` - internally the layers are stored as a - * bit mask], and by default all 3D objects are a member of layer `0`. - * - * This can be used to control visibility - an object must share a layer with - * a camera to be visible when that camera's view is - * rendered. - * - * All classes that inherit from {@link Object3D} have an `layers` property which - * is an instance of this class. - */ -class Layers { + this.setRGB( r, g, b ); - /** - * Constructs a new layers instance, with membership - * initially set to layer `0`. - */ - constructor() { + } - /** - * A bit mask storing which of the 32 layers this layers object is currently - * a member of. - * - * @type {number} - */ - this.mask = 1 | 0; + return this; } /** - * Sets membership to the given layer, and remove membership all other layers. + * Sets the colors's components to the given scalar value. * - * @param {number} layer - The layer to set. + * @param {number} scalar - The scalar value. + * @return {Color} A reference to this color. */ - set( layer ) { + setScalar( scalar ) { - this.mask = ( 1 << layer | 0 ) >>> 0; + this.r = scalar; + this.g = scalar; + this.b = scalar; + + return this; } /** - * Adds membership of the given layer. + * Sets this color from a hexadecimal value. * - * @param {number} layer - The layer to enable. + * @param {number} hex - The hexadecimal value. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {Color} A reference to this color. */ - enable( layer ) { + setHex( hex, colorSpace = SRGBColorSpace ) { - this.mask |= 1 << layer | 0; + hex = Math.floor( hex ); - } + this.r = ( hex >> 16 & 255 ) / 255; + this.g = ( hex >> 8 & 255 ) / 255; + this.b = ( hex & 255 ) / 255; - /** - * Adds membership to all layers. - */ - enableAll() { + ColorManagement.colorSpaceToWorking( this, colorSpace ); - this.mask = 0xffffffff | 0; + return this; } /** - * Toggles the membership of the given layer. + * Sets this color from RGB values. * - * @param {number} layer - The layer to toggle. + * @param {number} r - Red channel value between `0.0` and `1.0`. + * @param {number} g - Green channel value between `0.0` and `1.0`. + * @param {number} b - Blue channel value between `0.0` and `1.0`. + * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. + * @return {Color} A reference to this color. */ - toggle( layer ) { + setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) { - this.mask ^= 1 << layer | 0; + this.r = r; + this.g = g; + this.b = b; + + ColorManagement.colorSpaceToWorking( this, colorSpace ); + + return this; } /** - * Removes membership of the given layer. + * Sets this color from RGB values. * - * @param {number} layer - The layer to enable. + * @param {number} h - Hue value between `0.0` and `1.0`. + * @param {number} s - Saturation value between `0.0` and `1.0`. + * @param {number} l - Lightness value between `0.0` and `1.0`. + * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. + * @return {Color} A reference to this color. */ - disable( layer ) { + setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) { - this.mask &= ~ ( 1 << layer | 0 ); + // h,s,l ranges are in 0.0 - 1.0 + h = euclideanModulo( h, 1 ); + s = clamp( s, 0, 1 ); + l = clamp( l, 0, 1 ); - } + if ( s === 0 ) { - /** - * Removes the membership from all layers. - */ - disableAll() { + this.r = this.g = this.b = l; - this.mask = 0; + } else { - } + const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); + const q = ( 2 * l ) - p; - /** - * Returns `true` if this and the given layers object have at least one - * layer in common. - * - * @param {Layers} layers - The layers to test. - * @return {boolean } Whether this and the given layers object have at least one layer in common or not. - */ - test( layers ) { + this.r = hue2rgb( q, p, h + 1 / 3 ); + this.g = hue2rgb( q, p, h ); + this.b = hue2rgb( q, p, h - 1 / 3 ); - return ( this.mask & layers.mask ) !== 0; + } + + ColorManagement.colorSpaceToWorking( this, colorSpace ); + + return this; } /** - * Returns `true` if the given layer is enabled. + * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`, + * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or + * any [X11 color name](https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart) - + * all 140 color names are supported). * - * @param {number} layer - The layer to test. - * @return {boolean } Whether the given layer is enabled or not. + * @param {string} style - Color as a CSS-style string. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {Color} A reference to this color. */ - isEnabled( layer ) { + setStyle( style, colorSpace = SRGBColorSpace ) { - return ( this.mask & ( 1 << layer | 0 ) ) !== 0; + function handleAlpha( string ) { - } + if ( string === undefined ) return; -} + if ( parseFloat( string ) < 1 ) { -let _object3DId = 0; + warn( 'Color: Alpha component of ' + style + ' will be ignored.' ); -const _v1$4 = /*@__PURE__*/ new Vector3(); -const _q1 = /*@__PURE__*/ new Quaternion(); -const _m1$1 = /*@__PURE__*/ new Matrix4(); -const _target = /*@__PURE__*/ new Vector3(); + } -const _position$4 = /*@__PURE__*/ new Vector3(); -const _scale$3 = /*@__PURE__*/ new Vector3(); -const _quaternion$3 = /*@__PURE__*/ new Quaternion(); + } -const _xAxis = /*@__PURE__*/ new Vector3( 1, 0, 0 ); -const _yAxis = /*@__PURE__*/ new Vector3( 0, 1, 0 ); -const _zAxis = /*@__PURE__*/ new Vector3( 0, 0, 1 ); -/** - * Fires when the object has been added to its parent object. - * - * @event Object3D#added - * @type {Object} - */ -const _addedEvent = { type: 'added' }; + let m; -/** - * Fires when the object has been removed from its parent object. - * - * @event Object3D#removed - * @type {Object} - */ -const _removedEvent = { type: 'removed' }; + if ( m = /^(\w+)\(([^\)]*)\)/.exec( style ) ) { -/** - * Fires when a new child object has been added. - * - * @event Object3D#childadded - * @type {Object} - */ -const _childaddedEvent = { type: 'childadded', child: null }; + // rgb / hsl -/** - * Fires when a child object has been removed. - * - * @event Object3D#childremoved - * @type {Object} - */ -const _childremovedEvent = { type: 'childremoved', child: null }; + let color; + const name = m[ 1 ]; + const components = m[ 2 ]; -/** - * This is the base class for most objects in three.js and provides a set of - * properties and methods for manipulating objects in 3D space. - * - * @augments EventDispatcher - */ -class Object3D extends EventDispatcher { + switch ( name ) { - /** - * Constructs a new 3D object. - */ - constructor() { + case 'rgb': + case 'rgba': - super(); + if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isObject3D = true; + // rgb(255,0,0) rgba(255,0,0,0.5) - /** - * The ID of the 3D object. - * - * @name Object3D#id - * @type {number} - * @readonly - */ - Object.defineProperty( this, 'id', { value: _object3DId ++ } ); + handleAlpha( color[ 4 ] ); - /** - * The UUID of the 3D object. - * - * @type {string} - * @readonly - */ - this.uuid = generateUUID(); + return this.setRGB( + Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255, + Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255, + Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255, + colorSpace + ); - /** - * The name of the 3D object. - * - * @type {string} - */ - this.name = ''; + } - /** - * The type property is used for detecting the object type - * in context of serialization/deserialization. - * - * @type {string} - * @readonly - */ - this.type = 'Object3D'; + if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - /** - * A reference to the parent object. - * - * @type {?Object3D} - * @default null - */ - this.parent = null; + // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) - /** - * An array holding the child 3D objects of this instance. - * - * @type {Array} - */ - this.children = []; + handleAlpha( color[ 4 ] ); - /** - * Defines the `up` direction of the 3D object which influences - * the orientation via methods like {@link Object3D#lookAt}. - * - * The default values for all 3D objects is defined by `Object3D.DEFAULT_UP`. - * - * @type {Vector3} - */ - this.up = Object3D.DEFAULT_UP.clone(); + return this.setRGB( + Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100, + Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100, + Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100, + colorSpace + ); - const position = new Vector3(); - const rotation = new Euler(); - const quaternion = new Quaternion(); - const scale = new Vector3( 1, 1, 1 ); + } - function onRotationChange() { + break; - quaternion.setFromEuler( rotation, false ); + case 'hsl': + case 'hsla': - } + if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - function onQuaternionChange() { + // hsl(120,50%,50%) hsla(120,50%,50%,0.5) - rotation.setFromQuaternion( quaternion, undefined, false ); + handleAlpha( color[ 4 ] ); - } + return this.setHSL( + parseFloat( color[ 1 ] ) / 360, + parseFloat( color[ 2 ] ) / 100, + parseFloat( color[ 3 ] ) / 100, + colorSpace + ); - rotation._onChange( onRotationChange ); - quaternion._onChange( onQuaternionChange ); + } - Object.defineProperties( this, { - /** - * Represents the object's local position. - * - * @name Object3D#position - * @type {Vector3} - * @default (0,0,0) - */ - position: { - configurable: true, - enumerable: true, - value: position - }, - /** - * Represents the object's local rotation as Euler angles, in radians. - * - * @name Object3D#rotation - * @type {Euler} - * @default (0,0,0) - */ - rotation: { - configurable: true, - enumerable: true, - value: rotation - }, - /** - * Represents the object's local rotation as Quaternions. - * - * @name Object3D#quaternion - * @type {Quaternion} - */ - quaternion: { - configurable: true, - enumerable: true, - value: quaternion - }, - /** - * Represents the object's local scale. - * - * @name Object3D#scale - * @type {Vector3} - * @default (1,1,1) - */ - scale: { - configurable: true, - enumerable: true, - value: scale - }, - /** - * Represents the object's model-view matrix. - * - * @name Object3D#modelViewMatrix - * @type {Matrix4} - */ - modelViewMatrix: { - value: new Matrix4() - }, - /** - * Represents the object's normal matrix. - * - * @name Object3D#normalMatrix - * @type {Matrix3} - */ - normalMatrix: { - value: new Matrix3() - } - } ); + break; - /** - * Represents the object's transformation matrix in local space. - * - * @type {Matrix4} - */ - this.matrix = new Matrix4(); + default: - /** - * Represents the object's transformation matrix in world space. - * If the 3D object has no parent, then it's identical to the local transformation matrix - * - * @type {Matrix4} - */ - this.matrixWorld = new Matrix4(); + warn( 'Color: Unknown color model ' + style ); - /** - * When set to `true`, the engine automatically computes the local matrix from position, - * rotation and scale every frame. - * - * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_AUTO_UPDATE`. - * - * @type {boolean} - * @default true - */ - this.matrixAutoUpdate = Object3D.DEFAULT_MATRIX_AUTO_UPDATE; + } - /** - * When set to `true`, the engine automatically computes the world matrix from the current local - * matrix and the object's transformation hierarchy. - * - * The default values for all 3D objects is defined by `Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE`. - * - * @type {boolean} - * @default true - */ - this.matrixWorldAutoUpdate = Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE; // checked by the renderer + } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) { - /** - * When set to `true`, it calculates the world matrix in that frame and resets this property - * to `false`. - * - * @type {boolean} - * @default false - */ - this.matrixWorldNeedsUpdate = false; + // hex color - /** - * The layer membership of the 3D object. The 3D object is only visible if it has - * at least one layer in common with the camera in use. This property can also be - * used to filter out unwanted objects in ray-intersection tests when using {@link Raycaster}. - * - * @type {Layers} - */ - this.layers = new Layers(); + const hex = m[ 1 ]; + const size = hex.length; - /** - * When set to `true`, the 3D object gets rendered. - * - * @type {boolean} - * @default true - */ - this.visible = true; + if ( size === 3 ) { - /** - * When set to `true`, the 3D object gets rendered into shadow maps. - * - * @type {boolean} - * @default false - */ - this.castShadow = false; + // #ff0 + return this.setRGB( + parseInt( hex.charAt( 0 ), 16 ) / 15, + parseInt( hex.charAt( 1 ), 16 ) / 15, + parseInt( hex.charAt( 2 ), 16 ) / 15, + colorSpace + ); - /** - * When set to `true`, the 3D object is affected by shadows in the scene. - * - * @type {boolean} - * @default false - */ - this.receiveShadow = false; + } else if ( size === 6 ) { - /** - * When set to `true`, the 3D object is honored by view frustum culling. - * - * @type {boolean} - * @default true - */ - this.frustumCulled = true; + // #ff0000 + return this.setHex( parseInt( hex, 16 ), colorSpace ); - /** - * This value allows the default rendering order of scene graph objects to be - * overridden although opaque and transparent objects remain sorted independently. - * When this property is set for an instance of {@link Group},all descendants - * objects will be sorted and rendered together. Sorting is from lowest to highest - * render order. - * - * @type {number} - * @default 0 - */ - this.renderOrder = 0; + } else { - /** - * An array holding the animation clips of the 3D object. - * - * @type {Array} - */ - this.animations = []; + warn( 'Color: Invalid hex color ' + style ); - /** - * Custom depth material to be used when rendering to the depth map. Can only be used - * in context of meshes. When shadow-casting with a {@link DirectionalLight} or {@link SpotLight}, - * if you are modifying vertex positions in the vertex shader you must specify a custom depth - * material for proper shadows. - * - * Only relevant in context of {@link WebGLRenderer}. - * - * @type {(Material|undefined)} - * @default undefined - */ - this.customDepthMaterial = undefined; + } - /** - * Same as {@link Object3D#customDepthMaterial}, but used with {@link PointLight}. - * - * Only relevant in context of {@link WebGLRenderer}. - * - * @type {(Material|undefined)} - * @default undefined - */ - this.customDistanceMaterial = undefined; + } else if ( style && style.length > 0 ) { - /** - * Whether the 3D object is supposed to be static or not. If set to `true`, it means - * the 3D object is not going to be changed after the initial renderer. This includes - * geometry and material settings. A static 3D object can be processed by the renderer - * slightly faster since certain state checks can be bypassed. - * - * Only relevant in context of {@link WebGPURenderer}. - * - * @type {boolean} - * @default false - */ - this.static = false; + return this.setColorName( style, colorSpace ); - /** - * An object that can be used to store custom data about the 3D object. It - * should not hold references to functions as these will not be cloned. - * - * @type {Object} - */ - this.userData = {}; + } - /** - * The pivot point for rotation and scale transformations. - * When set, rotation and scale are applied around this point - * instead of the object's origin. - * - * @type {?Vector3} - * @default null - */ - this.pivot = null; + return this; } /** - * A callback that is executed immediately before a 3D object is rendered to a shadow map. + * Sets this color from a color name. Faster than {@link Color#setStyle} if + * you don't need the other CSS-style formats. * - * @param {Renderer|WebGLRenderer} renderer - The renderer. - * @param {Object3D} object - The 3D object. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {Camera} shadowCamera - The shadow camera. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Material} depthMaterial - The depth material. - * @param {Object} group - The geometry group data. - */ - onBeforeShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {} - - /** - * A callback that is executed immediately after a 3D object is rendered to a shadow map. + * For convenience, the list of names is exposed in `Color.NAMES` as a hash. + * ```js + * Color.NAMES.aliceblue // returns 0xF0F8FF + * ``` * - * @param {Renderer|WebGLRenderer} renderer - The renderer. - * @param {Object3D} object - The 3D object. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {Camera} shadowCamera - The shadow camera. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Material} depthMaterial - The depth material. - * @param {Object} group - The geometry group data. + * @param {string} style - The color name. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {Color} A reference to this color. */ - onAfterShadow( /* renderer, object, camera, shadowCamera, geometry, depthMaterial, group */ ) {} + setColorName( style, colorSpace = SRGBColorSpace ) { - /** - * A callback that is executed immediately before a 3D object is rendered. - * - * @param {Renderer|WebGLRenderer} renderer - The renderer. - * @param {Object3D} object - The 3D object. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Material} material - The 3D object's material. - * @param {Object} group - The geometry group data. - */ - onBeforeRender( /* renderer, scene, camera, geometry, material, group */ ) {} + // color keywords + const hex = _colorKeywords[ style.toLowerCase() ]; - /** - * A callback that is executed immediately after a 3D object is rendered. - * - * @param {Renderer|WebGLRenderer} renderer - The renderer. - * @param {Object3D} object - The 3D object. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Material} material - The 3D object's material. - * @param {Object} group - The geometry group data. - */ - onAfterRender( /* renderer, scene, camera, geometry, material, group */ ) {} + if ( hex !== undefined ) { - /** - * Applies the given transformation matrix to the object and updates the object's position, - * rotation and scale. - * - * @param {Matrix4} matrix - The transformation matrix. - */ - applyMatrix4( matrix ) { + // red + this.setHex( hex, colorSpace ); - if ( this.matrixAutoUpdate ) this.updateMatrix(); + } else { - this.matrix.premultiply( matrix ); + // unknown color + warn( 'Color: Unknown color ' + style ); - this.matrix.decompose( this.position, this.quaternion, this.scale ); + } + + return this; } /** - * Applies a rotation represented by given the quaternion to the 3D object. + * Returns a new color with copied values from this instance. * - * @param {Quaternion} q - The quaternion. - * @return {Object3D} A reference to this instance. + * @return {Color} A clone of this instance. */ - applyQuaternion( q ) { - - this.quaternion.premultiply( q ); + clone() { - return this; + return new this.constructor( this.r, this.g, this.b ); } /** - * Sets the given rotation represented as an axis/angle couple to the 3D object. + * Copies the values of the given color to this instance. * - * @param {Vector3} axis - The (normalized) axis vector. - * @param {number} angle - The angle in radians. + * @param {Color} color - The color to copy. + * @return {Color} A reference to this color. */ - setRotationFromAxisAngle( axis, angle ) { + copy( color ) { - // assumes axis is normalized + this.r = color.r; + this.g = color.g; + this.b = color.b; - this.quaternion.setFromAxisAngle( axis, angle ); + return this; } /** - * Sets the given rotation represented as Euler angles to the 3D object. + * Copies the given color into this color, and then converts this color from + * `SRGBColorSpace` to `LinearSRGBColorSpace`. * - * @param {Euler} euler - The Euler angles. + * @param {Color} color - The color to copy/convert. + * @return {Color} A reference to this color. */ - setRotationFromEuler( euler ) { + copySRGBToLinear( color ) { - this.quaternion.setFromEuler( euler, true ); + this.r = SRGBToLinear( color.r ); + this.g = SRGBToLinear( color.g ); + this.b = SRGBToLinear( color.b ); + + return this; } /** - * Sets the given rotation represented as rotation matrix to the 3D object. + * Copies the given color into this color, and then converts this color from + * `LinearSRGBColorSpace` to `SRGBColorSpace`. * - * @param {Matrix4} m - Although a 4x4 matrix is expected, the upper 3x3 portion must be - * a pure rotation matrix (i.e, unscaled). + * @param {Color} color - The color to copy/convert. + * @return {Color} A reference to this color. */ - setRotationFromMatrix( m ) { + copyLinearToSRGB( color ) { - // assumes the upper 3x3 of m is a pure rotation matrix (i.e, unscaled) + this.r = LinearToSRGB( color.r ); + this.g = LinearToSRGB( color.g ); + this.b = LinearToSRGB( color.b ); - this.quaternion.setFromRotationMatrix( m ); + return this; } /** - * Sets the given rotation represented as a Quaternion to the 3D object. + * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. * - * @param {Quaternion} q - The Quaternion + * @return {Color} A reference to this color. */ - setRotationFromQuaternion( q ) { + convertSRGBToLinear() { - // assumes q is normalized + this.copySRGBToLinear( this ); - this.quaternion.copy( q ); + return this; } /** - * Rotates the 3D object along an axis in local space. + * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. * - * @param {Vector3} axis - The (normalized) axis vector. - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. + * @return {Color} A reference to this color. */ - rotateOnAxis( axis, angle ) { - - // rotate object on axis in object space - // axis is assumed to be normalized - - _q1.setFromAxisAngle( axis, angle ); + convertLinearToSRGB() { - this.quaternion.multiply( _q1 ); + this.copyLinearToSRGB( this ); return this; } /** - * Rotates the 3D object along an axis in world space. + * Returns the hexadecimal value of this color. * - * @param {Vector3} axis - The (normalized) axis vector. - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {number} The hexadecimal value. */ - rotateOnWorldAxis( axis, angle ) { - - // rotate object on axis in world space - // axis is assumed to be normalized - // method assumes no rotated parent - - _q1.setFromAxisAngle( axis, angle ); + getHex( colorSpace = SRGBColorSpace ) { - this.quaternion.premultiply( _q1 ); + ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - return this; + return Math.round( clamp( _color.r * 255, 0, 255 ) ) * 65536 + Math.round( clamp( _color.g * 255, 0, 255 ) ) * 256 + Math.round( clamp( _color.b * 255, 0, 255 ) ); } /** - * Rotates the 3D object around its X axis in local space. + * Returns the hexadecimal value of this color as a string (for example, 'FFFFFF'). * - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {string} The hexadecimal value as a string. */ - rotateX( angle ) { + getHexString( colorSpace = SRGBColorSpace ) { - return this.rotateOnAxis( _xAxis, angle ); + return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( -6 ); } /** - * Rotates the 3D object around its Y axis in local space. + * Converts the colors RGB values into the HSL format and stores them into the + * given target object. * - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. + * @param {{h:number,s:number,l:number}} target - The target object that is used to store the method's result. + * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. + * @return {{h:number,s:number,l:number}} The HSL representation of this color. */ - rotateY( angle ) { + getHSL( target, colorSpace = ColorManagement.workingColorSpace ) { - return this.rotateOnAxis( _yAxis, angle ); + // h,s,l ranges are in 0.0 - 1.0 - } + ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); - /** - * Rotates the 3D object around its Z axis in local space. - * - * @param {number} angle - The angle in radians. - * @return {Object3D} A reference to this instance. - */ - rotateZ( angle ) { + const r = _color.r, g = _color.g, b = _color.b; - return this.rotateOnAxis( _zAxis, angle ); + const max = Math.max( r, g, b ); + const min = Math.min( r, g, b ); - } + let hue, saturation; + const lightness = ( min + max ) / 2.0; - /** - * Translate the 3D object by a distance along the given axis in local space. - * - * @param {Vector3} axis - The (normalized) axis vector. - * @param {number} distance - The distance in world units. - * @return {Object3D} A reference to this instance. - */ - translateOnAxis( axis, distance ) { + if ( min === max ) { - // translate object by distance along axis in object space - // axis is assumed to be normalized + hue = 0; + saturation = 0; - _v1$4.copy( axis ).applyQuaternion( this.quaternion ); + } else { - this.position.add( _v1$4.multiplyScalar( distance ) ); + const delta = max - min; - return this; + saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); - } + switch ( max ) { - /** - * Translate the 3D object by a distance along its X-axis in local space. - * - * @param {number} distance - The distance in world units. - * @return {Object3D} A reference to this instance. - */ - translateX( distance ) { + case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; + case g: hue = ( b - r ) / delta + 2; break; + case b: hue = ( r - g ) / delta + 4; break; - return this.translateOnAxis( _xAxis, distance ); + } + + hue /= 6; + + } + + target.h = hue; + target.s = saturation; + target.l = lightness; + + return target; } /** - * Translate the 3D object by a distance along its Y-axis in local space. + * Returns the RGB values of this color and stores them into the given target object. * - * @param {number} distance - The distance in world units. - * @return {Object3D} A reference to this instance. + * @param {Color} target - The target color that is used to store the method's result. + * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. + * @return {Color} The RGB representation of this color. */ - translateY( distance ) { + getRGB( target, colorSpace = ColorManagement.workingColorSpace ) { - return this.translateOnAxis( _yAxis, distance ); + ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); + + target.r = _color.r; + target.g = _color.g; + target.b = _color.b; + + return target; } /** - * Translate the 3D object by a distance along its Z-axis in local space. + * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`. * - * @param {number} distance - The distance in world units. - * @return {Object3D} A reference to this instance. + * @param {string} [colorSpace=SRGBColorSpace] - The color space. + * @return {string} The CSS representation of this color. */ - translateZ( distance ) { + getStyle( colorSpace = SRGBColorSpace ) { - return this.translateOnAxis( _zAxis, distance ); + ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); + + const r = _color.r, g = _color.g, b = _color.b; + + if ( colorSpace !== SRGBColorSpace ) { + + // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/). + return `color(${ colorSpace } ${ r.toFixed( 3 ) } ${ g.toFixed( 3 ) } ${ b.toFixed( 3 ) })`; + + } + + return `rgb(${ Math.round( r * 255 ) },${ Math.round( g * 255 ) },${ Math.round( b * 255 ) })`; } /** - * Converts the given vector from this 3D object's local space to world space. + * Adds the given HSL values to this color's values. + * Internally, this converts the color's RGB values to HSL, adds HSL + * and then converts the color back to RGB. * - * @param {Vector3} vector - The vector to convert. - * @return {Vector3} The converted vector. + * @param {number} h - Hue value between `0.0` and `1.0`. + * @param {number} s - Saturation value between `0.0` and `1.0`. + * @param {number} l - Lightness value between `0.0` and `1.0`. + * @return {Color} A reference to this color. */ - localToWorld( vector ) { + offsetHSL( h, s, l ) { - this.updateWorldMatrix( true, false ); + this.getHSL( _hslA ); - return vector.applyMatrix4( this.matrixWorld ); + return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l ); } /** - * Converts the given vector from this 3D object's world space to local space. + * Adds the RGB values of the given color to the RGB values of this color. * - * @param {Vector3} vector - The vector to convert. - * @return {Vector3} The converted vector. + * @param {Color} color - The color to add. + * @return {Color} A reference to this color. */ - worldToLocal( vector ) { + add( color ) { - this.updateWorldMatrix( true, false ); + this.r += color.r; + this.g += color.g; + this.b += color.b; - return vector.applyMatrix4( _m1$1.copy( this.matrixWorld ).invert() ); + return this; } /** - * Rotates the object to face a point in world space. - * - * This method does not support objects having non-uniformly-scaled parent(s). + * Adds the RGB values of the given colors and stores the result in this instance. * - * @param {number|Vector3} x - The x coordinate in world space. Alternatively, a vector representing a position in world space - * @param {number} [y] - The y coordinate in world space. - * @param {number} [z] - The z coordinate in world space. + * @param {Color} color1 - The first color. + * @param {Color} color2 - The second color. + * @return {Color} A reference to this color. */ - lookAt( x, y, z ) { + addColors( color1, color2 ) { - // This method does not support objects having non-uniformly-scaled parent(s) + this.r = color1.r + color2.r; + this.g = color1.g + color2.g; + this.b = color1.b + color2.b; - if ( x.isVector3 ) { + return this; - _target.copy( x ); + } - } else { + /** + * Adds the given scalar value to the RGB values of this color. + * + * @param {number} s - The scalar to add. + * @return {Color} A reference to this color. + */ + addScalar( s ) { - _target.set( x, y, z ); + this.r += s; + this.g += s; + this.b += s; - } + return this; - const parent = this.parent; + } - this.updateWorldMatrix( true, false ); + /** + * Subtracts the RGB values of the given color from the RGB values of this color. + * + * @param {Color} color - The color to subtract. + * @return {Color} A reference to this color. + */ + sub( color ) { - _position$4.setFromMatrixPosition( this.matrixWorld ); + this.r = Math.max( 0, this.r - color.r ); + this.g = Math.max( 0, this.g - color.g ); + this.b = Math.max( 0, this.b - color.b ); - if ( this.isCamera || this.isLight ) { + return this; - _m1$1.lookAt( _position$4, _target, this.up ); + } - } else { + /** + * Multiplies the RGB values of the given color with the RGB values of this color. + * + * @param {Color} color - The color to multiply. + * @return {Color} A reference to this color. + */ + multiply( color ) { - _m1$1.lookAt( _target, _position$4, this.up ); + this.r *= color.r; + this.g *= color.g; + this.b *= color.b; - } + return this; - this.quaternion.setFromRotationMatrix( _m1$1 ); + } - if ( parent ) { + /** + * Multiplies the given scalar value with the RGB values of this color. + * + * @param {number} s - The scalar to multiply. + * @return {Color} A reference to this color. + */ + multiplyScalar( s ) { - _m1$1.extractRotation( parent.matrixWorld ); - _q1.setFromRotationMatrix( _m1$1 ); - this.quaternion.premultiply( _q1.invert() ); + this.r *= s; + this.g *= s; + this.b *= s; - } + return this; } /** - * Adds the given 3D object as a child to this 3D object. An arbitrary number of - * objects may be added. Any current parent on an object passed in here will be - * removed, since an object can have at most one parent. + * Linearly interpolates this color's RGB values toward the RGB values of the + * given color. The alpha argument can be thought of as the ratio between + * the two colors, where `0.0` is this color and `1.0` is the first argument. * - * @fires Object3D#added - * @fires Object3D#childadded - * @param {Object3D} object - The 3D object to add. - * @return {Object3D} A reference to this instance. + * @param {Color} color - The color to converge on. + * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. + * @return {Color} A reference to this color. */ - add( object ) { - - if ( arguments.length > 1 ) { + lerp( color, alpha ) { - for ( let i = 0; i < arguments.length; i ++ ) { + this.r += ( color.r - this.r ) * alpha; + this.g += ( color.g - this.g ) * alpha; + this.b += ( color.b - this.b ) * alpha; - this.add( arguments[ i ] ); + return this; - } + } - return this; + /** + * Linearly interpolates between the given colors and stores the result in this instance. + * The alpha argument can be thought of as the ratio between the two colors, where `0.0` + * is the first and `1.0` is the second color. + * + * @param {Color} color1 - The first color. + * @param {Color} color2 - The second color. + * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. + * @return {Color} A reference to this color. + */ + lerpColors( color1, color2, alpha ) { - } + this.r = color1.r + ( color2.r - color1.r ) * alpha; + this.g = color1.g + ( color2.g - color1.g ) * alpha; + this.b = color1.b + ( color2.b - color1.b ) * alpha; - if ( object === this ) { + return this; - error( 'Object3D.add: object can\'t be added as a child of itself.', object ); - return this; + } - } + /** + * Linearly interpolates this color's HSL values toward the HSL values of the + * given color. It differs from {@link Color#lerp} by not interpolating straight + * from one color to the other, but instead going through all the hues in between + * those two colors. The alpha argument can be thought of as the ratio between + * the two colors, where 0.0 is this color and 1.0 is the first argument. + * + * @param {Color} color - The color to converge on. + * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. + * @return {Color} A reference to this color. + */ + lerpHSL( color, alpha ) { - if ( object && object.isObject3D ) { + this.getHSL( _hslA ); + color.getHSL( _hslB ); - object.removeFromParent(); - object.parent = this; - this.children.push( object ); + const h = lerp( _hslA.h, _hslB.h, alpha ); + const s = lerp( _hslA.s, _hslB.s, alpha ); + const l = lerp( _hslA.l, _hslB.l, alpha ); - object.dispatchEvent( _addedEvent ); + this.setHSL( h, s, l ); - _childaddedEvent.child = object; - this.dispatchEvent( _childaddedEvent ); - _childaddedEvent.child = null; + return this; - } else { + } - error( 'Object3D.add: object not an instance of THREE.Object3D.', object ); + /** + * Sets the color's RGB components from the given 3D vector. + * + * @param {Vector3} v - The vector to set. + * @return {Color} A reference to this color. + */ + setFromVector3( v ) { - } + this.r = v.x; + this.g = v.y; + this.b = v.z; return this; } /** - * Removes the given 3D object as child from this 3D object. - * An arbitrary number of objects may be removed. + * Transforms this color with the given 3x3 matrix. * - * @fires Object3D#removed - * @fires Object3D#childremoved - * @param {Object3D} object - The 3D object to remove. - * @return {Object3D} A reference to this instance. + * @param {Matrix3} m - The matrix. + * @return {Color} A reference to this color. */ - remove( object ) { - - if ( arguments.length > 1 ) { - - for ( let i = 0; i < arguments.length; i ++ ) { - - this.remove( arguments[ i ] ); + applyMatrix3( m ) { - } + const r = this.r, g = this.g, b = this.b; + const e = m.elements; - return this; + this.r = e[ 0 ] * r + e[ 3 ] * g + e[ 6 ] * b; + this.g = e[ 1 ] * r + e[ 4 ] * g + e[ 7 ] * b; + this.b = e[ 2 ] * r + e[ 5 ] * g + e[ 8 ] * b; - } + return this; - const index = this.children.indexOf( object ); + } - if ( index !== -1 ) { + /** + * Returns `true` if this color is equal with the given one. + * + * @param {Color} c - The color to test for equality. + * @return {boolean} Whether this bounding color is equal with the given one. + */ + equals( c ) { - object.parent = null; - this.children.splice( index, 1 ); + return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); - object.dispatchEvent( _removedEvent ); + } - _childremovedEvent.child = object; - this.dispatchEvent( _childremovedEvent ); - _childremovedEvent.child = null; + /** + * Sets this color's RGB components from the given array. + * + * @param {Array} array - An array holding the RGB values. + * @param {number} [offset=0] - The offset into the array. + * @return {Color} A reference to this color. + */ + fromArray( array, offset = 0 ) { - } + this.r = array[ offset ]; + this.g = array[ offset + 1 ]; + this.b = array[ offset + 2 ]; return this; } /** - * Removes this 3D object from its current parent. + * Writes the RGB components of this color to the given array. If no array is provided, + * the method returns a new instance. * - * @fires Object3D#removed - * @fires Object3D#childremoved - * @return {Object3D} A reference to this instance. + * @param {Array} [array=[]] - The target array holding the color components. + * @param {number} [offset=0] - Index of the first element in the array. + * @return {Array} The color components. */ - removeFromParent() { + toArray( array = [], offset = 0 ) { - const parent = this.parent; + array[ offset ] = this.r; + array[ offset + 1 ] = this.g; + array[ offset + 2 ] = this.b; - if ( parent !== null ) { + return array; - parent.remove( this ); + } - } + /** + * Sets the components of this color from the given buffer attribute. + * + * @param {BufferAttribute} attribute - The buffer attribute holding color data. + * @param {number} index - The index into the attribute. + * @return {Color} A reference to this color. + */ + fromBufferAttribute( attribute, index ) { + + this.r = attribute.getX( index ); + this.g = attribute.getY( index ); + this.b = attribute.getZ( index ); return this; } /** - * Removes all child objects. + * This methods defines the serialization result of this class. Returns the color + * as a hexadecimal value. * - * @fires Object3D#removed - * @fires Object3D#childremoved - * @return {Object3D} A reference to this instance. + * @return {number} The hexadecimal value. */ - clear() { + toJSON() { - return this.remove( ... this.children ); + return this.getHex(); } - /** - * Adds the given 3D object as a child of this 3D object, while maintaining the object's world - * transform. This method does not support scene graphs having non-uniformly-scaled nodes(s). - * - * @fires Object3D#added - * @fires Object3D#childadded - * @param {Object3D} object - The 3D object to attach. - * @return {Object3D} A reference to this instance. - */ - attach( object ) { - - // adds object as a child of this, while maintaining the object's world transform - - // Note: This method does not support scene graphs having non-uniformly-scaled nodes(s) - - this.updateWorldMatrix( true, false ); + *[ Symbol.iterator ]() { - _m1$1.copy( this.matrixWorld ).invert(); + yield this.r; + yield this.g; + yield this.b; - if ( object.parent !== null ) { + } - object.parent.updateWorldMatrix( true, false ); +} - _m1$1.multiply( object.parent.matrixWorld ); +const _color = /*@__PURE__*/ new Color(); - } +/** + * A dictionary with X11 color names. + * + * Note that multiple words such as Dark Orange become the string 'darkorange'. + * + * @static + * @type {Object} + */ +Color.NAMES = _colorKeywords; - object.applyMatrix4( _m1$1 ); +/** + * This class can be used to define an exponential squared fog, + * which gives a clear view near the camera and a faster than exponentially + * densening fog farther from the camera. + * + * ```js + * const scene = new THREE.Scene(); + * scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 ); + * ``` + */ +class FogExp2 { - object.removeFromParent(); - object.parent = this; - this.children.push( object ); + /** + * Constructs a new fog. + * + * @param {number|Color} color - The fog's color. + * @param {number} [density=0.00025] - Defines how fast the fog will grow dense. + */ + constructor( color, density = 0.00025 ) { - object.updateWorldMatrix( false, true ); + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isFogExp2 = true; - object.dispatchEvent( _addedEvent ); + /** + * The name of the fog. + * + * @type {string} + */ + this.name = ''; - _childaddedEvent.child = object; - this.dispatchEvent( _childaddedEvent ); - _childaddedEvent.child = null; + /** + * The fog's color. + * + * @type {Color} + */ + this.color = new Color( color ); - return this; + /** + * Defines how fast the fog will grow dense. + * + * @type {number} + * @default 0.00025 + */ + this.density = density; } /** - * Searches through the 3D object and its children, starting with the 3D object - * itself, and returns the first with a matching ID. + * Returns a new fog with copied values from this instance. * - * @param {number} id - The id. - * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. + * @return {FogExp2} A clone of this instance. */ - getObjectById( id ) { + clone() { - return this.getObjectByProperty( 'id', id ); + return new FogExp2( this.color, this.density ); } /** - * Searches through the 3D object and its children, starting with the 3D object - * itself, and returns the first with a matching name. + * Serializes the fog into JSON. * - * @param {string} name - The name. - * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. + * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized fog */ - getObjectByName( name ) { + toJSON( /* meta */ ) { - return this.getObjectByProperty( 'name', name ); + return { + type: 'FogExp2', + name: this.name, + color: this.color.getHex(), + density: this.density + }; } +} + +/** + * This class can be used to define a linear fog that grows linearly denser + * with the distance. + * + * ```js + * const scene = new THREE.Scene(); + * scene.fog = new THREE.Fog( 0xcccccc, 10, 15 ); + * ``` + */ +class Fog { + /** - * Searches through the 3D object and its children, starting with the 3D object - * itself, and returns the first with a matching property value. + * Constructs a new fog. * - * @param {string} name - The name of the property. - * @param {any} value - The value. - * @return {Object3D|undefined} The found 3D object. Returns `undefined` if no 3D object has been found. + * @param {number|Color} color - The fog's color. + * @param {number} [near=1] - The minimum distance to start applying fog. + * @param {number} [far=1000] - The maximum distance at which fog stops being calculated and applied. */ - getObjectByProperty( name, value ) { + constructor( color, near = 1, far = 1000 ) { - if ( this[ name ] === value ) return this; + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isFog = true; - for ( let i = 0, l = this.children.length; i < l; i ++ ) { + /** + * The name of the fog. + * + * @type {string} + */ + this.name = ''; - const child = this.children[ i ]; - const object = child.getObjectByProperty( name, value ); + /** + * The fog's color. + * + * @type {Color} + */ + this.color = new Color( color ); - if ( object !== undefined ) { + /** + * The minimum distance to start applying fog. Objects that are less than + * `near` units from the active camera won't be affected by fog. + * + * @type {number} + * @default 1 + */ + this.near = near; - return object; + /** + * The maximum distance at which fog stops being calculated and applied. + * Objects that are more than `far` units away from the active camera won't + * be affected by fog. + * + * @type {number} + * @default 1000 + */ + this.far = far; - } + } - } + /** + * Returns a new fog with copied values from this instance. + * + * @return {Fog} A clone of this instance. + */ + clone() { - return undefined; + return new Fog( this.color, this.near, this.far ); } /** - * Searches through the 3D object and its children, starting with the 3D object - * itself, and returns all 3D objects with a matching property value. + * Serializes the fog into JSON. * - * @param {string} name - The name of the property. - * @param {any} value - The value. - * @param {Array} result - The method stores the result in this array. - * @return {Array} The found 3D objects. + * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized fog */ - getObjectsByProperty( name, value, result = [] ) { + toJSON( /* meta */ ) { - if ( this[ name ] === value ) result.push( this ); + return { + type: 'Fog', + name: this.name, + color: this.color.getHex(), + near: this.near, + far: this.far + }; - const children = this.children; + } - for ( let i = 0, l = children.length; i < l; i ++ ) { +} - children[ i ].getObjectsByProperty( name, value, result ); +/** + * Scenes allow you to set up what is to be rendered and where by three.js. + * This is where you place 3D objects like meshes, lines or lights. + * + * @augments Object3D + */ +class Scene extends Object3D { - } + /** + * Constructs a new scene. + */ + constructor() { - return result; + super(); - } + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isScene = true; - /** - * Returns a vector representing the position of the 3D object in world space. - * - * @param {Vector3} target - The target vector the result is stored to. - * @return {Vector3} The 3D object's position in world space. - */ - getWorldPosition( target ) { + this.type = 'Scene'; - this.updateWorldMatrix( true, false ); + /** + * Defines the background of the scene. Valid inputs are: + * + * - A color for defining a uniform colored background. + * - A texture for defining a (flat) textured background. + * - Cube textures or equirectangular textures for defining a skybox. + * + * @type {?(Color|Texture)} + * @default null + */ + this.background = null; - return target.setFromMatrixPosition( this.matrixWorld ); + /** + * Sets the environment map for all physical materials in the scene. However, + * it's not possible to overwrite an existing texture assigned to the `envMap` + * material property. + * + * @type {?Texture} + * @default null + */ + this.environment = null; - } + /** + * A fog instance defining the type of fog that affects everything + * rendered in the scene. + * + * @type {?(Fog|FogExp2)} + * @default null + */ + this.fog = null; - /** - * Returns a Quaternion representing the position of the 3D object in world space. - * - * @param {Quaternion} target - The target Quaternion the result is stored to. - * @return {Quaternion} The 3D object's rotation in world space. - */ - getWorldQuaternion( target ) { + /** + * Sets the blurriness of the background. Only influences environment maps + * assigned to {@link Scene#background}. Valid input is a float between `0` + * and `1`. + * + * @type {number} + * @default 0 + */ + this.backgroundBlurriness = 0; - this.updateWorldMatrix( true, false ); + /** + * Attenuates the color of the background. Only applies to background textures. + * + * @type {number} + * @default 1 + */ + this.backgroundIntensity = 1; - this.matrixWorld.decompose( _position$4, target, _scale$3 ); + /** + * The rotation of the background in radians. Only influences environment maps + * assigned to {@link Scene#background}. + * + * @type {Euler} + * @default (0,0,0) + */ + this.backgroundRotation = new Euler(); - return target; + /** + * Attenuates the color of the environment. Only influences environment maps + * assigned to {@link Scene#environment}. + * + * @type {number} + * @default 1 + */ + this.environmentIntensity = 1; - } + /** + * The rotation of the environment map in radians. Only influences physical materials + * in the scene when {@link Scene#environment} is used. + * + * @type {Euler} + * @default (0,0,0) + */ + this.environmentRotation = new Euler(); - /** - * Returns a vector representing the scale of the 3D object in world space. - * - * @param {Vector3} target - The target vector the result is stored to. - * @return {Vector3} The 3D object's scale in world space. - */ - getWorldScale( target ) { + /** + * Forces everything in the scene to be rendered with the defined material. It is possible + * to exclude materials from override by setting {@link Material#allowOverride} to `false`. + * + * @type {?Material} + * @default null + */ + this.overrideMaterial = null; - this.updateWorldMatrix( true, false ); + if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { - this.matrixWorld.decompose( _position$4, _quaternion$3, target ); + __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); - return target; + } } - /** - * Returns a vector representing the ("look") direction of the 3D object in world space. - * - * @param {Vector3} target - The target vector the result is stored to. - * @return {Vector3} The 3D object's direction in world space. - */ - getWorldDirection( target ) { + copy( source, recursive ) { - this.updateWorldMatrix( true, false ); + super.copy( source, recursive ); - const e = this.matrixWorld.elements; + if ( source.background !== null ) this.background = source.background.clone(); + if ( source.environment !== null ) this.environment = source.environment.clone(); + if ( source.fog !== null ) this.fog = source.fog.clone(); - return target.set( e[ 8 ], e[ 9 ], e[ 10 ] ).normalize(); + this.backgroundBlurriness = source.backgroundBlurriness; + this.backgroundIntensity = source.backgroundIntensity; + this.backgroundRotation.copy( source.backgroundRotation ); - } + this.environmentIntensity = source.environmentIntensity; + this.environmentRotation.copy( source.environmentRotation ); - /** - * Abstract method to get intersections between a casted ray and this - * 3D object. Renderable 3D objects such as {@link Mesh}, {@link Line} or {@link Points} - * implement this method in order to use raycasting. - * - * @abstract - * @param {Raycaster} raycaster - The raycaster. - * @param {Array} intersects - An array holding the result of the method. - */ - raycast( /* raycaster, intersects */ ) {} + if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); - /** - * Executes the callback on this 3D object and all descendants. - * - * Note: Modifying the scene graph inside the callback is discouraged. - * - * @param {Function} callback - A callback function that allows to process the current 3D object. - */ - traverse( callback ) { + this.matrixAutoUpdate = source.matrixAutoUpdate; - callback( this ); + return this; - const children = this.children; + } - for ( let i = 0, l = children.length; i < l; i ++ ) { + toJSON( meta ) { - children[ i ].traverse( callback ); + const data = super.toJSON( meta ); - } + if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); - } + if ( this.backgroundBlurriness > 0 ) data.object.backgroundBlurriness = this.backgroundBlurriness; + if ( this.backgroundIntensity !== 1 ) data.object.backgroundIntensity = this.backgroundIntensity; + data.object.backgroundRotation = this.backgroundRotation.toArray(); - /** - * Like {@link Object3D#traverse}, but the callback will only be executed for visible 3D objects. - * Descendants of invisible 3D objects are not traversed. - * - * Note: Modifying the scene graph inside the callback is discouraged. - * - * @param {Function} callback - A callback function that allows to process the current 3D object. - */ - traverseVisible( callback ) { + if ( this.environmentIntensity !== 1 ) data.object.environmentIntensity = this.environmentIntensity; + data.object.environmentRotation = this.environmentRotation.toArray(); - if ( this.visible === false ) return; + return data; - callback( this ); + } - const children = this.children; +} - for ( let i = 0, l = children.length; i < l; i ++ ) { +const _v0$2 = /*@__PURE__*/ new Vector3(); +const _v1$5 = /*@__PURE__*/ new Vector3(); +const _v2$4 = /*@__PURE__*/ new Vector3(); +const _v3$2 = /*@__PURE__*/ new Vector3(); - children[ i ].traverseVisible( callback ); +const _vab = /*@__PURE__*/ new Vector3(); +const _vac = /*@__PURE__*/ new Vector3(); +const _vbc = /*@__PURE__*/ new Vector3(); +const _vap = /*@__PURE__*/ new Vector3(); +const _vbp = /*@__PURE__*/ new Vector3(); +const _vcp = /*@__PURE__*/ new Vector3(); - } +const _v40 = /*@__PURE__*/ new Vector4(); +const _v41 = /*@__PURE__*/ new Vector4(); +const _v42 = /*@__PURE__*/ new Vector4(); - } +/** + * A geometric triangle as defined by three vectors representing its three corners. + */ +class Triangle { /** - * Like {@link Object3D#traverse}, but the callback will only be executed for all ancestors. - * - * Note: Modifying the scene graph inside the callback is discouraged. + * Constructs a new triangle. * - * @param {Function} callback - A callback function that allows to process the current 3D object. + * @param {Vector3} [a=(0,0,0)] - The first corner of the triangle. + * @param {Vector3} [b=(0,0,0)] - The second corner of the triangle. + * @param {Vector3} [c=(0,0,0)] - The third corner of the triangle. */ - traverseAncestors( callback ) { - - const parent = this.parent; - - if ( parent !== null ) { + constructor( a = new Vector3(), b = new Vector3(), c = new Vector3() ) { - callback( parent ); + /** + * The first corner of the triangle. + * + * @type {Vector3} + */ + this.a = a; - parent.traverseAncestors( callback ); + /** + * The second corner of the triangle. + * + * @type {Vector3} + */ + this.b = b; - } + /** + * The third corner of the triangle. + * + * @type {Vector3} + */ + this.c = c; } /** - * Updates the transformation matrix in local space by computing it from the current - * position, rotation and scale values. + * Computes the normal vector of a triangle. + * + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The triangle's normal. */ - updateMatrix() { - - this.matrix.compose( this.position, this.quaternion, this.scale ); - - const pivot = this.pivot; + static getNormal( a, b, c, target ) { - if ( pivot !== null ) { + target.subVectors( c, b ); + _v0$2.subVectors( a, b ); + target.cross( _v0$2 ); - const px = pivot.x, py = pivot.y, pz = pivot.z; - const te = this.matrix.elements; + const targetLengthSq = target.lengthSq(); + if ( targetLengthSq > 0 ) { - te[ 12 ] += px - te[ 0 ] * px - te[ 4 ] * py - te[ 8 ] * pz; - te[ 13 ] += py - te[ 1 ] * px - te[ 5 ] * py - te[ 9 ] * pz; - te[ 14 ] += pz - te[ 2 ] * px - te[ 6 ] * py - te[ 10 ] * pz; + return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); } - this.matrixWorldNeedsUpdate = true; + return target.set( 0, 0, 0 ); } /** - * Updates the transformation matrix in world space of this 3D objects and its descendants. + * Computes a barycentric coordinates from the given vector. + * Returns `null` if the triangle is degenerate. * - * To ensure correct results, this method also recomputes the 3D object's transformation matrix in - * local space. The computation of the local and world matrix can be controlled with the - * {@link Object3D#matrixAutoUpdate} and {@link Object3D#matrixWorldAutoUpdate} flags which are both - * `true` by default. Set these flags to `false` if you need more control over the update matrix process. - * - * @param {boolean} [force=false] - When set to `true`, a recomputation of world matrices is forced even - * when {@link Object3D#matrixWorldAutoUpdate} is set to `false`. + * @param {Vector3} point - A point in 3D space. + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The barycentric coordinates for the given point */ - updateMatrixWorld( force ) { - - if ( this.matrixAutoUpdate ) this.updateMatrix(); - - if ( this.matrixWorldNeedsUpdate || force ) { - - if ( this.matrixWorldAutoUpdate === true ) { - - if ( this.parent === null ) { - - this.matrixWorld.copy( this.matrix ); + static getBarycoord( point, a, b, c, target ) { - } else { + // based on: http://www.blackpawn.com/texts/pointinpoly/default.html - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); + _v0$2.subVectors( c, a ); + _v1$5.subVectors( b, a ); + _v2$4.subVectors( point, a ); - } + const dot00 = _v0$2.dot( _v0$2 ); + const dot01 = _v0$2.dot( _v1$5 ); + const dot02 = _v0$2.dot( _v2$4 ); + const dot11 = _v1$5.dot( _v1$5 ); + const dot12 = _v1$5.dot( _v2$4 ); - } + const denom = ( dot00 * dot11 - dot01 * dot01 ); - this.matrixWorldNeedsUpdate = false; + // collinear or singular triangle + if ( denom === 0 ) { - force = true; + target.set( 0, 0, 0 ); + return null; } - // make sure descendants are updated if required - - const children = this.children; - - for ( let i = 0, l = children.length; i < l; i ++ ) { - - const child = children[ i ]; - - child.updateMatrixWorld( force ); + const invDenom = 1 / denom; + const u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; + const v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; - } + // barycentric coordinates must always sum to 1 + return target.set( 1 - u - v, v, u ); } /** - * An alternative version of {@link Object3D#updateMatrixWorld} with more control over the - * update of ancestor and descendant nodes. + * Returns `true` if the given point, when projected onto the plane of the + * triangle, lies within the triangle. * - * @param {boolean} [updateParents=false] Whether ancestor nodes should be updated or not. - * @param {boolean} [updateChildren=false] Whether descendant nodes should be updated or not. + * @param {Vector3} point - The point in 3D space to test. + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @return {boolean} Whether the given point, when projected onto the plane of the + * triangle, lies within the triangle or not. */ - updateWorldMatrix( updateParents, updateChildren ) { - - const parent = this.parent; + static containsPoint( point, a, b, c ) { - if ( updateParents === true && parent !== null ) { + // if the triangle is degenerate then we can't contain a point + if ( this.getBarycoord( point, a, b, c, _v3$2 ) === null ) { - parent.updateWorldMatrix( true, false ); + return false; } - if ( this.matrixAutoUpdate ) this.updateMatrix(); - - if ( this.matrixWorldAutoUpdate === true ) { - - if ( this.parent === null ) { + return ( _v3$2.x >= 0 ) && ( _v3$2.y >= 0 ) && ( ( _v3$2.x + _v3$2.y ) <= 1 ); - this.matrixWorld.copy( this.matrix ); + } - } else { + /** + * Computes the value barycentrically interpolated for the given point on the + * triangle. Returns `null` if the triangle is degenerate. + * + * @param {Vector3} point - Position of interpolated point. + * @param {Vector3} p1 - The first corner of the triangle. + * @param {Vector3} p2 - The second corner of the triangle. + * @param {Vector3} p3 - The third corner of the triangle. + * @param {Vector3} v1 - Value to interpolate of first vertex. + * @param {Vector3} v2 - Value to interpolate of second vertex. + * @param {Vector3} v3 - Value to interpolate of third vertex. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The interpolated value. + */ + static getInterpolation( point, p1, p2, p3, v1, v2, v3, target ) { - this.matrixWorld.multiplyMatrices( this.parent.matrixWorld, this.matrix ); + if ( this.getBarycoord( point, p1, p2, p3, _v3$2 ) === null ) { - } + target.x = 0; + target.y = 0; + if ( 'z' in target ) target.z = 0; + if ( 'w' in target ) target.w = 0; + return null; } - // make sure descendants are updated + target.setScalar( 0 ); + target.addScaledVector( v1, _v3$2.x ); + target.addScaledVector( v2, _v3$2.y ); + target.addScaledVector( v3, _v3$2.z ); - if ( updateChildren === true ) { + return target; - const children = this.children; + } - for ( let i = 0, l = children.length; i < l; i ++ ) { + /** + * Computes the value barycentrically interpolated for the given attribute and indices. + * + * @param {BufferAttribute} attr - The attribute to interpolate. + * @param {number} i1 - Index of first vertex. + * @param {number} i2 - Index of second vertex. + * @param {number} i3 - Index of third vertex. + * @param {Vector3} barycoord - The barycoordinate value to use to interpolate. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The interpolated attribute value. + */ + static getInterpolatedAttribute( attr, i1, i2, i3, barycoord, target ) { - const child = children[ i ]; + _v40.setScalar( 0 ); + _v41.setScalar( 0 ); + _v42.setScalar( 0 ); - child.updateWorldMatrix( false, true ); + _v40.fromBufferAttribute( attr, i1 ); + _v41.fromBufferAttribute( attr, i2 ); + _v42.fromBufferAttribute( attr, i3 ); - } + target.setScalar( 0 ); + target.addScaledVector( _v40, barycoord.x ); + target.addScaledVector( _v41, barycoord.y ); + target.addScaledVector( _v42, barycoord.z ); - } + return target; } /** - * Serializes the 3D object into JSON. + * Returns `true` if the triangle is oriented towards the given direction. * - * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized 3D object. - * @see {@link ObjectLoader#parse} + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @param {Vector3} direction - The (normalized) direction vector. + * @return {boolean} Whether the triangle is oriented towards the given direction or not. */ - toJSON( meta ) { + static isFrontFacing( a, b, c, direction ) { - // meta is a string when called from JSON.stringify - const isRootObject = ( meta === undefined || typeof meta === 'string' ); + _v0$2.subVectors( c, b ); + _v1$5.subVectors( a, b ); - const output = {}; + // strictly front facing + return ( _v0$2.cross( _v1$5 ).dot( direction ) < 0 ) ? true : false; - // meta is a hash used to collect geometries, materials. - // not providing it implies that this is the root object - // being serialized. - if ( isRootObject ) { + } - // initialize meta obj - meta = { - geometries: {}, - materials: {}, - textures: {}, - images: {}, - shapes: {}, - skeletons: {}, - animations: {}, - nodes: {} - }; + /** + * Sets the triangle's vertices by copying the given values. + * + * @param {Vector3} a - The first corner of the triangle. + * @param {Vector3} b - The second corner of the triangle. + * @param {Vector3} c - The third corner of the triangle. + * @return {Triangle} A reference to this triangle. + */ + set( a, b, c ) { - output.metadata = { - version: 4.7, - type: 'Object', - generator: 'Object3D.toJSON' - }; + this.a.copy( a ); + this.b.copy( b ); + this.c.copy( c ); - } + return this; - // standard Object3D serialization + } - const object = {}; + /** + * Sets the triangle's vertices by copying the given array values. + * + * @param {Array} points - An array with 3D points. + * @param {number} i0 - The array index representing the first corner of the triangle. + * @param {number} i1 - The array index representing the second corner of the triangle. + * @param {number} i2 - The array index representing the third corner of the triangle. + * @return {Triangle} A reference to this triangle. + */ + setFromPointsAndIndices( points, i0, i1, i2 ) { - object.uuid = this.uuid; - object.type = this.type; + this.a.copy( points[ i0 ] ); + this.b.copy( points[ i1 ] ); + this.c.copy( points[ i2 ] ); - if ( this.name !== '' ) object.name = this.name; - if ( this.castShadow === true ) object.castShadow = true; - if ( this.receiveShadow === true ) object.receiveShadow = true; - if ( this.visible === false ) object.visible = false; - if ( this.frustumCulled === false ) object.frustumCulled = false; - if ( this.renderOrder !== 0 ) object.renderOrder = this.renderOrder; - if ( this.static !== false ) object.static = this.static; - if ( Object.keys( this.userData ).length > 0 ) object.userData = this.userData; + return this; - object.layers = this.layers.mask; - object.matrix = this.matrix.toArray(); - object.up = this.up.toArray(); + } - if ( this.pivot !== null ) object.pivot = this.pivot.toArray(); + /** + * Sets the triangle's vertices by copying the given attribute values. + * + * @param {BufferAttribute} attribute - A buffer attribute with 3D points data. + * @param {number} i0 - The attribute index representing the first corner of the triangle. + * @param {number} i1 - The attribute index representing the second corner of the triangle. + * @param {number} i2 - The attribute index representing the third corner of the triangle. + * @return {Triangle} A reference to this triangle. + */ + setFromAttributeAndIndices( attribute, i0, i1, i2 ) { - if ( this.matrixAutoUpdate === false ) object.matrixAutoUpdate = false; + this.a.fromBufferAttribute( attribute, i0 ); + this.b.fromBufferAttribute( attribute, i1 ); + this.c.fromBufferAttribute( attribute, i2 ); - if ( this.morphTargetDictionary !== undefined ) object.morphTargetDictionary = Object.assign( {}, this.morphTargetDictionary ); - if ( this.morphTargetInfluences !== undefined ) object.morphTargetInfluences = this.morphTargetInfluences.slice(); + return this; - // object specific properties + } - if ( this.isInstancedMesh ) { + /** + * Returns a new triangle with copied values from this instance. + * + * @return {Triangle} A clone of this instance. + */ + clone() { - object.type = 'InstancedMesh'; - object.count = this.count; - object.instanceMatrix = this.instanceMatrix.toJSON(); - if ( this.instanceColor !== null ) object.instanceColor = this.instanceColor.toJSON(); + return new this.constructor().copy( this ); - } + } - if ( this.isBatchedMesh ) { + /** + * Copies the values of the given triangle to this instance. + * + * @param {Triangle} triangle - The triangle to copy. + * @return {Triangle} A reference to this triangle. + */ + copy( triangle ) { - object.type = 'BatchedMesh'; - object.perObjectFrustumCulled = this.perObjectFrustumCulled; - object.sortObjects = this.sortObjects; + this.a.copy( triangle.a ); + this.b.copy( triangle.b ); + this.c.copy( triangle.c ); - object.drawRanges = this._drawRanges; - object.reservedRanges = this._reservedRanges; + return this; - object.geometryInfo = this._geometryInfo.map( info => ( { - ...info, - boundingBox: info.boundingBox ? info.boundingBox.toJSON() : undefined, - boundingSphere: info.boundingSphere ? info.boundingSphere.toJSON() : undefined - } ) ); - object.instanceInfo = this._instanceInfo.map( info => ( { ...info } ) ); + } - object.availableInstanceIds = this._availableInstanceIds.slice(); - object.availableGeometryIds = this._availableGeometryIds.slice(); + /** + * Computes the area of the triangle. + * + * @return {number} The triangle's area. + */ + getArea() { - object.nextIndexStart = this._nextIndexStart; - object.nextVertexStart = this._nextVertexStart; - object.geometryCount = this._geometryCount; + _v0$2.subVectors( this.c, this.b ); + _v1$5.subVectors( this.a, this.b ); - object.maxInstanceCount = this._maxInstanceCount; - object.maxVertexCount = this._maxVertexCount; - object.maxIndexCount = this._maxIndexCount; + return _v0$2.cross( _v1$5 ).length() * 0.5; - object.geometryInitialized = this._geometryInitialized; + } - object.matricesTexture = this._matricesTexture.toJSON( meta ); + /** + * Computes the midpoint of the triangle. + * + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The triangle's midpoint. + */ + getMidpoint( target ) { - object.indirectTexture = this._indirectTexture.toJSON( meta ); + return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); - if ( this._colorsTexture !== null ) { + } - object.colorsTexture = this._colorsTexture.toJSON( meta ); + /** + * Computes the normal of the triangle. + * + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The triangle's normal. + */ + getNormal( target ) { - } + return Triangle.getNormal( this.a, this.b, this.c, target ); - if ( this.boundingSphere !== null ) { + } - object.boundingSphere = this.boundingSphere.toJSON(); + /** + * Computes a plane the triangle lies within. + * + * @param {Plane} target - The target vector that is used to store the method's result. + * @return {Plane} The plane the triangle lies within. + */ + getPlane( target ) { - } + return target.setFromCoplanarPoints( this.a, this.b, this.c ); - if ( this.boundingBox !== null ) { + } - object.boundingBox = this.boundingBox.toJSON(); + /** + * Computes a barycentric coordinates from the given vector. + * Returns `null` if the triangle is degenerate. + * + * @param {Vector3} point - A point in 3D space. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The barycentric coordinates for the given point + */ + getBarycoord( point, target ) { - } + return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); - } + } - // + /** + * Computes the value barycentrically interpolated for the given point on the + * triangle. Returns `null` if the triangle is degenerate. + * + * @param {Vector3} point - Position of interpolated point. + * @param {Vector3} v1 - Value to interpolate of first vertex. + * @param {Vector3} v2 - Value to interpolate of second vertex. + * @param {Vector3} v3 - Value to interpolate of third vertex. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The interpolated value. + */ + getInterpolation( point, v1, v2, v3, target ) { - function serialize( library, element ) { + return Triangle.getInterpolation( point, this.a, this.b, this.c, v1, v2, v3, target ); - if ( library[ element.uuid ] === undefined ) { + } - library[ element.uuid ] = element.toJSON( meta ); + /** + * Returns `true` if the given point, when projected onto the plane of the + * triangle, lies within the triangle. + * + * @param {Vector3} point - The point in 3D space to test. + * @return {boolean} Whether the given point, when projected onto the plane of the + * triangle, lies within the triangle or not. + */ + containsPoint( point ) { - } + return Triangle.containsPoint( point, this.a, this.b, this.c ); - return element.uuid; + } - } + /** + * Returns `true` if the triangle is oriented towards the given direction. + * + * @param {Vector3} direction - The (normalized) direction vector. + * @return {boolean} Whether the triangle is oriented towards the given direction or not. + */ + isFrontFacing( direction ) { - if ( this.isScene ) { + return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); - if ( this.background ) { + } - if ( this.background.isColor ) { + /** + * Returns `true` if this triangle intersects with the given box. + * + * @param {Box3} box - The box to intersect. + * @return {boolean} Whether this triangle intersects with the given box or not. + */ + intersectsBox( box ) { - object.background = this.background.toJSON(); + return box.intersectsTriangle( this ); - } else if ( this.background.isTexture ) { + } - object.background = this.background.toJSON( meta ).uuid; + /** + * Returns the closest point on the triangle to the given point. + * + * @param {Vector3} p - The point to compute the closest point for. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The closest point on the triangle. + */ + closestPointToPoint( p, target ) { - } + const a = this.a, b = this.b, c = this.c; + let v, w; - } + // algorithm thanks to Real-Time Collision Detection by Christer Ericson, + // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., + // under the accompanying license; see chapter 5.1.5 for detailed explanation. + // basically, we're distinguishing which of the voronoi regions of the triangle + // the point lies in with the minimum amount of redundant computation. - if ( this.environment && this.environment.isTexture && this.environment.isRenderTargetTexture !== true ) { + _vab.subVectors( b, a ); + _vac.subVectors( c, a ); + _vap.subVectors( p, a ); + const d1 = _vab.dot( _vap ); + const d2 = _vac.dot( _vap ); + if ( d1 <= 0 && d2 <= 0 ) { - object.environment = this.environment.toJSON( meta ).uuid; + // vertex region of A; barycentric coords (1, 0, 0) + return target.copy( a ); - } + } - } else if ( this.isMesh || this.isLine || this.isPoints ) { + _vbp.subVectors( p, b ); + const d3 = _vab.dot( _vbp ); + const d4 = _vac.dot( _vbp ); + if ( d3 >= 0 && d4 <= d3 ) { - object.geometry = serialize( meta.geometries, this.geometry ); + // vertex region of B; barycentric coords (0, 1, 0) + return target.copy( b ); - const parameters = this.geometry.parameters; + } - if ( parameters !== undefined && parameters.shapes !== undefined ) { + const vc = d1 * d4 - d3 * d2; + if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { - const shapes = parameters.shapes; + v = d1 / ( d1 - d3 ); + // edge region of AB; barycentric coords (1-v, v, 0) + return target.copy( a ).addScaledVector( _vab, v ); - if ( Array.isArray( shapes ) ) { + } - for ( let i = 0, l = shapes.length; i < l; i ++ ) { + _vcp.subVectors( p, c ); + const d5 = _vab.dot( _vcp ); + const d6 = _vac.dot( _vcp ); + if ( d6 >= 0 && d5 <= d6 ) { - const shape = shapes[ i ]; + // vertex region of C; barycentric coords (0, 0, 1) + return target.copy( c ); - serialize( meta.shapes, shape ); + } - } + const vb = d5 * d2 - d1 * d6; + if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { - } else { + w = d2 / ( d2 - d6 ); + // edge region of AC; barycentric coords (1-w, 0, w) + return target.copy( a ).addScaledVector( _vac, w ); - serialize( meta.shapes, shapes ); + } - } + const va = d3 * d6 - d5 * d4; + if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { - } + _vbc.subVectors( c, b ); + w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); + // edge region of BC; barycentric coords (0, 1-w, w) + return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC } - if ( this.isSkinnedMesh ) { - - object.bindMode = this.bindMode; - object.bindMatrix = this.bindMatrix.toArray(); - - if ( this.skeleton !== undefined ) { + // face region + const denom = 1 / ( va + vb + vc ); + // u = va * denom + v = vb * denom; + w = vc * denom; - serialize( meta.skeletons, this.skeleton ); + return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w ); - object.skeleton = this.skeleton.uuid; + } - } + /** + * Returns `true` if this triangle is equal with the given one. + * + * @param {Triangle} triangle - The triangle to test for equality. + * @return {boolean} Whether this triangle is equal with the given one. + */ + equals( triangle ) { - } + return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); - if ( this.material !== undefined ) { + } - if ( Array.isArray( this.material ) ) { +} - const uuids = []; - - for ( let i = 0, l = this.material.length; i < l; i ++ ) { - - uuids.push( serialize( meta.materials, this.material[ i ] ) ); - - } - - object.material = uuids; - - } else { - - object.material = serialize( meta.materials, this.material ); - - } - - } - - // - - if ( this.children.length > 0 ) { - - object.children = []; - - for ( let i = 0; i < this.children.length; i ++ ) { - - object.children.push( this.children[ i ].toJSON( meta ).object ); - - } - - } - - // - - if ( this.animations.length > 0 ) { - - object.animations = []; - - for ( let i = 0; i < this.animations.length; i ++ ) { - - const animation = this.animations[ i ]; - - object.animations.push( serialize( meta.animations, animation ) ); - - } - - } - - if ( isRootObject ) { - - const geometries = extractFromCache( meta.geometries ); - const materials = extractFromCache( meta.materials ); - const textures = extractFromCache( meta.textures ); - const images = extractFromCache( meta.images ); - const shapes = extractFromCache( meta.shapes ); - const skeletons = extractFromCache( meta.skeletons ); - const animations = extractFromCache( meta.animations ); - const nodes = extractFromCache( meta.nodes ); - - if ( geometries.length > 0 ) output.geometries = geometries; - if ( materials.length > 0 ) output.materials = materials; - if ( textures.length > 0 ) output.textures = textures; - if ( images.length > 0 ) output.images = images; - if ( shapes.length > 0 ) output.shapes = shapes; - if ( skeletons.length > 0 ) output.skeletons = skeletons; - if ( animations.length > 0 ) output.animations = animations; - if ( nodes.length > 0 ) output.nodes = nodes; - - } - - output.object = object; - - return output; - - // extract data from the cache hash - // remove metadata on each item - // and return as array - function extractFromCache( cache ) { - - const values = []; - for ( const key in cache ) { - - const data = cache[ key ]; - delete data.metadata; - values.push( data ); - - } - - return values; - - } - - } - - /** - * Returns a new 3D object with copied values from this instance. - * - * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are also cloned. - * @return {Object3D} A clone of this instance. - */ - clone( recursive ) { - - return new this.constructor().copy( this, recursive ); - - } - - /** - * Copies the values of the given 3D object to this instance. - * - * @param {Object3D} source - The 3D object to copy. - * @param {boolean} [recursive=true] - When set to `true`, descendants of the 3D object are cloned. - * @return {Object3D} A reference to this instance. - */ - copy( source, recursive = true ) { - - this.name = source.name; - - this.up.copy( source.up ); - - this.position.copy( source.position ); - this.rotation.order = source.rotation.order; - this.quaternion.copy( source.quaternion ); - this.scale.copy( source.scale ); - - if ( source.pivot !== null ) { - - this.pivot = source.pivot.clone(); - - } - - this.matrix.copy( source.matrix ); - this.matrixWorld.copy( source.matrixWorld ); - - this.matrixAutoUpdate = source.matrixAutoUpdate; - - this.matrixWorldAutoUpdate = source.matrixWorldAutoUpdate; - this.matrixWorldNeedsUpdate = source.matrixWorldNeedsUpdate; - - this.layers.mask = source.layers.mask; - this.visible = source.visible; - - this.castShadow = source.castShadow; - this.receiveShadow = source.receiveShadow; - - this.frustumCulled = source.frustumCulled; - this.renderOrder = source.renderOrder; - - this.static = source.static; - - this.animations = source.animations.slice(); - - this.userData = JSON.parse( JSON.stringify( source.userData ) ); - - if ( recursive === true ) { - - for ( let i = 0; i < source.children.length; i ++ ) { - - const child = source.children[ i ]; - this.add( child.clone() ); - - } - - } - - return this; - - } - -} - -/** - * The default up direction for objects, also used as the default - * position for {@link DirectionalLight} and {@link HemisphereLight}. - * - * @static - * @type {Vector3} - * @default (0,1,0) - */ -Object3D.DEFAULT_UP = /*@__PURE__*/ new Vector3( 0, 1, 0 ); - -/** - * The default setting for {@link Object3D#matrixAutoUpdate} for - * newly created 3D objects. - * - * @static - * @type {boolean} - * @default true - */ -Object3D.DEFAULT_MATRIX_AUTO_UPDATE = true; - -/** - * The default setting for {@link Object3D#matrixWorldAutoUpdate} for - * newly created 3D objects. - * - * @static - * @type {boolean} - * @default true - */ -Object3D.DEFAULT_MATRIX_WORLD_AUTO_UPDATE = true; - -const _v0$1 = /*@__PURE__*/ new Vector3(); -const _v1$3 = /*@__PURE__*/ new Vector3(); -const _v2$2 = /*@__PURE__*/ new Vector3(); -const _v3$2 = /*@__PURE__*/ new Vector3(); - -const _vab = /*@__PURE__*/ new Vector3(); -const _vac = /*@__PURE__*/ new Vector3(); -const _vbc = /*@__PURE__*/ new Vector3(); -const _vap = /*@__PURE__*/ new Vector3(); -const _vbp = /*@__PURE__*/ new Vector3(); -const _vcp = /*@__PURE__*/ new Vector3(); - -const _v40 = /*@__PURE__*/ new Vector4(); -const _v41 = /*@__PURE__*/ new Vector4(); -const _v42 = /*@__PURE__*/ new Vector4(); - -/** - * A geometric triangle as defined by three vectors representing its three corners. - */ -class Triangle { +/** + * Represents an axis-aligned bounding box (AABB) in 3D space. + */ +class Box3 { /** - * Constructs a new triangle. + * Constructs a new bounding box. * - * @param {Vector3} [a=(0,0,0)] - The first corner of the triangle. - * @param {Vector3} [b=(0,0,0)] - The second corner of the triangle. - * @param {Vector3} [c=(0,0,0)] - The third corner of the triangle. + * @param {Vector3} [min=(Infinity,Infinity,Infinity)] - A vector representing the lower boundary of the box. + * @param {Vector3} [max=(-Infinity,-Infinity,-Infinity)] - A vector representing the upper boundary of the box. */ - constructor( a = new Vector3(), b = new Vector3(), c = new Vector3() ) { + constructor( min = new Vector3( + Infinity, + Infinity, + Infinity ), max = new Vector3( - Infinity, - Infinity, - Infinity ) ) { /** - * The first corner of the triangle. + * This flag can be used for type testing. * - * @type {Vector3} + * @type {boolean} + * @readonly + * @default true */ - this.a = a; + this.isBox3 = true; /** - * The second corner of the triangle. + * The lower boundary of the box. * * @type {Vector3} */ - this.b = b; + this.min = min; /** - * The third corner of the triangle. + * The upper boundary of the box. * * @type {Vector3} */ - this.c = c; + this.max = max; } /** - * Computes the normal vector of a triangle. + * Sets the lower and upper boundaries of this box. + * Please note that this method only copies the values from the given objects. * - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The triangle's normal. + * @param {Vector3} min - The lower boundary of the box. + * @param {Vector3} max - The upper boundary of the box. + * @return {Box3} A reference to this bounding box. */ - static getNormal( a, b, c, target ) { - - target.subVectors( c, b ); - _v0$1.subVectors( a, b ); - target.cross( _v0$1 ); - - const targetLengthSq = target.lengthSq(); - if ( targetLengthSq > 0 ) { - - return target.multiplyScalar( 1 / Math.sqrt( targetLengthSq ) ); + set( min, max ) { - } + this.min.copy( min ); + this.max.copy( max ); - return target.set( 0, 0, 0 ); + return this; } /** - * Computes a barycentric coordinates from the given vector. - * Returns `null` if the triangle is degenerate. + * Sets the upper and lower bounds of this box so it encloses the position data + * in the given array. * - * @param {Vector3} point - A point in 3D space. - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The barycentric coordinates for the given point + * @param {Array} array - An array holding 3D position data. + * @return {Box3} A reference to this bounding box. */ - static getBarycoord( point, a, b, c, target ) { - - // based on: http://www.blackpawn.com/texts/pointinpoly/default.html - - _v0$1.subVectors( c, a ); - _v1$3.subVectors( b, a ); - _v2$2.subVectors( point, a ); - - const dot00 = _v0$1.dot( _v0$1 ); - const dot01 = _v0$1.dot( _v1$3 ); - const dot02 = _v0$1.dot( _v2$2 ); - const dot11 = _v1$3.dot( _v1$3 ); - const dot12 = _v1$3.dot( _v2$2 ); + setFromArray( array ) { - const denom = ( dot00 * dot11 - dot01 * dot01 ); + this.makeEmpty(); - // collinear or singular triangle - if ( denom === 0 ) { + for ( let i = 0, il = array.length; i < il; i += 3 ) { - target.set( 0, 0, 0 ); - return null; + this.expandByPoint( _vector$b.fromArray( array, i ) ); } - const invDenom = 1 / denom; - const u = ( dot11 * dot02 - dot01 * dot12 ) * invDenom; - const v = ( dot00 * dot12 - dot01 * dot02 ) * invDenom; - - // barycentric coordinates must always sum to 1 - return target.set( 1 - u - v, v, u ); + return this; } /** - * Returns `true` if the given point, when projected onto the plane of the - * triangle, lies within the triangle. + * Sets the upper and lower bounds of this box so it encloses the position data + * in the given buffer attribute. * - * @param {Vector3} point - The point in 3D space to test. - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @return {boolean} Whether the given point, when projected onto the plane of the - * triangle, lies within the triangle or not. + * @param {BufferAttribute} attribute - A buffer attribute holding 3D position data. + * @return {Box3} A reference to this bounding box. */ - static containsPoint( point, a, b, c ) { + setFromBufferAttribute( attribute ) { - // if the triangle is degenerate then we can't contain a point - if ( this.getBarycoord( point, a, b, c, _v3$2 ) === null ) { + this.makeEmpty(); - return false; + for ( let i = 0, il = attribute.count; i < il; i ++ ) { + + this.expandByPoint( _vector$b.fromBufferAttribute( attribute, i ) ); } - return ( _v3$2.x >= 0 ) && ( _v3$2.y >= 0 ) && ( ( _v3$2.x + _v3$2.y ) <= 1 ); + return this; } /** - * Computes the value barycentrically interpolated for the given point on the - * triangle. Returns `null` if the triangle is degenerate. + * Sets the upper and lower bounds of this box so it encloses the position data + * in the given array. * - * @param {Vector3} point - Position of interpolated point. - * @param {Vector3} p1 - The first corner of the triangle. - * @param {Vector3} p2 - The second corner of the triangle. - * @param {Vector3} p3 - The third corner of the triangle. - * @param {Vector3} v1 - Value to interpolate of first vertex. - * @param {Vector3} v2 - Value to interpolate of second vertex. - * @param {Vector3} v3 - Value to interpolate of third vertex. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The interpolated value. + * @param {Array} points - An array holding 3D position data as instances of {@link Vector3}. + * @return {Box3} A reference to this bounding box. */ - static getInterpolation( point, p1, p2, p3, v1, v2, v3, target ) { + setFromPoints( points ) { - if ( this.getBarycoord( point, p1, p2, p3, _v3$2 ) === null ) { + this.makeEmpty(); - target.x = 0; - target.y = 0; - if ( 'z' in target ) target.z = 0; - if ( 'w' in target ) target.w = 0; - return null; + for ( let i = 0, il = points.length; i < il; i ++ ) { - } + this.expandByPoint( points[ i ] ); - target.setScalar( 0 ); - target.addScaledVector( v1, _v3$2.x ); - target.addScaledVector( v2, _v3$2.y ); - target.addScaledVector( v3, _v3$2.z ); + } - return target; + return this; } /** - * Computes the value barycentrically interpolated for the given attribute and indices. + * Centers this box on the given center vector and sets this box's width, height and + * depth to the given size values. * - * @param {BufferAttribute} attr - The attribute to interpolate. - * @param {number} i1 - Index of first vertex. - * @param {number} i2 - Index of second vertex. - * @param {number} i3 - Index of third vertex. - * @param {Vector3} barycoord - The barycoordinate value to use to interpolate. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The interpolated attribute value. + * @param {Vector3} center - The center of the box. + * @param {Vector3} size - The x, y and z dimensions of the box. + * @return {Box3} A reference to this bounding box. */ - static getInterpolatedAttribute( attr, i1, i2, i3, barycoord, target ) { - - _v40.setScalar( 0 ); - _v41.setScalar( 0 ); - _v42.setScalar( 0 ); + setFromCenterAndSize( center, size ) { - _v40.fromBufferAttribute( attr, i1 ); - _v41.fromBufferAttribute( attr, i2 ); - _v42.fromBufferAttribute( attr, i3 ); + const halfSize = _vector$b.copy( size ).multiplyScalar( 0.5 ); - target.setScalar( 0 ); - target.addScaledVector( _v40, barycoord.x ); - target.addScaledVector( _v41, barycoord.y ); - target.addScaledVector( _v42, barycoord.z ); + this.min.copy( center ).sub( halfSize ); + this.max.copy( center ).add( halfSize ); - return target; + return this; } /** - * Returns `true` if the triangle is oriented towards the given direction. + * Computes the world-axis-aligned bounding box for the given 3D object + * (including its children), accounting for the object's, and children's, + * world transforms. The function may result in a larger box than strictly necessary. * - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @param {Vector3} direction - The (normalized) direction vector. - * @return {boolean} Whether the triangle is oriented towards the given direction or not. + * @param {Object3D} object - The 3D object to compute the bounding box for. + * @param {boolean} [precise=false] - If set to `true`, the method computes the smallest + * world-axis-aligned bounding box at the expense of more computation. + * @return {Box3} A reference to this bounding box. */ - static isFrontFacing( a, b, c, direction ) { + setFromObject( object, precise = false ) { - _v0$1.subVectors( c, b ); - _v1$3.subVectors( a, b ); + this.makeEmpty(); - // strictly front facing - return ( _v0$1.cross( _v1$3 ).dot( direction ) < 0 ) ? true : false; + return this.expandByObject( object, precise ); } /** - * Sets the triangle's vertices by copying the given values. + * Returns a new box with copied values from this instance. * - * @param {Vector3} a - The first corner of the triangle. - * @param {Vector3} b - The second corner of the triangle. - * @param {Vector3} c - The third corner of the triangle. - * @return {Triangle} A reference to this triangle. + * @return {Box3} A clone of this instance. */ - set( a, b, c ) { - - this.a.copy( a ); - this.b.copy( b ); - this.c.copy( c ); + clone() { - return this; + return new this.constructor().copy( this ); } /** - * Sets the triangle's vertices by copying the given array values. + * Copies the values of the given box to this instance. * - * @param {Array} points - An array with 3D points. - * @param {number} i0 - The array index representing the first corner of the triangle. - * @param {number} i1 - The array index representing the second corner of the triangle. - * @param {number} i2 - The array index representing the third corner of the triangle. - * @return {Triangle} A reference to this triangle. + * @param {Box3} box - The box to copy. + * @return {Box3} A reference to this bounding box. */ - setFromPointsAndIndices( points, i0, i1, i2 ) { + copy( box ) { - this.a.copy( points[ i0 ] ); - this.b.copy( points[ i1 ] ); - this.c.copy( points[ i2 ] ); + this.min.copy( box.min ); + this.max.copy( box.max ); return this; } /** - * Sets the triangle's vertices by copying the given attribute values. + * Makes this box empty which means in encloses a zero space in 3D. * - * @param {BufferAttribute} attribute - A buffer attribute with 3D points data. - * @param {number} i0 - The attribute index representing the first corner of the triangle. - * @param {number} i1 - The attribute index representing the second corner of the triangle. - * @param {number} i2 - The attribute index representing the third corner of the triangle. - * @return {Triangle} A reference to this triangle. + * @return {Box3} A reference to this bounding box. */ - setFromAttributeAndIndices( attribute, i0, i1, i2 ) { + makeEmpty() { - this.a.fromBufferAttribute( attribute, i0 ); - this.b.fromBufferAttribute( attribute, i1 ); - this.c.fromBufferAttribute( attribute, i2 ); + this.min.x = this.min.y = this.min.z = + Infinity; + this.max.x = this.max.y = this.max.z = - Infinity; return this; } /** - * Returns a new triangle with copied values from this instance. - * - * @return {Triangle} A clone of this instance. - */ - clone() { - - return new this.constructor().copy( this ); - - } - - /** - * Copies the values of the given triangle to this instance. + * Returns true if this box includes zero points within its bounds. + * Note that a box with equal lower and upper bounds still includes one + * point, the one both bounds share. * - * @param {Triangle} triangle - The triangle to copy. - * @return {Triangle} A reference to this triangle. + * @return {boolean} Whether this box is empty or not. */ - copy( triangle ) { + isEmpty() { - this.a.copy( triangle.a ); - this.b.copy( triangle.b ); - this.c.copy( triangle.c ); + // this is a more robust check for empty than ( volume <= 0 ) because volume can get positive with two negative axes - return this; + return ( this.max.x < this.min.x ) || ( this.max.y < this.min.y ) || ( this.max.z < this.min.z ); } /** - * Computes the area of the triangle. + * Returns the center point of this box. * - * @return {number} The triangle's area. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The center point. */ - getArea() { - - _v0$1.subVectors( this.c, this.b ); - _v1$3.subVectors( this.a, this.b ); + getCenter( target ) { - return _v0$1.cross( _v1$3 ).length() * 0.5; + return this.isEmpty() ? target.set( 0, 0, 0 ) : target.addVectors( this.min, this.max ).multiplyScalar( 0.5 ); } /** - * Computes the midpoint of the triangle. + * Returns the dimensions of this box. * * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The triangle's midpoint. + * @return {Vector3} The size. */ - getMidpoint( target ) { + getSize( target ) { - return target.addVectors( this.a, this.b ).add( this.c ).multiplyScalar( 1 / 3 ); + return this.isEmpty() ? target.set( 0, 0, 0 ) : target.subVectors( this.max, this.min ); } /** - * Computes the normal of the triangle. + * Expands the boundaries of this box to include the given point. * - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The triangle's normal. + * @param {Vector3} point - The point that should be included by the bounding box. + * @return {Box3} A reference to this bounding box. */ - getNormal( target ) { + expandByPoint( point ) { - return Triangle.getNormal( this.a, this.b, this.c, target ); + this.min.min( point ); + this.max.max( point ); + + return this; } /** - * Computes a plane the triangle lies within. - * - * @param {Plane} target - The target vector that is used to store the method's result. - * @return {Plane} The plane the triangle lies within. + * Expands this box equilaterally by the given vector. The width of this + * box will be expanded by the x component of the vector in both + * directions. The height of this box will be expanded by the y component of + * the vector in both directions. The depth of this box will be + * expanded by the z component of the vector in both directions. + * + * @param {Vector3} vector - The vector that should expand the bounding box. + * @return {Box3} A reference to this bounding box. */ - getPlane( target ) { + expandByVector( vector ) { - return target.setFromCoplanarPoints( this.a, this.b, this.c ); + this.min.sub( vector ); + this.max.add( vector ); + + return this; } /** - * Computes a barycentric coordinates from the given vector. - * Returns `null` if the triangle is degenerate. + * Expands each dimension of the box by the given scalar. If negative, the + * dimensions of the box will be contracted. * - * @param {Vector3} point - A point in 3D space. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The barycentric coordinates for the given point + * @param {number} scalar - The scalar value that should expand the bounding box. + * @return {Box3} A reference to this bounding box. */ - getBarycoord( point, target ) { + expandByScalar( scalar ) { - return Triangle.getBarycoord( point, this.a, this.b, this.c, target ); + this.min.addScalar( - scalar ); + this.max.addScalar( scalar ); + + return this; } /** - * Computes the value barycentrically interpolated for the given point on the - * triangle. Returns `null` if the triangle is degenerate. + * Expands the boundaries of this box to include the given 3D object and + * its children, accounting for the object's, and children's, world + * transforms. The function may result in a larger box than strictly + * necessary (unless the precise parameter is set to true). * - * @param {Vector3} point - Position of interpolated point. - * @param {Vector3} v1 - Value to interpolate of first vertex. - * @param {Vector3} v2 - Value to interpolate of second vertex. - * @param {Vector3} v3 - Value to interpolate of third vertex. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {?Vector3} The interpolated value. + * @param {Object3D} object - The 3D object that should expand the bounding box. + * @param {boolean} precise - If set to `true`, the method expands the bounding box + * as little as necessary at the expense of more computation. + * @return {Box3} A reference to this bounding box. */ - getInterpolation( point, v1, v2, v3, target ) { + expandByObject( object, precise = false ) { - return Triangle.getInterpolation( point, this.a, this.b, this.c, v1, v2, v3, target ); + // Computes the world-axis-aligned bounding box of an object (including its children), + // accounting for both the object's, and children's, world transforms - } + object.updateWorldMatrix( false, false ); - /** - * Returns `true` if the given point, when projected onto the plane of the - * triangle, lies within the triangle. - * - * @param {Vector3} point - The point in 3D space to test. - * @return {boolean} Whether the given point, when projected onto the plane of the - * triangle, lies within the triangle or not. - */ - containsPoint( point ) { + const geometry = object.geometry; - return Triangle.containsPoint( point, this.a, this.b, this.c ); + if ( geometry !== undefined ) { - } + const positionAttribute = geometry.getAttribute( 'position' ); - /** - * Returns `true` if the triangle is oriented towards the given direction. - * - * @param {Vector3} direction - The (normalized) direction vector. - * @return {boolean} Whether the triangle is oriented towards the given direction or not. - */ - isFrontFacing( direction ) { + // precise AABB computation based on vertex data requires at least a position attribute. + // instancing isn't supported so far and uses the normal (conservative) code path. - return Triangle.isFrontFacing( this.a, this.b, this.c, direction ); + if ( precise === true && positionAttribute !== undefined && object.isInstancedMesh !== true ) { - } + for ( let i = 0, l = positionAttribute.count; i < l; i ++ ) { - /** - * Returns `true` if this triangle intersects with the given box. - * - * @param {Box3} box - The box to intersect. - * @return {boolean} Whether this triangle intersects with the given box or not. - */ - intersectsBox( box ) { + if ( object.isMesh === true ) { - return box.intersectsTriangle( this ); + object.getVertexPosition( i, _vector$b ); - } + } else { - /** - * Returns the closest point on the triangle to the given point. - * - * @param {Vector3} p - The point to compute the closest point for. - * @param {Vector3} target - The target vector that is used to store the method's result. - * @return {Vector3} The closest point on the triangle. - */ - closestPointToPoint( p, target ) { + _vector$b.fromBufferAttribute( positionAttribute, i ); - const a = this.a, b = this.b, c = this.c; - let v, w; + } - // algorithm thanks to Real-Time Collision Detection by Christer Ericson, - // published by Morgan Kaufmann Publishers, (c) 2005 Elsevier Inc., - // under the accompanying license; see chapter 5.1.5 for detailed explanation. - // basically, we're distinguishing which of the voronoi regions of the triangle - // the point lies in with the minimum amount of redundant computation. + _vector$b.applyMatrix4( object.matrixWorld ); + this.expandByPoint( _vector$b ); - _vab.subVectors( b, a ); - _vac.subVectors( c, a ); - _vap.subVectors( p, a ); - const d1 = _vab.dot( _vap ); - const d2 = _vac.dot( _vap ); - if ( d1 <= 0 && d2 <= 0 ) { + } - // vertex region of A; barycentric coords (1, 0, 0) - return target.copy( a ); + } else { - } + if ( object.boundingBox !== undefined ) { - _vbp.subVectors( p, b ); - const d3 = _vab.dot( _vbp ); - const d4 = _vac.dot( _vbp ); - if ( d3 >= 0 && d4 <= d3 ) { + // object-level bounding box - // vertex region of B; barycentric coords (0, 1, 0) - return target.copy( b ); + if ( object.boundingBox === null ) { - } + object.computeBoundingBox(); - const vc = d1 * d4 - d3 * d2; - if ( vc <= 0 && d1 >= 0 && d3 <= 0 ) { + } - v = d1 / ( d1 - d3 ); - // edge region of AB; barycentric coords (1-v, v, 0) - return target.copy( a ).addScaledVector( _vab, v ); + _box$4.copy( object.boundingBox ); - } - _vcp.subVectors( p, c ); - const d5 = _vab.dot( _vcp ); - const d6 = _vac.dot( _vcp ); - if ( d6 >= 0 && d5 <= d6 ) { + } else { - // vertex region of C; barycentric coords (0, 0, 1) - return target.copy( c ); + // geometry-level bounding box - } + if ( geometry.boundingBox === null ) { - const vb = d5 * d2 - d1 * d6; - if ( vb <= 0 && d2 >= 0 && d6 <= 0 ) { + geometry.computeBoundingBox(); - w = d2 / ( d2 - d6 ); - // edge region of AC; barycentric coords (1-w, 0, w) - return target.copy( a ).addScaledVector( _vac, w ); + } - } + _box$4.copy( geometry.boundingBox ); - const va = d3 * d6 - d5 * d4; - if ( va <= 0 && ( d4 - d3 ) >= 0 && ( d5 - d6 ) >= 0 ) { + } - _vbc.subVectors( c, b ); - w = ( d4 - d3 ) / ( ( d4 - d3 ) + ( d5 - d6 ) ); - // edge region of BC; barycentric coords (0, 1-w, w) - return target.copy( b ).addScaledVector( _vbc, w ); // edge region of BC + _box$4.applyMatrix4( object.matrixWorld ); + + this.union( _box$4 ); + + } } - // face region - const denom = 1 / ( va + vb + vc ); - // u = va * denom - v = vb * denom; - w = vc * denom; + const children = object.children; - return target.copy( a ).addScaledVector( _vab, v ).addScaledVector( _vac, w ); + for ( let i = 0, l = children.length; i < l; i ++ ) { + + this.expandByObject( children[ i ], precise ); + + } + + return this; } /** - * Returns `true` if this triangle is equal with the given one. + * Returns `true` if the given point lies within or on the boundaries of this box. * - * @param {Triangle} triangle - The triangle to test for equality. - * @return {boolean} Whether this triangle is equal with the given one. + * @param {Vector3} point - The point to test. + * @return {boolean} Whether the bounding box contains the given point or not. */ - equals( triangle ) { + containsPoint( point ) { - return triangle.a.equals( this.a ) && triangle.b.equals( this.b ) && triangle.c.equals( this.c ); + return point.x >= this.min.x && point.x <= this.max.x && + point.y >= this.min.y && point.y <= this.max.y && + point.z >= this.min.z && point.z <= this.max.z; } -} - -const _colorKeywords = { 'aliceblue': 0xF0F8FF, 'antiquewhite': 0xFAEBD7, 'aqua': 0x00FFFF, 'aquamarine': 0x7FFFD4, 'azure': 0xF0FFFF, - 'beige': 0xF5F5DC, 'bisque': 0xFFE4C4, 'black': 0x000000, 'blanchedalmond': 0xFFEBCD, 'blue': 0x0000FF, 'blueviolet': 0x8A2BE2, - 'brown': 0xA52A2A, 'burlywood': 0xDEB887, 'cadetblue': 0x5F9EA0, 'chartreuse': 0x7FFF00, 'chocolate': 0xD2691E, 'coral': 0xFF7F50, - 'cornflowerblue': 0x6495ED, 'cornsilk': 0xFFF8DC, 'crimson': 0xDC143C, 'cyan': 0x00FFFF, 'darkblue': 0x00008B, 'darkcyan': 0x008B8B, - 'darkgoldenrod': 0xB8860B, 'darkgray': 0xA9A9A9, 'darkgreen': 0x006400, 'darkgrey': 0xA9A9A9, 'darkkhaki': 0xBDB76B, 'darkmagenta': 0x8B008B, - 'darkolivegreen': 0x556B2F, 'darkorange': 0xFF8C00, 'darkorchid': 0x9932CC, 'darkred': 0x8B0000, 'darksalmon': 0xE9967A, 'darkseagreen': 0x8FBC8F, - 'darkslateblue': 0x483D8B, 'darkslategray': 0x2F4F4F, 'darkslategrey': 0x2F4F4F, 'darkturquoise': 0x00CED1, 'darkviolet': 0x9400D3, - 'deeppink': 0xFF1493, 'deepskyblue': 0x00BFFF, 'dimgray': 0x696969, 'dimgrey': 0x696969, 'dodgerblue': 0x1E90FF, 'firebrick': 0xB22222, - 'floralwhite': 0xFFFAF0, 'forestgreen': 0x228B22, 'fuchsia': 0xFF00FF, 'gainsboro': 0xDCDCDC, 'ghostwhite': 0xF8F8FF, 'gold': 0xFFD700, - 'goldenrod': 0xDAA520, 'gray': 0x808080, 'green': 0x008000, 'greenyellow': 0xADFF2F, 'grey': 0x808080, 'honeydew': 0xF0FFF0, 'hotpink': 0xFF69B4, - 'indianred': 0xCD5C5C, 'indigo': 0x4B0082, 'ivory': 0xFFFFF0, 'khaki': 0xF0E68C, 'lavender': 0xE6E6FA, 'lavenderblush': 0xFFF0F5, 'lawngreen': 0x7CFC00, - 'lemonchiffon': 0xFFFACD, 'lightblue': 0xADD8E6, 'lightcoral': 0xF08080, 'lightcyan': 0xE0FFFF, 'lightgoldenrodyellow': 0xFAFAD2, 'lightgray': 0xD3D3D3, - 'lightgreen': 0x90EE90, 'lightgrey': 0xD3D3D3, 'lightpink': 0xFFB6C1, 'lightsalmon': 0xFFA07A, 'lightseagreen': 0x20B2AA, 'lightskyblue': 0x87CEFA, - 'lightslategray': 0x778899, 'lightslategrey': 0x778899, 'lightsteelblue': 0xB0C4DE, 'lightyellow': 0xFFFFE0, 'lime': 0x00FF00, 'limegreen': 0x32CD32, - 'linen': 0xFAF0E6, 'magenta': 0xFF00FF, 'maroon': 0x800000, 'mediumaquamarine': 0x66CDAA, 'mediumblue': 0x0000CD, 'mediumorchid': 0xBA55D3, - 'mediumpurple': 0x9370DB, 'mediumseagreen': 0x3CB371, 'mediumslateblue': 0x7B68EE, 'mediumspringgreen': 0x00FA9A, 'mediumturquoise': 0x48D1CC, - 'mediumvioletred': 0xC71585, 'midnightblue': 0x191970, 'mintcream': 0xF5FFFA, 'mistyrose': 0xFFE4E1, 'moccasin': 0xFFE4B5, 'navajowhite': 0xFFDEAD, - 'navy': 0x000080, 'oldlace': 0xFDF5E6, 'olive': 0x808000, 'olivedrab': 0x6B8E23, 'orange': 0xFFA500, 'orangered': 0xFF4500, 'orchid': 0xDA70D6, - 'palegoldenrod': 0xEEE8AA, 'palegreen': 0x98FB98, 'paleturquoise': 0xAFEEEE, 'palevioletred': 0xDB7093, 'papayawhip': 0xFFEFD5, 'peachpuff': 0xFFDAB9, - 'peru': 0xCD853F, 'pink': 0xFFC0CB, 'plum': 0xDDA0DD, 'powderblue': 0xB0E0E6, 'purple': 0x800080, 'rebeccapurple': 0x663399, 'red': 0xFF0000, 'rosybrown': 0xBC8F8F, - 'royalblue': 0x4169E1, 'saddlebrown': 0x8B4513, 'salmon': 0xFA8072, 'sandybrown': 0xF4A460, 'seagreen': 0x2E8B57, 'seashell': 0xFFF5EE, - 'sienna': 0xA0522D, 'silver': 0xC0C0C0, 'skyblue': 0x87CEEB, 'slateblue': 0x6A5ACD, 'slategray': 0x708090, 'slategrey': 0x708090, 'snow': 0xFFFAFA, - 'springgreen': 0x00FF7F, 'steelblue': 0x4682B4, 'tan': 0xD2B48C, 'teal': 0x008080, 'thistle': 0xD8BFD8, 'tomato': 0xFF6347, 'turquoise': 0x40E0D0, - 'violet': 0xEE82EE, 'wheat': 0xF5DEB3, 'white': 0xFFFFFF, 'whitesmoke': 0xF5F5F5, 'yellow': 0xFFFF00, 'yellowgreen': 0x9ACD32 }; - -const _hslA = { h: 0, s: 0, l: 0 }; -const _hslB = { h: 0, s: 0, l: 0 }; - -function hue2rgb( p, q, t ) { - - if ( t < 0 ) t += 1; - if ( t > 1 ) t -= 1; - if ( t < 1 / 6 ) return p + ( q - p ) * 6 * t; - if ( t < 1 / 2 ) return q; - if ( t < 2 / 3 ) return p + ( q - p ) * 6 * ( 2 / 3 - t ); - return p; + /** + * Returns `true` if this bounding box includes the entirety of the given bounding box. + * If this box and the given one are identical, this function also returns `true`. + * + * @param {Box3} box - The bounding box to test. + * @return {boolean} Whether the bounding box contains the given bounding box or not. + */ + containsBox( box ) { -} + return this.min.x <= box.min.x && box.max.x <= this.max.x && + this.min.y <= box.min.y && box.max.y <= this.max.y && + this.min.z <= box.min.z && box.max.z <= this.max.z; -/** - * A Color instance is represented by RGB components in the linear working - * color space, which defaults to `LinearSRGBColorSpace`. Inputs - * conventionally using `SRGBColorSpace` (such as hexadecimals and CSS - * strings) are converted to the working color space automatically. - * - * ```js - * // converted automatically from SRGBColorSpace to LinearSRGBColorSpace - * const color = new THREE.Color().setHex( 0x112233 ); - * ``` - * Source color spaces may be specified explicitly, to ensure correct conversions. - * ```js - * // assumed already LinearSRGBColorSpace; no conversion - * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5 ); - * - * // converted explicitly from SRGBColorSpace to LinearSRGBColorSpace - * const color = new THREE.Color().setRGB( 0.5, 0.5, 0.5, SRGBColorSpace ); - * ``` - * If THREE.ColorManagement is disabled, no conversions occur. For details, - * see Color management. Iterating through a Color instance will yield - * its components (r, g, b) in the corresponding order. A Color can be initialised - * in any of the following ways: - * ```js - * //empty constructor - will default white - * const color1 = new THREE.Color(); - * - * //Hexadecimal color (recommended) - * const color2 = new THREE.Color( 0xff0000 ); - * - * //RGB string - * const color3 = new THREE.Color("rgb(255, 0, 0)"); - * const color4 = new THREE.Color("rgb(100%, 0%, 0%)"); - * - * //X11 color name - all 140 color names are supported. - * //Note the lack of CamelCase in the name - * const color5 = new THREE.Color( 'skyblue' ); - * //HSL string - * const color6 = new THREE.Color("hsl(0, 100%, 50%)"); - * - * //Separate RGB values between 0 and 1 - * const color7 = new THREE.Color( 1, 0, 0 ); - * ``` - */ -class Color { + } /** - * Constructs a new color. - * - * Note that standard method of specifying color in three.js is with a hexadecimal triplet, - * and that method is used throughout the rest of the documentation. + * Returns a point as a proportion of this box's width, height and depth. * - * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are - * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. - * @param {number} [g] - The green component. - * @param {number} [b] - The blue component. + * @param {Vector3} point - A point in 3D space. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} A point as a proportion of this box's width, height and depth. */ - constructor( r, g, b ) { + getParameter( point, target ) { - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isColor = true; + // This can potentially have a divide by zero if the box + // has a size dimension of 0. - /** - * The red component. - * - * @type {number} - * @default 1 - */ - this.r = 1; + return target.set( + ( point.x - this.min.x ) / ( this.max.x - this.min.x ), + ( point.y - this.min.y ) / ( this.max.y - this.min.y ), + ( point.z - this.min.z ) / ( this.max.z - this.min.z ) + ); - /** - * The green component. - * - * @type {number} - * @default 1 - */ - this.g = 1; + } - /** - * The blue component. - * - * @type {number} - * @default 1 - */ - this.b = 1; + /** + * Returns `true` if the given bounding box intersects with this bounding box. + * + * @param {Box3} box - The bounding box to test. + * @return {boolean} Whether the given bounding box intersects with this bounding box. + */ + intersectsBox( box ) { - return this.set( r, g, b ); + // using 6 splitting planes to rule out intersections. + return box.max.x >= this.min.x && box.min.x <= this.max.x && + box.max.y >= this.min.y && box.min.y <= this.max.y && + box.max.z >= this.min.z && box.min.z <= this.max.z; } /** - * Sets the colors's components from the given values. + * Returns `true` if the given bounding sphere intersects with this bounding box. * - * @param {(number|string|Color)} [r] - The red component of the color. If `g` and `b` are - * not provided, it can be hexadecimal triplet, a CSS-style string or another `Color` instance. - * @param {number} [g] - The green component. - * @param {number} [b] - The blue component. - * @return {Color} A reference to this color. + * @param {Sphere} sphere - The bounding sphere to test. + * @return {boolean} Whether the given bounding sphere intersects with this bounding box. */ - set( r, g, b ) { - - if ( g === undefined && b === undefined ) { - - // r is THREE.Color, hex or string + intersectsSphere( sphere ) { - const value = r; + // Find the point on the AABB closest to the sphere center. + this.clampPoint( sphere.center, _vector$b ); - if ( value && value.isColor ) { + // If that point is inside the sphere, the AABB and sphere intersect. + return _vector$b.distanceToSquared( sphere.center ) <= ( sphere.radius * sphere.radius ); - this.copy( value ); + } - } else if ( typeof value === 'number' ) { + /** + * Returns `true` if the given plane intersects with this bounding box. + * + * @param {Plane} plane - The plane to test. + * @return {boolean} Whether the given plane intersects with this bounding box. + */ + intersectsPlane( plane ) { - this.setHex( value ); + // We compute the minimum and maximum dot product values. If those values + // are on the same side (back or front) of the plane, then there is no intersection. - } else if ( typeof value === 'string' ) { + let min, max; - this.setStyle( value ); + if ( plane.normal.x > 0 ) { - } + min = plane.normal.x * this.min.x; + max = plane.normal.x * this.max.x; } else { - this.setRGB( r, g, b ); + min = plane.normal.x * this.max.x; + max = plane.normal.x * this.min.x; } - return this; + if ( plane.normal.y > 0 ) { - } + min += plane.normal.y * this.min.y; + max += plane.normal.y * this.max.y; - /** - * Sets the colors's components to the given scalar value. - * - * @param {number} scalar - The scalar value. - * @return {Color} A reference to this color. - */ - setScalar( scalar ) { + } else { - this.r = scalar; - this.g = scalar; - this.b = scalar; + min += plane.normal.y * this.max.y; + max += plane.normal.y * this.min.y; - return this; + } - } + if ( plane.normal.z > 0 ) { - /** - * Sets this color from a hexadecimal value. - * - * @param {number} hex - The hexadecimal value. - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {Color} A reference to this color. - */ - setHex( hex, colorSpace = SRGBColorSpace ) { + min += plane.normal.z * this.min.z; + max += plane.normal.z * this.max.z; - hex = Math.floor( hex ); + } else { - this.r = ( hex >> 16 & 255 ) / 255; - this.g = ( hex >> 8 & 255 ) / 255; - this.b = ( hex & 255 ) / 255; + min += plane.normal.z * this.max.z; + max += plane.normal.z * this.min.z; - ColorManagement.colorSpaceToWorking( this, colorSpace ); + } - return this; + return ( min <= - plane.constant && max >= - plane.constant ); } /** - * Sets this color from RGB values. + * Returns `true` if the given triangle intersects with this bounding box. * - * @param {number} r - Red channel value between `0.0` and `1.0`. - * @param {number} g - Green channel value between `0.0` and `1.0`. - * @param {number} b - Blue channel value between `0.0` and `1.0`. - * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. - * @return {Color} A reference to this color. + * @param {Triangle} triangle - The triangle to test. + * @return {boolean} Whether the given triangle intersects with this bounding box. */ - setRGB( r, g, b, colorSpace = ColorManagement.workingColorSpace ) { + intersectsTriangle( triangle ) { - this.r = r; - this.g = g; - this.b = b; + if ( this.isEmpty() ) { - ColorManagement.colorSpaceToWorking( this, colorSpace ); + return false; - return this; + } - } + // compute box center and extents + this.getCenter( _center ); + _extents.subVectors( this.max, _center ); - /** - * Sets this color from RGB values. - * - * @param {number} h - Hue value between `0.0` and `1.0`. - * @param {number} s - Saturation value between `0.0` and `1.0`. - * @param {number} l - Lightness value between `0.0` and `1.0`. - * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. - * @return {Color} A reference to this color. - */ - setHSL( h, s, l, colorSpace = ColorManagement.workingColorSpace ) { + // translate triangle to aabb origin + _v0$1.subVectors( triangle.a, _center ); + _v1$4.subVectors( triangle.b, _center ); + _v2$3.subVectors( triangle.c, _center ); - // h,s,l ranges are in 0.0 - 1.0 - h = euclideanModulo( h, 1 ); - s = clamp( s, 0, 1 ); - l = clamp( l, 0, 1 ); + // compute edge vectors for triangle + _f0.subVectors( _v1$4, _v0$1 ); + _f1.subVectors( _v2$3, _v1$4 ); + _f2.subVectors( _v0$1, _v2$3 ); - if ( s === 0 ) { + // test against axes that are given by cross product combinations of the edges of the triangle and the edges of the aabb + // make an axis testing of each of the 3 sides of the aabb against each of the 3 sides of the triangle = 9 axis of separation + // axis_ij = u_i x f_j (u0, u1, u2 = face normals of aabb = x,y,z axes vectors since aabb is axis aligned) + let axes = [ + 0, - _f0.z, _f0.y, 0, - _f1.z, _f1.y, 0, - _f2.z, _f2.y, + _f0.z, 0, - _f0.x, _f1.z, 0, - _f1.x, _f2.z, 0, - _f2.x, + - _f0.y, _f0.x, 0, - _f1.y, _f1.x, 0, - _f2.y, _f2.x, 0 + ]; + if ( ! satForAxes( axes, _v0$1, _v1$4, _v2$3, _extents ) ) { - this.r = this.g = this.b = l; + return false; - } else { + } - const p = l <= 0.5 ? l * ( 1 + s ) : l + s - ( l * s ); - const q = ( 2 * l ) - p; + // test 3 face normals from the aabb + axes = [ 1, 0, 0, 0, 1, 0, 0, 0, 1 ]; + if ( ! satForAxes( axes, _v0$1, _v1$4, _v2$3, _extents ) ) { - this.r = hue2rgb( q, p, h + 1 / 3 ); - this.g = hue2rgb( q, p, h ); - this.b = hue2rgb( q, p, h - 1 / 3 ); + return false; } - ColorManagement.colorSpaceToWorking( this, colorSpace ); + // finally testing the face normal of the triangle + // use already existing triangle edge vectors here + _triangleNormal.crossVectors( _f0, _f1 ); + axes = [ _triangleNormal.x, _triangleNormal.y, _triangleNormal.z ]; - return this; + return satForAxes( axes, _v0$1, _v1$4, _v2$3, _extents ); } /** - * Sets this color from a CSS-style string. For example, `rgb(250, 0,0)`, - * `rgb(100%, 0%, 0%)`, `hsl(0, 100%, 50%)`, `#ff0000`, `#f00`, or `red` ( or - * any [X11 color name](https://en.wikipedia.org/wiki/X11_color_names#Color_name_chart) - - * all 140 color names are supported). + * Clamps the given point within the bounds of this box. * - * @param {string} style - Color as a CSS-style string. - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {Color} A reference to this color. + * @param {Vector3} point - The point to clamp. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The clamped point. */ - setStyle( style, colorSpace = SRGBColorSpace ) { - - function handleAlpha( string ) { - - if ( string === undefined ) return; - - if ( parseFloat( string ) < 1 ) { - - warn( 'Color: Alpha component of ' + style + ' will be ignored.' ); - - } - - } - - - let m; - - if ( m = /^(\w+)\(([^\)]*)\)/.exec( style ) ) { - - // rgb / hsl - - let color; - const name = m[ 1 ]; - const components = m[ 2 ]; - - switch ( name ) { - - case 'rgb': - case 'rgba': - - if ( color = /^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - - // rgb(255,0,0) rgba(255,0,0,0.5) - - handleAlpha( color[ 4 ] ); - - return this.setRGB( - Math.min( 255, parseInt( color[ 1 ], 10 ) ) / 255, - Math.min( 255, parseInt( color[ 2 ], 10 ) ) / 255, - Math.min( 255, parseInt( color[ 3 ], 10 ) ) / 255, - colorSpace - ); - - } - - if ( color = /^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - - // rgb(100%,0%,0%) rgba(100%,0%,0%,0.5) - - handleAlpha( color[ 4 ] ); - - return this.setRGB( - Math.min( 100, parseInt( color[ 1 ], 10 ) ) / 100, - Math.min( 100, parseInt( color[ 2 ], 10 ) ) / 100, - Math.min( 100, parseInt( color[ 3 ], 10 ) ) / 100, - colorSpace - ); - - } - - break; - - case 'hsl': - case 'hsla': - - if ( color = /^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec( components ) ) { - - // hsl(120,50%,50%) hsla(120,50%,50%,0.5) - - handleAlpha( color[ 4 ] ); - - return this.setHSL( - parseFloat( color[ 1 ] ) / 360, - parseFloat( color[ 2 ] ) / 100, - parseFloat( color[ 3 ] ) / 100, - colorSpace - ); - - } - - break; - - default: - - warn( 'Color: Unknown color model ' + style ); - - } - - } else if ( m = /^\#([A-Fa-f\d]+)$/.exec( style ) ) { - - // hex color - - const hex = m[ 1 ]; - const size = hex.length; - - if ( size === 3 ) { - - // #ff0 - return this.setRGB( - parseInt( hex.charAt( 0 ), 16 ) / 15, - parseInt( hex.charAt( 1 ), 16 ) / 15, - parseInt( hex.charAt( 2 ), 16 ) / 15, - colorSpace - ); - - } else if ( size === 6 ) { - - // #ff0000 - return this.setHex( parseInt( hex, 16 ), colorSpace ); - - } else { - - warn( 'Color: Invalid hex color ' + style ); - - } + clampPoint( point, target ) { - } else if ( style && style.length > 0 ) { + return target.copy( point ).clamp( this.min, this.max ); - return this.setColorName( style, colorSpace ); + } - } + /** + * Returns the euclidean distance from any edge of this box to the specified point. If + * the given point lies inside of this box, the distance will be `0`. + * + * @param {Vector3} point - The point to compute the distance to. + * @return {number} The euclidean distance. + */ + distanceToPoint( point ) { - return this; + return this.clampPoint( point, _vector$b ).distanceTo( point ); } /** - * Sets this color from a color name. Faster than {@link Color#setStyle} if - * you don't need the other CSS-style formats. - * - * For convenience, the list of names is exposed in `Color.NAMES` as a hash. - * ```js - * Color.NAMES.aliceblue // returns 0xF0F8FF - * ``` + * Returns a bounding sphere that encloses this bounding box. * - * @param {string} style - The color name. - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {Color} A reference to this color. + * @param {Sphere} target - The target sphere that is used to store the method's result. + * @return {Sphere} The bounding sphere that encloses this bounding box. */ - setColorName( style, colorSpace = SRGBColorSpace ) { - - // color keywords - const hex = _colorKeywords[ style.toLowerCase() ]; + getBoundingSphere( target ) { - if ( hex !== undefined ) { + if ( this.isEmpty() ) { - // red - this.setHex( hex, colorSpace ); + target.makeEmpty(); } else { - // unknown color - warn( 'Color: Unknown color ' + style ); + this.getCenter( target.center ); + + target.radius = this.getSize( _vector$b ).length() * 0.5; } - return this; + return target; } /** - * Returns a new color with copied values from this instance. + * Computes the intersection of this bounding box and the given one, setting the upper + * bound of this box to the lesser of the two boxes' upper bounds and the + * lower bound of this box to the greater of the two boxes' lower bounds. If + * there's no overlap, makes this box empty. * - * @return {Color} A clone of this instance. + * @param {Box3} box - The bounding box to intersect with. + * @return {Box3} A reference to this bounding box. */ - clone() { - - return new this.constructor( this.r, this.g, this.b ); - - } + intersect( box ) { - /** - * Copies the values of the given color to this instance. - * - * @param {Color} color - The color to copy. - * @return {Color} A reference to this color. - */ - copy( color ) { + this.min.max( box.min ); + this.max.min( box.max ); - this.r = color.r; - this.g = color.g; - this.b = color.b; + // ensure that if there is no overlap, the result is fully empty, not slightly empty with non-inf/+inf values that will cause subsequence intersects to erroneously return valid values. + if ( this.isEmpty() ) this.makeEmpty(); return this; } /** - * Copies the given color into this color, and then converts this color from - * `SRGBColorSpace` to `LinearSRGBColorSpace`. + * Computes the union of this box and another and the given one, setting the upper + * bound of this box to the greater of the two boxes' upper bounds and the + * lower bound of this box to the lesser of the two boxes' lower bounds. * - * @param {Color} color - The color to copy/convert. - * @return {Color} A reference to this color. + * @param {Box3} box - The bounding box that will be unioned with this instance. + * @return {Box3} A reference to this bounding box. */ - copySRGBToLinear( color ) { + union( box ) { - this.r = SRGBToLinear( color.r ); - this.g = SRGBToLinear( color.g ); - this.b = SRGBToLinear( color.b ); + this.min.min( box.min ); + this.max.max( box.max ); return this; } /** - * Copies the given color into this color, and then converts this color from - * `LinearSRGBColorSpace` to `SRGBColorSpace`. + * Transforms this bounding box by the given 4x4 transformation matrix. * - * @param {Color} color - The color to copy/convert. - * @return {Color} A reference to this color. + * @param {Matrix4} matrix - The transformation matrix. + * @return {Box3} A reference to this bounding box. */ - copyLinearToSRGB( color ) { - - this.r = LinearToSRGB( color.r ); - this.g = LinearToSRGB( color.g ); - this.b = LinearToSRGB( color.b ); - - return this; + applyMatrix4( matrix ) { - } + // transform of empty box is an empty box. + if ( this.isEmpty() ) return this; - /** - * Converts this color from `SRGBColorSpace` to `LinearSRGBColorSpace`. - * - * @return {Color} A reference to this color. - */ - convertSRGBToLinear() { + // NOTE: I am using a binary pattern to specify all 2^3 combinations below + _points[ 0 ].set( this.min.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 000 + _points[ 1 ].set( this.min.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 001 + _points[ 2 ].set( this.min.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 010 + _points[ 3 ].set( this.min.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 011 + _points[ 4 ].set( this.max.x, this.min.y, this.min.z ).applyMatrix4( matrix ); // 100 + _points[ 5 ].set( this.max.x, this.min.y, this.max.z ).applyMatrix4( matrix ); // 101 + _points[ 6 ].set( this.max.x, this.max.y, this.min.z ).applyMatrix4( matrix ); // 110 + _points[ 7 ].set( this.max.x, this.max.y, this.max.z ).applyMatrix4( matrix ); // 111 - this.copySRGBToLinear( this ); + this.setFromPoints( _points ); return this; } /** - * Converts this color from `LinearSRGBColorSpace` to `SRGBColorSpace`. + * Adds the given offset to both the upper and lower bounds of this bounding box, + * effectively moving it in 3D space. * - * @return {Color} A reference to this color. + * @param {Vector3} offset - The offset that should be used to translate the bounding box. + * @return {Box3} A reference to this bounding box. */ - convertLinearToSRGB() { + translate( offset ) { - this.copyLinearToSRGB( this ); + this.min.add( offset ); + this.max.add( offset ); return this; } /** - * Returns the hexadecimal value of this color. + * Returns `true` if this bounding box is equal with the given one. * - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {number} The hexadecimal value. + * @param {Box3} box - The box to test for equality. + * @return {boolean} Whether this bounding box is equal with the given one. */ - getHex( colorSpace = SRGBColorSpace ) { - - ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); + equals( box ) { - return Math.round( clamp( _color.r * 255, 0, 255 ) ) * 65536 + Math.round( clamp( _color.g * 255, 0, 255 ) ) * 256 + Math.round( clamp( _color.b * 255, 0, 255 ) ); + return box.min.equals( this.min ) && box.max.equals( this.max ); } /** - * Returns the hexadecimal value of this color as a string (for example, 'FFFFFF'). + * Returns a serialized structure of the bounding box. * - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {string} The hexadecimal value as a string. + * @return {Object} Serialized structure with fields representing the object state. */ - getHexString( colorSpace = SRGBColorSpace ) { + toJSON() { - return ( '000000' + this.getHex( colorSpace ).toString( 16 ) ).slice( -6 ); + return { + min: this.min.toArray(), + max: this.max.toArray() + }; } /** - * Converts the colors RGB values into the HSL format and stores them into the - * given target object. + * Returns a serialized structure of the bounding box. * - * @param {{h:number,s:number,l:number}} target - The target object that is used to store the method's result. - * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. - * @return {{h:number,s:number,l:number}} The HSL representation of this color. + * @param {Object} json - The serialized json to set the box from. + * @return {Box3} A reference to this bounding box. */ - getHSL( target, colorSpace = ColorManagement.workingColorSpace ) { + fromJSON( json ) { - // h,s,l ranges are in 0.0 - 1.0 + this.min.fromArray( json.min ); + this.max.fromArray( json.max ); + return this; - ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); + } - const r = _color.r, g = _color.g, b = _color.b; +} - const max = Math.max( r, g, b ); - const min = Math.min( r, g, b ); +const _points = [ + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3(), + /*@__PURE__*/ new Vector3() +]; - let hue, saturation; - const lightness = ( min + max ) / 2.0; +const _vector$b = /*@__PURE__*/ new Vector3(); - if ( min === max ) { +const _box$4 = /*@__PURE__*/ new Box3(); - hue = 0; - saturation = 0; +// triangle centered vertices - } else { +const _v0$1 = /*@__PURE__*/ new Vector3(); +const _v1$4 = /*@__PURE__*/ new Vector3(); +const _v2$3 = /*@__PURE__*/ new Vector3(); - const delta = max - min; +// triangle edge vectors - saturation = lightness <= 0.5 ? delta / ( max + min ) : delta / ( 2 - max - min ); +const _f0 = /*@__PURE__*/ new Vector3(); +const _f1 = /*@__PURE__*/ new Vector3(); +const _f2 = /*@__PURE__*/ new Vector3(); - switch ( max ) { +const _center = /*@__PURE__*/ new Vector3(); +const _extents = /*@__PURE__*/ new Vector3(); +const _triangleNormal = /*@__PURE__*/ new Vector3(); +const _testAxis = /*@__PURE__*/ new Vector3(); - case r: hue = ( g - b ) / delta + ( g < b ? 6 : 0 ); break; - case g: hue = ( b - r ) / delta + 2; break; - case b: hue = ( r - g ) / delta + 4; break; +function satForAxes( axes, v0, v1, v2, extents ) { - } + for ( let i = 0, j = axes.length - 3; i <= j; i += 3 ) { - hue /= 6; + _testAxis.fromArray( axes, i ); + // project the aabb onto the separating axis + const r = extents.x * Math.abs( _testAxis.x ) + extents.y * Math.abs( _testAxis.y ) + extents.z * Math.abs( _testAxis.z ); + // project all 3 vertices of the triangle onto the separating axis + const p0 = v0.dot( _testAxis ); + const p1 = v1.dot( _testAxis ); + const p2 = v2.dot( _testAxis ); + // actual test, basically see if either of the most extreme of the triangle points intersects r + if ( Math.max( - Math.max( p0, p1, p2 ), Math.min( p0, p1, p2 ) ) > r ) { + + // points of the projected triangle are outside the projected half-length of the aabb + // the axis is separating and we can exit + return false; } - target.h = hue; - target.s = saturation; - target.l = lightness; + } - return target; + return true; - } +} - /** - * Returns the RGB values of this color and stores them into the given target object. - * - * @param {Color} target - The target color that is used to store the method's result. - * @param {string} [colorSpace=ColorManagement.workingColorSpace] - The color space. - * @return {Color} The RGB representation of this color. - */ - getRGB( target, colorSpace = ColorManagement.workingColorSpace ) { +// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf - ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); +const _tables = /*@__PURE__*/ _generateTables(); - target.r = _color.r; - target.g = _color.g; - target.b = _color.b; +function _generateTables() { - return target; + // float32 to float16 helpers - } + const buffer = new ArrayBuffer( 4 ); + const floatView = new Float32Array( buffer ); + const uint32View = new Uint32Array( buffer ); - /** - * Returns the value of this color as a CSS style string. Example: `rgb(255,0,0)`. - * - * @param {string} [colorSpace=SRGBColorSpace] - The color space. - * @return {string} The CSS representation of this color. - */ - getStyle( colorSpace = SRGBColorSpace ) { + const baseTable = new Uint32Array( 512 ); + const shiftTable = new Uint32Array( 512 ); - ColorManagement.workingToColorSpace( _color.copy( this ), colorSpace ); + for ( let i = 0; i < 256; ++ i ) { - const r = _color.r, g = _color.g, b = _color.b; + const e = i - 127; - if ( colorSpace !== SRGBColorSpace ) { + // very small number (0, -0) - // Requires CSS Color Module Level 4 (https://www.w3.org/TR/css-color-4/). - return `color(${ colorSpace } ${ r.toFixed( 3 ) } ${ g.toFixed( 3 ) } ${ b.toFixed( 3 ) })`; + if ( e < -27 ) { - } + baseTable[ i ] = 0x0000; + baseTable[ i | 0x100 ] = 0x8000; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; - return `rgb(${ Math.round( r * 255 ) },${ Math.round( g * 255 ) },${ Math.round( b * 255 ) })`; + // small number (denorm) - } + } else if ( e < -14 ) { - /** - * Adds the given HSL values to this color's values. - * Internally, this converts the color's RGB values to HSL, adds HSL - * and then converts the color back to RGB. - * - * @param {number} h - Hue value between `0.0` and `1.0`. - * @param {number} s - Saturation value between `0.0` and `1.0`. - * @param {number} l - Lightness value between `0.0` and `1.0`. - * @return {Color} A reference to this color. - */ - offsetHSL( h, s, l ) { + baseTable[ i ] = 0x0400 >> ( - e - 14 ); + baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000; + shiftTable[ i ] = - e - 1; + shiftTable[ i | 0x100 ] = - e - 1; - this.getHSL( _hslA ); + // normal number - return this.setHSL( _hslA.h + h, _hslA.s + s, _hslA.l + l ); + } else if ( e <= 15 ) { - } + baseTable[ i ] = ( e + 15 ) << 10; + baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000; + shiftTable[ i ] = 13; + shiftTable[ i | 0x100 ] = 13; - /** - * Adds the RGB values of the given color to the RGB values of this color. - * - * @param {Color} color - The color to add. - * @return {Color} A reference to this color. - */ - add( color ) { + // large number (Infinity, -Infinity) - this.r += color.r; - this.g += color.g; - this.b += color.b; + } else if ( e < 128 ) { - return this; + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 24; + shiftTable[ i | 0x100 ] = 24; - } + // stay (NaN, Infinity, -Infinity) - /** - * Adds the RGB values of the given colors and stores the result in this instance. - * - * @param {Color} color1 - The first color. - * @param {Color} color2 - The second color. - * @return {Color} A reference to this color. - */ - addColors( color1, color2 ) { + } else { - this.r = color1.r + color2.r; - this.g = color1.g + color2.g; - this.b = color1.b + color2.b; + baseTable[ i ] = 0x7c00; + baseTable[ i | 0x100 ] = 0xfc00; + shiftTable[ i ] = 13; + shiftTable[ i | 0x100 ] = 13; - return this; + } } - /** - * Adds the given scalar value to the RGB values of this color. - * - * @param {number} s - The scalar to add. - * @return {Color} A reference to this color. - */ - addScalar( s ) { + // float16 to float32 helpers - this.r += s; - this.g += s; - this.b += s; + const mantissaTable = new Uint32Array( 2048 ); + const exponentTable = new Uint32Array( 64 ); + const offsetTable = new Uint32Array( 64 ); - return this; + for ( let i = 1; i < 1024; ++ i ) { - } + let m = i << 13; // zero pad mantissa bits + let e = 0; // zero exponent - /** - * Subtracts the RGB values of the given color from the RGB values of this color. - * - * @param {Color} color - The color to subtract. - * @return {Color} A reference to this color. - */ - sub( color ) { + // normalized + while ( ( m & 0x00800000 ) === 0 ) { - this.r = Math.max( 0, this.r - color.r ); - this.g = Math.max( 0, this.g - color.g ); - this.b = Math.max( 0, this.b - color.b ); + m <<= 1; + e -= 0x00800000; // decrement exponent - return this; + } - } - - /** - * Multiplies the RGB values of the given color with the RGB values of this color. - * - * @param {Color} color - The color to multiply. - * @return {Color} A reference to this color. - */ - multiply( color ) { - - this.r *= color.r; - this.g *= color.g; - this.b *= color.b; - - return this; - - } - - /** - * Multiplies the given scalar value with the RGB values of this color. - * - * @param {number} s - The scalar to multiply. - * @return {Color} A reference to this color. - */ - multiplyScalar( s ) { - - this.r *= s; - this.g *= s; - this.b *= s; + m &= -8388609; // clear leading 1 bit + e += 0x38800000; // adjust bias - return this; + mantissaTable[ i ] = m | e; } - /** - * Linearly interpolates this color's RGB values toward the RGB values of the - * given color. The alpha argument can be thought of as the ratio between - * the two colors, where `0.0` is this color and `1.0` is the first argument. - * - * @param {Color} color - The color to converge on. - * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. - * @return {Color} A reference to this color. - */ - lerp( color, alpha ) { - - this.r += ( color.r - this.r ) * alpha; - this.g += ( color.g - this.g ) * alpha; - this.b += ( color.b - this.b ) * alpha; + for ( let i = 1024; i < 2048; ++ i ) { - return this; + mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 ); } - /** - * Linearly interpolates between the given colors and stores the result in this instance. - * The alpha argument can be thought of as the ratio between the two colors, where `0.0` - * is the first and `1.0` is the second color. - * - * @param {Color} color1 - The first color. - * @param {Color} color2 - The second color. - * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. - * @return {Color} A reference to this color. - */ - lerpColors( color1, color2, alpha ) { - - this.r = color1.r + ( color2.r - color1.r ) * alpha; - this.g = color1.g + ( color2.g - color1.g ) * alpha; - this.b = color1.b + ( color2.b - color1.b ) * alpha; + for ( let i = 1; i < 31; ++ i ) { - return this; + exponentTable[ i ] = i << 23; } - /** - * Linearly interpolates this color's HSL values toward the HSL values of the - * given color. It differs from {@link Color#lerp} by not interpolating straight - * from one color to the other, but instead going through all the hues in between - * those two colors. The alpha argument can be thought of as the ratio between - * the two colors, where 0.0 is this color and 1.0 is the first argument. - * - * @param {Color} color - The color to converge on. - * @param {number} alpha - The interpolation factor in the closed interval `[0,1]`. - * @return {Color} A reference to this color. - */ - lerpHSL( color, alpha ) { - - this.getHSL( _hslA ); - color.getHSL( _hslB ); - - const h = lerp( _hslA.h, _hslB.h, alpha ); - const s = lerp( _hslA.s, _hslB.s, alpha ); - const l = lerp( _hslA.l, _hslB.l, alpha ); + exponentTable[ 31 ] = 0x47800000; + exponentTable[ 32 ] = 0x80000000; - this.setHSL( h, s, l ); + for ( let i = 33; i < 63; ++ i ) { - return this; + exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 ); } - /** - * Sets the color's RGB components from the given 3D vector. - * - * @param {Vector3} v - The vector to set. - * @return {Color} A reference to this color. - */ - setFromVector3( v ) { - - this.r = v.x; - this.g = v.y; - this.b = v.z; - - return this; - - } + exponentTable[ 63 ] = 0xc7800000; - /** - * Transforms this color with the given 3x3 matrix. - * - * @param {Matrix3} m - The matrix. - * @return {Color} A reference to this color. - */ - applyMatrix3( m ) { + for ( let i = 1; i < 64; ++ i ) { - const r = this.r, g = this.g, b = this.b; - const e = m.elements; + if ( i !== 32 ) { - this.r = e[ 0 ] * r + e[ 3 ] * g + e[ 6 ] * b; - this.g = e[ 1 ] * r + e[ 4 ] * g + e[ 7 ] * b; - this.b = e[ 2 ] * r + e[ 5 ] * g + e[ 8 ] * b; + offsetTable[ i ] = 1024; - return this; + } } - /** - * Returns `true` if this color is equal with the given one. - * - * @param {Color} c - The color to test for equality. - * @return {boolean} Whether this bounding color is equal with the given one. - */ - equals( c ) { + return { + floatView: floatView, + uint32View: uint32View, + baseTable: baseTable, + shiftTable: shiftTable, + mantissaTable: mantissaTable, + exponentTable: exponentTable, + offsetTable: offsetTable + }; - return ( c.r === this.r ) && ( c.g === this.g ) && ( c.b === this.b ); +} - } +/** + * Returns a half precision floating point value (FP16) from the given single + * precision floating point value (FP32). + * + * @param {number} val - A single precision floating point value. + * @return {number} The FP16 value. + */ +function toHalfFloat( val ) { - /** - * Sets this color's RGB components from the given array. - * - * @param {Array} array - An array holding the RGB values. - * @param {number} [offset=0] - The offset into the array. - * @return {Color} A reference to this color. - */ - fromArray( array, offset = 0 ) { + if ( Math.abs( val ) > 65504 ) warn( 'DataUtils.toHalfFloat(): Value out of range.' ); - this.r = array[ offset ]; - this.g = array[ offset + 1 ]; - this.b = array[ offset + 2 ]; + val = clamp( val, -65504, 65504 ); - return this; + _tables.floatView[ 0 ] = val; + const f = _tables.uint32View[ 0 ]; + const e = ( f >> 23 ) & 0x1ff; + return _tables.baseTable[ e ] + ( ( f & 0x007fffff ) >> _tables.shiftTable[ e ] ); - } +} - /** - * Writes the RGB components of this color to the given array. If no array is provided, - * the method returns a new instance. - * - * @param {Array} [array=[]] - The target array holding the color components. - * @param {number} [offset=0] - Index of the first element in the array. - * @return {Array} The color components. - */ - toArray( array = [], offset = 0 ) { +/** + * Returns a single precision floating point value (FP32) from the given half + * precision floating point value (FP16). + * + * @param {number} val - A half precision floating point value. + * @return {number} The FP32 value. + */ +function fromHalfFloat( val ) { - array[ offset ] = this.r; - array[ offset + 1 ] = this.g; - array[ offset + 2 ] = this.b; + const m = val >> 10; + _tables.uint32View[ 0 ] = _tables.mantissaTable[ _tables.offsetTable[ m ] + ( val & 0x3ff ) ] + _tables.exponentTable[ m ]; + return _tables.floatView[ 0 ]; - return array; +} - } +/** + * A class containing utility functions for data. + * + * @hideconstructor + */ +class DataUtils { /** - * Sets the components of this color from the given buffer attribute. + * Returns a half precision floating point value (FP16) from the given single + * precision floating point value (FP32). * - * @param {BufferAttribute} attribute - The buffer attribute holding color data. - * @param {number} index - The index into the attribute. - * @return {Color} A reference to this color. + * @param {number} val - A single precision floating point value. + * @return {number} The FP16 value. */ - fromBufferAttribute( attribute, index ) { - - this.r = attribute.getX( index ); - this.g = attribute.getY( index ); - this.b = attribute.getZ( index ); + static toHalfFloat( val ) { - return this; + return toHalfFloat( val ); } /** - * This methods defines the serialization result of this class. Returns the color - * as a hexadecimal value. + * Returns a single precision floating point value (FP32) from the given half + * precision floating point value (FP16). * - * @return {number} The hexadecimal value. + * @param {number} val - A half precision floating point value. + * @return {number} The FP32 value. */ - toJSON() { - - return this.getHex(); - - } - - *[ Symbol.iterator ]() { + static fromHalfFloat( val ) { - yield this.r; - yield this.g; - yield this.b; + return fromHalfFloat( val ); } } -const _color = /*@__PURE__*/ new Color(); - -/** - * A dictionary with X11 color names. - * - * Note that multiple words such as Dark Orange become the string 'darkorange'. - * - * @static - * @type {Object} - */ -Color.NAMES = _colorKeywords; +const _vector$a = /*@__PURE__*/ new Vector3(); +const _vector2$1 = /*@__PURE__*/ new Vector2(); -let _materialId = 0; +let _id$2 = 0; /** - * Abstract base class for materials. - * - * Materials define the appearance of renderable 3D objects. + * This class stores data for an attribute (such as vertex positions, face + * indices, normals, colors, UVs, and any custom attributes ) associated with + * a geometry, which allows for more efficient passing of data to the GPU. * - * @abstract - * @augments EventDispatcher + * When working with vector-like data, the `fromBufferAttribute( attribute, index )` + * helper methods on vector and color class might be helpful. E.g. {@link Vector3#fromBufferAttribute}. */ -class Material extends EventDispatcher { +class BufferAttribute { /** - * Constructs a new material. + * Constructs a new buffer attribute. + * + * @param {TypedArray} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - constructor() { + constructor( array, itemSize, normalized = false ) { - super(); + if ( Array.isArray( array ) ) { + + throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); + + } /** * This flag can be used for type testing. @@ -16628,1472 +16582,1010 @@ class Material extends EventDispatcher { * @readonly * @default true */ - this.isMaterial = true; + this.isBufferAttribute = true; /** - * The ID of the material. + * The ID of the buffer attribute. * - * @name Material#id + * @name BufferAttribute#id * @type {number} * @readonly */ - Object.defineProperty( this, 'id', { value: _materialId ++ } ); - - /** - * The UUID of the material. - * - * @type {string} - * @readonly - */ - this.uuid = generateUUID(); + Object.defineProperty( this, 'id', { value: _id$2 ++ } ); /** - * The name of the material. + * The name of the buffer attribute. * * @type {string} */ this.name = ''; /** - * The type property is used for detecting the object type - * in context of serialization/deserialization. + * The array holding the attribute data. It should have `itemSize * numVertices` + * elements, where `numVertices` is the number of vertices in the associated geometry. * - * @type {string} - * @readonly + * @type {TypedArray} */ - this.type = 'Material'; + this.array = array; /** - * Defines the blending type of the material. - * - * It must be set to `CustomBlending` if custom blending properties like - * {@link Material#blendSrc}, {@link Material#blendDst} or {@link Material#blendEquation} - * should have any effect. + * The number of values of the array that should be associated with a particular vertex. + * For instance, if this attribute is storing a 3-component vector (such as a position, + * normal, or color), then the value should be `3`. * - * @type {(NoBlending|NormalBlending|AdditiveBlending|SubtractiveBlending|MultiplyBlending|CustomBlending)} - * @default NormalBlending + * @type {number} */ - this.blending = NormalBlending; + this.itemSize = itemSize; /** - * Defines which side of faces will be rendered - front, back or both. + * Represents the number of items this buffer attribute stores. It is internally computed + * by dividing the `array` length by the `itemSize`. * - * @type {(FrontSide|BackSide|DoubleSide)} - * @default FrontSide + * @type {number} + * @readonly */ - this.side = FrontSide; + this.count = array !== undefined ? array.length / itemSize : 0; /** - * If set to `true`, vertex colors should be used. - * - * The engine supports RGB and RGBA vertex colors depending on whether a three (RGB) or - * four (RGBA) component color buffer attribute is used. + * Applies to integer data only. Indicates how the underlying data in the buffer maps to + * the values in the GLSL code. For instance, if `array` is an instance of `UInt16Array`, + * and `normalized` is `true`, the values `0 - +65535` in the array data will be mapped to + * `0.0f - +1.0f` in the GLSL attribute. If `normalized` is `false`, the values will be converted + * to floats unmodified, i.e. `65535` becomes `65535.0f`. * * @type {boolean} - * @default false */ - this.vertexColors = false; + this.normalized = normalized; /** - * Defines how transparent the material is. - * A value of `0.0` indicates fully transparent, `1.0` is fully opaque. + * Defines the intended usage pattern of the data store for optimization purposes. * - * If the {@link Material#transparent} is not set to `true`, - * the material will remain fully opaque and this value will only affect its color. + * Note: After the initial use of a buffer, its usage cannot be changed. Instead, + * instantiate a new one and set the desired usage before the next render. * - * @type {number} - * @default 1 + * @type {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} + * @default StaticDrawUsage */ - this.opacity = 1; + this.usage = StaticDrawUsage; /** - * Defines whether this material is transparent. This has an effect on - * rendering as transparent objects need special treatment and are rendered - * after non-transparent objects. - * - * When set to true, the extent to which the material is transparent is - * controlled by {@link Material#opacity}. + * This can be used to only update some components of stored vectors (for example, just the + * component related to color). Use the `addUpdateRange()` function to add ranges to this array. * - * @type {boolean} - * @default false + * @type {Array} */ - this.transparent = false; + this.updateRanges = []; /** - * Enables alpha hashed transparency, an alternative to {@link Material#transparent} or - * {@link Material#alphaTest}. The material will not be rendered if opacity is lower than - * a random threshold. Randomization introduces some grain or noise, but approximates alpha - * blending without the associated problems of sorting. Using TAA can reduce the resulting noise. + * Configures the bound GPU type for use in shaders. * - * @type {boolean} - * @default false - */ - this.alphaHash = false; - - /** - * Defines the blending source factor. + * Note: this only has an effect for integer arrays and is not configurable for float arrays. + * For lower precision float types, use `Float16BufferAttribute`. * - * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} - * @default SrcAlphaFactor + * @type {(FloatType|IntType)} + * @default FloatType */ - this.blendSrc = SrcAlphaFactor; + this.gpuType = FloatType; /** - * Defines the blending destination factor. + * A version number, incremented every time the `needsUpdate` is set to `true`. * - * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} - * @default OneMinusSrcAlphaFactor + * @type {number} */ - this.blendDst = OneMinusSrcAlphaFactor; + this.version = 0; - /** - * Defines the blending equation. - * - * @type {(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)} - * @default AddEquation - */ - this.blendEquation = AddEquation; + } - /** - * Defines the blending source alpha factor. - * - * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} - * @default null - */ - this.blendSrcAlpha = null; + /** + * A callback function that is executed after the renderer has transferred the attribute + * array data to the GPU. + */ + onUploadCallback() {} - /** - * Defines the blending destination alpha factor. - * - * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} - * @default null - */ - this.blendDstAlpha = null; + /** + * Flag to indicate that this attribute has changed and should be re-sent to + * the GPU. Set this to `true` when you modify the value of the array. + * + * @type {number} + * @default false + * @param {boolean} value + */ + set needsUpdate( value ) { - /** - * Defines the blending equation of the alpha channel. - * - * @type {?(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)} - * @default null - */ - this.blendEquationAlpha = null; + if ( value === true ) this.version ++; - /** - * Represents the RGB values of the constant blend color. - * - * This property has only an effect when using custom blending with `ConstantColor` or `OneMinusConstantColor`. - * - * @type {Color} - * @default (0,0,0) - */ - this.blendColor = new Color( 0, 0, 0 ); + } - /** - * Represents the alpha value of the constant blend color. - * - * This property has only an effect when using custom blending with `ConstantAlpha` or `OneMinusConstantAlpha`. - * - * @type {number} - * @default 0 - */ - this.blendAlpha = 0; + /** + * Sets the usage of this buffer attribute. + * + * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. + * @return {BufferAttribute} A reference to this buffer attribute. + */ + setUsage( value ) { - /** - * Defines the depth function. - * - * @type {(NeverDepth|AlwaysDepth|LessDepth|LessEqualDepth|EqualDepth|GreaterEqualDepth|GreaterDepth|NotEqualDepth)} - * @default LessEqualDepth - */ - this.depthFunc = LessEqualDepth; + this.usage = value; - /** - * Whether to have depth test enabled when rendering this material. - * When the depth test is disabled, the depth write will also be implicitly disabled. - * - * @type {boolean} - * @default true - */ - this.depthTest = true; + return this; - /** - * Whether rendering this material has any effect on the depth buffer. - * - * When drawing 2D overlays it can be useful to disable the depth writing in - * order to layer several things together without creating z-index artifacts. - * - * @type {boolean} - * @default true - */ - this.depthWrite = true; + } - /** - * The bit mask to use when writing to the stencil buffer. - * - * @type {number} - * @default 0xff - */ - this.stencilWriteMask = 0xff; + /** + * Adds a range of data in the data array to be updated on the GPU. + * + * @param {number} start - Position at which to start update. + * @param {number} count - The number of components to update. + */ + addUpdateRange( start, count ) { - /** - * The stencil comparison function to use. - * - * @type {NeverStencilFunc|LessStencilFunc|EqualStencilFunc|LessEqualStencilFunc|GreaterStencilFunc|NotEqualStencilFunc|GreaterEqualStencilFunc|AlwaysStencilFunc} - * @default AlwaysStencilFunc - */ - this.stencilFunc = AlwaysStencilFunc; - - /** - * The value to use when performing stencil comparisons or stencil operations. - * - * @type {number} - * @default 0 - */ - this.stencilRef = 0; - - /** - * The bit mask to use when comparing against the stencil buffer. - * - * @type {number} - * @default 0xff - */ - this.stencilFuncMask = 0xff; - - /** - * Which stencil operation to perform when the comparison function returns `false`. - * - * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} - * @default KeepStencilOp - */ - this.stencilFail = KeepStencilOp; - - /** - * Which stencil operation to perform when the comparison function returns - * `true` but the depth test fails. - * - * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} - * @default KeepStencilOp - */ - this.stencilZFail = KeepStencilOp; - - /** - * Which stencil operation to perform when the comparison function returns - * `true` and the depth test passes. - * - * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} - * @default KeepStencilOp - */ - this.stencilZPass = KeepStencilOp; - - /** - * Whether stencil operations are performed against the stencil buffer. In - * order to perform writes or comparisons against the stencil buffer this - * value must be `true`. - * - * @type {boolean} - * @default false - */ - this.stencilWrite = false; - - /** - * User-defined clipping planes specified as THREE.Plane objects in world - * space. These planes apply to the objects this material is attached to. - * Points in space whose signed distance to the plane is negative are clipped - * (not rendered). This requires {@link WebGLRenderer#localClippingEnabled} to - * be `true`. - * - * @type {?Array} - * @default null - */ - this.clippingPlanes = null; - - /** - * Changes the behavior of clipping planes so that only their intersection is - * clipped, rather than their union. - * - * @type {boolean} - * @default false - */ - this.clipIntersection = false; - - /** - * Defines whether to clip shadows according to the clipping planes specified - * on this material. - * - * @type {boolean} - * @default false - */ - this.clipShadows = false; - - /** - * Defines which side of faces cast shadows. If `null`, the side casting shadows - * is determined as follows: - * - * - When {@link Material#side} is set to `FrontSide`, the back side cast shadows. - * - When {@link Material#side} is set to `BackSide`, the front side cast shadows. - * - When {@link Material#side} is set to `DoubleSide`, both sides cast shadows. - * - * @type {?(FrontSide|BackSide|DoubleSide)} - * @default null - */ - this.shadowSide = null; - - /** - * Whether to render the material's color. - * - * This can be used in conjunction with {@link Object3D#renderOder} to create invisible - * objects that occlude other objects. - * - * @type {boolean} - * @default true - */ - this.colorWrite = true; - - /** - * Override the renderer's default precision for this material. - * - * @type {?('highp'|'mediump'|'lowp')} - * @default null - */ - this.precision = null; - - /** - * Whether to use polygon offset or not. When enabled, each fragment's depth value will - * be offset after it is interpolated from the depth values of the appropriate vertices. - * The offset is added before the depth test is performed and before the value is written - * into the depth buffer. - * - * Can be useful for rendering hidden-line images, for applying decals to surfaces, and for - * rendering solids with highlighted edges. - * - * @type {boolean} - * @default false - */ - this.polygonOffset = false; - - /** - * Specifies a scale factor that is used to create a variable depth offset for each polygon. - * - * @type {number} - * @default 0 - */ - this.polygonOffsetFactor = 0; - - /** - * Is multiplied by an implementation-specific value to create a constant depth offset. - * - * @type {number} - * @default 0 - */ - this.polygonOffsetUnits = 0; - - /** - * Whether to apply dithering to the color to remove the appearance of banding. - * - * @type {boolean} - * @default false - */ - this.dithering = false; - - /** - * Whether alpha to coverage should be enabled or not. Can only be used with MSAA-enabled contexts - * (meaning when the renderer was created with *antialias* parameter set to `true`). Enabling this - * will smooth aliasing on clip plane edges and alphaTest-clipped edges. - * - * @type {boolean} - * @default false - */ - this.alphaToCoverage = false; + this.updateRanges.push( { start, count } ); - /** - * Whether to premultiply the alpha (transparency) value. - * - * @type {boolean} - * @default false - */ - this.premultipliedAlpha = false; + } - /** - * Whether double-sided, transparent objects should be rendered with a single pass or not. - * - * The engine renders double-sided, transparent objects with two draw calls (back faces first, - * then front faces) to mitigate transparency artifacts. There are scenarios however where this - * approach produces no quality gains but still doubles draw calls e.g. when rendering flat - * vegetation like grass sprites. In these cases, set the `forceSinglePass` flag to `true` to - * disable the two pass rendering to avoid performance issues. - * - * @type {boolean} - * @default false - */ - this.forceSinglePass = false; + /** + * Clears the update ranges. + */ + clearUpdateRanges() { - /** - * Whether it's possible to override the material with {@link Scene#overrideMaterial} or not. - * - * @type {boolean} - * @default true - */ - this.allowOverride = true; + this.updateRanges.length = 0; - /** - * Defines whether 3D objects using this material are visible. - * - * @type {boolean} - * @default true - */ - this.visible = true; + } - /** - * Defines whether this material is tone mapped according to the renderer's tone mapping setting. - * - * It is ignored when rendering to a render target or using post processing or when using - * `WebGPURenderer`. In all these cases, all materials are honored by tone mapping. - * - * @type {boolean} - * @default true - */ - this.toneMapped = true; + /** + * Copies the values of the given buffer attribute to this instance. + * + * @param {BufferAttribute} source - The buffer attribute to copy. + * @return {BufferAttribute} A reference to this instance. + */ + copy( source ) { - /** - * An object that can be used to store custom data about the Material. It - * should not hold references to functions as these will not be cloned. - * - * @type {Object} - */ - this.userData = {}; + this.name = source.name; + this.array = new source.array.constructor( source.array ); + this.itemSize = source.itemSize; + this.count = source.count; + this.normalized = source.normalized; - /** - * This starts at `0` and counts how many times {@link Material#needsUpdate} is set to `true`. - * - * @type {number} - * @readonly - * @default 0 - */ - this.version = 0; + this.usage = source.usage; + this.gpuType = source.gpuType; - this._alphaTest = 0; + return this; } /** - * Sets the alpha value to be used when running an alpha test. The material - * will not be rendered if the opacity is lower than this value. + * Copies a vector from the given buffer attribute to this one. The start + * and destination position in the attribute buffers are represented by the + * given indices. * - * @type {number} - * @readonly - * @default 0 + * @param {number} index1 - The destination index into this buffer attribute. + * @param {BufferAttribute} attribute - The buffer attribute to copy from. + * @param {number} index2 - The source index into the given buffer attribute. + * @return {BufferAttribute} A reference to this instance. */ - get alphaTest() { - - return this._alphaTest; - - } + copyAt( index1, attribute, index2 ) { - set alphaTest( value ) { + index1 *= this.itemSize; + index2 *= attribute.itemSize; - if ( this._alphaTest > 0 !== value > 0 ) { + for ( let i = 0, l = this.itemSize; i < l; i ++ ) { - this.version ++; + this.array[ index1 + i ] = attribute.array[ index2 + i ]; } - this._alphaTest = value; + return this; } /** - * An optional callback that is executed immediately before the material is used to render a 3D object. - * - * This method can only be used when rendering with {@link WebGLRenderer}. - * - * @param {WebGLRenderer} renderer - The renderer. - * @param {Scene} scene - The scene. - * @param {Camera} camera - The camera that is used to render the scene. - * @param {BufferGeometry} geometry - The 3D object's geometry. - * @param {Object3D} object - The 3D object. - * @param {Object} group - The geometry group data. - */ - onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {} - - /** - * An optional callback that is executed immediately before the shader - * program is compiled. This function is called with the shader source code - * as a parameter. Useful for the modification of built-in materials. - * - * This method can only be used when rendering with {@link WebGLRenderer}. The - * recommended approach when customizing materials is to use `WebGPURenderer` with the new - * Node Material system and [TSL](https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language). + * Copies the given array data into this buffer attribute. * - * @param {{vertexShader:string,fragmentShader:string,uniforms:Object}} shaderobject - The object holds the uniforms and the vertex and fragment shader source. - * @param {WebGLRenderer} renderer - A reference to the renderer. + * @param {(TypedArray|Array)} array - The array to copy. + * @return {BufferAttribute} A reference to this instance. */ - onBeforeCompile( /* shaderobject, renderer */ ) {} + copyArray( array ) { - /** - * In case {@link Material#onBeforeCompile} is used, this callback can be used to identify - * values of settings used in `onBeforeCompile()`, so three.js can reuse a cached - * shader or recompile the shader for this material as needed. - * - * This method can only be used when rendering with {@link WebGLRenderer}. - * - * @return {string} The custom program cache key. - */ - customProgramCacheKey() { + this.array.set( array ); - return this.onBeforeCompile.toString(); + return this; } /** - * This method can be used to set default values from parameter objects. - * It is a generic implementation so it can be used with different types - * of materials. + * Applies the given 3x3 matrix to the given attribute. Works with + * item size `2` and `3`. * - * @param {Object} [values] - The material values to set. + * @param {Matrix3} m - The matrix to apply. + * @return {BufferAttribute} A reference to this instance. */ - setValues( values ) { - - if ( values === undefined ) return; + applyMatrix3( m ) { - for ( const key in values ) { + if ( this.itemSize === 2 ) { - const newValue = values[ key ]; + for ( let i = 0, l = this.count; i < l; i ++ ) { - if ( newValue === undefined ) { + _vector2$1.fromBufferAttribute( this, i ); + _vector2$1.applyMatrix3( m ); - warn( `Material: parameter '${ key }' has value of undefined.` ); - continue; + this.setXY( i, _vector2$1.x, _vector2$1.y ); } - const currentValue = this[ key ]; + } else if ( this.itemSize === 3 ) { - if ( currentValue === undefined ) { + for ( let i = 0, l = this.count; i < l; i ++ ) { - warn( `Material: '${ key }' is not a property of THREE.${ this.type }.` ); - continue; + _vector$a.fromBufferAttribute( this, i ); + _vector$a.applyMatrix3( m ); + + this.setXYZ( i, _vector$a.x, _vector$a.y, _vector$a.z ); } - if ( currentValue && currentValue.isColor ) { + } - currentValue.set( newValue ); + return this; - } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { + } - currentValue.copy( newValue ); + /** + * Applies the given 4x4 matrix to the given attribute. Only works with + * item size `3`. + * + * @param {Matrix4} m - The matrix to apply. + * @return {BufferAttribute} A reference to this instance. + */ + applyMatrix4( m ) { - } else { + for ( let i = 0, l = this.count; i < l; i ++ ) { - this[ key ] = newValue; + _vector$a.fromBufferAttribute( this, i ); - } + _vector$a.applyMatrix4( m ); + + this.setXYZ( i, _vector$a.x, _vector$a.y, _vector$a.z ); } + return this; + } /** - * Serializes the material into JSON. + * Applies the given 3x3 normal matrix to the given attribute. Only works with + * item size `3`. * - * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized material. - * @see {@link ObjectLoader#parse} + * @param {Matrix3} m - The normal matrix to apply. + * @return {BufferAttribute} A reference to this instance. */ - toJSON( meta ) { - - const isRootObject = ( meta === undefined || typeof meta === 'string' ); + applyNormalMatrix( m ) { - if ( isRootObject ) { + for ( let i = 0, l = this.count; i < l; i ++ ) { - meta = { - textures: {}, - images: {} - }; + _vector$a.fromBufferAttribute( this, i ); - } + _vector$a.applyNormalMatrix( m ); - const data = { - metadata: { - version: 4.7, - type: 'Material', - generator: 'Material.toJSON' - } - }; + this.setXYZ( i, _vector$a.x, _vector$a.y, _vector$a.z ); - // standard Material serialization - data.uuid = this.uuid; - data.type = this.type; + } - if ( this.name !== '' ) data.name = this.name; + return this; - if ( this.color && this.color.isColor ) data.color = this.color.getHex(); + } - if ( this.roughness !== undefined ) data.roughness = this.roughness; - if ( this.metalness !== undefined ) data.metalness = this.metalness; + /** + * Applies the given 4x4 matrix to the given attribute. Only works with + * item size `3` and with direction vectors. + * + * @param {Matrix4} m - The matrix to apply. + * @return {BufferAttribute} A reference to this instance. + */ + transformDirection( m ) { - if ( this.sheen !== undefined ) data.sheen = this.sheen; - if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex(); - if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness; - if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); - if ( this.emissiveIntensity !== undefined && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; + for ( let i = 0, l = this.count; i < l; i ++ ) { - if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); - if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity; - if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex(); - if ( this.shininess !== undefined ) data.shininess = this.shininess; - if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; - if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; + _vector$a.fromBufferAttribute( this, i ); - if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { + _vector$a.transformDirection( m ); - data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; + this.setXYZ( i, _vector$a.x, _vector$a.y, _vector$a.z ); } - if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { + return this; - data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; + } - } + /** + * Sets the given array data in the buffer attribute. + * + * @param {(TypedArray|Array)} value - The array data to set. + * @param {number} [offset=0] - The offset in this buffer attribute's array. + * @return {BufferAttribute} A reference to this instance. + */ + set( value, offset = 0 ) { - if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { + // Matching BufferAttribute constructor, do not normalize the array. + this.array.set( value, offset ); - data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; - data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); + return this; - } + } - if ( this.sheenColorMap && this.sheenColorMap.isTexture ) { + /** + * Returns the given component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} component - The component index. + * @return {number} The returned value. + */ + getComponent( index, component ) { - data.sheenColorMap = this.sheenColorMap.toJSON( meta ).uuid; + let value = this.array[ index * this.itemSize + component ]; - } + if ( this.normalized ) value = denormalize( value, this.array ); - if ( this.sheenRoughnessMap && this.sheenRoughnessMap.isTexture ) { + return value; - data.sheenRoughnessMap = this.sheenRoughnessMap.toJSON( meta ).uuid; + } - } + /** + * Sets the given value to the given component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} component - The component index. + * @param {number} value - The value to set. + * @return {BufferAttribute} A reference to this instance. + */ + setComponent( index, component, value ) { - if ( this.dispersion !== undefined ) data.dispersion = this.dispersion; + if ( this.normalized ) value = normalize( value, this.array ); - if ( this.iridescence !== undefined ) data.iridescence = this.iridescence; - if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR; - if ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange; + this.array[ index * this.itemSize + component ] = value; - if ( this.iridescenceMap && this.iridescenceMap.isTexture ) { + return this; - data.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid; + } - } + /** + * Returns the x component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The x component. + */ + getX( index ) { - if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) { + let x = this.array[ index * this.itemSize ]; - data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid; + if ( this.normalized ) x = denormalize( x, this.array ); - } + return x; - if ( this.anisotropy !== undefined ) data.anisotropy = this.anisotropy; - if ( this.anisotropyRotation !== undefined ) data.anisotropyRotation = this.anisotropyRotation; + } - if ( this.anisotropyMap && this.anisotropyMap.isTexture ) { + /** + * Sets the x component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value to set. + * @return {BufferAttribute} A reference to this instance. + */ + setX( index, x ) { - data.anisotropyMap = this.anisotropyMap.toJSON( meta ).uuid; + if ( this.normalized ) x = normalize( x, this.array ); - } + this.array[ index * this.itemSize ] = x; - if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; - if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; - if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; + return this; - if ( this.lightMap && this.lightMap.isTexture ) { + } - data.lightMap = this.lightMap.toJSON( meta ).uuid; - data.lightMapIntensity = this.lightMapIntensity; + /** + * Returns the y component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The y component. + */ + getY( index ) { - } + let y = this.array[ index * this.itemSize + 1 ]; - if ( this.aoMap && this.aoMap.isTexture ) { + if ( this.normalized ) y = denormalize( y, this.array ); - data.aoMap = this.aoMap.toJSON( meta ).uuid; - data.aoMapIntensity = this.aoMapIntensity; + return y; - } + } - if ( this.bumpMap && this.bumpMap.isTexture ) { + /** + * Sets the y component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} y - The value to set. + * @return {BufferAttribute} A reference to this instance. + */ + setY( index, y ) { - data.bumpMap = this.bumpMap.toJSON( meta ).uuid; - data.bumpScale = this.bumpScale; + if ( this.normalized ) y = normalize( y, this.array ); - } + this.array[ index * this.itemSize + 1 ] = y; - if ( this.normalMap && this.normalMap.isTexture ) { + return this; - data.normalMap = this.normalMap.toJSON( meta ).uuid; - data.normalMapType = this.normalMapType; - data.normalScale = this.normalScale.toArray(); + } - } + /** + * Returns the z component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The z component. + */ + getZ( index ) { - if ( this.displacementMap && this.displacementMap.isTexture ) { + let z = this.array[ index * this.itemSize + 2 ]; - data.displacementMap = this.displacementMap.toJSON( meta ).uuid; - data.displacementScale = this.displacementScale; - data.displacementBias = this.displacementBias; + if ( this.normalized ) z = denormalize( z, this.array ); - } + return z; - if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; - if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; + } - if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; - if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; - if ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid; - if ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid; + /** + * Sets the z component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} z - The value to set. + * @return {BufferAttribute} A reference to this instance. + */ + setZ( index, z ) { - if ( this.envMap && this.envMap.isTexture ) { + if ( this.normalized ) z = normalize( z, this.array ); - data.envMap = this.envMap.toJSON( meta ).uuid; + this.array[ index * this.itemSize + 2 ] = z; - if ( this.combine !== undefined ) data.combine = this.combine; + return this; - } + } - if ( this.envMapRotation !== undefined ) data.envMapRotation = this.envMapRotation.toArray(); - if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; - if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity; - if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio; + /** + * Returns the w component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The w component. + */ + getW( index ) { - if ( this.gradientMap && this.gradientMap.isTexture ) { + let w = this.array[ index * this.itemSize + 3 ]; - data.gradientMap = this.gradientMap.toJSON( meta ).uuid; + if ( this.normalized ) w = denormalize( w, this.array ); - } + return w; - if ( this.transmission !== undefined ) data.transmission = this.transmission; - if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid; - if ( this.thickness !== undefined ) data.thickness = this.thickness; - if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid; - if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance; - if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex(); + } - if ( this.size !== undefined ) data.size = this.size; - if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide; - if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; + /** + * Sets the w component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} w - The value to set. + * @return {BufferAttribute} A reference to this instance. + */ + setW( index, w ) { - if ( this.blending !== NormalBlending ) data.blending = this.blending; - if ( this.side !== FrontSide ) data.side = this.side; - if ( this.vertexColors === true ) data.vertexColors = true; + if ( this.normalized ) w = normalize( w, this.array ); - if ( this.opacity < 1 ) data.opacity = this.opacity; - if ( this.transparent === true ) data.transparent = true; + this.array[ index * this.itemSize + 3 ] = w; - if ( this.blendSrc !== SrcAlphaFactor ) data.blendSrc = this.blendSrc; - if ( this.blendDst !== OneMinusSrcAlphaFactor ) data.blendDst = this.blendDst; - if ( this.blendEquation !== AddEquation ) data.blendEquation = this.blendEquation; - if ( this.blendSrcAlpha !== null ) data.blendSrcAlpha = this.blendSrcAlpha; - if ( this.blendDstAlpha !== null ) data.blendDstAlpha = this.blendDstAlpha; - if ( this.blendEquationAlpha !== null ) data.blendEquationAlpha = this.blendEquationAlpha; - if ( this.blendColor && this.blendColor.isColor ) data.blendColor = this.blendColor.getHex(); - if ( this.blendAlpha !== 0 ) data.blendAlpha = this.blendAlpha; + return this; - if ( this.depthFunc !== LessEqualDepth ) data.depthFunc = this.depthFunc; - if ( this.depthTest === false ) data.depthTest = this.depthTest; - if ( this.depthWrite === false ) data.depthWrite = this.depthWrite; - if ( this.colorWrite === false ) data.colorWrite = this.colorWrite; + } - if ( this.stencilWriteMask !== 0xff ) data.stencilWriteMask = this.stencilWriteMask; - if ( this.stencilFunc !== AlwaysStencilFunc ) data.stencilFunc = this.stencilFunc; - if ( this.stencilRef !== 0 ) data.stencilRef = this.stencilRef; - if ( this.stencilFuncMask !== 0xff ) data.stencilFuncMask = this.stencilFuncMask; - if ( this.stencilFail !== KeepStencilOp ) data.stencilFail = this.stencilFail; - if ( this.stencilZFail !== KeepStencilOp ) data.stencilZFail = this.stencilZFail; - if ( this.stencilZPass !== KeepStencilOp ) data.stencilZPass = this.stencilZPass; - if ( this.stencilWrite === true ) data.stencilWrite = this.stencilWrite; + /** + * Sets the x and y component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @return {BufferAttribute} A reference to this instance. + */ + setXY( index, x, y ) { - // rotation (SpriteMaterial) - if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation; + index *= this.itemSize; - if ( this.polygonOffset === true ) data.polygonOffset = true; - if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; - if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; + if ( this.normalized ) { - if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth; - if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; - if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; - if ( this.scale !== undefined ) data.scale = this.scale; + x = normalize( x, this.array ); + y = normalize( y, this.array ); - if ( this.dithering === true ) data.dithering = true; + } - if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; - if ( this.alphaHash === true ) data.alphaHash = true; - if ( this.alphaToCoverage === true ) data.alphaToCoverage = true; - if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true; - if ( this.forceSinglePass === true ) data.forceSinglePass = true; - if ( this.allowOverride === false ) data.allowOverride = false; + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; - if ( this.wireframe === true ) data.wireframe = true; - if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; - if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; - if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; + return this; - if ( this.flatShading === true ) data.flatShading = true; + } - if ( this.visible === false ) data.visible = false; + /** + * Sets the x, y and z component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @param {number} z - The value for the z component to set. + * @return {BufferAttribute} A reference to this instance. + */ + setXYZ( index, x, y, z ) { - if ( this.toneMapped === false ) data.toneMapped = false; + index *= this.itemSize; - if ( this.fog === false ) data.fog = false; + if ( this.normalized ) { - if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); - // TODO: Copied from Object3D.toJSON + } - function extractFromCache( cache ) { + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; - const values = []; + return this; - for ( const key in cache ) { + } - const data = cache[ key ]; - delete data.metadata; - values.push( data ); + /** + * Sets the x, y, z and w component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @param {number} z - The value for the z component to set. + * @param {number} w - The value for the w component to set. + * @return {BufferAttribute} A reference to this instance. + */ + setXYZW( index, x, y, z, w ) { - } + index *= this.itemSize; - return values; + if ( this.normalized ) { + + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); } - if ( isRootObject ) { + this.array[ index + 0 ] = x; + this.array[ index + 1 ] = y; + this.array[ index + 2 ] = z; + this.array[ index + 3 ] = w; - const textures = extractFromCache( meta.textures ); - const images = extractFromCache( meta.images ); + return this; - if ( textures.length > 0 ) data.textures = textures; - if ( images.length > 0 ) data.images = images; + } - } + /** + * Sets the given callback function that is executed after the Renderer has transferred + * the attribute array data to the GPU. Can be used to perform clean-up operations after + * the upload when attribute data are not needed anymore on the CPU side. + * + * @param {Function} callback - The `onUpload()` callback. + * @return {BufferAttribute} A reference to this instance. + */ + onUpload( callback ) { - return data; + this.onUploadCallback = callback; + + return this; } /** - * Returns a new material with copied values from this instance. + * Returns a new buffer attribute with copied values from this instance. * - * @return {Material} A clone of this instance. + * @return {BufferAttribute} A clone of this instance. */ clone() { - return new this.constructor().copy( this ); + return new this.constructor( this.array, this.itemSize ).copy( this ); } /** - * Copies the values of the given material to this instance. + * Serializes the buffer attribute into JSON. * - * @param {Material} source - The material to copy. - * @return {Material} A reference to this instance. + * @return {Object} A JSON object representing the serialized buffer attribute. */ - copy( source ) { - - this.name = source.name; + toJSON() { - this.blending = source.blending; - this.side = source.side; - this.vertexColors = source.vertexColors; + const data = { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: Array.from( this.array ), + normalized: this.normalized + }; - this.opacity = source.opacity; - this.transparent = source.transparent; + if ( this.name !== '' ) data.name = this.name; + if ( this.usage !== StaticDrawUsage ) data.usage = this.usage; - this.blendSrc = source.blendSrc; - this.blendDst = source.blendDst; - this.blendEquation = source.blendEquation; - this.blendSrcAlpha = source.blendSrcAlpha; - this.blendDstAlpha = source.blendDstAlpha; - this.blendEquationAlpha = source.blendEquationAlpha; - this.blendColor.copy( source.blendColor ); - this.blendAlpha = source.blendAlpha; + return data; - this.depthFunc = source.depthFunc; - this.depthTest = source.depthTest; - this.depthWrite = source.depthWrite; + } - this.stencilWriteMask = source.stencilWriteMask; - this.stencilFunc = source.stencilFunc; - this.stencilRef = source.stencilRef; - this.stencilFuncMask = source.stencilFuncMask; - this.stencilFail = source.stencilFail; - this.stencilZFail = source.stencilZFail; - this.stencilZPass = source.stencilZPass; - this.stencilWrite = source.stencilWrite; +} - const srcPlanes = source.clippingPlanes; - let dstPlanes = null; +/** + * Convenient class that can be used when creating a `Int8` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Int8BufferAttribute extends BufferAttribute { - if ( srcPlanes !== null ) { + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Int8Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { - const n = srcPlanes.length; - dstPlanes = new Array( n ); + super( new Int8Array( array ), itemSize, normalized ); - for ( let i = 0; i !== n; ++ i ) { + } - dstPlanes[ i ] = srcPlanes[ i ].clone(); +} - } +/** + * Convenient class that can be used when creating a `UInt8` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Uint8BufferAttribute extends BufferAttribute { - } + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Uint8Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { - this.clippingPlanes = dstPlanes; - this.clipIntersection = source.clipIntersection; - this.clipShadows = source.clipShadows; + super( new Uint8Array( array ), itemSize, normalized ); - this.shadowSide = source.shadowSide; + } - this.colorWrite = source.colorWrite; +} - this.precision = source.precision; +/** + * Convenient class that can be used when creating a `UInt8Clamped` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Uint8ClampedBufferAttribute extends BufferAttribute { - this.polygonOffset = source.polygonOffset; - this.polygonOffsetFactor = source.polygonOffsetFactor; - this.polygonOffsetUnits = source.polygonOffsetUnits; + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Uint8ClampedArray)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { - this.dithering = source.dithering; + super( new Uint8ClampedArray( array ), itemSize, normalized ); - this.alphaTest = source.alphaTest; - this.alphaHash = source.alphaHash; - this.alphaToCoverage = source.alphaToCoverage; - this.premultipliedAlpha = source.premultipliedAlpha; - this.forceSinglePass = source.forceSinglePass; - this.allowOverride = source.allowOverride; + } - this.visible = source.visible; +} - this.toneMapped = source.toneMapped; +/** + * Convenient class that can be used when creating a `Int16` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Int16BufferAttribute extends BufferAttribute { - this.userData = JSON.parse( JSON.stringify( source.userData ) ); + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Int16Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { - return this; + super( new Int16Array( array ), itemSize, normalized ); } +} + +/** + * Convenient class that can be used when creating a `UInt16` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Uint16BufferAttribute extends BufferAttribute { + /** - * Frees the GPU-related resources allocated by this instance. Call this - * method whenever this instance is no longer used in your app. + * Constructs a new buffer attribute. * - * @fires Material#dispose + * @param {(Array|Uint16Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - dispose() { + constructor( array, itemSize, normalized ) { - /** - * Fires when the material has been disposed of. - * - * @event Material#dispose - * @type {Object} - */ - this.dispatchEvent( { type: 'dispose' } ); + super( new Uint16Array( array ), itemSize, normalized ); } +} + +/** + * Convenient class that can be used when creating a `Int32` buffer attribute with + * a plain `Array` instance. + * + * @augments BufferAttribute + */ +class Int32BufferAttribute extends BufferAttribute { + /** - * Setting this property to `true` indicates the engine the material - * needs to be recompiled. + * Constructs a new buffer attribute. * - * @type {boolean} - * @default false - * @param {boolean} value + * @param {(Array|Int32Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - set needsUpdate( value ) { + constructor( array, itemSize, normalized ) { - if ( value === true ) this.version ++; + super( new Int32Array( array ), itemSize, normalized ); } } /** - * A material for drawing geometries in a simple shaded (flat or wireframe) way. - * - * This material is not affected by lights. + * Convenient class that can be used when creating a `UInt32` buffer attribute with + * a plain `Array` instance. * - * @augments Material - * @demo scenes/material-browser.html#MeshBasicMaterial + * @augments BufferAttribute */ -class MeshBasicMaterial extends Material { +class Uint32BufferAttribute extends BufferAttribute { /** - * Constructs a new mesh basic material. + * Constructs a new buffer attribute. * - * @param {Object} [parameters] - An object with one or more properties - * defining the material's appearance. Any property of the material - * (including any property from inherited materials) can be passed - * in here. Color values can be passed any type of value accepted - * by {@link Color#set}. + * @param {(Array|Uint32Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - constructor( parameters ) { - - super(); + constructor( array, itemSize, normalized ) { - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isMeshBasicMaterial = true; + super( new Uint32Array( array ), itemSize, normalized ); - this.type = 'MeshBasicMaterial'; + } - /** - * Color of the material. - * - * @type {Color} - * @default (1,1,1) - */ - this.color = new Color( 0xffffff ); // diffuse +} - /** - * The color map. May optionally include an alpha channel, typically combined - * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map - * color is modulated by the diffuse `color`. - * - * @type {?Texture} - * @default null - */ - this.map = null; - - /** - * The light map. Requires a second set of UVs. - * - * @type {?Texture} - * @default null - */ - this.lightMap = null; - - /** - * Intensity of the baked light. - * - * @type {number} - * @default 1 - */ - this.lightMapIntensity = 1.0; - - /** - * The red channel of this texture is used as the ambient occlusion map. - * Requires a second set of UVs. - * - * @type {?Texture} - * @default null - */ - this.aoMap = null; - - /** - * Intensity of the ambient occlusion effect. Range is `[0,1]`, where `0` - * disables ambient occlusion. Where intensity is `1` and the AO map's - * red channel is also `1`, ambient light is fully occluded on a surface. - * - * @type {number} - * @default 1 - */ - this.aoMapIntensity = 1.0; +/** + * Convenient class that can be used when creating a `Float16` buffer attribute with + * a plain `Array` instance. + * + * This class automatically converts to and from FP16 via `Uint16Array` since `Float16Array` + * browser support is still problematic. + * + * @augments BufferAttribute + */ +class Float16BufferAttribute extends BufferAttribute { - /** - * Specular map used by the material. - * - * @type {?Texture} - * @default null - */ - this.specularMap = null; + /** + * Constructs a new buffer attribute. + * + * @param {(Array|Uint16Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( array, itemSize, normalized ) { - /** - * The alpha map is a grayscale texture that controls the opacity across the - * surface (black: fully transparent; white: fully opaque). - * - * Only the color of the texture is used, ignoring the alpha channel if one - * exists. For RGB and RGBA textures, the renderer will use the green channel - * when sampling this texture due to the extra bit of precision provided for - * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and - * luminance/alpha textures will also still work as expected. - * - * @type {?Texture} - * @default null - */ - this.alphaMap = null; + super( new Uint16Array( array ), itemSize, normalized ); - /** - * The environment map. - * - * @type {?Texture} - * @default null - */ - this.envMap = null; + this.isFloat16BufferAttribute = true; - /** - * The rotation of the environment map in radians. - * - * @type {Euler} - * @default (0,0,0) - */ - this.envMapRotation = new Euler(); + } - /** - * How to combine the result of the surface's color with the environment map, if any. - * - * When set to `MixOperation`, the {@link MeshBasicMaterial#reflectivity} is used to - * blend between the two colors. - * - * @type {(MultiplyOperation|MixOperation|AddOperation)} - * @default MultiplyOperation - */ - this.combine = MultiplyOperation; + getX( index ) { - /** - * How much the environment map affects the surface. - * The valid range is between `0` (no reflections) and `1` (full reflections). - * - * @type {number} - * @default 1 - */ - this.reflectivity = 1; + let x = fromHalfFloat( this.array[ index * this.itemSize ] ); - /** - * The index of refraction (IOR) of air (approximately 1) divided by the - * index of refraction of the material. It is used with environment mapping - * modes {@link CubeRefractionMapping} and {@link EquirectangularRefractionMapping}. - * The refraction ratio should not exceed `1`. - * - * @type {number} - * @default 0.98 - */ - this.refractionRatio = 0.98; + if ( this.normalized ) x = denormalize( x, this.array ); - /** - * Renders the geometry as a wireframe. - * - * @type {boolean} - * @default false - */ - this.wireframe = false; + return x; - /** - * Controls the thickness of the wireframe. - * - * Can only be used with {@link SVGRenderer}. - * - * @type {number} - * @default 1 - */ - this.wireframeLinewidth = 1; + } - /** - * Defines appearance of wireframe ends. - * - * Can only be used with {@link SVGRenderer}. - * - * @type {('round'|'bevel'|'miter')} - * @default 'round' - */ - this.wireframeLinecap = 'round'; + setX( index, x ) { - /** - * Defines appearance of wireframe joints. - * - * Can only be used with {@link SVGRenderer}. - * - * @type {('round'|'bevel'|'miter')} - * @default 'round' - */ - this.wireframeLinejoin = 'round'; + if ( this.normalized ) x = normalize( x, this.array ); - /** - * Whether the material is affected by fog or not. - * - * @type {boolean} - * @default true - */ - this.fog = true; + this.array[ index * this.itemSize ] = toHalfFloat( x ); - this.setValues( parameters ); + return this; } - copy( source ) { - - super.copy( source ); - - this.color.copy( source.color ); - - this.map = source.map; + getY( index ) { - this.lightMap = source.lightMap; - this.lightMapIntensity = source.lightMapIntensity; + let y = fromHalfFloat( this.array[ index * this.itemSize + 1 ] ); - this.aoMap = source.aoMap; - this.aoMapIntensity = source.aoMapIntensity; + if ( this.normalized ) y = denormalize( y, this.array ); - this.specularMap = source.specularMap; + return y; - this.alphaMap = source.alphaMap; + } - this.envMap = source.envMap; - this.envMapRotation.copy( source.envMapRotation ); - this.combine = source.combine; - this.reflectivity = source.reflectivity; - this.refractionRatio = source.refractionRatio; + setY( index, y ) { - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - this.wireframeLinecap = source.wireframeLinecap; - this.wireframeLinejoin = source.wireframeLinejoin; + if ( this.normalized ) y = normalize( y, this.array ); - this.fog = source.fog; + this.array[ index * this.itemSize + 1 ] = toHalfFloat( y ); return this; } -} - -// Fast Half Float Conversions, http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf - -const _tables = /*@__PURE__*/ _generateTables(); - -function _generateTables() { - - // float32 to float16 helpers - - const buffer = new ArrayBuffer( 4 ); - const floatView = new Float32Array( buffer ); - const uint32View = new Uint32Array( buffer ); - - const baseTable = new Uint32Array( 512 ); - const shiftTable = new Uint32Array( 512 ); + getZ( index ) { - for ( let i = 0; i < 256; ++ i ) { + let z = fromHalfFloat( this.array[ index * this.itemSize + 2 ] ); - const e = i - 127; + if ( this.normalized ) z = denormalize( z, this.array ); - // very small number (0, -0) + return z; - if ( e < -27 ) { + } - baseTable[ i ] = 0x0000; - baseTable[ i | 0x100 ] = 0x8000; - shiftTable[ i ] = 24; - shiftTable[ i | 0x100 ] = 24; + setZ( index, z ) { - // small number (denorm) + if ( this.normalized ) z = normalize( z, this.array ); - } else if ( e < -14 ) { + this.array[ index * this.itemSize + 2 ] = toHalfFloat( z ); - baseTable[ i ] = 0x0400 >> ( - e - 14 ); - baseTable[ i | 0x100 ] = ( 0x0400 >> ( - e - 14 ) ) | 0x8000; - shiftTable[ i ] = - e - 1; - shiftTable[ i | 0x100 ] = - e - 1; + return this; - // normal number + } - } else if ( e <= 15 ) { + getW( index ) { - baseTable[ i ] = ( e + 15 ) << 10; - baseTable[ i | 0x100 ] = ( ( e + 15 ) << 10 ) | 0x8000; - shiftTable[ i ] = 13; - shiftTable[ i | 0x100 ] = 13; + let w = fromHalfFloat( this.array[ index * this.itemSize + 3 ] ); - // large number (Infinity, -Infinity) + if ( this.normalized ) w = denormalize( w, this.array ); - } else if ( e < 128 ) { + return w; - baseTable[ i ] = 0x7c00; - baseTable[ i | 0x100 ] = 0xfc00; - shiftTable[ i ] = 24; - shiftTable[ i | 0x100 ] = 24; + } - // stay (NaN, Infinity, -Infinity) + setW( index, w ) { - } else { + if ( this.normalized ) w = normalize( w, this.array ); - baseTable[ i ] = 0x7c00; - baseTable[ i | 0x100 ] = 0xfc00; - shiftTable[ i ] = 13; - shiftTable[ i | 0x100 ] = 13; + this.array[ index * this.itemSize + 3 ] = toHalfFloat( w ); - } + return this; } - // float16 to float32 helpers - - const mantissaTable = new Uint32Array( 2048 ); - const exponentTable = new Uint32Array( 64 ); - const offsetTable = new Uint32Array( 64 ); - - for ( let i = 1; i < 1024; ++ i ) { + setXY( index, x, y ) { - let m = i << 13; // zero pad mantissa bits - let e = 0; // zero exponent + index *= this.itemSize; - // normalized - while ( ( m & 0x00800000 ) === 0 ) { + if ( this.normalized ) { - m <<= 1; - e -= 0x00800000; // decrement exponent + x = normalize( x, this.array ); + y = normalize( y, this.array ); } - m &= -8388609; // clear leading 1 bit - e += 0x38800000; // adjust bias + this.array[ index + 0 ] = toHalfFloat( x ); + this.array[ index + 1 ] = toHalfFloat( y ); - mantissaTable[ i ] = m | e; + return this; } - for ( let i = 1024; i < 2048; ++ i ) { - - mantissaTable[ i ] = 0x38000000 + ( ( i - 1024 ) << 13 ); - - } + setXYZ( index, x, y, z ) { - for ( let i = 1; i < 31; ++ i ) { + index *= this.itemSize; - exponentTable[ i ] = i << 23; + if ( this.normalized ) { - } + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); - exponentTable[ 31 ] = 0x47800000; - exponentTable[ 32 ] = 0x80000000; + } - for ( let i = 33; i < 63; ++ i ) { + this.array[ index + 0 ] = toHalfFloat( x ); + this.array[ index + 1 ] = toHalfFloat( y ); + this.array[ index + 2 ] = toHalfFloat( z ); - exponentTable[ i ] = 0x80000000 + ( ( i - 32 ) << 23 ); + return this; } - exponentTable[ 63 ] = 0xc7800000; + setXYZW( index, x, y, z, w ) { - for ( let i = 1; i < 64; ++ i ) { + index *= this.itemSize; - if ( i !== 32 ) { + if ( this.normalized ) { - offsetTable[ i ] = 1024; + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); } - } - - return { - floatView: floatView, - uint32View: uint32View, - baseTable: baseTable, - shiftTable: shiftTable, - mantissaTable: mantissaTable, - exponentTable: exponentTable, - offsetTable: offsetTable - }; - -} - -/** - * Returns a half precision floating point value (FP16) from the given single - * precision floating point value (FP32). - * - * @param {number} val - A single precision floating point value. - * @return {number} The FP16 value. - */ -function toHalfFloat( val ) { - - if ( Math.abs( val ) > 65504 ) warn( 'DataUtils.toHalfFloat(): Value out of range.' ); - - val = clamp( val, -65504, 65504 ); - - _tables.floatView[ 0 ] = val; - const f = _tables.uint32View[ 0 ]; - const e = ( f >> 23 ) & 0x1ff; - return _tables.baseTable[ e ] + ( ( f & 0x007fffff ) >> _tables.shiftTable[ e ] ); - -} + this.array[ index + 0 ] = toHalfFloat( x ); + this.array[ index + 1 ] = toHalfFloat( y ); + this.array[ index + 2 ] = toHalfFloat( z ); + this.array[ index + 3 ] = toHalfFloat( w ); -/** - * Returns a single precision floating point value (FP32) from the given half - * precision floating point value (FP16). - * - * @param {number} val - A half precision floating point value. - * @return {number} The FP32 value. - */ -function fromHalfFloat( val ) { + return this; - const m = val >> 10; - _tables.uint32View[ 0 ] = _tables.mantissaTable[ _tables.offsetTable[ m ] + ( val & 0x3ff ) ] + _tables.exponentTable[ m ]; - return _tables.floatView[ 0 ]; + } } /** - * A class containing utility functions for data. + * Convenient class that can be used when creating a `Float32` buffer attribute with + * a plain `Array` instance. * - * @hideconstructor + * @augments BufferAttribute */ -class DataUtils { - - /** - * Returns a half precision floating point value (FP16) from the given single - * precision floating point value (FP32). - * - * @param {number} val - A single precision floating point value. - * @return {number} The FP16 value. - */ - static toHalfFloat( val ) { - - return toHalfFloat( val ); - - } +class Float32BufferAttribute extends BufferAttribute { /** - * Returns a single precision floating point value (FP32) from the given half - * precision floating point value (FP16). + * Constructs a new buffer attribute. * - * @param {number} val - A half precision floating point value. - * @return {number} The FP32 value. + * @param {(Array|Float32Array)} array - The array holding the attribute data. + * @param {number} itemSize - The item size. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. */ - static fromHalfFloat( val ) { + constructor( array, itemSize, normalized ) { - return fromHalfFloat( val ); + super( new Float32Array( array ), itemSize, normalized ); } } -const _vector$9 = /*@__PURE__*/ new Vector3(); -const _vector2$1 = /*@__PURE__*/ new Vector2(); - -let _id$2 = 0; +const _box$3 = /*@__PURE__*/ new Box3(); +const _v1$3 = /*@__PURE__*/ new Vector3(); +const _v2$2 = /*@__PURE__*/ new Vector3(); /** - * This class stores data for an attribute (such as vertex positions, face - * indices, normals, colors, UVs, and any custom attributes ) associated with - * a geometry, which allows for more efficient passing of data to the GPU. - * - * When working with vector-like data, the `fromBufferAttribute( attribute, index )` - * helper methods on vector and color class might be helpful. E.g. {@link Vector3#fromBufferAttribute}. + * An analytical 3D sphere defined by a center and radius. This class is mainly + * used as a Bounding Sphere for 3D objects. */ -class BufferAttribute { +class Sphere { /** - * Constructs a new buffer attribute. + * Constructs a new sphere. * - * @param {TypedArray} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {Vector3} [center=(0,0,0)] - The center of the sphere + * @param {number} [radius=-1] - The radius of the sphere. */ - constructor( array, itemSize, normalized = false ) { - - if ( Array.isArray( array ) ) { - - throw new TypeError( 'THREE.BufferAttribute: array should be a Typed Array.' ); - - } + constructor( center = new Vector3(), radius = -1 ) { /** * This flag can be used for type testing. @@ -18102,993 +17594,397 @@ class BufferAttribute { * @readonly * @default true */ - this.isBufferAttribute = true; - - /** - * The ID of the buffer attribute. - * - * @name BufferAttribute#id - * @type {number} - * @readonly - */ - Object.defineProperty( this, 'id', { value: _id$2 ++ } ); - - /** - * The name of the buffer attribute. - * - * @type {string} - */ - this.name = ''; + this.isSphere = true; /** - * The array holding the attribute data. It should have `itemSize * numVertices` - * elements, where `numVertices` is the number of vertices in the associated geometry. + * The center of the sphere * - * @type {TypedArray} + * @type {Vector3} */ - this.array = array; + this.center = center; /** - * The number of values of the array that should be associated with a particular vertex. - * For instance, if this attribute is storing a 3-component vector (such as a position, - * normal, or color), then the value should be `3`. + * The radius of the sphere. * * @type {number} */ - this.itemSize = itemSize; + this.radius = radius; - /** - * Represents the number of items this buffer attribute stores. It is internally computed - * by dividing the `array` length by the `itemSize`. - * - * @type {number} - * @readonly - */ - this.count = array !== undefined ? array.length / itemSize : 0; + } - /** - * Applies to integer data only. Indicates how the underlying data in the buffer maps to - * the values in the GLSL code. For instance, if `array` is an instance of `UInt16Array`, - * and `normalized` is `true`, the values `0 - +65535` in the array data will be mapped to - * `0.0f - +1.0f` in the GLSL attribute. If `normalized` is `false`, the values will be converted - * to floats unmodified, i.e. `65535` becomes `65535.0f`. - * - * @type {boolean} - */ - this.normalized = normalized; + /** + * Sets the sphere's components by copying the given values. + * + * @param {Vector3} center - The center. + * @param {number} radius - The radius. + * @return {Sphere} A reference to this sphere. + */ + set( center, radius ) { - /** - * Defines the intended usage pattern of the data store for optimization purposes. - * - * Note: After the initial use of a buffer, its usage cannot be changed. Instead, - * instantiate a new one and set the desired usage before the next render. - * - * @type {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} - * @default StaticDrawUsage - */ - this.usage = StaticDrawUsage; - - /** - * This can be used to only update some components of stored vectors (for example, just the - * component related to color). Use the `addUpdateRange()` function to add ranges to this array. - * - * @type {Array} - */ - this.updateRanges = []; - - /** - * Configures the bound GPU type for use in shaders. - * - * Note: this only has an effect for integer arrays and is not configurable for float arrays. - * For lower precision float types, use `Float16BufferAttribute`. - * - * @type {(FloatType|IntType)} - * @default FloatType - */ - this.gpuType = FloatType; - - /** - * A version number, incremented every time the `needsUpdate` is set to `true`. - * - * @type {number} - */ - this.version = 0; - - } - - /** - * A callback function that is executed after the renderer has transferred the attribute - * array data to the GPU. - */ - onUploadCallback() {} - - /** - * Flag to indicate that this attribute has changed and should be re-sent to - * the GPU. Set this to `true` when you modify the value of the array. - * - * @type {number} - * @default false - * @param {boolean} value - */ - set needsUpdate( value ) { - - if ( value === true ) this.version ++; - - } - - /** - * Sets the usage of this buffer attribute. - * - * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. - * @return {BufferAttribute} A reference to this buffer attribute. - */ - setUsage( value ) { - - this.usage = value; + this.center.copy( center ); + this.radius = radius; return this; } /** - * Adds a range of data in the data array to be updated on the GPU. + * Computes the minimum bounding sphere for list of points. + * If the optional center point is given, it is used as the sphere's + * center. Otherwise, the center of the axis-aligned bounding box + * encompassing the points is calculated. * - * @param {number} start - Position at which to start update. - * @param {number} count - The number of components to update. - */ - addUpdateRange( start, count ) { - - this.updateRanges.push( { start, count } ); - - } - - /** - * Clears the update ranges. + * @param {Array} points - A list of points in 3D space. + * @param {Vector3} [optionalCenter] - The center of the sphere. + * @return {Sphere} A reference to this sphere. */ - clearUpdateRanges() { - - this.updateRanges.length = 0; - - } + setFromPoints( points, optionalCenter ) { - /** - * Copies the values of the given buffer attribute to this instance. - * - * @param {BufferAttribute} source - The buffer attribute to copy. - * @return {BufferAttribute} A reference to this instance. - */ - copy( source ) { + const center = this.center; - this.name = source.name; - this.array = new source.array.constructor( source.array ); - this.itemSize = source.itemSize; - this.count = source.count; - this.normalized = source.normalized; + if ( optionalCenter !== undefined ) { - this.usage = source.usage; - this.gpuType = source.gpuType; + center.copy( optionalCenter ); - return this; + } else { - } + _box$3.setFromPoints( points ).getCenter( center ); - /** - * Copies a vector from the given buffer attribute to this one. The start - * and destination position in the attribute buffers are represented by the - * given indices. - * - * @param {number} index1 - The destination index into this buffer attribute. - * @param {BufferAttribute} attribute - The buffer attribute to copy from. - * @param {number} index2 - The source index into the given buffer attribute. - * @return {BufferAttribute} A reference to this instance. - */ - copyAt( index1, attribute, index2 ) { + } - index1 *= this.itemSize; - index2 *= attribute.itemSize; + let maxRadiusSq = 0; - for ( let i = 0, l = this.itemSize; i < l; i ++ ) { + for ( let i = 0, il = points.length; i < il; i ++ ) { - this.array[ index1 + i ] = attribute.array[ index2 + i ]; + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( points[ i ] ) ); } + this.radius = Math.sqrt( maxRadiusSq ); + return this; } /** - * Copies the given array data into this buffer attribute. + * Copies the values of the given sphere to this instance. * - * @param {(TypedArray|Array)} array - The array to copy. - * @return {BufferAttribute} A reference to this instance. + * @param {Sphere} sphere - The sphere to copy. + * @return {Sphere} A reference to this sphere. */ - copyArray( array ) { + copy( sphere ) { - this.array.set( array ); + this.center.copy( sphere.center ); + this.radius = sphere.radius; return this; } /** - * Applies the given 3x3 matrix to the given attribute. Works with - * item size `2` and `3`. + * Returns `true` if the sphere is empty (the radius set to a negative number). * - * @param {Matrix3} m - The matrix to apply. - * @return {BufferAttribute} A reference to this instance. + * Spheres with a radius of `0` contain only their center point and are not + * considered to be empty. + * + * @return {boolean} Whether this sphere is empty or not. */ - applyMatrix3( m ) { - - if ( this.itemSize === 2 ) { - - for ( let i = 0, l = this.count; i < l; i ++ ) { - - _vector2$1.fromBufferAttribute( this, i ); - _vector2$1.applyMatrix3( m ); - - this.setXY( i, _vector2$1.x, _vector2$1.y ); - - } - - } else if ( this.itemSize === 3 ) { - - for ( let i = 0, l = this.count; i < l; i ++ ) { - - _vector$9.fromBufferAttribute( this, i ); - _vector$9.applyMatrix3( m ); - - this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - - } - - } + isEmpty() { - return this; + return ( this.radius < 0 ); } /** - * Applies the given 4x4 matrix to the given attribute. Only works with - * item size `3`. + * Makes this sphere empty which means in encloses a zero space in 3D. * - * @param {Matrix4} m - The matrix to apply. - * @return {BufferAttribute} A reference to this instance. + * @return {Sphere} A reference to this sphere. */ - applyMatrix4( m ) { - - for ( let i = 0, l = this.count; i < l; i ++ ) { - - _vector$9.fromBufferAttribute( this, i ); - - _vector$9.applyMatrix4( m ); - - this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); + makeEmpty() { - } + this.center.set( 0, 0, 0 ); + this.radius = -1; return this; } /** - * Applies the given 3x3 normal matrix to the given attribute. Only works with - * item size `3`. + * Returns `true` if this sphere contains the given point inclusive of + * the surface of the sphere. * - * @param {Matrix3} m - The normal matrix to apply. - * @return {BufferAttribute} A reference to this instance. + * @param {Vector3} point - The point to check. + * @return {boolean} Whether this sphere contains the given point or not. */ - applyNormalMatrix( m ) { - - for ( let i = 0, l = this.count; i < l; i ++ ) { - - _vector$9.fromBufferAttribute( this, i ); - - _vector$9.applyNormalMatrix( m ); - - this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - - } + containsPoint( point ) { - return this; + return ( point.distanceToSquared( this.center ) <= ( this.radius * this.radius ) ); } /** - * Applies the given 4x4 matrix to the given attribute. Only works with - * item size `3` and with direction vectors. + * Returns the closest distance from the boundary of the sphere to the + * given point. If the sphere contains the point, the distance will + * be negative. * - * @param {Matrix4} m - The matrix to apply. - * @return {BufferAttribute} A reference to this instance. + * @param {Vector3} point - The point to compute the distance to. + * @return {number} The distance to the point. */ - transformDirection( m ) { - - for ( let i = 0, l = this.count; i < l; i ++ ) { - - _vector$9.fromBufferAttribute( this, i ); - - _vector$9.transformDirection( m ); - - this.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); - - } + distanceToPoint( point ) { - return this; + return ( point.distanceTo( this.center ) - this.radius ); } /** - * Sets the given array data in the buffer attribute. + * Returns `true` if this sphere intersects with the given one. * - * @param {(TypedArray|Array)} value - The array data to set. - * @param {number} [offset=0] - The offset in this buffer attribute's array. - * @return {BufferAttribute} A reference to this instance. + * @param {Sphere} sphere - The sphere to test. + * @return {boolean} Whether this sphere intersects with the given one or not. */ - set( value, offset = 0 ) { + intersectsSphere( sphere ) { - // Matching BufferAttribute constructor, do not normalize the array. - this.array.set( value, offset ); + const radiusSum = this.radius + sphere.radius; - return this; + return sphere.center.distanceToSquared( this.center ) <= ( radiusSum * radiusSum ); } /** - * Returns the given component of the vector at the given index. + * Returns `true` if this sphere intersects with the given box. * - * @param {number} index - The index into the buffer attribute. - * @param {number} component - The component index. - * @return {number} The returned value. + * @param {Box3} box - The box to test. + * @return {boolean} Whether this sphere intersects with the given box or not. */ - getComponent( index, component ) { - - let value = this.array[ index * this.itemSize + component ]; - - if ( this.normalized ) value = denormalize( value, this.array ); + intersectsBox( box ) { - return value; + return box.intersectsSphere( this ); } /** - * Sets the given value to the given component of the vector at the given index. + * Returns `true` if this sphere intersects with the given plane. * - * @param {number} index - The index into the buffer attribute. - * @param {number} component - The component index. - * @param {number} value - The value to set. - * @return {BufferAttribute} A reference to this instance. + * @param {Plane} plane - The plane to test. + * @return {boolean} Whether this sphere intersects with the given plane or not. */ - setComponent( index, component, value ) { - - if ( this.normalized ) value = normalize( value, this.array ); - - this.array[ index * this.itemSize + component ] = value; + intersectsPlane( plane ) { - return this; + return Math.abs( plane.distanceToPoint( this.center ) ) <= this.radius; } /** - * Returns the x component of the vector at the given index. + * Clamps a point within the sphere. If the point is outside the sphere, it + * will clamp it to the closest point on the edge of the sphere. Points + * already inside the sphere will not be affected. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The x component. + * @param {Vector3} point - The plane to clamp. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The clamped point. */ - getX( index ) { - - let x = this.array[ index * this.itemSize ]; - - if ( this.normalized ) x = denormalize( x, this.array ); + clampPoint( point, target ) { - return x; + const deltaLengthSq = this.center.distanceToSquared( point ); - } + target.copy( point ); - /** - * Sets the x component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value to set. - * @return {BufferAttribute} A reference to this instance. - */ - setX( index, x ) { + if ( deltaLengthSq > ( this.radius * this.radius ) ) { - if ( this.normalized ) x = normalize( x, this.array ); + target.sub( this.center ).normalize(); + target.multiplyScalar( this.radius ).add( this.center ); - this.array[ index * this.itemSize ] = x; + } - return this; + return target; } /** - * Returns the y component of the vector at the given index. + * Returns a bounding box that encloses this sphere. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The y component. + * @param {Box3} target - The target box that is used to store the method's result. + * @return {Box3} The bounding box that encloses this sphere. */ - getY( index ) { - - let y = this.array[ index * this.itemSize + 1 ]; - - if ( this.normalized ) y = denormalize( y, this.array ); - - return y; + getBoundingBox( target ) { - } + if ( this.isEmpty() ) { - /** - * Sets the y component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} y - The value to set. - * @return {BufferAttribute} A reference to this instance. - */ - setY( index, y ) { + // Empty sphere produces empty bounding box + target.makeEmpty(); + return target; - if ( this.normalized ) y = normalize( y, this.array ); + } - this.array[ index * this.itemSize + 1 ] = y; + target.set( this.center, this.center ); + target.expandByScalar( this.radius ); - return this; + return target; } /** - * Returns the z component of the vector at the given index. + * Transforms this sphere with the given 4x4 transformation matrix. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The z component. + * @param {Matrix4} matrix - The transformation matrix. + * @return {Sphere} A reference to this sphere. */ - getZ( index ) { - - let z = this.array[ index * this.itemSize + 2 ]; + applyMatrix4( matrix ) { - if ( this.normalized ) z = denormalize( z, this.array ); + this.center.applyMatrix4( matrix ); + this.radius = this.radius * matrix.getMaxScaleOnAxis(); - return z; + return this; } /** - * Sets the z component of the vector at the given index. + * Translates the sphere's center by the given offset. * - * @param {number} index - The index into the buffer attribute. - * @param {number} z - The value to set. - * @return {BufferAttribute} A reference to this instance. + * @param {Vector3} offset - The offset. + * @return {Sphere} A reference to this sphere. */ - setZ( index, z ) { - - if ( this.normalized ) z = normalize( z, this.array ); + translate( offset ) { - this.array[ index * this.itemSize + 2 ] = z; + this.center.add( offset ); return this; } /** - * Returns the w component of the vector at the given index. + * Expands the boundaries of this sphere to include the given point. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The w component. + * @param {Vector3} point - The point to include. + * @return {Sphere} A reference to this sphere. */ - getW( index ) { + expandByPoint( point ) { - let w = this.array[ index * this.itemSize + 3 ]; + if ( this.isEmpty() ) { - if ( this.normalized ) w = denormalize( w, this.array ); + this.center.copy( point ); - return w; + this.radius = 0; - } + return this; - /** - * Sets the w component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} w - The value to set. - * @return {BufferAttribute} A reference to this instance. - */ - setW( index, w ) { + } - if ( this.normalized ) w = normalize( w, this.array ); + _v1$3.subVectors( point, this.center ); - this.array[ index * this.itemSize + 3 ] = w; + const lengthSq = _v1$3.lengthSq(); - return this; + if ( lengthSq > ( this.radius * this.radius ) ) { - } + // calculate the minimal sphere - /** - * Sets the x and y component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @return {BufferAttribute} A reference to this instance. - */ - setXY( index, x, y ) { + const length = Math.sqrt( lengthSq ); - index *= this.itemSize; + const delta = ( length - this.radius ) * 0.5; - if ( this.normalized ) { + this.center.addScaledVector( _v1$3, delta / length ); - x = normalize( x, this.array ); - y = normalize( y, this.array ); + this.radius += delta; } - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - return this; } /** - * Sets the x, y and z component of the vector at the given index. + * Expands this sphere to enclose both the original sphere and the given sphere. * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @param {number} z - The value for the z component to set. - * @return {BufferAttribute} A reference to this instance. + * @param {Sphere} sphere - The sphere to include. + * @return {Sphere} A reference to this sphere. */ - setXYZ( index, x, y, z ) { - - index *= this.itemSize; + union( sphere ) { - if ( this.normalized ) { + if ( sphere.isEmpty() ) { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); + return this; } - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; + if ( this.isEmpty() ) { - return this; + this.copy( sphere ); - } + return this; - /** - * Sets the x, y, z and w component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @param {number} z - The value for the z component to set. - * @param {number} w - The value for the w component to set. - * @return {BufferAttribute} A reference to this instance. - */ - setXYZW( index, x, y, z, w ) { + } - index *= this.itemSize; + if ( this.center.equals( sphere.center ) === true ) { - if ( this.normalized ) { + this.radius = Math.max( this.radius, sphere.radius ); - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - w = normalize( w, this.array ); + } else { - } + _v2$2.subVectors( sphere.center, this.center ).setLength( sphere.radius ); - this.array[ index + 0 ] = x; - this.array[ index + 1 ] = y; - this.array[ index + 2 ] = z; - this.array[ index + 3 ] = w; + this.expandByPoint( _v1$3.copy( sphere.center ).add( _v2$2 ) ); + + this.expandByPoint( _v1$3.copy( sphere.center ).sub( _v2$2 ) ); + + } return this; } /** - * Sets the given callback function that is executed after the Renderer has transferred - * the attribute array data to the GPU. Can be used to perform clean-up operations after - * the upload when attribute data are not needed anymore on the CPU side. + * Returns `true` if this sphere is equal with the given one. * - * @param {Function} callback - The `onUpload()` callback. - * @return {BufferAttribute} A reference to this instance. + * @param {Sphere} sphere - The sphere to test for equality. + * @return {boolean} Whether this bounding sphere is equal with the given one. */ - onUpload( callback ) { - - this.onUploadCallback = callback; + equals( sphere ) { - return this; + return sphere.center.equals( this.center ) && ( sphere.radius === this.radius ); } /** - * Returns a new buffer attribute with copied values from this instance. + * Returns a new sphere with copied values from this instance. * - * @return {BufferAttribute} A clone of this instance. + * @return {Sphere} A clone of this instance. */ clone() { - return new this.constructor( this.array, this.itemSize ).copy( this ); + return new this.constructor().copy( this ); } /** - * Serializes the buffer attribute into JSON. + * Returns a serialized structure of the bounding sphere. * - * @return {Object} A JSON object representing the serialized buffer attribute. + * @return {Object} Serialized structure with fields representing the object state. */ toJSON() { - const data = { - itemSize: this.itemSize, - type: this.array.constructor.name, - array: Array.from( this.array ), - normalized: this.normalized + return { + radius: this.radius, + center: this.center.toArray() }; - if ( this.name !== '' ) data.name = this.name; - if ( this.usage !== StaticDrawUsage ) data.usage = this.usage; - - return data; - } -} - -/** - * Convenient class that can be used when creating a `Int8` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Int8BufferAttribute extends BufferAttribute { - - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Int8Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { - - super( new Int8Array( array ), itemSize, normalized ); - - } - -} - -/** - * Convenient class that can be used when creating a `UInt8` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Uint8BufferAttribute extends BufferAttribute { - - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Uint8Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { - - super( new Uint8Array( array ), itemSize, normalized ); - - } - -} - -/** - * Convenient class that can be used when creating a `UInt8Clamped` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Uint8ClampedBufferAttribute extends BufferAttribute { - - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Uint8ClampedArray)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { - - super( new Uint8ClampedArray( array ), itemSize, normalized ); - - } - -} - -/** - * Convenient class that can be used when creating a `Int16` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Int16BufferAttribute extends BufferAttribute { - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Int16Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { - - super( new Int16Array( array ), itemSize, normalized ); - - } - -} - -/** - * Convenient class that can be used when creating a `UInt16` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Uint16BufferAttribute extends BufferAttribute { - - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Uint16Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { - - super( new Uint16Array( array ), itemSize, normalized ); - - } - -} - -/** - * Convenient class that can be used when creating a `Int32` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Int32BufferAttribute extends BufferAttribute { - - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Int32Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { - - super( new Int32Array( array ), itemSize, normalized ); - - } - -} - -/** - * Convenient class that can be used when creating a `UInt32` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Uint32BufferAttribute extends BufferAttribute { - - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Uint32Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { - - super( new Uint32Array( array ), itemSize, normalized ); - - } - -} - -/** - * Convenient class that can be used when creating a `Float16` buffer attribute with - * a plain `Array` instance. - * - * This class automatically converts to and from FP16 via `Uint16Array` since `Float16Array` - * browser support is still problematic. - * - * @augments BufferAttribute - */ -class Float16BufferAttribute extends BufferAttribute { - - /** - * Constructs a new buffer attribute. + * Returns a serialized structure of the bounding sphere. * - * @param {(Array|Uint16Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. + * @param {Object} json - The serialized json to set the sphere from. + * @return {Sphere} A reference to this bounding sphere. */ - constructor( array, itemSize, normalized ) { - - super( new Uint16Array( array ), itemSize, normalized ); - - this.isFloat16BufferAttribute = true; - - } - - getX( index ) { - - let x = fromHalfFloat( this.array[ index * this.itemSize ] ); - - if ( this.normalized ) x = denormalize( x, this.array ); - - return x; - - } - - setX( index, x ) { - - if ( this.normalized ) x = normalize( x, this.array ); - - this.array[ index * this.itemSize ] = toHalfFloat( x ); - - return this; - - } - - getY( index ) { - - let y = fromHalfFloat( this.array[ index * this.itemSize + 1 ] ); - - if ( this.normalized ) y = denormalize( y, this.array ); - - return y; - - } - - setY( index, y ) { - - if ( this.normalized ) y = normalize( y, this.array ); - - this.array[ index * this.itemSize + 1 ] = toHalfFloat( y ); - - return this; - - } - - getZ( index ) { - - let z = fromHalfFloat( this.array[ index * this.itemSize + 2 ] ); - - if ( this.normalized ) z = denormalize( z, this.array ); - - return z; - - } - - setZ( index, z ) { - - if ( this.normalized ) z = normalize( z, this.array ); - - this.array[ index * this.itemSize + 2 ] = toHalfFloat( z ); - - return this; - - } - - getW( index ) { - - let w = fromHalfFloat( this.array[ index * this.itemSize + 3 ] ); - - if ( this.normalized ) w = denormalize( w, this.array ); - - return w; - - } - - setW( index, w ) { - - if ( this.normalized ) w = normalize( w, this.array ); - - this.array[ index * this.itemSize + 3 ] = toHalfFloat( w ); - - return this; - - } - - setXY( index, x, y ) { - - index *= this.itemSize; - - if ( this.normalized ) { - - x = normalize( x, this.array ); - y = normalize( y, this.array ); - - } - - this.array[ index + 0 ] = toHalfFloat( x ); - this.array[ index + 1 ] = toHalfFloat( y ); - - return this; - - } - - setXYZ( index, x, y, z ) { - - index *= this.itemSize; - - if ( this.normalized ) { - - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - - } - - this.array[ index + 0 ] = toHalfFloat( x ); - this.array[ index + 1 ] = toHalfFloat( y ); - this.array[ index + 2 ] = toHalfFloat( z ); - - return this; - - } - - setXYZW( index, x, y, z, w ) { - - index *= this.itemSize; - - if ( this.normalized ) { - - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - w = normalize( w, this.array ); - - } - - this.array[ index + 0 ] = toHalfFloat( x ); - this.array[ index + 1 ] = toHalfFloat( y ); - this.array[ index + 2 ] = toHalfFloat( z ); - this.array[ index + 3 ] = toHalfFloat( w ); + fromJSON( json ) { + this.radius = json.radius; + this.center.fromArray( json.center ); return this; } } -/** - * Convenient class that can be used when creating a `Float32` buffer attribute with - * a plain `Array` instance. - * - * @augments BufferAttribute - */ -class Float32BufferAttribute extends BufferAttribute { - - /** - * Constructs a new buffer attribute. - * - * @param {(Array|Float32Array)} array - The array holding the attribute data. - * @param {number} itemSize - The item size. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( array, itemSize, normalized ) { - - super( new Float32Array( array ), itemSize, normalized ); - - } - -} - let _id$1 = 0; const _m1 = /*@__PURE__*/ new Matrix4(); @@ -19096,7 +17992,7 @@ const _obj = /*@__PURE__*/ new Object3D(); const _offset = /*@__PURE__*/ new Vector3(); const _box$2 = /*@__PURE__*/ new Box3(); const _boxMorphTargets = /*@__PURE__*/ new Box3(); -const _vector$8 = /*@__PURE__*/ new Vector3(); +const _vector$9 = /*@__PURE__*/ new Vector3(); /** * A representation of mesh, line, or point geometry. Includes vertex @@ -19743,11 +18639,11 @@ class BufferGeometry extends EventDispatcher { if ( this.morphTargetsRelative ) { - _vector$8.addVectors( this.boundingBox.min, _box$2.min ); - this.boundingBox.expandByPoint( _vector$8 ); + _vector$9.addVectors( this.boundingBox.min, _box$2.min ); + this.boundingBox.expandByPoint( _vector$9 ); - _vector$8.addVectors( this.boundingBox.max, _box$2.max ); - this.boundingBox.expandByPoint( _vector$8 ); + _vector$9.addVectors( this.boundingBox.max, _box$2.max ); + this.boundingBox.expandByPoint( _vector$9 ); } else { @@ -19819,11 +18715,11 @@ class BufferGeometry extends EventDispatcher { if ( this.morphTargetsRelative ) { - _vector$8.addVectors( _box$2.min, _boxMorphTargets.min ); - _box$2.expandByPoint( _vector$8 ); + _vector$9.addVectors( _box$2.min, _boxMorphTargets.min ); + _box$2.expandByPoint( _vector$9 ); - _vector$8.addVectors( _box$2.max, _boxMorphTargets.max ); - _box$2.expandByPoint( _vector$8 ); + _vector$9.addVectors( _box$2.max, _boxMorphTargets.max ); + _box$2.expandByPoint( _vector$9 ); } else { @@ -19845,9 +18741,9 @@ class BufferGeometry extends EventDispatcher { for ( let i = 0, il = position.count; i < il; i ++ ) { - _vector$8.fromBufferAttribute( position, i ); + _vector$9.fromBufferAttribute( position, i ); - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) ); + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$9 ) ); } @@ -19862,16 +18758,16 @@ class BufferGeometry extends EventDispatcher { for ( let j = 0, jl = morphAttribute.count; j < jl; j ++ ) { - _vector$8.fromBufferAttribute( morphAttribute, j ); + _vector$9.fromBufferAttribute( morphAttribute, j ); if ( morphTargetsRelative ) { _offset.fromBufferAttribute( position, j ); - _vector$8.add( _offset ); + _vector$9.add( _offset ); } - maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$8 ) ); + maxRadiusSq = Math.max( maxRadiusSq, center.distanceToSquared( _vector$9 ) ); } @@ -20165,11 +19061,11 @@ class BufferGeometry extends EventDispatcher { for ( let i = 0, il = normals.count; i < il; i ++ ) { - _vector$8.fromBufferAttribute( normals, i ); + _vector$9.fromBufferAttribute( normals, i ); - _vector$8.normalize(); + _vector$9.normalize(); - normals.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); + normals.setXYZ( i, _vector$9.x, _vector$9.y, _vector$9.z ); } @@ -20534,44 +19430,21 @@ class BufferGeometry extends EventDispatcher { } -const _inverseMatrix$3 = /*@__PURE__*/ new Matrix4(); -const _ray$3 = /*@__PURE__*/ new Ray(); -const _sphere$6 = /*@__PURE__*/ new Sphere(); -const _sphereHitAt = /*@__PURE__*/ new Vector3(); - -const _vA$1 = /*@__PURE__*/ new Vector3(); -const _vB$1 = /*@__PURE__*/ new Vector3(); -const _vC$1 = /*@__PURE__*/ new Vector3(); - -const _tempA = /*@__PURE__*/ new Vector3(); -const _morphA = /*@__PURE__*/ new Vector3(); - -const _intersectionPoint = /*@__PURE__*/ new Vector3(); -const _intersectionPointWorld = /*@__PURE__*/ new Vector3(); - /** - * Class representing triangular polygon mesh based objects. - * - * ```js - * const geometry = new THREE.BoxGeometry( 1, 1, 1 ); - * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); - * const mesh = new THREE.Mesh( geometry, material ); - * scene.add( mesh ); - * ``` + * "Interleaved" means that multiple attributes, possibly of different types, + * (e.g., position, normal, uv, color) are packed into a single array buffer. * - * @augments Object3D + * An introduction into interleaved arrays can be found here: [Interleaved array basics](https://blog.tojicode.com/2011/05/interleaved-array-basics.html) */ -class Mesh extends Object3D { +class InterleavedBuffer { /** - * Constructs a new mesh. + * Constructs a new interleaved buffer. * - * @param {BufferGeometry} [geometry] - The mesh geometry. - * @param {Material|Array} [material] - The mesh material. + * @param {TypedArray} array - A typed array with a shared buffer storing attribute data. + * @param {number} stride - The number of typed-array elements per vertex. */ - constructor( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) { - - super(); + constructor( array, stride ) { /** * This flag can be used for type testing. @@ -20580,2711 +19453,1850 @@ class Mesh extends Object3D { * @readonly * @default true */ - this.isMesh = true; + this.isInterleavedBuffer = true; - this.type = 'Mesh'; + /** + * A typed array with a shared buffer storing attribute data. + * + * @type {TypedArray} + */ + this.array = array; /** - * The mesh geometry. + * The number of typed-array elements per vertex. * - * @type {BufferGeometry} + * @type {number} */ - this.geometry = geometry; + this.stride = stride; /** - * The mesh material. + * The total number of elements in the array * - * @type {Material|Array} - * @default MeshBasicMaterial + * @type {number} + * @readonly */ - this.material = material; + this.count = array !== undefined ? array.length / stride : 0; /** - * A dictionary representing the morph targets in the geometry. The key is the - * morph targets name, the value its attribute index. This member is `undefined` - * by default and only set when morph targets are detected in the geometry. + * Defines the intended usage pattern of the data store for optimization purposes. * - * @type {Object|undefined} - * @default undefined + * Note: After the initial use of a buffer, its usage cannot be changed. Instead, + * instantiate a new one and set the desired usage before the next render. + * + * @type {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} + * @default StaticDrawUsage */ - this.morphTargetDictionary = undefined; + this.usage = StaticDrawUsage; /** - * An array of weights typically in the range `[0,1]` that specify how much of the morph - * is applied. This member is `undefined` by default and only set when morph targets are - * detected in the geometry. + * This can be used to only update some components of stored vectors (for example, just the + * component related to color). Use the `addUpdateRange()` function to add ranges to this array. * - * @type {Array|undefined} - * @default undefined + * @type {Array} */ - this.morphTargetInfluences = undefined; + this.updateRanges = []; /** - * The number of instances of this mesh. - * Can only be used with {@link WebGPURenderer}. + * A version number, incremented every time the `needsUpdate` is set to `true`. * * @type {number} - * @default 1 */ - this.count = 1; + this.version = 0; - this.updateMorphTargets(); + /** + * The UUID of the interleaved buffer. + * + * @type {string} + * @readonly + */ + this.uuid = generateUUID(); } - copy( source, recursive ) { + /** + * A callback function that is executed after the renderer has transferred the attribute array + * data to the GPU. + */ + onUploadCallback() {} - super.copy( source, recursive ); + /** + * Flag to indicate that this attribute has changed and should be re-sent to + * the GPU. Set this to `true` when you modify the value of the array. + * + * @type {number} + * @default false + * @param {boolean} value + */ + set needsUpdate( value ) { - if ( source.morphTargetInfluences !== undefined ) { + if ( value === true ) this.version ++; - this.morphTargetInfluences = source.morphTargetInfluences.slice(); + } - } + /** + * Sets the usage of this interleaved buffer. + * + * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. + * @return {InterleavedBuffer} A reference to this interleaved buffer. + */ + setUsage( value ) { - if ( source.morphTargetDictionary !== undefined ) { + this.usage = value; - this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); + return this; - } + } - this.material = Array.isArray( source.material ) ? source.material.slice() : source.material; - this.geometry = source.geometry; + /** + * Adds a range of data in the data array to be updated on the GPU. + * + * @param {number} start - Position at which to start update. + * @param {number} count - The number of components to update. + */ + addUpdateRange( start, count ) { - return this; + this.updateRanges.push( { start, count } ); } /** - * Sets the values of {@link Mesh#morphTargetDictionary} and {@link Mesh#morphTargetInfluences} - * to make sure existing morph targets can influence this 3D object. + * Clears the update ranges. */ - updateMorphTargets() { - - const geometry = this.geometry; + clearUpdateRanges() { - const morphAttributes = geometry.morphAttributes; - const keys = Object.keys( morphAttributes ); + this.updateRanges.length = 0; - if ( keys.length > 0 ) { + } - const morphAttribute = morphAttributes[ keys[ 0 ] ]; + /** + * Copies the values of the given interleaved buffer to this instance. + * + * @param {InterleavedBuffer} source - The interleaved buffer to copy. + * @return {InterleavedBuffer} A reference to this instance. + */ + copy( source ) { - if ( morphAttribute !== undefined ) { + this.array = new source.array.constructor( source.array ); + this.count = source.count; + this.stride = source.stride; + this.usage = source.usage; - this.morphTargetInfluences = []; - this.morphTargetDictionary = {}; + return this; - for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) { + } - const name = morphAttribute[ m ].name || String( m ); + /** + * Copies a vector from the given interleaved buffer to this one. The start + * and destination position in the attribute buffers are represented by the + * given indices. + * + * @param {number} index1 - The destination index into this interleaved buffer. + * @param {InterleavedBuffer} interleavedBuffer - The interleaved buffer to copy from. + * @param {number} index2 - The source index into the given interleaved buffer. + * @return {InterleavedBuffer} A reference to this instance. + */ + copyAt( index1, interleavedBuffer, index2 ) { - this.morphTargetInfluences.push( 0 ); - this.morphTargetDictionary[ name ] = m; + index1 *= this.stride; + index2 *= interleavedBuffer.stride; - } + for ( let i = 0, l = this.stride; i < l; i ++ ) { - } + this.array[ index1 + i ] = interleavedBuffer.array[ index2 + i ]; } + return this; + } /** - * Returns the local-space position of the vertex at the given index, taking into - * account the current animation state of both morph targets and skinning. + * Sets the given array data in the interleaved buffer. * - * @param {number} index - The vertex index. - * @param {Vector3} target - The target object that is used to store the method's result. - * @return {Vector3} The vertex position in local space. + * @param {(TypedArray|Array)} value - The array data to set. + * @param {number} [offset=0] - The offset in this interleaved buffer's array. + * @return {InterleavedBuffer} A reference to this instance. */ - getVertexPosition( index, target ) { - - const geometry = this.geometry; - const position = geometry.attributes.position; - const morphPosition = geometry.morphAttributes.position; - const morphTargetsRelative = geometry.morphTargetsRelative; - - target.fromBufferAttribute( position, index ); + set( value, offset = 0 ) { - const morphInfluences = this.morphTargetInfluences; + this.array.set( value, offset ); - if ( morphPosition && morphInfluences ) { + return this; - _morphA.set( 0, 0, 0 ); + } - for ( let i = 0, il = morphPosition.length; i < il; i ++ ) { + /** + * Returns a new interleaved buffer with copied values from this instance. + * + * @param {Object} [data] - An object with shared array buffers that allows to retain shared structures. + * @return {InterleavedBuffer} A clone of this instance. + */ + clone( data ) { - const influence = morphInfluences[ i ]; - const morphAttribute = morphPosition[ i ]; + if ( data.arrayBuffers === undefined ) { - if ( influence === 0 ) continue; + data.arrayBuffers = {}; - _tempA.fromBufferAttribute( morphAttribute, index ); + } - if ( morphTargetsRelative ) { + if ( this.array.buffer._uuid === undefined ) { - _morphA.addScaledVector( _tempA, influence ); + this.array.buffer._uuid = generateUUID(); - } else { + } - _morphA.addScaledVector( _tempA.sub( target ), influence ); + if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { - } + data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer; - } + } - target.add( _morphA ); + const array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] ); - } + const ib = new this.constructor( array, this.stride ); + ib.setUsage( this.usage ); - return target; + return ib; } /** - * Computes intersection points between a casted ray and this line. + * Sets the given callback function that is executed after the Renderer has transferred + * the array data to the GPU. Can be used to perform clean-up operations after + * the upload when data are not needed anymore on the CPU side. * - * @param {Raycaster} raycaster - The raycaster. - * @param {Array} intersects - The target array that holds the intersection points. + * @param {Function} callback - The `onUpload()` callback. + * @return {InterleavedBuffer} A reference to this instance. */ - raycast( raycaster, intersects ) { + onUpload( callback ) { - const geometry = this.geometry; - const material = this.material; - const matrixWorld = this.matrixWorld; + this.onUploadCallback = callback; - if ( material === undefined ) return; + return this; - // test with bounding sphere in world space + } - if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); + /** + * Serializes the interleaved buffer into JSON. + * + * @param {Object} [data] - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized interleaved buffer. + */ + toJSON( data ) { - _sphere$6.copy( geometry.boundingSphere ); - _sphere$6.applyMatrix4( matrixWorld ); + if ( data.arrayBuffers === undefined ) { - // check distance from ray origin to bounding sphere + data.arrayBuffers = {}; - _ray$3.copy( raycaster.ray ).recast( raycaster.near ); + } - if ( _sphere$6.containsPoint( _ray$3.origin ) === false ) { + // generate UUID for array buffer if necessary - if ( _ray$3.intersectSphere( _sphere$6, _sphereHitAt ) === null ) return; + if ( this.array.buffer._uuid === undefined ) { - if ( _ray$3.origin.distanceToSquared( _sphereHitAt ) > ( raycaster.far - raycaster.near ) ** 2 ) return; + this.array.buffer._uuid = generateUUID(); } - // convert ray to local space of mesh - - _inverseMatrix$3.copy( matrixWorld ).invert(); - _ray$3.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$3 ); - - // test with bounding box in local space - - if ( geometry.boundingBox !== null ) { + if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { - if ( _ray$3.intersectsBox( geometry.boundingBox ) === false ) return; + data.arrayBuffers[ this.array.buffer._uuid ] = Array.from( new Uint32Array( this.array.buffer ) ); } - // test for intersections with geometry + // - this._computeIntersections( raycaster, intersects, _ray$3 ); + return { + uuid: this.uuid, + buffer: this.array.buffer._uuid, + type: this.array.constructor.name, + stride: this.stride + }; } - _computeIntersections( raycaster, intersects, rayLocalSpace ) { +} - let intersection; +const _vector$8 = /*@__PURE__*/ new Vector3(); - const geometry = this.geometry; - const material = this.material; +/** + * An alternative version of a buffer attribute with interleaved data. Interleaved + * attributes share a common interleaved data storage ({@link InterleavedBuffer}) and refer with + * different offsets into the buffer. + */ +class InterleavedBufferAttribute { - const index = geometry.index; - const position = geometry.attributes.position; - const uv = geometry.attributes.uv; - const uv1 = geometry.attributes.uv1; - const normal = geometry.attributes.normal; - const groups = geometry.groups; - const drawRange = geometry.drawRange; + /** + * Constructs a new interleaved buffer attribute. + * + * @param {InterleavedBuffer} interleavedBuffer - The buffer holding the interleaved data. + * @param {number} itemSize - The item size. + * @param {number} offset - The attribute offset into the buffer. + * @param {boolean} [normalized=false] - Whether the data are normalized or not. + */ + constructor( interleavedBuffer, itemSize, offset, normalized = false ) { - if ( index !== null ) { + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isInterleavedBufferAttribute = true; - // indexed buffer geometry + /** + * The name of the buffer attribute. + * + * @type {string} + */ + this.name = ''; - if ( Array.isArray( material ) ) { + /** + * The buffer holding the interleaved data. + * + * @type {InterleavedBuffer} + */ + this.data = interleavedBuffer; - for ( let i = 0, il = groups.length; i < il; i ++ ) { + /** + * The item size, see {@link BufferAttribute#itemSize}. + * + * @type {number} + */ + this.itemSize = itemSize; - const group = groups[ i ]; - const groupMaterial = material[ group.materialIndex ]; + /** + * The attribute offset into the buffer. + * + * @type {number} + */ + this.offset = offset; - const start = Math.max( group.start, drawRange.start ); - const end = Math.min( index.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); + /** + * Whether the data are normalized or not, see {@link BufferAttribute#normalized} + * + * @type {InterleavedBuffer} + */ + this.normalized = normalized; - for ( let j = start, jl = end; j < jl; j += 3 ) { + } - const a = index.getX( j ); - const b = index.getX( j + 1 ); - const c = index.getX( j + 2 ); + /** + * The item count of this buffer attribute. + * + * @type {number} + * @readonly + */ + get count() { - intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); + return this.data.count; - if ( intersection ) { + } - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; - intersects.push( intersection ); + /** + * The array holding the interleaved buffer attribute data. + * + * @type {TypedArray} + */ + get array() { - } + return this.data.array; - } + } - } + /** + * Flag to indicate that this attribute has changed and should be re-sent to + * the GPU. Set this to `true` when you modify the value of the array. + * + * @type {number} + * @default false + * @param {boolean} value + */ + set needsUpdate( value ) { - } else { + this.data.needsUpdate = value; - const start = Math.max( 0, drawRange.start ); - const end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); + } - for ( let i = start, il = end; i < il; i += 3 ) { + /** + * Applies the given 4x4 matrix to the given attribute. Only works with + * item size `3`. + * + * @param {Matrix4} m - The matrix to apply. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + applyMatrix4( m ) { - const a = index.getX( i ); - const b = index.getX( i + 1 ); - const c = index.getX( i + 2 ); + for ( let i = 0, l = this.data.count; i < l; i ++ ) { - intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); + _vector$8.fromBufferAttribute( this, i ); - if ( intersection ) { + _vector$8.applyMatrix4( m ); - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics - intersects.push( intersection ); + this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); - } + } - } + return this; - } + } - } else if ( position !== undefined ) { + /** + * Applies the given 3x3 normal matrix to the given attribute. Only works with + * item size `3`. + * + * @param {Matrix3} m - The normal matrix to apply. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + applyNormalMatrix( m ) { - // non-indexed buffer geometry + for ( let i = 0, l = this.count; i < l; i ++ ) { - if ( Array.isArray( material ) ) { + _vector$8.fromBufferAttribute( this, i ); - for ( let i = 0, il = groups.length; i < il; i ++ ) { + _vector$8.applyNormalMatrix( m ); - const group = groups[ i ]; - const groupMaterial = material[ group.materialIndex ]; + this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); - const start = Math.max( group.start, drawRange.start ); - const end = Math.min( position.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); + } - for ( let j = start, jl = end; j < jl; j += 3 ) { + return this; - const a = j; - const b = j + 1; - const c = j + 2; + } - intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); + /** + * Applies the given 4x4 matrix to the given attribute. Only works with + * item size `3` and with direction vectors. + * + * @param {Matrix4} m - The matrix to apply. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + transformDirection( m ) { - if ( intersection ) { + for ( let i = 0, l = this.count; i < l; i ++ ) { - intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics - intersection.face.materialIndex = group.materialIndex; - intersects.push( intersection ); + _vector$8.fromBufferAttribute( this, i ); - } + _vector$8.transformDirection( m ); - } + this.setXYZ( i, _vector$8.x, _vector$8.y, _vector$8.z ); - } + } - } else { + return this; - const start = Math.max( 0, drawRange.start ); - const end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); + } - for ( let i = start, il = end; i < il; i += 3 ) { + /** + * Returns the given component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} component - The component index. + * @return {number} The returned value. + */ + getComponent( index, component ) { - const a = i; - const b = i + 1; - const c = i + 2; + let value = this.array[ index * this.data.stride + this.offset + component ]; - intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); + if ( this.normalized ) value = denormalize( value, this.array ); - if ( intersection ) { + return value; - intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics - intersects.push( intersection ); + } - } + /** + * Sets the given value to the given component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} component - The component index. + * @param {number} value - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setComponent( index, component, value ) { - } + if ( this.normalized ) value = normalize( value, this.array ); - } + this.data.array[ index * this.data.stride + this.offset + component ] = value; - } + return this; } -} - -function checkIntersection$1( object, material, raycaster, ray, pA, pB, pC, point ) { - - let intersect; - - if ( material.side === BackSide ) { + /** + * Sets the x component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setX( index, x ) { - intersect = ray.intersectTriangle( pC, pB, pA, true, point ); + if ( this.normalized ) x = normalize( x, this.array ); - } else { + this.data.array[ index * this.data.stride + this.offset ] = x; - intersect = ray.intersectTriangle( pA, pB, pC, ( material.side === FrontSide ), point ); + return this; } - if ( intersect === null ) return null; + /** + * Sets the y component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} y - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setY( index, y ) { - _intersectionPointWorld.copy( point ); - _intersectionPointWorld.applyMatrix4( object.matrixWorld ); + if ( this.normalized ) y = normalize( y, this.array ); - const distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); + this.data.array[ index * this.data.stride + this.offset + 1 ] = y; - if ( distance < raycaster.near || distance > raycaster.far ) return null; + return this; - return { - distance: distance, - point: _intersectionPointWorld.clone(), - object: object - }; + } -} + /** + * Sets the z component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} z - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setZ( index, z ) { -function checkGeometryIntersection( object, material, raycaster, ray, uv, uv1, normal, a, b, c ) { + if ( this.normalized ) z = normalize( z, this.array ); - object.getVertexPosition( a, _vA$1 ); - object.getVertexPosition( b, _vB$1 ); - object.getVertexPosition( c, _vC$1 ); + this.data.array[ index * this.data.stride + this.offset + 2 ] = z; - const intersection = checkIntersection$1( object, material, raycaster, ray, _vA$1, _vB$1, _vC$1, _intersectionPoint ); + return this; - if ( intersection ) { + } - const barycoord = new Vector3(); - Triangle.getBarycoord( _intersectionPoint, _vA$1, _vB$1, _vC$1, barycoord ); + /** + * Sets the w component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} w - The value to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setW( index, w ) { - if ( uv ) { + if ( this.normalized ) w = normalize( w, this.array ); - intersection.uv = Triangle.getInterpolatedAttribute( uv, a, b, c, barycoord, new Vector2() ); + this.data.array[ index * this.data.stride + this.offset + 3 ] = w; - } + return this; - if ( uv1 ) { + } - intersection.uv1 = Triangle.getInterpolatedAttribute( uv1, a, b, c, barycoord, new Vector2() ); + /** + * Returns the x component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The x component. + */ + getX( index ) { - } + let x = this.data.array[ index * this.data.stride + this.offset ]; - if ( normal ) { + if ( this.normalized ) x = denormalize( x, this.array ); - intersection.normal = Triangle.getInterpolatedAttribute( normal, a, b, c, barycoord, new Vector3() ); + return x; - if ( intersection.normal.dot( ray.direction ) > 0 ) { + } - intersection.normal.multiplyScalar( -1 ); + /** + * Returns the y component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The y component. + */ + getY( index ) { - } + let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; - } + if ( this.normalized ) y = denormalize( y, this.array ); - const face = { - a: a, - b: b, - c: c, - normal: new Vector3(), - materialIndex: 0 - }; + return y; - Triangle.getNormal( _vA$1, _vB$1, _vC$1, face.normal ); + } - intersection.face = face; - intersection.barycoord = barycoord; + /** + * Returns the z component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @return {number} The z component. + */ + getZ( index ) { - } + let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; - return intersection; + if ( this.normalized ) z = denormalize( z, this.array ); -} + return z; -/** - * A geometry class for a rectangular cuboid with a given width, height, and depth. - * On creation, the cuboid is centred on the origin, with each edge parallel to one - * of the axes. - * - * ```js - * const geometry = new THREE.BoxGeometry( 1, 1, 1 ); - * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); - * const cube = new THREE.Mesh( geometry, material ); - * scene.add( cube ); - * ``` - * - * @augments BufferGeometry - * @demo scenes/geometry-browser.html#BoxGeometry - */ -class BoxGeometry extends BufferGeometry { + } /** - * Constructs a new box geometry. + * Returns the w component of the vector at the given index. * - * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis. - * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis. - * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis. - * @param {number} [widthSegments=1] - Number of segmented rectangular faces along the width of the sides. - * @param {number} [heightSegments=1] - Number of segmented rectangular faces along the height of the sides. - * @param {number} [depthSegments=1] - Number of segmented rectangular faces along the depth of the sides. + * @param {number} index - The index into the buffer attribute. + * @return {number} The w component. */ - constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) { - - super(); + getW( index ) { - this.type = 'BoxGeometry'; + let w = this.data.array[ index * this.data.stride + this.offset + 3 ]; - /** - * Holds the constructor parameters that have been - * used to generate the geometry. Any modification - * after instantiation does not change the geometry. - * - * @type {Object} - */ - this.parameters = { - width: width, - height: height, - depth: depth, - widthSegments: widthSegments, - heightSegments: heightSegments, - depthSegments: depthSegments - }; + if ( this.normalized ) w = denormalize( w, this.array ); - const scope = this; + return w; - // segments + } - widthSegments = Math.floor( widthSegments ); - heightSegments = Math.floor( heightSegments ); - depthSegments = Math.floor( depthSegments ); + /** + * Sets the x and y component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setXY( index, x, y ) { - // buffers + index = index * this.data.stride + this.offset; - const indices = []; - const vertices = []; - const normals = []; - const uvs = []; + if ( this.normalized ) { - // helper variables + x = normalize( x, this.array ); + y = normalize( y, this.array ); - let numberOfVertices = 0; - let groupStart = 0; + } - // build each side of the box geometry + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; - buildPlane( 'z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0 ); // px - buildPlane( 'z', 'y', 'x', 1, -1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx - buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py - buildPlane( 'x', 'z', 'y', 1, -1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny - buildPlane( 'x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4 ); // pz - buildPlane( 'x', 'y', 'z', -1, -1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz + return this; - // build geometry + } - this.setIndex( indices ); - this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); - this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); - this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + /** + * Sets the x, y and z component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @param {number} z - The value for the z component to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setXYZ( index, x, y, z ) { - function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { + index = index * this.data.stride + this.offset; - const segmentWidth = width / gridX; - const segmentHeight = height / gridY; + if ( this.normalized ) { - const widthHalf = width / 2; - const heightHalf = height / 2; - const depthHalf = depth / 2; + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); - const gridX1 = gridX + 1; - const gridY1 = gridY + 1; + } - let vertexCounter = 0; - let groupCount = 0; + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; + this.data.array[ index + 2 ] = z; - const vector = new Vector3(); + return this; - // generate vertices, normals and uvs + } - for ( let iy = 0; iy < gridY1; iy ++ ) { + /** + * Sets the x, y, z and w component of the vector at the given index. + * + * @param {number} index - The index into the buffer attribute. + * @param {number} x - The value for the x component to set. + * @param {number} y - The value for the y component to set. + * @param {number} z - The value for the z component to set. + * @param {number} w - The value for the w component to set. + * @return {InterleavedBufferAttribute} A reference to this instance. + */ + setXYZW( index, x, y, z, w ) { - const y = iy * segmentHeight - heightHalf; + index = index * this.data.stride + this.offset; - for ( let ix = 0; ix < gridX1; ix ++ ) { + if ( this.normalized ) { - const x = ix * segmentWidth - widthHalf; + x = normalize( x, this.array ); + y = normalize( y, this.array ); + z = normalize( z, this.array ); + w = normalize( w, this.array ); - // set values to correct vector component + } - vector[ u ] = x * udir; - vector[ v ] = y * vdir; - vector[ w ] = depthHalf; + this.data.array[ index + 0 ] = x; + this.data.array[ index + 1 ] = y; + this.data.array[ index + 2 ] = z; + this.data.array[ index + 3 ] = w; - // now apply vector to vertex buffer + return this; - vertices.push( vector.x, vector.y, vector.z ); + } - // set values to correct vector component + /** + * Returns a new buffer attribute with copied values from this instance. + * + * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. + * + * @param {Object} [data] - An object with interleaved buffers that allows to retain the interleaved property. + * @return {BufferAttribute|InterleavedBufferAttribute} A clone of this instance. + */ + clone( data ) { - vector[ u ] = 0; - vector[ v ] = 0; - vector[ w ] = depth > 0 ? 1 : -1; + if ( data === undefined ) { - // now apply vector to normal buffer + log( 'InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' ); - normals.push( vector.x, vector.y, vector.z ); + const array = []; - // uvs + for ( let i = 0; i < this.count; i ++ ) { - uvs.push( ix / gridX ); - uvs.push( 1 - ( iy / gridY ) ); + const index = i * this.data.stride + this.offset; - // counters + for ( let j = 0; j < this.itemSize; j ++ ) { - vertexCounter += 1; + array.push( this.data.array[ index + j ] ); } } - // indices - - // 1. you need three indices to draw a single face - // 2. a single segment consists of two faces - // 3. so we need to generate six (2*3) indices per segment - - for ( let iy = 0; iy < gridY; iy ++ ) { - - for ( let ix = 0; ix < gridX; ix ++ ) { - - const a = numberOfVertices + ix + gridX1 * iy; - const b = numberOfVertices + ix + gridX1 * ( iy + 1 ); - const c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); - const d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; - - // faces - - indices.push( a, b, d ); - indices.push( b, c, d ); + return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized ); - // increase counter + } else { - groupCount += 6; + if ( data.interleavedBuffers === undefined ) { - } + data.interleavedBuffers = {}; } - // add a group to the geometry. this will ensure multi material support - - scope.addGroup( groupStart, groupCount, materialIndex ); - - // calculate new start value for groups + if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) { - groupStart += groupCount; + data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data ); - // update total number of vertices + } - numberOfVertices += vertexCounter; + return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized ); } } - copy( source ) { - - super.copy( source ); - - this.parameters = Object.assign( {}, source.parameters ); - - return this; - - } - /** - * Factory method for creating an instance of this class from the given - * JSON object. + * Serializes the buffer attribute into JSON. * - * @param {Object} data - A JSON object representing the serialized geometry. - * @return {BoxGeometry} A new instance. + * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. + * + * @param {Object} [data] - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized buffer attribute. */ - static fromJSON( data ) { - - return new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments ); - - } + toJSON( data ) { -} + if ( data === undefined ) { -/** - * Provides utility functions for managing uniforms. - * - * @module UniformsUtils - */ + log( 'InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' ); -/** - * Clones the given uniform definitions by performing a deep-copy. That means - * if the value of a uniform refers to an object like a Vector3 or Texture, - * the cloned uniform will refer to a new object reference. - * - * @param {Object} src - An object representing uniform definitions. - * @return {Object} The cloned uniforms. - */ -function cloneUniforms( src ) { + const array = []; - const dst = {}; + for ( let i = 0; i < this.count; i ++ ) { - for ( const u in src ) { + const index = i * this.data.stride + this.offset; - dst[ u ] = {}; + for ( let j = 0; j < this.itemSize; j ++ ) { - for ( const p in src[ u ] ) { + array.push( this.data.array[ index + j ] ); - const property = src[ u ][ p ]; + } - if ( property && ( property.isColor || - property.isMatrix3 || property.isMatrix4 || - property.isVector2 || property.isVector3 || property.isVector4 || - property.isTexture || property.isQuaternion ) ) { + } - if ( property.isRenderTargetTexture ) { + // de-interleave data and save it as an ordinary buffer attribute for now - warn( 'UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms().' ); - dst[ u ][ p ] = null; + return { + itemSize: this.itemSize, + type: this.array.constructor.name, + array: array, + normalized: this.normalized + }; - } else { + } else { - dst[ u ][ p ] = property.clone(); + // save as true interleaved attribute - } + if ( data.interleavedBuffers === undefined ) { - } else if ( Array.isArray( property ) ) { + data.interleavedBuffers = {}; - dst[ u ][ p ] = property.slice(); + } - } else { + if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) { - dst[ u ][ p ] = property; + data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data ); } + return { + isInterleavedBufferAttribute: true, + itemSize: this.itemSize, + data: this.data.uuid, + offset: this.offset, + normalized: this.normalized + }; + } } - return dst; - } +let _materialId = 0; + /** - * Merges the given uniform definitions into a single object. Since the - * method internally uses cloneUniforms(), it performs a deep-copy when - * producing the merged uniform definitions. + * Abstract base class for materials. * - * @param {Array} uniforms - An array of objects containing uniform definitions. - * @return {Object} The merged uniforms. + * Materials define the appearance of renderable 3D objects. + * + * @abstract + * @augments EventDispatcher */ -function mergeUniforms( uniforms ) { - - const merged = {}; +class Material extends EventDispatcher { - for ( let u = 0; u < uniforms.length; u ++ ) { + /** + * Constructs a new material. + */ + constructor() { - const tmp = cloneUniforms( uniforms[ u ] ); + super(); - for ( const p in tmp ) { + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isMaterial = true; - merged[ p ] = tmp[ p ]; + /** + * The ID of the material. + * + * @name Material#id + * @type {number} + * @readonly + */ + Object.defineProperty( this, 'id', { value: _materialId ++ } ); - } - - } - - return merged; - -} - -function cloneUniformsGroups( src ) { - - const dst = []; - - for ( let u = 0; u < src.length; u ++ ) { - - dst.push( src[ u ].clone() ); - - } - - return dst; - -} + /** + * The UUID of the material. + * + * @type {string} + * @readonly + */ + this.uuid = generateUUID(); -function getUnlitUniformColorSpace( renderer ) { + /** + * The name of the material. + * + * @type {string} + */ + this.name = ''; - const currentRenderTarget = renderer.getRenderTarget(); + /** + * The type property is used for detecting the object type + * in context of serialization/deserialization. + * + * @type {string} + * @readonly + */ + this.type = 'Material'; - if ( currentRenderTarget === null ) { + /** + * Defines the blending type of the material. + * + * It must be set to `CustomBlending` if custom blending properties like + * {@link Material#blendSrc}, {@link Material#blendDst} or {@link Material#blendEquation} + * should have any effect. + * + * @type {(NoBlending|NormalBlending|AdditiveBlending|SubtractiveBlending|MultiplyBlending|CustomBlending)} + * @default NormalBlending + */ + this.blending = NormalBlending; - // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 - return renderer.outputColorSpace; + /** + * Defines which side of faces will be rendered - front, back or both. + * + * @type {(FrontSide|BackSide|DoubleSide)} + * @default FrontSide + */ + this.side = FrontSide; - } + /** + * If set to `true`, vertex colors should be used. + * + * The engine supports RGB and RGBA vertex colors depending on whether a three (RGB) or + * four (RGBA) component color buffer attribute is used. + * + * @type {boolean} + * @default false + */ + this.vertexColors = false; - // https://github.com/mrdoob/three.js/issues/27868 - if ( currentRenderTarget.isXRRenderTarget === true ) { + /** + * Defines how transparent the material is. + * A value of `0.0` indicates fully transparent, `1.0` is fully opaque. + * + * If the {@link Material#transparent} is not set to `true`, + * the material will remain fully opaque and this value will only affect its color. + * + * @type {number} + * @default 1 + */ + this.opacity = 1; - return currentRenderTarget.texture.colorSpace; + /** + * Defines whether this material is transparent. This has an effect on + * rendering as transparent objects need special treatment and are rendered + * after non-transparent objects. + * + * When set to true, the extent to which the material is transparent is + * controlled by {@link Material#opacity}. + * + * @type {boolean} + * @default false + */ + this.transparent = false; - } + /** + * Enables alpha hashed transparency, an alternative to {@link Material#transparent} or + * {@link Material#alphaTest}. The material will not be rendered if opacity is lower than + * a random threshold. Randomization introduces some grain or noise, but approximates alpha + * blending without the associated problems of sorting. Using TAA can reduce the resulting noise. + * + * @type {boolean} + * @default false + */ + this.alphaHash = false; - return ColorManagement.workingColorSpace; + /** + * Defines the blending source factor. + * + * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} + * @default SrcAlphaFactor + */ + this.blendSrc = SrcAlphaFactor; -} + /** + * Defines the blending destination factor. + * + * @type {(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} + * @default OneMinusSrcAlphaFactor + */ + this.blendDst = OneMinusSrcAlphaFactor; -// Legacy + /** + * Defines the blending equation. + * + * @type {(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)} + * @default AddEquation + */ + this.blendEquation = AddEquation; -const UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; + /** + * Defines the blending source alpha factor. + * + * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} + * @default null + */ + this.blendSrcAlpha = null; -var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; + /** + * Defines the blending destination alpha factor. + * + * @type {?(ZeroFactor|OneFactor|SrcColorFactor|OneMinusSrcColorFactor|SrcAlphaFactor|OneMinusSrcAlphaFactor|DstAlphaFactor|OneMinusDstAlphaFactor|DstColorFactor|OneMinusDstColorFactor|SrcAlphaSaturateFactor|ConstantColorFactor|OneMinusConstantColorFactor|ConstantAlphaFactor|OneMinusConstantAlphaFactor)} + * @default null + */ + this.blendDstAlpha = null; -var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; + /** + * Defines the blending equation of the alpha channel. + * + * @type {?(AddEquation|SubtractEquation|ReverseSubtractEquation|MinEquation|MaxEquation)} + * @default null + */ + this.blendEquationAlpha = null; -/** - * A material rendered with custom shaders. A shader is a small program written in GLSL. - * that runs on the GPU. You may want to use a custom shader if you need to implement an - * effect not included with any of the built-in materials. - * - * There are the following notes to bear in mind when using a `ShaderMaterial`: - * - * - `ShaderMaterial` can only be used with {@link WebGLRenderer}. - * - Built in attributes and uniforms are passed to the shaders along with your code. If - * you don't want that, use {@link RawShaderMaterial} instead. - * - You can use the directive `#pragma unroll_loop_start` and `#pragma unroll_loop_end` - * in order to unroll a `for` loop in GLSL by the shader preprocessor. The directive has - * to be placed right above the loop. The loop formatting has to correspond to a defined standard. - * - The loop has to be [normalized](https://en.wikipedia.org/wiki/Normalized_loop). - * - The loop variable has to be *i*. - * - The value `UNROLLED_LOOP_INDEX` will be replaced with the explicitly - * value of *i* for the given iteration and can be used in preprocessor - * statements. - * - * ```js - * const material = new THREE.ShaderMaterial( { - * uniforms: { - * time: { value: 1.0 }, - * resolution: { value: new THREE.Vector2() } - * }, - * vertexShader: document.getElementById( 'vertexShader' ).textContent, - * fragmentShader: document.getElementById( 'fragmentShader' ).textContent - * } ); - * ``` - * - * @augments Material - */ -class ShaderMaterial extends Material { + /** + * Represents the RGB values of the constant blend color. + * + * This property has only an effect when using custom blending with `ConstantColor` or `OneMinusConstantColor`. + * + * @type {Color} + * @default (0,0,0) + */ + this.blendColor = new Color( 0, 0, 0 ); - /** - * Constructs a new shader material. - * - * @param {Object} [parameters] - An object with one or more properties - * defining the material's appearance. Any property of the material - * (including any property from inherited materials) can be passed - * in here. Color values can be passed any type of value accepted - * by {@link Color#set}. - */ - constructor( parameters ) { + /** + * Represents the alpha value of the constant blend color. + * + * This property has only an effect when using custom blending with `ConstantAlpha` or `OneMinusConstantAlpha`. + * + * @type {number} + * @default 0 + */ + this.blendAlpha = 0; - super(); + /** + * Defines the depth function. + * + * @type {(NeverDepth|AlwaysDepth|LessDepth|LessEqualDepth|EqualDepth|GreaterEqualDepth|GreaterDepth|NotEqualDepth)} + * @default LessEqualDepth + */ + this.depthFunc = LessEqualDepth; /** - * This flag can be used for type testing. + * Whether to have depth test enabled when rendering this material. + * When the depth test is disabled, the depth write will also be implicitly disabled. * * @type {boolean} - * @readonly * @default true */ - this.isShaderMaterial = true; + this.depthTest = true; - this.type = 'ShaderMaterial'; + /** + * Whether rendering this material has any effect on the depth buffer. + * + * When drawing 2D overlays it can be useful to disable the depth writing in + * order to layer several things together without creating z-index artifacts. + * + * @type {boolean} + * @default true + */ + this.depthWrite = true; /** - * Defines custom constants using `#define` directives within the GLSL code - * for both the vertex shader and the fragment shader; each key/value pair - * yields another directive. - * ```js - * defines: { - * FOO: 15, - * BAR: true - * } - * ``` - * Yields the lines: - * ``` - * #define FOO 15 - * #define BAR true - * ``` + * The bit mask to use when writing to the stencil buffer. * - * @type {Object} + * @type {number} + * @default 0xff */ - this.defines = {}; + this.stencilWriteMask = 0xff; /** - * An object of the form: - * ```js - * { - * "uniform1": { value: 1.0 }, - * "uniform2": { value: 2 } - * } - * ``` - * specifying the uniforms to be passed to the shader code; keys are uniform - * names, values are definitions of the form - * ``` - * { - * value: 1.0 - * } - * ``` - * where `value` is the value of the uniform. Names must match the name of - * the uniform, as defined in the GLSL code. Note that uniforms are refreshed - * on every frame, so updating the value of the uniform will immediately - * update the value available to the GLSL code. + * The stencil comparison function to use. * - * @type {Object} + * @type {NeverStencilFunc|LessStencilFunc|EqualStencilFunc|LessEqualStencilFunc|GreaterStencilFunc|NotEqualStencilFunc|GreaterEqualStencilFunc|AlwaysStencilFunc} + * @default AlwaysStencilFunc */ - this.uniforms = {}; + this.stencilFunc = AlwaysStencilFunc; /** - * An array holding uniforms groups for configuring UBOs. + * The value to use when performing stencil comparisons or stencil operations. * - * @type {Array} + * @type {number} + * @default 0 */ - this.uniformsGroups = []; + this.stencilRef = 0; /** - * Vertex shader GLSL code. This is the actual code for the shader. + * The bit mask to use when comparing against the stencil buffer. * - * @type {string} + * @type {number} + * @default 0xff */ - this.vertexShader = default_vertex; + this.stencilFuncMask = 0xff; /** - * Fragment shader GLSL code. This is the actual code for the shader. + * Which stencil operation to perform when the comparison function returns `false`. * - * @type {string} + * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} + * @default KeepStencilOp */ - this.fragmentShader = default_fragment; + this.stencilFail = KeepStencilOp; /** - * Controls line thickness or lines. + * Which stencil operation to perform when the comparison function returns + * `true` but the depth test fails. * - * WebGL and WebGPU ignore this setting and always render line primitives with a - * width of one pixel. + * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} + * @default KeepStencilOp + */ + this.stencilZFail = KeepStencilOp; + + /** + * Which stencil operation to perform when the comparison function returns + * `true` and the depth test passes. * - * @type {number} - * @default 1 + * @type {ZeroStencilOp|KeepStencilOp|ReplaceStencilOp|IncrementStencilOp|DecrementStencilOp|IncrementWrapStencilOp|DecrementWrapStencilOp|InvertStencilOp} + * @default KeepStencilOp */ - this.linewidth = 1; + this.stencilZPass = KeepStencilOp; /** - * Renders the geometry as a wireframe. + * Whether stencil operations are performed against the stencil buffer. In + * order to perform writes or comparisons against the stencil buffer this + * value must be `true`. * * @type {boolean} * @default false */ - this.wireframe = false; + this.stencilWrite = false; /** - * Controls the thickness of the wireframe. - * - * WebGL and WebGPU ignore this property and always render - * 1 pixel wide lines. + * User-defined clipping planes specified as THREE.Plane objects in world + * space. These planes apply to the objects this material is attached to. + * Points in space whose signed distance to the plane is negative are clipped + * (not rendered). This requires {@link WebGLRenderer#localClippingEnabled} to + * be `true`. * - * @type {number} - * @default 1 + * @type {?Array} + * @default null */ - this.wireframeLinewidth = 1; + this.clippingPlanes = null; /** - * Defines whether the material color is affected by global fog settings; `true` - * to pass fog uniforms to the shader. - * - * Setting this property to `true` requires the definition of fog uniforms. It is - * recommended to use `UniformsUtils.merge()` to combine the custom shader uniforms - * with predefined fog uniforms. - * - * ```js - * const material = new ShaderMaterial( { - * uniforms: UniformsUtils.merge( [ UniformsLib[ 'fog' ], shaderUniforms ] ); - * vertexShader: vertexShader, - * fragmentShader: fragmentShader, - * fog: true - * } ); - * ``` + * Changes the behavior of clipping planes so that only their intersection is + * clipped, rather than their union. * * @type {boolean} * @default false */ - this.fog = false; + this.clipIntersection = false; /** - * Defines whether this material uses lighting; `true` to pass uniform data - * related to lighting to this shader. + * Defines whether to clip shadows according to the clipping planes specified + * on this material. * * @type {boolean} * @default false */ - this.lights = false; + this.clipShadows = false; /** - * Defines whether this material supports clipping; `true` to let the renderer - * pass the clippingPlanes uniform. + * Defines which side of faces cast shadows. If `null`, the side casting shadows + * is determined as follows: * - * @type {boolean} - * @default false + * - When {@link Material#side} is set to `FrontSide`, the back side cast shadows. + * - When {@link Material#side} is set to `BackSide`, the front side cast shadows. + * - When {@link Material#side} is set to `DoubleSide`, both sides cast shadows. + * + * @type {?(FrontSide|BackSide|DoubleSide)} + * @default null */ - this.clipping = false; + this.shadowSide = null; /** - * Overwritten and set to `true` by default. + * Whether to render the material's color. + * + * This can be used in conjunction with {@link Object3D#renderOder} to create invisible + * objects that occlude other objects. * * @type {boolean} * @default true */ - this.forceSinglePass = true; + this.colorWrite = true; /** - * This object allows to enable certain WebGL 2 extensions. - * - * - clipCullDistance: set to `true` to use vertex shader clipping - * - multiDraw: set to `true` to use vertex shader multi_draw / enable gl_DrawID + * Override the renderer's default precision for this material. * - * @type {{clipCullDistance:false,multiDraw:false}} + * @type {?('highp'|'mediump'|'lowp')} + * @default null */ - this.extensions = { - clipCullDistance: false, // set to use vertex shader clipping - multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID - }; + this.precision = null; /** - * When the rendered geometry doesn't include these attributes but the - * material does, these default values will be passed to the shaders. This - * avoids errors when buffer data is missing. + * Whether to use polygon offset or not. When enabled, each fragment's depth value will + * be offset after it is interpolated from the depth values of the appropriate vertices. + * The offset is added before the depth test is performed and before the value is written + * into the depth buffer. * - * - color: [ 1, 1, 1 ] - * - uv: [ 0, 0 ] - * - uv1: [ 0, 0 ] + * Can be useful for rendering hidden-line images, for applying decals to surfaces, and for + * rendering solids with highlighted edges. * - * @type {Object} + * @type {boolean} + * @default false */ - this.defaultAttributeValues = { - 'color': [ 1, 1, 1 ], - 'uv': [ 0, 0 ], - 'uv1': [ 0, 0 ] - }; + this.polygonOffset = false; /** - * If set, this calls [gl.bindAttribLocation](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation) - * to bind a generic vertex index to an attribute variable. + * Specifies a scale factor that is used to create a variable depth offset for each polygon. * - * @type {string|undefined} - * @default undefined + * @type {number} + * @default 0 */ - this.index0AttributeName = undefined; + this.polygonOffsetFactor = 0; /** - * Can be used to force a uniform update while changing uniforms in - * {@link Object3D#onBeforeRender}. + * Is multiplied by an implementation-specific value to create a constant depth offset. + * + * @type {number} + * @default 0 + */ + this.polygonOffsetUnits = 0; + + /** + * Whether to apply dithering to the color to remove the appearance of banding. * * @type {boolean} * @default false */ - this.uniformsNeedUpdate = false; + this.dithering = false; /** - * Defines the GLSL version of custom shader code. + * Whether alpha to coverage should be enabled or not. Can only be used with MSAA-enabled contexts + * (meaning when the renderer was created with *antialias* parameter set to `true`). Enabling this + * will smooth aliasing on clip plane edges and alphaTest-clipped edges. * - * @type {?(GLSL1|GLSL3)} - * @default null + * @type {boolean} + * @default false */ - this.glslVersion = null; + this.alphaToCoverage = false; - if ( parameters !== undefined ) { + /** + * Whether to premultiply the alpha (transparency) value. + * + * @type {boolean} + * @default false + */ + this.premultipliedAlpha = false; - this.setValues( parameters ); + /** + * Whether double-sided, transparent objects should be rendered with a single pass or not. + * + * The engine renders double-sided, transparent objects with two draw calls (back faces first, + * then front faces) to mitigate transparency artifacts. There are scenarios however where this + * approach produces no quality gains but still doubles draw calls e.g. when rendering flat + * vegetation like grass sprites. In these cases, set the `forceSinglePass` flag to `true` to + * disable the two pass rendering to avoid performance issues. + * + * @type {boolean} + * @default false + */ + this.forceSinglePass = false; - } + /** + * Whether it's possible to override the material with {@link Scene#overrideMaterial} or not. + * + * @type {boolean} + * @default true + */ + this.allowOverride = true; - } + /** + * Defines whether 3D objects using this material are visible. + * + * @type {boolean} + * @default true + */ + this.visible = true; - copy( source ) { - - super.copy( source ); - - this.fragmentShader = source.fragmentShader; - this.vertexShader = source.vertexShader; - - this.uniforms = cloneUniforms( source.uniforms ); - this.uniformsGroups = cloneUniformsGroups( source.uniformsGroups ); - - this.defines = Object.assign( {}, source.defines ); - - this.wireframe = source.wireframe; - this.wireframeLinewidth = source.wireframeLinewidth; - - this.fog = source.fog; - this.lights = source.lights; - this.clipping = source.clipping; - - this.extensions = Object.assign( {}, source.extensions ); - - this.glslVersion = source.glslVersion; - - this.defaultAttributeValues = Object.assign( {}, source.defaultAttributeValues ); - - this.index0AttributeName = source.index0AttributeName; - - this.uniformsNeedUpdate = source.uniformsNeedUpdate; - - return this; - - } - - toJSON( meta ) { - - const data = super.toJSON( meta ); - - data.glslVersion = this.glslVersion; - data.uniforms = {}; - - for ( const name in this.uniforms ) { - - const uniform = this.uniforms[ name ]; - const value = uniform.value; - - if ( value && value.isTexture ) { - - data.uniforms[ name ] = { - type: 't', - value: value.toJSON( meta ).uuid - }; - - } else if ( value && value.isColor ) { - - data.uniforms[ name ] = { - type: 'c', - value: value.getHex() - }; - - } else if ( value && value.isVector2 ) { - - data.uniforms[ name ] = { - type: 'v2', - value: value.toArray() - }; - - } else if ( value && value.isVector3 ) { - - data.uniforms[ name ] = { - type: 'v3', - value: value.toArray() - }; - - } else if ( value && value.isVector4 ) { - - data.uniforms[ name ] = { - type: 'v4', - value: value.toArray() - }; - - } else if ( value && value.isMatrix3 ) { - - data.uniforms[ name ] = { - type: 'm3', - value: value.toArray() - }; - - } else if ( value && value.isMatrix4 ) { - - data.uniforms[ name ] = { - type: 'm4', - value: value.toArray() - }; - - } else { - - data.uniforms[ name ] = { - value: value - }; - - // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far - - } - - } - - if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines; - - data.vertexShader = this.vertexShader; - data.fragmentShader = this.fragmentShader; - - data.lights = this.lights; - data.clipping = this.clipping; - - const extensions = {}; - - for ( const key in this.extensions ) { - - if ( this.extensions[ key ] === true ) extensions[ key ] = true; - - } - - if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions; - - return data; - - } - -} - -const _position$3 = /*@__PURE__*/ new Vector3(); -const _quaternion$2 = /*@__PURE__*/ new Quaternion(); -const _scale$2 = /*@__PURE__*/ new Vector3(); - -/** - * Abstract base class for cameras. This class should always be inherited - * when you build a new camera. - * - * @abstract - * @augments Object3D - */ -class Camera extends Object3D { - - /** - * Constructs a new camera. - */ - constructor() { - - super(); - - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isCamera = true; - - this.type = 'Camera'; - - /** - * The inverse of the camera's world matrix. - * - * @type {Matrix4} - */ - this.matrixWorldInverse = new Matrix4(); - - /** - * The camera's projection matrix. - * - * @type {Matrix4} - */ - this.projectionMatrix = new Matrix4(); - - /** - * The inverse of the camera's projection matrix. - * - * @type {Matrix4} - */ - this.projectionMatrixInverse = new Matrix4(); - - /** - * The coordinate system in which the camera is used. - * - * @type {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} - */ - this.coordinateSystem = WebGLCoordinateSystem; - - this._reversedDepth = false; - - } - - /** - * The flag that indicates whether the camera uses a reversed depth buffer. - * - * @type {boolean} - * @default false - */ - get reversedDepth() { - - return this._reversedDepth; - - } - - copy( source, recursive ) { - - super.copy( source, recursive ); - - this.matrixWorldInverse.copy( source.matrixWorldInverse ); - - this.projectionMatrix.copy( source.projectionMatrix ); - this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); - - this.coordinateSystem = source.coordinateSystem; - - return this; - - } - - /** - * Returns a vector representing the ("look") direction of the 3D object in world space. - * - * This method is overwritten since cameras have a different forward vector compared to other - * 3D objects. A camera looks down its local, negative z-axis by default. - * - * @param {Vector3} target - The target vector the result is stored to. - * @return {Vector3} The 3D object's direction in world space. - */ - getWorldDirection( target ) { - - return super.getWorldDirection( target ).negate(); - - } - - updateMatrixWorld( force ) { - - super.updateMatrixWorld( force ); - - // exclude scale from view matrix to be glTF conform - - this.matrixWorld.decompose( _position$3, _quaternion$2, _scale$2 ); - - if ( _scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1 ) { - - this.matrixWorldInverse.copy( this.matrixWorld ).invert(); - - } else { - - this.matrixWorldInverse.compose( _position$3, _quaternion$2, _scale$2.set( 1, 1, 1 ) ).invert(); - - } - - } - - updateWorldMatrix( updateParents, updateChildren ) { - - super.updateWorldMatrix( updateParents, updateChildren ); - - // exclude scale from view matrix to be glTF conform - - this.matrixWorld.decompose( _position$3, _quaternion$2, _scale$2 ); - - if ( _scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1 ) { - - this.matrixWorldInverse.copy( this.matrixWorld ).invert(); - - } else { - - this.matrixWorldInverse.compose( _position$3, _quaternion$2, _scale$2.set( 1, 1, 1 ) ).invert(); - - } - - } - - clone() { - - return new this.constructor().copy( this ); - - } - -} - -const _v3$1 = /*@__PURE__*/ new Vector3(); -const _minTarget = /*@__PURE__*/ new Vector2(); -const _maxTarget = /*@__PURE__*/ new Vector2(); - -/** - * Camera that uses [perspective projection](https://en.wikipedia.org/wiki/Perspective_(graphical)). - * - * This projection mode is designed to mimic the way the human eye sees. It - * is the most common projection mode used for rendering a 3D scene. - * - * ```js - * const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); - * scene.add( camera ); - * ``` - * - * @augments Camera - */ -class PerspectiveCamera extends Camera { - - /** - * Constructs a new perspective camera. - * - * @param {number} [fov=50] - The vertical field of view. - * @param {number} [aspect=1] - The aspect ratio. - * @param {number} [near=0.1] - The camera's near plane. - * @param {number} [far=2000] - The camera's far plane. - */ - constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) { - - super(); - - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isPerspectiveCamera = true; - - this.type = 'PerspectiveCamera'; - - /** - * The vertical field of view, from bottom to top of view, - * in degrees. - * - * @type {number} - * @default 50 - */ - this.fov = fov; - - /** - * The zoom factor of the camera. - * - * @type {number} - * @default 1 - */ - this.zoom = 1; - - /** - * The camera's near plane. The valid range is greater than `0` - * and less than the current value of {@link PerspectiveCamera#far}. - * - * Note that, unlike for the {@link OrthographicCamera}, `0` is not a - * valid value for a perspective camera's near plane. - * - * @type {number} - * @default 0.1 - */ - this.near = near; - - /** - * The camera's far plane. Must be greater than the - * current value of {@link PerspectiveCamera#near}. - * - * @type {number} - * @default 2000 - */ - this.far = far; - - /** - * Object distance used for stereoscopy and depth-of-field effects. This - * parameter does not influence the projection matrix unless a - * {@link StereoCamera} is being used. - * - * @type {number} - * @default 10 - */ - this.focus = 10; - - /** - * The aspect ratio, usually the canvas width / canvas height. - * - * @type {number} - * @default 1 - */ - this.aspect = aspect; - - /** - * Represents the frustum window specification. This property should not be edited - * directly but via {@link PerspectiveCamera#setViewOffset} and {@link PerspectiveCamera#clearViewOffset}. - * - * @type {?Object} - * @default null - */ - this.view = null; - - /** - * Film size used for the larger axis. Default is `35` (millimeters). This - * parameter does not influence the projection matrix unless {@link PerspectiveCamera#filmOffset} - * is set to a nonzero value. - * - * @type {number} - * @default 35 - */ - this.filmGauge = 35; - - /** - * Horizontal off-center offset in the same unit as {@link PerspectiveCamera#filmGauge}. - * - * @type {number} - * @default 0 - */ - this.filmOffset = 0; - - this.updateProjectionMatrix(); - - } - - copy( source, recursive ) { - - super.copy( source, recursive ); - - this.fov = source.fov; - this.zoom = source.zoom; - - this.near = source.near; - this.far = source.far; - this.focus = source.focus; - - this.aspect = source.aspect; - this.view = source.view === null ? null : Object.assign( {}, source.view ); - - this.filmGauge = source.filmGauge; - this.filmOffset = source.filmOffset; - - return this; - - } - - /** - * Sets the FOV by focal length in respect to the current {@link PerspectiveCamera#filmGauge}. - * - * The default film gauge is 35, so that the focal length can be specified for - * a 35mm (full frame) camera. - * - * @param {number} focalLength - Values for focal length and film gauge must have the same unit. - */ - setFocalLength( focalLength ) { - - /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ - const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; - - this.fov = RAD2DEG * 2 * Math.atan( vExtentSlope ); - this.updateProjectionMatrix(); - - } - - /** - * Returns the focal length from the current {@link PerspectiveCamera#fov} and - * {@link PerspectiveCamera#filmGauge}. - * - * @return {number} The computed focal length. - */ - getFocalLength() { - - const vExtentSlope = Math.tan( DEG2RAD * 0.5 * this.fov ); - - return 0.5 * this.getFilmHeight() / vExtentSlope; - - } - - /** - * Returns the current vertical field of view angle in degrees considering {@link PerspectiveCamera#zoom}. - * - * @return {number} The effective FOV. - */ - getEffectiveFOV() { - - return RAD2DEG * 2 * Math.atan( - Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom ); - - } - - /** - * Returns the width of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or - * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. - * - * @return {number} The film width. - */ - getFilmWidth() { - - // film not completely covered in portrait format (aspect < 1) - return this.filmGauge * Math.min( this.aspect, 1 ); - - } - - /** - * Returns the height of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or - * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. - * - * @return {number} The film width. - */ - getFilmHeight() { - - // film not completely covered in landscape format (aspect > 1) - return this.filmGauge / Math.max( this.aspect, 1 ); - - } - - /** - * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. - * Sets `minTarget` and `maxTarget` to the coordinates of the lower-left and upper-right corners of the view rectangle. - * - * @param {number} distance - The viewing distance. - * @param {Vector2} minTarget - The lower-left corner of the view rectangle is written into this vector. - * @param {Vector2} maxTarget - The upper-right corner of the view rectangle is written into this vector. - */ - getViewBounds( distance, minTarget, maxTarget ) { - - _v3$1.set( -1, -1, 0.5 ).applyMatrix4( this.projectionMatrixInverse ); - - minTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z ); - - _v3$1.set( 1, 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse ); - - maxTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z ); - - } - - /** - * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. - * - * @param {number} distance - The viewing distance. - * @param {Vector2} target - The target vector that is used to store result where x is width and y is height. - * @returns {Vector2} The view size. - */ - getViewSize( distance, target ) { - - this.getViewBounds( distance, _minTarget, _maxTarget ); - - return target.subVectors( _maxTarget, _minTarget ); - - } - - /** - * Sets an offset in a larger frustum. This is useful for multi-window or - * multi-monitor/multi-machine setups. - * - * For example, if you have 3x2 monitors and each monitor is 1920x1080 and - * the monitors are in grid like this - *``` - * +---+---+---+ - * | A | B | C | - * +---+---+---+ - * | D | E | F | - * +---+---+---+ - *``` - * then for each monitor you would call it like this: - *```js - * const w = 1920; - * const h = 1080; - * const fullWidth = w * 3; - * const fullHeight = h * 2; - * - * // --A-- - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); - * // --B-- - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); - * // --C-- - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); - * // --D-- - * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); - * // --E-- - * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); - * // --F-- - * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); - * ``` - * - * Note there is no reason monitors have to be the same size or in a grid. - * - * @param {number} fullWidth - The full width of multiview setup. - * @param {number} fullHeight - The full height of multiview setup. - * @param {number} x - The horizontal offset of the subcamera. - * @param {number} y - The vertical offset of the subcamera. - * @param {number} width - The width of subcamera. - * @param {number} height - The height of subcamera. - */ - setViewOffset( fullWidth, fullHeight, x, y, width, height ) { - - this.aspect = fullWidth / fullHeight; - - if ( this.view === null ) { - - this.view = { - enabled: true, - fullWidth: 1, - fullHeight: 1, - offsetX: 0, - offsetY: 0, - width: 1, - height: 1 - }; - - } - - this.view.enabled = true; - this.view.fullWidth = fullWidth; - this.view.fullHeight = fullHeight; - this.view.offsetX = x; - this.view.offsetY = y; - this.view.width = width; - this.view.height = height; - - this.updateProjectionMatrix(); - - } - - /** - * Removes the view offset from the projection matrix. - */ - clearViewOffset() { - - if ( this.view !== null ) { - - this.view.enabled = false; - - } - - this.updateProjectionMatrix(); - - } - - /** - * Updates the camera's projection matrix. Must be called after any change of - * camera properties. - */ - updateProjectionMatrix() { - - const near = this.near; - let top = near * Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom; - let height = 2 * top; - let width = this.aspect * height; - let left = -0.5 * width; - const view = this.view; - - if ( this.view !== null && this.view.enabled ) { - - const fullWidth = view.fullWidth, - fullHeight = view.fullHeight; - - left += view.offsetX * width / fullWidth; - top -= view.offsetY * height / fullHeight; - width *= view.width / fullWidth; - height *= view.height / fullHeight; - - } - - const skew = this.filmOffset; - if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); - - this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far, this.coordinateSystem, this.reversedDepth ); - - this.projectionMatrixInverse.copy( this.projectionMatrix ).invert(); - - } - - toJSON( meta ) { - - const data = super.toJSON( meta ); - - data.object.fov = this.fov; - data.object.zoom = this.zoom; - - data.object.near = this.near; - data.object.far = this.far; - data.object.focus = this.focus; - - data.object.aspect = this.aspect; - - if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); - - data.object.filmGauge = this.filmGauge; - data.object.filmOffset = this.filmOffset; - - return data; - - } - -} - -const fov = -90; // negative fov is not an error -const aspect = 1; - -/** - * A special type of camera that is positioned in 3D space to render its surroundings into a - * cube render target. The render target can then be used as an environment map for rendering - * realtime reflections in your scene. - * - * ```js - * // Create cube render target - * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 256, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); - * - * // Create cube camera - * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); - * scene.add( cubeCamera ); - * - * // Create car - * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); - * const car = new THREE.Mesh( carGeometry, chromeMaterial ); - * scene.add( car ); - * - * // Update the render target cube - * car.visible = false; - * cubeCamera.position.copy( car.position ); - * cubeCamera.update( renderer, scene ); - * - * // Render the scene - * car.visible = true; - * renderer.render( scene, camera ); - * ``` - * - * @augments Object3D - */ -class CubeCamera extends Object3D { - - /** - * Constructs a new cube camera. - * - * @param {number} near - The camera's near plane. - * @param {number} far - The camera's far plane. - * @param {WebGLCubeRenderTarget} renderTarget - The cube render target. - */ - constructor( near, far, renderTarget ) { - - super(); - - this.type = 'CubeCamera'; - - /** - * A reference to the cube render target. - * - * @type {WebGLCubeRenderTarget} - */ - this.renderTarget = renderTarget; - - /** - * The current active coordinate system. - * - * @type {?(WebGLCoordinateSystem|WebGPUCoordinateSystem)} - * @default null - */ - this.coordinateSystem = null; - - /** - * The current active mipmap level - * - * @type {number} - * @default 0 - */ - this.activeMipmapLevel = 0; - - const cameraPX = new PerspectiveCamera( fov, aspect, near, far ); - cameraPX.layers = this.layers; - this.add( cameraPX ); - - const cameraNX = new PerspectiveCamera( fov, aspect, near, far ); - cameraNX.layers = this.layers; - this.add( cameraNX ); - - const cameraPY = new PerspectiveCamera( fov, aspect, near, far ); - cameraPY.layers = this.layers; - this.add( cameraPY ); - - const cameraNY = new PerspectiveCamera( fov, aspect, near, far ); - cameraNY.layers = this.layers; - this.add( cameraNY ); - - const cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); - cameraPZ.layers = this.layers; - this.add( cameraPZ ); - - const cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); - cameraNZ.layers = this.layers; - this.add( cameraNZ ); - - } - - /** - * Must be called when the coordinate system of the cube camera is changed. - */ - updateCoordinateSystem() { - - const coordinateSystem = this.coordinateSystem; - - const cameras = this.children.concat(); - - const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = cameras; - - for ( const camera of cameras ) this.remove( camera ); - - if ( coordinateSystem === WebGLCoordinateSystem ) { - - cameraPX.up.set( 0, 1, 0 ); - cameraPX.lookAt( 1, 0, 0 ); - - cameraNX.up.set( 0, 1, 0 ); - cameraNX.lookAt( -1, 0, 0 ); - - cameraPY.up.set( 0, 0, -1 ); - cameraPY.lookAt( 0, 1, 0 ); - - cameraNY.up.set( 0, 0, 1 ); - cameraNY.lookAt( 0, -1, 0 ); - - cameraPZ.up.set( 0, 1, 0 ); - cameraPZ.lookAt( 0, 0, 1 ); - - cameraNZ.up.set( 0, 1, 0 ); - cameraNZ.lookAt( 0, 0, -1 ); - - } else if ( coordinateSystem === WebGPUCoordinateSystem ) { - - cameraPX.up.set( 0, -1, 0 ); - cameraPX.lookAt( -1, 0, 0 ); - - cameraNX.up.set( 0, -1, 0 ); - cameraNX.lookAt( 1, 0, 0 ); - - cameraPY.up.set( 0, 0, 1 ); - cameraPY.lookAt( 0, 1, 0 ); - - cameraNY.up.set( 0, 0, -1 ); - cameraNY.lookAt( 0, -1, 0 ); - - cameraPZ.up.set( 0, -1, 0 ); - cameraPZ.lookAt( 0, 0, 1 ); - - cameraNZ.up.set( 0, -1, 0 ); - cameraNZ.lookAt( 0, 0, -1 ); - - } else { - - throw new Error( 'THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: ' + coordinateSystem ); - - } - - for ( const camera of cameras ) { - - this.add( camera ); - - camera.updateMatrixWorld(); - - } - - } - - /** - * Calling this method will render the given scene with the given renderer - * into the cube render target of the camera. - * - * @param {(Renderer|WebGLRenderer)} renderer - The renderer. - * @param {Scene} scene - The scene to render. - */ - update( renderer, scene ) { - - if ( this.parent === null ) this.updateMatrixWorld(); - - const { renderTarget, activeMipmapLevel } = this; - - if ( this.coordinateSystem !== renderer.coordinateSystem ) { - - this.coordinateSystem = renderer.coordinateSystem; - - this.updateCoordinateSystem(); - - } - - const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children; - - const currentRenderTarget = renderer.getRenderTarget(); - const currentActiveCubeFace = renderer.getActiveCubeFace(); - const currentActiveMipmapLevel = renderer.getActiveMipmapLevel(); - - const currentXrEnabled = renderer.xr.enabled; - - renderer.xr.enabled = false; - - const generateMipmaps = renderTarget.texture.generateMipmaps; - - renderTarget.texture.generateMipmaps = false; - - // https://github.com/mrdoob/three.js/issues/31413#issuecomment-3095966812 - const reversedDepthBuffer = !! ( renderer.isWebGLRenderer && renderer.state.buffers.depth.getReversed() ); - - renderer.setRenderTarget( renderTarget, 0, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraPX ); - - renderer.setRenderTarget( renderTarget, 1, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraNX ); - - renderer.setRenderTarget( renderTarget, 2, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraPY ); - - renderer.setRenderTarget( renderTarget, 3, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraNY ); - - renderer.setRenderTarget( renderTarget, 4, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraPZ ); - - // mipmaps are generated during the last call of render() - // at this point, all sides of the cube render target are defined - - renderTarget.texture.generateMipmaps = generateMipmaps; - - renderer.setRenderTarget( renderTarget, 5, activeMipmapLevel ); - if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); - renderer.render( scene, cameraNZ ); - - renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel ); - - renderer.xr.enabled = currentXrEnabled; - - renderTarget.texture.needsPMREMUpdate = true; - - } - -} - -/** - * Creates a cube texture made up of six images. - * - * ```js - * const loader = new THREE.CubeTextureLoader(); - * loader.setPath( 'textures/cube/pisa/' ); - * - * const textureCube = loader.load( [ - * 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' - * ] ); - * - * const material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube } ); - * ``` - * - * @augments Texture - */ -class CubeTexture extends Texture { - - /** - * Constructs a new cube texture. - * - * @param {Array} [images=[]] - An array holding a image for each side of a cube. - * @param {number} [mapping=CubeReflectionMapping] - The texture mapping. - * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. - * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. - * @param {number} [magFilter=LinearFilter] - The mag filter value. - * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value. - * @param {number} [format=RGBAFormat] - The texture format. - * @param {number} [type=UnsignedByteType] - The texture type. - * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. - * @param {string} [colorSpace=NoColorSpace] - The color space value. - */ - constructor( images = [], mapping = CubeReflectionMapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace ) { - - super( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace ); + /** + * Defines whether this material is tone mapped according to the renderer's tone mapping setting. + * + * It is ignored when rendering to a render target or using post processing or when using + * `WebGPURenderer`. In all these cases, all materials are honored by tone mapping. + * + * @type {boolean} + * @default true + */ + this.toneMapped = true; /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isCubeTexture = true; - - /** - * If set to `true`, the texture is flipped along the vertical axis when - * uploaded to the GPU. - * - * Overwritten and set to `false` by default. - * - * @type {boolean} - * @default false - */ - this.flipY = false; - - } - - /** - * Alias for {@link CubeTexture#image}. - * - * @type {Array} - */ - get images() { - - return this.image; - - } - - set images( value ) { - - this.image = value; - - } - -} - -/** - * A cube render target used in context of {@link WebGLRenderer}. - * - * @augments WebGLRenderTarget - */ -class WebGLCubeRenderTarget extends WebGLRenderTarget { - - /** - * Constructs a new cube render target. - * - * @param {number} [size=1] - The size of the render target. - * @param {RenderTarget~Options} [options] - The configuration object. - */ - constructor( size = 1, options = {} ) { - - super( size, size, options ); - - /** - * This flag can be used for type testing. + * An object that can be used to store custom data about the Material. It + * should not hold references to functions as these will not be cloned. * - * @type {boolean} - * @readonly - * @default true - */ - this.isWebGLCubeRenderTarget = true; - - const image = { width: size, height: size, depth: 1 }; - const images = [ image, image, image, image, image, image ]; + * @type {Object} + */ + this.userData = {}; /** - * Overwritten with a different texture type. + * This starts at `0` and counts how many times {@link Material#needsUpdate} is set to `true`. * - * @type {DataArrayTexture} + * @type {number} + * @readonly + * @default 0 */ - this.texture = new CubeTexture( images ); - this._setTextureOptions( options ); - - // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) - // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, - // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. - - // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped - // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture - // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). + this.version = 0; - this.texture.isRenderTargetTexture = true; + this._alphaTest = 0; } /** - * Converts the given equirectangular texture to a cube map. + * Sets the alpha value to be used when running an alpha test. The material + * will not be rendered if the opacity is lower than this value. * - * @param {WebGLRenderer} renderer - The renderer. - * @param {Texture} texture - The equirectangular texture. - * @return {WebGLCubeRenderTarget} A reference to this cube render target. + * @type {number} + * @readonly + * @default 0 */ - fromEquirectangularTexture( renderer, texture ) { - - this.texture.type = texture.type; - this.texture.colorSpace = texture.colorSpace; - - this.texture.generateMipmaps = texture.generateMipmaps; - this.texture.minFilter = texture.minFilter; - this.texture.magFilter = texture.magFilter; - - const shader = { - - uniforms: { - tEquirect: { value: null }, - }, - - vertexShader: /* glsl */` - - varying vec3 vWorldDirection; - - vec3 transformDirection( in vec3 dir, in mat4 matrix ) { - - return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); - - } - - void main() { - - vWorldDirection = transformDirection( position, modelMatrix ); - - #include - #include - - } - `, - - fragmentShader: /* glsl */` - - uniform sampler2D tEquirect; - - varying vec3 vWorldDirection; - - #include - - void main() { - - vec3 direction = normalize( vWorldDirection ); - - vec2 sampleUV = equirectUv( direction ); - - gl_FragColor = texture2D( tEquirect, sampleUV ); - - } - ` - }; - - const geometry = new BoxGeometry( 5, 5, 5 ); + get alphaTest() { - const material = new ShaderMaterial( { + return this._alphaTest; - name: 'CubemapFromEquirect', + } - uniforms: cloneUniforms( shader.uniforms ), - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader, - side: BackSide, - blending: NoBlending + set alphaTest( value ) { - } ); + if ( this._alphaTest > 0 !== value > 0 ) { - material.uniforms.tEquirect.value = texture; + this.version ++; - const mesh = new Mesh( geometry, material ); + } - const currentMinFilter = texture.minFilter; + this._alphaTest = value; - // Avoid blurred poles - if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter; + } - const camera = new CubeCamera( 1, 10, this ); - camera.update( renderer, mesh ); + /** + * An optional callback that is executed immediately before the material is used to render a 3D object. + * + * This method can only be used when rendering with {@link WebGLRenderer}. + * + * @param {WebGLRenderer} renderer - The renderer. + * @param {Scene} scene - The scene. + * @param {Camera} camera - The camera that is used to render the scene. + * @param {BufferGeometry} geometry - The 3D object's geometry. + * @param {Object3D} object - The 3D object. + * @param {Object} group - The geometry group data. + */ + onBeforeRender( /* renderer, scene, camera, geometry, object, group */ ) {} - texture.minFilter = currentMinFilter; + /** + * An optional callback that is executed immediately before the shader + * program is compiled. This function is called with the shader source code + * as a parameter. Useful for the modification of built-in materials. + * + * This method can only be used when rendering with {@link WebGLRenderer}. The + * recommended approach when customizing materials is to use `WebGPURenderer` with the new + * Node Material system and [TSL](https://github.com/mrdoob/three.js/wiki/Three.js-Shading-Language). + * + * @param {{vertexShader:string,fragmentShader:string,uniforms:Object}} shaderobject - The object holds the uniforms and the vertex and fragment shader source. + * @param {WebGLRenderer} renderer - A reference to the renderer. + */ + onBeforeCompile( /* shaderobject, renderer */ ) {} - mesh.geometry.dispose(); - mesh.material.dispose(); + /** + * In case {@link Material#onBeforeCompile} is used, this callback can be used to identify + * values of settings used in `onBeforeCompile()`, so three.js can reuse a cached + * shader or recompile the shader for this material as needed. + * + * This method can only be used when rendering with {@link WebGLRenderer}. + * + * @return {string} The custom program cache key. + */ + customProgramCacheKey() { - return this; + return this.onBeforeCompile.toString(); } /** - * Clears this cube render target. + * This method can be used to set default values from parameter objects. + * It is a generic implementation so it can be used with different types + * of materials. * - * @param {WebGLRenderer} renderer - The renderer. - * @param {boolean} [color=true] - Whether the color buffer should be cleared or not. - * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not. - * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not. + * @param {Object} [values] - The material values to set. */ - clear( renderer, color = true, depth = true, stencil = true ) { - - const currentRenderTarget = renderer.getRenderTarget(); - - for ( let i = 0; i < 6; i ++ ) { - - renderer.setRenderTarget( this, i ); + setValues( values ) { - renderer.clear( color, depth, stencil ); + if ( values === undefined ) return; - } + for ( const key in values ) { - renderer.setRenderTarget( currentRenderTarget ); + const newValue = values[ key ]; - } + if ( newValue === undefined ) { -} + warn( `Material: parameter '${ key }' has value of undefined.` ); + continue; -/** - * This is almost identical to an {@link Object3D}. Its purpose is to - * make working with groups of objects syntactically clearer. - * - * ```js - * // Create a group and add the two cubes. - * // These cubes can now be rotated / scaled etc as a group. - * const group = new THREE.Group(); - * - * group.add( meshA ); - * group.add( meshB ); - * - * scene.add( group ); - * ``` - * - * @augments Object3D - */ -class Group extends Object3D { + } - constructor() { + const currentValue = this[ key ]; - super(); + if ( currentValue === undefined ) { - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isGroup = true; + warn( `Material: '${ key }' is not a property of THREE.${ this.type }.` ); + continue; - this.type = 'Group'; + } - } + if ( currentValue && currentValue.isColor ) { -} + currentValue.set( newValue ); -const _moveEvent = { type: 'move' }; + } else if ( ( currentValue && currentValue.isVector3 ) && ( newValue && newValue.isVector3 ) ) { -/** - * Class for representing a XR controller with its - * different coordinate systems. - * - * @private - */ -class WebXRController { + currentValue.copy( newValue ); - /** - * Constructs a new XR controller. - */ - constructor() { + } else { - /** - * A group representing the target ray space - * of the XR controller. - * - * @private - * @type {?Group} - * @default null - */ - this._targetRay = null; + this[ key ] = newValue; - /** - * A group representing the grip space - * of the XR controller. - * - * @private - * @type {?Group} - * @default null - */ - this._grip = null; + } - /** - * A group representing the hand space - * of the XR controller. - * - * @private - * @type {?Group} - * @default null - */ - this._hand = null; + } } /** - * Returns a group representing the hand space of the XR controller. + * Serializes the material into JSON. * - * @return {Group} A group representing the hand space of the XR controller. + * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. + * @return {Object} A JSON object representing the serialized material. + * @see {@link ObjectLoader#parse} */ - getHandSpace() { + toJSON( meta ) { - if ( this._hand === null ) { + const isRootObject = ( meta === undefined || typeof meta === 'string' ); - this._hand = new Group(); - this._hand.matrixAutoUpdate = false; - this._hand.visible = false; + if ( isRootObject ) { - this._hand.joints = {}; - this._hand.inputState = { pinching: false }; + meta = { + textures: {}, + images: {} + }; } - return this._hand; - - } - - /** - * Returns a group representing the target ray space of the XR controller. - * - * @return {Group} A group representing the target ray space of the XR controller. - */ - getTargetRaySpace() { + const data = { + metadata: { + version: 4.7, + type: 'Material', + generator: 'Material.toJSON' + } + }; - if ( this._targetRay === null ) { + // standard Material serialization + data.uuid = this.uuid; + data.type = this.type; - this._targetRay = new Group(); - this._targetRay.matrixAutoUpdate = false; - this._targetRay.visible = false; - this._targetRay.hasLinearVelocity = false; - this._targetRay.linearVelocity = new Vector3(); - this._targetRay.hasAngularVelocity = false; - this._targetRay.angularVelocity = new Vector3(); + if ( this.name !== '' ) data.name = this.name; - } + if ( this.color && this.color.isColor ) data.color = this.color.getHex(); - return this._targetRay; + if ( this.roughness !== undefined ) data.roughness = this.roughness; + if ( this.metalness !== undefined ) data.metalness = this.metalness; - } + if ( this.sheen !== undefined ) data.sheen = this.sheen; + if ( this.sheenColor && this.sheenColor.isColor ) data.sheenColor = this.sheenColor.getHex(); + if ( this.sheenRoughness !== undefined ) data.sheenRoughness = this.sheenRoughness; + if ( this.emissive && this.emissive.isColor ) data.emissive = this.emissive.getHex(); + if ( this.emissiveIntensity !== undefined && this.emissiveIntensity !== 1 ) data.emissiveIntensity = this.emissiveIntensity; - /** - * Returns a group representing the grip space of the XR controller. - * - * @return {Group} A group representing the grip space of the XR controller. - */ - getGripSpace() { + if ( this.specular && this.specular.isColor ) data.specular = this.specular.getHex(); + if ( this.specularIntensity !== undefined ) data.specularIntensity = this.specularIntensity; + if ( this.specularColor && this.specularColor.isColor ) data.specularColor = this.specularColor.getHex(); + if ( this.shininess !== undefined ) data.shininess = this.shininess; + if ( this.clearcoat !== undefined ) data.clearcoat = this.clearcoat; + if ( this.clearcoatRoughness !== undefined ) data.clearcoatRoughness = this.clearcoatRoughness; - if ( this._grip === null ) { + if ( this.clearcoatMap && this.clearcoatMap.isTexture ) { - this._grip = new Group(); - this._grip.matrixAutoUpdate = false; - this._grip.visible = false; - this._grip.hasLinearVelocity = false; - this._grip.linearVelocity = new Vector3(); - this._grip.hasAngularVelocity = false; - this._grip.angularVelocity = new Vector3(); + data.clearcoatMap = this.clearcoatMap.toJSON( meta ).uuid; } - return this._grip; + if ( this.clearcoatRoughnessMap && this.clearcoatRoughnessMap.isTexture ) { - } + data.clearcoatRoughnessMap = this.clearcoatRoughnessMap.toJSON( meta ).uuid; - /** - * Dispatches the given event to the groups representing - * the different coordinate spaces of the XR controller. - * - * @param {Object} event - The event to dispatch. - * @return {WebXRController} A reference to this instance. - */ - dispatchEvent( event ) { + } - if ( this._targetRay !== null ) { + if ( this.clearcoatNormalMap && this.clearcoatNormalMap.isTexture ) { - this._targetRay.dispatchEvent( event ); + data.clearcoatNormalMap = this.clearcoatNormalMap.toJSON( meta ).uuid; + data.clearcoatNormalScale = this.clearcoatNormalScale.toArray(); } - if ( this._grip !== null ) { + if ( this.sheenColorMap && this.sheenColorMap.isTexture ) { - this._grip.dispatchEvent( event ); + data.sheenColorMap = this.sheenColorMap.toJSON( meta ).uuid; } - if ( this._hand !== null ) { + if ( this.sheenRoughnessMap && this.sheenRoughnessMap.isTexture ) { - this._hand.dispatchEvent( event ); + data.sheenRoughnessMap = this.sheenRoughnessMap.toJSON( meta ).uuid; } - return this; + if ( this.dispersion !== undefined ) data.dispersion = this.dispersion; - } + if ( this.iridescence !== undefined ) data.iridescence = this.iridescence; + if ( this.iridescenceIOR !== undefined ) data.iridescenceIOR = this.iridescenceIOR; + if ( this.iridescenceThicknessRange !== undefined ) data.iridescenceThicknessRange = this.iridescenceThicknessRange; - /** - * Connects the controller with the given XR input source. - * - * @param {XRInputSource} inputSource - The input source. - * @return {WebXRController} A reference to this instance. - */ - connect( inputSource ) { + if ( this.iridescenceMap && this.iridescenceMap.isTexture ) { - if ( inputSource && inputSource.hand ) { + data.iridescenceMap = this.iridescenceMap.toJSON( meta ).uuid; - const hand = this._hand; + } - if ( hand ) { + if ( this.iridescenceThicknessMap && this.iridescenceThicknessMap.isTexture ) { - for ( const inputjoint of inputSource.hand.values() ) { + data.iridescenceThicknessMap = this.iridescenceThicknessMap.toJSON( meta ).uuid; - // Initialize hand with joints when connected - this._getHandJoint( hand, inputjoint ); + } - } + if ( this.anisotropy !== undefined ) data.anisotropy = this.anisotropy; + if ( this.anisotropyRotation !== undefined ) data.anisotropyRotation = this.anisotropyRotation; - } + if ( this.anisotropyMap && this.anisotropyMap.isTexture ) { - } + data.anisotropyMap = this.anisotropyMap.toJSON( meta ).uuid; - this.dispatchEvent( { type: 'connected', data: inputSource } ); + } - return this; + if ( this.map && this.map.isTexture ) data.map = this.map.toJSON( meta ).uuid; + if ( this.matcap && this.matcap.isTexture ) data.matcap = this.matcap.toJSON( meta ).uuid; + if ( this.alphaMap && this.alphaMap.isTexture ) data.alphaMap = this.alphaMap.toJSON( meta ).uuid; - } + if ( this.lightMap && this.lightMap.isTexture ) { - /** - * Disconnects the controller from the given XR input source. - * - * @param {XRInputSource} inputSource - The input source. - * @return {WebXRController} A reference to this instance. - */ - disconnect( inputSource ) { + data.lightMap = this.lightMap.toJSON( meta ).uuid; + data.lightMapIntensity = this.lightMapIntensity; - this.dispatchEvent( { type: 'disconnected', data: inputSource } ); + } - if ( this._targetRay !== null ) { + if ( this.aoMap && this.aoMap.isTexture ) { - this._targetRay.visible = false; + data.aoMap = this.aoMap.toJSON( meta ).uuid; + data.aoMapIntensity = this.aoMapIntensity; } - if ( this._grip !== null ) { + if ( this.bumpMap && this.bumpMap.isTexture ) { - this._grip.visible = false; + data.bumpMap = this.bumpMap.toJSON( meta ).uuid; + data.bumpScale = this.bumpScale; } - if ( this._hand !== null ) { + if ( this.normalMap && this.normalMap.isTexture ) { - this._hand.visible = false; + data.normalMap = this.normalMap.toJSON( meta ).uuid; + data.normalMapType = this.normalMapType; + data.normalScale = this.normalScale.toArray(); } - return this; - - } + if ( this.displacementMap && this.displacementMap.isTexture ) { - /** - * Updates the controller with the given input source, XR frame and reference space. - * This updates the transformations of the groups that represent the different - * coordinate systems of the controller. - * - * @param {XRInputSource} inputSource - The input source. - * @param {XRFrame} frame - The XR frame. - * @param {XRReferenceSpace} referenceSpace - The reference space. - * @return {WebXRController} A reference to this instance. - */ - update( inputSource, frame, referenceSpace ) { + data.displacementMap = this.displacementMap.toJSON( meta ).uuid; + data.displacementScale = this.displacementScale; + data.displacementBias = this.displacementBias; - let inputPose = null; - let gripPose = null; - let handPose = null; + } - const targetRay = this._targetRay; - const grip = this._grip; - const hand = this._hand; + if ( this.roughnessMap && this.roughnessMap.isTexture ) data.roughnessMap = this.roughnessMap.toJSON( meta ).uuid; + if ( this.metalnessMap && this.metalnessMap.isTexture ) data.metalnessMap = this.metalnessMap.toJSON( meta ).uuid; - if ( inputSource && frame.session.visibilityState !== 'visible-blurred' ) { + if ( this.emissiveMap && this.emissiveMap.isTexture ) data.emissiveMap = this.emissiveMap.toJSON( meta ).uuid; + if ( this.specularMap && this.specularMap.isTexture ) data.specularMap = this.specularMap.toJSON( meta ).uuid; + if ( this.specularIntensityMap && this.specularIntensityMap.isTexture ) data.specularIntensityMap = this.specularIntensityMap.toJSON( meta ).uuid; + if ( this.specularColorMap && this.specularColorMap.isTexture ) data.specularColorMap = this.specularColorMap.toJSON( meta ).uuid; - if ( hand && inputSource.hand ) { + if ( this.envMap && this.envMap.isTexture ) { - handPose = true; + data.envMap = this.envMap.toJSON( meta ).uuid; - for ( const inputjoint of inputSource.hand.values() ) { + if ( this.combine !== undefined ) data.combine = this.combine; - // Update the joints groups with the XRJoint poses - const jointPose = frame.getJointPose( inputjoint, referenceSpace ); + } - // The transform of this joint will be updated with the joint pose on each frame - const joint = this._getHandJoint( hand, inputjoint ); + if ( this.envMapRotation !== undefined ) data.envMapRotation = this.envMapRotation.toArray(); + if ( this.envMapIntensity !== undefined ) data.envMapIntensity = this.envMapIntensity; + if ( this.reflectivity !== undefined ) data.reflectivity = this.reflectivity; + if ( this.refractionRatio !== undefined ) data.refractionRatio = this.refractionRatio; - if ( jointPose !== null ) { + if ( this.gradientMap && this.gradientMap.isTexture ) { - joint.matrix.fromArray( jointPose.transform.matrix ); - joint.matrix.decompose( joint.position, joint.rotation, joint.scale ); - joint.matrixWorldNeedsUpdate = true; - joint.jointRadius = jointPose.radius; + data.gradientMap = this.gradientMap.toJSON( meta ).uuid; - } + } - joint.visible = jointPose !== null; + if ( this.transmission !== undefined ) data.transmission = this.transmission; + if ( this.transmissionMap && this.transmissionMap.isTexture ) data.transmissionMap = this.transmissionMap.toJSON( meta ).uuid; + if ( this.thickness !== undefined ) data.thickness = this.thickness; + if ( this.thicknessMap && this.thicknessMap.isTexture ) data.thicknessMap = this.thicknessMap.toJSON( meta ).uuid; + if ( this.attenuationDistance !== undefined && this.attenuationDistance !== Infinity ) data.attenuationDistance = this.attenuationDistance; + if ( this.attenuationColor !== undefined ) data.attenuationColor = this.attenuationColor.getHex(); - } + if ( this.size !== undefined ) data.size = this.size; + if ( this.shadowSide !== null ) data.shadowSide = this.shadowSide; + if ( this.sizeAttenuation !== undefined ) data.sizeAttenuation = this.sizeAttenuation; - // Custom events + if ( this.blending !== NormalBlending ) data.blending = this.blending; + if ( this.side !== FrontSide ) data.side = this.side; + if ( this.vertexColors === true ) data.vertexColors = true; - // Check pinchz - const indexTip = hand.joints[ 'index-finger-tip' ]; - const thumbTip = hand.joints[ 'thumb-tip' ]; - const distance = indexTip.position.distanceTo( thumbTip.position ); + if ( this.opacity < 1 ) data.opacity = this.opacity; + if ( this.transparent === true ) data.transparent = true; - const distanceToPinch = 0.02; - const threshold = 0.005; + if ( this.blendSrc !== SrcAlphaFactor ) data.blendSrc = this.blendSrc; + if ( this.blendDst !== OneMinusSrcAlphaFactor ) data.blendDst = this.blendDst; + if ( this.blendEquation !== AddEquation ) data.blendEquation = this.blendEquation; + if ( this.blendSrcAlpha !== null ) data.blendSrcAlpha = this.blendSrcAlpha; + if ( this.blendDstAlpha !== null ) data.blendDstAlpha = this.blendDstAlpha; + if ( this.blendEquationAlpha !== null ) data.blendEquationAlpha = this.blendEquationAlpha; + if ( this.blendColor && this.blendColor.isColor ) data.blendColor = this.blendColor.getHex(); + if ( this.blendAlpha !== 0 ) data.blendAlpha = this.blendAlpha; - if ( hand.inputState.pinching && distance > distanceToPinch + threshold ) { + if ( this.depthFunc !== LessEqualDepth ) data.depthFunc = this.depthFunc; + if ( this.depthTest === false ) data.depthTest = this.depthTest; + if ( this.depthWrite === false ) data.depthWrite = this.depthWrite; + if ( this.colorWrite === false ) data.colorWrite = this.colorWrite; - hand.inputState.pinching = false; - this.dispatchEvent( { - type: 'pinchend', - handedness: inputSource.handedness, - target: this - } ); + if ( this.stencilWriteMask !== 0xff ) data.stencilWriteMask = this.stencilWriteMask; + if ( this.stencilFunc !== AlwaysStencilFunc ) data.stencilFunc = this.stencilFunc; + if ( this.stencilRef !== 0 ) data.stencilRef = this.stencilRef; + if ( this.stencilFuncMask !== 0xff ) data.stencilFuncMask = this.stencilFuncMask; + if ( this.stencilFail !== KeepStencilOp ) data.stencilFail = this.stencilFail; + if ( this.stencilZFail !== KeepStencilOp ) data.stencilZFail = this.stencilZFail; + if ( this.stencilZPass !== KeepStencilOp ) data.stencilZPass = this.stencilZPass; + if ( this.stencilWrite === true ) data.stencilWrite = this.stencilWrite; - } else if ( ! hand.inputState.pinching && distance <= distanceToPinch - threshold ) { + // rotation (SpriteMaterial) + if ( this.rotation !== undefined && this.rotation !== 0 ) data.rotation = this.rotation; - hand.inputState.pinching = true; - this.dispatchEvent( { - type: 'pinchstart', - handedness: inputSource.handedness, - target: this - } ); + if ( this.polygonOffset === true ) data.polygonOffset = true; + if ( this.polygonOffsetFactor !== 0 ) data.polygonOffsetFactor = this.polygonOffsetFactor; + if ( this.polygonOffsetUnits !== 0 ) data.polygonOffsetUnits = this.polygonOffsetUnits; - } + if ( this.linewidth !== undefined && this.linewidth !== 1 ) data.linewidth = this.linewidth; + if ( this.dashSize !== undefined ) data.dashSize = this.dashSize; + if ( this.gapSize !== undefined ) data.gapSize = this.gapSize; + if ( this.scale !== undefined ) data.scale = this.scale; - } else { + if ( this.dithering === true ) data.dithering = true; - if ( grip !== null && inputSource.gripSpace ) { + if ( this.alphaTest > 0 ) data.alphaTest = this.alphaTest; + if ( this.alphaHash === true ) data.alphaHash = true; + if ( this.alphaToCoverage === true ) data.alphaToCoverage = true; + if ( this.premultipliedAlpha === true ) data.premultipliedAlpha = true; + if ( this.forceSinglePass === true ) data.forceSinglePass = true; + if ( this.allowOverride === false ) data.allowOverride = false; - gripPose = frame.getPose( inputSource.gripSpace, referenceSpace ); + if ( this.wireframe === true ) data.wireframe = true; + if ( this.wireframeLinewidth > 1 ) data.wireframeLinewidth = this.wireframeLinewidth; + if ( this.wireframeLinecap !== 'round' ) data.wireframeLinecap = this.wireframeLinecap; + if ( this.wireframeLinejoin !== 'round' ) data.wireframeLinejoin = this.wireframeLinejoin; - if ( gripPose !== null ) { + if ( this.flatShading === true ) data.flatShading = true; - grip.matrix.fromArray( gripPose.transform.matrix ); - grip.matrix.decompose( grip.position, grip.rotation, grip.scale ); - grip.matrixWorldNeedsUpdate = true; + if ( this.visible === false ) data.visible = false; - if ( gripPose.linearVelocity ) { + if ( this.toneMapped === false ) data.toneMapped = false; - grip.hasLinearVelocity = true; - grip.linearVelocity.copy( gripPose.linearVelocity ); + if ( this.fog === false ) data.fog = false; - } else { + if ( Object.keys( this.userData ).length > 0 ) data.userData = this.userData; - grip.hasLinearVelocity = false; + // TODO: Copied from Object3D.toJSON - } + function extractFromCache( cache ) { - if ( gripPose.angularVelocity ) { + const values = []; - grip.hasAngularVelocity = true; - grip.angularVelocity.copy( gripPose.angularVelocity ); + for ( const key in cache ) { - } else { + const data = cache[ key ]; + delete data.metadata; + values.push( data ); - grip.hasAngularVelocity = false; + } - } + return values; - } + } - } + if ( isRootObject ) { - } + const textures = extractFromCache( meta.textures ); + const images = extractFromCache( meta.images ); - if ( targetRay !== null ) { + if ( textures.length > 0 ) data.textures = textures; + if ( images.length > 0 ) data.images = images; - inputPose = frame.getPose( inputSource.targetRaySpace, referenceSpace ); + } - // Some runtimes (namely Vive Cosmos with Vive OpenXR Runtime) have only grip space and ray space is equal to it - if ( inputPose === null && gripPose !== null ) { + return data; - inputPose = gripPose; + } - } + /** + * Returns a new material with copied values from this instance. + * + * @return {Material} A clone of this instance. + */ + clone() { - if ( inputPose !== null ) { + return new this.constructor().copy( this ); - targetRay.matrix.fromArray( inputPose.transform.matrix ); - targetRay.matrix.decompose( targetRay.position, targetRay.rotation, targetRay.scale ); - targetRay.matrixWorldNeedsUpdate = true; + } - if ( inputPose.linearVelocity ) { + /** + * Copies the values of the given material to this instance. + * + * @param {Material} source - The material to copy. + * @return {Material} A reference to this instance. + */ + copy( source ) { - targetRay.hasLinearVelocity = true; - targetRay.linearVelocity.copy( inputPose.linearVelocity ); + this.name = source.name; - } else { + this.blending = source.blending; + this.side = source.side; + this.vertexColors = source.vertexColors; - targetRay.hasLinearVelocity = false; + this.opacity = source.opacity; + this.transparent = source.transparent; - } + this.blendSrc = source.blendSrc; + this.blendDst = source.blendDst; + this.blendEquation = source.blendEquation; + this.blendSrcAlpha = source.blendSrcAlpha; + this.blendDstAlpha = source.blendDstAlpha; + this.blendEquationAlpha = source.blendEquationAlpha; + this.blendColor.copy( source.blendColor ); + this.blendAlpha = source.blendAlpha; - if ( inputPose.angularVelocity ) { + this.depthFunc = source.depthFunc; + this.depthTest = source.depthTest; + this.depthWrite = source.depthWrite; - targetRay.hasAngularVelocity = true; - targetRay.angularVelocity.copy( inputPose.angularVelocity ); + this.stencilWriteMask = source.stencilWriteMask; + this.stencilFunc = source.stencilFunc; + this.stencilRef = source.stencilRef; + this.stencilFuncMask = source.stencilFuncMask; + this.stencilFail = source.stencilFail; + this.stencilZFail = source.stencilZFail; + this.stencilZPass = source.stencilZPass; + this.stencilWrite = source.stencilWrite; - } else { + const srcPlanes = source.clippingPlanes; + let dstPlanes = null; - targetRay.hasAngularVelocity = false; + if ( srcPlanes !== null ) { - } + const n = srcPlanes.length; + dstPlanes = new Array( n ); - this.dispatchEvent( _moveEvent ); + for ( let i = 0; i !== n; ++ i ) { - } + dstPlanes[ i ] = srcPlanes[ i ].clone(); } - } - if ( targetRay !== null ) { + this.clippingPlanes = dstPlanes; + this.clipIntersection = source.clipIntersection; + this.clipShadows = source.clipShadows; - targetRay.visible = ( inputPose !== null ); + this.shadowSide = source.shadowSide; - } + this.colorWrite = source.colorWrite; - if ( grip !== null ) { + this.precision = source.precision; - grip.visible = ( gripPose !== null ); + this.polygonOffset = source.polygonOffset; + this.polygonOffsetFactor = source.polygonOffsetFactor; + this.polygonOffsetUnits = source.polygonOffsetUnits; - } + this.dithering = source.dithering; - if ( hand !== null ) { + this.alphaTest = source.alphaTest; + this.alphaHash = source.alphaHash; + this.alphaToCoverage = source.alphaToCoverage; + this.premultipliedAlpha = source.premultipliedAlpha; + this.forceSinglePass = source.forceSinglePass; + this.allowOverride = source.allowOverride; - hand.visible = ( handPose !== null ); + this.visible = source.visible; - } + this.toneMapped = source.toneMapped; + + this.userData = JSON.parse( JSON.stringify( source.userData ) ); return this; } /** - * Returns a group representing the hand joint for the given input joint. + * Frees the GPU-related resources allocated by this instance. Call this + * method whenever this instance is no longer used in your app. * - * @private - * @param {Group} hand - The group representing the hand space. - * @param {XRJointSpace} inputjoint - The hand joint data. - * @return {Group} A group representing the hand joint for the given input joint. + * @fires Material#dispose */ - _getHandJoint( hand, inputjoint ) { - - if ( hand.joints[ inputjoint.jointName ] === undefined ) { + dispose() { - const joint = new Group(); - joint.matrixAutoUpdate = false; - joint.visible = false; - hand.joints[ inputjoint.jointName ] = joint; + /** + * Fires when the material has been disposed of. + * + * @event Material#dispose + * @type {Object} + */ + this.dispatchEvent( { type: 'dispose' } ); - hand.add( joint ); + } - } + /** + * Setting this property to `true` indicates the engine the material + * needs to be recompiled. + * + * @type {boolean} + * @default false + * @param {boolean} value + */ + set needsUpdate( value ) { - return hand.joints[ inputjoint.jointName ]; + if ( value === true ) this.version ++; } } /** - * This class can be used to define an exponential squared fog, - * which gives a clear view near the camera and a faster than exponentially - * densening fog farther from the camera. + * A material for rendering instances of {@link Sprite}. * * ```js - * const scene = new THREE.Scene(); - * scene.fog = new THREE.FogExp2( 0xcccccc, 0.002 ); + * const map = new THREE.TextureLoader().load( 'textures/sprite.png' ); + * const material = new THREE.SpriteMaterial( { map: map, color: 0xffffff } ); + * + * const sprite = new THREE.Sprite( material ); + * sprite.scale.set(200, 200, 1) + * scene.add( sprite ); * ``` + * + * @augments Material */ -class FogExp2 { +class SpriteMaterial extends Material { /** - * Constructs a new fog. + * Constructs a new sprite material. * - * @param {number|Color} color - The fog's color. - * @param {number} [density=0.00025] - Defines how fast the fog will grow dense. + * @param {Object} [parameters] - An object with one or more properties + * defining the material's appearance. Any property of the material + * (including any property from inherited materials) can be passed + * in here. Color values can be passed any type of value accepted + * by {@link Color#set}. */ - constructor( color, density = 0.00025 ) { + constructor( parameters ) { + + super(); /** * This flag can be used for type testing. @@ -23293,169 +21305,145 @@ class FogExp2 { * @readonly * @default true */ - this.isFogExp2 = true; + this.isSpriteMaterial = true; - /** - * The name of the fog. - * - * @type {string} - */ - this.name = ''; + this.type = 'SpriteMaterial'; /** - * The fog's color. + * Color of the material. * * @type {Color} + * @default (1,1,1) */ - this.color = new Color( color ); + this.color = new Color( 0xffffff ); /** - * Defines how fast the fog will grow dense. + * The color map. May optionally include an alpha channel, typically combined + * with {@link Material#transparent} or {@link Material#alphaTest}. The texture map + * color is modulated by the diffuse `color`. * - * @type {number} - * @default 0.00025 + * @type {?Texture} + * @default null */ - this.density = density; - - } - - /** - * Returns a new fog with copied values from this instance. - * - * @return {FogExp2} A clone of this instance. - */ - clone() { - - return new FogExp2( this.color, this.density ); - - } - - /** - * Serializes the fog into JSON. - * - * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized fog - */ - toJSON( /* meta */ ) { - - return { - type: 'FogExp2', - name: this.name, - color: this.color.getHex(), - density: this.density - }; - - } - -} - -/** - * This class can be used to define a linear fog that grows linearly denser - * with the distance. - * - * ```js - * const scene = new THREE.Scene(); - * scene.fog = new THREE.Fog( 0xcccccc, 10, 15 ); - * ``` - */ -class Fog { - - /** - * Constructs a new fog. - * - * @param {number|Color} color - The fog's color. - * @param {number} [near=1] - The minimum distance to start applying fog. - * @param {number} [far=1000] - The maximum distance at which fog stops being calculated and applied. - */ - constructor( color, near = 1, far = 1000 ) { + this.map = null; /** - * This flag can be used for type testing. + * The alpha map is a grayscale texture that controls the opacity across the + * surface (black: fully transparent; white: fully opaque). * - * @type {boolean} - * @readonly - * @default true + * Only the color of the texture is used, ignoring the alpha channel if one + * exists. For RGB and RGBA textures, the renderer will use the green channel + * when sampling this texture due to the extra bit of precision provided for + * green in DXT-compressed and uncompressed RGB 565 formats. Luminance-only and + * luminance/alpha textures will also still work as expected. + * + * @type {?Texture} + * @default null */ - this.isFog = true; + this.alphaMap = null; /** - * The name of the fog. + * The rotation of the sprite in radians. * - * @type {string} + * @type {number} + * @default 0 */ - this.name = ''; + this.rotation = 0; /** - * The fog's color. + * Specifies whether size of the sprite is attenuated by the camera depth (perspective camera only). * - * @type {Color} + * @type {boolean} + * @default true */ - this.color = new Color( color ); + this.sizeAttenuation = true; /** - * The minimum distance to start applying fog. Objects that are less than - * `near` units from the active camera won't be affected by fog. + * Overwritten since sprite materials are transparent + * by default. * - * @type {number} - * @default 1 + * @type {boolean} + * @default true */ - this.near = near; + this.transparent = true; /** - * The maximum distance at which fog stops being calculated and applied. - * Objects that are more than `far` units away from the active camera won't - * be affected by fog. + * Whether the material is affected by fog or not. * - * @type {number} - * @default 1000 + * @type {boolean} + * @default true */ - this.far = far; + this.fog = true; + + this.setValues( parameters ); } - /** - * Returns a new fog with copied values from this instance. - * - * @return {Fog} A clone of this instance. - */ - clone() { + copy( source ) { - return new Fog( this.color, this.near, this.far ); + super.copy( source ); - } + this.color.copy( source.color ); - /** - * Serializes the fog into JSON. - * - * @param {?(Object|string)} meta - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized fog - */ - toJSON( /* meta */ ) { + this.map = source.map; - return { - type: 'Fog', - name: this.name, - color: this.color.getHex(), - near: this.near, - far: this.far - }; + this.alphaMap = source.alphaMap; + + this.rotation = source.rotation; + + this.sizeAttenuation = source.sizeAttenuation; + + this.fog = source.fog; + + return this; } } +let _geometry; + +const _intersectPoint = /*@__PURE__*/ new Vector3(); +const _worldScale = /*@__PURE__*/ new Vector3(); +const _mvPosition = /*@__PURE__*/ new Vector3(); + +const _alignedPosition = /*@__PURE__*/ new Vector2(); +const _rotatedPosition = /*@__PURE__*/ new Vector2(); +const _viewWorldMatrix = /*@__PURE__*/ new Matrix4(); + +const _vA$1 = /*@__PURE__*/ new Vector3(); +const _vB$1 = /*@__PURE__*/ new Vector3(); +const _vC$1 = /*@__PURE__*/ new Vector3(); + +const _uvA = /*@__PURE__*/ new Vector2(); +const _uvB = /*@__PURE__*/ new Vector2(); +const _uvC = /*@__PURE__*/ new Vector2(); + /** - * Scenes allow you to set up what is to be rendered and where by three.js. - * This is where you place 3D objects like meshes, lines or lights. + * A sprite is a plane that always faces towards the camera, generally with a + * partially transparent texture applied. + * + * Sprites do not cast shadows, setting {@link Object3D#castShadow} to `true` will + * have no effect. + * + * ```js + * const map = new THREE.TextureLoader().load( 'sprite.png' ); + * const material = new THREE.SpriteMaterial( { map: map } ); + * + * const sprite = new THREE.Sprite( material ); + * scene.add( sprite ); + * ``` * * @augments Object3D */ -class Scene extends Object3D { +class Sprite extends Object3D { /** - * Constructs a new scene. + * Constructs a new sprite. + * + * @param {(SpriteMaterial|SpriteNodeMaterial)} [material] - The sprite material. */ - constructor() { + constructor( material = new SpriteMaterial() ) { super(); @@ -23466,160 +21454,223 @@ class Scene extends Object3D { * @readonly * @default true */ - this.isScene = true; + this.isSprite = true; - this.type = 'Scene'; + this.type = 'Sprite'; + + if ( _geometry === undefined ) { + + _geometry = new BufferGeometry(); + + const float32Array = new Float32Array( [ + -0.5, -0.5, 0, 0, 0, + 0.5, -0.5, 0, 1, 0, + 0.5, 0.5, 0, 1, 1, + -0.5, 0.5, 0, 0, 1 + ] ); + + const interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); + + _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); + _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); + _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + + } /** - * Defines the background of the scene. Valid inputs are: - * - * - A color for defining a uniform colored background. - * - A texture for defining a (flat) textured background. - * - Cube textures or equirectangular textures for defining a skybox. + * The sprite geometry. * - * @type {?(Color|Texture)} - * @default null + * @type {BufferGeometry} */ - this.background = null; + this.geometry = _geometry; /** - * Sets the environment map for all physical materials in the scene. However, - * it's not possible to overwrite an existing texture assigned to the `envMap` - * material property. + * The sprite material. * - * @type {?Texture} - * @default null + * @type {(SpriteMaterial|SpriteNodeMaterial)} */ - this.environment = null; + this.material = material; /** - * A fog instance defining the type of fog that affects everything - * rendered in the scene. + * The sprite's anchor point, and the point around which the sprite rotates. + * A value of `(0.5, 0.5)` corresponds to the midpoint of the sprite. A value + * of `(0, 0)` corresponds to the lower left corner of the sprite. * - * @type {?(Fog|FogExp2)} - * @default null + * @type {Vector2} + * @default (0.5,0.5) */ - this.fog = null; + this.center = new Vector2( 0.5, 0.5 ); /** - * Sets the blurriness of the background. Only influences environment maps - * assigned to {@link Scene#background}. Valid input is a float between `0` - * and `1`. + * The number of instances of this sprite. + * Can only be used with {@link WebGPURenderer}. * * @type {number} - * @default 0 + * @default 1 */ - this.backgroundBlurriness = 0; + this.count = 1; + + } + + /** + * Computes intersection points between a casted ray and this sprite. + * + * @param {Raycaster} raycaster - The raycaster. + * @param {Array} intersects - The target array that holds the intersection points. + */ + raycast( raycaster, intersects ) { + + if ( raycaster.camera === null ) { + + error( 'Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' ); + + } + + _worldScale.setFromMatrixScale( this.matrixWorld ); + + _viewWorldMatrix.copy( raycaster.camera.matrixWorld ); + this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld ); + + _mvPosition.setFromMatrixPosition( this.modelViewMatrix ); + + if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) { + + _worldScale.multiplyScalar( - _mvPosition.z ); + + } + + const rotation = this.material.rotation; + let sin, cos; + + if ( rotation !== 0 ) { + + cos = Math.cos( rotation ); + sin = Math.sin( rotation ); - /** - * Attenuates the color of the background. Only applies to background textures. - * - * @type {number} - * @default 1 - */ - this.backgroundIntensity = 1; + } - /** - * The rotation of the background in radians. Only influences environment maps - * assigned to {@link Scene#background}. - * - * @type {Euler} - * @default (0,0,0) - */ - this.backgroundRotation = new Euler(); + const center = this.center; - /** - * Attenuates the color of the environment. Only influences environment maps - * assigned to {@link Scene#environment}. - * - * @type {number} - * @default 1 - */ - this.environmentIntensity = 1; + transformVertex( _vA$1.set( -0.5, -0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + transformVertex( _vB$1.set( 0.5, -0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + transformVertex( _vC$1.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - /** - * The rotation of the environment map in radians. Only influences physical materials - * in the scene when {@link Scene#environment} is used. - * - * @type {Euler} - * @default (0,0,0) - */ - this.environmentRotation = new Euler(); + _uvA.set( 0, 0 ); + _uvB.set( 1, 0 ); + _uvC.set( 1, 1 ); - /** - * Forces everything in the scene to be rendered with the defined material. It is possible - * to exclude materials from override by setting {@link Material#allowOverride} to `false`. - * - * @type {?Material} - * @default null - */ - this.overrideMaterial = null; + // check first triangle + let intersect = raycaster.ray.intersectTriangle( _vA$1, _vB$1, _vC$1, false, _intersectPoint ); - if ( typeof __THREE_DEVTOOLS__ !== 'undefined' ) { + if ( intersect === null ) { - __THREE_DEVTOOLS__.dispatchEvent( new CustomEvent( 'observe', { detail: this } ) ); + // check second triangle + transformVertex( _vB$1.set( -0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + _uvB.set( 0, 1 ); + + intersect = raycaster.ray.intersectTriangle( _vA$1, _vC$1, _vB$1, false, _intersectPoint ); + if ( intersect === null ) { + + return; + + } } - } + const distance = raycaster.ray.origin.distanceTo( _intersectPoint ); - copy( source, recursive ) { + if ( distance < raycaster.near || distance > raycaster.far ) return; - super.copy( source, recursive ); + intersects.push( { - if ( source.background !== null ) this.background = source.background.clone(); - if ( source.environment !== null ) this.environment = source.environment.clone(); - if ( source.fog !== null ) this.fog = source.fog.clone(); + distance: distance, + point: _intersectPoint.clone(), + uv: Triangle.getInterpolation( _intersectPoint, _vA$1, _vB$1, _vC$1, _uvA, _uvB, _uvC, new Vector2() ), + face: null, + object: this - this.backgroundBlurriness = source.backgroundBlurriness; - this.backgroundIntensity = source.backgroundIntensity; - this.backgroundRotation.copy( source.backgroundRotation ); + } ); - this.environmentIntensity = source.environmentIntensity; - this.environmentRotation.copy( source.environmentRotation ); + } - if ( source.overrideMaterial !== null ) this.overrideMaterial = source.overrideMaterial.clone(); + copy( source, recursive ) { - this.matrixAutoUpdate = source.matrixAutoUpdate; + super.copy( source, recursive ); + + if ( source.center !== undefined ) this.center.copy( source.center ); + + this.material = source.material; return this; } - toJSON( meta ) { +} - const data = super.toJSON( meta ); +function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { - if ( this.fog !== null ) data.object.fog = this.fog.toJSON(); + // compute position in camera space + _alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); - if ( this.backgroundBlurriness > 0 ) data.object.backgroundBlurriness = this.backgroundBlurriness; - if ( this.backgroundIntensity !== 1 ) data.object.backgroundIntensity = this.backgroundIntensity; - data.object.backgroundRotation = this.backgroundRotation.toArray(); + // to check if rotation is not zero + if ( sin !== undefined ) { - if ( this.environmentIntensity !== 1 ) data.object.environmentIntensity = this.environmentIntensity; - data.object.environmentRotation = this.environmentRotation.toArray(); + _rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y ); + _rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y ); - return data; + } else { + + _rotatedPosition.copy( _alignedPosition ); } + + vertexPosition.copy( mvPosition ); + vertexPosition.x += _rotatedPosition.x; + vertexPosition.y += _rotatedPosition.y; + + // transform to world space + vertexPosition.applyMatrix4( _viewWorldMatrix ); + } +const _v1$2 = /*@__PURE__*/ new Vector3(); +const _v2$1 = /*@__PURE__*/ new Vector3(); + /** - * "Interleaved" means that multiple attributes, possibly of different types, - * (e.g., position, normal, uv, color) are packed into a single array buffer. + * A component for providing a basic Level of Detail (LOD) mechanism. * - * An introduction into interleaved arrays can be found here: [Interleaved array basics](https://blog.tojicode.com/2011/05/interleaved-array-basics.html) + * Every LOD level is associated with an object, and rendering can be switched + * between them at the distances specified. Typically you would create, say, + * three meshes, one for far away (low detail), one for mid range (medium + * detail) and one for close up (high detail). + * + * ```js + * const lod = new THREE.LOD(); + * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + * + * //Create spheres with 3 levels of detail and create new LOD levels for them + * for( let i = 0; i < 3; i++ ) { + * + * const geometry = new THREE.IcosahedronGeometry( 10, 3 - i ); + * const mesh = new THREE.Mesh( geometry, material ); + * lod.addLevel( mesh, i * 75 ); + * + * } + * + * scene.add( lod ); + * ``` + * + * @augments Object3D */ -class InterleavedBuffer { +class LOD extends Object3D { /** - * Constructs a new interleaved buffer. - * - * @param {TypedArray} array - A typed array with a shared buffer storing attribute data. - * @param {number} stride - The number of typed-array elements per vertex. + * Constructs a new LOD. */ - constructor( array, stride ) { + constructor() { + + super(); /** * This flag can be used for type testing. @@ -23628,830 +21679,949 @@ class InterleavedBuffer { * @readonly * @default true */ - this.isInterleavedBuffer = true; - - /** - * A typed array with a shared buffer storing attribute data. - * - * @type {TypedArray} - */ - this.array = array; + this.isLOD = true; /** - * The number of typed-array elements per vertex. + * The current LOD index. * + * @private * @type {number} + * @default 0 */ - this.stride = stride; + this._currentLevel = 0; - /** - * The total number of elements in the array - * - * @type {number} - * @readonly - */ - this.count = array !== undefined ? array.length / stride : 0; + this.type = 'LOD'; - /** - * Defines the intended usage pattern of the data store for optimization purposes. - * - * Note: After the initial use of a buffer, its usage cannot be changed. Instead, - * instantiate a new one and set the desired usage before the next render. - * - * @type {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} - * @default StaticDrawUsage - */ - this.usage = StaticDrawUsage; + Object.defineProperties( this, { + /** + * This array holds the LOD levels. + * + * @name LOD#levels + * @type {Array<{object:Object3D,distance:number,hysteresis:number}>} + */ + levels: { + enumerable: true, + value: [] + } + } ); /** - * This can be used to only update some components of stored vectors (for example, just the - * component related to color). Use the `addUpdateRange()` function to add ranges to this array. + * Whether the LOD object is updated automatically by the renderer per frame + * or not. If set to `false`, you have to call {@link LOD#update} in the + * render loop by yourself. * - * @type {Array} + * @type {boolean} + * @default true */ - this.updateRanges = []; + this.autoUpdate = true; - /** - * A version number, incremented every time the `needsUpdate` is set to `true`. - * - * @type {number} - */ - this.version = 0; + } - /** - * The UUID of the interleaved buffer. - * - * @type {string} - * @readonly - */ - this.uuid = generateUUID(); + copy( source ) { - } + super.copy( source, false ); - /** - * A callback function that is executed after the renderer has transferred the attribute array - * data to the GPU. - */ - onUploadCallback() {} + const levels = source.levels; - /** - * Flag to indicate that this attribute has changed and should be re-sent to - * the GPU. Set this to `true` when you modify the value of the array. - * - * @type {number} - * @default false - * @param {boolean} value - */ - set needsUpdate( value ) { + for ( let i = 0, l = levels.length; i < l; i ++ ) { - if ( value === true ) this.version ++; + const level = levels[ i ]; - } + this.addLevel( level.object.clone(), level.distance, level.hysteresis ); - /** - * Sets the usage of this interleaved buffer. - * - * @param {(StaticDrawUsage|DynamicDrawUsage|StreamDrawUsage|StaticReadUsage|DynamicReadUsage|StreamReadUsage|StaticCopyUsage|DynamicCopyUsage|StreamCopyUsage)} value - The usage to set. - * @return {InterleavedBuffer} A reference to this interleaved buffer. - */ - setUsage( value ) { + } - this.usage = value; + this.autoUpdate = source.autoUpdate; return this; } /** - * Adds a range of data in the data array to be updated on the GPU. + * Adds a mesh that will display at a certain distance and greater. Typically + * the further away the distance, the lower the detail on the mesh. * - * @param {number} start - Position at which to start update. - * @param {number} count - The number of components to update. + * @param {Object3D} object - The 3D object to display at this level. + * @param {number} [distance=0] - The distance at which to display this level of detail. + * @param {number} [hysteresis=0] - Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. + * @return {LOD} A reference to this instance. */ - addUpdateRange( start, count ) { + addLevel( object, distance = 0, hysteresis = 0 ) { - this.updateRanges.push( { start, count } ); + distance = Math.abs( distance ); - } + const levels = this.levels; - /** - * Clears the update ranges. - */ - clearUpdateRanges() { + let l; - this.updateRanges.length = 0; + for ( l = 0; l < levels.length; l ++ ) { - } + if ( distance < levels[ l ].distance ) { - /** - * Copies the values of the given interleaved buffer to this instance. - * - * @param {InterleavedBuffer} source - The interleaved buffer to copy. - * @return {InterleavedBuffer} A reference to this instance. - */ - copy( source ) { + break; - this.array = new source.array.constructor( source.array ); - this.count = source.count; - this.stride = source.stride; - this.usage = source.usage; + } + + } + + levels.splice( l, 0, { distance: distance, hysteresis: hysteresis, object: object } ); + + this.add( object ); return this; } /** - * Copies a vector from the given interleaved buffer to this one. The start - * and destination position in the attribute buffers are represented by the - * given indices. + * Removes an existing level, based on the distance from the camera. + * Returns `true` when the level has been removed. Otherwise `false`. * - * @param {number} index1 - The destination index into this interleaved buffer. - * @param {InterleavedBuffer} interleavedBuffer - The interleaved buffer to copy from. - * @param {number} index2 - The source index into the given interleaved buffer. - * @return {InterleavedBuffer} A reference to this instance. + * @param {number} distance - Distance of the level to remove. + * @return {boolean} Whether the level has been removed or not. */ - copyAt( index1, interleavedBuffer, index2 ) { + removeLevel( distance ) { - index1 *= this.stride; - index2 *= interleavedBuffer.stride; + const levels = this.levels; - for ( let i = 0, l = this.stride; i < l; i ++ ) { + for ( let i = 0; i < levels.length; i ++ ) { - this.array[ index1 + i ] = interleavedBuffer.array[ index2 + i ]; + if ( levels[ i ].distance === distance ) { + + const removedElements = levels.splice( i, 1 ); + this.remove( removedElements[ 0 ].object ); + + return true; + + } } - return this; + return false; } /** - * Sets the given array data in the interleaved buffer. + * Returns the currently active LOD level index. * - * @param {(TypedArray|Array)} value - The array data to set. - * @param {number} [offset=0] - The offset in this interleaved buffer's array. - * @return {InterleavedBuffer} A reference to this instance. + * @return {number} The current active LOD level index. */ - set( value, offset = 0 ) { - - this.array.set( value, offset ); + getCurrentLevel() { - return this; + return this._currentLevel; } /** - * Returns a new interleaved buffer with copied values from this instance. + * Returns a reference to the first 3D object that is greater than + * the given distance. * - * @param {Object} [data] - An object with shared array buffers that allows to retain shared structures. - * @return {InterleavedBuffer} A clone of this instance. + * @param {number} distance - The LOD distance. + * @return {?Object3D} The found 3D object. `null` if no 3D object has been found. */ - clone( data ) { + getObjectForDistance( distance ) { - if ( data.arrayBuffers === undefined ) { + const levels = this.levels; - data.arrayBuffers = {}; + if ( levels.length > 0 ) { - } + let i, l; - if ( this.array.buffer._uuid === undefined ) { + for ( i = 1, l = levels.length; i < l; i ++ ) { - this.array.buffer._uuid = generateUUID(); + let levelDistance = levels[ i ].distance; - } + if ( levels[ i ].object.visible ) { - if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { + levelDistance -= levelDistance * levels[ i ].hysteresis; - data.arrayBuffers[ this.array.buffer._uuid ] = this.array.slice( 0 ).buffer; + } - } + if ( distance < levelDistance ) { - const array = new this.array.constructor( data.arrayBuffers[ this.array.buffer._uuid ] ); + break; - const ib = new this.constructor( array, this.stride ); - ib.setUsage( this.usage ); + } - return ib; + } + + return levels[ i - 1 ].object; + + } + + return null; } /** - * Sets the given callback function that is executed after the Renderer has transferred - * the array data to the GPU. Can be used to perform clean-up operations after - * the upload when data are not needed anymore on the CPU side. + * Computes intersection points between a casted ray and this LOD. * - * @param {Function} callback - The `onUpload()` callback. - * @return {InterleavedBuffer} A reference to this instance. + * @param {Raycaster} raycaster - The raycaster. + * @param {Array} intersects - The target array that holds the intersection points. */ - onUpload( callback ) { + raycast( raycaster, intersects ) { - this.onUploadCallback = callback; + const levels = this.levels; - return this; + if ( levels.length > 0 ) { + + _v1$2.setFromMatrixPosition( this.matrixWorld ); + + const distance = raycaster.ray.origin.distanceTo( _v1$2 ); + + this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + + } } /** - * Serializes the interleaved buffer into JSON. + * Updates the LOD by computing which LOD level should be visible according + * to the current distance of the given camera. * - * @param {Object} [data] - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized interleaved buffer. + * @param {Camera} camera - The camera the scene is rendered with. */ - toJSON( data ) { + update( camera ) { - if ( data.arrayBuffers === undefined ) { + const levels = this.levels; - data.arrayBuffers = {}; + if ( levels.length > 1 ) { - } + _v1$2.setFromMatrixPosition( camera.matrixWorld ); + _v2$1.setFromMatrixPosition( this.matrixWorld ); - // generate UUID for array buffer if necessary + const distance = _v1$2.distanceTo( _v2$1 ) / camera.zoom; - if ( this.array.buffer._uuid === undefined ) { + levels[ 0 ].object.visible = true; - this.array.buffer._uuid = generateUUID(); + let i, l; - } + for ( i = 1, l = levels.length; i < l; i ++ ) { - if ( data.arrayBuffers[ this.array.buffer._uuid ] === undefined ) { + let levelDistance = levels[ i ].distance; - data.arrayBuffers[ this.array.buffer._uuid ] = Array.from( new Uint32Array( this.array.buffer ) ); + if ( levels[ i ].object.visible ) { - } + levelDistance -= levelDistance * levels[ i ].hysteresis; - // + } - return { - uuid: this.uuid, - buffer: this.array.buffer._uuid, - type: this.array.constructor.name, - stride: this.stride - }; + if ( distance >= levelDistance ) { + + levels[ i - 1 ].object.visible = false; + levels[ i ].object.visible = true; + + } else { + + break; + + } + + } + + this._currentLevel = i - 1; + + for ( ; i < l; i ++ ) { + + levels[ i ].object.visible = false; + + } + + } } -} + toJSON( meta ) { -const _vector$7 = /*@__PURE__*/ new Vector3(); + const data = super.toJSON( meta ); -/** - * An alternative version of a buffer attribute with interleaved data. Interleaved - * attributes share a common interleaved data storage ({@link InterleavedBuffer}) and refer with - * different offsets into the buffer. - */ -class InterleavedBufferAttribute { + if ( this.autoUpdate === false ) data.object.autoUpdate = false; - /** - * Constructs a new interleaved buffer attribute. - * - * @param {InterleavedBuffer} interleavedBuffer - The buffer holding the interleaved data. - * @param {number} itemSize - The item size. - * @param {number} offset - The attribute offset into the buffer. - * @param {boolean} [normalized=false] - Whether the data are normalized or not. - */ - constructor( interleavedBuffer, itemSize, offset, normalized = false ) { + data.object.levels = []; - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isInterleavedBufferAttribute = true; + const levels = this.levels; + + for ( let i = 0, l = levels.length; i < l; i ++ ) { + + const level = levels[ i ]; + + data.object.levels.push( { + object: level.object.uuid, + distance: level.distance, + hysteresis: level.hysteresis + } ); + + } + + return data; + + } + +} + +const _vector$7 = /*@__PURE__*/ new Vector3(); +const _segCenter = /*@__PURE__*/ new Vector3(); +const _segDir = /*@__PURE__*/ new Vector3(); +const _diff = /*@__PURE__*/ new Vector3(); - /** - * The name of the buffer attribute. - * - * @type {string} - */ - this.name = ''; +const _edge1 = /*@__PURE__*/ new Vector3(); +const _edge2 = /*@__PURE__*/ new Vector3(); +const _normal$1 = /*@__PURE__*/ new Vector3(); - /** - * The buffer holding the interleaved data. - * - * @type {InterleavedBuffer} - */ - this.data = interleavedBuffer; +/** + * A ray that emits from an origin in a certain direction. The class is used by + * {@link Raycaster} to assist with raycasting. Raycasting is used for + * mouse picking (working out what objects in the 3D space the mouse is over) + * amongst other things. + */ +class Ray { - /** - * The item size, see {@link BufferAttribute#itemSize}. - * - * @type {number} - */ - this.itemSize = itemSize; + /** + * Constructs a new ray. + * + * @param {Vector3} [origin=(0,0,0)] - The origin of the ray. + * @param {Vector3} [direction=(0,0,-1)] - The (normalized) direction of the ray. + */ + constructor( origin = new Vector3(), direction = new Vector3( 0, 0, -1 ) ) { /** - * The attribute offset into the buffer. + * The origin of the ray. * - * @type {number} + * @type {Vector3} */ - this.offset = offset; + this.origin = origin; /** - * Whether the data are normalized or not, see {@link BufferAttribute#normalized} + * The (normalized) direction of the ray. * - * @type {InterleavedBuffer} + * @type {Vector3} */ - this.normalized = normalized; + this.direction = direction; } /** - * The item count of this buffer attribute. + * Sets the ray's components by copying the given values. * - * @type {number} - * @readonly + * @param {Vector3} origin - The origin. + * @param {Vector3} direction - The direction. + * @return {Ray} A reference to this ray. */ - get count() { + set( origin, direction ) { - return this.data.count; + this.origin.copy( origin ); + this.direction.copy( direction ); + + return this; } /** - * The array holding the interleaved buffer attribute data. + * Copies the values of the given ray to this instance. * - * @type {TypedArray} + * @param {Ray} ray - The ray to copy. + * @return {Ray} A reference to this ray. */ - get array() { + copy( ray ) { - return this.data.array; + this.origin.copy( ray.origin ); + this.direction.copy( ray.direction ); + + return this; } /** - * Flag to indicate that this attribute has changed and should be re-sent to - * the GPU. Set this to `true` when you modify the value of the array. + * Returns a vector that is located at a given distance along this ray. * - * @type {number} - * @default false - * @param {boolean} value + * @param {number} t - The distance along the ray to retrieve a position for. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} A position on the ray. */ - set needsUpdate( value ) { + at( t, target ) { - this.data.needsUpdate = value; + return target.copy( this.origin ).addScaledVector( this.direction, t ); } /** - * Applies the given 4x4 matrix to the given attribute. Only works with - * item size `3`. + * Adjusts the direction of the ray to point at the given vector in world space. * - * @param {Matrix4} m - The matrix to apply. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Vector3} v - The target position. + * @return {Ray} A reference to this ray. */ - applyMatrix4( m ) { + lookAt( v ) { - for ( let i = 0, l = this.data.count; i < l; i ++ ) { + this.direction.copy( v ).sub( this.origin ).normalize(); - _vector$7.fromBufferAttribute( this, i ); + return this; - _vector$7.applyMatrix4( m ); + } - this.setXYZ( i, _vector$7.x, _vector$7.y, _vector$7.z ); + /** + * Shift the origin of this ray along its direction by the given distance. + * + * @param {number} t - The distance along the ray to interpolate. + * @return {Ray} A reference to this ray. + */ + recast( t ) { - } + this.origin.copy( this.at( t, _vector$7 ) ); return this; } /** - * Applies the given 3x3 normal matrix to the given attribute. Only works with - * item size `3`. + * Returns the point along this ray that is closest to the given point. * - * @param {Matrix3} m - The normal matrix to apply. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Vector3} point - A point in 3D space to get the closet location on the ray for. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {Vector3} The closest point on this ray. */ - applyNormalMatrix( m ) { + closestPointToPoint( point, target ) { - for ( let i = 0, l = this.count; i < l; i ++ ) { + target.subVectors( point, this.origin ); - _vector$7.fromBufferAttribute( this, i ); + const directionDistance = target.dot( this.direction ); - _vector$7.applyNormalMatrix( m ); + if ( directionDistance < 0 ) { - this.setXYZ( i, _vector$7.x, _vector$7.y, _vector$7.z ); + return target.copy( this.origin ); } - return this; + return target.copy( this.origin ).addScaledVector( this.direction, directionDistance ); } /** - * Applies the given 4x4 matrix to the given attribute. Only works with - * item size `3` and with direction vectors. + * Returns the distance of the closest approach between this ray and the given point. * - * @param {Matrix4} m - The matrix to apply. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Vector3} point - A point in 3D space to compute the distance to. + * @return {number} The distance. */ - transformDirection( m ) { + distanceToPoint( point ) { - for ( let i = 0, l = this.count; i < l; i ++ ) { + return Math.sqrt( this.distanceSqToPoint( point ) ); + + } + + /** + * Returns the squared distance of the closest approach between this ray and the given point. + * + * @param {Vector3} point - A point in 3D space to compute the distance to. + * @return {number} The squared distance. + */ + distanceSqToPoint( point ) { - _vector$7.fromBufferAttribute( this, i ); + const directionDistance = _vector$7.subVectors( point, this.origin ).dot( this.direction ); + + // point behind the ray - _vector$7.transformDirection( m ); + if ( directionDistance < 0 ) { - this.setXYZ( i, _vector$7.x, _vector$7.y, _vector$7.z ); + return this.origin.distanceToSquared( point ); } - return this; + _vector$7.copy( this.origin ).addScaledVector( this.direction, directionDistance ); + + return _vector$7.distanceToSquared( point ); } /** - * Returns the given component of the vector at the given index. + * Returns the squared distance between this ray and the given line segment. * - * @param {number} index - The index into the buffer attribute. - * @param {number} component - The component index. - * @return {number} The returned value. + * @param {Vector3} v0 - The start point of the line segment. + * @param {Vector3} v1 - The end point of the line segment. + * @param {Vector3} [optionalPointOnRay] - When provided, it receives the point on this ray that is closest to the segment. + * @param {Vector3} [optionalPointOnSegment] - When provided, it receives the point on the line segment that is closest to this ray. + * @return {number} The squared distance. */ - getComponent( index, component ) { + distanceSqToSegment( v0, v1, optionalPointOnRay, optionalPointOnSegment ) { - let value = this.array[ index * this.data.stride + this.offset + component ]; + // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteDistRaySegment.h + // It returns the min distance between the ray and the segment + // defined by v0 and v1 + // It can also set two optional targets : + // - The closest point on the ray + // - The closest point on the segment - if ( this.normalized ) value = denormalize( value, this.array ); + _segCenter.copy( v0 ).add( v1 ).multiplyScalar( 0.5 ); + _segDir.copy( v1 ).sub( v0 ).normalize(); + _diff.copy( this.origin ).sub( _segCenter ); - return value; + const segExtent = v0.distanceTo( v1 ) * 0.5; + const a01 = - this.direction.dot( _segDir ); + const b0 = _diff.dot( this.direction ); + const b1 = - _diff.dot( _segDir ); + const c = _diff.lengthSq(); + const det = Math.abs( 1 - a01 * a01 ); + let s0, s1, sqrDist, extDet; - } + if ( det > 0 ) { - /** - * Sets the given value to the given component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} component - The component index. - * @param {number} value - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setComponent( index, component, value ) { + // The ray and segment are not parallel. - if ( this.normalized ) value = normalize( value, this.array ); + s0 = a01 * b1 - b0; + s1 = a01 * b0 - b1; + extDet = segExtent * det; - this.data.array[ index * this.data.stride + this.offset + component ] = value; + if ( s0 >= 0 ) { - return this; + if ( s1 >= - extDet ) { - } + if ( s1 <= extDet ) { - /** - * Sets the x component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setX( index, x ) { + // region 0 + // Minimum at interior points of ray and segment. - if ( this.normalized ) x = normalize( x, this.array ); + const invDet = 1 / det; + s0 *= invDet; + s1 *= invDet; + sqrDist = s0 * ( s0 + a01 * s1 + 2 * b0 ) + s1 * ( a01 * s0 + s1 + 2 * b1 ) + c; - this.data.array[ index * this.data.stride + this.offset ] = x; + } else { - return this; + // region 1 - } + s1 = segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - /** - * Sets the y component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} y - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setY( index, y ) { + } - if ( this.normalized ) y = normalize( y, this.array ); + } else { - this.data.array[ index * this.data.stride + this.offset + 1 ] = y; + // region 5 - return this; + s1 = - segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } + } - /** - * Sets the z component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} z - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setZ( index, z ) { + } else { - if ( this.normalized ) z = normalize( z, this.array ); + if ( s1 <= - extDet ) { - this.data.array[ index * this.data.stride + this.offset + 2 ] = z; + // region 4 - return this; + s0 = Math.max( 0, - ( - a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? - segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; - } + } else if ( s1 <= extDet ) { - /** - * Sets the w component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} w - The value to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setW( index, w ) { + // region 3 - if ( this.normalized ) w = normalize( w, this.array ); + s0 = 0; + s1 = Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = s1 * ( s1 + 2 * b1 ) + c; - this.data.array[ index * this.data.stride + this.offset + 3 ] = w; + } else { - return this; + // region 2 + + s0 = Math.max( 0, - ( a01 * segExtent + b0 ) ); + s1 = ( s0 > 0 ) ? segExtent : Math.min( Math.max( - segExtent, - b1 ), segExtent ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + + } + + } + + } else { + + // Ray and segment are parallel. + + s1 = ( a01 > 0 ) ? - segExtent : segExtent; + s0 = Math.max( 0, - ( a01 * s1 + b0 ) ); + sqrDist = - s0 * s0 + s1 * ( s1 + 2 * b1 ) + c; + + } + + if ( optionalPointOnRay ) { + + optionalPointOnRay.copy( this.origin ).addScaledVector( this.direction, s0 ); + + } + + if ( optionalPointOnSegment ) { + + optionalPointOnSegment.copy( _segCenter ).addScaledVector( _segDir, s1 ); + + } + + return sqrDist; } /** - * Returns the x component of the vector at the given index. + * Intersects this ray with the given sphere, returning the intersection + * point or `null` if there is no intersection. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The x component. + * @param {Sphere} sphere - The sphere to intersect. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The intersection point. */ - getX( index ) { + intersectSphere( sphere, target ) { - let x = this.data.array[ index * this.data.stride + this.offset ]; + _vector$7.subVectors( sphere.center, this.origin ); + const tca = _vector$7.dot( this.direction ); + const d2 = _vector$7.dot( _vector$7 ) - tca * tca; + const radius2 = sphere.radius * sphere.radius; - if ( this.normalized ) x = denormalize( x, this.array ); + if ( d2 > radius2 ) return null; - return x; + const thc = Math.sqrt( radius2 - d2 ); + + // t0 = first intersect point - entrance on front of sphere + const t0 = tca - thc; + + // t1 = second intersect point - exit point on back of sphere + const t1 = tca + thc; + + // test to see if t1 is behind the ray - if so, return null + if ( t1 < 0 ) return null; + + // test to see if t0 is behind the ray: + // if it is, the ray is inside the sphere, so return the second exit point scaled by t1, + // in order to always return an intersect point that is in front of the ray. + if ( t0 < 0 ) return this.at( t1, target ); + + // else t0 is in front of the ray, so return the first collision point scaled by t0 + return this.at( t0, target ); } /** - * Returns the y component of the vector at the given index. + * Returns `true` if this ray intersects with the given sphere. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The y component. + * @param {Sphere} sphere - The sphere to intersect. + * @return {boolean} Whether this ray intersects with the given sphere or not. */ - getY( index ) { - - let y = this.data.array[ index * this.data.stride + this.offset + 1 ]; + intersectsSphere( sphere ) { - if ( this.normalized ) y = denormalize( y, this.array ); + if ( sphere.radius < 0 ) return false; // handle empty spheres, see #31187 - return y; + return this.distanceSqToPoint( sphere.center ) <= ( sphere.radius * sphere.radius ); } /** - * Returns the z component of the vector at the given index. + * Computes the distance from the ray's origin to the given plane. Returns `null` if the ray + * does not intersect with the plane. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The z component. + * @param {Plane} plane - The plane to compute the distance to. + * @return {?number} Whether this ray intersects with the given sphere or not. */ - getZ( index ) { + distanceToPlane( plane ) { - let z = this.data.array[ index * this.data.stride + this.offset + 2 ]; + const denominator = plane.normal.dot( this.direction ); - if ( this.normalized ) z = denormalize( z, this.array ); + if ( denominator === 0 ) { - return z; + // line is coplanar, return origin + if ( plane.distanceToPoint( this.origin ) === 0 ) { + + return 0; + + } + + // Null is preferable to undefined since undefined means.... it is undefined + + return null; + + } + + const t = - ( this.origin.dot( plane.normal ) + plane.constant ) / denominator; + + // Return if the ray never intersects the plane + + return t >= 0 ? t : null; } /** - * Returns the w component of the vector at the given index. + * Intersects this ray with the given plane, returning the intersection + * point or `null` if there is no intersection. * - * @param {number} index - The index into the buffer attribute. - * @return {number} The w component. + * @param {Plane} plane - The plane to intersect. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The intersection point. */ - getW( index ) { + intersectPlane( plane, target ) { - let w = this.data.array[ index * this.data.stride + this.offset + 3 ]; + const t = this.distanceToPlane( plane ); - if ( this.normalized ) w = denormalize( w, this.array ); + if ( t === null ) { - return w; + return null; + + } + + return this.at( t, target ); } /** - * Sets the x and y component of the vector at the given index. + * Returns `true` if this ray intersects with the given plane. * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Plane} plane - The plane to intersect. + * @return {boolean} Whether this ray intersects with the given plane or not. */ - setXY( index, x, y ) { + intersectsPlane( plane ) { - index = index * this.data.stride + this.offset; + // check if the ray lies on the plane first - if ( this.normalized ) { + const distToPoint = plane.distanceToPoint( this.origin ); - x = normalize( x, this.array ); - y = normalize( y, this.array ); + if ( distToPoint === 0 ) { + + return true; } - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; + const denominator = plane.normal.dot( this.direction ); - return this; + if ( denominator * distToPoint < 0 ) { + + return true; + + } + + // ray origin is behind the plane (and is pointing behind it) + + return false; } /** - * Sets the x, y and z component of the vector at the given index. + * Intersects this ray with the given bounding box, returning the intersection + * point or `null` if there is no intersection. * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @param {number} z - The value for the z component to set. - * @return {InterleavedBufferAttribute} A reference to this instance. + * @param {Box3} box - The box to intersect. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The intersection point. */ - setXYZ( index, x, y, z ) { + intersectBox( box, target ) { - index = index * this.data.stride + this.offset; + let tmin, tmax, tymin, tymax, tzmin, tzmax; - if ( this.normalized ) { + const invdirx = 1 / this.direction.x, + invdiry = 1 / this.direction.y, + invdirz = 1 / this.direction.z; - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); + const origin = this.origin; + + if ( invdirx >= 0 ) { + + tmin = ( box.min.x - origin.x ) * invdirx; + tmax = ( box.max.x - origin.x ) * invdirx; + + } else { + + tmin = ( box.max.x - origin.x ) * invdirx; + tmax = ( box.min.x - origin.x ) * invdirx; } - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; - this.data.array[ index + 2 ] = z; + if ( invdiry >= 0 ) { - return this; + tymin = ( box.min.y - origin.y ) * invdiry; + tymax = ( box.max.y - origin.y ) * invdiry; - } + } else { - /** - * Sets the x, y, z and w component of the vector at the given index. - * - * @param {number} index - The index into the buffer attribute. - * @param {number} x - The value for the x component to set. - * @param {number} y - The value for the y component to set. - * @param {number} z - The value for the z component to set. - * @param {number} w - The value for the w component to set. - * @return {InterleavedBufferAttribute} A reference to this instance. - */ - setXYZW( index, x, y, z, w ) { + tymin = ( box.max.y - origin.y ) * invdiry; + tymax = ( box.min.y - origin.y ) * invdiry; - index = index * this.data.stride + this.offset; + } + + if ( ( tmin > tymax ) || ( tymin > tmax ) ) return null; + + if ( tymin > tmin || isNaN( tmin ) ) tmin = tymin; + + if ( tymax < tmax || isNaN( tmax ) ) tmax = tymax; + + if ( invdirz >= 0 ) { + + tzmin = ( box.min.z - origin.z ) * invdirz; + tzmax = ( box.max.z - origin.z ) * invdirz; - if ( this.normalized ) { + } else { - x = normalize( x, this.array ); - y = normalize( y, this.array ); - z = normalize( z, this.array ); - w = normalize( w, this.array ); + tzmin = ( box.max.z - origin.z ) * invdirz; + tzmax = ( box.min.z - origin.z ) * invdirz; } - this.data.array[ index + 0 ] = x; - this.data.array[ index + 1 ] = y; - this.data.array[ index + 2 ] = z; - this.data.array[ index + 3 ] = w; + if ( ( tmin > tzmax ) || ( tzmin > tmax ) ) return null; - return this; + if ( tzmin > tmin || tmin !== tmin ) tmin = tzmin; + + if ( tzmax < tmax || tmax !== tmax ) tmax = tzmax; + + //return point closest to the ray (positive side) + + if ( tmax < 0 ) return null; + + return this.at( tmin >= 0 ? tmin : tmax, target ); } /** - * Returns a new buffer attribute with copied values from this instance. - * - * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. + * Returns `true` if this ray intersects with the given box. * - * @param {Object} [data] - An object with interleaved buffers that allows to retain the interleaved property. - * @return {BufferAttribute|InterleavedBufferAttribute} A clone of this instance. + * @param {Box3} box - The box to intersect. + * @return {boolean} Whether this ray intersects with the given box or not. */ - clone( data ) { - - if ( data === undefined ) { + intersectsBox( box ) { - log( 'InterleavedBufferAttribute.clone(): Cloning an interleaved buffer attribute will de-interleave buffer data.' ); + return this.intersectBox( box, _vector$7 ) !== null; - const array = []; + } - for ( let i = 0; i < this.count; i ++ ) { + /** + * Intersects this ray with the given triangle, returning the intersection + * point or `null` if there is no intersection. + * + * @param {Vector3} a - The first vertex of the triangle. + * @param {Vector3} b - The second vertex of the triangle. + * @param {Vector3} c - The third vertex of the triangle. + * @param {boolean} backfaceCulling - Whether to use backface culling or not. + * @param {Vector3} target - The target vector that is used to store the method's result. + * @return {?Vector3} The intersection point. + */ + intersectTriangle( a, b, c, backfaceCulling, target ) { - const index = i * this.data.stride + this.offset; + // Compute the offset origin, edges, and normal. - for ( let j = 0; j < this.itemSize; j ++ ) { + // from https://github.com/pmjoniak/GeometricTools/blob/master/GTEngine/Include/Mathematics/GteIntrRay3Triangle3.h - array.push( this.data.array[ index + j ] ); + _edge1.subVectors( b, a ); + _edge2.subVectors( c, a ); + _normal$1.crossVectors( _edge1, _edge2 ); - } + // Solve Q + t*D = b1*E1 + b2*E2 (Q = kDiff, D = ray direction, + // E1 = kEdge1, E2 = kEdge2, N = Cross(E1,E2)) by + // |Dot(D,N)|*b1 = sign(Dot(D,N))*Dot(D,Cross(Q,E2)) + // |Dot(D,N)|*b2 = sign(Dot(D,N))*Dot(D,Cross(E1,Q)) + // |Dot(D,N)|*t = -sign(Dot(D,N))*Dot(Q,N) + let DdN = this.direction.dot( _normal$1 ); + let sign; - } + if ( DdN > 0 ) { - return new BufferAttribute( new this.array.constructor( array ), this.itemSize, this.normalized ); + if ( backfaceCulling ) return null; + sign = 1; - } else { + } else if ( DdN < 0 ) { - if ( data.interleavedBuffers === undefined ) { + sign = -1; + DdN = - DdN; - data.interleavedBuffers = {}; + } else { - } + return null; - if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) { + } - data.interleavedBuffers[ this.data.uuid ] = this.data.clone( data ); + _diff.subVectors( this.origin, a ); + const DdQxE2 = sign * this.direction.dot( _edge2.crossVectors( _diff, _edge2 ) ); - } + // b1 < 0, no intersection + if ( DdQxE2 < 0 ) { - return new InterleavedBufferAttribute( data.interleavedBuffers[ this.data.uuid ], this.itemSize, this.offset, this.normalized ); + return null; } - } - - /** - * Serializes the buffer attribute into JSON. - * - * If no parameter is provided, cloning an interleaved buffer attribute will de-interleave buffer data. - * - * @param {Object} [data] - An optional value holding meta information about the serialization. - * @return {Object} A JSON object representing the serialized buffer attribute. - */ - toJSON( data ) { + const DdE1xQ = sign * this.direction.dot( _edge1.cross( _diff ) ); - if ( data === undefined ) { + // b2 < 0, no intersection + if ( DdE1xQ < 0 ) { - log( 'InterleavedBufferAttribute.toJSON(): Serializing an interleaved buffer attribute will de-interleave buffer data.' ); + return null; - const array = []; + } - for ( let i = 0; i < this.count; i ++ ) { + // b1+b2 > 1, no intersection + if ( DdQxE2 + DdE1xQ > DdN ) { - const index = i * this.data.stride + this.offset; + return null; - for ( let j = 0; j < this.itemSize; j ++ ) { + } - array.push( this.data.array[ index + j ] ); + // Line intersects triangle, check if ray does. + const QdN = - sign * _diff.dot( _normal$1 ); - } + // t < 0, no intersection + if ( QdN < 0 ) { - } + return null; - // de-interleave data and save it as an ordinary buffer attribute for now + } - return { - itemSize: this.itemSize, - type: this.array.constructor.name, - array: array, - normalized: this.normalized - }; + // Ray intersects triangle. + return this.at( QdN / DdN, target ); - } else { + } - // save as true interleaved attribute + /** + * Transforms this ray with the given 4x4 transformation matrix. + * + * @param {Matrix4} matrix4 - The transformation matrix. + * @return {Ray} A reference to this ray. + */ + applyMatrix4( matrix4 ) { - if ( data.interleavedBuffers === undefined ) { + this.origin.applyMatrix4( matrix4 ); + this.direction.transformDirection( matrix4 ); - data.interleavedBuffers = {}; + return this; - } + } - if ( data.interleavedBuffers[ this.data.uuid ] === undefined ) { + /** + * Returns `true` if this ray is equal with the given one. + * + * @param {Ray} ray - The ray to test for equality. + * @return {boolean} Whether this ray is equal with the given one. + */ + equals( ray ) { - data.interleavedBuffers[ this.data.uuid ] = this.data.toJSON( data ); + return ray.origin.equals( this.origin ) && ray.direction.equals( this.direction ); - } + } - return { - isInterleavedBufferAttribute: true, - itemSize: this.itemSize, - data: this.data.uuid, - offset: this.offset, - normalized: this.normalized - }; + /** + * Returns a new ray with copied values from this instance. + * + * @return {Ray} A clone of this instance. + */ + clone() { - } + return new this.constructor().copy( this ); } } /** - * A material for rendering instances of {@link Sprite}. - * - * ```js - * const map = new THREE.TextureLoader().load( 'textures/sprite.png' ); - * const material = new THREE.SpriteMaterial( { map: map, color: 0xffffff } ); + * A material for drawing geometries in a simple shaded (flat or wireframe) way. * - * const sprite = new THREE.Sprite( material ); - * sprite.scale.set(200, 200, 1) - * scene.add( sprite ); - * ``` + * This material is not affected by lights. * * @augments Material + * @demo scenes/material-browser.html#MeshBasicMaterial */ -class SpriteMaterial extends Material { +class MeshBasicMaterial extends Material { /** - * Constructs a new sprite material. + * Constructs a new mesh basic material. * * @param {Object} [parameters] - An object with one or more properties * defining the material's appearance. Any property of the material @@ -24470,9 +22640,9 @@ class SpriteMaterial extends Material { * @readonly * @default true */ - this.isSpriteMaterial = true; + this.isMeshBasicMaterial = true; - this.type = 'SpriteMaterial'; + this.type = 'MeshBasicMaterial'; /** * Color of the material. @@ -24480,7 +22650,7 @@ class SpriteMaterial extends Material { * @type {Color} * @default (1,1,1) */ - this.color = new Color( 0xffffff ); + this.color = new Color( 0xffffff ); // diffuse /** * The color map. May optionally include an alpha channel, typically combined @@ -24492,6 +22662,49 @@ class SpriteMaterial extends Material { */ this.map = null; + /** + * The light map. Requires a second set of UVs. + * + * @type {?Texture} + * @default null + */ + this.lightMap = null; + + /** + * Intensity of the baked light. + * + * @type {number} + * @default 1 + */ + this.lightMapIntensity = 1.0; + + /** + * The red channel of this texture is used as the ambient occlusion map. + * Requires a second set of UVs. + * + * @type {?Texture} + * @default null + */ + this.aoMap = null; + + /** + * Intensity of the ambient occlusion effect. Range is `[0,1]`, where `0` + * disables ambient occlusion. Where intensity is `1` and the AO map's + * red channel is also `1`, ambient light is fully occluded on a surface. + * + * @type {number} + * @default 1 + */ + this.aoMapIntensity = 1.0; + + /** + * Specular map used by the material. + * + * @type {?Texture} + * @default null + */ + this.specularMap = null; + /** * The alpha map is a grayscale texture that controls the opacity across the * surface (black: fully transparent; white: fully opaque). @@ -24508,29 +22721,89 @@ class SpriteMaterial extends Material { this.alphaMap = null; /** - * The rotation of the sprite in radians. + * The environment map. + * + * @type {?Texture} + * @default null + */ + this.envMap = null; + + /** + * The rotation of the environment map in radians. + * + * @type {Euler} + * @default (0,0,0) + */ + this.envMapRotation = new Euler(); + + /** + * How to combine the result of the surface's color with the environment map, if any. + * + * When set to `MixOperation`, the {@link MeshBasicMaterial#reflectivity} is used to + * blend between the two colors. + * + * @type {(MultiplyOperation|MixOperation|AddOperation)} + * @default MultiplyOperation + */ + this.combine = MultiplyOperation; + + /** + * How much the environment map affects the surface. + * The valid range is between `0` (no reflections) and `1` (full reflections). * * @type {number} - * @default 0 + * @default 1 */ - this.rotation = 0; + this.reflectivity = 1; /** - * Specifies whether size of the sprite is attenuated by the camera depth (perspective camera only). + * The index of refraction (IOR) of air (approximately 1) divided by the + * index of refraction of the material. It is used with environment mapping + * modes {@link CubeRefractionMapping} and {@link EquirectangularRefractionMapping}. + * The refraction ratio should not exceed `1`. * - * @type {boolean} - * @default true + * @type {number} + * @default 0.98 */ - this.sizeAttenuation = true; + this.refractionRatio = 0.98; /** - * Overwritten since sprite materials are transparent - * by default. + * Renders the geometry as a wireframe. * * @type {boolean} - * @default true + * @default false */ - this.transparent = true; + this.wireframe = false; + + /** + * Controls the thickness of the wireframe. + * + * Can only be used with {@link SVGRenderer}. + * + * @type {number} + * @default 1 + */ + this.wireframeLinewidth = 1; + + /** + * Defines appearance of wireframe ends. + * + * Can only be used with {@link SVGRenderer}. + * + * @type {('round'|'bevel'|'miter')} + * @default 'round' + */ + this.wireframeLinecap = 'round'; + + /** + * Defines appearance of wireframe joints. + * + * Can only be used with {@link SVGRenderer}. + * + * @type {('round'|'bevel'|'miter')} + * @default 'round' + */ + this.wireframeLinejoin = 'round'; /** * Whether the material is affected by fog or not. @@ -24552,11 +22825,26 @@ class SpriteMaterial extends Material { this.map = source.map; + this.lightMap = source.lightMap; + this.lightMapIntensity = source.lightMapIntensity; + + this.aoMap = source.aoMap; + this.aoMapIntensity = source.aoMapIntensity; + + this.specularMap = source.specularMap; + this.alphaMap = source.alphaMap; - this.rotation = source.rotation; + this.envMap = source.envMap; + this.envMapRotation.copy( source.envMapRotation ); + this.combine = source.combine; + this.reflectivity = source.reflectivity; + this.refractionRatio = source.refractionRatio; - this.sizeAttenuation = source.sizeAttenuation; + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; + this.wireframeLinecap = source.wireframeLinecap; + this.wireframeLinejoin = source.wireframeLinejoin; this.fog = source.fog; @@ -24566,49 +22854,42 @@ class SpriteMaterial extends Material { } -let _geometry; - -const _intersectPoint = /*@__PURE__*/ new Vector3(); -const _worldScale = /*@__PURE__*/ new Vector3(); -const _mvPosition = /*@__PURE__*/ new Vector3(); - -const _alignedPosition = /*@__PURE__*/ new Vector2(); -const _rotatedPosition = /*@__PURE__*/ new Vector2(); -const _viewWorldMatrix = /*@__PURE__*/ new Matrix4(); +const _inverseMatrix$3 = /*@__PURE__*/ new Matrix4(); +const _ray$3 = /*@__PURE__*/ new Ray(); +const _sphere$6 = /*@__PURE__*/ new Sphere(); +const _sphereHitAt = /*@__PURE__*/ new Vector3(); const _vA = /*@__PURE__*/ new Vector3(); const _vB = /*@__PURE__*/ new Vector3(); const _vC = /*@__PURE__*/ new Vector3(); -const _uvA = /*@__PURE__*/ new Vector2(); -const _uvB = /*@__PURE__*/ new Vector2(); -const _uvC = /*@__PURE__*/ new Vector2(); +const _tempA = /*@__PURE__*/ new Vector3(); +const _morphA = /*@__PURE__*/ new Vector3(); + +const _intersectionPoint = /*@__PURE__*/ new Vector3(); +const _intersectionPointWorld = /*@__PURE__*/ new Vector3(); /** - * A sprite is a plane that always faces towards the camera, generally with a - * partially transparent texture applied. - * - * Sprites do not cast shadows, setting {@link Object3D#castShadow} to `true` will - * have no effect. + * Class representing triangular polygon mesh based objects. * * ```js - * const map = new THREE.TextureLoader().load( 'sprite.png' ); - * const material = new THREE.SpriteMaterial( { map: map } ); - * - * const sprite = new THREE.Sprite( material ); - * scene.add( sprite ); + * const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); + * const mesh = new THREE.Mesh( geometry, material ); + * scene.add( mesh ); * ``` * * @augments Object3D */ -class Sprite extends Object3D { +class Mesh extends Object3D { /** - * Constructs a new sprite. + * Constructs a new mesh. * - * @param {(SpriteMaterial|SpriteNodeMaterial)} [material] - The sprite material. + * @param {BufferGeometry} [geometry] - The mesh geometry. + * @param {Material|Array} [material] - The mesh material. */ - constructor( material = new SpriteMaterial() ) { + constructor( geometry = new BufferGeometry(), material = new MeshBasicMaterial() ) { super(); @@ -24619,55 +22900,47 @@ class Sprite extends Object3D { * @readonly * @default true */ - this.isSprite = true; - - this.type = 'Sprite'; - - if ( _geometry === undefined ) { - - _geometry = new BufferGeometry(); - - const float32Array = new Float32Array( [ - -0.5, -0.5, 0, 0, 0, - 0.5, -0.5, 0, 1, 0, - 0.5, 0.5, 0, 1, 1, - -0.5, 0.5, 0, 0, 1 - ] ); - - const interleavedBuffer = new InterleavedBuffer( float32Array, 5 ); - - _geometry.setIndex( [ 0, 1, 2, 0, 2, 3 ] ); - _geometry.setAttribute( 'position', new InterleavedBufferAttribute( interleavedBuffer, 3, 0, false ) ); - _geometry.setAttribute( 'uv', new InterleavedBufferAttribute( interleavedBuffer, 2, 3, false ) ); + this.isMesh = true; - } + this.type = 'Mesh'; /** - * The sprite geometry. + * The mesh geometry. * * @type {BufferGeometry} */ - this.geometry = _geometry; + this.geometry = geometry; /** - * The sprite material. + * The mesh material. * - * @type {(SpriteMaterial|SpriteNodeMaterial)} + * @type {Material|Array} + * @default MeshBasicMaterial */ this.material = material; /** - * The sprite's anchor point, and the point around which the sprite rotates. - * A value of `(0.5, 0.5)` corresponds to the midpoint of the sprite. A value - * of `(0, 0)` corresponds to the lower left corner of the sprite. + * A dictionary representing the morph targets in the geometry. The key is the + * morph targets name, the value its attribute index. This member is `undefined` + * by default and only set when morph targets are detected in the geometry. * - * @type {Vector2} - * @default (0.5,0.5) + * @type {Object|undefined} + * @default undefined */ - this.center = new Vector2( 0.5, 0.5 ); + this.morphTargetDictionary = undefined; /** - * The number of instances of this sprite. + * An array of weights typically in the range `[0,1]` that specify how much of the morph + * is applied. This member is `undefined` by default and only set when morph targets are + * detected in the geometry. + * + * @type {Array|undefined} + * @default undefined + */ + this.morphTargetInfluences = undefined; + + /** + * The number of instances of this mesh. * Can only be used with {@link WebGPURenderer}. * * @type {number} @@ -24675,452 +22948,394 @@ class Sprite extends Object3D { */ this.count = 1; + this.updateMorphTargets(); + } - /** - * Computes intersection points between a casted ray and this sprite. - * - * @param {Raycaster} raycaster - The raycaster. - * @param {Array} intersects - The target array that holds the intersection points. - */ - raycast( raycaster, intersects ) { + copy( source, recursive ) { - if ( raycaster.camera === null ) { + super.copy( source, recursive ); - error( 'Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.' ); + if ( source.morphTargetInfluences !== undefined ) { - } + this.morphTargetInfluences = source.morphTargetInfluences.slice(); - _worldScale.setFromMatrixScale( this.matrixWorld ); + } - _viewWorldMatrix.copy( raycaster.camera.matrixWorld ); - this.modelViewMatrix.multiplyMatrices( raycaster.camera.matrixWorldInverse, this.matrixWorld ); + if ( source.morphTargetDictionary !== undefined ) { - _mvPosition.setFromMatrixPosition( this.modelViewMatrix ); + this.morphTargetDictionary = Object.assign( {}, source.morphTargetDictionary ); - if ( raycaster.camera.isPerspectiveCamera && this.material.sizeAttenuation === false ) { + } - _worldScale.multiplyScalar( - _mvPosition.z ); + this.material = Array.isArray( source.material ) ? source.material.slice() : source.material; + this.geometry = source.geometry; - } + return this; - const rotation = this.material.rotation; - let sin, cos; + } - if ( rotation !== 0 ) { + /** + * Sets the values of {@link Mesh#morphTargetDictionary} and {@link Mesh#morphTargetInfluences} + * to make sure existing morph targets can influence this 3D object. + */ + updateMorphTargets() { - cos = Math.cos( rotation ); - sin = Math.sin( rotation ); + const geometry = this.geometry; - } + const morphAttributes = geometry.morphAttributes; + const keys = Object.keys( morphAttributes ); - const center = this.center; + if ( keys.length > 0 ) { - transformVertex( _vA.set( -0.5, -0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - transformVertex( _vB.set( 0.5, -0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - transformVertex( _vC.set( 0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); + const morphAttribute = morphAttributes[ keys[ 0 ] ]; - _uvA.set( 0, 0 ); - _uvB.set( 1, 0 ); - _uvC.set( 1, 1 ); + if ( morphAttribute !== undefined ) { - // check first triangle - let intersect = raycaster.ray.intersectTriangle( _vA, _vB, _vC, false, _intersectPoint ); + this.morphTargetInfluences = []; + this.morphTargetDictionary = {}; - if ( intersect === null ) { + for ( let m = 0, ml = morphAttribute.length; m < ml; m ++ ) { - // check second triangle - transformVertex( _vB.set( -0.5, 0.5, 0 ), _mvPosition, center, _worldScale, sin, cos ); - _uvB.set( 0, 1 ); + const name = morphAttribute[ m ].name || String( m ); - intersect = raycaster.ray.intersectTriangle( _vA, _vC, _vB, false, _intersectPoint ); - if ( intersect === null ) { + this.morphTargetInfluences.push( 0 ); + this.morphTargetDictionary[ name ] = m; - return; + } } } - const distance = raycaster.ray.origin.distanceTo( _intersectPoint ); + } - if ( distance < raycaster.near || distance > raycaster.far ) return; + /** + * Returns the local-space position of the vertex at the given index, taking into + * account the current animation state of both morph targets and skinning. + * + * @param {number} index - The vertex index. + * @param {Vector3} target - The target object that is used to store the method's result. + * @return {Vector3} The vertex position in local space. + */ + getVertexPosition( index, target ) { - intersects.push( { + const geometry = this.geometry; + const position = geometry.attributes.position; + const morphPosition = geometry.morphAttributes.position; + const morphTargetsRelative = geometry.morphTargetsRelative; - distance: distance, - point: _intersectPoint.clone(), - uv: Triangle.getInterpolation( _intersectPoint, _vA, _vB, _vC, _uvA, _uvB, _uvC, new Vector2() ), - face: null, - object: this + target.fromBufferAttribute( position, index ); - } ); + const morphInfluences = this.morphTargetInfluences; - } + if ( morphPosition && morphInfluences ) { - copy( source, recursive ) { + _morphA.set( 0, 0, 0 ); - super.copy( source, recursive ); + for ( let i = 0, il = morphPosition.length; i < il; i ++ ) { - if ( source.center !== undefined ) this.center.copy( source.center ); + const influence = morphInfluences[ i ]; + const morphAttribute = morphPosition[ i ]; - this.material = source.material; + if ( influence === 0 ) continue; - return this; + _tempA.fromBufferAttribute( morphAttribute, index ); - } + if ( morphTargetsRelative ) { -} + _morphA.addScaledVector( _tempA, influence ); -function transformVertex( vertexPosition, mvPosition, center, scale, sin, cos ) { + } else { - // compute position in camera space - _alignedPosition.subVectors( vertexPosition, center ).addScalar( 0.5 ).multiply( scale ); + _morphA.addScaledVector( _tempA.sub( target ), influence ); - // to check if rotation is not zero - if ( sin !== undefined ) { + } - _rotatedPosition.x = ( cos * _alignedPosition.x ) - ( sin * _alignedPosition.y ); - _rotatedPosition.y = ( sin * _alignedPosition.x ) + ( cos * _alignedPosition.y ); + } - } else { + target.add( _morphA ); - _rotatedPosition.copy( _alignedPosition ); + } + + return target; } + /** + * Computes intersection points between a casted ray and this line. + * + * @param {Raycaster} raycaster - The raycaster. + * @param {Array} intersects - The target array that holds the intersection points. + */ + raycast( raycaster, intersects ) { - vertexPosition.copy( mvPosition ); - vertexPosition.x += _rotatedPosition.x; - vertexPosition.y += _rotatedPosition.y; + const geometry = this.geometry; + const material = this.material; + const matrixWorld = this.matrixWorld; - // transform to world space - vertexPosition.applyMatrix4( _viewWorldMatrix ); + if ( material === undefined ) return; -} + // test with bounding sphere in world space -const _v1$2 = /*@__PURE__*/ new Vector3(); -const _v2$1 = /*@__PURE__*/ new Vector3(); + if ( geometry.boundingSphere === null ) geometry.computeBoundingSphere(); -/** - * A component for providing a basic Level of Detail (LOD) mechanism. - * - * Every LOD level is associated with an object, and rendering can be switched - * between them at the distances specified. Typically you would create, say, - * three meshes, one for far away (low detail), one for mid range (medium - * detail) and one for close up (high detail). - * - * ```js - * const lod = new THREE.LOD(); - * const material = new THREE.MeshBasicMaterial( { color: 0xffff00 } ); - * - * //Create spheres with 3 levels of detail and create new LOD levels for them - * for( let i = 0; i < 3; i++ ) { - * - * const geometry = new THREE.IcosahedronGeometry( 10, 3 - i ); - * const mesh = new THREE.Mesh( geometry, material ); - * lod.addLevel( mesh, i * 75 ); - * - * } - * - * scene.add( lod ); - * ``` - * - * @augments Object3D - */ -class LOD extends Object3D { + _sphere$6.copy( geometry.boundingSphere ); + _sphere$6.applyMatrix4( matrixWorld ); - /** - * Constructs a new LOD. - */ - constructor() { + // check distance from ray origin to bounding sphere - super(); + _ray$3.copy( raycaster.ray ).recast( raycaster.near ); - /** - * This flag can be used for type testing. - * - * @type {boolean} - * @readonly - * @default true - */ - this.isLOD = true; + if ( _sphere$6.containsPoint( _ray$3.origin ) === false ) { - /** - * The current LOD index. - * - * @private - * @type {number} - * @default 0 - */ - this._currentLevel = 0; + if ( _ray$3.intersectSphere( _sphere$6, _sphereHitAt ) === null ) return; - this.type = 'LOD'; + if ( _ray$3.origin.distanceToSquared( _sphereHitAt ) > ( raycaster.far - raycaster.near ) ** 2 ) return; - Object.defineProperties( this, { - /** - * This array holds the LOD levels. - * - * @name LOD#levels - * @type {Array<{object:Object3D,distance:number,hysteresis:number}>} - */ - levels: { - enumerable: true, - value: [] - } - } ); + } - /** - * Whether the LOD object is updated automatically by the renderer per frame - * or not. If set to `false`, you have to call {@link LOD#update} in the - * render loop by yourself. - * - * @type {boolean} - * @default true - */ - this.autoUpdate = true; + // convert ray to local space of mesh - } + _inverseMatrix$3.copy( matrixWorld ).invert(); + _ray$3.copy( raycaster.ray ).applyMatrix4( _inverseMatrix$3 ); - copy( source ) { + // test with bounding box in local space - super.copy( source, false ); + if ( geometry.boundingBox !== null ) { - const levels = source.levels; + if ( _ray$3.intersectsBox( geometry.boundingBox ) === false ) return; - for ( let i = 0, l = levels.length; i < l; i ++ ) { + } - const level = levels[ i ]; + // test for intersections with geometry - this.addLevel( level.object.clone(), level.distance, level.hysteresis ); + this._computeIntersections( raycaster, intersects, _ray$3 ); - } + } - this.autoUpdate = source.autoUpdate; + _computeIntersections( raycaster, intersects, rayLocalSpace ) { - return this; + let intersection; - } + const geometry = this.geometry; + const material = this.material; - /** - * Adds a mesh that will display at a certain distance and greater. Typically - * the further away the distance, the lower the detail on the mesh. - * - * @param {Object3D} object - The 3D object to display at this level. - * @param {number} [distance=0] - The distance at which to display this level of detail. - * @param {number} [hysteresis=0] - Threshold used to avoid flickering at LOD boundaries, as a fraction of distance. - * @return {LOD} A reference to this instance. - */ - addLevel( object, distance = 0, hysteresis = 0 ) { + const index = geometry.index; + const position = geometry.attributes.position; + const uv = geometry.attributes.uv; + const uv1 = geometry.attributes.uv1; + const normal = geometry.attributes.normal; + const groups = geometry.groups; + const drawRange = geometry.drawRange; - distance = Math.abs( distance ); + if ( index !== null ) { - const levels = this.levels; + // indexed buffer geometry - let l; + if ( Array.isArray( material ) ) { - for ( l = 0; l < levels.length; l ++ ) { + for ( let i = 0, il = groups.length; i < il; i ++ ) { - if ( distance < levels[ l ].distance ) { + const group = groups[ i ]; + const groupMaterial = material[ group.materialIndex ]; - break; + const start = Math.max( group.start, drawRange.start ); + const end = Math.min( index.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); - } + for ( let j = start, jl = end; j < jl; j += 3 ) { - } + const a = index.getX( j ); + const b = index.getX( j + 1 ); + const c = index.getX( j + 2 ); - levels.splice( l, 0, { distance: distance, hysteresis: hysteresis, object: object } ); + intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); - this.add( object ); + if ( intersection ) { - return this; + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - } + } - /** - * Removes an existing level, based on the distance from the camera. - * Returns `true` when the level has been removed. Otherwise `false`. - * - * @param {number} distance - Distance of the level to remove. - * @return {boolean} Whether the level has been removed or not. - */ - removeLevel( distance ) { + } - const levels = this.levels; + } - for ( let i = 0; i < levels.length; i ++ ) { + } else { - if ( levels[ i ].distance === distance ) { + const start = Math.max( 0, drawRange.start ); + const end = Math.min( index.count, ( drawRange.start + drawRange.count ) ); - const removedElements = levels.splice( i, 1 ); - this.remove( removedElements[ 0 ].object ); + for ( let i = start, il = end; i < il; i += 3 ) { - return true; + const a = index.getX( i ); + const b = index.getX( i + 1 ); + const c = index.getX( i + 2 ); - } + intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); - } + if ( intersection ) { - return false; + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in indexed buffer semantics + intersects.push( intersection ); - } + } - /** - * Returns the currently active LOD level index. - * - * @return {number} The current active LOD level index. - */ - getCurrentLevel() { + } - return this._currentLevel; + } - } + } else if ( position !== undefined ) { - /** - * Returns a reference to the first 3D object that is greater than - * the given distance. - * - * @param {number} distance - The LOD distance. - * @return {?Object3D} The found 3D object. `null` if no 3D object has been found. - */ - getObjectForDistance( distance ) { + // non-indexed buffer geometry - const levels = this.levels; + if ( Array.isArray( material ) ) { - if ( levels.length > 0 ) { + for ( let i = 0, il = groups.length; i < il; i ++ ) { - let i, l; + const group = groups[ i ]; + const groupMaterial = material[ group.materialIndex ]; - for ( i = 1, l = levels.length; i < l; i ++ ) { + const start = Math.max( group.start, drawRange.start ); + const end = Math.min( position.count, Math.min( ( group.start + group.count ), ( drawRange.start + drawRange.count ) ) ); - let levelDistance = levels[ i ].distance; + for ( let j = start, jl = end; j < jl; j += 3 ) { - if ( levels[ i ].object.visible ) { + const a = j; + const b = j + 1; + const c = j + 2; - levelDistance -= levelDistance * levels[ i ].hysteresis; + intersection = checkGeometryIntersection( this, groupMaterial, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); - } + if ( intersection ) { - if ( distance < levelDistance ) { + intersection.faceIndex = Math.floor( j / 3 ); // triangle number in non-indexed buffer semantics + intersection.face.materialIndex = group.materialIndex; + intersects.push( intersection ); - break; + } - } + } - } + } - return levels[ i - 1 ].object; + } else { - } + const start = Math.max( 0, drawRange.start ); + const end = Math.min( position.count, ( drawRange.start + drawRange.count ) ); - return null; + for ( let i = start, il = end; i < il; i += 3 ) { - } + const a = i; + const b = i + 1; + const c = i + 2; - /** - * Computes intersection points between a casted ray and this LOD. - * - * @param {Raycaster} raycaster - The raycaster. - * @param {Array} intersects - The target array that holds the intersection points. - */ - raycast( raycaster, intersects ) { + intersection = checkGeometryIntersection( this, material, raycaster, rayLocalSpace, uv, uv1, normal, a, b, c ); - const levels = this.levels; + if ( intersection ) { - if ( levels.length > 0 ) { + intersection.faceIndex = Math.floor( i / 3 ); // triangle number in non-indexed buffer semantics + intersects.push( intersection ); - _v1$2.setFromMatrixPosition( this.matrixWorld ); + } - const distance = raycaster.ray.origin.distanceTo( _v1$2 ); + } - this.getObjectForDistance( distance ).raycast( raycaster, intersects ); + } } } - /** - * Updates the LOD by computing which LOD level should be visible according - * to the current distance of the given camera. - * - * @param {Camera} camera - The camera the scene is rendered with. - */ - update( camera ) { - - const levels = this.levels; +} - if ( levels.length > 1 ) { +function checkIntersection$1( object, material, raycaster, ray, pA, pB, pC, point ) { - _v1$2.setFromMatrixPosition( camera.matrixWorld ); - _v2$1.setFromMatrixPosition( this.matrixWorld ); + let intersect; - const distance = _v1$2.distanceTo( _v2$1 ) / camera.zoom; + if ( material.side === BackSide ) { - levels[ 0 ].object.visible = true; + intersect = ray.intersectTriangle( pC, pB, pA, true, point ); - let i, l; + } else { - for ( i = 1, l = levels.length; i < l; i ++ ) { + intersect = ray.intersectTriangle( pA, pB, pC, ( material.side === FrontSide ), point ); - let levelDistance = levels[ i ].distance; + } - if ( levels[ i ].object.visible ) { + if ( intersect === null ) return null; - levelDistance -= levelDistance * levels[ i ].hysteresis; + _intersectionPointWorld.copy( point ); + _intersectionPointWorld.applyMatrix4( object.matrixWorld ); - } + const distance = raycaster.ray.origin.distanceTo( _intersectionPointWorld ); - if ( distance >= levelDistance ) { + if ( distance < raycaster.near || distance > raycaster.far ) return null; - levels[ i - 1 ].object.visible = false; - levels[ i ].object.visible = true; + return { + distance: distance, + point: _intersectionPointWorld.clone(), + object: object + }; - } else { +} - break; +function checkGeometryIntersection( object, material, raycaster, ray, uv, uv1, normal, a, b, c ) { - } + object.getVertexPosition( a, _vA ); + object.getVertexPosition( b, _vB ); + object.getVertexPosition( c, _vC ); - } + const intersection = checkIntersection$1( object, material, raycaster, ray, _vA, _vB, _vC, _intersectionPoint ); - this._currentLevel = i - 1; + if ( intersection ) { - for ( ; i < l; i ++ ) { + const barycoord = new Vector3(); + Triangle.getBarycoord( _intersectionPoint, _vA, _vB, _vC, barycoord ); - levels[ i ].object.visible = false; + if ( uv ) { - } + intersection.uv = Triangle.getInterpolatedAttribute( uv, a, b, c, barycoord, new Vector2() ); } - } - - toJSON( meta ) { + if ( uv1 ) { - const data = super.toJSON( meta ); + intersection.uv1 = Triangle.getInterpolatedAttribute( uv1, a, b, c, barycoord, new Vector2() ); - if ( this.autoUpdate === false ) data.object.autoUpdate = false; + } - data.object.levels = []; + if ( normal ) { - const levels = this.levels; + intersection.normal = Triangle.getInterpolatedAttribute( normal, a, b, c, barycoord, new Vector3() ); - for ( let i = 0, l = levels.length; i < l; i ++ ) { + if ( intersection.normal.dot( ray.direction ) > 0 ) { - const level = levels[ i ]; + intersection.normal.multiplyScalar( -1 ); - data.object.levels.push( { - object: level.object.uuid, - distance: level.distance, - hysteresis: level.hysteresis - } ); + } } - return data; + const face = { + a: a, + b: b, + c: c, + normal: new Vector3(), + materialIndex: 0 + }; + + Triangle.getNormal( _vA, _vB, _vC, face.normal ); + + intersection.face = face; + intersection.barycoord = barycoord; } + return intersection; + } const _basePosition = /*@__PURE__*/ new Vector3(); @@ -29638,7 +27853,7 @@ class PointsMaterial extends Material { const _inverseMatrix = /*@__PURE__*/ new Matrix4(); const _ray = /*@__PURE__*/ new Ray(); const _sphere = /*@__PURE__*/ new Sphere(); -const _position$2 = /*@__PURE__*/ new Vector3(); +const _position$3 = /*@__PURE__*/ new Vector3(); /** * A class for displaying points or point clouds. @@ -29762,9 +27977,9 @@ class Points extends Object3D { const a = index.getX( i ); - _position$2.fromBufferAttribute( positionAttribute, a ); + _position$3.fromBufferAttribute( positionAttribute, a ); - testPoint( _position$2, a, localThresholdSq, matrixWorld, raycaster, intersects, this ); + testPoint( _position$3, a, localThresholdSq, matrixWorld, raycaster, intersects, this ); } @@ -29775,9 +27990,9 @@ class Points extends Object3D { for ( let i = start, l = end; i < l; i ++ ) { - _position$2.fromBufferAttribute( positionAttribute, i ); + _position$3.fromBufferAttribute( positionAttribute, i ); - testPoint( _position$2, i, localThresholdSq, matrixWorld, raycaster, intersects, this ); + testPoint( _position$3, i, localThresholdSq, matrixWorld, raycaster, intersects, this ); } @@ -30339,6 +28554,83 @@ class CompressedCubeTexture extends CompressedTexture { } +/** + * Creates a cube texture made up of six images. + * + * ```js + * const loader = new THREE.CubeTextureLoader(); + * loader.setPath( 'textures/cube/pisa/' ); + * + * const textureCube = loader.load( [ + * 'px.png', 'nx.png', 'py.png', 'ny.png', 'pz.png', 'nz.png' + * ] ); + * + * const material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: textureCube } ); + * ``` + * + * @augments Texture + */ +class CubeTexture extends Texture { + + /** + * Constructs a new cube texture. + * + * @param {Array} [images=[]] - An array holding a image for each side of a cube. + * @param {number} [mapping=CubeReflectionMapping] - The texture mapping. + * @param {number} [wrapS=ClampToEdgeWrapping] - The wrapS value. + * @param {number} [wrapT=ClampToEdgeWrapping] - The wrapT value. + * @param {number} [magFilter=LinearFilter] - The mag filter value. + * @param {number} [minFilter=LinearMipmapLinearFilter] - The min filter value. + * @param {number} [format=RGBAFormat] - The texture format. + * @param {number} [type=UnsignedByteType] - The texture type. + * @param {number} [anisotropy=Texture.DEFAULT_ANISOTROPY] - The anisotropy value. + * @param {string} [colorSpace=NoColorSpace] - The color space value. + */ + constructor( images = [], mapping = CubeReflectionMapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace ) { + + super( images, mapping, wrapS, wrapT, magFilter, minFilter, format, type, anisotropy, colorSpace ); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isCubeTexture = true; + + /** + * If set to `true`, the texture is flipped along the vertical axis when + * uploaded to the GPU. + * + * Overwritten and set to `false` by default. + * + * @type {boolean} + * @default false + */ + this.flipY = false; + + } + + /** + * Alias for {@link CubeTexture#image}. + * + * @type {Array} + */ + get images() { + + return this.image; + + } + + set images( value ) { + + this.image = value; + + } + +} + /** * Creates a texture from a canvas element. * @@ -30605,6 +28897,220 @@ class ExternalTexture extends Texture { } +/** + * A geometry class for a rectangular cuboid with a given width, height, and depth. + * On creation, the cuboid is centred on the origin, with each edge parallel to one + * of the axes. + * + * ```js + * const geometry = new THREE.BoxGeometry( 1, 1, 1 ); + * const material = new THREE.MeshBasicMaterial( { color: 0x00ff00 } ); + * const cube = new THREE.Mesh( geometry, material ); + * scene.add( cube ); + * ``` + * + * @augments BufferGeometry + * @demo scenes/geometry-browser.html#BoxGeometry + */ +class BoxGeometry extends BufferGeometry { + + /** + * Constructs a new box geometry. + * + * @param {number} [width=1] - The width. That is, the length of the edges parallel to the X axis. + * @param {number} [height=1] - The height. That is, the length of the edges parallel to the Y axis. + * @param {number} [depth=1] - The depth. That is, the length of the edges parallel to the Z axis. + * @param {number} [widthSegments=1] - Number of segmented rectangular faces along the width of the sides. + * @param {number} [heightSegments=1] - Number of segmented rectangular faces along the height of the sides. + * @param {number} [depthSegments=1] - Number of segmented rectangular faces along the depth of the sides. + */ + constructor( width = 1, height = 1, depth = 1, widthSegments = 1, heightSegments = 1, depthSegments = 1 ) { + + super(); + + this.type = 'BoxGeometry'; + + /** + * Holds the constructor parameters that have been + * used to generate the geometry. Any modification + * after instantiation does not change the geometry. + * + * @type {Object} + */ + this.parameters = { + width: width, + height: height, + depth: depth, + widthSegments: widthSegments, + heightSegments: heightSegments, + depthSegments: depthSegments + }; + + const scope = this; + + // segments + + widthSegments = Math.floor( widthSegments ); + heightSegments = Math.floor( heightSegments ); + depthSegments = Math.floor( depthSegments ); + + // buffers + + const indices = []; + const vertices = []; + const normals = []; + const uvs = []; + + // helper variables + + let numberOfVertices = 0; + let groupStart = 0; + + // build each side of the box geometry + + buildPlane( 'z', 'y', 'x', -1, -1, depth, height, width, depthSegments, heightSegments, 0 ); // px + buildPlane( 'z', 'y', 'x', 1, -1, depth, height, - width, depthSegments, heightSegments, 1 ); // nx + buildPlane( 'x', 'z', 'y', 1, 1, width, depth, height, widthSegments, depthSegments, 2 ); // py + buildPlane( 'x', 'z', 'y', 1, -1, width, depth, - height, widthSegments, depthSegments, 3 ); // ny + buildPlane( 'x', 'y', 'z', 1, -1, width, height, depth, widthSegments, heightSegments, 4 ); // pz + buildPlane( 'x', 'y', 'z', -1, -1, width, height, - depth, widthSegments, heightSegments, 5 ); // nz + + // build geometry + + this.setIndex( indices ); + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + this.setAttribute( 'normal', new Float32BufferAttribute( normals, 3 ) ); + this.setAttribute( 'uv', new Float32BufferAttribute( uvs, 2 ) ); + + function buildPlane( u, v, w, udir, vdir, width, height, depth, gridX, gridY, materialIndex ) { + + const segmentWidth = width / gridX; + const segmentHeight = height / gridY; + + const widthHalf = width / 2; + const heightHalf = height / 2; + const depthHalf = depth / 2; + + const gridX1 = gridX + 1; + const gridY1 = gridY + 1; + + let vertexCounter = 0; + let groupCount = 0; + + const vector = new Vector3(); + + // generate vertices, normals and uvs + + for ( let iy = 0; iy < gridY1; iy ++ ) { + + const y = iy * segmentHeight - heightHalf; + + for ( let ix = 0; ix < gridX1; ix ++ ) { + + const x = ix * segmentWidth - widthHalf; + + // set values to correct vector component + + vector[ u ] = x * udir; + vector[ v ] = y * vdir; + vector[ w ] = depthHalf; + + // now apply vector to vertex buffer + + vertices.push( vector.x, vector.y, vector.z ); + + // set values to correct vector component + + vector[ u ] = 0; + vector[ v ] = 0; + vector[ w ] = depth > 0 ? 1 : -1; + + // now apply vector to normal buffer + + normals.push( vector.x, vector.y, vector.z ); + + // uvs + + uvs.push( ix / gridX ); + uvs.push( 1 - ( iy / gridY ) ); + + // counters + + vertexCounter += 1; + + } + + } + + // indices + + // 1. you need three indices to draw a single face + // 2. a single segment consists of two faces + // 3. so we need to generate six (2*3) indices per segment + + for ( let iy = 0; iy < gridY; iy ++ ) { + + for ( let ix = 0; ix < gridX; ix ++ ) { + + const a = numberOfVertices + ix + gridX1 * iy; + const b = numberOfVertices + ix + gridX1 * ( iy + 1 ); + const c = numberOfVertices + ( ix + 1 ) + gridX1 * ( iy + 1 ); + const d = numberOfVertices + ( ix + 1 ) + gridX1 * iy; + + // faces + + indices.push( a, b, d ); + indices.push( b, c, d ); + + // increase counter + + groupCount += 6; + + } + + } + + // add a group to the geometry. this will ensure multi material support + + scope.addGroup( groupStart, groupCount, materialIndex ); + + // calculate new start value for groups + + groupStart += groupCount; + + // update total number of vertices + + numberOfVertices += vertexCounter; + + } + + } + + copy( source ) { + + super.copy( source ); + + this.parameters = Object.assign( {}, source.parameters ); + + return this; + + } + + /** + * Factory method for creating an instance of this class from the given + * JSON object. + * + * @param {Object} data - A JSON object representing the serialized geometry. + * @return {BoxGeometry} A new instance. + */ + static fromJSON( data ) { + + return new BoxGeometry( data.width, data.height, data.depth, data.widthSegments, data.heightSegments, data.depthSegments ); + + } + +} + /** * A geometry class for representing a capsule. * @@ -38287,168 +36793,401 @@ class WireframeGeometry extends BufferGeometry { if ( geometry.index !== null ) { - // indexed BufferGeometry + // indexed BufferGeometry + + const position = geometry.attributes.position; + const indices = geometry.index; + let groups = geometry.groups; + + if ( groups.length === 0 ) { + + groups = [ { start: 0, count: indices.count, materialIndex: 0 } ]; + + } + + // create a data structure that contains all edges without duplicates + + for ( let o = 0, ol = groups.length; o < ol; ++ o ) { + + const group = groups[ o ]; + + const groupStart = group.start; + const groupCount = group.count; + + for ( let i = groupStart, l = ( groupStart + groupCount ); i < l; i += 3 ) { + + for ( let j = 0; j < 3; j ++ ) { + + const index1 = indices.getX( i + j ); + const index2 = indices.getX( i + ( j + 1 ) % 3 ); + + start.fromBufferAttribute( position, index1 ); + end.fromBufferAttribute( position, index2 ); + + if ( isUniqueEdge( start, end, edges ) === true ) { + + vertices.push( start.x, start.y, start.z ); + vertices.push( end.x, end.y, end.z ); + + } + + } + + } + + } + + } else { + + // non-indexed BufferGeometry + + const position = geometry.attributes.position; + + for ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) { + + for ( let j = 0; j < 3; j ++ ) { + + // three edges per triangle, an edge is represented as (index1, index2) + // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) + + const index1 = 3 * i + j; + const index2 = 3 * i + ( ( j + 1 ) % 3 ); + + start.fromBufferAttribute( position, index1 ); + end.fromBufferAttribute( position, index2 ); + + if ( isUniqueEdge( start, end, edges ) === true ) { + + vertices.push( start.x, start.y, start.z ); + vertices.push( end.x, end.y, end.z ); + + } + + } + + } + + } + + // build geometry + + this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + + } + + } + + copy( source ) { + + super.copy( source ); + + this.parameters = Object.assign( {}, source.parameters ); + + return this; + + } + +} + +function isUniqueEdge( start, end, edges ) { + + const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`; + const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge + + if ( edges.has( hash1 ) === true || edges.has( hash2 ) === true ) { + + return false; + + } else { + + edges.add( hash1 ); + edges.add( hash2 ); + return true; + + } + +} + +var Geometries = /*#__PURE__*/Object.freeze({ + __proto__: null, + BoxGeometry: BoxGeometry, + CapsuleGeometry: CapsuleGeometry, + CircleGeometry: CircleGeometry, + ConeGeometry: ConeGeometry, + CylinderGeometry: CylinderGeometry, + DodecahedronGeometry: DodecahedronGeometry, + EdgesGeometry: EdgesGeometry, + ExtrudeGeometry: ExtrudeGeometry, + IcosahedronGeometry: IcosahedronGeometry, + LatheGeometry: LatheGeometry, + OctahedronGeometry: OctahedronGeometry, + PlaneGeometry: PlaneGeometry, + PolyhedronGeometry: PolyhedronGeometry, + RingGeometry: RingGeometry, + ShapeGeometry: ShapeGeometry, + SphereGeometry: SphereGeometry, + TetrahedronGeometry: TetrahedronGeometry, + TorusGeometry: TorusGeometry, + TorusKnotGeometry: TorusKnotGeometry, + TubeGeometry: TubeGeometry, + WireframeGeometry: WireframeGeometry +}); + +/** + * This material can receive shadows, but otherwise is completely transparent. + * + * ```js + * const geometry = new THREE.PlaneGeometry( 2000, 2000 ); + * geometry.rotateX( - Math.PI / 2 ); + * + * const material = new THREE.ShadowMaterial(); + * material.opacity = 0.2; + * + * const plane = new THREE.Mesh( geometry, material ); + * plane.position.y = -200; + * plane.receiveShadow = true; + * scene.add( plane ); + * ``` + * + * @augments Material + */ +class ShadowMaterial extends Material { + + /** + * Constructs a new shadow material. + * + * @param {Object} [parameters] - An object with one or more properties + * defining the material's appearance. Any property of the material + * (including any property from inherited materials) can be passed + * in here. Color values can be passed any type of value accepted + * by {@link Color#set}. + */ + constructor( parameters ) { + + super(); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isShadowMaterial = true; + + this.type = 'ShadowMaterial'; + + /** + * Color of the material. + * + * @type {Color} + * @default (0,0,0) + */ + this.color = new Color( 0x000000 ); + + /** + * Overwritten since shadow materials are transparent + * by default. + * + * @type {boolean} + * @default true + */ + this.transparent = true; + + /** + * Whether the material is affected by fog or not. + * + * @type {boolean} + * @default true + */ + this.fog = true; + + this.setValues( parameters ); + + } + + copy( source ) { + + super.copy( source ); + + this.color.copy( source.color ); + + this.fog = source.fog; + + return this; + + } + +} + +/** + * Provides utility functions for managing uniforms. + * + * @module UniformsUtils + */ + +/** + * Clones the given uniform definitions by performing a deep-copy. That means + * if the value of a uniform refers to an object like a Vector3 or Texture, + * the cloned uniform will refer to a new object reference. + * + * @param {Object} src - An object representing uniform definitions. + * @return {Object} The cloned uniforms. + */ +function cloneUniforms( src ) { + + const dst = {}; - const position = geometry.attributes.position; - const indices = geometry.index; - let groups = geometry.groups; + for ( const u in src ) { - if ( groups.length === 0 ) { + dst[ u ] = {}; - groups = [ { start: 0, count: indices.count, materialIndex: 0 } ]; + for ( const p in src[ u ] ) { - } + const property = src[ u ][ p ]; - // create a data structure that contains all edges without duplicates + if ( property && ( property.isColor || + property.isMatrix3 || property.isMatrix4 || + property.isVector2 || property.isVector3 || property.isVector4 || + property.isTexture || property.isQuaternion ) ) { - for ( let o = 0, ol = groups.length; o < ol; ++ o ) { + if ( property.isRenderTargetTexture ) { - const group = groups[ o ]; + warn( 'UniformsUtils: Textures of render targets cannot be cloned via cloneUniforms() or mergeUniforms().' ); + dst[ u ][ p ] = null; - const groupStart = group.start; - const groupCount = group.count; + } else { - for ( let i = groupStart, l = ( groupStart + groupCount ); i < l; i += 3 ) { + dst[ u ][ p ] = property.clone(); - for ( let j = 0; j < 3; j ++ ) { + } - const index1 = indices.getX( i + j ); - const index2 = indices.getX( i + ( j + 1 ) % 3 ); + } else if ( Array.isArray( property ) ) { - start.fromBufferAttribute( position, index1 ); - end.fromBufferAttribute( position, index2 ); + dst[ u ][ p ] = property.slice(); - if ( isUniqueEdge( start, end, edges ) === true ) { + } else { - vertices.push( start.x, start.y, start.z ); - vertices.push( end.x, end.y, end.z ); + dst[ u ][ p ] = property; - } + } - } + } - } + } - } + return dst; - } else { +} - // non-indexed BufferGeometry +/** + * Merges the given uniform definitions into a single object. Since the + * method internally uses cloneUniforms(), it performs a deep-copy when + * producing the merged uniform definitions. + * + * @param {Array} uniforms - An array of objects containing uniform definitions. + * @return {Object} The merged uniforms. + */ +function mergeUniforms( uniforms ) { - const position = geometry.attributes.position; + const merged = {}; - for ( let i = 0, l = ( position.count / 3 ); i < l; i ++ ) { + for ( let u = 0; u < uniforms.length; u ++ ) { - for ( let j = 0; j < 3; j ++ ) { + const tmp = cloneUniforms( uniforms[ u ] ); - // three edges per triangle, an edge is represented as (index1, index2) - // e.g. the first triangle has the following edges: (0,1),(1,2),(2,0) + for ( const p in tmp ) { - const index1 = 3 * i + j; - const index2 = 3 * i + ( ( j + 1 ) % 3 ); + merged[ p ] = tmp[ p ]; - start.fromBufferAttribute( position, index1 ); - end.fromBufferAttribute( position, index2 ); + } - if ( isUniqueEdge( start, end, edges ) === true ) { + } - vertices.push( start.x, start.y, start.z ); - vertices.push( end.x, end.y, end.z ); + return merged; - } +} - } +function cloneUniformsGroups( src ) { - } + const dst = []; - } + for ( let u = 0; u < src.length; u ++ ) { - // build geometry + dst.push( src[ u ].clone() ); - this.setAttribute( 'position', new Float32BufferAttribute( vertices, 3 ) ); + } - } + return dst; - } +} - copy( source ) { +function getUnlitUniformColorSpace( renderer ) { - super.copy( source ); + const currentRenderTarget = renderer.getRenderTarget(); - this.parameters = Object.assign( {}, source.parameters ); + if ( currentRenderTarget === null ) { - return this; + // https://github.com/mrdoob/three.js/pull/23937#issuecomment-1111067398 + return renderer.outputColorSpace; } -} - -function isUniqueEdge( start, end, edges ) { + // https://github.com/mrdoob/three.js/issues/27868 + if ( currentRenderTarget.isXRRenderTarget === true ) { - const hash1 = `${start.x},${start.y},${start.z}-${end.x},${end.y},${end.z}`; - const hash2 = `${end.x},${end.y},${end.z}-${start.x},${start.y},${start.z}`; // coincident edge + return currentRenderTarget.texture.colorSpace; - if ( edges.has( hash1 ) === true || edges.has( hash2 ) === true ) { + } - return false; + return ColorManagement.workingColorSpace; - } else { +} - edges.add( hash1 ); - edges.add( hash2 ); - return true; +// Legacy - } +const UniformsUtils = { clone: cloneUniforms, merge: mergeUniforms }; -} +var default_vertex = "void main() {\n\tgl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\n}"; -var Geometries = /*#__PURE__*/Object.freeze({ - __proto__: null, - BoxGeometry: BoxGeometry, - CapsuleGeometry: CapsuleGeometry, - CircleGeometry: CircleGeometry, - ConeGeometry: ConeGeometry, - CylinderGeometry: CylinderGeometry, - DodecahedronGeometry: DodecahedronGeometry, - EdgesGeometry: EdgesGeometry, - ExtrudeGeometry: ExtrudeGeometry, - IcosahedronGeometry: IcosahedronGeometry, - LatheGeometry: LatheGeometry, - OctahedronGeometry: OctahedronGeometry, - PlaneGeometry: PlaneGeometry, - PolyhedronGeometry: PolyhedronGeometry, - RingGeometry: RingGeometry, - ShapeGeometry: ShapeGeometry, - SphereGeometry: SphereGeometry, - TetrahedronGeometry: TetrahedronGeometry, - TorusGeometry: TorusGeometry, - TorusKnotGeometry: TorusKnotGeometry, - TubeGeometry: TubeGeometry, - WireframeGeometry: WireframeGeometry -}); +var default_fragment = "void main() {\n\tgl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 );\n}"; /** - * This material can receive shadows, but otherwise is completely transparent. + * A material rendered with custom shaders. A shader is a small program written in GLSL. + * that runs on the GPU. You may want to use a custom shader if you need to implement an + * effect not included with any of the built-in materials. * - * ```js - * const geometry = new THREE.PlaneGeometry( 2000, 2000 ); - * geometry.rotateX( - Math.PI / 2 ); + * There are the following notes to bear in mind when using a `ShaderMaterial`: * - * const material = new THREE.ShadowMaterial(); - * material.opacity = 0.2; + * - `ShaderMaterial` can only be used with {@link WebGLRenderer}. + * - Built in attributes and uniforms are passed to the shaders along with your code. If + * you don't want that, use {@link RawShaderMaterial} instead. + * - You can use the directive `#pragma unroll_loop_start` and `#pragma unroll_loop_end` + * in order to unroll a `for` loop in GLSL by the shader preprocessor. The directive has + * to be placed right above the loop. The loop formatting has to correspond to a defined standard. + * - The loop has to be [normalized](https://en.wikipedia.org/wiki/Normalized_loop). + * - The loop variable has to be *i*. + * - The value `UNROLLED_LOOP_INDEX` will be replaced with the explicitly + * value of *i* for the given iteration and can be used in preprocessor + * statements. * - * const plane = new THREE.Mesh( geometry, material ); - * plane.position.y = -200; - * plane.receiveShadow = true; - * scene.add( plane ); + * ```js + * const material = new THREE.ShaderMaterial( { + * uniforms: { + * time: { value: 1.0 }, + * resolution: { value: new THREE.Vector2() } + * }, + * vertexShader: document.getElementById( 'vertexShader' ).textContent, + * fragmentShader: document.getElementById( 'fragmentShader' ).textContent + * } ); * ``` * * @augments Material */ -class ShadowMaterial extends Material { +class ShaderMaterial extends Material { /** - * Constructs a new shadow material. + * Constructs a new shader material. * * @param {Object} [parameters] - An object with one or more properties * defining the material's appearance. Any property of the material @@ -38467,36 +37206,214 @@ class ShadowMaterial extends Material { * @readonly * @default true */ - this.isShadowMaterial = true; + this.isShaderMaterial = true; - this.type = 'ShadowMaterial'; + this.type = 'ShaderMaterial'; /** - * Color of the material. + * Defines custom constants using `#define` directives within the GLSL code + * for both the vertex shader and the fragment shader; each key/value pair + * yields another directive. + * ```js + * defines: { + * FOO: 15, + * BAR: true + * } + * ``` + * Yields the lines: + * ``` + * #define FOO 15 + * #define BAR true + * ``` * - * @type {Color} - * @default (0,0,0) + * @type {Object} */ - this.color = new Color( 0x000000 ); + this.defines = {}; /** - * Overwritten since shadow materials are transparent - * by default. + * An object of the form: + * ```js + * { + * "uniform1": { value: 1.0 }, + * "uniform2": { value: 2 } + * } + * ``` + * specifying the uniforms to be passed to the shader code; keys are uniform + * names, values are definitions of the form + * ``` + * { + * value: 1.0 + * } + * ``` + * where `value` is the value of the uniform. Names must match the name of + * the uniform, as defined in the GLSL code. Note that uniforms are refreshed + * on every frame, so updating the value of the uniform will immediately + * update the value available to the GLSL code. + * + * @type {Object} + */ + this.uniforms = {}; + + /** + * An array holding uniforms groups for configuring UBOs. + * + * @type {Array} + */ + this.uniformsGroups = []; + + /** + * Vertex shader GLSL code. This is the actual code for the shader. + * + * @type {string} + */ + this.vertexShader = default_vertex; + + /** + * Fragment shader GLSL code. This is the actual code for the shader. + * + * @type {string} + */ + this.fragmentShader = default_fragment; + + /** + * Controls line thickness or lines. + * + * WebGL and WebGPU ignore this setting and always render line primitives with a + * width of one pixel. + * + * @type {number} + * @default 1 + */ + this.linewidth = 1; + + /** + * Renders the geometry as a wireframe. * * @type {boolean} - * @default true + * @default false */ - this.transparent = true; + this.wireframe = false; /** - * Whether the material is affected by fog or not. + * Controls the thickness of the wireframe. + * + * WebGL and WebGPU ignore this property and always render + * 1 pixel wide lines. + * + * @type {number} + * @default 1 + */ + this.wireframeLinewidth = 1; + + /** + * Defines whether the material color is affected by global fog settings; `true` + * to pass fog uniforms to the shader. + * + * Setting this property to `true` requires the definition of fog uniforms. It is + * recommended to use `UniformsUtils.merge()` to combine the custom shader uniforms + * with predefined fog uniforms. + * + * ```js + * const material = new ShaderMaterial( { + * uniforms: UniformsUtils.merge( [ UniformsLib[ 'fog' ], shaderUniforms ] ); + * vertexShader: vertexShader, + * fragmentShader: fragmentShader, + * fog: true + * } ); + * ``` + * + * @type {boolean} + * @default false + */ + this.fog = false; + + /** + * Defines whether this material uses lighting; `true` to pass uniform data + * related to lighting to this shader. + * + * @type {boolean} + * @default false + */ + this.lights = false; + + /** + * Defines whether this material supports clipping; `true` to let the renderer + * pass the clippingPlanes uniform. + * + * @type {boolean} + * @default false + */ + this.clipping = false; + + /** + * Overwritten and set to `true` by default. * * @type {boolean} * @default true */ - this.fog = true; + this.forceSinglePass = true; - this.setValues( parameters ); + /** + * This object allows to enable certain WebGL 2 extensions. + * + * - clipCullDistance: set to `true` to use vertex shader clipping + * - multiDraw: set to `true` to use vertex shader multi_draw / enable gl_DrawID + * + * @type {{clipCullDistance:false,multiDraw:false}} + */ + this.extensions = { + clipCullDistance: false, // set to use vertex shader clipping + multiDraw: false // set to use vertex shader multi_draw / enable gl_DrawID + }; + + /** + * When the rendered geometry doesn't include these attributes but the + * material does, these default values will be passed to the shaders. This + * avoids errors when buffer data is missing. + * + * - color: [ 1, 1, 1 ] + * - uv: [ 0, 0 ] + * - uv1: [ 0, 0 ] + * + * @type {Object} + */ + this.defaultAttributeValues = { + 'color': [ 1, 1, 1 ], + 'uv': [ 0, 0 ], + 'uv1': [ 0, 0 ] + }; + + /** + * If set, this calls [gl.bindAttribLocation](https://developer.mozilla.org/en-US/docs/Web/API/WebGLRenderingContext/bindAttribLocation) + * to bind a generic vertex index to an attribute variable. + * + * @type {string|undefined} + * @default undefined + */ + this.index0AttributeName = undefined; + + /** + * Can be used to force a uniform update while changing uniforms in + * {@link Object3D#onBeforeRender}. + * + * @type {boolean} + * @default false + */ + this.uniformsNeedUpdate = false; + + /** + * Defines the GLSL version of custom shader code. + * + * @type {?(GLSL1|GLSL3)} + * @default null + */ + this.glslVersion = null; + + if ( parameters !== undefined ) { + + this.setValues( parameters ); + + } } @@ -38504,14 +37421,130 @@ class ShadowMaterial extends Material { super.copy( source ); - this.color.copy( source.color ); + this.fragmentShader = source.fragmentShader; + this.vertexShader = source.vertexShader; + + this.uniforms = cloneUniforms( source.uniforms ); + this.uniformsGroups = cloneUniformsGroups( source.uniformsGroups ); + + this.defines = Object.assign( {}, source.defines ); + + this.wireframe = source.wireframe; + this.wireframeLinewidth = source.wireframeLinewidth; this.fog = source.fog; + this.lights = source.lights; + this.clipping = source.clipping; + + this.extensions = Object.assign( {}, source.extensions ); + + this.glslVersion = source.glslVersion; + + this.defaultAttributeValues = Object.assign( {}, source.defaultAttributeValues ); + + this.index0AttributeName = source.index0AttributeName; + + this.uniformsNeedUpdate = source.uniformsNeedUpdate; return this; } + toJSON( meta ) { + + const data = super.toJSON( meta ); + + data.glslVersion = this.glslVersion; + data.uniforms = {}; + + for ( const name in this.uniforms ) { + + const uniform = this.uniforms[ name ]; + const value = uniform.value; + + if ( value && value.isTexture ) { + + data.uniforms[ name ] = { + type: 't', + value: value.toJSON( meta ).uuid + }; + + } else if ( value && value.isColor ) { + + data.uniforms[ name ] = { + type: 'c', + value: value.getHex() + }; + + } else if ( value && value.isVector2 ) { + + data.uniforms[ name ] = { + type: 'v2', + value: value.toArray() + }; + + } else if ( value && value.isVector3 ) { + + data.uniforms[ name ] = { + type: 'v3', + value: value.toArray() + }; + + } else if ( value && value.isVector4 ) { + + data.uniforms[ name ] = { + type: 'v4', + value: value.toArray() + }; + + } else if ( value && value.isMatrix3 ) { + + data.uniforms[ name ] = { + type: 'm3', + value: value.toArray() + }; + + } else if ( value && value.isMatrix4 ) { + + data.uniforms[ name ] = { + type: 'm4', + value: value.toArray() + }; + + } else { + + data.uniforms[ name ] = { + value: value + }; + + // note: the array variants v2v, v3v, v4v, m4v and tv are not supported so far + + } + + } + + if ( Object.keys( this.defines ).length > 0 ) data.defines = this.defines; + + data.vertexShader = this.vertexShader; + data.fragmentShader = this.fragmentShader; + + data.lights = this.lights; + data.clipping = this.clipping; + + const extensions = {}; + + for ( const key in this.extensions ) { + + if ( this.extensions[ key ] === true ) extensions[ key ] = true; + + } + + if ( Object.keys( extensions ).length > 0 ) data.extensions = extensions; + + return data; + + } + } /** @@ -46049,183 +45082,737 @@ class LightShadow { this._viewportCount = 1; - this._viewports = [ + this._viewports = [ + + new 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, shadowCamera.coordinateSystem, shadowCamera.reversedDepth ); + + if ( shadowCamera.reversedDepth ) { + + shadowMatrix.set( + 0.5, 0.0, 0.0, 0.5, + 0.0, 0.5, 0.0, 0.5, + 0.0, 0.0, 1.0, 0.0, + 0.0, 0.0, 0.0, 1.0 + ); + + } else { + + 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.autoUpdate = source.autoUpdate; + this.needsUpdate = source.needsUpdate; + this.normalBias = source.normalBias; + this.blurSamples = source.blurSamples; + + this.mapSize.copy( source.mapSize ); + + this.biasNode = source.biasNode; + + 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; + + } + +} + +const _position$2 = /*@__PURE__*/ new Vector3(); +const _quaternion$2 = /*@__PURE__*/ new Quaternion(); +const _scale$2 = /*@__PURE__*/ new Vector3(); + +/** + * Abstract base class for cameras. This class should always be inherited + * when you build a new camera. + * + * @abstract + * @augments Object3D + */ +class Camera extends Object3D { + + /** + * Constructs a new camera. + */ + constructor() { + + super(); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isCamera = true; + + this.type = 'Camera'; + + /** + * The inverse of the camera's world matrix. + * + * @type {Matrix4} + */ + this.matrixWorldInverse = new Matrix4(); + + /** + * The camera's projection matrix. + * + * @type {Matrix4} + */ + this.projectionMatrix = new Matrix4(); + + /** + * The inverse of the camera's projection matrix. + * + * @type {Matrix4} + */ + this.projectionMatrixInverse = new Matrix4(); + + /** + * The coordinate system in which the camera is used. + * + * @type {(WebGLCoordinateSystem|WebGPUCoordinateSystem)} + */ + this.coordinateSystem = WebGLCoordinateSystem; + + this._reversedDepth = false; + + } + + /** + * The flag that indicates whether the camera uses a reversed depth buffer. + * + * @type {boolean} + * @default false + */ + get reversedDepth() { + + return this._reversedDepth; + + } + + copy( source, recursive ) { + + super.copy( source, recursive ); + + this.matrixWorldInverse.copy( source.matrixWorldInverse ); + + this.projectionMatrix.copy( source.projectionMatrix ); + this.projectionMatrixInverse.copy( source.projectionMatrixInverse ); + + this.coordinateSystem = source.coordinateSystem; + + return this; + + } + + /** + * Returns a vector representing the ("look") direction of the 3D object in world space. + * + * This method is overwritten since cameras have a different forward vector compared to other + * 3D objects. A camera looks down its local, negative z-axis by default. + * + * @param {Vector3} target - The target vector the result is stored to. + * @return {Vector3} The 3D object's direction in world space. + */ + getWorldDirection( target ) { + + return super.getWorldDirection( target ).negate(); + + } + + updateMatrixWorld( force ) { + + super.updateMatrixWorld( force ); + + // exclude scale from view matrix to be glTF conform + + this.matrixWorld.decompose( _position$2, _quaternion$2, _scale$2 ); + + if ( _scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1 ) { + + this.matrixWorldInverse.copy( this.matrixWorld ).invert(); + + } else { + + this.matrixWorldInverse.compose( _position$2, _quaternion$2, _scale$2.set( 1, 1, 1 ) ).invert(); + + } + + } + + updateWorldMatrix( updateParents, updateChildren ) { + + super.updateWorldMatrix( updateParents, updateChildren ); + + // exclude scale from view matrix to be glTF conform + + this.matrixWorld.decompose( _position$2, _quaternion$2, _scale$2 ); + + if ( _scale$2.x === 1 && _scale$2.y === 1 && _scale$2.z === 1 ) { + + this.matrixWorldInverse.copy( this.matrixWorld ).invert(); + + } else { + + this.matrixWorldInverse.compose( _position$2, _quaternion$2, _scale$2.set( 1, 1, 1 ) ).invert(); + + } + + } + + clone() { + + return new this.constructor().copy( this ); + + } + +} + +const _v3$1 = /*@__PURE__*/ new Vector3(); +const _minTarget = /*@__PURE__*/ new Vector2(); +const _maxTarget = /*@__PURE__*/ new Vector2(); + +/** + * Camera that uses [perspective projection](https://en.wikipedia.org/wiki/Perspective_(graphical)). + * + * This projection mode is designed to mimic the way the human eye sees. It + * is the most common projection mode used for rendering a 3D scene. + * + * ```js + * const camera = new THREE.PerspectiveCamera( 45, width / height, 1, 1000 ); + * scene.add( camera ); + * ``` + * + * @augments Camera + */ +class PerspectiveCamera extends Camera { + + /** + * Constructs a new perspective camera. + * + * @param {number} [fov=50] - The vertical field of view. + * @param {number} [aspect=1] - The aspect ratio. + * @param {number} [near=0.1] - The camera's near plane. + * @param {number} [far=2000] - The camera's far plane. + */ + constructor( fov = 50, aspect = 1, near = 0.1, far = 2000 ) { + + super(); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isPerspectiveCamera = true; + + this.type = 'PerspectiveCamera'; + + /** + * The vertical field of view, from bottom to top of view, + * in degrees. + * + * @type {number} + * @default 50 + */ + this.fov = fov; + + /** + * The zoom factor of the camera. + * + * @type {number} + * @default 1 + */ + this.zoom = 1; + + /** + * The camera's near plane. The valid range is greater than `0` + * and less than the current value of {@link PerspectiveCamera#far}. + * + * Note that, unlike for the {@link OrthographicCamera}, `0` is not a + * valid value for a perspective camera's near plane. + * + * @type {number} + * @default 0.1 + */ + this.near = near; + + /** + * The camera's far plane. Must be greater than the + * current value of {@link PerspectiveCamera#near}. + * + * @type {number} + * @default 2000 + */ + this.far = far; + + /** + * Object distance used for stereoscopy and depth-of-field effects. This + * parameter does not influence the projection matrix unless a + * {@link StereoCamera} is being used. + * + * @type {number} + * @default 10 + */ + this.focus = 10; + + /** + * The aspect ratio, usually the canvas width / canvas height. + * + * @type {number} + * @default 1 + */ + this.aspect = aspect; + + /** + * Represents the frustum window specification. This property should not be edited + * directly but via {@link PerspectiveCamera#setViewOffset} and {@link PerspectiveCamera#clearViewOffset}. + * + * @type {?Object} + * @default null + */ + this.view = null; + + /** + * Film size used for the larger axis. Default is `35` (millimeters). This + * parameter does not influence the projection matrix unless {@link PerspectiveCamera#filmOffset} + * is set to a nonzero value. + * + * @type {number} + * @default 35 + */ + this.filmGauge = 35; + + /** + * Horizontal off-center offset in the same unit as {@link PerspectiveCamera#filmGauge}. + * + * @type {number} + * @default 0 + */ + this.filmOffset = 0; + + this.updateProjectionMatrix(); + + } + + copy( source, recursive ) { + + super.copy( source, recursive ); + + this.fov = source.fov; + this.zoom = source.zoom; + + this.near = source.near; + this.far = source.far; + this.focus = source.focus; + + this.aspect = source.aspect; + this.view = source.view === null ? null : Object.assign( {}, source.view ); + + this.filmGauge = source.filmGauge; + this.filmOffset = source.filmOffset; + + return this; + + } + + /** + * Sets the FOV by focal length in respect to the current {@link PerspectiveCamera#filmGauge}. + * + * The default film gauge is 35, so that the focal length can be specified for + * a 35mm (full frame) camera. + * + * @param {number} focalLength - Values for focal length and film gauge must have the same unit. + */ + setFocalLength( focalLength ) { - new Vector4( 0, 0, 1, 1 ) + /** see {@link http://www.bobatkins.com/photography/technical/field_of_view.html} */ + const vExtentSlope = 0.5 * this.getFilmHeight() / focalLength; - ]; + this.fov = RAD2DEG * 2 * Math.atan( vExtentSlope ); + this.updateProjectionMatrix(); } /** - * Used internally by the renderer to get the number of viewports that need - * to be rendered for this shadow. + * Returns the focal length from the current {@link PerspectiveCamera#fov} and + * {@link PerspectiveCamera#filmGauge}. * - * @return {number} The viewport count. + * @return {number} The computed focal length. */ - getViewportCount() { + getFocalLength() { - return this._viewportCount; + const vExtentSlope = Math.tan( DEG2RAD * 0.5 * this.fov ); + + return 0.5 * this.getFilmHeight() / vExtentSlope; } /** - * Gets the shadow cameras frustum. Used internally by the renderer to cull objects. + * Returns the current vertical field of view angle in degrees considering {@link PerspectiveCamera#zoom}. * - * @return {Frustum} The shadow camera frustum. + * @return {number} The effective FOV. */ - getFrustum() { + getEffectiveFOV() { - return this._frustum; + return RAD2DEG * 2 * Math.atan( + Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom ); } /** - * Update the matrices for the camera and shadow, used internally by the renderer. + * Returns the width of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or + * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. * - * @param {Light} light - The light for which the shadow is being rendered. + * @return {number} The film width. */ - updateMatrices( light ) { + getFilmWidth() { - const shadowCamera = this.camera; - const shadowMatrix = this.matrix; + // film not completely covered in portrait format (aspect < 1) + return this.filmGauge * Math.min( this.aspect, 1 ); - _lightPositionWorld.setFromMatrixPosition( light.matrixWorld ); - shadowCamera.position.copy( _lightPositionWorld ); + } - _lookTarget.setFromMatrixPosition( light.target.matrixWorld ); - shadowCamera.lookAt( _lookTarget ); - shadowCamera.updateMatrixWorld(); + /** + * Returns the height of the image on the film. If {@link PerspectiveCamera#aspect} is greater than or + * equal to one (landscape format), the result equals {@link PerspectiveCamera#filmGauge}. + * + * @return {number} The film width. + */ + getFilmHeight() { - _projScreenMatrix.multiplyMatrices( shadowCamera.projectionMatrix, shadowCamera.matrixWorldInverse ); - this._frustum.setFromProjectionMatrix( _projScreenMatrix, shadowCamera.coordinateSystem, shadowCamera.reversedDepth ); + // film not completely covered in landscape format (aspect > 1) + return this.filmGauge / Math.max( this.aspect, 1 ); - if ( shadowCamera.reversedDepth ) { + } - shadowMatrix.set( - 0.5, 0.0, 0.0, 0.5, - 0.0, 0.5, 0.0, 0.5, - 0.0, 0.0, 1.0, 0.0, - 0.0, 0.0, 0.0, 1.0 - ); + /** + * Computes the 2D bounds of the camera's viewable rectangle at a given distance along the viewing direction. + * Sets `minTarget` and `maxTarget` to the coordinates of the lower-left and upper-right corners of the view rectangle. + * + * @param {number} distance - The viewing distance. + * @param {Vector2} minTarget - The lower-left corner of the view rectangle is written into this vector. + * @param {Vector2} maxTarget - The upper-right corner of the view rectangle is written into this vector. + */ + getViewBounds( distance, minTarget, maxTarget ) { - } else { + _v3$1.set( -1, -1, 0.5 ).applyMatrix4( this.projectionMatrixInverse ); - 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 - ); + minTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z ); - } + _v3$1.set( 1, 1, 0.5 ).applyMatrix4( this.projectionMatrixInverse ); - shadowMatrix.multiply( _projScreenMatrix ); + maxTarget.set( _v3$1.x, _v3$1.y ).multiplyScalar( - distance / _v3$1.z ); } /** - * Returns a viewport definition for the given viewport index. + * Computes the width and height of the camera's viewable rectangle at a given distance along the viewing direction. * - * @param {number} viewportIndex - The viewport index. - * @return {Vector4} The viewport. + * @param {number} distance - The viewing distance. + * @param {Vector2} target - The target vector that is used to store result where x is width and y is height. + * @returns {Vector2} The view size. */ - getViewport( viewportIndex ) { + getViewSize( distance, target ) { - return this._viewports[ viewportIndex ]; + this.getViewBounds( distance, _minTarget, _maxTarget ); + + return target.subVectors( _maxTarget, _minTarget ); } /** - * Returns the frame extends. + * Sets an offset in a larger frustum. This is useful for multi-window or + * multi-monitor/multi-machine setups. * - * @return {Vector2} The frame extends. + * For example, if you have 3x2 monitors and each monitor is 1920x1080 and + * the monitors are in grid like this + *``` + * +---+---+---+ + * | A | B | C | + * +---+---+---+ + * | D | E | F | + * +---+---+---+ + *``` + * then for each monitor you would call it like this: + *```js + * const w = 1920; + * const h = 1080; + * const fullWidth = w * 3; + * const fullHeight = h * 2; + * + * // --A-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 0, w, h ); + * // --B-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 0, w, h ); + * // --C-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 0, w, h ); + * // --D-- + * camera.setViewOffset( fullWidth, fullHeight, w * 0, h * 1, w, h ); + * // --E-- + * camera.setViewOffset( fullWidth, fullHeight, w * 1, h * 1, w, h ); + * // --F-- + * camera.setViewOffset( fullWidth, fullHeight, w * 2, h * 1, w, h ); + * ``` + * + * Note there is no reason monitors have to be the same size or in a grid. + * + * @param {number} fullWidth - The full width of multiview setup. + * @param {number} fullHeight - The full height of multiview setup. + * @param {number} x - The horizontal offset of the subcamera. + * @param {number} y - The vertical offset of the subcamera. + * @param {number} width - The width of subcamera. + * @param {number} height - The height of subcamera. */ - getFrameExtents() { + setViewOffset( fullWidth, fullHeight, x, y, width, height ) { - return this._frameExtents; + this.aspect = fullWidth / fullHeight; + + if ( this.view === null ) { + + this.view = { + enabled: true, + fullWidth: 1, + fullHeight: 1, + offsetX: 0, + offsetY: 0, + width: 1, + height: 1 + }; + + } + + this.view.enabled = true; + this.view.fullWidth = fullWidth; + this.view.fullHeight = fullHeight; + this.view.offsetX = x; + this.view.offsetY = y; + this.view.width = width; + this.view.height = height; + + this.updateProjectionMatrix(); } /** - * Frees the GPU-related resources allocated by this instance. Call this - * method whenever this instance is no longer used in your app. + * Removes the view offset from the projection matrix. */ - dispose() { + clearViewOffset() { - if ( this.map ) { + if ( this.view !== null ) { - this.map.dispose(); + this.view.enabled = false; } - if ( this.mapPass ) { - - this.mapPass.dispose(); - - } + this.updateProjectionMatrix(); } /** - * 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. + * Updates the camera's projection matrix. Must be called after any change of + * camera properties. */ - copy( source ) { + updateProjectionMatrix() { - this.camera = source.camera.clone(); + const near = this.near; + let top = near * Math.tan( DEG2RAD * 0.5 * this.fov ) / this.zoom; + let height = 2 * top; + let width = this.aspect * height; + let left = -0.5 * width; + const view = this.view; - this.intensity = source.intensity; + if ( this.view !== null && this.view.enabled ) { - this.bias = source.bias; - this.radius = source.radius; + const fullWidth = view.fullWidth, + fullHeight = view.fullHeight; - this.autoUpdate = source.autoUpdate; - this.needsUpdate = source.needsUpdate; - this.normalBias = source.normalBias; - this.blurSamples = source.blurSamples; + left += view.offsetX * width / fullWidth; + top -= view.offsetY * height / fullHeight; + width *= view.width / fullWidth; + height *= view.height / fullHeight; - this.mapSize.copy( source.mapSize ); + } - this.biasNode = source.biasNode; + const skew = this.filmOffset; + if ( skew !== 0 ) left += near * skew / this.getFilmWidth(); - return this; + this.projectionMatrix.makePerspective( left, left + width, top, top - height, near, this.far, this.coordinateSystem, this.reversedDepth ); + + this.projectionMatrixInverse.copy( this.projectionMatrix ).invert(); } - /** - * Returns a new light shadow instance with copied values from this instance. - * - * @return {LightShadow} A clone of this instance. - */ - clone() { + toJSON( meta ) { - return new this.constructor().copy( this ); + const data = super.toJSON( meta ); - } + data.object.fov = this.fov; + data.object.zoom = this.zoom; - /** - * Serializes the light shadow into JSON. - * - * @return {Object} A JSON object representing the serialized light shadow. - * @see {@link ObjectLoader#parse} - */ - toJSON() { + data.object.near = this.near; + data.object.far = this.far; + data.object.focus = this.focus; - const object = {}; + data.object.aspect = this.aspect; - 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(); + if ( this.view !== null ) data.object.view = Object.assign( {}, this.view ); - object.camera = this.camera.toJSON( false ).object; - delete object.camera.matrix; + data.object.filmGauge = this.filmGauge; + data.object.filmOffset = this.filmOffset; - return object; + return data; } @@ -50035,6 +49622,249 @@ class StereoCamera { } +const fov = -90; // negative fov is not an error +const aspect = 1; + +/** + * A special type of camera that is positioned in 3D space to render its surroundings into a + * cube render target. The render target can then be used as an environment map for rendering + * realtime reflections in your scene. + * + * ```js + * // Create cube render target + * const cubeRenderTarget = new THREE.WebGLCubeRenderTarget( 256, { generateMipmaps: true, minFilter: THREE.LinearMipmapLinearFilter } ); + * + * // Create cube camera + * const cubeCamera = new THREE.CubeCamera( 1, 100000, cubeRenderTarget ); + * scene.add( cubeCamera ); + * + * // Create car + * const chromeMaterial = new THREE.MeshLambertMaterial( { color: 0xffffff, envMap: cubeRenderTarget.texture } ); + * const car = new THREE.Mesh( carGeometry, chromeMaterial ); + * scene.add( car ); + * + * // Update the render target cube + * car.visible = false; + * cubeCamera.position.copy( car.position ); + * cubeCamera.update( renderer, scene ); + * + * // Render the scene + * car.visible = true; + * renderer.render( scene, camera ); + * ``` + * + * @augments Object3D + */ +class CubeCamera extends Object3D { + + /** + * Constructs a new cube camera. + * + * @param {number} near - The camera's near plane. + * @param {number} far - The camera's far plane. + * @param {WebGLCubeRenderTarget} renderTarget - The cube render target. + */ + constructor( near, far, renderTarget ) { + + super(); + + this.type = 'CubeCamera'; + + /** + * A reference to the cube render target. + * + * @type {WebGLCubeRenderTarget} + */ + this.renderTarget = renderTarget; + + /** + * The current active coordinate system. + * + * @type {?(WebGLCoordinateSystem|WebGPUCoordinateSystem)} + * @default null + */ + this.coordinateSystem = null; + + /** + * The current active mipmap level + * + * @type {number} + * @default 0 + */ + this.activeMipmapLevel = 0; + + const cameraPX = new PerspectiveCamera( fov, aspect, near, far ); + cameraPX.layers = this.layers; + this.add( cameraPX ); + + const cameraNX = new PerspectiveCamera( fov, aspect, near, far ); + cameraNX.layers = this.layers; + this.add( cameraNX ); + + const cameraPY = new PerspectiveCamera( fov, aspect, near, far ); + cameraPY.layers = this.layers; + this.add( cameraPY ); + + const cameraNY = new PerspectiveCamera( fov, aspect, near, far ); + cameraNY.layers = this.layers; + this.add( cameraNY ); + + const cameraPZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraPZ.layers = this.layers; + this.add( cameraPZ ); + + const cameraNZ = new PerspectiveCamera( fov, aspect, near, far ); + cameraNZ.layers = this.layers; + this.add( cameraNZ ); + + } + + /** + * Must be called when the coordinate system of the cube camera is changed. + */ + updateCoordinateSystem() { + + const coordinateSystem = this.coordinateSystem; + + const cameras = this.children.concat(); + + const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = cameras; + + for ( const camera of cameras ) this.remove( camera ); + + if ( coordinateSystem === WebGLCoordinateSystem ) { + + cameraPX.up.set( 0, 1, 0 ); + cameraPX.lookAt( 1, 0, 0 ); + + cameraNX.up.set( 0, 1, 0 ); + cameraNX.lookAt( -1, 0, 0 ); + + cameraPY.up.set( 0, 0, -1 ); + cameraPY.lookAt( 0, 1, 0 ); + + cameraNY.up.set( 0, 0, 1 ); + cameraNY.lookAt( 0, -1, 0 ); + + cameraPZ.up.set( 0, 1, 0 ); + cameraPZ.lookAt( 0, 0, 1 ); + + cameraNZ.up.set( 0, 1, 0 ); + cameraNZ.lookAt( 0, 0, -1 ); + + } else if ( coordinateSystem === WebGPUCoordinateSystem ) { + + cameraPX.up.set( 0, -1, 0 ); + cameraPX.lookAt( -1, 0, 0 ); + + cameraNX.up.set( 0, -1, 0 ); + cameraNX.lookAt( 1, 0, 0 ); + + cameraPY.up.set( 0, 0, 1 ); + cameraPY.lookAt( 0, 1, 0 ); + + cameraNY.up.set( 0, 0, -1 ); + cameraNY.lookAt( 0, -1, 0 ); + + cameraPZ.up.set( 0, -1, 0 ); + cameraPZ.lookAt( 0, 0, 1 ); + + cameraNZ.up.set( 0, -1, 0 ); + cameraNZ.lookAt( 0, 0, -1 ); + + } else { + + throw new Error( 'THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: ' + coordinateSystem ); + + } + + for ( const camera of cameras ) { + + this.add( camera ); + + camera.updateMatrixWorld(); + + } + + } + + /** + * Calling this method will render the given scene with the given renderer + * into the cube render target of the camera. + * + * @param {(Renderer|WebGLRenderer)} renderer - The renderer. + * @param {Scene} scene - The scene to render. + */ + update( renderer, scene ) { + + if ( this.parent === null ) this.updateMatrixWorld(); + + const { renderTarget, activeMipmapLevel } = this; + + if ( this.coordinateSystem !== renderer.coordinateSystem ) { + + this.coordinateSystem = renderer.coordinateSystem; + + this.updateCoordinateSystem(); + + } + + const [ cameraPX, cameraNX, cameraPY, cameraNY, cameraPZ, cameraNZ ] = this.children; + + const currentRenderTarget = renderer.getRenderTarget(); + const currentActiveCubeFace = renderer.getActiveCubeFace(); + const currentActiveMipmapLevel = renderer.getActiveMipmapLevel(); + + const currentXrEnabled = renderer.xr.enabled; + + renderer.xr.enabled = false; + + const generateMipmaps = renderTarget.texture.generateMipmaps; + + renderTarget.texture.generateMipmaps = false; + + // https://github.com/mrdoob/three.js/issues/31413#issuecomment-3095966812 + const reversedDepthBuffer = !! ( renderer.isWebGLRenderer && renderer.state.buffers.depth.getReversed() ); + + renderer.setRenderTarget( renderTarget, 0, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraPX ); + + renderer.setRenderTarget( renderTarget, 1, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraNX ); + + renderer.setRenderTarget( renderTarget, 2, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraPY ); + + renderer.setRenderTarget( renderTarget, 3, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraNY ); + + renderer.setRenderTarget( renderTarget, 4, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraPZ ); + + // mipmaps are generated during the last call of render() + // at this point, all sides of the cube render target are defined + + renderTarget.texture.generateMipmaps = generateMipmaps; + + renderer.setRenderTarget( renderTarget, 5, activeMipmapLevel ); + if ( reversedDepthBuffer && renderer.autoClear === false ) renderer.clearDepth(); + renderer.render( scene, cameraNZ ); + + renderer.setRenderTarget( currentRenderTarget, currentActiveCubeFace, currentActiveMipmapLevel ); + + renderer.xr.enabled = currentXrEnabled; + + renderTarget.texture.needsPMREMUpdate = true; + + } + +} + /** * This type of camera can be used in order to efficiently render a scene with a * predefined set of cameras. This is an important performance aspect for @@ -56896,12 +56726,10 @@ class Line3 { } - c1.copy( p1 ).add( _d1.multiplyScalar( s ) ); - c2.copy( p2 ).add( _d2.multiplyScalar( t ) ); - - c1.sub( c2 ); + c1.copy( p1 ).addScaledVector( _d1, s ); + c2.copy( p2 ).addScaledVector( _d2, t ); - return c1.dot( c1 ); + return c1.distanceToSquared( c2 ); } @@ -59535,4 +59363,4 @@ if ( typeof window !== 'undefined' ) { } -export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, AttachedBindMode, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BackSide, BasicDepthPacking, BasicShadowMap, BatchedMesh, BezierInterpolant, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CineonToneMapping, CircleGeometry, ClampToEdgeWrapping, Clock, Color, ColorKeyframeTrack, ColorManagement, Compatibility, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, ConstantAlphaFactor, ConstantColorFactor, Controls, CubeCamera, CubeDepthTexture, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderGeometry, Cylindrical, Data3DTexture, DataArrayTexture, DataTexture, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DetachedBindMode, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExternalTexture, ExtrudeGeometry, FileLoader, Float16BufferAttribute, Float32BufferAttribute, FloatType, Fog, FogExp2, FramebufferTexture, FrontSide, Frustum, FrustumArray, GLBufferAttribute, GLSL1, GLSL3, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateBezier, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InterpolationSamplingMode, InterpolationSamplingType, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry, Layers, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, MOUSE, Material, MaterialBlending, MaterialLoader, MathUtils, Matrix2, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoNormalPacking, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NormalGAPacking, NormalRGPacking, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronGeometry, OneFactor, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, Path, PerspectiveCamera, Plane, PlaneGeometry, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, R11_EAC_Format, RAD2DEG, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RG11_EAC_Format, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBDepthPacking, RGBFormat, RGBIntegerFormat, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGDepthPacking, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RenderTarget, RenderTarget3D, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingGeometry, SIGNED_R11_EAC_Format, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SIGNED_RG11_EAC_Format, SRGBColorSpace, SRGBTransfer, Scene, ShaderMaterial, ShadowMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, Source, Sphere, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronGeometry, Texture, TextureLoader, TextureUtils, Timer, TimestampQuery, TorusGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, UniformsUtils, UnsignedByteType, UnsignedInt101111Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, VideoFrameTexture, VideoTexture, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGLRenderTarget, WebGPUCoordinateSystem, WebXRController, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, arrayNeedsUint32, cloneUniforms, createCanvasElement, createElementNS, error, getByteLength, getConsoleFunction, getUnlitUniformColorSpace, isTypedArray, log, mergeUniforms, probeAsync, setConsoleFunction, warn, warnOnce }; +export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveAnimationBlendMode, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrayCamera, ArrowHelper, AttachedBindMode, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BackSide, BasicDepthPacking, BasicShadowMap, BatchedMesh, BezierInterpolant, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxGeometry, BoxHelper, BufferAttribute, BufferGeometry, BufferGeometryLoader, ByteType, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CineonToneMapping, CircleGeometry, ClampToEdgeWrapping, Clock, Color, ColorKeyframeTrack, ColorManagement, Compatibility, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, ConstantAlphaFactor, ConstantColorFactor, Controls, CubeCamera, CubeDepthTexture, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureLoader, CubeUVReflectionMapping, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceBack, CullFaceFront, CullFaceFrontBack, CullFaceNone, Curve, CurvePath, CustomBlending, CustomToneMapping, CylinderGeometry, Cylindrical, Data3DTexture, DataArrayTexture, DataTexture, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DepthFormat, DepthStencilFormat, DepthTexture, DetachedBindMode, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExternalTexture, ExtrudeGeometry, FileLoader, Float16BufferAttribute, Float32BufferAttribute, FloatType, Fog, FogExp2, FramebufferTexture, FrontSide, Frustum, FrustumArray, GLBufferAttribute, GLSL1, GLSL3, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HalfFloatType, HemisphereLight, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, IntType, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateBezier, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InterpolationSamplingMode, InterpolationSamplingType, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry, Layers, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearFilter, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, MOUSE, Material, MaterialBlending, MaterialLoader, MathUtils, Matrix2, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoNormalPacking, NoToneMapping, NormalAnimationBlendMode, NormalBlending, NormalGAPacking, NormalRGPacking, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, ObjectSpaceNormalMap, OctahedronGeometry, OneFactor, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, Path, PerspectiveCamera, Plane, PlaneGeometry, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, R11_EAC_Format, RAD2DEG, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RG11_EAC_Format, RGBADepthPacking, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBDepthPacking, RGBFormat, RGBIntegerFormat, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGDepthPacking, RGFormat, RGIntegerFormat, RawShaderMaterial, Ray, Raycaster, RectAreaLight, RedFormat, RedIntegerFormat, ReinhardToneMapping, RenderTarget, RenderTarget3D, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RingGeometry, SIGNED_R11_EAC_Format, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SIGNED_RG11_EAC_Format, SRGBColorSpace, SRGBTransfer, Scene, ShaderMaterial, ShadowMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, ShortType, Skeleton, SkeletonHelper, SkinnedMesh, Source, Sphere, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, SubtractEquation, SubtractiveBlending, TOUCH, TangentSpaceNormalMap, TetrahedronGeometry, Texture, TextureLoader, TextureUtils, Timer, TimestampQuery, TorusGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, UniformsUtils, UnsignedByteType, UnsignedInt101111Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, VectorKeyframeTrack, VideoFrameTexture, VideoTexture, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLCoordinateSystem, WebGLRenderTarget, WebGPUCoordinateSystem, WebXRController, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroFactor, ZeroSlopeEnding, ZeroStencilOp, arrayNeedsUint32, cloneUniforms, createCanvasElement, createElementNS, error, getByteLength, getConsoleFunction, getUnlitUniformColorSpace, isTypedArray, log, mergeUniforms, probeAsync, setConsoleFunction, warn, warnOnce }; diff --git a/build/three.core.min.js b/build/three.core.min.js index f565e37ad1d1de..a9d2c620068324 100644 --- a/build/three.core.min.js +++ b/build/three.core.min.js @@ -3,4 +3,4 @@ * Copyright 2010-2026 Three.js Authors * SPDX-License-Identifier: MIT */ -const t="183dev",e={LEFT:0,MIDDLE:1,RIGHT:2,ROTATE:0,DOLLY:1,PAN:2},i={ROTATE:0,PAN:1,DOLLY_PAN:2,DOLLY_ROTATE:3},s=0,r=1,n=2,a=3,o=0,h=1,l=2,c=3,u=0,d=1,p=2,m=0,y=1,g=2,f=3,x=4,b=5,v=6,w=100,M=101,S=102,_=103,A=104,T=200,z=201,C=202,I=203,B=204,k=205,O=206,P=207,R=208,N=209,V=210,F=211,E=212,L=213,D=214,j=0,W=1,U=2,q=3,J=4,X=5,Y=6,H=7,Z=0,G=1,$=2,Q=0,K=1,tt=2,et=3,it=4,st=5,rt=6,nt=7,at="attached",ot="detached",ht=300,lt=301,ct=302,ut=303,dt=304,pt=306,mt=1e3,yt=1001,gt=1002,ft=1003,xt=1004,bt=1004,vt=1005,wt=1005,Mt=1006,St=1007,_t=1007,At=1008,Tt=1008,zt=1009,Ct=1010,It=1011,Bt=1012,kt=1013,Ot=1014,Pt=1015,Rt=1016,Nt=1017,Vt=1018,Ft=1020,Et=35902,Lt=35899,Dt=1021,jt=1022,Wt=1023,Ut=1026,qt=1027,Jt=1028,Xt=1029,Yt=1030,Ht=1031,Zt=1032,Gt=1033,$t=33776,Qt=33777,Kt=33778,te=33779,ee=35840,ie=35841,se=35842,re=35843,ne=36196,ae=37492,oe=37496,he=37488,le=37489,ce=37490,ue=37491,de=37808,pe=37809,me=37810,ye=37811,ge=37812,fe=37813,xe=37814,be=37815,ve=37816,we=37817,Me=37818,Se=37819,_e=37820,Ae=37821,Te=36492,ze=36494,Ce=36495,Ie=36283,Be=36284,ke=36285,Oe=36286,Pe=2200,Re=2201,Ne=2202,Ve=2300,Fe=2301,Ee=2302,Le=2303,De=2400,je=2401,We=2402,Ue=2500,qe=2501,Je=0,Xe=1,Ye=2,He=3200,Ze=3201,Ge=3202,$e=3203,Qe=0,Ke=1,ti="",ei="srgb",ii="srgb-linear",si="linear",ri="srgb",ni="",ai="rg",oi="ga",hi=0,li=7680,ci=7681,ui=7682,di=7683,pi=34055,mi=34056,yi=5386,gi=512,fi=513,xi=514,bi=515,vi=516,wi=517,Mi=518,Si=519,_i=512,Ai=513,Ti=514,zi=515,Ci=516,Ii=517,Bi=518,ki=519,Oi=35044,Pi=35048,Ri=35040,Ni=35045,Vi=35049,Fi=35041,Ei=35046,Li=35050,Di=35042,ji="100",Wi="300 es",Ui=2e3,qi=2001,Ji={COMPUTE:"compute",RENDER:"render"},Xi={PERSPECTIVE:"perspective",LINEAR:"linear",FLAT:"flat"},Yi={NORMAL:"normal",CENTROID:"centroid",SAMPLE:"sample",FIRST:"first",EITHER:"either"},Hi={TEXTURE_COMPARE:"depthTextureCompare"};function Zi(t){for(let e=t.length-1;e>=0;--e)if(t[e]>=65535)return!0;return!1}const Gi={Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:Uint8ClampedArray,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array};function $i(t,e){return new Gi[t](e)}function Qi(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)}function Ki(t){return document.createElementNS("http://www.w3.org/1999/xhtml",t)}function ts(){const t=Ki("canvas");return t.style.display="block",t}const es={};let is=null;function ss(t){is=t}function rs(){return is}function ns(...t){const e="THREE."+t.shift();is?is("log",e,...t):console.log(e,...t)}function as(...t){const e="THREE."+t.shift();is?is("warn",e,...t):console.warn(e,...t)}function os(...t){const e="THREE."+t.shift();is?is("error",e,...t):console.error(e,...t)}function hs(...t){const e=t.join(" ");e in es||(es[e]=!0,as(...t))}function ls(t,e,i){return new Promise(function(s,r){setTimeout(function n(){switch(t.clientWaitSync(e,t.SYNC_FLUSH_COMMANDS_BIT,0)){case t.WAIT_FAILED:r();break;case t.TIMEOUT_EXPIRED:setTimeout(n,i);break;default:s()}},i)})}class cs{addEventListener(t,e){void 0===this._listeners&&(this._listeners={});const i=this._listeners;void 0===i[t]&&(i[t]=[]),-1===i[t].indexOf(e)&&i[t].push(e)}hasEventListener(t,e){const i=this._listeners;return void 0!==i&&(void 0!==i[t]&&-1!==i[t].indexOf(e))}removeEventListener(t,e){const i=this._listeners;if(void 0===i)return;const s=i[t];if(void 0!==s){const t=s.indexOf(e);-1!==t&&s.splice(t,1)}}dispatchEvent(t){const e=this._listeners;if(void 0===e)return;const i=e[t.type];if(void 0!==i){t.target=this;const e=i.slice(0);for(let i=0,s=e.length;i>8&255]+us[t>>16&255]+us[t>>24&255]+"-"+us[255&e]+us[e>>8&255]+"-"+us[e>>16&15|64]+us[e>>24&255]+"-"+us[63&i|128]+us[i>>8&255]+"-"+us[i>>16&255]+us[i>>24&255]+us[255&s]+us[s>>8&255]+us[s>>16&255]+us[s>>24&255]).toLowerCase()}function gs(t,e,i){return Math.max(e,Math.min(i,t))}function fs(t,e){return(t%e+e)%e}function xs(t,e,i){return(1-i)*t+i*e}function bs(t,e){switch(e.constructor){case Float32Array:return t;case Uint32Array:return t/4294967295;case Uint16Array:return t/65535;case Uint8Array:return t/255;case Int32Array:return Math.max(t/2147483647,-1);case Int16Array:return Math.max(t/32767,-1);case Int8Array:return Math.max(t/127,-1);default:throw new Error("Invalid component type.")}}function vs(t,e){switch(e.constructor){case Float32Array:return t;case Uint32Array:return Math.round(4294967295*t);case Uint16Array:return Math.round(65535*t);case Uint8Array:return Math.round(255*t);case Int32Array:return Math.round(2147483647*t);case Int16Array:return Math.round(32767*t);case Int8Array:return Math.round(127*t);default:throw new Error("Invalid component type.")}}const ws={DEG2RAD:ps,RAD2DEG:ms,generateUUID:ys,clamp:gs,euclideanModulo:fs,mapLinear:function(t,e,i,s,r){return s+(t-e)*(r-s)/(i-e)},inverseLerp:function(t,e,i){return t!==e?(i-t)/(e-t):0},lerp:xs,damp:function(t,e,i,s){return xs(t,e,1-Math.exp(-i*s))},pingpong:function(t,e=1){return e-Math.abs(fs(t,2*e)-e)},smoothstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*(3-2*t)},smootherstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*t*(t*(6*t-15)+10)},randInt:function(t,e){return t+Math.floor(Math.random()*(e-t+1))},randFloat:function(t,e){return t+Math.random()*(e-t)},randFloatSpread:function(t){return t*(.5-Math.random())},seededRandom:function(t){void 0!==t&&(ds=t);let e=ds+=1831565813;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296},degToRad:function(t){return t*ps},radToDeg:function(t){return t*ms},isPowerOfTwo:function(t){return!(t&t-1)&&0!==t},ceilPowerOfTwo:function(t){return Math.pow(2,Math.ceil(Math.log(t)/Math.LN2))},floorPowerOfTwo:function(t){return Math.pow(2,Math.floor(Math.log(t)/Math.LN2))},setQuaternionFromProperEuler:function(t,e,i,s,r){const n=Math.cos,a=Math.sin,o=n(i/2),h=a(i/2),l=n((e+s)/2),c=a((e+s)/2),u=n((e-s)/2),d=a((e-s)/2),p=n((s-e)/2),m=a((s-e)/2);switch(r){case"XYX":t.set(o*c,h*u,h*d,o*l);break;case"YZY":t.set(h*d,o*c,h*u,o*l);break;case"ZXZ":t.set(h*u,h*d,o*c,o*l);break;case"XZX":t.set(o*c,h*m,h*p,o*l);break;case"YXY":t.set(h*p,o*c,h*m,o*l);break;case"ZYZ":t.set(h*m,h*p,o*c,o*l);break;default:as("MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: "+r)}},normalize:vs,denormalize:bs};class Ms{constructor(t=0,e=0){Ms.prototype.isVector2=!0,this.x=t,this.y=e}get width(){return this.x}set width(t){this.x=t}get height(){return this.y}set height(t){this.y=t}set(t,e){return this.x=t,this.y=e,this}setScalar(t){return this.x=t,this.y=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y)}copy(t){return this.x=t.x,this.y=t.y,this}add(t){return this.x+=t.x,this.y+=t.y,this}addScalar(t){return this.x+=t,this.y+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this}subScalar(t){return this.x-=t,this.y-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this}multiply(t){return this.x*=t.x,this.y*=t.y,this}multiplyScalar(t){return this.x*=t,this.y*=t,this}divide(t){return this.x/=t.x,this.y/=t.y,this}divideScalar(t){return this.multiplyScalar(1/t)}applyMatrix3(t){const e=this.x,i=this.y,s=t.elements;return this.x=s[0]*e+s[3]*i+s[6],this.y=s[1]*e+s[4]*i+s[7],this}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this}clamp(t,e){return this.x=gs(this.x,t.x,e.x),this.y=gs(this.y,t.y,e.y),this}clampScalar(t,e){return this.x=gs(this.x,t,e),this.y=gs(this.y,t,e),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(gs(i,t,e))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const i=this.dot(t)/e;return Math.acos(gs(i,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y;return e*e+i*i}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this}equals(t){return t.x===this.x&&t.y===this.y}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this}rotateAround(t,e){const i=Math.cos(e),s=Math.sin(e),r=this.x-t.x,n=this.y-t.y;return this.x=r*i-n*s+t.x,this.y=r*s+n*i+t.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y}}class Ss{constructor(t=0,e=0,i=0,s=1){this.isQuaternion=!0,this._x=t,this._y=e,this._z=i,this._w=s}static slerpFlat(t,e,i,s,r,n,a){let o=i[s+0],h=i[s+1],l=i[s+2],c=i[s+3],u=r[n+0],d=r[n+1],p=r[n+2],m=r[n+3];if(c!==m||o!==u||h!==d||l!==p){let t=o*u+h*d+l*p+c*m;t<0&&(u=-u,d=-d,p=-p,m=-m,t=-t);let e=1-a;if(t<.9995){const i=Math.acos(t),s=Math.sin(i);e=Math.sin(e*i)/s,o=o*e+u*(a=Math.sin(a*i)/s),h=h*e+d*a,l=l*e+p*a,c=c*e+m*a}else{o=o*e+u*a,h=h*e+d*a,l=l*e+p*a,c=c*e+m*a;const t=1/Math.sqrt(o*o+h*h+l*l+c*c);o*=t,h*=t,l*=t,c*=t}}t[e]=o,t[e+1]=h,t[e+2]=l,t[e+3]=c}static multiplyQuaternionsFlat(t,e,i,s,r,n){const a=i[s],o=i[s+1],h=i[s+2],l=i[s+3],c=r[n],u=r[n+1],d=r[n+2],p=r[n+3];return t[e]=a*p+l*c+o*d-h*u,t[e+1]=o*p+l*u+h*c-a*d,t[e+2]=h*p+l*d+a*u-o*c,t[e+3]=l*p-a*c-o*u-h*d,t}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get w(){return this._w}set w(t){this._w=t,this._onChangeCallback()}set(t,e,i,s){return this._x=t,this._y=e,this._z=i,this._w=s,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(t){return this._x=t.x,this._y=t.y,this._z=t.z,this._w=t.w,this._onChangeCallback(),this}setFromEuler(t,e=!0){const i=t._x,s=t._y,r=t._z,n=t._order,a=Math.cos,o=Math.sin,h=a(i/2),l=a(s/2),c=a(r/2),u=o(i/2),d=o(s/2),p=o(r/2);switch(n){case"XYZ":this._x=u*l*c+h*d*p,this._y=h*d*c-u*l*p,this._z=h*l*p+u*d*c,this._w=h*l*c-u*d*p;break;case"YXZ":this._x=u*l*c+h*d*p,this._y=h*d*c-u*l*p,this._z=h*l*p-u*d*c,this._w=h*l*c+u*d*p;break;case"ZXY":this._x=u*l*c-h*d*p,this._y=h*d*c+u*l*p,this._z=h*l*p+u*d*c,this._w=h*l*c-u*d*p;break;case"ZYX":this._x=u*l*c-h*d*p,this._y=h*d*c+u*l*p,this._z=h*l*p-u*d*c,this._w=h*l*c+u*d*p;break;case"YZX":this._x=u*l*c+h*d*p,this._y=h*d*c+u*l*p,this._z=h*l*p-u*d*c,this._w=h*l*c-u*d*p;break;case"XZY":this._x=u*l*c-h*d*p,this._y=h*d*c-u*l*p,this._z=h*l*p+u*d*c,this._w=h*l*c+u*d*p;break;default:as("Quaternion: .setFromEuler() encountered an unknown order: "+n)}return!0===e&&this._onChangeCallback(),this}setFromAxisAngle(t,e){const i=e/2,s=Math.sin(i);return this._x=t.x*s,this._y=t.y*s,this._z=t.z*s,this._w=Math.cos(i),this._onChangeCallback(),this}setFromRotationMatrix(t){const e=t.elements,i=e[0],s=e[4],r=e[8],n=e[1],a=e[5],o=e[9],h=e[2],l=e[6],c=e[10],u=i+a+c;if(u>0){const t=.5/Math.sqrt(u+1);this._w=.25/t,this._x=(l-o)*t,this._y=(r-h)*t,this._z=(n-s)*t}else if(i>a&&i>c){const t=2*Math.sqrt(1+i-a-c);this._w=(l-o)/t,this._x=.25*t,this._y=(s+n)/t,this._z=(r+h)/t}else if(a>c){const t=2*Math.sqrt(1+a-i-c);this._w=(r-h)/t,this._x=(s+n)/t,this._y=.25*t,this._z=(o+l)/t}else{const t=2*Math.sqrt(1+c-i-a);this._w=(n-s)/t,this._x=(r+h)/t,this._y=(o+l)/t,this._z=.25*t}return this._onChangeCallback(),this}setFromUnitVectors(t,e){let i=t.dot(e)+1;return i<1e-8?(i=0,Math.abs(t.x)>Math.abs(t.z)?(this._x=-t.y,this._y=t.x,this._z=0,this._w=i):(this._x=0,this._y=-t.z,this._z=t.y,this._w=i)):(this._x=t.y*e.z-t.z*e.y,this._y=t.z*e.x-t.x*e.z,this._z=t.x*e.y-t.y*e.x,this._w=i),this.normalize()}angleTo(t){return 2*Math.acos(Math.abs(gs(this.dot(t),-1,1)))}rotateTowards(t,e){const i=this.angleTo(t);if(0===i)return this;const s=Math.min(1,e/i);return this.slerp(t,s),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(t){return this._x*t._x+this._y*t._y+this._z*t._z+this._w*t._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let t=this.length();return 0===t?(this._x=0,this._y=0,this._z=0,this._w=1):(t=1/t,this._x=this._x*t,this._y=this._y*t,this._z=this._z*t,this._w=this._w*t),this._onChangeCallback(),this}multiply(t){return this.multiplyQuaternions(this,t)}premultiply(t){return this.multiplyQuaternions(t,this)}multiplyQuaternions(t,e){const i=t._x,s=t._y,r=t._z,n=t._w,a=e._x,o=e._y,h=e._z,l=e._w;return this._x=i*l+n*a+s*h-r*o,this._y=s*l+n*o+r*a-i*h,this._z=r*l+n*h+i*o-s*a,this._w=n*l-i*a-s*o-r*h,this._onChangeCallback(),this}slerp(t,e){let i=t._x,s=t._y,r=t._z,n=t._w,a=this.dot(t);a<0&&(i=-i,s=-s,r=-r,n=-n,a=-a);let o=1-e;if(a<.9995){const t=Math.acos(a),h=Math.sin(t);o=Math.sin(o*t)/h,e=Math.sin(e*t)/h,this._x=this._x*o+i*e,this._y=this._y*o+s*e,this._z=this._z*o+r*e,this._w=this._w*o+n*e,this._onChangeCallback()}else this._x=this._x*o+i*e,this._y=this._y*o+s*e,this._z=this._z*o+r*e,this._w=this._w*o+n*e,this.normalize();return this}slerpQuaternions(t,e,i){return this.copy(t).slerp(e,i)}random(){const t=2*Math.PI*Math.random(),e=2*Math.PI*Math.random(),i=Math.random(),s=Math.sqrt(1-i),r=Math.sqrt(i);return this.set(s*Math.sin(t),s*Math.cos(t),r*Math.sin(e),r*Math.cos(e))}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._w===this._w}fromArray(t,e=0){return this._x=t[e],this._y=t[e+1],this._z=t[e+2],this._w=t[e+3],this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._w,t}fromBufferAttribute(t,e){return this._x=t.getX(e),this._y=t.getY(e),this._z=t.getZ(e),this._w=t.getW(e),this._onChangeCallback(),this}toJSON(){return this.toArray()}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._w}}class _s{constructor(t=0,e=0,i=0){_s.prototype.isVector3=!0,this.x=t,this.y=e,this.z=i}set(t,e,i){return void 0===i&&(i=this.z),this.x=t,this.y=e,this.z=i,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this}multiplyVectors(t,e){return this.x=t.x*e.x,this.y=t.y*e.y,this.z=t.z*e.z,this}applyEuler(t){return this.applyQuaternion(Ts.setFromEuler(t))}applyAxisAngle(t,e){return this.applyQuaternion(Ts.setFromAxisAngle(t,e))}applyMatrix3(t){const e=this.x,i=this.y,s=this.z,r=t.elements;return this.x=r[0]*e+r[3]*i+r[6]*s,this.y=r[1]*e+r[4]*i+r[7]*s,this.z=r[2]*e+r[5]*i+r[8]*s,this}applyNormalMatrix(t){return this.applyMatrix3(t).normalize()}applyMatrix4(t){const e=this.x,i=this.y,s=this.z,r=t.elements,n=1/(r[3]*e+r[7]*i+r[11]*s+r[15]);return this.x=(r[0]*e+r[4]*i+r[8]*s+r[12])*n,this.y=(r[1]*e+r[5]*i+r[9]*s+r[13])*n,this.z=(r[2]*e+r[6]*i+r[10]*s+r[14])*n,this}applyQuaternion(t){const e=this.x,i=this.y,s=this.z,r=t.x,n=t.y,a=t.z,o=t.w,h=2*(n*s-a*i),l=2*(a*e-r*s),c=2*(r*i-n*e);return this.x=e+o*h+n*c-a*l,this.y=i+o*l+a*h-r*c,this.z=s+o*c+r*l-n*h,this}project(t){return this.applyMatrix4(t.matrixWorldInverse).applyMatrix4(t.projectionMatrix)}unproject(t){return this.applyMatrix4(t.projectionMatrixInverse).applyMatrix4(t.matrixWorld)}transformDirection(t){const e=this.x,i=this.y,s=this.z,r=t.elements;return this.x=r[0]*e+r[4]*i+r[8]*s,this.y=r[1]*e+r[5]*i+r[9]*s,this.z=r[2]*e+r[6]*i+r[10]*s,this.normalize()}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this}divideScalar(t){return this.multiplyScalar(1/t)}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this}clamp(t,e){return this.x=gs(this.x,t.x,e.x),this.y=gs(this.y,t.y,e.y),this.z=gs(this.z,t.z,e.z),this}clampScalar(t,e){return this.x=gs(this.x,t,e),this.y=gs(this.y,t,e),this.z=gs(this.z,t,e),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(gs(i,t,e))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this.z+=(t.z-this.z)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this.z=t.z+(e.z-t.z)*i,this}cross(t){return this.crossVectors(this,t)}crossVectors(t,e){const i=t.x,s=t.y,r=t.z,n=e.x,a=e.y,o=e.z;return this.x=s*o-r*a,this.y=r*n-i*o,this.z=i*a-s*n,this}projectOnVector(t){const e=t.lengthSq();if(0===e)return this.set(0,0,0);const i=t.dot(this)/e;return this.copy(t).multiplyScalar(i)}projectOnPlane(t){return As.copy(this).projectOnVector(t),this.sub(As)}reflect(t){return this.sub(As.copy(t).multiplyScalar(2*this.dot(t)))}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const i=this.dot(t)/e;return Math.acos(gs(i,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y,s=this.z-t.z;return e*e+i*i+s*s}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)+Math.abs(this.z-t.z)}setFromSpherical(t){return this.setFromSphericalCoords(t.radius,t.phi,t.theta)}setFromSphericalCoords(t,e,i){const s=Math.sin(e)*t;return this.x=s*Math.sin(i),this.y=Math.cos(e)*t,this.z=s*Math.cos(i),this}setFromCylindrical(t){return this.setFromCylindricalCoords(t.radius,t.theta,t.y)}setFromCylindricalCoords(t,e,i){return this.x=t*Math.sin(e),this.y=i,this.z=t*Math.cos(e),this}setFromMatrixPosition(t){const e=t.elements;return this.x=e[12],this.y=e[13],this.z=e[14],this}setFromMatrixScale(t){const e=this.setFromMatrixColumn(t,0).length(),i=this.setFromMatrixColumn(t,1).length(),s=this.setFromMatrixColumn(t,2).length();return this.x=e,this.y=i,this.z=s,this}setFromMatrixColumn(t,e){return this.fromArray(t.elements,4*e)}setFromMatrix3Column(t,e){return this.fromArray(t.elements,3*e)}setFromEuler(t){return this.x=t._x,this.y=t._y,this.z=t._z,this}setFromColor(t){return this.x=t.r,this.y=t.g,this.z=t.b,this}equals(t){return t.x===this.x&&t.y===this.y&&t.z===this.z}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this.z=t[e+2],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t[e+2]=this.z,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const t=Math.random()*Math.PI*2,e=2*Math.random()-1,i=Math.sqrt(1-e*e);return this.x=i*Math.cos(t),this.y=e,this.z=i*Math.sin(t),this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}const As=new _s,Ts=new Ss;class zs{constructor(t,e,i,s,r,n,a,o,h){zs.prototype.isMatrix3=!0,this.elements=[1,0,0,0,1,0,0,0,1],void 0!==t&&this.set(t,e,i,s,r,n,a,o,h)}set(t,e,i,s,r,n,a,o,h){const l=this.elements;return l[0]=t,l[1]=s,l[2]=a,l[3]=e,l[4]=r,l[5]=o,l[6]=i,l[7]=n,l[8]=h,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],this}extractBasis(t,e,i){return t.setFromMatrix3Column(this,0),e.setFromMatrix3Column(this,1),i.setFromMatrix3Column(this,2),this}setFromMatrix4(t){const e=t.elements;return this.set(e[0],e[4],e[8],e[1],e[5],e[9],e[2],e[6],e[10]),this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,s=e.elements,r=this.elements,n=i[0],a=i[3],o=i[6],h=i[1],l=i[4],c=i[7],u=i[2],d=i[5],p=i[8],m=s[0],y=s[3],g=s[6],f=s[1],x=s[4],b=s[7],v=s[2],w=s[5],M=s[8];return r[0]=n*m+a*f+o*v,r[3]=n*y+a*x+o*w,r[6]=n*g+a*b+o*M,r[1]=h*m+l*f+c*v,r[4]=h*y+l*x+c*w,r[7]=h*g+l*b+c*M,r[2]=u*m+d*f+p*v,r[5]=u*y+d*x+p*w,r[8]=u*g+d*b+p*M,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[3]*=t,e[6]*=t,e[1]*=t,e[4]*=t,e[7]*=t,e[2]*=t,e[5]*=t,e[8]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[1],s=t[2],r=t[3],n=t[4],a=t[5],o=t[6],h=t[7],l=t[8];return e*n*l-e*a*h-i*r*l+i*a*o+s*r*h-s*n*o}invert(){const t=this.elements,e=t[0],i=t[1],s=t[2],r=t[3],n=t[4],a=t[5],o=t[6],h=t[7],l=t[8],c=l*n-a*h,u=a*o-l*r,d=h*r-n*o,p=e*c+i*u+s*d;if(0===p)return this.set(0,0,0,0,0,0,0,0,0);const m=1/p;return t[0]=c*m,t[1]=(s*h-l*i)*m,t[2]=(a*i-s*n)*m,t[3]=u*m,t[4]=(l*e-s*o)*m,t[5]=(s*r-a*e)*m,t[6]=d*m,t[7]=(i*o-h*e)*m,t[8]=(n*e-i*r)*m,this}transpose(){let t;const e=this.elements;return t=e[1],e[1]=e[3],e[3]=t,t=e[2],e[2]=e[6],e[6]=t,t=e[5],e[5]=e[7],e[7]=t,this}getNormalMatrix(t){return this.setFromMatrix4(t).invert().transpose()}transposeIntoArray(t){const e=this.elements;return t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],this}setUvTransform(t,e,i,s,r,n,a){const o=Math.cos(r),h=Math.sin(r);return this.set(i*o,i*h,-i*(o*n+h*a)+n+t,-s*h,s*o,-s*(-h*n+o*a)+a+e,0,0,1),this}scale(t,e){return this.premultiply(Cs.makeScale(t,e)),this}rotate(t){return this.premultiply(Cs.makeRotation(-t)),this}translate(t,e){return this.premultiply(Cs.makeTranslation(t,e)),this}makeTranslation(t,e){return t.isVector2?this.set(1,0,t.x,0,1,t.y,0,0,1):this.set(1,0,t,0,1,e,0,0,1),this}makeRotation(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,-i,0,i,e,0,0,0,1),this}makeScale(t,e){return this.set(t,0,0,0,e,0,0,0,1),this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<9;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<9;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t}clone(){return(new this.constructor).fromArray(this.elements)}}const Cs=new zs,Is=(new zs).set(.4123908,.3575843,.1804808,.212639,.7151687,.0721923,.0193308,.1191948,.9505322),Bs=(new zs).set(3.2409699,-1.5373832,-.4986108,-.9692436,1.8759675,.0415551,.0556301,-.203977,1.0569715);function ks(){const t={enabled:!0,workingColorSpace:ii,spaces:{},convert:function(t,e,i){return!1!==this.enabled&&e!==i&&e&&i?(this.spaces[e].transfer===ri&&(t.r=Ps(t.r),t.g=Ps(t.g),t.b=Ps(t.b)),this.spaces[e].primaries!==this.spaces[i].primaries&&(t.applyMatrix3(this.spaces[e].toXYZ),t.applyMatrix3(this.spaces[i].fromXYZ)),this.spaces[i].transfer===ri&&(t.r=Rs(t.r),t.g=Rs(t.g),t.b=Rs(t.b)),t):t},workingToColorSpace:function(t,e){return this.convert(t,this.workingColorSpace,e)},colorSpaceToWorking:function(t,e){return this.convert(t,e,this.workingColorSpace)},getPrimaries:function(t){return this.spaces[t].primaries},getTransfer:function(t){return""===t?si:this.spaces[t].transfer},getToneMappingMode:function(t){return this.spaces[t].outputColorSpaceConfig.toneMappingMode||"standard"},getLuminanceCoefficients:function(t,e=this.workingColorSpace){return t.fromArray(this.spaces[e].luminanceCoefficients)},define:function(t){Object.assign(this.spaces,t)},_getMatrix:function(t,e,i){return t.copy(this.spaces[e].toXYZ).multiply(this.spaces[i].fromXYZ)},_getDrawingBufferColorSpace:function(t){return this.spaces[t].outputColorSpaceConfig.drawingBufferColorSpace},_getUnpackColorSpace:function(t=this.workingColorSpace){return this.spaces[t].workingColorSpaceConfig.unpackColorSpace},fromWorkingColorSpace:function(e,i){return hs("ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace()."),t.workingToColorSpace(e,i)},toWorkingColorSpace:function(e,i){return hs("ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking()."),t.colorSpaceToWorking(e,i)}},e=[.64,.33,.3,.6,.15,.06],i=[.2126,.7152,.0722],s=[.3127,.329];return t.define({[ii]:{primaries:e,whitePoint:s,transfer:si,toXYZ:Is,fromXYZ:Bs,luminanceCoefficients:i,workingColorSpaceConfig:{unpackColorSpace:ei},outputColorSpaceConfig:{drawingBufferColorSpace:ei}},[ei]:{primaries:e,whitePoint:s,transfer:ri,toXYZ:Is,fromXYZ:Bs,luminanceCoefficients:i,outputColorSpaceConfig:{drawingBufferColorSpace:ei}}}),t}const Os=ks();function Ps(t){return t<.04045?.0773993808*t:Math.pow(.9478672986*t+.0521327014,2.4)}function Rs(t){return t<.0031308?12.92*t:1.055*Math.pow(t,.41666)-.055}let Ns;class Vs{static getDataURL(t,e="image/png"){if(/^data:/i.test(t.src))return t.src;if("undefined"==typeof HTMLCanvasElement)return t.src;let i;if(t instanceof HTMLCanvasElement)i=t;else{void 0===Ns&&(Ns=Ki("canvas")),Ns.width=t.width,Ns.height=t.height;const e=Ns.getContext("2d");t instanceof ImageData?e.putImageData(t,0,0):e.drawImage(t,0,0,t.width,t.height),i=Ns}return i.toDataURL(e)}static sRGBToLinear(t){if("undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&t instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap){const e=Ki("canvas");e.width=t.width,e.height=t.height;const i=e.getContext("2d");i.drawImage(t,0,0,t.width,t.height);const s=i.getImageData(0,0,t.width,t.height),r=s.data;for(let t=0;t1),this.pmremVersion=0}get width(){return this.source.getSize(js).x}get height(){return this.source.getSize(js).y}get depth(){return this.source.getSize(js).z}get image(){return this.source.data}set image(t=null){this.source.data=t}updateMatrix(){this.matrix.setUvTransform(this.offset.x,this.offset.y,this.repeat.x,this.repeat.y,this.rotation,this.center.x,this.center.y)}addUpdateRange(t,e){this.updateRanges.push({start:t,count:e})}clearUpdateRanges(){this.updateRanges.length=0}clone(){return(new this.constructor).copy(this)}copy(t){return this.name=t.name,this.source=t.source,this.mipmaps=t.mipmaps.slice(0),this.mapping=t.mapping,this.channel=t.channel,this.wrapS=t.wrapS,this.wrapT=t.wrapT,this.magFilter=t.magFilter,this.minFilter=t.minFilter,this.anisotropy=t.anisotropy,this.format=t.format,this.internalFormat=t.internalFormat,this.type=t.type,this.offset.copy(t.offset),this.repeat.copy(t.repeat),this.center.copy(t.center),this.rotation=t.rotation,this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrix.copy(t.matrix),this.generateMipmaps=t.generateMipmaps,this.premultiplyAlpha=t.premultiplyAlpha,this.flipY=t.flipY,this.unpackAlignment=t.unpackAlignment,this.colorSpace=t.colorSpace,this.renderTarget=t.renderTarget,this.isRenderTargetTexture=t.isRenderTargetTexture,this.isArrayTexture=t.isArrayTexture,this.userData=JSON.parse(JSON.stringify(t.userData)),this.needsUpdate=!0,this}setValues(t){for(const e in t){const i=t[e];if(void 0===i){as(`Texture.setValues(): parameter '${e}' has value of undefined.`);continue}const s=this[e];void 0!==s?s&&i&&s.isVector2&&i.isVector2||s&&i&&s.isVector3&&i.isVector3||s&&i&&s.isMatrix3&&i.isMatrix3?s.copy(i):this[e]=i:as(`Texture.setValues(): property '${e}' does not exist.`)}}toJSON(t){const e=void 0===t||"string"==typeof t;if(!e&&void 0!==t.textures[this.uuid])return t.textures[this.uuid];const i={metadata:{version:4.7,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,name:this.name,image:this.source.toJSON(t).uuid,mapping:this.mapping,channel:this.channel,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],center:[this.center.x,this.center.y],rotation:this.rotation,wrap:[this.wrapS,this.wrapT],format:this.format,internalFormat:this.internalFormat,type:this.type,colorSpace:this.colorSpace,minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY,generateMipmaps:this.generateMipmaps,premultiplyAlpha:this.premultiplyAlpha,unpackAlignment:this.unpackAlignment};return Object.keys(this.userData).length>0&&(i.userData=this.userData),e||(t.textures[this.uuid]=i),i}dispose(){this.dispatchEvent({type:"dispose"})}transformUv(t){if(this.mapping!==ht)return t;if(t.applyMatrix3(this.matrix),t.x<0||t.x>1)switch(this.wrapS){case mt:t.x=t.x-Math.floor(t.x);break;case yt:t.x=t.x<0?0:1;break;case gt:1===Math.abs(Math.floor(t.x)%2)?t.x=Math.ceil(t.x)-t.x:t.x=t.x-Math.floor(t.x)}if(t.y<0||t.y>1)switch(this.wrapT){case mt:t.y=t.y-Math.floor(t.y);break;case yt:t.y=t.y<0?0:1;break;case gt:1===Math.abs(Math.floor(t.y)%2)?t.y=Math.ceil(t.y)-t.y:t.y=t.y-Math.floor(t.y)}return this.flipY&&(t.y=1-t.y),t}set needsUpdate(t){!0===t&&(this.version++,this.source.needsUpdate=!0)}set needsPMREMUpdate(t){!0===t&&this.pmremVersion++}}Ws.DEFAULT_IMAGE=null,Ws.DEFAULT_MAPPING=ht,Ws.DEFAULT_ANISOTROPY=1;class Us{constructor(t=0,e=0,i=0,s=1){Us.prototype.isVector4=!0,this.x=t,this.y=e,this.z=i,this.w=s}get width(){return this.z}set width(t){this.z=t}get height(){return this.w}set height(t){this.w=t}set(t,e,i,s){return this.x=t,this.y=e,this.z=i,this.w=s,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this.w=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setW(t){return this.w=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;case 3:this.w=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this.w=void 0!==t.w?t.w:1,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this.w+=t.w,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this.w+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this.w=t.w+e.w,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this.w+=t.w*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this.w-=t.w,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this.w-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this.w=t.w-e.w,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this.w*=t.w,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this.w*=t,this}applyMatrix4(t){const e=this.x,i=this.y,s=this.z,r=this.w,n=t.elements;return this.x=n[0]*e+n[4]*i+n[8]*s+n[12]*r,this.y=n[1]*e+n[5]*i+n[9]*s+n[13]*r,this.z=n[2]*e+n[6]*i+n[10]*s+n[14]*r,this.w=n[3]*e+n[7]*i+n[11]*s+n[15]*r,this}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this.w/=t.w,this}divideScalar(t){return this.multiplyScalar(1/t)}setAxisAngleFromQuaternion(t){this.w=2*Math.acos(t.w);const e=Math.sqrt(1-t.w*t.w);return e<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=t.x/e,this.y=t.y/e,this.z=t.z/e),this}setAxisAngleFromRotationMatrix(t){let e,i,s,r;const n=.01,a=.1,o=t.elements,h=o[0],l=o[4],c=o[8],u=o[1],d=o[5],p=o[9],m=o[2],y=o[6],g=o[10];if(Math.abs(l-u)o&&t>f?tf?o1);this.dispose()}this.viewport.set(0,0,t,e),this.scissor.set(0,0,t,e)}clone(){return(new this.constructor).copy(this)}copy(t){this.width=t.width,this.height=t.height,this.depth=t.depth,this.scissor.copy(t.scissor),this.scissorTest=t.scissorTest,this.viewport.copy(t.viewport),this.textures.length=0;for(let e=0,i=t.textures.length;e=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y&&t.z>=this.min.z&&t.z<=this.max.z}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y&&this.min.z<=t.min.z&&t.max.z<=this.max.z}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y),(t.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(t){return t.max.x>=this.min.x&&t.min.x<=this.max.x&&t.max.y>=this.min.y&&t.min.y<=this.max.y&&t.max.z>=this.min.z&&t.min.z<=this.max.z}intersectsSphere(t){return this.clampPoint(t.center,Qs),Qs.distanceToSquared(t.center)<=t.radius*t.radius}intersectsPlane(t){let e,i;return t.normal.x>0?(e=t.normal.x*this.min.x,i=t.normal.x*this.max.x):(e=t.normal.x*this.max.x,i=t.normal.x*this.min.x),t.normal.y>0?(e+=t.normal.y*this.min.y,i+=t.normal.y*this.max.y):(e+=t.normal.y*this.max.y,i+=t.normal.y*this.min.y),t.normal.z>0?(e+=t.normal.z*this.min.z,i+=t.normal.z*this.max.z):(e+=t.normal.z*this.max.z,i+=t.normal.z*this.min.z),e<=-t.constant&&i>=-t.constant}intersectsTriangle(t){if(this.isEmpty())return!1;this.getCenter(ar),or.subVectors(this.max,ar),tr.subVectors(t.a,ar),er.subVectors(t.b,ar),ir.subVectors(t.c,ar),sr.subVectors(er,tr),rr.subVectors(ir,er),nr.subVectors(tr,ir);let e=[0,-sr.z,sr.y,0,-rr.z,rr.y,0,-nr.z,nr.y,sr.z,0,-sr.x,rr.z,0,-rr.x,nr.z,0,-nr.x,-sr.y,sr.x,0,-rr.y,rr.x,0,-nr.y,nr.x,0];return!!cr(e,tr,er,ir,or)&&(e=[1,0,0,0,1,0,0,0,1],!!cr(e,tr,er,ir,or)&&(hr.crossVectors(sr,rr),e=[hr.x,hr.y,hr.z],cr(e,tr,er,ir,or)))}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return this.clampPoint(t,Qs).distanceTo(t)}getBoundingSphere(t){return this.isEmpty()?t.makeEmpty():(this.getCenter(t.center),t.radius=.5*this.getSize(Qs).length()),t}intersect(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}applyMatrix4(t){return this.isEmpty()||($s[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(t),$s[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(t),$s[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(t),$s[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(t),$s[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(t),$s[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(t),$s[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(t),$s[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(t),this.setFromPoints($s)),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}toJSON(){return{min:this.min.toArray(),max:this.max.toArray()}}fromJSON(t){return this.min.fromArray(t.min),this.max.fromArray(t.max),this}}const $s=[new _s,new _s,new _s,new _s,new _s,new _s,new _s,new _s],Qs=new _s,Ks=new Gs,tr=new _s,er=new _s,ir=new _s,sr=new _s,rr=new _s,nr=new _s,ar=new _s,or=new _s,hr=new _s,lr=new _s;function cr(t,e,i,s,r){for(let n=0,a=t.length-3;n<=a;n+=3){lr.fromArray(t,n);const a=r.x*Math.abs(lr.x)+r.y*Math.abs(lr.y)+r.z*Math.abs(lr.z),o=e.dot(lr),h=i.dot(lr),l=s.dot(lr);if(Math.max(-Math.max(o,h,l),Math.min(o,h,l))>a)return!1}return!0}const ur=new Gs,dr=new _s,pr=new _s;class mr{constructor(t=new _s,e=-1){this.isSphere=!0,this.center=t,this.radius=e}set(t,e){return this.center.copy(t),this.radius=e,this}setFromPoints(t,e){const i=this.center;void 0!==e?i.copy(e):ur.setFromPoints(t).getCenter(i);let s=0;for(let e=0,r=t.length;ethis.radius*this.radius&&(e.sub(this.center).normalize(),e.multiplyScalar(this.radius).add(this.center)),e}getBoundingBox(t){return this.isEmpty()?(t.makeEmpty(),t):(t.set(this.center,this.center),t.expandByScalar(this.radius),t)}applyMatrix4(t){return this.center.applyMatrix4(t),this.radius=this.radius*t.getMaxScaleOnAxis(),this}translate(t){return this.center.add(t),this}expandByPoint(t){if(this.isEmpty())return this.center.copy(t),this.radius=0,this;dr.subVectors(t,this.center);const e=dr.lengthSq();if(e>this.radius*this.radius){const t=Math.sqrt(e),i=.5*(t-this.radius);this.center.addScaledVector(dr,i/t),this.radius+=i}return this}union(t){return t.isEmpty()?this:this.isEmpty()?(this.copy(t),this):(!0===this.center.equals(t.center)?this.radius=Math.max(this.radius,t.radius):(pr.subVectors(t.center,this.center).setLength(t.radius),this.expandByPoint(dr.copy(t.center).add(pr)),this.expandByPoint(dr.copy(t.center).sub(pr))),this)}equals(t){return t.center.equals(this.center)&&t.radius===this.radius}clone(){return(new this.constructor).copy(this)}toJSON(){return{radius:this.radius,center:this.center.toArray()}}fromJSON(t){return this.radius=t.radius,this.center.fromArray(t.center),this}}const yr=new _s,gr=new _s,fr=new _s,xr=new _s,br=new _s,vr=new _s,wr=new _s;class Mr{constructor(t=new _s,e=new _s(0,0,-1)){this.origin=t,this.direction=e}set(t,e){return this.origin.copy(t),this.direction.copy(e),this}copy(t){return this.origin.copy(t.origin),this.direction.copy(t.direction),this}at(t,e){return e.copy(this.origin).addScaledVector(this.direction,t)}lookAt(t){return this.direction.copy(t).sub(this.origin).normalize(),this}recast(t){return this.origin.copy(this.at(t,yr)),this}closestPointToPoint(t,e){e.subVectors(t,this.origin);const i=e.dot(this.direction);return i<0?e.copy(this.origin):e.copy(this.origin).addScaledVector(this.direction,i)}distanceToPoint(t){return Math.sqrt(this.distanceSqToPoint(t))}distanceSqToPoint(t){const e=yr.subVectors(t,this.origin).dot(this.direction);return e<0?this.origin.distanceToSquared(t):(yr.copy(this.origin).addScaledVector(this.direction,e),yr.distanceToSquared(t))}distanceSqToSegment(t,e,i,s){gr.copy(t).add(e).multiplyScalar(.5),fr.copy(e).sub(t).normalize(),xr.copy(this.origin).sub(gr);const r=.5*t.distanceTo(e),n=-this.direction.dot(fr),a=xr.dot(this.direction),o=-xr.dot(fr),h=xr.lengthSq(),l=Math.abs(1-n*n);let c,u,d,p;if(l>0)if(c=n*o-a,u=n*a-o,p=r*l,c>=0)if(u>=-p)if(u<=p){const t=1/l;c*=t,u*=t,d=c*(c+n*u+2*a)+u*(n*c+u+2*o)+h}else u=r,c=Math.max(0,-(n*u+a)),d=-c*c+u*(u+2*o)+h;else u=-r,c=Math.max(0,-(n*u+a)),d=-c*c+u*(u+2*o)+h;else u<=-p?(c=Math.max(0,-(-n*r+a)),u=c>0?-r:Math.min(Math.max(-r,-o),r),d=-c*c+u*(u+2*o)+h):u<=p?(c=0,u=Math.min(Math.max(-r,-o),r),d=u*(u+2*o)+h):(c=Math.max(0,-(n*r+a)),u=c>0?r:Math.min(Math.max(-r,-o),r),d=-c*c+u*(u+2*o)+h);else u=n>0?-r:r,c=Math.max(0,-(n*u+a)),d=-c*c+u*(u+2*o)+h;return i&&i.copy(this.origin).addScaledVector(this.direction,c),s&&s.copy(gr).addScaledVector(fr,u),d}intersectSphere(t,e){yr.subVectors(t.center,this.origin);const i=yr.dot(this.direction),s=yr.dot(yr)-i*i,r=t.radius*t.radius;if(s>r)return null;const n=Math.sqrt(r-s),a=i-n,o=i+n;return o<0?null:a<0?this.at(o,e):this.at(a,e)}intersectsSphere(t){return!(t.radius<0)&&this.distanceSqToPoint(t.center)<=t.radius*t.radius}distanceToPlane(t){const e=t.normal.dot(this.direction);if(0===e)return 0===t.distanceToPoint(this.origin)?0:null;const i=-(this.origin.dot(t.normal)+t.constant)/e;return i>=0?i:null}intersectPlane(t,e){const i=this.distanceToPlane(t);return null===i?null:this.at(i,e)}intersectsPlane(t){const e=t.distanceToPoint(this.origin);if(0===e)return!0;return t.normal.dot(this.direction)*e<0}intersectBox(t,e){let i,s,r,n,a,o;const h=1/this.direction.x,l=1/this.direction.y,c=1/this.direction.z,u=this.origin;return h>=0?(i=(t.min.x-u.x)*h,s=(t.max.x-u.x)*h):(i=(t.max.x-u.x)*h,s=(t.min.x-u.x)*h),l>=0?(r=(t.min.y-u.y)*l,n=(t.max.y-u.y)*l):(r=(t.max.y-u.y)*l,n=(t.min.y-u.y)*l),i>n||r>s?null:((r>i||isNaN(i))&&(i=r),(n=0?(a=(t.min.z-u.z)*c,o=(t.max.z-u.z)*c):(a=(t.max.z-u.z)*c,o=(t.min.z-u.z)*c),i>o||a>s?null:((a>i||i!=i)&&(i=a),(o=0?i:s,e)))}intersectsBox(t){return null!==this.intersectBox(t,yr)}intersectTriangle(t,e,i,s,r){br.subVectors(e,t),vr.subVectors(i,t),wr.crossVectors(br,vr);let n,a=this.direction.dot(wr);if(a>0){if(s)return null;n=1}else{if(!(a<0))return null;n=-1,a=-a}xr.subVectors(this.origin,t);const o=n*this.direction.dot(vr.crossVectors(xr,vr));if(o<0)return null;const h=n*this.direction.dot(br.cross(xr));if(h<0)return null;if(o+h>a)return null;const l=-n*xr.dot(wr);return l<0?null:this.at(l/a,r)}applyMatrix4(t){return this.origin.applyMatrix4(t),this.direction.transformDirection(t),this}equals(t){return t.origin.equals(this.origin)&&t.direction.equals(this.direction)}clone(){return(new this.constructor).copy(this)}}class Sr{constructor(t,e,i,s,r,n,a,o,h,l,c,u,d,p,m,y){Sr.prototype.isMatrix4=!0,this.elements=[1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1],void 0!==t&&this.set(t,e,i,s,r,n,a,o,h,l,c,u,d,p,m,y)}set(t,e,i,s,r,n,a,o,h,l,c,u,d,p,m,y){const g=this.elements;return g[0]=t,g[4]=e,g[8]=i,g[12]=s,g[1]=r,g[5]=n,g[9]=a,g[13]=o,g[2]=h,g[6]=l,g[10]=c,g[14]=u,g[3]=d,g[7]=p,g[11]=m,g[15]=y,this}identity(){return this.set(1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1),this}clone(){return(new Sr).fromArray(this.elements)}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],e[9]=i[9],e[10]=i[10],e[11]=i[11],e[12]=i[12],e[13]=i[13],e[14]=i[14],e[15]=i[15],this}copyPosition(t){const e=this.elements,i=t.elements;return e[12]=i[12],e[13]=i[13],e[14]=i[14],this}setFromMatrix3(t){const e=t.elements;return this.set(e[0],e[3],e[6],0,e[1],e[4],e[7],0,e[2],e[5],e[8],0,0,0,0,1),this}extractBasis(t,e,i){return 0===this.determinant()?(t.set(1,0,0),e.set(0,1,0),i.set(0,0,1),this):(t.setFromMatrixColumn(this,0),e.setFromMatrixColumn(this,1),i.setFromMatrixColumn(this,2),this)}makeBasis(t,e,i){return this.set(t.x,e.x,i.x,0,t.y,e.y,i.y,0,t.z,e.z,i.z,0,0,0,0,1),this}extractRotation(t){if(0===t.determinant())return this.identity();const e=this.elements,i=t.elements,s=1/_r.setFromMatrixColumn(t,0).length(),r=1/_r.setFromMatrixColumn(t,1).length(),n=1/_r.setFromMatrixColumn(t,2).length();return e[0]=i[0]*s,e[1]=i[1]*s,e[2]=i[2]*s,e[3]=0,e[4]=i[4]*r,e[5]=i[5]*r,e[6]=i[6]*r,e[7]=0,e[8]=i[8]*n,e[9]=i[9]*n,e[10]=i[10]*n,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromEuler(t){const e=this.elements,i=t.x,s=t.y,r=t.z,n=Math.cos(i),a=Math.sin(i),o=Math.cos(s),h=Math.sin(s),l=Math.cos(r),c=Math.sin(r);if("XYZ"===t.order){const t=n*l,i=n*c,s=a*l,r=a*c;e[0]=o*l,e[4]=-o*c,e[8]=h,e[1]=i+s*h,e[5]=t-r*h,e[9]=-a*o,e[2]=r-t*h,e[6]=s+i*h,e[10]=n*o}else if("YXZ"===t.order){const t=o*l,i=o*c,s=h*l,r=h*c;e[0]=t+r*a,e[4]=s*a-i,e[8]=n*h,e[1]=n*c,e[5]=n*l,e[9]=-a,e[2]=i*a-s,e[6]=r+t*a,e[10]=n*o}else if("ZXY"===t.order){const t=o*l,i=o*c,s=h*l,r=h*c;e[0]=t-r*a,e[4]=-n*c,e[8]=s+i*a,e[1]=i+s*a,e[5]=n*l,e[9]=r-t*a,e[2]=-n*h,e[6]=a,e[10]=n*o}else if("ZYX"===t.order){const t=n*l,i=n*c,s=a*l,r=a*c;e[0]=o*l,e[4]=s*h-i,e[8]=t*h+r,e[1]=o*c,e[5]=r*h+t,e[9]=i*h-s,e[2]=-h,e[6]=a*o,e[10]=n*o}else if("YZX"===t.order){const t=n*o,i=n*h,s=a*o,r=a*h;e[0]=o*l,e[4]=r-t*c,e[8]=s*c+i,e[1]=c,e[5]=n*l,e[9]=-a*l,e[2]=-h*l,e[6]=i*c+s,e[10]=t-r*c}else if("XZY"===t.order){const t=n*o,i=n*h,s=a*o,r=a*h;e[0]=o*l,e[4]=-c,e[8]=h*l,e[1]=t*c+r,e[5]=n*l,e[9]=i*c-s,e[2]=s*c-i,e[6]=a*l,e[10]=r*c+t}return e[3]=0,e[7]=0,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,this}makeRotationFromQuaternion(t){return this.compose(Tr,t,zr)}lookAt(t,e,i){const s=this.elements;return Br.subVectors(t,e),0===Br.lengthSq()&&(Br.z=1),Br.normalize(),Cr.crossVectors(i,Br),0===Cr.lengthSq()&&(1===Math.abs(i.z)?Br.x+=1e-4:Br.z+=1e-4,Br.normalize(),Cr.crossVectors(i,Br)),Cr.normalize(),Ir.crossVectors(Br,Cr),s[0]=Cr.x,s[4]=Ir.x,s[8]=Br.x,s[1]=Cr.y,s[5]=Ir.y,s[9]=Br.y,s[2]=Cr.z,s[6]=Ir.z,s[10]=Br.z,this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,s=e.elements,r=this.elements,n=i[0],a=i[4],o=i[8],h=i[12],l=i[1],c=i[5],u=i[9],d=i[13],p=i[2],m=i[6],y=i[10],g=i[14],f=i[3],x=i[7],b=i[11],v=i[15],w=s[0],M=s[4],S=s[8],_=s[12],A=s[1],T=s[5],z=s[9],C=s[13],I=s[2],B=s[6],k=s[10],O=s[14],P=s[3],R=s[7],N=s[11],V=s[15];return r[0]=n*w+a*A+o*I+h*P,r[4]=n*M+a*T+o*B+h*R,r[8]=n*S+a*z+o*k+h*N,r[12]=n*_+a*C+o*O+h*V,r[1]=l*w+c*A+u*I+d*P,r[5]=l*M+c*T+u*B+d*R,r[9]=l*S+c*z+u*k+d*N,r[13]=l*_+c*C+u*O+d*V,r[2]=p*w+m*A+y*I+g*P,r[6]=p*M+m*T+y*B+g*R,r[10]=p*S+m*z+y*k+g*N,r[14]=p*_+m*C+y*O+g*V,r[3]=f*w+x*A+b*I+v*P,r[7]=f*M+x*T+b*B+v*R,r[11]=f*S+x*z+b*k+v*N,r[15]=f*_+x*C+b*O+v*V,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[4]*=t,e[8]*=t,e[12]*=t,e[1]*=t,e[5]*=t,e[9]*=t,e[13]*=t,e[2]*=t,e[6]*=t,e[10]*=t,e[14]*=t,e[3]*=t,e[7]*=t,e[11]*=t,e[15]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[4],s=t[8],r=t[12],n=t[1],a=t[5],o=t[9],h=t[13],l=t[2],c=t[6],u=t[10],d=t[14],p=t[3],m=t[7],y=t[11],g=t[15],f=o*d-h*u,x=a*d-h*c,b=a*u-o*c,v=n*d-h*l,w=n*u-o*l,M=n*c-a*l;return e*(m*f-y*x+g*b)-i*(p*f-y*v+g*w)+s*(p*x-m*v+g*M)-r*(p*b-m*w+y*M)}transpose(){const t=this.elements;let e;return e=t[1],t[1]=t[4],t[4]=e,e=t[2],t[2]=t[8],t[8]=e,e=t[6],t[6]=t[9],t[9]=e,e=t[3],t[3]=t[12],t[12]=e,e=t[7],t[7]=t[13],t[13]=e,e=t[11],t[11]=t[14],t[14]=e,this}setPosition(t,e,i){const s=this.elements;return t.isVector3?(s[12]=t.x,s[13]=t.y,s[14]=t.z):(s[12]=t,s[13]=e,s[14]=i),this}invert(){const t=this.elements,e=t[0],i=t[1],s=t[2],r=t[3],n=t[4],a=t[5],o=t[6],h=t[7],l=t[8],c=t[9],u=t[10],d=t[11],p=t[12],m=t[13],y=t[14],g=t[15],f=e*a-i*n,x=e*o-s*n,b=e*h-r*n,v=i*o-s*a,w=i*h-r*a,M=s*h-r*o,S=l*m-c*p,_=l*y-u*p,A=l*g-d*p,T=c*y-u*m,z=c*g-d*m,C=u*g-d*y,I=f*C-x*z+b*T+v*A-w*_+M*S;if(0===I)return this.set(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);const B=1/I;return t[0]=(a*C-o*z+h*T)*B,t[1]=(s*z-i*C-r*T)*B,t[2]=(m*M-y*w+g*v)*B,t[3]=(u*w-c*M-d*v)*B,t[4]=(o*A-n*C-h*_)*B,t[5]=(e*C-s*A+r*_)*B,t[6]=(y*b-p*M-g*x)*B,t[7]=(l*M-u*b+d*x)*B,t[8]=(n*z-a*A+h*S)*B,t[9]=(i*A-e*z-r*S)*B,t[10]=(p*w-m*b+g*f)*B,t[11]=(c*b-l*w-d*f)*B,t[12]=(a*_-n*T-o*S)*B,t[13]=(e*T-i*_+s*S)*B,t[14]=(m*x-p*v-y*f)*B,t[15]=(l*v-c*x+u*f)*B,this}scale(t){const e=this.elements,i=t.x,s=t.y,r=t.z;return e[0]*=i,e[4]*=s,e[8]*=r,e[1]*=i,e[5]*=s,e[9]*=r,e[2]*=i,e[6]*=s,e[10]*=r,e[3]*=i,e[7]*=s,e[11]*=r,this}getMaxScaleOnAxis(){const t=this.elements,e=t[0]*t[0]+t[1]*t[1]+t[2]*t[2],i=t[4]*t[4]+t[5]*t[5]+t[6]*t[6],s=t[8]*t[8]+t[9]*t[9]+t[10]*t[10];return Math.sqrt(Math.max(e,i,s))}makeTranslation(t,e,i){return t.isVector3?this.set(1,0,0,t.x,0,1,0,t.y,0,0,1,t.z,0,0,0,1):this.set(1,0,0,t,0,1,0,e,0,0,1,i,0,0,0,1),this}makeRotationX(t){const e=Math.cos(t),i=Math.sin(t);return this.set(1,0,0,0,0,e,-i,0,0,i,e,0,0,0,0,1),this}makeRotationY(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,0,i,0,0,1,0,0,-i,0,e,0,0,0,0,1),this}makeRotationZ(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,-i,0,0,i,e,0,0,0,0,1,0,0,0,0,1),this}makeRotationAxis(t,e){const i=Math.cos(e),s=Math.sin(e),r=1-i,n=t.x,a=t.y,o=t.z,h=r*n,l=r*a;return this.set(h*n+i,h*a-s*o,h*o+s*a,0,h*a+s*o,l*a+i,l*o-s*n,0,h*o-s*a,l*o+s*n,r*o*o+i,0,0,0,0,1),this}makeScale(t,e,i){return this.set(t,0,0,0,0,e,0,0,0,0,i,0,0,0,0,1),this}makeShear(t,e,i,s,r,n){return this.set(1,i,r,0,t,1,n,0,e,s,1,0,0,0,0,1),this}compose(t,e,i){const s=this.elements,r=e._x,n=e._y,a=e._z,o=e._w,h=r+r,l=n+n,c=a+a,u=r*h,d=r*l,p=r*c,m=n*l,y=n*c,g=a*c,f=o*h,x=o*l,b=o*c,v=i.x,w=i.y,M=i.z;return s[0]=(1-(m+g))*v,s[1]=(d+b)*v,s[2]=(p-x)*v,s[3]=0,s[4]=(d-b)*w,s[5]=(1-(u+g))*w,s[6]=(y+f)*w,s[7]=0,s[8]=(p+x)*M,s[9]=(y-f)*M,s[10]=(1-(u+m))*M,s[11]=0,s[12]=t.x,s[13]=t.y,s[14]=t.z,s[15]=1,this}decompose(t,e,i){const s=this.elements;t.x=s[12],t.y=s[13],t.z=s[14];const r=this.determinant();if(0===r)return i.set(1,1,1),e.identity(),this;let n=_r.set(s[0],s[1],s[2]).length();const a=_r.set(s[4],s[5],s[6]).length(),o=_r.set(s[8],s[9],s[10]).length();r<0&&(n=-n),Ar.copy(this);const h=1/n,l=1/a,c=1/o;return Ar.elements[0]*=h,Ar.elements[1]*=h,Ar.elements[2]*=h,Ar.elements[4]*=l,Ar.elements[5]*=l,Ar.elements[6]*=l,Ar.elements[8]*=c,Ar.elements[9]*=c,Ar.elements[10]*=c,e.setFromRotationMatrix(Ar),i.x=n,i.y=a,i.z=o,this}makePerspective(t,e,i,s,r,n,a=2e3,o=!1){const h=this.elements,l=2*r/(e-t),c=2*r/(i-s),u=(e+t)/(e-t),d=(i+s)/(i-s);let p,m;if(o)p=r/(n-r),m=n*r/(n-r);else if(a===Ui)p=-(n+r)/(n-r),m=-2*n*r/(n-r);else{if(a!==qi)throw new Error("THREE.Matrix4.makePerspective(): Invalid coordinate system: "+a);p=-n/(n-r),m=-n*r/(n-r)}return h[0]=l,h[4]=0,h[8]=u,h[12]=0,h[1]=0,h[5]=c,h[9]=d,h[13]=0,h[2]=0,h[6]=0,h[10]=p,h[14]=m,h[3]=0,h[7]=0,h[11]=-1,h[15]=0,this}makeOrthographic(t,e,i,s,r,n,a=2e3,o=!1){const h=this.elements,l=2/(e-t),c=2/(i-s),u=-(e+t)/(e-t),d=-(i+s)/(i-s);let p,m;if(o)p=1/(n-r),m=n/(n-r);else if(a===Ui)p=-2/(n-r),m=-(n+r)/(n-r);else{if(a!==qi)throw new Error("THREE.Matrix4.makeOrthographic(): Invalid coordinate system: "+a);p=-1/(n-r),m=-r/(n-r)}return h[0]=l,h[4]=0,h[8]=0,h[12]=u,h[1]=0,h[5]=c,h[9]=0,h[13]=d,h[2]=0,h[6]=0,h[10]=p,h[14]=m,h[3]=0,h[7]=0,h[11]=0,h[15]=1,this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<16;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<16;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t[e+9]=i[9],t[e+10]=i[10],t[e+11]=i[11],t[e+12]=i[12],t[e+13]=i[13],t[e+14]=i[14],t[e+15]=i[15],t}}const _r=new _s,Ar=new Sr,Tr=new _s(0,0,0),zr=new _s(1,1,1),Cr=new _s,Ir=new _s,Br=new _s,kr=new Sr,Or=new Ss;class Pr{constructor(t=0,e=0,i=0,s=Pr.DEFAULT_ORDER){this.isEuler=!0,this._x=t,this._y=e,this._z=i,this._order=s}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get order(){return this._order}set order(t){this._order=t,this._onChangeCallback()}set(t,e,i,s=this._order){return this._x=t,this._y=e,this._z=i,this._order=s,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._order)}copy(t){return this._x=t._x,this._y=t._y,this._z=t._z,this._order=t._order,this._onChangeCallback(),this}setFromRotationMatrix(t,e=this._order,i=!0){const s=t.elements,r=s[0],n=s[4],a=s[8],o=s[1],h=s[5],l=s[9],c=s[2],u=s[6],d=s[10];switch(e){case"XYZ":this._y=Math.asin(gs(a,-1,1)),Math.abs(a)<.9999999?(this._x=Math.atan2(-l,d),this._z=Math.atan2(-n,r)):(this._x=Math.atan2(u,h),this._z=0);break;case"YXZ":this._x=Math.asin(-gs(l,-1,1)),Math.abs(l)<.9999999?(this._y=Math.atan2(a,d),this._z=Math.atan2(o,h)):(this._y=Math.atan2(-c,r),this._z=0);break;case"ZXY":this._x=Math.asin(gs(u,-1,1)),Math.abs(u)<.9999999?(this._y=Math.atan2(-c,d),this._z=Math.atan2(-n,h)):(this._y=0,this._z=Math.atan2(o,r));break;case"ZYX":this._y=Math.asin(-gs(c,-1,1)),Math.abs(c)<.9999999?(this._x=Math.atan2(u,d),this._z=Math.atan2(o,r)):(this._x=0,this._z=Math.atan2(-n,h));break;case"YZX":this._z=Math.asin(gs(o,-1,1)),Math.abs(o)<.9999999?(this._x=Math.atan2(-l,h),this._y=Math.atan2(-c,r)):(this._x=0,this._y=Math.atan2(a,d));break;case"XZY":this._z=Math.asin(-gs(n,-1,1)),Math.abs(n)<.9999999?(this._x=Math.atan2(u,h),this._y=Math.atan2(a,r)):(this._x=Math.atan2(-l,d),this._y=0);break;default:as("Euler: .setFromRotationMatrix() encountered an unknown order: "+e)}return this._order=e,!0===i&&this._onChangeCallback(),this}setFromQuaternion(t,e,i){return kr.makeRotationFromQuaternion(t),this.setFromRotationMatrix(kr,e,i)}setFromVector3(t,e=this._order){return this.set(t.x,t.y,t.z,e)}reorder(t){return Or.setFromEuler(this),this.setFromQuaternion(Or,t)}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._order===this._order}fromArray(t){return this._x=t[0],this._y=t[1],this._z=t[2],void 0!==t[3]&&(this._order=t[3]),this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._order,t}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._order}}Pr.DEFAULT_ORDER="XYZ";class Rr{constructor(){this.mask=1}set(t){this.mask=1<>>0}enable(t){this.mask|=1<1){for(let t=0;t1){for(let t=0;t0&&(s.userData=this.userData),s.layers=this.layers.mask,s.matrix=this.matrix.toArray(),s.up=this.up.toArray(),null!==this.pivot&&(s.pivot=this.pivot.toArray()),!1===this.matrixAutoUpdate&&(s.matrixAutoUpdate=!1),void 0!==this.morphTargetDictionary&&(s.morphTargetDictionary=Object.assign({},this.morphTargetDictionary)),void 0!==this.morphTargetInfluences&&(s.morphTargetInfluences=this.morphTargetInfluences.slice()),this.isInstancedMesh&&(s.type="InstancedMesh",s.count=this.count,s.instanceMatrix=this.instanceMatrix.toJSON(),null!==this.instanceColor&&(s.instanceColor=this.instanceColor.toJSON())),this.isBatchedMesh&&(s.type="BatchedMesh",s.perObjectFrustumCulled=this.perObjectFrustumCulled,s.sortObjects=this.sortObjects,s.drawRanges=this._drawRanges,s.reservedRanges=this._reservedRanges,s.geometryInfo=this._geometryInfo.map(t=>({...t,boundingBox:t.boundingBox?t.boundingBox.toJSON():void 0,boundingSphere:t.boundingSphere?t.boundingSphere.toJSON():void 0})),s.instanceInfo=this._instanceInfo.map(t=>({...t})),s.availableInstanceIds=this._availableInstanceIds.slice(),s.availableGeometryIds=this._availableGeometryIds.slice(),s.nextIndexStart=this._nextIndexStart,s.nextVertexStart=this._nextVertexStart,s.geometryCount=this._geometryCount,s.maxInstanceCount=this._maxInstanceCount,s.maxVertexCount=this._maxVertexCount,s.maxIndexCount=this._maxIndexCount,s.geometryInitialized=this._geometryInitialized,s.matricesTexture=this._matricesTexture.toJSON(t),s.indirectTexture=this._indirectTexture.toJSON(t),null!==this._colorsTexture&&(s.colorsTexture=this._colorsTexture.toJSON(t)),null!==this.boundingSphere&&(s.boundingSphere=this.boundingSphere.toJSON()),null!==this.boundingBox&&(s.boundingBox=this.boundingBox.toJSON())),this.isScene)this.background&&(this.background.isColor?s.background=this.background.toJSON():this.background.isTexture&&(s.background=this.background.toJSON(t).uuid)),this.environment&&this.environment.isTexture&&!0!==this.environment.isRenderTargetTexture&&(s.environment=this.environment.toJSON(t).uuid);else if(this.isMesh||this.isLine||this.isPoints){s.geometry=r(t.geometries,this.geometry);const e=this.geometry.parameters;if(void 0!==e&&void 0!==e.shapes){const i=e.shapes;if(Array.isArray(i))for(let e=0,s=i.length;e0){s.children=[];for(let e=0;e0){s.animations=[];for(let e=0;e0&&(i.geometries=e),s.length>0&&(i.materials=s),r.length>0&&(i.textures=r),a.length>0&&(i.images=a),o.length>0&&(i.shapes=o),h.length>0&&(i.skeletons=h),l.length>0&&(i.animations=l),c.length>0&&(i.nodes=c)}return i.object=s,i;function n(t){const e=[];for(const i in t){const s=t[i];delete s.metadata,e.push(s)}return e}}clone(t){return(new this.constructor).copy(this,t)}copy(t,e=!0){if(this.name=t.name,this.up.copy(t.up),this.position.copy(t.position),this.rotation.order=t.rotation.order,this.quaternion.copy(t.quaternion),this.scale.copy(t.scale),null!==t.pivot&&(this.pivot=t.pivot.clone()),this.matrix.copy(t.matrix),this.matrixWorld.copy(t.matrixWorld),this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrixWorldAutoUpdate=t.matrixWorldAutoUpdate,this.matrixWorldNeedsUpdate=t.matrixWorldNeedsUpdate,this.layers.mask=t.layers.mask,this.visible=t.visible,this.castShadow=t.castShadow,this.receiveShadow=t.receiveShadow,this.frustumCulled=t.frustumCulled,this.renderOrder=t.renderOrder,this.static=t.static,this.animations=t.animations.slice(),this.userData=JSON.parse(JSON.stringify(t.userData)),!0===e)for(let e=0;e0?s.multiplyScalar(1/Math.sqrt(r)):s.set(0,0,0)}static getBarycoord(t,e,i,s,r){$r.subVectors(s,e),Qr.subVectors(i,e),Kr.subVectors(t,e);const n=$r.dot($r),a=$r.dot(Qr),o=$r.dot(Kr),h=Qr.dot(Qr),l=Qr.dot(Kr),c=n*h-a*a;if(0===c)return r.set(0,0,0),null;const u=1/c,d=(h*o-a*l)*u,p=(n*l-a*o)*u;return r.set(1-d-p,p,d)}static containsPoint(t,e,i,s){return null!==this.getBarycoord(t,e,i,s,tn)&&(tn.x>=0&&tn.y>=0&&tn.x+tn.y<=1)}static getInterpolation(t,e,i,s,r,n,a,o){return null===this.getBarycoord(t,e,i,s,tn)?(o.x=0,o.y=0,"z"in o&&(o.z=0),"w"in o&&(o.w=0),null):(o.setScalar(0),o.addScaledVector(r,tn.x),o.addScaledVector(n,tn.y),o.addScaledVector(a,tn.z),o)}static getInterpolatedAttribute(t,e,i,s,r,n){return hn.setScalar(0),ln.setScalar(0),cn.setScalar(0),hn.fromBufferAttribute(t,e),ln.fromBufferAttribute(t,i),cn.fromBufferAttribute(t,s),n.setScalar(0),n.addScaledVector(hn,r.x),n.addScaledVector(ln,r.y),n.addScaledVector(cn,r.z),n}static isFrontFacing(t,e,i,s){return $r.subVectors(i,e),Qr.subVectors(t,e),$r.cross(Qr).dot(s)<0}set(t,e,i){return this.a.copy(t),this.b.copy(e),this.c.copy(i),this}setFromPointsAndIndices(t,e,i,s){return this.a.copy(t[e]),this.b.copy(t[i]),this.c.copy(t[s]),this}setFromAttributeAndIndices(t,e,i,s){return this.a.fromBufferAttribute(t,e),this.b.fromBufferAttribute(t,i),this.c.fromBufferAttribute(t,s),this}clone(){return(new this.constructor).copy(this)}copy(t){return this.a.copy(t.a),this.b.copy(t.b),this.c.copy(t.c),this}getArea(){return $r.subVectors(this.c,this.b),Qr.subVectors(this.a,this.b),.5*$r.cross(Qr).length()}getMidpoint(t){return t.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(t){return un.getNormal(this.a,this.b,this.c,t)}getPlane(t){return t.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(t,e){return un.getBarycoord(t,this.a,this.b,this.c,e)}getInterpolation(t,e,i,s,r){return un.getInterpolation(t,this.a,this.b,this.c,e,i,s,r)}containsPoint(t){return un.containsPoint(t,this.a,this.b,this.c)}isFrontFacing(t){return un.isFrontFacing(this.a,this.b,this.c,t)}intersectsBox(t){return t.intersectsTriangle(this)}closestPointToPoint(t,e){const i=this.a,s=this.b,r=this.c;let n,a;en.subVectors(s,i),sn.subVectors(r,i),nn.subVectors(t,i);const o=en.dot(nn),h=sn.dot(nn);if(o<=0&&h<=0)return e.copy(i);an.subVectors(t,s);const l=en.dot(an),c=sn.dot(an);if(l>=0&&c<=l)return e.copy(s);const u=o*c-l*h;if(u<=0&&o>=0&&l<=0)return n=o/(o-l),e.copy(i).addScaledVector(en,n);on.subVectors(t,r);const d=en.dot(on),p=sn.dot(on);if(p>=0&&d<=p)return e.copy(r);const m=d*h-o*p;if(m<=0&&h>=0&&p<=0)return a=h/(h-p),e.copy(i).addScaledVector(sn,a);const y=l*p-d*c;if(y<=0&&c-l>=0&&d-p>=0)return rn.subVectors(r,s),a=(c-l)/(c-l+(d-p)),e.copy(s).addScaledVector(rn,a);const g=1/(y+m+u);return n=m*g,a=u*g,e.copy(i).addScaledVector(en,n).addScaledVector(sn,a)}equals(t){return t.a.equals(this.a)&&t.b.equals(this.b)&&t.c.equals(this.c)}}const dn={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},pn={h:0,s:0,l:0},mn={h:0,s:0,l:0};function yn(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+6*(e-t)*(2/3-i):t}class gn{constructor(t,e,i){return this.isColor=!0,this.r=1,this.g=1,this.b=1,this.set(t,e,i)}set(t,e,i){if(void 0===e&&void 0===i){const e=t;e&&e.isColor?this.copy(e):"number"==typeof e?this.setHex(e):"string"==typeof e&&this.setStyle(e)}else this.setRGB(t,e,i);return this}setScalar(t){return this.r=t,this.g=t,this.b=t,this}setHex(t,e=ei){return t=Math.floor(t),this.r=(t>>16&255)/255,this.g=(t>>8&255)/255,this.b=(255&t)/255,Os.colorSpaceToWorking(this,e),this}setRGB(t,e,i,s=Os.workingColorSpace){return this.r=t,this.g=e,this.b=i,Os.colorSpaceToWorking(this,s),this}setHSL(t,e,i,s=Os.workingColorSpace){if(t=fs(t,1),e=gs(e,0,1),i=gs(i,0,1),0===e)this.r=this.g=this.b=i;else{const s=i<=.5?i*(1+e):i+e-i*e,r=2*i-s;this.r=yn(r,s,t+1/3),this.g=yn(r,s,t),this.b=yn(r,s,t-1/3)}return Os.colorSpaceToWorking(this,s),this}setStyle(t,e=ei){function i(e){void 0!==e&&parseFloat(e)<1&&as("Color: Alpha component of "+t+" will be ignored.")}let s;if(s=/^(\w+)\(([^\)]*)\)/.exec(t)){let r;const n=s[1],a=s[2];switch(n){case"rgb":case"rgba":if(r=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return i(r[4]),this.setRGB(Math.min(255,parseInt(r[1],10))/255,Math.min(255,parseInt(r[2],10))/255,Math.min(255,parseInt(r[3],10))/255,e);if(r=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return i(r[4]),this.setRGB(Math.min(100,parseInt(r[1],10))/100,Math.min(100,parseInt(r[2],10))/100,Math.min(100,parseInt(r[3],10))/100,e);break;case"hsl":case"hsla":if(r=/^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return i(r[4]),this.setHSL(parseFloat(r[1])/360,parseFloat(r[2])/100,parseFloat(r[3])/100,e);break;default:as("Color: Unknown color model "+t)}}else if(s=/^\#([A-Fa-f\d]+)$/.exec(t)){const i=s[1],r=i.length;if(3===r)return this.setRGB(parseInt(i.charAt(0),16)/15,parseInt(i.charAt(1),16)/15,parseInt(i.charAt(2),16)/15,e);if(6===r)return this.setHex(parseInt(i,16),e);as("Color: Invalid hex color "+t)}else if(t&&t.length>0)return this.setColorName(t,e);return this}setColorName(t,e=ei){const i=dn[t.toLowerCase()];return void 0!==i?this.setHex(i,e):as("Color: Unknown color "+t),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(t){return this.r=t.r,this.g=t.g,this.b=t.b,this}copySRGBToLinear(t){return this.r=Ps(t.r),this.g=Ps(t.g),this.b=Ps(t.b),this}copyLinearToSRGB(t){return this.r=Rs(t.r),this.g=Rs(t.g),this.b=Rs(t.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(t=ei){return Os.workingToColorSpace(fn.copy(this),t),65536*Math.round(gs(255*fn.r,0,255))+256*Math.round(gs(255*fn.g,0,255))+Math.round(gs(255*fn.b,0,255))}getHexString(t=ei){return("000000"+this.getHex(t).toString(16)).slice(-6)}getHSL(t,e=Os.workingColorSpace){Os.workingToColorSpace(fn.copy(this),e);const i=fn.r,s=fn.g,r=fn.b,n=Math.max(i,s,r),a=Math.min(i,s,r);let o,h;const l=(a+n)/2;if(a===n)o=0,h=0;else{const t=n-a;switch(h=l<=.5?t/(n+a):t/(2-n-a),n){case i:o=(s-r)/t+(s0!=t>0&&this.version++,this._alphaTest=t}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(t){if(void 0!==t)for(const e in t){const i=t[e];if(void 0===i){as(`Material: parameter '${e}' has value of undefined.`);continue}const s=this[e];void 0!==s?s&&s.isColor?s.set(i):s&&s.isVector3&&i&&i.isVector3?s.copy(i):this[e]=i:as(`Material: '${e}' is not a property of THREE.${this.type}.`)}}toJSON(t){const e=void 0===t||"string"==typeof t;e&&(t={textures:{},images:{}});const i={metadata:{version:4.7,type:"Material",generator:"Material.toJSON"}};function s(t){const e=[];for(const i in t){const s=t[i];delete s.metadata,e.push(s)}return e}if(i.uuid=this.uuid,i.type=this.type,""!==this.name&&(i.name=this.name),this.color&&this.color.isColor&&(i.color=this.color.getHex()),void 0!==this.roughness&&(i.roughness=this.roughness),void 0!==this.metalness&&(i.metalness=this.metalness),void 0!==this.sheen&&(i.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(i.sheenColor=this.sheenColor.getHex()),void 0!==this.sheenRoughness&&(i.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(i.emissive=this.emissive.getHex()),void 0!==this.emissiveIntensity&&1!==this.emissiveIntensity&&(i.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(i.specular=this.specular.getHex()),void 0!==this.specularIntensity&&(i.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(i.specularColor=this.specularColor.getHex()),void 0!==this.shininess&&(i.shininess=this.shininess),void 0!==this.clearcoat&&(i.clearcoat=this.clearcoat),void 0!==this.clearcoatRoughness&&(i.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(i.clearcoatMap=this.clearcoatMap.toJSON(t).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(i.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(t).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(i.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(t).uuid,i.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),this.sheenColorMap&&this.sheenColorMap.isTexture&&(i.sheenColorMap=this.sheenColorMap.toJSON(t).uuid),this.sheenRoughnessMap&&this.sheenRoughnessMap.isTexture&&(i.sheenRoughnessMap=this.sheenRoughnessMap.toJSON(t).uuid),void 0!==this.dispersion&&(i.dispersion=this.dispersion),void 0!==this.iridescence&&(i.iridescence=this.iridescence),void 0!==this.iridescenceIOR&&(i.iridescenceIOR=this.iridescenceIOR),void 0!==this.iridescenceThicknessRange&&(i.iridescenceThicknessRange=this.iridescenceThicknessRange),this.iridescenceMap&&this.iridescenceMap.isTexture&&(i.iridescenceMap=this.iridescenceMap.toJSON(t).uuid),this.iridescenceThicknessMap&&this.iridescenceThicknessMap.isTexture&&(i.iridescenceThicknessMap=this.iridescenceThicknessMap.toJSON(t).uuid),void 0!==this.anisotropy&&(i.anisotropy=this.anisotropy),void 0!==this.anisotropyRotation&&(i.anisotropyRotation=this.anisotropyRotation),this.anisotropyMap&&this.anisotropyMap.isTexture&&(i.anisotropyMap=this.anisotropyMap.toJSON(t).uuid),this.map&&this.map.isTexture&&(i.map=this.map.toJSON(t).uuid),this.matcap&&this.matcap.isTexture&&(i.matcap=this.matcap.toJSON(t).uuid),this.alphaMap&&this.alphaMap.isTexture&&(i.alphaMap=this.alphaMap.toJSON(t).uuid),this.lightMap&&this.lightMap.isTexture&&(i.lightMap=this.lightMap.toJSON(t).uuid,i.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(i.aoMap=this.aoMap.toJSON(t).uuid,i.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(i.bumpMap=this.bumpMap.toJSON(t).uuid,i.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(i.normalMap=this.normalMap.toJSON(t).uuid,i.normalMapType=this.normalMapType,i.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(i.displacementMap=this.displacementMap.toJSON(t).uuid,i.displacementScale=this.displacementScale,i.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(i.roughnessMap=this.roughnessMap.toJSON(t).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(i.metalnessMap=this.metalnessMap.toJSON(t).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(i.emissiveMap=this.emissiveMap.toJSON(t).uuid),this.specularMap&&this.specularMap.isTexture&&(i.specularMap=this.specularMap.toJSON(t).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(i.specularIntensityMap=this.specularIntensityMap.toJSON(t).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(i.specularColorMap=this.specularColorMap.toJSON(t).uuid),this.envMap&&this.envMap.isTexture&&(i.envMap=this.envMap.toJSON(t).uuid,void 0!==this.combine&&(i.combine=this.combine)),void 0!==this.envMapRotation&&(i.envMapRotation=this.envMapRotation.toArray()),void 0!==this.envMapIntensity&&(i.envMapIntensity=this.envMapIntensity),void 0!==this.reflectivity&&(i.reflectivity=this.reflectivity),void 0!==this.refractionRatio&&(i.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(i.gradientMap=this.gradientMap.toJSON(t).uuid),void 0!==this.transmission&&(i.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(i.transmissionMap=this.transmissionMap.toJSON(t).uuid),void 0!==this.thickness&&(i.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(i.thicknessMap=this.thicknessMap.toJSON(t).uuid),void 0!==this.attenuationDistance&&this.attenuationDistance!==1/0&&(i.attenuationDistance=this.attenuationDistance),void 0!==this.attenuationColor&&(i.attenuationColor=this.attenuationColor.getHex()),void 0!==this.size&&(i.size=this.size),null!==this.shadowSide&&(i.shadowSide=this.shadowSide),void 0!==this.sizeAttenuation&&(i.sizeAttenuation=this.sizeAttenuation),1!==this.blending&&(i.blending=this.blending),0!==this.side&&(i.side=this.side),!0===this.vertexColors&&(i.vertexColors=!0),this.opacity<1&&(i.opacity=this.opacity),!0===this.transparent&&(i.transparent=!0),204!==this.blendSrc&&(i.blendSrc=this.blendSrc),205!==this.blendDst&&(i.blendDst=this.blendDst),100!==this.blendEquation&&(i.blendEquation=this.blendEquation),null!==this.blendSrcAlpha&&(i.blendSrcAlpha=this.blendSrcAlpha),null!==this.blendDstAlpha&&(i.blendDstAlpha=this.blendDstAlpha),null!==this.blendEquationAlpha&&(i.blendEquationAlpha=this.blendEquationAlpha),this.blendColor&&this.blendColor.isColor&&(i.blendColor=this.blendColor.getHex()),0!==this.blendAlpha&&(i.blendAlpha=this.blendAlpha),3!==this.depthFunc&&(i.depthFunc=this.depthFunc),!1===this.depthTest&&(i.depthTest=this.depthTest),!1===this.depthWrite&&(i.depthWrite=this.depthWrite),!1===this.colorWrite&&(i.colorWrite=this.colorWrite),255!==this.stencilWriteMask&&(i.stencilWriteMask=this.stencilWriteMask),519!==this.stencilFunc&&(i.stencilFunc=this.stencilFunc),0!==this.stencilRef&&(i.stencilRef=this.stencilRef),255!==this.stencilFuncMask&&(i.stencilFuncMask=this.stencilFuncMask),this.stencilFail!==li&&(i.stencilFail=this.stencilFail),this.stencilZFail!==li&&(i.stencilZFail=this.stencilZFail),this.stencilZPass!==li&&(i.stencilZPass=this.stencilZPass),!0===this.stencilWrite&&(i.stencilWrite=this.stencilWrite),void 0!==this.rotation&&0!==this.rotation&&(i.rotation=this.rotation),!0===this.polygonOffset&&(i.polygonOffset=!0),0!==this.polygonOffsetFactor&&(i.polygonOffsetFactor=this.polygonOffsetFactor),0!==this.polygonOffsetUnits&&(i.polygonOffsetUnits=this.polygonOffsetUnits),void 0!==this.linewidth&&1!==this.linewidth&&(i.linewidth=this.linewidth),void 0!==this.dashSize&&(i.dashSize=this.dashSize),void 0!==this.gapSize&&(i.gapSize=this.gapSize),void 0!==this.scale&&(i.scale=this.scale),!0===this.dithering&&(i.dithering=!0),this.alphaTest>0&&(i.alphaTest=this.alphaTest),!0===this.alphaHash&&(i.alphaHash=!0),!0===this.alphaToCoverage&&(i.alphaToCoverage=!0),!0===this.premultipliedAlpha&&(i.premultipliedAlpha=!0),!0===this.forceSinglePass&&(i.forceSinglePass=!0),!1===this.allowOverride&&(i.allowOverride=!1),!0===this.wireframe&&(i.wireframe=!0),this.wireframeLinewidth>1&&(i.wireframeLinewidth=this.wireframeLinewidth),"round"!==this.wireframeLinecap&&(i.wireframeLinecap=this.wireframeLinecap),"round"!==this.wireframeLinejoin&&(i.wireframeLinejoin=this.wireframeLinejoin),!0===this.flatShading&&(i.flatShading=!0),!1===this.visible&&(i.visible=!1),!1===this.toneMapped&&(i.toneMapped=!1),!1===this.fog&&(i.fog=!1),Object.keys(this.userData).length>0&&(i.userData=this.userData),e){const e=s(t.textures),r=s(t.images);e.length>0&&(i.textures=e),r.length>0&&(i.images=r)}return i}clone(){return(new this.constructor).copy(this)}copy(t){this.name=t.name,this.blending=t.blending,this.side=t.side,this.vertexColors=t.vertexColors,this.opacity=t.opacity,this.transparent=t.transparent,this.blendSrc=t.blendSrc,this.blendDst=t.blendDst,this.blendEquation=t.blendEquation,this.blendSrcAlpha=t.blendSrcAlpha,this.blendDstAlpha=t.blendDstAlpha,this.blendEquationAlpha=t.blendEquationAlpha,this.blendColor.copy(t.blendColor),this.blendAlpha=t.blendAlpha,this.depthFunc=t.depthFunc,this.depthTest=t.depthTest,this.depthWrite=t.depthWrite,this.stencilWriteMask=t.stencilWriteMask,this.stencilFunc=t.stencilFunc,this.stencilRef=t.stencilRef,this.stencilFuncMask=t.stencilFuncMask,this.stencilFail=t.stencilFail,this.stencilZFail=t.stencilZFail,this.stencilZPass=t.stencilZPass,this.stencilWrite=t.stencilWrite;const e=t.clippingPlanes;let i=null;if(null!==e){const t=e.length;i=new Array(t);for(let s=0;s!==t;++s)i[s]=e[s].clone()}return this.clippingPlanes=i,this.clipIntersection=t.clipIntersection,this.clipShadows=t.clipShadows,this.shadowSide=t.shadowSide,this.colorWrite=t.colorWrite,this.precision=t.precision,this.polygonOffset=t.polygonOffset,this.polygonOffsetFactor=t.polygonOffsetFactor,this.polygonOffsetUnits=t.polygonOffsetUnits,this.dithering=t.dithering,this.alphaTest=t.alphaTest,this.alphaHash=t.alphaHash,this.alphaToCoverage=t.alphaToCoverage,this.premultipliedAlpha=t.premultipliedAlpha,this.forceSinglePass=t.forceSinglePass,this.allowOverride=t.allowOverride,this.visible=t.visible,this.toneMapped=t.toneMapped,this.userData=JSON.parse(JSON.stringify(t.userData)),this}dispose(){this.dispatchEvent({type:"dispose"})}set needsUpdate(t){!0===t&&this.version++}}class vn extends bn{constructor(t){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicMaterial",this.color=new gn(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new Pr,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}const wn=Mn();function Mn(){const t=new ArrayBuffer(4),e=new Float32Array(t),i=new Uint32Array(t),s=new Uint32Array(512),r=new Uint32Array(512);for(let t=0;t<256;++t){const e=t-127;e<-27?(s[t]=0,s[256|t]=32768,r[t]=24,r[256|t]=24):e<-14?(s[t]=1024>>-e-14,s[256|t]=1024>>-e-14|32768,r[t]=-e-1,r[256|t]=-e-1):e<=15?(s[t]=e+15<<10,s[256|t]=e+15<<10|32768,r[t]=13,r[256|t]=13):e<128?(s[t]=31744,s[256|t]=64512,r[t]=24,r[256|t]=24):(s[t]=31744,s[256|t]=64512,r[t]=13,r[256|t]=13)}const n=new Uint32Array(2048),a=new Uint32Array(64),o=new Uint32Array(64);for(let t=1;t<1024;++t){let e=t<<13,i=0;for(;!(8388608&e);)e<<=1,i-=8388608;e&=-8388609,i+=947912704,n[t]=e|i}for(let t=1024;t<2048;++t)n[t]=939524096+(t-1024<<13);for(let t=1;t<31;++t)a[t]=t<<23;a[31]=1199570944,a[32]=2147483648;for(let t=33;t<63;++t)a[t]=2147483648+(t-32<<23);a[63]=3347054592;for(let t=1;t<64;++t)32!==t&&(o[t]=1024);return{floatView:e,uint32View:i,baseTable:s,shiftTable:r,mantissaTable:n,exponentTable:a,offsetTable:o}}function Sn(t){Math.abs(t)>65504&&as("DataUtils.toHalfFloat(): Value out of range."),t=gs(t,-65504,65504),wn.floatView[0]=t;const e=wn.uint32View[0],i=e>>23&511;return wn.baseTable[i]+((8388607&e)>>wn.shiftTable[i])}function _n(t){const e=t>>10;return wn.uint32View[0]=wn.mantissaTable[wn.offsetTable[e]+(1023&t)]+wn.exponentTable[e],wn.floatView[0]}class An{static toHalfFloat(t){return Sn(t)}static fromHalfFloat(t){return _n(t)}}const Tn=new _s,zn=new Ms;let Cn=0;class In{constructor(t,e,i=!1){if(Array.isArray(t))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.isBufferAttribute=!0,Object.defineProperty(this,"id",{value:Cn++}),this.name="",this.array=t,this.itemSize=e,this.count=void 0!==t?t.length/e:0,this.normalized=i,this.usage=Oi,this.updateRanges=[],this.gpuType=Pt,this.version=0}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}addUpdateRange(t,e){this.updateRanges.push({start:t,count:e})}clearUpdateRanges(){this.updateRanges.length=0}copy(t){return this.name=t.name,this.array=new t.array.constructor(t.array),this.itemSize=t.itemSize,this.count=t.count,this.normalized=t.normalized,this.usage=t.usage,this.gpuType=t.gpuType,this}copyAt(t,e,i){t*=this.itemSize,i*=e.itemSize;for(let s=0,r=this.itemSize;se.count&&as("BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."),e.needsUpdate=!0}return this}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new Gs);const t=this.attributes.position,e=this.morphAttributes.position;if(t&&t.isGLBufferAttribute)return os("BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.",this),void this.boundingBox.set(new _s(-1/0,-1/0,-1/0),new _s(1/0,1/0,1/0));if(void 0!==t){if(this.boundingBox.setFromBufferAttribute(t),e)for(let t=0,i=e.length;t0&&(t.userData=this.userData),void 0!==this.parameters){const e=this.parameters;for(const i in e)void 0!==e[i]&&(t[i]=e[i]);return t}t.data={attributes:{}};const e=this.index;null!==e&&(t.data.index={type:e.array.constructor.name,array:Array.prototype.slice.call(e.array)});const i=this.attributes;for(const e in i){const s=i[e];t.data.attributes[e]=s.toJSON(t.data)}const s={};let r=!1;for(const e in this.morphAttributes){const i=this.morphAttributes[e],n=[];for(let e=0,s=i.length;e0&&(s[e]=n,r=!0)}r&&(t.data.morphAttributes=s,t.data.morphTargetsRelative=this.morphTargetsRelative);const n=this.groups;n.length>0&&(t.data.groups=JSON.parse(JSON.stringify(n)));const a=this.boundingSphere;return null!==a&&(t.data.boundingSphere=a.toJSON()),t}clone(){return(new this.constructor).copy(this)}copy(t){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;const e={};this.name=t.name;const i=t.index;null!==i&&this.setIndex(i.clone());const s=t.attributes;for(const t in s){const i=s[t];this.setAttribute(t,i.clone(e))}const r=t.morphAttributes;for(const t in r){const i=[],s=r[t];for(let t=0,r=s.length;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;t(t.far-t.near)**2)return}Yn.copy(r).invert(),Hn.copy(t.ray).applyMatrix4(Yn),null!==i.boundingBox&&!1===Hn.intersectsBox(i.boundingBox)||this._computeIntersections(t,e,Hn)}}_computeIntersections(t,e,i){let s;const r=this.geometry,n=this.material,a=r.index,o=r.attributes.position,h=r.attributes.uv,l=r.attributes.uv1,c=r.attributes.normal,u=r.groups,d=r.drawRange;if(null!==a)if(Array.isArray(n))for(let r=0,o=u.length;ri.far?null:{distance:l,point:sa.clone(),object:t}}(t,e,i,s,$n,Qn,Kn,ia);if(c){const t=new _s;un.getBarycoord(ia,$n,Qn,Kn,t),r&&(c.uv=un.getInterpolatedAttribute(r,o,h,l,t,new Ms)),n&&(c.uv1=un.getInterpolatedAttribute(n,o,h,l,t,new Ms)),a&&(c.normal=un.getInterpolatedAttribute(a,o,h,l,t,new _s),c.normal.dot(s.direction)>0&&c.normal.multiplyScalar(-1));const e={a:o,b:h,c:l,normal:new _s,materialIndex:0};un.getNormal($n,Qn,Kn,e.normal),c.face=e,c.barycoord=t}return c}class aa extends Xn{constructor(t=1,e=1,i=1,s=1,r=1,n=1){super(),this.type="BoxGeometry",this.parameters={width:t,height:e,depth:i,widthSegments:s,heightSegments:r,depthSegments:n};const a=this;s=Math.floor(s),r=Math.floor(r),n=Math.floor(n);const o=[],h=[],l=[],c=[];let u=0,d=0;function p(t,e,i,s,r,n,p,m,y,g,f){const x=n/y,b=p/g,v=n/2,w=p/2,M=m/2,S=y+1,_=g+1;let A=0,T=0;const z=new _s;for(let n=0;n<_;n++){const a=n*b-w;for(let o=0;o0?1:-1,l.push(z.x,z.y,z.z),c.push(o/y),c.push(1-n/g),A+=1}}for(let t=0;t0&&(e.defines=this.defines),e.vertexShader=this.vertexShader,e.fragmentShader=this.fragmentShader,e.lights=this.lights,e.clipping=this.clipping;const i={};for(const t in this.extensions)!0===this.extensions[t]&&(i[t]=!0);return Object.keys(i).length>0&&(e.extensions=i),e}}const da=new _s,pa=new Ss,ma=new _s;class ya extends Gr{constructor(){super(),this.isCamera=!0,this.type="Camera",this.matrixWorldInverse=new Sr,this.projectionMatrix=new Sr,this.projectionMatrixInverse=new Sr,this.coordinateSystem=Ui,this._reversedDepth=!1}get reversedDepth(){return this._reversedDepth}copy(t,e){return super.copy(t,e),this.matrixWorldInverse.copy(t.matrixWorldInverse),this.projectionMatrix.copy(t.projectionMatrix),this.projectionMatrixInverse.copy(t.projectionMatrixInverse),this.coordinateSystem=t.coordinateSystem,this}getWorldDirection(t){return super.getWorldDirection(t).negate()}updateMatrixWorld(t){super.updateMatrixWorld(t),this.matrixWorld.decompose(da,pa,ma),1===ma.x&&1===ma.y&&1===ma.z?this.matrixWorldInverse.copy(this.matrixWorld).invert():this.matrixWorldInverse.compose(da,pa,ma.set(1,1,1)).invert()}updateWorldMatrix(t,e){super.updateWorldMatrix(t,e),this.matrixWorld.decompose(da,pa,ma),1===ma.x&&1===ma.y&&1===ma.z?this.matrixWorldInverse.copy(this.matrixWorld).invert():this.matrixWorldInverse.compose(da,pa,ma.set(1,1,1)).invert()}clone(){return(new this.constructor).copy(this)}}const ga=new _s,fa=new Ms,xa=new Ms;class ba extends ya{constructor(t=50,e=1,i=.1,s=2e3){super(),this.isPerspectiveCamera=!0,this.type="PerspectiveCamera",this.fov=t,this.zoom=1,this.near=i,this.far=s,this.focus=10,this.aspect=e,this.view=null,this.filmGauge=35,this.filmOffset=0,this.updateProjectionMatrix()}copy(t,e){return super.copy(t,e),this.fov=t.fov,this.zoom=t.zoom,this.near=t.near,this.far=t.far,this.focus=t.focus,this.aspect=t.aspect,this.view=null===t.view?null:Object.assign({},t.view),this.filmGauge=t.filmGauge,this.filmOffset=t.filmOffset,this}setFocalLength(t){const e=.5*this.getFilmHeight()/t;this.fov=2*ms*Math.atan(e),this.updateProjectionMatrix()}getFocalLength(){const t=Math.tan(.5*ps*this.fov);return.5*this.getFilmHeight()/t}getEffectiveFOV(){return 2*ms*Math.atan(Math.tan(.5*ps*this.fov)/this.zoom)}getFilmWidth(){return this.filmGauge*Math.min(this.aspect,1)}getFilmHeight(){return this.filmGauge/Math.max(this.aspect,1)}getViewBounds(t,e,i){ga.set(-1,-1,.5).applyMatrix4(this.projectionMatrixInverse),e.set(ga.x,ga.y).multiplyScalar(-t/ga.z),ga.set(1,1,.5).applyMatrix4(this.projectionMatrixInverse),i.set(ga.x,ga.y).multiplyScalar(-t/ga.z)}getViewSize(t,e){return this.getViewBounds(t,fa,xa),e.subVectors(xa,fa)}setViewOffset(t,e,i,s,r,n){this.aspect=t/e,null===this.view&&(this.view={enabled:!0,fullWidth:1,fullHeight:1,offsetX:0,offsetY:0,width:1,height:1}),this.view.enabled=!0,this.view.fullWidth=t,this.view.fullHeight=e,this.view.offsetX=i,this.view.offsetY=s,this.view.width=r,this.view.height=n,this.updateProjectionMatrix()}clearViewOffset(){null!==this.view&&(this.view.enabled=!1),this.updateProjectionMatrix()}updateProjectionMatrix(){const t=this.near;let e=t*Math.tan(.5*ps*this.fov)/this.zoom,i=2*e,s=this.aspect*i,r=-.5*s;const n=this.view;if(null!==this.view&&this.view.enabled){const t=n.fullWidth,a=n.fullHeight;r+=n.offsetX*s/t,e-=n.offsetY*i/a,s*=n.width/t,i*=n.height/a}const a=this.filmOffset;0!==a&&(r+=t*a/this.getFilmWidth()),this.projectionMatrix.makePerspective(r,r+s,e,e-i,t,this.far,this.coordinateSystem,this.reversedDepth),this.projectionMatrixInverse.copy(this.projectionMatrix).invert()}toJSON(t){const e=super.toJSON(t);return e.object.fov=this.fov,e.object.zoom=this.zoom,e.object.near=this.near,e.object.far=this.far,e.object.focus=this.focus,e.object.aspect=this.aspect,null!==this.view&&(e.object.view=Object.assign({},this.view)),e.object.filmGauge=this.filmGauge,e.object.filmOffset=this.filmOffset,e}}const va=-90;class wa extends Gr{constructor(t,e,i){super(),this.type="CubeCamera",this.renderTarget=i,this.coordinateSystem=null,this.activeMipmapLevel=0;const s=new ba(va,1,t,e);s.layers=this.layers,this.add(s);const r=new ba(va,1,t,e);r.layers=this.layers,this.add(r);const n=new ba(va,1,t,e);n.layers=this.layers,this.add(n);const a=new ba(va,1,t,e);a.layers=this.layers,this.add(a);const o=new ba(va,1,t,e);o.layers=this.layers,this.add(o);const h=new ba(va,1,t,e);h.layers=this.layers,this.add(h)}updateCoordinateSystem(){const t=this.coordinateSystem,e=this.children.concat(),[i,s,r,n,a,o]=e;for(const t of e)this.remove(t);if(t===Ui)i.up.set(0,1,0),i.lookAt(1,0,0),s.up.set(0,1,0),s.lookAt(-1,0,0),r.up.set(0,0,-1),r.lookAt(0,1,0),n.up.set(0,0,1),n.lookAt(0,-1,0),a.up.set(0,1,0),a.lookAt(0,0,1),o.up.set(0,1,0),o.lookAt(0,0,-1);else{if(t!==qi)throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: "+t);i.up.set(0,-1,0),i.lookAt(-1,0,0),s.up.set(0,-1,0),s.lookAt(1,0,0),r.up.set(0,0,1),r.lookAt(0,1,0),n.up.set(0,0,-1),n.lookAt(0,-1,0),a.up.set(0,-1,0),a.lookAt(0,0,1),o.up.set(0,-1,0),o.lookAt(0,0,-1)}for(const t of e)this.add(t),t.updateMatrixWorld()}update(t,e){null===this.parent&&this.updateMatrixWorld();const{renderTarget:i,activeMipmapLevel:s}=this;this.coordinateSystem!==t.coordinateSystem&&(this.coordinateSystem=t.coordinateSystem,this.updateCoordinateSystem());const[r,n,a,o,h,l]=this.children,c=t.getRenderTarget(),u=t.getActiveCubeFace(),d=t.getActiveMipmapLevel(),p=t.xr.enabled;t.xr.enabled=!1;const m=i.texture.generateMipmaps;i.texture.generateMipmaps=!1;const y=!(!t.isWebGLRenderer||!t.state.buffers.depth.getReversed());t.setRenderTarget(i,0,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,r),t.setRenderTarget(i,1,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,n),t.setRenderTarget(i,2,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,a),t.setRenderTarget(i,3,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,o),t.setRenderTarget(i,4,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,h),i.texture.generateMipmaps=m,t.setRenderTarget(i,5,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,l),t.setRenderTarget(c,u,d),t.xr.enabled=p,i.texture.needsPMREMUpdate=!0}}class Ma extends Ws{constructor(t=[],e=301,i,s,r,n,a,o,h,l){super(t,e,i,s,r,n,a,o,h,l),this.isCubeTexture=!0,this.flipY=!1}get images(){return this.image}set images(t){this.image=t}}class Sa extends Js{constructor(t=1,e={}){super(t,t,e),this.isWebGLCubeRenderTarget=!0;const i={width:t,height:t,depth:1},s=[i,i,i,i,i,i];this.texture=new Ma(s),this._setTextureOptions(e),this.texture.isRenderTargetTexture=!0}fromEquirectangularTexture(t,e){this.texture.type=e.type,this.texture.colorSpace=e.colorSpace,this.texture.generateMipmaps=e.generateMipmaps,this.texture.minFilter=e.minFilter,this.texture.magFilter=e.magFilter;const i={uniforms:{tEquirect:{value:null}},vertexShader:"\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t}\n\t\t\t",fragmentShader:"\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include \n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t"},s=new aa(5,5,5),r=new ua({name:"CubemapFromEquirect",uniforms:oa(i.uniforms),vertexShader:i.vertexShader,fragmentShader:i.fragmentShader,side:1,blending:0});r.uniforms.tEquirect.value=e;const n=new ra(s,r),a=e.minFilter;e.minFilter===At&&(e.minFilter=Mt);return new wa(1,10,this).update(t,n),e.minFilter=a,n.geometry.dispose(),n.material.dispose(),this}clear(t,e=!0,i=!0,s=!0){const r=t.getRenderTarget();for(let r=0;r<6;r++)t.setRenderTarget(this,r),t.clear(e,i,s);t.setRenderTarget(r)}}class _a extends Gr{constructor(){super(),this.isGroup=!0,this.type="Group"}}const Aa={type:"move"};class Ta{constructor(){this._targetRay=null,this._grip=null,this._hand=null}getHandSpace(){return null===this._hand&&(this._hand=new _a,this._hand.matrixAutoUpdate=!1,this._hand.visible=!1,this._hand.joints={},this._hand.inputState={pinching:!1}),this._hand}getTargetRaySpace(){return null===this._targetRay&&(this._targetRay=new _a,this._targetRay.matrixAutoUpdate=!1,this._targetRay.visible=!1,this._targetRay.hasLinearVelocity=!1,this._targetRay.linearVelocity=new _s,this._targetRay.hasAngularVelocity=!1,this._targetRay.angularVelocity=new _s),this._targetRay}getGripSpace(){return null===this._grip&&(this._grip=new _a,this._grip.matrixAutoUpdate=!1,this._grip.visible=!1,this._grip.hasLinearVelocity=!1,this._grip.linearVelocity=new _s,this._grip.hasAngularVelocity=!1,this._grip.angularVelocity=new _s),this._grip}dispatchEvent(t){return null!==this._targetRay&&this._targetRay.dispatchEvent(t),null!==this._grip&&this._grip.dispatchEvent(t),null!==this._hand&&this._hand.dispatchEvent(t),this}connect(t){if(t&&t.hand){const e=this._hand;if(e)for(const i of t.hand.values())this._getHandJoint(e,i)}return this.dispatchEvent({type:"connected",data:t}),this}disconnect(t){return this.dispatchEvent({type:"disconnected",data:t}),null!==this._targetRay&&(this._targetRay.visible=!1),null!==this._grip&&(this._grip.visible=!1),null!==this._hand&&(this._hand.visible=!1),this}update(t,e,i){let s=null,r=null,n=null;const a=this._targetRay,o=this._grip,h=this._hand;if(t&&"visible-blurred"!==e.session.visibilityState){if(h&&t.hand){n=!0;for(const s of t.hand.values()){const t=e.getJointPose(s,i),r=this._getHandJoint(h,s);null!==t&&(r.matrix.fromArray(t.transform.matrix),r.matrix.decompose(r.position,r.rotation,r.scale),r.matrixWorldNeedsUpdate=!0,r.jointRadius=t.radius),r.visible=null!==t}const s=h.joints["index-finger-tip"],r=h.joints["thumb-tip"],a=s.position.distanceTo(r.position),o=.02,l=.005;h.inputState.pinching&&a>o+l?(h.inputState.pinching=!1,this.dispatchEvent({type:"pinchend",handedness:t.handedness,target:this})):!h.inputState.pinching&&a<=o-l&&(h.inputState.pinching=!0,this.dispatchEvent({type:"pinchstart",handedness:t.handedness,target:this}))}else null!==o&&t.gripSpace&&(r=e.getPose(t.gripSpace,i),null!==r&&(o.matrix.fromArray(r.transform.matrix),o.matrix.decompose(o.position,o.rotation,o.scale),o.matrixWorldNeedsUpdate=!0,r.linearVelocity?(o.hasLinearVelocity=!0,o.linearVelocity.copy(r.linearVelocity)):o.hasLinearVelocity=!1,r.angularVelocity?(o.hasAngularVelocity=!0,o.angularVelocity.copy(r.angularVelocity)):o.hasAngularVelocity=!1));null!==a&&(s=e.getPose(t.targetRaySpace,i),null===s&&null!==r&&(s=r),null!==s&&(a.matrix.fromArray(s.transform.matrix),a.matrix.decompose(a.position,a.rotation,a.scale),a.matrixWorldNeedsUpdate=!0,s.linearVelocity?(a.hasLinearVelocity=!0,a.linearVelocity.copy(s.linearVelocity)):a.hasLinearVelocity=!1,s.angularVelocity?(a.hasAngularVelocity=!0,a.angularVelocity.copy(s.angularVelocity)):a.hasAngularVelocity=!1,this.dispatchEvent(Aa)))}return null!==a&&(a.visible=null!==s),null!==o&&(o.visible=null!==r),null!==h&&(h.visible=null!==n),this}_getHandJoint(t,e){if(void 0===t.joints[e.jointName]){const i=new _a;i.matrixAutoUpdate=!1,i.visible=!1,t.joints[e.jointName]=i,t.add(i)}return t.joints[e.jointName]}}class za{constructor(t,e=25e-5){this.isFogExp2=!0,this.name="",this.color=new gn(t),this.density=e}clone(){return new za(this.color,this.density)}toJSON(){return{type:"FogExp2",name:this.name,color:this.color.getHex(),density:this.density}}}class Ca{constructor(t,e=1,i=1e3){this.isFog=!0,this.name="",this.color=new gn(t),this.near=e,this.far=i}clone(){return new Ca(this.color,this.near,this.far)}toJSON(){return{type:"Fog",name:this.name,color:this.color.getHex(),near:this.near,far:this.far}}}class Ia extends Gr{constructor(){super(),this.isScene=!0,this.type="Scene",this.background=null,this.environment=null,this.fog=null,this.backgroundBlurriness=0,this.backgroundIntensity=1,this.backgroundRotation=new Pr,this.environmentIntensity=1,this.environmentRotation=new Pr,this.overrideMaterial=null,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}copy(t,e){return super.copy(t,e),null!==t.background&&(this.background=t.background.clone()),null!==t.environment&&(this.environment=t.environment.clone()),null!==t.fog&&(this.fog=t.fog.clone()),this.backgroundBlurriness=t.backgroundBlurriness,this.backgroundIntensity=t.backgroundIntensity,this.backgroundRotation.copy(t.backgroundRotation),this.environmentIntensity=t.environmentIntensity,this.environmentRotation.copy(t.environmentRotation),null!==t.overrideMaterial&&(this.overrideMaterial=t.overrideMaterial.clone()),this.matrixAutoUpdate=t.matrixAutoUpdate,this}toJSON(t){const e=super.toJSON(t);return null!==this.fog&&(e.object.fog=this.fog.toJSON()),this.backgroundBlurriness>0&&(e.object.backgroundBlurriness=this.backgroundBlurriness),1!==this.backgroundIntensity&&(e.object.backgroundIntensity=this.backgroundIntensity),e.object.backgroundRotation=this.backgroundRotation.toArray(),1!==this.environmentIntensity&&(e.object.environmentIntensity=this.environmentIntensity),e.object.environmentRotation=this.environmentRotation.toArray(),e}}class Ba{constructor(t,e){this.isInterleavedBuffer=!0,this.array=t,this.stride=e,this.count=void 0!==t?t.length/e:0,this.usage=Oi,this.updateRanges=[],this.version=0,this.uuid=ys()}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}addUpdateRange(t,e){this.updateRanges.push({start:t,count:e})}clearUpdateRanges(){this.updateRanges.length=0}copy(t){return this.array=new t.array.constructor(t.array),this.count=t.count,this.stride=t.stride,this.usage=t.usage,this}copyAt(t,e,i){t*=this.stride,i*=e.stride;for(let s=0,r=this.stride;st.far||e.push({distance:o,point:Na.clone(),uv:un.getInterpolation(Na,ja,Wa,Ua,qa,Ja,Xa,new Ms),face:null,object:this})}copy(t,e){return super.copy(t,e),void 0!==t.center&&this.center.copy(t.center),this.material=t.material,this}}function Ha(t,e,i,s,r,n){Ea.subVectors(t,i).addScalar(.5).multiply(s),void 0!==r?(La.x=n*Ea.x-r*Ea.y,La.y=r*Ea.x+n*Ea.y):La.copy(Ea),t.copy(e),t.x+=La.x,t.y+=La.y,t.applyMatrix4(Da)}const Za=new _s,Ga=new _s;class $a extends Gr{constructor(){super(),this.isLOD=!0,this._currentLevel=0,this.type="LOD",Object.defineProperties(this,{levels:{enumerable:!0,value:[]}}),this.autoUpdate=!0}copy(t){super.copy(t,!1);const e=t.levels;for(let t=0,i=e.length;t0){let i,s;for(i=1,s=e.length;i0){Za.setFromMatrixPosition(this.matrixWorld);const i=t.ray.origin.distanceTo(Za);this.getObjectForDistance(i).raycast(t,e)}}update(t){const e=this.levels;if(e.length>1){Za.setFromMatrixPosition(t.matrixWorld),Ga.setFromMatrixPosition(this.matrixWorld);const i=Za.distanceTo(Ga)/t.zoom;let s,r;for(e[0].object.visible=!0,s=1,r=e.length;s=t))break;e[s-1].object.visible=!1,e[s].object.visible=!0}for(this._currentLevel=s-1;s1?null:e.copy(t.start).addScaledVector(i,r)}intersectsLine(t){const e=this.distanceToPoint(t.start),i=this.distanceToPoint(t.end);return e<0&&i>0||i<0&&e>0}intersectsBox(t){return t.intersectsPlane(this)}intersectsSphere(t){return t.intersectsPlane(this)}coplanarPoint(t){return t.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(t,e){const i=e||Ao.getNormalMatrix(t),s=this.coplanarPoint(So).applyMatrix4(t),r=this.normal.applyMatrix3(i).normalize();return this.constant=-s.dot(r),this}translate(t){return this.constant-=t.dot(this.normal),this}equals(t){return t.normal.equals(this.normal)&&t.constant===this.constant}clone(){return(new this.constructor).copy(this)}}const zo=new mr,Co=new Ms(.5,.5),Io=new _s;class Bo{constructor(t=new To,e=new To,i=new To,s=new To,r=new To,n=new To){this.planes=[t,e,i,s,r,n]}set(t,e,i,s,r,n){const a=this.planes;return a[0].copy(t),a[1].copy(e),a[2].copy(i),a[3].copy(s),a[4].copy(r),a[5].copy(n),this}copy(t){const e=this.planes;for(let i=0;i<6;i++)e[i].copy(t.planes[i]);return this}setFromProjectionMatrix(t,e=2e3,i=!1){const s=this.planes,r=t.elements,n=r[0],a=r[1],o=r[2],h=r[3],l=r[4],c=r[5],u=r[6],d=r[7],p=r[8],m=r[9],y=r[10],g=r[11],f=r[12],x=r[13],b=r[14],v=r[15];if(s[0].setComponents(h-n,d-l,g-p,v-f).normalize(),s[1].setComponents(h+n,d+l,g+p,v+f).normalize(),s[2].setComponents(h+a,d+c,g+m,v+x).normalize(),s[3].setComponents(h-a,d-c,g-m,v-x).normalize(),i)s[4].setComponents(o,u,y,b).normalize(),s[5].setComponents(h-o,d-u,g-y,v-b).normalize();else if(s[4].setComponents(h-o,d-u,g-y,v-b).normalize(),e===Ui)s[5].setComponents(h+o,d+u,g+y,v+b).normalize();else{if(e!==qi)throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: "+e);s[5].setComponents(o,u,y,b).normalize()}return this}intersectsObject(t){if(void 0!==t.boundingSphere)null===t.boundingSphere&&t.computeBoundingSphere(),zo.copy(t.boundingSphere).applyMatrix4(t.matrixWorld);else{const e=t.geometry;null===e.boundingSphere&&e.computeBoundingSphere(),zo.copy(e.boundingSphere).applyMatrix4(t.matrixWorld)}return this.intersectsSphere(zo)}intersectsSprite(t){zo.center.set(0,0,0);const e=Co.distanceTo(t.center);return zo.radius=.7071067811865476+e,zo.applyMatrix4(t.matrixWorld),this.intersectsSphere(zo)}intersectsSphere(t){const e=this.planes,i=t.center,s=-t.radius;for(let t=0;t<6;t++){if(e[t].distanceToPoint(i)0?t.max.x:t.min.x,Io.y=s.normal.y>0?t.max.y:t.min.y,Io.z=s.normal.z>0?t.max.z:t.min.z,s.distanceToPoint(Io)<0)return!1}return!0}containsPoint(t){const e=this.planes;for(let i=0;i<6;i++)if(e[i].distanceToPoint(t)<0)return!1;return!0}clone(){return(new this.constructor).copy(this)}}const ko=new Sr,Oo=new Bo;class Po{constructor(){this.coordinateSystem=Ui}intersectsObject(t,e){if(!e.isArrayCamera||0===e.cameras.length)return!1;for(let i=0;i=r.length&&r.push({start:-1,count:-1,z:-1,index:-1});const a=r[this.index];n.push(a),this.index++,a.start=t,a.count=e,a.z=i,a.index=s}reset(){this.list.length=0,this.index=0}}const Eo=new Sr,Lo=new gn(1,1,1),Do=new Bo,jo=new Po,Wo=new Gs,Uo=new mr,qo=new _s,Jo=new _s,Xo=new _s,Yo=new Fo,Ho=new ra,Zo=[];function Go(t,e,i=0){const s=e.itemSize;if(t.isInterleavedBufferAttribute||t.array.constructor!==e.array.constructor){const r=t.count;for(let n=0;n65535?new Uint32Array(s):new Uint16Array(s);e.setIndex(new In(t,1))}this._geometryInitialized=!0}}_validateGeometry(t){const e=this.geometry;if(Boolean(t.getIndex())!==Boolean(e.getIndex()))throw new Error('THREE.BatchedMesh: All geometries must consistently have "index".');for(const i in e.attributes){if(!t.hasAttribute(i))throw new Error(`THREE.BatchedMesh: Added geometry missing "${i}". All geometries must have consistent attributes.`);const s=t.getAttribute(i),r=e.getAttribute(i);if(s.itemSize!==r.itemSize||s.normalized!==r.normalized)throw new Error("THREE.BatchedMesh: All attributes must have a consistent itemSize and normalized value.")}}validateInstanceId(t){const e=this._instanceInfo;if(t<0||t>=e.length||!1===e[t].active)throw new Error(`THREE.BatchedMesh: Invalid instanceId ${t}. Instance is either out of range or has been deleted.`)}validateGeometryId(t){const e=this._geometryInfo;if(t<0||t>=e.length||!1===e[t].active)throw new Error(`THREE.BatchedMesh: Invalid geometryId ${t}. Geometry is either out of range or has been deleted.`)}setCustomSort(t){return this.customSort=t,this}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new Gs);const t=this.boundingBox,e=this._instanceInfo;t.makeEmpty();for(let i=0,s=e.length;i=this.maxInstanceCount&&0===this._availableInstanceIds.length)throw new Error("THREE.BatchedMesh: Maximum item count reached.");const e={visible:!0,active:!0,geometryIndex:t};let i=null;this._availableInstanceIds.length>0?(this._availableInstanceIds.sort(Ro),i=this._availableInstanceIds.shift(),this._instanceInfo[i]=e):(i=this._instanceInfo.length,this._instanceInfo.push(e));const s=this._matricesTexture;Eo.identity().toArray(s.image.data,16*i),s.needsUpdate=!0;const r=this._colorsTexture;return r&&(Lo.toArray(r.image.data,4*i),r.needsUpdate=!0),this._visibilityChanged=!0,i}addGeometry(t,e=-1,i=-1){this._initializeGeometry(t),this._validateGeometry(t);const s={vertexStart:-1,vertexCount:-1,reservedVertexCount:-1,indexStart:-1,indexCount:-1,reservedIndexCount:-1,start:-1,count:-1,boundingBox:null,boundingSphere:null,active:!0},r=this._geometryInfo;s.vertexStart=this._nextVertexStart,s.reservedVertexCount=-1===e?t.getAttribute("position").count:e;const n=t.getIndex();if(null!==n&&(s.indexStart=this._nextIndexStart,s.reservedIndexCount=-1===i?n.count:i),-1!==s.indexStart&&s.indexStart+s.reservedIndexCount>this._maxIndexCount||s.vertexStart+s.reservedVertexCount>this._maxVertexCount)throw new Error("THREE.BatchedMesh: Reserved space request exceeds the maximum buffer size.");let a;return this._availableGeometryIds.length>0?(this._availableGeometryIds.sort(Ro),a=this._availableGeometryIds.shift(),r[a]=s):(a=this._geometryCount,this._geometryCount++,r.push(s)),this.setGeometryAt(a,t),this._nextIndexStart=s.indexStart+s.reservedIndexCount,this._nextVertexStart=s.vertexStart+s.reservedVertexCount,a}setGeometryAt(t,e){if(t>=this._geometryCount)throw new Error("THREE.BatchedMesh: Maximum geometry count reached.");this._validateGeometry(e);const i=this.geometry,s=null!==i.getIndex(),r=i.getIndex(),n=e.getIndex(),a=this._geometryInfo[t];if(s&&n.count>a.reservedIndexCount||e.attributes.position.count>a.reservedVertexCount)throw new Error("THREE.BatchedMesh: Reserved space not large enough for provided geometry.");const o=a.vertexStart,h=a.reservedVertexCount;a.vertexCount=e.getAttribute("position").count;for(const t in i.attributes){const s=e.getAttribute(t),r=i.getAttribute(t);Go(s,r,o);const n=s.itemSize;for(let t=s.count,e=h;t=e.length||!1===e[t].active)return this;const i=this._instanceInfo;for(let e=0,s=i.length;ee).sort((t,e)=>i[t].vertexStart-i[e].vertexStart),r=this.geometry;for(let n=0,a=i.length;n=this._geometryCount)return null;const i=this.geometry,s=this._geometryInfo[t];if(null===s.boundingBox){const t=new Gs,e=i.index,r=i.attributes.position;for(let i=s.start,n=s.start+s.count;i=this._geometryCount)return null;const i=this.geometry,s=this._geometryInfo[t];if(null===s.boundingSphere){const e=new mr;this.getBoundingBoxAt(t,Wo),Wo.getCenter(e.center);const r=i.index,n=i.attributes.position;let a=0;for(let t=s.start,i=s.start+s.count;tt.active);if(Math.max(...i.map(t=>t.vertexStart+t.reservedVertexCount))>t)throw new Error(`BatchedMesh: Geometry vertex values are being used outside the range ${e}. Cannot shrink further.`);if(this.geometry.index){if(Math.max(...i.map(t=>t.indexStart+t.reservedIndexCount))>e)throw new Error(`BatchedMesh: Geometry index values are being used outside the range ${e}. Cannot shrink further.`)}const s=this.geometry;s.dispose(),this._maxVertexCount=t,this._maxIndexCount=e,this._geometryInitialized&&(this._geometryInitialized=!1,this.geometry=new Xn,this._initializeGeometry(s));const r=this.geometry;s.index&&$o(s.index.array,r.index.array);for(const t in s.attributes)$o(s.attributes[t].array,r.attributes[t].array)}raycast(t,e){const i=this._instanceInfo,s=this._geometryInfo,r=this.matrixWorld,n=this.geometry;Ho.material=this.material,Ho.geometry.index=n.index,Ho.geometry.attributes=n.attributes,null===Ho.geometry.boundingBox&&(Ho.geometry.boundingBox=new Gs),null===Ho.geometry.boundingSphere&&(Ho.geometry.boundingSphere=new mr);for(let n=0,a=i.length;n({...t,boundingBox:null!==t.boundingBox?t.boundingBox.clone():null,boundingSphere:null!==t.boundingSphere?t.boundingSphere.clone():null})),this._instanceInfo=t._instanceInfo.map(t=>({...t})),this._availableInstanceIds=t._availableInstanceIds.slice(),this._availableGeometryIds=t._availableGeometryIds.slice(),this._nextIndexStart=t._nextIndexStart,this._nextVertexStart=t._nextVertexStart,this._geometryCount=t._geometryCount,this._maxInstanceCount=t._maxInstanceCount,this._maxVertexCount=t._maxVertexCount,this._maxIndexCount=t._maxIndexCount,this._geometryInitialized=t._geometryInitialized,this._multiDrawCounts=t._multiDrawCounts.slice(),this._multiDrawStarts=t._multiDrawStarts.slice(),this._indirectTexture=t._indirectTexture.clone(),this._indirectTexture.image.data=this._indirectTexture.image.data.slice(),this._matricesTexture=t._matricesTexture.clone(),this._matricesTexture.image.data=this._matricesTexture.image.data.slice(),null!==this._colorsTexture&&(this._colorsTexture=t._colorsTexture.clone(),this._colorsTexture.image.data=this._colorsTexture.image.data.slice()),this}dispose(){this.geometry.dispose(),this._matricesTexture.dispose(),this._matricesTexture=null,this._indirectTexture.dispose(),this._indirectTexture=null,null!==this._colorsTexture&&(this._colorsTexture.dispose(),this._colorsTexture=null)}onBeforeRender(t,e,i,s,r){if(!this._visibilityChanged&&!this.perObjectFrustumCulled&&!this.sortObjects)return;const n=s.getIndex(),a=null===n?1:n.array.BYTES_PER_ELEMENT,o=this._instanceInfo,h=this._multiDrawStarts,l=this._multiDrawCounts,c=this._geometryInfo,u=this.perObjectFrustumCulled,d=this._indirectTexture,p=d.image.data,m=i.isArrayCamera?jo:Do;u&&!i.isArrayCamera&&(Eo.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse).multiply(this.matrixWorld),Do.setFromProjectionMatrix(Eo,i.coordinateSystem,i.reversedDepth));let y=0;if(this.sortObjects){Eo.copy(this.matrixWorld).invert(),qo.setFromMatrixPosition(i.matrixWorld).applyMatrix4(Eo),Jo.set(0,0,-1).transformDirection(i.matrixWorld).transformDirection(Eo);for(let t=0,e=o.length;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;ts)return;nh.applyMatrix4(t.matrixWorld);const h=e.ray.origin.distanceTo(nh);return he.far?void 0:{distance:h,point:ah.clone().applyMatrix4(t.matrixWorld),index:a,face:null,faceIndex:null,barycoord:null,object:t}}const lh=new _s,ch=new _s;class uh extends oh{constructor(t,e){super(t,e),this.isLineSegments=!0,this.type="LineSegments"}computeLineDistances(){const t=this.geometry;if(null===t.index){const e=t.attributes.position,i=[];for(let t=0,s=e.count;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;tr.far)return;n.push({distance:h,distanceToRay:Math.sqrt(o),point:i,index:e,face:null,faceIndex:null,barycoord:null,object:a})}}class vh extends Ws{constructor(t,e,i,s,r=1006,n=1006,a,o,h){super(t,e,i,s,r,n,a,o,h),this.isVideoTexture=!0,this.generateMipmaps=!1,this._requestVideoFrameCallbackId=0;const l=this;"requestVideoFrameCallback"in t&&(this._requestVideoFrameCallbackId=t.requestVideoFrameCallback(function e(){l.needsUpdate=!0,l._requestVideoFrameCallbackId=t.requestVideoFrameCallback(e)}))}clone(){return new this.constructor(this.image).copy(this)}update(){const t=this.image;!1==="requestVideoFrameCallback"in t&&t.readyState>=t.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}dispose(){0!==this._requestVideoFrameCallbackId&&(this.source.data.cancelVideoFrameCallback(this._requestVideoFrameCallbackId),this._requestVideoFrameCallbackId=0),super.dispose()}}class wh extends vh{constructor(t,e,i,s,r,n,a,o){super({},t,e,i,s,r,n,a,o),this.isVideoFrameTexture=!0}update(){}clone(){return(new this.constructor).copy(this)}setFrame(t){this.image=t,this.needsUpdate=!0}}class Mh extends Ws{constructor(t,e){super({width:t,height:e}),this.isFramebufferTexture=!0,this.magFilter=ft,this.minFilter=ft,this.generateMipmaps=!1,this.needsUpdate=!0}}class Sh extends Ws{constructor(t,e,i,s,r,n,a,o,h,l,c,u){super(null,n,a,o,h,l,s,r,c,u),this.isCompressedTexture=!0,this.image={width:e,height:i},this.mipmaps=t,this.flipY=!1,this.generateMipmaps=!1}}class _h extends Sh{constructor(t,e,i,s,r,n){super(t,e,i,r,n),this.isCompressedArrayTexture=!0,this.image.depth=s,this.wrapR=yt,this.layerUpdates=new Set}addLayerUpdate(t){this.layerUpdates.add(t)}clearLayerUpdates(){this.layerUpdates.clear()}}class Ah extends Sh{constructor(t,e,i){super(void 0,t[0].width,t[0].height,e,i,lt),this.isCompressedCubeTexture=!0,this.isCubeTexture=!0,this.image=t}}class Th extends Ws{constructor(t,e,i,s,r,n,a,o,h){super(t,e,i,s,r,n,a,o,h),this.isCanvasTexture=!0,this.needsUpdate=!0}}class zh extends Ws{constructor(t,e,i=1014,s,r,n,a=1003,o=1003,h,l=1026,c=1){if(l!==Ut&&1027!==l)throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");super({width:t,height:e,depth:c},s,r,n,a,o,l,i,h),this.isDepthTexture=!0,this.flipY=!1,this.generateMipmaps=!1,this.compareFunction=null}copy(t){return super.copy(t),this.source=new Es(Object.assign({},t.image)),this.compareFunction=t.compareFunction,this}toJSON(t){const e=super.toJSON(t);return null!==this.compareFunction&&(e.compareFunction=this.compareFunction),e}}class Ch extends zh{constructor(t,e=1014,i=301,s,r,n=1003,a=1003,o,h=1026){const l={width:t,height:t,depth:1},c=[l,l,l,l,l,l];super(t,t,e,i,s,r,n,a,o,h),this.image=c,this.isCubeDepthTexture=!0,this.isCubeTexture=!0}get images(){return this.image}set images(t){this.image=t}}class Ih extends Ws{constructor(t=null){super(),this.sourceTexture=t,this.isExternalTexture=!0}copy(t){return super.copy(t),this.sourceTexture=t.sourceTexture,this}}class Bh extends Xn{constructor(t=1,e=1,i=4,s=8,r=1){super(),this.type="CapsuleGeometry",this.parameters={radius:t,height:e,capSegments:i,radialSegments:s,heightSegments:r},e=Math.max(0,e),i=Math.max(1,Math.floor(i)),s=Math.max(3,Math.floor(s)),r=Math.max(1,Math.floor(r));const n=[],a=[],o=[],h=[],l=e/2,c=Math.PI/2*t,u=e,d=2*c+u,p=2*i+r,m=s+1,y=new _s,g=new _s;for(let f=0;f<=p;f++){let x=0,b=0,v=0,w=0;if(f<=i){const e=f/i,s=e*Math.PI/2;b=-l-t*Math.cos(s),v=t*Math.sin(s),w=-t*Math.cos(s),x=e*c}else if(f<=i+r){const s=(f-i)/r;b=s*e-l,v=t,w=0,x=c+s*u}else{const e=(f-i-r)/i,s=e*Math.PI/2;b=l+t*Math.sin(s),v=t*Math.cos(s),w=t*Math.sin(s),x=c+u+e*c}const M=Math.max(0,Math.min(1,x/d));let S=0;0===f?S=.5/s:f===p&&(S=-.5/s);for(let t=0;t<=s;t++){const e=t/s,i=e*Math.PI*2,r=Math.sin(i),n=Math.cos(i);g.x=-v*n,g.y=b,g.z=v*r,a.push(g.x,g.y,g.z),y.set(-v*n,w,v*r),y.normalize(),o.push(y.x,y.y,y.z),h.push(e+S,M)}if(f>0){const t=(f-1)*m;for(let e=0;e0||0!==s)&&(l.push(n,a,h),x+=3),(e>0||s!==r-1)&&(l.push(a,o,h),x+=3)}h.addGroup(g,x,0),g+=x}(),!1===n&&(t>0&&f(!0),e>0&&f(!1)),this.setIndex(l),this.setAttribute("position",new En(c,3)),this.setAttribute("normal",new En(u,3)),this.setAttribute("uv",new En(d,2))}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}static fromJSON(t){return new Oh(t.radiusTop,t.radiusBottom,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Ph extends Oh{constructor(t=1,e=1,i=32,s=1,r=!1,n=0,a=2*Math.PI){super(0,t,e,i,s,r,n,a),this.type="ConeGeometry",this.parameters={radius:t,height:e,radialSegments:i,heightSegments:s,openEnded:r,thetaStart:n,thetaLength:a}}static fromJSON(t){return new Ph(t.radius,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class Rh extends Xn{constructor(t=[],e=[],i=1,s=0){super(),this.type="PolyhedronGeometry",this.parameters={vertices:t,indices:e,radius:i,detail:s};const r=[],n=[];function a(t,e,i,s){const r=s+1,n=[];for(let s=0;s<=r;s++){n[s]=[];const a=t.clone().lerp(i,s/r),o=e.clone().lerp(i,s/r),h=r-s;for(let t=0;t<=h;t++)n[s][t]=0===t&&s===r?a:a.clone().lerp(o,t/h)}for(let t=0;t.9&&a<.1&&(e<.2&&(n[t+0]+=1),i<.2&&(n[t+2]+=1),s<.2&&(n[t+4]+=1))}}()}(),this.setAttribute("position",new En(r,3)),this.setAttribute("normal",new En(r.slice(),3)),this.setAttribute("uv",new En(n,2)),0===s?this.computeVertexNormals():this.normalizeNormals()}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}static fromJSON(t){return new Rh(t.vertices,t.indices,t.radius,t.detail)}}class Nh extends Rh{constructor(t=1,e=0){const i=(1+Math.sqrt(5))/2,s=1/i;super([-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-s,-i,0,-s,i,0,s,-i,0,s,i,-s,-i,0,-s,i,0,s,-i,0,s,i,0,-i,0,-s,i,0,-s,-i,0,s,i,0,s],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],t,e),this.type="DodecahedronGeometry",this.parameters={radius:t,detail:e}}static fromJSON(t){return new Nh(t.radius,t.detail)}}const Vh=new _s,Fh=new _s,Eh=new _s,Lh=new un;class Dh extends Xn{constructor(t=null,e=1){if(super(),this.type="EdgesGeometry",this.parameters={geometry:t,thresholdAngle:e},null!==t){const i=4,s=Math.pow(10,i),r=Math.cos(ps*e),n=t.getIndex(),a=t.getAttribute("position"),o=n?n.count:a.count,h=[0,0,0],l=["a","b","c"],c=new Array(3),u={},d=[];for(let t=0;t0)){h=s;break}h=s-1}if(s=h,i[s]===n)return s/(r-1);const l=i[s];return(s+(n-l)/(i[s+1]-l))/(r-1)}getTangent(t,e){const i=1e-4;let s=t-i,r=t+i;s<0&&(s=0),r>1&&(r=1);const n=this.getPoint(s),a=this.getPoint(r),o=e||(n.isVector2?new Ms:new _s);return o.copy(a).sub(n).normalize(),o}getTangentAt(t,e){const i=this.getUtoTmapping(t);return this.getTangent(i,e)}computeFrenetFrames(t,e=!1){const i=new _s,s=[],r=[],n=[],a=new _s,o=new Sr;for(let e=0;e<=t;e++){const i=e/t;s[e]=this.getTangentAt(i,new _s)}r[0]=new _s,n[0]=new _s;let h=Number.MAX_VALUE;const l=Math.abs(s[0].x),c=Math.abs(s[0].y),u=Math.abs(s[0].z);l<=h&&(h=l,i.set(1,0,0)),c<=h&&(h=c,i.set(0,1,0)),u<=h&&i.set(0,0,1),a.crossVectors(s[0],i).normalize(),r[0].crossVectors(s[0],a),n[0].crossVectors(s[0],r[0]);for(let e=1;e<=t;e++){if(r[e]=r[e-1].clone(),n[e]=n[e-1].clone(),a.crossVectors(s[e-1],s[e]),a.length()>Number.EPSILON){a.normalize();const t=Math.acos(gs(s[e-1].dot(s[e]),-1,1));r[e].applyMatrix4(o.makeRotationAxis(a,t))}n[e].crossVectors(s[e],r[e])}if(!0===e){let e=Math.acos(gs(r[0].dot(r[t]),-1,1));e/=t,s[0].dot(a.crossVectors(r[0],r[t]))>0&&(e=-e);for(let i=1;i<=t;i++)r[i].applyMatrix4(o.makeRotationAxis(s[i],e*i)),n[i].crossVectors(s[i],r[i])}return{tangents:s,normals:r,binormals:n}}clone(){return(new this.constructor).copy(this)}copy(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}toJSON(){const t={metadata:{version:4.7,type:"Curve",generator:"Curve.toJSON"}};return t.arcLengthDivisions=this.arcLengthDivisions,t.type=this.type,t}fromJSON(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}}class Wh extends jh{constructor(t=0,e=0,i=1,s=1,r=0,n=2*Math.PI,a=!1,o=0){super(),this.isEllipseCurve=!0,this.type="EllipseCurve",this.aX=t,this.aY=e,this.xRadius=i,this.yRadius=s,this.aStartAngle=r,this.aEndAngle=n,this.aClockwise=a,this.aRotation=o}getPoint(t,e=new Ms){const i=e,s=2*Math.PI;let r=this.aEndAngle-this.aStartAngle;const n=Math.abs(r)s;)r-=s;r0?0:(Math.floor(Math.abs(h)/r)+1)*r:0===l&&h===r-1&&(h=r-2,l=1),this.closed||h>0?a=s[(h-1)%r]:(Jh.subVectors(s[0],s[1]).add(s[0]),a=Jh);const c=s[h%r],u=s[(h+1)%r];if(this.closed||h+2s.length-2?s.length-1:n+1],c=s[n>s.length-3?s.length-1:n+2];return i.set(Gh(a,o.x,h.x,l.x,c.x),Gh(a,o.y,h.y,l.y,c.y)),i}copy(t){super.copy(t),this.points=[];for(let e=0,i=t.points.length;e=i){const t=s[r]-i,n=this.curves[r],a=n.getLength(),o=0===a?0:1-t/a;return n.getPointAt(o,e)}r++}return null}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){this.needsUpdate=!0,this.cacheLengths=null,this.getCurveLengths()}getCurveLengths(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;const t=[];let e=0;for(let i=0,s=this.curves.length;i1&&!e[e.length-1].equals(e[0])&&e.push(e[0]),e}copy(t){super.copy(t),this.curves=[];for(let e=0,i=t.curves.length;e0){const t=h.getPoint(0);t.equals(this.currentPoint)||this.lineTo(t.x,t.y)}this.curves.push(h);const l=h.getPoint(1);return this.currentPoint.copy(l),this}copy(t){return super.copy(t),this.currentPoint.copy(t.currentPoint),this}toJSON(){const t=super.toJSON();return t.currentPoint=this.currentPoint.toArray(),t}fromJSON(t){return super.fromJSON(t),this.currentPoint.fromArray(t.currentPoint),this}}class ll extends hl{constructor(t){super(t),this.uuid=ys(),this.type="Shape",this.holes=[]}getPointsHoles(t){const e=[];for(let i=0,s=this.holes.length;i80*i){o=t[0],h=t[1];let e=o,s=h;for(let n=i;ne&&(e=i),r>s&&(s=r)}l=Math.max(e-o,s-h),l=0!==l?32767/l:0}return pl(n,a,i,o,h,l,0),a}function ul(t,e,i,s,r){let n;if(r===function(t,e,i,s){let r=0;for(let n=e,a=i-s;n0)for(let r=e;r=e;r-=s)n=Pl(r/s|0,t[r],t[r+1],n);return n&&zl(n,n.next)&&(Rl(n),n=n.next),n}function dl(t,e){if(!t)return t;e||(e=t);let i,s=t;do{if(i=!1,s.steiner||!zl(s,s.next)&&0!==Tl(s.prev,s,s.next))s=s.next;else{if(Rl(s),s=e=s.prev,s===s.next)break;i=!0}}while(i||s!==e);return e}function pl(t,e,i,s,r,n,a){if(!t)return;!a&&n&&function(t,e,i,s){let r=t;do{0===r.z&&(r.z=wl(r.x,r.y,e,i,s)),r.prevZ=r.prev,r.nextZ=r.next,r=r.next}while(r!==t);r.prevZ.nextZ=null,r.prevZ=null,function(t){let e,i=1;do{let s,r=t;t=null;let n=null;for(e=0;r;){e++;let a=r,o=0;for(let t=0;t0||h>0&&a;)0!==o&&(0===h||!a||r.z<=a.z)?(s=r,r=r.nextZ,o--):(s=a,a=a.nextZ,h--),n?n.nextZ=s:t=s,s.prevZ=n,n=s;r=a}n.nextZ=null,i*=2}while(e>1)}(r)}(t,s,r,n);let o=t;for(;t.prev!==t.next;){const h=t.prev,l=t.next;if(n?yl(t,s,r,n):ml(t))e.push(h.i,t.i,l.i),Rl(t),t=l.next,o=l.next;else if((t=l)===o){a?1===a?pl(t=gl(dl(t),e),e,i,s,r,n,2):2===a&&fl(t,e,i,s,r,n):pl(dl(t),e,i,s,r,n,1);break}}}function ml(t){const e=t.prev,i=t,s=t.next;if(Tl(e,i,s)>=0)return!1;const r=e.x,n=i.x,a=s.x,o=e.y,h=i.y,l=s.y,c=Math.min(r,n,a),u=Math.min(o,h,l),d=Math.max(r,n,a),p=Math.max(o,h,l);let m=s.next;for(;m!==e;){if(m.x>=c&&m.x<=d&&m.y>=u&&m.y<=p&&_l(r,o,n,h,a,l,m.x,m.y)&&Tl(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function yl(t,e,i,s){const r=t.prev,n=t,a=t.next;if(Tl(r,n,a)>=0)return!1;const o=r.x,h=n.x,l=a.x,c=r.y,u=n.y,d=a.y,p=Math.min(o,h,l),m=Math.min(c,u,d),y=Math.max(o,h,l),g=Math.max(c,u,d),f=wl(p,m,e,i,s),x=wl(y,g,e,i,s);let b=t.prevZ,v=t.nextZ;for(;b&&b.z>=f&&v&&v.z<=x;){if(b.x>=p&&b.x<=y&&b.y>=m&&b.y<=g&&b!==r&&b!==a&&_l(o,c,h,u,l,d,b.x,b.y)&&Tl(b.prev,b,b.next)>=0)return!1;if(b=b.prevZ,v.x>=p&&v.x<=y&&v.y>=m&&v.y<=g&&v!==r&&v!==a&&_l(o,c,h,u,l,d,v.x,v.y)&&Tl(v.prev,v,v.next)>=0)return!1;v=v.nextZ}for(;b&&b.z>=f;){if(b.x>=p&&b.x<=y&&b.y>=m&&b.y<=g&&b!==r&&b!==a&&_l(o,c,h,u,l,d,b.x,b.y)&&Tl(b.prev,b,b.next)>=0)return!1;b=b.prevZ}for(;v&&v.z<=x;){if(v.x>=p&&v.x<=y&&v.y>=m&&v.y<=g&&v!==r&&v!==a&&_l(o,c,h,u,l,d,v.x,v.y)&&Tl(v.prev,v,v.next)>=0)return!1;v=v.nextZ}return!0}function gl(t,e){let i=t;do{const s=i.prev,r=i.next.next;!zl(s,r)&&Cl(s,i,i.next,r)&&kl(s,r)&&kl(r,s)&&(e.push(s.i,i.i,r.i),Rl(i),Rl(i.next),i=t=r),i=i.next}while(i!==t);return dl(i)}function fl(t,e,i,s,r,n){let a=t;do{let t=a.next.next;for(;t!==a.prev;){if(a.i!==t.i&&Al(a,t)){let o=Ol(a,t);return a=dl(a,a.next),o=dl(o,o.next),pl(a,e,i,s,r,n,0),void pl(o,e,i,s,r,n,0)}t=t.next}a=a.next}while(a!==t)}function xl(t,e){let i=t.x-e.x;if(0===i&&(i=t.y-e.y,0===i)){i=(t.next.y-t.y)/(t.next.x-t.x)-(e.next.y-e.y)/(e.next.x-e.x)}return i}function bl(t,e){const i=function(t,e){let i=e;const s=t.x,r=t.y;let n,a=-1/0;if(zl(t,i))return i;do{if(zl(t,i.next))return i.next;if(r<=i.y&&r>=i.next.y&&i.next.y!==i.y){const t=i.x+(r-i.y)*(i.next.x-i.x)/(i.next.y-i.y);if(t<=s&&t>a&&(a=t,n=i.x=i.x&&i.x>=h&&s!==i.x&&Sl(rn.x||i.x===n.x&&vl(n,i)))&&(n=i,c=e)}i=i.next}while(i!==o);return n}(t,e);if(!i)return e;const s=Ol(i,t);return dl(s,s.next),dl(i,i.next)}function vl(t,e){return Tl(t.prev,t,e.prev)<0&&Tl(e.next,t,t.next)<0}function wl(t,e,i,s,r){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=(t-i)*r|0)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-s)*r|0)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function Ml(t){let e=t,i=t;do{(e.x=(t-a)*(n-o)&&(t-a)*(s-o)>=(i-a)*(e-o)&&(i-a)*(n-o)>=(r-a)*(s-o)}function _l(t,e,i,s,r,n,a,o){return!(t===a&&e===o)&&Sl(t,e,i,s,r,n,a,o)}function Al(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){let i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&Cl(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(kl(t,e)&&kl(e,t)&&function(t,e){let i=t,s=!1;const r=(t.x+e.x)/2,n=(t.y+e.y)/2;do{i.y>n!=i.next.y>n&&i.next.y!==i.y&&r<(i.next.x-i.x)*(n-i.y)/(i.next.y-i.y)+i.x&&(s=!s),i=i.next}while(i!==t);return s}(t,e)&&(Tl(t.prev,t,e.prev)||Tl(t,e.prev,e))||zl(t,e)&&Tl(t.prev,t,t.next)>0&&Tl(e.prev,e,e.next)>0)}function Tl(t,e,i){return(e.y-t.y)*(i.x-e.x)-(e.x-t.x)*(i.y-e.y)}function zl(t,e){return t.x===e.x&&t.y===e.y}function Cl(t,e,i,s){const r=Bl(Tl(t,e,i)),n=Bl(Tl(t,e,s)),a=Bl(Tl(i,s,t)),o=Bl(Tl(i,s,e));return r!==n&&a!==o||(!(0!==r||!Il(t,i,e))||(!(0!==n||!Il(t,s,e))||(!(0!==a||!Il(i,t,s))||!(0!==o||!Il(i,e,s)))))}function Il(t,e,i){return e.x<=Math.max(t.x,i.x)&&e.x>=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function Bl(t){return t>0?1:t<0?-1:0}function kl(t,e){return Tl(t.prev,t,t.next)<0?Tl(t,e,t.next)>=0&&Tl(t,t.prev,e)>=0:Tl(t,e,t.prev)<0||Tl(t,t.next,e)<0}function Ol(t,e){const i=Nl(t.i,t.x,t.y),s=Nl(e.i,e.x,e.y),r=t.next,n=e.prev;return t.next=e,e.prev=t,i.next=r,r.prev=i,s.next=i,i.prev=s,n.next=s,s.prev=n,s}function Pl(t,e,i,s){const r=Nl(t,e,i);return s?(r.next=s.next,r.prev=s,s.next.prev=r,s.next=r):(r.prev=r,r.next=r),r}function Rl(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function Nl(t,e,i){return{i:t,x:e,y:i,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}class Vl{static triangulate(t,e,i=2){return cl(t,e,i)}}class Fl{static area(t){const e=t.length;let i=0;for(let s=e-1,r=0;r2&&t[e-1].equals(t[0])&&t.pop()}function Ll(t,e){for(let i=0;iNumber.EPSILON){const u=Math.sqrt(c),d=Math.sqrt(h*h+l*l),p=e.x-o/u,m=e.y+a/u,y=((i.x-l/d-p)*l-(i.y+h/d-m)*h)/(a*l-o*h);s=p+a*y-t.x,r=m+o*y-t.y;const g=s*s+r*r;if(g<=2)return new Ms(s,r);n=Math.sqrt(g/2)}else{let t=!1;a>Number.EPSILON?h>Number.EPSILON&&(t=!0):a<-Number.EPSILON?h<-Number.EPSILON&&(t=!0):Math.sign(o)===Math.sign(l)&&(t=!0),t?(s=-o,r=a,n=Math.sqrt(c)):(s=a,r=o,n=Math.sqrt(c/2))}return new Ms(s/n,r/n)}const k=[];for(let t=0,e=z.length,i=e-1,s=t+1;t=0;t--){const e=t/p,i=c*Math.cos(e*Math.PI/2),s=u*Math.sin(e*Math.PI/2)+d;for(let t=0,e=z.length;t=0;){const s=i;let r=i-1;r<0&&(r=t.length-1);for(let t=0,i=o+2*p;t0)&&d.push(e,r,h),(t!==i-1||o0!=t>0&&this.version++,this._anisotropy=t}get clearcoat(){return this._clearcoat}set clearcoat(t){this._clearcoat>0!=t>0&&this.version++,this._clearcoat=t}get iridescence(){return this._iridescence}set iridescence(t){this._iridescence>0!=t>0&&this.version++,this._iridescence=t}get dispersion(){return this._dispersion}set dispersion(t){this._dispersion>0!=t>0&&this.version++,this._dispersion=t}get sheen(){return this._sheen}set sheen(t){this._sheen>0!=t>0&&this.version++,this._sheen=t}get transmission(){return this._transmission}set transmission(t){this._transmission>0!=t>0&&this.version++,this._transmission=t}copy(t){return super.copy(t),this.defines={STANDARD:"",PHYSICAL:""},this.anisotropy=t.anisotropy,this.anisotropyRotation=t.anisotropyRotation,this.anisotropyMap=t.anisotropyMap,this.clearcoat=t.clearcoat,this.clearcoatMap=t.clearcoatMap,this.clearcoatRoughness=t.clearcoatRoughness,this.clearcoatRoughnessMap=t.clearcoatRoughnessMap,this.clearcoatNormalMap=t.clearcoatNormalMap,this.clearcoatNormalScale.copy(t.clearcoatNormalScale),this.dispersion=t.dispersion,this.ior=t.ior,this.iridescence=t.iridescence,this.iridescenceMap=t.iridescenceMap,this.iridescenceIOR=t.iridescenceIOR,this.iridescenceThicknessRange=[...t.iridescenceThicknessRange],this.iridescenceThicknessMap=t.iridescenceThicknessMap,this.sheen=t.sheen,this.sheenColor.copy(t.sheenColor),this.sheenColorMap=t.sheenColorMap,this.sheenRoughness=t.sheenRoughness,this.sheenRoughnessMap=t.sheenRoughnessMap,this.transmission=t.transmission,this.transmissionMap=t.transmissionMap,this.thickness=t.thickness,this.thicknessMap=t.thicknessMap,this.attenuationDistance=t.attenuationDistance,this.attenuationColor.copy(t.attenuationColor),this.specularIntensity=t.specularIntensity,this.specularIntensityMap=t.specularIntensityMap,this.specularColor.copy(t.specularColor),this.specularColorMap=t.specularColorMap,this}}class ac extends bn{constructor(t){super(),this.isMeshPhongMaterial=!0,this.type="MeshPhongMaterial",this.color=new gn(16777215),this.specular=new gn(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new gn(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new Pr,this.combine=0,this.reflectivity=1,this.envMapIntensity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.specular.copy(t.specular),this.shininess=t.shininess,this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.envMapIntensity=t.envMapIntensity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class oc extends bn{constructor(t){super(),this.isMeshToonMaterial=!0,this.defines={TOON:""},this.type="MeshToonMaterial",this.color=new gn(16777215),this.map=null,this.gradientMap=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new gn(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.alphaMap=null,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.gradientMap=t.gradientMap,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.alphaMap=t.alphaMap,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}class hc extends bn{constructor(t){super(),this.isMeshNormalMaterial=!0,this.type="MeshNormalMaterial",this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.flatShading=!1,this.setValues(t)}copy(t){return super.copy(t),this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.flatShading=t.flatShading,this}}class lc extends bn{constructor(t){super(),this.isMeshLambertMaterial=!0,this.type="MeshLambertMaterial",this.color=new gn(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new gn(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new Pr,this.combine=0,this.reflectivity=1,this.envMapIntensity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.envMapIntensity=t.envMapIntensity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class cc extends bn{constructor(t){super(),this.isMeshDepthMaterial=!0,this.type="MeshDepthMaterial",this.depthPacking=3200,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.setValues(t)}copy(t){return super.copy(t),this.depthPacking=t.depthPacking,this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this}}class uc extends bn{constructor(t){super(),this.isMeshDistanceMaterial=!0,this.type="MeshDistanceMaterial",this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.setValues(t)}copy(t){return super.copy(t),this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this}}class dc extends bn{constructor(t){super(),this.isMeshMatcapMaterial=!0,this.defines={MATCAP:""},this.type="MeshMatcapMaterial",this.color=new gn(16777215),this.matcap=null,this.map=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.alphaMap=null,this.wireframe=!1,this.wireframeLinewidth=1,this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.defines={MATCAP:""},this.color.copy(t.color),this.matcap=t.matcap,this.map=t.map,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.alphaMap=t.alphaMap,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.flatShading=t.flatShading,this.fog=t.fog,this}}class pc extends Ko{constructor(t){super(),this.isLineDashedMaterial=!0,this.type="LineDashedMaterial",this.scale=1,this.dashSize=3,this.gapSize=1,this.setValues(t)}copy(t){return super.copy(t),this.scale=t.scale,this.dashSize=t.dashSize,this.gapSize=t.gapSize,this}}function mc(t,e){return t&&t.constructor!==e?"number"==typeof e.BYTES_PER_ELEMENT?new e(t):Array.prototype.slice.call(t):t}function yc(t){const e=t.length,i=new Array(e);for(let t=0;t!==e;++t)i[t]=t;return i.sort(function(e,i){return t[e]-t[i]}),i}function gc(t,e,i){const s=t.length,r=new t.constructor(s);for(let n=0,a=0;a!==s;++n){const s=i[n]*e;for(let i=0;i!==e;++i)r[a++]=t[s+i]}return r}function fc(t,e,i,s){let r=1,n=t[0];for(;void 0!==n&&void 0===n[s];)n=t[r++];if(void 0===n)return;let a=n[s];if(void 0!==a)if(Array.isArray(a))do{a=n[s],void 0!==a&&(e.push(n.time),i.push(...a)),n=t[r++]}while(void 0!==n);else if(void 0!==a.toArray)do{a=n[s],void 0!==a&&(e.push(n.time),a.toArray(i,i.length)),n=t[r++]}while(void 0!==n);else do{a=n[s],void 0!==a&&(e.push(n.time),i.push(a)),n=t[r++]}while(void 0!==n)}class xc{static convertArray(t,e){return mc(t,e)}static isTypedArray(t){return Qi(t)}static getKeyframeOrder(t){return yc(t)}static sortedArray(t,e,i){return gc(t,e,i)}static flattenJSON(t,e,i,s){fc(t,e,i,s)}static subclip(t,e,i,s,r=30){return function(t,e,i,s,r=30){const n=t.clone();n.name=e;const a=[];for(let t=0;t=s)){h.push(e.times[t]);for(let i=0;in.tracks[t].times[0]&&(o=n.tracks[t].times[0]);for(let t=0;t=s.times[u]){const t=u*h+o,e=t+h-o;d=s.values.slice(t,e)}else{const t=s.createInterpolant(),e=o,i=h-o;t.evaluate(n),d=t.resultBuffer.slice(e,i)}"quaternion"===r&&(new Ss).fromArray(d).normalize().conjugate().toArray(d);const p=a.times.length;for(let t=0;t=r)){const a=e[1];t=r)break e}n=i,i=0;break i}break t}for(;i>>1;te;)--n;if(++n,0!==r||n!==s){r>=n&&(n=Math.max(n,1),r=n-1);const t=this.getValueSize();this.times=i.slice(r,n),this.values=this.values.slice(r*t,n*t)}return this}validate(){let t=!0;const e=this.getValueSize();e-Math.floor(e)!==0&&(os("KeyframeTrack: Invalid value size in track.",this),t=!1);const i=this.times,s=this.values,r=i.length;0===r&&(os("KeyframeTrack: Track is empty.",this),t=!1);let n=null;for(let e=0;e!==r;e++){const s=i[e];if("number"==typeof s&&isNaN(s)){os("KeyframeTrack: Time is not a valid number.",this,e,s),t=!1;break}if(null!==n&&n>s){os("KeyframeTrack: Out of order keys.",this,e,s,n),t=!1;break}n=s}if(void 0!==s&&Qi(s))for(let e=0,i=s.length;e!==i;++e){const i=s[e];if(isNaN(i)){os("KeyframeTrack: Value is not a valid number.",this,e,i),t=!1;break}}return t}optimize(){const t=this.times.slice(),e=this.values.slice(),i=this.getValueSize(),s=this.getInterpolation()===Ee,r=t.length-1;let n=1;for(let a=1;a0){t[n]=t[r];for(let t=r*i,s=n*i,a=0;a!==i;++a)e[s+a]=e[t+a];++n}return n!==t.length?(this.times=t.slice(0,n),this.values=e.slice(0,n*i)):(this.times=t,this.values=e),this}clone(){const t=this.times.slice(),e=this.values.slice(),i=new(0,this.constructor)(this.name,t,e);return i.createInterpolant=this.createInterpolant,i}}_c.prototype.ValueTypeName="",_c.prototype.TimeBufferType=Float32Array,_c.prototype.ValueBufferType=Float32Array,_c.prototype.DefaultInterpolation=Fe;class Ac extends _c{constructor(t,e,i){super(t,e,i)}}Ac.prototype.ValueTypeName="bool",Ac.prototype.ValueBufferType=Array,Ac.prototype.DefaultInterpolation=Ve,Ac.prototype.InterpolantFactoryMethodLinear=void 0,Ac.prototype.InterpolantFactoryMethodSmooth=void 0;class Tc extends _c{constructor(t,e,i,s){super(t,e,i,s)}}Tc.prototype.ValueTypeName="color";class zc extends _c{constructor(t,e,i,s){super(t,e,i,s)}}zc.prototype.ValueTypeName="number";class Cc extends bc{constructor(t,e,i,s){super(t,e,i,s)}interpolate_(t,e,i,s){const r=this.resultBuffer,n=this.sampleValues,a=this.valueSize,o=(i-e)/(s-e);let h=t*a;for(let t=h+a;h!==t;h+=4)Ss.slerpFlat(r,0,n,h-a,n,h,o);return r}}class Ic extends _c{constructor(t,e,i,s){super(t,e,i,s)}InterpolantFactoryMethodLinear(t){return new Cc(this.times,this.values,this.getValueSize(),t)}}Ic.prototype.ValueTypeName="quaternion",Ic.prototype.InterpolantFactoryMethodSmooth=void 0;class Bc extends _c{constructor(t,e,i){super(t,e,i)}}Bc.prototype.ValueTypeName="string",Bc.prototype.ValueBufferType=Array,Bc.prototype.DefaultInterpolation=Ve,Bc.prototype.InterpolantFactoryMethodLinear=void 0,Bc.prototype.InterpolantFactoryMethodSmooth=void 0;class kc extends _c{constructor(t,e,i,s){super(t,e,i,s)}}kc.prototype.ValueTypeName="vector";class Oc{constructor(t="",e=-1,i=[],s=2500){this.name=t,this.tracks=i,this.duration=e,this.blendMode=s,this.uuid=ys(),this.userData={},this.duration<0&&this.resetDuration()}static parse(t){const e=[],i=t.tracks,s=1/(t.fps||1);for(let t=0,r=i.length;t!==r;++t)e.push(Pc(i[t]).scale(s));const r=new this(t.name,t.duration,e,t.blendMode);return r.uuid=t.uuid,r.userData=JSON.parse(t.userData||"{}"),r}static toJSON(t){const e=[],i=t.tracks,s={name:t.name,duration:t.duration,tracks:e,uuid:t.uuid,blendMode:t.blendMode,userData:JSON.stringify(t.userData)};for(let t=0,s=i.length;t!==s;++t)e.push(_c.toJSON(i[t]));return s}static CreateFromMorphTargetSequence(t,e,i,s){const r=e.length,n=[];for(let t=0;t1){const t=n[1];let e=s[t];e||(s[t]=e=[]),e.push(i)}}const n=[];for(const t in s)n.push(this.CreateFromMorphTargetSequence(t,s[t],e,i));return n}static parseAnimation(t,e){if(as("AnimationClip: parseAnimation() is deprecated and will be removed with r185"),!t)return os("AnimationClip: No animation in JSONLoader data."),null;const i=function(t,e,i,s,r){if(0!==i.length){const n=[],a=[];fc(i,n,a,s),0!==n.length&&r.push(new t(e,n,a))}},s=[],r=t.name||"default",n=t.fps||30,a=t.blendMode;let o=t.length||-1;const h=t.hierarchy||[];for(let t=0;t{e&&e(r),this.manager.itemEnd(t)},0),r;if(void 0!==Ec[t])return void Ec[t].push({onLoad:e,onProgress:i,onError:s});Ec[t]=[],Ec[t].push({onLoad:e,onProgress:i,onError:s});const n=new Request(t,{headers:new Headers(this.requestHeader),credentials:this.withCredentials?"include":"same-origin",signal:"function"==typeof AbortSignal.any?AbortSignal.any([this._abortController.signal,this.manager.abortController.signal]):this._abortController.signal}),a=this.mimeType,o=this.responseType;fetch(n).then(e=>{if(200===e.status||0===e.status){if(0===e.status&&as("FileLoader: HTTP Status 0 received."),"undefined"==typeof ReadableStream||void 0===e.body||void 0===e.body.getReader)return e;const i=Ec[t],s=e.body.getReader(),r=e.headers.get("X-File-Size")||e.headers.get("Content-Length"),n=r?parseInt(r):0,a=0!==n;let o=0;const h=new ReadableStream({start(t){!function e(){s.read().then(({done:s,value:r})=>{if(s)t.close();else{o+=r.byteLength;const s=new ProgressEvent("progress",{lengthComputable:a,loaded:o,total:n});for(let t=0,e=i.length;t{t.error(e)})}()}});return new Response(h)}throw new Lc(`fetch for "${e.url}" responded with ${e.status}: ${e.statusText}`,e)}).then(t=>{switch(o){case"arraybuffer":return t.arrayBuffer();case"blob":return t.blob();case"document":return t.text().then(t=>(new DOMParser).parseFromString(t,a));case"json":return t.json();default:if(""===a)return t.text();{const e=/charset="?([^;"\s]*)"?/i.exec(a),i=e&&e[1]?e[1].toLowerCase():void 0,s=new TextDecoder(i);return t.arrayBuffer().then(t=>s.decode(t))}}}).then(e=>{Rc.add(`file:${t}`,e);const i=Ec[t];delete Ec[t];for(let t=0,s=i.length;t{const i=Ec[t];if(void 0===i)throw this.manager.itemError(t),e;delete Ec[t];for(let t=0,s=i.length;t{this.manager.itemEnd(t)}),this.manager.itemStart(t)}setResponseType(t){return this.responseType=t,this}setMimeType(t){return this.mimeType=t,this}abort(){return this._abortController.abort(),this._abortController=new AbortController,this}}class jc extends Fc{constructor(t){super(t)}load(t,e,i,s){const r=this,n=new Dc(this.manager);n.setPath(this.path),n.setRequestHeader(this.requestHeader),n.setWithCredentials(this.withCredentials),n.load(t,function(i){try{e(r.parse(JSON.parse(i)))}catch(e){s?s(e):os(e),r.manager.itemError(t)}},i,s)}parse(t){const e=[];for(let i=0;i0:s.vertexColors=t.vertexColors),void 0!==t.uniforms)for(const e in t.uniforms){const r=t.uniforms[e];switch(s.uniforms[e]={},r.type){case"t":s.uniforms[e].value=i(r.value);break;case"c":s.uniforms[e].value=(new gn).setHex(r.value);break;case"v2":s.uniforms[e].value=(new Ms).fromArray(r.value);break;case"v3":s.uniforms[e].value=(new _s).fromArray(r.value);break;case"v4":s.uniforms[e].value=(new Us).fromArray(r.value);break;case"m3":s.uniforms[e].value=(new zs).fromArray(r.value);break;case"m4":s.uniforms[e].value=(new Sr).fromArray(r.value);break;default:s.uniforms[e].value=r.value}}if(void 0!==t.defines&&(s.defines=t.defines),void 0!==t.vertexShader&&(s.vertexShader=t.vertexShader),void 0!==t.fragmentShader&&(s.fragmentShader=t.fragmentShader),void 0!==t.glslVersion&&(s.glslVersion=t.glslVersion),void 0!==t.extensions)for(const e in t.extensions)s.extensions[e]=t.extensions[e];if(void 0!==t.lights&&(s.lights=t.lights),void 0!==t.clipping&&(s.clipping=t.clipping),void 0!==t.size&&(s.size=t.size),void 0!==t.sizeAttenuation&&(s.sizeAttenuation=t.sizeAttenuation),void 0!==t.map&&(s.map=i(t.map)),void 0!==t.matcap&&(s.matcap=i(t.matcap)),void 0!==t.alphaMap&&(s.alphaMap=i(t.alphaMap)),void 0!==t.bumpMap&&(s.bumpMap=i(t.bumpMap)),void 0!==t.bumpScale&&(s.bumpScale=t.bumpScale),void 0!==t.normalMap&&(s.normalMap=i(t.normalMap)),void 0!==t.normalMapType&&(s.normalMapType=t.normalMapType),void 0!==t.normalScale){let e=t.normalScale;!1===Array.isArray(e)&&(e=[e,e]),s.normalScale=(new Ms).fromArray(e)}return void 0!==t.displacementMap&&(s.displacementMap=i(t.displacementMap)),void 0!==t.displacementScale&&(s.displacementScale=t.displacementScale),void 0!==t.displacementBias&&(s.displacementBias=t.displacementBias),void 0!==t.roughnessMap&&(s.roughnessMap=i(t.roughnessMap)),void 0!==t.metalnessMap&&(s.metalnessMap=i(t.metalnessMap)),void 0!==t.emissiveMap&&(s.emissiveMap=i(t.emissiveMap)),void 0!==t.emissiveIntensity&&(s.emissiveIntensity=t.emissiveIntensity),void 0!==t.specularMap&&(s.specularMap=i(t.specularMap)),void 0!==t.specularIntensityMap&&(s.specularIntensityMap=i(t.specularIntensityMap)),void 0!==t.specularColorMap&&(s.specularColorMap=i(t.specularColorMap)),void 0!==t.envMap&&(s.envMap=i(t.envMap)),void 0!==t.envMapRotation&&s.envMapRotation.fromArray(t.envMapRotation),void 0!==t.envMapIntensity&&(s.envMapIntensity=t.envMapIntensity),void 0!==t.reflectivity&&(s.reflectivity=t.reflectivity),void 0!==t.refractionRatio&&(s.refractionRatio=t.refractionRatio),void 0!==t.lightMap&&(s.lightMap=i(t.lightMap)),void 0!==t.lightMapIntensity&&(s.lightMapIntensity=t.lightMapIntensity),void 0!==t.aoMap&&(s.aoMap=i(t.aoMap)),void 0!==t.aoMapIntensity&&(s.aoMapIntensity=t.aoMapIntensity),void 0!==t.gradientMap&&(s.gradientMap=i(t.gradientMap)),void 0!==t.clearcoatMap&&(s.clearcoatMap=i(t.clearcoatMap)),void 0!==t.clearcoatRoughnessMap&&(s.clearcoatRoughnessMap=i(t.clearcoatRoughnessMap)),void 0!==t.clearcoatNormalMap&&(s.clearcoatNormalMap=i(t.clearcoatNormalMap)),void 0!==t.clearcoatNormalScale&&(s.clearcoatNormalScale=(new Ms).fromArray(t.clearcoatNormalScale)),void 0!==t.iridescenceMap&&(s.iridescenceMap=i(t.iridescenceMap)),void 0!==t.iridescenceThicknessMap&&(s.iridescenceThicknessMap=i(t.iridescenceThicknessMap)),void 0!==t.transmissionMap&&(s.transmissionMap=i(t.transmissionMap)),void 0!==t.thicknessMap&&(s.thicknessMap=i(t.thicknessMap)),void 0!==t.anisotropyMap&&(s.anisotropyMap=i(t.anisotropyMap)),void 0!==t.sheenColorMap&&(s.sheenColorMap=i(t.sheenColorMap)),void 0!==t.sheenRoughnessMap&&(s.sheenRoughnessMap=i(t.sheenRoughnessMap)),s}setTextures(t){return this.textures=t,this}createMaterialFromType(t){return uu.createMaterialFromType(t)}static createMaterialFromType(t){return new{ShadowMaterial:ic,SpriteMaterial:Pa,RawShaderMaterial:sc,ShaderMaterial:ua,PointsMaterial:ph,MeshPhysicalMaterial:nc,MeshStandardMaterial:rc,MeshPhongMaterial:ac,MeshToonMaterial:oc,MeshNormalMaterial:hc,MeshLambertMaterial:lc,MeshDepthMaterial:cc,MeshDistanceMaterial:uc,MeshBasicMaterial:vn,MeshMatcapMaterial:dc,LineDashedMaterial:pc,LineBasicMaterial:Ko,Material:bn}[t]}}class du{static extractUrlBase(t){const e=t.lastIndexOf("/");return-1===e?"./":t.slice(0,e+1)}static resolveURL(t,e){return"string"!=typeof t||""===t?"":(/^https?:\/\//i.test(e)&&/^\//.test(t)&&(e=e.replace(/(^https?:\/\/[^\/]+).*/i,"$1")),/^(https?:)?\/\//i.test(t)||/^data:.*,.*$/i.test(t)||/^blob:.*$/i.test(t)?t:e+t)}}class pu extends Xn{constructor(){super(),this.isInstancedBufferGeometry=!0,this.type="InstancedBufferGeometry",this.instanceCount=1/0}copy(t){return super.copy(t),this.instanceCount=t.instanceCount,this}toJSON(){const t=super.toJSON();return t.instanceCount=this.instanceCount,t.isInstancedBufferGeometry=!0,t}}class mu extends Fc{constructor(t){super(t)}load(t,e,i,s){const r=this,n=new Dc(r.manager);n.setPath(r.path),n.setRequestHeader(r.requestHeader),n.setWithCredentials(r.withCredentials),n.load(t,function(i){try{e(r.parse(JSON.parse(i)))}catch(e){s?s(e):os(e),r.manager.itemError(t)}},i,s)}parse(t){const e={},i={};function s(t,s){if(void 0!==e[s])return e[s];const r=t.interleavedBuffers[s],n=function(t,e){if(void 0!==i[e])return i[e];const s=t.arrayBuffers,r=s[e],n=new Uint32Array(r).buffer;return i[e]=n,n}(t,r.buffer),a=$i(r.type,n),o=new Ba(a,r.stride);return o.uuid=r.uuid,e[s]=o,o}const r=t.isInstancedBufferGeometry?new pu:new Xn,n=t.data.index;if(void 0!==n){const t=$i(n.type,n.array);r.setIndex(new In(t,1))}const a=t.data.attributes;for(const e in a){const i=a[e];let n;if(i.isInterleavedBufferAttribute){const e=s(t.data,i.data);n=new Oa(e,i.itemSize,i.offset,i.normalized)}else{const t=$i(i.type,i.array);n=new(i.isInstancedBufferAttribute?mo:In)(t,i.itemSize,i.normalized)}void 0!==i.name&&(n.name=i.name),void 0!==i.usage&&n.setUsage(i.usage),r.setAttribute(e,n)}const o=t.data.morphAttributes;if(o)for(const e in o){const i=o[e],n=[];for(let e=0,r=i.length;e0){const i=new Nc(e);r=new qc(i),r.setCrossOrigin(this.crossOrigin);for(let e=0,i=t.length;e0){s=new qc(this.manager),s.setCrossOrigin(this.crossOrigin);for(let e=0,s=t.length;e{let e=null,i=null;return void 0!==t.boundingBox&&(e=(new Gs).fromJSON(t.boundingBox)),void 0!==t.boundingSphere&&(i=(new mr).fromJSON(t.boundingSphere)),{...t,boundingBox:e,boundingSphere:i}}),n._instanceInfo=t.instanceInfo,n._availableInstanceIds=t._availableInstanceIds,n._availableGeometryIds=t._availableGeometryIds,n._nextIndexStart=t.nextIndexStart,n._nextVertexStart=t.nextVertexStart,n._geometryCount=t.geometryCount,n._maxInstanceCount=t.maxInstanceCount,n._maxVertexCount=t.maxVertexCount,n._maxIndexCount=t.maxIndexCount,n._geometryInitialized=t.geometryInitialized,n._matricesTexture=c(t.matricesTexture.uuid),n._indirectTexture=c(t.indirectTexture.uuid),void 0!==t.colorsTexture&&(n._colorsTexture=c(t.colorsTexture.uuid)),void 0!==t.boundingSphere&&(n.boundingSphere=(new mr).fromJSON(t.boundingSphere)),void 0!==t.boundingBox&&(n.boundingBox=(new Gs).fromJSON(t.boundingBox));break;case"LOD":n=new $a;break;case"Line":n=new oh(h(t.geometry),l(t.material));break;case"LineLoop":n=new dh(h(t.geometry),l(t.material));break;case"LineSegments":n=new uh(h(t.geometry),l(t.material));break;case"PointCloud":case"Points":n=new xh(h(t.geometry),l(t.material));break;case"Sprite":n=new Ya(l(t.material));break;case"Group":n=new _a;break;case"Bone":n=new ho;break;default:n=new Gr}if(n.uuid=t.uuid,void 0!==t.name&&(n.name=t.name),void 0!==t.matrix?(n.matrix.fromArray(t.matrix),void 0!==t.matrixAutoUpdate&&(n.matrixAutoUpdate=t.matrixAutoUpdate),n.matrixAutoUpdate&&n.matrix.decompose(n.position,n.quaternion,n.scale)):(void 0!==t.position&&n.position.fromArray(t.position),void 0!==t.rotation&&n.rotation.fromArray(t.rotation),void 0!==t.quaternion&&n.quaternion.fromArray(t.quaternion),void 0!==t.scale&&n.scale.fromArray(t.scale)),void 0!==t.up&&n.up.fromArray(t.up),void 0!==t.pivot&&(n.pivot=(new _s).fromArray(t.pivot)),void 0!==t.morphTargetDictionary&&(n.morphTargetDictionary=Object.assign({},t.morphTargetDictionary)),void 0!==t.morphTargetInfluences&&(n.morphTargetInfluences=t.morphTargetInfluences.slice()),void 0!==t.castShadow&&(n.castShadow=t.castShadow),void 0!==t.receiveShadow&&(n.receiveShadow=t.receiveShadow),t.shadow&&(void 0!==t.shadow.intensity&&(n.shadow.intensity=t.shadow.intensity),void 0!==t.shadow.bias&&(n.shadow.bias=t.shadow.bias),void 0!==t.shadow.normalBias&&(n.shadow.normalBias=t.shadow.normalBias),void 0!==t.shadow.radius&&(n.shadow.radius=t.shadow.radius),void 0!==t.shadow.mapSize&&n.shadow.mapSize.fromArray(t.shadow.mapSize),void 0!==t.shadow.camera&&(n.shadow.camera=this.parseObject(t.shadow.camera))),void 0!==t.visible&&(n.visible=t.visible),void 0!==t.frustumCulled&&(n.frustumCulled=t.frustumCulled),void 0!==t.renderOrder&&(n.renderOrder=t.renderOrder),void 0!==t.static&&(n.static=t.static),void 0!==t.userData&&(n.userData=t.userData),void 0!==t.layers&&(n.layers.mask=t.layers),void 0!==t.children){const a=t.children;for(let t=0;t{if(!0!==bu.has(n))return e&&e(i),r.manager.itemEnd(t),i;s&&s(bu.get(n)),r.manager.itemError(t),r.manager.itemEnd(t)}):(setTimeout(function(){e&&e(n),r.manager.itemEnd(t)},0),n);const a={};a.credentials="anonymous"===this.crossOrigin?"same-origin":"include",a.headers=this.requestHeader,a.signal="function"==typeof AbortSignal.any?AbortSignal.any([this._abortController.signal,this.manager.abortController.signal]):this._abortController.signal;const o=fetch(t,a).then(function(t){return t.blob()}).then(function(t){return createImageBitmap(t,Object.assign(r.options,{colorSpaceConversion:"none"}))}).then(function(i){return Rc.add(`image-bitmap:${t}`,i),e&&e(i),r.manager.itemEnd(t),i}).catch(function(e){s&&s(e),bu.set(o,e),Rc.remove(`image-bitmap:${t}`),r.manager.itemError(t),r.manager.itemEnd(t)});Rc.add(`image-bitmap:${t}`,o),r.manager.itemStart(t)}abort(){return this._abortController.abort(),this._abortController=new AbortController,this}}let wu;class Mu{static getContext(){return void 0===wu&&(wu=new(window.AudioContext||window.webkitAudioContext)),wu}static setContext(t){wu=t}}class Su extends Fc{constructor(t){super(t)}load(t,e,i,s){const r=this,n=new Dc(this.manager);function a(e){s?s(e):os(e),r.manager.itemError(t)}n.setResponseType("arraybuffer"),n.setPath(this.path),n.setRequestHeader(this.requestHeader),n.setWithCredentials(this.withCredentials),n.load(t,function(t){try{const i=t.slice(0);Mu.getContext().decodeAudioData(i,function(t){e(t)}).catch(a)}catch(t){a(t)}},i,s)}}const _u=new Sr,Au=new Sr,Tu=new Sr;class zu{constructor(){this.type="StereoCamera",this.aspect=1,this.eyeSep=.064,this.cameraL=new ba,this.cameraL.layers.enable(1),this.cameraL.matrixAutoUpdate=!1,this.cameraR=new ba,this.cameraR.layers.enable(2),this.cameraR.matrixAutoUpdate=!1,this._cache={focus:null,fov:null,aspect:null,near:null,far:null,zoom:null,eyeSep:null}}update(t){const e=this._cache;if(e.focus!==t.focus||e.fov!==t.fov||e.aspect!==t.aspect*this.aspect||e.near!==t.near||e.far!==t.far||e.zoom!==t.zoom||e.eyeSep!==this.eyeSep){e.focus=t.focus,e.fov=t.fov,e.aspect=t.aspect*this.aspect,e.near=t.near,e.far=t.far,e.zoom=t.zoom,e.eyeSep=this.eyeSep,Tu.copy(t.projectionMatrix);const i=e.eyeSep/2,s=i*e.near/e.focus,r=e.near*Math.tan(ps*e.fov*.5)/e.zoom;let n,a;Au.elements[12]=-i,_u.elements[12]=i,n=-r*e.aspect+s,a=r*e.aspect+s,Tu.elements[0]=2*e.near/(a-n),Tu.elements[8]=(a+n)/(a-n),this.cameraL.projectionMatrix.copy(Tu),n=-r*e.aspect-s,a=r*e.aspect-s,Tu.elements[0]=2*e.near/(a-n),Tu.elements[8]=(a+n)/(a-n),this.cameraR.projectionMatrix.copy(Tu)}this.cameraL.matrixWorld.copy(t.matrixWorld).multiply(Au),this.cameraR.matrixWorld.copy(t.matrixWorld).multiply(_u)}}class Cu extends ba{constructor(t=[]){super(),this.isArrayCamera=!0,this.isMultiViewCamera=!1,this.cameras=t}}class Iu{constructor(t=!0){this.autoStart=t,this.startTime=0,this.oldTime=0,this.elapsedTime=0,this.running=!1,as("THREE.Clock: This module has been deprecated. Please use THREE.Timer instead.")}start(){this.startTime=performance.now(),this.oldTime=this.startTime,this.elapsedTime=0,this.running=!0}stop(){this.getElapsedTime(),this.running=!1,this.autoStart=!1}getElapsedTime(){return this.getDelta(),this.elapsedTime}getDelta(){let t=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){const e=performance.now();t=(e-this.oldTime)/1e3,this.oldTime=e,this.elapsedTime+=t}return t}}const Bu=new _s,ku=new Ss,Ou=new _s,Pu=new _s,Ru=new _s;class Nu extends Gr{constructor(){super(),this.type="AudioListener",this.context=Mu.getContext(),this.gain=this.context.createGain(),this.gain.connect(this.context.destination),this.filter=null,this.timeDelta=0,this._clock=new Iu}getInput(){return this.gain}removeFilter(){return null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null),this}getFilter(){return this.filter}setFilter(t){return null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination),this.filter=t,this.gain.connect(this.filter),this.filter.connect(this.context.destination),this}getMasterVolume(){return this.gain.gain.value}setMasterVolume(t){return this.gain.gain.setTargetAtTime(t,this.context.currentTime,.01),this}updateMatrixWorld(t){super.updateMatrixWorld(t);const e=this.context.listener;if(this.timeDelta=this._clock.getDelta(),this.matrixWorld.decompose(Bu,ku,Ou),Pu.set(0,0,-1).applyQuaternion(ku),Ru.set(0,1,0).applyQuaternion(ku),e.positionX){const t=this.context.currentTime+this.timeDelta;e.positionX.linearRampToValueAtTime(Bu.x,t),e.positionY.linearRampToValueAtTime(Bu.y,t),e.positionZ.linearRampToValueAtTime(Bu.z,t),e.forwardX.linearRampToValueAtTime(Pu.x,t),e.forwardY.linearRampToValueAtTime(Pu.y,t),e.forwardZ.linearRampToValueAtTime(Pu.z,t),e.upX.linearRampToValueAtTime(Ru.x,t),e.upY.linearRampToValueAtTime(Ru.y,t),e.upZ.linearRampToValueAtTime(Ru.z,t)}else e.setPosition(Bu.x,Bu.y,Bu.z),e.setOrientation(Pu.x,Pu.y,Pu.z,Ru.x,Ru.y,Ru.z)}}class Vu extends Gr{constructor(t){super(),this.type="Audio",this.listener=t,this.context=t.context,this.gain=this.context.createGain(),this.gain.connect(t.getInput()),this.autoplay=!1,this.buffer=null,this.detune=0,this.loop=!1,this.loopStart=0,this.loopEnd=0,this.offset=0,this.duration=void 0,this.playbackRate=1,this.isPlaying=!1,this.hasPlaybackControl=!0,this.source=null,this.sourceType="empty",this._startedAt=0,this._progress=0,this._connected=!1,this.filters=[]}getOutput(){return this.gain}setNodeSource(t){return this.hasPlaybackControl=!1,this.sourceType="audioNode",this.source=t,this.connect(),this}setMediaElementSource(t){return this.hasPlaybackControl=!1,this.sourceType="mediaNode",this.source=this.context.createMediaElementSource(t),this.connect(),this}setMediaStreamSource(t){return this.hasPlaybackControl=!1,this.sourceType="mediaStreamNode",this.source=this.context.createMediaStreamSource(t),this.connect(),this}setBuffer(t){return this.buffer=t,this.sourceType="buffer",this.autoplay&&this.play(),this}play(t=0){if(!0===this.isPlaying)return void as("Audio: Audio is already playing.");if(!1===this.hasPlaybackControl)return void as("Audio: this Audio has no playback control.");this._startedAt=this.context.currentTime+t;const e=this.context.createBufferSource();return e.buffer=this.buffer,e.loop=this.loop,e.loopStart=this.loopStart,e.loopEnd=this.loopEnd,e.onended=this.onEnded.bind(this),e.start(this._startedAt,this._progress+this.offset,this.duration),this.isPlaying=!0,this.source=e,this.setDetune(this.detune),this.setPlaybackRate(this.playbackRate),this.connect()}pause(){if(!1!==this.hasPlaybackControl)return!0===this.isPlaying&&(this._progress+=Math.max(this.context.currentTime-this._startedAt,0)*this.playbackRate,!0===this.loop&&(this._progress=this._progress%(this.duration||this.buffer.duration)),this.source.stop(),this.source.onended=null,this.isPlaying=!1),this;as("Audio: this Audio has no playback control.")}stop(t=0){if(!1!==this.hasPlaybackControl)return this._progress=0,null!==this.source&&(this.source.stop(this.context.currentTime+t),this.source.onended=null),this.isPlaying=!1,this;as("Audio: this Audio has no playback control.")}connect(){if(this.filters.length>0){this.source.connect(this.filters[0]);for(let t=1,e=this.filters.length;t0){this.source.disconnect(this.filters[0]);for(let t=1,e=this.filters.length;t0&&this._mixBufferRegionAdditive(i,s,this._addIndex*e,1,e);for(let t=e,r=e+e;t!==r;++t)if(i[t]!==i[t+e]){a.setValue(i,s);break}}saveOriginalState(){const t=this.binding,e=this.buffer,i=this.valueSize,s=i*this._origIndex;t.getValue(e,s);for(let t=i,r=s;t!==r;++t)e[t]=e[s+t%i];this._setIdentity(),this.cumulativeWeight=0,this.cumulativeWeightAdditive=0}restoreOriginalState(){const t=3*this.valueSize;this.binding.setValue(this.buffer,t)}_setAdditiveIdentityNumeric(){const t=this._addIndex*this.valueSize,e=t+this.valueSize;for(let i=t;i=.5)for(let s=0;s!==r;++s)t[e+s]=t[i+s]}_slerp(t,e,i,s){Ss.slerpFlat(t,e,t,e,t,i,s)}_slerpAdditive(t,e,i,s,r){const n=this._workIndex*r;Ss.multiplyQuaternionsFlat(t,n,t,e,t,i),Ss.slerpFlat(t,e,t,e,t,n,s)}_lerp(t,e,i,s,r){const n=1-s;for(let a=0;a!==r;++a){const r=e+a;t[r]=t[r]*n+t[i+a]*s}}_lerpAdditive(t,e,i,s,r){for(let n=0;n!==r;++n){const r=e+n;t[r]=t[r]+t[i+n]*s}}}const qu="\\[\\]\\.:\\/",Ju=new RegExp("["+qu+"]","g"),Xu="[^"+qu+"]",Yu="[^"+qu.replace("\\.","")+"]",Hu=new RegExp("^"+/((?:WC+[\/:])*)/.source.replace("WC",Xu)+/(WCOD+)?/.source.replace("WCOD",Yu)+/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC",Xu)+/\.(WC+)(?:\[(.+)\])?/.source.replace("WC",Xu)+"$"),Zu=["material","materials","bones","map"];class Gu{constructor(t,e,i){this.path=e,this.parsedPath=i||Gu.parseTrackName(e),this.node=Gu.findNode(t,this.parsedPath.nodeName),this.rootNode=t,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}static create(t,e,i){return t&&t.isAnimationObjectGroup?new Gu.Composite(t,e,i):new Gu(t,e,i)}static sanitizeNodeName(t){return t.replace(/\s/g,"_").replace(Ju,"")}static parseTrackName(t){const e=Hu.exec(t);if(null===e)throw new Error("PropertyBinding: Cannot parse trackName: "+t);const i={nodeName:e[2],objectName:e[3],objectIndex:e[4],propertyName:e[5],propertyIndex:e[6]},s=i.nodeName&&i.nodeName.lastIndexOf(".");if(void 0!==s&&-1!==s){const t=i.nodeName.substring(s+1);-1!==Zu.indexOf(t)&&(i.nodeName=i.nodeName.substring(0,s),i.objectName=t)}if(null===i.propertyName||0===i.propertyName.length)throw new Error("PropertyBinding: can not parse propertyName from trackName: "+t);return i}static findNode(t,e){if(void 0===e||""===e||"."===e||-1===e||e===t.name||e===t.uuid)return t;if(t.skeleton){const i=t.skeleton.getBoneByName(e);if(void 0!==i)return i}if(t.children){const i=function(t){for(let s=0;s=r){const n=r++,l=t[n];e[l.uuid]=h,t[h]=l,e[o]=n,t[n]=a;for(let t=0,e=s;t!==e;++t){const e=i[t],s=e[n],r=e[h];e[h]=s,e[n]=r}}}this.nCachedObjects_=r}uncache(){const t=this._objects,e=this._indicesByUUID,i=this._bindings,s=i.length;let r=this.nCachedObjects_,n=t.length;for(let a=0,o=arguments.length;a!==o;++a){const o=arguments[a].uuid,h=e[o];if(void 0!==h)if(delete e[o],h0&&(e[a.uuid]=h),t[h]=a,t.pop();for(let t=0,e=s;t!==e;++t){const e=i[t];e[h]=e[r],e.pop()}}}this.nCachedObjects_=r}subscribe_(t,e){const i=this._bindingsIndicesByPath;let s=i[t];const r=this._bindings;if(void 0!==s)return r[s];const n=this._paths,a=this._parsedPaths,o=this._objects,h=o.length,l=this.nCachedObjects_,c=new Array(h);s=r.length,i[t]=s,n.push(t),a.push(e),r.push(c);for(let i=l,s=o.length;i!==s;++i){const s=o[i];c[i]=new Gu(s,t,e)}return c}unsubscribe_(t){const e=this._bindingsIndicesByPath,i=e[t];if(void 0!==i){const s=this._paths,r=this._parsedPaths,n=this._bindings,a=n.length-1,o=n[a];e[t[a]]=i,n[i]=o,n.pop(),r[i]=r[a],r.pop(),s[i]=s[a],s.pop()}}}class Qu{constructor(t,e,i=null,s=e.blendMode){this._mixer=t,this._clip=e,this._localRoot=i,this.blendMode=s;const r=e.tracks,n=r.length,a=new Array(n),o={endingStart:De,endingEnd:De};for(let t=0;t!==n;++t){const e=r[t].createInterpolant(null);a[t]=e,e.settings=o}this._interpolantSettings=o,this._interpolants=a,this._propertyBindings=new Array(n),this._cacheIndex=null,this._byClipCacheIndex=null,this._timeScaleInterpolant=null,this._weightInterpolant=null,this.loop=2201,this._loopCount=-1,this._startTime=null,this.time=0,this.timeScale=1,this._effectiveTimeScale=1,this.weight=1,this._effectiveWeight=1,this.repetitions=1/0,this.paused=!1,this.enabled=!0,this.clampWhenFinished=!1,this.zeroSlopeAtStart=!0,this.zeroSlopeAtEnd=!0}play(){return this._mixer._activateAction(this),this}stop(){return this._mixer._deactivateAction(this),this.reset()}reset(){return this.paused=!1,this.enabled=!0,this.time=0,this._loopCount=-1,this._startTime=null,this.stopFading().stopWarping()}isRunning(){return this.enabled&&!this.paused&&0!==this.timeScale&&null===this._startTime&&this._mixer._isActiveAction(this)}isScheduled(){return this._mixer._isActiveAction(this)}startAt(t){return this._startTime=t,this}setLoop(t,e){return this.loop=t,this.repetitions=e,this}setEffectiveWeight(t){return this.weight=t,this._effectiveWeight=this.enabled?t:0,this.stopFading()}getEffectiveWeight(){return this._effectiveWeight}fadeIn(t){return this._scheduleFading(t,0,1)}fadeOut(t){return this._scheduleFading(t,1,0)}crossFadeFrom(t,e,i=!1){if(t.fadeOut(e),this.fadeIn(e),!0===i){const i=this._clip.duration,s=t._clip.duration,r=s/i,n=i/s;t.warp(1,r,e),this.warp(n,1,e)}return this}crossFadeTo(t,e,i=!1){return t.crossFadeFrom(this,e,i)}stopFading(){const t=this._weightInterpolant;return null!==t&&(this._weightInterpolant=null,this._mixer._takeBackControlInterpolant(t)),this}setEffectiveTimeScale(t){return this.timeScale=t,this._effectiveTimeScale=this.paused?0:t,this.stopWarping()}getEffectiveTimeScale(){return this._effectiveTimeScale}setDuration(t){return this.timeScale=this._clip.duration/t,this.stopWarping()}syncWith(t){return this.time=t.time,this.timeScale=t.timeScale,this.stopWarping()}halt(t){return this.warp(this._effectiveTimeScale,0,t)}warp(t,e,i){const s=this._mixer,r=s.time,n=this.timeScale;let a=this._timeScaleInterpolant;null===a&&(a=s._lendControlInterpolant(),this._timeScaleInterpolant=a);const o=a.parameterPositions,h=a.sampleValues;return o[0]=r,o[1]=r+i,h[0]=t/n,h[1]=e/n,this}stopWarping(){const t=this._timeScaleInterpolant;return null!==t&&(this._timeScaleInterpolant=null,this._mixer._takeBackControlInterpolant(t)),this}getMixer(){return this._mixer}getClip(){return this._clip}getRoot(){return this._localRoot||this._mixer._root}_update(t,e,i,s){if(!this.enabled)return void this._updateWeight(t);const r=this._startTime;if(null!==r){const s=(t-r)*i;s<0||0===i?e=0:(this._startTime=null,e=i*s)}e*=this._updateTimeScale(t);const n=this._updateTime(e),a=this._updateWeight(t);if(a>0){const t=this._interpolants,e=this._propertyBindings;if(this.blendMode===qe)for(let i=0,s=t.length;i!==s;++i)t[i].evaluate(n),e[i].accumulateAdditive(a);else for(let i=0,r=t.length;i!==r;++i)t[i].evaluate(n),e[i].accumulate(s,a)}}_updateWeight(t){let e=0;if(this.enabled){e=this.weight;const i=this._weightInterpolant;if(null!==i){const s=i.evaluate(t)[0];e*=s,t>i.parameterPositions[1]&&(this.stopFading(),0===s&&(this.enabled=!1))}}return this._effectiveWeight=e,e}_updateTimeScale(t){let e=0;if(!this.paused){e=this.timeScale;const i=this._timeScaleInterpolant;if(null!==i){e*=i.evaluate(t)[0],t>i.parameterPositions[1]&&(this.stopWarping(),0===e?this.paused=!0:this.timeScale=e)}}return this._effectiveTimeScale=e,e}_updateTime(t){const e=this._clip.duration,i=this.loop;let s=this.time+t,r=this._loopCount;const n=2202===i;if(0===t)return-1===r||!n||1&~r?s:e-s;if(2200===i){-1===r&&(this._loopCount=0,this._setEndings(!0,!0,!1));t:{if(s>=e)s=e;else{if(!(s<0)){this.time=s;break t}s=0}this.clampWhenFinished?this.paused=!0:this.enabled=!1,this.time=s,this._mixer.dispatchEvent({type:"finished",action:this,direction:t<0?-1:1})}}else{if(-1===r&&(t>=0?(r=0,this._setEndings(!0,0===this.repetitions,n)):this._setEndings(0===this.repetitions,!0,n)),s>=e||s<0){const i=Math.floor(s/e);s-=e*i,r+=Math.abs(i);const a=this.repetitions-r;if(a<=0)this.clampWhenFinished?this.paused=!0:this.enabled=!1,s=t>0?e:0,this.time=s,this._mixer.dispatchEvent({type:"finished",action:this,direction:t>0?1:-1});else{if(1===a){const e=t<0;this._setEndings(e,!e,n)}else this._setEndings(!1,!1,n);this._loopCount=r,this.time=s,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:i})}}else this.time=s;if(n&&!(1&~r))return e-s}return s}_setEndings(t,e,i){const s=this._interpolantSettings;i?(s.endingStart=je,s.endingEnd=je):(s.endingStart=t?this.zeroSlopeAtStart?je:De:We,s.endingEnd=e?this.zeroSlopeAtEnd?je:De:We)}_scheduleFading(t,e,i){const s=this._mixer,r=s.time;let n=this._weightInterpolant;null===n&&(n=s._lendControlInterpolant(),this._weightInterpolant=n);const a=n.parameterPositions,o=n.sampleValues;return a[0]=r,o[0]=e,a[1]=r+t,o[1]=i,this}}const Ku=new Float32Array(1);class td extends cs{constructor(t){super(),this._root=t,this._initMemoryManager(),this._accuIndex=0,this.time=0,this.timeScale=1,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}_bindAction(t,e){const i=t._localRoot||this._root,s=t._clip.tracks,r=s.length,n=t._propertyBindings,a=t._interpolants,o=i.uuid,h=this._bindingsByRootAndName;let l=h[o];void 0===l&&(l={},h[o]=l);for(let t=0;t!==r;++t){const r=s[t],h=r.name;let c=l[h];if(void 0!==c)++c.referenceCount,n[t]=c;else{if(c=n[t],void 0!==c){null===c._cacheIndex&&(++c.referenceCount,this._addInactiveBinding(c,o,h));continue}const s=e&&e._propertyBindings[t].binding.parsedPath;c=new Uu(Gu.create(i,h,s),r.ValueTypeName,r.getValueSize()),++c.referenceCount,this._addInactiveBinding(c,o,h),n[t]=c}a[t].resultBuffer=c.buffer}}_activateAction(t){if(!this._isActiveAction(t)){if(null===t._cacheIndex){const e=(t._localRoot||this._root).uuid,i=t._clip.uuid,s=this._actionsByClip[i];this._bindAction(t,s&&s.knownActions[0]),this._addInactiveAction(t,i,e)}const e=t._propertyBindings;for(let t=0,i=e.length;t!==i;++t){const i=e[t];0===i.useCount++&&(this._lendBinding(i),i.saveOriginalState())}this._lendAction(t)}}_deactivateAction(t){if(this._isActiveAction(t)){const e=t._propertyBindings;for(let t=0,i=e.length;t!==i;++t){const i=e[t];0===--i.useCount&&(i.restoreOriginalState(),this._takeBackBinding(i))}this._takeBackAction(t)}}_initMemoryManager(){this._actions=[],this._nActiveActions=0,this._actionsByClip={},this._bindings=[],this._nActiveBindings=0,this._bindingsByRootAndName={},this._controlInterpolants=[],this._nActiveControlInterpolants=0;const t=this;this.stats={actions:{get total(){return t._actions.length},get inUse(){return t._nActiveActions}},bindings:{get total(){return t._bindings.length},get inUse(){return t._nActiveBindings}},controlInterpolants:{get total(){return t._controlInterpolants.length},get inUse(){return t._nActiveControlInterpolants}}}}_isActiveAction(t){const e=t._cacheIndex;return null!==e&&e=0;--e)t[e].stop();return this}update(t){t*=this.timeScale;const e=this._actions,i=this._nActiveActions,s=this.time+=t,r=Math.sign(t),n=this._accuIndex^=1;for(let a=0;a!==i;++a){e[a]._update(s,t,r,n)}const a=this._bindings,o=this._nActiveBindings;for(let t=0;t!==o;++t)a[t].apply(n);return this}setTime(t){this.time=0;for(let t=0;t=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y))}intersectsBox(t){return t.max.x>=this.min.x&&t.min.x<=this.max.x&&t.max.y>=this.min.y&&t.min.y<=this.max.y}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return this.clampPoint(t,gd).distanceTo(t)}intersect(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}}const xd=new _s,bd=new _s,vd=new _s,wd=new _s,Md=new _s,Sd=new _s,_d=new _s;class Ad{constructor(t=new _s,e=new _s){this.start=t,this.end=e}set(t,e){return this.start.copy(t),this.end.copy(e),this}copy(t){return this.start.copy(t.start),this.end.copy(t.end),this}getCenter(t){return t.addVectors(this.start,this.end).multiplyScalar(.5)}delta(t){return t.subVectors(this.end,this.start)}distanceSq(){return this.start.distanceToSquared(this.end)}distance(){return this.start.distanceTo(this.end)}at(t,e){return this.delta(e).multiplyScalar(t).add(this.start)}closestPointToPointParameter(t,e){xd.subVectors(t,this.start),bd.subVectors(this.end,this.start);const i=bd.dot(bd);let s=bd.dot(xd)/i;return e&&(s=gs(s,0,1)),s}closestPointToPoint(t,e,i){const s=this.closestPointToPointParameter(t,e);return this.delta(i).multiplyScalar(s).add(this.start)}distanceSqToLine3(t,e=Sd,i=_d){const s=1e-8*1e-8;let r,n;const a=this.start,o=t.start,h=this.end,l=t.end;vd.subVectors(h,a),wd.subVectors(l,o),Md.subVectors(a,o);const c=vd.dot(vd),u=wd.dot(wd),d=wd.dot(Md);if(c<=s&&u<=s)return e.copy(a),i.copy(o),e.sub(i),e.dot(e);if(c<=s)r=0,n=d/u,n=gs(n,0,1);else{const t=vd.dot(Md);if(u<=s)n=0,r=gs(-t/c,0,1);else{const e=vd.dot(wd),i=c*u-e*e;r=0!==i?gs((e*d-t*u)/i,0,1):0,n=(e*r+d)/u,n<0?(n=0,r=gs(-t/c,0,1)):n>1&&(n=1,r=gs((e-t)/c,0,1))}}return e.copy(a).add(vd.multiplyScalar(r)),i.copy(o).add(wd.multiplyScalar(n)),e.sub(i),e.dot(e)}applyMatrix4(t){return this.start.applyMatrix4(t),this.end.applyMatrix4(t),this}equals(t){return t.start.equals(this.start)&&t.end.equals(this.end)}clone(){return(new this.constructor).copy(this)}}const Td=new _s;class zd extends Gr{constructor(t,e){super(),this.light=t,this.matrixAutoUpdate=!1,this.color=e,this.type="SpotLightHelper";const i=new Xn,s=[0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,-1,0,1,0,0,0,0,1,1,0,0,0,0,-1,1];for(let t=0,e=1,i=32;t1)for(let i=0;i.99999)this.quaternion.set(0,0,0,1);else if(t.y<-.99999)this.quaternion.set(1,0,0,0);else{Qd.set(t.z,0,-t.x).normalize();const e=Math.acos(t.y);this.quaternion.setFromAxisAngle(Qd,e)}}setLength(t,e=.2*t,i=.2*e){this.line.scale.set(1,Math.max(1e-4,t-e),1),this.line.updateMatrix(),this.cone.scale.set(i,e,i),this.cone.position.y=t,this.cone.updateMatrix()}setColor(t){this.line.material.color.set(t),this.cone.material.color.set(t)}copy(t){return super.copy(t,!1),this.line.copy(t.line),this.cone.copy(t.cone),this}dispose(){this.line.geometry.dispose(),this.line.material.dispose(),this.cone.geometry.dispose(),this.cone.material.dispose()}}class ip extends uh{constructor(t=1){const e=[0,0,0,t,0,0,0,0,0,0,t,0,0,0,0,0,0,t],i=new Xn;i.setAttribute("position",new En(e,3)),i.setAttribute("color",new En([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1],3));super(i,new Ko({vertexColors:!0,toneMapped:!1})),this.type="AxesHelper"}setColors(t,e,i){const s=new gn,r=this.geometry.attributes.color.array;return s.set(t),s.toArray(r,0),s.toArray(r,3),s.set(e),s.toArray(r,6),s.toArray(r,9),s.set(i),s.toArray(r,12),s.toArray(r,15),this.geometry.attributes.color.needsUpdate=!0,this}dispose(){this.geometry.dispose(),this.material.dispose()}}class sp{constructor(){this.type="ShapePath",this.color=new gn,this.subPaths=[],this.currentPath=null}moveTo(t,e){return this.currentPath=new hl,this.subPaths.push(this.currentPath),this.currentPath.moveTo(t,e),this}lineTo(t,e){return this.currentPath.lineTo(t,e),this}quadraticCurveTo(t,e,i,s){return this.currentPath.quadraticCurveTo(t,e,i,s),this}bezierCurveTo(t,e,i,s,r,n){return this.currentPath.bezierCurveTo(t,e,i,s,r,n),this}splineThru(t){return this.currentPath.splineThru(t),this}toShapes(t){function e(t,e){const i=e.length;let s=!1;for(let r=i-1,n=0;nNumber.EPSILON){if(h<0&&(i=e[n],o=-o,a=e[r],h=-h),t.ya.y)continue;if(t.y===i.y){if(t.x===i.x)return!0}else{const e=h*(t.x-i.x)-o*(t.y-i.y);if(0===e)return!0;if(e<0)continue;s=!s}}else{if(t.y!==i.y)continue;if(a.x<=t.x&&t.x<=i.x||i.x<=t.x&&t.x<=a.x)return!0}}return s}const i=Fl.isClockWise,s=this.subPaths;if(0===s.length)return[];let r,n,a;const o=[];if(1===s.length)return n=s[0],a=new ll,a.curves=n.curves,o.push(a),o;let h=!i(s[0].getPoints());h=t?!h:h;const l=[],c=[];let u,d,p=[],m=0;c[m]=void 0,p[m]=[];for(let e=0,a=s.length;e1){let t=!1,i=0;for(let t=0,e=c.length;t0&&!1===t&&(p=l)}for(let t=0,e=c.length;te?(t.repeat.x=1,t.repeat.y=i/e,t.offset.x=0,t.offset.y=(1-t.repeat.y)/2):(t.repeat.x=e/i,t.repeat.y=1,t.offset.x=(1-t.repeat.x)/2,t.offset.y=0),t}(t,e)}static cover(t,e){return function(t,e){const i=t.image&&t.image.width?t.image.width/t.image.height:1;return i>e?(t.repeat.x=e/i,t.repeat.y=1,t.offset.x=(1-t.repeat.x)/2,t.offset.y=0):(t.repeat.x=1,t.repeat.y=i/e,t.offset.x=0,t.offset.y=(1-t.repeat.y)/2),t}(t,e)}static fill(t){return function(t){return t.repeat.x=1,t.repeat.y=1,t.offset.x=0,t.offset.y=0,t}(t)}static getByteLength(t,e,i,s){return np(t,e,i,s)}}"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register",{detail:{revision:t}})),"undefined"!=typeof window&&(window.__THREE__?as("WARNING: Multiple instances of Three.js being imported."):window.__THREE__=t);export{it as ACESFilmicToneMapping,w as AddEquation,$ as AddOperation,qe as AdditiveAnimationBlendMode,g as AdditiveBlending,rt as AgXToneMapping,Dt as AlphaFormat,ki as AlwaysCompare,W as AlwaysDepth,Si as AlwaysStencilFunc,ou as AmbientLight,Qu as AnimationAction,Oc as AnimationClip,jc as AnimationLoader,td as AnimationMixer,$u as AnimationObjectGroup,xc as AnimationUtils,Uh as ArcCurve,Cu as ArrayCamera,ep as ArrowHelper,at as AttachedBindMode,Vu as Audio,Wu as AudioAnalyser,Mu as AudioContext,Nu as AudioListener,Su as AudioLoader,ip as AxesHelper,d as BackSide,He as BasicDepthPacking,o as BasicShadowMap,Qo as BatchedMesh,Sc as BezierInterpolant,ho as Bone,Ac as BooleanKeyframeTrack,fd as Box2,Gs as Box3,Gd as Box3Helper,aa as BoxGeometry,Zd as BoxHelper,In as BufferAttribute,Xn as BufferGeometry,mu as BufferGeometryLoader,Ct as ByteType,Rc as Cache,ya as Camera,Xd as CameraHelper,Th as CanvasTexture,Bh as CapsuleGeometry,Zh as CatmullRomCurve3,et as CineonToneMapping,kh as CircleGeometry,yt as ClampToEdgeWrapping,Iu as Clock,gn as Color,Tc as ColorKeyframeTrack,Os as ColorManagement,Hi as Compatibility,_h as CompressedArrayTexture,Ah as CompressedCubeTexture,Sh as CompressedTexture,Wc as CompressedTextureLoader,Ph as ConeGeometry,L as ConstantAlphaFactor,F as ConstantColorFactor,rp as Controls,wa as CubeCamera,Ch as CubeDepthTexture,lt as CubeReflectionMapping,ct as CubeRefractionMapping,Ma as CubeTexture,Jc as CubeTextureLoader,pt as CubeUVReflectionMapping,Kh as CubicBezierCurve,tl as CubicBezierCurve3,vc as CubicInterpolant,r as CullFaceBack,n as CullFaceFront,a as CullFaceFrontBack,s as CullFaceNone,jh as Curve,ol as CurvePath,b as CustomBlending,st as CustomToneMapping,Oh as CylinderGeometry,md as Cylindrical,Hs as Data3DTexture,Xs as DataArrayTexture,lo as DataTexture,Xc as DataTextureLoader,An as DataUtils,di as DecrementStencilOp,mi as DecrementWrapStencilOp,Vc as DefaultLoadingManager,Ut as DepthFormat,qt as DepthStencilFormat,zh as DepthTexture,ot as DetachedBindMode,au as DirectionalLight,Ud as DirectionalLightHelper,Mc as DiscreteInterpolant,Nh as DodecahedronGeometry,p as DoubleSide,O as DstAlphaFactor,R as DstColorFactor,Li as DynamicCopyUsage,Pi as DynamicDrawUsage,Vi as DynamicReadUsage,Dh as EdgesGeometry,Wh as EllipseCurve,Ti as EqualCompare,J as EqualDepth,xi as EqualStencilFunc,ut as EquirectangularReflectionMapping,dt as EquirectangularRefractionMapping,Pr as Euler,cs as EventDispatcher,Ih as ExternalTexture,Dl as ExtrudeGeometry,Dc as FileLoader,Fn as Float16BufferAttribute,En as Float32BufferAttribute,Pt as FloatType,Ca as Fog,za as FogExp2,Mh as FramebufferTexture,u as FrontSide,Bo as Frustum,Po as FrustumArray,ad as GLBufferAttribute,ji as GLSL1,Wi as GLSL3,Ci as GreaterCompare,Y as GreaterDepth,Bi as GreaterEqualCompare,X as GreaterEqualDepth,Mi as GreaterEqualStencilFunc,vi as GreaterStencilFunc,Ed as GridHelper,_a as Group,Rt as HalfFloatType,Zc as HemisphereLight,Fd as HemisphereLightHelper,Wl as IcosahedronGeometry,vu as ImageBitmapLoader,qc as ImageLoader,Vs as ImageUtils,ui as IncrementStencilOp,pi as IncrementWrapStencilOp,mo as InstancedBufferAttribute,pu as InstancedBufferGeometry,nd as InstancedInterleavedBuffer,Mo as InstancedMesh,Pn as Int16BufferAttribute,Nn as Int32BufferAttribute,Bn as Int8BufferAttribute,kt as IntType,Ba as InterleavedBuffer,Oa as InterleavedBufferAttribute,bc as Interpolant,Le as InterpolateBezier,Ve as InterpolateDiscrete,Fe as InterpolateLinear,Ee as InterpolateSmooth,Yi as InterpolationSamplingMode,Xi as InterpolationSamplingType,yi as InvertStencilOp,li as KeepStencilOp,_c as KeyframeTrack,$a as LOD,Ul as LatheGeometry,Rr as Layers,Ai as LessCompare,U as LessDepth,zi as LessEqualCompare,q as LessEqualDepth,bi as LessEqualStencilFunc,fi as LessStencilFunc,Hc as Light,cu as LightProbe,oh as Line,Ad as Line3,Ko as LineBasicMaterial,el as LineCurve,il as LineCurve3,pc as LineDashedMaterial,dh as LineLoop,uh as LineSegments,Mt as LinearFilter,wc as LinearInterpolant,Tt as LinearMipMapLinearFilter,_t as LinearMipMapNearestFilter,At as LinearMipmapLinearFilter,St as LinearMipmapNearestFilter,ii as LinearSRGBColorSpace,K as LinearToneMapping,si as LinearTransfer,Fc as Loader,du as LoaderUtils,Nc as LoadingManager,Pe as LoopOnce,Ne as LoopPingPong,Re as LoopRepeat,e as MOUSE,bn as Material,v as MaterialBlending,uu as MaterialLoader,ws as MathUtils,yd as Matrix2,zs as Matrix3,Sr as Matrix4,A as MaxEquation,ra as Mesh,vn as MeshBasicMaterial,cc as MeshDepthMaterial,uc as MeshDistanceMaterial,lc as MeshLambertMaterial,dc as MeshMatcapMaterial,hc as MeshNormalMaterial,ac as MeshPhongMaterial,nc as MeshPhysicalMaterial,rc as MeshStandardMaterial,oc as MeshToonMaterial,_ as MinEquation,gt as MirroredRepeatWrapping,G as MixOperation,x as MultiplyBlending,Z as MultiplyOperation,ft as NearestFilter,wt as NearestMipMapLinearFilter,bt as NearestMipMapNearestFilter,vt as NearestMipmapLinearFilter,xt as NearestMipmapNearestFilter,nt as NeutralToneMapping,_i as NeverCompare,j as NeverDepth,gi as NeverStencilFunc,m as NoBlending,ti as NoColorSpace,ni as NoNormalPacking,Q as NoToneMapping,Ue as NormalAnimationBlendMode,y as NormalBlending,oi as NormalGAPacking,ai as NormalRGPacking,Ii as NotEqualCompare,H as NotEqualDepth,wi as NotEqualStencilFunc,zc as NumberKeyframeTrack,Gr as Object3D,yu as ObjectLoader,Ke as ObjectSpaceNormalMap,ql as OctahedronGeometry,z as OneFactor,D as OneMinusConstantAlphaFactor,E as OneMinusConstantColorFactor,P as OneMinusDstAlphaFactor,N as OneMinusDstColorFactor,k as OneMinusSrcAlphaFactor,I as OneMinusSrcColorFactor,ru as OrthographicCamera,h as PCFShadowMap,l as PCFSoftShadowMap,hl as Path,ba as PerspectiveCamera,To as Plane,Jl as PlaneGeometry,$d as PlaneHelper,su as PointLight,Pd as PointLightHelper,xh as Points,ph as PointsMaterial,Ld as PolarGridHelper,Rh as PolyhedronGeometry,ju as PositionalAudio,Gu as PropertyBinding,Uu as PropertyMixer,sl as QuadraticBezierCurve,rl as QuadraticBezierCurve3,Ss as Quaternion,Ic as QuaternionKeyframeTrack,Cc as QuaternionLinearInterpolant,he as R11_EAC_Format,ms as RAD2DEG,ke as RED_GREEN_RGTC2_Format,Ie as RED_RGTC1_Format,t as REVISION,ce as RG11_EAC_Format,Ze as RGBADepthPacking,Wt as RGBAFormat,Gt as RGBAIntegerFormat,Se as RGBA_ASTC_10x10_Format,ve as RGBA_ASTC_10x5_Format,we as RGBA_ASTC_10x6_Format,Me as RGBA_ASTC_10x8_Format,_e as RGBA_ASTC_12x10_Format,Ae as RGBA_ASTC_12x12_Format,de as RGBA_ASTC_4x4_Format,pe as RGBA_ASTC_5x4_Format,me as RGBA_ASTC_5x5_Format,ye as RGBA_ASTC_6x5_Format,ge as RGBA_ASTC_6x6_Format,fe as RGBA_ASTC_8x5_Format,xe as RGBA_ASTC_8x6_Format,be as RGBA_ASTC_8x8_Format,Te as RGBA_BPTC_Format,oe as RGBA_ETC2_EAC_Format,re as RGBA_PVRTC_2BPPV1_Format,se as RGBA_PVRTC_4BPPV1_Format,Qt as RGBA_S3TC_DXT1_Format,Kt as RGBA_S3TC_DXT3_Format,te as RGBA_S3TC_DXT5_Format,Ge as RGBDepthPacking,jt as RGBFormat,Zt as RGBIntegerFormat,ze as RGB_BPTC_SIGNED_Format,Ce as RGB_BPTC_UNSIGNED_Format,ne as RGB_ETC1_Format,ae as RGB_ETC2_Format,ie as RGB_PVRTC_2BPPV1_Format,ee as RGB_PVRTC_4BPPV1_Format,$t as RGB_S3TC_DXT1_Format,$e as RGDepthPacking,Yt as RGFormat,Ht as RGIntegerFormat,sc as RawShaderMaterial,Mr as Ray,hd as Raycaster,hu as RectAreaLight,Jt as RedFormat,Xt as RedIntegerFormat,tt as ReinhardToneMapping,qs as RenderTarget,ed as RenderTarget3D,mt as RepeatWrapping,ci as ReplaceStencilOp,S as ReverseSubtractEquation,Xl as RingGeometry,le as SIGNED_R11_EAC_Format,Oe as SIGNED_RED_GREEN_RGTC2_Format,Be as SIGNED_RED_RGTC1_Format,ue as SIGNED_RG11_EAC_Format,ei as SRGBColorSpace,ri as SRGBTransfer,Ia as Scene,ua as ShaderMaterial,ic as ShadowMaterial,ll as Shape,Yl as ShapeGeometry,sp as ShapePath,Fl as ShapeUtils,It as ShortType,po as Skeleton,kd as SkeletonHelper,oo as SkinnedMesh,Es as Source,mr as Sphere,Hl as SphereGeometry,pd as Spherical,lu as SphericalHarmonics3,nl as SplineCurve,eu as SpotLight,zd as SpotLightHelper,Ya as Sprite,Pa as SpriteMaterial,B as SrcAlphaFactor,V as SrcAlphaSaturateFactor,C as SrcColorFactor,Ei as StaticCopyUsage,Oi as StaticDrawUsage,Ni as StaticReadUsage,zu as StereoCamera,Di as StreamCopyUsage,Ri as StreamDrawUsage,Fi as StreamReadUsage,Bc as StringKeyframeTrack,M as SubtractEquation,f as SubtractiveBlending,i as TOUCH,Qe as TangentSpaceNormalMap,Zl as TetrahedronGeometry,Ws as Texture,Yc as TextureLoader,ap as TextureUtils,ud as Timer,Ji as TimestampQuery,Gl as TorusGeometry,$l as TorusKnotGeometry,un as Triangle,Ye as TriangleFanDrawMode,Xe as TriangleStripDrawMode,Je as TrianglesDrawMode,Ql as TubeGeometry,ht as UVMapping,Rn as Uint16BufferAttribute,Vn as Uint32BufferAttribute,kn as Uint8BufferAttribute,On as Uint8ClampedBufferAttribute,id as Uniform,rd as UniformsGroup,ca as UniformsUtils,zt as UnsignedByteType,Lt as UnsignedInt101111Type,Ft as UnsignedInt248Type,Et as UnsignedInt5999Type,Ot as UnsignedIntType,Nt as UnsignedShort4444Type,Vt as UnsignedShort5551Type,Bt as UnsignedShortType,c as VSMShadowMap,Ms as Vector2,_s as Vector3,Us as Vector4,kc as VectorKeyframeTrack,wh as VideoFrameTexture,vh as VideoTexture,Zs as WebGL3DRenderTarget,Ys as WebGLArrayRenderTarget,Ui as WebGLCoordinateSystem,Sa as WebGLCubeRenderTarget,Js as WebGLRenderTarget,qi as WebGPUCoordinateSystem,Ta as WebXRController,Kl as WireframeGeometry,We as WrapAroundEnding,De as ZeroCurvatureEnding,T as ZeroFactor,je as ZeroSlopeEnding,hi as ZeroStencilOp,Zi as arrayNeedsUint32,oa as cloneUniforms,ts as createCanvasElement,Ki as createElementNS,os as error,np as getByteLength,rs as getConsoleFunction,la as getUnlitUniformColorSpace,Qi as isTypedArray,ns as log,ha as mergeUniforms,ls as probeAsync,ss as setConsoleFunction,as as warn,hs as warnOnce}; +const t="183dev",e={LEFT:0,MIDDLE:1,RIGHT:2,ROTATE:0,DOLLY:1,PAN:2},i={ROTATE:0,PAN:1,DOLLY_PAN:2,DOLLY_ROTATE:3},s=0,r=1,n=2,a=3,o=0,h=1,l=2,c=3,u=0,d=1,p=2,m=0,y=1,g=2,f=3,x=4,b=5,v=6,w=100,M=101,S=102,_=103,A=104,T=200,z=201,C=202,I=203,B=204,k=205,O=206,P=207,R=208,N=209,V=210,E=211,F=212,L=213,D=214,j=0,W=1,U=2,J=3,q=4,X=5,Y=6,H=7,Z=0,G=1,$=2,Q=0,K=1,tt=2,et=3,it=4,st=5,rt=6,nt=7,at="attached",ot="detached",ht=300,lt=301,ct=302,ut=303,dt=304,pt=306,mt=1e3,yt=1001,gt=1002,ft=1003,xt=1004,bt=1004,vt=1005,wt=1005,Mt=1006,St=1007,_t=1007,At=1008,Tt=1008,zt=1009,Ct=1010,It=1011,Bt=1012,kt=1013,Ot=1014,Pt=1015,Rt=1016,Nt=1017,Vt=1018,Et=1020,Ft=35902,Lt=35899,Dt=1021,jt=1022,Wt=1023,Ut=1026,Jt=1027,qt=1028,Xt=1029,Yt=1030,Ht=1031,Zt=1032,Gt=1033,$t=33776,Qt=33777,Kt=33778,te=33779,ee=35840,ie=35841,se=35842,re=35843,ne=36196,ae=37492,oe=37496,he=37488,le=37489,ce=37490,ue=37491,de=37808,pe=37809,me=37810,ye=37811,ge=37812,fe=37813,xe=37814,be=37815,ve=37816,we=37817,Me=37818,Se=37819,_e=37820,Ae=37821,Te=36492,ze=36494,Ce=36495,Ie=36283,Be=36284,ke=36285,Oe=36286,Pe=2200,Re=2201,Ne=2202,Ve=2300,Ee=2301,Fe=2302,Le=2303,De=2400,je=2401,We=2402,Ue=2500,Je=2501,qe=0,Xe=1,Ye=2,He=3200,Ze=3201,Ge=3202,$e=3203,Qe=0,Ke=1,ti="",ei="srgb",ii="srgb-linear",si="linear",ri="srgb",ni="",ai="rg",oi="ga",hi=0,li=7680,ci=7681,ui=7682,di=7683,pi=34055,mi=34056,yi=5386,gi=512,fi=513,xi=514,bi=515,vi=516,wi=517,Mi=518,Si=519,_i=512,Ai=513,Ti=514,zi=515,Ci=516,Ii=517,Bi=518,ki=519,Oi=35044,Pi=35048,Ri=35040,Ni=35045,Vi=35049,Ei=35041,Fi=35046,Li=35050,Di=35042,ji="100",Wi="300 es",Ui=2e3,Ji=2001,qi={COMPUTE:"compute",RENDER:"render"},Xi={PERSPECTIVE:"perspective",LINEAR:"linear",FLAT:"flat"},Yi={NORMAL:"normal",CENTROID:"centroid",SAMPLE:"sample",FIRST:"first",EITHER:"either"},Hi={TEXTURE_COMPARE:"depthTextureCompare"};function Zi(t){for(let e=t.length-1;e>=0;--e)if(t[e]>=65535)return!0;return!1}const Gi={Int8Array:Int8Array,Uint8Array:Uint8Array,Uint8ClampedArray:Uint8ClampedArray,Int16Array:Int16Array,Uint16Array:Uint16Array,Int32Array:Int32Array,Uint32Array:Uint32Array,Float32Array:Float32Array,Float64Array:Float64Array};function $i(t,e){return new Gi[t](e)}function Qi(t){return ArrayBuffer.isView(t)&&!(t instanceof DataView)}function Ki(t){return document.createElementNS("http://www.w3.org/1999/xhtml",t)}function ts(){const t=Ki("canvas");return t.style.display="block",t}const es={};let is=null;function ss(t){is=t}function rs(){return is}function ns(...t){const e="THREE."+t.shift();is?is("log",e,...t):console.log(e,...t)}function as(...t){const e="THREE."+t.shift();is?is("warn",e,...t):console.warn(e,...t)}function os(...t){const e="THREE."+t.shift();is?is("error",e,...t):console.error(e,...t)}function hs(...t){const e=t.join(" ");e in es||(es[e]=!0,as(...t))}function ls(t,e,i){return new Promise(function(s,r){setTimeout(function n(){switch(t.clientWaitSync(e,t.SYNC_FLUSH_COMMANDS_BIT,0)){case t.WAIT_FAILED:r();break;case t.TIMEOUT_EXPIRED:setTimeout(n,i);break;default:s()}},i)})}class cs{addEventListener(t,e){void 0===this._listeners&&(this._listeners={});const i=this._listeners;void 0===i[t]&&(i[t]=[]),-1===i[t].indexOf(e)&&i[t].push(e)}hasEventListener(t,e){const i=this._listeners;return void 0!==i&&(void 0!==i[t]&&-1!==i[t].indexOf(e))}removeEventListener(t,e){const i=this._listeners;if(void 0===i)return;const s=i[t];if(void 0!==s){const t=s.indexOf(e);-1!==t&&s.splice(t,1)}}dispatchEvent(t){const e=this._listeners;if(void 0===e)return;const i=e[t.type];if(void 0!==i){t.target=this;const e=i.slice(0);for(let i=0,s=e.length;i>8&255]+us[t>>16&255]+us[t>>24&255]+"-"+us[255&e]+us[e>>8&255]+"-"+us[e>>16&15|64]+us[e>>24&255]+"-"+us[63&i|128]+us[i>>8&255]+"-"+us[i>>16&255]+us[i>>24&255]+us[255&s]+us[s>>8&255]+us[s>>16&255]+us[s>>24&255]).toLowerCase()}function gs(t,e,i){return Math.max(e,Math.min(i,t))}function fs(t,e){return(t%e+e)%e}function xs(t,e,i){return(1-i)*t+i*e}function bs(t,e){switch(e.constructor){case Float32Array:return t;case Uint32Array:return t/4294967295;case Uint16Array:return t/65535;case Uint8Array:return t/255;case Int32Array:return Math.max(t/2147483647,-1);case Int16Array:return Math.max(t/32767,-1);case Int8Array:return Math.max(t/127,-1);default:throw new Error("Invalid component type.")}}function vs(t,e){switch(e.constructor){case Float32Array:return t;case Uint32Array:return Math.round(4294967295*t);case Uint16Array:return Math.round(65535*t);case Uint8Array:return Math.round(255*t);case Int32Array:return Math.round(2147483647*t);case Int16Array:return Math.round(32767*t);case Int8Array:return Math.round(127*t);default:throw new Error("Invalid component type.")}}const ws={DEG2RAD:ps,RAD2DEG:ms,generateUUID:ys,clamp:gs,euclideanModulo:fs,mapLinear:function(t,e,i,s,r){return s+(t-e)*(r-s)/(i-e)},inverseLerp:function(t,e,i){return t!==e?(i-t)/(e-t):0},lerp:xs,damp:function(t,e,i,s){return xs(t,e,1-Math.exp(-i*s))},pingpong:function(t,e=1){return e-Math.abs(fs(t,2*e)-e)},smoothstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*(3-2*t)},smootherstep:function(t,e,i){return t<=e?0:t>=i?1:(t=(t-e)/(i-e))*t*t*(t*(6*t-15)+10)},randInt:function(t,e){return t+Math.floor(Math.random()*(e-t+1))},randFloat:function(t,e){return t+Math.random()*(e-t)},randFloatSpread:function(t){return t*(.5-Math.random())},seededRandom:function(t){void 0!==t&&(ds=t);let e=ds+=1831565813;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296},degToRad:function(t){return t*ps},radToDeg:function(t){return t*ms},isPowerOfTwo:function(t){return!(t&t-1)&&0!==t},ceilPowerOfTwo:function(t){return Math.pow(2,Math.ceil(Math.log(t)/Math.LN2))},floorPowerOfTwo:function(t){return Math.pow(2,Math.floor(Math.log(t)/Math.LN2))},setQuaternionFromProperEuler:function(t,e,i,s,r){const n=Math.cos,a=Math.sin,o=n(i/2),h=a(i/2),l=n((e+s)/2),c=a((e+s)/2),u=n((e-s)/2),d=a((e-s)/2),p=n((s-e)/2),m=a((s-e)/2);switch(r){case"XYX":t.set(o*c,h*u,h*d,o*l);break;case"YZY":t.set(h*d,o*c,h*u,o*l);break;case"ZXZ":t.set(h*u,h*d,o*c,o*l);break;case"XZX":t.set(o*c,h*m,h*p,o*l);break;case"YXY":t.set(h*p,o*c,h*m,o*l);break;case"ZYZ":t.set(h*m,h*p,o*c,o*l);break;default:as("MathUtils: .setQuaternionFromProperEuler() encountered an unknown order: "+r)}},normalize:vs,denormalize:bs};class Ms{constructor(t=0,e=0){Ms.prototype.isVector2=!0,this.x=t,this.y=e}get width(){return this.x}set width(t){this.x=t}get height(){return this.y}set height(t){this.y=t}set(t,e){return this.x=t,this.y=e,this}setScalar(t){return this.x=t,this.y=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y)}copy(t){return this.x=t.x,this.y=t.y,this}add(t){return this.x+=t.x,this.y+=t.y,this}addScalar(t){return this.x+=t,this.y+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this}subScalar(t){return this.x-=t,this.y-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this}multiply(t){return this.x*=t.x,this.y*=t.y,this}multiplyScalar(t){return this.x*=t,this.y*=t,this}divide(t){return this.x/=t.x,this.y/=t.y,this}divideScalar(t){return this.multiplyScalar(1/t)}applyMatrix3(t){const e=this.x,i=this.y,s=t.elements;return this.x=s[0]*e+s[3]*i+s[6],this.y=s[1]*e+s[4]*i+s[7],this}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this}clamp(t,e){return this.x=gs(this.x,t.x,e.x),this.y=gs(this.y,t.y,e.y),this}clampScalar(t,e){return this.x=gs(this.x,t,e),this.y=gs(this.y,t,e),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(gs(i,t,e))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this}negate(){return this.x=-this.x,this.y=-this.y,this}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}lengthSq(){return this.x*this.x+this.y*this.y}length(){return Math.sqrt(this.x*this.x+this.y*this.y)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)}normalize(){return this.divideScalar(this.length()||1)}angle(){return Math.atan2(-this.y,-this.x)+Math.PI}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const i=this.dot(t)/e;return Math.acos(gs(i,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y;return e*e+i*i}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this}equals(t){return t.x===this.x&&t.y===this.y}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this}rotateAround(t,e){const i=Math.cos(e),s=Math.sin(e),r=this.x-t.x,n=this.y-t.y;return this.x=r*i-n*s+t.x,this.y=r*s+n*i+t.y,this}random(){return this.x=Math.random(),this.y=Math.random(),this}*[Symbol.iterator](){yield this.x,yield this.y}}class Ss{constructor(t=0,e=0,i=0,s=1){this.isQuaternion=!0,this._x=t,this._y=e,this._z=i,this._w=s}static slerpFlat(t,e,i,s,r,n,a){let o=i[s+0],h=i[s+1],l=i[s+2],c=i[s+3],u=r[n+0],d=r[n+1],p=r[n+2],m=r[n+3];if(c!==m||o!==u||h!==d||l!==p){let t=o*u+h*d+l*p+c*m;t<0&&(u=-u,d=-d,p=-p,m=-m,t=-t);let e=1-a;if(t<.9995){const i=Math.acos(t),s=Math.sin(i);e=Math.sin(e*i)/s,o=o*e+u*(a=Math.sin(a*i)/s),h=h*e+d*a,l=l*e+p*a,c=c*e+m*a}else{o=o*e+u*a,h=h*e+d*a,l=l*e+p*a,c=c*e+m*a;const t=1/Math.sqrt(o*o+h*h+l*l+c*c);o*=t,h*=t,l*=t,c*=t}}t[e]=o,t[e+1]=h,t[e+2]=l,t[e+3]=c}static multiplyQuaternionsFlat(t,e,i,s,r,n){const a=i[s],o=i[s+1],h=i[s+2],l=i[s+3],c=r[n],u=r[n+1],d=r[n+2],p=r[n+3];return t[e]=a*p+l*c+o*d-h*u,t[e+1]=o*p+l*u+h*c-a*d,t[e+2]=h*p+l*d+a*u-o*c,t[e+3]=l*p-a*c-o*u-h*d,t}get x(){return this._x}set x(t){this._x=t,this._onChangeCallback()}get y(){return this._y}set y(t){this._y=t,this._onChangeCallback()}get z(){return this._z}set z(t){this._z=t,this._onChangeCallback()}get w(){return this._w}set w(t){this._w=t,this._onChangeCallback()}set(t,e,i,s){return this._x=t,this._y=e,this._z=i,this._w=s,this._onChangeCallback(),this}clone(){return new this.constructor(this._x,this._y,this._z,this._w)}copy(t){return this._x=t.x,this._y=t.y,this._z=t.z,this._w=t.w,this._onChangeCallback(),this}setFromEuler(t,e=!0){const i=t._x,s=t._y,r=t._z,n=t._order,a=Math.cos,o=Math.sin,h=a(i/2),l=a(s/2),c=a(r/2),u=o(i/2),d=o(s/2),p=o(r/2);switch(n){case"XYZ":this._x=u*l*c+h*d*p,this._y=h*d*c-u*l*p,this._z=h*l*p+u*d*c,this._w=h*l*c-u*d*p;break;case"YXZ":this._x=u*l*c+h*d*p,this._y=h*d*c-u*l*p,this._z=h*l*p-u*d*c,this._w=h*l*c+u*d*p;break;case"ZXY":this._x=u*l*c-h*d*p,this._y=h*d*c+u*l*p,this._z=h*l*p+u*d*c,this._w=h*l*c-u*d*p;break;case"ZYX":this._x=u*l*c-h*d*p,this._y=h*d*c+u*l*p,this._z=h*l*p-u*d*c,this._w=h*l*c+u*d*p;break;case"YZX":this._x=u*l*c+h*d*p,this._y=h*d*c+u*l*p,this._z=h*l*p-u*d*c,this._w=h*l*c-u*d*p;break;case"XZY":this._x=u*l*c-h*d*p,this._y=h*d*c-u*l*p,this._z=h*l*p+u*d*c,this._w=h*l*c+u*d*p;break;default:as("Quaternion: .setFromEuler() encountered an unknown order: "+n)}return!0===e&&this._onChangeCallback(),this}setFromAxisAngle(t,e){const i=e/2,s=Math.sin(i);return this._x=t.x*s,this._y=t.y*s,this._z=t.z*s,this._w=Math.cos(i),this._onChangeCallback(),this}setFromRotationMatrix(t){const e=t.elements,i=e[0],s=e[4],r=e[8],n=e[1],a=e[5],o=e[9],h=e[2],l=e[6],c=e[10],u=i+a+c;if(u>0){const t=.5/Math.sqrt(u+1);this._w=.25/t,this._x=(l-o)*t,this._y=(r-h)*t,this._z=(n-s)*t}else if(i>a&&i>c){const t=2*Math.sqrt(1+i-a-c);this._w=(l-o)/t,this._x=.25*t,this._y=(s+n)/t,this._z=(r+h)/t}else if(a>c){const t=2*Math.sqrt(1+a-i-c);this._w=(r-h)/t,this._x=(s+n)/t,this._y=.25*t,this._z=(o+l)/t}else{const t=2*Math.sqrt(1+c-i-a);this._w=(n-s)/t,this._x=(r+h)/t,this._y=(o+l)/t,this._z=.25*t}return this._onChangeCallback(),this}setFromUnitVectors(t,e){let i=t.dot(e)+1;return i<1e-8?(i=0,Math.abs(t.x)>Math.abs(t.z)?(this._x=-t.y,this._y=t.x,this._z=0,this._w=i):(this._x=0,this._y=-t.z,this._z=t.y,this._w=i)):(this._x=t.y*e.z-t.z*e.y,this._y=t.z*e.x-t.x*e.z,this._z=t.x*e.y-t.y*e.x,this._w=i),this.normalize()}angleTo(t){return 2*Math.acos(Math.abs(gs(this.dot(t),-1,1)))}rotateTowards(t,e){const i=this.angleTo(t);if(0===i)return this;const s=Math.min(1,e/i);return this.slerp(t,s),this}identity(){return this.set(0,0,0,1)}invert(){return this.conjugate()}conjugate(){return this._x*=-1,this._y*=-1,this._z*=-1,this._onChangeCallback(),this}dot(t){return this._x*t._x+this._y*t._y+this._z*t._z+this._w*t._w}lengthSq(){return this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w}length(){return Math.sqrt(this._x*this._x+this._y*this._y+this._z*this._z+this._w*this._w)}normalize(){let t=this.length();return 0===t?(this._x=0,this._y=0,this._z=0,this._w=1):(t=1/t,this._x=this._x*t,this._y=this._y*t,this._z=this._z*t,this._w=this._w*t),this._onChangeCallback(),this}multiply(t){return this.multiplyQuaternions(this,t)}premultiply(t){return this.multiplyQuaternions(t,this)}multiplyQuaternions(t,e){const i=t._x,s=t._y,r=t._z,n=t._w,a=e._x,o=e._y,h=e._z,l=e._w;return this._x=i*l+n*a+s*h-r*o,this._y=s*l+n*o+r*a-i*h,this._z=r*l+n*h+i*o-s*a,this._w=n*l-i*a-s*o-r*h,this._onChangeCallback(),this}slerp(t,e){let i=t._x,s=t._y,r=t._z,n=t._w,a=this.dot(t);a<0&&(i=-i,s=-s,r=-r,n=-n,a=-a);let o=1-e;if(a<.9995){const t=Math.acos(a),h=Math.sin(t);o=Math.sin(o*t)/h,e=Math.sin(e*t)/h,this._x=this._x*o+i*e,this._y=this._y*o+s*e,this._z=this._z*o+r*e,this._w=this._w*o+n*e,this._onChangeCallback()}else this._x=this._x*o+i*e,this._y=this._y*o+s*e,this._z=this._z*o+r*e,this._w=this._w*o+n*e,this.normalize();return this}slerpQuaternions(t,e,i){return this.copy(t).slerp(e,i)}random(){const t=2*Math.PI*Math.random(),e=2*Math.PI*Math.random(),i=Math.random(),s=Math.sqrt(1-i),r=Math.sqrt(i);return this.set(s*Math.sin(t),s*Math.cos(t),r*Math.sin(e),r*Math.cos(e))}equals(t){return t._x===this._x&&t._y===this._y&&t._z===this._z&&t._w===this._w}fromArray(t,e=0){return this._x=t[e],this._y=t[e+1],this._z=t[e+2],this._w=t[e+3],this._onChangeCallback(),this}toArray(t=[],e=0){return t[e]=this._x,t[e+1]=this._y,t[e+2]=this._z,t[e+3]=this._w,t}fromBufferAttribute(t,e){return this._x=t.getX(e),this._y=t.getY(e),this._z=t.getZ(e),this._w=t.getW(e),this._onChangeCallback(),this}toJSON(){return this.toArray()}_onChange(t){return this._onChangeCallback=t,this}_onChangeCallback(){}*[Symbol.iterator](){yield this._x,yield this._y,yield this._z,yield this._w}}class _s{constructor(t=0,e=0,i=0){_s.prototype.isVector3=!0,this.x=t,this.y=e,this.z=i}set(t,e,i){return void 0===i&&(i=this.z),this.x=t,this.y=e,this.z=i,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this}multiplyVectors(t,e){return this.x=t.x*e.x,this.y=t.y*e.y,this.z=t.z*e.z,this}applyEuler(t){return this.applyQuaternion(Ts.setFromEuler(t))}applyAxisAngle(t,e){return this.applyQuaternion(Ts.setFromAxisAngle(t,e))}applyMatrix3(t){const e=this.x,i=this.y,s=this.z,r=t.elements;return this.x=r[0]*e+r[3]*i+r[6]*s,this.y=r[1]*e+r[4]*i+r[7]*s,this.z=r[2]*e+r[5]*i+r[8]*s,this}applyNormalMatrix(t){return this.applyMatrix3(t).normalize()}applyMatrix4(t){const e=this.x,i=this.y,s=this.z,r=t.elements,n=1/(r[3]*e+r[7]*i+r[11]*s+r[15]);return this.x=(r[0]*e+r[4]*i+r[8]*s+r[12])*n,this.y=(r[1]*e+r[5]*i+r[9]*s+r[13])*n,this.z=(r[2]*e+r[6]*i+r[10]*s+r[14])*n,this}applyQuaternion(t){const e=this.x,i=this.y,s=this.z,r=t.x,n=t.y,a=t.z,o=t.w,h=2*(n*s-a*i),l=2*(a*e-r*s),c=2*(r*i-n*e);return this.x=e+o*h+n*c-a*l,this.y=i+o*l+a*h-r*c,this.z=s+o*c+r*l-n*h,this}project(t){return this.applyMatrix4(t.matrixWorldInverse).applyMatrix4(t.projectionMatrix)}unproject(t){return this.applyMatrix4(t.projectionMatrixInverse).applyMatrix4(t.matrixWorld)}transformDirection(t){const e=this.x,i=this.y,s=this.z,r=t.elements;return this.x=r[0]*e+r[4]*i+r[8]*s,this.y=r[1]*e+r[5]*i+r[9]*s,this.z=r[2]*e+r[6]*i+r[10]*s,this.normalize()}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this}divideScalar(t){return this.multiplyScalar(1/t)}min(t){return this.x=Math.min(this.x,t.x),this.y=Math.min(this.y,t.y),this.z=Math.min(this.z,t.z),this}max(t){return this.x=Math.max(this.x,t.x),this.y=Math.max(this.y,t.y),this.z=Math.max(this.z,t.z),this}clamp(t,e){return this.x=gs(this.x,t.x,e.x),this.y=gs(this.y,t.y,e.y),this.z=gs(this.z,t.z,e.z),this}clampScalar(t,e){return this.x=gs(this.x,t,e),this.y=gs(this.y,t,e),this.z=gs(this.z,t,e),this}clampLength(t,e){const i=this.length();return this.divideScalar(i||1).multiplyScalar(gs(i,t,e))}floor(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.z=Math.floor(this.z),this}ceil(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this.z=Math.ceil(this.z),this}round(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this.z=Math.round(this.z),this}roundToZero(){return this.x=Math.trunc(this.x),this.y=Math.trunc(this.y),this.z=Math.trunc(this.z),this}negate(){return this.x=-this.x,this.y=-this.y,this.z=-this.z,this}dot(t){return this.x*t.x+this.y*t.y+this.z*t.z}lengthSq(){return this.x*this.x+this.y*this.y+this.z*this.z}length(){return Math.sqrt(this.x*this.x+this.y*this.y+this.z*this.z)}manhattanLength(){return Math.abs(this.x)+Math.abs(this.y)+Math.abs(this.z)}normalize(){return this.divideScalar(this.length()||1)}setLength(t){return this.normalize().multiplyScalar(t)}lerp(t,e){return this.x+=(t.x-this.x)*e,this.y+=(t.y-this.y)*e,this.z+=(t.z-this.z)*e,this}lerpVectors(t,e,i){return this.x=t.x+(e.x-t.x)*i,this.y=t.y+(e.y-t.y)*i,this.z=t.z+(e.z-t.z)*i,this}cross(t){return this.crossVectors(this,t)}crossVectors(t,e){const i=t.x,s=t.y,r=t.z,n=e.x,a=e.y,o=e.z;return this.x=s*o-r*a,this.y=r*n-i*o,this.z=i*a-s*n,this}projectOnVector(t){const e=t.lengthSq();if(0===e)return this.set(0,0,0);const i=t.dot(this)/e;return this.copy(t).multiplyScalar(i)}projectOnPlane(t){return As.copy(this).projectOnVector(t),this.sub(As)}reflect(t){return this.sub(As.copy(t).multiplyScalar(2*this.dot(t)))}angleTo(t){const e=Math.sqrt(this.lengthSq()*t.lengthSq());if(0===e)return Math.PI/2;const i=this.dot(t)/e;return Math.acos(gs(i,-1,1))}distanceTo(t){return Math.sqrt(this.distanceToSquared(t))}distanceToSquared(t){const e=this.x-t.x,i=this.y-t.y,s=this.z-t.z;return e*e+i*i+s*s}manhattanDistanceTo(t){return Math.abs(this.x-t.x)+Math.abs(this.y-t.y)+Math.abs(this.z-t.z)}setFromSpherical(t){return this.setFromSphericalCoords(t.radius,t.phi,t.theta)}setFromSphericalCoords(t,e,i){const s=Math.sin(e)*t;return this.x=s*Math.sin(i),this.y=Math.cos(e)*t,this.z=s*Math.cos(i),this}setFromCylindrical(t){return this.setFromCylindricalCoords(t.radius,t.theta,t.y)}setFromCylindricalCoords(t,e,i){return this.x=t*Math.sin(e),this.y=i,this.z=t*Math.cos(e),this}setFromMatrixPosition(t){const e=t.elements;return this.x=e[12],this.y=e[13],this.z=e[14],this}setFromMatrixScale(t){const e=this.setFromMatrixColumn(t,0).length(),i=this.setFromMatrixColumn(t,1).length(),s=this.setFromMatrixColumn(t,2).length();return this.x=e,this.y=i,this.z=s,this}setFromMatrixColumn(t,e){return this.fromArray(t.elements,4*e)}setFromMatrix3Column(t,e){return this.fromArray(t.elements,3*e)}setFromEuler(t){return this.x=t._x,this.y=t._y,this.z=t._z,this}setFromColor(t){return this.x=t.r,this.y=t.g,this.z=t.b,this}equals(t){return t.x===this.x&&t.y===this.y&&t.z===this.z}fromArray(t,e=0){return this.x=t[e],this.y=t[e+1],this.z=t[e+2],this}toArray(t=[],e=0){return t[e]=this.x,t[e+1]=this.y,t[e+2]=this.z,t}fromBufferAttribute(t,e){return this.x=t.getX(e),this.y=t.getY(e),this.z=t.getZ(e),this}random(){return this.x=Math.random(),this.y=Math.random(),this.z=Math.random(),this}randomDirection(){const t=Math.random()*Math.PI*2,e=2*Math.random()-1,i=Math.sqrt(1-e*e);return this.x=i*Math.cos(t),this.y=e,this.z=i*Math.sin(t),this}*[Symbol.iterator](){yield this.x,yield this.y,yield this.z}}const As=new _s,Ts=new Ss;class zs{constructor(t,e,i,s,r,n,a,o,h){zs.prototype.isMatrix3=!0,this.elements=[1,0,0,0,1,0,0,0,1],void 0!==t&&this.set(t,e,i,s,r,n,a,o,h)}set(t,e,i,s,r,n,a,o,h){const l=this.elements;return l[0]=t,l[1]=s,l[2]=a,l[3]=e,l[4]=r,l[5]=o,l[6]=i,l[7]=n,l[8]=h,this}identity(){return this.set(1,0,0,0,1,0,0,0,1),this}copy(t){const e=this.elements,i=t.elements;return e[0]=i[0],e[1]=i[1],e[2]=i[2],e[3]=i[3],e[4]=i[4],e[5]=i[5],e[6]=i[6],e[7]=i[7],e[8]=i[8],this}extractBasis(t,e,i){return t.setFromMatrix3Column(this,0),e.setFromMatrix3Column(this,1),i.setFromMatrix3Column(this,2),this}setFromMatrix4(t){const e=t.elements;return this.set(e[0],e[4],e[8],e[1],e[5],e[9],e[2],e[6],e[10]),this}multiply(t){return this.multiplyMatrices(this,t)}premultiply(t){return this.multiplyMatrices(t,this)}multiplyMatrices(t,e){const i=t.elements,s=e.elements,r=this.elements,n=i[0],a=i[3],o=i[6],h=i[1],l=i[4],c=i[7],u=i[2],d=i[5],p=i[8],m=s[0],y=s[3],g=s[6],f=s[1],x=s[4],b=s[7],v=s[2],w=s[5],M=s[8];return r[0]=n*m+a*f+o*v,r[3]=n*y+a*x+o*w,r[6]=n*g+a*b+o*M,r[1]=h*m+l*f+c*v,r[4]=h*y+l*x+c*w,r[7]=h*g+l*b+c*M,r[2]=u*m+d*f+p*v,r[5]=u*y+d*x+p*w,r[8]=u*g+d*b+p*M,this}multiplyScalar(t){const e=this.elements;return e[0]*=t,e[3]*=t,e[6]*=t,e[1]*=t,e[4]*=t,e[7]*=t,e[2]*=t,e[5]*=t,e[8]*=t,this}determinant(){const t=this.elements,e=t[0],i=t[1],s=t[2],r=t[3],n=t[4],a=t[5],o=t[6],h=t[7],l=t[8];return e*n*l-e*a*h-i*r*l+i*a*o+s*r*h-s*n*o}invert(){const t=this.elements,e=t[0],i=t[1],s=t[2],r=t[3],n=t[4],a=t[5],o=t[6],h=t[7],l=t[8],c=l*n-a*h,u=a*o-l*r,d=h*r-n*o,p=e*c+i*u+s*d;if(0===p)return this.set(0,0,0,0,0,0,0,0,0);const m=1/p;return t[0]=c*m,t[1]=(s*h-l*i)*m,t[2]=(a*i-s*n)*m,t[3]=u*m,t[4]=(l*e-s*o)*m,t[5]=(s*r-a*e)*m,t[6]=d*m,t[7]=(i*o-h*e)*m,t[8]=(n*e-i*r)*m,this}transpose(){let t;const e=this.elements;return t=e[1],e[1]=e[3],e[3]=t,t=e[2],e[2]=e[6],e[6]=t,t=e[5],e[5]=e[7],e[7]=t,this}getNormalMatrix(t){return this.setFromMatrix4(t).invert().transpose()}transposeIntoArray(t){const e=this.elements;return t[0]=e[0],t[1]=e[3],t[2]=e[6],t[3]=e[1],t[4]=e[4],t[5]=e[7],t[6]=e[2],t[7]=e[5],t[8]=e[8],this}setUvTransform(t,e,i,s,r,n,a){const o=Math.cos(r),h=Math.sin(r);return this.set(i*o,i*h,-i*(o*n+h*a)+n+t,-s*h,s*o,-s*(-h*n+o*a)+a+e,0,0,1),this}scale(t,e){return this.premultiply(Cs.makeScale(t,e)),this}rotate(t){return this.premultiply(Cs.makeRotation(-t)),this}translate(t,e){return this.premultiply(Cs.makeTranslation(t,e)),this}makeTranslation(t,e){return t.isVector2?this.set(1,0,t.x,0,1,t.y,0,0,1):this.set(1,0,t,0,1,e,0,0,1),this}makeRotation(t){const e=Math.cos(t),i=Math.sin(t);return this.set(e,-i,0,i,e,0,0,0,1),this}makeScale(t,e){return this.set(t,0,0,0,e,0,0,0,1),this}equals(t){const e=this.elements,i=t.elements;for(let t=0;t<9;t++)if(e[t]!==i[t])return!1;return!0}fromArray(t,e=0){for(let i=0;i<9;i++)this.elements[i]=t[i+e];return this}toArray(t=[],e=0){const i=this.elements;return t[e]=i[0],t[e+1]=i[1],t[e+2]=i[2],t[e+3]=i[3],t[e+4]=i[4],t[e+5]=i[5],t[e+6]=i[6],t[e+7]=i[7],t[e+8]=i[8],t}clone(){return(new this.constructor).fromArray(this.elements)}}const Cs=new zs,Is=(new zs).set(.4123908,.3575843,.1804808,.212639,.7151687,.0721923,.0193308,.1191948,.9505322),Bs=(new zs).set(3.2409699,-1.5373832,-.4986108,-.9692436,1.8759675,.0415551,.0556301,-.203977,1.0569715);function ks(){const t={enabled:!0,workingColorSpace:ii,spaces:{},convert:function(t,e,i){return!1!==this.enabled&&e!==i&&e&&i?(this.spaces[e].transfer===ri&&(t.r=Ps(t.r),t.g=Ps(t.g),t.b=Ps(t.b)),this.spaces[e].primaries!==this.spaces[i].primaries&&(t.applyMatrix3(this.spaces[e].toXYZ),t.applyMatrix3(this.spaces[i].fromXYZ)),this.spaces[i].transfer===ri&&(t.r=Rs(t.r),t.g=Rs(t.g),t.b=Rs(t.b)),t):t},workingToColorSpace:function(t,e){return this.convert(t,this.workingColorSpace,e)},colorSpaceToWorking:function(t,e){return this.convert(t,e,this.workingColorSpace)},getPrimaries:function(t){return this.spaces[t].primaries},getTransfer:function(t){return""===t?si:this.spaces[t].transfer},getToneMappingMode:function(t){return this.spaces[t].outputColorSpaceConfig.toneMappingMode||"standard"},getLuminanceCoefficients:function(t,e=this.workingColorSpace){return t.fromArray(this.spaces[e].luminanceCoefficients)},define:function(t){Object.assign(this.spaces,t)},_getMatrix:function(t,e,i){return t.copy(this.spaces[e].toXYZ).multiply(this.spaces[i].fromXYZ)},_getDrawingBufferColorSpace:function(t){return this.spaces[t].outputColorSpaceConfig.drawingBufferColorSpace},_getUnpackColorSpace:function(t=this.workingColorSpace){return this.spaces[t].workingColorSpaceConfig.unpackColorSpace},fromWorkingColorSpace:function(e,i){return hs("ColorManagement: .fromWorkingColorSpace() has been renamed to .workingToColorSpace()."),t.workingToColorSpace(e,i)},toWorkingColorSpace:function(e,i){return hs("ColorManagement: .toWorkingColorSpace() has been renamed to .colorSpaceToWorking()."),t.colorSpaceToWorking(e,i)}},e=[.64,.33,.3,.6,.15,.06],i=[.2126,.7152,.0722],s=[.3127,.329];return t.define({[ii]:{primaries:e,whitePoint:s,transfer:si,toXYZ:Is,fromXYZ:Bs,luminanceCoefficients:i,workingColorSpaceConfig:{unpackColorSpace:ei},outputColorSpaceConfig:{drawingBufferColorSpace:ei}},[ei]:{primaries:e,whitePoint:s,transfer:ri,toXYZ:Is,fromXYZ:Bs,luminanceCoefficients:i,outputColorSpaceConfig:{drawingBufferColorSpace:ei}}}),t}const Os=ks();function Ps(t){return t<.04045?.0773993808*t:Math.pow(.9478672986*t+.0521327014,2.4)}function Rs(t){return t<.0031308?12.92*t:1.055*Math.pow(t,.41666)-.055}let Ns;class Vs{static getDataURL(t,e="image/png"){if(/^data:/i.test(t.src))return t.src;if("undefined"==typeof HTMLCanvasElement)return t.src;let i;if(t instanceof HTMLCanvasElement)i=t;else{void 0===Ns&&(Ns=Ki("canvas")),Ns.width=t.width,Ns.height=t.height;const e=Ns.getContext("2d");t instanceof ImageData?e.putImageData(t,0,0):e.drawImage(t,0,0,t.width,t.height),i=Ns}return i.toDataURL(e)}static sRGBToLinear(t){if("undefined"!=typeof HTMLImageElement&&t instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&t instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&t instanceof ImageBitmap){const e=Ki("canvas");e.width=t.width,e.height=t.height;const i=e.getContext("2d");i.drawImage(t,0,0,t.width,t.height);const s=i.getImageData(0,0,t.width,t.height),r=s.data;for(let t=0;t1),this.pmremVersion=0}get width(){return this.source.getSize(js).x}get height(){return this.source.getSize(js).y}get depth(){return this.source.getSize(js).z}get image(){return this.source.data}set image(t=null){this.source.data=t}updateMatrix(){this.matrix.setUvTransform(this.offset.x,this.offset.y,this.repeat.x,this.repeat.y,this.rotation,this.center.x,this.center.y)}addUpdateRange(t,e){this.updateRanges.push({start:t,count:e})}clearUpdateRanges(){this.updateRanges.length=0}clone(){return(new this.constructor).copy(this)}copy(t){return this.name=t.name,this.source=t.source,this.mipmaps=t.mipmaps.slice(0),this.mapping=t.mapping,this.channel=t.channel,this.wrapS=t.wrapS,this.wrapT=t.wrapT,this.magFilter=t.magFilter,this.minFilter=t.minFilter,this.anisotropy=t.anisotropy,this.format=t.format,this.internalFormat=t.internalFormat,this.type=t.type,this.offset.copy(t.offset),this.repeat.copy(t.repeat),this.center.copy(t.center),this.rotation=t.rotation,this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrix.copy(t.matrix),this.generateMipmaps=t.generateMipmaps,this.premultiplyAlpha=t.premultiplyAlpha,this.flipY=t.flipY,this.unpackAlignment=t.unpackAlignment,this.colorSpace=t.colorSpace,this.renderTarget=t.renderTarget,this.isRenderTargetTexture=t.isRenderTargetTexture,this.isArrayTexture=t.isArrayTexture,this.userData=JSON.parse(JSON.stringify(t.userData)),this.needsUpdate=!0,this}setValues(t){for(const e in t){const i=t[e];if(void 0===i){as(`Texture.setValues(): parameter '${e}' has value of undefined.`);continue}const s=this[e];void 0!==s?s&&i&&s.isVector2&&i.isVector2||s&&i&&s.isVector3&&i.isVector3||s&&i&&s.isMatrix3&&i.isMatrix3?s.copy(i):this[e]=i:as(`Texture.setValues(): property '${e}' does not exist.`)}}toJSON(t){const e=void 0===t||"string"==typeof t;if(!e&&void 0!==t.textures[this.uuid])return t.textures[this.uuid];const i={metadata:{version:4.7,type:"Texture",generator:"Texture.toJSON"},uuid:this.uuid,name:this.name,image:this.source.toJSON(t).uuid,mapping:this.mapping,channel:this.channel,repeat:[this.repeat.x,this.repeat.y],offset:[this.offset.x,this.offset.y],center:[this.center.x,this.center.y],rotation:this.rotation,wrap:[this.wrapS,this.wrapT],format:this.format,internalFormat:this.internalFormat,type:this.type,colorSpace:this.colorSpace,minFilter:this.minFilter,magFilter:this.magFilter,anisotropy:this.anisotropy,flipY:this.flipY,generateMipmaps:this.generateMipmaps,premultiplyAlpha:this.premultiplyAlpha,unpackAlignment:this.unpackAlignment};return Object.keys(this.userData).length>0&&(i.userData=this.userData),e||(t.textures[this.uuid]=i),i}dispose(){this.dispatchEvent({type:"dispose"})}transformUv(t){if(this.mapping!==ht)return t;if(t.applyMatrix3(this.matrix),t.x<0||t.x>1)switch(this.wrapS){case mt:t.x=t.x-Math.floor(t.x);break;case yt:t.x=t.x<0?0:1;break;case gt:1===Math.abs(Math.floor(t.x)%2)?t.x=Math.ceil(t.x)-t.x:t.x=t.x-Math.floor(t.x)}if(t.y<0||t.y>1)switch(this.wrapT){case mt:t.y=t.y-Math.floor(t.y);break;case yt:t.y=t.y<0?0:1;break;case gt:1===Math.abs(Math.floor(t.y)%2)?t.y=Math.ceil(t.y)-t.y:t.y=t.y-Math.floor(t.y)}return this.flipY&&(t.y=1-t.y),t}set needsUpdate(t){!0===t&&(this.version++,this.source.needsUpdate=!0)}set needsPMREMUpdate(t){!0===t&&this.pmremVersion++}}Ws.DEFAULT_IMAGE=null,Ws.DEFAULT_MAPPING=ht,Ws.DEFAULT_ANISOTROPY=1;class Us{constructor(t=0,e=0,i=0,s=1){Us.prototype.isVector4=!0,this.x=t,this.y=e,this.z=i,this.w=s}get width(){return this.z}set width(t){this.z=t}get height(){return this.w}set height(t){this.w=t}set(t,e,i,s){return this.x=t,this.y=e,this.z=i,this.w=s,this}setScalar(t){return this.x=t,this.y=t,this.z=t,this.w=t,this}setX(t){return this.x=t,this}setY(t){return this.y=t,this}setZ(t){return this.z=t,this}setW(t){return this.w=t,this}setComponent(t,e){switch(t){case 0:this.x=e;break;case 1:this.y=e;break;case 2:this.z=e;break;case 3:this.w=e;break;default:throw new Error("index is out of range: "+t)}return this}getComponent(t){switch(t){case 0:return this.x;case 1:return this.y;case 2:return this.z;case 3:return this.w;default:throw new Error("index is out of range: "+t)}}clone(){return new this.constructor(this.x,this.y,this.z,this.w)}copy(t){return this.x=t.x,this.y=t.y,this.z=t.z,this.w=void 0!==t.w?t.w:1,this}add(t){return this.x+=t.x,this.y+=t.y,this.z+=t.z,this.w+=t.w,this}addScalar(t){return this.x+=t,this.y+=t,this.z+=t,this.w+=t,this}addVectors(t,e){return this.x=t.x+e.x,this.y=t.y+e.y,this.z=t.z+e.z,this.w=t.w+e.w,this}addScaledVector(t,e){return this.x+=t.x*e,this.y+=t.y*e,this.z+=t.z*e,this.w+=t.w*e,this}sub(t){return this.x-=t.x,this.y-=t.y,this.z-=t.z,this.w-=t.w,this}subScalar(t){return this.x-=t,this.y-=t,this.z-=t,this.w-=t,this}subVectors(t,e){return this.x=t.x-e.x,this.y=t.y-e.y,this.z=t.z-e.z,this.w=t.w-e.w,this}multiply(t){return this.x*=t.x,this.y*=t.y,this.z*=t.z,this.w*=t.w,this}multiplyScalar(t){return this.x*=t,this.y*=t,this.z*=t,this.w*=t,this}applyMatrix4(t){const e=this.x,i=this.y,s=this.z,r=this.w,n=t.elements;return this.x=n[0]*e+n[4]*i+n[8]*s+n[12]*r,this.y=n[1]*e+n[5]*i+n[9]*s+n[13]*r,this.z=n[2]*e+n[6]*i+n[10]*s+n[14]*r,this.w=n[3]*e+n[7]*i+n[11]*s+n[15]*r,this}divide(t){return this.x/=t.x,this.y/=t.y,this.z/=t.z,this.w/=t.w,this}divideScalar(t){return this.multiplyScalar(1/t)}setAxisAngleFromQuaternion(t){this.w=2*Math.acos(t.w);const e=Math.sqrt(1-t.w*t.w);return e<1e-4?(this.x=1,this.y=0,this.z=0):(this.x=t.x/e,this.y=t.y/e,this.z=t.z/e),this}setAxisAngleFromRotationMatrix(t){let e,i,s,r;const n=.01,a=.1,o=t.elements,h=o[0],l=o[4],c=o[8],u=o[1],d=o[5],p=o[9],m=o[2],y=o[6],g=o[10];if(Math.abs(l-u)o&&t>f?tf?o1);this.dispose()}this.viewport.set(0,0,t,e),this.scissor.set(0,0,t,e)}clone(){return(new this.constructor).copy(this)}copy(t){this.width=t.width,this.height=t.height,this.depth=t.depth,this.scissor.copy(t.scissor),this.scissorTest=t.scissorTest,this.viewport.copy(t.viewport),this.textures.length=0;for(let e=0,i=t.textures.length;e>>0}enable(t){this.mask|=1<1){for(let t=0;t1){for(let t=0;t0&&(s.userData=this.userData),s.layers=this.layers.mask,s.matrix=this.matrix.toArray(),s.up=this.up.toArray(),null!==this.pivot&&(s.pivot=this.pivot.toArray()),!1===this.matrixAutoUpdate&&(s.matrixAutoUpdate=!1),void 0!==this.morphTargetDictionary&&(s.morphTargetDictionary=Object.assign({},this.morphTargetDictionary)),void 0!==this.morphTargetInfluences&&(s.morphTargetInfluences=this.morphTargetInfluences.slice()),this.isInstancedMesh&&(s.type="InstancedMesh",s.count=this.count,s.instanceMatrix=this.instanceMatrix.toJSON(),null!==this.instanceColor&&(s.instanceColor=this.instanceColor.toJSON())),this.isBatchedMesh&&(s.type="BatchedMesh",s.perObjectFrustumCulled=this.perObjectFrustumCulled,s.sortObjects=this.sortObjects,s.drawRanges=this._drawRanges,s.reservedRanges=this._reservedRanges,s.geometryInfo=this._geometryInfo.map(t=>({...t,boundingBox:t.boundingBox?t.boundingBox.toJSON():void 0,boundingSphere:t.boundingSphere?t.boundingSphere.toJSON():void 0})),s.instanceInfo=this._instanceInfo.map(t=>({...t})),s.availableInstanceIds=this._availableInstanceIds.slice(),s.availableGeometryIds=this._availableGeometryIds.slice(),s.nextIndexStart=this._nextIndexStart,s.nextVertexStart=this._nextVertexStart,s.geometryCount=this._geometryCount,s.maxInstanceCount=this._maxInstanceCount,s.maxVertexCount=this._maxVertexCount,s.maxIndexCount=this._maxIndexCount,s.geometryInitialized=this._geometryInitialized,s.matricesTexture=this._matricesTexture.toJSON(t),s.indirectTexture=this._indirectTexture.toJSON(t),null!==this._colorsTexture&&(s.colorsTexture=this._colorsTexture.toJSON(t)),null!==this.boundingSphere&&(s.boundingSphere=this.boundingSphere.toJSON()),null!==this.boundingBox&&(s.boundingBox=this.boundingBox.toJSON())),this.isScene)this.background&&(this.background.isColor?s.background=this.background.toJSON():this.background.isTexture&&(s.background=this.background.toJSON(t).uuid)),this.environment&&this.environment.isTexture&&!0!==this.environment.isRenderTargetTexture&&(s.environment=this.environment.toJSON(t).uuid);else if(this.isMesh||this.isLine||this.isPoints){s.geometry=r(t.geometries,this.geometry);const e=this.geometry.parameters;if(void 0!==e&&void 0!==e.shapes){const i=e.shapes;if(Array.isArray(i))for(let e=0,s=i.length;e0){s.children=[];for(let e=0;e0){s.animations=[];for(let e=0;e0&&(i.geometries=e),s.length>0&&(i.materials=s),r.length>0&&(i.textures=r),a.length>0&&(i.images=a),o.length>0&&(i.shapes=o),h.length>0&&(i.skeletons=h),l.length>0&&(i.animations=l),c.length>0&&(i.nodes=c)}return i.object=s,i;function n(t){const e=[];for(const i in t){const s=t[i];delete s.metadata,e.push(s)}return e}}clone(t){return(new this.constructor).copy(this,t)}copy(t,e=!0){if(this.name=t.name,this.up.copy(t.up),this.position.copy(t.position),this.rotation.order=t.rotation.order,this.quaternion.copy(t.quaternion),this.scale.copy(t.scale),null!==t.pivot&&(this.pivot=t.pivot.clone()),this.matrix.copy(t.matrix),this.matrixWorld.copy(t.matrixWorld),this.matrixAutoUpdate=t.matrixAutoUpdate,this.matrixWorldAutoUpdate=t.matrixWorldAutoUpdate,this.matrixWorldNeedsUpdate=t.matrixWorldNeedsUpdate,this.layers.mask=t.layers.mask,this.visible=t.visible,this.castShadow=t.castShadow,this.receiveShadow=t.receiveShadow,this.frustumCulled=t.frustumCulled,this.renderOrder=t.renderOrder,this.static=t.static,this.animations=t.animations.slice(),this.userData=JSON.parse(JSON.stringify(t.userData)),!0===e)for(let e=0;eo+l?(h.inputState.pinching=!1,this.dispatchEvent({type:"pinchend",handedness:t.handedness,target:this})):!h.inputState.pinching&&a<=o-l&&(h.inputState.pinching=!0,this.dispatchEvent({type:"pinchstart",handedness:t.handedness,target:this}))}else null!==o&&t.gripSpace&&(r=e.getPose(t.gripSpace,i),null!==r&&(o.matrix.fromArray(r.transform.matrix),o.matrix.decompose(o.position,o.rotation,o.scale),o.matrixWorldNeedsUpdate=!0,r.linearVelocity?(o.hasLinearVelocity=!0,o.linearVelocity.copy(r.linearVelocity)):o.hasLinearVelocity=!1,r.angularVelocity?(o.hasAngularVelocity=!0,o.angularVelocity.copy(r.angularVelocity)):o.hasAngularVelocity=!1));null!==a&&(s=e.getPose(t.targetRaySpace,i),null===s&&null!==r&&(s=r),null!==s&&(a.matrix.fromArray(s.transform.matrix),a.matrix.decompose(a.position,a.rotation,a.scale),a.matrixWorldNeedsUpdate=!0,s.linearVelocity?(a.hasLinearVelocity=!0,a.linearVelocity.copy(s.linearVelocity)):a.hasLinearVelocity=!1,s.angularVelocity?(a.hasAngularVelocity=!0,a.angularVelocity.copy(s.angularVelocity)):a.hasAngularVelocity=!1,this.dispatchEvent(Ar)))}return null!==a&&(a.visible=null!==s),null!==o&&(o.visible=null!==r),null!==h&&(h.visible=null!==n),this}_getHandJoint(t,e){if(void 0===t.joints[e.jointName]){const i=new _r;i.matrixAutoUpdate=!1,i.visible=!1,t.joints[e.jointName]=i,t.add(i)}return t.joints[e.jointName]}}const zr={aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,rebeccapurple:6697881,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074},Cr={h:0,s:0,l:0},Ir={h:0,s:0,l:0};function Br(t,e,i){return i<0&&(i+=1),i>1&&(i-=1),i<1/6?t+6*(e-t)*i:i<.5?e:i<2/3?t+6*(e-t)*(2/3-i):t}class kr{constructor(t,e,i){return this.isColor=!0,this.r=1,this.g=1,this.b=1,this.set(t,e,i)}set(t,e,i){if(void 0===e&&void 0===i){const e=t;e&&e.isColor?this.copy(e):"number"==typeof e?this.setHex(e):"string"==typeof e&&this.setStyle(e)}else this.setRGB(t,e,i);return this}setScalar(t){return this.r=t,this.g=t,this.b=t,this}setHex(t,e=ei){return t=Math.floor(t),this.r=(t>>16&255)/255,this.g=(t>>8&255)/255,this.b=(255&t)/255,Os.colorSpaceToWorking(this,e),this}setRGB(t,e,i,s=Os.workingColorSpace){return this.r=t,this.g=e,this.b=i,Os.colorSpaceToWorking(this,s),this}setHSL(t,e,i,s=Os.workingColorSpace){if(t=fs(t,1),e=gs(e,0,1),i=gs(i,0,1),0===e)this.r=this.g=this.b=i;else{const s=i<=.5?i*(1+e):i+e-i*e,r=2*i-s;this.r=Br(r,s,t+1/3),this.g=Br(r,s,t),this.b=Br(r,s,t-1/3)}return Os.colorSpaceToWorking(this,s),this}setStyle(t,e=ei){function i(e){void 0!==e&&parseFloat(e)<1&&as("Color: Alpha component of "+t+" will be ignored.")}let s;if(s=/^(\w+)\(([^\)]*)\)/.exec(t)){let r;const n=s[1],a=s[2];switch(n){case"rgb":case"rgba":if(r=/^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return i(r[4]),this.setRGB(Math.min(255,parseInt(r[1],10))/255,Math.min(255,parseInt(r[2],10))/255,Math.min(255,parseInt(r[3],10))/255,e);if(r=/^\s*(\d+)\%\s*,\s*(\d+)\%\s*,\s*(\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return i(r[4]),this.setRGB(Math.min(100,parseInt(r[1],10))/100,Math.min(100,parseInt(r[2],10))/100,Math.min(100,parseInt(r[3],10))/100,e);break;case"hsl":case"hsla":if(r=/^\s*(\d*\.?\d+)\s*,\s*(\d*\.?\d+)\%\s*,\s*(\d*\.?\d+)\%\s*(?:,\s*(\d*\.?\d+)\s*)?$/.exec(a))return i(r[4]),this.setHSL(parseFloat(r[1])/360,parseFloat(r[2])/100,parseFloat(r[3])/100,e);break;default:as("Color: Unknown color model "+t)}}else if(s=/^\#([A-Fa-f\d]+)$/.exec(t)){const i=s[1],r=i.length;if(3===r)return this.setRGB(parseInt(i.charAt(0),16)/15,parseInt(i.charAt(1),16)/15,parseInt(i.charAt(2),16)/15,e);if(6===r)return this.setHex(parseInt(i,16),e);as("Color: Invalid hex color "+t)}else if(t&&t.length>0)return this.setColorName(t,e);return this}setColorName(t,e=ei){const i=zr[t.toLowerCase()];return void 0!==i?this.setHex(i,e):as("Color: Unknown color "+t),this}clone(){return new this.constructor(this.r,this.g,this.b)}copy(t){return this.r=t.r,this.g=t.g,this.b=t.b,this}copySRGBToLinear(t){return this.r=Ps(t.r),this.g=Ps(t.g),this.b=Ps(t.b),this}copyLinearToSRGB(t){return this.r=Rs(t.r),this.g=Rs(t.g),this.b=Rs(t.b),this}convertSRGBToLinear(){return this.copySRGBToLinear(this),this}convertLinearToSRGB(){return this.copyLinearToSRGB(this),this}getHex(t=ei){return Os.workingToColorSpace(Or.copy(this),t),65536*Math.round(gs(255*Or.r,0,255))+256*Math.round(gs(255*Or.g,0,255))+Math.round(gs(255*Or.b,0,255))}getHexString(t=ei){return("000000"+this.getHex(t).toString(16)).slice(-6)}getHSL(t,e=Os.workingColorSpace){Os.workingToColorSpace(Or.copy(this),e);const i=Or.r,s=Or.g,r=Or.b,n=Math.max(i,s,r),a=Math.min(i,s,r);let o,h;const l=(a+n)/2;if(a===n)o=0,h=0;else{const t=n-a;switch(h=l<=.5?t/(n+a):t/(2-n-a),n){case i:o=(s-r)/t+(s0&&(e.object.backgroundBlurriness=this.backgroundBlurriness),1!==this.backgroundIntensity&&(e.object.backgroundIntensity=this.backgroundIntensity),e.object.backgroundRotation=this.backgroundRotation.toArray(),1!==this.environmentIntensity&&(e.object.environmentIntensity=this.environmentIntensity),e.object.environmentRotation=this.environmentRotation.toArray(),e}}const Vr=new _s,Er=new _s,Fr=new _s,Lr=new _s,Dr=new _s,jr=new _s,Wr=new _s,Ur=new _s,Jr=new _s,qr=new _s,Xr=new Us,Yr=new Us,Hr=new Us;class Zr{constructor(t=new _s,e=new _s,i=new _s){this.a=t,this.b=e,this.c=i}static getNormal(t,e,i,s){s.subVectors(i,e),Vr.subVectors(t,e),s.cross(Vr);const r=s.lengthSq();return r>0?s.multiplyScalar(1/Math.sqrt(r)):s.set(0,0,0)}static getBarycoord(t,e,i,s,r){Vr.subVectors(s,e),Er.subVectors(i,e),Fr.subVectors(t,e);const n=Vr.dot(Vr),a=Vr.dot(Er),o=Vr.dot(Fr),h=Er.dot(Er),l=Er.dot(Fr),c=n*h-a*a;if(0===c)return r.set(0,0,0),null;const u=1/c,d=(h*o-a*l)*u,p=(n*l-a*o)*u;return r.set(1-d-p,p,d)}static containsPoint(t,e,i,s){return null!==this.getBarycoord(t,e,i,s,Lr)&&(Lr.x>=0&&Lr.y>=0&&Lr.x+Lr.y<=1)}static getInterpolation(t,e,i,s,r,n,a,o){return null===this.getBarycoord(t,e,i,s,Lr)?(o.x=0,o.y=0,"z"in o&&(o.z=0),"w"in o&&(o.w=0),null):(o.setScalar(0),o.addScaledVector(r,Lr.x),o.addScaledVector(n,Lr.y),o.addScaledVector(a,Lr.z),o)}static getInterpolatedAttribute(t,e,i,s,r,n){return Xr.setScalar(0),Yr.setScalar(0),Hr.setScalar(0),Xr.fromBufferAttribute(t,e),Yr.fromBufferAttribute(t,i),Hr.fromBufferAttribute(t,s),n.setScalar(0),n.addScaledVector(Xr,r.x),n.addScaledVector(Yr,r.y),n.addScaledVector(Hr,r.z),n}static isFrontFacing(t,e,i,s){return Vr.subVectors(i,e),Er.subVectors(t,e),Vr.cross(Er).dot(s)<0}set(t,e,i){return this.a.copy(t),this.b.copy(e),this.c.copy(i),this}setFromPointsAndIndices(t,e,i,s){return this.a.copy(t[e]),this.b.copy(t[i]),this.c.copy(t[s]),this}setFromAttributeAndIndices(t,e,i,s){return this.a.fromBufferAttribute(t,e),this.b.fromBufferAttribute(t,i),this.c.fromBufferAttribute(t,s),this}clone(){return(new this.constructor).copy(this)}copy(t){return this.a.copy(t.a),this.b.copy(t.b),this.c.copy(t.c),this}getArea(){return Vr.subVectors(this.c,this.b),Er.subVectors(this.a,this.b),.5*Vr.cross(Er).length()}getMidpoint(t){return t.addVectors(this.a,this.b).add(this.c).multiplyScalar(1/3)}getNormal(t){return Zr.getNormal(this.a,this.b,this.c,t)}getPlane(t){return t.setFromCoplanarPoints(this.a,this.b,this.c)}getBarycoord(t,e){return Zr.getBarycoord(t,this.a,this.b,this.c,e)}getInterpolation(t,e,i,s,r){return Zr.getInterpolation(t,this.a,this.b,this.c,e,i,s,r)}containsPoint(t){return Zr.containsPoint(t,this.a,this.b,this.c)}isFrontFacing(t){return Zr.isFrontFacing(this.a,this.b,this.c,t)}intersectsBox(t){return t.intersectsTriangle(this)}closestPointToPoint(t,e){const i=this.a,s=this.b,r=this.c;let n,a;Dr.subVectors(s,i),jr.subVectors(r,i),Ur.subVectors(t,i);const o=Dr.dot(Ur),h=jr.dot(Ur);if(o<=0&&h<=0)return e.copy(i);Jr.subVectors(t,s);const l=Dr.dot(Jr),c=jr.dot(Jr);if(l>=0&&c<=l)return e.copy(s);const u=o*c-l*h;if(u<=0&&o>=0&&l<=0)return n=o/(o-l),e.copy(i).addScaledVector(Dr,n);qr.subVectors(t,r);const d=Dr.dot(qr),p=jr.dot(qr);if(p>=0&&d<=p)return e.copy(r);const m=d*h-o*p;if(m<=0&&h>=0&&p<=0)return a=h/(h-p),e.copy(i).addScaledVector(jr,a);const y=l*p-d*c;if(y<=0&&c-l>=0&&d-p>=0)return Wr.subVectors(r,s),a=(c-l)/(c-l+(d-p)),e.copy(s).addScaledVector(Wr,a);const g=1/(y+m+u);return n=m*g,a=u*g,e.copy(i).addScaledVector(Dr,n).addScaledVector(jr,a)}equals(t){return t.a.equals(this.a)&&t.b.equals(this.b)&&t.c.equals(this.c)}}class Gr{constructor(t=new _s(1/0,1/0,1/0),e=new _s(-1/0,-1/0,-1/0)){this.isBox3=!0,this.min=t,this.max=e}set(t,e){return this.min.copy(t),this.max.copy(e),this}setFromArray(t){this.makeEmpty();for(let e=0,i=t.length;e=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y&&t.z>=this.min.z&&t.z<=this.max.z}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y&&this.min.z<=t.min.z&&t.max.z<=this.max.z}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y),(t.z-this.min.z)/(this.max.z-this.min.z))}intersectsBox(t){return t.max.x>=this.min.x&&t.min.x<=this.max.x&&t.max.y>=this.min.y&&t.min.y<=this.max.y&&t.max.z>=this.min.z&&t.min.z<=this.max.z}intersectsSphere(t){return this.clampPoint(t.center,Qr),Qr.distanceToSquared(t.center)<=t.radius*t.radius}intersectsPlane(t){let e,i;return t.normal.x>0?(e=t.normal.x*this.min.x,i=t.normal.x*this.max.x):(e=t.normal.x*this.max.x,i=t.normal.x*this.min.x),t.normal.y>0?(e+=t.normal.y*this.min.y,i+=t.normal.y*this.max.y):(e+=t.normal.y*this.max.y,i+=t.normal.y*this.min.y),t.normal.z>0?(e+=t.normal.z*this.min.z,i+=t.normal.z*this.max.z):(e+=t.normal.z*this.max.z,i+=t.normal.z*this.min.z),e<=-t.constant&&i>=-t.constant}intersectsTriangle(t){if(this.isEmpty())return!1;this.getCenter(on),hn.subVectors(this.max,on),tn.subVectors(t.a,on),en.subVectors(t.b,on),sn.subVectors(t.c,on),rn.subVectors(en,tn),nn.subVectors(sn,en),an.subVectors(tn,sn);let e=[0,-rn.z,rn.y,0,-nn.z,nn.y,0,-an.z,an.y,rn.z,0,-rn.x,nn.z,0,-nn.x,an.z,0,-an.x,-rn.y,rn.x,0,-nn.y,nn.x,0,-an.y,an.x,0];return!!un(e,tn,en,sn,hn)&&(e=[1,0,0,0,1,0,0,0,1],!!un(e,tn,en,sn,hn)&&(ln.crossVectors(rn,nn),e=[ln.x,ln.y,ln.z],un(e,tn,en,sn,hn)))}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return this.clampPoint(t,Qr).distanceTo(t)}getBoundingSphere(t){return this.isEmpty()?t.makeEmpty():(this.getCenter(t.center),t.radius=.5*this.getSize(Qr).length()),t}intersect(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}applyMatrix4(t){return this.isEmpty()||($r[0].set(this.min.x,this.min.y,this.min.z).applyMatrix4(t),$r[1].set(this.min.x,this.min.y,this.max.z).applyMatrix4(t),$r[2].set(this.min.x,this.max.y,this.min.z).applyMatrix4(t),$r[3].set(this.min.x,this.max.y,this.max.z).applyMatrix4(t),$r[4].set(this.max.x,this.min.y,this.min.z).applyMatrix4(t),$r[5].set(this.max.x,this.min.y,this.max.z).applyMatrix4(t),$r[6].set(this.max.x,this.max.y,this.min.z).applyMatrix4(t),$r[7].set(this.max.x,this.max.y,this.max.z).applyMatrix4(t),this.setFromPoints($r)),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}toJSON(){return{min:this.min.toArray(),max:this.max.toArray()}}fromJSON(t){return this.min.fromArray(t.min),this.max.fromArray(t.max),this}}const $r=[new _s,new _s,new _s,new _s,new _s,new _s,new _s,new _s],Qr=new _s,Kr=new Gr,tn=new _s,en=new _s,sn=new _s,rn=new _s,nn=new _s,an=new _s,on=new _s,hn=new _s,ln=new _s,cn=new _s;function un(t,e,i,s,r){for(let n=0,a=t.length-3;n<=a;n+=3){cn.fromArray(t,n);const a=r.x*Math.abs(cn.x)+r.y*Math.abs(cn.y)+r.z*Math.abs(cn.z),o=e.dot(cn),h=i.dot(cn),l=s.dot(cn);if(Math.max(-Math.max(o,h,l),Math.min(o,h,l))>a)return!1}return!0}const dn=pn();function pn(){const t=new ArrayBuffer(4),e=new Float32Array(t),i=new Uint32Array(t),s=new Uint32Array(512),r=new Uint32Array(512);for(let t=0;t<256;++t){const e=t-127;e<-27?(s[t]=0,s[256|t]=32768,r[t]=24,r[256|t]=24):e<-14?(s[t]=1024>>-e-14,s[256|t]=1024>>-e-14|32768,r[t]=-e-1,r[256|t]=-e-1):e<=15?(s[t]=e+15<<10,s[256|t]=e+15<<10|32768,r[t]=13,r[256|t]=13):e<128?(s[t]=31744,s[256|t]=64512,r[t]=24,r[256|t]=24):(s[t]=31744,s[256|t]=64512,r[t]=13,r[256|t]=13)}const n=new Uint32Array(2048),a=new Uint32Array(64),o=new Uint32Array(64);for(let t=1;t<1024;++t){let e=t<<13,i=0;for(;!(8388608&e);)e<<=1,i-=8388608;e&=-8388609,i+=947912704,n[t]=e|i}for(let t=1024;t<2048;++t)n[t]=939524096+(t-1024<<13);for(let t=1;t<31;++t)a[t]=t<<23;a[31]=1199570944,a[32]=2147483648;for(let t=33;t<63;++t)a[t]=2147483648+(t-32<<23);a[63]=3347054592;for(let t=1;t<64;++t)32!==t&&(o[t]=1024);return{floatView:e,uint32View:i,baseTable:s,shiftTable:r,mantissaTable:n,exponentTable:a,offsetTable:o}}function mn(t){Math.abs(t)>65504&&as("DataUtils.toHalfFloat(): Value out of range."),t=gs(t,-65504,65504),dn.floatView[0]=t;const e=dn.uint32View[0],i=e>>23&511;return dn.baseTable[i]+((8388607&e)>>dn.shiftTable[i])}function yn(t){const e=t>>10;return dn.uint32View[0]=dn.mantissaTable[dn.offsetTable[e]+(1023&t)]+dn.exponentTable[e],dn.floatView[0]}class gn{static toHalfFloat(t){return mn(t)}static fromHalfFloat(t){return yn(t)}}const fn=new _s,xn=new Ms;let bn=0;class vn{constructor(t,e,i=!1){if(Array.isArray(t))throw new TypeError("THREE.BufferAttribute: array should be a Typed Array.");this.isBufferAttribute=!0,Object.defineProperty(this,"id",{value:bn++}),this.name="",this.array=t,this.itemSize=e,this.count=void 0!==t?t.length/e:0,this.normalized=i,this.usage=Oi,this.updateRanges=[],this.gpuType=Pt,this.version=0}onUploadCallback(){}set needsUpdate(t){!0===t&&this.version++}setUsage(t){return this.usage=t,this}addUpdateRange(t,e){this.updateRanges.push({start:t,count:e})}clearUpdateRanges(){this.updateRanges.length=0}copy(t){return this.name=t.name,this.array=new t.array.constructor(t.array),this.itemSize=t.itemSize,this.count=t.count,this.normalized=t.normalized,this.usage=t.usage,this.gpuType=t.gpuType,this}copyAt(t,e,i){t*=this.itemSize,i*=e.itemSize;for(let s=0,r=this.itemSize;sthis.radius*this.radius&&(e.sub(this.center).normalize(),e.multiplyScalar(this.radius).add(this.center)),e}getBoundingBox(t){return this.isEmpty()?(t.makeEmpty(),t):(t.set(this.center,this.center),t.expandByScalar(this.radius),t)}applyMatrix4(t){return this.center.applyMatrix4(t),this.radius=this.radius*t.getMaxScaleOnAxis(),this}translate(t){return this.center.add(t),this}expandByPoint(t){if(this.isEmpty())return this.center.copy(t),this.radius=0,this;kn.subVectors(t,this.center);const e=kn.lengthSq();if(e>this.radius*this.radius){const t=Math.sqrt(e),i=.5*(t-this.radius);this.center.addScaledVector(kn,i/t),this.radius+=i}return this}union(t){return t.isEmpty()?this:this.isEmpty()?(this.copy(t),this):(!0===this.center.equals(t.center)?this.radius=Math.max(this.radius,t.radius):(On.subVectors(t.center,this.center).setLength(t.radius),this.expandByPoint(kn.copy(t.center).add(On)),this.expandByPoint(kn.copy(t.center).sub(On))),this)}equals(t){return t.center.equals(this.center)&&t.radius===this.radius}clone(){return(new this.constructor).copy(this)}toJSON(){return{radius:this.radius,center:this.center.toArray()}}fromJSON(t){return this.radius=t.radius,this.center.fromArray(t.center),this}}let Rn=0;const Nn=new Gs,Vn=new Sr,En=new _s,Fn=new Gr,Ln=new Gr,Dn=new _s;class jn extends cs{constructor(){super(),this.isBufferGeometry=!0,Object.defineProperty(this,"id",{value:Rn++}),this.uuid=ys(),this.name="",this.type="BufferGeometry",this.index=null,this.indirect=null,this.indirectOffset=0,this.attributes={},this.morphAttributes={},this.morphTargetsRelative=!1,this.groups=[],this.boundingBox=null,this.boundingSphere=null,this.drawRange={start:0,count:1/0},this.userData={}}getIndex(){return this.index}setIndex(t){return Array.isArray(t)?this.index=new(Zi(t)?zn:An)(t,1):this.index=t,this}setIndirect(t,e=0){return this.indirect=t,this.indirectOffset=e,this}getIndirect(){return this.indirect}getAttribute(t){return this.attributes[t]}setAttribute(t,e){return this.attributes[t]=e,this}deleteAttribute(t){return delete this.attributes[t],this}hasAttribute(t){return void 0!==this.attributes[t]}addGroup(t,e,i=0){this.groups.push({start:t,count:e,materialIndex:i})}clearGroups(){this.groups=[]}setDrawRange(t,e){this.drawRange.start=t,this.drawRange.count=e}applyMatrix4(t){const e=this.attributes.position;void 0!==e&&(e.applyMatrix4(t),e.needsUpdate=!0);const i=this.attributes.normal;if(void 0!==i){const e=(new zs).getNormalMatrix(t);i.applyNormalMatrix(e),i.needsUpdate=!0}const s=this.attributes.tangent;return void 0!==s&&(s.transformDirection(t),s.needsUpdate=!0),null!==this.boundingBox&&this.computeBoundingBox(),null!==this.boundingSphere&&this.computeBoundingSphere(),this}applyQuaternion(t){return Nn.makeRotationFromQuaternion(t),this.applyMatrix4(Nn),this}rotateX(t){return Nn.makeRotationX(t),this.applyMatrix4(Nn),this}rotateY(t){return Nn.makeRotationY(t),this.applyMatrix4(Nn),this}rotateZ(t){return Nn.makeRotationZ(t),this.applyMatrix4(Nn),this}translate(t,e,i){return Nn.makeTranslation(t,e,i),this.applyMatrix4(Nn),this}scale(t,e,i){return Nn.makeScale(t,e,i),this.applyMatrix4(Nn),this}lookAt(t){return Vn.lookAt(t),Vn.updateMatrix(),this.applyMatrix4(Vn.matrix),this}center(){return this.computeBoundingBox(),this.boundingBox.getCenter(En).negate(),this.translate(En.x,En.y,En.z),this}setFromPoints(t){const e=this.getAttribute("position");if(void 0===e){const e=[];for(let i=0,s=t.length;ie.count&&as("BufferGeometry: Buffer size too small for points data. Use .dispose() and create a new geometry."),e.needsUpdate=!0}return this}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new Gr);const t=this.attributes.position,e=this.morphAttributes.position;if(t&&t.isGLBufferAttribute)return os("BufferGeometry.computeBoundingBox(): GLBufferAttribute requires a manual bounding box.",this),void this.boundingBox.set(new _s(-1/0,-1/0,-1/0),new _s(1/0,1/0,1/0));if(void 0!==t){if(this.boundingBox.setFromBufferAttribute(t),e)for(let t=0,i=e.length;t0&&(t.userData=this.userData),void 0!==this.parameters){const e=this.parameters;for(const i in e)void 0!==e[i]&&(t[i]=e[i]);return t}t.data={attributes:{}};const e=this.index;null!==e&&(t.data.index={type:e.array.constructor.name,array:Array.prototype.slice.call(e.array)});const i=this.attributes;for(const e in i){const s=i[e];t.data.attributes[e]=s.toJSON(t.data)}const s={};let r=!1;for(const e in this.morphAttributes){const i=this.morphAttributes[e],n=[];for(let e=0,s=i.length;e0&&(s[e]=n,r=!0)}r&&(t.data.morphAttributes=s,t.data.morphTargetsRelative=this.morphTargetsRelative);const n=this.groups;n.length>0&&(t.data.groups=JSON.parse(JSON.stringify(n)));const a=this.boundingSphere;return null!==a&&(t.data.boundingSphere=a.toJSON()),t}clone(){return(new this.constructor).copy(this)}copy(t){this.index=null,this.attributes={},this.morphAttributes={},this.groups=[],this.boundingBox=null,this.boundingSphere=null;const e={};this.name=t.name;const i=t.index;null!==i&&this.setIndex(i.clone());const s=t.attributes;for(const t in s){const i=s[t];this.setAttribute(t,i.clone(e))}const r=t.morphAttributes;for(const t in r){const i=[],s=r[t];for(let t=0,r=s.length;t0!=t>0&&this.version++,this._alphaTest=t}onBeforeRender(){}onBeforeCompile(){}customProgramCacheKey(){return this.onBeforeCompile.toString()}setValues(t){if(void 0!==t)for(const e in t){const i=t[e];if(void 0===i){as(`Material: parameter '${e}' has value of undefined.`);continue}const s=this[e];void 0!==s?s&&s.isColor?s.set(i):s&&s.isVector3&&i&&i.isVector3?s.copy(i):this[e]=i:as(`Material: '${e}' is not a property of THREE.${this.type}.`)}}toJSON(t){const e=void 0===t||"string"==typeof t;e&&(t={textures:{},images:{}});const i={metadata:{version:4.7,type:"Material",generator:"Material.toJSON"}};function s(t){const e=[];for(const i in t){const s=t[i];delete s.metadata,e.push(s)}return e}if(i.uuid=this.uuid,i.type=this.type,""!==this.name&&(i.name=this.name),this.color&&this.color.isColor&&(i.color=this.color.getHex()),void 0!==this.roughness&&(i.roughness=this.roughness),void 0!==this.metalness&&(i.metalness=this.metalness),void 0!==this.sheen&&(i.sheen=this.sheen),this.sheenColor&&this.sheenColor.isColor&&(i.sheenColor=this.sheenColor.getHex()),void 0!==this.sheenRoughness&&(i.sheenRoughness=this.sheenRoughness),this.emissive&&this.emissive.isColor&&(i.emissive=this.emissive.getHex()),void 0!==this.emissiveIntensity&&1!==this.emissiveIntensity&&(i.emissiveIntensity=this.emissiveIntensity),this.specular&&this.specular.isColor&&(i.specular=this.specular.getHex()),void 0!==this.specularIntensity&&(i.specularIntensity=this.specularIntensity),this.specularColor&&this.specularColor.isColor&&(i.specularColor=this.specularColor.getHex()),void 0!==this.shininess&&(i.shininess=this.shininess),void 0!==this.clearcoat&&(i.clearcoat=this.clearcoat),void 0!==this.clearcoatRoughness&&(i.clearcoatRoughness=this.clearcoatRoughness),this.clearcoatMap&&this.clearcoatMap.isTexture&&(i.clearcoatMap=this.clearcoatMap.toJSON(t).uuid),this.clearcoatRoughnessMap&&this.clearcoatRoughnessMap.isTexture&&(i.clearcoatRoughnessMap=this.clearcoatRoughnessMap.toJSON(t).uuid),this.clearcoatNormalMap&&this.clearcoatNormalMap.isTexture&&(i.clearcoatNormalMap=this.clearcoatNormalMap.toJSON(t).uuid,i.clearcoatNormalScale=this.clearcoatNormalScale.toArray()),this.sheenColorMap&&this.sheenColorMap.isTexture&&(i.sheenColorMap=this.sheenColorMap.toJSON(t).uuid),this.sheenRoughnessMap&&this.sheenRoughnessMap.isTexture&&(i.sheenRoughnessMap=this.sheenRoughnessMap.toJSON(t).uuid),void 0!==this.dispersion&&(i.dispersion=this.dispersion),void 0!==this.iridescence&&(i.iridescence=this.iridescence),void 0!==this.iridescenceIOR&&(i.iridescenceIOR=this.iridescenceIOR),void 0!==this.iridescenceThicknessRange&&(i.iridescenceThicknessRange=this.iridescenceThicknessRange),this.iridescenceMap&&this.iridescenceMap.isTexture&&(i.iridescenceMap=this.iridescenceMap.toJSON(t).uuid),this.iridescenceThicknessMap&&this.iridescenceThicknessMap.isTexture&&(i.iridescenceThicknessMap=this.iridescenceThicknessMap.toJSON(t).uuid),void 0!==this.anisotropy&&(i.anisotropy=this.anisotropy),void 0!==this.anisotropyRotation&&(i.anisotropyRotation=this.anisotropyRotation),this.anisotropyMap&&this.anisotropyMap.isTexture&&(i.anisotropyMap=this.anisotropyMap.toJSON(t).uuid),this.map&&this.map.isTexture&&(i.map=this.map.toJSON(t).uuid),this.matcap&&this.matcap.isTexture&&(i.matcap=this.matcap.toJSON(t).uuid),this.alphaMap&&this.alphaMap.isTexture&&(i.alphaMap=this.alphaMap.toJSON(t).uuid),this.lightMap&&this.lightMap.isTexture&&(i.lightMap=this.lightMap.toJSON(t).uuid,i.lightMapIntensity=this.lightMapIntensity),this.aoMap&&this.aoMap.isTexture&&(i.aoMap=this.aoMap.toJSON(t).uuid,i.aoMapIntensity=this.aoMapIntensity),this.bumpMap&&this.bumpMap.isTexture&&(i.bumpMap=this.bumpMap.toJSON(t).uuid,i.bumpScale=this.bumpScale),this.normalMap&&this.normalMap.isTexture&&(i.normalMap=this.normalMap.toJSON(t).uuid,i.normalMapType=this.normalMapType,i.normalScale=this.normalScale.toArray()),this.displacementMap&&this.displacementMap.isTexture&&(i.displacementMap=this.displacementMap.toJSON(t).uuid,i.displacementScale=this.displacementScale,i.displacementBias=this.displacementBias),this.roughnessMap&&this.roughnessMap.isTexture&&(i.roughnessMap=this.roughnessMap.toJSON(t).uuid),this.metalnessMap&&this.metalnessMap.isTexture&&(i.metalnessMap=this.metalnessMap.toJSON(t).uuid),this.emissiveMap&&this.emissiveMap.isTexture&&(i.emissiveMap=this.emissiveMap.toJSON(t).uuid),this.specularMap&&this.specularMap.isTexture&&(i.specularMap=this.specularMap.toJSON(t).uuid),this.specularIntensityMap&&this.specularIntensityMap.isTexture&&(i.specularIntensityMap=this.specularIntensityMap.toJSON(t).uuid),this.specularColorMap&&this.specularColorMap.isTexture&&(i.specularColorMap=this.specularColorMap.toJSON(t).uuid),this.envMap&&this.envMap.isTexture&&(i.envMap=this.envMap.toJSON(t).uuid,void 0!==this.combine&&(i.combine=this.combine)),void 0!==this.envMapRotation&&(i.envMapRotation=this.envMapRotation.toArray()),void 0!==this.envMapIntensity&&(i.envMapIntensity=this.envMapIntensity),void 0!==this.reflectivity&&(i.reflectivity=this.reflectivity),void 0!==this.refractionRatio&&(i.refractionRatio=this.refractionRatio),this.gradientMap&&this.gradientMap.isTexture&&(i.gradientMap=this.gradientMap.toJSON(t).uuid),void 0!==this.transmission&&(i.transmission=this.transmission),this.transmissionMap&&this.transmissionMap.isTexture&&(i.transmissionMap=this.transmissionMap.toJSON(t).uuid),void 0!==this.thickness&&(i.thickness=this.thickness),this.thicknessMap&&this.thicknessMap.isTexture&&(i.thicknessMap=this.thicknessMap.toJSON(t).uuid),void 0!==this.attenuationDistance&&this.attenuationDistance!==1/0&&(i.attenuationDistance=this.attenuationDistance),void 0!==this.attenuationColor&&(i.attenuationColor=this.attenuationColor.getHex()),void 0!==this.size&&(i.size=this.size),null!==this.shadowSide&&(i.shadowSide=this.shadowSide),void 0!==this.sizeAttenuation&&(i.sizeAttenuation=this.sizeAttenuation),1!==this.blending&&(i.blending=this.blending),0!==this.side&&(i.side=this.side),!0===this.vertexColors&&(i.vertexColors=!0),this.opacity<1&&(i.opacity=this.opacity),!0===this.transparent&&(i.transparent=!0),204!==this.blendSrc&&(i.blendSrc=this.blendSrc),205!==this.blendDst&&(i.blendDst=this.blendDst),100!==this.blendEquation&&(i.blendEquation=this.blendEquation),null!==this.blendSrcAlpha&&(i.blendSrcAlpha=this.blendSrcAlpha),null!==this.blendDstAlpha&&(i.blendDstAlpha=this.blendDstAlpha),null!==this.blendEquationAlpha&&(i.blendEquationAlpha=this.blendEquationAlpha),this.blendColor&&this.blendColor.isColor&&(i.blendColor=this.blendColor.getHex()),0!==this.blendAlpha&&(i.blendAlpha=this.blendAlpha),3!==this.depthFunc&&(i.depthFunc=this.depthFunc),!1===this.depthTest&&(i.depthTest=this.depthTest),!1===this.depthWrite&&(i.depthWrite=this.depthWrite),!1===this.colorWrite&&(i.colorWrite=this.colorWrite),255!==this.stencilWriteMask&&(i.stencilWriteMask=this.stencilWriteMask),519!==this.stencilFunc&&(i.stencilFunc=this.stencilFunc),0!==this.stencilRef&&(i.stencilRef=this.stencilRef),255!==this.stencilFuncMask&&(i.stencilFuncMask=this.stencilFuncMask),this.stencilFail!==li&&(i.stencilFail=this.stencilFail),this.stencilZFail!==li&&(i.stencilZFail=this.stencilZFail),this.stencilZPass!==li&&(i.stencilZPass=this.stencilZPass),!0===this.stencilWrite&&(i.stencilWrite=this.stencilWrite),void 0!==this.rotation&&0!==this.rotation&&(i.rotation=this.rotation),!0===this.polygonOffset&&(i.polygonOffset=!0),0!==this.polygonOffsetFactor&&(i.polygonOffsetFactor=this.polygonOffsetFactor),0!==this.polygonOffsetUnits&&(i.polygonOffsetUnits=this.polygonOffsetUnits),void 0!==this.linewidth&&1!==this.linewidth&&(i.linewidth=this.linewidth),void 0!==this.dashSize&&(i.dashSize=this.dashSize),void 0!==this.gapSize&&(i.gapSize=this.gapSize),void 0!==this.scale&&(i.scale=this.scale),!0===this.dithering&&(i.dithering=!0),this.alphaTest>0&&(i.alphaTest=this.alphaTest),!0===this.alphaHash&&(i.alphaHash=!0),!0===this.alphaToCoverage&&(i.alphaToCoverage=!0),!0===this.premultipliedAlpha&&(i.premultipliedAlpha=!0),!0===this.forceSinglePass&&(i.forceSinglePass=!0),!1===this.allowOverride&&(i.allowOverride=!1),!0===this.wireframe&&(i.wireframe=!0),this.wireframeLinewidth>1&&(i.wireframeLinewidth=this.wireframeLinewidth),"round"!==this.wireframeLinecap&&(i.wireframeLinecap=this.wireframeLinecap),"round"!==this.wireframeLinejoin&&(i.wireframeLinejoin=this.wireframeLinejoin),!0===this.flatShading&&(i.flatShading=!0),!1===this.visible&&(i.visible=!1),!1===this.toneMapped&&(i.toneMapped=!1),!1===this.fog&&(i.fog=!1),Object.keys(this.userData).length>0&&(i.userData=this.userData),e){const e=s(t.textures),r=s(t.images);e.length>0&&(i.textures=e),r.length>0&&(i.images=r)}return i}clone(){return(new this.constructor).copy(this)}copy(t){this.name=t.name,this.blending=t.blending,this.side=t.side,this.vertexColors=t.vertexColors,this.opacity=t.opacity,this.transparent=t.transparent,this.blendSrc=t.blendSrc,this.blendDst=t.blendDst,this.blendEquation=t.blendEquation,this.blendSrcAlpha=t.blendSrcAlpha,this.blendDstAlpha=t.blendDstAlpha,this.blendEquationAlpha=t.blendEquationAlpha,this.blendColor.copy(t.blendColor),this.blendAlpha=t.blendAlpha,this.depthFunc=t.depthFunc,this.depthTest=t.depthTest,this.depthWrite=t.depthWrite,this.stencilWriteMask=t.stencilWriteMask,this.stencilFunc=t.stencilFunc,this.stencilRef=t.stencilRef,this.stencilFuncMask=t.stencilFuncMask,this.stencilFail=t.stencilFail,this.stencilZFail=t.stencilZFail,this.stencilZPass=t.stencilZPass,this.stencilWrite=t.stencilWrite;const e=t.clippingPlanes;let i=null;if(null!==e){const t=e.length;i=new Array(t);for(let s=0;s!==t;++s)i[s]=e[s].clone()}return this.clippingPlanes=i,this.clipIntersection=t.clipIntersection,this.clipShadows=t.clipShadows,this.shadowSide=t.shadowSide,this.colorWrite=t.colorWrite,this.precision=t.precision,this.polygonOffset=t.polygonOffset,this.polygonOffsetFactor=t.polygonOffsetFactor,this.polygonOffsetUnits=t.polygonOffsetUnits,this.dithering=t.dithering,this.alphaTest=t.alphaTest,this.alphaHash=t.alphaHash,this.alphaToCoverage=t.alphaToCoverage,this.premultipliedAlpha=t.premultipliedAlpha,this.forceSinglePass=t.forceSinglePass,this.allowOverride=t.allowOverride,this.visible=t.visible,this.toneMapped=t.toneMapped,this.userData=JSON.parse(JSON.stringify(t.userData)),this}dispose(){this.dispatchEvent({type:"dispose"})}set needsUpdate(t){!0===t&&this.version++}}class Hn extends Yn{constructor(t){super(),this.isSpriteMaterial=!0,this.type="SpriteMaterial",this.color=new kr(16777215),this.map=null,this.alphaMap=null,this.rotation=0,this.sizeAttenuation=!0,this.transparent=!0,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.alphaMap=t.alphaMap,this.rotation=t.rotation,this.sizeAttenuation=t.sizeAttenuation,this.fog=t.fog,this}}const Zn=new _s,Gn=new _s,$n=new _s,Qn=new Ms,Kn=new Ms,ta=new Gs,ea=new _s,ia=new _s,sa=new _s,ra=new Ms,na=new Ms,aa=new Ms;class oa extends Sr{constructor(t=new Hn){if(super(),this.isSprite=!0,this.type="Sprite",void 0===qn){qn=new jn;const t=new Float32Array([-.5,-.5,0,0,0,.5,-.5,0,1,0,.5,.5,0,1,1,-.5,.5,0,0,1]),e=new Wn(t,5);qn.setIndex([0,1,2,0,2,3]),qn.setAttribute("position",new Jn(e,3,0,!1)),qn.setAttribute("uv",new Jn(e,2,3,!1))}this.geometry=qn,this.material=t,this.center=new Ms(.5,.5),this.count=1}raycast(t,e){null===t.camera&&os('Sprite: "Raycaster.camera" needs to be set in order to raycast against sprites.'),Gn.setFromMatrixScale(this.matrixWorld),ta.copy(t.camera.matrixWorld),this.modelViewMatrix.multiplyMatrices(t.camera.matrixWorldInverse,this.matrixWorld),$n.setFromMatrixPosition(this.modelViewMatrix),t.camera.isPerspectiveCamera&&!1===this.material.sizeAttenuation&&Gn.multiplyScalar(-$n.z);const i=this.material.rotation;let s,r;0!==i&&(r=Math.cos(i),s=Math.sin(i));const n=this.center;ha(ea.set(-.5,-.5,0),$n,n,Gn,s,r),ha(ia.set(.5,-.5,0),$n,n,Gn,s,r),ha(sa.set(.5,.5,0),$n,n,Gn,s,r),ra.set(0,0),na.set(1,0),aa.set(1,1);let a=t.ray.intersectTriangle(ea,ia,sa,!1,Zn);if(null===a&&(ha(ia.set(-.5,.5,0),$n,n,Gn,s,r),na.set(0,1),a=t.ray.intersectTriangle(ea,sa,ia,!1,Zn),null===a))return;const o=t.ray.origin.distanceTo(Zn);ot.far||e.push({distance:o,point:Zn.clone(),uv:Zr.getInterpolation(Zn,ea,ia,sa,ra,na,aa,new Ms),face:null,object:this})}copy(t,e){return super.copy(t,e),void 0!==t.center&&this.center.copy(t.center),this.material=t.material,this}}function ha(t,e,i,s,r,n){Qn.subVectors(t,i).addScalar(.5).multiply(s),void 0!==r?(Kn.x=n*Qn.x-r*Qn.y,Kn.y=r*Qn.x+n*Qn.y):Kn.copy(Qn),t.copy(e),t.x+=Kn.x,t.y+=Kn.y,t.applyMatrix4(ta)}const la=new _s,ca=new _s;class ua extends Sr{constructor(){super(),this.isLOD=!0,this._currentLevel=0,this.type="LOD",Object.defineProperties(this,{levels:{enumerable:!0,value:[]}}),this.autoUpdate=!0}copy(t){super.copy(t,!1);const e=t.levels;for(let t=0,i=e.length;t0){let i,s;for(i=1,s=e.length;i0){la.setFromMatrixPosition(this.matrixWorld);const i=t.ray.origin.distanceTo(la);this.getObjectForDistance(i).raycast(t,e)}}update(t){const e=this.levels;if(e.length>1){la.setFromMatrixPosition(t.matrixWorld),ca.setFromMatrixPosition(this.matrixWorld);const i=la.distanceTo(ca)/t.zoom;let s,r;for(e[0].object.visible=!0,s=1,r=e.length;s=t))break;e[s-1].object.visible=!1,e[s].object.visible=!0}for(this._currentLevel=s-1;s0)if(c=n*o-a,u=n*a-o,p=r*l,c>=0)if(u>=-p)if(u<=p){const t=1/l;c*=t,u*=t,d=c*(c+n*u+2*a)+u*(n*c+u+2*o)+h}else u=r,c=Math.max(0,-(n*u+a)),d=-c*c+u*(u+2*o)+h;else u=-r,c=Math.max(0,-(n*u+a)),d=-c*c+u*(u+2*o)+h;else u<=-p?(c=Math.max(0,-(-n*r+a)),u=c>0?-r:Math.min(Math.max(-r,-o),r),d=-c*c+u*(u+2*o)+h):u<=p?(c=0,u=Math.min(Math.max(-r,-o),r),d=u*(u+2*o)+h):(c=Math.max(0,-(n*r+a)),u=c>0?r:Math.min(Math.max(-r,-o),r),d=-c*c+u*(u+2*o)+h);else u=n>0?-r:r,c=Math.max(0,-(n*u+a)),d=-c*c+u*(u+2*o)+h;return i&&i.copy(this.origin).addScaledVector(this.direction,c),s&&s.copy(pa).addScaledVector(ma,u),d}intersectSphere(t,e){da.subVectors(t.center,this.origin);const i=da.dot(this.direction),s=da.dot(da)-i*i,r=t.radius*t.radius;if(s>r)return null;const n=Math.sqrt(r-s),a=i-n,o=i+n;return o<0?null:a<0?this.at(o,e):this.at(a,e)}intersectsSphere(t){return!(t.radius<0)&&this.distanceSqToPoint(t.center)<=t.radius*t.radius}distanceToPlane(t){const e=t.normal.dot(this.direction);if(0===e)return 0===t.distanceToPoint(this.origin)?0:null;const i=-(this.origin.dot(t.normal)+t.constant)/e;return i>=0?i:null}intersectPlane(t,e){const i=this.distanceToPlane(t);return null===i?null:this.at(i,e)}intersectsPlane(t){const e=t.distanceToPoint(this.origin);if(0===e)return!0;return t.normal.dot(this.direction)*e<0}intersectBox(t,e){let i,s,r,n,a,o;const h=1/this.direction.x,l=1/this.direction.y,c=1/this.direction.z,u=this.origin;return h>=0?(i=(t.min.x-u.x)*h,s=(t.max.x-u.x)*h):(i=(t.max.x-u.x)*h,s=(t.min.x-u.x)*h),l>=0?(r=(t.min.y-u.y)*l,n=(t.max.y-u.y)*l):(r=(t.max.y-u.y)*l,n=(t.min.y-u.y)*l),i>n||r>s?null:((r>i||isNaN(i))&&(i=r),(n=0?(a=(t.min.z-u.z)*c,o=(t.max.z-u.z)*c):(a=(t.max.z-u.z)*c,o=(t.min.z-u.z)*c),i>o||a>s?null:((a>i||i!=i)&&(i=a),(o=0?i:s,e)))}intersectsBox(t){return null!==this.intersectBox(t,da)}intersectTriangle(t,e,i,s,r){ga.subVectors(e,t),fa.subVectors(i,t),xa.crossVectors(ga,fa);let n,a=this.direction.dot(xa);if(a>0){if(s)return null;n=1}else{if(!(a<0))return null;n=-1,a=-a}ya.subVectors(this.origin,t);const o=n*this.direction.dot(fa.crossVectors(ya,fa));if(o<0)return null;const h=n*this.direction.dot(ga.cross(ya));if(h<0)return null;if(o+h>a)return null;const l=-n*ya.dot(xa);return l<0?null:this.at(l/a,r)}applyMatrix4(t){return this.origin.applyMatrix4(t),this.direction.transformDirection(t),this}equals(t){return t.origin.equals(this.origin)&&t.direction.equals(this.direction)}clone(){return(new this.constructor).copy(this)}}class va extends Yn{constructor(t){super(),this.isMeshBasicMaterial=!0,this.type="MeshBasicMaterial",this.color=new kr(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new ar,this.combine=0,this.reflectivity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}const wa=new Gs,Ma=new ba,Sa=new Pn,_a=new _s,Aa=new _s,Ta=new _s,za=new _s,Ca=new _s,Ia=new _s,Ba=new _s,ka=new _s;class Oa extends Sr{constructor(t=new jn,e=new va){super(),this.isMesh=!0,this.type="Mesh",this.geometry=t,this.material=e,this.morphTargetDictionary=void 0,this.morphTargetInfluences=void 0,this.count=1,this.updateMorphTargets()}copy(t,e){return super.copy(t,e),void 0!==t.morphTargetInfluences&&(this.morphTargetInfluences=t.morphTargetInfluences.slice()),void 0!==t.morphTargetDictionary&&(this.morphTargetDictionary=Object.assign({},t.morphTargetDictionary)),this.material=Array.isArray(t.material)?t.material.slice():t.material,this.geometry=t.geometry,this}updateMorphTargets(){const t=this.geometry.morphAttributes,e=Object.keys(t);if(e.length>0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;t(t.far-t.near)**2)return}wa.copy(r).invert(),Ma.copy(t.ray).applyMatrix4(wa),null!==i.boundingBox&&!1===Ma.intersectsBox(i.boundingBox)||this._computeIntersections(t,e,Ma)}}_computeIntersections(t,e,i){let s;const r=this.geometry,n=this.material,a=r.index,o=r.attributes.position,h=r.attributes.uv,l=r.attributes.uv1,c=r.attributes.normal,u=r.groups,d=r.drawRange;if(null!==a)if(Array.isArray(n))for(let r=0,o=u.length;ri.far?null:{distance:l,point:ka.clone(),object:t}}(t,e,i,s,Aa,Ta,za,Ba);if(c){const t=new _s;Zr.getBarycoord(Ba,Aa,Ta,za,t),r&&(c.uv=Zr.getInterpolatedAttribute(r,o,h,l,t,new Ms)),n&&(c.uv1=Zr.getInterpolatedAttribute(n,o,h,l,t,new Ms)),a&&(c.normal=Zr.getInterpolatedAttribute(a,o,h,l,t,new _s),c.normal.dot(s.direction)>0&&c.normal.multiplyScalar(-1));const e={a:o,b:h,c:l,normal:new _s,materialIndex:0};Zr.getNormal(Aa,Ta,za,e.normal),c.face=e,c.barycoord=t}return c}const Ra=new _s,Na=new Us,Va=new Us,Ea=new _s,Fa=new Gs,La=new _s,Da=new Pn,ja=new Gs,Wa=new ba;class Ua extends Oa{constructor(t,e){super(t,e),this.isSkinnedMesh=!0,this.type="SkinnedMesh",this.bindMode=at,this.bindMatrix=new Gs,this.bindMatrixInverse=new Gs,this.boundingBox=null,this.boundingSphere=null}computeBoundingBox(){const t=this.geometry;null===this.boundingBox&&(this.boundingBox=new Gr),this.boundingBox.makeEmpty();const e=t.getAttribute("position");for(let t=0;t1?null:e.copy(t.start).addScaledVector(i,r)}intersectsLine(t){const e=this.distanceToPoint(t.start),i=this.distanceToPoint(t.end);return e<0&&i>0||i<0&&e>0}intersectsBox(t){return t.intersectsPlane(this)}intersectsSphere(t){return t.intersectsPlane(this)}coplanarPoint(t){return t.copy(this.normal).multiplyScalar(-this.constant)}applyMatrix4(t,e){const i=e||ao.getNormalMatrix(t),s=this.coplanarPoint(ro).applyMatrix4(t),r=this.normal.applyMatrix3(i).normalize();return this.constant=-s.dot(r),this}translate(t){return this.constant-=t.dot(this.normal),this}equals(t){return t.normal.equals(this.normal)&&t.constant===this.constant}clone(){return(new this.constructor).copy(this)}}const ho=new Pn,lo=new Ms(.5,.5),co=new _s;class uo{constructor(t=new oo,e=new oo,i=new oo,s=new oo,r=new oo,n=new oo){this.planes=[t,e,i,s,r,n]}set(t,e,i,s,r,n){const a=this.planes;return a[0].copy(t),a[1].copy(e),a[2].copy(i),a[3].copy(s),a[4].copy(r),a[5].copy(n),this}copy(t){const e=this.planes;for(let i=0;i<6;i++)e[i].copy(t.planes[i]);return this}setFromProjectionMatrix(t,e=2e3,i=!1){const s=this.planes,r=t.elements,n=r[0],a=r[1],o=r[2],h=r[3],l=r[4],c=r[5],u=r[6],d=r[7],p=r[8],m=r[9],y=r[10],g=r[11],f=r[12],x=r[13],b=r[14],v=r[15];if(s[0].setComponents(h-n,d-l,g-p,v-f).normalize(),s[1].setComponents(h+n,d+l,g+p,v+f).normalize(),s[2].setComponents(h+a,d+c,g+m,v+x).normalize(),s[3].setComponents(h-a,d-c,g-m,v-x).normalize(),i)s[4].setComponents(o,u,y,b).normalize(),s[5].setComponents(h-o,d-u,g-y,v-b).normalize();else if(s[4].setComponents(h-o,d-u,g-y,v-b).normalize(),e===Ui)s[5].setComponents(h+o,d+u,g+y,v+b).normalize();else{if(e!==Ji)throw new Error("THREE.Frustum.setFromProjectionMatrix(): Invalid coordinate system: "+e);s[5].setComponents(o,u,y,b).normalize()}return this}intersectsObject(t){if(void 0!==t.boundingSphere)null===t.boundingSphere&&t.computeBoundingSphere(),ho.copy(t.boundingSphere).applyMatrix4(t.matrixWorld);else{const e=t.geometry;null===e.boundingSphere&&e.computeBoundingSphere(),ho.copy(e.boundingSphere).applyMatrix4(t.matrixWorld)}return this.intersectsSphere(ho)}intersectsSprite(t){ho.center.set(0,0,0);const e=lo.distanceTo(t.center);return ho.radius=.7071067811865476+e,ho.applyMatrix4(t.matrixWorld),this.intersectsSphere(ho)}intersectsSphere(t){const e=this.planes,i=t.center,s=-t.radius;for(let t=0;t<6;t++){if(e[t].distanceToPoint(i)0?t.max.x:t.min.x,co.y=s.normal.y>0?t.max.y:t.min.y,co.z=s.normal.z>0?t.max.z:t.min.z,s.distanceToPoint(co)<0)return!1}return!0}containsPoint(t){const e=this.planes;for(let i=0;i<6;i++)if(e[i].distanceToPoint(t)<0)return!1;return!0}clone(){return(new this.constructor).copy(this)}}const po=new Gs,mo=new uo;class yo{constructor(){this.coordinateSystem=Ui}intersectsObject(t,e){if(!e.isArrayCamera||0===e.cameras.length)return!1;for(let i=0;i=r.length&&r.push({start:-1,count:-1,z:-1,index:-1});const a=r[this.index];n.push(a),this.index++,a.start=t,a.count=e,a.z=i,a.index=s}reset(){this.list.length=0,this.index=0}}const vo=new Gs,wo=new kr(1,1,1),Mo=new uo,So=new yo,_o=new Gr,Ao=new Pn,To=new _s,zo=new _s,Co=new _s,Io=new bo,Bo=new Oa,ko=[];function Oo(t,e,i=0){const s=e.itemSize;if(t.isInterleavedBufferAttribute||t.array.constructor!==e.array.constructor){const r=t.count;for(let n=0;n65535?new Uint32Array(s):new Uint16Array(s);e.setIndex(new vn(t,1))}this._geometryInitialized=!0}}_validateGeometry(t){const e=this.geometry;if(Boolean(t.getIndex())!==Boolean(e.getIndex()))throw new Error('THREE.BatchedMesh: All geometries must consistently have "index".');for(const i in e.attributes){if(!t.hasAttribute(i))throw new Error(`THREE.BatchedMesh: Added geometry missing "${i}". All geometries must have consistent attributes.`);const s=t.getAttribute(i),r=e.getAttribute(i);if(s.itemSize!==r.itemSize||s.normalized!==r.normalized)throw new Error("THREE.BatchedMesh: All attributes must have a consistent itemSize and normalized value.")}}validateInstanceId(t){const e=this._instanceInfo;if(t<0||t>=e.length||!1===e[t].active)throw new Error(`THREE.BatchedMesh: Invalid instanceId ${t}. Instance is either out of range or has been deleted.`)}validateGeometryId(t){const e=this._geometryInfo;if(t<0||t>=e.length||!1===e[t].active)throw new Error(`THREE.BatchedMesh: Invalid geometryId ${t}. Geometry is either out of range or has been deleted.`)}setCustomSort(t){return this.customSort=t,this}computeBoundingBox(){null===this.boundingBox&&(this.boundingBox=new Gr);const t=this.boundingBox,e=this._instanceInfo;t.makeEmpty();for(let i=0,s=e.length;i=this.maxInstanceCount&&0===this._availableInstanceIds.length)throw new Error("THREE.BatchedMesh: Maximum item count reached.");const e={visible:!0,active:!0,geometryIndex:t};let i=null;this._availableInstanceIds.length>0?(this._availableInstanceIds.sort(go),i=this._availableInstanceIds.shift(),this._instanceInfo[i]=e):(i=this._instanceInfo.length,this._instanceInfo.push(e));const s=this._matricesTexture;vo.identity().toArray(s.image.data,16*i),s.needsUpdate=!0;const r=this._colorsTexture;return r&&(wo.toArray(r.image.data,4*i),r.needsUpdate=!0),this._visibilityChanged=!0,i}addGeometry(t,e=-1,i=-1){this._initializeGeometry(t),this._validateGeometry(t);const s={vertexStart:-1,vertexCount:-1,reservedVertexCount:-1,indexStart:-1,indexCount:-1,reservedIndexCount:-1,start:-1,count:-1,boundingBox:null,boundingSphere:null,active:!0},r=this._geometryInfo;s.vertexStart=this._nextVertexStart,s.reservedVertexCount=-1===e?t.getAttribute("position").count:e;const n=t.getIndex();if(null!==n&&(s.indexStart=this._nextIndexStart,s.reservedIndexCount=-1===i?n.count:i),-1!==s.indexStart&&s.indexStart+s.reservedIndexCount>this._maxIndexCount||s.vertexStart+s.reservedVertexCount>this._maxVertexCount)throw new Error("THREE.BatchedMesh: Reserved space request exceeds the maximum buffer size.");let a;return this._availableGeometryIds.length>0?(this._availableGeometryIds.sort(go),a=this._availableGeometryIds.shift(),r[a]=s):(a=this._geometryCount,this._geometryCount++,r.push(s)),this.setGeometryAt(a,t),this._nextIndexStart=s.indexStart+s.reservedIndexCount,this._nextVertexStart=s.vertexStart+s.reservedVertexCount,a}setGeometryAt(t,e){if(t>=this._geometryCount)throw new Error("THREE.BatchedMesh: Maximum geometry count reached.");this._validateGeometry(e);const i=this.geometry,s=null!==i.getIndex(),r=i.getIndex(),n=e.getIndex(),a=this._geometryInfo[t];if(s&&n.count>a.reservedIndexCount||e.attributes.position.count>a.reservedVertexCount)throw new Error("THREE.BatchedMesh: Reserved space not large enough for provided geometry.");const o=a.vertexStart,h=a.reservedVertexCount;a.vertexCount=e.getAttribute("position").count;for(const t in i.attributes){const s=e.getAttribute(t),r=i.getAttribute(t);Oo(s,r,o);const n=s.itemSize;for(let t=s.count,e=h;t=e.length||!1===e[t].active)return this;const i=this._instanceInfo;for(let e=0,s=i.length;ee).sort((t,e)=>i[t].vertexStart-i[e].vertexStart),r=this.geometry;for(let n=0,a=i.length;n=this._geometryCount)return null;const i=this.geometry,s=this._geometryInfo[t];if(null===s.boundingBox){const t=new Gr,e=i.index,r=i.attributes.position;for(let i=s.start,n=s.start+s.count;i=this._geometryCount)return null;const i=this.geometry,s=this._geometryInfo[t];if(null===s.boundingSphere){const e=new Pn;this.getBoundingBoxAt(t,_o),_o.getCenter(e.center);const r=i.index,n=i.attributes.position;let a=0;for(let t=s.start,i=s.start+s.count;tt.active);if(Math.max(...i.map(t=>t.vertexStart+t.reservedVertexCount))>t)throw new Error(`BatchedMesh: Geometry vertex values are being used outside the range ${e}. Cannot shrink further.`);if(this.geometry.index){if(Math.max(...i.map(t=>t.indexStart+t.reservedIndexCount))>e)throw new Error(`BatchedMesh: Geometry index values are being used outside the range ${e}. Cannot shrink further.`)}const s=this.geometry;s.dispose(),this._maxVertexCount=t,this._maxIndexCount=e,this._geometryInitialized&&(this._geometryInitialized=!1,this.geometry=new jn,this._initializeGeometry(s));const r=this.geometry;s.index&&Po(s.index.array,r.index.array);for(const t in s.attributes)Po(s.attributes[t].array,r.attributes[t].array)}raycast(t,e){const i=this._instanceInfo,s=this._geometryInfo,r=this.matrixWorld,n=this.geometry;Bo.material=this.material,Bo.geometry.index=n.index,Bo.geometry.attributes=n.attributes,null===Bo.geometry.boundingBox&&(Bo.geometry.boundingBox=new Gr),null===Bo.geometry.boundingSphere&&(Bo.geometry.boundingSphere=new Pn);for(let n=0,a=i.length;n({...t,boundingBox:null!==t.boundingBox?t.boundingBox.clone():null,boundingSphere:null!==t.boundingSphere?t.boundingSphere.clone():null})),this._instanceInfo=t._instanceInfo.map(t=>({...t})),this._availableInstanceIds=t._availableInstanceIds.slice(),this._availableGeometryIds=t._availableGeometryIds.slice(),this._nextIndexStart=t._nextIndexStart,this._nextVertexStart=t._nextVertexStart,this._geometryCount=t._geometryCount,this._maxInstanceCount=t._maxInstanceCount,this._maxVertexCount=t._maxVertexCount,this._maxIndexCount=t._maxIndexCount,this._geometryInitialized=t._geometryInitialized,this._multiDrawCounts=t._multiDrawCounts.slice(),this._multiDrawStarts=t._multiDrawStarts.slice(),this._indirectTexture=t._indirectTexture.clone(),this._indirectTexture.image.data=this._indirectTexture.image.data.slice(),this._matricesTexture=t._matricesTexture.clone(),this._matricesTexture.image.data=this._matricesTexture.image.data.slice(),null!==this._colorsTexture&&(this._colorsTexture=t._colorsTexture.clone(),this._colorsTexture.image.data=this._colorsTexture.image.data.slice()),this}dispose(){this.geometry.dispose(),this._matricesTexture.dispose(),this._matricesTexture=null,this._indirectTexture.dispose(),this._indirectTexture=null,null!==this._colorsTexture&&(this._colorsTexture.dispose(),this._colorsTexture=null)}onBeforeRender(t,e,i,s,r){if(!this._visibilityChanged&&!this.perObjectFrustumCulled&&!this.sortObjects)return;const n=s.getIndex(),a=null===n?1:n.array.BYTES_PER_ELEMENT,o=this._instanceInfo,h=this._multiDrawStarts,l=this._multiDrawCounts,c=this._geometryInfo,u=this.perObjectFrustumCulled,d=this._indirectTexture,p=d.image.data,m=i.isArrayCamera?So:Mo;u&&!i.isArrayCamera&&(vo.multiplyMatrices(i.projectionMatrix,i.matrixWorldInverse).multiply(this.matrixWorld),Mo.setFromProjectionMatrix(vo,i.coordinateSystem,i.reversedDepth));let y=0;if(this.sortObjects){vo.copy(this.matrixWorld).invert(),To.setFromMatrixPosition(i.matrixWorld).applyMatrix4(vo),zo.set(0,0,-1).transformDirection(i.matrixWorld).transformDirection(vo);for(let t=0,e=o.length;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;ts)return;jo.applyMatrix4(t.matrixWorld);const h=e.ray.origin.distanceTo(jo);return he.far?void 0:{distance:h,point:Wo.clone().applyMatrix4(t.matrixWorld),index:a,face:null,faceIndex:null,barycoord:null,object:t}}const qo=new _s,Xo=new _s;class Yo extends Uo{constructor(t,e){super(t,e),this.isLineSegments=!0,this.type="LineSegments"}computeLineDistances(){const t=this.geometry;if(null===t.index){const e=t.attributes.position,i=[];for(let t=0,s=e.count;t0){const i=t[e[0]];if(void 0!==i){this.morphTargetInfluences=[],this.morphTargetDictionary={};for(let t=0,e=i.length;tr.far)return;n.push({distance:h,distanceToRay:Math.sqrt(o),point:i,index:e,face:null,faceIndex:null,barycoord:null,object:a})}}class ih extends Ws{constructor(t,e,i,s,r=1006,n=1006,a,o,h){super(t,e,i,s,r,n,a,o,h),this.isVideoTexture=!0,this.generateMipmaps=!1,this._requestVideoFrameCallbackId=0;const l=this;"requestVideoFrameCallback"in t&&(this._requestVideoFrameCallbackId=t.requestVideoFrameCallback(function e(){l.needsUpdate=!0,l._requestVideoFrameCallbackId=t.requestVideoFrameCallback(e)}))}clone(){return new this.constructor(this.image).copy(this)}update(){const t=this.image;!1==="requestVideoFrameCallback"in t&&t.readyState>=t.HAVE_CURRENT_DATA&&(this.needsUpdate=!0)}dispose(){0!==this._requestVideoFrameCallbackId&&(this.source.data.cancelVideoFrameCallback(this._requestVideoFrameCallbackId),this._requestVideoFrameCallbackId=0),super.dispose()}}class sh extends ih{constructor(t,e,i,s,r,n,a,o){super({},t,e,i,s,r,n,a,o),this.isVideoFrameTexture=!0}update(){}clone(){return(new this.constructor).copy(this)}setFrame(t){this.image=t,this.needsUpdate=!0}}class rh extends Ws{constructor(t,e){super({width:t,height:e}),this.isFramebufferTexture=!0,this.magFilter=ft,this.minFilter=ft,this.generateMipmaps=!1,this.needsUpdate=!0}}class nh extends Ws{constructor(t,e,i,s,r,n,a,o,h,l,c,u){super(null,n,a,o,h,l,s,r,c,u),this.isCompressedTexture=!0,this.image={width:e,height:i},this.mipmaps=t,this.flipY=!1,this.generateMipmaps=!1}}class ah extends nh{constructor(t,e,i,s,r,n){super(t,e,i,r,n),this.isCompressedArrayTexture=!0,this.image.depth=s,this.wrapR=yt,this.layerUpdates=new Set}addLayerUpdate(t){this.layerUpdates.add(t)}clearLayerUpdates(){this.layerUpdates.clear()}}class oh extends nh{constructor(t,e,i){super(void 0,t[0].width,t[0].height,e,i,lt),this.isCompressedCubeTexture=!0,this.isCubeTexture=!0,this.image=t}}class hh extends Ws{constructor(t=[],e=301,i,s,r,n,a,o,h,l){super(t,e,i,s,r,n,a,o,h,l),this.isCubeTexture=!0,this.flipY=!1}get images(){return this.image}set images(t){this.image=t}}class lh extends Ws{constructor(t,e,i,s,r,n,a,o,h){super(t,e,i,s,r,n,a,o,h),this.isCanvasTexture=!0,this.needsUpdate=!0}}class ch extends Ws{constructor(t,e,i=1014,s,r,n,a=1003,o=1003,h,l=1026,c=1){if(l!==Ut&&1027!==l)throw new Error("DepthTexture format must be either THREE.DepthFormat or THREE.DepthStencilFormat");super({width:t,height:e,depth:c},s,r,n,a,o,l,i,h),this.isDepthTexture=!0,this.flipY=!1,this.generateMipmaps=!1,this.compareFunction=null}copy(t){return super.copy(t),this.source=new Fs(Object.assign({},t.image)),this.compareFunction=t.compareFunction,this}toJSON(t){const e=super.toJSON(t);return null!==this.compareFunction&&(e.compareFunction=this.compareFunction),e}}class uh extends ch{constructor(t,e=1014,i=301,s,r,n=1003,a=1003,o,h=1026){const l={width:t,height:t,depth:1},c=[l,l,l,l,l,l];super(t,t,e,i,s,r,n,a,o,h),this.image=c,this.isCubeDepthTexture=!0,this.isCubeTexture=!0}get images(){return this.image}set images(t){this.image=t}}class dh extends Ws{constructor(t=null){super(),this.sourceTexture=t,this.isExternalTexture=!0}copy(t){return super.copy(t),this.sourceTexture=t.sourceTexture,this}}class ph extends jn{constructor(t=1,e=1,i=1,s=1,r=1,n=1){super(),this.type="BoxGeometry",this.parameters={width:t,height:e,depth:i,widthSegments:s,heightSegments:r,depthSegments:n};const a=this;s=Math.floor(s),r=Math.floor(r),n=Math.floor(n);const o=[],h=[],l=[],c=[];let u=0,d=0;function p(t,e,i,s,r,n,p,m,y,g,f){const x=n/y,b=p/g,v=n/2,w=p/2,M=m/2,S=y+1,_=g+1;let A=0,T=0;const z=new _s;for(let n=0;n<_;n++){const a=n*b-w;for(let o=0;o0?1:-1,l.push(z.x,z.y,z.z),c.push(o/y),c.push(1-n/g),A+=1}}for(let t=0;t0){const t=(f-1)*m;for(let e=0;e0||0!==s)&&(l.push(n,a,h),x+=3),(e>0||s!==r-1)&&(l.push(a,o,h),x+=3)}h.addGroup(g,x,0),g+=x}(),!1===n&&(t>0&&f(!0),e>0&&f(!1)),this.setIndex(l),this.setAttribute("position",new In(c,3)),this.setAttribute("normal",new In(u,3)),this.setAttribute("uv",new In(d,2))}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}static fromJSON(t){return new gh(t.radiusTop,t.radiusBottom,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class fh extends gh{constructor(t=1,e=1,i=32,s=1,r=!1,n=0,a=2*Math.PI){super(0,t,e,i,s,r,n,a),this.type="ConeGeometry",this.parameters={radius:t,height:e,radialSegments:i,heightSegments:s,openEnded:r,thetaStart:n,thetaLength:a}}static fromJSON(t){return new fh(t.radius,t.height,t.radialSegments,t.heightSegments,t.openEnded,t.thetaStart,t.thetaLength)}}class xh extends jn{constructor(t=[],e=[],i=1,s=0){super(),this.type="PolyhedronGeometry",this.parameters={vertices:t,indices:e,radius:i,detail:s};const r=[],n=[];function a(t,e,i,s){const r=s+1,n=[];for(let s=0;s<=r;s++){n[s]=[];const a=t.clone().lerp(i,s/r),o=e.clone().lerp(i,s/r),h=r-s;for(let t=0;t<=h;t++)n[s][t]=0===t&&s===r?a:a.clone().lerp(o,t/h)}for(let t=0;t.9&&a<.1&&(e<.2&&(n[t+0]+=1),i<.2&&(n[t+2]+=1),s<.2&&(n[t+4]+=1))}}()}(),this.setAttribute("position",new In(r,3)),this.setAttribute("normal",new In(r.slice(),3)),this.setAttribute("uv",new In(n,2)),0===s?this.computeVertexNormals():this.normalizeNormals()}copy(t){return super.copy(t),this.parameters=Object.assign({},t.parameters),this}static fromJSON(t){return new xh(t.vertices,t.indices,t.radius,t.detail)}}class bh extends xh{constructor(t=1,e=0){const i=(1+Math.sqrt(5))/2,s=1/i;super([-1,-1,-1,-1,-1,1,-1,1,-1,-1,1,1,1,-1,-1,1,-1,1,1,1,-1,1,1,1,0,-s,-i,0,-s,i,0,s,-i,0,s,i,-s,-i,0,-s,i,0,s,-i,0,s,i,0,-i,0,-s,i,0,-s,-i,0,s,i,0,s],[3,11,7,3,7,15,3,15,13,7,19,17,7,17,6,7,6,15,17,4,8,17,8,10,17,10,6,8,0,16,8,16,2,8,2,10,0,12,1,0,1,18,0,18,16,6,10,2,6,2,13,6,13,15,2,16,18,2,18,3,2,3,13,18,1,9,18,9,11,18,11,3,4,14,12,4,12,0,4,0,8,11,9,5,11,5,19,11,19,7,19,5,14,19,14,4,19,4,17,1,12,14,1,14,5,1,5,9],t,e),this.type="DodecahedronGeometry",this.parameters={radius:t,detail:e}}static fromJSON(t){return new bh(t.radius,t.detail)}}const vh=new _s,wh=new _s,Mh=new _s,Sh=new Zr;class _h extends jn{constructor(t=null,e=1){if(super(),this.type="EdgesGeometry",this.parameters={geometry:t,thresholdAngle:e},null!==t){const i=4,s=Math.pow(10,i),r=Math.cos(ps*e),n=t.getIndex(),a=t.getAttribute("position"),o=n?n.count:a.count,h=[0,0,0],l=["a","b","c"],c=new Array(3),u={},d=[];for(let t=0;t0)){h=s;break}h=s-1}if(s=h,i[s]===n)return s/(r-1);const l=i[s];return(s+(n-l)/(i[s+1]-l))/(r-1)}getTangent(t,e){const i=1e-4;let s=t-i,r=t+i;s<0&&(s=0),r>1&&(r=1);const n=this.getPoint(s),a=this.getPoint(r),o=e||(n.isVector2?new Ms:new _s);return o.copy(a).sub(n).normalize(),o}getTangentAt(t,e){const i=this.getUtoTmapping(t);return this.getTangent(i,e)}computeFrenetFrames(t,e=!1){const i=new _s,s=[],r=[],n=[],a=new _s,o=new Gs;for(let e=0;e<=t;e++){const i=e/t;s[e]=this.getTangentAt(i,new _s)}r[0]=new _s,n[0]=new _s;let h=Number.MAX_VALUE;const l=Math.abs(s[0].x),c=Math.abs(s[0].y),u=Math.abs(s[0].z);l<=h&&(h=l,i.set(1,0,0)),c<=h&&(h=c,i.set(0,1,0)),u<=h&&i.set(0,0,1),a.crossVectors(s[0],i).normalize(),r[0].crossVectors(s[0],a),n[0].crossVectors(s[0],r[0]);for(let e=1;e<=t;e++){if(r[e]=r[e-1].clone(),n[e]=n[e-1].clone(),a.crossVectors(s[e-1],s[e]),a.length()>Number.EPSILON){a.normalize();const t=Math.acos(gs(s[e-1].dot(s[e]),-1,1));r[e].applyMatrix4(o.makeRotationAxis(a,t))}n[e].crossVectors(s[e],r[e])}if(!0===e){let e=Math.acos(gs(r[0].dot(r[t]),-1,1));e/=t,s[0].dot(a.crossVectors(r[0],r[t]))>0&&(e=-e);for(let i=1;i<=t;i++)r[i].applyMatrix4(o.makeRotationAxis(s[i],e*i)),n[i].crossVectors(s[i],r[i])}return{tangents:s,normals:r,binormals:n}}clone(){return(new this.constructor).copy(this)}copy(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}toJSON(){const t={metadata:{version:4.7,type:"Curve",generator:"Curve.toJSON"}};return t.arcLengthDivisions=this.arcLengthDivisions,t.type=this.type,t}fromJSON(t){return this.arcLengthDivisions=t.arcLengthDivisions,this}}class Th extends Ah{constructor(t=0,e=0,i=1,s=1,r=0,n=2*Math.PI,a=!1,o=0){super(),this.isEllipseCurve=!0,this.type="EllipseCurve",this.aX=t,this.aY=e,this.xRadius=i,this.yRadius=s,this.aStartAngle=r,this.aEndAngle=n,this.aClockwise=a,this.aRotation=o}getPoint(t,e=new Ms){const i=e,s=2*Math.PI;let r=this.aEndAngle-this.aStartAngle;const n=Math.abs(r)s;)r-=s;r0?0:(Math.floor(Math.abs(h)/r)+1)*r:0===l&&h===r-1&&(h=r-2,l=1),this.closed||h>0?a=s[(h-1)%r]:(Ih.subVectors(s[0],s[1]).add(s[0]),a=Ih);const c=s[h%r],u=s[(h+1)%r];if(this.closed||h+2s.length-2?s.length-1:n+1],c=s[n>s.length-3?s.length-1:n+2];return i.set(Rh(a,o.x,h.x,l.x,c.x),Rh(a,o.y,h.y,l.y,c.y)),i}copy(t){super.copy(t),this.points=[];for(let e=0,i=t.points.length;e=i){const t=s[r]-i,n=this.curves[r],a=n.getLength(),o=0===a?0:1-t/a;return n.getPointAt(o,e)}r++}return null}getLength(){const t=this.getCurveLengths();return t[t.length-1]}updateArcLengths(){this.needsUpdate=!0,this.cacheLengths=null,this.getCurveLengths()}getCurveLengths(){if(this.cacheLengths&&this.cacheLengths.length===this.curves.length)return this.cacheLengths;const t=[];let e=0;for(let i=0,s=this.curves.length;i1&&!e[e.length-1].equals(e[0])&&e.push(e[0]),e}copy(t){super.copy(t),this.curves=[];for(let e=0,i=t.curves.length;e0){const t=h.getPoint(0);t.equals(this.currentPoint)||this.lineTo(t.x,t.y)}this.curves.push(h);const l=h.getPoint(1);return this.currentPoint.copy(l),this}copy(t){return super.copy(t),this.currentPoint.copy(t.currentPoint),this}toJSON(){const t=super.toJSON();return t.currentPoint=this.currentPoint.toArray(),t}fromJSON(t){return super.fromJSON(t),this.currentPoint.fromArray(t.currentPoint),this}}class Yh extends Xh{constructor(t){super(t),this.uuid=ys(),this.type="Shape",this.holes=[]}getPointsHoles(t){const e=[];for(let i=0,s=this.holes.length;i80*i){o=t[0],h=t[1];let e=o,s=h;for(let n=i;ne&&(e=i),r>s&&(s=r)}l=Math.max(e-o,s-h),l=0!==l?32767/l:0}return $h(n,a,i,o,h,l,0),a}function Zh(t,e,i,s,r){let n;if(r===function(t,e,i,s){let r=0;for(let n=e,a=i-s;n0)for(let r=e;r=e;r-=s)n=fl(r/s|0,t[r],t[r+1],n);return n&&ul(n,n.next)&&(xl(n),n=n.next),n}function Gh(t,e){if(!t)return t;e||(e=t);let i,s=t;do{if(i=!1,s.steiner||!ul(s,s.next)&&0!==cl(s.prev,s,s.next))s=s.next;else{if(xl(s),s=e=s.prev,s===s.next)break;i=!0}}while(i||s!==e);return e}function $h(t,e,i,s,r,n,a){if(!t)return;!a&&n&&function(t,e,i,s){let r=t;do{0===r.z&&(r.z=nl(r.x,r.y,e,i,s)),r.prevZ=r.prev,r.nextZ=r.next,r=r.next}while(r!==t);r.prevZ.nextZ=null,r.prevZ=null,function(t){let e,i=1;do{let s,r=t;t=null;let n=null;for(e=0;r;){e++;let a=r,o=0;for(let t=0;t0||h>0&&a;)0!==o&&(0===h||!a||r.z<=a.z)?(s=r,r=r.nextZ,o--):(s=a,a=a.nextZ,h--),n?n.nextZ=s:t=s,s.prevZ=n,n=s;r=a}n.nextZ=null,i*=2}while(e>1)}(r)}(t,s,r,n);let o=t;for(;t.prev!==t.next;){const h=t.prev,l=t.next;if(n?Kh(t,s,r,n):Qh(t))e.push(h.i,t.i,l.i),xl(t),t=l.next,o=l.next;else if((t=l)===o){a?1===a?$h(t=tl(Gh(t),e),e,i,s,r,n,2):2===a&&el(t,e,i,s,r,n):$h(Gh(t),e,i,s,r,n,1);break}}}function Qh(t){const e=t.prev,i=t,s=t.next;if(cl(e,i,s)>=0)return!1;const r=e.x,n=i.x,a=s.x,o=e.y,h=i.y,l=s.y,c=Math.min(r,n,a),u=Math.min(o,h,l),d=Math.max(r,n,a),p=Math.max(o,h,l);let m=s.next;for(;m!==e;){if(m.x>=c&&m.x<=d&&m.y>=u&&m.y<=p&&hl(r,o,n,h,a,l,m.x,m.y)&&cl(m.prev,m,m.next)>=0)return!1;m=m.next}return!0}function Kh(t,e,i,s){const r=t.prev,n=t,a=t.next;if(cl(r,n,a)>=0)return!1;const o=r.x,h=n.x,l=a.x,c=r.y,u=n.y,d=a.y,p=Math.min(o,h,l),m=Math.min(c,u,d),y=Math.max(o,h,l),g=Math.max(c,u,d),f=nl(p,m,e,i,s),x=nl(y,g,e,i,s);let b=t.prevZ,v=t.nextZ;for(;b&&b.z>=f&&v&&v.z<=x;){if(b.x>=p&&b.x<=y&&b.y>=m&&b.y<=g&&b!==r&&b!==a&&hl(o,c,h,u,l,d,b.x,b.y)&&cl(b.prev,b,b.next)>=0)return!1;if(b=b.prevZ,v.x>=p&&v.x<=y&&v.y>=m&&v.y<=g&&v!==r&&v!==a&&hl(o,c,h,u,l,d,v.x,v.y)&&cl(v.prev,v,v.next)>=0)return!1;v=v.nextZ}for(;b&&b.z>=f;){if(b.x>=p&&b.x<=y&&b.y>=m&&b.y<=g&&b!==r&&b!==a&&hl(o,c,h,u,l,d,b.x,b.y)&&cl(b.prev,b,b.next)>=0)return!1;b=b.prevZ}for(;v&&v.z<=x;){if(v.x>=p&&v.x<=y&&v.y>=m&&v.y<=g&&v!==r&&v!==a&&hl(o,c,h,u,l,d,v.x,v.y)&&cl(v.prev,v,v.next)>=0)return!1;v=v.nextZ}return!0}function tl(t,e){let i=t;do{const s=i.prev,r=i.next.next;!ul(s,r)&&dl(s,i,i.next,r)&&yl(s,r)&&yl(r,s)&&(e.push(s.i,i.i,r.i),xl(i),xl(i.next),i=t=r),i=i.next}while(i!==t);return Gh(i)}function el(t,e,i,s,r,n){let a=t;do{let t=a.next.next;for(;t!==a.prev;){if(a.i!==t.i&&ll(a,t)){let o=gl(a,t);return a=Gh(a,a.next),o=Gh(o,o.next),$h(a,e,i,s,r,n,0),void $h(o,e,i,s,r,n,0)}t=t.next}a=a.next}while(a!==t)}function il(t,e){let i=t.x-e.x;if(0===i&&(i=t.y-e.y,0===i)){i=(t.next.y-t.y)/(t.next.x-t.x)-(e.next.y-e.y)/(e.next.x-e.x)}return i}function sl(t,e){const i=function(t,e){let i=e;const s=t.x,r=t.y;let n,a=-1/0;if(ul(t,i))return i;do{if(ul(t,i.next))return i.next;if(r<=i.y&&r>=i.next.y&&i.next.y!==i.y){const t=i.x+(r-i.y)*(i.next.x-i.x)/(i.next.y-i.y);if(t<=s&&t>a&&(a=t,n=i.x=i.x&&i.x>=h&&s!==i.x&&ol(rn.x||i.x===n.x&&rl(n,i)))&&(n=i,c=e)}i=i.next}while(i!==o);return n}(t,e);if(!i)return e;const s=gl(i,t);return Gh(s,s.next),Gh(i,i.next)}function rl(t,e){return cl(t.prev,t,e.prev)<0&&cl(e.next,t,t.next)<0}function nl(t,e,i,s,r){return(t=1431655765&((t=858993459&((t=252645135&((t=16711935&((t=(t-i)*r|0)|t<<8))|t<<4))|t<<2))|t<<1))|(e=1431655765&((e=858993459&((e=252645135&((e=16711935&((e=(e-s)*r|0)|e<<8))|e<<4))|e<<2))|e<<1))<<1}function al(t){let e=t,i=t;do{(e.x=(t-a)*(n-o)&&(t-a)*(s-o)>=(i-a)*(e-o)&&(i-a)*(n-o)>=(r-a)*(s-o)}function hl(t,e,i,s,r,n,a,o){return!(t===a&&e===o)&&ol(t,e,i,s,r,n,a,o)}function ll(t,e){return t.next.i!==e.i&&t.prev.i!==e.i&&!function(t,e){let i=t;do{if(i.i!==t.i&&i.next.i!==t.i&&i.i!==e.i&&i.next.i!==e.i&&dl(i,i.next,t,e))return!0;i=i.next}while(i!==t);return!1}(t,e)&&(yl(t,e)&&yl(e,t)&&function(t,e){let i=t,s=!1;const r=(t.x+e.x)/2,n=(t.y+e.y)/2;do{i.y>n!=i.next.y>n&&i.next.y!==i.y&&r<(i.next.x-i.x)*(n-i.y)/(i.next.y-i.y)+i.x&&(s=!s),i=i.next}while(i!==t);return s}(t,e)&&(cl(t.prev,t,e.prev)||cl(t,e.prev,e))||ul(t,e)&&cl(t.prev,t,t.next)>0&&cl(e.prev,e,e.next)>0)}function cl(t,e,i){return(e.y-t.y)*(i.x-e.x)-(e.x-t.x)*(i.y-e.y)}function ul(t,e){return t.x===e.x&&t.y===e.y}function dl(t,e,i,s){const r=ml(cl(t,e,i)),n=ml(cl(t,e,s)),a=ml(cl(i,s,t)),o=ml(cl(i,s,e));return r!==n&&a!==o||(!(0!==r||!pl(t,i,e))||(!(0!==n||!pl(t,s,e))||(!(0!==a||!pl(i,t,s))||!(0!==o||!pl(i,e,s)))))}function pl(t,e,i){return e.x<=Math.max(t.x,i.x)&&e.x>=Math.min(t.x,i.x)&&e.y<=Math.max(t.y,i.y)&&e.y>=Math.min(t.y,i.y)}function ml(t){return t>0?1:t<0?-1:0}function yl(t,e){return cl(t.prev,t,t.next)<0?cl(t,e,t.next)>=0&&cl(t,t.prev,e)>=0:cl(t,e,t.prev)<0||cl(t,t.next,e)<0}function gl(t,e){const i=bl(t.i,t.x,t.y),s=bl(e.i,e.x,e.y),r=t.next,n=e.prev;return t.next=e,e.prev=t,i.next=r,r.prev=i,s.next=i,i.prev=s,n.next=s,s.prev=n,s}function fl(t,e,i,s){const r=bl(t,e,i);return s?(r.next=s.next,r.prev=s,s.next.prev=r,s.next=r):(r.prev=r,r.next=r),r}function xl(t){t.next.prev=t.prev,t.prev.next=t.next,t.prevZ&&(t.prevZ.nextZ=t.nextZ),t.nextZ&&(t.nextZ.prevZ=t.prevZ)}function bl(t,e,i){return{i:t,x:e,y:i,prev:null,next:null,z:0,prevZ:null,nextZ:null,steiner:!1}}class vl{static triangulate(t,e,i=2){return Hh(t,e,i)}}class wl{static area(t){const e=t.length;let i=0;for(let s=e-1,r=0;r2&&t[e-1].equals(t[0])&&t.pop()}function Sl(t,e){for(let i=0;iNumber.EPSILON){const u=Math.sqrt(c),d=Math.sqrt(h*h+l*l),p=e.x-o/u,m=e.y+a/u,y=((i.x-l/d-p)*l-(i.y+h/d-m)*h)/(a*l-o*h);s=p+a*y-t.x,r=m+o*y-t.y;const g=s*s+r*r;if(g<=2)return new Ms(s,r);n=Math.sqrt(g/2)}else{let t=!1;a>Number.EPSILON?h>Number.EPSILON&&(t=!0):a<-Number.EPSILON?h<-Number.EPSILON&&(t=!0):Math.sign(o)===Math.sign(l)&&(t=!0),t?(s=-o,r=a,n=Math.sqrt(c)):(s=a,r=o,n=Math.sqrt(c/2))}return new Ms(s/n,r/n)}const k=[];for(let t=0,e=z.length,i=e-1,s=t+1;t=0;t--){const e=t/p,i=c*Math.cos(e*Math.PI/2),s=u*Math.sin(e*Math.PI/2)+d;for(let t=0,e=z.length;t=0;){const s=i;let r=i-1;r<0&&(r=t.length-1);for(let t=0,i=o+2*p;t0)&&d.push(e,r,h),(t!==i-1||o0&&(e.defines=this.defines),e.vertexShader=this.vertexShader,e.fragmentShader=this.fragmentShader,e.lights=this.lights,e.clipping=this.clipping;const i={};for(const t in this.extensions)!0===this.extensions[t]&&(i[t]=!0);return Object.keys(i).length>0&&(e.extensions=i),e}}class Xl extends ql{constructor(t){super(t),this.isRawShaderMaterial=!0,this.type="RawShaderMaterial"}}class Yl extends Yn{constructor(t){super(),this.isMeshStandardMaterial=!0,this.type="MeshStandardMaterial",this.defines={STANDARD:""},this.color=new kr(16777215),this.roughness=1,this.metalness=0,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new kr(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.roughnessMap=null,this.metalnessMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new ar,this.envMapIntensity=1,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.defines={STANDARD:""},this.color.copy(t.color),this.roughness=t.roughness,this.metalness=t.metalness,this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.roughnessMap=t.roughnessMap,this.metalnessMap=t.metalnessMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.envMapIntensity=t.envMapIntensity,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class Hl extends Yl{constructor(t){super(),this.isMeshPhysicalMaterial=!0,this.defines={STANDARD:"",PHYSICAL:""},this.type="MeshPhysicalMaterial",this.anisotropyRotation=0,this.anisotropyMap=null,this.clearcoatMap=null,this.clearcoatRoughness=0,this.clearcoatRoughnessMap=null,this.clearcoatNormalScale=new Ms(1,1),this.clearcoatNormalMap=null,this.ior=1.5,Object.defineProperty(this,"reflectivity",{get:function(){return gs(2.5*(this.ior-1)/(this.ior+1),0,1)},set:function(t){this.ior=(1+.4*t)/(1-.4*t)}}),this.iridescenceMap=null,this.iridescenceIOR=1.3,this.iridescenceThicknessRange=[100,400],this.iridescenceThicknessMap=null,this.sheenColor=new kr(0),this.sheenColorMap=null,this.sheenRoughness=1,this.sheenRoughnessMap=null,this.transmissionMap=null,this.thickness=0,this.thicknessMap=null,this.attenuationDistance=1/0,this.attenuationColor=new kr(1,1,1),this.specularIntensity=1,this.specularIntensityMap=null,this.specularColor=new kr(1,1,1),this.specularColorMap=null,this._anisotropy=0,this._clearcoat=0,this._dispersion=0,this._iridescence=0,this._sheen=0,this._transmission=0,this.setValues(t)}get anisotropy(){return this._anisotropy}set anisotropy(t){this._anisotropy>0!=t>0&&this.version++,this._anisotropy=t}get clearcoat(){return this._clearcoat}set clearcoat(t){this._clearcoat>0!=t>0&&this.version++,this._clearcoat=t}get iridescence(){return this._iridescence}set iridescence(t){this._iridescence>0!=t>0&&this.version++,this._iridescence=t}get dispersion(){return this._dispersion}set dispersion(t){this._dispersion>0!=t>0&&this.version++,this._dispersion=t}get sheen(){return this._sheen}set sheen(t){this._sheen>0!=t>0&&this.version++,this._sheen=t}get transmission(){return this._transmission}set transmission(t){this._transmission>0!=t>0&&this.version++,this._transmission=t}copy(t){return super.copy(t),this.defines={STANDARD:"",PHYSICAL:""},this.anisotropy=t.anisotropy,this.anisotropyRotation=t.anisotropyRotation,this.anisotropyMap=t.anisotropyMap,this.clearcoat=t.clearcoat,this.clearcoatMap=t.clearcoatMap,this.clearcoatRoughness=t.clearcoatRoughness,this.clearcoatRoughnessMap=t.clearcoatRoughnessMap,this.clearcoatNormalMap=t.clearcoatNormalMap,this.clearcoatNormalScale.copy(t.clearcoatNormalScale),this.dispersion=t.dispersion,this.ior=t.ior,this.iridescence=t.iridescence,this.iridescenceMap=t.iridescenceMap,this.iridescenceIOR=t.iridescenceIOR,this.iridescenceThicknessRange=[...t.iridescenceThicknessRange],this.iridescenceThicknessMap=t.iridescenceThicknessMap,this.sheen=t.sheen,this.sheenColor.copy(t.sheenColor),this.sheenColorMap=t.sheenColorMap,this.sheenRoughness=t.sheenRoughness,this.sheenRoughnessMap=t.sheenRoughnessMap,this.transmission=t.transmission,this.transmissionMap=t.transmissionMap,this.thickness=t.thickness,this.thicknessMap=t.thicknessMap,this.attenuationDistance=t.attenuationDistance,this.attenuationColor.copy(t.attenuationColor),this.specularIntensity=t.specularIntensity,this.specularIntensityMap=t.specularIntensityMap,this.specularColor.copy(t.specularColor),this.specularColorMap=t.specularColorMap,this}}class Zl extends Yn{constructor(t){super(),this.isMeshPhongMaterial=!0,this.type="MeshPhongMaterial",this.color=new kr(16777215),this.specular=new kr(1118481),this.shininess=30,this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new kr(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new ar,this.combine=0,this.reflectivity=1,this.envMapIntensity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.specular.copy(t.specular),this.shininess=t.shininess,this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.envMapIntensity=t.envMapIntensity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class Gl extends Yn{constructor(t){super(),this.isMeshToonMaterial=!0,this.defines={TOON:""},this.type="MeshToonMaterial",this.color=new kr(16777215),this.map=null,this.gradientMap=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new kr(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.alphaMap=null,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.gradientMap=t.gradientMap,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.alphaMap=t.alphaMap,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.fog=t.fog,this}}class $l extends Yn{constructor(t){super(),this.isMeshNormalMaterial=!0,this.type="MeshNormalMaterial",this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.flatShading=!1,this.setValues(t)}copy(t){return super.copy(t),this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.flatShading=t.flatShading,this}}class Ql extends Yn{constructor(t){super(),this.isMeshLambertMaterial=!0,this.type="MeshLambertMaterial",this.color=new kr(16777215),this.map=null,this.lightMap=null,this.lightMapIntensity=1,this.aoMap=null,this.aoMapIntensity=1,this.emissive=new kr(0),this.emissiveIntensity=1,this.emissiveMap=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.specularMap=null,this.alphaMap=null,this.envMap=null,this.envMapRotation=new ar,this.combine=0,this.reflectivity=1,this.envMapIntensity=1,this.refractionRatio=.98,this.wireframe=!1,this.wireframeLinewidth=1,this.wireframeLinecap="round",this.wireframeLinejoin="round",this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.color.copy(t.color),this.map=t.map,this.lightMap=t.lightMap,this.lightMapIntensity=t.lightMapIntensity,this.aoMap=t.aoMap,this.aoMapIntensity=t.aoMapIntensity,this.emissive.copy(t.emissive),this.emissiveMap=t.emissiveMap,this.emissiveIntensity=t.emissiveIntensity,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.specularMap=t.specularMap,this.alphaMap=t.alphaMap,this.envMap=t.envMap,this.envMapRotation.copy(t.envMapRotation),this.combine=t.combine,this.reflectivity=t.reflectivity,this.envMapIntensity=t.envMapIntensity,this.refractionRatio=t.refractionRatio,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.wireframeLinecap=t.wireframeLinecap,this.wireframeLinejoin=t.wireframeLinejoin,this.flatShading=t.flatShading,this.fog=t.fog,this}}class Kl extends Yn{constructor(t){super(),this.isMeshDepthMaterial=!0,this.type="MeshDepthMaterial",this.depthPacking=3200,this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.wireframe=!1,this.wireframeLinewidth=1,this.setValues(t)}copy(t){return super.copy(t),this.depthPacking=t.depthPacking,this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this}}class tc extends Yn{constructor(t){super(),this.isMeshDistanceMaterial=!0,this.type="MeshDistanceMaterial",this.map=null,this.alphaMap=null,this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.setValues(t)}copy(t){return super.copy(t),this.map=t.map,this.alphaMap=t.alphaMap,this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this}}class ec extends Yn{constructor(t){super(),this.isMeshMatcapMaterial=!0,this.defines={MATCAP:""},this.type="MeshMatcapMaterial",this.color=new kr(16777215),this.matcap=null,this.map=null,this.bumpMap=null,this.bumpScale=1,this.normalMap=null,this.normalMapType=0,this.normalScale=new Ms(1,1),this.displacementMap=null,this.displacementScale=1,this.displacementBias=0,this.alphaMap=null,this.wireframe=!1,this.wireframeLinewidth=1,this.flatShading=!1,this.fog=!0,this.setValues(t)}copy(t){return super.copy(t),this.defines={MATCAP:""},this.color.copy(t.color),this.matcap=t.matcap,this.map=t.map,this.bumpMap=t.bumpMap,this.bumpScale=t.bumpScale,this.normalMap=t.normalMap,this.normalMapType=t.normalMapType,this.normalScale.copy(t.normalScale),this.displacementMap=t.displacementMap,this.displacementScale=t.displacementScale,this.displacementBias=t.displacementBias,this.alphaMap=t.alphaMap,this.wireframe=t.wireframe,this.wireframeLinewidth=t.wireframeLinewidth,this.flatShading=t.flatShading,this.fog=t.fog,this}}class ic extends No{constructor(t){super(),this.isLineDashedMaterial=!0,this.type="LineDashedMaterial",this.scale=1,this.dashSize=3,this.gapSize=1,this.setValues(t)}copy(t){return super.copy(t),this.scale=t.scale,this.dashSize=t.dashSize,this.gapSize=t.gapSize,this}}function sc(t,e){return t&&t.constructor!==e?"number"==typeof e.BYTES_PER_ELEMENT?new e(t):Array.prototype.slice.call(t):t}function rc(t){const e=t.length,i=new Array(e);for(let t=0;t!==e;++t)i[t]=t;return i.sort(function(e,i){return t[e]-t[i]}),i}function nc(t,e,i){const s=t.length,r=new t.constructor(s);for(let n=0,a=0;a!==s;++n){const s=i[n]*e;for(let i=0;i!==e;++i)r[a++]=t[s+i]}return r}function ac(t,e,i,s){let r=1,n=t[0];for(;void 0!==n&&void 0===n[s];)n=t[r++];if(void 0===n)return;let a=n[s];if(void 0!==a)if(Array.isArray(a))do{a=n[s],void 0!==a&&(e.push(n.time),i.push(...a)),n=t[r++]}while(void 0!==n);else if(void 0!==a.toArray)do{a=n[s],void 0!==a&&(e.push(n.time),a.toArray(i,i.length)),n=t[r++]}while(void 0!==n);else do{a=n[s],void 0!==a&&(e.push(n.time),i.push(a)),n=t[r++]}while(void 0!==n)}class oc{static convertArray(t,e){return sc(t,e)}static isTypedArray(t){return Qi(t)}static getKeyframeOrder(t){return rc(t)}static sortedArray(t,e,i){return nc(t,e,i)}static flattenJSON(t,e,i,s){ac(t,e,i,s)}static subclip(t,e,i,s,r=30){return function(t,e,i,s,r=30){const n=t.clone();n.name=e;const a=[];for(let t=0;t=s)){h.push(e.times[t]);for(let i=0;in.tracks[t].times[0]&&(o=n.tracks[t].times[0]);for(let t=0;t=s.times[u]){const t=u*h+o,e=t+h-o;d=s.values.slice(t,e)}else{const t=s.createInterpolant(),e=o,i=h-o;t.evaluate(n),d=t.resultBuffer.slice(e,i)}"quaternion"===r&&(new Ss).fromArray(d).normalize().conjugate().toArray(d);const p=a.times.length;for(let t=0;t=r)){const a=e[1];t=r)break e}n=i,i=0;break i}break t}for(;i>>1;te;)--n;if(++n,0!==r||n!==s){r>=n&&(n=Math.max(n,1),r=n-1);const t=this.getValueSize();this.times=i.slice(r,n),this.values=this.values.slice(r*t,n*t)}return this}validate(){let t=!0;const e=this.getValueSize();e-Math.floor(e)!==0&&(os("KeyframeTrack: Invalid value size in track.",this),t=!1);const i=this.times,s=this.values,r=i.length;0===r&&(os("KeyframeTrack: Track is empty.",this),t=!1);let n=null;for(let e=0;e!==r;e++){const s=i[e];if("number"==typeof s&&isNaN(s)){os("KeyframeTrack: Time is not a valid number.",this,e,s),t=!1;break}if(null!==n&&n>s){os("KeyframeTrack: Out of order keys.",this,e,s,n),t=!1;break}n=s}if(void 0!==s&&Qi(s))for(let e=0,i=s.length;e!==i;++e){const i=s[e];if(isNaN(i)){os("KeyframeTrack: Value is not a valid number.",this,e,i),t=!1;break}}return t}optimize(){const t=this.times.slice(),e=this.values.slice(),i=this.getValueSize(),s=this.getInterpolation()===Fe,r=t.length-1;let n=1;for(let a=1;a0){t[n]=t[r];for(let t=r*i,s=n*i,a=0;a!==i;++a)e[s+a]=e[t+a];++n}return n!==t.length?(this.times=t.slice(0,n),this.values=e.slice(0,n*i)):(this.times=t,this.values=e),this}clone(){const t=this.times.slice(),e=this.values.slice(),i=new(0,this.constructor)(this.name,t,e);return i.createInterpolant=this.createInterpolant,i}}pc.prototype.ValueTypeName="",pc.prototype.TimeBufferType=Float32Array,pc.prototype.ValueBufferType=Float32Array,pc.prototype.DefaultInterpolation=Ee;class mc extends pc{constructor(t,e,i){super(t,e,i)}}mc.prototype.ValueTypeName="bool",mc.prototype.ValueBufferType=Array,mc.prototype.DefaultInterpolation=Ve,mc.prototype.InterpolantFactoryMethodLinear=void 0,mc.prototype.InterpolantFactoryMethodSmooth=void 0;class yc extends pc{constructor(t,e,i,s){super(t,e,i,s)}}yc.prototype.ValueTypeName="color";class gc extends pc{constructor(t,e,i,s){super(t,e,i,s)}}gc.prototype.ValueTypeName="number";class fc extends hc{constructor(t,e,i,s){super(t,e,i,s)}interpolate_(t,e,i,s){const r=this.resultBuffer,n=this.sampleValues,a=this.valueSize,o=(i-e)/(s-e);let h=t*a;for(let t=h+a;h!==t;h+=4)Ss.slerpFlat(r,0,n,h-a,n,h,o);return r}}class xc extends pc{constructor(t,e,i,s){super(t,e,i,s)}InterpolantFactoryMethodLinear(t){return new fc(this.times,this.values,this.getValueSize(),t)}}xc.prototype.ValueTypeName="quaternion",xc.prototype.InterpolantFactoryMethodSmooth=void 0;class bc extends pc{constructor(t,e,i){super(t,e,i)}}bc.prototype.ValueTypeName="string",bc.prototype.ValueBufferType=Array,bc.prototype.DefaultInterpolation=Ve,bc.prototype.InterpolantFactoryMethodLinear=void 0,bc.prototype.InterpolantFactoryMethodSmooth=void 0;class vc extends pc{constructor(t,e,i,s){super(t,e,i,s)}}vc.prototype.ValueTypeName="vector";class wc{constructor(t="",e=-1,i=[],s=2500){this.name=t,this.tracks=i,this.duration=e,this.blendMode=s,this.uuid=ys(),this.userData={},this.duration<0&&this.resetDuration()}static parse(t){const e=[],i=t.tracks,s=1/(t.fps||1);for(let t=0,r=i.length;t!==r;++t)e.push(Mc(i[t]).scale(s));const r=new this(t.name,t.duration,e,t.blendMode);return r.uuid=t.uuid,r.userData=JSON.parse(t.userData||"{}"),r}static toJSON(t){const e=[],i=t.tracks,s={name:t.name,duration:t.duration,tracks:e,uuid:t.uuid,blendMode:t.blendMode,userData:JSON.stringify(t.userData)};for(let t=0,s=i.length;t!==s;++t)e.push(pc.toJSON(i[t]));return s}static CreateFromMorphTargetSequence(t,e,i,s){const r=e.length,n=[];for(let t=0;t1){const t=n[1];let e=s[t];e||(s[t]=e=[]),e.push(i)}}const n=[];for(const t in s)n.push(this.CreateFromMorphTargetSequence(t,s[t],e,i));return n}static parseAnimation(t,e){if(as("AnimationClip: parseAnimation() is deprecated and will be removed with r185"),!t)return os("AnimationClip: No animation in JSONLoader data."),null;const i=function(t,e,i,s,r){if(0!==i.length){const n=[],a=[];ac(i,n,a,s),0!==n.length&&r.push(new t(e,n,a))}},s=[],r=t.name||"default",n=t.fps||30,a=t.blendMode;let o=t.length||-1;const h=t.hierarchy||[];for(let t=0;t{e&&e(r),this.manager.itemEnd(t)},0),r;if(void 0!==zc[t])return void zc[t].push({onLoad:e,onProgress:i,onError:s});zc[t]=[],zc[t].push({onLoad:e,onProgress:i,onError:s});const n=new Request(t,{headers:new Headers(this.requestHeader),credentials:this.withCredentials?"include":"same-origin",signal:"function"==typeof AbortSignal.any?AbortSignal.any([this._abortController.signal,this.manager.abortController.signal]):this._abortController.signal}),a=this.mimeType,o=this.responseType;fetch(n).then(e=>{if(200===e.status||0===e.status){if(0===e.status&&as("FileLoader: HTTP Status 0 received."),"undefined"==typeof ReadableStream||void 0===e.body||void 0===e.body.getReader)return e;const i=zc[t],s=e.body.getReader(),r=e.headers.get("X-File-Size")||e.headers.get("Content-Length"),n=r?parseInt(r):0,a=0!==n;let o=0;const h=new ReadableStream({start(t){!function e(){s.read().then(({done:s,value:r})=>{if(s)t.close();else{o+=r.byteLength;const s=new ProgressEvent("progress",{lengthComputable:a,loaded:o,total:n});for(let t=0,e=i.length;t{t.error(e)})}()}});return new Response(h)}throw new Cc(`fetch for "${e.url}" responded with ${e.status}: ${e.statusText}`,e)}).then(t=>{switch(o){case"arraybuffer":return t.arrayBuffer();case"blob":return t.blob();case"document":return t.text().then(t=>(new DOMParser).parseFromString(t,a));case"json":return t.json();default:if(""===a)return t.text();{const e=/charset="?([^;"\s]*)"?/i.exec(a),i=e&&e[1]?e[1].toLowerCase():void 0,s=new TextDecoder(i);return t.arrayBuffer().then(t=>s.decode(t))}}}).then(e=>{Sc.add(`file:${t}`,e);const i=zc[t];delete zc[t];for(let t=0,s=i.length;t{const i=zc[t];if(void 0===i)throw this.manager.itemError(t),e;delete zc[t];for(let t=0,s=i.length;t{this.manager.itemEnd(t)}),this.manager.itemStart(t)}setResponseType(t){return this.responseType=t,this}setMimeType(t){return this.mimeType=t,this}abort(){return this._abortController.abort(),this._abortController=new AbortController,this}}class Bc extends Tc{constructor(t){super(t)}load(t,e,i,s){const r=this,n=new Ic(this.manager);n.setPath(this.path),n.setRequestHeader(this.requestHeader),n.setWithCredentials(this.withCredentials),n.load(t,function(i){try{e(r.parse(JSON.parse(i)))}catch(e){s?s(e):os(e),r.manager.itemError(t)}},i,s)}parse(t){const e=[];for(let i=0;i0:s.vertexColors=t.vertexColors),void 0!==t.uniforms)for(const e in t.uniforms){const r=t.uniforms[e];switch(s.uniforms[e]={},r.type){case"t":s.uniforms[e].value=i(r.value);break;case"c":s.uniforms[e].value=(new kr).setHex(r.value);break;case"v2":s.uniforms[e].value=(new Ms).fromArray(r.value);break;case"v3":s.uniforms[e].value=(new _s).fromArray(r.value);break;case"v4":s.uniforms[e].value=(new Us).fromArray(r.value);break;case"m3":s.uniforms[e].value=(new zs).fromArray(r.value);break;case"m4":s.uniforms[e].value=(new Gs).fromArray(r.value);break;default:s.uniforms[e].value=r.value}}if(void 0!==t.defines&&(s.defines=t.defines),void 0!==t.vertexShader&&(s.vertexShader=t.vertexShader),void 0!==t.fragmentShader&&(s.fragmentShader=t.fragmentShader),void 0!==t.glslVersion&&(s.glslVersion=t.glslVersion),void 0!==t.extensions)for(const e in t.extensions)s.extensions[e]=t.extensions[e];if(void 0!==t.lights&&(s.lights=t.lights),void 0!==t.clipping&&(s.clipping=t.clipping),void 0!==t.size&&(s.size=t.size),void 0!==t.sizeAttenuation&&(s.sizeAttenuation=t.sizeAttenuation),void 0!==t.map&&(s.map=i(t.map)),void 0!==t.matcap&&(s.matcap=i(t.matcap)),void 0!==t.alphaMap&&(s.alphaMap=i(t.alphaMap)),void 0!==t.bumpMap&&(s.bumpMap=i(t.bumpMap)),void 0!==t.bumpScale&&(s.bumpScale=t.bumpScale),void 0!==t.normalMap&&(s.normalMap=i(t.normalMap)),void 0!==t.normalMapType&&(s.normalMapType=t.normalMapType),void 0!==t.normalScale){let e=t.normalScale;!1===Array.isArray(e)&&(e=[e,e]),s.normalScale=(new Ms).fromArray(e)}return void 0!==t.displacementMap&&(s.displacementMap=i(t.displacementMap)),void 0!==t.displacementScale&&(s.displacementScale=t.displacementScale),void 0!==t.displacementBias&&(s.displacementBias=t.displacementBias),void 0!==t.roughnessMap&&(s.roughnessMap=i(t.roughnessMap)),void 0!==t.metalnessMap&&(s.metalnessMap=i(t.metalnessMap)),void 0!==t.emissiveMap&&(s.emissiveMap=i(t.emissiveMap)),void 0!==t.emissiveIntensity&&(s.emissiveIntensity=t.emissiveIntensity),void 0!==t.specularMap&&(s.specularMap=i(t.specularMap)),void 0!==t.specularIntensityMap&&(s.specularIntensityMap=i(t.specularIntensityMap)),void 0!==t.specularColorMap&&(s.specularColorMap=i(t.specularColorMap)),void 0!==t.envMap&&(s.envMap=i(t.envMap)),void 0!==t.envMapRotation&&s.envMapRotation.fromArray(t.envMapRotation),void 0!==t.envMapIntensity&&(s.envMapIntensity=t.envMapIntensity),void 0!==t.reflectivity&&(s.reflectivity=t.reflectivity),void 0!==t.refractionRatio&&(s.refractionRatio=t.refractionRatio),void 0!==t.lightMap&&(s.lightMap=i(t.lightMap)),void 0!==t.lightMapIntensity&&(s.lightMapIntensity=t.lightMapIntensity),void 0!==t.aoMap&&(s.aoMap=i(t.aoMap)),void 0!==t.aoMapIntensity&&(s.aoMapIntensity=t.aoMapIntensity),void 0!==t.gradientMap&&(s.gradientMap=i(t.gradientMap)),void 0!==t.clearcoatMap&&(s.clearcoatMap=i(t.clearcoatMap)),void 0!==t.clearcoatRoughnessMap&&(s.clearcoatRoughnessMap=i(t.clearcoatRoughnessMap)),void 0!==t.clearcoatNormalMap&&(s.clearcoatNormalMap=i(t.clearcoatNormalMap)),void 0!==t.clearcoatNormalScale&&(s.clearcoatNormalScale=(new Ms).fromArray(t.clearcoatNormalScale)),void 0!==t.iridescenceMap&&(s.iridescenceMap=i(t.iridescenceMap)),void 0!==t.iridescenceThicknessMap&&(s.iridescenceThicknessMap=i(t.iridescenceThicknessMap)),void 0!==t.transmissionMap&&(s.transmissionMap=i(t.transmissionMap)),void 0!==t.thicknessMap&&(s.thicknessMap=i(t.thicknessMap)),void 0!==t.anisotropyMap&&(s.anisotropyMap=i(t.anisotropyMap)),void 0!==t.sheenColorMap&&(s.sheenColorMap=i(t.sheenColorMap)),void 0!==t.sheenRoughnessMap&&(s.sheenRoughnessMap=i(t.sheenRoughnessMap)),s}setTextures(t){return this.textures=t,this}createMaterialFromType(t){return hu.createMaterialFromType(t)}static createMaterialFromType(t){return new{ShadowMaterial:Dl,SpriteMaterial:Hn,RawShaderMaterial:Xl,ShaderMaterial:ql,PointsMaterial:Zo,MeshPhysicalMaterial:Hl,MeshStandardMaterial:Yl,MeshPhongMaterial:Zl,MeshToonMaterial:Gl,MeshNormalMaterial:$l,MeshLambertMaterial:Ql,MeshDepthMaterial:Kl,MeshDistanceMaterial:tc,MeshBasicMaterial:va,MeshMatcapMaterial:ec,LineDashedMaterial:ic,LineBasicMaterial:No,Material:Yn}[t]}}class lu{static extractUrlBase(t){const e=t.lastIndexOf("/");return-1===e?"./":t.slice(0,e+1)}static resolveURL(t,e){return"string"!=typeof t||""===t?"":(/^https?:\/\//i.test(e)&&/^\//.test(t)&&(e=e.replace(/(^https?:\/\/[^\/]+).*/i,"$1")),/^(https?:)?\/\//i.test(t)||/^data:.*,.*$/i.test(t)||/^blob:.*$/i.test(t)?t:e+t)}}class cu extends jn{constructor(){super(),this.isInstancedBufferGeometry=!0,this.type="InstancedBufferGeometry",this.instanceCount=1/0}copy(t){return super.copy(t),this.instanceCount=t.instanceCount,this}toJSON(){const t=super.toJSON();return t.instanceCount=this.instanceCount,t.isInstancedBufferGeometry=!0,t}}class uu extends Tc{constructor(t){super(t)}load(t,e,i,s){const r=this,n=new Ic(r.manager);n.setPath(r.path),n.setRequestHeader(r.requestHeader),n.setWithCredentials(r.withCredentials),n.load(t,function(i){try{e(r.parse(JSON.parse(i)))}catch(e){s?s(e):os(e),r.manager.itemError(t)}},i,s)}parse(t){const e={},i={};function s(t,s){if(void 0!==e[s])return e[s];const r=t.interleavedBuffers[s],n=function(t,e){if(void 0!==i[e])return i[e];const s=t.arrayBuffers,r=s[e],n=new Uint32Array(r).buffer;return i[e]=n,n}(t,r.buffer),a=$i(r.type,n),o=new Wn(a,r.stride);return o.uuid=r.uuid,e[s]=o,o}const r=t.isInstancedBufferGeometry?new cu:new jn,n=t.data.index;if(void 0!==n){const t=$i(n.type,n.array);r.setIndex(new vn(t,1))}const a=t.data.attributes;for(const e in a){const i=a[e];let n;if(i.isInterleavedBufferAttribute){const e=s(t.data,i.data);n=new Jn(e,i.itemSize,i.offset,i.normalized)}else{const t=$i(i.type,i.array);n=new(i.isInstancedBufferAttribute?Za:vn)(t,i.itemSize,i.normalized)}void 0!==i.name&&(n.name=i.name),void 0!==i.usage&&n.setUsage(i.usage),r.setAttribute(e,n)}const o=t.data.morphAttributes;if(o)for(const e in o){const i=o[e],n=[];for(let e=0,r=i.length;e0){const i=new _c(e);r=new Pc(i),r.setCrossOrigin(this.crossOrigin);for(let e=0,i=t.length;e0){s=new Pc(this.manager),s.setCrossOrigin(this.crossOrigin);for(let e=0,s=t.length;e{let e=null,i=null;return void 0!==t.boundingBox&&(e=(new Gr).fromJSON(t.boundingBox)),void 0!==t.boundingSphere&&(i=(new Pn).fromJSON(t.boundingSphere)),{...t,boundingBox:e,boundingSphere:i}}),n._instanceInfo=t.instanceInfo,n._availableInstanceIds=t._availableInstanceIds,n._availableGeometryIds=t._availableGeometryIds,n._nextIndexStart=t.nextIndexStart,n._nextVertexStart=t.nextVertexStart,n._geometryCount=t.geometryCount,n._maxInstanceCount=t.maxInstanceCount,n._maxVertexCount=t.maxVertexCount,n._maxIndexCount=t.maxIndexCount,n._geometryInitialized=t.geometryInitialized,n._matricesTexture=c(t.matricesTexture.uuid),n._indirectTexture=c(t.indirectTexture.uuid),void 0!==t.colorsTexture&&(n._colorsTexture=c(t.colorsTexture.uuid)),void 0!==t.boundingSphere&&(n.boundingSphere=(new Pn).fromJSON(t.boundingSphere)),void 0!==t.boundingBox&&(n.boundingBox=(new Gr).fromJSON(t.boundingBox));break;case"LOD":n=new ua;break;case"Line":n=new Uo(h(t.geometry),l(t.material));break;case"LineLoop":n=new Ho(h(t.geometry),l(t.material));break;case"LineSegments":n=new Yo(h(t.geometry),l(t.material));break;case"PointCloud":case"Points":n=new th(h(t.geometry),l(t.material));break;case"Sprite":n=new oa(l(t.material));break;case"Group":n=new _r;break;case"Bone":n=new Ja;break;default:n=new Sr}if(n.uuid=t.uuid,void 0!==t.name&&(n.name=t.name),void 0!==t.matrix?(n.matrix.fromArray(t.matrix),void 0!==t.matrixAutoUpdate&&(n.matrixAutoUpdate=t.matrixAutoUpdate),n.matrixAutoUpdate&&n.matrix.decompose(n.position,n.quaternion,n.scale)):(void 0!==t.position&&n.position.fromArray(t.position),void 0!==t.rotation&&n.rotation.fromArray(t.rotation),void 0!==t.quaternion&&n.quaternion.fromArray(t.quaternion),void 0!==t.scale&&n.scale.fromArray(t.scale)),void 0!==t.up&&n.up.fromArray(t.up),void 0!==t.pivot&&(n.pivot=(new _s).fromArray(t.pivot)),void 0!==t.morphTargetDictionary&&(n.morphTargetDictionary=Object.assign({},t.morphTargetDictionary)),void 0!==t.morphTargetInfluences&&(n.morphTargetInfluences=t.morphTargetInfluences.slice()),void 0!==t.castShadow&&(n.castShadow=t.castShadow),void 0!==t.receiveShadow&&(n.receiveShadow=t.receiveShadow),t.shadow&&(void 0!==t.shadow.intensity&&(n.shadow.intensity=t.shadow.intensity),void 0!==t.shadow.bias&&(n.shadow.bias=t.shadow.bias),void 0!==t.shadow.normalBias&&(n.shadow.normalBias=t.shadow.normalBias),void 0!==t.shadow.radius&&(n.shadow.radius=t.shadow.radius),void 0!==t.shadow.mapSize&&n.shadow.mapSize.fromArray(t.shadow.mapSize),void 0!==t.shadow.camera&&(n.shadow.camera=this.parseObject(t.shadow.camera))),void 0!==t.visible&&(n.visible=t.visible),void 0!==t.frustumCulled&&(n.frustumCulled=t.frustumCulled),void 0!==t.renderOrder&&(n.renderOrder=t.renderOrder),void 0!==t.static&&(n.static=t.static),void 0!==t.userData&&(n.userData=t.userData),void 0!==t.layers&&(n.layers.mask=t.layers),void 0!==t.children){const a=t.children;for(let t=0;t{if(!0!==gu.has(n))return e&&e(i),r.manager.itemEnd(t),i;s&&s(gu.get(n)),r.manager.itemError(t),r.manager.itemEnd(t)}):(setTimeout(function(){e&&e(n),r.manager.itemEnd(t)},0),n);const a={};a.credentials="anonymous"===this.crossOrigin?"same-origin":"include",a.headers=this.requestHeader,a.signal="function"==typeof AbortSignal.any?AbortSignal.any([this._abortController.signal,this.manager.abortController.signal]):this._abortController.signal;const o=fetch(t,a).then(function(t){return t.blob()}).then(function(t){return createImageBitmap(t,Object.assign(r.options,{colorSpaceConversion:"none"}))}).then(function(i){return Sc.add(`image-bitmap:${t}`,i),e&&e(i),r.manager.itemEnd(t),i}).catch(function(e){s&&s(e),gu.set(o,e),Sc.remove(`image-bitmap:${t}`),r.manager.itemError(t),r.manager.itemEnd(t)});Sc.add(`image-bitmap:${t}`,o),r.manager.itemStart(t)}abort(){return this._abortController.abort(),this._abortController=new AbortController,this}}let xu;class bu{static getContext(){return void 0===xu&&(xu=new(window.AudioContext||window.webkitAudioContext)),xu}static setContext(t){xu=t}}class vu extends Tc{constructor(t){super(t)}load(t,e,i,s){const r=this,n=new Ic(this.manager);function a(e){s?s(e):os(e),r.manager.itemError(t)}n.setResponseType("arraybuffer"),n.setPath(this.path),n.setRequestHeader(this.requestHeader),n.setWithCredentials(this.withCredentials),n.load(t,function(t){try{const i=t.slice(0);bu.getContext().decodeAudioData(i,function(t){e(t)}).catch(a)}catch(t){a(t)}},i,s)}}const wu=new Gs,Mu=new Gs,Su=new Gs;class _u{constructor(){this.type="StereoCamera",this.aspect=1,this.eyeSep=.064,this.cameraL=new Gc,this.cameraL.layers.enable(1),this.cameraL.matrixAutoUpdate=!1,this.cameraR=new Gc,this.cameraR.layers.enable(2),this.cameraR.matrixAutoUpdate=!1,this._cache={focus:null,fov:null,aspect:null,near:null,far:null,zoom:null,eyeSep:null}}update(t){const e=this._cache;if(e.focus!==t.focus||e.fov!==t.fov||e.aspect!==t.aspect*this.aspect||e.near!==t.near||e.far!==t.far||e.zoom!==t.zoom||e.eyeSep!==this.eyeSep){e.focus=t.focus,e.fov=t.fov,e.aspect=t.aspect*this.aspect,e.near=t.near,e.far=t.far,e.zoom=t.zoom,e.eyeSep=this.eyeSep,Su.copy(t.projectionMatrix);const i=e.eyeSep/2,s=i*e.near/e.focus,r=e.near*Math.tan(ps*e.fov*.5)/e.zoom;let n,a;Mu.elements[12]=-i,wu.elements[12]=i,n=-r*e.aspect+s,a=r*e.aspect+s,Su.elements[0]=2*e.near/(a-n),Su.elements[8]=(a+n)/(a-n),this.cameraL.projectionMatrix.copy(Su),n=-r*e.aspect-s,a=r*e.aspect-s,Su.elements[0]=2*e.near/(a-n),Su.elements[8]=(a+n)/(a-n),this.cameraR.projectionMatrix.copy(Su)}this.cameraL.matrixWorld.copy(t.matrixWorld).multiply(Mu),this.cameraR.matrixWorld.copy(t.matrixWorld).multiply(wu)}}const Au=-90;class Tu extends Sr{constructor(t,e,i){super(),this.type="CubeCamera",this.renderTarget=i,this.coordinateSystem=null,this.activeMipmapLevel=0;const s=new Gc(Au,1,t,e);s.layers=this.layers,this.add(s);const r=new Gc(Au,1,t,e);r.layers=this.layers,this.add(r);const n=new Gc(Au,1,t,e);n.layers=this.layers,this.add(n);const a=new Gc(Au,1,t,e);a.layers=this.layers,this.add(a);const o=new Gc(Au,1,t,e);o.layers=this.layers,this.add(o);const h=new Gc(Au,1,t,e);h.layers=this.layers,this.add(h)}updateCoordinateSystem(){const t=this.coordinateSystem,e=this.children.concat(),[i,s,r,n,a,o]=e;for(const t of e)this.remove(t);if(t===Ui)i.up.set(0,1,0),i.lookAt(1,0,0),s.up.set(0,1,0),s.lookAt(-1,0,0),r.up.set(0,0,-1),r.lookAt(0,1,0),n.up.set(0,0,1),n.lookAt(0,-1,0),a.up.set(0,1,0),a.lookAt(0,0,1),o.up.set(0,1,0),o.lookAt(0,0,-1);else{if(t!==Ji)throw new Error("THREE.CubeCamera.updateCoordinateSystem(): Invalid coordinate system: "+t);i.up.set(0,-1,0),i.lookAt(-1,0,0),s.up.set(0,-1,0),s.lookAt(1,0,0),r.up.set(0,0,1),r.lookAt(0,1,0),n.up.set(0,0,-1),n.lookAt(0,-1,0),a.up.set(0,-1,0),a.lookAt(0,0,1),o.up.set(0,-1,0),o.lookAt(0,0,-1)}for(const t of e)this.add(t),t.updateMatrixWorld()}update(t,e){null===this.parent&&this.updateMatrixWorld();const{renderTarget:i,activeMipmapLevel:s}=this;this.coordinateSystem!==t.coordinateSystem&&(this.coordinateSystem=t.coordinateSystem,this.updateCoordinateSystem());const[r,n,a,o,h,l]=this.children,c=t.getRenderTarget(),u=t.getActiveCubeFace(),d=t.getActiveMipmapLevel(),p=t.xr.enabled;t.xr.enabled=!1;const m=i.texture.generateMipmaps;i.texture.generateMipmaps=!1;const y=!(!t.isWebGLRenderer||!t.state.buffers.depth.getReversed());t.setRenderTarget(i,0,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,r),t.setRenderTarget(i,1,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,n),t.setRenderTarget(i,2,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,a),t.setRenderTarget(i,3,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,o),t.setRenderTarget(i,4,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,h),i.texture.generateMipmaps=m,t.setRenderTarget(i,5,s),y&&!1===t.autoClear&&t.clearDepth(),t.render(e,l),t.setRenderTarget(c,u,d),t.xr.enabled=p,i.texture.needsPMREMUpdate=!0}}class zu extends Gc{constructor(t=[]){super(),this.isArrayCamera=!0,this.isMultiViewCamera=!1,this.cameras=t}}class Cu{constructor(t=!0){this.autoStart=t,this.startTime=0,this.oldTime=0,this.elapsedTime=0,this.running=!1,as("THREE.Clock: This module has been deprecated. Please use THREE.Timer instead.")}start(){this.startTime=performance.now(),this.oldTime=this.startTime,this.elapsedTime=0,this.running=!0}stop(){this.getElapsedTime(),this.running=!1,this.autoStart=!1}getElapsedTime(){return this.getDelta(),this.elapsedTime}getDelta(){let t=0;if(this.autoStart&&!this.running)return this.start(),0;if(this.running){const e=performance.now();t=(e-this.oldTime)/1e3,this.oldTime=e,this.elapsedTime+=t}return t}}const Iu=new _s,Bu=new Ss,ku=new _s,Ou=new _s,Pu=new _s;class Ru extends Sr{constructor(){super(),this.type="AudioListener",this.context=bu.getContext(),this.gain=this.context.createGain(),this.gain.connect(this.context.destination),this.filter=null,this.timeDelta=0,this._clock=new Cu}getInput(){return this.gain}removeFilter(){return null!==this.filter&&(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination),this.gain.connect(this.context.destination),this.filter=null),this}getFilter(){return this.filter}setFilter(t){return null!==this.filter?(this.gain.disconnect(this.filter),this.filter.disconnect(this.context.destination)):this.gain.disconnect(this.context.destination),this.filter=t,this.gain.connect(this.filter),this.filter.connect(this.context.destination),this}getMasterVolume(){return this.gain.gain.value}setMasterVolume(t){return this.gain.gain.setTargetAtTime(t,this.context.currentTime,.01),this}updateMatrixWorld(t){super.updateMatrixWorld(t);const e=this.context.listener;if(this.timeDelta=this._clock.getDelta(),this.matrixWorld.decompose(Iu,Bu,ku),Ou.set(0,0,-1).applyQuaternion(Bu),Pu.set(0,1,0).applyQuaternion(Bu),e.positionX){const t=this.context.currentTime+this.timeDelta;e.positionX.linearRampToValueAtTime(Iu.x,t),e.positionY.linearRampToValueAtTime(Iu.y,t),e.positionZ.linearRampToValueAtTime(Iu.z,t),e.forwardX.linearRampToValueAtTime(Ou.x,t),e.forwardY.linearRampToValueAtTime(Ou.y,t),e.forwardZ.linearRampToValueAtTime(Ou.z,t),e.upX.linearRampToValueAtTime(Pu.x,t),e.upY.linearRampToValueAtTime(Pu.y,t),e.upZ.linearRampToValueAtTime(Pu.z,t)}else e.setPosition(Iu.x,Iu.y,Iu.z),e.setOrientation(Ou.x,Ou.y,Ou.z,Pu.x,Pu.y,Pu.z)}}class Nu extends Sr{constructor(t){super(),this.type="Audio",this.listener=t,this.context=t.context,this.gain=this.context.createGain(),this.gain.connect(t.getInput()),this.autoplay=!1,this.buffer=null,this.detune=0,this.loop=!1,this.loopStart=0,this.loopEnd=0,this.offset=0,this.duration=void 0,this.playbackRate=1,this.isPlaying=!1,this.hasPlaybackControl=!0,this.source=null,this.sourceType="empty",this._startedAt=0,this._progress=0,this._connected=!1,this.filters=[]}getOutput(){return this.gain}setNodeSource(t){return this.hasPlaybackControl=!1,this.sourceType="audioNode",this.source=t,this.connect(),this}setMediaElementSource(t){return this.hasPlaybackControl=!1,this.sourceType="mediaNode",this.source=this.context.createMediaElementSource(t),this.connect(),this}setMediaStreamSource(t){return this.hasPlaybackControl=!1,this.sourceType="mediaStreamNode",this.source=this.context.createMediaStreamSource(t),this.connect(),this}setBuffer(t){return this.buffer=t,this.sourceType="buffer",this.autoplay&&this.play(),this}play(t=0){if(!0===this.isPlaying)return void as("Audio: Audio is already playing.");if(!1===this.hasPlaybackControl)return void as("Audio: this Audio has no playback control.");this._startedAt=this.context.currentTime+t;const e=this.context.createBufferSource();return e.buffer=this.buffer,e.loop=this.loop,e.loopStart=this.loopStart,e.loopEnd=this.loopEnd,e.onended=this.onEnded.bind(this),e.start(this._startedAt,this._progress+this.offset,this.duration),this.isPlaying=!0,this.source=e,this.setDetune(this.detune),this.setPlaybackRate(this.playbackRate),this.connect()}pause(){if(!1!==this.hasPlaybackControl)return!0===this.isPlaying&&(this._progress+=Math.max(this.context.currentTime-this._startedAt,0)*this.playbackRate,!0===this.loop&&(this._progress=this._progress%(this.duration||this.buffer.duration)),this.source.stop(),this.source.onended=null,this.isPlaying=!1),this;as("Audio: this Audio has no playback control.")}stop(t=0){if(!1!==this.hasPlaybackControl)return this._progress=0,null!==this.source&&(this.source.stop(this.context.currentTime+t),this.source.onended=null),this.isPlaying=!1,this;as("Audio: this Audio has no playback control.")}connect(){if(this.filters.length>0){this.source.connect(this.filters[0]);for(let t=1,e=this.filters.length;t0){this.source.disconnect(this.filters[0]);for(let t=1,e=this.filters.length;t0&&this._mixBufferRegionAdditive(i,s,this._addIndex*e,1,e);for(let t=e,r=e+e;t!==r;++t)if(i[t]!==i[t+e]){a.setValue(i,s);break}}saveOriginalState(){const t=this.binding,e=this.buffer,i=this.valueSize,s=i*this._origIndex;t.getValue(e,s);for(let t=i,r=s;t!==r;++t)e[t]=e[s+t%i];this._setIdentity(),this.cumulativeWeight=0,this.cumulativeWeightAdditive=0}restoreOriginalState(){const t=3*this.valueSize;this.binding.setValue(this.buffer,t)}_setAdditiveIdentityNumeric(){const t=this._addIndex*this.valueSize,e=t+this.valueSize;for(let i=t;i=.5)for(let s=0;s!==r;++s)t[e+s]=t[i+s]}_slerp(t,e,i,s){Ss.slerpFlat(t,e,t,e,t,i,s)}_slerpAdditive(t,e,i,s,r){const n=this._workIndex*r;Ss.multiplyQuaternionsFlat(t,n,t,e,t,i),Ss.slerpFlat(t,e,t,e,t,n,s)}_lerp(t,e,i,s,r){const n=1-s;for(let a=0;a!==r;++a){const r=e+a;t[r]=t[r]*n+t[i+a]*s}}_lerpAdditive(t,e,i,s,r){for(let n=0;n!==r;++n){const r=e+n;t[r]=t[r]+t[i+n]*s}}}const Uu="\\[\\]\\.:\\/",Ju=new RegExp("["+Uu+"]","g"),qu="[^"+Uu+"]",Xu="[^"+Uu.replace("\\.","")+"]",Yu=new RegExp("^"+/((?:WC+[\/:])*)/.source.replace("WC",qu)+/(WCOD+)?/.source.replace("WCOD",Xu)+/(?:\.(WC+)(?:\[(.+)\])?)?/.source.replace("WC",qu)+/\.(WC+)(?:\[(.+)\])?/.source.replace("WC",qu)+"$"),Hu=["material","materials","bones","map"];class Zu{constructor(t,e,i){this.path=e,this.parsedPath=i||Zu.parseTrackName(e),this.node=Zu.findNode(t,this.parsedPath.nodeName),this.rootNode=t,this.getValue=this._getValue_unbound,this.setValue=this._setValue_unbound}static create(t,e,i){return t&&t.isAnimationObjectGroup?new Zu.Composite(t,e,i):new Zu(t,e,i)}static sanitizeNodeName(t){return t.replace(/\s/g,"_").replace(Ju,"")}static parseTrackName(t){const e=Yu.exec(t);if(null===e)throw new Error("PropertyBinding: Cannot parse trackName: "+t);const i={nodeName:e[2],objectName:e[3],objectIndex:e[4],propertyName:e[5],propertyIndex:e[6]},s=i.nodeName&&i.nodeName.lastIndexOf(".");if(void 0!==s&&-1!==s){const t=i.nodeName.substring(s+1);-1!==Hu.indexOf(t)&&(i.nodeName=i.nodeName.substring(0,s),i.objectName=t)}if(null===i.propertyName||0===i.propertyName.length)throw new Error("PropertyBinding: can not parse propertyName from trackName: "+t);return i}static findNode(t,e){if(void 0===e||""===e||"."===e||-1===e||e===t.name||e===t.uuid)return t;if(t.skeleton){const i=t.skeleton.getBoneByName(e);if(void 0!==i)return i}if(t.children){const i=function(t){for(let s=0;s=r){const n=r++,l=t[n];e[l.uuid]=h,t[h]=l,e[o]=n,t[n]=a;for(let t=0,e=s;t!==e;++t){const e=i[t],s=e[n],r=e[h];e[h]=s,e[n]=r}}}this.nCachedObjects_=r}uncache(){const t=this._objects,e=this._indicesByUUID,i=this._bindings,s=i.length;let r=this.nCachedObjects_,n=t.length;for(let a=0,o=arguments.length;a!==o;++a){const o=arguments[a].uuid,h=e[o];if(void 0!==h)if(delete e[o],h0&&(e[a.uuid]=h),t[h]=a,t.pop();for(let t=0,e=s;t!==e;++t){const e=i[t];e[h]=e[r],e.pop()}}}this.nCachedObjects_=r}subscribe_(t,e){const i=this._bindingsIndicesByPath;let s=i[t];const r=this._bindings;if(void 0!==s)return r[s];const n=this._paths,a=this._parsedPaths,o=this._objects,h=o.length,l=this.nCachedObjects_,c=new Array(h);s=r.length,i[t]=s,n.push(t),a.push(e),r.push(c);for(let i=l,s=o.length;i!==s;++i){const s=o[i];c[i]=new Zu(s,t,e)}return c}unsubscribe_(t){const e=this._bindingsIndicesByPath,i=e[t];if(void 0!==i){const s=this._paths,r=this._parsedPaths,n=this._bindings,a=n.length-1,o=n[a];e[t[a]]=i,n[i]=o,n.pop(),r[i]=r[a],r.pop(),s[i]=s[a],s.pop()}}}class $u{constructor(t,e,i=null,s=e.blendMode){this._mixer=t,this._clip=e,this._localRoot=i,this.blendMode=s;const r=e.tracks,n=r.length,a=new Array(n),o={endingStart:De,endingEnd:De};for(let t=0;t!==n;++t){const e=r[t].createInterpolant(null);a[t]=e,e.settings=o}this._interpolantSettings=o,this._interpolants=a,this._propertyBindings=new Array(n),this._cacheIndex=null,this._byClipCacheIndex=null,this._timeScaleInterpolant=null,this._weightInterpolant=null,this.loop=2201,this._loopCount=-1,this._startTime=null,this.time=0,this.timeScale=1,this._effectiveTimeScale=1,this.weight=1,this._effectiveWeight=1,this.repetitions=1/0,this.paused=!1,this.enabled=!0,this.clampWhenFinished=!1,this.zeroSlopeAtStart=!0,this.zeroSlopeAtEnd=!0}play(){return this._mixer._activateAction(this),this}stop(){return this._mixer._deactivateAction(this),this.reset()}reset(){return this.paused=!1,this.enabled=!0,this.time=0,this._loopCount=-1,this._startTime=null,this.stopFading().stopWarping()}isRunning(){return this.enabled&&!this.paused&&0!==this.timeScale&&null===this._startTime&&this._mixer._isActiveAction(this)}isScheduled(){return this._mixer._isActiveAction(this)}startAt(t){return this._startTime=t,this}setLoop(t,e){return this.loop=t,this.repetitions=e,this}setEffectiveWeight(t){return this.weight=t,this._effectiveWeight=this.enabled?t:0,this.stopFading()}getEffectiveWeight(){return this._effectiveWeight}fadeIn(t){return this._scheduleFading(t,0,1)}fadeOut(t){return this._scheduleFading(t,1,0)}crossFadeFrom(t,e,i=!1){if(t.fadeOut(e),this.fadeIn(e),!0===i){const i=this._clip.duration,s=t._clip.duration,r=s/i,n=i/s;t.warp(1,r,e),this.warp(n,1,e)}return this}crossFadeTo(t,e,i=!1){return t.crossFadeFrom(this,e,i)}stopFading(){const t=this._weightInterpolant;return null!==t&&(this._weightInterpolant=null,this._mixer._takeBackControlInterpolant(t)),this}setEffectiveTimeScale(t){return this.timeScale=t,this._effectiveTimeScale=this.paused?0:t,this.stopWarping()}getEffectiveTimeScale(){return this._effectiveTimeScale}setDuration(t){return this.timeScale=this._clip.duration/t,this.stopWarping()}syncWith(t){return this.time=t.time,this.timeScale=t.timeScale,this.stopWarping()}halt(t){return this.warp(this._effectiveTimeScale,0,t)}warp(t,e,i){const s=this._mixer,r=s.time,n=this.timeScale;let a=this._timeScaleInterpolant;null===a&&(a=s._lendControlInterpolant(),this._timeScaleInterpolant=a);const o=a.parameterPositions,h=a.sampleValues;return o[0]=r,o[1]=r+i,h[0]=t/n,h[1]=e/n,this}stopWarping(){const t=this._timeScaleInterpolant;return null!==t&&(this._timeScaleInterpolant=null,this._mixer._takeBackControlInterpolant(t)),this}getMixer(){return this._mixer}getClip(){return this._clip}getRoot(){return this._localRoot||this._mixer._root}_update(t,e,i,s){if(!this.enabled)return void this._updateWeight(t);const r=this._startTime;if(null!==r){const s=(t-r)*i;s<0||0===i?e=0:(this._startTime=null,e=i*s)}e*=this._updateTimeScale(t);const n=this._updateTime(e),a=this._updateWeight(t);if(a>0){const t=this._interpolants,e=this._propertyBindings;if(this.blendMode===Je)for(let i=0,s=t.length;i!==s;++i)t[i].evaluate(n),e[i].accumulateAdditive(a);else for(let i=0,r=t.length;i!==r;++i)t[i].evaluate(n),e[i].accumulate(s,a)}}_updateWeight(t){let e=0;if(this.enabled){e=this.weight;const i=this._weightInterpolant;if(null!==i){const s=i.evaluate(t)[0];e*=s,t>i.parameterPositions[1]&&(this.stopFading(),0===s&&(this.enabled=!1))}}return this._effectiveWeight=e,e}_updateTimeScale(t){let e=0;if(!this.paused){e=this.timeScale;const i=this._timeScaleInterpolant;if(null!==i){e*=i.evaluate(t)[0],t>i.parameterPositions[1]&&(this.stopWarping(),0===e?this.paused=!0:this.timeScale=e)}}return this._effectiveTimeScale=e,e}_updateTime(t){const e=this._clip.duration,i=this.loop;let s=this.time+t,r=this._loopCount;const n=2202===i;if(0===t)return-1===r||!n||1&~r?s:e-s;if(2200===i){-1===r&&(this._loopCount=0,this._setEndings(!0,!0,!1));t:{if(s>=e)s=e;else{if(!(s<0)){this.time=s;break t}s=0}this.clampWhenFinished?this.paused=!0:this.enabled=!1,this.time=s,this._mixer.dispatchEvent({type:"finished",action:this,direction:t<0?-1:1})}}else{if(-1===r&&(t>=0?(r=0,this._setEndings(!0,0===this.repetitions,n)):this._setEndings(0===this.repetitions,!0,n)),s>=e||s<0){const i=Math.floor(s/e);s-=e*i,r+=Math.abs(i);const a=this.repetitions-r;if(a<=0)this.clampWhenFinished?this.paused=!0:this.enabled=!1,s=t>0?e:0,this.time=s,this._mixer.dispatchEvent({type:"finished",action:this,direction:t>0?1:-1});else{if(1===a){const e=t<0;this._setEndings(e,!e,n)}else this._setEndings(!1,!1,n);this._loopCount=r,this.time=s,this._mixer.dispatchEvent({type:"loop",action:this,loopDelta:i})}}else this.time=s;if(n&&!(1&~r))return e-s}return s}_setEndings(t,e,i){const s=this._interpolantSettings;i?(s.endingStart=je,s.endingEnd=je):(s.endingStart=t?this.zeroSlopeAtStart?je:De:We,s.endingEnd=e?this.zeroSlopeAtEnd?je:De:We)}_scheduleFading(t,e,i){const s=this._mixer,r=s.time;let n=this._weightInterpolant;null===n&&(n=s._lendControlInterpolant(),this._weightInterpolant=n);const a=n.parameterPositions,o=n.sampleValues;return a[0]=r,o[0]=e,a[1]=r+t,o[1]=i,this}}const Qu=new Float32Array(1);class Ku extends cs{constructor(t){super(),this._root=t,this._initMemoryManager(),this._accuIndex=0,this.time=0,this.timeScale=1,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}_bindAction(t,e){const i=t._localRoot||this._root,s=t._clip.tracks,r=s.length,n=t._propertyBindings,a=t._interpolants,o=i.uuid,h=this._bindingsByRootAndName;let l=h[o];void 0===l&&(l={},h[o]=l);for(let t=0;t!==r;++t){const r=s[t],h=r.name;let c=l[h];if(void 0!==c)++c.referenceCount,n[t]=c;else{if(c=n[t],void 0!==c){null===c._cacheIndex&&(++c.referenceCount,this._addInactiveBinding(c,o,h));continue}const s=e&&e._propertyBindings[t].binding.parsedPath;c=new Wu(Zu.create(i,h,s),r.ValueTypeName,r.getValueSize()),++c.referenceCount,this._addInactiveBinding(c,o,h),n[t]=c}a[t].resultBuffer=c.buffer}}_activateAction(t){if(!this._isActiveAction(t)){if(null===t._cacheIndex){const e=(t._localRoot||this._root).uuid,i=t._clip.uuid,s=this._actionsByClip[i];this._bindAction(t,s&&s.knownActions[0]),this._addInactiveAction(t,i,e)}const e=t._propertyBindings;for(let t=0,i=e.length;t!==i;++t){const i=e[t];0===i.useCount++&&(this._lendBinding(i),i.saveOriginalState())}this._lendAction(t)}}_deactivateAction(t){if(this._isActiveAction(t)){const e=t._propertyBindings;for(let t=0,i=e.length;t!==i;++t){const i=e[t];0===--i.useCount&&(i.restoreOriginalState(),this._takeBackBinding(i))}this._takeBackAction(t)}}_initMemoryManager(){this._actions=[],this._nActiveActions=0,this._actionsByClip={},this._bindings=[],this._nActiveBindings=0,this._bindingsByRootAndName={},this._controlInterpolants=[],this._nActiveControlInterpolants=0;const t=this;this.stats={actions:{get total(){return t._actions.length},get inUse(){return t._nActiveActions}},bindings:{get total(){return t._bindings.length},get inUse(){return t._nActiveBindings}},controlInterpolants:{get total(){return t._controlInterpolants.length},get inUse(){return t._nActiveControlInterpolants}}}}_isActiveAction(t){const e=t._cacheIndex;return null!==e&&e=0;--e)t[e].stop();return this}update(t){t*=this.timeScale;const e=this._actions,i=this._nActiveActions,s=this.time+=t,r=Math.sign(t),n=this._accuIndex^=1;for(let a=0;a!==i;++a){e[a]._update(s,t,r,n)}const a=this._bindings,o=this._nActiveBindings;for(let t=0;t!==o;++t)a[t].apply(n);return this}setTime(t){this.time=0;for(let t=0;t=this.min.x&&t.x<=this.max.x&&t.y>=this.min.y&&t.y<=this.max.y}containsBox(t){return this.min.x<=t.min.x&&t.max.x<=this.max.x&&this.min.y<=t.min.y&&t.max.y<=this.max.y}getParameter(t,e){return e.set((t.x-this.min.x)/(this.max.x-this.min.x),(t.y-this.min.y)/(this.max.y-this.min.y))}intersectsBox(t){return t.max.x>=this.min.x&&t.min.x<=this.max.x&&t.max.y>=this.min.y&&t.min.y<=this.max.y}clampPoint(t,e){return e.copy(t).clamp(this.min,this.max)}distanceToPoint(t){return this.clampPoint(t,yd).distanceTo(t)}intersect(t){return this.min.max(t.min),this.max.min(t.max),this.isEmpty()&&this.makeEmpty(),this}union(t){return this.min.min(t.min),this.max.max(t.max),this}translate(t){return this.min.add(t),this.max.add(t),this}equals(t){return t.min.equals(this.min)&&t.max.equals(this.max)}}const fd=new _s,xd=new _s,bd=new _s,vd=new _s,wd=new _s,Md=new _s,Sd=new _s;class _d{constructor(t=new _s,e=new _s){this.start=t,this.end=e}set(t,e){return this.start.copy(t),this.end.copy(e),this}copy(t){return this.start.copy(t.start),this.end.copy(t.end),this}getCenter(t){return t.addVectors(this.start,this.end).multiplyScalar(.5)}delta(t){return t.subVectors(this.end,this.start)}distanceSq(){return this.start.distanceToSquared(this.end)}distance(){return this.start.distanceTo(this.end)}at(t,e){return this.delta(e).multiplyScalar(t).add(this.start)}closestPointToPointParameter(t,e){fd.subVectors(t,this.start),xd.subVectors(this.end,this.start);const i=xd.dot(xd);let s=xd.dot(fd)/i;return e&&(s=gs(s,0,1)),s}closestPointToPoint(t,e,i){const s=this.closestPointToPointParameter(t,e);return this.delta(i).multiplyScalar(s).add(this.start)}distanceSqToLine3(t,e=Md,i=Sd){const s=1e-8*1e-8;let r,n;const a=this.start,o=t.start,h=this.end,l=t.end;bd.subVectors(h,a),vd.subVectors(l,o),wd.subVectors(a,o);const c=bd.dot(bd),u=vd.dot(vd),d=vd.dot(wd);if(c<=s&&u<=s)return e.copy(a),i.copy(o),e.sub(i),e.dot(e);if(c<=s)r=0,n=d/u,n=gs(n,0,1);else{const t=bd.dot(wd);if(u<=s)n=0,r=gs(-t/c,0,1);else{const e=bd.dot(vd),i=c*u-e*e;r=0!==i?gs((e*d-t*u)/i,0,1):0,n=(e*r+d)/u,n<0?(n=0,r=gs(-t/c,0,1)):n>1&&(n=1,r=gs((e-t)/c,0,1))}}return e.copy(a).addScaledVector(bd,r),i.copy(o).addScaledVector(vd,n),e.distanceToSquared(i)}applyMatrix4(t){return this.start.applyMatrix4(t),this.end.applyMatrix4(t),this}equals(t){return t.start.equals(this.start)&&t.end.equals(this.end)}clone(){return(new this.constructor).copy(this)}}const Ad=new _s;class Td extends Sr{constructor(t,e){super(),this.light=t,this.matrixAutoUpdate=!1,this.color=e,this.type="SpotLightHelper";const i=new jn,s=[0,0,0,0,0,1,0,0,0,1,0,1,0,0,0,-1,0,1,0,0,0,0,1,1,0,0,0,0,-1,1];for(let t=0,e=1,i=32;t1)for(let i=0;i.99999)this.quaternion.set(0,0,0,1);else if(t.y<-.99999)this.quaternion.set(1,0,0,0);else{$d.set(t.z,0,-t.x).normalize();const e=Math.acos(t.y);this.quaternion.setFromAxisAngle($d,e)}}setLength(t,e=.2*t,i=.2*e){this.line.scale.set(1,Math.max(1e-4,t-e),1),this.line.updateMatrix(),this.cone.scale.set(i,e,i),this.cone.position.y=t,this.cone.updateMatrix()}setColor(t){this.line.material.color.set(t),this.cone.material.color.set(t)}copy(t){return super.copy(t,!1),this.line.copy(t.line),this.cone.copy(t.cone),this}dispose(){this.line.geometry.dispose(),this.line.material.dispose(),this.cone.geometry.dispose(),this.cone.material.dispose()}}class ep extends Yo{constructor(t=1){const e=[0,0,0,t,0,0,0,0,0,0,t,0,0,0,0,0,0,t],i=new jn;i.setAttribute("position",new In(e,3)),i.setAttribute("color",new In([1,0,0,1,.6,0,0,1,0,.6,1,0,0,0,1,0,.6,1],3));super(i,new No({vertexColors:!0,toneMapped:!1})),this.type="AxesHelper"}setColors(t,e,i){const s=new kr,r=this.geometry.attributes.color.array;return s.set(t),s.toArray(r,0),s.toArray(r,3),s.set(e),s.toArray(r,6),s.toArray(r,9),s.set(i),s.toArray(r,12),s.toArray(r,15),this.geometry.attributes.color.needsUpdate=!0,this}dispose(){this.geometry.dispose(),this.material.dispose()}}class ip{constructor(){this.type="ShapePath",this.color=new kr,this.subPaths=[],this.currentPath=null}moveTo(t,e){return this.currentPath=new Xh,this.subPaths.push(this.currentPath),this.currentPath.moveTo(t,e),this}lineTo(t,e){return this.currentPath.lineTo(t,e),this}quadraticCurveTo(t,e,i,s){return this.currentPath.quadraticCurveTo(t,e,i,s),this}bezierCurveTo(t,e,i,s,r,n){return this.currentPath.bezierCurveTo(t,e,i,s,r,n),this}splineThru(t){return this.currentPath.splineThru(t),this}toShapes(t){function e(t,e){const i=e.length;let s=!1;for(let r=i-1,n=0;nNumber.EPSILON){if(h<0&&(i=e[n],o=-o,a=e[r],h=-h),t.ya.y)continue;if(t.y===i.y){if(t.x===i.x)return!0}else{const e=h*(t.x-i.x)-o*(t.y-i.y);if(0===e)return!0;if(e<0)continue;s=!s}}else{if(t.y!==i.y)continue;if(a.x<=t.x&&t.x<=i.x||i.x<=t.x&&t.x<=a.x)return!0}}return s}const i=wl.isClockWise,s=this.subPaths;if(0===s.length)return[];let r,n,a;const o=[];if(1===s.length)return n=s[0],a=new Yh,a.curves=n.curves,o.push(a),o;let h=!i(s[0].getPoints());h=t?!h:h;const l=[],c=[];let u,d,p=[],m=0;c[m]=void 0,p[m]=[];for(let e=0,a=s.length;e1){let t=!1,i=0;for(let t=0,e=c.length;t0&&!1===t&&(p=l)}for(let t=0,e=c.length;te?(t.repeat.x=1,t.repeat.y=i/e,t.offset.x=0,t.offset.y=(1-t.repeat.y)/2):(t.repeat.x=e/i,t.repeat.y=1,t.offset.x=(1-t.repeat.x)/2,t.offset.y=0),t}(t,e)}static cover(t,e){return function(t,e){const i=t.image&&t.image.width?t.image.width/t.image.height:1;return i>e?(t.repeat.x=e/i,t.repeat.y=1,t.offset.x=(1-t.repeat.x)/2,t.offset.y=0):(t.repeat.x=1,t.repeat.y=i/e,t.offset.x=0,t.offset.y=(1-t.repeat.y)/2),t}(t,e)}static fill(t){return function(t){return t.repeat.x=1,t.repeat.y=1,t.offset.x=0,t.offset.y=0,t}(t)}static getByteLength(t,e,i,s){return rp(t,e,i,s)}}"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("register",{detail:{revision:t}})),"undefined"!=typeof window&&(window.__THREE__?as("WARNING: Multiple instances of Three.js being imported."):window.__THREE__=t);export{it as ACESFilmicToneMapping,w as AddEquation,$ as AddOperation,Je as AdditiveAnimationBlendMode,g as AdditiveBlending,rt as AgXToneMapping,Dt as AlphaFormat,ki as AlwaysCompare,W as AlwaysDepth,Si as AlwaysStencilFunc,ru as AmbientLight,$u as AnimationAction,wc as AnimationClip,Bc as AnimationLoader,Ku as AnimationMixer,Gu as AnimationObjectGroup,oc as AnimationUtils,zh as ArcCurve,zu as ArrayCamera,tp as ArrowHelper,at as AttachedBindMode,Nu as Audio,ju as AudioAnalyser,bu as AudioContext,Ru as AudioListener,vu as AudioLoader,ep as AxesHelper,d as BackSide,He as BasicDepthPacking,o as BasicShadowMap,Ro as BatchedMesh,dc as BezierInterpolant,Ja as Bone,mc as BooleanKeyframeTrack,gd as Box2,Gr as Box3,Zd as Box3Helper,ph as BoxGeometry,Hd as BoxHelper,vn as BufferAttribute,jn as BufferGeometry,uu as BufferGeometryLoader,Ct as ByteType,Sc as Cache,Xc as Camera,qd as CameraHelper,lh as CanvasTexture,mh as CapsuleGeometry,Ph as CatmullRomCurve3,et as CineonToneMapping,yh as CircleGeometry,yt as ClampToEdgeWrapping,Cu as Clock,kr as Color,yc as ColorKeyframeTrack,Os as ColorManagement,Hi as Compatibility,ah as CompressedArrayTexture,oh as CompressedCubeTexture,nh as CompressedTexture,kc as CompressedTextureLoader,fh as ConeGeometry,L as ConstantAlphaFactor,E as ConstantColorFactor,sp as Controls,Tu as CubeCamera,uh as CubeDepthTexture,lt as CubeReflectionMapping,ct as CubeRefractionMapping,hh as CubeTexture,Rc as CubeTextureLoader,pt as CubeUVReflectionMapping,Eh as CubicBezierCurve,Fh as CubicBezierCurve3,lc as CubicInterpolant,r as CullFaceBack,n as CullFaceFront,a as CullFaceFrontBack,s as CullFaceNone,Ah as Curve,qh as CurvePath,b as CustomBlending,st as CustomToneMapping,gh as CylinderGeometry,pd as Cylindrical,Hs as Data3DTexture,Xs as DataArrayTexture,qa as DataTexture,Nc as DataTextureLoader,gn as DataUtils,di as DecrementStencilOp,mi as DecrementWrapStencilOp,Ac as DefaultLoadingManager,Ut as DepthFormat,Jt as DepthStencilFormat,ch as DepthTexture,ot as DetachedBindMode,su as DirectionalLight,Wd as DirectionalLightHelper,uc as DiscreteInterpolant,bh as DodecahedronGeometry,p as DoubleSide,O as DstAlphaFactor,R as DstColorFactor,Li as DynamicCopyUsage,Pi as DynamicDrawUsage,Vi as DynamicReadUsage,_h as EdgesGeometry,Th as EllipseCurve,Ti as EqualCompare,q as EqualDepth,xi as EqualStencilFunc,ut as EquirectangularReflectionMapping,dt as EquirectangularRefractionMapping,ar as Euler,cs as EventDispatcher,dh as ExternalTexture,_l as ExtrudeGeometry,Ic as FileLoader,Cn as Float16BufferAttribute,In as Float32BufferAttribute,Pt as FloatType,Rr as Fog,Pr as FogExp2,rh as FramebufferTexture,u as FrontSide,uo as Frustum,yo as FrustumArray,nd as GLBufferAttribute,ji as GLSL1,Wi as GLSL3,Ci as GreaterCompare,Y as GreaterDepth,Bi as GreaterEqualCompare,X as GreaterEqualDepth,Mi as GreaterEqualStencilFunc,vi as GreaterStencilFunc,Ed as GridHelper,_r as Group,Rt as HalfFloatType,Fc as HemisphereLight,Vd as HemisphereLightHelper,Tl as IcosahedronGeometry,fu as ImageBitmapLoader,Pc as ImageLoader,Vs as ImageUtils,ui as IncrementStencilOp,pi as IncrementWrapStencilOp,Za as InstancedBufferAttribute,cu as InstancedBufferGeometry,rd as InstancedInterleavedBuffer,so as InstancedMesh,_n as Int16BufferAttribute,Tn as Int32BufferAttribute,wn as Int8BufferAttribute,kt as IntType,Wn as InterleavedBuffer,Jn as InterleavedBufferAttribute,hc as Interpolant,Le as InterpolateBezier,Ve as InterpolateDiscrete,Ee as InterpolateLinear,Fe as InterpolateSmooth,Yi as InterpolationSamplingMode,Xi as InterpolationSamplingType,yi as InvertStencilOp,li as KeepStencilOp,pc as KeyframeTrack,ua as LOD,zl as LatheGeometry,or as Layers,Ai as LessCompare,U as LessDepth,zi as LessEqualCompare,J as LessEqualDepth,bi as LessEqualStencilFunc,fi as LessStencilFunc,Ec as Light,ou as LightProbe,Uo as Line,_d as Line3,No as LineBasicMaterial,Lh as LineCurve,Dh as LineCurve3,ic as LineDashedMaterial,Ho as LineLoop,Yo as LineSegments,Mt as LinearFilter,cc as LinearInterpolant,Tt as LinearMipMapLinearFilter,_t as LinearMipMapNearestFilter,At as LinearMipmapLinearFilter,St as LinearMipmapNearestFilter,ii as LinearSRGBColorSpace,K as LinearToneMapping,si as LinearTransfer,Tc as Loader,lu as LoaderUtils,_c as LoadingManager,Pe as LoopOnce,Ne as LoopPingPong,Re as LoopRepeat,e as MOUSE,Yn as Material,v as MaterialBlending,hu as MaterialLoader,ws as MathUtils,md as Matrix2,zs as Matrix3,Gs as Matrix4,A as MaxEquation,Oa as Mesh,va as MeshBasicMaterial,Kl as MeshDepthMaterial,tc as MeshDistanceMaterial,Ql as MeshLambertMaterial,ec as MeshMatcapMaterial,$l as MeshNormalMaterial,Zl as MeshPhongMaterial,Hl as MeshPhysicalMaterial,Yl as MeshStandardMaterial,Gl as MeshToonMaterial,_ as MinEquation,gt as MirroredRepeatWrapping,G as MixOperation,x as MultiplyBlending,Z as MultiplyOperation,ft as NearestFilter,wt as NearestMipMapLinearFilter,bt as NearestMipMapNearestFilter,vt as NearestMipmapLinearFilter,xt as NearestMipmapNearestFilter,nt as NeutralToneMapping,_i as NeverCompare,j as NeverDepth,gi as NeverStencilFunc,m as NoBlending,ti as NoColorSpace,ni as NoNormalPacking,Q as NoToneMapping,Ue as NormalAnimationBlendMode,y as NormalBlending,oi as NormalGAPacking,ai as NormalRGPacking,Ii as NotEqualCompare,H as NotEqualDepth,wi as NotEqualStencilFunc,gc as NumberKeyframeTrack,Sr as Object3D,du as ObjectLoader,Ke as ObjectSpaceNormalMap,Cl as OctahedronGeometry,z as OneFactor,D as OneMinusConstantAlphaFactor,F as OneMinusConstantColorFactor,P as OneMinusDstAlphaFactor,N as OneMinusDstColorFactor,k as OneMinusSrcAlphaFactor,I as OneMinusSrcColorFactor,eu as OrthographicCamera,h as PCFShadowMap,l as PCFSoftShadowMap,Xh as Path,Gc as PerspectiveCamera,oo as Plane,Il as PlaneGeometry,Gd as PlaneHelper,tu as PointLight,Od as PointLightHelper,th as Points,Zo as PointsMaterial,Fd as PolarGridHelper,xh as PolyhedronGeometry,Du as PositionalAudio,Zu as PropertyBinding,Wu as PropertyMixer,jh as QuadraticBezierCurve,Wh as QuadraticBezierCurve3,Ss as Quaternion,xc as QuaternionKeyframeTrack,fc as QuaternionLinearInterpolant,he as R11_EAC_Format,ms as RAD2DEG,ke as RED_GREEN_RGTC2_Format,Ie as RED_RGTC1_Format,t as REVISION,ce as RG11_EAC_Format,Ze as RGBADepthPacking,Wt as RGBAFormat,Gt as RGBAIntegerFormat,Se as RGBA_ASTC_10x10_Format,ve as RGBA_ASTC_10x5_Format,we as RGBA_ASTC_10x6_Format,Me as RGBA_ASTC_10x8_Format,_e as RGBA_ASTC_12x10_Format,Ae as RGBA_ASTC_12x12_Format,de as RGBA_ASTC_4x4_Format,pe as RGBA_ASTC_5x4_Format,me as RGBA_ASTC_5x5_Format,ye as RGBA_ASTC_6x5_Format,ge as RGBA_ASTC_6x6_Format,fe as RGBA_ASTC_8x5_Format,xe as RGBA_ASTC_8x6_Format,be as RGBA_ASTC_8x8_Format,Te as RGBA_BPTC_Format,oe as RGBA_ETC2_EAC_Format,re as RGBA_PVRTC_2BPPV1_Format,se as RGBA_PVRTC_4BPPV1_Format,Qt as RGBA_S3TC_DXT1_Format,Kt as RGBA_S3TC_DXT3_Format,te as RGBA_S3TC_DXT5_Format,Ge as RGBDepthPacking,jt as RGBFormat,Zt as RGBIntegerFormat,ze as RGB_BPTC_SIGNED_Format,Ce as RGB_BPTC_UNSIGNED_Format,ne as RGB_ETC1_Format,ae as RGB_ETC2_Format,ie as RGB_PVRTC_2BPPV1_Format,ee as RGB_PVRTC_4BPPV1_Format,$t as RGB_S3TC_DXT1_Format,$e as RGDepthPacking,Yt as RGFormat,Ht as RGIntegerFormat,Xl as RawShaderMaterial,ba as Ray,od as Raycaster,nu as RectAreaLight,qt as RedFormat,Xt as RedIntegerFormat,tt as ReinhardToneMapping,Js as RenderTarget,td as RenderTarget3D,mt as RepeatWrapping,ci as ReplaceStencilOp,S as ReverseSubtractEquation,Bl as RingGeometry,le as SIGNED_R11_EAC_Format,Oe as SIGNED_RED_GREEN_RGTC2_Format,Be as SIGNED_RED_RGTC1_Format,ue as SIGNED_RG11_EAC_Format,ei as SRGBColorSpace,ri as SRGBTransfer,Nr as Scene,ql as ShaderMaterial,Dl as ShadowMaterial,Yh as Shape,kl as ShapeGeometry,ip as ShapePath,wl as ShapeUtils,It as ShortType,Ha as Skeleton,Bd as SkeletonHelper,Ua as SkinnedMesh,Fs as Source,Pn as Sphere,Ol as SphereGeometry,dd as Spherical,au as SphericalHarmonics3,Uh as SplineCurve,Qc as SpotLight,Td as SpotLightHelper,oa as Sprite,Hn as SpriteMaterial,B as SrcAlphaFactor,V as SrcAlphaSaturateFactor,C as SrcColorFactor,Fi as StaticCopyUsage,Oi as StaticDrawUsage,Ni as StaticReadUsage,_u as StereoCamera,Di as StreamCopyUsage,Ri as StreamDrawUsage,Ei as StreamReadUsage,bc as StringKeyframeTrack,M as SubtractEquation,f as SubtractiveBlending,i as TOUCH,Qe as TangentSpaceNormalMap,Pl as TetrahedronGeometry,Ws as Texture,Vc as TextureLoader,np as TextureUtils,cd as Timer,qi as TimestampQuery,Rl as TorusGeometry,Nl as TorusKnotGeometry,Zr as Triangle,Ye as TriangleFanDrawMode,Xe as TriangleStripDrawMode,qe as TrianglesDrawMode,Vl as TubeGeometry,ht as UVMapping,An as Uint16BufferAttribute,zn as Uint32BufferAttribute,Mn as Uint8BufferAttribute,Sn as Uint8ClampedBufferAttribute,ed as Uniform,sd as UniformsGroup,Jl as UniformsUtils,zt as UnsignedByteType,Lt as UnsignedInt101111Type,Et as UnsignedInt248Type,Ft as UnsignedInt5999Type,Ot as UnsignedIntType,Nt as UnsignedShort4444Type,Vt as UnsignedShort5551Type,Bt as UnsignedShortType,c as VSMShadowMap,Ms as Vector2,_s as Vector3,Us as Vector4,vc as VectorKeyframeTrack,sh as VideoFrameTexture,ih as VideoTexture,Zs as WebGL3DRenderTarget,Ys as WebGLArrayRenderTarget,Ui as WebGLCoordinateSystem,qs as WebGLRenderTarget,Ji as WebGPUCoordinateSystem,Tr as WebXRController,El as WireframeGeometry,We as WrapAroundEnding,De as ZeroCurvatureEnding,T as ZeroFactor,je as ZeroSlopeEnding,hi as ZeroStencilOp,Zi as arrayNeedsUint32,jl as cloneUniforms,ts as createCanvasElement,Ki as createElementNS,os as error,rp as getByteLength,rs as getConsoleFunction,Ul as getUnlitUniformColorSpace,Qi as isTypedArray,ns as log,Wl as mergeUniforms,ls as probeAsync,ss as setConsoleFunction,as as warn,hs as warnOnce}; diff --git a/build/three.module.js b/build/three.module.js index cefe4d7a3b4b39..84f96994be1c7d 100644 --- a/build/three.module.js +++ b/build/three.module.js @@ -3,8 +3,8 @@ * Copyright 2010-2026 Three.js Authors * SPDX-License-Identifier: MIT */ -import { Matrix3, Vector2, Color, mergeUniforms, Vector3, CubeUVReflectionMapping, Mesh, BoxGeometry, ShaderMaterial, BackSide, cloneUniforms, Euler, Matrix4, ColorManagement, SRGBTransfer, PlaneGeometry, FrontSide, getUnlitUniformColorSpace, IntType, warn, HalfFloatType, UnsignedByteType, FloatType, RGBAFormat, Plane, CubeReflectionMapping, CubeRefractionMapping, BufferGeometry, OrthographicCamera, PerspectiveCamera, NoToneMapping, MeshBasicMaterial, error, NoBlending, WebGLRenderTarget, BufferAttribute, LinearSRGBColorSpace, LinearFilter, EquirectangularReflectionMapping, EquirectangularRefractionMapping, WebGLCubeRenderTarget, warnOnce, Uint32BufferAttribute, Uint16BufferAttribute, arrayNeedsUint32, Vector4, DataArrayTexture, Float32BufferAttribute, RawShaderMaterial, CustomToneMapping, NeutralToneMapping, AgXToneMapping, ACESFilmicToneMapping, CineonToneMapping, ReinhardToneMapping, LinearToneMapping, CubeTexture, Data3DTexture, GreaterEqualCompare, LessEqualCompare, DepthTexture, Texture, GLSL3, VSMShadowMap, PCFShadowMap, AddOperation, MixOperation, MultiplyOperation, LinearTransfer, UniformsUtils, DoubleSide, NormalBlending, TangentSpaceNormalMap, ObjectSpaceNormalMap, Layers, RGFormat, Frustum, MeshDepthMaterial, MeshDistanceMaterial, PCFSoftShadowMap, DepthFormat, NearestFilter, CubeDepthTexture, UnsignedIntType, LessEqualDepth, ReverseSubtractEquation, SubtractEquation, AddEquation, OneMinusConstantAlphaFactor, ConstantAlphaFactor, OneMinusConstantColorFactor, ConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, DstAlphaFactor, DstColorFactor, SrcAlphaSaturateFactor, SrcAlphaFactor, SrcColorFactor, OneFactor, ZeroFactor, NotEqualDepth, GreaterDepth, GreaterEqualDepth, EqualDepth, LessDepth, AlwaysDepth, NeverDepth, CullFaceNone, CullFaceBack, CullFaceFront, CustomBlending, MultiplyBlending, SubtractiveBlending, AdditiveBlending, MinEquation, MaxEquation, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, LinearMipmapLinearFilter, LinearMipmapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NotEqualCompare, GreaterCompare, EqualCompare, LessCompare, AlwaysCompare, NeverCompare, NoColorSpace, DepthStencilFormat, getByteLength, UnsignedInt248Type, UnsignedShortType, createElementNS, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt5999Type, UnsignedInt101111Type, ByteType, ShortType, AlphaFormat, RGBFormat, RedFormat, RedIntegerFormat, RGIntegerFormat, RGBAIntegerFormat, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, R11_EAC_Format, SIGNED_R11_EAC_Format, RG11_EAC_Format, SIGNED_RG11_EAC_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, ExternalTexture, EventDispatcher, ArrayCamera, WebXRController, RAD2DEG, DataTexture, createCanvasElement, SRGBColorSpace, REVISION, log, WebGLCoordinateSystem, probeAsync } from './three.core.js'; -export { AdditiveAnimationBlendMode, AlwaysStencilFunc, AmbientLight, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrowHelper, AttachedBindMode, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BasicDepthPacking, BasicShadowMap, BatchedMesh, BezierInterpolant, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxHelper, BufferGeometryLoader, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CircleGeometry, Clock, ColorKeyframeTrack, Compatibility, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, Controls, CubeCamera, CubeTextureLoader, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceFrontBack, Curve, CurvePath, CylinderGeometry, Cylindrical, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DetachedBindMode, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualStencilFunc, ExtrudeGeometry, FileLoader, Float16BufferAttribute, Fog, FogExp2, FramebufferTexture, FrustumArray, GLBufferAttribute, GLSL1, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HemisphereLight, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateBezier, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InterpolationSamplingMode, InterpolationSamplingType, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, MOUSE, Material, MaterialBlending, MaterialLoader, MathUtils, Matrix2, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NeverStencilFunc, NoNormalPacking, NormalAnimationBlendMode, NormalGAPacking, NormalRGPacking, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, OctahedronGeometry, Path, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, RGBADepthPacking, RGBDepthPacking, RGBIntegerFormat, RGDepthPacking, Ray, Raycaster, RectAreaLight, RenderTarget, RenderTarget3D, ReplaceStencilOp, RingGeometry, Scene, ShadowMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, Skeleton, SkeletonHelper, SkinnedMesh, Source, Sphere, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, TOUCH, TetrahedronGeometry, TextureLoader, TextureUtils, Timer, TimestampQuery, TorusGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, UVMapping, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, VectorKeyframeTrack, VideoFrameTexture, VideoTexture, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGPUCoordinateSystem, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroSlopeEnding, ZeroStencilOp, getConsoleFunction, setConsoleFunction } from './three.core.js'; +import { Matrix3, Vector2, Color, mergeUniforms, Vector3, CubeUVReflectionMapping, Mesh, BoxGeometry, ShaderMaterial, BackSide, cloneUniforms, Euler, Matrix4, ColorManagement, SRGBTransfer, PlaneGeometry, FrontSide, getUnlitUniformColorSpace, IntType, warn, HalfFloatType, UnsignedByteType, FloatType, RGBAFormat, Plane, CubeReflectionMapping, CubeRefractionMapping, BufferGeometry, OrthographicCamera, PerspectiveCamera, NoToneMapping, MeshBasicMaterial, error, NoBlending, WebGLRenderTarget, BufferAttribute, LinearSRGBColorSpace, LinearFilter, CubeTexture, LinearMipmapLinearFilter, CubeCamera, EquirectangularReflectionMapping, EquirectangularRefractionMapping, warnOnce, Uint32BufferAttribute, Uint16BufferAttribute, arrayNeedsUint32, Vector4, DataArrayTexture, Float32BufferAttribute, RawShaderMaterial, CustomToneMapping, NeutralToneMapping, AgXToneMapping, ACESFilmicToneMapping, CineonToneMapping, ReinhardToneMapping, LinearToneMapping, Data3DTexture, GreaterEqualCompare, LessEqualCompare, DepthTexture, Texture, GLSL3, VSMShadowMap, PCFShadowMap, AddOperation, MixOperation, MultiplyOperation, LinearTransfer, UniformsUtils, DoubleSide, NormalBlending, TangentSpaceNormalMap, ObjectSpaceNormalMap, Layers, RGFormat, Frustum, MeshDepthMaterial, MeshDistanceMaterial, PCFSoftShadowMap, DepthFormat, NearestFilter, CubeDepthTexture, UnsignedIntType, LessEqualDepth, ReverseSubtractEquation, SubtractEquation, AddEquation, OneMinusConstantAlphaFactor, ConstantAlphaFactor, OneMinusConstantColorFactor, ConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, DstAlphaFactor, DstColorFactor, SrcAlphaSaturateFactor, SrcAlphaFactor, SrcColorFactor, OneFactor, ZeroFactor, NotEqualDepth, GreaterDepth, GreaterEqualDepth, EqualDepth, LessDepth, AlwaysDepth, NeverDepth, CullFaceNone, CullFaceBack, CullFaceFront, CustomBlending, MultiplyBlending, SubtractiveBlending, AdditiveBlending, MinEquation, MaxEquation, MirroredRepeatWrapping, ClampToEdgeWrapping, RepeatWrapping, LinearMipmapNearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NotEqualCompare, GreaterCompare, EqualCompare, LessCompare, AlwaysCompare, NeverCompare, NoColorSpace, DepthStencilFormat, getByteLength, UnsignedInt248Type, UnsignedShortType, createElementNS, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt5999Type, UnsignedInt101111Type, ByteType, ShortType, AlphaFormat, RGBFormat, RedFormat, RedIntegerFormat, RGIntegerFormat, RGBAIntegerFormat, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, R11_EAC_Format, SIGNED_R11_EAC_Format, RG11_EAC_Format, SIGNED_RG11_EAC_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, ExternalTexture, EventDispatcher, ArrayCamera, WebXRController, RAD2DEG, DataTexture, createCanvasElement, SRGBColorSpace, REVISION, log, WebGLCoordinateSystem, probeAsync } from './three.core.js'; +export { AdditiveAnimationBlendMode, AlwaysStencilFunc, AmbientLight, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrowHelper, AttachedBindMode, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BasicDepthPacking, BasicShadowMap, BatchedMesh, BezierInterpolant, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxHelper, BufferGeometryLoader, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CircleGeometry, Clock, ColorKeyframeTrack, Compatibility, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, Controls, CubeTextureLoader, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceFrontBack, Curve, CurvePath, CylinderGeometry, Cylindrical, DataTextureLoader, DataUtils, DecrementStencilOp, DecrementWrapStencilOp, DefaultLoadingManager, DetachedBindMode, DirectionalLight, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry, DynamicCopyUsage, DynamicDrawUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, EqualStencilFunc, ExtrudeGeometry, FileLoader, Float16BufferAttribute, Fog, FogExp2, FramebufferTexture, FrustumArray, GLBufferAttribute, GLSL1, GreaterEqualStencilFunc, GreaterStencilFunc, GridHelper, Group, HemisphereLight, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, IncrementStencilOp, IncrementWrapStencilOp, InstancedBufferAttribute, InstancedBufferGeometry, InstancedInterleavedBuffer, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, InterleavedBuffer, InterleavedBufferAttribute, Interpolant, InterpolateBezier, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InterpolationSamplingMode, InterpolationSamplingType, InvertStencilOp, KeepStencilOp, KeyframeTrack, LOD, LatheGeometry, LessEqualStencilFunc, LessStencilFunc, Light, LightProbe, Line, Line3, LineBasicMaterial, LineCurve, LineCurve3, LineDashedMaterial, LineLoop, LineSegments, LinearInterpolant, LinearMipMapLinearFilter, LinearMipMapNearestFilter, Loader, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, MOUSE, Material, MaterialBlending, MaterialLoader, MathUtils, Matrix2, MeshLambertMaterial, MeshMatcapMaterial, MeshNormalMaterial, MeshPhongMaterial, MeshPhysicalMaterial, MeshStandardMaterial, MeshToonMaterial, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NeverStencilFunc, NoNormalPacking, NormalAnimationBlendMode, NormalGAPacking, NormalRGPacking, NotEqualStencilFunc, NumberKeyframeTrack, Object3D, ObjectLoader, OctahedronGeometry, Path, PlaneHelper, PointLight, PointLightHelper, Points, PointsMaterial, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, Quaternion, QuaternionKeyframeTrack, QuaternionLinearInterpolant, RGBADepthPacking, RGBDepthPacking, RGBIntegerFormat, RGDepthPacking, Ray, Raycaster, RectAreaLight, RenderTarget, RenderTarget3D, ReplaceStencilOp, RingGeometry, Scene, ShadowMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, Skeleton, SkeletonHelper, SkinnedMesh, Source, Sphere, SphereGeometry, Spherical, SphericalHarmonics3, SplineCurve, SpotLight, SpotLightHelper, Sprite, SpriteMaterial, StaticCopyUsage, StaticDrawUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, TOUCH, TetrahedronGeometry, TextureLoader, TextureUtils, Timer, TimestampQuery, TorusGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, UVMapping, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, VectorKeyframeTrack, VideoFrameTexture, VideoTexture, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGPUCoordinateSystem, WireframeGeometry, WrapAroundEnding, ZeroCurvatureEnding, ZeroSlopeEnding, ZeroStencilOp, getConsoleFunction, setConsoleFunction } from './three.core.js'; function WebGLAnimation() { @@ -3780,6 +3780,178 @@ function _getCommonVertexShader() { } +/** + * A cube render target used in context of {@link WebGLRenderer}. + * + * @augments WebGLRenderTarget + */ +class WebGLCubeRenderTarget extends WebGLRenderTarget { + + /** + * Constructs a new cube render target. + * + * @param {number} [size=1] - The size of the render target. + * @param {RenderTarget~Options} [options] - The configuration object. + */ + constructor( size = 1, options = {} ) { + + super( size, size, options ); + + /** + * This flag can be used for type testing. + * + * @type {boolean} + * @readonly + * @default true + */ + this.isWebGLCubeRenderTarget = true; + + const image = { width: size, height: size, depth: 1 }; + const images = [ image, image, image, image, image, image ]; + + /** + * Overwritten with a different texture type. + * + * @type {DataArrayTexture} + */ + this.texture = new CubeTexture( images ); + this._setTextureOptions( options ); + + // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, + // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. + + // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped + // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture + // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). + + this.texture.isRenderTargetTexture = true; + + } + + /** + * Converts the given equirectangular texture to a cube map. + * + * @param {WebGLRenderer} renderer - The renderer. + * @param {Texture} texture - The equirectangular texture. + * @return {WebGLCubeRenderTarget} A reference to this cube render target. + */ + fromEquirectangularTexture( renderer, texture ) { + + this.texture.type = texture.type; + this.texture.colorSpace = texture.colorSpace; + + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; + + const shader = { + + uniforms: { + tEquirect: { value: null }, + }, + + vertexShader: /* glsl */` + + varying vec3 vWorldDirection; + + vec3 transformDirection( in vec3 dir, in mat4 matrix ) { + + return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); + + } + + void main() { + + vWorldDirection = transformDirection( position, modelMatrix ); + + #include + #include + + } + `, + + fragmentShader: /* glsl */` + + uniform sampler2D tEquirect; + + varying vec3 vWorldDirection; + + #include + + void main() { + + vec3 direction = normalize( vWorldDirection ); + + vec2 sampleUV = equirectUv( direction ); + + gl_FragColor = texture2D( tEquirect, sampleUV ); + + } + ` + }; + + const geometry = new BoxGeometry( 5, 5, 5 ); + + const material = new ShaderMaterial( { + + name: 'CubemapFromEquirect', + + uniforms: cloneUniforms( shader.uniforms ), + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader, + side: BackSide, + blending: NoBlending + + } ); + + material.uniforms.tEquirect.value = texture; + + const mesh = new Mesh( geometry, material ); + + const currentMinFilter = texture.minFilter; + + // Avoid blurred poles + if ( texture.minFilter === LinearMipmapLinearFilter ) texture.minFilter = LinearFilter; + + const camera = new CubeCamera( 1, 10, this ); + camera.update( renderer, mesh ); + + texture.minFilter = currentMinFilter; + + mesh.geometry.dispose(); + mesh.material.dispose(); + + return this; + + } + + /** + * Clears this cube render target. + * + * @param {WebGLRenderer} renderer - The renderer. + * @param {boolean} [color=true] - Whether the color buffer should be cleared or not. + * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not. + * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not. + */ + clear( renderer, color = true, depth = true, stencil = true ) { + + const currentRenderTarget = renderer.getRenderTarget(); + + for ( let i = 0; i < 6; i ++ ) { + + renderer.setRenderTarget( this, i ); + + renderer.clear( color, depth, stencil ); + + } + + renderer.setRenderTarget( currentRenderTarget ); + + } + +} + function WebGLEnvironments( renderer ) { let cubeMaps = new WeakMap(); @@ -19135,4 +19307,4 @@ class WebGLRenderer { } -export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, ArrayCamera, BackSide, BoxGeometry, BufferAttribute, BufferGeometry, ByteType, CineonToneMapping, ClampToEdgeWrapping, Color, ColorManagement, ConstantAlphaFactor, ConstantColorFactor, CubeDepthTexture, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeUVReflectionMapping, CullFaceBack, CullFaceFront, CullFaceNone, CustomBlending, CustomToneMapping, Data3DTexture, DataArrayTexture, DataTexture, DepthFormat, DepthStencilFormat, DepthTexture, DoubleSide, DstAlphaFactor, DstColorFactor, EqualCompare, EqualDepth, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExternalTexture, Float32BufferAttribute, FloatType, FrontSide, Frustum, GLSL3, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, HalfFloatType, IntType, Layers, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NoBlending, NoColorSpace, NoToneMapping, NormalBlending, NotEqualCompare, NotEqualDepth, ObjectSpaceNormalMap, OneFactor, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, PerspectiveCamera, Plane, PlaneGeometry, R11_EAC_Format, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RG11_EAC_Format, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReverseSubtractEquation, SIGNED_R11_EAC_Format, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SIGNED_RG11_EAC_Format, SRGBColorSpace, SRGBTransfer, ShaderChunk, ShaderLib, ShaderMaterial, ShortType, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, SubtractEquation, SubtractiveBlending, TangentSpaceNormalMap, Texture, Uint16BufferAttribute, Uint32BufferAttribute, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt101111Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGLRenderTarget, WebGLRenderer, WebGLUtils, WebXRController, ZeroFactor, createCanvasElement, error, log, warn, warnOnce }; +export { ACESFilmicToneMapping, AddEquation, AddOperation, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, ArrayCamera, BackSide, BoxGeometry, BufferAttribute, BufferGeometry, ByteType, CineonToneMapping, ClampToEdgeWrapping, Color, ColorManagement, ConstantAlphaFactor, ConstantColorFactor, CubeCamera, CubeDepthTexture, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeUVReflectionMapping, CullFaceBack, CullFaceFront, CullFaceNone, CustomBlending, CustomToneMapping, Data3DTexture, DataArrayTexture, DataTexture, DepthFormat, DepthStencilFormat, DepthTexture, DoubleSide, DstAlphaFactor, DstColorFactor, EqualCompare, EqualDepth, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, ExternalTexture, Float32BufferAttribute, FloatType, FrontSide, Frustum, GLSL3, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, HalfFloatType, IntType, Layers, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Matrix3, Matrix4, MaxEquation, Mesh, MeshBasicMaterial, MeshDepthMaterial, MeshDistanceMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NoBlending, NoColorSpace, NoToneMapping, NormalBlending, NotEqualCompare, NotEqualDepth, ObjectSpaceNormalMap, OneFactor, OneMinusConstantAlphaFactor, OneMinusConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OrthographicCamera, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, PerspectiveCamera, Plane, PlaneGeometry, R11_EAC_Format, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RG11_EAC_Format, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RawShaderMaterial, RedFormat, RedIntegerFormat, ReinhardToneMapping, RepeatWrapping, ReverseSubtractEquation, SIGNED_R11_EAC_Format, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SIGNED_RG11_EAC_Format, SRGBColorSpace, SRGBTransfer, ShaderChunk, ShaderLib, ShaderMaterial, ShortType, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, SubtractEquation, SubtractiveBlending, TangentSpaceNormalMap, Texture, Uint16BufferAttribute, Uint32BufferAttribute, UniformsLib, UniformsUtils, UnsignedByteType, UnsignedInt101111Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, VSMShadowMap, Vector2, Vector3, Vector4, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGLRenderTarget, WebGLRenderer, WebGLUtils, WebXRController, ZeroFactor, createCanvasElement, error, log, warn, warnOnce }; diff --git a/build/three.module.min.js b/build/three.module.min.js index 7943289f09ecc1..46484ae4260275 100644 --- a/build/three.module.min.js +++ b/build/three.module.min.js @@ -3,4 +3,4 @@ * Copyright 2010-2026 Three.js Authors * SPDX-License-Identifier: MIT */ -import{Matrix3 as e,Vector2 as t,Color as n,mergeUniforms as i,Vector3 as r,CubeUVReflectionMapping as a,Mesh as o,BoxGeometry as s,ShaderMaterial as l,BackSide as c,cloneUniforms as d,Euler as u,Matrix4 as f,ColorManagement as p,SRGBTransfer as m,PlaneGeometry as h,FrontSide as _,getUnlitUniformColorSpace as g,IntType as v,warn as E,HalfFloatType as S,UnsignedByteType as M,FloatType as T,RGBAFormat as x,Plane as A,CubeReflectionMapping as R,CubeRefractionMapping as b,BufferGeometry as C,OrthographicCamera as P,PerspectiveCamera as L,NoToneMapping as U,MeshBasicMaterial as D,error as w,NoBlending as I,WebGLRenderTarget as N,BufferAttribute as y,LinearSRGBColorSpace as F,LinearFilter as O,EquirectangularReflectionMapping as B,EquirectangularRefractionMapping as G,WebGLCubeRenderTarget as H,warnOnce as V,Uint32BufferAttribute as W,Uint16BufferAttribute as z,arrayNeedsUint32 as k,Vector4 as X,DataArrayTexture as Y,Float32BufferAttribute as K,RawShaderMaterial as j,CustomToneMapping as q,NeutralToneMapping as Z,AgXToneMapping as $,ACESFilmicToneMapping as Q,CineonToneMapping as J,ReinhardToneMapping as ee,LinearToneMapping as te,CubeTexture as ne,Data3DTexture as ie,GreaterEqualCompare as re,LessEqualCompare as ae,DepthTexture as oe,Texture as se,GLSL3 as le,VSMShadowMap as ce,PCFShadowMap as de,AddOperation as ue,MixOperation as fe,MultiplyOperation as pe,LinearTransfer as me,UniformsUtils as he,DoubleSide as _e,NormalBlending as ge,TangentSpaceNormalMap as ve,ObjectSpaceNormalMap as Ee,Layers as Se,RGFormat as Me,Frustum as Te,MeshDepthMaterial as xe,MeshDistanceMaterial as Ae,PCFSoftShadowMap as Re,DepthFormat as be,NearestFilter as Ce,CubeDepthTexture as Pe,UnsignedIntType as Le,LessEqualDepth as Ue,ReverseSubtractEquation as De,SubtractEquation as we,AddEquation as Ie,OneMinusConstantAlphaFactor as Ne,ConstantAlphaFactor as ye,OneMinusConstantColorFactor as Fe,ConstantColorFactor as Oe,OneMinusDstAlphaFactor as Be,OneMinusDstColorFactor as Ge,OneMinusSrcAlphaFactor as He,OneMinusSrcColorFactor as Ve,DstAlphaFactor as We,DstColorFactor as ze,SrcAlphaSaturateFactor as ke,SrcAlphaFactor as Xe,SrcColorFactor as Ye,OneFactor as Ke,ZeroFactor as je,NotEqualDepth as qe,GreaterDepth as Ze,GreaterEqualDepth as $e,EqualDepth as Qe,LessDepth as Je,AlwaysDepth as et,NeverDepth as tt,CullFaceNone as nt,CullFaceBack as it,CullFaceFront as rt,CustomBlending as at,MultiplyBlending as ot,SubtractiveBlending as st,AdditiveBlending as lt,MinEquation as ct,MaxEquation as dt,MirroredRepeatWrapping as ut,ClampToEdgeWrapping as ft,RepeatWrapping as pt,LinearMipmapLinearFilter as mt,LinearMipmapNearestFilter as ht,NearestMipmapLinearFilter as _t,NearestMipmapNearestFilter as gt,NotEqualCompare as vt,GreaterCompare as Et,EqualCompare as St,LessCompare as Mt,AlwaysCompare as Tt,NeverCompare as xt,NoColorSpace as At,DepthStencilFormat as Rt,getByteLength as bt,UnsignedInt248Type as Ct,UnsignedShortType as Pt,createElementNS as Lt,UnsignedShort4444Type as Ut,UnsignedShort5551Type as Dt,UnsignedInt5999Type as wt,UnsignedInt101111Type as It,ByteType as Nt,ShortType as yt,AlphaFormat as Ft,RGBFormat as Ot,RedFormat as Bt,RedIntegerFormat as Gt,RGIntegerFormat as Ht,RGBAIntegerFormat as Vt,RGB_S3TC_DXT1_Format as Wt,RGBA_S3TC_DXT1_Format as zt,RGBA_S3TC_DXT3_Format as kt,RGBA_S3TC_DXT5_Format as Xt,RGB_PVRTC_4BPPV1_Format as Yt,RGB_PVRTC_2BPPV1_Format as Kt,RGBA_PVRTC_4BPPV1_Format as jt,RGBA_PVRTC_2BPPV1_Format as qt,RGB_ETC1_Format as Zt,RGB_ETC2_Format as $t,RGBA_ETC2_EAC_Format as Qt,R11_EAC_Format as Jt,SIGNED_R11_EAC_Format as en,RG11_EAC_Format as tn,SIGNED_RG11_EAC_Format as nn,RGBA_ASTC_4x4_Format as rn,RGBA_ASTC_5x4_Format as an,RGBA_ASTC_5x5_Format as on,RGBA_ASTC_6x5_Format as sn,RGBA_ASTC_6x6_Format as ln,RGBA_ASTC_8x5_Format as cn,RGBA_ASTC_8x6_Format as dn,RGBA_ASTC_8x8_Format as un,RGBA_ASTC_10x5_Format as fn,RGBA_ASTC_10x6_Format as pn,RGBA_ASTC_10x8_Format as mn,RGBA_ASTC_10x10_Format as hn,RGBA_ASTC_12x10_Format as _n,RGBA_ASTC_12x12_Format as gn,RGBA_BPTC_Format as vn,RGB_BPTC_SIGNED_Format as En,RGB_BPTC_UNSIGNED_Format as Sn,RED_RGTC1_Format as Mn,SIGNED_RED_RGTC1_Format as Tn,RED_GREEN_RGTC2_Format as xn,SIGNED_RED_GREEN_RGTC2_Format as An,ExternalTexture as Rn,EventDispatcher as bn,ArrayCamera as Cn,WebXRController as Pn,RAD2DEG as Ln,DataTexture as Un,createCanvasElement as Dn,SRGBColorSpace as wn,REVISION as In,log as Nn,WebGLCoordinateSystem as yn,probeAsync as Fn}from"./three.core.min.js";export{AdditiveAnimationBlendMode,AlwaysStencilFunc,AmbientLight,AnimationAction,AnimationClip,AnimationLoader,AnimationMixer,AnimationObjectGroup,AnimationUtils,ArcCurve,ArrowHelper,AttachedBindMode,Audio,AudioAnalyser,AudioContext,AudioListener,AudioLoader,AxesHelper,BasicDepthPacking,BasicShadowMap,BatchedMesh,BezierInterpolant,Bone,BooleanKeyframeTrack,Box2,Box3,Box3Helper,BoxHelper,BufferGeometryLoader,Cache,Camera,CameraHelper,CanvasTexture,CapsuleGeometry,CatmullRomCurve3,CircleGeometry,Clock,ColorKeyframeTrack,Compatibility,CompressedArrayTexture,CompressedCubeTexture,CompressedTexture,CompressedTextureLoader,ConeGeometry,Controls,CubeCamera,CubeTextureLoader,CubicBezierCurve,CubicBezierCurve3,CubicInterpolant,CullFaceFrontBack,Curve,CurvePath,CylinderGeometry,Cylindrical,DataTextureLoader,DataUtils,DecrementStencilOp,DecrementWrapStencilOp,DefaultLoadingManager,DetachedBindMode,DirectionalLight,DirectionalLightHelper,DiscreteInterpolant,DodecahedronGeometry,DynamicCopyUsage,DynamicDrawUsage,DynamicReadUsage,EdgesGeometry,EllipseCurve,EqualStencilFunc,ExtrudeGeometry,FileLoader,Float16BufferAttribute,Fog,FogExp2,FramebufferTexture,FrustumArray,GLBufferAttribute,GLSL1,GreaterEqualStencilFunc,GreaterStencilFunc,GridHelper,Group,HemisphereLight,HemisphereLightHelper,IcosahedronGeometry,ImageBitmapLoader,ImageLoader,ImageUtils,IncrementStencilOp,IncrementWrapStencilOp,InstancedBufferAttribute,InstancedBufferGeometry,InstancedInterleavedBuffer,InstancedMesh,Int16BufferAttribute,Int32BufferAttribute,Int8BufferAttribute,InterleavedBuffer,InterleavedBufferAttribute,Interpolant,InterpolateBezier,InterpolateDiscrete,InterpolateLinear,InterpolateSmooth,InterpolationSamplingMode,InterpolationSamplingType,InvertStencilOp,KeepStencilOp,KeyframeTrack,LOD,LatheGeometry,LessEqualStencilFunc,LessStencilFunc,Light,LightProbe,Line,Line3,LineBasicMaterial,LineCurve,LineCurve3,LineDashedMaterial,LineLoop,LineSegments,LinearInterpolant,LinearMipMapLinearFilter,LinearMipMapNearestFilter,Loader,LoaderUtils,LoadingManager,LoopOnce,LoopPingPong,LoopRepeat,MOUSE,Material,MaterialBlending,MaterialLoader,MathUtils,Matrix2,MeshLambertMaterial,MeshMatcapMaterial,MeshNormalMaterial,MeshPhongMaterial,MeshPhysicalMaterial,MeshStandardMaterial,MeshToonMaterial,NearestMipMapLinearFilter,NearestMipMapNearestFilter,NeverStencilFunc,NoNormalPacking,NormalAnimationBlendMode,NormalGAPacking,NormalRGPacking,NotEqualStencilFunc,NumberKeyframeTrack,Object3D,ObjectLoader,OctahedronGeometry,Path,PlaneHelper,PointLight,PointLightHelper,Points,PointsMaterial,PolarGridHelper,PolyhedronGeometry,PositionalAudio,PropertyBinding,PropertyMixer,QuadraticBezierCurve,QuadraticBezierCurve3,Quaternion,QuaternionKeyframeTrack,QuaternionLinearInterpolant,RGBADepthPacking,RGBDepthPacking,RGBIntegerFormat,RGDepthPacking,Ray,Raycaster,RectAreaLight,RenderTarget,RenderTarget3D,ReplaceStencilOp,RingGeometry,Scene,ShadowMaterial,Shape,ShapeGeometry,ShapePath,ShapeUtils,Skeleton,SkeletonHelper,SkinnedMesh,Source,Sphere,SphereGeometry,Spherical,SphericalHarmonics3,SplineCurve,SpotLight,SpotLightHelper,Sprite,SpriteMaterial,StaticCopyUsage,StaticDrawUsage,StaticReadUsage,StereoCamera,StreamCopyUsage,StreamDrawUsage,StreamReadUsage,StringKeyframeTrack,TOUCH,TetrahedronGeometry,TextureLoader,TextureUtils,Timer,TimestampQuery,TorusGeometry,TorusKnotGeometry,Triangle,TriangleFanDrawMode,TriangleStripDrawMode,TrianglesDrawMode,TubeGeometry,UVMapping,Uint8BufferAttribute,Uint8ClampedBufferAttribute,Uniform,UniformsGroup,VectorKeyframeTrack,VideoFrameTexture,VideoTexture,WebGL3DRenderTarget,WebGLArrayRenderTarget,WebGPUCoordinateSystem,WireframeGeometry,WrapAroundEnding,ZeroCurvatureEnding,ZeroSlopeEnding,ZeroStencilOp,getConsoleFunction,setConsoleFunction}from"./three.core.min.js";function On(){let e=null,t=!1,n=null,i=null;function r(t,a){n(t,a),i=e.requestAnimationFrame(r)}return{start:function(){!0!==t&&null!==n&&(i=e.requestAnimationFrame(r),t=!0)},stop:function(){e.cancelAnimationFrame(i),t=!1},setAnimationLoop:function(e){n=e},setContext:function(t){e=t}}}function Bn(e){const t=new WeakMap;return{get:function(e){return e.isInterleavedBufferAttribute&&(e=e.data),t.get(e)},remove:function(n){n.isInterleavedBufferAttribute&&(n=n.data);const i=t.get(n);i&&(e.deleteBuffer(i.buffer),t.delete(n))},update:function(n,i){if(n.isInterleavedBufferAttribute&&(n=n.data),n.isGLBufferAttribute){const e=t.get(n);return void((!e||e.versione.start-t.start);let t=0;for(let e=1;e 0\n\tvec4 plane;\n\t#ifdef ALPHA_TO_COVERAGE\n\t\tfloat distanceToPlane, distanceGradient;\n\t\tfloat clipOpacity = 1.0;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\tclipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\tif ( clipOpacity == 0.0 ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tfloat unionClipOpacity = 1.0;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\t\tunionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tclipOpacity *= 1.0 - unionClipOpacity;\n\t\t#endif\n\t\tdiffuseColor.a *= clipOpacity;\n\t\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tbool clipped = true;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tif ( clipped ) discard;\n\t\t#endif\n\t#endif\n#endif",clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif",color_fragment:"#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#endif",color_pars_fragment:"#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#endif",color_pars_vertex:"#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvarying vec4 vColor;\n#endif",color_vertex:"#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvColor = vec4( 1.0 );\n#endif\n#ifdef USE_COLOR_ALPHA\n\tvColor *= color;\n#elif defined( USE_COLOR )\n\tvColor.rgb *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.rgb *= instanceColor.rgb;\n#endif\n#ifdef USE_BATCHING_COLOR\n\tvColor *= getBatchingColor( getIndirectIndex( gl_DrawID ) );\n#endif",common:"#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated",cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif",defaultnormal_vertex:"vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE_EMISSIVE\n\t\temissiveColor = sRGBTransferEOTF( emissiveColor );\n\t#endif\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",colorspace_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",colorspace_pars_fragment:"vec4 LinearTransferOETF( in vec4 value ) {\n\treturn value;\n}\nvec4 sRGBTransferEOTF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 sRGBTransferOETF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}",envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t\t#endif\n\t#endif\n#endif",envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform mat3 envMapRotation;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif",envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#ifdef USE_ENVMAP\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\t#ifdef USE_ANISOTROPY\n\t\tvec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n\t\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\t\tvec3 bentNormal = cross( bitangent, viewDir );\n\t\t\t\tbentNormal = normalize( cross( bentNormal, bitangent ) );\n\t\t\t\tbentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n\t\t\t\treturn getIBLRadiance( viewDir, bentNormal, roughness );\n\t\t\t#else\n\t\t\t\treturn vec3( 0.0 );\n\t\t\t#endif\n\t\t}\n\t#endif\n#endif",envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif",fog_vertex:"#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif",gradientmap_pars_fragment:"#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}",lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_fragment:"LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;",lights_lambert_pars_fragment:"varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert",lights_pars_begin:"uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n\tuniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif ( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif",lights_toon_fragment:"ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;",lights_toon_pars_fragment:"varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon",lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong",lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.diffuseContribution = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.metalness = metalnessFactor;\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor;\n\tmaterial.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = vec3( 0.04 );\n\tmaterial.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.0001, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif",lights_physical_pars_fragment:"uniform sampler2D dfgLUT;\nstruct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tvec3 diffuseContribution;\n\tvec3 specularColor;\n\tvec3 specularColorBlended;\n\tfloat roughness;\n\tfloat metalness;\n\tfloat specularF90;\n\tfloat dispersion;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t\tvec3 iridescenceFresnelDielectric;\n\t\tvec3 iridescenceFresnelMetallic;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat anisotropy;\n\t\tfloat alphaT;\n\t\tvec3 anisotropyT;\n\t\tvec3 anisotropyB;\n\t#endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n\tfloat V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n\t\tfloat gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n\t\tfloat gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n\t\tfloat v = 0.5 / ( gv + gl );\n\t\treturn v;\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.specularColorBlended;\n\tfloat f90 = material.specularF90;\n\tfloat roughness = material.roughness;\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t#ifdef USE_IRIDESCENCE\n\t\tF = mix( F, material.iridescenceFresnel, material.iridescence );\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat dotTL = dot( material.anisotropyT, lightDir );\n\t\tfloat dotTV = dot( material.anisotropyT, viewDir );\n\t\tfloat dotTH = dot( material.anisotropyT, halfDir );\n\t\tfloat dotBL = dot( material.anisotropyB, lightDir );\n\t\tfloat dotBV = dot( material.anisotropyB, viewDir );\n\t\tfloat dotBH = dot( material.anisotropyB, halfDir );\n\t\tfloat V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n\t\tfloat D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n\t#else\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t#endif\n\treturn F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat rInv = 1.0 / ( roughness + 0.1 );\n\tfloat a = -1.9362 + 1.0678 * roughness + 0.4573 * r2 - 0.8469 * rInv;\n\tfloat b = -0.6014 + 0.5538 * roughness - 0.4670 * r2 - 0.1255 * rInv;\n\tfloat DG = exp( a * dotNV + b );\n\treturn saturate( DG );\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nvec3 BRDF_GGX_Multiscatter( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 singleScatter = BRDF_GGX( lightDir, viewDir, normal, material );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 dfgV = texture2D( dfgLUT, vec2( material.roughness, dotNV ) ).rg;\n\tvec2 dfgL = texture2D( dfgLUT, vec2( material.roughness, dotNL ) ).rg;\n\tvec3 FssEss_V = material.specularColorBlended * dfgV.x + material.specularF90 * dfgV.y;\n\tvec3 FssEss_L = material.specularColorBlended * dfgL.x + material.specularF90 * dfgL.y;\n\tfloat Ess_V = dfgV.x + dfgV.y;\n\tfloat Ess_L = dfgL.x + dfgL.y;\n\tfloat Ems_V = 1.0 - Ess_V;\n\tfloat Ems_L = 1.0 - Ess_L;\n\tvec3 Favg = material.specularColorBlended + ( 1.0 - material.specularColorBlended ) * 0.047619;\n\tvec3 Fms = FssEss_V * FssEss_L * Favg / ( 1.0 - Ems_V * Ems_L * Favg + EPSILON );\n\tfloat compensationFactor = Ems_V * Ems_L;\n\tvec3 multiScatter = Fms * compensationFactor;\n\treturn singleScatter + multiScatter;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometryNormal;\n\t\tvec3 viewDir = geometryViewDir;\n\t\tvec3 position = geometryPosition;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColorBlended * t2.x + ( material.specularF90 - material.specularColorBlended ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseContribution * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t\t#ifdef USE_CLEARCOAT\n\t\t\tvec3 Ncc = geometryClearcoatNormal;\n\t\t\tvec2 uvClearcoat = LTC_Uv( Ncc, viewDir, material.clearcoatRoughness );\n\t\t\tvec4 t1Clearcoat = texture2D( ltc_1, uvClearcoat );\n\t\t\tvec4 t2Clearcoat = texture2D( ltc_2, uvClearcoat );\n\t\t\tmat3 mInvClearcoat = mat3(\n\t\t\t\tvec3( t1Clearcoat.x, 0, t1Clearcoat.y ),\n\t\t\t\tvec3( 0, 1, 0 ),\n\t\t\t\tvec3( t1Clearcoat.z, 0, t1Clearcoat.w )\n\t\t\t);\n\t\t\tvec3 fresnelClearcoat = material.clearcoatF0 * t2Clearcoat.x + ( material.clearcoatF90 - material.clearcoatF0 ) * t2Clearcoat.y;\n\t\t\tclearcoatSpecularDirect += lightColor * fresnelClearcoat * LTC_Evaluate( Ncc, viewDir, position, mInvClearcoat, rectCoords );\n\t\t#endif\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n \n \t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n \n \t\tfloat sheenAlbedoV = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n \t\tfloat sheenAlbedoL = IBLSheenBRDF( geometryNormal, directLight.direction, material.sheenRoughness );\n \n \t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * max( sheenAlbedoV, sheenAlbedoL );\n \n \t\tirradiance *= sheenEnergyComp;\n \n \t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX_Multiscatter( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseContribution );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 diffuse = irradiance * BRDF_Lambert( material.diffuseContribution );\n\t#ifdef USE_SHEEN\n\t\tfloat sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n\t\tdiffuse *= sheenEnergyComp;\n\t#endif\n\treflectedLight.indirectDiffuse += diffuse;\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness ) * RECIPROCAL_PI;\n \t#endif\n\tvec3 singleScatteringDielectric = vec3( 0.0 );\n\tvec3 multiScatteringDielectric = vec3( 0.0 );\n\tvec3 singleScatteringMetallic = vec3( 0.0 );\n\tvec3 multiScatteringMetallic = vec3( 0.0 );\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnelDielectric, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.iridescence, material.iridescenceFresnelMetallic, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n\t#endif\n\tvec3 singleScattering = mix( singleScatteringDielectric, singleScatteringMetallic, material.metalness );\n\tvec3 multiScattering = mix( multiScatteringDielectric, multiScatteringMetallic, material.metalness );\n\tvec3 totalScatteringDielectric = singleScatteringDielectric + multiScatteringDielectric;\n\tvec3 diffuse = material.diffuseContribution * ( 1.0 - totalScatteringDielectric );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tvec3 indirectSpecular = radiance * singleScattering;\n\tindirectSpecular += multiScattering * cosineWeightedIrradiance;\n\tvec3 indirectDiffuse = diffuse * cosineWeightedIrradiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n\t\tindirectSpecular *= sheenEnergyComp;\n\t\tindirectDiffuse *= sheenEnergyComp;\n\t#endif\n\treflectedLight.indirectSpecular += indirectSpecular;\n\treflectedLight.indirectDiffuse += indirectDiffuse;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}",lights_fragment_begin:"\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n\tgeometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnelDielectric = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceFresnelMetallic = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.diffuseColor );\n\t\tmaterial.iridescenceFresnel = mix( material.iridescenceFresnelDielectric, material.iridescenceFresnelMetallic, material.metalness );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if defined( USE_LIGHT_PROBES )\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif",lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\t#if defined( STANDARD ) || defined( LAMBERT ) || defined( PHONG )\n\t\t\tiblIrradiance += getIBLIrradiance( geometryNormal );\n\t\t#endif\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\t#ifdef USE_ANISOTROPY\n\t\tradiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n\t#else\n\t\tradiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif",lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\t#if defined( LAMBERT ) || defined( PHONG )\n\t\tirradiance += iblIrradiance;\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n\tgl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",logdepthbuf_pars_vertex:"#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n\tvFragDepth = 1.0 + gl_Position.w;\n\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n#endif",map_fragment:"#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t#if defined( USE_POINTS_UV )\n\t\tvec2 uv = vUv;\n\t#else\n\t\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif",map_particle_pars_fragment:"#if defined( USE_POINTS_UV )\n\tvarying vec2 vUv;\n#else\n\t#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t\tuniform mat3 uvTransform;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphinstance_vertex:"#ifdef USE_INSTANCING_MORPH\n\tfloat morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\tfloat morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tmorphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;\n\t}\n#endif",morphcolor_vertex:"#if defined( USE_MORPHCOLORS )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_INSTANCING_MORPH\n\t\tuniform float morphTargetBaseInfluence;\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t#endif\n\tuniform sampler2DArray morphTargetsTexture;\n\tuniform ivec2 morphTargetsTextureSize;\n\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t}\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif",normal_fragment_begin:"float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal *= faceDirection;\n\t#endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn = getTangentFrame( - vViewPosition, normal,\n\t\t#if defined( USE_NORMALMAP )\n\t\t\tvNormalMapUv\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tvClearcoatNormalMapUv\n\t\t#else\n\t\t\tvUv\n\t\t#endif\n\t\t);\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn[0] *= faceDirection;\n\t\ttbn[1] *= faceDirection;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn2[0] *= faceDirection;\n\t\ttbn2[1] *= faceDirection;\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;",normal_fragment_maps:"#ifdef USE_NORMALMAP_OBJECTSPACE\n\tnormal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( USE_NORMALMAP_TANGENTSPACE )\n\tvec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\tnormal = normalize( tbn * mapN );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif",normal_pars_fragment:"#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif",normal_pars_vertex:"#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif",normal_vertex:"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif",normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef USE_NORMALMAP_OBJECTSPACE\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n\tmat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( uv.st );\n\t\tvec2 st1 = dFdy( uv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );\n\t\treturn mat3( T * scale, B * scale, N );\n\t}\n#endif",clearcoat_normal_fragment_begin:"#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = nonPerturbedNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\tclearcoatNormal = normalize( tbn2 * clearcoatMapN );\n#endif",clearcoat_pars_fragment:"#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif",iridescence_pars_fragment:"#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif",opaque_fragment:"#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.;\nconst float Inv255 = 1. / 255.;\nconst vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );\nconst vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );\nconst vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );\nconst vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );\nvec4 packDepthToRGBA( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec4( 0., 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec4( 1., 1., 1., 1. );\n\tfloat vuf;\n\tfloat af = modf( v * PackFactors.a, vuf );\n\tfloat bf = modf( vuf * ShiftRight8, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );\n}\nvec3 packDepthToRGB( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec3( 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec3( 1., 1., 1. );\n\tfloat vuf;\n\tfloat bf = modf( v * PackFactors.b, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec3( vuf * Inv255, gf * PackUpscale, bf );\n}\nvec2 packDepthToRG( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec2( 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec2( 1., 1. );\n\tfloat vuf;\n\tfloat gf = modf( v * 256., vuf );\n\treturn vec2( vuf * Inv255, gf );\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors4 );\n}\nfloat unpackRGBToDepth( const in vec3 v ) {\n\treturn dot( v, UnpackFactors3 );\n}\nfloat unpackRGToDepth( const in vec2 v ) {\n\treturn v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;\n}\nvec4 pack2HalfToRGBA( const in vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( const in vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\n\t\treturn depth * ( far - near ) - far;\n\t#else\n\t\treturn depth * ( near - far ) - near;\n\t#endif\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\t\n\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\treturn ( near * far ) / ( ( near - far ) * depth - near );\n\t#else\n\t\treturn ( near * far ) / ( ( far - near ) * depth - far );\n\t#endif\n}",premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n\tmvPosition = batchingMatrix * mvPosition;\n#endif\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif",roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n\tuniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tuniform sampler2DShadow directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\t#else\n\t\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\t#endif\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tuniform sampler2DShadow spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\t#else\n\t\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\t#endif\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tuniform samplerCubeShadow pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\t#elif defined( SHADOWMAP_TYPE_BASIC )\n\t\t\tuniform samplerCube pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\t#endif\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\tfloat interleavedGradientNoise( vec2 position ) {\n\t\t\treturn fract( 52.9829189 * fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) );\n\t\t}\n\t\tvec2 vogelDiskSample( int sampleIndex, int samplesCount, float phi ) {\n\t\t\tconst float goldenAngle = 2.399963229728653;\n\t\t\tfloat r = sqrt( ( float( sampleIndex ) + 0.5 ) / float( samplesCount ) );\n\t\t\tfloat theta = float( sampleIndex ) * goldenAngle + phi;\n\t\t\treturn vec2( cos( theta ), sin( theta ) ) * r;\n\t\t}\n\t#endif\n\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\tfloat getShadow( sampler2DShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\t\tfloat shadow = 1.0;\n\t\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\t\tshadowCoord.z += shadowBias;\n\t\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\t\tif ( frustumTest ) {\n\t\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\t\tfloat radius = shadowRadius * texelSize.x;\n\t\t\t\tfloat phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n\t\t\t\tshadow = (\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 0, 5, phi ) * radius, shadowCoord.z ) ) +\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 1, 5, phi ) * radius, shadowCoord.z ) ) +\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 2, 5, phi ) * radius, shadowCoord.z ) ) +\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 3, 5, phi ) * radius, shadowCoord.z ) ) +\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 4, 5, phi ) * radius, shadowCoord.z ) )\n\t\t\t\t) * 0.2;\n\t\t\t}\n\t\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t\t}\n\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\t\tfloat shadow = 1.0;\n\t\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\tshadowCoord.z -= shadowBias;\n\t\t\t#else\n\t\t\t\tshadowCoord.z += shadowBias;\n\t\t\t#endif\n\t\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\t\tif ( frustumTest ) {\n\t\t\t\tvec2 distribution = texture2D( shadowMap, shadowCoord.xy ).rg;\n\t\t\t\tfloat mean = distribution.x;\n\t\t\t\tfloat variance = distribution.y * distribution.y;\n\t\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\t\tfloat hard_shadow = step( mean, shadowCoord.z );\n\t\t\t\t#else\n\t\t\t\t\tfloat hard_shadow = step( shadowCoord.z, mean );\n\t\t\t\t#endif\n\t\t\t\t\n\t\t\t\tif ( hard_shadow == 1.0 ) {\n\t\t\t\t\tshadow = 1.0;\n\t\t\t\t} else {\n\t\t\t\t\tvariance = max( variance, 0.0000001 );\n\t\t\t\t\tfloat d = shadowCoord.z - mean;\n\t\t\t\t\tfloat p_max = variance / ( variance + d * d );\n\t\t\t\t\tp_max = clamp( ( p_max - 0.3 ) / 0.65, 0.0, 1.0 );\n\t\t\t\t\tshadow = max( hard_shadow, p_max );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t\t}\n\t#else\n\t\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\t\tfloat shadow = 1.0;\n\t\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\tshadowCoord.z -= shadowBias;\n\t\t\t#else\n\t\t\t\tshadowCoord.z += shadowBias;\n\t\t\t#endif\n\t\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\t\tif ( frustumTest ) {\n\t\t\t\tfloat depth = texture2D( shadowMap, shadowCoord.xy ).r;\n\t\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\t\tshadow = step( depth, shadowCoord.z );\n\t\t\t\t#else\n\t\t\t\t\tshadow = step( shadowCoord.z, depth );\n\t\t\t\t#endif\n\t\t\t}\n\t\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#if defined( SHADOWMAP_TYPE_PCF )\n\tfloat getPointShadow( samplerCubeShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tfloat shadow = 1.0;\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\tvec3 absVec = abs( lightToPosition );\n\t\tfloat viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n\t\tif ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\tfloat dp = ( shadowCameraNear * ( shadowCameraFar - viewSpaceZ ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n\t\t\t\tdp -= shadowBias;\n\t\t\t#else\n\t\t\t\tfloat dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n\t\t\t\tdp += shadowBias;\n\t\t\t#endif\n\t\t\tfloat texelSize = shadowRadius / shadowMapSize.x;\n\t\t\tvec3 absDir = abs( bd3D );\n\t\t\tvec3 tangent = absDir.x > absDir.z ? vec3( 0.0, 1.0, 0.0 ) : vec3( 1.0, 0.0, 0.0 );\n\t\t\ttangent = normalize( cross( bd3D, tangent ) );\n\t\t\tvec3 bitangent = cross( bd3D, tangent );\n\t\t\tfloat phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n\t\t\tvec2 sample0 = vogelDiskSample( 0, 5, phi );\n\t\t\tvec2 sample1 = vogelDiskSample( 1, 5, phi );\n\t\t\tvec2 sample2 = vogelDiskSample( 2, 5, phi );\n\t\t\tvec2 sample3 = vogelDiskSample( 3, 5, phi );\n\t\t\tvec2 sample4 = vogelDiskSample( 4, 5, phi );\n\t\t\tshadow = (\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample0.x + bitangent * sample0.y ) * texelSize, dp ) ) +\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample1.x + bitangent * sample1.y ) * texelSize, dp ) ) +\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample2.x + bitangent * sample2.y ) * texelSize, dp ) ) +\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample3.x + bitangent * sample3.y ) * texelSize, dp ) ) +\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample4.x + bitangent * sample4.y ) * texelSize, dp ) )\n\t\t\t) * 0.2;\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n\t#elif defined( SHADOWMAP_TYPE_BASIC )\n\tfloat getPointShadow( samplerCube shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tfloat shadow = 1.0;\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 absVec = abs( lightToPosition );\n\t\tfloat viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n\t\tif ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n\t\t\tfloat dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n\t\t\tdp += shadowBias;\n\t\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t\tfloat depth = textureCube( shadowMap, bd3D ).r;\n\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\tdepth = 1.0 - depth;\n\t\t\t#endif\n\t\t\tshadow = step( dp, depth );\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n\t#endif\n\t#endif\n#endif",shadowmap_pars_vertex:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif",shadowmap_vertex:"#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n#endif",shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0 && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}",skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tint size = textureSize( boneTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif",skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif",specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n\tvec3( 1.6605, - 0.1246, - 0.0182 ),\n\tvec3( - 0.5876, 1.1329, - 0.1006 ),\n\tvec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n\tvec3( 0.6274, 0.0691, 0.0164 ),\n\tvec3( 0.3293, 0.9195, 0.0880 ),\n\tvec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n\tvec3 x2 = x * x;\n\tvec3 x4 = x2 * x2;\n\treturn + 15.5 * x4 * x2\n\t\t- 40.14 * x4 * x\n\t\t+ 31.96 * x4\n\t\t- 6.868 * x2 * x\n\t\t+ 0.4298 * x2\n\t\t+ 0.1191 * x\n\t\t- 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n\tconst mat3 AgXInsetMatrix = mat3(\n\t\tvec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n\t\tvec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n\t\tvec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n\t);\n\tconst mat3 AgXOutsetMatrix = mat3(\n\t\tvec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n\t\tvec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n\t\tvec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n\t);\n\tconst float AgxMinEv = - 12.47393;\tconst float AgxMaxEv = 4.026069;\n\tcolor *= toneMappingExposure;\n\tcolor = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n\tcolor = AgXInsetMatrix * color;\n\tcolor = max( color, 1e-10 );\tcolor = log2( color );\n\tcolor = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n\tcolor = clamp( color, 0.0, 1.0 );\n\tcolor = agxDefaultContrastApprox( color );\n\tcolor = AgXOutsetMatrix * color;\n\tcolor = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n\tcolor = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n\tcolor = clamp( color, 0.0, 1.0 );\n\treturn color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n\tconst float StartCompression = 0.8 - 0.04;\n\tconst float Desaturation = 0.15;\n\tcolor *= toneMappingExposure;\n\tfloat x = min( color.r, min( color.g, color.b ) );\n\tfloat offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n\tcolor -= offset;\n\tfloat peak = max( color.r, max( color.g, color.b ) );\n\tif ( peak < StartCompression ) return color;\n\tfloat d = 1. - StartCompression;\n\tfloat newPeak = 1. - d * d / ( peak + d - StartCompression );\n\tcolor *= newPeak / peak;\n\tfloat g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n\treturn mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }",transmission_fragment:"#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseContribution, material.specularColorBlended, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif",transmission_pars_fragment:"#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tfloat w0( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n\t}\n\tfloat w1( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 );\n\t}\n\tfloat w2( float a ){\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n\t}\n\tfloat w3( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * a );\n\t}\n\tfloat g0( float a ) {\n\t\treturn w0( a ) + w1( a );\n\t}\n\tfloat g1( float a ) {\n\t\treturn w2( a ) + w3( a );\n\t}\n\tfloat h0( float a ) {\n\t\treturn - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n\t}\n\tfloat h1( float a ) {\n\t\treturn 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n\t}\n\tvec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n\t\tuv = uv * texelSize.zw + 0.5;\n\t\tvec2 iuv = floor( uv );\n\t\tvec2 fuv = fract( uv );\n\t\tfloat g0x = g0( fuv.x );\n\t\tfloat g1x = g1( fuv.x );\n\t\tfloat h0x = h0( fuv.x );\n\t\tfloat h1x = h1( fuv.x );\n\t\tfloat h0y = h0( fuv.y );\n\t\tfloat h1y = h1( fuv.y );\n\t\tvec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\treturn g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n\t\t\tg1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n\t}\n\tvec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n\t\tvec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n\t\tvec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n\t\tvec2 fLodSizeInv = 1.0 / fLodSize;\n\t\tvec2 cLodSizeInv = 1.0 / cLodSize;\n\t\tvec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n\t\tvec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n\t\treturn mix( fSample, cSample, fract( lod ) );\n\t}\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\treturn textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n\t}\n\tvec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn vec3( 1.0 );\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec4 transmittedLight;\n\t\tvec3 transmittance;\n\t\t#ifdef USE_DISPERSION\n\t\t\tfloat halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n\t\t\tvec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n\t\t\tfor ( int i = 0; i < 3; i ++ ) {\n\t\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n\t\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\t\trefractionCoords += 1.0;\n\t\t\t\trefractionCoords /= 2.0;\n\t\t\t\tvec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n\t\t\t\ttransmittedLight[ i ] = transmissionSample[ i ];\n\t\t\t\ttransmittedLight.a += transmissionSample.a;\n\t\t\t\ttransmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n\t\t\t}\n\t\t\ttransmittedLight.a /= 3.0;\n\t\t#else\n\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\trefractionCoords += 1.0;\n\t\t\trefractionCoords /= 2.0;\n\t\t\ttransmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\t\ttransmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\t#endif\n\t\tvec3 attenuatedColor = transmittance * transmittedLight.rgb;\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\tfloat transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n\t}\n#endif",uv_pars_fragment:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif",uv_pars_vertex:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tuniform mat3 mapTransform;\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform mat3 alphaMapTransform;\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tuniform mat3 lightMapTransform;\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tuniform mat3 aoMapTransform;\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tuniform mat3 bumpMapTransform;\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tuniform mat3 normalMapTransform;\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tuniform mat3 displacementMapTransform;\n\tvarying vec2 vDisplacementMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tuniform mat3 emissiveMapTransform;\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tuniform mat3 metalnessMapTransform;\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tuniform mat3 roughnessMapTransform;\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tuniform mat3 anisotropyMapTransform;\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tuniform mat3 clearcoatMapTransform;\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform mat3 clearcoatNormalMapTransform;\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform mat3 clearcoatRoughnessMapTransform;\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tuniform mat3 sheenColorMapTransform;\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tuniform mat3 sheenRoughnessMapTransform;\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tuniform mat3 iridescenceMapTransform;\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform mat3 iridescenceThicknessMapTransform;\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tuniform mat3 specularMapTransform;\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tuniform mat3 specularColorMapTransform;\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tuniform mat3 specularIntensityMapTransform;\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif",uv_vertex:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n\tvMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n\tvAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n\tvLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n\tvAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n\tvBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n\tvNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tvDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n\tvMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n\tvSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tvTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n\tvThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_BATCHING\n\t\tworldPosition = batchingMatrix * worldPosition;\n\t#endif\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif",background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}",background_frag:"uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}",backgroundCube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",backgroundCube_frag:"#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}",cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}",depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\tfloat fragCoordZ = vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ];\n\t#else\n\t\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ] + 0.5;\n\t#endif\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#elif DEPTH_PACKING == 3202\n\t\tgl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );\n\t#elif DEPTH_PACKING == 3203\n\t\tgl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );\n\t#endif\n}",distance_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}",distance_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = vec4( dist, 0.0, 0.0, 1.0 );\n}",equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include \n\t#include \n}",linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshlambert_vert:"#define LAMBERT\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}",meshlambert_frag:"#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}",meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshnormal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}",meshnormal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( normalize( normal ) * 0.5 + 0.5, diffuseColor.a );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}",meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}",meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}",meshphysical_frag:"#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef USE_SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULAR_COLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n\tuniform float dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\tuniform vec2 anisotropyVector;\n\t#ifdef USE_ANISOTROPYMAP\n\t\tuniform sampler2D anisotropyMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include \n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n \n\t\toutgoingLight = outgoingLight + sheenSpecularDirect + sheenSpecularIndirect;\n \n \t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshtoon_vert:"#define TOON\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}",meshtoon_frag:"#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef USE_POINTS_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\nvoid main() {\n\t#ifdef USE_POINTS_UV\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}",points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",shadow_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n\t#include \n\t#include \n\t#include \n}",sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix[ 3 ];\n\tvec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}",sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n}"},Hn={common:{diffuse:{value:new n(16777215)},opacity:{value:1},map:{value:null},mapTransform:{value:new e},alphaMap:{value:null},alphaMapTransform:{value:new e},alphaTest:{value:0}},specularmap:{specularMap:{value:null},specularMapTransform:{value:new e}},envmap:{envMap:{value:null},envMapRotation:{value:new e},flipEnvMap:{value:-1},reflectivity:{value:1},ior:{value:1.5},refractionRatio:{value:.98},dfgLUT:{value:null}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1},aoMapTransform:{value:new e}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1},lightMapTransform:{value:new e}},bumpmap:{bumpMap:{value:null},bumpMapTransform:{value:new e},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalMapTransform:{value:new e},normalScale:{value:new t(1,1)}},displacementmap:{displacementMap:{value:null},displacementMapTransform:{value:new e},displacementScale:{value:1},displacementBias:{value:0}},emissivemap:{emissiveMap:{value:null},emissiveMapTransform:{value:new e}},metalnessmap:{metalnessMap:{value:null},metalnessMapTransform:{value:new e}},roughnessmap:{roughnessMap:{value:null},roughnessMapTransform:{value:new e}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new n(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{}}},directionalLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{}}},spotLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},spotLightMap:{value:[]},spotLightMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{}}},pointLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}},ltc_1:{value:null},ltc_2:{value:null}},points:{diffuse:{value:new n(16777215)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},alphaMapTransform:{value:new e},alphaTest:{value:0},uvTransform:{value:new e}},sprite:{diffuse:{value:new n(16777215)},opacity:{value:1},center:{value:new t(.5,.5)},rotation:{value:0},map:{value:null},mapTransform:{value:new e},alphaMap:{value:null},alphaMapTransform:{value:new e},alphaTest:{value:0}}},Vn={basic:{uniforms:i([Hn.common,Hn.specularmap,Hn.envmap,Hn.aomap,Hn.lightmap,Hn.fog]),vertexShader:Gn.meshbasic_vert,fragmentShader:Gn.meshbasic_frag},lambert:{uniforms:i([Hn.common,Hn.specularmap,Hn.envmap,Hn.aomap,Hn.lightmap,Hn.emissivemap,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.fog,Hn.lights,{emissive:{value:new n(0)},envMapIntensity:{value:1}}]),vertexShader:Gn.meshlambert_vert,fragmentShader:Gn.meshlambert_frag},phong:{uniforms:i([Hn.common,Hn.specularmap,Hn.envmap,Hn.aomap,Hn.lightmap,Hn.emissivemap,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.fog,Hn.lights,{emissive:{value:new n(0)},specular:{value:new n(1118481)},shininess:{value:30},envMapIntensity:{value:1}}]),vertexShader:Gn.meshphong_vert,fragmentShader:Gn.meshphong_frag},standard:{uniforms:i([Hn.common,Hn.envmap,Hn.aomap,Hn.lightmap,Hn.emissivemap,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.roughnessmap,Hn.metalnessmap,Hn.fog,Hn.lights,{emissive:{value:new n(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:Gn.meshphysical_vert,fragmentShader:Gn.meshphysical_frag},toon:{uniforms:i([Hn.common,Hn.aomap,Hn.lightmap,Hn.emissivemap,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.gradientmap,Hn.fog,Hn.lights,{emissive:{value:new n(0)}}]),vertexShader:Gn.meshtoon_vert,fragmentShader:Gn.meshtoon_frag},matcap:{uniforms:i([Hn.common,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.fog,{matcap:{value:null}}]),vertexShader:Gn.meshmatcap_vert,fragmentShader:Gn.meshmatcap_frag},points:{uniforms:i([Hn.points,Hn.fog]),vertexShader:Gn.points_vert,fragmentShader:Gn.points_frag},dashed:{uniforms:i([Hn.common,Hn.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:Gn.linedashed_vert,fragmentShader:Gn.linedashed_frag},depth:{uniforms:i([Hn.common,Hn.displacementmap]),vertexShader:Gn.depth_vert,fragmentShader:Gn.depth_frag},normal:{uniforms:i([Hn.common,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,{opacity:{value:1}}]),vertexShader:Gn.meshnormal_vert,fragmentShader:Gn.meshnormal_frag},sprite:{uniforms:i([Hn.sprite,Hn.fog]),vertexShader:Gn.sprite_vert,fragmentShader:Gn.sprite_frag},background:{uniforms:{uvTransform:{value:new e},t2D:{value:null},backgroundIntensity:{value:1}},vertexShader:Gn.background_vert,fragmentShader:Gn.background_frag},backgroundCube:{uniforms:{envMap:{value:null},flipEnvMap:{value:-1},backgroundBlurriness:{value:0},backgroundIntensity:{value:1},backgroundRotation:{value:new e}},vertexShader:Gn.backgroundCube_vert,fragmentShader:Gn.backgroundCube_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:Gn.cube_vert,fragmentShader:Gn.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:Gn.equirect_vert,fragmentShader:Gn.equirect_frag},distance:{uniforms:i([Hn.common,Hn.displacementmap,{referencePosition:{value:new r},nearDistance:{value:1},farDistance:{value:1e3}}]),vertexShader:Gn.distance_vert,fragmentShader:Gn.distance_frag},shadow:{uniforms:i([Hn.lights,Hn.fog,{color:{value:new n(0)},opacity:{value:1}}]),vertexShader:Gn.shadow_vert,fragmentShader:Gn.shadow_frag}};Vn.physical={uniforms:i([Vn.standard.uniforms,{clearcoat:{value:0},clearcoatMap:{value:null},clearcoatMapTransform:{value:new e},clearcoatNormalMap:{value:null},clearcoatNormalMapTransform:{value:new e},clearcoatNormalScale:{value:new t(1,1)},clearcoatRoughness:{value:0},clearcoatRoughnessMap:{value:null},clearcoatRoughnessMapTransform:{value:new e},dispersion:{value:0},iridescence:{value:0},iridescenceMap:{value:null},iridescenceMapTransform:{value:new e},iridescenceIOR:{value:1.3},iridescenceThicknessMinimum:{value:100},iridescenceThicknessMaximum:{value:400},iridescenceThicknessMap:{value:null},iridescenceThicknessMapTransform:{value:new e},sheen:{value:0},sheenColor:{value:new n(0)},sheenColorMap:{value:null},sheenColorMapTransform:{value:new e},sheenRoughness:{value:1},sheenRoughnessMap:{value:null},sheenRoughnessMapTransform:{value:new e},transmission:{value:0},transmissionMap:{value:null},transmissionMapTransform:{value:new e},transmissionSamplerSize:{value:new t},transmissionSamplerMap:{value:null},thickness:{value:0},thicknessMap:{value:null},thicknessMapTransform:{value:new e},attenuationDistance:{value:0},attenuationColor:{value:new n(0)},specularColor:{value:new n(1,1,1)},specularColorMap:{value:null},specularColorMapTransform:{value:new e},specularIntensity:{value:1},specularIntensityMap:{value:null},specularIntensityMapTransform:{value:new e},anisotropyVector:{value:new t},anisotropyMap:{value:null},anisotropyMapTransform:{value:new e}}]),vertexShader:Gn.meshphysical_vert,fragmentShader:Gn.meshphysical_frag};const Wn={r:0,b:0,g:0},zn=new u,kn=new f;function Xn(e,t,i,r,u,f){const v=new n(0);let E,S,M=!0===u?0:1,T=null,x=0,A=null;function R(e){let n=!0===e.isScene?e.background:null;if(n&&n.isTexture){const i=e.backgroundBlurriness>0;n=t.get(n,i)}return n}function b(t,n){t.getRGB(Wn,g(e)),i.buffers.color.setClear(Wn.r,Wn.g,Wn.b,n,f)}return{getClearColor:function(){return v},setClearColor:function(e,t=1){v.set(e),M=t,b(v,M)},getClearAlpha:function(){return M},setClearAlpha:function(e){M=e,b(v,M)},render:function(t){let n=!1;const r=R(t);null===r?b(v,M):r&&r.isColor&&(b(r,1),n=!0);const a=e.xr.getEnvironmentBlendMode();"additive"===a?i.buffers.color.setClear(0,0,0,1,f):"alpha-blend"===a&&i.buffers.color.setClear(0,0,0,0,f),(e.autoClear||n)&&(i.buffers.depth.setTest(!0),i.buffers.depth.setMask(!0),i.buffers.color.setMask(!0),e.clear(e.autoClearColor,e.autoClearDepth,e.autoClearStencil))},addToRenderList:function(t,n){const i=R(n);i&&(i.isCubeTexture||i.mapping===a)?(void 0===S&&(S=new o(new s(1,1,1),new l({name:"BackgroundCubeMaterial",uniforms:d(Vn.backgroundCube.uniforms),vertexShader:Vn.backgroundCube.vertexShader,fragmentShader:Vn.backgroundCube.fragmentShader,side:c,depthTest:!1,depthWrite:!1,fog:!1,allowOverride:!1})),S.geometry.deleteAttribute("normal"),S.geometry.deleteAttribute("uv"),S.onBeforeRender=function(e,t,n){this.matrixWorld.copyPosition(n.matrixWorld)},Object.defineProperty(S.material,"envMap",{get:function(){return this.uniforms.envMap.value}}),r.update(S)),zn.copy(n.backgroundRotation),zn.x*=-1,zn.y*=-1,zn.z*=-1,i.isCubeTexture&&!1===i.isRenderTargetTexture&&(zn.y*=-1,zn.z*=-1),S.material.uniforms.envMap.value=i,S.material.uniforms.flipEnvMap.value=i.isCubeTexture&&!1===i.isRenderTargetTexture?-1:1,S.material.uniforms.backgroundBlurriness.value=n.backgroundBlurriness,S.material.uniforms.backgroundIntensity.value=n.backgroundIntensity,S.material.uniforms.backgroundRotation.value.setFromMatrix4(kn.makeRotationFromEuler(zn)),S.material.toneMapped=p.getTransfer(i.colorSpace)!==m,T===i&&x===i.version&&A===e.toneMapping||(S.material.needsUpdate=!0,T=i,x=i.version,A=e.toneMapping),S.layers.enableAll(),t.unshift(S,S.geometry,S.material,0,0,null)):i&&i.isTexture&&(void 0===E&&(E=new o(new h(2,2),new l({name:"BackgroundMaterial",uniforms:d(Vn.background.uniforms),vertexShader:Vn.background.vertexShader,fragmentShader:Vn.background.fragmentShader,side:_,depthTest:!1,depthWrite:!1,fog:!1,allowOverride:!1})),E.geometry.deleteAttribute("normal"),Object.defineProperty(E.material,"map",{get:function(){return this.uniforms.t2D.value}}),r.update(E)),E.material.uniforms.t2D.value=i,E.material.uniforms.backgroundIntensity.value=n.backgroundIntensity,E.material.toneMapped=p.getTransfer(i.colorSpace)!==m,!0===i.matrixAutoUpdate&&i.updateMatrix(),E.material.uniforms.uvTransform.value.copy(i.matrix),T===i&&x===i.version&&A===e.toneMapping||(E.material.needsUpdate=!0,T=i,x=i.version,A=e.toneMapping),E.layers.enableAll(),t.unshift(E,E.geometry,E.material,0,0,null))},dispose:function(){void 0!==S&&(S.geometry.dispose(),S.material.dispose(),S=void 0),void 0!==E&&(E.geometry.dispose(),E.material.dispose(),E=void 0)}}}function Yn(e,t){const n=e.getParameter(e.MAX_VERTEX_ATTRIBS),i={},r=c(null);let a=r,o=!1;function s(t){return e.bindVertexArray(t)}function l(t){return e.deleteVertexArray(t)}function c(e){const t=[],i=[],r=[];for(let e=0;e=0){const n=r[t];let i=o[t];if(void 0===i&&("instanceMatrix"===t&&e.instanceMatrix&&(i=e.instanceMatrix),"instanceColor"===t&&e.instanceColor&&(i=e.instanceColor)),void 0===n)return!0;if(n.attribute!==i)return!0;if(i&&n.data!==i.data)return!0;s++}}return a.attributesNum!==s||a.index!==i}(n,h,l,_),g&&function(e,t,n,i){const r={},o=t.attributes;let s=0;const l=n.getAttributes();for(const t in l){if(l[t].location>=0){let n=o[t];void 0===n&&("instanceMatrix"===t&&e.instanceMatrix&&(n=e.instanceMatrix),"instanceColor"===t&&e.instanceColor&&(n=e.instanceColor));const i={};i.attribute=n,n&&n.data&&(i.data=n.data),r[t]=i,s++}}a.attributes=r,a.attributesNum=s,a.index=i}(n,h,l,_),null!==_&&t.update(_,e.ELEMENT_ARRAY_BUFFER),(g||o)&&(o=!1,function(n,i,r,a){d();const o=a.attributes,s=r.getAttributes(),l=i.defaultAttributeValues;for(const i in s){const r=s[i];if(r.location>=0){let s=o[i];if(void 0===s&&("instanceMatrix"===i&&n.instanceMatrix&&(s=n.instanceMatrix),"instanceColor"===i&&n.instanceColor&&(s=n.instanceColor)),void 0!==s){const i=s.normalized,o=s.itemSize,l=t.get(s);if(void 0===l)continue;const c=l.buffer,d=l.type,p=l.bytesPerElement,h=d===e.INT||d===e.UNSIGNED_INT||s.gpuType===v;if(s.isInterleavedBufferAttribute){const t=s.data,l=t.stride,_=s.offset;if(t.isInstancedInterleavedBuffer){for(let e=0;e0&&e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).precision>0)return"highp";t="mediump"}return"mediump"===t&&e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).precision>0&&e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).precision>0?"mediump":"lowp"}let o=void 0!==n.precision?n.precision:"highp";const s=a(o);s!==o&&(E("WebGLRenderer:",o,"not supported, using",s,"instead."),o=s);return{isWebGL2:!0,getMaxAnisotropy:function(){if(void 0!==r)return r;if(!0===t.has("EXT_texture_filter_anisotropic")){const n=t.get("EXT_texture_filter_anisotropic");r=e.getParameter(n.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else r=0;return r},getMaxPrecision:a,textureFormatReadable:function(t){return t===x||i.convert(t)===e.getParameter(e.IMPLEMENTATION_COLOR_READ_FORMAT)},textureTypeReadable:function(n){const r=n===S&&(t.has("EXT_color_buffer_half_float")||t.has("EXT_color_buffer_float"));return!(n!==M&&i.convert(n)!==e.getParameter(e.IMPLEMENTATION_COLOR_READ_TYPE)&&n!==T&&!r)},precision:o,logarithmicDepthBuffer:!0===n.logarithmicDepthBuffer,reversedDepthBuffer:!0===n.reversedDepthBuffer&&t.has("EXT_clip_control"),maxTextures:e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextures:e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS),maxTextureSize:e.getParameter(e.MAX_TEXTURE_SIZE),maxCubemapSize:e.getParameter(e.MAX_CUBE_MAP_TEXTURE_SIZE),maxAttributes:e.getParameter(e.MAX_VERTEX_ATTRIBS),maxVertexUniforms:e.getParameter(e.MAX_VERTEX_UNIFORM_VECTORS),maxVaryings:e.getParameter(e.MAX_VARYING_VECTORS),maxFragmentUniforms:e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS),maxSamples:e.getParameter(e.MAX_SAMPLES),samples:e.getParameter(e.SAMPLES)}}function qn(t){const n=this;let i=null,r=0,a=!1,o=!1;const s=new A,l=new e,c={value:null,needsUpdate:!1};function d(e,t,i,r){const a=null!==e?e.length:0;let o=null;if(0!==a){if(o=c.value,!0!==r||null===o){const n=i+4*a,r=t.matrixWorldInverse;l.getNormalMatrix(r),(null===o||o.length0);n.numPlanes=r,n.numIntersection=0}();else{const e=o?0:r,t=4*e;let n=m.clippingState||null;c.value=n,n=d(u,s,t,l);for(let e=0;e!==t;++e)n[e]=i[e];m.clippingState=n,this.numIntersection=f?this.numPlanes:0,this.numPlanes+=e}}}const Zn=[.125,.215,.35,.446,.526,.582],$n=20,Qn=new P,Jn=new n;let ei=null,ti=0,ni=0,ii=!1;const ri=new r;class ai{constructor(e){this._renderer=e,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._sizeLods=[],this._sigmas=[],this._lodMeshes=[],this._backgroundBox=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._blurMaterial=null,this._ggxMaterial=null}fromScene(e,t=0,n=.1,i=100,r={}){const{size:a=256,position:o=ri}=r;ei=this._renderer.getRenderTarget(),ti=this._renderer.getActiveCubeFace(),ni=this._renderer.getActiveMipmapLevel(),ii=this._renderer.xr.enabled,this._renderer.xr.enabled=!1,this._setSize(a);const s=this._allocateTargets();return s.depthBuffer=!0,this._sceneToCubeUV(e,n,i,s,o),t>0&&this._blur(s,0,0,t),this._applyPMREM(s),this._cleanup(s),s}fromEquirectangular(e,t=null){return this._fromTexture(e,t)}fromCubemap(e,t=null){return this._fromTexture(e,t)}compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=ci(),this._compileMaterial(this._cubemapMaterial))}compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=li(),this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose(),null!==this._backgroundBox&&(this._backgroundBox.geometry.dispose(),this._backgroundBox.material.dispose())}_setSize(e){this._lodMax=Math.floor(Math.log2(e)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._ggxMaterial&&this._ggxMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let e=0;ee-4?l=Zn[s-e+4-1]:0===s&&(l=0),n.push(l);const c=1/(a-2),d=-c,u=1+c,f=[d,d,u,d,u,u,d,d,u,u,d,u],p=6,m=6,h=3,_=2,g=1,v=new Float32Array(h*m*p),E=new Float32Array(_*m*p),S=new Float32Array(g*m*p);for(let e=0;e2?0:-1,i=[t,n,0,t+2/3,n,0,t+2/3,n+1,0,t,n,0,t+2/3,n+1,0,t,n+1,0];v.set(i,h*m*e),E.set(f,_*m*e);const r=[e,e,e,e,e,e];S.set(r,g*m*e)}const M=new C;M.setAttribute("position",new y(v,h)),M.setAttribute("uv",new y(E,_)),M.setAttribute("faceIndex",new y(S,g)),i.push(new o(M,null)),r>4&&r--}return{lodMeshes:i,sizeLods:t,sigmas:n}}(i)),this._blurMaterial=function(e,t,n){const i=new Float32Array($n),a=new r(0,1,0),o=new l({name:"SphericalGaussianBlur",defines:{n:$n,CUBEUV_TEXEL_WIDTH:1/t,CUBEUV_TEXEL_HEIGHT:1/n,CUBEUV_MAX_MIP:`${e}.0`},uniforms:{envMap:{value:null},samples:{value:1},weights:{value:i},latitudinal:{value:!1},dTheta:{value:0},mipInt:{value:0},poleAxis:{value:a}},vertexShader:di(),fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform int samples;\n\t\t\tuniform float weights[ n ];\n\t\t\tuniform bool latitudinal;\n\t\t\tuniform float dTheta;\n\t\t\tuniform float mipInt;\n\t\t\tuniform vec3 poleAxis;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include \n\n\t\t\tvec3 getSample( float theta, vec3 axis ) {\n\n\t\t\t\tfloat cosTheta = cos( theta );\n\t\t\t\t// Rodrigues' axis-angle rotation\n\t\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross( axis, vOutputDirection ) * sin( theta )\n\t\t\t\t\t+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );\n\n\t\t\t\treturn bilinearCubeUV( envMap, sampleDirection, mipInt );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );\n\n\t\t\t\tif ( all( equal( axis, vec3( 0.0 ) ) ) ) {\n\n\t\t\t\t\taxis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );\n\n\t\t\t\t}\n\n\t\t\t\taxis = normalize( axis );\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );\n\n\t\t\t\tfor ( int i = 1; i < n; i++ ) {\n\n\t\t\t\t\tif ( i >= samples ) {\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfloat theta = dTheta * float( i );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( theta, axis );\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t",blending:I,depthTest:!1,depthWrite:!1});return o}(i,e,t),this._ggxMaterial=function(e,t,n){const i=new l({name:"PMREMGGXConvolution",defines:{GGX_SAMPLES:256,CUBEUV_TEXEL_WIDTH:1/t,CUBEUV_TEXEL_HEIGHT:1/n,CUBEUV_MAX_MIP:`${e}.0`},uniforms:{envMap:{value:null},roughness:{value:0},mipInt:{value:0}},vertexShader:di(),fragmentShader:'\n\n\t\t\tprecision highp float;\n\t\t\tprecision highp int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform float roughness;\n\t\t\tuniform float mipInt;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include \n\n\t\t\t#define PI 3.14159265359\n\n\t\t\t// Van der Corput radical inverse\n\t\t\tfloat radicalInverse_VdC(uint bits) {\n\t\t\t\tbits = (bits << 16u) | (bits >> 16u);\n\t\t\t\tbits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);\n\t\t\t\tbits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);\n\t\t\t\tbits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);\n\t\t\t\tbits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);\n\t\t\t\treturn float(bits) * 2.3283064365386963e-10; // / 0x100000000\n\t\t\t}\n\n\t\t\t// Hammersley sequence\n\t\t\tvec2 hammersley(uint i, uint N) {\n\t\t\t\treturn vec2(float(i) / float(N), radicalInverse_VdC(i));\n\t\t\t}\n\n\t\t\t// GGX VNDF importance sampling (Eric Heitz 2018)\n\t\t\t// "Sampling the GGX Distribution of Visible Normals"\n\t\t\t// https://jcgt.org/published/0007/04/01/\n\t\t\tvec3 importanceSampleGGX_VNDF(vec2 Xi, vec3 V, float roughness) {\n\t\t\t\tfloat alpha = roughness * roughness;\n\n\t\t\t\t// Section 4.1: Orthonormal basis\n\t\t\t\tvec3 T1 = vec3(1.0, 0.0, 0.0);\n\t\t\t\tvec3 T2 = cross(V, T1);\n\n\t\t\t\t// Section 4.2: Parameterization of projected area\n\t\t\t\tfloat r = sqrt(Xi.x);\n\t\t\t\tfloat phi = 2.0 * PI * Xi.y;\n\t\t\t\tfloat t1 = r * cos(phi);\n\t\t\t\tfloat t2 = r * sin(phi);\n\t\t\t\tfloat s = 0.5 * (1.0 + V.z);\n\t\t\t\tt2 = (1.0 - s) * sqrt(1.0 - t1 * t1) + s * t2;\n\n\t\t\t\t// Section 4.3: Reprojection onto hemisphere\n\t\t\t\tvec3 Nh = t1 * T1 + t2 * T2 + sqrt(max(0.0, 1.0 - t1 * t1 - t2 * t2)) * V;\n\n\t\t\t\t// Section 3.4: Transform back to ellipsoid configuration\n\t\t\t\treturn normalize(vec3(alpha * Nh.x, alpha * Nh.y, max(0.0, Nh.z)));\n\t\t\t}\n\n\t\t\tvoid main() {\n\t\t\t\tvec3 N = normalize(vOutputDirection);\n\t\t\t\tvec3 V = N; // Assume view direction equals normal for pre-filtering\n\n\t\t\t\tvec3 prefilteredColor = vec3(0.0);\n\t\t\t\tfloat totalWeight = 0.0;\n\n\t\t\t\t// For very low roughness, just sample the environment directly\n\t\t\t\tif (roughness < 0.001) {\n\t\t\t\t\tgl_FragColor = vec4(bilinearCubeUV(envMap, N, mipInt), 1.0);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Tangent space basis for VNDF sampling\n\t\t\t\tvec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n\t\t\t\tvec3 tangent = normalize(cross(up, N));\n\t\t\t\tvec3 bitangent = cross(N, tangent);\n\n\t\t\t\tfor(uint i = 0u; i < uint(GGX_SAMPLES); i++) {\n\t\t\t\t\tvec2 Xi = hammersley(i, uint(GGX_SAMPLES));\n\n\t\t\t\t\t// For PMREM, V = N, so in tangent space V is always (0, 0, 1)\n\t\t\t\t\tvec3 H_tangent = importanceSampleGGX_VNDF(Xi, vec3(0.0, 0.0, 1.0), roughness);\n\n\t\t\t\t\t// Transform H back to world space\n\t\t\t\t\tvec3 H = normalize(tangent * H_tangent.x + bitangent * H_tangent.y + N * H_tangent.z);\n\t\t\t\t\tvec3 L = normalize(2.0 * dot(V, H) * H - V);\n\n\t\t\t\t\tfloat NdotL = max(dot(N, L), 0.0);\n\n\t\t\t\t\tif(NdotL > 0.0) {\n\t\t\t\t\t\t// Sample environment at fixed mip level\n\t\t\t\t\t\t// VNDF importance sampling handles the distribution filtering\n\t\t\t\t\t\tvec3 sampleColor = bilinearCubeUV(envMap, L, mipInt);\n\n\t\t\t\t\t\t// Weight by NdotL for the split-sum approximation\n\t\t\t\t\t\t// VNDF PDF naturally accounts for the visible microfacet distribution\n\t\t\t\t\t\tprefilteredColor += sampleColor * NdotL;\n\t\t\t\t\t\ttotalWeight += NdotL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (totalWeight > 0.0) {\n\t\t\t\t\tprefilteredColor = prefilteredColor / totalWeight;\n\t\t\t\t}\n\n\t\t\t\tgl_FragColor = vec4(prefilteredColor, 1.0);\n\t\t\t}\n\t\t',blending:I,depthTest:!1,depthWrite:!1});return i}(i,e,t)}return i}_compileMaterial(e){const t=new o(new C,e);this._renderer.compile(t,Qn)}_sceneToCubeUV(e,t,n,i,r){const a=new L(90,1,t,n),l=[1,-1,1,1,1,1],d=[1,1,1,-1,-1,-1],u=this._renderer,f=u.autoClear,p=u.toneMapping;u.getClearColor(Jn),u.toneMapping=U,u.autoClear=!1;u.state.buffers.depth.getReversed()&&(u.setRenderTarget(i),u.clearDepth(),u.setRenderTarget(null)),null===this._backgroundBox&&(this._backgroundBox=new o(new s,new D({name:"PMREM.Background",side:c,depthWrite:!1,depthTest:!1})));const m=this._backgroundBox,h=m.material;let _=!1;const g=e.background;g?g.isColor&&(h.color.copy(g),e.background=null,_=!0):(h.color.copy(Jn),_=!0);for(let t=0;t<6;t++){const n=t%3;0===n?(a.up.set(0,l[t],0),a.position.set(r.x,r.y,r.z),a.lookAt(r.x+d[t],r.y,r.z)):1===n?(a.up.set(0,0,l[t]),a.position.set(r.x,r.y,r.z),a.lookAt(r.x,r.y+d[t],r.z)):(a.up.set(0,l[t],0),a.position.set(r.x,r.y,r.z),a.lookAt(r.x,r.y,r.z+d[t]));const o=this._cubeSize;si(i,n*o,t>2?o:0,o,o),u.setRenderTarget(i),_&&u.render(m,a),u.render(e,a)}u.toneMapping=p,u.autoClear=f,e.background=g}_textureToCubeUV(e,t){const n=this._renderer,i=e.mapping===R||e.mapping===b;i?(null===this._cubemapMaterial&&(this._cubemapMaterial=ci()),this._cubemapMaterial.uniforms.flipEnvMap.value=!1===e.isRenderTargetTexture?-1:1):null===this._equirectMaterial&&(this._equirectMaterial=li());const r=i?this._cubemapMaterial:this._equirectMaterial,a=this._lodMeshes[0];a.material=r;r.uniforms.envMap.value=e;const o=this._cubeSize;si(t,0,0,3*o,2*o),n.setRenderTarget(t),n.render(a,Qn)}_applyPMREM(e){const t=this._renderer,n=t.autoClear;t.autoClear=!1;const i=this._lodMeshes.length;for(let t=1;tu-4?n-u+4:0),m=4*(this._cubeSize-f);s.envMap.value=e.texture,s.roughness.value=d,s.mipInt.value=u-t,si(r,p,m,3*f,2*f),i.setRenderTarget(r),i.render(o,Qn),s.envMap.value=r.texture,s.roughness.value=0,s.mipInt.value=u-n,si(e,p,m,3*f,2*f),i.setRenderTarget(e),i.render(o,Qn)}_blur(e,t,n,i,r){const a=this._pingPongRenderTarget;this._halfBlur(e,a,t,n,i,"latitudinal",r),this._halfBlur(a,e,n,n,i,"longitudinal",r)}_halfBlur(e,t,n,i,r,a,o){const s=this._renderer,l=this._blurMaterial;"latitudinal"!==a&&"longitudinal"!==a&&w("blur direction must be either latitudinal or longitudinal!");const c=this._lodMeshes[i];c.material=l;const d=l.uniforms,u=this._sizeLods[n]-1,f=isFinite(r)?Math.PI/(2*u):2*Math.PI/39,p=r/f,m=isFinite(r)?1+Math.floor(3*p):$n;m>$n&&E(`sigmaRadians, ${r}, is too large and will clip, as it requested ${m} samples when the maximum is set to 20`);const h=[];let _=0;for(let e=0;e<$n;++e){const t=e/p,n=Math.exp(-t*t/2);h.push(n),0===e?_+=n:eg-4?i-g+4:0),4*(this._cubeSize-v),3*v,2*v),s.setRenderTarget(t),s.render(c,Qn)}}function oi(e,t,n){const i=new N(e,t,n);return i.texture.mapping=a,i.texture.name="PMREM.cubeUv",i.scissorTest=!0,i}function si(e,t,n,i,r){e.viewport.set(t,n,i,r),e.scissor.set(t,n,i,r)}function li(){return new l({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:di(),fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tgl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );\n\n\t\t\t}\n\t\t",blending:I,depthTest:!1,depthWrite:!1})}function ci(){return new l({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:di(),fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tuniform float flipEnvMap;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );\n\n\t\t\t}\n\t\t",blending:I,depthTest:!1,depthWrite:!1})}function di(){return"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t"}function ui(e){let t=new WeakMap,n=new WeakMap,i=null;function r(e,t){return t===B?e.mapping=R:t===G&&(e.mapping=b),e}function a(e){const n=e.target;n.removeEventListener("dispose",a);const i=t.get(n);void 0!==i&&(t.delete(n),i.dispose())}function o(e){const t=e.target;t.removeEventListener("dispose",o);const i=n.get(t);void 0!==i&&(n.delete(t),i.dispose())}return{get:function(s,l=!1){return null==s?null:l?function(t){if(t&&t.isTexture){const r=t.mapping,a=r===B||r===G,s=r===R||r===b;if(a||s){let r=n.get(t);const l=void 0!==r?r.texture.pmremVersion:0;if(t.isRenderTargetTexture&&t.pmremVersion!==l)return null===i&&(i=new ai(e)),r=a?i.fromEquirectangular(t,r):i.fromCubemap(t,r),r.texture.pmremVersion=t.pmremVersion,n.set(t,r),r.texture;if(void 0!==r)return r.texture;{const l=t.image;return a&&l&&l.height>0||s&&l&&function(e){let t=0;const n=6;for(let i=0;i0){const o=new H(i.height);return o.fromEquirectangularTexture(e,n),t.set(n,o),n.addEventListener("dispose",a),r(o.texture,n.mapping)}return null}}}return n}(s)},dispose:function(){t=new WeakMap,n=new WeakMap,null!==i&&(i.dispose(),i=null)}}}function fi(e){const t={};function n(n){if(void 0!==t[n])return t[n];const i=e.getExtension(n);return t[n]=i,i}return{has:function(e){return null!==n(e)},init:function(){n("EXT_color_buffer_float"),n("WEBGL_clip_cull_distance"),n("OES_texture_float_linear"),n("EXT_color_buffer_half_float"),n("WEBGL_multisampled_render_to_texture"),n("WEBGL_render_shared_exponent")},get:function(e){const t=n(e);return null===t&&V("WebGLRenderer: "+e+" extension not supported."),t}}}function pi(e,t,n,i){const r={},a=new WeakMap;function o(e){const s=e.target;null!==s.index&&t.remove(s.index);for(const e in s.attributes)t.remove(s.attributes[e]);s.removeEventListener("dispose",o),delete r[s.id];const l=a.get(s);l&&(t.remove(l),a.delete(s)),i.releaseStatesOfGeometry(s),!0===s.isInstancedBufferGeometry&&delete s._maxInstanceCount,n.memory.geometries--}function s(e){const n=[],i=e.index,r=e.attributes.position;let o=0;if(null!==i){const e=i.array;o=i.version;for(let t=0,i=e.length;tn.maxTextureSize&&(M=Math.ceil(S/n.maxTextureSize),S=n.maxTextureSize);const x=new Float32Array(S*M*4*u),A=new Y(x,S,M,u);A.type=T,A.needsUpdate=!0;const R=4*E;for(let C=0;C\n\t\t\t#include \n\n\t\t\tvoid main() {\n\t\t\t\tgl_FragColor = texture2D( tDiffuse, vUv );\n\n\t\t\t\t#ifdef LINEAR_TONE_MAPPING\n\t\t\t\t\tgl_FragColor.rgb = LinearToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( REINHARD_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = ReinhardToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( CINEON_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = CineonToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( ACES_FILMIC_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = ACESFilmicToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( AGX_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = AgXToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( NEUTRAL_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = NeutralToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( CUSTOM_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = CustomToneMapping( gl_FragColor.rgb );\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef SRGB_TRANSFER\n\t\t\t\t\tgl_FragColor = sRGBTransferOETF( gl_FragColor );\n\t\t\t\t#endif\n\t\t\t}",depthTest:!1,depthWrite:!1}),d=new o(l,c),u=new P(-1,1,1,-1,0,1);let f,h=null,_=null,g=!1,v=null,E=[],M=!1;this.setSize=function(e,t){a.setSize(e,t),s.setSize(e,t);for(let n=0;n0&&!0===E[0].isRenderPass;const t=a.width,n=a.height;for(let e=0;e0)return e;const r=t*n;let a=Ri[r];if(void 0===a&&(a=new Float32Array(r),Ri[r]=a),0!==t){i.toArray(a,0);for(let i=1,r=0;i!==t;++i)r+=n,e[i].toArray(a,r)}return a}function Di(e,t){if(e.length!==t.length)return!1;for(let n=0,i=e.length;n0&&(this.seq=i.concat(r))}setValue(e,t,n,i){const r=this.map[t];void 0!==r&&r.setValue(e,n,i)}setOptional(e,t,n){const i=t[n];void 0!==i&&this.setValue(e,n,i)}static upload(e,t,n,i){for(let r=0,a=t.length;r!==a;++r){const a=t[r],o=n[a.id];!1!==o.needsUpdate&&a.setValue(e,o.value,i)}}static seqWithValue(e,t){const n=[];for(let i=0,r=e.length;i!==r;++i){const r=e[i];r.id in t&&n.push(r)}return n}}function Rr(e,t,n){const i=e.createShader(t);return e.shaderSource(i,n),e.compileShader(i),i}let br=0;const Cr=new e;function Pr(e,t,n){const i=e.getShaderParameter(t,e.COMPILE_STATUS),r=(e.getShaderInfoLog(t)||"").trim();if(i&&""===r)return"";const a=/ERROR: 0:(\d+)/.exec(r);if(a){const i=parseInt(a[1]);return n.toUpperCase()+"\n\n"+r+"\n\n"+function(e,t){const n=e.split("\n"),i=[],r=Math.max(t-6,0),a=Math.min(t+6,n.length);for(let e=r;e":" "} ${r}: ${n[e]}`)}return i.join("\n")}(e.getShaderSource(t),i)}return r}function Lr(e,t){const n=function(e){p._getMatrix(Cr,p.workingColorSpace,e);const t=`mat3( ${Cr.elements.map(e=>e.toFixed(4))} )`;switch(p.getTransfer(e)){case me:return[t,"LinearTransferOETF"];case m:return[t,"sRGBTransferOETF"];default:return E("WebGLProgram: Unsupported color space: ",e),[t,"LinearTransferOETF"]}}(t);return[`vec4 ${e}( vec4 value ) {`,`\treturn ${n[1]}( vec4( value.rgb * ${n[0]}, value.a ) );`,"}"].join("\n")}const Ur={[te]:"Linear",[ee]:"Reinhard",[J]:"Cineon",[Q]:"ACESFilmic",[$]:"AgX",[Z]:"Neutral",[q]:"Custom"};function Dr(e,t){const n=Ur[t];return void 0===n?(E("WebGLProgram: Unsupported toneMapping:",t),"vec3 "+e+"( vec3 color ) { return LinearToneMapping( color ); }"):"vec3 "+e+"( vec3 color ) { return "+n+"ToneMapping( color ); }"}const wr=new r;function Ir(){p.getLuminanceCoefficients(wr);return["float luminance( const in vec3 rgb ) {",`\tconst vec3 weights = vec3( ${wr.x.toFixed(4)}, ${wr.y.toFixed(4)}, ${wr.z.toFixed(4)} );`,"\treturn dot( weights, rgb );","}"].join("\n")}function Nr(e){return""!==e}function yr(e,t){const n=t.numSpotLightShadows+t.numSpotLightMaps-t.numSpotLightShadowsWithMaps;return e.replace(/NUM_DIR_LIGHTS/g,t.numDirLights).replace(/NUM_SPOT_LIGHTS/g,t.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g,t.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g,n).replace(/NUM_RECT_AREA_LIGHTS/g,t.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g,t.numPointLights).replace(/NUM_HEMI_LIGHTS/g,t.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g,t.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g,t.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g,t.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g,t.numPointLightShadows)}function Fr(e,t){return e.replace(/NUM_CLIPPING_PLANES/g,t.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g,t.numClippingPlanes-t.numClipIntersection)}const Or=/^[ \t]*#include +<([\w\d./]+)>/gm;function Br(e){return e.replace(Or,Hr)}const Gr=new Map;function Hr(e,t){let n=Gn[t];if(void 0===n){const e=Gr.get(t);if(void 0===e)throw new Error("Can not resolve #include <"+t+">");n=Gn[e],E('WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.',t,e)}return Br(n)}const Vr=/#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;function Wr(e){return e.replace(Vr,zr)}function zr(e,t,n,i){let r="";for(let e=parseInt(t);e0&&(_+="\n"),g=["#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,m].filter(Nr).join("\n"),g.length>0&&(g+="\n")):(_=[kr(n),"#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,m,n.extensionClipCullDistance?"#define USE_CLIP_DISTANCE":"",n.batching?"#define USE_BATCHING":"",n.batchingColor?"#define USE_BATCHING_COLOR":"",n.instancing?"#define USE_INSTANCING":"",n.instancingColor?"#define USE_INSTANCING_COLOR":"",n.instancingMorph?"#define USE_INSTANCING_MORPH":"",n.useFog&&n.fog?"#define USE_FOG":"",n.useFog&&n.fogExp2?"#define FOG_EXP2":"",n.map?"#define USE_MAP":"",n.envMap?"#define USE_ENVMAP":"",n.envMap?"#define "+d:"",n.lightMap?"#define USE_LIGHTMAP":"",n.aoMap?"#define USE_AOMAP":"",n.bumpMap?"#define USE_BUMPMAP":"",n.normalMap?"#define USE_NORMALMAP":"",n.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",n.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",n.displacementMap?"#define USE_DISPLACEMENTMAP":"",n.emissiveMap?"#define USE_EMISSIVEMAP":"",n.anisotropy?"#define USE_ANISOTROPY":"",n.anisotropyMap?"#define USE_ANISOTROPYMAP":"",n.clearcoatMap?"#define USE_CLEARCOATMAP":"",n.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",n.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",n.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",n.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",n.specularMap?"#define USE_SPECULARMAP":"",n.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",n.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",n.roughnessMap?"#define USE_ROUGHNESSMAP":"",n.metalnessMap?"#define USE_METALNESSMAP":"",n.alphaMap?"#define USE_ALPHAMAP":"",n.alphaHash?"#define USE_ALPHAHASH":"",n.transmission?"#define USE_TRANSMISSION":"",n.transmissionMap?"#define USE_TRANSMISSIONMAP":"",n.thicknessMap?"#define USE_THICKNESSMAP":"",n.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",n.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",n.mapUv?"#define MAP_UV "+n.mapUv:"",n.alphaMapUv?"#define ALPHAMAP_UV "+n.alphaMapUv:"",n.lightMapUv?"#define LIGHTMAP_UV "+n.lightMapUv:"",n.aoMapUv?"#define AOMAP_UV "+n.aoMapUv:"",n.emissiveMapUv?"#define EMISSIVEMAP_UV "+n.emissiveMapUv:"",n.bumpMapUv?"#define BUMPMAP_UV "+n.bumpMapUv:"",n.normalMapUv?"#define NORMALMAP_UV "+n.normalMapUv:"",n.displacementMapUv?"#define DISPLACEMENTMAP_UV "+n.displacementMapUv:"",n.metalnessMapUv?"#define METALNESSMAP_UV "+n.metalnessMapUv:"",n.roughnessMapUv?"#define ROUGHNESSMAP_UV "+n.roughnessMapUv:"",n.anisotropyMapUv?"#define ANISOTROPYMAP_UV "+n.anisotropyMapUv:"",n.clearcoatMapUv?"#define CLEARCOATMAP_UV "+n.clearcoatMapUv:"",n.clearcoatNormalMapUv?"#define CLEARCOAT_NORMALMAP_UV "+n.clearcoatNormalMapUv:"",n.clearcoatRoughnessMapUv?"#define CLEARCOAT_ROUGHNESSMAP_UV "+n.clearcoatRoughnessMapUv:"",n.iridescenceMapUv?"#define IRIDESCENCEMAP_UV "+n.iridescenceMapUv:"",n.iridescenceThicknessMapUv?"#define IRIDESCENCE_THICKNESSMAP_UV "+n.iridescenceThicknessMapUv:"",n.sheenColorMapUv?"#define SHEEN_COLORMAP_UV "+n.sheenColorMapUv:"",n.sheenRoughnessMapUv?"#define SHEEN_ROUGHNESSMAP_UV "+n.sheenRoughnessMapUv:"",n.specularMapUv?"#define SPECULARMAP_UV "+n.specularMapUv:"",n.specularColorMapUv?"#define SPECULAR_COLORMAP_UV "+n.specularColorMapUv:"",n.specularIntensityMapUv?"#define SPECULAR_INTENSITYMAP_UV "+n.specularIntensityMapUv:"",n.transmissionMapUv?"#define TRANSMISSIONMAP_UV "+n.transmissionMapUv:"",n.thicknessMapUv?"#define THICKNESSMAP_UV "+n.thicknessMapUv:"",n.vertexTangents&&!1===n.flatShading?"#define USE_TANGENT":"",n.vertexColors?"#define USE_COLOR":"",n.vertexAlphas?"#define USE_COLOR_ALPHA":"",n.vertexUv1s?"#define USE_UV1":"",n.vertexUv2s?"#define USE_UV2":"",n.vertexUv3s?"#define USE_UV3":"",n.pointsUvs?"#define USE_POINTS_UV":"",n.flatShading?"#define FLAT_SHADED":"",n.skinning?"#define USE_SKINNING":"",n.morphTargets?"#define USE_MORPHTARGETS":"",n.morphNormals&&!1===n.flatShading?"#define USE_MORPHNORMALS":"",n.morphColors?"#define USE_MORPHCOLORS":"",n.morphTargetsCount>0?"#define MORPHTARGETS_TEXTURE_STRIDE "+n.morphTextureStride:"",n.morphTargetsCount>0?"#define MORPHTARGETS_COUNT "+n.morphTargetsCount:"",n.doubleSided?"#define DOUBLE_SIDED":"",n.flipSided?"#define FLIP_SIDED":"",n.shadowMapEnabled?"#define USE_SHADOWMAP":"",n.shadowMapEnabled?"#define "+l:"",n.sizeAttenuation?"#define USE_SIZEATTENUATION":"",n.numLightProbes>0?"#define USE_LIGHT_PROBES":"",n.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",n.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 modelMatrix;","uniform mat4 modelViewMatrix;","uniform mat4 projectionMatrix;","uniform mat4 viewMatrix;","uniform mat3 normalMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;","#ifdef USE_INSTANCING","\tattribute mat4 instanceMatrix;","#endif","#ifdef USE_INSTANCING_COLOR","\tattribute vec3 instanceColor;","#endif","#ifdef USE_INSTANCING_MORPH","\tuniform sampler2D morphTexture;","#endif","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_UV1","\tattribute vec2 uv1;","#endif","#ifdef USE_UV2","\tattribute vec2 uv2;","#endif","#ifdef USE_UV3","\tattribute vec2 uv3;","#endif","#ifdef USE_TANGENT","\tattribute vec4 tangent;","#endif","#if defined( USE_COLOR_ALPHA )","\tattribute vec4 color;","#elif defined( USE_COLOR )","\tattribute vec3 color;","#endif","#ifdef USE_SKINNING","\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(Nr).join("\n"),g=[kr(n),"#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,m,n.useFog&&n.fog?"#define USE_FOG":"",n.useFog&&n.fogExp2?"#define FOG_EXP2":"",n.alphaToCoverage?"#define ALPHA_TO_COVERAGE":"",n.map?"#define USE_MAP":"",n.matcap?"#define USE_MATCAP":"",n.envMap?"#define USE_ENVMAP":"",n.envMap?"#define "+c:"",n.envMap?"#define "+d:"",n.envMap?"#define "+u:"",f?"#define CUBEUV_TEXEL_WIDTH "+f.texelWidth:"",f?"#define CUBEUV_TEXEL_HEIGHT "+f.texelHeight:"",f?"#define CUBEUV_MAX_MIP "+f.maxMip+".0":"",n.lightMap?"#define USE_LIGHTMAP":"",n.aoMap?"#define USE_AOMAP":"",n.bumpMap?"#define USE_BUMPMAP":"",n.normalMap?"#define USE_NORMALMAP":"",n.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",n.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",n.emissiveMap?"#define USE_EMISSIVEMAP":"",n.anisotropy?"#define USE_ANISOTROPY":"",n.anisotropyMap?"#define USE_ANISOTROPYMAP":"",n.clearcoat?"#define USE_CLEARCOAT":"",n.clearcoatMap?"#define USE_CLEARCOATMAP":"",n.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",n.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",n.dispersion?"#define USE_DISPERSION":"",n.iridescence?"#define USE_IRIDESCENCE":"",n.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",n.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",n.specularMap?"#define USE_SPECULARMAP":"",n.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",n.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",n.roughnessMap?"#define USE_ROUGHNESSMAP":"",n.metalnessMap?"#define USE_METALNESSMAP":"",n.alphaMap?"#define USE_ALPHAMAP":"",n.alphaTest?"#define USE_ALPHATEST":"",n.alphaHash?"#define USE_ALPHAHASH":"",n.sheen?"#define USE_SHEEN":"",n.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",n.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",n.transmission?"#define USE_TRANSMISSION":"",n.transmissionMap?"#define USE_TRANSMISSIONMAP":"",n.thicknessMap?"#define USE_THICKNESSMAP":"",n.vertexTangents&&!1===n.flatShading?"#define USE_TANGENT":"",n.vertexColors||n.instancingColor?"#define USE_COLOR":"",n.vertexAlphas||n.batchingColor?"#define USE_COLOR_ALPHA":"",n.vertexUv1s?"#define USE_UV1":"",n.vertexUv2s?"#define USE_UV2":"",n.vertexUv3s?"#define USE_UV3":"",n.pointsUvs?"#define USE_POINTS_UV":"",n.gradientMap?"#define USE_GRADIENTMAP":"",n.flatShading?"#define FLAT_SHADED":"",n.doubleSided?"#define DOUBLE_SIDED":"",n.flipSided?"#define FLIP_SIDED":"",n.shadowMapEnabled?"#define USE_SHADOWMAP":"",n.shadowMapEnabled?"#define "+l:"",n.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",n.numLightProbes>0?"#define USE_LIGHT_PROBES":"",n.decodeVideoTexture?"#define DECODE_VIDEO_TEXTURE":"",n.decodeVideoTextureEmissive?"#define DECODE_VIDEO_TEXTURE_EMISSIVE":"",n.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",n.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;",n.toneMapping!==U?"#define TONE_MAPPING":"",n.toneMapping!==U?Gn.tonemapping_pars_fragment:"",n.toneMapping!==U?Dr("toneMapping",n.toneMapping):"",n.dithering?"#define DITHERING":"",n.opaque?"#define OPAQUE":"",Gn.colorspace_pars_fragment,Lr("linearToOutputTexel",n.outputColorSpace),Ir(),n.useDepthPacking?"#define DEPTH_PACKING "+n.depthPacking:"","\n"].filter(Nr).join("\n")),o=Br(o),o=yr(o,n),o=Fr(o,n),s=Br(s),s=yr(s,n),s=Fr(s,n),o=Wr(o),s=Wr(s),!0!==n.isRawShaderMaterial&&(v="#version 300 es\n",_=[p,"#define attribute in","#define varying out","#define texture2D texture"].join("\n")+"\n"+_,g=["#define varying in",n.glslVersion===le?"":"layout(location = 0) out highp vec4 pc_fragColor;",n.glslVersion===le?"":"#define gl_FragColor pc_fragColor","#define gl_FragDepthEXT gl_FragDepth","#define texture2D texture","#define textureCube texture","#define texture2DProj textureProj","#define texture2DLodEXT textureLod","#define texture2DProjLodEXT textureProjLod","#define textureCubeLodEXT textureLod","#define texture2DGradEXT textureGrad","#define texture2DProjGradEXT textureProjGrad","#define textureCubeGradEXT textureGrad"].join("\n")+"\n"+g);const S=v+_+o,M=v+g+s,T=Rr(r,r.VERTEX_SHADER,S),x=Rr(r,r.FRAGMENT_SHADER,M);function A(t){if(e.debug.checkShaderErrors){const n=r.getProgramInfoLog(h)||"",i=r.getShaderInfoLog(T)||"",a=r.getShaderInfoLog(x)||"",o=n.trim(),s=i.trim(),l=a.trim();let c=!0,d=!0;if(!1===r.getProgramParameter(h,r.LINK_STATUS))if(c=!1,"function"==typeof e.debug.onShaderError)e.debug.onShaderError(r,h,T,x);else{const e=Pr(r,T,"vertex"),n=Pr(r,x,"fragment");w("THREE.WebGLProgram: Shader Error "+r.getError()+" - VALIDATE_STATUS "+r.getProgramParameter(h,r.VALIDATE_STATUS)+"\n\nMaterial Name: "+t.name+"\nMaterial Type: "+t.type+"\n\nProgram Info Log: "+o+"\n"+e+"\n"+n)}else""!==o?E("WebGLProgram: Program Info Log:",o):""!==s&&""!==l||(d=!1);d&&(t.diagnostics={runnable:c,programLog:o,vertexShader:{log:s,prefix:_},fragmentShader:{log:l,prefix:g}})}r.deleteShader(T),r.deleteShader(x),R=new Ar(r,h),b=function(e,t){const n={},i=e.getProgramParameter(t,e.ACTIVE_ATTRIBUTES);for(let r=0;r0,J=r.clearcoat>0,ee=r.dispersion>0,te=r.iridescence>0,ne=r.sheen>0,ie=r.transmission>0,re=Q&&!!r.anisotropyMap,ae=J&&!!r.clearcoatMap,oe=J&&!!r.clearcoatNormalMap,se=J&&!!r.clearcoatRoughnessMap,le=te&&!!r.iridescenceMap,ce=te&&!!r.iridescenceThicknessMap,de=ne&&!!r.sheenColorMap,ue=ne&&!!r.sheenRoughnessMap,fe=!!r.specularMap,pe=!!r.specularColorMap,me=!!r.specularIntensityMap,he=ie&&!!r.transmissionMap,Se=ie&&!!r.thicknessMap,Me=!!r.gradientMap,Te=!!r.alphaMap,xe=r.alphaTest>0,Ae=!!r.alphaHash,Re=!!r.extensions;let be=U;r.toneMapped&&(null!==O&&!0!==O.isXRRenderTarget||(be=e.toneMapping));const Ce={shaderID:C,shaderType:r.type,shaderName:r.name,vertexShader:D,fragmentShader:w,defines:r.defines,customVertexShaderID:I,customFragmentShaderID:N,isRawShaderMaterial:!0===r.isRawShaderMaterial,glslVersion:r.glslVersion,precision:_,batching:H,batchingColor:H&&null!==S._colorsTexture,instancing:G,instancingColor:G&&null!==S.instanceColor,instancingMorph:G&&null!==S.morphTexture,outputColorSpace:null===O?e.outputColorSpace:!0===O.isXRRenderTarget?O.texture.colorSpace:F,alphaToCoverage:!!r.alphaToCoverage,map:V,matcap:W,envMap:z,envMapMode:z&&R.mapping,envMapCubeUVHeight:b,aoMap:k,lightMap:X,bumpMap:Y,normalMap:K,displacementMap:j,emissiveMap:q,normalMapObjectSpace:K&&r.normalMapType===Ee,normalMapTangentSpace:K&&r.normalMapType===ve,metalnessMap:Z,roughnessMap:$,anisotropy:Q,anisotropyMap:re,clearcoat:J,clearcoatMap:ae,clearcoatNormalMap:oe,clearcoatRoughnessMap:se,dispersion:ee,iridescence:te,iridescenceMap:le,iridescenceThicknessMap:ce,sheen:ne,sheenColorMap:de,sheenRoughnessMap:ue,specularMap:fe,specularColorMap:pe,specularIntensityMap:me,transmission:ie,transmissionMap:he,thicknessMap:Se,gradientMap:Me,opaque:!1===r.transparent&&r.blending===ge&&!1===r.alphaToCoverage,alphaMap:Te,alphaTest:xe,alphaHash:Ae,combine:r.combine,mapUv:V&&v(r.map.channel),aoMapUv:k&&v(r.aoMap.channel),lightMapUv:X&&v(r.lightMap.channel),bumpMapUv:Y&&v(r.bumpMap.channel),normalMapUv:K&&v(r.normalMap.channel),displacementMapUv:j&&v(r.displacementMap.channel),emissiveMapUv:q&&v(r.emissiveMap.channel),metalnessMapUv:Z&&v(r.metalnessMap.channel),roughnessMapUv:$&&v(r.roughnessMap.channel),anisotropyMapUv:re&&v(r.anisotropyMap.channel),clearcoatMapUv:ae&&v(r.clearcoatMap.channel),clearcoatNormalMapUv:oe&&v(r.clearcoatNormalMap.channel),clearcoatRoughnessMapUv:se&&v(r.clearcoatRoughnessMap.channel),iridescenceMapUv:le&&v(r.iridescenceMap.channel),iridescenceThicknessMapUv:ce&&v(r.iridescenceThicknessMap.channel),sheenColorMapUv:de&&v(r.sheenColorMap.channel),sheenRoughnessMapUv:ue&&v(r.sheenRoughnessMap.channel),specularMapUv:fe&&v(r.specularMap.channel),specularColorMapUv:pe&&v(r.specularColorMap.channel),specularIntensityMapUv:me&&v(r.specularIntensityMap.channel),transmissionMapUv:he&&v(r.transmissionMap.channel),thicknessMapUv:Se&&v(r.thicknessMap.channel),alphaMapUv:Te&&v(r.alphaMap.channel),vertexTangents:!!T.attributes.tangent&&(K||Q),vertexColors:r.vertexColors,vertexAlphas:!0===r.vertexColors&&!!T.attributes.color&&4===T.attributes.color.itemSize,pointsUvs:!0===S.isPoints&&!!T.attributes.uv&&(V||Te),fog:!!M,useFog:!0===r.fog,fogExp2:!!M&&M.isFogExp2,flatShading:!1===r.wireframe&&(!0===r.flatShading||void 0===T.attributes.normal&&!1===K&&(r.isMeshLambertMaterial||r.isMeshPhongMaterial||r.isMeshStandardMaterial||r.isMeshPhysicalMaterial)),sizeAttenuation:!0===r.sizeAttenuation,logarithmicDepthBuffer:h,reversedDepthBuffer:B,skinning:!0===S.isSkinnedMesh,morphTargets:void 0!==T.morphAttributes.position,morphNormals:void 0!==T.morphAttributes.normal,morphColors:void 0!==T.morphAttributes.color,morphTargetsCount:L,morphTextureStride:y,numDirLights:s.directional.length,numPointLights:s.point.length,numSpotLights:s.spot.length,numSpotLightMaps:s.spotLightMap.length,numRectAreaLights:s.rectArea.length,numHemiLights:s.hemi.length,numDirLightShadows:s.directionalShadowMap.length,numPointLightShadows:s.pointShadowMap.length,numSpotLightShadows:s.spotShadowMap.length,numSpotLightShadowsWithMaps:s.numSpotLightShadowsWithMaps,numLightProbes:s.numLightProbes,numClippingPlanes:o.numPlanes,numClipIntersection:o.numIntersection,dithering:r.dithering,shadowMapEnabled:e.shadowMap.enabled&&u.length>0,shadowMapType:e.shadowMap.type,toneMapping:be,decodeVideoTexture:V&&!0===r.map.isVideoTexture&&p.getTransfer(r.map.colorSpace)===m,decodeVideoTextureEmissive:q&&!0===r.emissiveMap.isVideoTexture&&p.getTransfer(r.emissiveMap.colorSpace)===m,premultipliedAlpha:r.premultipliedAlpha,doubleSided:r.side===_e,flipSided:r.side===c,useDepthPacking:r.depthPacking>=0,depthPacking:r.depthPacking||0,index0AttributeName:r.index0AttributeName,extensionClipCullDistance:Re&&!0===r.extensions.clipCullDistance&&n.has("WEBGL_clip_cull_distance"),extensionMultiDraw:(Re&&!0===r.extensions.multiDraw||H)&&n.has("WEBGL_multi_draw"),rendererExtensionParallelShaderCompile:n.has("KHR_parallel_shader_compile"),customProgramCacheKey:r.customProgramCacheKey()};return Ce.vertexUv1s=d.has(1),Ce.vertexUv2s=d.has(2),Ce.vertexUv3s=d.has(3),d.clear(),Ce},getProgramCacheKey:function(t){const n=[];if(t.shaderID?n.push(t.shaderID):(n.push(t.customVertexShaderID),n.push(t.customFragmentShaderID)),void 0!==t.defines)for(const e in t.defines)n.push(e),n.push(t.defines[e]);return!1===t.isRawShaderMaterial&&(!function(e,t){e.push(t.precision),e.push(t.outputColorSpace),e.push(t.envMapMode),e.push(t.envMapCubeUVHeight),e.push(t.mapUv),e.push(t.alphaMapUv),e.push(t.lightMapUv),e.push(t.aoMapUv),e.push(t.bumpMapUv),e.push(t.normalMapUv),e.push(t.displacementMapUv),e.push(t.emissiveMapUv),e.push(t.metalnessMapUv),e.push(t.roughnessMapUv),e.push(t.anisotropyMapUv),e.push(t.clearcoatMapUv),e.push(t.clearcoatNormalMapUv),e.push(t.clearcoatRoughnessMapUv),e.push(t.iridescenceMapUv),e.push(t.iridescenceThicknessMapUv),e.push(t.sheenColorMapUv),e.push(t.sheenRoughnessMapUv),e.push(t.specularMapUv),e.push(t.specularColorMapUv),e.push(t.specularIntensityMapUv),e.push(t.transmissionMapUv),e.push(t.thicknessMapUv),e.push(t.combine),e.push(t.fogExp2),e.push(t.sizeAttenuation),e.push(t.morphTargetsCount),e.push(t.morphAttributeCount),e.push(t.numDirLights),e.push(t.numPointLights),e.push(t.numSpotLights),e.push(t.numSpotLightMaps),e.push(t.numHemiLights),e.push(t.numRectAreaLights),e.push(t.numDirLightShadows),e.push(t.numPointLightShadows),e.push(t.numSpotLightShadows),e.push(t.numSpotLightShadowsWithMaps),e.push(t.numLightProbes),e.push(t.shadowMapType),e.push(t.toneMapping),e.push(t.numClippingPlanes),e.push(t.numClipIntersection),e.push(t.depthPacking)}(n,t),function(e,t){s.disableAll(),t.instancing&&s.enable(0);t.instancingColor&&s.enable(1);t.instancingMorph&&s.enable(2);t.matcap&&s.enable(3);t.envMap&&s.enable(4);t.normalMapObjectSpace&&s.enable(5);t.normalMapTangentSpace&&s.enable(6);t.clearcoat&&s.enable(7);t.iridescence&&s.enable(8);t.alphaTest&&s.enable(9);t.vertexColors&&s.enable(10);t.vertexAlphas&&s.enable(11);t.vertexUv1s&&s.enable(12);t.vertexUv2s&&s.enable(13);t.vertexUv3s&&s.enable(14);t.vertexTangents&&s.enable(15);t.anisotropy&&s.enable(16);t.alphaHash&&s.enable(17);t.batching&&s.enable(18);t.dispersion&&s.enable(19);t.batchingColor&&s.enable(20);t.gradientMap&&s.enable(21);e.push(s.mask),s.disableAll(),t.fog&&s.enable(0);t.useFog&&s.enable(1);t.flatShading&&s.enable(2);t.logarithmicDepthBuffer&&s.enable(3);t.reversedDepthBuffer&&s.enable(4);t.skinning&&s.enable(5);t.morphTargets&&s.enable(6);t.morphNormals&&s.enable(7);t.morphColors&&s.enable(8);t.premultipliedAlpha&&s.enable(9);t.shadowMapEnabled&&s.enable(10);t.doubleSided&&s.enable(11);t.flipSided&&s.enable(12);t.useDepthPacking&&s.enable(13);t.dithering&&s.enable(14);t.transmission&&s.enable(15);t.sheen&&s.enable(16);t.opaque&&s.enable(17);t.pointsUvs&&s.enable(18);t.decodeVideoTexture&&s.enable(19);t.decodeVideoTextureEmissive&&s.enable(20);t.alphaToCoverage&&s.enable(21);e.push(s.mask)}(n,t),n.push(e.outputColorSpace)),n.push(t.customProgramCacheKey),n.join()},getUniforms:function(e){const t=g[e.type];let n;if(t){const e=Vn[t];n=he.clone(e.uniforms)}else n=e.uniforms;return n},acquireProgram:function(t,n){let i=f.get(n);return void 0!==i?++i.usedTimes:(i=new qr(e,n,t,r),u.push(i),f.set(n,i)),i},releaseProgram:function(e){if(0===--e.usedTimes){const t=u.indexOf(e);u[t]=u[u.length-1],u.pop(),f.delete(e.cacheKey),e.destroy()}},releaseShaderCache:function(e){l.remove(e)},programs:u,dispose:function(){l.dispose()}}}function ea(){let e=new WeakMap;return{has:function(t){return e.has(t)},get:function(t){let n=e.get(t);return void 0===n&&(n={},e.set(t,n)),n},remove:function(t){e.delete(t)},update:function(t,n,i){e.get(t)[n]=i},dispose:function(){e=new WeakMap}}}function ta(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.material.id!==t.material.id?e.material.id-t.material.id:e.materialVariant!==t.materialVariant?e.materialVariant-t.materialVariant:e.z!==t.z?e.z-t.z:e.id-t.id}function na(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?t.z-e.z:e.id-t.id}function ia(){const e=[];let t=0;const n=[],i=[],r=[];function a(e){let t=0;return e.isInstancedMesh&&(t+=2),e.isSkinnedMesh&&(t+=1),t}function o(n,i,r,o,s,l){let c=e[t];return void 0===c?(c={id:n.id,object:n,geometry:i,material:r,materialVariant:a(n),groupOrder:o,renderOrder:n.renderOrder,z:s,group:l},e[t]=c):(c.id=n.id,c.object=n,c.geometry=i,c.material=r,c.materialVariant=a(n),c.groupOrder=o,c.renderOrder=n.renderOrder,c.z=s,c.group=l),t++,c}return{opaque:n,transmissive:i,transparent:r,init:function(){t=0,n.length=0,i.length=0,r.length=0},push:function(e,t,a,s,l,c){const d=o(e,t,a,s,l,c);a.transmission>0?i.push(d):!0===a.transparent?r.push(d):n.push(d)},unshift:function(e,t,a,s,l,c){const d=o(e,t,a,s,l,c);a.transmission>0?i.unshift(d):!0===a.transparent?r.unshift(d):n.unshift(d)},finish:function(){for(let n=t,i=e.length;n1&&n.sort(e||ta),i.length>1&&i.sort(t||na),r.length>1&&r.sort(t||na)}}}function ra(){let e=new WeakMap;return{get:function(t,n){const i=e.get(t);let r;return void 0===i?(r=new ia,e.set(t,[r])):n>=i.length?(r=new ia,i.push(r)):r=i[n],r},dispose:function(){e=new WeakMap}}}function aa(){const e={};return{get:function(t){if(void 0!==e[t.id])return e[t.id];let i;switch(t.type){case"DirectionalLight":i={direction:new r,color:new n};break;case"SpotLight":i={position:new r,direction:new r,color:new n,distance:0,coneCos:0,penumbraCos:0,decay:0};break;case"PointLight":i={position:new r,color:new n,distance:0,decay:0};break;case"HemisphereLight":i={direction:new r,skyColor:new n,groundColor:new n};break;case"RectAreaLight":i={color:new n,position:new r,halfWidth:new r,halfHeight:new r}}return e[t.id]=i,i}}}let oa=0;function sa(e,t){return(t.castShadow?2:0)-(e.castShadow?2:0)+(t.map?1:0)-(e.map?1:0)}function la(e){const n=new aa,i=function(){const e={};return{get:function(n){if(void 0!==e[n.id])return e[n.id];let i;switch(n.type){case"DirectionalLight":case"SpotLight":i={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new t};break;case"PointLight":i={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new t,shadowCameraNear:1,shadowCameraFar:1e3}}return e[n.id]=i,i}}}(),a={version:0,hash:{directionalLength:-1,pointLength:-1,spotLength:-1,rectAreaLength:-1,hemiLength:-1,numDirectionalShadows:-1,numPointShadows:-1,numSpotShadows:-1,numSpotMaps:-1,numLightProbes:-1},ambient:[0,0,0],probe:[],directional:[],directionalShadow:[],directionalShadowMap:[],directionalShadowMatrix:[],spot:[],spotLightMap:[],spotShadow:[],spotShadowMap:[],spotLightMatrix:[],rectArea:[],rectAreaLTC1:null,rectAreaLTC2:null,point:[],pointShadow:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],numSpotLightShadowsWithMaps:0,numLightProbes:0};for(let e=0;e<9;e++)a.probe.push(new r);const o=new r,s=new f,l=new f;return{setup:function(t){let r=0,o=0,s=0;for(let e=0;e<9;e++)a.probe[e].set(0,0,0);let l=0,c=0,d=0,u=0,f=0,p=0,m=0,h=0,_=0,g=0,v=0;t.sort(sa);for(let e=0,E=t.length;e0&&(!0===e.has("OES_texture_float_linear")?(a.rectAreaLTC1=Hn.LTC_FLOAT_1,a.rectAreaLTC2=Hn.LTC_FLOAT_2):(a.rectAreaLTC1=Hn.LTC_HALF_1,a.rectAreaLTC2=Hn.LTC_HALF_2)),a.ambient[0]=r,a.ambient[1]=o,a.ambient[2]=s;const E=a.hash;E.directionalLength===l&&E.pointLength===c&&E.spotLength===d&&E.rectAreaLength===u&&E.hemiLength===f&&E.numDirectionalShadows===p&&E.numPointShadows===m&&E.numSpotShadows===h&&E.numSpotMaps===_&&E.numLightProbes===v||(a.directional.length=l,a.spot.length=d,a.rectArea.length=u,a.point.length=c,a.hemi.length=f,a.directionalShadow.length=p,a.directionalShadowMap.length=p,a.pointShadow.length=m,a.pointShadowMap.length=m,a.spotShadow.length=h,a.spotShadowMap.length=h,a.directionalShadowMatrix.length=p,a.pointShadowMatrix.length=m,a.spotLightMatrix.length=h+_-g,a.spotLightMap.length=_,a.numSpotLightShadowsWithMaps=g,a.numLightProbes=v,E.directionalLength=l,E.pointLength=c,E.spotLength=d,E.rectAreaLength=u,E.hemiLength=f,E.numDirectionalShadows=p,E.numPointShadows=m,E.numSpotShadows=h,E.numSpotMaps=_,E.numLightProbes=v,a.version=oa++)},setupView:function(e,t){let n=0,i=0,r=0,c=0,d=0;const u=t.matrixWorldInverse;for(let t=0,f=e.length;t=r.length?(a=new ca(e),r.push(a)):a=r[i],a},dispose:function(){t=new WeakMap}}}const ua=[new r(1,0,0),new r(-1,0,0),new r(0,1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1)],fa=[new r(0,-1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1),new r(0,-1,0),new r(0,-1,0)],pa=new f,ma=new r,ha=new r;function _a(e,n,i){let r=new Te;const a=new t,s=new t,d=new X,u=new xe,f=new Ae,p={},m=i.maxTextureSize,h={[_]:c,[c]:_,[_e]:_e},g=new l({defines:{VSM_SAMPLES:8},uniforms:{shadow_pass:{value:null},resolution:{value:new t},radius:{value:4}},vertexShader:"void main() {\n\tgl_Position = vec4( position, 1.0 );\n}",fragmentShader:"uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ).rg;\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ).r;\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( max( 0.0, squared_mean - mean * mean ) );\n\tgl_FragColor = vec4( mean, std_dev, 0.0, 1.0 );\n}"}),v=g.clone();v.defines.HORIZONTAL_PASS=1;const M=new C;M.setAttribute("position",new y(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const x=new o(M,g),A=this;this.enabled=!1,this.autoUpdate=!0,this.needsUpdate=!1,this.type=de;let R=this.type;function b(t,i){const r=n.update(x);g.defines.VSM_SAMPLES!==t.blurSamples&&(g.defines.VSM_SAMPLES=t.blurSamples,v.defines.VSM_SAMPLES=t.blurSamples,g.needsUpdate=!0,v.needsUpdate=!0),null===t.mapPass&&(t.mapPass=new N(a.x,a.y,{format:Me,type:S})),g.uniforms.shadow_pass.value=t.map.depthTexture,g.uniforms.resolution.value=t.mapSize,g.uniforms.radius.value=t.radius,e.setRenderTarget(t.mapPass),e.clear(),e.renderBufferDirect(i,null,r,g,x,null),v.uniforms.shadow_pass.value=t.mapPass.texture,v.uniforms.resolution.value=t.mapSize,v.uniforms.radius.value=t.radius,e.setRenderTarget(t.map),e.clear(),e.renderBufferDirect(i,null,r,v,x,null)}function P(t,n,i,r){let a=null;const o=!0===i.isPointLight?t.customDistanceMaterial:t.customDepthMaterial;if(void 0!==o)a=o;else if(a=!0===i.isPointLight?f:u,e.localClippingEnabled&&!0===n.clipShadows&&Array.isArray(n.clippingPlanes)&&0!==n.clippingPlanes.length||n.displacementMap&&0!==n.displacementScale||n.alphaMap&&n.alphaTest>0||n.map&&n.alphaTest>0||!0===n.alphaToCoverage){const e=a.uuid,t=n.uuid;let i=p[e];void 0===i&&(i={},p[e]=i);let r=i[t];void 0===r&&(r=a.clone(),i[t]=r,n.addEventListener("dispose",U)),a=r}if(a.visible=n.visible,a.wireframe=n.wireframe,a.side=r===ce?null!==n.shadowSide?n.shadowSide:n.side:null!==n.shadowSide?n.shadowSide:h[n.side],a.alphaMap=n.alphaMap,a.alphaTest=!0===n.alphaToCoverage?.5:n.alphaTest,a.map=n.map,a.clipShadows=n.clipShadows,a.clippingPlanes=n.clippingPlanes,a.clipIntersection=n.clipIntersection,a.displacementMap=n.displacementMap,a.displacementScale=n.displacementScale,a.displacementBias=n.displacementBias,a.wireframeLinewidth=n.wireframeLinewidth,a.linewidth=n.linewidth,!0===i.isPointLight&&!0===a.isMeshDistanceMaterial){e.properties.get(a).light=i}return a}function L(t,i,a,o,s){if(!1===t.visible)return;if(t.layers.test(i.layers)&&(t.isMesh||t.isLine||t.isPoints)&&(t.castShadow||t.receiveShadow&&s===ce)&&(!t.frustumCulled||r.intersectsObject(t))){t.modelViewMatrix.multiplyMatrices(a.matrixWorldInverse,t.matrixWorld);const r=n.update(t),l=t.material;if(Array.isArray(l)){const n=r.groups;for(let c=0,d=n.length;ce.needsUpdate=!0):e.material.needsUpdate=!0)});for(let o=0,l=t.length;om||a.y>m)&&(a.x>m&&(s.x=Math.floor(m/p.x),a.x=s.x*p.x,c.mapSize.x=s.x),a.y>m&&(s.y=Math.floor(m/p.y),a.y=s.y*p.y,c.mapSize.y=s.y));const h=e.state.buffers.depth.getReversed();if(c.camera._reversedDepth=h,null===c.map||!0===f){if(null!==c.map&&(null!==c.map.depthTexture&&(c.map.depthTexture.dispose(),c.map.depthTexture=null),c.map.dispose()),this.type===ce){if(l.isPointLight){E("WebGLShadowMap: VSM shadow maps are not supported for PointLights. Use PCF or BasicShadowMap instead.");continue}c.map=new N(a.x,a.y,{format:Me,type:S,minFilter:O,magFilter:O,generateMipmaps:!1}),c.map.texture.name=l.name+".shadowMap",c.map.depthTexture=new oe(a.x,a.y,T),c.map.depthTexture.name=l.name+".shadowMapDepth",c.map.depthTexture.format=be,c.map.depthTexture.compareFunction=null,c.map.depthTexture.minFilter=Ce,c.map.depthTexture.magFilter=Ce}else l.isPointLight?(c.map=new H(a.x),c.map.depthTexture=new Pe(a.x,Le)):(c.map=new N(a.x,a.y),c.map.depthTexture=new oe(a.x,a.y,Le)),c.map.depthTexture.name=l.name+".shadowMap",c.map.depthTexture.format=be,this.type===de?(c.map.depthTexture.compareFunction=h?re:ae,c.map.depthTexture.minFilter=O,c.map.depthTexture.magFilter=O):(c.map.depthTexture.compareFunction=null,c.map.depthTexture.minFilter=Ce,c.map.depthTexture.magFilter=Ce);c.camera.updateProjectionMatrix()}const _=c.map.isWebGLCubeRenderTarget?6:1;for(let t=0;t<_;t++){if(c.map.isWebGLCubeRenderTarget)e.setRenderTarget(c.map,t),e.clear();else{0===t&&(e.setRenderTarget(c.map),e.clear());const n=c.getViewport(t);d.set(s.x*n.x,s.y*n.y,s.x*n.z,s.y*n.w),u.viewport(d)}if(l.isPointLight){const e=c.camera,n=c.matrix,i=l.distance||e.far;i!==e.far&&(e.far=i,e.updateProjectionMatrix()),ma.setFromMatrixPosition(l.matrixWorld),e.position.copy(ma),ha.copy(e.position),ha.add(ua[t]),e.up.copy(fa[t]),e.lookAt(ha),e.updateMatrixWorld(),n.makeTranslation(-ma.x,-ma.y,-ma.z),pa.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),c._frustum.setFromProjectionMatrix(pa,e.coordinateSystem,e.reversedDepth)}else c.updateMatrices(l);r=c.getFrustum(),L(n,i,c.camera,l,this.type)}!0!==c.isPointLightShadow&&this.type===ce&&b(c,i),c.needsUpdate=!1}R=this.type,A.needsUpdate=!1,e.setRenderTarget(o,l,c)}}const ga={[tt]:et,[Je]:Ze,[Qe]:qe,[Ue]:$e,[et]:tt,[Ze]:Je,[qe]:Qe,[$e]:Ue};function va(e,t){const i=new function(){let t=!1;const n=new X;let i=null;const r=new X(0,0,0,0);return{setMask:function(n){i===n||t||(e.colorMask(n,n,n,n),i=n)},setLocked:function(e){t=e},setClear:function(t,i,a,o,s){!0===s&&(t*=o,i*=o,a*=o),n.set(t,i,a,o),!1===r.equals(n)&&(e.clearColor(t,i,a,o),r.copy(n))},reset:function(){t=!1,i=null,r.set(-1,0,0,0)}}},r=new function(){let n=!1,i=!1,r=null,a=null,o=null;return{setReversed:function(e){if(i!==e){const n=t.get("EXT_clip_control");e?n.clipControlEXT(n.LOWER_LEFT_EXT,n.ZERO_TO_ONE_EXT):n.clipControlEXT(n.LOWER_LEFT_EXT,n.NEGATIVE_ONE_TO_ONE_EXT),i=e;const r=o;o=null,this.setClear(r)}},getReversed:function(){return i},setTest:function(t){t?k(e.DEPTH_TEST):Y(e.DEPTH_TEST)},setMask:function(t){r===t||n||(e.depthMask(t),r=t)},setFunc:function(t){if(i&&(t=ga[t]),a!==t){switch(t){case tt:e.depthFunc(e.NEVER);break;case et:e.depthFunc(e.ALWAYS);break;case Je:e.depthFunc(e.LESS);break;case Ue:e.depthFunc(e.LEQUAL);break;case Qe:e.depthFunc(e.EQUAL);break;case $e:e.depthFunc(e.GEQUAL);break;case Ze:e.depthFunc(e.GREATER);break;case qe:e.depthFunc(e.NOTEQUAL);break;default:e.depthFunc(e.LEQUAL)}a=t}},setLocked:function(e){n=e},setClear:function(t){o!==t&&(o=t,i&&(t=1-t),e.clearDepth(t))},reset:function(){n=!1,r=null,a=null,o=null,i=!1}}},a=new function(){let t=!1,n=null,i=null,r=null,a=null,o=null,s=null,l=null,c=null;return{setTest:function(n){t||(n?k(e.STENCIL_TEST):Y(e.STENCIL_TEST))},setMask:function(i){n===i||t||(e.stencilMask(i),n=i)},setFunc:function(t,n,o){i===t&&r===n&&a===o||(e.stencilFunc(t,n,o),i=t,r=n,a=o)},setOp:function(t,n,i){o===t&&s===n&&l===i||(e.stencilOp(t,n,i),o=t,s=n,l=i)},setLocked:function(e){t=e},setClear:function(t){c!==t&&(e.clearStencil(t),c=t)},reset:function(){t=!1,n=null,i=null,r=null,a=null,o=null,s=null,l=null,c=null}}},o=new WeakMap,s=new WeakMap;let l={},d={},u=new WeakMap,f=[],p=null,m=!1,h=null,_=null,g=null,v=null,E=null,S=null,M=null,T=new n(0,0,0),x=0,A=!1,R=null,b=null,C=null,P=null,L=null;const U=e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS);let D=!1,N=0;const y=e.getParameter(e.VERSION);-1!==y.indexOf("WebGL")?(N=parseFloat(/^WebGL (\d)/.exec(y)[1]),D=N>=1):-1!==y.indexOf("OpenGL ES")&&(N=parseFloat(/^OpenGL ES (\d)/.exec(y)[1]),D=N>=2);let F=null,O={};const B=e.getParameter(e.SCISSOR_BOX),G=e.getParameter(e.VIEWPORT),H=(new X).fromArray(B),V=(new X).fromArray(G);function W(t,n,i,r){const a=new Uint8Array(4),o=e.createTexture();e.bindTexture(t,o),e.texParameteri(t,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(t,e.TEXTURE_MAG_FILTER,e.NEAREST);for(let o=0;on||r.height>n)&&(i=n/Math.max(r.width,r.height)),i<1){if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof VideoFrame&&e instanceof VideoFrame){const n=Math.floor(i*r.width),a=Math.floor(i*r.height);void 0===f&&(f=g(n,a));const o=t?g(n,a):f;o.width=n,o.height=a;return o.getContext("2d").drawImage(e,0,0,n,a),E("WebGLRenderer: Texture has been resized from ("+r.width+"x"+r.height+") to ("+n+"x"+a+")."),o}return"data"in e&&E("WebGLRenderer: Image in DataTexture is too big ("+r.width+"x"+r.height+")."),e}return e}function S(e){return e.generateMipmaps}function A(t){e.generateMipmap(t)}function R(t){return t.isWebGLCubeRenderTarget?e.TEXTURE_CUBE_MAP:t.isWebGL3DRenderTarget?e.TEXTURE_3D:t.isWebGLArrayRenderTarget||t.isCompressedArrayTexture?e.TEXTURE_2D_ARRAY:e.TEXTURE_2D}function b(t,i,r,a,o=!1){if(null!==t){if(void 0!==e[t])return e[t];E("WebGLRenderer: Attempt to use non-existing WebGL internal format '"+t+"'")}let s=i;if(i===e.RED&&(r===e.FLOAT&&(s=e.R32F),r===e.HALF_FLOAT&&(s=e.R16F),r===e.UNSIGNED_BYTE&&(s=e.R8)),i===e.RED_INTEGER&&(r===e.UNSIGNED_BYTE&&(s=e.R8UI),r===e.UNSIGNED_SHORT&&(s=e.R16UI),r===e.UNSIGNED_INT&&(s=e.R32UI),r===e.BYTE&&(s=e.R8I),r===e.SHORT&&(s=e.R16I),r===e.INT&&(s=e.R32I)),i===e.RG&&(r===e.FLOAT&&(s=e.RG32F),r===e.HALF_FLOAT&&(s=e.RG16F),r===e.UNSIGNED_BYTE&&(s=e.RG8)),i===e.RG_INTEGER&&(r===e.UNSIGNED_BYTE&&(s=e.RG8UI),r===e.UNSIGNED_SHORT&&(s=e.RG16UI),r===e.UNSIGNED_INT&&(s=e.RG32UI),r===e.BYTE&&(s=e.RG8I),r===e.SHORT&&(s=e.RG16I),r===e.INT&&(s=e.RG32I)),i===e.RGB_INTEGER&&(r===e.UNSIGNED_BYTE&&(s=e.RGB8UI),r===e.UNSIGNED_SHORT&&(s=e.RGB16UI),r===e.UNSIGNED_INT&&(s=e.RGB32UI),r===e.BYTE&&(s=e.RGB8I),r===e.SHORT&&(s=e.RGB16I),r===e.INT&&(s=e.RGB32I)),i===e.RGBA_INTEGER&&(r===e.UNSIGNED_BYTE&&(s=e.RGBA8UI),r===e.UNSIGNED_SHORT&&(s=e.RGBA16UI),r===e.UNSIGNED_INT&&(s=e.RGBA32UI),r===e.BYTE&&(s=e.RGBA8I),r===e.SHORT&&(s=e.RGBA16I),r===e.INT&&(s=e.RGBA32I)),i===e.RGB&&(r===e.UNSIGNED_INT_5_9_9_9_REV&&(s=e.RGB9_E5),r===e.UNSIGNED_INT_10F_11F_11F_REV&&(s=e.R11F_G11F_B10F)),i===e.RGBA){const t=o?me:p.getTransfer(a);r===e.FLOAT&&(s=e.RGBA32F),r===e.HALF_FLOAT&&(s=e.RGBA16F),r===e.UNSIGNED_BYTE&&(s=t===m?e.SRGB8_ALPHA8:e.RGBA8),r===e.UNSIGNED_SHORT_4_4_4_4&&(s=e.RGBA4),r===e.UNSIGNED_SHORT_5_5_5_1&&(s=e.RGB5_A1)}return s!==e.R16F&&s!==e.R32F&&s!==e.RG16F&&s!==e.RG32F&&s!==e.RGBA16F&&s!==e.RGBA32F||n.get("EXT_color_buffer_float"),s}function C(t,n){let i;return t?null===n||n===Le||n===Ct?i=e.DEPTH24_STENCIL8:n===T?i=e.DEPTH32F_STENCIL8:n===Pt&&(i=e.DEPTH24_STENCIL8,E("DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.")):null===n||n===Le||n===Ct?i=e.DEPTH_COMPONENT24:n===T?i=e.DEPTH_COMPONENT32F:n===Pt&&(i=e.DEPTH_COMPONENT16),i}function P(e,t){return!0===S(e)||e.isFramebufferTexture&&e.minFilter!==Ce&&e.minFilter!==O?Math.log2(Math.max(t.width,t.height))+1:void 0!==e.mipmaps&&e.mipmaps.length>0?e.mipmaps.length:e.isCompressedTexture&&Array.isArray(e.image)?t.mipmaps.length:1}function L(e){const t=e.target;t.removeEventListener("dispose",L),function(e){const t=r.get(e);if(void 0===t.__webglInit)return;const n=e.source,i=h.get(n);if(i){const r=i[t.__cacheKey];r.usedTimes--,0===r.usedTimes&&D(e),0===Object.keys(i).length&&h.delete(n)}r.remove(e)}(t),t.isVideoTexture&&u.delete(t)}function U(t){const n=t.target;n.removeEventListener("dispose",U),function(t){const n=r.get(t);t.depthTexture&&(t.depthTexture.dispose(),r.remove(t.depthTexture));if(t.isWebGLCubeRenderTarget)for(let t=0;t<6;t++){if(Array.isArray(n.__webglFramebuffer[t]))for(let i=0;i0&&a.__version!==t.version){const e=t.image;if(null===e)E("WebGLRenderer: Texture marked for update but no image data found.");else{if(!1!==e.complete)return void z(a,t,n);E("WebGLRenderer: Texture marked for update but image is incomplete")}}else t.isExternalTexture&&(a.__webglTexture=t.sourceTexture?t.sourceTexture:null);i.bindTexture(e.TEXTURE_2D,a.__webglTexture,e.TEXTURE0+n)}const y={[pt]:e.REPEAT,[ft]:e.CLAMP_TO_EDGE,[ut]:e.MIRRORED_REPEAT},B={[Ce]:e.NEAREST,[gt]:e.NEAREST_MIPMAP_NEAREST,[_t]:e.NEAREST_MIPMAP_LINEAR,[O]:e.LINEAR,[ht]:e.LINEAR_MIPMAP_NEAREST,[mt]:e.LINEAR_MIPMAP_LINEAR},G={[xt]:e.NEVER,[Tt]:e.ALWAYS,[Mt]:e.LESS,[ae]:e.LEQUAL,[St]:e.EQUAL,[re]:e.GEQUAL,[Et]:e.GREATER,[vt]:e.NOTEQUAL};function H(t,i){if(i.type!==T||!1!==n.has("OES_texture_float_linear")||i.magFilter!==O&&i.magFilter!==ht&&i.magFilter!==_t&&i.magFilter!==mt&&i.minFilter!==O&&i.minFilter!==ht&&i.minFilter!==_t&&i.minFilter!==mt||E("WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device."),e.texParameteri(t,e.TEXTURE_WRAP_S,y[i.wrapS]),e.texParameteri(t,e.TEXTURE_WRAP_T,y[i.wrapT]),t!==e.TEXTURE_3D&&t!==e.TEXTURE_2D_ARRAY||e.texParameteri(t,e.TEXTURE_WRAP_R,y[i.wrapR]),e.texParameteri(t,e.TEXTURE_MAG_FILTER,B[i.magFilter]),e.texParameteri(t,e.TEXTURE_MIN_FILTER,B[i.minFilter]),i.compareFunction&&(e.texParameteri(t,e.TEXTURE_COMPARE_MODE,e.COMPARE_REF_TO_TEXTURE),e.texParameteri(t,e.TEXTURE_COMPARE_FUNC,G[i.compareFunction])),!0===n.has("EXT_texture_filter_anisotropic")){if(i.magFilter===Ce)return;if(i.minFilter!==_t&&i.minFilter!==mt)return;if(i.type===T&&!1===n.has("OES_texture_float_linear"))return;if(i.anisotropy>1||r.get(i).__currentAnisotropy){const o=n.get("EXT_texture_filter_anisotropic");e.texParameterf(t,o.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(i.anisotropy,a.getMaxAnisotropy())),r.get(i).__currentAnisotropy=i.anisotropy}}}function V(t,n){let i=!1;void 0===t.__webglInit&&(t.__webglInit=!0,n.addEventListener("dispose",L));const r=n.source;let a=h.get(r);void 0===a&&(a={},h.set(r,a));const o=function(e){const t=[];return t.push(e.wrapS),t.push(e.wrapT),t.push(e.wrapR||0),t.push(e.magFilter),t.push(e.minFilter),t.push(e.anisotropy),t.push(e.internalFormat),t.push(e.format),t.push(e.type),t.push(e.generateMipmaps),t.push(e.premultiplyAlpha),t.push(e.flipY),t.push(e.unpackAlignment),t.push(e.colorSpace),t.join()}(n);if(o!==t.__cacheKey){void 0===a[o]&&(a[o]={texture:e.createTexture(),usedTimes:0},s.memory.textures++,i=!0),a[o].usedTimes++;const r=a[t.__cacheKey];void 0!==r&&(a[t.__cacheKey].usedTimes--,0===r.usedTimes&&D(n)),t.__cacheKey=o,t.__webglTexture=a[o].texture}return i}function W(e,t,n){return Math.floor(Math.floor(e/n)/t)}function z(t,n,s){let l=e.TEXTURE_2D;(n.isDataArrayTexture||n.isCompressedArrayTexture)&&(l=e.TEXTURE_2D_ARRAY),n.isData3DTexture&&(l=e.TEXTURE_3D);const c=V(t,n),d=n.source;i.bindTexture(l,t.__webglTexture,e.TEXTURE0+s);const u=r.get(d);if(d.version!==u.__version||!0===c){i.activeTexture(e.TEXTURE0+s);const t=p.getPrimaries(p.workingColorSpace),r=n.colorSpace===At?null:p.getPrimaries(n.colorSpace),f=n.colorSpace===At||t===r?e.NONE:e.BROWSER_DEFAULT_WEBGL;e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,n.flipY),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,n.premultiplyAlpha),e.pixelStorei(e.UNPACK_ALIGNMENT,n.unpackAlignment),e.pixelStorei(e.UNPACK_COLORSPACE_CONVERSION_WEBGL,f);let m=v(n.image,!1,a.maxTextureSize);m=Q(n,m);const h=o.convert(n.format,n.colorSpace),_=o.convert(n.type);let g,M=b(n.internalFormat,h,_,n.colorSpace,n.isVideoTexture);H(l,n);const T=n.mipmaps,R=!0!==n.isVideoTexture,L=void 0===u.__version||!0===c,U=d.dataReady,D=P(n,m);if(n.isDepthTexture)M=C(n.format===Rt,n.type),L&&(R?i.texStorage2D(e.TEXTURE_2D,1,M,m.width,m.height):i.texImage2D(e.TEXTURE_2D,0,M,m.width,m.height,0,h,_,null));else if(n.isDataTexture)if(T.length>0){R&&L&&i.texStorage2D(e.TEXTURE_2D,D,M,T[0].width,T[0].height);for(let t=0,n=T.length;te.start-t.start);let s=0;for(let e=1;e0){const r=bt(g.width,g.height,n.format,n.type);for(const a of n.layerUpdates){const n=g.data.subarray(a*r/g.data.BYTES_PER_ELEMENT,(a+1)*r/g.data.BYTES_PER_ELEMENT);i.compressedTexSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,a,g.width,g.height,1,h,n)}n.clearLayerUpdates()}else i.compressedTexSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,0,g.width,g.height,m.depth,h,g.data)}else i.compressedTexImage3D(e.TEXTURE_2D_ARRAY,t,M,g.width,g.height,m.depth,0,g.data,0,0);else E("WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()");else R?U&&i.texSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,0,g.width,g.height,m.depth,h,_,g.data):i.texImage3D(e.TEXTURE_2D_ARRAY,t,M,g.width,g.height,m.depth,0,h,_,g.data)}else{R&&L&&i.texStorage2D(e.TEXTURE_2D,D,M,T[0].width,T[0].height);for(let t=0,r=T.length;t0){const t=bt(m.width,m.height,n.format,n.type);for(const r of n.layerUpdates){const n=m.data.subarray(r*t/m.data.BYTES_PER_ELEMENT,(r+1)*t/m.data.BYTES_PER_ELEMENT);i.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,r,m.width,m.height,1,h,_,n)}n.clearLayerUpdates()}else i.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,0,m.width,m.height,m.depth,h,_,m.data)}else i.texImage3D(e.TEXTURE_2D_ARRAY,0,M,m.width,m.height,m.depth,0,h,_,m.data);else if(n.isData3DTexture)R?(L&&i.texStorage3D(e.TEXTURE_3D,D,M,m.width,m.height,m.depth),U&&i.texSubImage3D(e.TEXTURE_3D,0,0,0,0,m.width,m.height,m.depth,h,_,m.data)):i.texImage3D(e.TEXTURE_3D,0,M,m.width,m.height,m.depth,0,h,_,m.data);else if(n.isFramebufferTexture){if(L)if(R)i.texStorage2D(e.TEXTURE_2D,D,M,m.width,m.height);else{let t=m.width,n=m.height;for(let r=0;r>=1,n>>=1}}else if(T.length>0){if(R&&L){const t=J(T[0]);i.texStorage2D(e.TEXTURE_2D,D,M,t.width,t.height)}for(let t=0,n=T.length;t>d),r=Math.max(1,n.height>>d);c===e.TEXTURE_3D||c===e.TEXTURE_2D_ARRAY?i.texImage3D(c,d,p,t,r,n.depth,0,u,f,null):i.texImage2D(c,d,p,t,r,0,u,f,null)}i.bindFramebuffer(e.FRAMEBUFFER,t),$(n)?l.framebufferTexture2DMultisampleEXT(e.FRAMEBUFFER,s,c,h.__webglTexture,0,Z(n)):(c===e.TEXTURE_2D||c>=e.TEXTURE_CUBE_MAP_POSITIVE_X&&c<=e.TEXTURE_CUBE_MAP_NEGATIVE_Z)&&e.framebufferTexture2D(e.FRAMEBUFFER,s,c,h.__webglTexture,d),i.bindFramebuffer(e.FRAMEBUFFER,null)}function X(t,n,i){if(e.bindRenderbuffer(e.RENDERBUFFER,t),n.depthBuffer){const r=n.depthTexture,a=r&&r.isDepthTexture?r.type:null,o=C(n.stencilBuffer,a),s=n.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT;$(n)?l.renderbufferStorageMultisampleEXT(e.RENDERBUFFER,Z(n),o,n.width,n.height):i?e.renderbufferStorageMultisample(e.RENDERBUFFER,Z(n),o,n.width,n.height):e.renderbufferStorage(e.RENDERBUFFER,o,n.width,n.height),e.framebufferRenderbuffer(e.FRAMEBUFFER,s,e.RENDERBUFFER,t)}else{const t=n.textures;for(let r=0;r{delete n.__boundDepthTexture,delete n.__depthDisposeCallback,e.removeEventListener("dispose",t)};e.addEventListener("dispose",t),n.__depthDisposeCallback=t}n.__boundDepthTexture=e}if(t.depthTexture&&!n.__autoAllocateDepthBuffer)if(a)for(let e=0;e<6;e++)Y(n.__webglFramebuffer[e],t,e);else{const e=t.texture.mipmaps;e&&e.length>0?Y(n.__webglFramebuffer[0],t,0):Y(n.__webglFramebuffer,t,0)}else if(a){n.__webglDepthbuffer=[];for(let r=0;r<6;r++)if(i.bindFramebuffer(e.FRAMEBUFFER,n.__webglFramebuffer[r]),void 0===n.__webglDepthbuffer[r])n.__webglDepthbuffer[r]=e.createRenderbuffer(),X(n.__webglDepthbuffer[r],t,!1);else{const i=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,a=n.__webglDepthbuffer[r];e.bindRenderbuffer(e.RENDERBUFFER,a),e.framebufferRenderbuffer(e.FRAMEBUFFER,i,e.RENDERBUFFER,a)}}else{const r=t.texture.mipmaps;if(r&&r.length>0?i.bindFramebuffer(e.FRAMEBUFFER,n.__webglFramebuffer[0]):i.bindFramebuffer(e.FRAMEBUFFER,n.__webglFramebuffer),void 0===n.__webglDepthbuffer)n.__webglDepthbuffer=e.createRenderbuffer(),X(n.__webglDepthbuffer,t,!1);else{const i=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,r=n.__webglDepthbuffer;e.bindRenderbuffer(e.RENDERBUFFER,r),e.framebufferRenderbuffer(e.FRAMEBUFFER,i,e.RENDERBUFFER,r)}}i.bindFramebuffer(e.FRAMEBUFFER,null)}const j=[],q=[];function Z(e){return Math.min(a.maxSamples,e.samples)}function $(e){const t=r.get(e);return e.samples>0&&!0===n.has("WEBGL_multisampled_render_to_texture")&&!1!==t.__useRenderToTexture}function Q(e,t){const n=e.colorSpace,i=e.format,r=e.type;return!0===e.isCompressedTexture||!0===e.isVideoTexture||n!==F&&n!==At&&(p.getTransfer(n)===m?i===x&&r===M||E("WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType."):w("WebGLTextures: Unsupported texture color space:",n)),t}function J(e){return"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement?(d.width=e.naturalWidth||e.width,d.height=e.naturalHeight||e.height):"undefined"!=typeof VideoFrame&&e instanceof VideoFrame?(d.width=e.displayWidth,d.height=e.displayHeight):(d.width=e.width,d.height=e.height),d}this.allocateTextureUnit=function(){const e=I;return e>=a.maxTextures&&E("WebGLTextures: Trying to use "+e+" texture units while this GPU supports only "+a.maxTextures),I+=1,e},this.resetTextureUnits=function(){I=0},this.setTexture2D=N,this.setTexture2DArray=function(t,n){const a=r.get(t);!1===t.isRenderTargetTexture&&t.version>0&&a.__version!==t.version?z(a,t,n):(t.isExternalTexture&&(a.__webglTexture=t.sourceTexture?t.sourceTexture:null),i.bindTexture(e.TEXTURE_2D_ARRAY,a.__webglTexture,e.TEXTURE0+n))},this.setTexture3D=function(t,n){const a=r.get(t);!1===t.isRenderTargetTexture&&t.version>0&&a.__version!==t.version?z(a,t,n):i.bindTexture(e.TEXTURE_3D,a.__webglTexture,e.TEXTURE0+n)},this.setTextureCube=function(t,n){const s=r.get(t);!0!==t.isCubeDepthTexture&&t.version>0&&s.__version!==t.version?function(t,n,s){if(6!==n.image.length)return;const l=V(t,n),c=n.source;i.bindTexture(e.TEXTURE_CUBE_MAP,t.__webglTexture,e.TEXTURE0+s);const d=r.get(c);if(c.version!==d.__version||!0===l){i.activeTexture(e.TEXTURE0+s);const t=p.getPrimaries(p.workingColorSpace),r=n.colorSpace===At?null:p.getPrimaries(n.colorSpace),u=n.colorSpace===At||t===r?e.NONE:e.BROWSER_DEFAULT_WEBGL;e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,n.flipY),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,n.premultiplyAlpha),e.pixelStorei(e.UNPACK_ALIGNMENT,n.unpackAlignment),e.pixelStorei(e.UNPACK_COLORSPACE_CONVERSION_WEBGL,u);const f=n.isCompressedTexture||n.image[0].isCompressedTexture,m=n.image[0]&&n.image[0].isDataTexture,h=[];for(let e=0;e<6;e++)h[e]=f||m?m?n.image[e].image:n.image[e]:v(n.image[e],!0,a.maxCubemapSize),h[e]=Q(n,h[e]);const _=h[0],g=o.convert(n.format,n.colorSpace),M=o.convert(n.type),T=b(n.internalFormat,g,M,n.colorSpace),R=!0!==n.isVideoTexture,C=void 0===d.__version||!0===l,L=c.dataReady;let U,D=P(n,_);if(H(e.TEXTURE_CUBE_MAP,n),f){R&&C&&i.texStorage2D(e.TEXTURE_CUBE_MAP,D,T,_.width,_.height);for(let t=0;t<6;t++){U=h[t].mipmaps;for(let r=0;r0&&D++;const t=J(h[0]);i.texStorage2D(e.TEXTURE_CUBE_MAP,D,T,t.width,t.height)}for(let t=0;t<6;t++)if(m){R?L&&i.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,0,0,0,h[t].width,h[t].height,g,M,h[t].data):i.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,0,T,h[t].width,h[t].height,0,g,M,h[t].data);for(let n=0;n1;if(u||(void 0===l.__webglTexture&&(l.__webglTexture=e.createTexture()),l.__version=n.version,s.memory.textures++),d){a.__webglFramebuffer=[];for(let t=0;t<6;t++)if(n.mipmaps&&n.mipmaps.length>0){a.__webglFramebuffer[t]=[];for(let i=0;i0){a.__webglFramebuffer=[];for(let t=0;t0&&!1===$(t)){a.__webglMultisampledFramebuffer=e.createFramebuffer(),a.__webglColorRenderbuffer=[],i.bindFramebuffer(e.FRAMEBUFFER,a.__webglMultisampledFramebuffer);for(let n=0;n0)for(let r=0;r0)for(let i=0;i0)if(!1===$(t)){const n=t.textures,a=t.width,o=t.height;let s=e.COLOR_BUFFER_BIT;const l=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,d=r.get(t),u=n.length>1;if(u)for(let t=0;t0?i.bindFramebuffer(e.DRAW_FRAMEBUFFER,d.__webglFramebuffer[0]):i.bindFramebuffer(e.DRAW_FRAMEBUFFER,d.__webglFramebuffer);for(let i=0;i= 1.0 ) {\n\n\t\tgl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r;\n\n\t} else {\n\n\t\tgl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r;\n\n\t}\n\n}",uniforms:{depthColor:{value:this.texture},depthWidth:{value:t.z},depthHeight:{value:t.w}}});this.mesh=new o(new h(20,20),n)}return this.mesh}reset(){this.texture=null,this.mesh=null}getDepthTexture(){return this.texture}}class Ta extends bn{constructor(e,n){super();const i=this;let a=null,o=1,s=null,l="local-floor",c=1,d=null,u=null,f=null,p=null,m=null,h=null;const _="undefined"!=typeof XRWebGLBinding,g=new Ma,v={},S=n.getContextAttributes();let T=null,A=null;const R=[],b=[],C=new t;let P=null;const U=new L;U.viewport=new X;const D=new L;D.viewport=new X;const w=[U,D],I=new Cn;let y=null,F=null;function O(e){const t=b.indexOf(e.inputSource);if(-1===t)return;const n=R[t];void 0!==n&&(n.update(e.inputSource,e.frame,d||s),n.dispatchEvent({type:e.type,data:e.inputSource}))}function B(){a.removeEventListener("select",O),a.removeEventListener("selectstart",O),a.removeEventListener("selectend",O),a.removeEventListener("squeeze",O),a.removeEventListener("squeezestart",O),a.removeEventListener("squeezeend",O),a.removeEventListener("end",B),a.removeEventListener("inputsourceschange",G);for(let e=0;e=0&&(b[i]=null,R[i].disconnect(n))}for(let t=0;t=b.length){b.push(n),i=e;break}if(null===b[e]){b[e]=n,i=e;break}}if(-1===i)break}const r=R[i];r&&r.connect(n)}}this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(e){let t=R[e];return void 0===t&&(t=new Pn,R[e]=t),t.getTargetRaySpace()},this.getControllerGrip=function(e){let t=R[e];return void 0===t&&(t=new Pn,R[e]=t),t.getGripSpace()},this.getHand=function(e){let t=R[e];return void 0===t&&(t=new Pn,R[e]=t),t.getHandSpace()},this.setFramebufferScaleFactor=function(e){o=e,!0===i.isPresenting&&E("WebXRManager: Cannot change framebuffer scale while presenting.")},this.setReferenceSpaceType=function(e){l=e,!0===i.isPresenting&&E("WebXRManager: Cannot change reference space type while presenting.")},this.getReferenceSpace=function(){return d||s},this.setReferenceSpace=function(e){d=e},this.getBaseLayer=function(){return null!==p?p:m},this.getBinding=function(){return null===f&&_&&(f=new XRWebGLBinding(a,n)),f},this.getFrame=function(){return h},this.getSession=function(){return a},this.setSession=async function(t){if(a=t,null!==a){T=e.getRenderTarget(),a.addEventListener("select",O),a.addEventListener("selectstart",O),a.addEventListener("selectend",O),a.addEventListener("squeeze",O),a.addEventListener("squeezestart",O),a.addEventListener("squeezeend",O),a.addEventListener("end",B),a.addEventListener("inputsourceschange",G),!0!==S.xrCompatible&&await n.makeXRCompatible(),P=e.getPixelRatio(),e.getSize(C);if(_&&"createProjectionLayer"in XRWebGLBinding.prototype){let t=null,i=null,r=null;S.depth&&(r=S.stencil?n.DEPTH24_STENCIL8:n.DEPTH_COMPONENT24,t=S.stencil?Rt:be,i=S.stencil?Ct:Le);const s={colorFormat:n.RGBA8,depthFormat:r,scaleFactor:o};f=this.getBinding(),p=f.createProjectionLayer(s),a.updateRenderState({layers:[p]}),e.setPixelRatio(1),e.setSize(p.textureWidth,p.textureHeight,!1),A=new N(p.textureWidth,p.textureHeight,{format:x,type:M,depthTexture:new oe(p.textureWidth,p.textureHeight,i,void 0,void 0,void 0,void 0,void 0,void 0,t),stencilBuffer:S.stencil,colorSpace:e.outputColorSpace,samples:S.antialias?4:0,resolveDepthBuffer:!1===p.ignoreDepthValues,resolveStencilBuffer:!1===p.ignoreDepthValues})}else{const t={antialias:S.antialias,alpha:!0,depth:S.depth,stencil:S.stencil,framebufferScaleFactor:o};m=new XRWebGLLayer(a,n,t),a.updateRenderState({baseLayer:m}),e.setPixelRatio(1),e.setSize(m.framebufferWidth,m.framebufferHeight,!1),A=new N(m.framebufferWidth,m.framebufferHeight,{format:x,type:M,colorSpace:e.outputColorSpace,stencilBuffer:S.stencil,resolveDepthBuffer:!1===m.ignoreDepthValues,resolveStencilBuffer:!1===m.ignoreDepthValues})}A.isXRRenderTarget=!0,this.setFoveation(c),d=null,s=await a.requestReferenceSpace(l),k.setContext(a),k.start(),i.isPresenting=!0,i.dispatchEvent({type:"sessionstart"})}},this.getEnvironmentBlendMode=function(){if(null!==a)return a.environmentBlendMode},this.getDepthTexture=function(){return g.getDepthTexture()};const H=new r,V=new r;function W(e,t){null===t?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(t.matrixWorld,e.matrix),e.matrixWorldInverse.copy(e.matrixWorld).invert()}this.updateCamera=function(e){if(null===a)return;let t=e.near,n=e.far;null!==g.texture&&(g.depthNear>0&&(t=g.depthNear),g.depthFar>0&&(n=g.depthFar)),I.near=D.near=U.near=t,I.far=D.far=U.far=n,y===I.near&&F===I.far||(a.updateRenderState({depthNear:I.near,depthFar:I.far}),y=I.near,F=I.far),I.layers.mask=6|e.layers.mask,U.layers.mask=-5&I.layers.mask,D.layers.mask=-3&I.layers.mask;const i=e.parent,r=I.cameras;W(I,i);for(let e=0;e0&&(e.alphaTest.value=i.alphaTest);const r=t.get(i),a=r.envMap,o=r.envMapRotation;a&&(e.envMap.value=a,xa.copy(o),xa.x*=-1,xa.y*=-1,xa.z*=-1,a.isCubeTexture&&!1===a.isRenderTargetTexture&&(xa.y*=-1,xa.z*=-1),e.envMapRotation.value.setFromMatrix4(Aa.makeRotationFromEuler(xa)),e.flipEnvMap.value=a.isCubeTexture&&!1===a.isRenderTargetTexture?-1:1,e.reflectivity.value=i.reflectivity,e.ior.value=i.ior,e.refractionRatio.value=i.refractionRatio),i.lightMap&&(e.lightMap.value=i.lightMap,e.lightMapIntensity.value=i.lightMapIntensity,n(i.lightMap,e.lightMapTransform)),i.aoMap&&(e.aoMap.value=i.aoMap,e.aoMapIntensity.value=i.aoMapIntensity,n(i.aoMap,e.aoMapTransform))}return{refreshFogUniforms:function(t,n){n.color.getRGB(t.fogColor.value,g(e)),n.isFog?(t.fogNear.value=n.near,t.fogFar.value=n.far):n.isFogExp2&&(t.fogDensity.value=n.density)},refreshMaterialUniforms:function(e,r,a,o,s){r.isMeshBasicMaterial?i(e,r):r.isMeshLambertMaterial?(i(e,r),r.envMap&&(e.envMapIntensity.value=r.envMapIntensity)):r.isMeshToonMaterial?(i(e,r),function(e,t){t.gradientMap&&(e.gradientMap.value=t.gradientMap)}(e,r)):r.isMeshPhongMaterial?(i(e,r),function(e,t){e.specular.value.copy(t.specular),e.shininess.value=Math.max(t.shininess,1e-4)}(e,r),r.envMap&&(e.envMapIntensity.value=r.envMapIntensity)):r.isMeshStandardMaterial?(i(e,r),function(e,t){e.metalness.value=t.metalness,t.metalnessMap&&(e.metalnessMap.value=t.metalnessMap,n(t.metalnessMap,e.metalnessMapTransform));e.roughness.value=t.roughness,t.roughnessMap&&(e.roughnessMap.value=t.roughnessMap,n(t.roughnessMap,e.roughnessMapTransform));t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)}(e,r),r.isMeshPhysicalMaterial&&function(e,t,i){e.ior.value=t.ior,t.sheen>0&&(e.sheenColor.value.copy(t.sheenColor).multiplyScalar(t.sheen),e.sheenRoughness.value=t.sheenRoughness,t.sheenColorMap&&(e.sheenColorMap.value=t.sheenColorMap,n(t.sheenColorMap,e.sheenColorMapTransform)),t.sheenRoughnessMap&&(e.sheenRoughnessMap.value=t.sheenRoughnessMap,n(t.sheenRoughnessMap,e.sheenRoughnessMapTransform)));t.clearcoat>0&&(e.clearcoat.value=t.clearcoat,e.clearcoatRoughness.value=t.clearcoatRoughness,t.clearcoatMap&&(e.clearcoatMap.value=t.clearcoatMap,n(t.clearcoatMap,e.clearcoatMapTransform)),t.clearcoatRoughnessMap&&(e.clearcoatRoughnessMap.value=t.clearcoatRoughnessMap,n(t.clearcoatRoughnessMap,e.clearcoatRoughnessMapTransform)),t.clearcoatNormalMap&&(e.clearcoatNormalMap.value=t.clearcoatNormalMap,n(t.clearcoatNormalMap,e.clearcoatNormalMapTransform),e.clearcoatNormalScale.value.copy(t.clearcoatNormalScale),t.side===c&&e.clearcoatNormalScale.value.negate()));t.dispersion>0&&(e.dispersion.value=t.dispersion);t.iridescence>0&&(e.iridescence.value=t.iridescence,e.iridescenceIOR.value=t.iridescenceIOR,e.iridescenceThicknessMinimum.value=t.iridescenceThicknessRange[0],e.iridescenceThicknessMaximum.value=t.iridescenceThicknessRange[1],t.iridescenceMap&&(e.iridescenceMap.value=t.iridescenceMap,n(t.iridescenceMap,e.iridescenceMapTransform)),t.iridescenceThicknessMap&&(e.iridescenceThicknessMap.value=t.iridescenceThicknessMap,n(t.iridescenceThicknessMap,e.iridescenceThicknessMapTransform)));t.transmission>0&&(e.transmission.value=t.transmission,e.transmissionSamplerMap.value=i.texture,e.transmissionSamplerSize.value.set(i.width,i.height),t.transmissionMap&&(e.transmissionMap.value=t.transmissionMap,n(t.transmissionMap,e.transmissionMapTransform)),e.thickness.value=t.thickness,t.thicknessMap&&(e.thicknessMap.value=t.thicknessMap,n(t.thicknessMap,e.thicknessMapTransform)),e.attenuationDistance.value=t.attenuationDistance,e.attenuationColor.value.copy(t.attenuationColor));t.anisotropy>0&&(e.anisotropyVector.value.set(t.anisotropy*Math.cos(t.anisotropyRotation),t.anisotropy*Math.sin(t.anisotropyRotation)),t.anisotropyMap&&(e.anisotropyMap.value=t.anisotropyMap,n(t.anisotropyMap,e.anisotropyMapTransform)));e.specularIntensity.value=t.specularIntensity,e.specularColor.value.copy(t.specularColor),t.specularColorMap&&(e.specularColorMap.value=t.specularColorMap,n(t.specularColorMap,e.specularColorMapTransform));t.specularIntensityMap&&(e.specularIntensityMap.value=t.specularIntensityMap,n(t.specularIntensityMap,e.specularIntensityMapTransform))}(e,r,s)):r.isMeshMatcapMaterial?(i(e,r),function(e,t){t.matcap&&(e.matcap.value=t.matcap)}(e,r)):r.isMeshDepthMaterial?i(e,r):r.isMeshDistanceMaterial?(i(e,r),function(e,n){const i=t.get(n).light;e.referencePosition.value.setFromMatrixPosition(i.matrixWorld),e.nearDistance.value=i.shadow.camera.near,e.farDistance.value=i.shadow.camera.far}(e,r)):r.isMeshNormalMaterial?i(e,r):r.isLineBasicMaterial?(function(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,t.map&&(e.map.value=t.map,n(t.map,e.mapTransform))}(e,r),r.isLineDashedMaterial&&function(e,t){e.dashSize.value=t.dashSize,e.totalSize.value=t.dashSize+t.gapSize,e.scale.value=t.scale}(e,r)):r.isPointsMaterial?function(e,t,i,r){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.size.value=t.size*i,e.scale.value=.5*r,t.map&&(e.map.value=t.map,n(t.map,e.uvTransform));t.alphaMap&&(e.alphaMap.value=t.alphaMap,n(t.alphaMap,e.alphaMapTransform));t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}(e,r,a,o):r.isSpriteMaterial?function(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.rotation.value=t.rotation,t.map&&(e.map.value=t.map,n(t.map,e.mapTransform));t.alphaMap&&(e.alphaMap.value=t.alphaMap,n(t.alphaMap,e.alphaMapTransform));t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}(e,r):r.isShadowMaterial?(e.color.value.copy(r.color),e.opacity.value=r.opacity):r.isShaderMaterial&&(r.uniformsNeedUpdate=!1)}}}function ba(e,t,n,i){let r={},a={},o=[];const s=e.getParameter(e.MAX_UNIFORM_BUFFER_BINDINGS);function l(e,t,n,i){const r=e.value,a=t+"_"+n;if(void 0===i[a])return i[a]="number"==typeof r||"boolean"==typeof r?r:r.clone(),!0;{const e=i[a];if("number"==typeof r||"boolean"==typeof r){if(e!==r)return i[a]=r,!0}else if(!1===e.equals(r))return e.copy(r),!0}return!1}function c(e){const t={boundary:0,storage:0};return"number"==typeof e||"boolean"==typeof e?(t.boundary=4,t.storage=4):e.isVector2?(t.boundary=8,t.storage=8):e.isVector3||e.isColor?(t.boundary=16,t.storage=12):e.isVector4?(t.boundary=16,t.storage=16):e.isMatrix3?(t.boundary=48,t.storage=48):e.isMatrix4?(t.boundary=64,t.storage=64):e.isTexture?E("WebGLRenderer: Texture samplers can not be part of an uniforms group."):E("WebGLRenderer: Unsupported uniform value type.",e),t}function d(t){const n=t.target;n.removeEventListener("dispose",d);const i=o.indexOf(n.__bindingPointIndex);o.splice(i,1),e.deleteBuffer(r[n.id]),delete r[n.id],delete a[n.id]}return{bind:function(e,t){const n=t.program;i.uniformBlockBinding(e,n)},update:function(n,u){let f=r[n.id];void 0===f&&(!function(e){const t=e.uniforms;let n=0;const i=16;for(let e=0,r=t.length;e0&&(n+=i-r);e.__size=n,e.__cache={}}(n),f=function(t){const n=function(){for(let e=0;e0),f=!!n.morphAttributes.position,p=!!n.morphAttributes.normal,m=!!n.morphAttributes.color;let h=U;i.toneMapped&&(null!==z&&!0!==z.isXRRenderTarget||(h=B.toneMapping));const _=n.morphAttributes.position||n.morphAttributes.normal||n.morphAttributes.color,g=void 0!==_?_.length:0,v=Se.get(i),E=L.state.lights;if(!0===se&&(!0===le||e!==Y)){const t=e===Y&&i.id===k;Ie.setState(i,e,t)}let M=!1;i.version===v.__version?v.needsLights&&v.lightsStateVersion!==E.state.version||v.outputColorSpace!==s||r.isBatchedMesh&&!1===v.batching?M=!0:r.isBatchedMesh||!0!==v.batching?r.isBatchedMesh&&!0===v.batchingColor&&null===r.colorTexture||r.isBatchedMesh&&!1===v.batchingColor&&null!==r.colorTexture||r.isInstancedMesh&&!1===v.instancing?M=!0:r.isInstancedMesh||!0!==v.instancing?r.isSkinnedMesh&&!1===v.skinning?M=!0:r.isSkinnedMesh||!0!==v.skinning?r.isInstancedMesh&&!0===v.instancingColor&&null===r.instanceColor||r.isInstancedMesh&&!1===v.instancingColor&&null!==r.instanceColor||r.isInstancedMesh&&!0===v.instancingMorph&&null===r.morphTexture||r.isInstancedMesh&&!1===v.instancingMorph&&null!==r.morphTexture||v.envMap!==c||!0===i.fog&&v.fog!==a?M=!0:void 0===v.numClippingPlanes||v.numClippingPlanes===Ie.numPlanes&&v.numIntersection===Ie.numIntersection?(v.vertexAlphas!==d||v.vertexTangents!==u||v.morphTargets!==f||v.morphNormals!==p||v.morphColors!==m||v.toneMapping!==h||v.morphTargetsCount!==g)&&(M=!0):M=!0:M=!0:M=!0:M=!0:(M=!0,v.__version=i.version);let T=v.currentProgram;!0===M&&(T=ot(i,t,r));let x=!1,A=!1,R=!1;const b=T.getUniforms(),C=v.uniforms;ve.useProgram(T.program)&&(x=!0,A=!0,R=!0);i.id!==k&&(k=i.id,A=!0);if(x||Y!==e){ve.buffers.depth.getReversed()&&!0!==e.reversedDepth&&(e._reversedDepth=!0,e.updateProjectionMatrix()),b.setValue(We,"projectionMatrix",e.projectionMatrix),b.setValue(We,"viewMatrix",e.matrixWorldInverse);const t=b.map.cameraPosition;void 0!==t&&t.setValue(We,de.setFromMatrixPosition(e.matrixWorld)),ge.logarithmicDepthBuffer&&b.setValue(We,"logDepthBufFC",2/(Math.log(e.far+1)/Math.LN2)),(i.isMeshPhongMaterial||i.isMeshToonMaterial||i.isMeshLambertMaterial||i.isMeshBasicMaterial||i.isMeshStandardMaterial||i.isShaderMaterial)&&b.setValue(We,"isOrthographic",!0===e.isOrthographicCamera),Y!==e&&(Y=e,A=!0,R=!0)}v.needsLights&&(E.state.directionalShadowMap.length>0&&b.setValue(We,"directionalShadowMap",E.state.directionalShadowMap,xe),E.state.spotShadowMap.length>0&&b.setValue(We,"spotShadowMap",E.state.spotShadowMap,xe),E.state.pointShadowMap.length>0&&b.setValue(We,"pointShadowMap",E.state.pointShadowMap,xe));if(r.isSkinnedMesh){b.setOptional(We,r,"bindMatrix"),b.setOptional(We,r,"bindMatrixInverse");const e=r.skeleton;e&&(null===e.boneTexture&&e.computeBoneTexture(),b.setValue(We,"boneTexture",e.boneTexture,xe))}r.isBatchedMesh&&(b.setOptional(We,r,"batchingTexture"),b.setValue(We,"batchingTexture",r._matricesTexture,xe),b.setOptional(We,r,"batchingIdTexture"),b.setValue(We,"batchingIdTexture",r._indirectTexture,xe),b.setOptional(We,r,"batchingColorTexture"),null!==r._colorsTexture&&b.setValue(We,"batchingColorTexture",r._colorsTexture,xe));const P=n.morphAttributes;void 0===P.position&&void 0===P.normal&&void 0===P.color||Fe.update(r,n,T);(A||v.receiveShadow!==r.receiveShadow)&&(v.receiveShadow=r.receiveShadow,b.setValue(We,"receiveShadow",r.receiveShadow));(i.isMeshStandardMaterial||i.isMeshLambertMaterial||i.isMeshPhongMaterial)&&null===i.envMap&&null!==t.environment&&(C.envMapIntensity.value=t.environmentIntensity);void 0!==C.dfgLUT&&(C.dfgLUT.value=(null===Pa&&(Pa=new Un(Ca,16,16,Me,S),Pa.name="DFG_LUT",Pa.minFilter=O,Pa.magFilter=O,Pa.wrapS=ft,Pa.wrapT=ft,Pa.generateMipmaps=!1,Pa.needsUpdate=!0),Pa));A&&(b.setValue(We,"toneMappingExposure",B.toneMappingExposure),v.needsLights&&(w=R,(D=C).ambientLightColor.needsUpdate=w,D.lightProbe.needsUpdate=w,D.directionalLights.needsUpdate=w,D.directionalLightShadows.needsUpdate=w,D.pointLights.needsUpdate=w,D.pointLightShadows.needsUpdate=w,D.spotLights.needsUpdate=w,D.spotLightShadows.needsUpdate=w,D.rectAreaLights.needsUpdate=w,D.hemisphereLights.needsUpdate=w),a&&!0===i.fog&&Ue.refreshFogUniforms(C,a),Ue.refreshMaterialUniforms(C,i,ee,J,L.state.transmissionRenderTarget[e.id]),Ar.upload(We,st(v),C,xe));var D,w;i.isShaderMaterial&&!0===i.uniformsNeedUpdate&&(Ar.upload(We,st(v),C,xe),i.uniformsNeedUpdate=!1);i.isSpriteMaterial&&b.setValue(We,"center",r.center);if(b.setValue(We,"modelViewMatrix",r.modelViewMatrix),b.setValue(We,"normalMatrix",r.normalMatrix),b.setValue(We,"modelMatrix",r.matrixWorld),i.isShaderMaterial||i.isRawShaderMaterial){const e=i.uniformsGroups;for(let t=0,n=e.length;t{function n(){i.forEach(function(e){Se.get(e).currentProgram.isReady()&&i.delete(e)}),0!==i.size?setTimeout(n,10):t(e)}null!==he.get("KHR_parallel_shader_compile")?n():setTimeout(n,10)})};let $e=null;function Qe(){et.stop()}function Je(){et.start()}const et=new On;function tt(e,t,n,i){if(!1===e.visible)return;if(e.layers.test(t.layers))if(e.isGroup)n=e.renderOrder;else if(e.isLOD)!0===e.autoUpdate&&e.update(t);else if(e.isLight)L.pushLight(e),e.castShadow&&L.pushShadow(e);else if(e.isSprite){if(!e.frustumCulled||oe.intersectsSprite(e)){i&&ue.setFromMatrixPosition(e.matrixWorld).applyMatrix4(ce);const t=Ce.update(e),r=e.material;r.visible&&P.push(e,t,r,n,ue.z,null)}}else if((e.isMesh||e.isLine||e.isPoints)&&(!e.frustumCulled||oe.intersectsObject(e))){const t=Ce.update(e),r=e.material;if(i&&(void 0!==e.boundingSphere?(null===e.boundingSphere&&e.computeBoundingSphere(),ue.copy(e.boundingSphere.center)):(null===t.boundingSphere&&t.computeBoundingSphere(),ue.copy(t.boundingSphere.center)),ue.applyMatrix4(e.matrixWorld).applyMatrix4(ce)),Array.isArray(r)){const i=t.groups;for(let a=0,o=i.length;a0&&rt(r,t,n),a.length>0&&rt(a,t,n),o.length>0&&rt(o,t,n),ve.buffers.depth.setTest(!0),ve.buffers.depth.setMask(!0),ve.buffers.color.setMask(!0),ve.setPolygonOffset(!1)}function it(e,t,n,i){if(null!==(!0===n.isScene?n.overrideMaterial:null))return;if(void 0===L.state.transmissionRenderTarget[i.id]){const e=he.has("EXT_color_buffer_half_float")||he.has("EXT_color_buffer_float");L.state.transmissionRenderTarget[i.id]=new N(1,1,{generateMipmaps:!0,type:e?S:M,minFilter:mt,samples:ge.samples,stencilBuffer:o,resolveDepthBuffer:!1,resolveStencilBuffer:!1,colorSpace:p.workingColorSpace})}const r=L.state.transmissionRenderTarget[i.id],a=i.viewport||K;r.setSize(a.z*B.transmissionResolutionScale,a.w*B.transmissionResolutionScale);const s=B.getRenderTarget(),l=B.getActiveCubeFace(),d=B.getActiveMipmapLevel();B.setRenderTarget(r),B.getClearColor(Z),$=B.getClearAlpha(),$<1&&B.setClearColor(16777215,.5),B.clear(),pe&&ye.render(n);const u=B.toneMapping;B.toneMapping=U;const f=i.viewport;if(void 0!==i.viewport&&(i.viewport=void 0),L.setupLightsView(i),!0===se&&Ie.setGlobalState(B.clippingPlanes,i),rt(e,n,i),xe.updateMultisampleRenderTarget(r),xe.updateRenderTargetMipmap(r),!1===he.has("WEBGL_multisampled_render_to_texture")){let e=!1;for(let r=0,a=t.length;r0)for(let t=0,a=r.length;t0&&it(n,i,e,t),pe&&ye.render(e),nt(P,e,t)}null!==z&&0===W&&(xe.updateMultisampleRenderTarget(z),xe.updateRenderTargetMipmap(z)),i&&y.end(B),!0===e.isScene&&e.onAfterRender(B,e,t),He.resetDefaultState(),k=-1,Y=null,I.pop(),I.length>0?(L=I[I.length-1],!0===se&&Ie.setGlobalState(B.clippingPlanes,L.state.camera)):L=null,D.pop(),P=D.length>0?D[D.length-1]:null},this.getActiveCubeFace=function(){return H},this.getActiveMipmapLevel=function(){return W},this.getRenderTarget=function(){return z},this.setRenderTargetTextures=function(e,t,n){const i=Se.get(e);i.__autoAllocateDepthBuffer=!1===e.resolveDepthBuffer,!1===i.__autoAllocateDepthBuffer&&(i.__useRenderToTexture=!1),Se.get(e.texture).__webglTexture=t,Se.get(e.depthTexture).__webglTexture=i.__autoAllocateDepthBuffer?void 0:n,i.__hasExternalTextures=!0},this.setRenderTargetFramebuffer=function(e,t){const n=Se.get(e);n.__webglFramebuffer=t,n.__useDefaultFramebuffer=void 0===t};const ct=We.createFramebuffer();this.setRenderTarget=function(e,t=0,n=0){z=e,H=t,W=n;let i=null,r=!1,a=!1;if(e){const o=Se.get(e);if(void 0!==o.__useDefaultFramebuffer)return ve.bindFramebuffer(We.FRAMEBUFFER,o.__webglFramebuffer),K.copy(e.viewport),j.copy(e.scissor),q=e.scissorTest,ve.viewport(K),ve.scissor(j),ve.setScissorTest(q),void(k=-1);if(void 0===o.__webglFramebuffer)xe.setupRenderTarget(e);else if(o.__hasExternalTextures)xe.rebindTextures(e,Se.get(e.texture).__webglTexture,Se.get(e.depthTexture).__webglTexture);else if(e.depthBuffer){const t=e.depthTexture;if(o.__boundDepthTexture!==t){if(null!==t&&Se.has(t)&&(e.width!==t.image.width||e.height!==t.image.height))throw new Error("WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.");xe.setupDepthRenderbuffer(e)}}const s=e.texture;(s.isData3DTexture||s.isDataArrayTexture||s.isCompressedArrayTexture)&&(a=!0);const l=Se.get(e).__webglFramebuffer;e.isWebGLCubeRenderTarget?(i=Array.isArray(l[t])?l[t][n]:l[t],r=!0):i=e.samples>0&&!1===xe.useMultisampledRTT(e)?Se.get(e).__webglMultisampledFramebuffer:Array.isArray(l)?l[n]:l,K.copy(e.viewport),j.copy(e.scissor),q=e.scissorTest}else K.copy(ie).multiplyScalar(ee).floor(),j.copy(re).multiplyScalar(ee).floor(),q=ae;0!==n&&(i=ct);if(ve.bindFramebuffer(We.FRAMEBUFFER,i)&&ve.drawBuffers(e,i),ve.viewport(K),ve.scissor(j),ve.setScissorTest(q),r){const i=Se.get(e.texture);We.framebufferTexture2D(We.FRAMEBUFFER,We.COLOR_ATTACHMENT0,We.TEXTURE_CUBE_MAP_POSITIVE_X+t,i.__webglTexture,n)}else if(a){const i=t;for(let t=0;t1&&We.readBuffer(We.COLOR_ATTACHMENT0+s),!ge.textureFormatReadable(l))return void w("WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");if(!ge.textureTypeReadable(c))return void w("WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.");t>=0&&t<=e.width-i&&n>=0&&n<=e.height-r&&We.readPixels(t,n,i,r,Ge.convert(l),Ge.convert(c),a)}finally{const e=null!==z?Se.get(z).__webglFramebuffer:null;ve.bindFramebuffer(We.FRAMEBUFFER,e)}}},this.readRenderTargetPixelsAsync=async function(e,t,n,i,r,a,o,s=0){if(!e||!e.isWebGLRenderTarget)throw new Error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");let l=Se.get(e).__webglFramebuffer;if(e.isWebGLCubeRenderTarget&&void 0!==o&&(l=l[o]),l){if(t>=0&&t<=e.width-i&&n>=0&&n<=e.height-r){ve.bindFramebuffer(We.FRAMEBUFFER,l);const o=e.textures[s],c=o.format,d=o.type;if(e.textures.length>1&&We.readBuffer(We.COLOR_ATTACHMENT0+s),!ge.textureFormatReadable(c))throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.");if(!ge.textureTypeReadable(d))throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.");const u=We.createBuffer();We.bindBuffer(We.PIXEL_PACK_BUFFER,u),We.bufferData(We.PIXEL_PACK_BUFFER,a.byteLength,We.STREAM_READ),We.readPixels(t,n,i,r,Ge.convert(c),Ge.convert(d),0);const f=null!==z?Se.get(z).__webglFramebuffer:null;ve.bindFramebuffer(We.FRAMEBUFFER,f);const p=We.fenceSync(We.SYNC_GPU_COMMANDS_COMPLETE,0);return We.flush(),await Fn(We,p,4),We.bindBuffer(We.PIXEL_PACK_BUFFER,u),We.getBufferSubData(We.PIXEL_PACK_BUFFER,0,a),We.deleteBuffer(u),We.deleteSync(p),a}throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.")}},this.copyFramebufferToTexture=function(e,t=null,n=0){const i=Math.pow(2,-n),r=Math.floor(e.image.width*i),a=Math.floor(e.image.height*i),o=null!==t?t.x:0,s=null!==t?t.y:0;xe.setTexture2D(e,0),We.copyTexSubImage2D(We.TEXTURE_2D,n,0,0,o,s,r,a),ve.unbindTexture()};const dt=We.createFramebuffer(),ut=We.createFramebuffer();this.copyTextureToTexture=function(e,t,n=null,i=null,r=0,a=0){let o,s,l,c,d,u,f,p,m;const h=e.isCompressedTexture?e.mipmaps[a]:e.image;if(null!==n)o=n.max.x-n.min.x,s=n.max.y-n.min.y,l=n.isBox3?n.max.z-n.min.z:1,c=n.min.x,d=n.min.y,u=n.isBox3?n.min.z:0;else{const t=Math.pow(2,-r);o=Math.floor(h.width*t),s=Math.floor(h.height*t),l=e.isDataArrayTexture?h.depth:e.isData3DTexture?Math.floor(h.depth*t):1,c=0,d=0,u=0}null!==i?(f=i.x,p=i.y,m=i.z):(f=0,p=0,m=0);const _=Ge.convert(t.format),g=Ge.convert(t.type);let v;t.isData3DTexture?(xe.setTexture3D(t,0),v=We.TEXTURE_3D):t.isDataArrayTexture||t.isCompressedArrayTexture?(xe.setTexture2DArray(t,0),v=We.TEXTURE_2D_ARRAY):(xe.setTexture2D(t,0),v=We.TEXTURE_2D),We.pixelStorei(We.UNPACK_FLIP_Y_WEBGL,t.flipY),We.pixelStorei(We.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),We.pixelStorei(We.UNPACK_ALIGNMENT,t.unpackAlignment);const E=We.getParameter(We.UNPACK_ROW_LENGTH),S=We.getParameter(We.UNPACK_IMAGE_HEIGHT),M=We.getParameter(We.UNPACK_SKIP_PIXELS),T=We.getParameter(We.UNPACK_SKIP_ROWS),x=We.getParameter(We.UNPACK_SKIP_IMAGES);We.pixelStorei(We.UNPACK_ROW_LENGTH,h.width),We.pixelStorei(We.UNPACK_IMAGE_HEIGHT,h.height),We.pixelStorei(We.UNPACK_SKIP_PIXELS,c),We.pixelStorei(We.UNPACK_SKIP_ROWS,d),We.pixelStorei(We.UNPACK_SKIP_IMAGES,u);const A=e.isDataArrayTexture||e.isData3DTexture,R=t.isDataArrayTexture||t.isData3DTexture;if(e.isDepthTexture){const n=Se.get(e),i=Se.get(t),h=Se.get(n.__renderTarget),_=Se.get(i.__renderTarget);ve.bindFramebuffer(We.READ_FRAMEBUFFER,h.__webglFramebuffer),ve.bindFramebuffer(We.DRAW_FRAMEBUFFER,_.__webglFramebuffer);for(let n=0;ne.start-t.start);let t=0;for(let e=1;e 0\n\tvec4 plane;\n\t#ifdef ALPHA_TO_COVERAGE\n\t\tfloat distanceToPlane, distanceGradient;\n\t\tfloat clipOpacity = 1.0;\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\tclipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\tif ( clipOpacity == 0.0 ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tfloat unionClipOpacity = 1.0;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tdistanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w;\n\t\t\t\tdistanceGradient = fwidth( distanceToPlane ) / 2.0;\n\t\t\t\tunionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane );\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tclipOpacity *= 1.0 - unionClipOpacity;\n\t\t#endif\n\t\tdiffuseColor.a *= clipOpacity;\n\t\tif ( diffuseColor.a == 0.0 ) discard;\n\t#else\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) {\n\t\t\tplane = clippingPlanes[ i ];\n\t\t\tif ( dot( vClipPosition, plane.xyz ) > plane.w ) discard;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t\t#if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES\n\t\t\tbool clipped = true;\n\t\t\t#pragma unroll_loop_start\n\t\t\tfor ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) {\n\t\t\t\tplane = clippingPlanes[ i ];\n\t\t\t\tclipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped;\n\t\t\t}\n\t\t\t#pragma unroll_loop_end\n\t\t\tif ( clipped ) discard;\n\t\t#endif\n\t#endif\n#endif",clipping_planes_pars_fragment:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n\tuniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ];\n#endif",clipping_planes_pars_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvarying vec3 vClipPosition;\n#endif",clipping_planes_vertex:"#if NUM_CLIPPING_PLANES > 0\n\tvClipPosition = - mvPosition.xyz;\n#endif",color_fragment:"#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )\n\tdiffuseColor *= vColor;\n#endif",color_pars_fragment:"#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )\n\tvarying vec4 vColor;\n#endif",color_pars_vertex:"#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvarying vec4 vColor;\n#endif",color_vertex:"#if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA ) || defined( USE_INSTANCING_COLOR ) || defined( USE_BATCHING_COLOR )\n\tvColor = vec4( 1.0 );\n#endif\n#ifdef USE_COLOR_ALPHA\n\tvColor *= color;\n#elif defined( USE_COLOR )\n\tvColor.rgb *= color;\n#endif\n#ifdef USE_INSTANCING_COLOR\n\tvColor.rgb *= instanceColor.rgb;\n#endif\n#ifdef USE_BATCHING_COLOR\n\tvColor *= getBatchingColor( getIndirectIndex( gl_DrawID ) );\n#endif",common:"#define PI 3.141592653589793\n#define PI2 6.283185307179586\n#define PI_HALF 1.5707963267948966\n#define RECIPROCAL_PI 0.3183098861837907\n#define RECIPROCAL_PI2 0.15915494309189535\n#define EPSILON 1e-6\n#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\n#define whiteComplement( a ) ( 1.0 - saturate( a ) )\nfloat pow2( const in float x ) { return x*x; }\nvec3 pow2( const in vec3 x ) { return x*x; }\nfloat pow3( const in float x ) { return x*x*x; }\nfloat pow4( const in float x ) { float x2 = x*x; return x2*x2; }\nfloat max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); }\nfloat average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); }\nhighp float rand( const in vec2 uv ) {\n\tconst highp float a = 12.9898, b = 78.233, c = 43758.5453;\n\thighp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI );\n\treturn fract( sin( sn ) * c );\n}\n#ifdef HIGH_PRECISION\n\tfloat precisionSafeLength( vec3 v ) { return length( v ); }\n#else\n\tfloat precisionSafeLength( vec3 v ) {\n\t\tfloat maxComponent = max3( abs( v ) );\n\t\treturn length( v / maxComponent ) * maxComponent;\n\t}\n#endif\nstruct IncidentLight {\n\tvec3 color;\n\tvec3 direction;\n\tbool visible;\n};\nstruct ReflectedLight {\n\tvec3 directDiffuse;\n\tvec3 directSpecular;\n\tvec3 indirectDiffuse;\n\tvec3 indirectSpecular;\n};\n#ifdef USE_ALPHAHASH\n\tvarying vec3 vPosition;\n#endif\nvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n}\nvec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {\n\treturn normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );\n}\nbool isPerspectiveMatrix( mat4 m ) {\n\treturn m[ 2 ][ 3 ] == - 1.0;\n}\nvec2 equirectUv( in vec3 dir ) {\n\tfloat u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5;\n\tfloat v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5;\n\treturn vec2( u, v );\n}\nvec3 BRDF_Lambert( const in vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\nvec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n}\nfloat F_Schlick( const in float f0, const in float f90, const in float dotVH ) {\n\tfloat fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH );\n\treturn f0 * ( 1.0 - fresnel ) + ( f90 * fresnel );\n} // validated",cube_uv_reflection_fragment:"#ifdef ENVMAP_TYPE_CUBE_UV\n\t#define cubeUV_minMipLevel 4.0\n\t#define cubeUV_minTileSize 16.0\n\tfloat getFace( vec3 direction ) {\n\t\tvec3 absDirection = abs( direction );\n\t\tfloat face = - 1.0;\n\t\tif ( absDirection.x > absDirection.z ) {\n\t\t\tif ( absDirection.x > absDirection.y )\n\t\t\t\tface = direction.x > 0.0 ? 0.0 : 3.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t} else {\n\t\t\tif ( absDirection.z > absDirection.y )\n\t\t\t\tface = direction.z > 0.0 ? 2.0 : 5.0;\n\t\t\telse\n\t\t\t\tface = direction.y > 0.0 ? 1.0 : 4.0;\n\t\t}\n\t\treturn face;\n\t}\n\tvec2 getUV( vec3 direction, float face ) {\n\t\tvec2 uv;\n\t\tif ( face == 0.0 ) {\n\t\t\tuv = vec2( direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 1.0 ) {\n\t\t\tuv = vec2( - direction.x, - direction.z ) / abs( direction.y );\n\t\t} else if ( face == 2.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.y ) / abs( direction.z );\n\t\t} else if ( face == 3.0 ) {\n\t\t\tuv = vec2( - direction.z, direction.y ) / abs( direction.x );\n\t\t} else if ( face == 4.0 ) {\n\t\t\tuv = vec2( - direction.x, direction.z ) / abs( direction.y );\n\t\t} else {\n\t\t\tuv = vec2( direction.x, direction.y ) / abs( direction.z );\n\t\t}\n\t\treturn 0.5 * ( uv + 1.0 );\n\t}\n\tvec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) {\n\t\tfloat face = getFace( direction );\n\t\tfloat filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 );\n\t\tmipInt = max( mipInt, cubeUV_minMipLevel );\n\t\tfloat faceSize = exp2( mipInt );\n\t\thighp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0;\n\t\tif ( face > 2.0 ) {\n\t\t\tuv.y += faceSize;\n\t\t\tface -= 3.0;\n\t\t}\n\t\tuv.x += face * faceSize;\n\t\tuv.x += filterInt * 3.0 * cubeUV_minTileSize;\n\t\tuv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize );\n\t\tuv.x *= CUBEUV_TEXEL_WIDTH;\n\t\tuv.y *= CUBEUV_TEXEL_HEIGHT;\n\t\t#ifdef texture2DGradEXT\n\t\t\treturn texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb;\n\t\t#else\n\t\t\treturn texture2D( envMap, uv ).rgb;\n\t\t#endif\n\t}\n\t#define cubeUV_r0 1.0\n\t#define cubeUV_m0 - 2.0\n\t#define cubeUV_r1 0.8\n\t#define cubeUV_m1 - 1.0\n\t#define cubeUV_r4 0.4\n\t#define cubeUV_m4 2.0\n\t#define cubeUV_r5 0.305\n\t#define cubeUV_m5 3.0\n\t#define cubeUV_r6 0.21\n\t#define cubeUV_m6 4.0\n\tfloat roughnessToMip( float roughness ) {\n\t\tfloat mip = 0.0;\n\t\tif ( roughness >= cubeUV_r1 ) {\n\t\t\tmip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0;\n\t\t} else if ( roughness >= cubeUV_r4 ) {\n\t\t\tmip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1;\n\t\t} else if ( roughness >= cubeUV_r5 ) {\n\t\t\tmip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4;\n\t\t} else if ( roughness >= cubeUV_r6 ) {\n\t\t\tmip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5;\n\t\t} else {\n\t\t\tmip = - 2.0 * log2( 1.16 * roughness );\t\t}\n\t\treturn mip;\n\t}\n\tvec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) {\n\t\tfloat mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP );\n\t\tfloat mipF = fract( mip );\n\t\tfloat mipInt = floor( mip );\n\t\tvec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt );\n\t\tif ( mipF == 0.0 ) {\n\t\t\treturn vec4( color0, 1.0 );\n\t\t} else {\n\t\t\tvec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 );\n\t\t\treturn vec4( mix( color0, color1, mipF ), 1.0 );\n\t\t}\n\t}\n#endif",defaultnormal_vertex:"vec3 transformedNormal = objectNormal;\n#ifdef USE_TANGENT\n\tvec3 transformedTangent = objectTangent;\n#endif\n#ifdef USE_BATCHING\n\tmat3 bm = mat3( batchingMatrix );\n\ttransformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) );\n\ttransformedNormal = bm * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = bm * transformedTangent;\n\t#endif\n#endif\n#ifdef USE_INSTANCING\n\tmat3 im = mat3( instanceMatrix );\n\ttransformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) );\n\ttransformedNormal = im * transformedNormal;\n\t#ifdef USE_TANGENT\n\t\ttransformedTangent = im * transformedTangent;\n\t#endif\n#endif\ntransformedNormal = normalMatrix * transformedNormal;\n#ifdef FLIP_SIDED\n\ttransformedNormal = - transformedNormal;\n#endif\n#ifdef USE_TANGENT\n\ttransformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz;\n\t#ifdef FLIP_SIDED\n\t\ttransformedTangent = - transformedTangent;\n\t#endif\n#endif",displacementmap_pars_vertex:"#ifdef USE_DISPLACEMENTMAP\n\tuniform sampler2D displacementMap;\n\tuniform float displacementScale;\n\tuniform float displacementBias;\n#endif",displacementmap_vertex:"#ifdef USE_DISPLACEMENTMAP\n\ttransformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias );\n#endif",emissivemap_fragment:"#ifdef USE_EMISSIVEMAP\n\tvec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE_EMISSIVE\n\t\temissiveColor = sRGBTransferEOTF( emissiveColor );\n\t#endif\n\ttotalEmissiveRadiance *= emissiveColor.rgb;\n#endif",emissivemap_pars_fragment:"#ifdef USE_EMISSIVEMAP\n\tuniform sampler2D emissiveMap;\n#endif",colorspace_fragment:"gl_FragColor = linearToOutputTexel( gl_FragColor );",colorspace_pars_fragment:"vec4 LinearTransferOETF( in vec4 value ) {\n\treturn value;\n}\nvec4 sRGBTransferEOTF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), value.rgb * 0.0773993808, vec3( lessThanEqual( value.rgb, vec3( 0.04045 ) ) ) ), value.a );\n}\nvec4 sRGBTransferOETF( in vec4 value ) {\n\treturn vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a );\n}",envmap_fragment:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvec3 cameraToFrag;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToFrag = normalize( vWorldPosition - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvec3 reflectVec = reflect( cameraToFrag, worldNormal );\n\t\t#else\n\t\t\tvec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio );\n\t\t#endif\n\t#else\n\t\tvec3 reflectVec = vReflect;\n\t#endif\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) );\n\t\t#ifdef ENVMAP_BLENDING_MULTIPLY\n\t\t\toutgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity );\n\t\t#elif defined( ENVMAP_BLENDING_MIX )\n\t\t\toutgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity );\n\t\t#elif defined( ENVMAP_BLENDING_ADD )\n\t\t\toutgoingLight += envColor.xyz * specularStrength * reflectivity;\n\t\t#endif\n\t#endif\n#endif",envmap_common_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float envMapIntensity;\n\tuniform float flipEnvMap;\n\tuniform mat3 envMapRotation;\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tuniform samplerCube envMap;\n\t#else\n\t\tuniform sampler2D envMap;\n\t#endif\n#endif",envmap_pars_fragment:"#ifdef USE_ENVMAP\n\tuniform float reflectivity;\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\tvarying vec3 vWorldPosition;\n\t\tuniform float refractionRatio;\n\t#else\n\t\tvarying vec3 vReflect;\n\t#endif\n#endif",envmap_pars_vertex:"#ifdef USE_ENVMAP\n\t#if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT )\n\t\t#define ENV_WORLDPOS\n\t#endif\n\t#ifdef ENV_WORLDPOS\n\t\t\n\t\tvarying vec3 vWorldPosition;\n\t#else\n\t\tvarying vec3 vReflect;\n\t\tuniform float refractionRatio;\n\t#endif\n#endif",envmap_physical_pars_fragment:"#ifdef USE_ENVMAP\n\tvec3 getIBLIrradiance( const in vec3 normal ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 );\n\t\t\treturn PI * envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\tvec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) {\n\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\tvec3 reflectVec = reflect( - viewDir, normal );\n\t\t\treflectVec = normalize( mix( reflectVec, normal, pow4( roughness ) ) );\n\t\t\treflectVec = inverseTransformDirection( reflectVec, viewMatrix );\n\t\t\tvec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness );\n\t\t\treturn envMapColor.rgb * envMapIntensity;\n\t\t#else\n\t\t\treturn vec3( 0.0 );\n\t\t#endif\n\t}\n\t#ifdef USE_ANISOTROPY\n\t\tvec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) {\n\t\t\t#ifdef ENVMAP_TYPE_CUBE_UV\n\t\t\t\tvec3 bentNormal = cross( bitangent, viewDir );\n\t\t\t\tbentNormal = normalize( cross( bentNormal, bitangent ) );\n\t\t\t\tbentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) );\n\t\t\t\treturn getIBLRadiance( viewDir, bentNormal, roughness );\n\t\t\t#else\n\t\t\t\treturn vec3( 0.0 );\n\t\t\t#endif\n\t\t}\n\t#endif\n#endif",envmap_vertex:"#ifdef USE_ENVMAP\n\t#ifdef ENV_WORLDPOS\n\t\tvWorldPosition = worldPosition.xyz;\n\t#else\n\t\tvec3 cameraToVertex;\n\t\tif ( isOrthographic ) {\n\t\t\tcameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) );\n\t\t} else {\n\t\t\tcameraToVertex = normalize( worldPosition.xyz - cameraPosition );\n\t\t}\n\t\tvec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\t\t#ifdef ENVMAP_MODE_REFLECTION\n\t\t\tvReflect = reflect( cameraToVertex, worldNormal );\n\t\t#else\n\t\t\tvReflect = refract( cameraToVertex, worldNormal, refractionRatio );\n\t\t#endif\n\t#endif\n#endif",fog_vertex:"#ifdef USE_FOG\n\tvFogDepth = - mvPosition.z;\n#endif",fog_pars_vertex:"#ifdef USE_FOG\n\tvarying float vFogDepth;\n#endif",fog_fragment:"#ifdef USE_FOG\n\t#ifdef FOG_EXP2\n\t\tfloat fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth );\n\t#else\n\t\tfloat fogFactor = smoothstep( fogNear, fogFar, vFogDepth );\n\t#endif\n\tgl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor );\n#endif",fog_pars_fragment:"#ifdef USE_FOG\n\tuniform vec3 fogColor;\n\tvarying float vFogDepth;\n\t#ifdef FOG_EXP2\n\t\tuniform float fogDensity;\n\t#else\n\t\tuniform float fogNear;\n\t\tuniform float fogFar;\n\t#endif\n#endif",gradientmap_pars_fragment:"#ifdef USE_GRADIENTMAP\n\tuniform sampler2D gradientMap;\n#endif\nvec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) {\n\tfloat dotNL = dot( normal, lightDirection );\n\tvec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 );\n\t#ifdef USE_GRADIENTMAP\n\t\treturn vec3( texture2D( gradientMap, coord ).r );\n\t#else\n\t\tvec2 fw = fwidth( coord ) * 0.5;\n\t\treturn mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) );\n\t#endif\n}",lightmap_pars_fragment:"#ifdef USE_LIGHTMAP\n\tuniform sampler2D lightMap;\n\tuniform float lightMapIntensity;\n#endif",lights_lambert_fragment:"LambertMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularStrength = specularStrength;",lights_lambert_pars_fragment:"varying vec3 vViewPosition;\nstruct LambertMaterial {\n\tvec3 diffuseColor;\n\tfloat specularStrength;\n};\nvoid RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Lambert\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Lambert",lights_pars_begin:"uniform bool receiveShadow;\nuniform vec3 ambientLightColor;\n#if defined( USE_LIGHT_PROBES )\n\tuniform vec3 lightProbe[ 9 ];\n#endif\nvec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) {\n\tfloat x = normal.x, y = normal.y, z = normal.z;\n\tvec3 result = shCoefficients[ 0 ] * 0.886227;\n\tresult += shCoefficients[ 1 ] * 2.0 * 0.511664 * y;\n\tresult += shCoefficients[ 2 ] * 2.0 * 0.511664 * z;\n\tresult += shCoefficients[ 3 ] * 2.0 * 0.511664 * x;\n\tresult += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y;\n\tresult += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z;\n\tresult += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 );\n\tresult += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z;\n\tresult += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y );\n\treturn result;\n}\nvec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) {\n\tvec3 worldNormal = inverseTransformDirection( normal, viewMatrix );\n\tvec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe );\n\treturn irradiance;\n}\nvec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {\n\tvec3 irradiance = ambientLightColor;\n\treturn irradiance;\n}\nfloat getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) {\n\tfloat distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 );\n\tif ( cutoffDistance > 0.0 ) {\n\t\tdistanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) );\n\t}\n\treturn distanceFalloff;\n}\nfloat getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) {\n\treturn smoothstep( coneCosine, penumbraCosine, angleCosine );\n}\n#if NUM_DIR_LIGHTS > 0\n\tstruct DirectionalLight {\n\t\tvec3 direction;\n\t\tvec3 color;\n\t};\n\tuniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ];\n\tvoid getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) {\n\t\tlight.color = directionalLight.color;\n\t\tlight.direction = directionalLight.direction;\n\t\tlight.visible = true;\n\t}\n#endif\n#if NUM_POINT_LIGHTS > 0\n\tstruct PointLight {\n\t\tvec3 position;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t};\n\tuniform PointLight pointLights[ NUM_POINT_LIGHTS ];\n\tvoid getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = pointLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat lightDistance = length( lVector );\n\t\tlight.color = pointLight.color;\n\t\tlight.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay );\n\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t}\n#endif\n#if NUM_SPOT_LIGHTS > 0\n\tstruct SpotLight {\n\t\tvec3 position;\n\t\tvec3 direction;\n\t\tvec3 color;\n\t\tfloat distance;\n\t\tfloat decay;\n\t\tfloat coneCos;\n\t\tfloat penumbraCos;\n\t};\n\tuniform SpotLight spotLights[ NUM_SPOT_LIGHTS ];\n\tvoid getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) {\n\t\tvec3 lVector = spotLight.position - geometryPosition;\n\t\tlight.direction = normalize( lVector );\n\t\tfloat angleCos = dot( light.direction, spotLight.direction );\n\t\tfloat spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos );\n\t\tif ( spotAttenuation > 0.0 ) {\n\t\t\tfloat lightDistance = length( lVector );\n\t\t\tlight.color = spotLight.color * spotAttenuation;\n\t\t\tlight.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay );\n\t\t\tlight.visible = ( light.color != vec3( 0.0 ) );\n\t\t} else {\n\t\t\tlight.color = vec3( 0.0 );\n\t\t\tlight.visible = false;\n\t\t}\n\t}\n#endif\n#if NUM_RECT_AREA_LIGHTS > 0\n\tstruct RectAreaLight {\n\t\tvec3 color;\n\t\tvec3 position;\n\t\tvec3 halfWidth;\n\t\tvec3 halfHeight;\n\t};\n\tuniform sampler2D ltc_1;\tuniform sampler2D ltc_2;\n\tuniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];\n#endif\n#if NUM_HEMI_LIGHTS > 0\n\tstruct HemisphereLight {\n\t\tvec3 direction;\n\t\tvec3 skyColor;\n\t\tvec3 groundColor;\n\t};\n\tuniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ];\n\tvec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) {\n\t\tfloat dotNL = dot( normal, hemiLight.direction );\n\t\tfloat hemiDiffuseWeight = 0.5 * dotNL + 0.5;\n\t\tvec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight );\n\t\treturn irradiance;\n\t}\n#endif",lights_toon_fragment:"ToonMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;",lights_toon_pars_fragment:"varying vec3 vViewPosition;\nstruct ToonMaterial {\n\tvec3 diffuseColor;\n};\nvoid RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\nvoid RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_Toon\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Toon",lights_phong_fragment:"BlinnPhongMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.specularColor = specular;\nmaterial.specularShininess = shininess;\nmaterial.specularStrength = specularStrength;",lights_phong_pars_fragment:"varying vec3 vViewPosition;\nstruct BlinnPhongMaterial {\n\tvec3 diffuseColor;\n\tvec3 specularColor;\n\tfloat specularShininess;\n\tfloat specularStrength;\n};\nvoid RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n\treflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength;\n}\nvoid RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) {\n\treflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor );\n}\n#define RE_Direct\t\t\t\tRE_Direct_BlinnPhong\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_BlinnPhong",lights_physical_fragment:"PhysicalMaterial material;\nmaterial.diffuseColor = diffuseColor.rgb;\nmaterial.diffuseContribution = diffuseColor.rgb * ( 1.0 - metalnessFactor );\nmaterial.metalness = metalnessFactor;\nvec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) );\nfloat geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z );\nmaterial.roughness = max( roughnessFactor, 0.0525 );material.roughness += geometryRoughness;\nmaterial.roughness = min( material.roughness, 1.0 );\n#ifdef IOR\n\tmaterial.ior = ior;\n\t#ifdef USE_SPECULAR\n\t\tfloat specularIntensityFactor = specularIntensity;\n\t\tvec3 specularColorFactor = specularColor;\n\t\t#ifdef USE_SPECULAR_COLORMAP\n\t\t\tspecularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb;\n\t\t#endif\n\t\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\t\tspecularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a;\n\t\t#endif\n\t\tmaterial.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor );\n\t#else\n\t\tfloat specularIntensityFactor = 1.0;\n\t\tvec3 specularColorFactor = vec3( 1.0 );\n\t\tmaterial.specularF90 = 1.0;\n\t#endif\n\tmaterial.specularColor = min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor;\n\tmaterial.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n#else\n\tmaterial.specularColor = vec3( 0.04 );\n\tmaterial.specularColorBlended = mix( material.specularColor, diffuseColor.rgb, metalnessFactor );\n\tmaterial.specularF90 = 1.0;\n#endif\n#ifdef USE_CLEARCOAT\n\tmaterial.clearcoat = clearcoat;\n\tmaterial.clearcoatRoughness = clearcoatRoughness;\n\tmaterial.clearcoatF0 = vec3( 0.04 );\n\tmaterial.clearcoatF90 = 1.0;\n\t#ifdef USE_CLEARCOATMAP\n\t\tmaterial.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x;\n\t#endif\n\t#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\t\tmaterial.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y;\n\t#endif\n\tmaterial.clearcoat = saturate( material.clearcoat );\tmaterial.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 );\n\tmaterial.clearcoatRoughness += geometryRoughness;\n\tmaterial.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 );\n#endif\n#ifdef USE_DISPERSION\n\tmaterial.dispersion = dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tmaterial.iridescence = iridescence;\n\tmaterial.iridescenceIOR = iridescenceIOR;\n\t#ifdef USE_IRIDESCENCEMAP\n\t\tmaterial.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r;\n\t#endif\n\t#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\t\tmaterial.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum;\n\t#else\n\t\tmaterial.iridescenceThickness = iridescenceThicknessMaximum;\n\t#endif\n#endif\n#ifdef USE_SHEEN\n\tmaterial.sheenColor = sheenColor;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tmaterial.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb;\n\t#endif\n\tmaterial.sheenRoughness = clamp( sheenRoughness, 0.0001, 1.0 );\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tmaterial.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\t#ifdef USE_ANISOTROPYMAP\n\t\tmat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x );\n\t\tvec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb;\n\t\tvec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b;\n\t#else\n\t\tvec2 anisotropyV = anisotropyVector;\n\t#endif\n\tmaterial.anisotropy = length( anisotropyV );\n\tif( material.anisotropy == 0.0 ) {\n\t\tanisotropyV = vec2( 1.0, 0.0 );\n\t} else {\n\t\tanisotropyV /= material.anisotropy;\n\t\tmaterial.anisotropy = saturate( material.anisotropy );\n\t}\n\tmaterial.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) );\n\tmaterial.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y;\n\tmaterial.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y;\n#endif",lights_physical_pars_fragment:"uniform sampler2D dfgLUT;\nstruct PhysicalMaterial {\n\tvec3 diffuseColor;\n\tvec3 diffuseContribution;\n\tvec3 specularColor;\n\tvec3 specularColorBlended;\n\tfloat roughness;\n\tfloat metalness;\n\tfloat specularF90;\n\tfloat dispersion;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat clearcoat;\n\t\tfloat clearcoatRoughness;\n\t\tvec3 clearcoatF0;\n\t\tfloat clearcoatF90;\n\t#endif\n\t#ifdef USE_IRIDESCENCE\n\t\tfloat iridescence;\n\t\tfloat iridescenceIOR;\n\t\tfloat iridescenceThickness;\n\t\tvec3 iridescenceFresnel;\n\t\tvec3 iridescenceF0;\n\t\tvec3 iridescenceFresnelDielectric;\n\t\tvec3 iridescenceFresnelMetallic;\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tvec3 sheenColor;\n\t\tfloat sheenRoughness;\n\t#endif\n\t#ifdef IOR\n\t\tfloat ior;\n\t#endif\n\t#ifdef USE_TRANSMISSION\n\t\tfloat transmission;\n\t\tfloat transmissionAlpha;\n\t\tfloat thickness;\n\t\tfloat attenuationDistance;\n\t\tvec3 attenuationColor;\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat anisotropy;\n\t\tfloat alphaT;\n\t\tvec3 anisotropyT;\n\t\tvec3 anisotropyB;\n\t#endif\n};\nvec3 clearcoatSpecularDirect = vec3( 0.0 );\nvec3 clearcoatSpecularIndirect = vec3( 0.0 );\nvec3 sheenSpecularDirect = vec3( 0.0 );\nvec3 sheenSpecularIndirect = vec3(0.0 );\nvec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) {\n float x = clamp( 1.0 - dotVH, 0.0, 1.0 );\n float x2 = x * x;\n float x5 = clamp( x * x2 * x2, 0.0, 0.9999 );\n return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 );\n}\nfloat V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) {\n\tfloat a2 = pow2( alpha );\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\treturn 0.5 / max( gv + gl, EPSILON );\n}\nfloat D_GGX( const in float alpha, const in float dotNH ) {\n\tfloat a2 = pow2( alpha );\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0;\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n}\n#ifdef USE_ANISOTROPY\n\tfloat V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) {\n\t\tfloat gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) );\n\t\tfloat gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) );\n\t\tfloat v = 0.5 / ( gv + gl );\n\t\treturn v;\n\t}\n\tfloat D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) {\n\t\tfloat a2 = alphaT * alphaB;\n\t\thighp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH );\n\t\thighp float v2 = dot( v, v );\n\t\tfloat w2 = a2 / v2;\n\t\treturn RECIPROCAL_PI * a2 * pow2 ( w2 );\n\t}\n#endif\n#ifdef USE_CLEARCOAT\n\tvec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) {\n\t\tvec3 f0 = material.clearcoatF0;\n\t\tfloat f90 = material.clearcoatF90;\n\t\tfloat roughness = material.clearcoatRoughness;\n\t\tfloat alpha = pow2( roughness );\n\t\tvec3 halfDir = normalize( lightDir + viewDir );\n\t\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\t\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\t\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\t\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\t\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t\treturn F * ( V * D );\n\t}\n#endif\nvec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 f0 = material.specularColorBlended;\n\tfloat f90 = material.specularF90;\n\tfloat roughness = material.roughness;\n\tfloat alpha = pow2( roughness );\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotVH = saturate( dot( viewDir, halfDir ) );\n\tvec3 F = F_Schlick( f0, f90, dotVH );\n\t#ifdef USE_IRIDESCENCE\n\t\tF = mix( F, material.iridescenceFresnel, material.iridescence );\n\t#endif\n\t#ifdef USE_ANISOTROPY\n\t\tfloat dotTL = dot( material.anisotropyT, lightDir );\n\t\tfloat dotTV = dot( material.anisotropyT, viewDir );\n\t\tfloat dotTH = dot( material.anisotropyT, halfDir );\n\t\tfloat dotBL = dot( material.anisotropyB, lightDir );\n\t\tfloat dotBV = dot( material.anisotropyB, viewDir );\n\t\tfloat dotBH = dot( material.anisotropyB, halfDir );\n\t\tfloat V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL );\n\t\tfloat D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH );\n\t#else\n\t\tfloat V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n\t\tfloat D = D_GGX( alpha, dotNH );\n\t#endif\n\treturn F * ( V * D );\n}\nvec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {\n\tconst float LUT_SIZE = 64.0;\n\tconst float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;\n\tconst float LUT_BIAS = 0.5 / LUT_SIZE;\n\tfloat dotNV = saturate( dot( N, V ) );\n\tvec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );\n\tuv = uv * LUT_SCALE + LUT_BIAS;\n\treturn uv;\n}\nfloat LTC_ClippedSphereFormFactor( const in vec3 f ) {\n\tfloat l = length( f );\n\treturn max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );\n}\nvec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {\n\tfloat x = dot( v1, v2 );\n\tfloat y = abs( x );\n\tfloat a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;\n\tfloat b = 3.4175940 + ( 4.1616724 + y ) * y;\n\tfloat v = a / b;\n\tfloat theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;\n\treturn cross( v1, v2 ) * theta_sintheta;\n}\nvec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) {\n\tvec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ];\n\tvec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ];\n\tvec3 lightNormal = cross( v1, v2 );\n\tif( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 );\n\tvec3 T1, T2;\n\tT1 = normalize( V - N * dot( V, N ) );\n\tT2 = - cross( N, T1 );\n\tmat3 mat = mInv * transpose( mat3( T1, T2, N ) );\n\tvec3 coords[ 4 ];\n\tcoords[ 0 ] = mat * ( rectCoords[ 0 ] - P );\n\tcoords[ 1 ] = mat * ( rectCoords[ 1 ] - P );\n\tcoords[ 2 ] = mat * ( rectCoords[ 2 ] - P );\n\tcoords[ 3 ] = mat * ( rectCoords[ 3 ] - P );\n\tcoords[ 0 ] = normalize( coords[ 0 ] );\n\tcoords[ 1 ] = normalize( coords[ 1 ] );\n\tcoords[ 2 ] = normalize( coords[ 2 ] );\n\tcoords[ 3 ] = normalize( coords[ 3 ] );\n\tvec3 vectorFormFactor = vec3( 0.0 );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] );\n\tvectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );\n\tfloat result = LTC_ClippedSphereFormFactor( vectorFormFactor );\n\treturn vec3( result );\n}\n#if defined( USE_SHEEN )\nfloat D_Charlie( float roughness, float dotNH ) {\n\tfloat alpha = pow2( roughness );\n\tfloat invAlpha = 1.0 / alpha;\n\tfloat cos2h = dotNH * dotNH;\n\tfloat sin2h = max( 1.0 - cos2h, 0.0078125 );\n\treturn ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI );\n}\nfloat V_Neubelt( float dotNV, float dotNL ) {\n\treturn saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) );\n}\nvec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) {\n\tvec3 halfDir = normalize( lightDir + viewDir );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat D = D_Charlie( sheenRoughness, dotNH );\n\tfloat V = V_Neubelt( dotNV, dotNL );\n\treturn sheenColor * ( D * V );\n}\n#endif\nfloat IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tfloat r2 = roughness * roughness;\n\tfloat rInv = 1.0 / ( roughness + 0.1 );\n\tfloat a = -1.9362 + 1.0678 * roughness + 0.4573 * r2 - 0.8469 * rInv;\n\tfloat b = -0.6014 + 0.5538 * roughness - 0.4670 * r2 - 0.1255 * rInv;\n\tfloat DG = exp( a * dotNV + b );\n\treturn saturate( DG );\n}\nvec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) {\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n\treturn specularColor * fab.x + specularF90 * fab.y;\n}\n#ifdef USE_IRIDESCENCE\nvoid computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#else\nvoid computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) {\n#endif\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 fab = texture2D( dfgLUT, vec2( roughness, dotNV ) ).rg;\n\t#ifdef USE_IRIDESCENCE\n\t\tvec3 Fr = mix( specularColor, iridescenceF0, iridescence );\n\t#else\n\t\tvec3 Fr = specularColor;\n\t#endif\n\tvec3 FssEss = Fr * fab.x + specularF90 * fab.y;\n\tfloat Ess = fab.x + fab.y;\n\tfloat Ems = 1.0 - Ess;\n\tvec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619;\tvec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg );\n\tsingleScatter += FssEss;\n\tmultiScatter += Fms * Ems;\n}\nvec3 BRDF_GGX_Multiscatter( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) {\n\tvec3 singleScatter = BRDF_GGX( lightDir, viewDir, normal, material );\n\tfloat dotNL = saturate( dot( normal, lightDir ) );\n\tfloat dotNV = saturate( dot( normal, viewDir ) );\n\tvec2 dfgV = texture2D( dfgLUT, vec2( material.roughness, dotNV ) ).rg;\n\tvec2 dfgL = texture2D( dfgLUT, vec2( material.roughness, dotNL ) ).rg;\n\tvec3 FssEss_V = material.specularColorBlended * dfgV.x + material.specularF90 * dfgV.y;\n\tvec3 FssEss_L = material.specularColorBlended * dfgL.x + material.specularF90 * dfgL.y;\n\tfloat Ess_V = dfgV.x + dfgV.y;\n\tfloat Ess_L = dfgL.x + dfgL.y;\n\tfloat Ems_V = 1.0 - Ess_V;\n\tfloat Ems_L = 1.0 - Ess_L;\n\tvec3 Favg = material.specularColorBlended + ( 1.0 - material.specularColorBlended ) * 0.047619;\n\tvec3 Fms = FssEss_V * FssEss_L * Favg / ( 1.0 - Ems_V * Ems_L * Favg + EPSILON );\n\tfloat compensationFactor = Ems_V * Ems_L;\n\tvec3 multiScatter = Fms * compensationFactor;\n\treturn singleScatter + multiScatter;\n}\n#if NUM_RECT_AREA_LIGHTS > 0\n\tvoid RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\t\tvec3 normal = geometryNormal;\n\t\tvec3 viewDir = geometryViewDir;\n\t\tvec3 position = geometryPosition;\n\t\tvec3 lightPos = rectAreaLight.position;\n\t\tvec3 halfWidth = rectAreaLight.halfWidth;\n\t\tvec3 halfHeight = rectAreaLight.halfHeight;\n\t\tvec3 lightColor = rectAreaLight.color;\n\t\tfloat roughness = material.roughness;\n\t\tvec3 rectCoords[ 4 ];\n\t\trectCoords[ 0 ] = lightPos + halfWidth - halfHeight;\t\trectCoords[ 1 ] = lightPos - halfWidth - halfHeight;\n\t\trectCoords[ 2 ] = lightPos - halfWidth + halfHeight;\n\t\trectCoords[ 3 ] = lightPos + halfWidth + halfHeight;\n\t\tvec2 uv = LTC_Uv( normal, viewDir, roughness );\n\t\tvec4 t1 = texture2D( ltc_1, uv );\n\t\tvec4 t2 = texture2D( ltc_2, uv );\n\t\tmat3 mInv = mat3(\n\t\t\tvec3( t1.x, 0, t1.y ),\n\t\t\tvec3( 0, 1, 0 ),\n\t\t\tvec3( t1.z, 0, t1.w )\n\t\t);\n\t\tvec3 fresnel = ( material.specularColorBlended * t2.x + ( material.specularF90 - material.specularColorBlended ) * t2.y );\n\t\treflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );\n\t\treflectedLight.directDiffuse += lightColor * material.diffuseContribution * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );\n\t\t#ifdef USE_CLEARCOAT\n\t\t\tvec3 Ncc = geometryClearcoatNormal;\n\t\t\tvec2 uvClearcoat = LTC_Uv( Ncc, viewDir, material.clearcoatRoughness );\n\t\t\tvec4 t1Clearcoat = texture2D( ltc_1, uvClearcoat );\n\t\t\tvec4 t2Clearcoat = texture2D( ltc_2, uvClearcoat );\n\t\t\tmat3 mInvClearcoat = mat3(\n\t\t\t\tvec3( t1Clearcoat.x, 0, t1Clearcoat.y ),\n\t\t\t\tvec3( 0, 1, 0 ),\n\t\t\t\tvec3( t1Clearcoat.z, 0, t1Clearcoat.w )\n\t\t\t);\n\t\t\tvec3 fresnelClearcoat = material.clearcoatF0 * t2Clearcoat.x + ( material.clearcoatF90 - material.clearcoatF0 ) * t2Clearcoat.y;\n\t\t\tclearcoatSpecularDirect += lightColor * fresnelClearcoat * LTC_Evaluate( Ncc, viewDir, position, mInvClearcoat, rectCoords );\n\t\t#endif\n\t}\n#endif\nvoid RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tfloat dotNL = saturate( dot( geometryNormal, directLight.direction ) );\n\tvec3 irradiance = dotNL * directLight.color;\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) );\n\t\tvec3 ccIrradiance = dotNLcc * directLight.color;\n\t\tclearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material );\n\t#endif\n\t#ifdef USE_SHEEN\n \n \t\tsheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness );\n \n \t\tfloat sheenAlbedoV = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n \t\tfloat sheenAlbedoL = IBLSheenBRDF( geometryNormal, directLight.direction, material.sheenRoughness );\n \n \t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * max( sheenAlbedoV, sheenAlbedoL );\n \n \t\tirradiance *= sheenEnergyComp;\n \n \t#endif\n\treflectedLight.directSpecular += irradiance * BRDF_GGX_Multiscatter( directLight.direction, geometryViewDir, geometryNormal, material );\n\treflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseContribution );\n}\nvoid RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) {\n\tvec3 diffuse = irradiance * BRDF_Lambert( material.diffuseContribution );\n\t#ifdef USE_SHEEN\n\t\tfloat sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n\t\tdiffuse *= sheenEnergyComp;\n\t#endif\n\treflectedLight.indirectDiffuse += diffuse;\n}\nvoid RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) {\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness );\n\t#endif\n\t#ifdef USE_SHEEN\n\t\tsheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness ) * RECIPROCAL_PI;\n \t#endif\n\tvec3 singleScatteringDielectric = vec3( 0.0 );\n\tvec3 multiScatteringDielectric = vec3( 0.0 );\n\tvec3 singleScatteringMetallic = vec3( 0.0 );\n\tvec3 multiScatteringMetallic = vec3( 0.0 );\n\t#ifdef USE_IRIDESCENCE\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnelDielectric, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n\t\tcomputeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.iridescence, material.iridescenceFresnelMetallic, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n\t#else\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScatteringDielectric, multiScatteringDielectric );\n\t\tcomputeMultiscattering( geometryNormal, geometryViewDir, material.diffuseColor, material.specularF90, material.roughness, singleScatteringMetallic, multiScatteringMetallic );\n\t#endif\n\tvec3 singleScattering = mix( singleScatteringDielectric, singleScatteringMetallic, material.metalness );\n\tvec3 multiScattering = mix( multiScatteringDielectric, multiScatteringMetallic, material.metalness );\n\tvec3 totalScatteringDielectric = singleScatteringDielectric + multiScatteringDielectric;\n\tvec3 diffuse = material.diffuseContribution * ( 1.0 - totalScatteringDielectric );\n\tvec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI;\n\tvec3 indirectSpecular = radiance * singleScattering;\n\tindirectSpecular += multiScattering * cosineWeightedIrradiance;\n\tvec3 indirectDiffuse = diffuse * cosineWeightedIrradiance;\n\t#ifdef USE_SHEEN\n\t\tfloat sheenAlbedo = IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness );\n\t\tfloat sheenEnergyComp = 1.0 - max3( material.sheenColor ) * sheenAlbedo;\n\t\tindirectSpecular *= sheenEnergyComp;\n\t\tindirectDiffuse *= sheenEnergyComp;\n\t#endif\n\treflectedLight.indirectSpecular += indirectSpecular;\n\treflectedLight.indirectDiffuse += indirectDiffuse;\n}\n#define RE_Direct\t\t\t\tRE_Direct_Physical\n#define RE_Direct_RectArea\t\tRE_Direct_RectArea_Physical\n#define RE_IndirectDiffuse\t\tRE_IndirectDiffuse_Physical\n#define RE_IndirectSpecular\t\tRE_IndirectSpecular_Physical\nfloat computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) {\n\treturn saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}",lights_fragment_begin:"\nvec3 geometryPosition = - vViewPosition;\nvec3 geometryNormal = normal;\nvec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition );\nvec3 geometryClearcoatNormal = vec3( 0.0 );\n#ifdef USE_CLEARCOAT\n\tgeometryClearcoatNormal = clearcoatNormal;\n#endif\n#ifdef USE_IRIDESCENCE\n\tfloat dotNVi = saturate( dot( normal, geometryViewDir ) );\n\tif ( material.iridescenceThickness == 0.0 ) {\n\t\tmaterial.iridescence = 0.0;\n\t} else {\n\t\tmaterial.iridescence = saturate( material.iridescence );\n\t}\n\tif ( material.iridescence > 0.0 ) {\n\t\tmaterial.iridescenceFresnelDielectric = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor );\n\t\tmaterial.iridescenceFresnelMetallic = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.diffuseColor );\n\t\tmaterial.iridescenceFresnel = mix( material.iridescenceFresnelDielectric, material.iridescenceFresnelMetallic, material.metalness );\n\t\tmaterial.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi );\n\t}\n#endif\nIncidentLight directLight;\n#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct )\n\tPointLight pointLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0\n\tPointLightShadow pointLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {\n\t\tpointLight = pointLights[ i ];\n\t\tgetPointLightInfo( pointLight, geometryPosition, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n\t\tpointLightShadow = pointLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowIntensity, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct )\n\tSpotLight spotLight;\n\tvec4 spotColor;\n\tvec3 spotLightCoord;\n\tbool inSpotLightMap;\n\t#if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {\n\t\tspotLight = spotLights[ i ];\n\t\tgetSpotLightInfo( spotLight, geometryPosition, directLight );\n\t\t#if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX\n\t\t#elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t#define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS\n\t\t#else\n\t\t#define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS )\n\t\t#endif\n\t\t#if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS )\n\t\t\tspotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w;\n\t\t\tinSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) );\n\t\t\tspotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy );\n\t\t\tdirectLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color;\n\t\t#endif\n\t\t#undef SPOT_LIGHT_MAP_INDEX\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\tspotLightShadow = spotLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowIntensity, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct )\n\tDirectionalLight directionalLight;\n\t#if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLightShadow;\n\t#endif\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {\n\t\tdirectionalLight = directionalLights[ i ];\n\t\tgetDirectionalLightInfo( directionalLight, directLight );\n\t\t#if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS )\n\t\tdirectionalLightShadow = directionalLightShadows[ i ];\n\t\tdirectLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowIntensity, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t\t#endif\n\t\tRE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea )\n\tRectAreaLight rectAreaLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {\n\t\trectAreaLight = rectAreaLights[ i ];\n\t\tRE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n\t}\n\t#pragma unroll_loop_end\n#endif\n#if defined( RE_IndirectDiffuse )\n\tvec3 iblIrradiance = vec3( 0.0 );\n\tvec3 irradiance = getAmbientLightIrradiance( ambientLightColor );\n\t#if defined( USE_LIGHT_PROBES )\n\t\tirradiance += getLightProbeIrradiance( lightProbe, geometryNormal );\n\t#endif\n\t#if ( NUM_HEMI_LIGHTS > 0 )\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {\n\t\t\tirradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal );\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if defined( RE_IndirectSpecular )\n\tvec3 radiance = vec3( 0.0 );\n\tvec3 clearcoatRadiance = vec3( 0.0 );\n#endif",lights_fragment_maps:"#if defined( RE_IndirectDiffuse )\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\tvec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity;\n\t\tirradiance += lightMapIrradiance;\n\t#endif\n\t#if defined( USE_ENVMAP ) && defined( ENVMAP_TYPE_CUBE_UV )\n\t\t#if defined( STANDARD ) || defined( LAMBERT ) || defined( PHONG )\n\t\t\tiblIrradiance += getIBLIrradiance( geometryNormal );\n\t\t#endif\n\t#endif\n#endif\n#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular )\n\t#ifdef USE_ANISOTROPY\n\t\tradiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy );\n\t#else\n\t\tradiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness );\n\t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tclearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness );\n\t#endif\n#endif",lights_fragment_end:"#if defined( RE_IndirectDiffuse )\n\t#if defined( LAMBERT ) || defined( PHONG )\n\t\tirradiance += iblIrradiance;\n\t#endif\n\tRE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif\n#if defined( RE_IndirectSpecular )\n\tRE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight );\n#endif",logdepthbuf_fragment:"#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n\tgl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5;\n#endif",logdepthbuf_pars_fragment:"#if defined( USE_LOGARITHMIC_DEPTH_BUFFER )\n\tuniform float logDepthBufFC;\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",logdepthbuf_pars_vertex:"#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n\tvarying float vFragDepth;\n\tvarying float vIsPerspective;\n#endif",logdepthbuf_vertex:"#ifdef USE_LOGARITHMIC_DEPTH_BUFFER\n\tvFragDepth = 1.0 + gl_Position.w;\n\tvIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) );\n#endif",map_fragment:"#ifdef USE_MAP\n\tvec4 sampledDiffuseColor = texture2D( map, vMapUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\tsampledDiffuseColor = sRGBTransferEOTF( sampledDiffuseColor );\n\t#endif\n\tdiffuseColor *= sampledDiffuseColor;\n#endif",map_pars_fragment:"#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif",map_particle_fragment:"#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t#if defined( USE_POINTS_UV )\n\t\tvec2 uv = vUv;\n\t#else\n\t\tvec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tdiffuseColor *= texture2D( map, uv );\n#endif\n#ifdef USE_ALPHAMAP\n\tdiffuseColor.a *= texture2D( alphaMap, uv ).g;\n#endif",map_particle_pars_fragment:"#if defined( USE_POINTS_UV )\n\tvarying vec2 vUv;\n#else\n\t#if defined( USE_MAP ) || defined( USE_ALPHAMAP )\n\t\tuniform mat3 uvTransform;\n\t#endif\n#endif\n#ifdef USE_MAP\n\tuniform sampler2D map;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform sampler2D alphaMap;\n#endif",metalnessmap_fragment:"float metalnessFactor = metalness;\n#ifdef USE_METALNESSMAP\n\tvec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv );\n\tmetalnessFactor *= texelMetalness.b;\n#endif",metalnessmap_pars_fragment:"#ifdef USE_METALNESSMAP\n\tuniform sampler2D metalnessMap;\n#endif",morphinstance_vertex:"#ifdef USE_INSTANCING_MORPH\n\tfloat morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\tfloat morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tmorphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r;\n\t}\n#endif",morphcolor_vertex:"#if defined( USE_MORPHCOLORS )\n\tvColor *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\t#if defined( USE_COLOR_ALPHA )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ];\n\t\t#elif defined( USE_COLOR )\n\t\t\tif ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ];\n\t\t#endif\n\t}\n#endif",morphnormal_vertex:"#ifdef USE_MORPHNORMALS\n\tobjectNormal *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif",morphtarget_pars_vertex:"#ifdef USE_MORPHTARGETS\n\t#ifndef USE_INSTANCING_MORPH\n\t\tuniform float morphTargetBaseInfluence;\n\t\tuniform float morphTargetInfluences[ MORPHTARGETS_COUNT ];\n\t#endif\n\tuniform sampler2DArray morphTargetsTexture;\n\tuniform ivec2 morphTargetsTextureSize;\n\tvec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) {\n\t\tint texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset;\n\t\tint y = texelIndex / morphTargetsTextureSize.x;\n\t\tint x = texelIndex - y * morphTargetsTextureSize.x;\n\t\tivec3 morphUV = ivec3( x, y, morphTargetIndex );\n\t\treturn texelFetch( morphTargetsTexture, morphUV, 0 );\n\t}\n#endif",morphtarget_vertex:"#ifdef USE_MORPHTARGETS\n\ttransformed *= morphTargetBaseInfluence;\n\tfor ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) {\n\t\tif ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ];\n\t}\n#endif",normal_fragment_begin:"float faceDirection = gl_FrontFacing ? 1.0 : - 1.0;\n#ifdef FLAT_SHADED\n\tvec3 fdx = dFdx( vViewPosition );\n\tvec3 fdy = dFdy( vViewPosition );\n\tvec3 normal = normalize( cross( fdx, fdy ) );\n#else\n\tvec3 normal = normalize( vNormal );\n\t#ifdef DOUBLE_SIDED\n\t\tnormal *= faceDirection;\n\t#endif\n#endif\n#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY )\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn = getTangentFrame( - vViewPosition, normal,\n\t\t#if defined( USE_NORMALMAP )\n\t\t\tvNormalMapUv\n\t\t#elif defined( USE_CLEARCOAT_NORMALMAP )\n\t\t\tvClearcoatNormalMapUv\n\t\t#else\n\t\t\tvUv\n\t\t#endif\n\t\t);\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn[0] *= faceDirection;\n\t\ttbn[1] *= faceDirection;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\t#ifdef USE_TANGENT\n\t\tmat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal );\n\t#else\n\t\tmat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv );\n\t#endif\n\t#if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED )\n\t\ttbn2[0] *= faceDirection;\n\t\ttbn2[1] *= faceDirection;\n\t#endif\n#endif\nvec3 nonPerturbedNormal = normal;",normal_fragment_maps:"#ifdef USE_NORMALMAP_OBJECTSPACE\n\tnormal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\t#ifdef FLIP_SIDED\n\t\tnormal = - normal;\n\t#endif\n\t#ifdef DOUBLE_SIDED\n\t\tnormal = normal * faceDirection;\n\t#endif\n\tnormal = normalize( normalMatrix * normal );\n#elif defined( USE_NORMALMAP_TANGENTSPACE )\n\tvec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;\n\tmapN.xy *= normalScale;\n\tnormal = normalize( tbn * mapN );\n#elif defined( USE_BUMPMAP )\n\tnormal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection );\n#endif",normal_pars_fragment:"#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif",normal_pars_vertex:"#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n\t#ifdef USE_TANGENT\n\t\tvarying vec3 vTangent;\n\t\tvarying vec3 vBitangent;\n\t#endif\n#endif",normal_vertex:"#ifndef FLAT_SHADED\n\tvNormal = normalize( transformedNormal );\n\t#ifdef USE_TANGENT\n\t\tvTangent = normalize( transformedTangent );\n\t\tvBitangent = normalize( cross( vNormal, vTangent ) * tangent.w );\n\t#endif\n#endif",normalmap_pars_fragment:"#ifdef USE_NORMALMAP\n\tuniform sampler2D normalMap;\n\tuniform vec2 normalScale;\n#endif\n#ifdef USE_NORMALMAP_OBJECTSPACE\n\tuniform mat3 normalMatrix;\n#endif\n#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) )\n\tmat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) {\n\t\tvec3 q0 = dFdx( eye_pos.xyz );\n\t\tvec3 q1 = dFdy( eye_pos.xyz );\n\t\tvec2 st0 = dFdx( uv.st );\n\t\tvec2 st1 = dFdy( uv.st );\n\t\tvec3 N = surf_norm;\n\t\tvec3 q1perp = cross( q1, N );\n\t\tvec3 q0perp = cross( N, q0 );\n\t\tvec3 T = q1perp * st0.x + q0perp * st1.x;\n\t\tvec3 B = q1perp * st0.y + q0perp * st1.y;\n\t\tfloat det = max( dot( T, T ), dot( B, B ) );\n\t\tfloat scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det );\n\t\treturn mat3( T * scale, B * scale, N );\n\t}\n#endif",clearcoat_normal_fragment_begin:"#ifdef USE_CLEARCOAT\n\tvec3 clearcoatNormal = nonPerturbedNormal;\n#endif",clearcoat_normal_fragment_maps:"#ifdef USE_CLEARCOAT_NORMALMAP\n\tvec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0;\n\tclearcoatMapN.xy *= clearcoatNormalScale;\n\tclearcoatNormal = normalize( tbn2 * clearcoatMapN );\n#endif",clearcoat_pars_fragment:"#ifdef USE_CLEARCOATMAP\n\tuniform sampler2D clearcoatMap;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform sampler2D clearcoatNormalMap;\n\tuniform vec2 clearcoatNormalScale;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform sampler2D clearcoatRoughnessMap;\n#endif",iridescence_pars_fragment:"#ifdef USE_IRIDESCENCEMAP\n\tuniform sampler2D iridescenceMap;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform sampler2D iridescenceThicknessMap;\n#endif",opaque_fragment:"#ifdef OPAQUE\ndiffuseColor.a = 1.0;\n#endif\n#ifdef USE_TRANSMISSION\ndiffuseColor.a *= material.transmissionAlpha;\n#endif\ngl_FragColor = vec4( outgoingLight, diffuseColor.a );",packing:"vec3 packNormalToRGB( const in vec3 normal ) {\n\treturn normalize( normal ) * 0.5 + 0.5;\n}\nvec3 unpackRGBToNormal( const in vec3 rgb ) {\n\treturn 2.0 * rgb.xyz - 1.0;\n}\nconst float PackUpscale = 256. / 255.;const float UnpackDownscale = 255. / 256.;const float ShiftRight8 = 1. / 256.;\nconst float Inv255 = 1. / 255.;\nconst vec4 PackFactors = vec4( 1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0 );\nconst vec2 UnpackFactors2 = vec2( UnpackDownscale, 1.0 / PackFactors.g );\nconst vec3 UnpackFactors3 = vec3( UnpackDownscale / PackFactors.rg, 1.0 / PackFactors.b );\nconst vec4 UnpackFactors4 = vec4( UnpackDownscale / PackFactors.rgb, 1.0 / PackFactors.a );\nvec4 packDepthToRGBA( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec4( 0., 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec4( 1., 1., 1., 1. );\n\tfloat vuf;\n\tfloat af = modf( v * PackFactors.a, vuf );\n\tfloat bf = modf( vuf * ShiftRight8, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec4( vuf * Inv255, gf * PackUpscale, bf * PackUpscale, af );\n}\nvec3 packDepthToRGB( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec3( 0., 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec3( 1., 1., 1. );\n\tfloat vuf;\n\tfloat bf = modf( v * PackFactors.b, vuf );\n\tfloat gf = modf( vuf * ShiftRight8, vuf );\n\treturn vec3( vuf * Inv255, gf * PackUpscale, bf );\n}\nvec2 packDepthToRG( const in float v ) {\n\tif( v <= 0.0 )\n\t\treturn vec2( 0., 0. );\n\tif( v >= 1.0 )\n\t\treturn vec2( 1., 1. );\n\tfloat vuf;\n\tfloat gf = modf( v * 256., vuf );\n\treturn vec2( vuf * Inv255, gf );\n}\nfloat unpackRGBAToDepth( const in vec4 v ) {\n\treturn dot( v, UnpackFactors4 );\n}\nfloat unpackRGBToDepth( const in vec3 v ) {\n\treturn dot( v, UnpackFactors3 );\n}\nfloat unpackRGToDepth( const in vec2 v ) {\n\treturn v.r * UnpackFactors2.r + v.g * UnpackFactors2.g;\n}\nvec4 pack2HalfToRGBA( const in vec2 v ) {\n\tvec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) );\n\treturn vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w );\n}\nvec2 unpackRGBATo2Half( const in vec4 v ) {\n\treturn vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) );\n}\nfloat viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( viewZ + near ) / ( near - far );\n}\nfloat orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\n\t\treturn depth * ( far - near ) - far;\n\t#else\n\t\treturn depth * ( near - far ) - near;\n\t#endif\n}\nfloat viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) {\n\treturn ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ );\n}\nfloat perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) {\n\t\n\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\treturn ( near * far ) / ( ( near - far ) * depth - near );\n\t#else\n\t\treturn ( near * far ) / ( ( far - near ) * depth - far );\n\t#endif\n}",premultiplied_alpha_fragment:"#ifdef PREMULTIPLIED_ALPHA\n\tgl_FragColor.rgb *= gl_FragColor.a;\n#endif",project_vertex:"vec4 mvPosition = vec4( transformed, 1.0 );\n#ifdef USE_BATCHING\n\tmvPosition = batchingMatrix * mvPosition;\n#endif\n#ifdef USE_INSTANCING\n\tmvPosition = instanceMatrix * mvPosition;\n#endif\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;",dithering_fragment:"#ifdef DITHERING\n\tgl_FragColor.rgb = dithering( gl_FragColor.rgb );\n#endif",dithering_pars_fragment:"#ifdef DITHERING\n\tvec3 dithering( vec3 color ) {\n\t\tfloat grid_position = rand( gl_FragCoord.xy );\n\t\tvec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 );\n\t\tdither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position );\n\t\treturn color + dither_shift_RGB;\n\t}\n#endif",roughnessmap_fragment:"float roughnessFactor = roughness;\n#ifdef USE_ROUGHNESSMAP\n\tvec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv );\n\troughnessFactor *= texelRoughness.g;\n#endif",roughnessmap_pars_fragment:"#ifdef USE_ROUGHNESSMAP\n\tuniform sampler2D roughnessMap;\n#endif",shadowmap_pars_fragment:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#if NUM_SPOT_LIGHT_MAPS > 0\n\tuniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tuniform sampler2DShadow directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\t#else\n\t\t\tuniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ];\n\t\t#endif\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tuniform sampler2DShadow spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\t#else\n\t\t\tuniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ];\n\t\t#endif\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\t\tuniform samplerCubeShadow pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\t#elif defined( SHADOWMAP_TYPE_BASIC )\n\t\t\tuniform samplerCube pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ];\n\t\t#endif\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\tfloat interleavedGradientNoise( vec2 position ) {\n\t\t\treturn fract( 52.9829189 * fract( dot( position, vec2( 0.06711056, 0.00583715 ) ) ) );\n\t\t}\n\t\tvec2 vogelDiskSample( int sampleIndex, int samplesCount, float phi ) {\n\t\t\tconst float goldenAngle = 2.399963229728653;\n\t\t\tfloat r = sqrt( ( float( sampleIndex ) + 0.5 ) / float( samplesCount ) );\n\t\t\tfloat theta = float( sampleIndex ) * goldenAngle + phi;\n\t\t\treturn vec2( cos( theta ), sin( theta ) ) * r;\n\t\t}\n\t#endif\n\t#if defined( SHADOWMAP_TYPE_PCF )\n\t\tfloat getShadow( sampler2DShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\t\tfloat shadow = 1.0;\n\t\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\t\tshadowCoord.z += shadowBias;\n\t\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\t\tif ( frustumTest ) {\n\t\t\t\tvec2 texelSize = vec2( 1.0 ) / shadowMapSize;\n\t\t\t\tfloat radius = shadowRadius * texelSize.x;\n\t\t\t\tfloat phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n\t\t\t\tshadow = (\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 0, 5, phi ) * radius, shadowCoord.z ) ) +\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 1, 5, phi ) * radius, shadowCoord.z ) ) +\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 2, 5, phi ) * radius, shadowCoord.z ) ) +\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 3, 5, phi ) * radius, shadowCoord.z ) ) +\n\t\t\t\t\ttexture( shadowMap, vec3( shadowCoord.xy + vogelDiskSample( 4, 5, phi ) * radius, shadowCoord.z ) )\n\t\t\t\t) * 0.2;\n\t\t\t}\n\t\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t\t}\n\t#elif defined( SHADOWMAP_TYPE_VSM )\n\t\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\t\tfloat shadow = 1.0;\n\t\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\tshadowCoord.z -= shadowBias;\n\t\t\t#else\n\t\t\t\tshadowCoord.z += shadowBias;\n\t\t\t#endif\n\t\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\t\tif ( frustumTest ) {\n\t\t\t\tvec2 distribution = texture2D( shadowMap, shadowCoord.xy ).rg;\n\t\t\t\tfloat mean = distribution.x;\n\t\t\t\tfloat variance = distribution.y * distribution.y;\n\t\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\t\tfloat hard_shadow = step( mean, shadowCoord.z );\n\t\t\t\t#else\n\t\t\t\t\tfloat hard_shadow = step( shadowCoord.z, mean );\n\t\t\t\t#endif\n\t\t\t\t\n\t\t\t\tif ( hard_shadow == 1.0 ) {\n\t\t\t\t\tshadow = 1.0;\n\t\t\t\t} else {\n\t\t\t\t\tvariance = max( variance, 0.0000001 );\n\t\t\t\t\tfloat d = shadowCoord.z - mean;\n\t\t\t\t\tfloat p_max = variance / ( variance + d * d );\n\t\t\t\t\tp_max = clamp( ( p_max - 0.3 ) / 0.65, 0.0, 1.0 );\n\t\t\t\t\tshadow = max( hard_shadow, p_max );\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t\t}\n\t#else\n\t\tfloat getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord ) {\n\t\t\tfloat shadow = 1.0;\n\t\t\tshadowCoord.xyz /= shadowCoord.w;\n\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\tshadowCoord.z -= shadowBias;\n\t\t\t#else\n\t\t\t\tshadowCoord.z += shadowBias;\n\t\t\t#endif\n\t\t\tbool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0;\n\t\t\tbool frustumTest = inFrustum && shadowCoord.z <= 1.0;\n\t\t\tif ( frustumTest ) {\n\t\t\t\tfloat depth = texture2D( shadowMap, shadowCoord.xy ).r;\n\t\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\t\tshadow = step( depth, shadowCoord.z );\n\t\t\t\t#else\n\t\t\t\t\tshadow = step( shadowCoord.z, depth );\n\t\t\t\t#endif\n\t\t\t}\n\t\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t\t}\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t#if defined( SHADOWMAP_TYPE_PCF )\n\tfloat getPointShadow( samplerCubeShadow shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tfloat shadow = 1.0;\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 bd3D = normalize( lightToPosition );\n\t\tvec3 absVec = abs( lightToPosition );\n\t\tfloat viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n\t\tif ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\tfloat dp = ( shadowCameraNear * ( shadowCameraFar - viewSpaceZ ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n\t\t\t\tdp -= shadowBias;\n\t\t\t#else\n\t\t\t\tfloat dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n\t\t\t\tdp += shadowBias;\n\t\t\t#endif\n\t\t\tfloat texelSize = shadowRadius / shadowMapSize.x;\n\t\t\tvec3 absDir = abs( bd3D );\n\t\t\tvec3 tangent = absDir.x > absDir.z ? vec3( 0.0, 1.0, 0.0 ) : vec3( 1.0, 0.0, 0.0 );\n\t\t\ttangent = normalize( cross( bd3D, tangent ) );\n\t\t\tvec3 bitangent = cross( bd3D, tangent );\n\t\t\tfloat phi = interleavedGradientNoise( gl_FragCoord.xy ) * PI2;\n\t\t\tvec2 sample0 = vogelDiskSample( 0, 5, phi );\n\t\t\tvec2 sample1 = vogelDiskSample( 1, 5, phi );\n\t\t\tvec2 sample2 = vogelDiskSample( 2, 5, phi );\n\t\t\tvec2 sample3 = vogelDiskSample( 3, 5, phi );\n\t\t\tvec2 sample4 = vogelDiskSample( 4, 5, phi );\n\t\t\tshadow = (\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample0.x + bitangent * sample0.y ) * texelSize, dp ) ) +\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample1.x + bitangent * sample1.y ) * texelSize, dp ) ) +\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample2.x + bitangent * sample2.y ) * texelSize, dp ) ) +\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample3.x + bitangent * sample3.y ) * texelSize, dp ) ) +\n\t\t\t\ttexture( shadowMap, vec4( bd3D + ( tangent * sample4.x + bitangent * sample4.y ) * texelSize, dp ) )\n\t\t\t) * 0.2;\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n\t#elif defined( SHADOWMAP_TYPE_BASIC )\n\tfloat getPointShadow( samplerCube shadowMap, vec2 shadowMapSize, float shadowIntensity, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) {\n\t\tfloat shadow = 1.0;\n\t\tvec3 lightToPosition = shadowCoord.xyz;\n\t\tvec3 absVec = abs( lightToPosition );\n\t\tfloat viewSpaceZ = max( max( absVec.x, absVec.y ), absVec.z );\n\t\tif ( viewSpaceZ - shadowCameraFar <= 0.0 && viewSpaceZ - shadowCameraNear >= 0.0 ) {\n\t\t\tfloat dp = ( shadowCameraFar * ( viewSpaceZ - shadowCameraNear ) ) / ( viewSpaceZ * ( shadowCameraFar - shadowCameraNear ) );\n\t\t\tdp += shadowBias;\n\t\t\tvec3 bd3D = normalize( lightToPosition );\n\t\t\tfloat depth = textureCube( shadowMap, bd3D ).r;\n\t\t\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\t\t\tdepth = 1.0 - depth;\n\t\t\t#endif\n\t\t\tshadow = step( dp, depth );\n\t\t}\n\t\treturn mix( 1.0, shadow, shadowIntensity );\n\t}\n\t#endif\n\t#endif\n#endif",shadowmap_pars_vertex:"#if NUM_SPOT_LIGHT_COORDS > 0\n\tuniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ];\n\tvarying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ];\n#endif\n#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\tuniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tvarying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ];\n\t\tstruct DirectionalLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\t\tstruct SpotLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t};\n\t\tuniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ];\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\tuniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tvarying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ];\n\t\tstruct PointLightShadow {\n\t\t\tfloat shadowIntensity;\n\t\t\tfloat shadowBias;\n\t\t\tfloat shadowNormalBias;\n\t\t\tfloat shadowRadius;\n\t\t\tvec2 shadowMapSize;\n\t\t\tfloat shadowCameraNear;\n\t\t\tfloat shadowCameraFar;\n\t\t};\n\t\tuniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ];\n\t#endif\n#endif",shadowmap_vertex:"#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 )\n\tvec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix );\n\tvec4 shadowWorldPosition;\n#endif\n#if defined( USE_SHADOWMAP )\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0\n\t\t#pragma unroll_loop_start\n\t\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\t\tshadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 );\n\t\t\tvPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition;\n\t\t}\n\t\t#pragma unroll_loop_end\n\t#endif\n#endif\n#if NUM_SPOT_LIGHT_COORDS > 0\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) {\n\t\tshadowWorldPosition = worldPosition;\n\t\t#if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS )\n\t\t\tshadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias;\n\t\t#endif\n\t\tvSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition;\n\t}\n\t#pragma unroll_loop_end\n#endif",shadowmask_pars_fragment:"float getShadowMask() {\n\tfloat shadow = 1.0;\n\t#ifdef USE_SHADOWMAP\n\t#if NUM_DIR_LIGHT_SHADOWS > 0\n\tDirectionalLightShadow directionalLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) {\n\t\tdirectionalLight = directionalLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowIntensity, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_SPOT_LIGHT_SHADOWS > 0\n\tSpotLightShadow spotLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) {\n\t\tspotLight = spotLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowIntensity, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#if NUM_POINT_LIGHT_SHADOWS > 0 && ( defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_BASIC ) )\n\tPointLightShadow pointLight;\n\t#pragma unroll_loop_start\n\tfor ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) {\n\t\tpointLight = pointLightShadows[ i ];\n\t\tshadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowIntensity, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0;\n\t}\n\t#pragma unroll_loop_end\n\t#endif\n\t#endif\n\treturn shadow;\n}",skinbase_vertex:"#ifdef USE_SKINNING\n\tmat4 boneMatX = getBoneMatrix( skinIndex.x );\n\tmat4 boneMatY = getBoneMatrix( skinIndex.y );\n\tmat4 boneMatZ = getBoneMatrix( skinIndex.z );\n\tmat4 boneMatW = getBoneMatrix( skinIndex.w );\n#endif",skinning_pars_vertex:"#ifdef USE_SKINNING\n\tuniform mat4 bindMatrix;\n\tuniform mat4 bindMatrixInverse;\n\tuniform highp sampler2D boneTexture;\n\tmat4 getBoneMatrix( const in float i ) {\n\t\tint size = textureSize( boneTexture, 0 ).x;\n\t\tint j = int( i ) * 4;\n\t\tint x = j % size;\n\t\tint y = j / size;\n\t\tvec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 );\n\t\tvec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 );\n\t\tvec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 );\n\t\tvec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 );\n\t\treturn mat4( v1, v2, v3, v4 );\n\t}\n#endif",skinning_vertex:"#ifdef USE_SKINNING\n\tvec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );\n\tvec4 skinned = vec4( 0.0 );\n\tskinned += boneMatX * skinVertex * skinWeight.x;\n\tskinned += boneMatY * skinVertex * skinWeight.y;\n\tskinned += boneMatZ * skinVertex * skinWeight.z;\n\tskinned += boneMatW * skinVertex * skinWeight.w;\n\ttransformed = ( bindMatrixInverse * skinned ).xyz;\n#endif",skinnormal_vertex:"#ifdef USE_SKINNING\n\tmat4 skinMatrix = mat4( 0.0 );\n\tskinMatrix += skinWeight.x * boneMatX;\n\tskinMatrix += skinWeight.y * boneMatY;\n\tskinMatrix += skinWeight.z * boneMatZ;\n\tskinMatrix += skinWeight.w * boneMatW;\n\tskinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;\n\tobjectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;\n\t#ifdef USE_TANGENT\n\t\tobjectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz;\n\t#endif\n#endif",specularmap_fragment:"float specularStrength;\n#ifdef USE_SPECULARMAP\n\tvec4 texelSpecular = texture2D( specularMap, vSpecularMapUv );\n\tspecularStrength = texelSpecular.r;\n#else\n\tspecularStrength = 1.0;\n#endif",specularmap_pars_fragment:"#ifdef USE_SPECULARMAP\n\tuniform sampler2D specularMap;\n#endif",tonemapping_fragment:"#if defined( TONE_MAPPING )\n\tgl_FragColor.rgb = toneMapping( gl_FragColor.rgb );\n#endif",tonemapping_pars_fragment:"#ifndef saturate\n#define saturate( a ) clamp( a, 0.0, 1.0 )\n#endif\nuniform float toneMappingExposure;\nvec3 LinearToneMapping( vec3 color ) {\n\treturn saturate( toneMappingExposure * color );\n}\nvec3 ReinhardToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\treturn saturate( color / ( vec3( 1.0 ) + color ) );\n}\nvec3 CineonToneMapping( vec3 color ) {\n\tcolor *= toneMappingExposure;\n\tcolor = max( vec3( 0.0 ), color - 0.004 );\n\treturn pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) );\n}\nvec3 RRTAndODTFit( vec3 v ) {\n\tvec3 a = v * ( v + 0.0245786 ) - 0.000090537;\n\tvec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081;\n\treturn a / b;\n}\nvec3 ACESFilmicToneMapping( vec3 color ) {\n\tconst mat3 ACESInputMat = mat3(\n\t\tvec3( 0.59719, 0.07600, 0.02840 ),\t\tvec3( 0.35458, 0.90834, 0.13383 ),\n\t\tvec3( 0.04823, 0.01566, 0.83777 )\n\t);\n\tconst mat3 ACESOutputMat = mat3(\n\t\tvec3( 1.60475, -0.10208, -0.00327 ),\t\tvec3( -0.53108, 1.10813, -0.07276 ),\n\t\tvec3( -0.07367, -0.00605, 1.07602 )\n\t);\n\tcolor *= toneMappingExposure / 0.6;\n\tcolor = ACESInputMat * color;\n\tcolor = RRTAndODTFit( color );\n\tcolor = ACESOutputMat * color;\n\treturn saturate( color );\n}\nconst mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3(\n\tvec3( 1.6605, - 0.1246, - 0.0182 ),\n\tvec3( - 0.5876, 1.1329, - 0.1006 ),\n\tvec3( - 0.0728, - 0.0083, 1.1187 )\n);\nconst mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3(\n\tvec3( 0.6274, 0.0691, 0.0164 ),\n\tvec3( 0.3293, 0.9195, 0.0880 ),\n\tvec3( 0.0433, 0.0113, 0.8956 )\n);\nvec3 agxDefaultContrastApprox( vec3 x ) {\n\tvec3 x2 = x * x;\n\tvec3 x4 = x2 * x2;\n\treturn + 15.5 * x4 * x2\n\t\t- 40.14 * x4 * x\n\t\t+ 31.96 * x4\n\t\t- 6.868 * x2 * x\n\t\t+ 0.4298 * x2\n\t\t+ 0.1191 * x\n\t\t- 0.00232;\n}\nvec3 AgXToneMapping( vec3 color ) {\n\tconst mat3 AgXInsetMatrix = mat3(\n\t\tvec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ),\n\t\tvec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ),\n\t\tvec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 )\n\t);\n\tconst mat3 AgXOutsetMatrix = mat3(\n\t\tvec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ),\n\t\tvec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ),\n\t\tvec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 )\n\t);\n\tconst float AgxMinEv = - 12.47393;\tconst float AgxMaxEv = 4.026069;\n\tcolor *= toneMappingExposure;\n\tcolor = LINEAR_SRGB_TO_LINEAR_REC2020 * color;\n\tcolor = AgXInsetMatrix * color;\n\tcolor = max( color, 1e-10 );\tcolor = log2( color );\n\tcolor = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv );\n\tcolor = clamp( color, 0.0, 1.0 );\n\tcolor = agxDefaultContrastApprox( color );\n\tcolor = AgXOutsetMatrix * color;\n\tcolor = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) );\n\tcolor = LINEAR_REC2020_TO_LINEAR_SRGB * color;\n\tcolor = clamp( color, 0.0, 1.0 );\n\treturn color;\n}\nvec3 NeutralToneMapping( vec3 color ) {\n\tconst float StartCompression = 0.8 - 0.04;\n\tconst float Desaturation = 0.15;\n\tcolor *= toneMappingExposure;\n\tfloat x = min( color.r, min( color.g, color.b ) );\n\tfloat offset = x < 0.08 ? x - 6.25 * x * x : 0.04;\n\tcolor -= offset;\n\tfloat peak = max( color.r, max( color.g, color.b ) );\n\tif ( peak < StartCompression ) return color;\n\tfloat d = 1. - StartCompression;\n\tfloat newPeak = 1. - d * d / ( peak + d - StartCompression );\n\tcolor *= newPeak / peak;\n\tfloat g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. );\n\treturn mix( color, vec3( newPeak ), g );\n}\nvec3 CustomToneMapping( vec3 color ) { return color; }",transmission_fragment:"#ifdef USE_TRANSMISSION\n\tmaterial.transmission = transmission;\n\tmaterial.transmissionAlpha = 1.0;\n\tmaterial.thickness = thickness;\n\tmaterial.attenuationDistance = attenuationDistance;\n\tmaterial.attenuationColor = attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tmaterial.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tmaterial.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g;\n\t#endif\n\tvec3 pos = vWorldPosition;\n\tvec3 v = normalize( cameraPosition - pos );\n\tvec3 n = inverseTransformDirection( normal, viewMatrix );\n\tvec4 transmitted = getIBLVolumeRefraction(\n\t\tn, v, material.roughness, material.diffuseContribution, material.specularColorBlended, material.specularF90,\n\t\tpos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness,\n\t\tmaterial.attenuationColor, material.attenuationDistance );\n\tmaterial.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission );\n\ttotalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission );\n#endif",transmission_pars_fragment:"#ifdef USE_TRANSMISSION\n\tuniform float transmission;\n\tuniform float thickness;\n\tuniform float attenuationDistance;\n\tuniform vec3 attenuationColor;\n\t#ifdef USE_TRANSMISSIONMAP\n\t\tuniform sampler2D transmissionMap;\n\t#endif\n\t#ifdef USE_THICKNESSMAP\n\t\tuniform sampler2D thicknessMap;\n\t#endif\n\tuniform vec2 transmissionSamplerSize;\n\tuniform sampler2D transmissionSamplerMap;\n\tuniform mat4 modelMatrix;\n\tuniform mat4 projectionMatrix;\n\tvarying vec3 vWorldPosition;\n\tfloat w0( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 );\n\t}\n\tfloat w1( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 );\n\t}\n\tfloat w2( float a ){\n\t\treturn ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 );\n\t}\n\tfloat w3( float a ) {\n\t\treturn ( 1.0 / 6.0 ) * ( a * a * a );\n\t}\n\tfloat g0( float a ) {\n\t\treturn w0( a ) + w1( a );\n\t}\n\tfloat g1( float a ) {\n\t\treturn w2( a ) + w3( a );\n\t}\n\tfloat h0( float a ) {\n\t\treturn - 1.0 + w1( a ) / ( w0( a ) + w1( a ) );\n\t}\n\tfloat h1( float a ) {\n\t\treturn 1.0 + w3( a ) / ( w2( a ) + w3( a ) );\n\t}\n\tvec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) {\n\t\tuv = uv * texelSize.zw + 0.5;\n\t\tvec2 iuv = floor( uv );\n\t\tvec2 fuv = fract( uv );\n\t\tfloat g0x = g0( fuv.x );\n\t\tfloat g1x = g1( fuv.x );\n\t\tfloat h0x = h0( fuv.x );\n\t\tfloat h1x = h1( fuv.x );\n\t\tfloat h0y = h0( fuv.y );\n\t\tfloat h1y = h1( fuv.y );\n\t\tvec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\tvec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy;\n\t\treturn g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) +\n\t\t\tg1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) );\n\t}\n\tvec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) {\n\t\tvec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) );\n\t\tvec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) );\n\t\tvec2 fLodSizeInv = 1.0 / fLodSize;\n\t\tvec2 cLodSizeInv = 1.0 / cLodSize;\n\t\tvec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) );\n\t\tvec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) );\n\t\treturn mix( fSample, cSample, fract( lod ) );\n\t}\n\tvec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) {\n\t\tvec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior );\n\t\tvec3 modelScale;\n\t\tmodelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) );\n\t\tmodelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) );\n\t\tmodelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) );\n\t\treturn normalize( refractionVector ) * thickness * modelScale;\n\t}\n\tfloat applyIorToRoughness( const in float roughness, const in float ior ) {\n\t\treturn roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 );\n\t}\n\tvec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) {\n\t\tfloat lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior );\n\t\treturn textureBicubic( transmissionSamplerMap, fragCoord.xy, lod );\n\t}\n\tvec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tif ( isinf( attenuationDistance ) ) {\n\t\t\treturn vec3( 1.0 );\n\t\t} else {\n\t\t\tvec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance;\n\t\t\tvec3 transmittance = exp( - attenuationCoefficient * transmissionDistance );\t\t\treturn transmittance;\n\t\t}\n\t}\n\tvec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor,\n\t\tconst in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix,\n\t\tconst in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness,\n\t\tconst in vec3 attenuationColor, const in float attenuationDistance ) {\n\t\tvec4 transmittedLight;\n\t\tvec3 transmittance;\n\t\t#ifdef USE_DISPERSION\n\t\t\tfloat halfSpread = ( ior - 1.0 ) * 0.025 * dispersion;\n\t\t\tvec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread );\n\t\t\tfor ( int i = 0; i < 3; i ++ ) {\n\t\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix );\n\t\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\t\trefractionCoords += 1.0;\n\t\t\t\trefractionCoords /= 2.0;\n\t\t\t\tvec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] );\n\t\t\t\ttransmittedLight[ i ] = transmissionSample[ i ];\n\t\t\t\ttransmittedLight.a += transmissionSample.a;\n\t\t\t\ttransmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ];\n\t\t\t}\n\t\t\ttransmittedLight.a /= 3.0;\n\t\t#else\n\t\t\tvec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix );\n\t\t\tvec3 refractedRayExit = position + transmissionRay;\n\t\t\tvec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 );\n\t\t\tvec2 refractionCoords = ndcPos.xy / ndcPos.w;\n\t\t\trefractionCoords += 1.0;\n\t\t\trefractionCoords /= 2.0;\n\t\t\ttransmittedLight = getTransmissionSample( refractionCoords, roughness, ior );\n\t\t\ttransmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance );\n\t\t#endif\n\t\tvec3 attenuatedColor = transmittance * transmittedLight.rgb;\n\t\tvec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness );\n\t\tfloat transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0;\n\t\treturn vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor );\n\t}\n#endif",uv_pars_fragment:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif",uv_pars_vertex:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvarying vec2 vUv;\n#endif\n#ifdef USE_MAP\n\tuniform mat3 mapTransform;\n\tvarying vec2 vMapUv;\n#endif\n#ifdef USE_ALPHAMAP\n\tuniform mat3 alphaMapTransform;\n\tvarying vec2 vAlphaMapUv;\n#endif\n#ifdef USE_LIGHTMAP\n\tuniform mat3 lightMapTransform;\n\tvarying vec2 vLightMapUv;\n#endif\n#ifdef USE_AOMAP\n\tuniform mat3 aoMapTransform;\n\tvarying vec2 vAoMapUv;\n#endif\n#ifdef USE_BUMPMAP\n\tuniform mat3 bumpMapTransform;\n\tvarying vec2 vBumpMapUv;\n#endif\n#ifdef USE_NORMALMAP\n\tuniform mat3 normalMapTransform;\n\tvarying vec2 vNormalMapUv;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tuniform mat3 displacementMapTransform;\n\tvarying vec2 vDisplacementMapUv;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tuniform mat3 emissiveMapTransform;\n\tvarying vec2 vEmissiveMapUv;\n#endif\n#ifdef USE_METALNESSMAP\n\tuniform mat3 metalnessMapTransform;\n\tvarying vec2 vMetalnessMapUv;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tuniform mat3 roughnessMapTransform;\n\tvarying vec2 vRoughnessMapUv;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tuniform mat3 anisotropyMapTransform;\n\tvarying vec2 vAnisotropyMapUv;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tuniform mat3 clearcoatMapTransform;\n\tvarying vec2 vClearcoatMapUv;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tuniform mat3 clearcoatNormalMapTransform;\n\tvarying vec2 vClearcoatNormalMapUv;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tuniform mat3 clearcoatRoughnessMapTransform;\n\tvarying vec2 vClearcoatRoughnessMapUv;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tuniform mat3 sheenColorMapTransform;\n\tvarying vec2 vSheenColorMapUv;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tuniform mat3 sheenRoughnessMapTransform;\n\tvarying vec2 vSheenRoughnessMapUv;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tuniform mat3 iridescenceMapTransform;\n\tvarying vec2 vIridescenceMapUv;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tuniform mat3 iridescenceThicknessMapTransform;\n\tvarying vec2 vIridescenceThicknessMapUv;\n#endif\n#ifdef USE_SPECULARMAP\n\tuniform mat3 specularMapTransform;\n\tvarying vec2 vSpecularMapUv;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tuniform mat3 specularColorMapTransform;\n\tvarying vec2 vSpecularColorMapUv;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tuniform mat3 specularIntensityMapTransform;\n\tvarying vec2 vSpecularIntensityMapUv;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tuniform mat3 transmissionMapTransform;\n\tvarying vec2 vTransmissionMapUv;\n#endif\n#ifdef USE_THICKNESSMAP\n\tuniform mat3 thicknessMapTransform;\n\tvarying vec2 vThicknessMapUv;\n#endif",uv_vertex:"#if defined( USE_UV ) || defined( USE_ANISOTROPY )\n\tvUv = vec3( uv, 1 ).xy;\n#endif\n#ifdef USE_MAP\n\tvMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ALPHAMAP\n\tvAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_LIGHTMAP\n\tvLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_AOMAP\n\tvAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_BUMPMAP\n\tvBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_NORMALMAP\n\tvNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_DISPLACEMENTMAP\n\tvDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_EMISSIVEMAP\n\tvEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_METALNESSMAP\n\tvMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ROUGHNESSMAP\n\tvRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_ANISOTROPYMAP\n\tvAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOATMAP\n\tvClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_NORMALMAP\n\tvClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_CLEARCOAT_ROUGHNESSMAP\n\tvClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCEMAP\n\tvIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_IRIDESCENCE_THICKNESSMAP\n\tvIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_COLORMAP\n\tvSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SHEEN_ROUGHNESSMAP\n\tvSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULARMAP\n\tvSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_COLORMAP\n\tvSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_SPECULAR_INTENSITYMAP\n\tvSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_TRANSMISSIONMAP\n\tvTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy;\n#endif\n#ifdef USE_THICKNESSMAP\n\tvThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy;\n#endif",worldpos_vertex:"#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0\n\tvec4 worldPosition = vec4( transformed, 1.0 );\n\t#ifdef USE_BATCHING\n\t\tworldPosition = batchingMatrix * worldPosition;\n\t#endif\n\t#ifdef USE_INSTANCING\n\t\tworldPosition = instanceMatrix * worldPosition;\n\t#endif\n\tworldPosition = modelMatrix * worldPosition;\n#endif",background_vert:"varying vec2 vUv;\nuniform mat3 uvTransform;\nvoid main() {\n\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\tgl_Position = vec4( position.xy, 1.0, 1.0 );\n}",background_frag:"uniform sampler2D t2D;\nuniform float backgroundIntensity;\nvarying vec2 vUv;\nvoid main() {\n\tvec4 texColor = texture2D( t2D, vUv );\n\t#ifdef DECODE_VIDEO_TEXTURE\n\t\ttexColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}",backgroundCube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",backgroundCube_frag:"#ifdef ENVMAP_TYPE_CUBE\n\tuniform samplerCube envMap;\n#elif defined( ENVMAP_TYPE_CUBE_UV )\n\tuniform sampler2D envMap;\n#endif\nuniform float flipEnvMap;\nuniform float backgroundBlurriness;\nuniform float backgroundIntensity;\nuniform mat3 backgroundRotation;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\t#ifdef ENVMAP_TYPE_CUBE\n\t\tvec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) );\n\t#elif defined( ENVMAP_TYPE_CUBE_UV )\n\t\tvec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness );\n\t#else\n\t\tvec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t#endif\n\ttexColor.rgb *= backgroundIntensity;\n\tgl_FragColor = texColor;\n\t#include \n\t#include \n}",cube_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n\tgl_Position.z = gl_Position.w;\n}",cube_frag:"uniform samplerCube tCube;\nuniform float tFlip;\nuniform float opacity;\nvarying vec3 vWorldDirection;\nvoid main() {\n\tvec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) );\n\tgl_FragColor = texColor;\n\tgl_FragColor.a *= opacity;\n\t#include \n\t#include \n}",depth_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvHighPrecisionZW = gl_Position.zw;\n}",depth_frag:"#if DEPTH_PACKING == 3200\n\tuniform float opacity;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvarying vec2 vHighPrecisionZW;\nvoid main() {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#if DEPTH_PACKING == 3200\n\t\tdiffuseColor.a = opacity;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_REVERSED_DEPTH_BUFFER\n\t\tfloat fragCoordZ = vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ];\n\t#else\n\t\tfloat fragCoordZ = 0.5 * vHighPrecisionZW[ 0 ] / vHighPrecisionZW[ 1 ] + 0.5;\n\t#endif\n\t#if DEPTH_PACKING == 3200\n\t\tgl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity );\n\t#elif DEPTH_PACKING == 3201\n\t\tgl_FragColor = packDepthToRGBA( fragCoordZ );\n\t#elif DEPTH_PACKING == 3202\n\t\tgl_FragColor = vec4( packDepthToRGB( fragCoordZ ), 1.0 );\n\t#elif DEPTH_PACKING == 3203\n\t\tgl_FragColor = vec4( packDepthToRG( fragCoordZ ), 0.0, 1.0 );\n\t#endif\n}",distance_vert:"#define DISTANCE\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#ifdef USE_DISPLACEMENTMAP\n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvWorldPosition = worldPosition.xyz;\n}",distance_frag:"#define DISTANCE\nuniform vec3 referencePosition;\nuniform float nearDistance;\nuniform float farDistance;\nvarying vec3 vWorldPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main () {\n\tvec4 diffuseColor = vec4( 1.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tfloat dist = length( vWorldPosition - referencePosition );\n\tdist = ( dist - nearDistance ) / ( farDistance - nearDistance );\n\tdist = saturate( dist );\n\tgl_FragColor = vec4( dist, 0.0, 0.0, 1.0 );\n}",equirect_vert:"varying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvWorldDirection = transformDirection( position, modelMatrix );\n\t#include \n\t#include \n}",equirect_frag:"uniform sampler2D tEquirect;\nvarying vec3 vWorldDirection;\n#include \nvoid main() {\n\tvec3 direction = normalize( vWorldDirection );\n\tvec2 sampleUV = equirectUv( direction );\n\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\t#include \n\t#include \n}",linedashed_vert:"uniform float scale;\nattribute float lineDistance;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvLineDistance = scale * lineDistance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",linedashed_frag:"uniform vec3 diffuse;\nuniform float opacity;\nuniform float dashSize;\nuniform float totalSize;\nvarying float vLineDistance;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tif ( mod( vLineDistance, totalSize ) > dashSize ) {\n\t\tdiscard;\n\t}\n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshbasic_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#if defined ( USE_ENVMAP ) || defined ( USE_SKINNING )\n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t\t#include \n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshbasic_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#ifndef FLAT_SHADED\n\tvarying vec3 vNormal;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\t#ifdef USE_LIGHTMAP\n\t\tvec4 lightMapTexel = texture2D( lightMap, vLightMapUv );\n\t\treflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI;\n\t#else\n\t\treflectedLight.indirectDiffuse += vec3( 1.0 );\n\t#endif\n\t#include \n\treflectedLight.indirectDiffuse *= diffuseColor.rgb;\n\tvec3 outgoingLight = reflectedLight.indirectDiffuse;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshlambert_vert:"#define LAMBERT\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}",meshlambert_frag:"#define LAMBERT\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshmatcap_vert:"#define MATCAP\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n}",meshmatcap_frag:"#define MATCAP\nuniform vec3 diffuse;\nuniform float opacity;\nuniform sampler2D matcap;\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 viewDir = normalize( vViewPosition );\n\tvec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n\tvec3 y = cross( viewDir, x );\n\tvec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5;\n\t#ifdef USE_MATCAP\n\t\tvec4 matcapColor = texture2D( matcap, uv );\n\t#else\n\t\tvec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 );\n\t#endif\n\tvec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshnormal_vert:"#define NORMAL\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvViewPosition = - mvPosition.xyz;\n#endif\n}",meshnormal_frag:"#define NORMAL\nuniform float opacity;\n#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE )\n\tvarying vec3 vViewPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity );\n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_FragColor = vec4( normalize( normal ) * 0.5 + 0.5, diffuseColor.a );\n\t#ifdef OPAQUE\n\t\tgl_FragColor.a = 1.0;\n\t#endif\n}",meshphong_vert:"#define PHONG\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n\t#include \n}",meshphong_frag:"#define PHONG\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform vec3 specular;\nuniform float shininess;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshphysical_vert:"#define STANDARD\nvarying vec3 vViewPosition;\n#ifdef USE_TRANSMISSION\n\tvarying vec3 vWorldPosition;\n#endif\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n#ifdef USE_TRANSMISSION\n\tvWorldPosition = worldPosition.xyz;\n#endif\n}",meshphysical_frag:"#define STANDARD\n#ifdef PHYSICAL\n\t#define IOR\n\t#define USE_SPECULAR\n#endif\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float roughness;\nuniform float metalness;\nuniform float opacity;\n#ifdef IOR\n\tuniform float ior;\n#endif\n#ifdef USE_SPECULAR\n\tuniform float specularIntensity;\n\tuniform vec3 specularColor;\n\t#ifdef USE_SPECULAR_COLORMAP\n\t\tuniform sampler2D specularColorMap;\n\t#endif\n\t#ifdef USE_SPECULAR_INTENSITYMAP\n\t\tuniform sampler2D specularIntensityMap;\n\t#endif\n#endif\n#ifdef USE_CLEARCOAT\n\tuniform float clearcoat;\n\tuniform float clearcoatRoughness;\n#endif\n#ifdef USE_DISPERSION\n\tuniform float dispersion;\n#endif\n#ifdef USE_IRIDESCENCE\n\tuniform float iridescence;\n\tuniform float iridescenceIOR;\n\tuniform float iridescenceThicknessMinimum;\n\tuniform float iridescenceThicknessMaximum;\n#endif\n#ifdef USE_SHEEN\n\tuniform vec3 sheenColor;\n\tuniform float sheenRoughness;\n\t#ifdef USE_SHEEN_COLORMAP\n\t\tuniform sampler2D sheenColorMap;\n\t#endif\n\t#ifdef USE_SHEEN_ROUGHNESSMAP\n\t\tuniform sampler2D sheenRoughnessMap;\n\t#endif\n#endif\n#ifdef USE_ANISOTROPY\n\tuniform vec2 anisotropyVector;\n\t#ifdef USE_ANISOTROPYMAP\n\t\tuniform sampler2D anisotropyMap;\n\t#endif\n#endif\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\n\tvec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\t#include \n\tvec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance;\n\t#ifdef USE_SHEEN\n \n\t\toutgoingLight = outgoingLight + sheenSpecularDirect + sheenSpecularIndirect;\n \n \t#endif\n\t#ifdef USE_CLEARCOAT\n\t\tfloat dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) );\n\t\tvec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc );\n\t\toutgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",meshtoon_vert:"#define TOON\nvarying vec3 vViewPosition;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvViewPosition = - mvPosition.xyz;\n\t#include \n\t#include \n\t#include \n}",meshtoon_frag:"#define TOON\nuniform vec3 diffuse;\nuniform vec3 emissive;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\tvec3 totalEmissiveRadiance = emissive;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tvec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",points_vert:"uniform float size;\nuniform float scale;\n#include \n#include \n#include \n#include \n#include \n#include \n#ifdef USE_POINTS_UV\n\tvarying vec2 vUv;\n\tuniform mat3 uvTransform;\n#endif\nvoid main() {\n\t#ifdef USE_POINTS_UV\n\t\tvUv = ( uvTransform * vec3( uv, 1 ) ).xy;\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\tgl_PointSize = size;\n\t#ifdef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z );\n\t#endif\n\t#include \n\t#include \n\t#include \n\t#include \n}",points_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",shadow_vert:"#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n}",shadow_frag:"uniform vec3 color;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tgl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) );\n\t#include \n\t#include \n\t#include \n\t#include \n}",sprite_vert:"uniform float rotation;\nuniform vec2 center;\n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\t#include \n\tvec4 mvPosition = modelViewMatrix[ 3 ];\n\tvec2 scale = vec2( length( modelMatrix[ 0 ].xyz ), length( modelMatrix[ 1 ].xyz ) );\n\t#ifndef USE_SIZEATTENUATION\n\t\tbool isPerspective = isPerspectiveMatrix( projectionMatrix );\n\t\tif ( isPerspective ) scale *= - mvPosition.z;\n\t#endif\n\tvec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale;\n\tvec2 rotatedPosition;\n\trotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y;\n\trotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y;\n\tmvPosition.xy += rotatedPosition;\n\tgl_Position = projectionMatrix * mvPosition;\n\t#include \n\t#include \n\t#include \n}",sprite_frag:"uniform vec3 diffuse;\nuniform float opacity;\n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \n#include \nvoid main() {\n\tvec4 diffuseColor = vec4( diffuse, opacity );\n\t#include \n\tvec3 outgoingLight = vec3( 0.0 );\n\t#include \n\t#include \n\t#include \n\t#include \n\t#include \n\toutgoingLight = diffuseColor.rgb;\n\t#include \n\t#include \n\t#include \n\t#include \n}"},Hn={common:{diffuse:{value:new n(16777215)},opacity:{value:1},map:{value:null},mapTransform:{value:new e},alphaMap:{value:null},alphaMapTransform:{value:new e},alphaTest:{value:0}},specularmap:{specularMap:{value:null},specularMapTransform:{value:new e}},envmap:{envMap:{value:null},envMapRotation:{value:new e},flipEnvMap:{value:-1},reflectivity:{value:1},ior:{value:1.5},refractionRatio:{value:.98},dfgLUT:{value:null}},aomap:{aoMap:{value:null},aoMapIntensity:{value:1},aoMapTransform:{value:new e}},lightmap:{lightMap:{value:null},lightMapIntensity:{value:1},lightMapTransform:{value:new e}},bumpmap:{bumpMap:{value:null},bumpMapTransform:{value:new e},bumpScale:{value:1}},normalmap:{normalMap:{value:null},normalMapTransform:{value:new e},normalScale:{value:new t(1,1)}},displacementmap:{displacementMap:{value:null},displacementMapTransform:{value:new e},displacementScale:{value:1},displacementBias:{value:0}},emissivemap:{emissiveMap:{value:null},emissiveMapTransform:{value:new e}},metalnessmap:{metalnessMap:{value:null},metalnessMapTransform:{value:new e}},roughnessmap:{roughnessMap:{value:null},roughnessMapTransform:{value:new e}},gradientmap:{gradientMap:{value:null}},fog:{fogDensity:{value:25e-5},fogNear:{value:1},fogFar:{value:2e3},fogColor:{value:new n(16777215)}},lights:{ambientLightColor:{value:[]},lightProbe:{value:[]},directionalLights:{value:[],properties:{direction:{},color:{}}},directionalLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},directionalShadowMatrix:{value:[]},spotLights:{value:[],properties:{color:{},position:{},direction:{},distance:{},coneCos:{},penumbraCos:{},decay:{}}},spotLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{}}},spotLightMap:{value:[]},spotLightMatrix:{value:[]},pointLights:{value:[],properties:{color:{},position:{},decay:{},distance:{}}},pointLightShadows:{value:[],properties:{shadowIntensity:1,shadowBias:{},shadowNormalBias:{},shadowRadius:{},shadowMapSize:{},shadowCameraNear:{},shadowCameraFar:{}}},pointShadowMatrix:{value:[]},hemisphereLights:{value:[],properties:{direction:{},skyColor:{},groundColor:{}}},rectAreaLights:{value:[],properties:{color:{},position:{},width:{},height:{}}},ltc_1:{value:null},ltc_2:{value:null}},points:{diffuse:{value:new n(16777215)},opacity:{value:1},size:{value:1},scale:{value:1},map:{value:null},alphaMap:{value:null},alphaMapTransform:{value:new e},alphaTest:{value:0},uvTransform:{value:new e}},sprite:{diffuse:{value:new n(16777215)},opacity:{value:1},center:{value:new t(.5,.5)},rotation:{value:0},map:{value:null},mapTransform:{value:new e},alphaMap:{value:null},alphaMapTransform:{value:new e},alphaTest:{value:0}}},Vn={basic:{uniforms:i([Hn.common,Hn.specularmap,Hn.envmap,Hn.aomap,Hn.lightmap,Hn.fog]),vertexShader:Gn.meshbasic_vert,fragmentShader:Gn.meshbasic_frag},lambert:{uniforms:i([Hn.common,Hn.specularmap,Hn.envmap,Hn.aomap,Hn.lightmap,Hn.emissivemap,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.fog,Hn.lights,{emissive:{value:new n(0)},envMapIntensity:{value:1}}]),vertexShader:Gn.meshlambert_vert,fragmentShader:Gn.meshlambert_frag},phong:{uniforms:i([Hn.common,Hn.specularmap,Hn.envmap,Hn.aomap,Hn.lightmap,Hn.emissivemap,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.fog,Hn.lights,{emissive:{value:new n(0)},specular:{value:new n(1118481)},shininess:{value:30},envMapIntensity:{value:1}}]),vertexShader:Gn.meshphong_vert,fragmentShader:Gn.meshphong_frag},standard:{uniforms:i([Hn.common,Hn.envmap,Hn.aomap,Hn.lightmap,Hn.emissivemap,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.roughnessmap,Hn.metalnessmap,Hn.fog,Hn.lights,{emissive:{value:new n(0)},roughness:{value:1},metalness:{value:0},envMapIntensity:{value:1}}]),vertexShader:Gn.meshphysical_vert,fragmentShader:Gn.meshphysical_frag},toon:{uniforms:i([Hn.common,Hn.aomap,Hn.lightmap,Hn.emissivemap,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.gradientmap,Hn.fog,Hn.lights,{emissive:{value:new n(0)}}]),vertexShader:Gn.meshtoon_vert,fragmentShader:Gn.meshtoon_frag},matcap:{uniforms:i([Hn.common,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,Hn.fog,{matcap:{value:null}}]),vertexShader:Gn.meshmatcap_vert,fragmentShader:Gn.meshmatcap_frag},points:{uniforms:i([Hn.points,Hn.fog]),vertexShader:Gn.points_vert,fragmentShader:Gn.points_frag},dashed:{uniforms:i([Hn.common,Hn.fog,{scale:{value:1},dashSize:{value:1},totalSize:{value:2}}]),vertexShader:Gn.linedashed_vert,fragmentShader:Gn.linedashed_frag},depth:{uniforms:i([Hn.common,Hn.displacementmap]),vertexShader:Gn.depth_vert,fragmentShader:Gn.depth_frag},normal:{uniforms:i([Hn.common,Hn.bumpmap,Hn.normalmap,Hn.displacementmap,{opacity:{value:1}}]),vertexShader:Gn.meshnormal_vert,fragmentShader:Gn.meshnormal_frag},sprite:{uniforms:i([Hn.sprite,Hn.fog]),vertexShader:Gn.sprite_vert,fragmentShader:Gn.sprite_frag},background:{uniforms:{uvTransform:{value:new e},t2D:{value:null},backgroundIntensity:{value:1}},vertexShader:Gn.background_vert,fragmentShader:Gn.background_frag},backgroundCube:{uniforms:{envMap:{value:null},flipEnvMap:{value:-1},backgroundBlurriness:{value:0},backgroundIntensity:{value:1},backgroundRotation:{value:new e}},vertexShader:Gn.backgroundCube_vert,fragmentShader:Gn.backgroundCube_frag},cube:{uniforms:{tCube:{value:null},tFlip:{value:-1},opacity:{value:1}},vertexShader:Gn.cube_vert,fragmentShader:Gn.cube_frag},equirect:{uniforms:{tEquirect:{value:null}},vertexShader:Gn.equirect_vert,fragmentShader:Gn.equirect_frag},distance:{uniforms:i([Hn.common,Hn.displacementmap,{referencePosition:{value:new r},nearDistance:{value:1},farDistance:{value:1e3}}]),vertexShader:Gn.distance_vert,fragmentShader:Gn.distance_frag},shadow:{uniforms:i([Hn.lights,Hn.fog,{color:{value:new n(0)},opacity:{value:1}}]),vertexShader:Gn.shadow_vert,fragmentShader:Gn.shadow_frag}};Vn.physical={uniforms:i([Vn.standard.uniforms,{clearcoat:{value:0},clearcoatMap:{value:null},clearcoatMapTransform:{value:new e},clearcoatNormalMap:{value:null},clearcoatNormalMapTransform:{value:new e},clearcoatNormalScale:{value:new t(1,1)},clearcoatRoughness:{value:0},clearcoatRoughnessMap:{value:null},clearcoatRoughnessMapTransform:{value:new e},dispersion:{value:0},iridescence:{value:0},iridescenceMap:{value:null},iridescenceMapTransform:{value:new e},iridescenceIOR:{value:1.3},iridescenceThicknessMinimum:{value:100},iridescenceThicknessMaximum:{value:400},iridescenceThicknessMap:{value:null},iridescenceThicknessMapTransform:{value:new e},sheen:{value:0},sheenColor:{value:new n(0)},sheenColorMap:{value:null},sheenColorMapTransform:{value:new e},sheenRoughness:{value:1},sheenRoughnessMap:{value:null},sheenRoughnessMapTransform:{value:new e},transmission:{value:0},transmissionMap:{value:null},transmissionMapTransform:{value:new e},transmissionSamplerSize:{value:new t},transmissionSamplerMap:{value:null},thickness:{value:0},thicknessMap:{value:null},thicknessMapTransform:{value:new e},attenuationDistance:{value:0},attenuationColor:{value:new n(0)},specularColor:{value:new n(1,1,1)},specularColorMap:{value:null},specularColorMapTransform:{value:new e},specularIntensity:{value:1},specularIntensityMap:{value:null},specularIntensityMapTransform:{value:new e},anisotropyVector:{value:new t},anisotropyMap:{value:null},anisotropyMapTransform:{value:new e}}]),vertexShader:Gn.meshphysical_vert,fragmentShader:Gn.meshphysical_frag};const Wn={r:0,b:0,g:0},zn=new u,kn=new f;function Xn(e,t,i,r,u,f){const v=new n(0);let E,S,M=!0===u?0:1,T=null,x=0,A=null;function R(e){let n=!0===e.isScene?e.background:null;if(n&&n.isTexture){const i=e.backgroundBlurriness>0;n=t.get(n,i)}return n}function b(t,n){t.getRGB(Wn,g(e)),i.buffers.color.setClear(Wn.r,Wn.g,Wn.b,n,f)}return{getClearColor:function(){return v},setClearColor:function(e,t=1){v.set(e),M=t,b(v,M)},getClearAlpha:function(){return M},setClearAlpha:function(e){M=e,b(v,M)},render:function(t){let n=!1;const r=R(t);null===r?b(v,M):r&&r.isColor&&(b(r,1),n=!0);const a=e.xr.getEnvironmentBlendMode();"additive"===a?i.buffers.color.setClear(0,0,0,1,f):"alpha-blend"===a&&i.buffers.color.setClear(0,0,0,0,f),(e.autoClear||n)&&(i.buffers.depth.setTest(!0),i.buffers.depth.setMask(!0),i.buffers.color.setMask(!0),e.clear(e.autoClearColor,e.autoClearDepth,e.autoClearStencil))},addToRenderList:function(t,n){const i=R(n);i&&(i.isCubeTexture||i.mapping===a)?(void 0===S&&(S=new o(new s(1,1,1),new l({name:"BackgroundCubeMaterial",uniforms:d(Vn.backgroundCube.uniforms),vertexShader:Vn.backgroundCube.vertexShader,fragmentShader:Vn.backgroundCube.fragmentShader,side:c,depthTest:!1,depthWrite:!1,fog:!1,allowOverride:!1})),S.geometry.deleteAttribute("normal"),S.geometry.deleteAttribute("uv"),S.onBeforeRender=function(e,t,n){this.matrixWorld.copyPosition(n.matrixWorld)},Object.defineProperty(S.material,"envMap",{get:function(){return this.uniforms.envMap.value}}),r.update(S)),zn.copy(n.backgroundRotation),zn.x*=-1,zn.y*=-1,zn.z*=-1,i.isCubeTexture&&!1===i.isRenderTargetTexture&&(zn.y*=-1,zn.z*=-1),S.material.uniforms.envMap.value=i,S.material.uniforms.flipEnvMap.value=i.isCubeTexture&&!1===i.isRenderTargetTexture?-1:1,S.material.uniforms.backgroundBlurriness.value=n.backgroundBlurriness,S.material.uniforms.backgroundIntensity.value=n.backgroundIntensity,S.material.uniforms.backgroundRotation.value.setFromMatrix4(kn.makeRotationFromEuler(zn)),S.material.toneMapped=p.getTransfer(i.colorSpace)!==m,T===i&&x===i.version&&A===e.toneMapping||(S.material.needsUpdate=!0,T=i,x=i.version,A=e.toneMapping),S.layers.enableAll(),t.unshift(S,S.geometry,S.material,0,0,null)):i&&i.isTexture&&(void 0===E&&(E=new o(new h(2,2),new l({name:"BackgroundMaterial",uniforms:d(Vn.background.uniforms),vertexShader:Vn.background.vertexShader,fragmentShader:Vn.background.fragmentShader,side:_,depthTest:!1,depthWrite:!1,fog:!1,allowOverride:!1})),E.geometry.deleteAttribute("normal"),Object.defineProperty(E.material,"map",{get:function(){return this.uniforms.t2D.value}}),r.update(E)),E.material.uniforms.t2D.value=i,E.material.uniforms.backgroundIntensity.value=n.backgroundIntensity,E.material.toneMapped=p.getTransfer(i.colorSpace)!==m,!0===i.matrixAutoUpdate&&i.updateMatrix(),E.material.uniforms.uvTransform.value.copy(i.matrix),T===i&&x===i.version&&A===e.toneMapping||(E.material.needsUpdate=!0,T=i,x=i.version,A=e.toneMapping),E.layers.enableAll(),t.unshift(E,E.geometry,E.material,0,0,null))},dispose:function(){void 0!==S&&(S.geometry.dispose(),S.material.dispose(),S=void 0),void 0!==E&&(E.geometry.dispose(),E.material.dispose(),E=void 0)}}}function Yn(e,t){const n=e.getParameter(e.MAX_VERTEX_ATTRIBS),i={},r=c(null);let a=r,o=!1;function s(t){return e.bindVertexArray(t)}function l(t){return e.deleteVertexArray(t)}function c(e){const t=[],i=[],r=[];for(let e=0;e=0){const n=r[t];let i=o[t];if(void 0===i&&("instanceMatrix"===t&&e.instanceMatrix&&(i=e.instanceMatrix),"instanceColor"===t&&e.instanceColor&&(i=e.instanceColor)),void 0===n)return!0;if(n.attribute!==i)return!0;if(i&&n.data!==i.data)return!0;s++}}return a.attributesNum!==s||a.index!==i}(n,h,l,_),g&&function(e,t,n,i){const r={},o=t.attributes;let s=0;const l=n.getAttributes();for(const t in l){if(l[t].location>=0){let n=o[t];void 0===n&&("instanceMatrix"===t&&e.instanceMatrix&&(n=e.instanceMatrix),"instanceColor"===t&&e.instanceColor&&(n=e.instanceColor));const i={};i.attribute=n,n&&n.data&&(i.data=n.data),r[t]=i,s++}}a.attributes=r,a.attributesNum=s,a.index=i}(n,h,l,_),null!==_&&t.update(_,e.ELEMENT_ARRAY_BUFFER),(g||o)&&(o=!1,function(n,i,r,a){d();const o=a.attributes,s=r.getAttributes(),l=i.defaultAttributeValues;for(const i in s){const r=s[i];if(r.location>=0){let s=o[i];if(void 0===s&&("instanceMatrix"===i&&n.instanceMatrix&&(s=n.instanceMatrix),"instanceColor"===i&&n.instanceColor&&(s=n.instanceColor)),void 0!==s){const i=s.normalized,o=s.itemSize,l=t.get(s);if(void 0===l)continue;const c=l.buffer,d=l.type,p=l.bytesPerElement,h=d===e.INT||d===e.UNSIGNED_INT||s.gpuType===v;if(s.isInterleavedBufferAttribute){const t=s.data,l=t.stride,_=s.offset;if(t.isInstancedInterleavedBuffer){for(let e=0;e0&&e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.HIGH_FLOAT).precision>0)return"highp";t="mediump"}return"mediump"===t&&e.getShaderPrecisionFormat(e.VERTEX_SHADER,e.MEDIUM_FLOAT).precision>0&&e.getShaderPrecisionFormat(e.FRAGMENT_SHADER,e.MEDIUM_FLOAT).precision>0?"mediump":"lowp"}let o=void 0!==n.precision?n.precision:"highp";const s=a(o);s!==o&&(E("WebGLRenderer:",o,"not supported, using",s,"instead."),o=s);return{isWebGL2:!0,getMaxAnisotropy:function(){if(void 0!==r)return r;if(!0===t.has("EXT_texture_filter_anisotropic")){const n=t.get("EXT_texture_filter_anisotropic");r=e.getParameter(n.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else r=0;return r},getMaxPrecision:a,textureFormatReadable:function(t){return t===x||i.convert(t)===e.getParameter(e.IMPLEMENTATION_COLOR_READ_FORMAT)},textureTypeReadable:function(n){const r=n===S&&(t.has("EXT_color_buffer_half_float")||t.has("EXT_color_buffer_float"));return!(n!==M&&i.convert(n)!==e.getParameter(e.IMPLEMENTATION_COLOR_READ_TYPE)&&n!==T&&!r)},precision:o,logarithmicDepthBuffer:!0===n.logarithmicDepthBuffer,reversedDepthBuffer:!0===n.reversedDepthBuffer&&t.has("EXT_clip_control"),maxTextures:e.getParameter(e.MAX_TEXTURE_IMAGE_UNITS),maxVertexTextures:e.getParameter(e.MAX_VERTEX_TEXTURE_IMAGE_UNITS),maxTextureSize:e.getParameter(e.MAX_TEXTURE_SIZE),maxCubemapSize:e.getParameter(e.MAX_CUBE_MAP_TEXTURE_SIZE),maxAttributes:e.getParameter(e.MAX_VERTEX_ATTRIBS),maxVertexUniforms:e.getParameter(e.MAX_VERTEX_UNIFORM_VECTORS),maxVaryings:e.getParameter(e.MAX_VARYING_VECTORS),maxFragmentUniforms:e.getParameter(e.MAX_FRAGMENT_UNIFORM_VECTORS),maxSamples:e.getParameter(e.MAX_SAMPLES),samples:e.getParameter(e.SAMPLES)}}function jn(t){const n=this;let i=null,r=0,a=!1,o=!1;const s=new A,l=new e,c={value:null,needsUpdate:!1};function d(e,t,i,r){const a=null!==e?e.length:0;let o=null;if(0!==a){if(o=c.value,!0!==r||null===o){const n=i+4*a,r=t.matrixWorldInverse;l.getNormalMatrix(r),(null===o||o.length0);n.numPlanes=r,n.numIntersection=0}();else{const e=o?0:r,t=4*e;let n=m.clippingState||null;c.value=n,n=d(u,s,t,l);for(let e=0;e!==t;++e)n[e]=i[e];m.clippingState=n,this.numIntersection=f?this.numPlanes:0,this.numPlanes+=e}}}const Zn=[.125,.215,.35,.446,.526,.582],$n=20,Qn=new P,Jn=new n;let ei=null,ti=0,ni=0,ii=!1;const ri=new r;class ai{constructor(e){this._renderer=e,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._sizeLods=[],this._sigmas=[],this._lodMeshes=[],this._backgroundBox=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._blurMaterial=null,this._ggxMaterial=null}fromScene(e,t=0,n=.1,i=100,r={}){const{size:a=256,position:o=ri}=r;ei=this._renderer.getRenderTarget(),ti=this._renderer.getActiveCubeFace(),ni=this._renderer.getActiveMipmapLevel(),ii=this._renderer.xr.enabled,this._renderer.xr.enabled=!1,this._setSize(a);const s=this._allocateTargets();return s.depthBuffer=!0,this._sceneToCubeUV(e,n,i,s,o),t>0&&this._blur(s,0,0,t),this._applyPMREM(s),this._cleanup(s),s}fromEquirectangular(e,t=null){return this._fromTexture(e,t)}fromCubemap(e,t=null){return this._fromTexture(e,t)}compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=ci(),this._compileMaterial(this._cubemapMaterial))}compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=li(),this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose(),null!==this._backgroundBox&&(this._backgroundBox.geometry.dispose(),this._backgroundBox.material.dispose())}_setSize(e){this._lodMax=Math.floor(Math.log2(e)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._ggxMaterial&&this._ggxMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let e=0;ee-4?l=Zn[s-e+4-1]:0===s&&(l=0),n.push(l);const c=1/(a-2),d=-c,u=1+c,f=[d,d,u,d,u,u,d,d,u,u,d,u],p=6,m=6,h=3,_=2,g=1,v=new Float32Array(h*m*p),E=new Float32Array(_*m*p),S=new Float32Array(g*m*p);for(let e=0;e2?0:-1,i=[t,n,0,t+2/3,n,0,t+2/3,n+1,0,t,n,0,t+2/3,n+1,0,t,n+1,0];v.set(i,h*m*e),E.set(f,_*m*e);const r=[e,e,e,e,e,e];S.set(r,g*m*e)}const M=new C;M.setAttribute("position",new y(v,h)),M.setAttribute("uv",new y(E,_)),M.setAttribute("faceIndex",new y(S,g)),i.push(new o(M,null)),r>4&&r--}return{lodMeshes:i,sizeLods:t,sigmas:n}}(i)),this._blurMaterial=function(e,t,n){const i=new Float32Array($n),a=new r(0,1,0),o=new l({name:"SphericalGaussianBlur",defines:{n:$n,CUBEUV_TEXEL_WIDTH:1/t,CUBEUV_TEXEL_HEIGHT:1/n,CUBEUV_MAX_MIP:`${e}.0`},uniforms:{envMap:{value:null},samples:{value:1},weights:{value:i},latitudinal:{value:!1},dTheta:{value:0},mipInt:{value:0},poleAxis:{value:a}},vertexShader:di(),fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform int samples;\n\t\t\tuniform float weights[ n ];\n\t\t\tuniform bool latitudinal;\n\t\t\tuniform float dTheta;\n\t\t\tuniform float mipInt;\n\t\t\tuniform vec3 poleAxis;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include \n\n\t\t\tvec3 getSample( float theta, vec3 axis ) {\n\n\t\t\t\tfloat cosTheta = cos( theta );\n\t\t\t\t// Rodrigues' axis-angle rotation\n\t\t\t\tvec3 sampleDirection = vOutputDirection * cosTheta\n\t\t\t\t\t+ cross( axis, vOutputDirection ) * sin( theta )\n\t\t\t\t\t+ axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta );\n\n\t\t\t\treturn bilinearCubeUV( envMap, sampleDirection, mipInt );\n\n\t\t\t}\n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection );\n\n\t\t\t\tif ( all( equal( axis, vec3( 0.0 ) ) ) ) {\n\n\t\t\t\t\taxis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x );\n\n\t\t\t\t}\n\n\t\t\t\taxis = normalize( axis );\n\n\t\t\t\tgl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 );\n\t\t\t\tgl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis );\n\n\t\t\t\tfor ( int i = 1; i < n; i++ ) {\n\n\t\t\t\t\tif ( i >= samples ) {\n\n\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t}\n\n\t\t\t\t\tfloat theta = dTheta * float( i );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis );\n\t\t\t\t\tgl_FragColor.rgb += weights[ i ] * getSample( theta, axis );\n\n\t\t\t\t}\n\n\t\t\t}\n\t\t",blending:I,depthTest:!1,depthWrite:!1});return o}(i,e,t),this._ggxMaterial=function(e,t,n){const i=new l({name:"PMREMGGXConvolution",defines:{GGX_SAMPLES:256,CUBEUV_TEXEL_WIDTH:1/t,CUBEUV_TEXEL_HEIGHT:1/n,CUBEUV_MAX_MIP:`${e}.0`},uniforms:{envMap:{value:null},roughness:{value:0},mipInt:{value:0}},vertexShader:di(),fragmentShader:'\n\n\t\t\tprecision highp float;\n\t\t\tprecision highp int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\t\t\tuniform float roughness;\n\t\t\tuniform float mipInt;\n\n\t\t\t#define ENVMAP_TYPE_CUBE_UV\n\t\t\t#include \n\n\t\t\t#define PI 3.14159265359\n\n\t\t\t// Van der Corput radical inverse\n\t\t\tfloat radicalInverse_VdC(uint bits) {\n\t\t\t\tbits = (bits << 16u) | (bits >> 16u);\n\t\t\t\tbits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);\n\t\t\t\tbits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);\n\t\t\t\tbits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);\n\t\t\t\tbits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);\n\t\t\t\treturn float(bits) * 2.3283064365386963e-10; // / 0x100000000\n\t\t\t}\n\n\t\t\t// Hammersley sequence\n\t\t\tvec2 hammersley(uint i, uint N) {\n\t\t\t\treturn vec2(float(i) / float(N), radicalInverse_VdC(i));\n\t\t\t}\n\n\t\t\t// GGX VNDF importance sampling (Eric Heitz 2018)\n\t\t\t// "Sampling the GGX Distribution of Visible Normals"\n\t\t\t// https://jcgt.org/published/0007/04/01/\n\t\t\tvec3 importanceSampleGGX_VNDF(vec2 Xi, vec3 V, float roughness) {\n\t\t\t\tfloat alpha = roughness * roughness;\n\n\t\t\t\t// Section 4.1: Orthonormal basis\n\t\t\t\tvec3 T1 = vec3(1.0, 0.0, 0.0);\n\t\t\t\tvec3 T2 = cross(V, T1);\n\n\t\t\t\t// Section 4.2: Parameterization of projected area\n\t\t\t\tfloat r = sqrt(Xi.x);\n\t\t\t\tfloat phi = 2.0 * PI * Xi.y;\n\t\t\t\tfloat t1 = r * cos(phi);\n\t\t\t\tfloat t2 = r * sin(phi);\n\t\t\t\tfloat s = 0.5 * (1.0 + V.z);\n\t\t\t\tt2 = (1.0 - s) * sqrt(1.0 - t1 * t1) + s * t2;\n\n\t\t\t\t// Section 4.3: Reprojection onto hemisphere\n\t\t\t\tvec3 Nh = t1 * T1 + t2 * T2 + sqrt(max(0.0, 1.0 - t1 * t1 - t2 * t2)) * V;\n\n\t\t\t\t// Section 3.4: Transform back to ellipsoid configuration\n\t\t\t\treturn normalize(vec3(alpha * Nh.x, alpha * Nh.y, max(0.0, Nh.z)));\n\t\t\t}\n\n\t\t\tvoid main() {\n\t\t\t\tvec3 N = normalize(vOutputDirection);\n\t\t\t\tvec3 V = N; // Assume view direction equals normal for pre-filtering\n\n\t\t\t\tvec3 prefilteredColor = vec3(0.0);\n\t\t\t\tfloat totalWeight = 0.0;\n\n\t\t\t\t// For very low roughness, just sample the environment directly\n\t\t\t\tif (roughness < 0.001) {\n\t\t\t\t\tgl_FragColor = vec4(bilinearCubeUV(envMap, N, mipInt), 1.0);\n\t\t\t\t\treturn;\n\t\t\t\t}\n\n\t\t\t\t// Tangent space basis for VNDF sampling\n\t\t\t\tvec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);\n\t\t\t\tvec3 tangent = normalize(cross(up, N));\n\t\t\t\tvec3 bitangent = cross(N, tangent);\n\n\t\t\t\tfor(uint i = 0u; i < uint(GGX_SAMPLES); i++) {\n\t\t\t\t\tvec2 Xi = hammersley(i, uint(GGX_SAMPLES));\n\n\t\t\t\t\t// For PMREM, V = N, so in tangent space V is always (0, 0, 1)\n\t\t\t\t\tvec3 H_tangent = importanceSampleGGX_VNDF(Xi, vec3(0.0, 0.0, 1.0), roughness);\n\n\t\t\t\t\t// Transform H back to world space\n\t\t\t\t\tvec3 H = normalize(tangent * H_tangent.x + bitangent * H_tangent.y + N * H_tangent.z);\n\t\t\t\t\tvec3 L = normalize(2.0 * dot(V, H) * H - V);\n\n\t\t\t\t\tfloat NdotL = max(dot(N, L), 0.0);\n\n\t\t\t\t\tif(NdotL > 0.0) {\n\t\t\t\t\t\t// Sample environment at fixed mip level\n\t\t\t\t\t\t// VNDF importance sampling handles the distribution filtering\n\t\t\t\t\t\tvec3 sampleColor = bilinearCubeUV(envMap, L, mipInt);\n\n\t\t\t\t\t\t// Weight by NdotL for the split-sum approximation\n\t\t\t\t\t\t// VNDF PDF naturally accounts for the visible microfacet distribution\n\t\t\t\t\t\tprefilteredColor += sampleColor * NdotL;\n\t\t\t\t\t\ttotalWeight += NdotL;\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tif (totalWeight > 0.0) {\n\t\t\t\t\tprefilteredColor = prefilteredColor / totalWeight;\n\t\t\t\t}\n\n\t\t\t\tgl_FragColor = vec4(prefilteredColor, 1.0);\n\t\t\t}\n\t\t',blending:I,depthTest:!1,depthWrite:!1});return i}(i,e,t)}return i}_compileMaterial(e){const t=new o(new C,e);this._renderer.compile(t,Qn)}_sceneToCubeUV(e,t,n,i,r){const a=new L(90,1,t,n),l=[1,-1,1,1,1,1],d=[1,1,1,-1,-1,-1],u=this._renderer,f=u.autoClear,p=u.toneMapping;u.getClearColor(Jn),u.toneMapping=U,u.autoClear=!1;u.state.buffers.depth.getReversed()&&(u.setRenderTarget(i),u.clearDepth(),u.setRenderTarget(null)),null===this._backgroundBox&&(this._backgroundBox=new o(new s,new D({name:"PMREM.Background",side:c,depthWrite:!1,depthTest:!1})));const m=this._backgroundBox,h=m.material;let _=!1;const g=e.background;g?g.isColor&&(h.color.copy(g),e.background=null,_=!0):(h.color.copy(Jn),_=!0);for(let t=0;t<6;t++){const n=t%3;0===n?(a.up.set(0,l[t],0),a.position.set(r.x,r.y,r.z),a.lookAt(r.x+d[t],r.y,r.z)):1===n?(a.up.set(0,0,l[t]),a.position.set(r.x,r.y,r.z),a.lookAt(r.x,r.y+d[t],r.z)):(a.up.set(0,l[t],0),a.position.set(r.x,r.y,r.z),a.lookAt(r.x,r.y,r.z+d[t]));const o=this._cubeSize;si(i,n*o,t>2?o:0,o,o),u.setRenderTarget(i),_&&u.render(m,a),u.render(e,a)}u.toneMapping=p,u.autoClear=f,e.background=g}_textureToCubeUV(e,t){const n=this._renderer,i=e.mapping===R||e.mapping===b;i?(null===this._cubemapMaterial&&(this._cubemapMaterial=ci()),this._cubemapMaterial.uniforms.flipEnvMap.value=!1===e.isRenderTargetTexture?-1:1):null===this._equirectMaterial&&(this._equirectMaterial=li());const r=i?this._cubemapMaterial:this._equirectMaterial,a=this._lodMeshes[0];a.material=r;r.uniforms.envMap.value=e;const o=this._cubeSize;si(t,0,0,3*o,2*o),n.setRenderTarget(t),n.render(a,Qn)}_applyPMREM(e){const t=this._renderer,n=t.autoClear;t.autoClear=!1;const i=this._lodMeshes.length;for(let t=1;tu-4?n-u+4:0),m=4*(this._cubeSize-f);s.envMap.value=e.texture,s.roughness.value=d,s.mipInt.value=u-t,si(r,p,m,3*f,2*f),i.setRenderTarget(r),i.render(o,Qn),s.envMap.value=r.texture,s.roughness.value=0,s.mipInt.value=u-n,si(e,p,m,3*f,2*f),i.setRenderTarget(e),i.render(o,Qn)}_blur(e,t,n,i,r){const a=this._pingPongRenderTarget;this._halfBlur(e,a,t,n,i,"latitudinal",r),this._halfBlur(a,e,n,n,i,"longitudinal",r)}_halfBlur(e,t,n,i,r,a,o){const s=this._renderer,l=this._blurMaterial;"latitudinal"!==a&&"longitudinal"!==a&&w("blur direction must be either latitudinal or longitudinal!");const c=this._lodMeshes[i];c.material=l;const d=l.uniforms,u=this._sizeLods[n]-1,f=isFinite(r)?Math.PI/(2*u):2*Math.PI/39,p=r/f,m=isFinite(r)?1+Math.floor(3*p):$n;m>$n&&E(`sigmaRadians, ${r}, is too large and will clip, as it requested ${m} samples when the maximum is set to 20`);const h=[];let _=0;for(let e=0;e<$n;++e){const t=e/p,n=Math.exp(-t*t/2);h.push(n),0===e?_+=n:eg-4?i-g+4:0),4*(this._cubeSize-v),3*v,2*v),s.setRenderTarget(t),s.render(c,Qn)}}function oi(e,t,n){const i=new N(e,t,n);return i.texture.mapping=a,i.texture.name="PMREM.cubeUv",i.scissorTest=!0,i}function si(e,t,n,i,r){e.viewport.set(t,n,i,r),e.scissor.set(t,n,i,r)}function li(){return new l({name:"EquirectangularToCubeUV",uniforms:{envMap:{value:null}},vertexShader:di(),fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform sampler2D envMap;\n\n\t\t\t#include \n\n\t\t\tvoid main() {\n\n\t\t\t\tvec3 outputDirection = normalize( vOutputDirection );\n\t\t\t\tvec2 uv = equirectUv( outputDirection );\n\n\t\t\t\tgl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 );\n\n\t\t\t}\n\t\t",blending:I,depthTest:!1,depthWrite:!1})}function ci(){return new l({name:"CubemapToCubeUV",uniforms:{envMap:{value:null},flipEnvMap:{value:-1}},vertexShader:di(),fragmentShader:"\n\n\t\t\tprecision mediump float;\n\t\t\tprecision mediump int;\n\n\t\t\tuniform float flipEnvMap;\n\n\t\t\tvarying vec3 vOutputDirection;\n\n\t\t\tuniform samplerCube envMap;\n\n\t\t\tvoid main() {\n\n\t\t\t\tgl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) );\n\n\t\t\t}\n\t\t",blending:I,depthTest:!1,depthWrite:!1})}function di(){return"\n\n\t\tprecision mediump float;\n\t\tprecision mediump int;\n\n\t\tattribute float faceIndex;\n\n\t\tvarying vec3 vOutputDirection;\n\n\t\t// RH coordinate system; PMREM face-indexing convention\n\t\tvec3 getDirection( vec2 uv, float face ) {\n\n\t\t\tuv = 2.0 * uv - 1.0;\n\n\t\t\tvec3 direction = vec3( uv, 1.0 );\n\n\t\t\tif ( face == 0.0 ) {\n\n\t\t\t\tdirection = direction.zyx; // ( 1, v, u ) pos x\n\n\t\t\t} else if ( face == 1.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xz *= -1.0; // ( -u, 1, -v ) pos y\n\n\t\t\t} else if ( face == 2.0 ) {\n\n\t\t\t\tdirection.x *= -1.0; // ( -u, v, 1 ) pos z\n\n\t\t\t} else if ( face == 3.0 ) {\n\n\t\t\t\tdirection = direction.zyx;\n\t\t\t\tdirection.xz *= -1.0; // ( -1, v, -u ) neg x\n\n\t\t\t} else if ( face == 4.0 ) {\n\n\t\t\t\tdirection = direction.xzy;\n\t\t\t\tdirection.xy *= -1.0; // ( -u, -1, v ) neg y\n\n\t\t\t} else if ( face == 5.0 ) {\n\n\t\t\t\tdirection.z *= -1.0; // ( u, v, -1 ) neg z\n\n\t\t\t}\n\n\t\t\treturn direction;\n\n\t\t}\n\n\t\tvoid main() {\n\n\t\t\tvOutputDirection = getDirection( uv, faceIndex );\n\t\t\tgl_Position = vec4( position, 1.0 );\n\n\t\t}\n\t"}class ui extends N{constructor(e=1,t={}){super(e,e,t),this.isWebGLCubeRenderTarget=!0;const n={width:e,height:e,depth:1},i=[n,n,n,n,n,n];this.texture=new B(i),this._setTextureOptions(t),this.texture.isRenderTargetTexture=!0}fromEquirectangularTexture(e,t){this.texture.type=t.type,this.texture.colorSpace=t.colorSpace,this.texture.generateMipmaps=t.generateMipmaps,this.texture.minFilter=t.minFilter,this.texture.magFilter=t.magFilter;const n={uniforms:{tEquirect:{value:null}},vertexShader:"\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\tvec3 transformDirection( in vec3 dir, in mat4 matrix ) {\n\n\t\t\t\t\treturn normalize( ( matrix * vec4( dir, 0.0 ) ).xyz );\n\n\t\t\t\t}\n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvWorldDirection = transformDirection( position, modelMatrix );\n\n\t\t\t\t\t#include \n\t\t\t\t\t#include \n\n\t\t\t\t}\n\t\t\t",fragmentShader:"\n\n\t\t\t\tuniform sampler2D tEquirect;\n\n\t\t\t\tvarying vec3 vWorldDirection;\n\n\t\t\t\t#include \n\n\t\t\t\tvoid main() {\n\n\t\t\t\t\tvec3 direction = normalize( vWorldDirection );\n\n\t\t\t\t\tvec2 sampleUV = equirectUv( direction );\n\n\t\t\t\t\tgl_FragColor = texture2D( tEquirect, sampleUV );\n\n\t\t\t\t}\n\t\t\t"},i=new s(5,5,5),r=new l({name:"CubemapFromEquirect",uniforms:d(n.uniforms),vertexShader:n.vertexShader,fragmentShader:n.fragmentShader,side:c,blending:I});r.uniforms.tEquirect.value=t;const a=new o(i,r),u=t.minFilter;t.minFilter===G&&(t.minFilter=O);return new H(1,10,this).update(e,a),t.minFilter=u,a.geometry.dispose(),a.material.dispose(),this}clear(e,t=!0,n=!0,i=!0){const r=e.getRenderTarget();for(let r=0;r<6;r++)e.setRenderTarget(this,r),e.clear(t,n,i);e.setRenderTarget(r)}}function fi(e){let t=new WeakMap,n=new WeakMap,i=null;function r(e,t){return t===V?e.mapping=R:t===W&&(e.mapping=b),e}function a(e){const n=e.target;n.removeEventListener("dispose",a);const i=t.get(n);void 0!==i&&(t.delete(n),i.dispose())}function o(e){const t=e.target;t.removeEventListener("dispose",o);const i=n.get(t);void 0!==i&&(n.delete(t),i.dispose())}return{get:function(s,l=!1){return null==s?null:l?function(t){if(t&&t.isTexture){const r=t.mapping,a=r===V||r===W,s=r===R||r===b;if(a||s){let r=n.get(t);const l=void 0!==r?r.texture.pmremVersion:0;if(t.isRenderTargetTexture&&t.pmremVersion!==l)return null===i&&(i=new ai(e)),r=a?i.fromEquirectangular(t,r):i.fromCubemap(t,r),r.texture.pmremVersion=t.pmremVersion,n.set(t,r),r.texture;if(void 0!==r)return r.texture;{const l=t.image;return a&&l&&l.height>0||s&&l&&function(e){let t=0;const n=6;for(let i=0;i0){const o=new ui(i.height);return o.fromEquirectangularTexture(e,n),t.set(n,o),n.addEventListener("dispose",a),r(o.texture,n.mapping)}return null}}}return n}(s)},dispose:function(){t=new WeakMap,n=new WeakMap,null!==i&&(i.dispose(),i=null)}}}function pi(e){const t={};function n(n){if(void 0!==t[n])return t[n];const i=e.getExtension(n);return t[n]=i,i}return{has:function(e){return null!==n(e)},init:function(){n("EXT_color_buffer_float"),n("WEBGL_clip_cull_distance"),n("OES_texture_float_linear"),n("EXT_color_buffer_half_float"),n("WEBGL_multisampled_render_to_texture"),n("WEBGL_render_shared_exponent")},get:function(e){const t=n(e);return null===t&&z("WebGLRenderer: "+e+" extension not supported."),t}}}function mi(e,t,n,i){const r={},a=new WeakMap;function o(e){const s=e.target;null!==s.index&&t.remove(s.index);for(const e in s.attributes)t.remove(s.attributes[e]);s.removeEventListener("dispose",o),delete r[s.id];const l=a.get(s);l&&(t.remove(l),a.delete(s)),i.releaseStatesOfGeometry(s),!0===s.isInstancedBufferGeometry&&delete s._maxInstanceCount,n.memory.geometries--}function s(e){const n=[],i=e.index,r=e.attributes.position;let o=0;if(null!==i){const e=i.array;o=i.version;for(let t=0,i=e.length;tn.maxTextureSize&&(M=Math.ceil(S/n.maxTextureSize),S=n.maxTextureSize);const x=new Float32Array(S*M*4*u),A=new q(x,S,M,u);A.type=T,A.needsUpdate=!0;const R=4*E;for(let C=0;C\n\t\t\t#include \n\n\t\t\tvoid main() {\n\t\t\t\tgl_FragColor = texture2D( tDiffuse, vUv );\n\n\t\t\t\t#ifdef LINEAR_TONE_MAPPING\n\t\t\t\t\tgl_FragColor.rgb = LinearToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( REINHARD_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = ReinhardToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( CINEON_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = CineonToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( ACES_FILMIC_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = ACESFilmicToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( AGX_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = AgXToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( NEUTRAL_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = NeutralToneMapping( gl_FragColor.rgb );\n\t\t\t\t#elif defined( CUSTOM_TONE_MAPPING )\n\t\t\t\t\tgl_FragColor.rgb = CustomToneMapping( gl_FragColor.rgb );\n\t\t\t\t#endif\n\n\t\t\t\t#ifdef SRGB_TRANSFER\n\t\t\t\t\tgl_FragColor = sRGBTransferOETF( gl_FragColor );\n\t\t\t\t#endif\n\t\t\t}",depthTest:!1,depthWrite:!1}),d=new o(l,c),u=new P(-1,1,1,-1,0,1);let f,h=null,_=null,g=!1,v=null,E=[],M=!1;this.setSize=function(e,t){a.setSize(e,t),s.setSize(e,t);for(let n=0;n0&&!0===E[0].isRenderPass;const t=a.width,n=a.height;for(let e=0;e0)return e;const r=t*n;let a=bi[r];if(void 0===a&&(a=new Float32Array(r),bi[r]=a),0!==t){i.toArray(a,0);for(let i=1,r=0;i!==t;++i)r+=n,e[i].toArray(a,r)}return a}function wi(e,t){if(e.length!==t.length)return!1;for(let n=0,i=e.length;n0&&(this.seq=i.concat(r))}setValue(e,t,n,i){const r=this.map[t];void 0!==r&&r.setValue(e,n,i)}setOptional(e,t,n){const i=t[n];void 0!==i&&this.setValue(e,n,i)}static upload(e,t,n,i){for(let r=0,a=t.length;r!==a;++r){const a=t[r],o=n[a.id];!1!==o.needsUpdate&&a.setValue(e,o.value,i)}}static seqWithValue(e,t){const n=[];for(let i=0,r=e.length;i!==r;++i){const r=e[i];r.id in t&&n.push(r)}return n}}function br(e,t,n){const i=e.createShader(t);return e.shaderSource(i,n),e.compileShader(i),i}let Cr=0;const Pr=new e;function Lr(e,t,n){const i=e.getShaderParameter(t,e.COMPILE_STATUS),r=(e.getShaderInfoLog(t)||"").trim();if(i&&""===r)return"";const a=/ERROR: 0:(\d+)/.exec(r);if(a){const i=parseInt(a[1]);return n.toUpperCase()+"\n\n"+r+"\n\n"+function(e,t){const n=e.split("\n"),i=[],r=Math.max(t-6,0),a=Math.min(t+6,n.length);for(let e=r;e":" "} ${r}: ${n[e]}`)}return i.join("\n")}(e.getShaderSource(t),i)}return r}function Ur(e,t){const n=function(e){p._getMatrix(Pr,p.workingColorSpace,e);const t=`mat3( ${Pr.elements.map(e=>e.toFixed(4))} )`;switch(p.getTransfer(e)){case he:return[t,"LinearTransferOETF"];case m:return[t,"sRGBTransferOETF"];default:return E("WebGLProgram: Unsupported color space: ",e),[t,"LinearTransferOETF"]}}(t);return[`vec4 ${e}( vec4 value ) {`,`\treturn ${n[1]}( vec4( value.rgb * ${n[0]}, value.a ) );`,"}"].join("\n")}const Dr={[ie]:"Linear",[ne]:"Reinhard",[te]:"Cineon",[ee]:"ACESFilmic",[J]:"AgX",[Q]:"Neutral",[$]:"Custom"};function wr(e,t){const n=Dr[t];return void 0===n?(E("WebGLProgram: Unsupported toneMapping:",t),"vec3 "+e+"( vec3 color ) { return LinearToneMapping( color ); }"):"vec3 "+e+"( vec3 color ) { return "+n+"ToneMapping( color ); }"}const Ir=new r;function Nr(){p.getLuminanceCoefficients(Ir);return["float luminance( const in vec3 rgb ) {",`\tconst vec3 weights = vec3( ${Ir.x.toFixed(4)}, ${Ir.y.toFixed(4)}, ${Ir.z.toFixed(4)} );`,"\treturn dot( weights, rgb );","}"].join("\n")}function yr(e){return""!==e}function Fr(e,t){const n=t.numSpotLightShadows+t.numSpotLightMaps-t.numSpotLightShadowsWithMaps;return e.replace(/NUM_DIR_LIGHTS/g,t.numDirLights).replace(/NUM_SPOT_LIGHTS/g,t.numSpotLights).replace(/NUM_SPOT_LIGHT_MAPS/g,t.numSpotLightMaps).replace(/NUM_SPOT_LIGHT_COORDS/g,n).replace(/NUM_RECT_AREA_LIGHTS/g,t.numRectAreaLights).replace(/NUM_POINT_LIGHTS/g,t.numPointLights).replace(/NUM_HEMI_LIGHTS/g,t.numHemiLights).replace(/NUM_DIR_LIGHT_SHADOWS/g,t.numDirLightShadows).replace(/NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS/g,t.numSpotLightShadowsWithMaps).replace(/NUM_SPOT_LIGHT_SHADOWS/g,t.numSpotLightShadows).replace(/NUM_POINT_LIGHT_SHADOWS/g,t.numPointLightShadows)}function Or(e,t){return e.replace(/NUM_CLIPPING_PLANES/g,t.numClippingPlanes).replace(/UNION_CLIPPING_PLANES/g,t.numClippingPlanes-t.numClipIntersection)}const Br=/^[ \t]*#include +<([\w\d./]+)>/gm;function Gr(e){return e.replace(Br,Vr)}const Hr=new Map;function Vr(e,t){let n=Gn[t];if(void 0===n){const e=Hr.get(t);if(void 0===e)throw new Error("Can not resolve #include <"+t+">");n=Gn[e],E('WebGLRenderer: Shader chunk "%s" has been deprecated. Use "%s" instead.',t,e)}return Gr(n)}const Wr=/#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end/g;function zr(e){return e.replace(Wr,kr)}function kr(e,t,n,i){let r="";for(let e=parseInt(t);e0&&(_+="\n"),g=["#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,m].filter(yr).join("\n"),g.length>0&&(g+="\n")):(_=[Xr(n),"#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,m,n.extensionClipCullDistance?"#define USE_CLIP_DISTANCE":"",n.batching?"#define USE_BATCHING":"",n.batchingColor?"#define USE_BATCHING_COLOR":"",n.instancing?"#define USE_INSTANCING":"",n.instancingColor?"#define USE_INSTANCING_COLOR":"",n.instancingMorph?"#define USE_INSTANCING_MORPH":"",n.useFog&&n.fog?"#define USE_FOG":"",n.useFog&&n.fogExp2?"#define FOG_EXP2":"",n.map?"#define USE_MAP":"",n.envMap?"#define USE_ENVMAP":"",n.envMap?"#define "+d:"",n.lightMap?"#define USE_LIGHTMAP":"",n.aoMap?"#define USE_AOMAP":"",n.bumpMap?"#define USE_BUMPMAP":"",n.normalMap?"#define USE_NORMALMAP":"",n.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",n.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",n.displacementMap?"#define USE_DISPLACEMENTMAP":"",n.emissiveMap?"#define USE_EMISSIVEMAP":"",n.anisotropy?"#define USE_ANISOTROPY":"",n.anisotropyMap?"#define USE_ANISOTROPYMAP":"",n.clearcoatMap?"#define USE_CLEARCOATMAP":"",n.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",n.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",n.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",n.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",n.specularMap?"#define USE_SPECULARMAP":"",n.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",n.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",n.roughnessMap?"#define USE_ROUGHNESSMAP":"",n.metalnessMap?"#define USE_METALNESSMAP":"",n.alphaMap?"#define USE_ALPHAMAP":"",n.alphaHash?"#define USE_ALPHAHASH":"",n.transmission?"#define USE_TRANSMISSION":"",n.transmissionMap?"#define USE_TRANSMISSIONMAP":"",n.thicknessMap?"#define USE_THICKNESSMAP":"",n.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",n.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",n.mapUv?"#define MAP_UV "+n.mapUv:"",n.alphaMapUv?"#define ALPHAMAP_UV "+n.alphaMapUv:"",n.lightMapUv?"#define LIGHTMAP_UV "+n.lightMapUv:"",n.aoMapUv?"#define AOMAP_UV "+n.aoMapUv:"",n.emissiveMapUv?"#define EMISSIVEMAP_UV "+n.emissiveMapUv:"",n.bumpMapUv?"#define BUMPMAP_UV "+n.bumpMapUv:"",n.normalMapUv?"#define NORMALMAP_UV "+n.normalMapUv:"",n.displacementMapUv?"#define DISPLACEMENTMAP_UV "+n.displacementMapUv:"",n.metalnessMapUv?"#define METALNESSMAP_UV "+n.metalnessMapUv:"",n.roughnessMapUv?"#define ROUGHNESSMAP_UV "+n.roughnessMapUv:"",n.anisotropyMapUv?"#define ANISOTROPYMAP_UV "+n.anisotropyMapUv:"",n.clearcoatMapUv?"#define CLEARCOATMAP_UV "+n.clearcoatMapUv:"",n.clearcoatNormalMapUv?"#define CLEARCOAT_NORMALMAP_UV "+n.clearcoatNormalMapUv:"",n.clearcoatRoughnessMapUv?"#define CLEARCOAT_ROUGHNESSMAP_UV "+n.clearcoatRoughnessMapUv:"",n.iridescenceMapUv?"#define IRIDESCENCEMAP_UV "+n.iridescenceMapUv:"",n.iridescenceThicknessMapUv?"#define IRIDESCENCE_THICKNESSMAP_UV "+n.iridescenceThicknessMapUv:"",n.sheenColorMapUv?"#define SHEEN_COLORMAP_UV "+n.sheenColorMapUv:"",n.sheenRoughnessMapUv?"#define SHEEN_ROUGHNESSMAP_UV "+n.sheenRoughnessMapUv:"",n.specularMapUv?"#define SPECULARMAP_UV "+n.specularMapUv:"",n.specularColorMapUv?"#define SPECULAR_COLORMAP_UV "+n.specularColorMapUv:"",n.specularIntensityMapUv?"#define SPECULAR_INTENSITYMAP_UV "+n.specularIntensityMapUv:"",n.transmissionMapUv?"#define TRANSMISSIONMAP_UV "+n.transmissionMapUv:"",n.thicknessMapUv?"#define THICKNESSMAP_UV "+n.thicknessMapUv:"",n.vertexTangents&&!1===n.flatShading?"#define USE_TANGENT":"",n.vertexColors?"#define USE_COLOR":"",n.vertexAlphas?"#define USE_COLOR_ALPHA":"",n.vertexUv1s?"#define USE_UV1":"",n.vertexUv2s?"#define USE_UV2":"",n.vertexUv3s?"#define USE_UV3":"",n.pointsUvs?"#define USE_POINTS_UV":"",n.flatShading?"#define FLAT_SHADED":"",n.skinning?"#define USE_SKINNING":"",n.morphTargets?"#define USE_MORPHTARGETS":"",n.morphNormals&&!1===n.flatShading?"#define USE_MORPHNORMALS":"",n.morphColors?"#define USE_MORPHCOLORS":"",n.morphTargetsCount>0?"#define MORPHTARGETS_TEXTURE_STRIDE "+n.morphTextureStride:"",n.morphTargetsCount>0?"#define MORPHTARGETS_COUNT "+n.morphTargetsCount:"",n.doubleSided?"#define DOUBLE_SIDED":"",n.flipSided?"#define FLIP_SIDED":"",n.shadowMapEnabled?"#define USE_SHADOWMAP":"",n.shadowMapEnabled?"#define "+l:"",n.sizeAttenuation?"#define USE_SIZEATTENUATION":"",n.numLightProbes>0?"#define USE_LIGHT_PROBES":"",n.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",n.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 modelMatrix;","uniform mat4 modelViewMatrix;","uniform mat4 projectionMatrix;","uniform mat4 viewMatrix;","uniform mat3 normalMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;","#ifdef USE_INSTANCING","\tattribute mat4 instanceMatrix;","#endif","#ifdef USE_INSTANCING_COLOR","\tattribute vec3 instanceColor;","#endif","#ifdef USE_INSTANCING_MORPH","\tuniform sampler2D morphTexture;","#endif","attribute vec3 position;","attribute vec3 normal;","attribute vec2 uv;","#ifdef USE_UV1","\tattribute vec2 uv1;","#endif","#ifdef USE_UV2","\tattribute vec2 uv2;","#endif","#ifdef USE_UV3","\tattribute vec2 uv3;","#endif","#ifdef USE_TANGENT","\tattribute vec4 tangent;","#endif","#if defined( USE_COLOR_ALPHA )","\tattribute vec4 color;","#elif defined( USE_COLOR )","\tattribute vec3 color;","#endif","#ifdef USE_SKINNING","\tattribute vec4 skinIndex;","\tattribute vec4 skinWeight;","#endif","\n"].filter(yr).join("\n"),g=[Xr(n),"#define SHADER_TYPE "+n.shaderType,"#define SHADER_NAME "+n.shaderName,m,n.useFog&&n.fog?"#define USE_FOG":"",n.useFog&&n.fogExp2?"#define FOG_EXP2":"",n.alphaToCoverage?"#define ALPHA_TO_COVERAGE":"",n.map?"#define USE_MAP":"",n.matcap?"#define USE_MATCAP":"",n.envMap?"#define USE_ENVMAP":"",n.envMap?"#define "+c:"",n.envMap?"#define "+d:"",n.envMap?"#define "+u:"",f?"#define CUBEUV_TEXEL_WIDTH "+f.texelWidth:"",f?"#define CUBEUV_TEXEL_HEIGHT "+f.texelHeight:"",f?"#define CUBEUV_MAX_MIP "+f.maxMip+".0":"",n.lightMap?"#define USE_LIGHTMAP":"",n.aoMap?"#define USE_AOMAP":"",n.bumpMap?"#define USE_BUMPMAP":"",n.normalMap?"#define USE_NORMALMAP":"",n.normalMapObjectSpace?"#define USE_NORMALMAP_OBJECTSPACE":"",n.normalMapTangentSpace?"#define USE_NORMALMAP_TANGENTSPACE":"",n.emissiveMap?"#define USE_EMISSIVEMAP":"",n.anisotropy?"#define USE_ANISOTROPY":"",n.anisotropyMap?"#define USE_ANISOTROPYMAP":"",n.clearcoat?"#define USE_CLEARCOAT":"",n.clearcoatMap?"#define USE_CLEARCOATMAP":"",n.clearcoatRoughnessMap?"#define USE_CLEARCOAT_ROUGHNESSMAP":"",n.clearcoatNormalMap?"#define USE_CLEARCOAT_NORMALMAP":"",n.dispersion?"#define USE_DISPERSION":"",n.iridescence?"#define USE_IRIDESCENCE":"",n.iridescenceMap?"#define USE_IRIDESCENCEMAP":"",n.iridescenceThicknessMap?"#define USE_IRIDESCENCE_THICKNESSMAP":"",n.specularMap?"#define USE_SPECULARMAP":"",n.specularColorMap?"#define USE_SPECULAR_COLORMAP":"",n.specularIntensityMap?"#define USE_SPECULAR_INTENSITYMAP":"",n.roughnessMap?"#define USE_ROUGHNESSMAP":"",n.metalnessMap?"#define USE_METALNESSMAP":"",n.alphaMap?"#define USE_ALPHAMAP":"",n.alphaTest?"#define USE_ALPHATEST":"",n.alphaHash?"#define USE_ALPHAHASH":"",n.sheen?"#define USE_SHEEN":"",n.sheenColorMap?"#define USE_SHEEN_COLORMAP":"",n.sheenRoughnessMap?"#define USE_SHEEN_ROUGHNESSMAP":"",n.transmission?"#define USE_TRANSMISSION":"",n.transmissionMap?"#define USE_TRANSMISSIONMAP":"",n.thicknessMap?"#define USE_THICKNESSMAP":"",n.vertexTangents&&!1===n.flatShading?"#define USE_TANGENT":"",n.vertexColors||n.instancingColor?"#define USE_COLOR":"",n.vertexAlphas||n.batchingColor?"#define USE_COLOR_ALPHA":"",n.vertexUv1s?"#define USE_UV1":"",n.vertexUv2s?"#define USE_UV2":"",n.vertexUv3s?"#define USE_UV3":"",n.pointsUvs?"#define USE_POINTS_UV":"",n.gradientMap?"#define USE_GRADIENTMAP":"",n.flatShading?"#define FLAT_SHADED":"",n.doubleSided?"#define DOUBLE_SIDED":"",n.flipSided?"#define FLIP_SIDED":"",n.shadowMapEnabled?"#define USE_SHADOWMAP":"",n.shadowMapEnabled?"#define "+l:"",n.premultipliedAlpha?"#define PREMULTIPLIED_ALPHA":"",n.numLightProbes>0?"#define USE_LIGHT_PROBES":"",n.decodeVideoTexture?"#define DECODE_VIDEO_TEXTURE":"",n.decodeVideoTextureEmissive?"#define DECODE_VIDEO_TEXTURE_EMISSIVE":"",n.logarithmicDepthBuffer?"#define USE_LOGARITHMIC_DEPTH_BUFFER":"",n.reversedDepthBuffer?"#define USE_REVERSED_DEPTH_BUFFER":"","uniform mat4 viewMatrix;","uniform vec3 cameraPosition;","uniform bool isOrthographic;",n.toneMapping!==U?"#define TONE_MAPPING":"",n.toneMapping!==U?Gn.tonemapping_pars_fragment:"",n.toneMapping!==U?wr("toneMapping",n.toneMapping):"",n.dithering?"#define DITHERING":"",n.opaque?"#define OPAQUE":"",Gn.colorspace_pars_fragment,Ur("linearToOutputTexel",n.outputColorSpace),Nr(),n.useDepthPacking?"#define DEPTH_PACKING "+n.depthPacking:"","\n"].filter(yr).join("\n")),o=Gr(o),o=Fr(o,n),o=Or(o,n),s=Gr(s),s=Fr(s,n),s=Or(s,n),o=zr(o),s=zr(s),!0!==n.isRawShaderMaterial&&(v="#version 300 es\n",_=[p,"#define attribute in","#define varying out","#define texture2D texture"].join("\n")+"\n"+_,g=["#define varying in",n.glslVersion===ce?"":"layout(location = 0) out highp vec4 pc_fragColor;",n.glslVersion===ce?"":"#define gl_FragColor pc_fragColor","#define gl_FragDepthEXT gl_FragDepth","#define texture2D texture","#define textureCube texture","#define texture2DProj textureProj","#define texture2DLodEXT textureLod","#define texture2DProjLodEXT textureProjLod","#define textureCubeLodEXT textureLod","#define texture2DGradEXT textureGrad","#define texture2DProjGradEXT textureProjGrad","#define textureCubeGradEXT textureGrad"].join("\n")+"\n"+g);const S=v+_+o,M=v+g+s,T=br(r,r.VERTEX_SHADER,S),x=br(r,r.FRAGMENT_SHADER,M);function A(t){if(e.debug.checkShaderErrors){const n=r.getProgramInfoLog(h)||"",i=r.getShaderInfoLog(T)||"",a=r.getShaderInfoLog(x)||"",o=n.trim(),s=i.trim(),l=a.trim();let c=!0,d=!0;if(!1===r.getProgramParameter(h,r.LINK_STATUS))if(c=!1,"function"==typeof e.debug.onShaderError)e.debug.onShaderError(r,h,T,x);else{const e=Lr(r,T,"vertex"),n=Lr(r,x,"fragment");w("THREE.WebGLProgram: Shader Error "+r.getError()+" - VALIDATE_STATUS "+r.getProgramParameter(h,r.VALIDATE_STATUS)+"\n\nMaterial Name: "+t.name+"\nMaterial Type: "+t.type+"\n\nProgram Info Log: "+o+"\n"+e+"\n"+n)}else""!==o?E("WebGLProgram: Program Info Log:",o):""!==s&&""!==l||(d=!1);d&&(t.diagnostics={runnable:c,programLog:o,vertexShader:{log:s,prefix:_},fragmentShader:{log:l,prefix:g}})}r.deleteShader(T),r.deleteShader(x),R=new Rr(r,h),b=function(e,t){const n={},i=e.getProgramParameter(t,e.ACTIVE_ATTRIBUTES);for(let r=0;r0,J=r.clearcoat>0,ee=r.dispersion>0,te=r.iridescence>0,ne=r.sheen>0,ie=r.transmission>0,re=Q&&!!r.anisotropyMap,ae=J&&!!r.clearcoatMap,oe=J&&!!r.clearcoatNormalMap,se=J&&!!r.clearcoatRoughnessMap,le=te&&!!r.iridescenceMap,ce=te&&!!r.iridescenceThicknessMap,de=ne&&!!r.sheenColorMap,ue=ne&&!!r.sheenRoughnessMap,fe=!!r.specularMap,pe=!!r.specularColorMap,me=!!r.specularIntensityMap,he=ie&&!!r.transmissionMap,_e=ie&&!!r.thicknessMap,Me=!!r.gradientMap,Te=!!r.alphaMap,xe=r.alphaTest>0,Ae=!!r.alphaHash,Re=!!r.extensions;let be=U;r.toneMapped&&(null!==O&&!0!==O.isXRRenderTarget||(be=e.toneMapping));const Ce={shaderID:C,shaderType:r.type,shaderName:r.name,vertexShader:D,fragmentShader:w,defines:r.defines,customVertexShaderID:I,customFragmentShaderID:N,isRawShaderMaterial:!0===r.isRawShaderMaterial,glslVersion:r.glslVersion,precision:_,batching:H,batchingColor:H&&null!==S._colorsTexture,instancing:G,instancingColor:G&&null!==S.instanceColor,instancingMorph:G&&null!==S.morphTexture,outputColorSpace:null===O?e.outputColorSpace:!0===O.isXRRenderTarget?O.texture.colorSpace:F,alphaToCoverage:!!r.alphaToCoverage,map:V,matcap:W,envMap:z,envMapMode:z&&R.mapping,envMapCubeUVHeight:b,aoMap:k,lightMap:X,bumpMap:Y,normalMap:K,displacementMap:q,emissiveMap:j,normalMapObjectSpace:K&&r.normalMapType===Se,normalMapTangentSpace:K&&r.normalMapType===Ee,metalnessMap:Z,roughnessMap:$,anisotropy:Q,anisotropyMap:re,clearcoat:J,clearcoatMap:ae,clearcoatNormalMap:oe,clearcoatRoughnessMap:se,dispersion:ee,iridescence:te,iridescenceMap:le,iridescenceThicknessMap:ce,sheen:ne,sheenColorMap:de,sheenRoughnessMap:ue,specularMap:fe,specularColorMap:pe,specularIntensityMap:me,transmission:ie,transmissionMap:he,thicknessMap:_e,gradientMap:Me,opaque:!1===r.transparent&&r.blending===ve&&!1===r.alphaToCoverage,alphaMap:Te,alphaTest:xe,alphaHash:Ae,combine:r.combine,mapUv:V&&v(r.map.channel),aoMapUv:k&&v(r.aoMap.channel),lightMapUv:X&&v(r.lightMap.channel),bumpMapUv:Y&&v(r.bumpMap.channel),normalMapUv:K&&v(r.normalMap.channel),displacementMapUv:q&&v(r.displacementMap.channel),emissiveMapUv:j&&v(r.emissiveMap.channel),metalnessMapUv:Z&&v(r.metalnessMap.channel),roughnessMapUv:$&&v(r.roughnessMap.channel),anisotropyMapUv:re&&v(r.anisotropyMap.channel),clearcoatMapUv:ae&&v(r.clearcoatMap.channel),clearcoatNormalMapUv:oe&&v(r.clearcoatNormalMap.channel),clearcoatRoughnessMapUv:se&&v(r.clearcoatRoughnessMap.channel),iridescenceMapUv:le&&v(r.iridescenceMap.channel),iridescenceThicknessMapUv:ce&&v(r.iridescenceThicknessMap.channel),sheenColorMapUv:de&&v(r.sheenColorMap.channel),sheenRoughnessMapUv:ue&&v(r.sheenRoughnessMap.channel),specularMapUv:fe&&v(r.specularMap.channel),specularColorMapUv:pe&&v(r.specularColorMap.channel),specularIntensityMapUv:me&&v(r.specularIntensityMap.channel),transmissionMapUv:he&&v(r.transmissionMap.channel),thicknessMapUv:_e&&v(r.thicknessMap.channel),alphaMapUv:Te&&v(r.alphaMap.channel),vertexTangents:!!T.attributes.tangent&&(K||Q),vertexColors:r.vertexColors,vertexAlphas:!0===r.vertexColors&&!!T.attributes.color&&4===T.attributes.color.itemSize,pointsUvs:!0===S.isPoints&&!!T.attributes.uv&&(V||Te),fog:!!M,useFog:!0===r.fog,fogExp2:!!M&&M.isFogExp2,flatShading:!1===r.wireframe&&(!0===r.flatShading||void 0===T.attributes.normal&&!1===K&&(r.isMeshLambertMaterial||r.isMeshPhongMaterial||r.isMeshStandardMaterial||r.isMeshPhysicalMaterial)),sizeAttenuation:!0===r.sizeAttenuation,logarithmicDepthBuffer:h,reversedDepthBuffer:B,skinning:!0===S.isSkinnedMesh,morphTargets:void 0!==T.morphAttributes.position,morphNormals:void 0!==T.morphAttributes.normal,morphColors:void 0!==T.morphAttributes.color,morphTargetsCount:L,morphTextureStride:y,numDirLights:s.directional.length,numPointLights:s.point.length,numSpotLights:s.spot.length,numSpotLightMaps:s.spotLightMap.length,numRectAreaLights:s.rectArea.length,numHemiLights:s.hemi.length,numDirLightShadows:s.directionalShadowMap.length,numPointLightShadows:s.pointShadowMap.length,numSpotLightShadows:s.spotShadowMap.length,numSpotLightShadowsWithMaps:s.numSpotLightShadowsWithMaps,numLightProbes:s.numLightProbes,numClippingPlanes:o.numPlanes,numClipIntersection:o.numIntersection,dithering:r.dithering,shadowMapEnabled:e.shadowMap.enabled&&u.length>0,shadowMapType:e.shadowMap.type,toneMapping:be,decodeVideoTexture:V&&!0===r.map.isVideoTexture&&p.getTransfer(r.map.colorSpace)===m,decodeVideoTextureEmissive:j&&!0===r.emissiveMap.isVideoTexture&&p.getTransfer(r.emissiveMap.colorSpace)===m,premultipliedAlpha:r.premultipliedAlpha,doubleSided:r.side===ge,flipSided:r.side===c,useDepthPacking:r.depthPacking>=0,depthPacking:r.depthPacking||0,index0AttributeName:r.index0AttributeName,extensionClipCullDistance:Re&&!0===r.extensions.clipCullDistance&&n.has("WEBGL_clip_cull_distance"),extensionMultiDraw:(Re&&!0===r.extensions.multiDraw||H)&&n.has("WEBGL_multi_draw"),rendererExtensionParallelShaderCompile:n.has("KHR_parallel_shader_compile"),customProgramCacheKey:r.customProgramCacheKey()};return Ce.vertexUv1s=d.has(1),Ce.vertexUv2s=d.has(2),Ce.vertexUv3s=d.has(3),d.clear(),Ce},getProgramCacheKey:function(t){const n=[];if(t.shaderID?n.push(t.shaderID):(n.push(t.customVertexShaderID),n.push(t.customFragmentShaderID)),void 0!==t.defines)for(const e in t.defines)n.push(e),n.push(t.defines[e]);return!1===t.isRawShaderMaterial&&(!function(e,t){e.push(t.precision),e.push(t.outputColorSpace),e.push(t.envMapMode),e.push(t.envMapCubeUVHeight),e.push(t.mapUv),e.push(t.alphaMapUv),e.push(t.lightMapUv),e.push(t.aoMapUv),e.push(t.bumpMapUv),e.push(t.normalMapUv),e.push(t.displacementMapUv),e.push(t.emissiveMapUv),e.push(t.metalnessMapUv),e.push(t.roughnessMapUv),e.push(t.anisotropyMapUv),e.push(t.clearcoatMapUv),e.push(t.clearcoatNormalMapUv),e.push(t.clearcoatRoughnessMapUv),e.push(t.iridescenceMapUv),e.push(t.iridescenceThicknessMapUv),e.push(t.sheenColorMapUv),e.push(t.sheenRoughnessMapUv),e.push(t.specularMapUv),e.push(t.specularColorMapUv),e.push(t.specularIntensityMapUv),e.push(t.transmissionMapUv),e.push(t.thicknessMapUv),e.push(t.combine),e.push(t.fogExp2),e.push(t.sizeAttenuation),e.push(t.morphTargetsCount),e.push(t.morphAttributeCount),e.push(t.numDirLights),e.push(t.numPointLights),e.push(t.numSpotLights),e.push(t.numSpotLightMaps),e.push(t.numHemiLights),e.push(t.numRectAreaLights),e.push(t.numDirLightShadows),e.push(t.numPointLightShadows),e.push(t.numSpotLightShadows),e.push(t.numSpotLightShadowsWithMaps),e.push(t.numLightProbes),e.push(t.shadowMapType),e.push(t.toneMapping),e.push(t.numClippingPlanes),e.push(t.numClipIntersection),e.push(t.depthPacking)}(n,t),function(e,t){s.disableAll(),t.instancing&&s.enable(0);t.instancingColor&&s.enable(1);t.instancingMorph&&s.enable(2);t.matcap&&s.enable(3);t.envMap&&s.enable(4);t.normalMapObjectSpace&&s.enable(5);t.normalMapTangentSpace&&s.enable(6);t.clearcoat&&s.enable(7);t.iridescence&&s.enable(8);t.alphaTest&&s.enable(9);t.vertexColors&&s.enable(10);t.vertexAlphas&&s.enable(11);t.vertexUv1s&&s.enable(12);t.vertexUv2s&&s.enable(13);t.vertexUv3s&&s.enable(14);t.vertexTangents&&s.enable(15);t.anisotropy&&s.enable(16);t.alphaHash&&s.enable(17);t.batching&&s.enable(18);t.dispersion&&s.enable(19);t.batchingColor&&s.enable(20);t.gradientMap&&s.enable(21);e.push(s.mask),s.disableAll(),t.fog&&s.enable(0);t.useFog&&s.enable(1);t.flatShading&&s.enable(2);t.logarithmicDepthBuffer&&s.enable(3);t.reversedDepthBuffer&&s.enable(4);t.skinning&&s.enable(5);t.morphTargets&&s.enable(6);t.morphNormals&&s.enable(7);t.morphColors&&s.enable(8);t.premultipliedAlpha&&s.enable(9);t.shadowMapEnabled&&s.enable(10);t.doubleSided&&s.enable(11);t.flipSided&&s.enable(12);t.useDepthPacking&&s.enable(13);t.dithering&&s.enable(14);t.transmission&&s.enable(15);t.sheen&&s.enable(16);t.opaque&&s.enable(17);t.pointsUvs&&s.enable(18);t.decodeVideoTexture&&s.enable(19);t.decodeVideoTextureEmissive&&s.enable(20);t.alphaToCoverage&&s.enable(21);e.push(s.mask)}(n,t),n.push(e.outputColorSpace)),n.push(t.customProgramCacheKey),n.join()},getUniforms:function(e){const t=g[e.type];let n;if(t){const e=Vn[t];n=_e.clone(e.uniforms)}else n=e.uniforms;return n},acquireProgram:function(t,n){let i=f.get(n);return void 0!==i?++i.usedTimes:(i=new Zr(e,n,t,r),u.push(i),f.set(n,i)),i},releaseProgram:function(e){if(0===--e.usedTimes){const t=u.indexOf(e);u[t]=u[u.length-1],u.pop(),f.delete(e.cacheKey),e.destroy()}},releaseShaderCache:function(e){l.remove(e)},programs:u,dispose:function(){l.dispose()}}}function ta(){let e=new WeakMap;return{has:function(t){return e.has(t)},get:function(t){let n=e.get(t);return void 0===n&&(n={},e.set(t,n)),n},remove:function(t){e.delete(t)},update:function(t,n,i){e.get(t)[n]=i},dispose:function(){e=new WeakMap}}}function na(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.material.id!==t.material.id?e.material.id-t.material.id:e.materialVariant!==t.materialVariant?e.materialVariant-t.materialVariant:e.z!==t.z?e.z-t.z:e.id-t.id}function ia(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?t.z-e.z:e.id-t.id}function ra(){const e=[];let t=0;const n=[],i=[],r=[];function a(e){let t=0;return e.isInstancedMesh&&(t+=2),e.isSkinnedMesh&&(t+=1),t}function o(n,i,r,o,s,l){let c=e[t];return void 0===c?(c={id:n.id,object:n,geometry:i,material:r,materialVariant:a(n),groupOrder:o,renderOrder:n.renderOrder,z:s,group:l},e[t]=c):(c.id=n.id,c.object=n,c.geometry=i,c.material=r,c.materialVariant=a(n),c.groupOrder=o,c.renderOrder=n.renderOrder,c.z=s,c.group=l),t++,c}return{opaque:n,transmissive:i,transparent:r,init:function(){t=0,n.length=0,i.length=0,r.length=0},push:function(e,t,a,s,l,c){const d=o(e,t,a,s,l,c);a.transmission>0?i.push(d):!0===a.transparent?r.push(d):n.push(d)},unshift:function(e,t,a,s,l,c){const d=o(e,t,a,s,l,c);a.transmission>0?i.unshift(d):!0===a.transparent?r.unshift(d):n.unshift(d)},finish:function(){for(let n=t,i=e.length;n1&&n.sort(e||na),i.length>1&&i.sort(t||ia),r.length>1&&r.sort(t||ia)}}}function aa(){let e=new WeakMap;return{get:function(t,n){const i=e.get(t);let r;return void 0===i?(r=new ra,e.set(t,[r])):n>=i.length?(r=new ra,i.push(r)):r=i[n],r},dispose:function(){e=new WeakMap}}}function oa(){const e={};return{get:function(t){if(void 0!==e[t.id])return e[t.id];let i;switch(t.type){case"DirectionalLight":i={direction:new r,color:new n};break;case"SpotLight":i={position:new r,direction:new r,color:new n,distance:0,coneCos:0,penumbraCos:0,decay:0};break;case"PointLight":i={position:new r,color:new n,distance:0,decay:0};break;case"HemisphereLight":i={direction:new r,skyColor:new n,groundColor:new n};break;case"RectAreaLight":i={color:new n,position:new r,halfWidth:new r,halfHeight:new r}}return e[t.id]=i,i}}}let sa=0;function la(e,t){return(t.castShadow?2:0)-(e.castShadow?2:0)+(t.map?1:0)-(e.map?1:0)}function ca(e){const n=new oa,i=function(){const e={};return{get:function(n){if(void 0!==e[n.id])return e[n.id];let i;switch(n.type){case"DirectionalLight":case"SpotLight":i={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new t};break;case"PointLight":i={shadowIntensity:1,shadowBias:0,shadowNormalBias:0,shadowRadius:1,shadowMapSize:new t,shadowCameraNear:1,shadowCameraFar:1e3}}return e[n.id]=i,i}}}(),a={version:0,hash:{directionalLength:-1,pointLength:-1,spotLength:-1,rectAreaLength:-1,hemiLength:-1,numDirectionalShadows:-1,numPointShadows:-1,numSpotShadows:-1,numSpotMaps:-1,numLightProbes:-1},ambient:[0,0,0],probe:[],directional:[],directionalShadow:[],directionalShadowMap:[],directionalShadowMatrix:[],spot:[],spotLightMap:[],spotShadow:[],spotShadowMap:[],spotLightMatrix:[],rectArea:[],rectAreaLTC1:null,rectAreaLTC2:null,point:[],pointShadow:[],pointShadowMap:[],pointShadowMatrix:[],hemi:[],numSpotLightShadowsWithMaps:0,numLightProbes:0};for(let e=0;e<9;e++)a.probe.push(new r);const o=new r,s=new f,l=new f;return{setup:function(t){let r=0,o=0,s=0;for(let e=0;e<9;e++)a.probe[e].set(0,0,0);let l=0,c=0,d=0,u=0,f=0,p=0,m=0,h=0,_=0,g=0,v=0;t.sort(la);for(let e=0,E=t.length;e0&&(!0===e.has("OES_texture_float_linear")?(a.rectAreaLTC1=Hn.LTC_FLOAT_1,a.rectAreaLTC2=Hn.LTC_FLOAT_2):(a.rectAreaLTC1=Hn.LTC_HALF_1,a.rectAreaLTC2=Hn.LTC_HALF_2)),a.ambient[0]=r,a.ambient[1]=o,a.ambient[2]=s;const E=a.hash;E.directionalLength===l&&E.pointLength===c&&E.spotLength===d&&E.rectAreaLength===u&&E.hemiLength===f&&E.numDirectionalShadows===p&&E.numPointShadows===m&&E.numSpotShadows===h&&E.numSpotMaps===_&&E.numLightProbes===v||(a.directional.length=l,a.spot.length=d,a.rectArea.length=u,a.point.length=c,a.hemi.length=f,a.directionalShadow.length=p,a.directionalShadowMap.length=p,a.pointShadow.length=m,a.pointShadowMap.length=m,a.spotShadow.length=h,a.spotShadowMap.length=h,a.directionalShadowMatrix.length=p,a.pointShadowMatrix.length=m,a.spotLightMatrix.length=h+_-g,a.spotLightMap.length=_,a.numSpotLightShadowsWithMaps=g,a.numLightProbes=v,E.directionalLength=l,E.pointLength=c,E.spotLength=d,E.rectAreaLength=u,E.hemiLength=f,E.numDirectionalShadows=p,E.numPointShadows=m,E.numSpotShadows=h,E.numSpotMaps=_,E.numLightProbes=v,a.version=sa++)},setupView:function(e,t){let n=0,i=0,r=0,c=0,d=0;const u=t.matrixWorldInverse;for(let t=0,f=e.length;t=r.length?(a=new da(e),r.push(a)):a=r[i],a},dispose:function(){t=new WeakMap}}}const fa=[new r(1,0,0),new r(-1,0,0),new r(0,1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1)],pa=[new r(0,-1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1),new r(0,-1,0),new r(0,-1,0)],ma=new f,ha=new r,_a=new r;function ga(e,n,i){let r=new xe;const a=new t,s=new t,d=new K,u=new Ae,f=new Re,p={},m=i.maxTextureSize,h={[_]:c,[c]:_,[ge]:ge},g=new l({defines:{VSM_SAMPLES:8},uniforms:{shadow_pass:{value:null},resolution:{value:new t},radius:{value:4}},vertexShader:"void main() {\n\tgl_Position = vec4( position, 1.0 );\n}",fragmentShader:"uniform sampler2D shadow_pass;\nuniform vec2 resolution;\nuniform float radius;\nvoid main() {\n\tconst float samples = float( VSM_SAMPLES );\n\tfloat mean = 0.0;\n\tfloat squared_mean = 0.0;\n\tfloat uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 );\n\tfloat uvStart = samples <= 1.0 ? 0.0 : - 1.0;\n\tfor ( float i = 0.0; i < samples; i ++ ) {\n\t\tfloat uvOffset = uvStart + i * uvStride;\n\t\t#ifdef HORIZONTAL_PASS\n\t\t\tvec2 distribution = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ).rg;\n\t\t\tmean += distribution.x;\n\t\t\tsquared_mean += distribution.y * distribution.y + distribution.x * distribution.x;\n\t\t#else\n\t\t\tfloat depth = texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ).r;\n\t\t\tmean += depth;\n\t\t\tsquared_mean += depth * depth;\n\t\t#endif\n\t}\n\tmean = mean / samples;\n\tsquared_mean = squared_mean / samples;\n\tfloat std_dev = sqrt( max( 0.0, squared_mean - mean * mean ) );\n\tgl_FragColor = vec4( mean, std_dev, 0.0, 1.0 );\n}"}),v=g.clone();v.defines.HORIZONTAL_PASS=1;const M=new C;M.setAttribute("position",new y(new Float32Array([-1,-1,.5,3,-1,.5,-1,3,.5]),3));const x=new o(M,g),A=this;this.enabled=!1,this.autoUpdate=!0,this.needsUpdate=!1,this.type=ue;let R=this.type;function b(t,i){const r=n.update(x);g.defines.VSM_SAMPLES!==t.blurSamples&&(g.defines.VSM_SAMPLES=t.blurSamples,v.defines.VSM_SAMPLES=t.blurSamples,g.needsUpdate=!0,v.needsUpdate=!0),null===t.mapPass&&(t.mapPass=new N(a.x,a.y,{format:Te,type:S})),g.uniforms.shadow_pass.value=t.map.depthTexture,g.uniforms.resolution.value=t.mapSize,g.uniforms.radius.value=t.radius,e.setRenderTarget(t.mapPass),e.clear(),e.renderBufferDirect(i,null,r,g,x,null),v.uniforms.shadow_pass.value=t.mapPass.texture,v.uniforms.resolution.value=t.mapSize,v.uniforms.radius.value=t.radius,e.setRenderTarget(t.map),e.clear(),e.renderBufferDirect(i,null,r,v,x,null)}function P(t,n,i,r){let a=null;const o=!0===i.isPointLight?t.customDistanceMaterial:t.customDepthMaterial;if(void 0!==o)a=o;else if(a=!0===i.isPointLight?f:u,e.localClippingEnabled&&!0===n.clipShadows&&Array.isArray(n.clippingPlanes)&&0!==n.clippingPlanes.length||n.displacementMap&&0!==n.displacementScale||n.alphaMap&&n.alphaTest>0||n.map&&n.alphaTest>0||!0===n.alphaToCoverage){const e=a.uuid,t=n.uuid;let i=p[e];void 0===i&&(i={},p[e]=i);let r=i[t];void 0===r&&(r=a.clone(),i[t]=r,n.addEventListener("dispose",U)),a=r}if(a.visible=n.visible,a.wireframe=n.wireframe,a.side=r===de?null!==n.shadowSide?n.shadowSide:n.side:null!==n.shadowSide?n.shadowSide:h[n.side],a.alphaMap=n.alphaMap,a.alphaTest=!0===n.alphaToCoverage?.5:n.alphaTest,a.map=n.map,a.clipShadows=n.clipShadows,a.clippingPlanes=n.clippingPlanes,a.clipIntersection=n.clipIntersection,a.displacementMap=n.displacementMap,a.displacementScale=n.displacementScale,a.displacementBias=n.displacementBias,a.wireframeLinewidth=n.wireframeLinewidth,a.linewidth=n.linewidth,!0===i.isPointLight&&!0===a.isMeshDistanceMaterial){e.properties.get(a).light=i}return a}function L(t,i,a,o,s){if(!1===t.visible)return;if(t.layers.test(i.layers)&&(t.isMesh||t.isLine||t.isPoints)&&(t.castShadow||t.receiveShadow&&s===de)&&(!t.frustumCulled||r.intersectsObject(t))){t.modelViewMatrix.multiplyMatrices(a.matrixWorldInverse,t.matrixWorld);const r=n.update(t),l=t.material;if(Array.isArray(l)){const n=r.groups;for(let c=0,d=n.length;ce.needsUpdate=!0):e.material.needsUpdate=!0)});for(let o=0,l=t.length;om||a.y>m)&&(a.x>m&&(s.x=Math.floor(m/p.x),a.x=s.x*p.x,c.mapSize.x=s.x),a.y>m&&(s.y=Math.floor(m/p.y),a.y=s.y*p.y,c.mapSize.y=s.y));const h=e.state.buffers.depth.getReversed();if(c.camera._reversedDepth=h,null===c.map||!0===f){if(null!==c.map&&(null!==c.map.depthTexture&&(c.map.depthTexture.dispose(),c.map.depthTexture=null),c.map.dispose()),this.type===de){if(l.isPointLight){E("WebGLShadowMap: VSM shadow maps are not supported for PointLights. Use PCF or BasicShadowMap instead.");continue}c.map=new N(a.x,a.y,{format:Te,type:S,minFilter:O,magFilter:O,generateMipmaps:!1}),c.map.texture.name=l.name+".shadowMap",c.map.depthTexture=new se(a.x,a.y,T),c.map.depthTexture.name=l.name+".shadowMapDepth",c.map.depthTexture.format=Ce,c.map.depthTexture.compareFunction=null,c.map.depthTexture.minFilter=Pe,c.map.depthTexture.magFilter=Pe}else l.isPointLight?(c.map=new ui(a.x),c.map.depthTexture=new Le(a.x,Ue)):(c.map=new N(a.x,a.y),c.map.depthTexture=new se(a.x,a.y,Ue)),c.map.depthTexture.name=l.name+".shadowMap",c.map.depthTexture.format=Ce,this.type===ue?(c.map.depthTexture.compareFunction=h?ae:oe,c.map.depthTexture.minFilter=O,c.map.depthTexture.magFilter=O):(c.map.depthTexture.compareFunction=null,c.map.depthTexture.minFilter=Pe,c.map.depthTexture.magFilter=Pe);c.camera.updateProjectionMatrix()}const _=c.map.isWebGLCubeRenderTarget?6:1;for(let t=0;t<_;t++){if(c.map.isWebGLCubeRenderTarget)e.setRenderTarget(c.map,t),e.clear();else{0===t&&(e.setRenderTarget(c.map),e.clear());const n=c.getViewport(t);d.set(s.x*n.x,s.y*n.y,s.x*n.z,s.y*n.w),u.viewport(d)}if(l.isPointLight){const e=c.camera,n=c.matrix,i=l.distance||e.far;i!==e.far&&(e.far=i,e.updateProjectionMatrix()),ha.setFromMatrixPosition(l.matrixWorld),e.position.copy(ha),_a.copy(e.position),_a.add(fa[t]),e.up.copy(pa[t]),e.lookAt(_a),e.updateMatrixWorld(),n.makeTranslation(-ha.x,-ha.y,-ha.z),ma.multiplyMatrices(e.projectionMatrix,e.matrixWorldInverse),c._frustum.setFromProjectionMatrix(ma,e.coordinateSystem,e.reversedDepth)}else c.updateMatrices(l);r=c.getFrustum(),L(n,i,c.camera,l,this.type)}!0!==c.isPointLightShadow&&this.type===de&&b(c,i),c.needsUpdate=!1}R=this.type,A.needsUpdate=!1,e.setRenderTarget(o,l,c)}}const va={[nt]:tt,[et]:$e,[Je]:Ze,[De]:Qe,[tt]:nt,[$e]:et,[Ze]:Je,[Qe]:De};function Ea(e,t){const i=new function(){let t=!1;const n=new K;let i=null;const r=new K(0,0,0,0);return{setMask:function(n){i===n||t||(e.colorMask(n,n,n,n),i=n)},setLocked:function(e){t=e},setClear:function(t,i,a,o,s){!0===s&&(t*=o,i*=o,a*=o),n.set(t,i,a,o),!1===r.equals(n)&&(e.clearColor(t,i,a,o),r.copy(n))},reset:function(){t=!1,i=null,r.set(-1,0,0,0)}}},r=new function(){let n=!1,i=!1,r=null,a=null,o=null;return{setReversed:function(e){if(i!==e){const n=t.get("EXT_clip_control");e?n.clipControlEXT(n.LOWER_LEFT_EXT,n.ZERO_TO_ONE_EXT):n.clipControlEXT(n.LOWER_LEFT_EXT,n.NEGATIVE_ONE_TO_ONE_EXT),i=e;const r=o;o=null,this.setClear(r)}},getReversed:function(){return i},setTest:function(t){t?k(e.DEPTH_TEST):X(e.DEPTH_TEST)},setMask:function(t){r===t||n||(e.depthMask(t),r=t)},setFunc:function(t){if(i&&(t=va[t]),a!==t){switch(t){case nt:e.depthFunc(e.NEVER);break;case tt:e.depthFunc(e.ALWAYS);break;case et:e.depthFunc(e.LESS);break;case De:e.depthFunc(e.LEQUAL);break;case Je:e.depthFunc(e.EQUAL);break;case Qe:e.depthFunc(e.GEQUAL);break;case $e:e.depthFunc(e.GREATER);break;case Ze:e.depthFunc(e.NOTEQUAL);break;default:e.depthFunc(e.LEQUAL)}a=t}},setLocked:function(e){n=e},setClear:function(t){o!==t&&(o=t,i&&(t=1-t),e.clearDepth(t))},reset:function(){n=!1,r=null,a=null,o=null,i=!1}}},a=new function(){let t=!1,n=null,i=null,r=null,a=null,o=null,s=null,l=null,c=null;return{setTest:function(n){t||(n?k(e.STENCIL_TEST):X(e.STENCIL_TEST))},setMask:function(i){n===i||t||(e.stencilMask(i),n=i)},setFunc:function(t,n,o){i===t&&r===n&&a===o||(e.stencilFunc(t,n,o),i=t,r=n,a=o)},setOp:function(t,n,i){o===t&&s===n&&l===i||(e.stencilOp(t,n,i),o=t,s=n,l=i)},setLocked:function(e){t=e},setClear:function(t){c!==t&&(e.clearStencil(t),c=t)},reset:function(){t=!1,n=null,i=null,r=null,a=null,o=null,s=null,l=null,c=null}}},o=new WeakMap,s=new WeakMap;let l={},d={},u=new WeakMap,f=[],p=null,m=!1,h=null,_=null,g=null,v=null,E=null,S=null,M=null,T=new n(0,0,0),x=0,A=!1,R=null,b=null,C=null,P=null,L=null;const U=e.getParameter(e.MAX_COMBINED_TEXTURE_IMAGE_UNITS);let D=!1,N=0;const y=e.getParameter(e.VERSION);-1!==y.indexOf("WebGL")?(N=parseFloat(/^WebGL (\d)/.exec(y)[1]),D=N>=1):-1!==y.indexOf("OpenGL ES")&&(N=parseFloat(/^OpenGL ES (\d)/.exec(y)[1]),D=N>=2);let F=null,O={};const B=e.getParameter(e.SCISSOR_BOX),G=e.getParameter(e.VIEWPORT),H=(new K).fromArray(B),V=(new K).fromArray(G);function W(t,n,i,r){const a=new Uint8Array(4),o=e.createTexture();e.bindTexture(t,o),e.texParameteri(t,e.TEXTURE_MIN_FILTER,e.NEAREST),e.texParameteri(t,e.TEXTURE_MAG_FILTER,e.NEAREST);for(let o=0;on||r.height>n)&&(i=n/Math.max(r.width,r.height)),i<1){if("undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof VideoFrame&&e instanceof VideoFrame){const n=Math.floor(i*r.width),a=Math.floor(i*r.height);void 0===f&&(f=g(n,a));const o=t?g(n,a):f;o.width=n,o.height=a;return o.getContext("2d").drawImage(e,0,0,n,a),E("WebGLRenderer: Texture has been resized from ("+r.width+"x"+r.height+") to ("+n+"x"+a+")."),o}return"data"in e&&E("WebGLRenderer: Image in DataTexture is too big ("+r.width+"x"+r.height+")."),e}return e}function S(e){return e.generateMipmaps}function A(t){e.generateMipmap(t)}function R(t){return t.isWebGLCubeRenderTarget?e.TEXTURE_CUBE_MAP:t.isWebGL3DRenderTarget?e.TEXTURE_3D:t.isWebGLArrayRenderTarget||t.isCompressedArrayTexture?e.TEXTURE_2D_ARRAY:e.TEXTURE_2D}function b(t,i,r,a,o=!1){if(null!==t){if(void 0!==e[t])return e[t];E("WebGLRenderer: Attempt to use non-existing WebGL internal format '"+t+"'")}let s=i;if(i===e.RED&&(r===e.FLOAT&&(s=e.R32F),r===e.HALF_FLOAT&&(s=e.R16F),r===e.UNSIGNED_BYTE&&(s=e.R8)),i===e.RED_INTEGER&&(r===e.UNSIGNED_BYTE&&(s=e.R8UI),r===e.UNSIGNED_SHORT&&(s=e.R16UI),r===e.UNSIGNED_INT&&(s=e.R32UI),r===e.BYTE&&(s=e.R8I),r===e.SHORT&&(s=e.R16I),r===e.INT&&(s=e.R32I)),i===e.RG&&(r===e.FLOAT&&(s=e.RG32F),r===e.HALF_FLOAT&&(s=e.RG16F),r===e.UNSIGNED_BYTE&&(s=e.RG8)),i===e.RG_INTEGER&&(r===e.UNSIGNED_BYTE&&(s=e.RG8UI),r===e.UNSIGNED_SHORT&&(s=e.RG16UI),r===e.UNSIGNED_INT&&(s=e.RG32UI),r===e.BYTE&&(s=e.RG8I),r===e.SHORT&&(s=e.RG16I),r===e.INT&&(s=e.RG32I)),i===e.RGB_INTEGER&&(r===e.UNSIGNED_BYTE&&(s=e.RGB8UI),r===e.UNSIGNED_SHORT&&(s=e.RGB16UI),r===e.UNSIGNED_INT&&(s=e.RGB32UI),r===e.BYTE&&(s=e.RGB8I),r===e.SHORT&&(s=e.RGB16I),r===e.INT&&(s=e.RGB32I)),i===e.RGBA_INTEGER&&(r===e.UNSIGNED_BYTE&&(s=e.RGBA8UI),r===e.UNSIGNED_SHORT&&(s=e.RGBA16UI),r===e.UNSIGNED_INT&&(s=e.RGBA32UI),r===e.BYTE&&(s=e.RGBA8I),r===e.SHORT&&(s=e.RGBA16I),r===e.INT&&(s=e.RGBA32I)),i===e.RGB&&(r===e.UNSIGNED_INT_5_9_9_9_REV&&(s=e.RGB9_E5),r===e.UNSIGNED_INT_10F_11F_11F_REV&&(s=e.R11F_G11F_B10F)),i===e.RGBA){const t=o?he:p.getTransfer(a);r===e.FLOAT&&(s=e.RGBA32F),r===e.HALF_FLOAT&&(s=e.RGBA16F),r===e.UNSIGNED_BYTE&&(s=t===m?e.SRGB8_ALPHA8:e.RGBA8),r===e.UNSIGNED_SHORT_4_4_4_4&&(s=e.RGBA4),r===e.UNSIGNED_SHORT_5_5_5_1&&(s=e.RGB5_A1)}return s!==e.R16F&&s!==e.R32F&&s!==e.RG16F&&s!==e.RG32F&&s!==e.RGBA16F&&s!==e.RGBA32F||n.get("EXT_color_buffer_float"),s}function C(t,n){let i;return t?null===n||n===Ue||n===Ct?i=e.DEPTH24_STENCIL8:n===T?i=e.DEPTH32F_STENCIL8:n===Pt&&(i=e.DEPTH24_STENCIL8,E("DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.")):null===n||n===Ue||n===Ct?i=e.DEPTH_COMPONENT24:n===T?i=e.DEPTH_COMPONENT32F:n===Pt&&(i=e.DEPTH_COMPONENT16),i}function P(e,t){return!0===S(e)||e.isFramebufferTexture&&e.minFilter!==Pe&&e.minFilter!==O?Math.log2(Math.max(t.width,t.height))+1:void 0!==e.mipmaps&&e.mipmaps.length>0?e.mipmaps.length:e.isCompressedTexture&&Array.isArray(e.image)?t.mipmaps.length:1}function L(e){const t=e.target;t.removeEventListener("dispose",L),function(e){const t=r.get(e);if(void 0===t.__webglInit)return;const n=e.source,i=h.get(n);if(i){const r=i[t.__cacheKey];r.usedTimes--,0===r.usedTimes&&D(e),0===Object.keys(i).length&&h.delete(n)}r.remove(e)}(t),t.isVideoTexture&&u.delete(t)}function U(t){const n=t.target;n.removeEventListener("dispose",U),function(t){const n=r.get(t);t.depthTexture&&(t.depthTexture.dispose(),r.remove(t.depthTexture));if(t.isWebGLCubeRenderTarget)for(let t=0;t<6;t++){if(Array.isArray(n.__webglFramebuffer[t]))for(let i=0;i0&&a.__version!==t.version){const e=t.image;if(null===e)E("WebGLRenderer: Texture marked for update but no image data found.");else{if(!1!==e.complete)return void k(a,t,n);E("WebGLRenderer: Texture marked for update but image is incomplete")}}else t.isExternalTexture&&(a.__webglTexture=t.sourceTexture?t.sourceTexture:null);i.bindTexture(e.TEXTURE_2D,a.__webglTexture,e.TEXTURE0+n)}const y={[mt]:e.REPEAT,[pt]:e.CLAMP_TO_EDGE,[ft]:e.MIRRORED_REPEAT},B={[Pe]:e.NEAREST,[gt]:e.NEAREST_MIPMAP_NEAREST,[_t]:e.NEAREST_MIPMAP_LINEAR,[O]:e.LINEAR,[ht]:e.LINEAR_MIPMAP_NEAREST,[G]:e.LINEAR_MIPMAP_LINEAR},H={[xt]:e.NEVER,[Tt]:e.ALWAYS,[Mt]:e.LESS,[oe]:e.LEQUAL,[St]:e.EQUAL,[ae]:e.GEQUAL,[Et]:e.GREATER,[vt]:e.NOTEQUAL};function V(t,i){if(i.type!==T||!1!==n.has("OES_texture_float_linear")||i.magFilter!==O&&i.magFilter!==ht&&i.magFilter!==_t&&i.magFilter!==G&&i.minFilter!==O&&i.minFilter!==ht&&i.minFilter!==_t&&i.minFilter!==G||E("WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device."),e.texParameteri(t,e.TEXTURE_WRAP_S,y[i.wrapS]),e.texParameteri(t,e.TEXTURE_WRAP_T,y[i.wrapT]),t!==e.TEXTURE_3D&&t!==e.TEXTURE_2D_ARRAY||e.texParameteri(t,e.TEXTURE_WRAP_R,y[i.wrapR]),e.texParameteri(t,e.TEXTURE_MAG_FILTER,B[i.magFilter]),e.texParameteri(t,e.TEXTURE_MIN_FILTER,B[i.minFilter]),i.compareFunction&&(e.texParameteri(t,e.TEXTURE_COMPARE_MODE,e.COMPARE_REF_TO_TEXTURE),e.texParameteri(t,e.TEXTURE_COMPARE_FUNC,H[i.compareFunction])),!0===n.has("EXT_texture_filter_anisotropic")){if(i.magFilter===Pe)return;if(i.minFilter!==_t&&i.minFilter!==G)return;if(i.type===T&&!1===n.has("OES_texture_float_linear"))return;if(i.anisotropy>1||r.get(i).__currentAnisotropy){const o=n.get("EXT_texture_filter_anisotropic");e.texParameterf(t,o.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(i.anisotropy,a.getMaxAnisotropy())),r.get(i).__currentAnisotropy=i.anisotropy}}}function W(t,n){let i=!1;void 0===t.__webglInit&&(t.__webglInit=!0,n.addEventListener("dispose",L));const r=n.source;let a=h.get(r);void 0===a&&(a={},h.set(r,a));const o=function(e){const t=[];return t.push(e.wrapS),t.push(e.wrapT),t.push(e.wrapR||0),t.push(e.magFilter),t.push(e.minFilter),t.push(e.anisotropy),t.push(e.internalFormat),t.push(e.format),t.push(e.type),t.push(e.generateMipmaps),t.push(e.premultiplyAlpha),t.push(e.flipY),t.push(e.unpackAlignment),t.push(e.colorSpace),t.join()}(n);if(o!==t.__cacheKey){void 0===a[o]&&(a[o]={texture:e.createTexture(),usedTimes:0},s.memory.textures++,i=!0),a[o].usedTimes++;const r=a[t.__cacheKey];void 0!==r&&(a[t.__cacheKey].usedTimes--,0===r.usedTimes&&D(n)),t.__cacheKey=o,t.__webglTexture=a[o].texture}return i}function z(e,t,n){return Math.floor(Math.floor(e/n)/t)}function k(t,n,s){let l=e.TEXTURE_2D;(n.isDataArrayTexture||n.isCompressedArrayTexture)&&(l=e.TEXTURE_2D_ARRAY),n.isData3DTexture&&(l=e.TEXTURE_3D);const c=W(t,n),d=n.source;i.bindTexture(l,t.__webglTexture,e.TEXTURE0+s);const u=r.get(d);if(d.version!==u.__version||!0===c){i.activeTexture(e.TEXTURE0+s);const t=p.getPrimaries(p.workingColorSpace),r=n.colorSpace===At?null:p.getPrimaries(n.colorSpace),f=n.colorSpace===At||t===r?e.NONE:e.BROWSER_DEFAULT_WEBGL;e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,n.flipY),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,n.premultiplyAlpha),e.pixelStorei(e.UNPACK_ALIGNMENT,n.unpackAlignment),e.pixelStorei(e.UNPACK_COLORSPACE_CONVERSION_WEBGL,f);let m=v(n.image,!1,a.maxTextureSize);m=J(n,m);const h=o.convert(n.format,n.colorSpace),_=o.convert(n.type);let g,M=b(n.internalFormat,h,_,n.colorSpace,n.isVideoTexture);V(l,n);const T=n.mipmaps,R=!0!==n.isVideoTexture,L=void 0===u.__version||!0===c,U=d.dataReady,D=P(n,m);if(n.isDepthTexture)M=C(n.format===Rt,n.type),L&&(R?i.texStorage2D(e.TEXTURE_2D,1,M,m.width,m.height):i.texImage2D(e.TEXTURE_2D,0,M,m.width,m.height,0,h,_,null));else if(n.isDataTexture)if(T.length>0){R&&L&&i.texStorage2D(e.TEXTURE_2D,D,M,T[0].width,T[0].height);for(let t=0,n=T.length;te.start-t.start);let s=0;for(let e=1;e0){const r=bt(g.width,g.height,n.format,n.type);for(const a of n.layerUpdates){const n=g.data.subarray(a*r/g.data.BYTES_PER_ELEMENT,(a+1)*r/g.data.BYTES_PER_ELEMENT);i.compressedTexSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,a,g.width,g.height,1,h,n)}n.clearLayerUpdates()}else i.compressedTexSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,0,g.width,g.height,m.depth,h,g.data)}else i.compressedTexImage3D(e.TEXTURE_2D_ARRAY,t,M,g.width,g.height,m.depth,0,g.data,0,0);else E("WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()");else R?U&&i.texSubImage3D(e.TEXTURE_2D_ARRAY,t,0,0,0,g.width,g.height,m.depth,h,_,g.data):i.texImage3D(e.TEXTURE_2D_ARRAY,t,M,g.width,g.height,m.depth,0,h,_,g.data)}else{R&&L&&i.texStorage2D(e.TEXTURE_2D,D,M,T[0].width,T[0].height);for(let t=0,r=T.length;t0){const t=bt(m.width,m.height,n.format,n.type);for(const r of n.layerUpdates){const n=m.data.subarray(r*t/m.data.BYTES_PER_ELEMENT,(r+1)*t/m.data.BYTES_PER_ELEMENT);i.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,r,m.width,m.height,1,h,_,n)}n.clearLayerUpdates()}else i.texSubImage3D(e.TEXTURE_2D_ARRAY,0,0,0,0,m.width,m.height,m.depth,h,_,m.data)}else i.texImage3D(e.TEXTURE_2D_ARRAY,0,M,m.width,m.height,m.depth,0,h,_,m.data);else if(n.isData3DTexture)R?(L&&i.texStorage3D(e.TEXTURE_3D,D,M,m.width,m.height,m.depth),U&&i.texSubImage3D(e.TEXTURE_3D,0,0,0,0,m.width,m.height,m.depth,h,_,m.data)):i.texImage3D(e.TEXTURE_3D,0,M,m.width,m.height,m.depth,0,h,_,m.data);else if(n.isFramebufferTexture){if(L)if(R)i.texStorage2D(e.TEXTURE_2D,D,M,m.width,m.height);else{let t=m.width,n=m.height;for(let r=0;r>=1,n>>=1}}else if(T.length>0){if(R&&L){const t=ee(T[0]);i.texStorage2D(e.TEXTURE_2D,D,M,t.width,t.height)}for(let t=0,n=T.length;t>d),r=Math.max(1,n.height>>d);c===e.TEXTURE_3D||c===e.TEXTURE_2D_ARRAY?i.texImage3D(c,d,p,t,r,n.depth,0,u,f,null):i.texImage2D(c,d,p,t,r,0,u,f,null)}i.bindFramebuffer(e.FRAMEBUFFER,t),Q(n)?l.framebufferTexture2DMultisampleEXT(e.FRAMEBUFFER,s,c,h.__webglTexture,0,$(n)):(c===e.TEXTURE_2D||c>=e.TEXTURE_CUBE_MAP_POSITIVE_X&&c<=e.TEXTURE_CUBE_MAP_NEGATIVE_Z)&&e.framebufferTexture2D(e.FRAMEBUFFER,s,c,h.__webglTexture,d),i.bindFramebuffer(e.FRAMEBUFFER,null)}function Y(t,n,i){if(e.bindRenderbuffer(e.RENDERBUFFER,t),n.depthBuffer){const r=n.depthTexture,a=r&&r.isDepthTexture?r.type:null,o=C(n.stencilBuffer,a),s=n.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT;Q(n)?l.renderbufferStorageMultisampleEXT(e.RENDERBUFFER,$(n),o,n.width,n.height):i?e.renderbufferStorageMultisample(e.RENDERBUFFER,$(n),o,n.width,n.height):e.renderbufferStorage(e.RENDERBUFFER,o,n.width,n.height),e.framebufferRenderbuffer(e.FRAMEBUFFER,s,e.RENDERBUFFER,t)}else{const t=n.textures;for(let r=0;r{delete n.__boundDepthTexture,delete n.__depthDisposeCallback,e.removeEventListener("dispose",t)};e.addEventListener("dispose",t),n.__depthDisposeCallback=t}n.__boundDepthTexture=e}if(t.depthTexture&&!n.__autoAllocateDepthBuffer)if(a)for(let e=0;e<6;e++)K(n.__webglFramebuffer[e],t,e);else{const e=t.texture.mipmaps;e&&e.length>0?K(n.__webglFramebuffer[0],t,0):K(n.__webglFramebuffer,t,0)}else if(a){n.__webglDepthbuffer=[];for(let r=0;r<6;r++)if(i.bindFramebuffer(e.FRAMEBUFFER,n.__webglFramebuffer[r]),void 0===n.__webglDepthbuffer[r])n.__webglDepthbuffer[r]=e.createRenderbuffer(),Y(n.__webglDepthbuffer[r],t,!1);else{const i=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,a=n.__webglDepthbuffer[r];e.bindRenderbuffer(e.RENDERBUFFER,a),e.framebufferRenderbuffer(e.FRAMEBUFFER,i,e.RENDERBUFFER,a)}}else{const r=t.texture.mipmaps;if(r&&r.length>0?i.bindFramebuffer(e.FRAMEBUFFER,n.__webglFramebuffer[0]):i.bindFramebuffer(e.FRAMEBUFFER,n.__webglFramebuffer),void 0===n.__webglDepthbuffer)n.__webglDepthbuffer=e.createRenderbuffer(),Y(n.__webglDepthbuffer,t,!1);else{const i=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,r=n.__webglDepthbuffer;e.bindRenderbuffer(e.RENDERBUFFER,r),e.framebufferRenderbuffer(e.FRAMEBUFFER,i,e.RENDERBUFFER,r)}}i.bindFramebuffer(e.FRAMEBUFFER,null)}const j=[],Z=[];function $(e){return Math.min(a.maxSamples,e.samples)}function Q(e){const t=r.get(e);return e.samples>0&&!0===n.has("WEBGL_multisampled_render_to_texture")&&!1!==t.__useRenderToTexture}function J(e,t){const n=e.colorSpace,i=e.format,r=e.type;return!0===e.isCompressedTexture||!0===e.isVideoTexture||n!==F&&n!==At&&(p.getTransfer(n)===m?i===x&&r===M||E("WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType."):w("WebGLTextures: Unsupported texture color space:",n)),t}function ee(e){return"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement?(d.width=e.naturalWidth||e.width,d.height=e.naturalHeight||e.height):"undefined"!=typeof VideoFrame&&e instanceof VideoFrame?(d.width=e.displayWidth,d.height=e.displayHeight):(d.width=e.width,d.height=e.height),d}this.allocateTextureUnit=function(){const e=I;return e>=a.maxTextures&&E("WebGLTextures: Trying to use "+e+" texture units while this GPU supports only "+a.maxTextures),I+=1,e},this.resetTextureUnits=function(){I=0},this.setTexture2D=N,this.setTexture2DArray=function(t,n){const a=r.get(t);!1===t.isRenderTargetTexture&&t.version>0&&a.__version!==t.version?k(a,t,n):(t.isExternalTexture&&(a.__webglTexture=t.sourceTexture?t.sourceTexture:null),i.bindTexture(e.TEXTURE_2D_ARRAY,a.__webglTexture,e.TEXTURE0+n))},this.setTexture3D=function(t,n){const a=r.get(t);!1===t.isRenderTargetTexture&&t.version>0&&a.__version!==t.version?k(a,t,n):i.bindTexture(e.TEXTURE_3D,a.__webglTexture,e.TEXTURE0+n)},this.setTextureCube=function(t,n){const s=r.get(t);!0!==t.isCubeDepthTexture&&t.version>0&&s.__version!==t.version?function(t,n,s){if(6!==n.image.length)return;const l=W(t,n),c=n.source;i.bindTexture(e.TEXTURE_CUBE_MAP,t.__webglTexture,e.TEXTURE0+s);const d=r.get(c);if(c.version!==d.__version||!0===l){i.activeTexture(e.TEXTURE0+s);const t=p.getPrimaries(p.workingColorSpace),r=n.colorSpace===At?null:p.getPrimaries(n.colorSpace),u=n.colorSpace===At||t===r?e.NONE:e.BROWSER_DEFAULT_WEBGL;e.pixelStorei(e.UNPACK_FLIP_Y_WEBGL,n.flipY),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,n.premultiplyAlpha),e.pixelStorei(e.UNPACK_ALIGNMENT,n.unpackAlignment),e.pixelStorei(e.UNPACK_COLORSPACE_CONVERSION_WEBGL,u);const f=n.isCompressedTexture||n.image[0].isCompressedTexture,m=n.image[0]&&n.image[0].isDataTexture,h=[];for(let e=0;e<6;e++)h[e]=f||m?m?n.image[e].image:n.image[e]:v(n.image[e],!0,a.maxCubemapSize),h[e]=J(n,h[e]);const _=h[0],g=o.convert(n.format,n.colorSpace),M=o.convert(n.type),T=b(n.internalFormat,g,M,n.colorSpace),R=!0!==n.isVideoTexture,C=void 0===d.__version||!0===l,L=c.dataReady;let U,D=P(n,_);if(V(e.TEXTURE_CUBE_MAP,n),f){R&&C&&i.texStorage2D(e.TEXTURE_CUBE_MAP,D,T,_.width,_.height);for(let t=0;t<6;t++){U=h[t].mipmaps;for(let r=0;r0&&D++;const t=ee(h[0]);i.texStorage2D(e.TEXTURE_CUBE_MAP,D,T,t.width,t.height)}for(let t=0;t<6;t++)if(m){R?L&&i.texSubImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,0,0,0,h[t].width,h[t].height,g,M,h[t].data):i.texImage2D(e.TEXTURE_CUBE_MAP_POSITIVE_X+t,0,T,h[t].width,h[t].height,0,g,M,h[t].data);for(let n=0;n1;if(u||(void 0===l.__webglTexture&&(l.__webglTexture=e.createTexture()),l.__version=n.version,s.memory.textures++),d){a.__webglFramebuffer=[];for(let t=0;t<6;t++)if(n.mipmaps&&n.mipmaps.length>0){a.__webglFramebuffer[t]=[];for(let i=0;i0){a.__webglFramebuffer=[];for(let t=0;t0&&!1===Q(t)){a.__webglMultisampledFramebuffer=e.createFramebuffer(),a.__webglColorRenderbuffer=[],i.bindFramebuffer(e.FRAMEBUFFER,a.__webglMultisampledFramebuffer);for(let n=0;n0)for(let r=0;r0)for(let i=0;i0)if(!1===Q(t)){const n=t.textures,a=t.width,o=t.height;let s=e.COLOR_BUFFER_BIT;const l=t.stencilBuffer?e.DEPTH_STENCIL_ATTACHMENT:e.DEPTH_ATTACHMENT,d=r.get(t),u=n.length>1;if(u)for(let t=0;t0?i.bindFramebuffer(e.DRAW_FRAMEBUFFER,d.__webglFramebuffer[0]):i.bindFramebuffer(e.DRAW_FRAMEBUFFER,d.__webglFramebuffer);for(let i=0;i= 1.0 ) {\n\n\t\tgl_FragDepth = texture( depthColor, vec3( coord.x - 1.0, coord.y, 1 ) ).r;\n\n\t} else {\n\n\t\tgl_FragDepth = texture( depthColor, vec3( coord.x, coord.y, 0 ) ).r;\n\n\t}\n\n}",uniforms:{depthColor:{value:this.texture},depthWidth:{value:t.z},depthHeight:{value:t.w}}});this.mesh=new o(new h(20,20),n)}return this.mesh}reset(){this.texture=null,this.mesh=null}getDepthTexture(){return this.texture}}class xa extends bn{constructor(e,n){super();const i=this;let a=null,o=1,s=null,l="local-floor",c=1,d=null,u=null,f=null,p=null,m=null,h=null;const _="undefined"!=typeof XRWebGLBinding,g=new Ta,v={},S=n.getContextAttributes();let T=null,A=null;const R=[],b=[],C=new t;let P=null;const U=new L;U.viewport=new K;const D=new L;D.viewport=new K;const w=[U,D],I=new Cn;let y=null,F=null;function O(e){const t=b.indexOf(e.inputSource);if(-1===t)return;const n=R[t];void 0!==n&&(n.update(e.inputSource,e.frame,d||s),n.dispatchEvent({type:e.type,data:e.inputSource}))}function B(){a.removeEventListener("select",O),a.removeEventListener("selectstart",O),a.removeEventListener("selectend",O),a.removeEventListener("squeeze",O),a.removeEventListener("squeezestart",O),a.removeEventListener("squeezeend",O),a.removeEventListener("end",B),a.removeEventListener("inputsourceschange",G);for(let e=0;e=0&&(b[i]=null,R[i].disconnect(n))}for(let t=0;t=b.length){b.push(n),i=e;break}if(null===b[e]){b[e]=n,i=e;break}}if(-1===i)break}const r=R[i];r&&r.connect(n)}}this.cameraAutoUpdate=!0,this.enabled=!1,this.isPresenting=!1,this.getController=function(e){let t=R[e];return void 0===t&&(t=new Pn,R[e]=t),t.getTargetRaySpace()},this.getControllerGrip=function(e){let t=R[e];return void 0===t&&(t=new Pn,R[e]=t),t.getGripSpace()},this.getHand=function(e){let t=R[e];return void 0===t&&(t=new Pn,R[e]=t),t.getHandSpace()},this.setFramebufferScaleFactor=function(e){o=e,!0===i.isPresenting&&E("WebXRManager: Cannot change framebuffer scale while presenting.")},this.setReferenceSpaceType=function(e){l=e,!0===i.isPresenting&&E("WebXRManager: Cannot change reference space type while presenting.")},this.getReferenceSpace=function(){return d||s},this.setReferenceSpace=function(e){d=e},this.getBaseLayer=function(){return null!==p?p:m},this.getBinding=function(){return null===f&&_&&(f=new XRWebGLBinding(a,n)),f},this.getFrame=function(){return h},this.getSession=function(){return a},this.setSession=async function(t){if(a=t,null!==a){T=e.getRenderTarget(),a.addEventListener("select",O),a.addEventListener("selectstart",O),a.addEventListener("selectend",O),a.addEventListener("squeeze",O),a.addEventListener("squeezestart",O),a.addEventListener("squeezeend",O),a.addEventListener("end",B),a.addEventListener("inputsourceschange",G),!0!==S.xrCompatible&&await n.makeXRCompatible(),P=e.getPixelRatio(),e.getSize(C);if(_&&"createProjectionLayer"in XRWebGLBinding.prototype){let t=null,i=null,r=null;S.depth&&(r=S.stencil?n.DEPTH24_STENCIL8:n.DEPTH_COMPONENT24,t=S.stencil?Rt:Ce,i=S.stencil?Ct:Ue);const s={colorFormat:n.RGBA8,depthFormat:r,scaleFactor:o};f=this.getBinding(),p=f.createProjectionLayer(s),a.updateRenderState({layers:[p]}),e.setPixelRatio(1),e.setSize(p.textureWidth,p.textureHeight,!1),A=new N(p.textureWidth,p.textureHeight,{format:x,type:M,depthTexture:new se(p.textureWidth,p.textureHeight,i,void 0,void 0,void 0,void 0,void 0,void 0,t),stencilBuffer:S.stencil,colorSpace:e.outputColorSpace,samples:S.antialias?4:0,resolveDepthBuffer:!1===p.ignoreDepthValues,resolveStencilBuffer:!1===p.ignoreDepthValues})}else{const t={antialias:S.antialias,alpha:!0,depth:S.depth,stencil:S.stencil,framebufferScaleFactor:o};m=new XRWebGLLayer(a,n,t),a.updateRenderState({baseLayer:m}),e.setPixelRatio(1),e.setSize(m.framebufferWidth,m.framebufferHeight,!1),A=new N(m.framebufferWidth,m.framebufferHeight,{format:x,type:M,colorSpace:e.outputColorSpace,stencilBuffer:S.stencil,resolveDepthBuffer:!1===m.ignoreDepthValues,resolveStencilBuffer:!1===m.ignoreDepthValues})}A.isXRRenderTarget=!0,this.setFoveation(c),d=null,s=await a.requestReferenceSpace(l),k.setContext(a),k.start(),i.isPresenting=!0,i.dispatchEvent({type:"sessionstart"})}},this.getEnvironmentBlendMode=function(){if(null!==a)return a.environmentBlendMode},this.getDepthTexture=function(){return g.getDepthTexture()};const H=new r,V=new r;function W(e,t){null===t?e.matrixWorld.copy(e.matrix):e.matrixWorld.multiplyMatrices(t.matrixWorld,e.matrix),e.matrixWorldInverse.copy(e.matrixWorld).invert()}this.updateCamera=function(e){if(null===a)return;let t=e.near,n=e.far;null!==g.texture&&(g.depthNear>0&&(t=g.depthNear),g.depthFar>0&&(n=g.depthFar)),I.near=D.near=U.near=t,I.far=D.far=U.far=n,y===I.near&&F===I.far||(a.updateRenderState({depthNear:I.near,depthFar:I.far}),y=I.near,F=I.far),I.layers.mask=6|e.layers.mask,U.layers.mask=-5&I.layers.mask,D.layers.mask=-3&I.layers.mask;const i=e.parent,r=I.cameras;W(I,i);for(let e=0;e0&&(e.alphaTest.value=i.alphaTest);const r=t.get(i),a=r.envMap,o=r.envMapRotation;a&&(e.envMap.value=a,Aa.copy(o),Aa.x*=-1,Aa.y*=-1,Aa.z*=-1,a.isCubeTexture&&!1===a.isRenderTargetTexture&&(Aa.y*=-1,Aa.z*=-1),e.envMapRotation.value.setFromMatrix4(Ra.makeRotationFromEuler(Aa)),e.flipEnvMap.value=a.isCubeTexture&&!1===a.isRenderTargetTexture?-1:1,e.reflectivity.value=i.reflectivity,e.ior.value=i.ior,e.refractionRatio.value=i.refractionRatio),i.lightMap&&(e.lightMap.value=i.lightMap,e.lightMapIntensity.value=i.lightMapIntensity,n(i.lightMap,e.lightMapTransform)),i.aoMap&&(e.aoMap.value=i.aoMap,e.aoMapIntensity.value=i.aoMapIntensity,n(i.aoMap,e.aoMapTransform))}return{refreshFogUniforms:function(t,n){n.color.getRGB(t.fogColor.value,g(e)),n.isFog?(t.fogNear.value=n.near,t.fogFar.value=n.far):n.isFogExp2&&(t.fogDensity.value=n.density)},refreshMaterialUniforms:function(e,r,a,o,s){r.isMeshBasicMaterial?i(e,r):r.isMeshLambertMaterial?(i(e,r),r.envMap&&(e.envMapIntensity.value=r.envMapIntensity)):r.isMeshToonMaterial?(i(e,r),function(e,t){t.gradientMap&&(e.gradientMap.value=t.gradientMap)}(e,r)):r.isMeshPhongMaterial?(i(e,r),function(e,t){e.specular.value.copy(t.specular),e.shininess.value=Math.max(t.shininess,1e-4)}(e,r),r.envMap&&(e.envMapIntensity.value=r.envMapIntensity)):r.isMeshStandardMaterial?(i(e,r),function(e,t){e.metalness.value=t.metalness,t.metalnessMap&&(e.metalnessMap.value=t.metalnessMap,n(t.metalnessMap,e.metalnessMapTransform));e.roughness.value=t.roughness,t.roughnessMap&&(e.roughnessMap.value=t.roughnessMap,n(t.roughnessMap,e.roughnessMapTransform));t.envMap&&(e.envMapIntensity.value=t.envMapIntensity)}(e,r),r.isMeshPhysicalMaterial&&function(e,t,i){e.ior.value=t.ior,t.sheen>0&&(e.sheenColor.value.copy(t.sheenColor).multiplyScalar(t.sheen),e.sheenRoughness.value=t.sheenRoughness,t.sheenColorMap&&(e.sheenColorMap.value=t.sheenColorMap,n(t.sheenColorMap,e.sheenColorMapTransform)),t.sheenRoughnessMap&&(e.sheenRoughnessMap.value=t.sheenRoughnessMap,n(t.sheenRoughnessMap,e.sheenRoughnessMapTransform)));t.clearcoat>0&&(e.clearcoat.value=t.clearcoat,e.clearcoatRoughness.value=t.clearcoatRoughness,t.clearcoatMap&&(e.clearcoatMap.value=t.clearcoatMap,n(t.clearcoatMap,e.clearcoatMapTransform)),t.clearcoatRoughnessMap&&(e.clearcoatRoughnessMap.value=t.clearcoatRoughnessMap,n(t.clearcoatRoughnessMap,e.clearcoatRoughnessMapTransform)),t.clearcoatNormalMap&&(e.clearcoatNormalMap.value=t.clearcoatNormalMap,n(t.clearcoatNormalMap,e.clearcoatNormalMapTransform),e.clearcoatNormalScale.value.copy(t.clearcoatNormalScale),t.side===c&&e.clearcoatNormalScale.value.negate()));t.dispersion>0&&(e.dispersion.value=t.dispersion);t.iridescence>0&&(e.iridescence.value=t.iridescence,e.iridescenceIOR.value=t.iridescenceIOR,e.iridescenceThicknessMinimum.value=t.iridescenceThicknessRange[0],e.iridescenceThicknessMaximum.value=t.iridescenceThicknessRange[1],t.iridescenceMap&&(e.iridescenceMap.value=t.iridescenceMap,n(t.iridescenceMap,e.iridescenceMapTransform)),t.iridescenceThicknessMap&&(e.iridescenceThicknessMap.value=t.iridescenceThicknessMap,n(t.iridescenceThicknessMap,e.iridescenceThicknessMapTransform)));t.transmission>0&&(e.transmission.value=t.transmission,e.transmissionSamplerMap.value=i.texture,e.transmissionSamplerSize.value.set(i.width,i.height),t.transmissionMap&&(e.transmissionMap.value=t.transmissionMap,n(t.transmissionMap,e.transmissionMapTransform)),e.thickness.value=t.thickness,t.thicknessMap&&(e.thicknessMap.value=t.thicknessMap,n(t.thicknessMap,e.thicknessMapTransform)),e.attenuationDistance.value=t.attenuationDistance,e.attenuationColor.value.copy(t.attenuationColor));t.anisotropy>0&&(e.anisotropyVector.value.set(t.anisotropy*Math.cos(t.anisotropyRotation),t.anisotropy*Math.sin(t.anisotropyRotation)),t.anisotropyMap&&(e.anisotropyMap.value=t.anisotropyMap,n(t.anisotropyMap,e.anisotropyMapTransform)));e.specularIntensity.value=t.specularIntensity,e.specularColor.value.copy(t.specularColor),t.specularColorMap&&(e.specularColorMap.value=t.specularColorMap,n(t.specularColorMap,e.specularColorMapTransform));t.specularIntensityMap&&(e.specularIntensityMap.value=t.specularIntensityMap,n(t.specularIntensityMap,e.specularIntensityMapTransform))}(e,r,s)):r.isMeshMatcapMaterial?(i(e,r),function(e,t){t.matcap&&(e.matcap.value=t.matcap)}(e,r)):r.isMeshDepthMaterial?i(e,r):r.isMeshDistanceMaterial?(i(e,r),function(e,n){const i=t.get(n).light;e.referencePosition.value.setFromMatrixPosition(i.matrixWorld),e.nearDistance.value=i.shadow.camera.near,e.farDistance.value=i.shadow.camera.far}(e,r)):r.isMeshNormalMaterial?i(e,r):r.isLineBasicMaterial?(function(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,t.map&&(e.map.value=t.map,n(t.map,e.mapTransform))}(e,r),r.isLineDashedMaterial&&function(e,t){e.dashSize.value=t.dashSize,e.totalSize.value=t.dashSize+t.gapSize,e.scale.value=t.scale}(e,r)):r.isPointsMaterial?function(e,t,i,r){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.size.value=t.size*i,e.scale.value=.5*r,t.map&&(e.map.value=t.map,n(t.map,e.uvTransform));t.alphaMap&&(e.alphaMap.value=t.alphaMap,n(t.alphaMap,e.alphaMapTransform));t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}(e,r,a,o):r.isSpriteMaterial?function(e,t){e.diffuse.value.copy(t.color),e.opacity.value=t.opacity,e.rotation.value=t.rotation,t.map&&(e.map.value=t.map,n(t.map,e.mapTransform));t.alphaMap&&(e.alphaMap.value=t.alphaMap,n(t.alphaMap,e.alphaMapTransform));t.alphaTest>0&&(e.alphaTest.value=t.alphaTest)}(e,r):r.isShadowMaterial?(e.color.value.copy(r.color),e.opacity.value=r.opacity):r.isShaderMaterial&&(r.uniformsNeedUpdate=!1)}}}function Ca(e,t,n,i){let r={},a={},o=[];const s=e.getParameter(e.MAX_UNIFORM_BUFFER_BINDINGS);function l(e,t,n,i){const r=e.value,a=t+"_"+n;if(void 0===i[a])return i[a]="number"==typeof r||"boolean"==typeof r?r:r.clone(),!0;{const e=i[a];if("number"==typeof r||"boolean"==typeof r){if(e!==r)return i[a]=r,!0}else if(!1===e.equals(r))return e.copy(r),!0}return!1}function c(e){const t={boundary:0,storage:0};return"number"==typeof e||"boolean"==typeof e?(t.boundary=4,t.storage=4):e.isVector2?(t.boundary=8,t.storage=8):e.isVector3||e.isColor?(t.boundary=16,t.storage=12):e.isVector4?(t.boundary=16,t.storage=16):e.isMatrix3?(t.boundary=48,t.storage=48):e.isMatrix4?(t.boundary=64,t.storage=64):e.isTexture?E("WebGLRenderer: Texture samplers can not be part of an uniforms group."):E("WebGLRenderer: Unsupported uniform value type.",e),t}function d(t){const n=t.target;n.removeEventListener("dispose",d);const i=o.indexOf(n.__bindingPointIndex);o.splice(i,1),e.deleteBuffer(r[n.id]),delete r[n.id],delete a[n.id]}return{bind:function(e,t){const n=t.program;i.uniformBlockBinding(e,n)},update:function(n,u){let f=r[n.id];void 0===f&&(!function(e){const t=e.uniforms;let n=0;const i=16;for(let e=0,r=t.length;e0&&(n+=i-r);e.__size=n,e.__cache={}}(n),f=function(t){const n=function(){for(let e=0;e0),f=!!n.morphAttributes.position,p=!!n.morphAttributes.normal,m=!!n.morphAttributes.color;let h=U;i.toneMapped&&(null!==k&&!0!==k.isXRRenderTarget||(h=B.toneMapping));const _=n.morphAttributes.position||n.morphAttributes.normal||n.morphAttributes.color,g=void 0!==_?_.length:0,v=Me.get(i),E=L.state.lights;if(!0===le&&(!0===ce||e!==Y)){const t=e===Y&&i.id===X;Ne.setState(i,e,t)}let M=!1;i.version===v.__version?v.needsLights&&v.lightsStateVersion!==E.state.version||v.outputColorSpace!==s||r.isBatchedMesh&&!1===v.batching?M=!0:r.isBatchedMesh||!0!==v.batching?r.isBatchedMesh&&!0===v.batchingColor&&null===r.colorTexture||r.isBatchedMesh&&!1===v.batchingColor&&null!==r.colorTexture||r.isInstancedMesh&&!1===v.instancing?M=!0:r.isInstancedMesh||!0!==v.instancing?r.isSkinnedMesh&&!1===v.skinning?M=!0:r.isSkinnedMesh||!0!==v.skinning?r.isInstancedMesh&&!0===v.instancingColor&&null===r.instanceColor||r.isInstancedMesh&&!1===v.instancingColor&&null!==r.instanceColor||r.isInstancedMesh&&!0===v.instancingMorph&&null===r.morphTexture||r.isInstancedMesh&&!1===v.instancingMorph&&null!==r.morphTexture||v.envMap!==c||!0===i.fog&&v.fog!==a?M=!0:void 0===v.numClippingPlanes||v.numClippingPlanes===Ne.numPlanes&&v.numIntersection===Ne.numIntersection?(v.vertexAlphas!==d||v.vertexTangents!==u||v.morphTargets!==f||v.morphNormals!==p||v.morphColors!==m||v.toneMapping!==h||v.morphTargetsCount!==g)&&(M=!0):M=!0:M=!0:M=!0:M=!0:(M=!0,v.__version=i.version);let T=v.currentProgram;!0===M&&(T=st(i,t,r));let x=!1,A=!1,R=!1;const b=T.getUniforms(),C=v.uniforms;Ee.useProgram(T.program)&&(x=!0,A=!0,R=!0);i.id!==X&&(X=i.id,A=!0);if(x||Y!==e){Ee.buffers.depth.getReversed()&&!0!==e.reversedDepth&&(e._reversedDepth=!0,e.updateProjectionMatrix()),b.setValue(ze,"projectionMatrix",e.projectionMatrix),b.setValue(ze,"viewMatrix",e.matrixWorldInverse);const t=b.map.cameraPosition;void 0!==t&&t.setValue(ze,ue.setFromMatrixPosition(e.matrixWorld)),ve.logarithmicDepthBuffer&&b.setValue(ze,"logDepthBufFC",2/(Math.log(e.far+1)/Math.LN2)),(i.isMeshPhongMaterial||i.isMeshToonMaterial||i.isMeshLambertMaterial||i.isMeshBasicMaterial||i.isMeshStandardMaterial||i.isShaderMaterial)&&b.setValue(ze,"isOrthographic",!0===e.isOrthographicCamera),Y!==e&&(Y=e,A=!0,R=!0)}v.needsLights&&(E.state.directionalShadowMap.length>0&&b.setValue(ze,"directionalShadowMap",E.state.directionalShadowMap,Ae),E.state.spotShadowMap.length>0&&b.setValue(ze,"spotShadowMap",E.state.spotShadowMap,Ae),E.state.pointShadowMap.length>0&&b.setValue(ze,"pointShadowMap",E.state.pointShadowMap,Ae));if(r.isSkinnedMesh){b.setOptional(ze,r,"bindMatrix"),b.setOptional(ze,r,"bindMatrixInverse");const e=r.skeleton;e&&(null===e.boneTexture&&e.computeBoneTexture(),b.setValue(ze,"boneTexture",e.boneTexture,Ae))}r.isBatchedMesh&&(b.setOptional(ze,r,"batchingTexture"),b.setValue(ze,"batchingTexture",r._matricesTexture,Ae),b.setOptional(ze,r,"batchingIdTexture"),b.setValue(ze,"batchingIdTexture",r._indirectTexture,Ae),b.setOptional(ze,r,"batchingColorTexture"),null!==r._colorsTexture&&b.setValue(ze,"batchingColorTexture",r._colorsTexture,Ae));const P=n.morphAttributes;void 0===P.position&&void 0===P.normal&&void 0===P.color||Oe.update(r,n,T);(A||v.receiveShadow!==r.receiveShadow)&&(v.receiveShadow=r.receiveShadow,b.setValue(ze,"receiveShadow",r.receiveShadow));(i.isMeshStandardMaterial||i.isMeshLambertMaterial||i.isMeshPhongMaterial)&&null===i.envMap&&null!==t.environment&&(C.envMapIntensity.value=t.environmentIntensity);void 0!==C.dfgLUT&&(C.dfgLUT.value=(null===La&&(La=new Un(Pa,16,16,Te,S),La.name="DFG_LUT",La.minFilter=O,La.magFilter=O,La.wrapS=pt,La.wrapT=pt,La.generateMipmaps=!1,La.needsUpdate=!0),La));A&&(b.setValue(ze,"toneMappingExposure",B.toneMappingExposure),v.needsLights&&(w=R,(D=C).ambientLightColor.needsUpdate=w,D.lightProbe.needsUpdate=w,D.directionalLights.needsUpdate=w,D.directionalLightShadows.needsUpdate=w,D.pointLights.needsUpdate=w,D.pointLightShadows.needsUpdate=w,D.spotLights.needsUpdate=w,D.spotLightShadows.needsUpdate=w,D.rectAreaLights.needsUpdate=w,D.hemisphereLights.needsUpdate=w),a&&!0===i.fog&&De.refreshFogUniforms(C,a),De.refreshMaterialUniforms(C,i,te,ee,L.state.transmissionRenderTarget[e.id]),Rr.upload(ze,lt(v),C,Ae));var D,w;i.isShaderMaterial&&!0===i.uniformsNeedUpdate&&(Rr.upload(ze,lt(v),C,Ae),i.uniformsNeedUpdate=!1);i.isSpriteMaterial&&b.setValue(ze,"center",r.center);if(b.setValue(ze,"modelViewMatrix",r.modelViewMatrix),b.setValue(ze,"normalMatrix",r.normalMatrix),b.setValue(ze,"modelMatrix",r.matrixWorld),i.isShaderMaterial||i.isRawShaderMaterial){const e=i.uniformsGroups;for(let t=0,n=e.length;t{function n(){i.forEach(function(e){Me.get(e).currentProgram.isReady()&&i.delete(e)}),0!==i.size?setTimeout(n,10):t(e)}null!==_e.get("KHR_parallel_shader_compile")?n():setTimeout(n,10)})};let Qe=null;function Je(){tt.stop()}function et(){tt.start()}const tt=new On;function nt(e,t,n,i){if(!1===e.visible)return;if(e.layers.test(t.layers))if(e.isGroup)n=e.renderOrder;else if(e.isLOD)!0===e.autoUpdate&&e.update(t);else if(e.isLight)L.pushLight(e),e.castShadow&&L.pushShadow(e);else if(e.isSprite){if(!e.frustumCulled||se.intersectsSprite(e)){i&&fe.setFromMatrixPosition(e.matrixWorld).applyMatrix4(de);const t=Pe.update(e),r=e.material;r.visible&&P.push(e,t,r,n,fe.z,null)}}else if((e.isMesh||e.isLine||e.isPoints)&&(!e.frustumCulled||se.intersectsObject(e))){const t=Pe.update(e),r=e.material;if(i&&(void 0!==e.boundingSphere?(null===e.boundingSphere&&e.computeBoundingSphere(),fe.copy(e.boundingSphere.center)):(null===t.boundingSphere&&t.computeBoundingSphere(),fe.copy(t.boundingSphere.center)),fe.applyMatrix4(e.matrixWorld).applyMatrix4(de)),Array.isArray(r)){const i=t.groups;for(let a=0,o=i.length;a0&&at(r,t,n),a.length>0&&at(a,t,n),o.length>0&&at(o,t,n),Ee.buffers.depth.setTest(!0),Ee.buffers.depth.setMask(!0),Ee.buffers.color.setMask(!0),Ee.setPolygonOffset(!1)}function rt(e,t,n,i){if(null!==(!0===n.isScene?n.overrideMaterial:null))return;if(void 0===L.state.transmissionRenderTarget[i.id]){const e=_e.has("EXT_color_buffer_half_float")||_e.has("EXT_color_buffer_float");L.state.transmissionRenderTarget[i.id]=new N(1,1,{generateMipmaps:!0,type:e?S:M,minFilter:G,samples:ve.samples,stencilBuffer:o,resolveDepthBuffer:!1,resolveStencilBuffer:!1,colorSpace:p.workingColorSpace})}const r=L.state.transmissionRenderTarget[i.id],a=i.viewport||q;r.setSize(a.z*B.transmissionResolutionScale,a.w*B.transmissionResolutionScale);const s=B.getRenderTarget(),l=B.getActiveCubeFace(),d=B.getActiveMipmapLevel();B.setRenderTarget(r),B.getClearColor($),Q=B.getClearAlpha(),Q<1&&B.setClearColor(16777215,.5),B.clear(),me&&Fe.render(n);const u=B.toneMapping;B.toneMapping=U;const f=i.viewport;if(void 0!==i.viewport&&(i.viewport=void 0),L.setupLightsView(i),!0===le&&Ne.setGlobalState(B.clippingPlanes,i),at(e,n,i),Ae.updateMultisampleRenderTarget(r),Ae.updateRenderTargetMipmap(r),!1===_e.has("WEBGL_multisampled_render_to_texture")){let e=!1;for(let r=0,a=t.length;r0)for(let t=0,a=r.length;t0&&rt(n,i,e,t),me&&Fe.render(e),it(P,e,t)}null!==k&&0===W&&(Ae.updateMultisampleRenderTarget(k),Ae.updateRenderTargetMipmap(k)),i&&y.end(B),!0===e.isScene&&e.onAfterRender(B,e,t),Ve.resetDefaultState(),X=-1,Y=null,I.pop(),I.length>0?(L=I[I.length-1],!0===le&&Ne.setGlobalState(B.clippingPlanes,L.state.camera)):L=null,D.pop(),P=D.length>0?D[D.length-1]:null},this.getActiveCubeFace=function(){return V},this.getActiveMipmapLevel=function(){return W},this.getRenderTarget=function(){return k},this.setRenderTargetTextures=function(e,t,n){const i=Me.get(e);i.__autoAllocateDepthBuffer=!1===e.resolveDepthBuffer,!1===i.__autoAllocateDepthBuffer&&(i.__useRenderToTexture=!1),Me.get(e.texture).__webglTexture=t,Me.get(e.depthTexture).__webglTexture=i.__autoAllocateDepthBuffer?void 0:n,i.__hasExternalTextures=!0},this.setRenderTargetFramebuffer=function(e,t){const n=Me.get(e);n.__webglFramebuffer=t,n.__useDefaultFramebuffer=void 0===t};const dt=ze.createFramebuffer();this.setRenderTarget=function(e,t=0,n=0){k=e,V=t,W=n;let i=null,r=!1,a=!1;if(e){const o=Me.get(e);if(void 0!==o.__useDefaultFramebuffer)return Ee.bindFramebuffer(ze.FRAMEBUFFER,o.__webglFramebuffer),q.copy(e.viewport),j.copy(e.scissor),Z=e.scissorTest,Ee.viewport(q),Ee.scissor(j),Ee.setScissorTest(Z),void(X=-1);if(void 0===o.__webglFramebuffer)Ae.setupRenderTarget(e);else if(o.__hasExternalTextures)Ae.rebindTextures(e,Me.get(e.texture).__webglTexture,Me.get(e.depthTexture).__webglTexture);else if(e.depthBuffer){const t=e.depthTexture;if(o.__boundDepthTexture!==t){if(null!==t&&Me.has(t)&&(e.width!==t.image.width||e.height!==t.image.height))throw new Error("WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.");Ae.setupDepthRenderbuffer(e)}}const s=e.texture;(s.isData3DTexture||s.isDataArrayTexture||s.isCompressedArrayTexture)&&(a=!0);const l=Me.get(e).__webglFramebuffer;e.isWebGLCubeRenderTarget?(i=Array.isArray(l[t])?l[t][n]:l[t],r=!0):i=e.samples>0&&!1===Ae.useMultisampledRTT(e)?Me.get(e).__webglMultisampledFramebuffer:Array.isArray(l)?l[n]:l,q.copy(e.viewport),j.copy(e.scissor),Z=e.scissorTest}else q.copy(re).multiplyScalar(te).floor(),j.copy(ae).multiplyScalar(te).floor(),Z=oe;0!==n&&(i=dt);if(Ee.bindFramebuffer(ze.FRAMEBUFFER,i)&&Ee.drawBuffers(e,i),Ee.viewport(q),Ee.scissor(j),Ee.setScissorTest(Z),r){const i=Me.get(e.texture);ze.framebufferTexture2D(ze.FRAMEBUFFER,ze.COLOR_ATTACHMENT0,ze.TEXTURE_CUBE_MAP_POSITIVE_X+t,i.__webglTexture,n)}else if(a){const i=t;for(let t=0;t1&&ze.readBuffer(ze.COLOR_ATTACHMENT0+s),!ve.textureFormatReadable(l))return void w("WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.");if(!ve.textureTypeReadable(c))return void w("WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.");t>=0&&t<=e.width-i&&n>=0&&n<=e.height-r&&ze.readPixels(t,n,i,r,He.convert(l),He.convert(c),a)}finally{const e=null!==k?Me.get(k).__webglFramebuffer:null;Ee.bindFramebuffer(ze.FRAMEBUFFER,e)}}},this.readRenderTargetPixelsAsync=async function(e,t,n,i,r,a,o,s=0){if(!e||!e.isWebGLRenderTarget)throw new Error("THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not THREE.WebGLRenderTarget.");let l=Me.get(e).__webglFramebuffer;if(e.isWebGLCubeRenderTarget&&void 0!==o&&(l=l[o]),l){if(t>=0&&t<=e.width-i&&n>=0&&n<=e.height-r){Ee.bindFramebuffer(ze.FRAMEBUFFER,l);const o=e.textures[s],c=o.format,d=o.type;if(e.textures.length>1&&ze.readBuffer(ze.COLOR_ATTACHMENT0+s),!ve.textureFormatReadable(c))throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in RGBA or implementation defined format.");if(!ve.textureTypeReadable(d))throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: renderTarget is not in UnsignedByteType or implementation defined type.");const u=ze.createBuffer();ze.bindBuffer(ze.PIXEL_PACK_BUFFER,u),ze.bufferData(ze.PIXEL_PACK_BUFFER,a.byteLength,ze.STREAM_READ),ze.readPixels(t,n,i,r,He.convert(c),He.convert(d),0);const f=null!==k?Me.get(k).__webglFramebuffer:null;Ee.bindFramebuffer(ze.FRAMEBUFFER,f);const p=ze.fenceSync(ze.SYNC_GPU_COMMANDS_COMPLETE,0);return ze.flush(),await Fn(ze,p,4),ze.bindBuffer(ze.PIXEL_PACK_BUFFER,u),ze.getBufferSubData(ze.PIXEL_PACK_BUFFER,0,a),ze.deleteBuffer(u),ze.deleteSync(p),a}throw new Error("THREE.WebGLRenderer.readRenderTargetPixelsAsync: requested read bounds are out of range.")}},this.copyFramebufferToTexture=function(e,t=null,n=0){const i=Math.pow(2,-n),r=Math.floor(e.image.width*i),a=Math.floor(e.image.height*i),o=null!==t?t.x:0,s=null!==t?t.y:0;Ae.setTexture2D(e,0),ze.copyTexSubImage2D(ze.TEXTURE_2D,n,0,0,o,s,r,a),Ee.unbindTexture()};const ut=ze.createFramebuffer(),ft=ze.createFramebuffer();this.copyTextureToTexture=function(e,t,n=null,i=null,r=0,a=0){let o,s,l,c,d,u,f,p,m;const h=e.isCompressedTexture?e.mipmaps[a]:e.image;if(null!==n)o=n.max.x-n.min.x,s=n.max.y-n.min.y,l=n.isBox3?n.max.z-n.min.z:1,c=n.min.x,d=n.min.y,u=n.isBox3?n.min.z:0;else{const t=Math.pow(2,-r);o=Math.floor(h.width*t),s=Math.floor(h.height*t),l=e.isDataArrayTexture?h.depth:e.isData3DTexture?Math.floor(h.depth*t):1,c=0,d=0,u=0}null!==i?(f=i.x,p=i.y,m=i.z):(f=0,p=0,m=0);const _=He.convert(t.format),g=He.convert(t.type);let v;t.isData3DTexture?(Ae.setTexture3D(t,0),v=ze.TEXTURE_3D):t.isDataArrayTexture||t.isCompressedArrayTexture?(Ae.setTexture2DArray(t,0),v=ze.TEXTURE_2D_ARRAY):(Ae.setTexture2D(t,0),v=ze.TEXTURE_2D),ze.pixelStorei(ze.UNPACK_FLIP_Y_WEBGL,t.flipY),ze.pixelStorei(ze.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),ze.pixelStorei(ze.UNPACK_ALIGNMENT,t.unpackAlignment);const E=ze.getParameter(ze.UNPACK_ROW_LENGTH),S=ze.getParameter(ze.UNPACK_IMAGE_HEIGHT),M=ze.getParameter(ze.UNPACK_SKIP_PIXELS),T=ze.getParameter(ze.UNPACK_SKIP_ROWS),x=ze.getParameter(ze.UNPACK_SKIP_IMAGES);ze.pixelStorei(ze.UNPACK_ROW_LENGTH,h.width),ze.pixelStorei(ze.UNPACK_IMAGE_HEIGHT,h.height),ze.pixelStorei(ze.UNPACK_SKIP_PIXELS,c),ze.pixelStorei(ze.UNPACK_SKIP_ROWS,d),ze.pixelStorei(ze.UNPACK_SKIP_IMAGES,u);const A=e.isDataArrayTexture||e.isData3DTexture,R=t.isDataArrayTexture||t.isData3DTexture;if(e.isDepthTexture){const n=Me.get(e),i=Me.get(t),h=Me.get(n.__renderTarget),_=Me.get(i.__renderTarget);Ee.bindFramebuffer(ze.READ_FRAMEBUFFER,h.__webglFramebuffer),Ee.bindFramebuffer(ze.DRAW_FRAMEBUFFER,_.__webglFramebuffer);for(let n=0;n { } else { - // Use getUV context to avoid side effects from nodes overwriting getUV in the context (e.g. EnvironmentNode) + // Use custom context to avoid side effects from nodes overwriting getUV, getTextureLevel in the context (e.g. EnvironmentNode) - node = builder.context.setupNormal().context( { getUV: null } ); + node = builder.context.setupNormal().context( { getUV: null, getTextureLevel: null } ); } @@ -14295,9 +14295,9 @@ const clearcoatNormalView = /*@__PURE__*/ ( Fn( ( { subBuildFn, context } ) => { } else { - // Use getUV context to avoid side effects from nodes overwriting getUV in the context (e.g. EnvironmentNode) + // Use custom context to avoid side effects from nodes overwriting getUV, getTextureLevel in the context (e.g. EnvironmentNode) - node = context.setupClearcoatNormal().context( { getUV: null } ); + node = context.setupClearcoatNormal().context( { getUV: null, getTextureLevel: null } ); } @@ -22115,15 +22115,13 @@ const equirectUV = /*@__PURE__*/ Fn( ( [ dir = positionWorldDirection ] ) => { } ); -// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget - /** * This class represents a cube render target. It is a special version * of `WebGLCubeRenderTarget` which is compatible with `WebGPURenderer`. * - * @augments WebGLCubeRenderTarget + * @augments RenderTarget */ -class CubeRenderTarget extends WebGLCubeRenderTarget { +class CubeRenderTarget extends RenderTarget { /** * Constructs a new cube render target. @@ -22133,7 +22131,7 @@ class CubeRenderTarget extends WebGLCubeRenderTarget { */ constructor( size = 1, options = {} ) { - super( size, options ); + super( size, size, options ); /** * This flag can be used for type testing. @@ -22144,6 +22142,27 @@ class CubeRenderTarget extends WebGLCubeRenderTarget { */ this.isCubeRenderTarget = true; + const image = { width: size, height: size, depth: 1 }; + const images = [ image, image, image, image, image, image ]; + + /** + * Overwritten with a different texture type. + * + * @type {DataArrayTexture} + */ + this.texture = new CubeTexture( images ); + this._setTextureOptions( options ); + + // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, + // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. + + // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped + // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture + // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). + + this.texture.isRenderTargetTexture = true; + } /** @@ -22203,6 +22222,30 @@ class CubeRenderTarget extends WebGLCubeRenderTarget { } + /** + * Clears this cube render target. + * + * @param {Renderer} renderer - The renderer. + * @param {boolean} [color=true] - Whether the color buffer should be cleared or not. + * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not. + * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not. + */ + clear( renderer, color = true, depth = true, stencil = true ) { + + const currentRenderTarget = renderer.getRenderTarget(); + + for ( let i = 0; i < 6; i ++ ) { + + renderer.setRenderTarget( this, i ); + + renderer.clear( color, depth, stencil ); + + } + + renderer.setRenderTarget( currentRenderTarget ); + + } + } const _cache$1 = new WeakMap(); @@ -30025,6 +30068,20 @@ function getWireframeVersion( geometry ) { } +/** + * Returns the wireframe ID for the given geometry. + * + * @private + * @function + * @param {BufferGeometry} geometry - The geometry. + * @return {number} The ID. + */ +function getWireframeId( geometry ) { + + return ( geometry.index !== null ) ? geometry.index.id : geometry.attributes.position.id; + +} + /** * Returns a wireframe index attribute for the given geometry. * @@ -30072,6 +30129,7 @@ function getWireframeIndex( geometry ) { const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); attribute.version = getWireframeVersion( geometry ); + attribute.__id = getWireframeId( geometry ); return attribute; @@ -30354,7 +30412,7 @@ class Geometries extends DataMap { wireframes.set( geometry, wireframeAttribute ); - } else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) ) { + } else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) || wireframeAttribute.__id !== getWireframeId( geometry ) ) { this.attributes.delete( wireframeAttribute ); @@ -47982,9 +48040,8 @@ class BindGroup { * @param {string} name - The bind group's name. * @param {Array} bindings - An array of bindings. * @param {number} index - The group index. - * @param {Array} bindingsReference - An array of reference bindings. */ - constructor( name = '', bindings = [], index = 0, bindingsReference = [] ) { + constructor( name = '', bindings = [], index = 0 ) { /** * The bind group's name. @@ -48007,13 +48064,6 @@ class BindGroup { */ this.index = index; - /** - * An array of reference bindings. - * - * @type {Array} - */ - this.bindingsReference = bindingsReference; - /** * The group's ID. * @@ -48151,7 +48201,7 @@ class NodeBuilderState { if ( shared !== true ) { - const bindingsGroup = new BindGroup( instanceGroup.name, [], instanceGroup.index, instanceGroup.bindingsReference ); + const bindingsGroup = new BindGroup( instanceGroup.name, [], instanceGroup.index ); bindings.push( bindingsGroup ); for ( const instanceBinding of instanceGroup.bindings ) { @@ -49888,7 +49938,7 @@ class NodeBuilder { bindingsArray.push( binding ); - sharedGroup = sharedGroup && binding.groupNode.shared !== true; + sharedGroup = sharedGroup && binding.groupNode.shared; } @@ -49902,7 +49952,7 @@ class NodeBuilder { if ( bindGroup === undefined ) { - bindGroup = new BindGroup( groupName, bindingsArray, this.bindingsIndexes[ groupName ].group, bindingsArray ); + bindGroup = new BindGroup( groupName, bindingsArray, this.bindingsIndexes[ groupName ].group ); bindGroupsCache.set( bindingsArray, bindGroup ); @@ -49910,7 +49960,7 @@ class NodeBuilder { } else { - bindGroup = new BindGroup( groupName, bindingsArray, this.bindingsIndexes[ groupName ].group, bindingsArray ); + bindGroup = new BindGroup( groupName, bindingsArray, this.bindingsIndexes[ groupName ].group ); } @@ -59868,6 +59918,37 @@ class Renderer { } + /** + * Initializes the given render target. + * + * @param {RenderTarget} renderTarget - The render target to intialize. + */ + initRenderTarget( renderTarget ) { + + if ( this._initialized === false ) { + + throw new Error( 'Renderer: .initRenderTarget() called before the backend is initialized. Use "await renderer.init();" before before using this method.' ); + + } + + this._textures.updateRenderTarget( renderTarget ); + + const renderTargetData = this._textures.get( renderTarget ); + + const renderContext = this._renderContexts.get( renderTarget ); + + renderContext.textures = renderTargetData.textures; + renderContext.depthTexture = renderTargetData.depthTexture; + renderContext.width = renderTargetData.width; + renderContext.height = renderTargetData.height; + renderContext.renderTarget = renderTarget; + renderContext.depth = renderTarget.depthBuffer; + renderContext.stencil = renderTarget.stencilBuffer; + + this.backend.initRenderTarget( renderContext ); + + } + /** * Copies the current bound framebuffer into the given texture. * @@ -60343,9 +60424,9 @@ class Renderer { materialOverride = true; // store original nodes - materialColorNode = scene.overrideMaterial.colorNode; - materialDepthNode = scene.overrideMaterial.depthNode; - materialPositionNode = scene.overrideMaterial.positionNode; + materialColorNode = ( overrideMaterial.isNodeMaterial ) ? overrideMaterial.colorNode : null; + materialDepthNode = ( overrideMaterial.isNodeMaterial ) ? overrideMaterial.depthNode : null; + materialPositionNode = ( overrideMaterial.isNodeMaterial ) ? overrideMaterial.positionNode : null; materialSide = scene.overrideMaterial.side; if ( material.positionNode && material.positionNode.isNode ) { @@ -60452,6 +60533,16 @@ class Renderer { renderObject.drawRange = object.geometry.drawRange; renderObject.group = group; + if ( this._currentRenderBundle !== null ) { + + const renderBundleData = this.backend.get( this._currentRenderBundle ); + + renderBundleData.renderObjects.push( renderObject ); + + renderObject.bundle = this._currentRenderBundle.bundleGroup; + + } + // const needsRefresh = this._nodes.needsRefresh( renderObject ); @@ -60471,16 +60562,6 @@ class Renderer { // - if ( this._currentRenderBundle !== null ) { - - const renderBundleData = this.backend.get( this._currentRenderBundle ); - - renderBundleData.renderObjects.push( renderObject ); - - renderObject.bundle = this._currentRenderBundle.bundleGroup; - - } - this.backend.draw( renderObject, this.info ); if ( needsRefresh ) this._nodes.updateAfter( renderObject ); @@ -62581,7 +62662,17 @@ ${ flowData.code } } else if ( uniform.type === 'cubeDepthTexture' ) { - snippet = `samplerCubeShadow ${ uniform.name };`; + const texture = uniform.node.value; + + if ( texture.compareFunction ) { + + snippet = `samplerCubeShadow ${ uniform.name };`; + + } else { + + snippet = `samplerCube ${ uniform.name };`; + + } } else if ( uniform.type === 'buffer' ) { @@ -64181,6 +64272,14 @@ class Backend { } + /** + * Initializes the render target defined in the given render context. + * + * @abstract + * @param {RenderContext} renderContext - The render context. + */ + initRenderTarget( /*renderContext*/ ) {} + /** * Sets a dictionary for the given object into the * internal data structure. @@ -68744,9 +68843,12 @@ class WebGLBackend extends Backend { if ( renderContext.scissor ) { - const { x, y, width, height } = renderContext.scissorValue; + this.updateScissor( renderContext ); + + } else { - state.scissor( x, renderContext.height - height - y, width, height ); + const { width, height } = this.getDrawingBufferSize(); + state.scissor( 0, 0, width, height ); } @@ -68843,6 +68945,17 @@ class WebGLBackend extends Backend { } + if ( previousContext.scissor ) { + + this.updateScissor( previousContext ); + + } else { + + const { width, height } = this.getDrawingBufferSize(); + state.scissor( 0, 0, width, height ); + + } + } this.prepareTimestampBuffer( TimestampQuery.RENDER, this.getTimestampUID( renderContext ) ); @@ -68944,6 +69057,20 @@ class WebGLBackend extends Backend { } + /** + * Updates the scissor with the values from the given render context. + * + * @param {RenderContext} renderContext - The render context. + */ + updateScissor( renderContext ) { + + const { state } = this; + const { x, y, width, height } = renderContext.scissorValue; + + state.scissor( x, renderContext.height - height - y, width, height ); + + } + /** * Defines the scissor test. * @@ -70309,6 +70436,21 @@ class WebGLBackend extends Backend { } + /** + * Initializes the render target defined in the given render context. + * + * @param {RenderContext} renderContext - The render context. + */ + initRenderTarget( renderContext ) { + + const { gl, state } = this; + + this._setFramebuffer( renderContext ); + + state.bindFramebuffer( gl.FRAMEBUFFER, null ); + + } + /** * Configures the active framebuffer from the given render context. * @@ -70327,7 +70469,7 @@ class WebGLBackend extends Backend { const renderTargetContextData = this.get( renderTarget ); const { samples, depthBuffer, stencilBuffer } = renderTarget; - const isCube = renderTarget.isWebGLCubeRenderTarget === true; + const isCube = renderTarget.isCubeRenderTarget === true; const isRenderTarget3D = renderTarget.isRenderTarget3D === true; const isRenderTargetArray = renderTarget.depth > 1; const isXRRenderTarget = renderTarget.isXRRenderTarget === true; @@ -70991,9 +71133,7 @@ const GPUPrimitiveTopology = { PointList: 'point-list', LineList: 'line-list', LineStrip: 'line-strip', - TriangleList: 'triangle-list', - TriangleStrip: 'triangle-strip', -}; + TriangleList: 'triangle-list'}; const GPUShaderStage = ( typeof self !== 'undefined' && self.GPUShaderStage ) ? self.GPUShaderStage : { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 }; @@ -71483,65 +71623,88 @@ class WebGPUTexturePassUtils extends DataMap { */ this.device = device; - const mipmapVertexSource = ` + const mipmapSource = ` struct VarysStruct { - @builtin( position ) Position: vec4, - @location( 0 ) vTex : vec2 + @builtin( position ) Position: vec4f, + @location( 0 ) vTex : vec2f, + @location( 1 ) @interpolate(flat, either) vBaseArrayLayer: u32, }; +@group( 0 ) @binding ( 2 ) +var flipY: u32; + @vertex -fn main( @builtin( vertex_index ) vertexIndex : u32 ) -> VarysStruct { +fn mainVS( + @builtin( vertex_index ) vertexIndex : u32, + @builtin( instance_index ) instanceIndex : u32 ) -> VarysStruct { var Varys : VarysStruct; - var pos = array< vec2, 4 >( - vec2( -1.0, 1.0 ), - vec2( 1.0, 1.0 ), - vec2( -1.0, -1.0 ), - vec2( 1.0, -1.0 ) + var pos = array( + vec2f( -1, -1 ), + vec2f( -1, 3 ), + vec2f( 3, -1 ), ); - var tex = array< vec2, 4 >( - vec2( 0.0, 0.0 ), - vec2( 1.0, 0.0 ), - vec2( 0.0, 1.0 ), - vec2( 1.0, 1.0 ) - ); - - Varys.vTex = tex[ vertexIndex ]; - Varys.Position = vec4( pos[ vertexIndex ], 0.0, 1.0 ); + let p = pos[ vertexIndex ]; + let mult = select( vec2f( 0.5, -0.5 ), vec2f( 0.5, 0.5 ), flipY != 0 ); + Varys.vTex = p * vec2f( 0.5, -0.5 ) + vec2f( 0.5 ); + Varys.Position = vec4f( p, 0, 1 ); + Varys.vBaseArrayLayer = instanceIndex; return Varys; } -`; - const mipmapFragmentSource = ` @group( 0 ) @binding( 0 ) var imgSampler : sampler; @group( 0 ) @binding( 1 ) -var img : texture_2d; +var img2d : texture_2d; @fragment -fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { +fn main_2d( Varys: VarysStruct ) -> @location( 0 ) vec4 { - return textureSample( img, imgSampler, vTex ); + return textureSample( img2d, imgSampler, Varys.vTex ); } -`; - const flipYFragmentSource = ` -@group( 0 ) @binding( 0 ) -var imgSampler : sampler; +@group( 0 ) @binding( 1 ) +var img2dArray : texture_2d_array; + +@fragment +fn main_2d_array( Varys: VarysStruct ) -> @location( 0 ) vec4 { + + return textureSample( img2dArray, imgSampler, Varys.vTex, Varys.vBaseArrayLayer ); + +} + +const faceMat = array( + mat3x3f( 0, 0, -2, 0, -2, 0, 1, 1, 1 ), // pos-x + mat3x3f( 0, 0, 2, 0, -2, 0, -1, 1, -1 ), // neg-x + mat3x3f( 2, 0, 0, 0, 0, 2, -1, 1, -1 ), // pos-y + mat3x3f( 2, 0, 0, 0, 0, -2, -1, -1, 1 ), // neg-y + mat3x3f( 2, 0, 0, 0, -2, 0, -1, 1, 1 ), // pos-z + mat3x3f( -2, 0, 0, 0, -2, 0, 1, 1, -1 ), // neg-z +); + +@group( 0 ) @binding( 1 ) +var imgCube : texture_cube; + +@fragment +fn main_cube( Varys: VarysStruct ) -> @location( 0 ) vec4 { + + return textureSample( imgCube, imgSampler, faceMat[ Varys.vBaseArrayLayer ] * vec3f( fract( Varys.vTex ), 1 ) ); + +} @group( 0 ) @binding( 1 ) -var img : texture_2d; +var imgCubeArray : texture_cube_array; @fragment -fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { +fn main_cube_array( Varys: VarysStruct ) -> @location( 0 ) vec4 { - return textureSample( img, imgSampler, vec2( vTex.x, 1.0 - vTex.y ) ); + return textureSample( imgCubeArray, imgSampler, faceMat[ Varys.vBaseArrayLayer % 6 ] * vec3f( fract( Varys.vTex ), 1 ), Varys.vBaseArrayLayer ); } `; @@ -71561,49 +71724,40 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { this.flipYSampler = device.createSampler( { minFilter: GPUFilterMode.Nearest } ); //@TODO?: Consider using textureLoad() /** - * A cache for GPU render pipelines used for copy/transfer passes. - * Every texture format requires a unique pipeline. - * - * @type {Object} + * flip uniform buffer + * @type {GPUBuffer} */ - this.transferPipelines = {}; - - /** - * A cache for GPU render pipelines used for flipY passes. - * Every texture format requires a unique pipeline. - * - * @type {Object} - */ - this.flipYPipelines = {}; + this.flipUniformBuffer = device.createBuffer( { + size: 4, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST + } ); + device.queue.writeBuffer( this.flipUniformBuffer, 0, new Uint32Array( [ 1 ] ) ); /** - * The mipmap vertex shader module. - * - * @type {GPUShaderModule} + * no flip uniform buffer + * @type {GPUBuffer} */ - this.mipmapVertexShaderModule = device.createShaderModule( { - label: 'mipmapVertex', - code: mipmapVertexSource + this.noFlipUniformBuffer = device.createBuffer( { + size: 4, + usage: GPUBufferUsage.UNIFORM } ); /** - * The mipmap fragment shader module. + * A cache for GPU render pipelines used for copy/transfer passes. + * Every texture format and textureBindingViewDimension combo requires a unique pipeline. * - * @type {GPUShaderModule} + * @type {Object} */ - this.mipmapFragmentShaderModule = device.createShaderModule( { - label: 'mipmapFragment', - code: mipmapFragmentSource - } ); + this.transferPipelines = {}; /** - * The flipY fragment shader module. + * The mipmap shader module. * * @type {GPUShaderModule} */ - this.flipYFragmentShaderModule = device.createShaderModule( { - label: 'flipYFragment', - code: flipYFragmentSource + this.mipmapShaderModule = device.createShaderModule( { + label: 'mipmap', + code: mipmapSource } ); } @@ -71613,29 +71767,27 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { * requires a unique render pipeline for each texture format. * * @param {string} format - The GPU texture format + * @param {string?} textureBindingViewDimension - The GPU texture binding view dimension * @return {GPURenderPipeline} The GPU render pipeline. */ - getTransferPipeline( format ) { + getTransferPipeline( format, textureBindingViewDimension ) { - let pipeline = this.transferPipelines[ format ]; + textureBindingViewDimension = textureBindingViewDimension || '2d-array'; + const key = `${ format }-${ textureBindingViewDimension }`; + let pipeline = this.transferPipelines[ key ]; if ( pipeline === undefined ) { pipeline = this.device.createRenderPipeline( { - label: `mipmap-${ format }`, + label: `mipmap-${ format }-${ textureBindingViewDimension }`, vertex: { - module: this.mipmapVertexShaderModule, - entryPoint: 'main' + module: this.mipmapShaderModule, }, fragment: { - module: this.mipmapFragmentShaderModule, - entryPoint: 'main', + module: this.mipmapShaderModule, + entryPoint: `main_${ textureBindingViewDimension.replace( '-', '_' ) }`, targets: [ { format } ] }, - primitive: { - topology: GPUPrimitiveTopology.TriangleStrip, - stripIndexFormat: GPUIndexFormat.Uint32 - }, layout: 'auto' } ); @@ -71647,45 +71799,6 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { } - /** - * Returns a render pipeline for the flipY render pass. The pass - * requires a unique render pipeline for each texture format. - * - * @param {string} format - The GPU texture format - * @return {GPURenderPipeline} The GPU render pipeline. - */ - getFlipYPipeline( format ) { - - let pipeline = this.flipYPipelines[ format ]; - - if ( pipeline === undefined ) { - - pipeline = this.device.createRenderPipeline( { - label: `flipY-${ format }`, - vertex: { - module: this.mipmapVertexShaderModule, - entryPoint: 'main' - }, - fragment: { - module: this.flipYFragmentShaderModule, - entryPoint: 'main', - targets: [ { format } ] - }, - primitive: { - topology: GPUPrimitiveTopology.TriangleStrip, - stripIndexFormat: GPUIndexFormat.Uint32 - }, - layout: 'auto' - } ); - - this.flipYPipelines[ format ] = pipeline; - - } - - return pipeline; - - } - /** * Flip the contents of the given GPU texture along its vertical axis. * @@ -71698,32 +71811,18 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { const format = textureGPUDescriptor.format; const { width, height } = textureGPUDescriptor.size; - const transferPipeline = this.getTransferPipeline( format ); - const flipYPipeline = this.getFlipYPipeline( format ); - const tempTexture = this.device.createTexture( { - size: { width, height, depthOrArrayLayers: 1 }, + size: { width, height }, format, usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING } ); - const srcView = textureGPU.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); - - const dstView = tempTexture.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer: 0 - } ); + const copyTransferPipeline = this.getTransferPipeline( format, textureGPU.textureBindingViewDimension ); + const flipTransferPipeline = this.getTransferPipeline( format, tempTexture.textureBindingViewDimension ); const commandEncoder = this.device.createCommandEncoder( {} ); - const pass = ( pipeline, sourceView, destinationView ) => { + const pass = ( pipeline, sourceTexture, sourceArrayLayer, destinationTexture, destinationArrayLayer, flipY ) => { const bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static. @@ -71734,28 +71833,40 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { resource: this.flipYSampler }, { binding: 1, - resource: sourceView + resource: sourceTexture.createView( { + dimension: sourceTexture.textureBindingViewDimension || '2d-array', + baseMipLevel: 0, + mipLevelCount: 1, + } ), + }, { + binding: 2, + resource: { buffer: flipY ? this.flipUniformBuffer : this.noFlipUniformBuffer } } ] } ); const passEncoder = commandEncoder.beginRenderPass( { colorAttachments: [ { - view: destinationView, + view: destinationTexture.createView( { + dimension: '2d', + baseMipLevel: 0, + mipLevelCount: 1, + baseArrayLayer: destinationArrayLayer, + arrayLayerCount: 1, + } ), loadOp: GPULoadOp.Clear, storeOp: GPUStoreOp.Store, - clearValue: [ 0, 0, 0, 0 ] } ] } ); passEncoder.setPipeline( pipeline ); passEncoder.setBindGroup( 0, bindGroup ); - passEncoder.draw( 4, 1, 0, 0 ); + passEncoder.draw( 3, 1, 0, sourceArrayLayer ); passEncoder.end(); }; - pass( transferPipeline, srcView, dstView ); - pass( flipYPipeline, dstView, srcView ); + pass( copyTransferPipeline, textureGPU, baseArrayLayer, tempTexture, 0, false ); + pass( flipTransferPipeline, tempTexture, 0, textureGPU, baseArrayLayer, true ); this.device.queue.submit( [ commandEncoder.finish() ] ); @@ -71767,21 +71878,13 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { * Generates mipmaps for the given GPU texture. * * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureGPUDescriptor - The texture descriptor. - * @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. * @param {?GPUCommandEncoder} [encoder=null] - An optional command encoder used to generate mipmaps. */ - generateMipmaps( textureGPU, textureGPUDescriptor, baseArrayLayer = 0, encoder = null ) { + generateMipmaps( textureGPU, encoder = null ) { const textureData = this.get( textureGPU ); - if ( textureData.layers === undefined ) { - - textureData.layers = []; - - } - - const passes = textureData.layers[ baseArrayLayer ] || this._mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ); + const passes = textureData.layers || this._mipmapCreateBundles( textureGPU ); const commandEncoder = encoder || this.device.createCommandEncoder( { label: 'mipmapEncoder' } ); @@ -71789,7 +71892,7 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { if ( encoder === null ) this.device.queue.submit( [ commandEncoder.finish() ] ); - textureData.layers[ baseArrayLayer ] = passes; + textureData.layers = passes; } @@ -71798,68 +71901,67 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { * are managed as render bundles to improve performance. * * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureGPUDescriptor - The texture descriptor. - * @param {number} baseArrayLayer - The index of the first array layer accessible to the texture view. * @return {Array} An array of render bundles. */ - _mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ) { + _mipmapCreateBundles( textureGPU ) { - const pipeline = this.getTransferPipeline( textureGPUDescriptor.format ); + const textureBindingViewDimension = textureGPU.textureBindingViewDimension || '2d-array'; + const pipeline = this.getTransferPipeline( textureGPU.format, textureBindingViewDimension ); const bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static. - let srcView = textureGPU.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); - const passes = []; - for ( let i = 1; i < textureGPUDescriptor.mipLevelCount; i ++ ) { - - const bindGroup = this.device.createBindGroup( { - layout: bindGroupLayout, - entries: [ { - binding: 0, - resource: this.mipmapSampler - }, { - binding: 1, - resource: srcView - } ] - } ); - - const dstView = textureGPU.createView( { - baseMipLevel: i, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); + for ( let baseMipLevel = 1; baseMipLevel < textureGPU.mipLevelCount; baseMipLevel ++ ) { + + for ( let baseArrayLayer = 0; baseArrayLayer < textureGPU.depthOrArrayLayers; baseArrayLayer ++ ) { + + const bindGroup = this.device.createBindGroup( { + layout: bindGroupLayout, + entries: [ { + binding: 0, + resource: this.mipmapSampler + }, { + binding: 1, + resource: textureGPU.createView( { + dimension: textureBindingViewDimension, + baseMipLevel: baseMipLevel - 1, + mipLevelCount: 1, + } ), + }, { + binding: 2, + resource: { buffer: this.noFlipUniformBuffer } + } ] + } ); - const passDescriptor = { - colorAttachments: [ { - view: dstView, - loadOp: GPULoadOp.Clear, - storeOp: GPUStoreOp.Store, - clearValue: [ 0, 0, 0, 0 ] - } ] - }; + const passDescriptor = { + colorAttachments: [ { + view: textureGPU.createView( { + dimension: '2d', + baseMipLevel, + mipLevelCount: 1, + baseArrayLayer, + arrayLayerCount: 1, + } ), + loadOp: GPULoadOp.Clear, + storeOp: GPUStoreOp.Store, + } ] + }; - const passEncoder = this.device.createRenderBundleEncoder( { - colorFormats: [ textureGPUDescriptor.format ] - } ); + const passEncoder = this.device.createRenderBundleEncoder( { + colorFormats: [ textureGPU.format ] + } ); - passEncoder.setPipeline( pipeline ); - passEncoder.setBindGroup( 0, bindGroup ); - passEncoder.draw( 4, 1, 0, 0 ); + passEncoder.setPipeline( pipeline ); + passEncoder.setBindGroup( 0, bindGroup ); + passEncoder.draw( 3, 1, 0, baseArrayLayer ); - passes.push( { - renderBundles: [ passEncoder.finish() ], - passDescriptor - } ); + passes.push( { + renderBundles: [ passEncoder.finish() ], + passDescriptor + } ); - srcView = dstView; + } } @@ -72242,25 +72344,7 @@ class WebGPUTextureUtils { const textureData = this.backend.get( texture ); - if ( texture.isCubeTexture ) { - - for ( let i = 0; i < 6; i ++ ) { - - this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i, encoder ); - - } - - } else { - - const depth = texture.image.depth || 1; - - for ( let i = 0; i < depth; i ++ ) { - - this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i, encoder ); - - } - - } + this._generateMipmaps( textureData.texture, encoder ); } @@ -78701,6 +78785,12 @@ class WebGPUBackend extends Backend { this.compatibilityMode = ! device.features.has( 'core-features-and-limits' ); + if ( this.compatibilityMode ) { + + renderer._samples = 0; + + } + device.lost.then( ( info ) => { if ( info.reason === 'destroyed' ) return; @@ -82408,4 +82498,4 @@ class ClippingGroup extends Group { } -export { ACESFilmicToneMapping, AONode, AddEquation, AddOperation, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightNode, AnalyticLightNode, ArrayCamera, ArrayElementNode, ArrayNode, AssignNode, AtomicFunctionNode, AttributeNode, BackSide, BarrierNode, BasicEnvironmentNode, BasicLightMapNode, BasicShadowMap, BatchNode, BitcastNode, BitcountNode, BlendMode, BoxGeometry, BufferAttribute, BufferAttributeNode, BufferGeometry, BufferNode, BuiltinNode, BumpMapNode, BundleGroup, BypassNode, ByteType, CanvasTarget, CineonToneMapping, ClampToEdgeWrapping, ClippingGroup, ClippingNode, CodeNode, Color, ColorManagement, ColorSpaceNode, Compatibility, ComputeBuiltinNode, ComputeNode, ConditionalNode, ConstNode, ContextNode, ConvertNode, CubeCamera, CubeDepthTexture, CubeMapNode, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureNode, CubeUVReflectionMapping, CullFaceBack, CullFaceFront, CullFaceNone, CustomBlending, CylinderGeometry, DataArrayTexture, DataTexture, DebugNode, DecrementStencilOp, DecrementWrapStencilOp, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightNode, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicDrawUsage, EnvironmentNode, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, EventNode, ExpressionNode, FileLoader, FlipNode, Float16BufferAttribute, Float32BufferAttribute, FloatType, FramebufferTexture, FrontFacingNode, FrontSide, Frustum, FrustumArray, FunctionCallNode, FunctionNode, FunctionOverloadingNode, GLSLNodeParser, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, Group, HalfFloatType, HemisphereLight, HemisphereLightNode, IESSpotLight, IESSpotLightNode, IncrementStencilOp, IncrementWrapStencilOp, IndexNode, IndirectStorageBufferAttribute, InputNode, InspectorBase, InspectorNode, InstanceNode, InstancedBufferAttribute, InstancedInterleavedBuffer, InstancedMeshNode, IntType, InterleavedBuffer, InterleavedBufferAttribute, InvertStencilOp, IrradianceNode, IsolateNode, JoinNode, KeepStencilOp, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, LightProbe, LightProbeNode, Lighting, LightingContextNode, LightingModel, LightingNode, LightsNode, Line2NodeMaterial, LineBasicMaterial, LineBasicNodeMaterial, LineDashedMaterial, LineDashedNodeMaterial, LinearFilter, LinearMipMapLinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoopNode, MRTNode, Material, MaterialBlending, MaterialLoader, MaterialNode, MaterialReferenceNode, MathNode, MathUtils, Matrix2, Matrix3, Matrix4, MaxEquation, MaxMipLevelNode, MemberNode, Mesh, MeshBasicMaterial, MeshBasicNodeMaterial, MeshLambertMaterial, MeshLambertNodeMaterial, MeshMatcapMaterial, MeshMatcapNodeMaterial, MeshNormalMaterial, MeshNormalNodeMaterial, MeshPhongMaterial, MeshPhongNodeMaterial, MeshPhysicalMaterial, MeshPhysicalNodeMaterial, MeshSSSNodeMaterial, MeshStandardMaterial, MeshStandardNodeMaterial, MeshToonMaterial, MeshToonNodeMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, ModelNode, MorphNode, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoNormalPacking, NoToneMapping, Node, NodeAccess, NodeAttribute, NodeBuilder, NodeCache, NodeCode, NodeFrame, NodeFunctionInput, NodeLoader, NodeMaterial, NodeMaterialLoader, NodeMaterialObserver, NodeObjectLoader, NodeShaderStage, NodeType, NodeUniform, NodeUpdateType, NodeUtils, NodeVar, NodeVarying, NormalBlending, NormalGAPacking, NormalMapNode, NormalRGPacking, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, Object3D, Object3DNode, ObjectLoader, ObjectSpaceNormalMap, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OperatorNode, OrthographicCamera, OutputStructNode, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, PMREMNode, PackFloatNode, ParameterNode, PassNode, PerspectiveCamera, PhongLightingModel, PhysicalLightingModel, Plane, PlaneGeometry, PointLight, PointLightNode, PointShadowNode, PointUVNode, PointsMaterial, PointsNodeMaterial, PostProcessing, PosterizeNode, ProjectorLight, ProjectorLightNode, PropertyNode, QuadMesh, Quaternion, R11_EAC_Format, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RG11_EAC_Format, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGBIntegerFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RTTNode, RangeNode, RectAreaLight, RectAreaLightNode, RedFormat, RedIntegerFormat, ReferenceBaseNode, ReferenceNode, ReflectorNode, ReinhardToneMapping, RemapNode, RenderOutputNode, RenderPipeline, RenderTarget, RendererReferenceNode, RendererUtils, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RotateNode, SIGNED_R11_EAC_Format, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SIGNED_RG11_EAC_Format, SRGBColorSpace, SRGBTransfer, SampleNode, Scene, ScreenNode, ScriptableNode, ScriptableValueNode, SetNode, ShadowBaseNode, ShadowMaterial, ShadowNode, ShadowNodeMaterial, ShortType, SkinningNode, Sphere, SphereGeometry, SplitNode, SpotLight, SpotLightNode, SpriteMaterial, SpriteNodeMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StackNode, StaticDrawUsage, Storage3DTexture, StorageArrayElementNode, StorageArrayTexture, StorageBufferAttribute, StorageBufferNode, StorageInstancedBufferAttribute, StorageTexture, StorageTextureNode, StructNode, StructTypeNode, SubBuildNode, SubgroupFunctionNode, SubtractEquation, SubtractiveBlending, TSL, TangentSpaceNormalMap, TempNode, Texture, Texture3DNode, TextureNode, TextureSizeNode, TimestampQuery, ToneMappingNode, ToonOutlinePassNode, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, UniformArrayNode, UniformGroupNode, UniformNode, UnpackFloatNode, UnsignedByteType, UnsignedInt101111Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, UserDataNode, VSMShadowMap, VarNode, VaryingNode, Vector2, Vector3, Vector4, VelocityNode, VertexColorNode, ViewportDepthNode, ViewportDepthTextureNode, ViewportSharedTextureNode, ViewportTextureNode, VolumeNodeMaterial, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGPUCoordinateSystem, WebGPURenderer, WebXRController, WorkgroupInfoNode, ZeroFactor, ZeroStencilOp, createCanvasElement, defaultBuildStages, defaultShaderStages, error, log$1 as log, shaderStages, vectorComponents, warn, warnOnce }; +export { ACESFilmicToneMapping, AONode, AddEquation, AddOperation, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightNode, AnalyticLightNode, ArrayCamera, ArrayElementNode, ArrayNode, AssignNode, AtomicFunctionNode, AttributeNode, BackSide, BarrierNode, BasicEnvironmentNode, BasicLightMapNode, BasicShadowMap, BatchNode, BitcastNode, BitcountNode, BlendMode, BoxGeometry, BufferAttribute, BufferAttributeNode, BufferGeometry, BufferNode, BuiltinNode, BumpMapNode, BundleGroup, BypassNode, ByteType, CanvasTarget, CineonToneMapping, ClampToEdgeWrapping, ClippingGroup, ClippingNode, CodeNode, Color, ColorManagement, ColorSpaceNode, Compatibility, ComputeBuiltinNode, ComputeNode, ConditionalNode, ConstNode, ContextNode, ConvertNode, CubeCamera, CubeDepthTexture, CubeMapNode, CubeReflectionMapping, CubeRefractionMapping, CubeRenderTarget, CubeTexture, CubeTextureNode, CubeUVReflectionMapping, CullFaceBack, CullFaceFront, CullFaceNone, CustomBlending, CylinderGeometry, DataArrayTexture, DataTexture, DebugNode, DecrementStencilOp, DecrementWrapStencilOp, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightNode, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicDrawUsage, EnvironmentNode, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, EventNode, ExpressionNode, FileLoader, FlipNode, Float16BufferAttribute, Float32BufferAttribute, FloatType, FramebufferTexture, FrontFacingNode, FrontSide, Frustum, FrustumArray, FunctionCallNode, FunctionNode, FunctionOverloadingNode, GLSLNodeParser, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, Group, HalfFloatType, HemisphereLight, HemisphereLightNode, IESSpotLight, IESSpotLightNode, IncrementStencilOp, IncrementWrapStencilOp, IndexNode, IndirectStorageBufferAttribute, InputNode, InspectorBase, InspectorNode, InstanceNode, InstancedBufferAttribute, InstancedInterleavedBuffer, InstancedMeshNode, IntType, InterleavedBuffer, InterleavedBufferAttribute, InvertStencilOp, IrradianceNode, IsolateNode, JoinNode, KeepStencilOp, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, LightProbe, LightProbeNode, Lighting, LightingContextNode, LightingModel, LightingNode, LightsNode, Line2NodeMaterial, LineBasicMaterial, LineBasicNodeMaterial, LineDashedMaterial, LineDashedNodeMaterial, LinearFilter, LinearMipMapLinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoopNode, MRTNode, Material, MaterialBlending, MaterialLoader, MaterialNode, MaterialReferenceNode, MathNode, MathUtils, Matrix2, Matrix3, Matrix4, MaxEquation, MaxMipLevelNode, MemberNode, Mesh, MeshBasicMaterial, MeshBasicNodeMaterial, MeshLambertMaterial, MeshLambertNodeMaterial, MeshMatcapMaterial, MeshMatcapNodeMaterial, MeshNormalMaterial, MeshNormalNodeMaterial, MeshPhongMaterial, MeshPhongNodeMaterial, MeshPhysicalMaterial, MeshPhysicalNodeMaterial, MeshSSSNodeMaterial, MeshStandardMaterial, MeshStandardNodeMaterial, MeshToonMaterial, MeshToonNodeMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, ModelNode, MorphNode, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoNormalPacking, NoToneMapping, Node, NodeAccess, NodeAttribute, NodeBuilder, NodeCache, NodeCode, NodeFrame, NodeFunctionInput, NodeLoader, NodeMaterial, NodeMaterialLoader, NodeMaterialObserver, NodeObjectLoader, NodeShaderStage, NodeType, NodeUniform, NodeUpdateType, NodeUtils, NodeVar, NodeVarying, NormalBlending, NormalGAPacking, NormalMapNode, NormalRGPacking, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, Object3D, Object3DNode, ObjectLoader, ObjectSpaceNormalMap, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OperatorNode, OrthographicCamera, OutputStructNode, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, PMREMNode, PackFloatNode, ParameterNode, PassNode, PerspectiveCamera, PhongLightingModel, PhysicalLightingModel, Plane, PlaneGeometry, PointLight, PointLightNode, PointShadowNode, PointUVNode, PointsMaterial, PointsNodeMaterial, PostProcessing, PosterizeNode, ProjectorLight, ProjectorLightNode, PropertyNode, QuadMesh, Quaternion, R11_EAC_Format, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RG11_EAC_Format, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGBIntegerFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RTTNode, RangeNode, RectAreaLight, RectAreaLightNode, RedFormat, RedIntegerFormat, ReferenceBaseNode, ReferenceNode, ReflectorNode, ReinhardToneMapping, RemapNode, RenderOutputNode, RenderPipeline, RenderTarget, RendererReferenceNode, RendererUtils, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RotateNode, SIGNED_R11_EAC_Format, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SIGNED_RG11_EAC_Format, SRGBColorSpace, SRGBTransfer, SampleNode, Scene, ScreenNode, ScriptableNode, ScriptableValueNode, SetNode, ShadowBaseNode, ShadowMaterial, ShadowNode, ShadowNodeMaterial, ShortType, SkinningNode, Sphere, SphereGeometry, SplitNode, SpotLight, SpotLightNode, SpriteMaterial, SpriteNodeMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StackNode, StaticDrawUsage, Storage3DTexture, StorageArrayElementNode, StorageArrayTexture, StorageBufferAttribute, StorageBufferNode, StorageInstancedBufferAttribute, StorageTexture, StorageTextureNode, StructNode, StructTypeNode, SubBuildNode, SubgroupFunctionNode, SubtractEquation, SubtractiveBlending, TSL, TangentSpaceNormalMap, TempNode, Texture, Texture3DNode, TextureNode, TextureSizeNode, TimestampQuery, ToneMappingNode, ToonOutlinePassNode, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, UniformArrayNode, UniformGroupNode, UniformNode, UnpackFloatNode, UnsignedByteType, UnsignedInt101111Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, UserDataNode, VSMShadowMap, VarNode, VaryingNode, Vector2, Vector3, Vector4, VelocityNode, VertexColorNode, ViewportDepthNode, ViewportDepthTextureNode, ViewportSharedTextureNode, ViewportTextureNode, VolumeNodeMaterial, WebGLCoordinateSystem, WebGPUCoordinateSystem, WebGPURenderer, WebXRController, WorkgroupInfoNode, ZeroFactor, ZeroStencilOp, createCanvasElement, defaultBuildStages, defaultShaderStages, error, log$1 as log, shaderStages, vectorComponents, warn, warnOnce }; diff --git a/build/three.webgpu.min.js b/build/three.webgpu.min.js index ffebce4b55e2ab..0cb6d6e8c71b5f 100644 --- a/build/three.webgpu.min.js +++ b/build/three.webgpu.min.js @@ -3,4 +3,4 @@ * Copyright 2010-2026 Three.js Authors * SPDX-License-Identifier: MIT */ -import{Color as e,Vector2 as t,Vector3 as r,Vector4 as s,Matrix2 as i,Matrix3 as n,Matrix4 as a,error as o,EventDispatcher as u,MathUtils as l,warn as d,WebGLCoordinateSystem as c,WebGPUCoordinateSystem as h,ColorManagement as p,SRGBTransfer as g,NoToneMapping as m,StaticDrawUsage as f,InterleavedBufferAttribute as y,InterleavedBuffer as b,DynamicDrawUsage as x,NoColorSpace as T,log as _,warnOnce as v,Texture as N,UnsignedIntType as S,IntType as R,Compatibility as E,LessCompare as A,NearestFilter as w,Sphere as C,BackSide as M,DoubleSide as F,Euler as L,CubeTexture as P,CubeReflectionMapping as B,CubeRefractionMapping as D,TangentSpaceNormalMap as U,NoNormalPacking as I,NormalRGPacking as O,NormalGAPacking as V,ObjectSpaceNormalMap as k,RGFormat as G,RED_GREEN_RGTC2_Format as z,RG11_EAC_Format as $,InstancedBufferAttribute as W,InstancedInterleavedBuffer as H,DataArrayTexture as q,FloatType as j,FramebufferTexture as X,LinearMipmapLinearFilter as K,DepthTexture as Y,Material as Q,LineBasicMaterial as Z,LineDashedMaterial as J,NoBlending as ee,MeshNormalMaterial as te,SRGBColorSpace as re,WebGLCubeRenderTarget as se,BoxGeometry as ie,Mesh as ne,Scene as ae,LinearFilter as oe,CubeCamera as ue,EquirectangularReflectionMapping as le,EquirectangularRefractionMapping as de,AddOperation as ce,MixOperation as he,MultiplyOperation as pe,MeshBasicMaterial as ge,MeshLambertMaterial as me,MeshPhongMaterial as fe,DataTexture as ye,HalfFloatType as be,ClampToEdgeWrapping as xe,BufferGeometry as Te,OrthographicCamera as _e,PerspectiveCamera as ve,RenderTarget as Ne,LinearSRGBColorSpace as Se,RGBAFormat as Re,CubeUVReflectionMapping as Ee,BufferAttribute as Ae,MeshStandardMaterial as we,MeshPhysicalMaterial as Ce,MeshToonMaterial as Me,MeshMatcapMaterial as Fe,SpriteMaterial as Le,PointsMaterial as Pe,ShadowMaterial as Be,Uint32BufferAttribute as De,Uint16BufferAttribute as Ue,arrayNeedsUint32 as Ie,DepthStencilFormat as Oe,DepthFormat as Ve,UnsignedInt248Type as ke,UnsignedByteType as Ge,NormalBlending as ze,SrcAlphaFactor as $e,OneMinusSrcAlphaFactor as We,AddEquation as He,MaterialBlending as qe,Plane as je,Object3D as Xe,LinearMipMapLinearFilter as Ke,Float32BufferAttribute as Ye,UVMapping as Qe,VSMShadowMap as Ze,LessEqualCompare as Je,PCFShadowMap as et,PCFSoftShadowMap as tt,BasicShadowMap as rt,CubeDepthTexture as st,SphereGeometry as it,LinearMipmapNearestFilter as nt,NearestMipmapLinearFilter as at,Float16BufferAttribute as ot,REVISION as ut,ArrayCamera as lt,PlaneGeometry as dt,FrontSide as ct,CustomBlending as ht,ZeroFactor as pt,CylinderGeometry as gt,Quaternion as mt,WebXRController as ft,RAD2DEG as yt,FrustumArray as bt,Frustum as xt,RedIntegerFormat as Tt,RedFormat as _t,ShortType as vt,ByteType as Nt,UnsignedShortType as St,RGIntegerFormat as Rt,RGBIntegerFormat as Et,RGBFormat as At,RGBAIntegerFormat as wt,TimestampQuery as Ct,createCanvasElement as Mt,ReverseSubtractEquation as Ft,SubtractEquation as Lt,OneMinusDstAlphaFactor as Pt,OneMinusDstColorFactor as Bt,OneMinusSrcColorFactor as Dt,DstAlphaFactor as Ut,DstColorFactor as It,SrcAlphaSaturateFactor as Ot,SrcColorFactor as Vt,OneFactor as kt,CullFaceNone as Gt,CullFaceBack as zt,CullFaceFront as $t,MultiplyBlending as Wt,SubtractiveBlending as Ht,AdditiveBlending as qt,NotEqualDepth as jt,GreaterDepth as Xt,GreaterEqualDepth as Kt,EqualDepth as Yt,LessEqualDepth as Qt,LessDepth as Zt,AlwaysDepth as Jt,NeverDepth as er,UnsignedShort4444Type as tr,UnsignedShort5551Type as rr,UnsignedInt5999Type as sr,UnsignedInt101111Type as ir,AlphaFormat as nr,RGB_S3TC_DXT1_Format as ar,RGBA_S3TC_DXT1_Format as or,RGBA_S3TC_DXT3_Format as ur,RGBA_S3TC_DXT5_Format as lr,RGB_PVRTC_4BPPV1_Format as dr,RGB_PVRTC_2BPPV1_Format as cr,RGBA_PVRTC_4BPPV1_Format as hr,RGBA_PVRTC_2BPPV1_Format as pr,RGB_ETC1_Format as gr,RGB_ETC2_Format as mr,RGBA_ETC2_EAC_Format as fr,R11_EAC_Format as yr,SIGNED_R11_EAC_Format as br,SIGNED_RG11_EAC_Format as xr,RGBA_ASTC_4x4_Format as Tr,RGBA_ASTC_5x4_Format as _r,RGBA_ASTC_5x5_Format as vr,RGBA_ASTC_6x5_Format as Nr,RGBA_ASTC_6x6_Format as Sr,RGBA_ASTC_8x5_Format as Rr,RGBA_ASTC_8x6_Format as Er,RGBA_ASTC_8x8_Format as Ar,RGBA_ASTC_10x5_Format as wr,RGBA_ASTC_10x6_Format as Cr,RGBA_ASTC_10x8_Format as Mr,RGBA_ASTC_10x10_Format as Fr,RGBA_ASTC_12x10_Format as Lr,RGBA_ASTC_12x12_Format as Pr,RGBA_BPTC_Format as Br,RED_RGTC1_Format as Dr,SIGNED_RED_RGTC1_Format as Ur,SIGNED_RED_GREEN_RGTC2_Format as Ir,MirroredRepeatWrapping as Or,RepeatWrapping as Vr,NearestMipmapNearestFilter as kr,NotEqualCompare as Gr,GreaterCompare as zr,GreaterEqualCompare as $r,EqualCompare as Wr,AlwaysCompare as Hr,NeverCompare as qr,LinearTransfer as jr,getByteLength as Xr,isTypedArray as Kr,NotEqualStencilFunc as Yr,GreaterStencilFunc as Qr,GreaterEqualStencilFunc as Zr,EqualStencilFunc as Jr,LessEqualStencilFunc as es,LessStencilFunc as ts,AlwaysStencilFunc as rs,NeverStencilFunc as ss,DecrementWrapStencilOp as is,IncrementWrapStencilOp as ns,DecrementStencilOp as as,IncrementStencilOp as os,InvertStencilOp as us,ReplaceStencilOp as ls,ZeroStencilOp as ds,KeepStencilOp as cs,MaxEquation as hs,MinEquation as ps,SpotLight as gs,PointLight as ms,DirectionalLight as fs,RectAreaLight as ys,AmbientLight as bs,HemisphereLight as xs,LightProbe as Ts,LinearToneMapping as _s,ReinhardToneMapping as vs,CineonToneMapping as Ns,ACESFilmicToneMapping as Ss,AgXToneMapping as Rs,NeutralToneMapping as Es,Group as As,Loader as ws,FileLoader as Cs,MaterialLoader as Ms,ObjectLoader as Fs}from"./three.core.min.js";export{AdditiveAnimationBlendMode,AnimationAction,AnimationClip,AnimationLoader,AnimationMixer,AnimationObjectGroup,AnimationUtils,ArcCurve,ArrowHelper,AttachedBindMode,Audio,AudioAnalyser,AudioContext,AudioListener,AudioLoader,AxesHelper,BasicDepthPacking,BatchedMesh,BezierInterpolant,Bone,BooleanKeyframeTrack,Box2,Box3,Box3Helper,BoxHelper,BufferGeometryLoader,Cache,Camera,CameraHelper,CanvasTexture,CapsuleGeometry,CatmullRomCurve3,CircleGeometry,Clock,ColorKeyframeTrack,CompressedArrayTexture,CompressedCubeTexture,CompressedTexture,CompressedTextureLoader,ConeGeometry,ConstantAlphaFactor,ConstantColorFactor,Controls,CubeTextureLoader,CubicBezierCurve,CubicBezierCurve3,CubicInterpolant,CullFaceFrontBack,Curve,CurvePath,CustomToneMapping,Cylindrical,Data3DTexture,DataTextureLoader,DataUtils,DefaultLoadingManager,DetachedBindMode,DirectionalLightHelper,DiscreteInterpolant,DodecahedronGeometry,DynamicCopyUsage,DynamicReadUsage,EdgesGeometry,EllipseCurve,ExternalTexture,ExtrudeGeometry,Fog,FogExp2,GLBufferAttribute,GLSL1,GLSL3,GridHelper,HemisphereLightHelper,IcosahedronGeometry,ImageBitmapLoader,ImageLoader,ImageUtils,InstancedBufferGeometry,InstancedMesh,Int16BufferAttribute,Int32BufferAttribute,Int8BufferAttribute,Interpolant,InterpolateBezier,InterpolateDiscrete,InterpolateLinear,InterpolateSmooth,InterpolationSamplingMode,InterpolationSamplingType,KeyframeTrack,LOD,LatheGeometry,Layers,Light,Line,Line3,LineCurve,LineCurve3,LineLoop,LineSegments,LinearInterpolant,LinearMipMapNearestFilter,LoaderUtils,LoadingManager,LoopOnce,LoopPingPong,LoopRepeat,MOUSE,MeshDepthMaterial,MeshDistanceMaterial,NearestMipMapLinearFilter,NearestMipMapNearestFilter,NormalAnimationBlendMode,NumberKeyframeTrack,OctahedronGeometry,OneMinusConstantAlphaFactor,OneMinusConstantColorFactor,Path,PlaneHelper,PointLightHelper,Points,PolarGridHelper,PolyhedronGeometry,PositionalAudio,PropertyBinding,PropertyMixer,QuadraticBezierCurve,QuadraticBezierCurve3,QuaternionKeyframeTrack,QuaternionLinearInterpolant,RGBADepthPacking,RGBDepthPacking,RGB_BPTC_SIGNED_Format,RGB_BPTC_UNSIGNED_Format,RGDepthPacking,RawShaderMaterial,Ray,Raycaster,RenderTarget3D,RingGeometry,ShaderMaterial,Shape,ShapeGeometry,ShapePath,ShapeUtils,Skeleton,SkeletonHelper,SkinnedMesh,Source,Spherical,SphericalHarmonics3,SplineCurve,SpotLightHelper,Sprite,StaticCopyUsage,StaticReadUsage,StereoCamera,StreamCopyUsage,StreamDrawUsage,StreamReadUsage,StringKeyframeTrack,TOUCH,TetrahedronGeometry,TextureLoader,TextureUtils,Timer,TorusGeometry,TorusKnotGeometry,Triangle,TriangleFanDrawMode,TriangleStripDrawMode,TrianglesDrawMode,TubeGeometry,Uint8BufferAttribute,Uint8ClampedBufferAttribute,Uniform,UniformsGroup,VectorKeyframeTrack,VideoFrameTexture,VideoTexture,WebGL3DRenderTarget,WebGLArrayRenderTarget,WebGLRenderTarget,WireframeGeometry,WrapAroundEnding,ZeroCurvatureEnding,ZeroSlopeEnding,getConsoleFunction,setConsoleFunction}from"./three.core.min.js";const Ls=["alphaMap","alphaTest","anisotropy","anisotropyMap","anisotropyRotation","aoMap","aoMapIntensity","attenuationColor","attenuationDistance","bumpMap","clearcoat","clearcoatMap","clearcoatNormalMap","clearcoatNormalScale","clearcoatRoughness","color","dispersion","displacementMap","emissive","emissiveIntensity","emissiveMap","envMap","envMapIntensity","gradientMap","ior","iridescence","iridescenceIOR","iridescenceMap","iridescenceThicknessMap","lightMap","lightMapIntensity","map","matcap","metalness","metalnessMap","normalMap","normalScale","opacity","roughness","roughnessMap","sheen","sheenColor","sheenColorMap","sheenRoughnessMap","shininess","specular","specularColor","specularColorMap","specularIntensity","specularIntensityMap","specularMap","thickness","transmission","transmissionMap"],Ps=new WeakMap;class Bs{constructor(e){this.renderObjects=new WeakMap,this.hasNode=this.containsNode(e),this.hasAnimation=!0===e.object.isSkinnedMesh,this.refreshUniforms=Ls,this.renderId=0}firstInitialization(e){return!1===this.renderObjects.has(e)&&(this.getRenderObjectData(e),!0)}needsVelocity(e){const t=e.getMRT();return null!==t&&t.has("velocity")}getRenderObjectData(e){let t=this.renderObjects.get(e);if(void 0===t){const{geometry:r,material:s,object:i}=e;if(t={material:this.getMaterialData(s),geometry:{id:r.id,attributes:this.getAttributesData(r.attributes),indexVersion:r.index?r.index.version:null,drawRange:{start:r.drawRange.start,count:r.drawRange.count}},worldMatrix:i.matrixWorld.clone()},i.center&&(t.center=i.center.clone()),i.morphTargetInfluences&&(t.morphTargetInfluences=i.morphTargetInfluences.slice()),null!==e.bundle&&(t.version=e.bundle.version),t.material.transmission>0){const{width:r,height:s}=e.context;t.bufferWidth=r,t.bufferHeight=s}t.lights=this.getLightsData(e.lightsNode.getLights()),this.renderObjects.set(e,t)}return t}getAttributesData(e){const t={};for(const r in e){const s=e[r];t[r]={version:s.version}}return t}containsNode(e){const t=e.material;for(const e in t)if(t[e]&&t[e].isNode)return!0;return!!(e.context.modelViewMatrix||e.context.modelNormalViewMatrix||e.context.getAO||e.context.getShadow)}getMaterialData(e){const t={};for(const r of this.refreshUniforms){const s=e[r];null!=s&&("object"==typeof s&&void 0!==s.clone?!0===s.isTexture?t[r]={id:s.id,version:s.version}:t[r]=s.clone():t[r]=s)}return t}equals(e,t){const{object:r,material:s,geometry:i}=e,n=this.getRenderObjectData(e);if(!0!==n.worldMatrix.equals(r.matrixWorld))return n.worldMatrix.copy(r.matrixWorld),!1;const a=n.material;for(const e in a){const t=a[e],r=s[e];if(void 0!==t.equals){if(!1===t.equals(r))return t.copy(r),!1}else if(!0===r.isTexture){if(t.id!==r.id||t.version!==r.version)return t.id=r.id,t.version=r.version,!1}else if(t!==r)return a[e]=r,!1}if(a.transmission>0){const{width:t,height:r}=e.context;if(n.bufferWidth!==t||n.bufferHeight!==r)return n.bufferWidth=t,n.bufferHeight=r,!1}const o=n.geometry,u=i.attributes,l=o.attributes,d=Object.keys(l),c=Object.keys(u);if(o.id!==i.id)return o.id=i.id,!1;if(d.length!==c.length)return n.geometry.attributes=this.getAttributesData(u),!1;for(const e of d){const t=l[e],r=u[e];if(void 0===r)return delete l[e],!1;if(t.version!==r.version)return t.version=r.version,!1}const h=i.index,p=o.indexVersion,g=h?h.version:null;if(p!==g)return o.indexVersion=g,!1;if(o.drawRange.start!==i.drawRange.start||o.drawRange.count!==i.drawRange.count)return o.drawRange.start=i.drawRange.start,o.drawRange.count=i.drawRange.count,!1;if(n.morphTargetInfluences){let e=!1;for(let t=0;t>>16,2246822507),r^=Math.imul(s^s>>>13,3266489909),s=Math.imul(s^s>>>16,2246822507),s^=Math.imul(r^r>>>13,3266489909),4294967296*(2097151&s)+(r>>>0)}const Us=e=>Ds(e),Is=e=>Ds(e),Os=(...e)=>Ds(e),Vs=new Map([[1,"float"],[2,"vec2"],[3,"vec3"],[4,"vec4"],[9,"mat3"],[16,"mat4"]]),ks=new WeakMap;function Gs(e){return Vs.get(e)}function zs(e){if(/[iu]?vec\d/.test(e))return e.startsWith("ivec")?Int32Array:e.startsWith("uvec")?Uint32Array:Float32Array;if(/mat\d/.test(e))return Float32Array;if(/float/.test(e))return Float32Array;if(/uint/.test(e))return Uint32Array;if(/int/.test(e))return Int32Array;throw new Error(`THREE.NodeUtils: Unsupported type: ${e}`)}function $s(e){return/float|int|uint/.test(e)?1:/vec2/.test(e)?2:/vec3/.test(e)?3:/vec4/.test(e)||/mat2/.test(e)?4:/mat3/.test(e)?9:/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function Ws(e){return/float|int|uint/.test(e)?1:/vec2/.test(e)?2:/vec3/.test(e)?3:/vec4/.test(e)||/mat2/.test(e)?4:/mat3/.test(e)?12:/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function Hs(e){return/float|int|uint/.test(e)?4:/vec2/.test(e)?8:/vec3/.test(e)||/vec4/.test(e)?16:/mat2/.test(e)?8:/mat3/.test(e)||/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function qs(e){if(null==e)return null;const t=typeof e;return!0===e.isNode?"node":"number"===t?"float":"boolean"===t?"bool":"string"===t?"string":"function"===t?"shader":!0===e.isVector2?"vec2":!0===e.isVector3?"vec3":!0===e.isVector4?"vec4":!0===e.isMatrix2?"mat2":!0===e.isMatrix3?"mat3":!0===e.isMatrix4?"mat4":!0===e.isColor?"color":e instanceof ArrayBuffer?"ArrayBuffer":null}function js(o,...u){const l=o?o.slice(-4):void 0;return 1===u.length&&("vec2"===l?u=[u[0],u[0]]:"vec3"===l?u=[u[0],u[0],u[0]]:"vec4"===l&&(u=[u[0],u[0],u[0],u[0]])),"color"===o?new e(...u):"vec2"===l?new t(...u):"vec3"===l?new r(...u):"vec4"===l?new s(...u):"mat2"===l?new i(...u):"mat3"===l?new n(...u):"mat4"===l?new a(...u):"bool"===o?u[0]||!1:"float"===o||"int"===o||"uint"===o?u[0]||0:"string"===o?u[0]||"":"ArrayBuffer"===o?Ys(u[0]):null}function Xs(e){let t=ks.get(e);return void 0===t&&(t={},ks.set(e,t)),t}function Ks(e){let t="";const r=new Uint8Array(e);for(let e=0;ee.charCodeAt(0)).buffer}var Qs=Object.freeze({__proto__:null,arrayBufferToBase64:Ks,base64ToArrayBuffer:Ys,getAlignmentFromType:Hs,getDataFromObject:Xs,getLengthFromType:$s,getMemoryLengthFromType:Ws,getTypeFromLength:Gs,getTypedArrayFromType:zs,getValueFromType:js,getValueType:qs,hash:Os,hashArray:Is,hashString:Us});const Zs={VERTEX:"vertex",FRAGMENT:"fragment"},Js={NONE:"none",FRAME:"frame",RENDER:"render",OBJECT:"object"},ei={BOOLEAN:"bool",INTEGER:"int",FLOAT:"float",VECTOR2:"vec2",VECTOR3:"vec3",VECTOR4:"vec4",MATRIX2:"mat2",MATRIX3:"mat3",MATRIX4:"mat4"},ti={READ_ONLY:"readOnly",WRITE_ONLY:"writeOnly",READ_WRITE:"readWrite"},ri=["fragment","vertex"],si=["setup","analyze","generate"],ii=[...ri,"compute"],ni=["x","y","z","w"],ai={analyze:"setup",generate:"analyze"};let oi=0;class ui extends u{static get type(){return"Node"}constructor(e=null){super(),this.nodeType=e,this.updateType=Js.NONE,this.updateBeforeType=Js.NONE,this.updateAfterType=Js.NONE,this.uuid=l.generateUUID(),this.version=0,this.name="",this.global=!1,this.parents=!1,this.isNode=!0,this._beforeNodes=null,this._cacheKey=null,this._cacheKeyVersion=0,Object.defineProperty(this,"id",{value:oi++})}set needsUpdate(e){!0===e&&this.version++}get type(){return this.constructor.type}onUpdate(e,t){return this.updateType=t,this.update=e.bind(this),this}onFrameUpdate(e){return this.onUpdate(e,Js.FRAME)}onRenderUpdate(e){return this.onUpdate(e,Js.RENDER)}onObjectUpdate(e){return this.onUpdate(e,Js.OBJECT)}onReference(e){return this.updateReference=e.bind(this),this}updateReference(){return this}isGlobal(){return this.global}*getChildren(){for(const{childNode:e}of this._getChildren())yield e}dispose(){this.dispatchEvent({type:"dispose"})}traverse(e){e(this);for(const t of this.getChildren())t.traverse(e)}_getChildren(e=new Set){const t=[];e.add(this);for(const r of Object.getOwnPropertyNames(this)){const s=this[r];if(!0!==r.startsWith("_")&&!e.has(s))if(!0===Array.isArray(s))for(let e=0;e0&&(e.inputNodes=r)}deserialize(e){if(void 0!==e.inputNodes){const t=e.meta.nodes;for(const r in e.inputNodes)if(Array.isArray(e.inputNodes[r])){const s=[];for(const i of e.inputNodes[r])s.push(t[i]);this[r]=s}else if("object"==typeof e.inputNodes[r]){const s={};for(const i in e.inputNodes[r]){const n=e.inputNodes[r][i];s[i]=t[n]}this[r]=s}else{const s=e.inputNodes[r];this[r]=t[s]}}}toJSON(e){const{uuid:t,type:r}=this,s=void 0===e||"string"==typeof e;s&&(e={textures:{},images:{},nodes:{}});let i=e.nodes[t];function n(e){const t=[];for(const r in e){const s=e[r];delete s.metadata,t.push(s)}return t}if(void 0===i&&(i={uuid:t,type:r,meta:e,metadata:{version:4.7,type:"Node",generator:"Node.toJSON"}},!0!==s&&(e.nodes[i.uuid]=i),this.serialize(i),delete i.meta),s){const t=n(e.textures),r=n(e.images),s=n(e.nodes);t.length>0&&(i.textures=t),r.length>0&&(i.images=r),s.length>0&&(i.nodes=s)}return i}}class li extends ui{static get type(){return"ArrayElementNode"}constructor(e,t){super(),this.node=e,this.indexNode=t,this.isArrayElementNode=!0}getNodeType(e){return this.node.getElementType(e)}getMemberType(e,t){return this.node.getMemberType(e,t)}generate(e){const t=this.indexNode.getNodeType(e);return`${this.node.build(e)}[ ${this.indexNode.build(e,!e.isVector(t)&&e.isInteger(t)?t:"uint")} ]`}}class di extends ui{static get type(){return"ConvertNode"}constructor(e,t){super(),this.node=e,this.convertTo=t}getNodeType(e){const t=this.node.getNodeType(e);let r=null;for(const s of this.convertTo.split("|"))null!==r&&e.getTypeLength(t)!==e.getTypeLength(s)||(r=s);return r}serialize(e){super.serialize(e),e.convertTo=this.convertTo}deserialize(e){super.deserialize(e),this.convertTo=e.convertTo}generate(e,t){const r=this.node,s=this.getNodeType(e),i=r.build(e,s);return e.format(i,s,t)}}class ci extends ui{static get type(){return"TempNode"}constructor(e=null){super(e),this.isTempNode=!0}hasDependencies(e){return e.getDataFromNode(this).usageCount>1}build(e,t){if("generate"===e.getBuildStage()){const r=e.getVectorType(this.getNodeType(e,t)),s=e.getDataFromNode(this);if(void 0!==s.propertyName)return e.format(s.propertyName,r,t);if("void"!==r&&"void"!==t&&this.hasDependencies(e)){const i=super.build(e,r),n=e.getVarFromNode(this,null,r),a=e.getPropertyName(n);return e.addLineFlowCode(`${a} = ${i}`,this),s.snippet=i,s.propertyName=a,e.format(s.propertyName,r,t)}}return super.build(e,t)}}class hi extends ci{static get type(){return"JoinNode"}constructor(e=[],t=null){super(t),this.nodes=e}getNodeType(e){return null!==this.nodeType?e.getVectorType(this.nodeType):e.getTypeFromLength(this.nodes.reduce((t,r)=>t+e.getTypeLength(r.getNodeType(e)),0))}generate(e,t){const r=this.getNodeType(e),s=e.getTypeLength(r),i=this.nodes,n=e.getComponentType(r),a=[];let u=0;for(const t of i){if(u>=s){o(`TSL: Length of parameters exceeds maximum length of function '${r}()' type.`);break}let i,l=t.getNodeType(e),d=e.getTypeLength(l);u+d>s&&(o(`TSL: Length of '${r}()' data exceeds maximum length of output type.`),d=s-u,l=e.getTypeFromLength(d)),u+=d,i=t.build(e,l);if(e.getComponentType(l)!==n){const t=e.getTypeFromLength(d,n);i=e.format(i,l,t)}a.push(i)}const l=`${e.getType(r)}( ${a.join(", ")} )`;return e.format(l,r,t)}}const pi=ni.join("");class gi extends ui{static get type(){return"SplitNode"}constructor(e,t="x"){super(),this.node=e,this.components=t,this.isSplitNode=!0}getVectorLength(){let e=this.components.length;for(const t of this.components)e=Math.max(ni.indexOf(t)+1,e);return e}getComponentType(e){return e.getComponentType(this.node.getNodeType(e))}getNodeType(e){return e.getTypeFromLength(this.components.length,this.getComponentType(e))}getScope(){return this.node.getScope()}generate(e,t){const r=this.node,s=e.getTypeLength(r.getNodeType(e));let i=null;if(s>1){let n=null;this.getVectorLength()>=s&&(n=e.getTypeFromLength(this.getVectorLength(),this.getComponentType(e)));const a=r.build(e,n);i=this.components.length===s&&this.components===pi.slice(0,this.components.length)?e.format(a,n,t):e.format(`${a}.${this.components}`,this.getNodeType(e),t)}else i=r.build(e,t);return i}serialize(e){super.serialize(e),e.components=this.components}deserialize(e){super.deserialize(e),this.components=e.components}}class mi extends ci{static get type(){return"SetNode"}constructor(e,t,r){super(),this.sourceNode=e,this.components=t,this.targetNode=r}getNodeType(e){return this.sourceNode.getNodeType(e)}generate(e){const{sourceNode:t,components:r,targetNode:s}=this,i=this.getNodeType(e),n=e.getComponentType(s.getNodeType(e)),a=e.getTypeFromLength(r.length,n),o=s.build(e,a),u=t.build(e,i),l=e.getTypeLength(i),d=[];for(let e=0;e(e=>e.replace(/r|s/g,"x").replace(/g|t/g,"y").replace(/b|p/g,"z").replace(/a|q/g,"w"))(e).split("").sort().join("");ui.prototype.assign=function(...e){if(!0!==this.isStackNode)return null!==_i?_i.assign(this,...e):o("TSL: No stack defined for assign operation. Make sure the assign is inside a Fn()."),this;{const t=vi.get("assign");return this.addToStack(t(...e))}},ui.prototype.toVarIntent=function(){return this},ui.prototype.get=function(e){return new Ti(this,e)};const Ri={};function Ei(e,t,r){Ri[e]=Ri[t]=Ri[r]={get(){this._cache=this._cache||{};let t=this._cache[e];return void 0===t&&(t=new gi(this,e),this._cache[e]=t),t},set(t){this[e].assign(Zi(t))}};const s=e.toUpperCase(),i=t.toUpperCase(),n=r.toUpperCase();ui.prototype["set"+s]=ui.prototype["set"+i]=ui.prototype["set"+n]=function(t){const r=Si(e);return new mi(this,r,Zi(t))},ui.prototype["flip"+s]=ui.prototype["flip"+i]=ui.prototype["flip"+n]=function(){const t=Si(e);return new fi(this,t)}}const Ai=["x","y","z","w"],wi=["r","g","b","a"],Ci=["s","t","p","q"];for(let e=0;e<4;e++){let t=Ai[e],r=wi[e],s=Ci[e];Ei(t,r,s);for(let i=0;i<4;i++){t=Ai[e]+Ai[i],r=wi[e]+wi[i],s=Ci[e]+Ci[i],Ei(t,r,s);for(let n=0;n<4;n++){t=Ai[e]+Ai[i]+Ai[n],r=wi[e]+wi[i]+wi[n],s=Ci[e]+Ci[i]+Ci[n],Ei(t,r,s);for(let a=0;a<4;a++)t=Ai[e]+Ai[i]+Ai[n]+Ai[a],r=wi[e]+wi[i]+wi[n]+wi[a],s=Ci[e]+Ci[i]+Ci[n]+Ci[a],Ei(t,r,s)}}}for(let e=0;e<32;e++)Ri[e]={get(){this._cache=this._cache||{};let t=this._cache[e];return void 0===t&&(t=new li(this,new xi(e,"uint")),this._cache[e]=t),t},set(t){this[e].assign(Zi(t))}};Object.defineProperties(ui.prototype,Ri);const Mi=new WeakMap,Fi=function(e,t=null){for(const r in e)e[r]=Zi(e[r],t);return e},Li=function(e,t=null){const r=e.length;for(let s=0;su?(o(`TSL: "${r}" parameter length exceeds limit.`),t.slice(0,u)):t}return null===t?n=(...t)=>i(new e(...tn(d(t)))):null!==r?(r=Zi(r),n=(...s)=>i(new e(t,...tn(d(s)),r))):n=(...r)=>i(new e(t,...tn(d(r)))),n.setParameterLength=(...e)=>(1===e.length?a=u=e[0]:2===e.length&&([a,u]=e),n),n.setName=e=>(l=e,n),n},Bi=function(e,...t){return new e(...tn(t))};class Di extends ui{constructor(e,t){super(),this.shaderNode=e,this.rawInputs=t,this.isShaderCallNodeInternal=!0}getNodeType(e){return this.shaderNode.nodeType||this.getOutputNode(e).getNodeType(e)}getElementType(e){return this.getOutputNode(e).getElementType(e)}getMemberType(e,t){return this.getOutputNode(e).getMemberType(e,t)}call(e){const{shaderNode:t,rawInputs:r}=this,s=e.getNodeProperties(t),i=e.getClosestSubBuild(t.subBuilds)||"",n=i||"default";if(s[n])return s[n];const a=e.subBuildFn,o=e.fnCall;e.subBuildFn=i,e.fnCall=this;let u=null;if(t.layout){let s=Mi.get(e.constructor);void 0===s&&(s=new WeakMap,Mi.set(e.constructor,s));let i=s.get(t);void 0===i&&(i=Zi(e.buildFunctionNode(t)),s.set(t,i)),e.addInclude(i);const n=r?function(e){let t;en(e);t=e[0]&&(e[0].isNode||Object.getPrototypeOf(e[0])!==Object.prototype)?[...e]:e[0];return t}(r):null;u=Zi(i.call(n))}else{const s=new Proxy(e,{get:(e,t,r)=>{let s;return s=Symbol.iterator===t?function*(){yield}:Reflect.get(e,t,r),s}}),i=r?function(e){let t=0;return en(e),new Proxy(e,{get:(r,s,i)=>{let n;if("length"===s)return n=e.length,n;if(Symbol.iterator===s)n=function*(){for(const t of e)yield Zi(t)};else{if(e.length>0)if(Object.getPrototypeOf(e[0])===Object.prototype){const r=e[0];n=void 0===r[s]?r[t++]:Reflect.get(r,s,i)}else e[0]instanceof ui&&(n=void 0===e[s]?e[t++]:Reflect.get(e,s,i));else n=Reflect.get(r,s,i);n=Zi(n)}return n}})}(r):null,n=Array.isArray(r)?r.length>0:null!==r,a=t.jsFunc,o=n||a.length>1?a(i,s):a(s);u=Zi(o)}return e.subBuildFn=a,e.fnCall=o,t.once&&(s[n]=u),u}setupOutput(e){return e.addStack(),e.stack.outputNode=this.call(e),e.removeStack()}getOutputNode(e){const t=e.getNodeProperties(this),r=e.getSubBuildOutput(this);return t[r]=t[r]||this.setupOutput(e),t[r].subBuild=e.getClosestSubBuild(this),t[r]}build(e,t=null){let r=null;const s=e.getBuildStage(),i=e.getNodeProperties(this),n=e.getSubBuildOutput(this),a=this.getOutputNode(e),o=e.fnCall;if(e.fnCall=this,"setup"===s){const t=e.getSubBuildProperty("initialized",this);if(!0!==i[t]&&(i[t]=!0,i[n]=this.getOutputNode(e),i[n].build(e),this.shaderNode.subBuilds))for(const t of e.chaining){const r=e.getDataFromNode(t,"any");r.subBuilds=r.subBuilds||new Set;for(const e of this.shaderNode.subBuilds)r.subBuilds.add(e)}r=i[n]}else"analyze"===s?a.build(e,t):"generate"===s&&(r=a.build(e,t)||"");return e.fnCall=o,r}}class Ui extends ui{constructor(e,t){super(t),this.jsFunc=e,this.layout=null,this.global=!0,this.once=!1}setLayout(e){return this.layout=e,this}getLayout(){return this.layout}call(e=null){return new Di(this,e)}setup(){return this.call()}}const Ii=[!1,!0],Oi=[0,1,2,3],Vi=[-1,-2],ki=[.5,1.5,1/3,1e-6,1e6,Math.PI,2*Math.PI,1/Math.PI,2/Math.PI,1/(2*Math.PI),Math.PI/2],Gi=new Map;for(const e of Ii)Gi.set(e,new xi(e));const zi=new Map;for(const e of Oi)zi.set(e,new xi(e,"uint"));const $i=new Map([...zi].map(e=>new xi(e.value,"int")));for(const e of Vi)$i.set(e,new xi(e,"int"));const Wi=new Map([...$i].map(e=>new xi(e.value)));for(const e of ki)Wi.set(e,new xi(e));for(const e of ki)Wi.set(-e,new xi(-e));const Hi={bool:Gi,uint:zi,ints:$i,float:Wi},qi=new Map([...Gi,...Wi]),ji=(e,t)=>qi.has(e)?qi.get(e):!0===e.isNode?e:new xi(e,t),Xi=function(e,t=null){return(...r)=>{for(const t of r)if(void 0===t)return o(`TSL: Invalid parameter for the type "${e}".`),new xi(0,e);if((0===r.length||!["bool","float","int","uint"].includes(e)&&r.every(e=>{const t=typeof e;return"object"!==t&&"function"!==t}))&&(r=[js(e,...r)]),1===r.length&&null!==t&&t.has(r[0]))return Ji(t.get(r[0]));if(1===r.length){const t=ji(r[0],e);return t.nodeType===e?Ji(t):Ji(new di(t,e))}const s=r.map(e=>ji(e));return Ji(new hi(s,e))}},Ki=e=>"object"==typeof e&&null!==e?e.value:e,Yi=e=>null!=e?e.nodeType||e.convertTo||("string"==typeof e?e:null):null;function Qi(e,t){return new Ui(e,t)}const Zi=(e,t=null)=>function(e,t=null){const r=qs(e);return"node"===r?e:null===t&&("float"===r||"boolean"===r)||r&&"shader"!==r&&"string"!==r?Zi(ji(e,t)):"shader"===r?e.isFn?e:un(e):e}(e,t),Ji=(e,t=null)=>Zi(e,t).toVarIntent(),en=(e,t=null)=>new Fi(e,t),tn=(e,t=null)=>new Li(e,t),rn=(e,t=null,r=null,s=null)=>new Pi(e,t,r,s),sn=(e,...t)=>new Bi(e,...t),nn=(e,t=null,r=null,s={})=>new Pi(e,t,r,{...s,intent:!0});let an=0;class on extends ui{constructor(e,t=null){super();let r=null;null!==t&&("object"==typeof t?r=t.return:("string"==typeof t?r=t:o("TSL: Invalid layout type."),t=null)),this.shaderNode=new Qi(e,r),null!==t&&this.setLayout(t),this.isFn=!0}setLayout(e){const t=this.shaderNode.nodeType;if("object"!=typeof e.inputs){const r={name:"fn"+an++,type:t,inputs:[]};for(const t in e)"return"!==t&&r.inputs.push({name:t,type:e[t]});e=r}return this.shaderNode.setLayout(e),this}getNodeType(e){return this.shaderNode.getNodeType(e)||"float"}call(...e){const t=this.shaderNode.call(e);return"void"===this.shaderNode.nodeType&&t.toStack(),t.toVarIntent()}once(e=null){return this.shaderNode.once=!0,this.shaderNode.subBuilds=e,this}generate(e){const t=this.getNodeType(e);return o('TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".'),e.generateConst(t)}}function un(e,t=null){const r=new on(e,t);return new Proxy(()=>{},{apply:(e,t,s)=>r.call(...s),get:(e,t,s)=>Reflect.get(r,t,s),set:(e,t,s,i)=>Reflect.set(r,t,s,i)})}const ln=e=>{_i=e},dn=()=>_i,cn=(...e)=>_i.If(...e);function hn(e){return _i&&_i.addToStack(e),e}Ni("toStack",hn);const pn=new Xi("color"),gn=new Xi("float",Hi.float),mn=new Xi("int",Hi.ints),fn=new Xi("uint",Hi.uint),yn=new Xi("bool",Hi.bool),bn=new Xi("vec2"),xn=new Xi("ivec2"),Tn=new Xi("uvec2"),_n=new Xi("bvec2"),vn=new Xi("vec3"),Nn=new Xi("ivec3"),Sn=new Xi("uvec3"),Rn=new Xi("bvec3"),En=new Xi("vec4"),An=new Xi("ivec4"),wn=new Xi("uvec4"),Cn=new Xi("bvec4"),Mn=new Xi("mat2"),Fn=new Xi("mat3"),Ln=new Xi("mat4");Ni("toColor",pn),Ni("toFloat",gn),Ni("toInt",mn),Ni("toUint",fn),Ni("toBool",yn),Ni("toVec2",bn),Ni("toIVec2",xn),Ni("toUVec2",Tn),Ni("toBVec2",_n),Ni("toVec3",vn),Ni("toIVec3",Nn),Ni("toUVec3",Sn),Ni("toBVec3",Rn),Ni("toVec4",En),Ni("toIVec4",An),Ni("toUVec4",wn),Ni("toBVec4",Cn),Ni("toMat2",Mn),Ni("toMat3",Fn),Ni("toMat4",Ln);const Pn=rn(li).setParameterLength(2),Bn=(e,t)=>Zi(new di(Zi(e),t));Ni("element",Pn),Ni("convert",Bn);Ni("append",e=>(d("TSL: .append() has been renamed to .toStack()."),hn(e)));class Dn extends ui{static get type(){return"PropertyNode"}constructor(e,t=null,r=!1){super(e),this.name=t,this.varying=r,this.isPropertyNode=!0,this.global=!0}customCacheKey(){return Us(this.type+":"+(this.name||"")+":"+(this.varying?"1":"0"))}getHash(e){return this.name||super.getHash(e)}generate(e){let t;return!0===this.varying?(t=e.getVaryingFromNode(this,this.name),t.needsInterpolation=!0):t=e.getVarFromNode(this,this.name),e.getPropertyName(t)}}const Un=(e,t)=>new Dn(e,t),In=(e,t)=>new Dn(e,t,!0),On=sn(Dn,"vec4","DiffuseColor"),Vn=sn(Dn,"vec3","DiffuseContribution"),kn=sn(Dn,"vec3","EmissiveColor"),Gn=sn(Dn,"float","Roughness"),zn=sn(Dn,"float","Metalness"),$n=sn(Dn,"float","Clearcoat"),Wn=sn(Dn,"float","ClearcoatRoughness"),Hn=sn(Dn,"vec3","Sheen"),qn=sn(Dn,"float","SheenRoughness"),jn=sn(Dn,"float","Iridescence"),Xn=sn(Dn,"float","IridescenceIOR"),Kn=sn(Dn,"float","IridescenceThickness"),Yn=sn(Dn,"float","AlphaT"),Qn=sn(Dn,"float","Anisotropy"),Zn=sn(Dn,"vec3","AnisotropyT"),Jn=sn(Dn,"vec3","AnisotropyB"),ea=sn(Dn,"color","SpecularColor"),ta=sn(Dn,"color","SpecularColorBlended"),ra=sn(Dn,"float","SpecularF90"),sa=sn(Dn,"float","Shininess"),ia=sn(Dn,"vec4","Output"),na=sn(Dn,"float","dashSize"),aa=sn(Dn,"float","gapSize"),oa=sn(Dn,"float","pointWidth"),ua=sn(Dn,"float","IOR"),la=sn(Dn,"float","Transmission"),da=sn(Dn,"float","Thickness"),ca=sn(Dn,"float","AttenuationDistance"),ha=sn(Dn,"color","AttenuationColor"),pa=sn(Dn,"float","Dispersion");class ga extends ui{static get type(){return"UniformGroupNode"}constructor(e,t=!1,r=1){super("string"),this.name=e,this.shared=t,this.order=r,this.isUniformGroup=!0}serialize(e){super.serialize(e),e.name=this.name,e.version=this.version,e.shared=this.shared}deserialize(e){super.deserialize(e),this.name=e.name,this.version=e.version,this.shared=e.shared}}const ma=e=>new ga(e),fa=(e,t=0)=>new ga(e,!0,t),ya=fa("frame"),ba=fa("render"),xa=ma("object");class Ta extends yi{static get type(){return"UniformNode"}constructor(e,t=null){super(e,t),this.isUniformNode=!0,this.name="",this.groupNode=xa}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setGroup(e){return this.groupNode=e,this}getGroup(){return this.groupNode}getUniformHash(e){return this.getHash(e)}onUpdate(e,t){return e=e.bind(this),super.onUpdate(t=>{const r=e(t,this);void 0!==r&&(this.value=r)},t)}getInputType(e){let t=super.getInputType(e);return"bool"===t&&(t="uint"),t}generate(e,t){const r=this.getNodeType(e),s=this.getUniformHash(e);let i=e.getNodeFromHash(s);void 0===i&&(e.setHashNode(this,s),i=this);const n=i.getInputType(e),a=e.getUniformFromNode(i,n,e.shaderStage,this.name||e.context.nodeName),o=e.getPropertyName(a);void 0!==e.context.nodeName&&delete e.context.nodeName;let u=o;if("bool"===r){const t=e.getDataFromNode(this);let s=t.propertyName;if(void 0===s){const i=e.getVarFromNode(this,null,"bool");s=e.getPropertyName(i),t.propertyName=s,u=e.format(o,n,r),e.addLineFlowCode(`${s} = ${u}`,this)}u=s}return e.format(u,r,t)}}const _a=(e,t)=>{const r=Yi(t||e);if(r===e&&(e=js(r)),e&&!0===e.isNode){let t=e.value;e.traverse(e=>{!0===e.isConstNode&&(t=e.value)}),e=t}return new Ta(e,r)};class va extends ci{static get type(){return"ArrayNode"}constructor(e,t,r=null){super(e),this.count=t,this.values=r,this.isArrayNode=!0}getArrayCount(){return this.count}getNodeType(e){return null===this.nodeType?this.values[0].getNodeType(e):this.nodeType}getElementType(e){return this.getNodeType(e)}getMemberType(e,t){return null===this.nodeType?this.values[0].getMemberType(e,t):super.getMemberType(e,t)}generate(e){const t=this.getNodeType(e);return e.generateArray(t,this.count,this.values)}}const Na=(...e)=>{let t;if(1===e.length){const r=e[0];t=new va(null,r.length,r)}else{const r=e[0],s=e[1];t=new va(r,s)}return Zi(t)};Ni("toArray",(e,t)=>Na(Array(t).fill(e)));class Sa extends ci{static get type(){return"AssignNode"}constructor(e,t){super(),this.targetNode=e,this.sourceNode=t,this.isAssignNode=!0}hasDependencies(){return!1}getNodeType(e,t){return"void"!==t?this.targetNode.getNodeType(e):"void"}needsSplitAssign(e){const{targetNode:t}=this;if(!1===e.isAvailable("swizzleAssign")&&t.isSplitNode&&t.components.length>1){const r=e.getTypeLength(t.node.getNodeType(e));return ni.join("").slice(0,r)!==t.components}return!1}setup(e){const{targetNode:t,sourceNode:r}=this,s=t.getScope();e.getDataFromNode(s).assign=!0;const i=e.getNodeProperties(this);i.sourceNode=r,i.targetNode=t.context({assign:!0})}generate(e,t){const{targetNode:r,sourceNode:s}=e.getNodeProperties(this),i=this.needsSplitAssign(e),n=r.build(e),a=r.getNodeType(e),o=s.build(e,a),u=s.getNodeType(e),l=e.getDataFromNode(this);let d;if(!0===l.initialized)"void"!==t&&(d=n);else if(i){const s=e.getVarFromNode(this,null,a),i=e.getPropertyName(s);e.addLineFlowCode(`${i} = ${o}`,this);const u=r.node,l=u.node.context({assign:!0}).build(e);for(let t=0;t{const s=r.type;let i;return i="pointer"===s?"&"+t.build(e):t.build(e,s),i};if(Array.isArray(i)){if(i.length>s.length)o("TSL: The number of provided parameters exceeds the expected number of inputs in 'Fn()'."),i.length=s.length;else if(i.length(t=t.length>1||t[0]&&!0===t[0].isNode?tn(t):en(t[0]),new Ea(Zi(e),t));Ni("call",Aa);const wa={"==":"equal","!=":"notEqual","<":"lessThan",">":"greaterThan","<=":"lessThanEqual",">=":"greaterThanEqual","%":"mod"};class Ca extends ci{static get type(){return"OperatorNode"}constructor(e,t,r,...s){if(super(),s.length>0){let i=new Ca(e,t,r);for(let t=0;t>"===r||"<<"===r)return e.getIntegerType(n);if("!"===r||"&&"===r||"||"===r||"^^"===r)return"bool";if("=="===r||"!="===r||"<"===r||">"===r||"<="===r||">="===r){const t=Math.max(e.getTypeLength(n),e.getTypeLength(a));return t>1?`bvec${t}`:"bool"}if(e.isMatrix(n)){if("float"===a)return n;if(e.isVector(a))return e.getVectorFromMatrix(n);if(e.isMatrix(a))return n}else if(e.isMatrix(a)){if("float"===n)return a;if(e.isVector(n))return e.getVectorFromMatrix(a)}return e.getTypeLength(a)>e.getTypeLength(n)?a:n}generate(e,t){const r=this.op,{aNode:s,bNode:i}=this,n=this.getNodeType(e,t);let a=null,o=null;"void"!==n?(a=s.getNodeType(e),o=i?i.getNodeType(e):null,"<"===r||">"===r||"<="===r||">="===r||"=="===r||"!="===r?e.isVector(a)?o=a:e.isVector(o)?a=o:a!==o&&(a=o="float"):">>"===r||"<<"===r?(a=n,o=e.changeComponentType(o,"uint")):"%"===r?(a=n,o=e.isInteger(a)&&e.isInteger(o)?o:a):e.isMatrix(a)?"float"===o?o="float":e.isVector(o)?o=e.getVectorFromMatrix(a):e.isMatrix(o)||(a=o=n):a=e.isMatrix(o)?"float"===a?"float":e.isVector(a)?e.getVectorFromMatrix(o):o=n:o=n):a=o=n;const u=s.build(e,a),l=i?i.build(e,o):null,d=e.getFunctionOperator(r);if("void"!==t){const s=e.renderer.coordinateSystem===c;if("=="===r||"!="===r||"<"===r||">"===r||"<="===r||">="===r)return s&&e.isVector(a)?e.format(`${this.getOperatorMethod(e,t)}( ${u}, ${l} )`,n,t):e.format(`( ${u} ${r} ${l} )`,n,t);if("%"===r)return e.isInteger(o)?e.format(`( ${u} % ${l} )`,n,t):e.format(`${this.getOperatorMethod(e,n)}( ${u}, ${l} )`,n,t);if("!"===r||"~"===r)return e.format(`(${r}${u})`,a,t);if(d)return e.format(`${d}( ${u}, ${l} )`,n,t);if(e.isMatrix(a)&&"float"===o)return e.format(`( ${l} ${r} ${u} )`,n,t);if("float"===a&&e.isMatrix(o))return e.format(`${u} ${r} ${l}`,n,t);{let i=`( ${u} ${r} ${l} )`;return!s&&"bool"===n&&e.isVector(a)&&e.isVector(o)&&(i=`all${i}`),e.format(i,n,t)}}if("void"!==a)return d?e.format(`${d}( ${u}, ${l} )`,n,t):e.isMatrix(a)&&"float"===o?e.format(`${l} ${r} ${u}`,n,t):e.format(`${u} ${r} ${l}`,n,t)}serialize(e){super.serialize(e),e.op=this.op}deserialize(e){super.deserialize(e),this.op=e.op}}const Ma=nn(Ca,"+").setParameterLength(2,1/0).setName("add"),Fa=nn(Ca,"-").setParameterLength(2,1/0).setName("sub"),La=nn(Ca,"*").setParameterLength(2,1/0).setName("mul"),Pa=nn(Ca,"/").setParameterLength(2,1/0).setName("div"),Ba=nn(Ca,"%").setParameterLength(2).setName("mod"),Da=nn(Ca,"==").setParameterLength(2).setName("equal"),Ua=nn(Ca,"!=").setParameterLength(2).setName("notEqual"),Ia=nn(Ca,"<").setParameterLength(2).setName("lessThan"),Oa=nn(Ca,">").setParameterLength(2).setName("greaterThan"),Va=nn(Ca,"<=").setParameterLength(2).setName("lessThanEqual"),ka=nn(Ca,">=").setParameterLength(2).setName("greaterThanEqual"),Ga=nn(Ca,"&&").setParameterLength(2,1/0).setName("and"),za=nn(Ca,"||").setParameterLength(2,1/0).setName("or"),$a=nn(Ca,"!").setParameterLength(1).setName("not"),Wa=nn(Ca,"^^").setParameterLength(2).setName("xor"),Ha=nn(Ca,"&").setParameterLength(2).setName("bitAnd"),qa=nn(Ca,"~").setParameterLength(1).setName("bitNot"),ja=nn(Ca,"|").setParameterLength(2).setName("bitOr"),Xa=nn(Ca,"^").setParameterLength(2).setName("bitXor"),Ka=nn(Ca,"<<").setParameterLength(2).setName("shiftLeft"),Ya=nn(Ca,">>").setParameterLength(2).setName("shiftRight"),Qa=un(([e])=>(e.addAssign(1),e)),Za=un(([e])=>(e.subAssign(1),e)),Ja=un(([e])=>{const t=mn(e).toConst();return e.addAssign(1),t}),eo=un(([e])=>{const t=mn(e).toConst();return e.subAssign(1),t});Ni("add",Ma),Ni("sub",Fa),Ni("mul",La),Ni("div",Pa),Ni("mod",Ba),Ni("equal",Da),Ni("notEqual",Ua),Ni("lessThan",Ia),Ni("greaterThan",Oa),Ni("lessThanEqual",Va),Ni("greaterThanEqual",ka),Ni("and",Ga),Ni("or",za),Ni("not",$a),Ni("xor",Wa),Ni("bitAnd",Ha),Ni("bitNot",qa),Ni("bitOr",ja),Ni("bitXor",Xa),Ni("shiftLeft",Ka),Ni("shiftRight",Ya),Ni("incrementBefore",Qa),Ni("decrementBefore",Za),Ni("increment",Ja),Ni("decrement",eo);const to=(e,t)=>(d('TSL: "modInt()" is deprecated. Use "mod( int( ... ) )" instead.'),Ba(mn(e),mn(t)));Ni("modInt",to);class ro extends ci{static get type(){return"MathNode"}constructor(e,t,r=null,s=null){if(super(),(e===ro.MAX||e===ro.MIN)&&arguments.length>3){let i=new ro(e,t,r);for(let t=2;tn&&i>a?t:n>a?r:a>i?s:t}getNodeType(e){const t=this.method;return t===ro.LENGTH||t===ro.DISTANCE||t===ro.DOT?"float":t===ro.CROSS?"vec3":t===ro.ALL||t===ro.ANY?"bool":t===ro.EQUALS?e.changeComponentType(this.aNode.getNodeType(e),"bool"):this.getInputType(e)}setup(e){const{aNode:t,bNode:r,method:s}=this;let i=null;if(s===ro.ONE_MINUS)i=Fa(1,t);else if(s===ro.RECIPROCAL)i=Pa(1,t);else if(s===ro.DIFFERENCE)i=Mo(Fa(t,r));else if(s===ro.TRANSFORM_DIRECTION){let s=t,n=r;e.isMatrix(s.getNodeType(e))?n=En(vn(n),0):s=En(vn(s),0);const a=La(s,n).xyz;i=vo(a)}return null!==i?i:super.setup(e)}generate(e,t){if(e.getNodeProperties(this).outputNode)return super.generate(e,t);let r=this.method;const s=this.getNodeType(e),i=this.getInputType(e),n=this.aNode,a=this.bNode,o=this.cNode,u=e.renderer.coordinateSystem;if(r===ro.NEGATE)return e.format("( - "+n.build(e,i)+" )",s,t);{const l=[];return r===ro.CROSS?l.push(n.build(e,s),a.build(e,s)):u===c&&r===ro.STEP?l.push(n.build(e,1===e.getTypeLength(n.getNodeType(e))?"float":i),a.build(e,i)):u!==c||r!==ro.MIN&&r!==ro.MAX?r===ro.REFRACT?l.push(n.build(e,i),a.build(e,i),o.build(e,"float")):r===ro.MIX?l.push(n.build(e,i),a.build(e,i),o.build(e,1===e.getTypeLength(o.getNodeType(e))?"float":i)):(u===h&&r===ro.ATAN&&null!==a&&(r="atan2"),"fragment"===e.shaderStage||r!==ro.DFDX&&r!==ro.DFDY||(d(`TSL: '${r}' is not supported in the ${e.shaderStage} stage.`),r="/*"+r+"*/"),l.push(n.build(e,i)),null!==a&&l.push(a.build(e,i)),null!==o&&l.push(o.build(e,i))):l.push(n.build(e,i),a.build(e,1===e.getTypeLength(a.getNodeType(e))?"float":i)),e.format(`${e.getMethod(r,s)}( ${l.join(", ")} )`,s,t)}}serialize(e){super.serialize(e),e.method=this.method}deserialize(e){super.deserialize(e),this.method=e.method}}ro.ALL="all",ro.ANY="any",ro.RADIANS="radians",ro.DEGREES="degrees",ro.EXP="exp",ro.EXP2="exp2",ro.LOG="log",ro.LOG2="log2",ro.SQRT="sqrt",ro.INVERSE_SQRT="inversesqrt",ro.FLOOR="floor",ro.CEIL="ceil",ro.NORMALIZE="normalize",ro.FRACT="fract",ro.SIN="sin",ro.COS="cos",ro.TAN="tan",ro.ASIN="asin",ro.ACOS="acos",ro.ATAN="atan",ro.ABS="abs",ro.SIGN="sign",ro.LENGTH="length",ro.NEGATE="negate",ro.ONE_MINUS="oneMinus",ro.DFDX="dFdx",ro.DFDY="dFdy",ro.ROUND="round",ro.RECIPROCAL="reciprocal",ro.TRUNC="trunc",ro.FWIDTH="fwidth",ro.TRANSPOSE="transpose",ro.DETERMINANT="determinant",ro.INVERSE="inverse",ro.EQUALS="equals",ro.MIN="min",ro.MAX="max",ro.STEP="step",ro.REFLECT="reflect",ro.DISTANCE="distance",ro.DIFFERENCE="difference",ro.DOT="dot",ro.CROSS="cross",ro.POW="pow",ro.TRANSFORM_DIRECTION="transformDirection",ro.MIX="mix",ro.CLAMP="clamp",ro.REFRACT="refract",ro.SMOOTHSTEP="smoothstep",ro.FACEFORWARD="faceforward";const so=gn(1e-6),io=gn(1e6),no=gn(Math.PI),ao=gn(2*Math.PI),oo=gn(2*Math.PI),uo=gn(.5*Math.PI),lo=nn(ro,ro.ALL).setParameterLength(1),co=nn(ro,ro.ANY).setParameterLength(1),ho=nn(ro,ro.RADIANS).setParameterLength(1),po=nn(ro,ro.DEGREES).setParameterLength(1),go=nn(ro,ro.EXP).setParameterLength(1),mo=nn(ro,ro.EXP2).setParameterLength(1),fo=nn(ro,ro.LOG).setParameterLength(1),yo=nn(ro,ro.LOG2).setParameterLength(1),bo=nn(ro,ro.SQRT).setParameterLength(1),xo=nn(ro,ro.INVERSE_SQRT).setParameterLength(1),To=nn(ro,ro.FLOOR).setParameterLength(1),_o=nn(ro,ro.CEIL).setParameterLength(1),vo=nn(ro,ro.NORMALIZE).setParameterLength(1),No=nn(ro,ro.FRACT).setParameterLength(1),So=nn(ro,ro.SIN).setParameterLength(1),Ro=nn(ro,ro.COS).setParameterLength(1),Eo=nn(ro,ro.TAN).setParameterLength(1),Ao=nn(ro,ro.ASIN).setParameterLength(1),wo=nn(ro,ro.ACOS).setParameterLength(1),Co=nn(ro,ro.ATAN).setParameterLength(1,2),Mo=nn(ro,ro.ABS).setParameterLength(1),Fo=nn(ro,ro.SIGN).setParameterLength(1),Lo=nn(ro,ro.LENGTH).setParameterLength(1),Po=nn(ro,ro.NEGATE).setParameterLength(1),Bo=nn(ro,ro.ONE_MINUS).setParameterLength(1),Do=nn(ro,ro.DFDX).setParameterLength(1),Uo=nn(ro,ro.DFDY).setParameterLength(1),Io=nn(ro,ro.ROUND).setParameterLength(1),Oo=nn(ro,ro.RECIPROCAL).setParameterLength(1),Vo=nn(ro,ro.TRUNC).setParameterLength(1),ko=nn(ro,ro.FWIDTH).setParameterLength(1),Go=nn(ro,ro.TRANSPOSE).setParameterLength(1),zo=nn(ro,ro.DETERMINANT).setParameterLength(1),$o=nn(ro,ro.INVERSE).setParameterLength(1),Wo=nn(ro,ro.MIN).setParameterLength(2,1/0),Ho=nn(ro,ro.MAX).setParameterLength(2,1/0),qo=nn(ro,ro.STEP).setParameterLength(2),jo=nn(ro,ro.REFLECT).setParameterLength(2),Xo=nn(ro,ro.DISTANCE).setParameterLength(2),Ko=nn(ro,ro.DIFFERENCE).setParameterLength(2),Yo=nn(ro,ro.DOT).setParameterLength(2),Qo=nn(ro,ro.CROSS).setParameterLength(2),Zo=nn(ro,ro.POW).setParameterLength(2),Jo=e=>La(e,e),eu=e=>La(e,e,e),tu=e=>La(e,e,e,e),ru=nn(ro,ro.TRANSFORM_DIRECTION).setParameterLength(2),su=e=>La(Fo(e),Zo(Mo(e),1/3)),iu=e=>Yo(e,e),nu=nn(ro,ro.MIX).setParameterLength(3),au=(e,t=0,r=1)=>Zi(new ro(ro.CLAMP,Zi(e),Zi(t),Zi(r))),ou=e=>au(e),uu=nn(ro,ro.REFRACT).setParameterLength(3),lu=nn(ro,ro.SMOOTHSTEP).setParameterLength(3),du=nn(ro,ro.FACEFORWARD).setParameterLength(3),cu=un(([e])=>{const t=Yo(e.xy,bn(12.9898,78.233)),r=Ba(t,no);return No(So(r).mul(43758.5453))}),hu=(e,t,r)=>nu(t,r,e),pu=(e,t,r)=>lu(t,r,e),gu=(e,t)=>qo(t,e),mu=du,fu=xo;Ni("all",lo),Ni("any",co),Ni("radians",ho),Ni("degrees",po),Ni("exp",go),Ni("exp2",mo),Ni("log",fo),Ni("log2",yo),Ni("sqrt",bo),Ni("inverseSqrt",xo),Ni("floor",To),Ni("ceil",_o),Ni("normalize",vo),Ni("fract",No),Ni("sin",So),Ni("cos",Ro),Ni("tan",Eo),Ni("asin",Ao),Ni("acos",wo),Ni("atan",Co),Ni("abs",Mo),Ni("sign",Fo),Ni("length",Lo),Ni("lengthSq",iu),Ni("negate",Po),Ni("oneMinus",Bo),Ni("dFdx",Do),Ni("dFdy",Uo),Ni("round",Io),Ni("reciprocal",Oo),Ni("trunc",Vo),Ni("fwidth",ko),Ni("min",Wo),Ni("max",Ho),Ni("step",gu),Ni("reflect",jo),Ni("distance",Xo),Ni("dot",Yo),Ni("cross",Qo),Ni("pow",Zo),Ni("pow2",Jo),Ni("pow3",eu),Ni("pow4",tu),Ni("transformDirection",ru),Ni("mix",hu),Ni("clamp",au),Ni("refract",uu),Ni("smoothstep",pu),Ni("faceForward",du),Ni("difference",Ko),Ni("saturate",ou),Ni("cbrt",su),Ni("transpose",Go),Ni("determinant",zo),Ni("inverse",$o),Ni("rand",cu);class yu extends ui{static get type(){return"ConditionalNode"}constructor(e,t,r=null){super(),this.condNode=e,this.ifNode=t,this.elseNode=r}getNodeType(e){const{ifNode:t,elseNode:r}=e.getNodeProperties(this);if(void 0===t)return e.flowBuildStage(this,"setup"),this.getNodeType(e);const s=t.getNodeType(e);if(null!==r){const t=r.getNodeType(e);if(e.getTypeLength(t)>e.getTypeLength(s))return t}return s}setup(e){const t=this.condNode,r=this.ifNode.isolate(),s=this.elseNode?this.elseNode.isolate():null,i=e.context.nodeBlock;e.getDataFromNode(r).parentNodeBlock=i,null!==s&&(e.getDataFromNode(s).parentNodeBlock=i);const n=e.context.uniformFlow,a=e.getNodeProperties(this);a.condNode=t,a.ifNode=n?r:r.context({nodeBlock:r}),a.elseNode=s?n?s:s.context({nodeBlock:s}):null}generate(e,t){const r=this.getNodeType(e),s=e.getDataFromNode(this);if(void 0!==s.nodeProperty)return s.nodeProperty;const{condNode:i,ifNode:n,elseNode:a}=e.getNodeProperties(this),o=e.currentFunctionNode,u="void"!==t,l=u?Un(r).build(e):"";s.nodeProperty=l;const c=i.build(e,"bool");if(e.context.uniformFlow&&null!==a){const s=n.build(e,r),i=a.build(e,r),o=e.getTernary(c,s,i);return e.format(o,r,t)}e.addFlowCode(`\n${e.tab}if ( ${c} ) {\n\n`).addFlowTab();let h=n.build(e,r);if(h&&(u?h=l+" = "+h+";":(h="return "+h+";",null===o&&(d("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values."),h="// "+h))),e.removeFlowTab().addFlowCode(e.tab+"\t"+h+"\n\n"+e.tab+"}"),null!==a){e.addFlowCode(" else {\n\n").addFlowTab();let t=a.build(e,r);t&&(u?t=l+" = "+t+";":(t="return "+t+";",null===o&&(d("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values."),t="// "+t))),e.removeFlowTab().addFlowCode(e.tab+"\t"+t+"\n\n"+e.tab+"}\n\n")}else e.addFlowCode("\n\n");return e.format(l,r,t)}}const bu=rn(yu).setParameterLength(2,3);Ni("select",bu);class xu extends ui{static get type(){return"ContextNode"}constructor(e=null,t={}){super(),this.isContextNode=!0,this.node=e,this.value=t}getScope(){return this.node.getScope()}getNodeType(e){return this.node.getNodeType(e)}getFlowContextData(){const e=[];return this.traverse(t=>{!0===t.isContextNode&&e.push(t.value)}),Object.assign({},...e)}getMemberType(e,t){return this.node.getMemberType(e,t)}analyze(e){const t=e.addContext(this.value);this.node.build(e),e.setContext(t)}setup(e){const t=e.addContext(this.value);this.node.build(e),e.setContext(t)}generate(e,t){const r=e.addContext(this.value),s=this.node.build(e,t);return e.setContext(r),s}}const Tu=(e=null,t={})=>{let r=e;return null!==r&&!0===r.isNode||(t=r||t,r=null),new xu(r,t)},_u=e=>Tu(e,{uniformFlow:!0}),vu=(e,t)=>Tu(e,{nodeName:t});function Nu(e,t,r=null){return Tu(r,{getShadow:({light:r,shadowColorNode:s})=>t===r?s.mul(e):s})}function Su(e,t=null){return Tu(t,{getAO:(t,{material:r})=>!0===r.transparent?t:null!==t?t.mul(e):e})}function Ru(e,t){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),vu(e,t)}Ni("context",Tu),Ni("label",Ru),Ni("uniformFlow",_u),Ni("setName",vu),Ni("builtinShadowContext",(e,t,r)=>Nu(t,r,e)),Ni("builtinAOContext",(e,t)=>Su(t,e));class Eu extends ui{static get type(){return"VarNode"}constructor(e,t=null,r=!1){super(),this.node=e,this.name=t,this.global=!0,this.isVarNode=!0,this.readOnly=r,this.parents=!0,this.intent=!1}setIntent(e){return this.intent=e,this}isIntent(e){return!0!==e.getDataFromNode(this).forceDeclaration&&this.intent}getIntent(){return this.intent}getMemberType(e,t){return this.node.getMemberType(e,t)}getElementType(e){return this.node.getElementType(e)}getNodeType(e){return this.node.getNodeType(e)}getArrayCount(e){return this.node.getArrayCount(e)}isAssign(e){return e.getDataFromNode(this).assign}build(...e){const t=e[0];if(!1===this._hasStack(t)&&"setup"===t.buildStage&&(t.context.nodeLoop||t.context.nodeBlock)){let e=!1;if(this.node.isShaderCallNodeInternal&&null===this.node.shaderNode.getLayout()&&t.fnCall&&t.fnCall.shaderNode){if(t.getDataFromNode(this.node.shaderNode).hasLoop){t.getDataFromNode(this).forceDeclaration=!0,e=!0}}const r=t.getBaseStack();e?r.addToStackBefore(this):r.addToStack(this)}return this.isIntent(t)&&!0!==this.isAssign(t)?this.node.build(...e):super.build(...e)}generate(e){const{node:t,name:r,readOnly:s}=this,{renderer:i}=e,n=!0===i.backend.isWebGPUBackend;let a=!1,u=!1;s&&(a=e.isDeterministic(t),u=n?s:a);const l=this.getNodeType(e);if("void"==l){!0!==this.isIntent(e)&&o('TSL: ".toVar()" can not be used with void type.');return t.build(e)}const d=e.getVectorType(l),c=t.build(e,d),h=e.getVarFromNode(this,r,d,void 0,u),p=e.getPropertyName(h);let g=p;if(u)if(n)g=a?`const ${p}`:`let ${p}`;else{const r=t.getArrayCount(e);g=`const ${e.getVar(h.type,p,r)}`}return e.addLineFlowCode(`${g} = ${c}`,this),p}_hasStack(e){return void 0!==e.getDataFromNode(this).stack}}const Au=rn(Eu),wu=(e,t=null)=>Au(e,t).toStack(),Cu=(e,t=null)=>Au(e,t,!0).toStack(),Mu=e=>Au(e).setIntent(!0).toStack();Ni("toVar",wu),Ni("toConst",Cu),Ni("toVarIntent",Mu);class Fu extends ui{static get type(){return"SubBuild"}constructor(e,t,r=null){super(r),this.node=e,this.name=t,this.isSubBuildNode=!0}getNodeType(e){if(null!==this.nodeType)return this.nodeType;e.addSubBuild(this.name);const t=this.node.getNodeType(e);return e.removeSubBuild(),t}build(e,...t){e.addSubBuild(this.name);const r=this.node.build(e,...t);return e.removeSubBuild(),r}}const Lu=(e,t,r=null)=>Zi(new Fu(Zi(e),t,r));class Pu extends ui{static get type(){return"VaryingNode"}constructor(e,t=null){super(),this.node=Lu(e,"VERTEX"),this.name=t,this.isVaryingNode=!0,this.interpolationType=null,this.interpolationSampling=null,this.global=!0}setInterpolation(e,t=null){return this.interpolationType=e,this.interpolationSampling=t,this}getHash(e){return this.name||super.getHash(e)}getNodeType(e){return this.node.getNodeType(e)}setupVarying(e){const t=e.getNodeProperties(this);let r=t.varying;if(void 0===r){const s=this.name,i=this.getNodeType(e),n=this.interpolationType,a=this.interpolationSampling;t.varying=r=e.getVaryingFromNode(this,s,i,n,a),t.node=Lu(this.node,"VERTEX")}return r.needsInterpolation||(r.needsInterpolation="fragment"===e.shaderStage),r}setup(e){this.setupVarying(e),e.flowNodeFromShaderStage(Zs.VERTEX,this.node)}analyze(e){this.setupVarying(e),e.flowNodeFromShaderStage(Zs.VERTEX,this.node)}generate(e){const t=e.getSubBuildProperty("property",e.currentStack),r=e.getNodeProperties(this),s=this.setupVarying(e);if(void 0===r[t]){const i=this.getNodeType(e),n=e.getPropertyName(s,Zs.VERTEX);e.flowNodeFromShaderStage(Zs.VERTEX,r.node,i,n),r[t]=n}return e.getPropertyName(s)}}const Bu=rn(Pu).setParameterLength(1,2),Du=e=>Bu(e);Ni("toVarying",Bu),Ni("toVertexStage",Du);const Uu=un(([e])=>{const t=e.mul(.9478672986).add(.0521327014).pow(2.4),r=e.mul(.0773993808),s=e.lessThanEqual(.04045);return nu(t,r,s)}).setLayout({name:"sRGBTransferEOTF",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Iu=un(([e])=>{const t=e.pow(.41666).mul(1.055).sub(.055),r=e.mul(12.92),s=e.lessThanEqual(.0031308);return nu(t,r,s)}).setLayout({name:"sRGBTransferOETF",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Ou="WorkingColorSpace";class Vu extends ci{static get type(){return"ColorSpaceNode"}constructor(e,t,r){super("vec4"),this.colorNode=e,this.source=t,this.target=r}resolveColorSpace(e,t){return t===Ou?p.workingColorSpace:"OutputColorSpace"===t?e.context.outputColorSpace||e.renderer.outputColorSpace:t}setup(e){const{colorNode:t}=this,r=this.resolveColorSpace(e,this.source),s=this.resolveColorSpace(e,this.target);let i=t;return!1!==p.enabled&&r!==s&&r&&s?(p.getTransfer(r)===g&&(i=En(Uu(i.rgb),i.a)),p.getPrimaries(r)!==p.getPrimaries(s)&&(i=En(Fn(p._getMatrix(new n,r,s)).mul(i.rgb),i.a)),p.getTransfer(s)===g&&(i=En(Iu(i.rgb),i.a)),i):i}}const ku=(e,t)=>Zi(new Vu(Zi(e),Ou,t)),Gu=(e,t)=>Zi(new Vu(Zi(e),t,Ou));Ni("workingToColorSpace",ku),Ni("colorSpaceToWorking",Gu);let zu=class extends li{static get type(){return"ReferenceElementNode"}constructor(e,t){super(e,t),this.referenceNode=e,this.isReferenceElementNode=!0}getNodeType(){return this.referenceNode.uniformType}generate(e){const t=super.generate(e),r=this.referenceNode.getNodeType(),s=this.getNodeType();return e.format(t,r,s)}};class $u extends ui{static get type(){return"ReferenceBaseNode"}constructor(e,t,r=null,s=null){super(),this.property=e,this.uniformType=t,this.object=r,this.count=s,this.properties=e.split("."),this.reference=r,this.node=null,this.group=null,this.updateType=Js.OBJECT}setGroup(e){return this.group=e,this}element(e){return new zu(this,Zi(e))}setNodeType(e){const t=_a(null,e);null!==this.group&&t.setGroup(this.group),this.node=t}getNodeType(e){return null===this.node&&(this.updateReference(e),this.updateValue()),this.node.getNodeType(e)}getValueFromReference(e=this.reference){const{properties:t}=this;let r=e[t[0]];for(let e=1;enew Wu(e,t,r);class qu extends ci{static get type(){return"ToneMappingNode"}constructor(e,t=Xu,r=null){super("vec3"),this._toneMapping=e,this.exposureNode=t,this.colorNode=r}customCacheKey(){return Os(this._toneMapping)}setToneMapping(e){return this._toneMapping=e,this}getToneMapping(){return this._toneMapping}setup(e){const t=this.colorNode||e.context.color,r=this._toneMapping;if(r===m)return t;let s=null;const i=e.renderer.library.getToneMappingFunction(r);return null!==i?s=En(i(t.rgb,this.exposureNode),t.a):(o("ToneMappingNode: Unsupported Tone Mapping configuration.",r),s=t),s}}const ju=(e,t,r)=>Zi(new qu(e,Zi(t),Zi(r))),Xu=Hu("toneMappingExposure","float");Ni("toneMapping",(e,t,r)=>ju(t,r,e));const Ku=new WeakMap;function Yu(e,t){let r=Ku.get(e);return void 0===r&&(r=new b(e,t),Ku.set(e,r)),r}class Qu extends yi{static get type(){return"BufferAttributeNode"}constructor(e,t=null,r=0,s=0){super(e,t),this.isBufferNode=!0,this.bufferType=t,this.bufferStride=r,this.bufferOffset=s,this.usage=f,this.instanced=!1,this.attribute=null,this.global=!0,e&&!0===e.isBufferAttribute&&e.itemSize<=4&&(this.attribute=e,this.usage=e.usage,this.instanced=e.isInstancedBufferAttribute)}getHash(e){if(0===this.bufferStride&&0===this.bufferOffset){let t=e.globalCache.getData(this.value);return void 0===t&&(t={node:this},e.globalCache.setData(this.value,t)),t.node.uuid}return this.uuid}getNodeType(e){return null===this.bufferType&&(this.bufferType=e.getTypeFromAttribute(this.attribute)),this.bufferType}setup(e){if(null!==this.attribute)return;const t=this.getNodeType(e),r=e.getTypeLength(t),s=this.value,i=this.bufferStride||r,n=this.bufferOffset;let a;a=!0===s.isInterleavedBuffer?s:!0===s.isBufferAttribute?Yu(s.array,i):Yu(s,i);const o=new y(a,r,n);a.setUsage(this.usage),this.attribute=o,this.attribute.isInstancedBufferAttribute=this.instanced}generate(e){const t=this.getNodeType(e),r=e.getBufferAttributeFromNode(this,t),s=e.getPropertyName(r);let i=null;if("vertex"===e.shaderStage||"compute"===e.shaderStage)this.name=s,i=s;else{i=Bu(this).build(e,t)}return i}getInputType(){return"bufferAttribute"}setUsage(e){return this.usage=e,this.attribute&&!0===this.attribute.isBufferAttribute&&(this.attribute.usage=e),this}setInstanced(e){return this.instanced=e,this}}function Zu(e,t=null,r=0,s=0,i=f,n=!1){return"mat3"===t||null===t&&9===e.itemSize?Fn(new Qu(e,"vec3",9,0).setUsage(i).setInstanced(n),new Qu(e,"vec3",9,3).setUsage(i).setInstanced(n),new Qu(e,"vec3",9,6).setUsage(i).setInstanced(n)):"mat4"===t||null===t&&16===e.itemSize?Ln(new Qu(e,"vec4",16,0).setUsage(i).setInstanced(n),new Qu(e,"vec4",16,4).setUsage(i).setInstanced(n),new Qu(e,"vec4",16,8).setUsage(i).setInstanced(n),new Qu(e,"vec4",16,12).setUsage(i).setInstanced(n)):new Qu(e,t,r,s).setUsage(i)}const Ju=(e,t=null,r=0,s=0)=>Zu(e,t,r,s),el=(e,t=null,r=0,s=0)=>Zu(e,t,r,s,f,!0),tl=(e,t=null,r=0,s=0)=>Zu(e,t,r,s,x,!0);Ni("toAttribute",e=>Ju(e.value));class rl extends ui{static get type(){return"ComputeNode"}constructor(e,t){super("void"),this.isComputeNode=!0,this.computeNode=e,this.workgroupSize=t,this.count=null,this.version=1,this.name="",this.updateBeforeType=Js.OBJECT,this.onInitFunction=null}setCount(e){return this.count=e,this}getCount(){return this.count}dispose(){this.dispatchEvent({type:"dispose"})}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}onInit(e){return this.onInitFunction=e,this}updateBefore({renderer:e}){e.compute(this)}setup(e){const t=this.computeNode.build(e);if(t){e.getNodeProperties(this).outputComputeNode=t.outputNode,t.outputNode=null}return t}generate(e,t){const{shaderStage:r}=e;if("compute"===r){const t=this.computeNode.build(e,"void");""!==t&&e.addLineFlowCode(t,this)}else{const r=e.getNodeProperties(this).outputComputeNode;if(r)return r.build(e,t)}}}const sl=(e,t=[64])=>{(0===t.length||t.length>3)&&o("TSL: compute() workgroupSize must have 1, 2, or 3 elements");for(let e=0;esl(e,r).setCount(t);Ni("compute",il),Ni("computeKernel",sl);class nl extends ui{static get type(){return"IsolateNode"}constructor(e,t=!0){super(),this.node=e,this.parent=t,this.isIsolateNode=!0}getNodeType(e){const t=e.getCache(),r=e.getCacheFromNode(this,this.parent);e.setCache(r);const s=this.node.getNodeType(e);return e.setCache(t),s}build(e,...t){const r=e.getCache(),s=e.getCacheFromNode(this,this.parent);e.setCache(s);const i=this.node.build(e,...t);return e.setCache(r),i}setParent(e){return this.parent=e,this}getParent(){return this.parent}}const al=e=>new nl(Zi(e));function ol(e,t=!0){return d('TSL: "cache()" has been deprecated. Use "isolate()" instead.'),al(e).setParent(t)}Ni("cache",ol),Ni("isolate",al);class ul extends ui{static get type(){return"BypassNode"}constructor(e,t){super(),this.isBypassNode=!0,this.outputNode=e,this.callNode=t}getNodeType(e){return this.outputNode.getNodeType(e)}generate(e){const t=this.callNode.build(e,"void");return""!==t&&e.addLineFlowCode(t,this),this.outputNode.build(e)}}const ll=rn(ul).setParameterLength(2);Ni("bypass",ll);class dl extends ui{static get type(){return"RemapNode"}constructor(e,t,r,s=gn(0),i=gn(1)){super(),this.node=e,this.inLowNode=t,this.inHighNode=r,this.outLowNode=s,this.outHighNode=i,this.doClamp=!0}setup(){const{node:e,inLowNode:t,inHighNode:r,outLowNode:s,outHighNode:i,doClamp:n}=this;let a=e.sub(t).div(r.sub(t));return!0===n&&(a=a.clamp()),a.mul(i.sub(s)).add(s)}}const cl=rn(dl,null,null,{doClamp:!1}).setParameterLength(3,5),hl=rn(dl).setParameterLength(3,5);Ni("remap",cl),Ni("remapClamp",hl);class pl extends ui{static get type(){return"ExpressionNode"}constructor(e="",t="void"){super(t),this.snippet=e}generate(e,t){const r=this.getNodeType(e),s=this.snippet;if("void"!==r)return e.format(s,r,t);e.addLineFlowCode(s,this)}}const gl=rn(pl).setParameterLength(1,2),ml=e=>(e?bu(e,gl("discard")):gl("discard")).toStack();Ni("discard",ml);class fl extends ci{static get type(){return"RenderOutputNode"}constructor(e,t,r){super("vec4"),this.colorNode=e,this._toneMapping=t,this.outputColorSpace=r,this.isRenderOutputNode=!0}setToneMapping(e){return this._toneMapping=e,this}getToneMapping(){return this._toneMapping}setup({context:e}){let t=this.colorNode||e.color;const r=(null!==this._toneMapping?this._toneMapping:e.toneMapping)||m,s=(null!==this.outputColorSpace?this.outputColorSpace:e.outputColorSpace)||T;return r!==m&&(t=t.toneMapping(r)),s!==T&&s!==p.workingColorSpace&&(t=t.workingToColorSpace(s)),t}}const yl=(e,t=null,r=null)=>Zi(new fl(Zi(e),t,r));Ni("renderOutput",yl);class bl extends ci{static get type(){return"DebugNode"}constructor(e,t=null){super(),this.node=e,this.callback=t}getNodeType(e){return this.node.getNodeType(e)}setup(e){return this.node.build(e)}analyze(e){return this.node.build(e)}generate(e){const t=this.callback,r=this.node.build(e);if(null!==t)t(e,r);else{const t="--- TSL debug - "+e.shaderStage+" shader ---",s="-".repeat(t.length);let i="";i+="// #"+t+"#\n",i+=e.flow.code.replace(/^\t/gm,"")+"\n",i+="/* ... */ "+r+" /* ... */\n",i+="// #"+s+"#\n",_(i)}return r}}const xl=(e,t=null)=>Zi(new bl(Zi(e),t)).toStack();Ni("debug",xl);class Tl{constructor(){this._renderer=null,this.currentFrame=null}get nodeFrame(){return this._renderer._nodes.nodeFrame}setRenderer(e){return this._renderer=e,this}getRenderer(){return this._renderer}init(){}begin(){}finish(){}inspect(){}computeAsync(){}beginCompute(){}finishCompute(){}beginRender(){}finishRender(){}copyTextureToTexture(){}copyFramebufferToTexture(){}}class _l extends ui{static get type(){return"InspectorNode"}constructor(e,t="",r=null){super(),this.node=e,this.name=t,this.callback=r,this.updateType=Js.FRAME,this.isInspectorNode=!0}getName(){return this.name||this.node.name}update(e){e.renderer.inspector.inspect(this)}getNodeType(e){return this.node.getNodeType(e)}setup(e){let t=this.node;return!0===e.context.inspector&&null!==this.callback&&(t=this.callback(t)),!0!==e.renderer.backend.isWebGPUBackend&&e.renderer.inspector.constructor!==Tl&&v('TSL: ".toInspector()" is only available with WebGPU.'),t}}function vl(e,t="",r=null){return(e=Zi(e)).before(new _l(e,t,r))}Ni("toInspector",vl);class Nl extends ui{static get type(){return"AttributeNode"}constructor(e,t=null){super(t),this.global=!0,this._attributeName=e}getHash(e){return this.getAttributeName(e)}getNodeType(e){let t=this.nodeType;if(null===t){const r=this.getAttributeName(e);if(e.hasGeometryAttribute(r)){const s=e.geometry.getAttribute(r);t=e.getTypeFromAttribute(s)}else t="float"}return t}setAttributeName(e){return this._attributeName=e,this}getAttributeName(){return this._attributeName}generate(e){const t=this.getAttributeName(e),r=this.getNodeType(e);if(!0===e.hasGeometryAttribute(t)){const s=e.geometry.getAttribute(t),i=e.getTypeFromAttribute(s),n=e.getAttribute(t,i);if("vertex"===e.shaderStage)return e.format(n.name,i,r);return Bu(this).build(e,r)}return d(`AttributeNode: Vertex attribute "${t}" not found on geometry.`),e.generateConst(r)}serialize(e){super.serialize(e),e.global=this.global,e._attributeName=this._attributeName}deserialize(e){super.deserialize(e),this.global=e.global,this._attributeName=e._attributeName}}const Sl=(e,t=null)=>new Nl(e,t),Rl=(e=0)=>Sl("uv"+(e>0?e:""),"vec2");class El extends ui{static get type(){return"TextureSizeNode"}constructor(e,t=null){super("uvec2"),this.isTextureSizeNode=!0,this.textureNode=e,this.levelNode=t}generate(e,t){const r=this.textureNode.build(e,"property"),s=null===this.levelNode?"0":this.levelNode.build(e,"int");return e.format(`${e.getMethod("textureDimensions")}( ${r}, ${s} )`,this.getNodeType(e),t)}}const Al=rn(El).setParameterLength(1,2);class wl extends Ta{static get type(){return"MaxMipLevelNode"}constructor(e){super(0),this._textureNode=e,this.updateType=Js.FRAME}get textureNode(){return this._textureNode}get texture(){return this._textureNode.value}update(){const e=this.texture,t=e.images,r=t&&t.length>0?t[0]&&t[0].image||t[0]:e.image;if(r&&void 0!==r.width){const{width:e,height:t}=r;this.value=Math.log2(Math.max(e,t))}}}const Cl=rn(wl).setParameterLength(1),Ml=new N;class Fl extends Ta{static get type(){return"TextureNode"}constructor(e=Ml,t=null,r=null,s=null){super(e),this.isTextureNode=!0,this.uvNode=t,this.levelNode=r,this.biasNode=s,this.compareNode=null,this.depthNode=null,this.gradNode=null,this.offsetNode=null,this.sampler=!0,this.updateMatrix=!1,this.updateType=Js.NONE,this.referenceNode=null,this._value=e,this._matrixUniform=null,this._flipYUniform=null,this.setUpdateMatrix(null===t)}set value(e){this.referenceNode?this.referenceNode.value=e:this._value=e}get value(){return this.referenceNode?this.referenceNode.value:this._value}getUniformHash(){return this.value.uuid}getNodeType(){return!0===this.value.isDepthTexture?"float":this.value.type===S?"uvec4":this.value.type===R?"ivec4":"vec4"}getInputType(){return"texture"}getDefaultUV(){return Rl(this.value.channel)}updateReference(){return this.value}getTransformedUV(e){return null===this._matrixUniform&&(this._matrixUniform=_a(this.value.matrix)),this._matrixUniform.mul(vn(e,1)).xy}setUpdateMatrix(e){return this.updateMatrix=e,this}setupUV(e,t){return e.isFlipY()&&(null===this._flipYUniform&&(this._flipYUniform=_a(!1)),t=t.toVar(),t=this.sampler?this._flipYUniform.select(t.flipY(),t):this._flipYUniform.select(t.setY(mn(Al(this,this.levelNode).y).sub(t.y).sub(1)),t)),t}setup(e){const t=e.getNodeProperties(this);t.referenceNode=this.referenceNode;const r=this.value;if(!r||!0!==r.isTexture)throw new Error("THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().");const s=un(()=>{let t=this.uvNode;return null!==t&&!0!==e.context.forceUVContext||!e.context.getUV||(t=e.context.getUV(this,e)),t||(t=this.getDefaultUV()),!0===this.updateMatrix&&(t=this.getTransformedUV(t)),t=this.setupUV(e,t),this.updateType=null!==this._matrixUniform||null!==this._flipYUniform?Js.OBJECT:Js.NONE,t})();let i=this.levelNode;null===i&&e.context.getTextureLevel&&(i=e.context.getTextureLevel(this));let n=null,a=null;null!==this.compareNode&&(e.renderer.hasCompatibility(E.TEXTURE_COMPARE)?n=this.compareNode:(null!==this.value.compareFunction&&this.value.compareFunction!==A&&v('TSL: Only "LessCompare" is supported for depth texture comparison fallback.'),a=this.compareNode)),t.uvNode=s,t.levelNode=i,t.biasNode=this.biasNode,t.compareNode=n,t.compareStepNode=a,t.gradNode=this.gradNode,t.depthNode=this.depthNode,t.offsetNode=this.offsetNode}generateUV(e,t){return t.build(e,!0===this.sampler?"vec2":"ivec2")}generateOffset(e,t){return t.build(e,"ivec2")}generateSnippet(e,t,r,s,i,n,a,o,u){const l=this.value;let d;return d=i?e.generateTextureBias(l,t,r,i,n,u):o?e.generateTextureGrad(l,t,r,o,n,u):a?e.generateTextureCompare(l,t,r,a,n,u):!1===this.sampler?e.generateTextureLoad(l,t,r,s,n,u):s?e.generateTextureLevel(l,t,r,s,n,u):e.generateTexture(l,t,r,n,u),d}generate(e,t){const r=this.value,s=e.getNodeProperties(this),i=super.generate(e,"property");if(/^sampler/.test(t))return i+"_sampler";if(e.isReference(t))return i;{const n=e.getDataFromNode(this),a=this.getNodeType(e);let o=n.propertyName;if(void 0===o){const{uvNode:t,levelNode:r,biasNode:u,compareNode:l,compareStepNode:d,depthNode:c,gradNode:h,offsetNode:p}=s,g=this.generateUV(e,t),m=r?r.build(e,"float"):null,f=u?u.build(e,"float"):null,y=c?c.build(e,"int"):null,b=l?l.build(e,"float"):null,x=d?d.build(e,"float"):null,T=h?[h[0].build(e,"vec2"),h[1].build(e,"vec2")]:null,_=p?this.generateOffset(e,p):null,v=e.getVarFromNode(this);o=e.getPropertyName(v);let N=this.generateSnippet(e,i,g,m,f,y,b,T,_);null!==x&&(N=qo(gl(x,"float"),gl(N,a)).build(e,a)),e.addLineFlowCode(`${o} = ${N}`,this),n.snippet=N,n.propertyName=o}let u=o;return e.needsToWorkingColorSpace(r)&&(u=Gu(gl(u,a),r.colorSpace).setup(e).build(e,a)),e.format(u,a,t)}}setSampler(e){return this.sampler=e,this}getSampler(){return this.sampler}sample(e){const t=this.clone();return t.uvNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}load(e){return this.sample(e).setSampler(!1)}blur(e){const t=this.clone();t.biasNode=Zi(e).mul(Cl(t)),t.referenceNode=this.getBase();const r=t.value;return!1===t.generateMipmaps&&(r&&!1===r.generateMipmaps||r.minFilter===w||r.magFilter===w)&&(d("TSL: texture().blur() requires mipmaps and sampling. Use .generateMipmaps=true and .minFilter/.magFilter=THREE.LinearFilter in the Texture."),t.biasNode=null),Zi(t)}level(e){const t=this.clone();return t.levelNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}size(e){return Al(this,e)}bias(e){const t=this.clone();return t.biasNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}getBase(){return this.referenceNode?this.referenceNode.getBase():this}compare(e){const t=this.clone();return t.compareNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}grad(e,t){const r=this.clone();return r.gradNode=[Zi(e),Zi(t)],r.referenceNode=this.getBase(),Zi(r)}depth(e){const t=this.clone();return t.depthNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}offset(e){const t=this.clone();return t.offsetNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}serialize(e){super.serialize(e),e.value=this.value.toJSON(e.meta).uuid,e.sampler=this.sampler,e.updateMatrix=this.updateMatrix,e.updateType=this.updateType}deserialize(e){super.deserialize(e),this.value=e.meta.textures[e.value],this.sampler=e.sampler,this.updateMatrix=e.updateMatrix,this.updateType=e.updateType}update(){const e=this.value,t=this._matrixUniform;null!==t&&(t.value=e.matrix),!0===e.matrixAutoUpdate&&e.updateMatrix();const r=this._flipYUniform;null!==r&&(r.value=e.image instanceof ImageBitmap&&!0===e.flipY||!0===e.isRenderTargetTexture||!0===e.isFramebufferTexture||!0===e.isDepthTexture)}clone(){const e=new this.constructor(this.value,this.uvNode,this.levelNode,this.biasNode);return e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e}}const Ll=rn(Fl).setParameterLength(1,4).setName("texture"),Pl=(e=Ml,t=null,r=null,s=null)=>{let i;return e&&!0===e.isTextureNode?(i=Zi(e.clone()),i.referenceNode=e.getBase(),null!==t&&(i.uvNode=Zi(t)),null!==r&&(i.levelNode=Zi(r)),null!==s&&(i.biasNode=Zi(s))):i=Ll(e,t,r,s),i},Bl=(...e)=>Pl(...e).setSampler(!1);class Dl extends Ta{static get type(){return"BufferNode"}constructor(e,t,r=0){super(e,t),this.isBufferNode=!0,this.bufferType=t,this.bufferCount=r,this.updateRanges=[]}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}getElementType(e){return this.getNodeType(e)}getInputType(){return"buffer"}}const Ul=(e,t,r)=>new Dl(e,t,r);class Il extends li{static get type(){return"UniformArrayElementNode"}constructor(e,t){super(e,t),this.isArrayBufferElementNode=!0}generate(e){const t=super.generate(e),r=this.getNodeType(),s=this.node.getPaddedType();return e.format(t,s,r)}}class Ol extends Dl{static get type(){return"UniformArrayNode"}constructor(e,t=null){super(null),this.array=e,this.elementType=null===t?qs(e[0]):t,this.paddedType=this.getPaddedType(),this.updateType=Js.RENDER,this.isArrayBufferNode=!0}getNodeType(){return this.paddedType}getElementType(){return this.elementType}getPaddedType(){const e=this.elementType;let t="vec4";return"mat2"===e?t="mat2":!0===/mat/.test(e)?t="mat4":"i"===e.charAt(0)?t="ivec4":"u"===e.charAt(0)&&(t="uvec4"),t}update(){const{array:e,value:t}=this,r=this.elementType;if("float"===r||"int"===r||"uint"===r)for(let r=0;rnew Ol(e,t);class kl extends ui{constructor(e){super("float"),this.name=e,this.isBuiltinNode=!0}generate(){return this.name}}const Gl=rn(kl).setParameterLength(1);let zl,$l;class Wl extends ui{static get type(){return"ScreenNode"}constructor(e){super(),this.scope=e,this._output=null,this.isViewportNode=!0}getNodeType(){return this.scope===Wl.DPR?"float":this.scope===Wl.VIEWPORT?"vec4":"vec2"}getUpdateType(){let e=Js.NONE;return this.scope!==Wl.SIZE&&this.scope!==Wl.VIEWPORT&&this.scope!==Wl.DPR||(e=Js.RENDER),this.updateType=e,e}update({renderer:e}){const t=e.getRenderTarget();this.scope===Wl.VIEWPORT?null!==t?$l.copy(t.viewport):(e.getViewport($l),$l.multiplyScalar(e.getPixelRatio())):this.scope===Wl.DPR?this._output.value=e.getPixelRatio():null!==t?(zl.width=t.width,zl.height=t.height):e.getDrawingBufferSize(zl)}setup(){const e=this.scope;let r=null;return r=e===Wl.SIZE?_a(zl||(zl=new t)):e===Wl.VIEWPORT?_a($l||($l=new s)):e===Wl.DPR?_a(1):bn(Xl.div(jl)),this._output=r,r}generate(e){if(this.scope===Wl.COORDINATE){let t=e.getFragCoord();if(e.isFlipY()){const r=e.getNodeProperties(jl).outputNode.build(e);t=`${e.getType("vec2")}( ${t}.x, ${r}.y - ${t}.y )`}return t}return super.generate(e)}}Wl.COORDINATE="coordinate",Wl.VIEWPORT="viewport",Wl.SIZE="size",Wl.UV="uv",Wl.DPR="dpr";const Hl=sn(Wl,Wl.DPR),ql=sn(Wl,Wl.UV),jl=sn(Wl,Wl.SIZE),Xl=sn(Wl,Wl.COORDINATE),Kl=sn(Wl,Wl.VIEWPORT),Yl=Kl.zw,Ql=Xl.sub(Kl.xy),Zl=Ql.div(Yl),Jl=un(()=>(d('TSL: "viewportResolution" is deprecated. Use "screenSize" instead.'),jl),"vec2").once()(),ed=_a(0,"uint").setName("u_cameraIndex").setGroup(fa("cameraIndex")).toVarying("v_cameraIndex"),td=_a("float").setName("cameraNear").setGroup(ba).onRenderUpdate(({camera:e})=>e.near),rd=_a("float").setName("cameraFar").setGroup(ba).onRenderUpdate(({camera:e})=>e.far),sd=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.projectionMatrix);t=Vl(r).setGroup(ba).setName("cameraProjectionMatrices").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraProjectionMatrix")}else t=_a("mat4").setName("cameraProjectionMatrix").setGroup(ba).onRenderUpdate(({camera:e})=>e.projectionMatrix);return t}).once()(),id=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.projectionMatrixInverse);t=Vl(r).setGroup(ba).setName("cameraProjectionMatricesInverse").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraProjectionMatrixInverse")}else t=_a("mat4").setName("cameraProjectionMatrixInverse").setGroup(ba).onRenderUpdate(({camera:e})=>e.projectionMatrixInverse);return t}).once()(),nd=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.matrixWorldInverse);t=Vl(r).setGroup(ba).setName("cameraViewMatrices").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraViewMatrix")}else t=_a("mat4").setName("cameraViewMatrix").setGroup(ba).onRenderUpdate(({camera:e})=>e.matrixWorldInverse);return t}).once()(),ad=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.matrixWorld);t=Vl(r).setGroup(ba).setName("cameraWorldMatrices").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraWorldMatrix")}else t=_a("mat4").setName("cameraWorldMatrix").setGroup(ba).onRenderUpdate(({camera:e})=>e.matrixWorld);return t}).once()(),od=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.normalMatrix);t=Vl(r).setGroup(ba).setName("cameraNormalMatrices").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraNormalMatrix")}else t=_a("mat3").setName("cameraNormalMatrix").setGroup(ba).onRenderUpdate(({camera:e})=>e.normalMatrix);return t}).once()(),ud=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const s=[];for(let t=0,i=e.cameras.length;t{const r=e.cameras,s=t.array;for(let e=0,t=r.length;et.value.setFromMatrixPosition(e.matrixWorld));return t}).once()(),ld=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.viewport);t=Vl(r,"vec4").setGroup(ba).setName("cameraViewports").element(ed).toConst("cameraViewport")}else t=En(0,0,jl.x,jl.y).toConst("cameraViewport");return t}).once()(),dd=new C;class cd extends ui{static get type(){return"Object3DNode"}constructor(e,t=null){super(),this.scope=e,this.object3d=t,this.updateType=Js.OBJECT,this.uniformNode=new Ta(null)}getNodeType(){const e=this.scope;return e===cd.WORLD_MATRIX?"mat4":e===cd.POSITION||e===cd.VIEW_POSITION||e===cd.DIRECTION||e===cd.SCALE?"vec3":e===cd.RADIUS?"float":void 0}update(e){const t=this.object3d,s=this.uniformNode,i=this.scope;if(i===cd.WORLD_MATRIX)s.value=t.matrixWorld;else if(i===cd.POSITION)s.value=s.value||new r,s.value.setFromMatrixPosition(t.matrixWorld);else if(i===cd.SCALE)s.value=s.value||new r,s.value.setFromMatrixScale(t.matrixWorld);else if(i===cd.DIRECTION)s.value=s.value||new r,t.getWorldDirection(s.value);else if(i===cd.VIEW_POSITION){const i=e.camera;s.value=s.value||new r,s.value.setFromMatrixPosition(t.matrixWorld),s.value.applyMatrix4(i.matrixWorldInverse)}else if(i===cd.RADIUS){const r=e.object.geometry;null===r.boundingSphere&&r.computeBoundingSphere(),dd.copy(r.boundingSphere).applyMatrix4(t.matrixWorld),s.value=dd.radius}}generate(e){const t=this.scope;return t===cd.WORLD_MATRIX?this.uniformNode.nodeType="mat4":t===cd.POSITION||t===cd.VIEW_POSITION||t===cd.DIRECTION||t===cd.SCALE?this.uniformNode.nodeType="vec3":t===cd.RADIUS&&(this.uniformNode.nodeType="float"),this.uniformNode.build(e)}serialize(e){super.serialize(e),e.scope=this.scope}deserialize(e){super.deserialize(e),this.scope=e.scope}}cd.WORLD_MATRIX="worldMatrix",cd.POSITION="position",cd.SCALE="scale",cd.VIEW_POSITION="viewPosition",cd.DIRECTION="direction",cd.RADIUS="radius";const hd=rn(cd,cd.DIRECTION).setParameterLength(1),pd=rn(cd,cd.WORLD_MATRIX).setParameterLength(1),gd=rn(cd,cd.POSITION).setParameterLength(1),md=rn(cd,cd.SCALE).setParameterLength(1),fd=rn(cd,cd.VIEW_POSITION).setParameterLength(1),yd=rn(cd,cd.RADIUS).setParameterLength(1);class bd extends cd{static get type(){return"ModelNode"}constructor(e){super(e)}update(e){this.object3d=e.object,super.update(e)}}const xd=sn(bd,bd.DIRECTION),Td=sn(bd,bd.WORLD_MATRIX),_d=sn(bd,bd.POSITION),vd=sn(bd,bd.SCALE),Nd=sn(bd,bd.VIEW_POSITION),Sd=sn(bd,bd.RADIUS),Rd=_a(new n).onObjectUpdate(({object:e},t)=>t.value.getNormalMatrix(e.matrixWorld)),Ed=_a(new a).onObjectUpdate(({object:e},t)=>t.value.copy(e.matrixWorld).invert()),Ad=un(e=>e.context.modelViewMatrix||wd).once()().toVar("modelViewMatrix"),wd=nd.mul(Td),Cd=un(e=>(e.context.isHighPrecisionModelViewMatrix=!0,_a("mat4").onObjectUpdate(({object:e,camera:t})=>e.modelViewMatrix.multiplyMatrices(t.matrixWorldInverse,e.matrixWorld)))).once()().toVar("highpModelViewMatrix"),Md=un(e=>{const t=e.context.isHighPrecisionModelViewMatrix;return _a("mat3").onObjectUpdate(({object:e,camera:r})=>(!0!==t&&e.modelViewMatrix.multiplyMatrices(r.matrixWorldInverse,e.matrixWorld),e.normalMatrix.getNormalMatrix(e.modelViewMatrix)))}).once()().toVar("highpModelNormalViewMatrix"),Fd=un(e=>"fragment"!==e.shaderStage?(v("TSL: `clipSpace` is only available in fragment stage."),En()):e.context.clipSpace.toVarying("v_clipSpace")).once()(),Ld=Sl("position","vec3"),Pd=Ld.toVarying("positionLocal"),Bd=Ld.toVarying("positionPrevious"),Dd=un(e=>Td.mul(Pd).xyz.toVarying(e.getSubBuildProperty("v_positionWorld")),"vec3").once(["POSITION"])(),Ud=un(()=>Pd.transformDirection(Td).toVarying("v_positionWorldDirection").normalize().toVar("positionWorldDirection"),"vec3").once(["POSITION"])(),Id=un(e=>{if("fragment"===e.shaderStage&&e.material.vertexNode){const e=id.mul(Fd);return e.xyz.div(e.w).toVar("positionView")}return e.context.setupPositionView().toVarying("v_positionView")},"vec3").once(["POSITION","VERTEX"])(),Od=un(e=>{let t;return t=e.camera.isOrthographicCamera?vn(0,0,1):Id.negate().toVarying("v_positionViewDirection").normalize(),t.toVar("positionViewDirection")},"vec3").once(["POSITION"])();class Vd extends ui{static get type(){return"FrontFacingNode"}constructor(){super("bool"),this.isFrontFacingNode=!0}generate(e){if("fragment"!==e.shaderStage)return"true";const{material:t}=e;return t.side===M?"false":e.getFrontFacing()}}const kd=sn(Vd),Gd=gn(kd).mul(2).sub(1),zd=un(([e],{material:t})=>{const r=t.side;return r===M?e=e.mul(-1):r===F&&(e=e.mul(Gd)),e}),$d=Sl("normal","vec3"),Wd=un(e=>!1===e.geometry.hasAttribute("normal")?(d('TSL: Vertex attribute "normal" not found on geometry.'),vn(0,1,0)):$d,"vec3").once()().toVar("normalLocal"),Hd=Id.dFdx().cross(Id.dFdy()).normalize().toVar("normalFlat"),qd=un(e=>{let t;return t=e.isFlatShading()?Hd:Zd(Wd).toVarying("v_normalViewGeometry").normalize(),t},"vec3").once()().toVar("normalViewGeometry"),jd=un(e=>{let t=qd.transformDirection(nd);return!0!==e.isFlatShading()&&(t=t.toVarying("v_normalWorldGeometry")),t.normalize().toVar("normalWorldGeometry")},"vec3").once()(),Xd=un(e=>{let t;return"NORMAL"===e.subBuildFn||"VERTEX"===e.subBuildFn?(t=qd,!0!==e.isFlatShading()&&(t=zd(t))):t=e.context.setupNormal().context({getUV:null}),t},"vec3").once(["NORMAL","VERTEX"])().toVar("normalView"),Kd=Xd.transformDirection(nd).toVar("normalWorld"),Yd=un(({subBuildFn:e,context:t})=>{let r;return r="NORMAL"===e||"VERTEX"===e?Xd:t.setupClearcoatNormal().context({getUV:null}),r},"vec3").once(["NORMAL","VERTEX"])().toVar("clearcoatNormalView"),Qd=un(([e,t=Td])=>{const r=Fn(t),s=e.div(vn(r[0].dot(r[0]),r[1].dot(r[1]),r[2].dot(r[2])));return r.mul(s).xyz}),Zd=un(([e],t)=>{const r=t.context.modelNormalViewMatrix;if(r)return r.transformDirection(e);const s=Rd.mul(e);return nd.transformDirection(s)}),Jd=un(()=>(d('TSL: "transformedNormalView" is deprecated. Use "normalView" instead.'),Xd)).once(["NORMAL","VERTEX"])(),ec=un(()=>(d('TSL: "transformedNormalWorld" is deprecated. Use "normalWorld" instead.'),Kd)).once(["NORMAL","VERTEX"])(),tc=un(()=>(d('TSL: "transformedClearcoatNormalView" is deprecated. Use "clearcoatNormalView" instead.'),Yd)).once(["NORMAL","VERTEX"])(),rc=new L,sc=new a,ic=_a(0).onReference(({material:e})=>e).onObjectUpdate(({material:e})=>e.refractionRatio),nc=_a(1).onReference(({material:e})=>e).onObjectUpdate(function({material:e,scene:t}){return e.envMap?e.envMapIntensity:t.environmentIntensity}),ac=_a(new a).onReference(function(e){return e.material}).onObjectUpdate(function({material:e,scene:t}){const r=null!==t.environment&&null===e.envMap?t.environmentRotation:e.envMapRotation;return r?(rc.copy(r),sc.makeRotationFromEuler(rc)):sc.identity(),sc}),oc=Od.negate().reflect(Xd),uc=Od.negate().refract(Xd,ic),lc=oc.transformDirection(nd).toVar("reflectVector"),dc=uc.transformDirection(nd).toVar("reflectVector"),cc=new P;class hc extends Fl{static get type(){return"CubeTextureNode"}constructor(e,t=null,r=null,s=null){super(e,t,r,s),this.isCubeTextureNode=!0}getInputType(){return!0===this.value.isDepthTexture?"cubeDepthTexture":"cubeTexture"}getDefaultUV(){const e=this.value;return e.mapping===B?lc:e.mapping===D?dc:(o('CubeTextureNode: Mapping "%s" not supported.',e.mapping),vn(0,0,0))}setUpdateMatrix(){}setupUV(e,t){const r=this.value;return!0===r.isDepthTexture?e.renderer.coordinateSystem===h?vn(t.x,t.y.negate(),t.z):t:(e.renderer.coordinateSystem!==h&&r.isRenderTargetTexture||(t=vn(t.x.negate(),t.yz)),ac.mul(t))}generateUV(e,t){return t.build(e,!0===this.sampler?"vec3":"ivec3")}}const pc=rn(hc).setParameterLength(1,4).setName("cubeTexture"),gc=(e=cc,t=null,r=null,s=null)=>{let i;return e&&!0===e.isCubeTextureNode?(i=Zi(e.clone()),i.referenceNode=e,null!==t&&(i.uvNode=Zi(t)),null!==r&&(i.levelNode=Zi(r)),null!==s&&(i.biasNode=Zi(s))):i=pc(e,t,r,s),i};class mc extends li{static get type(){return"ReferenceElementNode"}constructor(e,t){super(e,t),this.referenceNode=e,this.isReferenceElementNode=!0}getNodeType(){return this.referenceNode.uniformType}generate(e){const t=super.generate(e),r=this.referenceNode.getNodeType(),s=this.getNodeType();return e.format(t,r,s)}}class fc extends ui{static get type(){return"ReferenceNode"}constructor(e,t,r=null,s=null){super(),this.property=e,this.uniformType=t,this.object=r,this.count=s,this.properties=e.split("."),this.reference=r,this.node=null,this.group=null,this.name=null,this.updateType=Js.OBJECT}element(e){return new mc(this,Zi(e))}setGroup(e){return this.group=e,this}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setNodeType(e){let t=null;t=null!==this.count?Ul(null,e,this.count):Array.isArray(this.getValueFromReference())?Vl(null,e):"texture"===e?Pl(null):"cubeTexture"===e?gc(null):_a(null,e),null!==this.group&&t.setGroup(this.group),null!==this.name&&t.setName(this.name),this.node=t}getNodeType(e){return null===this.node&&(this.updateReference(e),this.updateValue()),this.node.getNodeType(e)}getValueFromReference(e=this.reference){const{properties:t}=this;let r=e[t[0]];for(let e=1;enew fc(e,t,r),bc=(e,t,r,s)=>new fc(e,t,s,r);class xc extends fc{static get type(){return"MaterialReferenceNode"}constructor(e,t,r=null){super(e,t,r),this.material=r,this.isMaterialReferenceNode=!0}updateReference(e){return this.reference=null!==this.material?this.material:e.material,this.reference}}const Tc=(e,t,r=null)=>new xc(e,t,r),_c=Rl(),vc=Id.dFdx(),Nc=Id.dFdy(),Sc=_c.dFdx(),Rc=_c.dFdy(),Ec=Xd,Ac=Nc.cross(Ec),wc=Ec.cross(vc),Cc=Ac.mul(Sc.x).add(wc.mul(Rc.x)),Mc=Ac.mul(Sc.y).add(wc.mul(Rc.y)),Fc=Cc.dot(Cc).max(Mc.dot(Mc)),Lc=Fc.equal(0).select(0,Fc.inverseSqrt()),Pc=Cc.mul(Lc).toVar("tangentViewFrame"),Bc=Mc.mul(Lc).toVar("bitangentViewFrame"),Dc=Sl("tangent","vec4"),Uc=Dc.xyz.toVar("tangentLocal"),Ic=un(e=>{let t;return t="VERTEX"===e.subBuildFn||e.geometry.hasAttribute("tangent")?Ad.mul(En(Uc,0)).xyz.toVarying("v_tangentView").normalize():Pc,!0!==e.isFlatShading()&&(t=zd(t)),t},"vec3").once(["NORMAL","VERTEX"])().toVar("tangentView"),Oc=Ic.transformDirection(nd).toVarying("v_tangentWorld").normalize().toVar("tangentWorld"),Vc=un(([e,t],r)=>{let s=e.mul(Dc.w).xyz;return"NORMAL"===r.subBuildFn&&!0!==r.isFlatShading()&&(s=s.toVarying(t)),s}).once(["NORMAL"]),kc=Vc($d.cross(Dc),"v_bitangentGeometry").normalize().toVar("bitangentGeometry"),Gc=Vc(Wd.cross(Uc),"v_bitangentLocal").normalize().toVar("bitangentLocal"),zc=un(e=>{let t;return t="VERTEX"===e.subBuildFn||e.geometry.hasAttribute("tangent")?Vc(Xd.cross(Ic),"v_bitangentView").normalize():Bc,!0!==e.isFlatShading()&&(t=zd(t)),t},"vec3").once(["NORMAL","VERTEX"])().toVar("bitangentView"),$c=Vc(Kd.cross(Oc),"v_bitangentWorld").normalize().toVar("bitangentWorld"),Wc=Fn(Ic,zc,Xd).toVar("TBNViewMatrix"),Hc=Od.mul(Wc),qc=un(()=>{let e=Jn.cross(Od);return e=e.cross(Jn).normalize(),e=nu(e,Xd,Qn.mul(Gn.oneMinus()).oneMinus().pow2().pow2()).normalize(),e}).once()(),jc=e=>Zi(e).mul(.5).add(.5),Xc=e=>vn(e,bo(ou(gn(1).sub(Yo(e,e)))));class Kc extends ci{static get type(){return"NormalMapNode"}constructor(e,t=null){super("vec3"),this.node=e,this.scaleNode=t,this.normalMapType=U,this.unpackNormalMode=I}setup(e){const{normalMapType:t,scaleNode:r,unpackNormalMode:s}=this;let i=this.node.mul(2).sub(1);if(t===U?s===O?i=Xc(i.xy):s===V?i=Xc(i.yw):s!==I&&console.error(`THREE.NodeMaterial: Unexpected unpack normal mode: ${s}`):s!==I&&console.error(`THREE.NodeMaterial: Normal map type '${t}' is not compatible with unpack normal mode '${s}'`),null!==r){let t=r;!0===e.isFlatShading()&&(t=zd(t)),i=vn(i.xy.mul(t),i.z)}let n=null;return t===k?n=Zd(i):t===U?n=Wc.mul(i).normalize():(o(`NodeMaterial: Unsupported normal map type: ${t}`),n=Xd),n}}const Yc=rn(Kc).setParameterLength(1,2),Qc=un(({textureNode:e,bumpScale:t})=>{const r=t=>e.isolate().context({getUV:e=>t(e.uvNode||Rl()),forceUVContext:!0}),s=gn(r(e=>e));return bn(gn(r(e=>e.add(e.dFdx()))).sub(s),gn(r(e=>e.add(e.dFdy()))).sub(s)).mul(t)}),Zc=un(e=>{const{surf_pos:t,surf_norm:r,dHdxy:s}=e,i=t.dFdx().normalize(),n=r,a=t.dFdy().normalize().cross(n),o=n.cross(i),u=i.dot(a).mul(Gd),l=u.sign().mul(s.x.mul(a).add(s.y.mul(o)));return u.abs().mul(r).sub(l).normalize()});class Jc extends ci{static get type(){return"BumpMapNode"}constructor(e,t=null){super("vec3"),this.textureNode=e,this.scaleNode=t}setup(){const e=null!==this.scaleNode?this.scaleNode:1,t=Qc({textureNode:this.textureNode,bumpScale:e});return Zc({surf_pos:Id,surf_norm:Xd,dHdxy:t})}}const eh=rn(Jc).setParameterLength(1,2),th=new Map;class rh extends ui{static get type(){return"MaterialNode"}constructor(e){super(),this.scope=e}getCache(e,t){let r=th.get(e);return void 0===r&&(r=Tc(e,t),th.set(e,r)),r}getFloat(e){return this.getCache(e,"float")}getColor(e){return this.getCache(e,"color")}getTexture(e){return this.getCache("map"===e?"map":e+"Map","texture")}setup(e){const t=e.context.material,r=this.scope;let s=null;if(r===rh.COLOR){const e=void 0!==t.color?this.getColor(r):vn();s=t.map&&!0===t.map.isTexture?e.mul(this.getTexture("map")):e}else if(r===rh.OPACITY){const e=this.getFloat(r);s=t.alphaMap&&!0===t.alphaMap.isTexture?e.mul(this.getTexture("alpha")):e}else if(r===rh.SPECULAR_STRENGTH)s=t.specularMap&&!0===t.specularMap.isTexture?this.getTexture("specular").r:gn(1);else if(r===rh.SPECULAR_INTENSITY){const e=this.getFloat(r);s=t.specularIntensityMap&&!0===t.specularIntensityMap.isTexture?e.mul(this.getTexture(r).a):e}else if(r===rh.SPECULAR_COLOR){const e=this.getColor(r);s=t.specularColorMap&&!0===t.specularColorMap.isTexture?e.mul(this.getTexture(r).rgb):e}else if(r===rh.ROUGHNESS){const e=this.getFloat(r);s=t.roughnessMap&&!0===t.roughnessMap.isTexture?e.mul(this.getTexture(r).g):e}else if(r===rh.METALNESS){const e=this.getFloat(r);s=t.metalnessMap&&!0===t.metalnessMap.isTexture?e.mul(this.getTexture(r).b):e}else if(r===rh.EMISSIVE){const e=this.getFloat("emissiveIntensity"),i=this.getColor(r).mul(e);s=t.emissiveMap&&!0===t.emissiveMap.isTexture?i.mul(this.getTexture(r)):i}else if(r===rh.NORMAL)t.normalMap?(s=Yc(this.getTexture("normal"),this.getCache("normalScale","vec2")),s.normalMapType=t.normalMapType,t.normalMap.format!=G&&t.normalMap.format!=z&&t.normalMap.format!=$||(s.unpackNormalMode=O)):s=t.bumpMap?eh(this.getTexture("bump").r,this.getFloat("bumpScale")):Xd;else if(r===rh.CLEARCOAT){const e=this.getFloat(r);s=t.clearcoatMap&&!0===t.clearcoatMap.isTexture?e.mul(this.getTexture(r).r):e}else if(r===rh.CLEARCOAT_ROUGHNESS){const e=this.getFloat(r);s=t.clearcoatRoughnessMap&&!0===t.clearcoatRoughnessMap.isTexture?e.mul(this.getTexture(r).r):e}else if(r===rh.CLEARCOAT_NORMAL)s=t.clearcoatNormalMap?Yc(this.getTexture(r),this.getCache(r+"Scale","vec2")):Xd;else if(r===rh.SHEEN){const e=this.getColor("sheenColor").mul(this.getFloat("sheen"));s=t.sheenColorMap&&!0===t.sheenColorMap.isTexture?e.mul(this.getTexture("sheenColor").rgb):e}else if(r===rh.SHEEN_ROUGHNESS){const e=this.getFloat(r);s=t.sheenRoughnessMap&&!0===t.sheenRoughnessMap.isTexture?e.mul(this.getTexture(r).a):e,s=s.clamp(1e-4,1)}else if(r===rh.ANISOTROPY)if(t.anisotropyMap&&!0===t.anisotropyMap.isTexture){const e=this.getTexture(r);s=Mn(kh.x,kh.y,kh.y.negate(),kh.x).mul(e.rg.mul(2).sub(bn(1)).normalize().mul(e.b))}else s=kh;else if(r===rh.IRIDESCENCE_THICKNESS){const e=yc("1","float",t.iridescenceThicknessRange);if(t.iridescenceThicknessMap){const i=yc("0","float",t.iridescenceThicknessRange);s=e.sub(i).mul(this.getTexture(r).g).add(i)}else s=e}else if(r===rh.TRANSMISSION){const e=this.getFloat(r);s=t.transmissionMap?e.mul(this.getTexture(r).r):e}else if(r===rh.THICKNESS){const e=this.getFloat(r);s=t.thicknessMap?e.mul(this.getTexture(r).g):e}else if(r===rh.IOR)s=this.getFloat(r);else if(r===rh.LIGHT_MAP)s=this.getTexture(r).rgb.mul(this.getFloat("lightMapIntensity"));else if(r===rh.AO)s=this.getTexture(r).r.sub(1).mul(this.getFloat("aoMapIntensity")).add(1);else if(r===rh.LINE_DASH_OFFSET)s=t.dashOffset?this.getFloat(r):gn(0);else{const t=this.getNodeType(e);s=this.getCache(r,t)}return s}}rh.ALPHA_TEST="alphaTest",rh.COLOR="color",rh.OPACITY="opacity",rh.SHININESS="shininess",rh.SPECULAR="specular",rh.SPECULAR_STRENGTH="specularStrength",rh.SPECULAR_INTENSITY="specularIntensity",rh.SPECULAR_COLOR="specularColor",rh.REFLECTIVITY="reflectivity",rh.ROUGHNESS="roughness",rh.METALNESS="metalness",rh.NORMAL="normal",rh.CLEARCOAT="clearcoat",rh.CLEARCOAT_ROUGHNESS="clearcoatRoughness",rh.CLEARCOAT_NORMAL="clearcoatNormal",rh.EMISSIVE="emissive",rh.ROTATION="rotation",rh.SHEEN="sheen",rh.SHEEN_ROUGHNESS="sheenRoughness",rh.ANISOTROPY="anisotropy",rh.IRIDESCENCE="iridescence",rh.IRIDESCENCE_IOR="iridescenceIOR",rh.IRIDESCENCE_THICKNESS="iridescenceThickness",rh.IOR="ior",rh.TRANSMISSION="transmission",rh.THICKNESS="thickness",rh.ATTENUATION_DISTANCE="attenuationDistance",rh.ATTENUATION_COLOR="attenuationColor",rh.LINE_SCALE="scale",rh.LINE_DASH_SIZE="dashSize",rh.LINE_GAP_SIZE="gapSize",rh.LINE_WIDTH="linewidth",rh.LINE_DASH_OFFSET="dashOffset",rh.POINT_SIZE="size",rh.DISPERSION="dispersion",rh.LIGHT_MAP="light",rh.AO="ao";const sh=sn(rh,rh.ALPHA_TEST),ih=sn(rh,rh.COLOR),nh=sn(rh,rh.SHININESS),ah=sn(rh,rh.EMISSIVE),oh=sn(rh,rh.OPACITY),uh=sn(rh,rh.SPECULAR),lh=sn(rh,rh.SPECULAR_INTENSITY),dh=sn(rh,rh.SPECULAR_COLOR),ch=sn(rh,rh.SPECULAR_STRENGTH),hh=sn(rh,rh.REFLECTIVITY),ph=sn(rh,rh.ROUGHNESS),gh=sn(rh,rh.METALNESS),mh=sn(rh,rh.NORMAL),fh=sn(rh,rh.CLEARCOAT),yh=sn(rh,rh.CLEARCOAT_ROUGHNESS),bh=sn(rh,rh.CLEARCOAT_NORMAL),xh=sn(rh,rh.ROTATION),Th=sn(rh,rh.SHEEN),_h=sn(rh,rh.SHEEN_ROUGHNESS),vh=sn(rh,rh.ANISOTROPY),Nh=sn(rh,rh.IRIDESCENCE),Sh=sn(rh,rh.IRIDESCENCE_IOR),Rh=sn(rh,rh.IRIDESCENCE_THICKNESS),Eh=sn(rh,rh.TRANSMISSION),Ah=sn(rh,rh.THICKNESS),wh=sn(rh,rh.IOR),Ch=sn(rh,rh.ATTENUATION_DISTANCE),Mh=sn(rh,rh.ATTENUATION_COLOR),Fh=sn(rh,rh.LINE_SCALE),Lh=sn(rh,rh.LINE_DASH_SIZE),Ph=sn(rh,rh.LINE_GAP_SIZE),Bh=sn(rh,rh.LINE_WIDTH),Dh=sn(rh,rh.LINE_DASH_OFFSET),Uh=sn(rh,rh.POINT_SIZE),Ih=sn(rh,rh.DISPERSION),Oh=sn(rh,rh.LIGHT_MAP),Vh=sn(rh,rh.AO),kh=_a(new t).onReference(function(e){return e.material}).onRenderUpdate(function({material:e}){this.value.set(e.anisotropy*Math.cos(e.anisotropyRotation),e.anisotropy*Math.sin(e.anisotropyRotation))}),Gh=un(e=>e.context.setupModelViewProjection(),"vec4").once()().toVarying("v_modelViewProjection");class zh extends li{static get type(){return"StorageArrayElementNode"}constructor(e,t){super(e,t),this.isStorageArrayElementNode=!0}set storageBufferNode(e){this.node=e}get storageBufferNode(){return this.node}getMemberType(e,t){const r=this.storageBufferNode.structTypeNode;return r?r.getMemberType(e,t):"void"}setup(e){return!1===e.isAvailable("storageBuffer")&&!0===this.node.isPBO&&e.setupPBO(this.node),super.setup(e)}generate(e,t){let r;const s=e.context.assign;if(r=!1===e.isAvailable("storageBuffer")?!0!==this.node.isPBO||!0===s||!this.node.value.isInstancedBufferAttribute&&"compute"===e.shaderStage?this.node.build(e):e.generatePBO(this):super.generate(e),!0!==s){const s=this.getNodeType(e);r=e.format(r,s,t)}return r}}const $h=rn(zh).setParameterLength(2);class Wh extends Dl{static get type(){return"StorageBufferNode"}constructor(e,t=null,r=0){let s,i=null;t&&t.isStruct?(s="struct",i=t.layout,(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute)&&(r=e.count)):null===t&&(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute)?(s=Gs(e.itemSize),r=e.count):s=t,super(e,s,r),this.isStorageBufferNode=!0,this.structTypeNode=i,this.access=ti.READ_WRITE,this.isAtomic=!1,this.isPBO=!1,this._attribute=null,this._varying=null,this.global=!0,!0!==e.isStorageBufferAttribute&&!0!==e.isStorageInstancedBufferAttribute&&(e.isInstancedBufferAttribute?e.isStorageInstancedBufferAttribute=!0:e.isStorageBufferAttribute=!0)}getHash(e){if(0===this.bufferCount){let t=e.globalCache.getData(this.value);return void 0===t&&(t={node:this},e.globalCache.setData(this.value,t)),t.node.uuid}return this.uuid}getInputType(){return this.value.isIndirectStorageBufferAttribute?"indirectStorageBuffer":"storageBuffer"}element(e){return $h(this,e)}setPBO(e){return this.isPBO=e,this}getPBO(){return this.isPBO}setAccess(e){return this.access=e,this}toReadOnly(){return this.setAccess(ti.READ_ONLY)}setAtomic(e){return this.isAtomic=e,this}toAtomic(){return this.setAtomic(!0)}getAttributeData(){return null===this._attribute&&(this._attribute=Ju(this.value),this._varying=Bu(this._attribute)),{attribute:this._attribute,varying:this._varying}}getNodeType(e){if(null!==this.structTypeNode)return this.structTypeNode.getNodeType(e);if(e.isAvailable("storageBuffer")||e.isAvailable("indirectStorageBuffer"))return super.getNodeType(e);const{attribute:t}=this.getAttributeData();return t.getNodeType(e)}getMemberType(e,t){return null!==this.structTypeNode?this.structTypeNode.getMemberType(e,t):"void"}generate(e){if(null!==this.structTypeNode&&this.structTypeNode.build(e),e.isAvailable("storageBuffer")||e.isAvailable("indirectStorageBuffer"))return super.generate(e);const{attribute:t,varying:r}=this.getAttributeData(),s=r.build(e);return e.registerTransform(s,t),s}}const Hh=(e,t=null,r=0)=>new Wh(e,t,r);class qh extends ui{static get type(){return"IndexNode"}constructor(e){super("uint"),this.scope=e,this.isIndexNode=!0}generate(e){const t=this.getNodeType(e),r=this.scope;let s,i;if(r===qh.VERTEX)s=e.getVertexIndex();else if(r===qh.INSTANCE)s=e.getInstanceIndex();else if(r===qh.DRAW)s=e.getDrawIndex();else if(r===qh.INVOCATION_LOCAL)s=e.getInvocationLocalIndex();else if(r===qh.INVOCATION_SUBGROUP)s=e.getInvocationSubgroupIndex();else{if(r!==qh.SUBGROUP)throw new Error("THREE.IndexNode: Unknown scope: "+r);s=e.getSubgroupIndex()}if("vertex"===e.shaderStage||"compute"===e.shaderStage)i=s;else{i=Bu(this).build(e,t)}return i}}qh.VERTEX="vertex",qh.INSTANCE="instance",qh.SUBGROUP="subgroup",qh.INVOCATION_LOCAL="invocationLocal",qh.INVOCATION_SUBGROUP="invocationSubgroup",qh.DRAW="draw";const jh=sn(qh,qh.VERTEX),Xh=sn(qh,qh.INSTANCE),Kh=sn(qh,qh.SUBGROUP),Yh=sn(qh,qh.INVOCATION_SUBGROUP),Qh=sn(qh,qh.INVOCATION_LOCAL),Zh=sn(qh,qh.DRAW);class Jh extends ui{static get type(){return"InstanceNode"}constructor(e,t,r=null){super("void"),this.count=e,this.instanceMatrix=t,this.instanceColor=r,this.instanceMatrixNode=null,this.instanceColorNode=null,this.updateType=Js.FRAME,this.buffer=null,this.bufferColor=null,this.previousInstanceMatrixNode=null}get isStorageMatrix(){const{instanceMatrix:e}=this;return e&&!0===e.isStorageInstancedBufferAttribute}get isStorageColor(){const{instanceColor:e}=this;return e&&!0===e.isStorageInstancedBufferAttribute}setup(e){let{instanceMatrixNode:t,instanceColorNode:r}=this;null===t&&(t=this._createInstanceMatrixNode(!0,e),this.instanceMatrixNode=t);const{instanceColor:s,isStorageColor:i}=this;if(s&&null===r){if(i)r=Hh(s,"vec3",Math.max(s.count,1)).element(Xh);else{const e=new W(s.array,3),t=s.usage===x?tl:el;this.bufferColor=e,r=vn(t(e,"vec3",3,0))}this.instanceColorNode=r}const n=t.mul(Pd).xyz;if(Pd.assign(n),e.needsPreviousData()&&Bd.assign(this.getPreviousInstancedPosition(e)),e.hasGeometryAttribute("normal")){const e=Qd(Wd,t);Wd.assign(e)}null!==this.instanceColorNode&&In("vec3","vInstanceColor").assign(this.instanceColorNode)}update(e){null!==this.buffer&&!0!==this.isStorageMatrix&&(this.buffer.clearUpdateRanges(),this.buffer.updateRanges.push(...this.instanceMatrix.updateRanges),this.instanceMatrix.version!==this.buffer.version&&(this.buffer.version=this.instanceMatrix.version)),this.instanceColor&&null!==this.bufferColor&&!0!==this.isStorageColor&&(this.bufferColor.clearUpdateRanges(),this.bufferColor.updateRanges.push(...this.instanceColor.updateRanges),this.instanceColor.version!==this.bufferColor.version&&(this.bufferColor.version=this.instanceColor.version)),null!==this.previousInstanceMatrixNode&&e.object.previousInstanceMatrix.array.set(this.instanceMatrix.array)}getPreviousInstancedPosition(e){const t=e.object;return null===this.previousInstanceMatrixNode&&(t.previousInstanceMatrix=this.instanceMatrix.clone(),this.previousInstanceMatrixNode=this._createInstanceMatrixNode(!1,e)),this.previousInstanceMatrixNode.mul(Bd).xyz}_createInstanceMatrixNode(e,t){let r;const{instanceMatrix:s}=this,{count:i}=s;if(this.isStorageMatrix)r=Hh(s,"mat4",Math.max(i,1)).element(Xh);else{if(i<=(!0===t.renderer.backend.isWebGPUBackend?1e3:250))r=Ul(s.array,"mat4",Math.max(i,1)).element(Xh);else{const t=new H(s.array,16,1);!0===e&&(this.buffer=t);const i=s.usage===x?tl:el,n=[i(t,"vec4",16,0),i(t,"vec4",16,4),i(t,"vec4",16,8),i(t,"vec4",16,12)];r=Ln(...n)}}return r}}const ep=rn(Jh).setParameterLength(2,3);class tp extends Jh{static get type(){return"InstancedMeshNode"}constructor(e){const{count:t,instanceMatrix:r,instanceColor:s}=e;super(t,r,s),this.instancedMesh=e}}const rp=rn(tp).setParameterLength(1);class sp extends ui{static get type(){return"BatchNode"}constructor(e){super("void"),this.batchMesh=e,this.batchingIdNode=null}setup(e){null===this.batchingIdNode&&(null===e.getDrawIndex()?this.batchingIdNode=Xh:this.batchingIdNode=Zh);const t=un(([e])=>{const t=mn(Al(Bl(this.batchMesh._indirectTexture),0).x).toConst(),r=mn(e).mod(t).toConst(),s=mn(e).div(t).toConst();return Bl(this.batchMesh._indirectTexture,xn(r,s)).x}).setLayout({name:"getIndirectIndex",type:"uint",inputs:[{name:"id",type:"int"}]}),r=t(mn(this.batchingIdNode)),s=this.batchMesh._matricesTexture,i=mn(Al(Bl(s),0).x).toConst(),n=gn(r).mul(4).toInt().toConst(),a=n.mod(i).toConst(),o=n.div(i).toConst(),u=Ln(Bl(s,xn(a,o)),Bl(s,xn(a.add(1),o)),Bl(s,xn(a.add(2),o)),Bl(s,xn(a.add(3),o))),l=this.batchMesh._colorsTexture;if(null!==l){const e=un(([e])=>{const t=mn(Al(Bl(l),0).x).toConst(),r=e,s=r.mod(t).toConst(),i=r.div(t).toConst();return Bl(l,xn(s,i)).rgb}).setLayout({name:"getBatchingColor",type:"vec3",inputs:[{name:"id",type:"int"}]}),t=e(r);In("vec3","vBatchColor").assign(t)}const d=Fn(u);Pd.assign(u.mul(Pd));const c=Wd.div(vn(d[0].dot(d[0]),d[1].dot(d[1]),d[2].dot(d[2]))),h=d.mul(c).xyz;Wd.assign(h),e.hasGeometryAttribute("tangent")&&Uc.mulAssign(d)}}const ip=rn(sp).setParameterLength(1),np=new WeakMap;class ap extends ui{static get type(){return"SkinningNode"}constructor(e){super("void"),this.skinnedMesh=e,this.updateType=Js.OBJECT,this.skinIndexNode=Sl("skinIndex","uvec4"),this.skinWeightNode=Sl("skinWeight","vec4"),this.bindMatrixNode=yc("bindMatrix","mat4"),this.bindMatrixInverseNode=yc("bindMatrixInverse","mat4"),this.boneMatricesNode=bc("skeleton.boneMatrices","mat4",e.skeleton.bones.length),this.positionNode=Pd,this.toPositionNode=Pd,this.previousBoneMatricesNode=null}getSkinnedPosition(e=this.boneMatricesNode,t=this.positionNode){const{skinIndexNode:r,skinWeightNode:s,bindMatrixNode:i,bindMatrixInverseNode:n}=this,a=e.element(r.x),o=e.element(r.y),u=e.element(r.z),l=e.element(r.w),d=i.mul(t),c=Ma(a.mul(s.x).mul(d),o.mul(s.y).mul(d),u.mul(s.z).mul(d),l.mul(s.w).mul(d));return n.mul(c).xyz}getSkinnedNormalAndTangent(e=this.boneMatricesNode,t=Wd,r=Uc){const{skinIndexNode:s,skinWeightNode:i,bindMatrixNode:n,bindMatrixInverseNode:a}=this,o=e.element(s.x),u=e.element(s.y),l=e.element(s.z),d=e.element(s.w);let c=Ma(i.x.mul(o),i.y.mul(u),i.z.mul(l),i.w.mul(d));c=a.mul(c).mul(n);return{skinNormal:c.transformDirection(t).xyz,skinTangent:c.transformDirection(r).xyz}}getPreviousSkinnedPosition(e){const t=e.object;return null===this.previousBoneMatricesNode&&(t.skeleton.previousBoneMatrices=new Float32Array(t.skeleton.boneMatrices),this.previousBoneMatricesNode=bc("skeleton.previousBoneMatrices","mat4",t.skeleton.bones.length)),this.getSkinnedPosition(this.previousBoneMatricesNode,Bd)}setup(e){e.needsPreviousData()&&Bd.assign(this.getPreviousSkinnedPosition(e));const t=this.getSkinnedPosition();if(this.toPositionNode&&this.toPositionNode.assign(t),e.hasGeometryAttribute("normal")){const{skinNormal:t,skinTangent:r}=this.getSkinnedNormalAndTangent();Wd.assign(t),e.hasGeometryAttribute("tangent")&&Uc.assign(r)}return t}generate(e,t){if("void"!==t)return super.generate(e,t)}update(e){const t=e.object&&e.object.skeleton?e.object.skeleton:this.skinnedMesh.skeleton;np.get(t)!==e.frameId&&(np.set(t,e.frameId),null!==this.previousBoneMatricesNode&&(null===t.previousBoneMatrices&&(t.previousBoneMatrices=new Float32Array(t.boneMatrices)),t.previousBoneMatrices.set(t.boneMatrices)),t.update())}}const op=e=>new ap(e);class up extends ui{static get type(){return"LoopNode"}constructor(e=[]){super("void"),this.params=e}getVarName(e){return String.fromCharCode("i".charCodeAt(0)+e)}getProperties(e){const t=e.getNodeProperties(this);if(void 0!==t.stackNode)return t;const r={};for(let e=0,t=this.params.length-1;eNumber(l)?">=":"<")),a)n=`while ( ${l} )`;else{const r={start:u,end:l},s=r.start,i=r.end;let a;const g=()=>h.includes("<")?"+=":"-=";if(null!=p)switch(typeof p){case"function":a=e.flowStagesNode(t.updateNode,"void").code.replace(/\t|;/g,"");break;case"number":a=d+" "+g()+" "+e.generateConst(c,p);break;case"string":a=d+" "+p;break;default:p.isNode?a=d+" "+g()+" "+p.build(e):(o("TSL: 'Loop( { update: ... } )' is not a function, string or number."),a="break /* invalid update */")}else p="int"===c||"uint"===c?h.includes("<")?"++":"--":g()+" 1.",a=d+" "+p;n=`for ( ${e.getVar(c,d)+" = "+s}; ${d+" "+h+" "+i}; ${a} )`}e.addFlowCode((0===s?"\n":"")+e.tab+n+" {\n\n").addFlowTab()}const i=s.build(e,"void");t.returnsNode.build(e,"void"),e.removeFlowTab().addFlowCode("\n"+e.tab+i);for(let t=0,r=this.params.length-1;tnew up(tn(e,"int")).toStack(),dp=()=>gl("break").toStack(),cp=new WeakMap,hp=new s,pp=un(({bufferMap:e,influence:t,stride:r,width:s,depth:i,offset:n})=>{const a=mn(jh).mul(r).add(n),o=a.div(s),u=a.sub(o.mul(s));return Bl(e,xn(u,o)).depth(i).xyz.mul(t)});class gp extends ui{static get type(){return"MorphNode"}constructor(e){super("void"),this.mesh=e,this.morphBaseInfluence=_a(1),this.updateType=Js.OBJECT}setup(e){const{geometry:r}=e,s=void 0!==r.morphAttributes.position,i=r.hasAttribute("normal")&&void 0!==r.morphAttributes.normal,n=r.morphAttributes.position||r.morphAttributes.normal||r.morphAttributes.color,a=void 0!==n?n.length:0,{texture:o,stride:u,size:l}=function(e){const r=void 0!==e.morphAttributes.position,s=void 0!==e.morphAttributes.normal,i=void 0!==e.morphAttributes.color,n=e.morphAttributes.position||e.morphAttributes.normal||e.morphAttributes.color,a=void 0!==n?n.length:0;let o=cp.get(e);if(void 0===o||o.count!==a){void 0!==o&&o.texture.dispose();const u=e.morphAttributes.position||[],l=e.morphAttributes.normal||[],d=e.morphAttributes.color||[];let c=0;!0===r&&(c=1),!0===s&&(c=2),!0===i&&(c=3);let h=e.attributes.position.count*c,p=1;const g=4096;h>g&&(p=Math.ceil(h/g),h=g);const m=new Float32Array(h*p*4*a),f=new q(m,h,p,a);f.type=j,f.needsUpdate=!0;const y=4*c;for(let x=0;x{const t=gn(0).toVar();this.mesh.count>1&&null!==this.mesh.morphTexture&&void 0!==this.mesh.morphTexture?t.assign(Bl(this.mesh.morphTexture,xn(mn(e).add(1),mn(Xh))).r):t.assign(yc("morphTargetInfluences","float").element(e).toVar()),cn(t.notEqual(0),()=>{!0===s&&Pd.addAssign(pp({bufferMap:o,influence:t,stride:u,width:d,depth:e,offset:mn(0)})),!0===i&&Wd.addAssign(pp({bufferMap:o,influence:t,stride:u,width:d,depth:e,offset:mn(1)}))})})}update(){const e=this.morphBaseInfluence;this.mesh.geometry.morphTargetsRelative?e.value=1:e.value=1-this.mesh.morphTargetInfluences.reduce((e,t)=>e+t,0)}}const mp=rn(gp).setParameterLength(1);class fp extends ui{static get type(){return"LightingNode"}constructor(){super("vec3"),this.isLightingNode=!0}}class yp extends fp{static get type(){return"AONode"}constructor(e=null){super(),this.aoNode=e}setup(e){e.context.ambientOcclusion.mulAssign(this.aoNode)}}class bp extends xu{static get type(){return"LightingContextNode"}constructor(e,t=null,r=null,s=null){super(e),this.lightingModel=t,this.backdropNode=r,this.backdropAlphaNode=s,this._value=null}getContext(){const{backdropNode:e,backdropAlphaNode:t}=this,r={directDiffuse:vn().toVar("directDiffuse"),directSpecular:vn().toVar("directSpecular"),indirectDiffuse:vn().toVar("indirectDiffuse"),indirectSpecular:vn().toVar("indirectSpecular")};return{radiance:vn().toVar("radiance"),irradiance:vn().toVar("irradiance"),iblIrradiance:vn().toVar("iblIrradiance"),ambientOcclusion:gn(1).toVar("ambientOcclusion"),reflectedLight:r,backdrop:e,backdropAlpha:t}}setup(e){return this.value=this._value||(this._value=this.getContext()),this.value.lightingModel=this.lightingModel||e.context.lightingModel,super.setup(e)}}const xp=rn(bp);class Tp extends fp{static get type(){return"IrradianceNode"}constructor(e){super(),this.node=e}setup(e){e.context.irradiance.addAssign(this.node)}}const _p=new t;class vp extends Fl{static get type(){return"ViewportTextureNode"}constructor(e=ql,t=null,r=null){let s=null;null===r?(s=new X,s.minFilter=K,r=s):s=r,super(r,e,t),this.generateMipmaps=!1,this.defaultFramebuffer=s,this.isOutputTextureNode=!0,this.updateBeforeType=Js.RENDER,this._cacheTextures=new WeakMap}getTextureForReference(e=null){let t,r;if(this.referenceNode?(t=this.referenceNode.defaultFramebuffer,r=this.referenceNode._cacheTextures):(t=this.defaultFramebuffer,r=this._cacheTextures),null===e)return t;if(!1===r.has(e)){const s=t.clone();r.set(e,s)}return r.get(e)}updateReference(e){const t=e.renderer.getRenderTarget();return this.value=this.getTextureForReference(t),this.value}updateBefore(e){const t=e.renderer,r=t.getRenderTarget();null===r?t.getDrawingBufferSize(_p):_p.set(r.width,r.height);const s=this.getTextureForReference(r);s.image.width===_p.width&&s.image.height===_p.height||(s.image.width=_p.width,s.image.height=_p.height,s.needsUpdate=!0);const i=s.generateMipmaps;s.generateMipmaps=this.generateMipmaps,t.copyFramebufferToTexture(s),s.generateMipmaps=i}clone(){const e=new this.constructor(this.uvNode,this.levelNode,this.value);return e.generateMipmaps=this.generateMipmaps,e}}const Np=rn(vp).setParameterLength(0,3),Sp=rn(vp,null,null,{generateMipmaps:!0}).setParameterLength(0,3),Rp=Sp(),Ep=(e=ql,t=null)=>Rp.sample(e,t);let Ap=null;class wp extends vp{static get type(){return"ViewportDepthTextureNode"}constructor(e=ql,t=null){null===Ap&&(Ap=new Y),super(e,t,Ap)}getTextureForReference(){return Ap}}const Cp=rn(wp).setParameterLength(0,2);class Mp extends ui{static get type(){return"ViewportDepthNode"}constructor(e,t=null){super("float"),this.scope=e,this.valueNode=t,this.isViewportDepthNode=!0}generate(e){const{scope:t}=this;return t===Mp.DEPTH_BASE?e.getFragDepth():super.generate(e)}setup({camera:e}){const{scope:t}=this,r=this.valueNode;let s=null;if(t===Mp.DEPTH_BASE)null!==r&&(s=Dp().assign(r));else if(t===Mp.DEPTH)s=e.isPerspectiveCamera?Lp(Id.z,td,rd):Fp(Id.z,td,rd);else if(t===Mp.LINEAR_DEPTH)if(null!==r)if(e.isPerspectiveCamera){const e=Pp(r,td,rd);s=Fp(e,td,rd)}else s=r;else s=Fp(Id.z,td,rd);return s}}Mp.DEPTH_BASE="depthBase",Mp.DEPTH="depth",Mp.LINEAR_DEPTH="linearDepth";const Fp=(e,t,r)=>e.add(t).div(t.sub(r)),Lp=(e,t,r)=>t.add(e).mul(r).div(r.sub(t).mul(e)),Pp=(e,t,r)=>t.mul(r).div(r.sub(t).mul(e).sub(r)),Bp=(e,t,r)=>{t=t.max(1e-6).toVar();const s=yo(e.negate().div(t)),i=yo(r.div(t));return s.div(i)},Dp=rn(Mp,Mp.DEPTH_BASE),Up=sn(Mp,Mp.DEPTH),Ip=rn(Mp,Mp.LINEAR_DEPTH).setParameterLength(0,1),Op=Ip(Cp());Up.assign=e=>Dp(e);class Vp extends ui{static get type(){return"ClippingNode"}constructor(e=Vp.DEFAULT){super(),this.scope=e}setup(e){super.setup(e);const t=e.clippingContext,{intersectionPlanes:r,unionPlanes:s}=t;return this.hardwareClipping=e.material.hardwareClipping,this.scope===Vp.ALPHA_TO_COVERAGE?this.setupAlphaToCoverage(r,s):this.scope===Vp.HARDWARE?this.setupHardwareClipping(s,e):this.setupDefault(r,s)}setupAlphaToCoverage(e,t){return un(()=>{const r=gn().toVar("distanceToPlane"),s=gn().toVar("distanceToGradient"),i=gn(1).toVar("clipOpacity"),n=t.length;if(!1===this.hardwareClipping&&n>0){const e=Vl(t).setGroup(ba);lp(n,({i:t})=>{const n=e.element(t);r.assign(Id.dot(n.xyz).negate().add(n.w)),s.assign(r.fwidth().div(2)),i.mulAssign(lu(s.negate(),s,r))})}const a=e.length;if(a>0){const t=Vl(e).setGroup(ba),n=gn(1).toVar("intersectionClipOpacity");lp(a,({i:e})=>{const i=t.element(e);r.assign(Id.dot(i.xyz).negate().add(i.w)),s.assign(r.fwidth().div(2)),n.mulAssign(lu(s.negate(),s,r).oneMinus())}),i.mulAssign(n.oneMinus())}On.a.mulAssign(i),On.a.equal(0).discard()})()}setupDefault(e,t){return un(()=>{const r=t.length;if(!1===this.hardwareClipping&&r>0){const e=Vl(t).setGroup(ba);lp(r,({i:t})=>{const r=e.element(t);Id.dot(r.xyz).greaterThan(r.w).discard()})}const s=e.length;if(s>0){const t=Vl(e).setGroup(ba),r=yn(!0).toVar("clipped");lp(s,({i:e})=>{const s=t.element(e);r.assign(Id.dot(s.xyz).greaterThan(s.w).and(r))}),r.discard()}})()}setupHardwareClipping(e,t){const r=e.length;return t.enableHardwareClipping(r),un(()=>{const s=Vl(e).setGroup(ba),i=Gl(t.getClipDistance());lp(r,({i:e})=>{const t=s.element(e),r=Id.dot(t.xyz).sub(t.w).negate();i.element(e).assign(r)})})()}}Vp.ALPHA_TO_COVERAGE="alphaToCoverage",Vp.DEFAULT="default",Vp.HARDWARE="hardware";const kp=un(([e])=>No(La(1e4,So(La(17,e.x).add(La(.1,e.y)))).mul(Ma(.1,Mo(So(La(13,e.y).add(e.x))))))),Gp=un(([e])=>kp(bn(kp(e.xy),e.z))),zp=un(([e])=>{const t=Ho(Lo(Do(e.xyz)),Lo(Uo(e.xyz))),r=gn(1).div(gn(.05).mul(t)).toVar("pixScale"),s=bn(mo(To(yo(r))),mo(_o(yo(r)))),i=bn(Gp(To(s.x.mul(e.xyz))),Gp(To(s.y.mul(e.xyz)))),n=No(yo(r)),a=Ma(La(n.oneMinus(),i.x),La(n,i.y)),o=Wo(n,n.oneMinus()),u=vn(a.mul(a).div(La(2,o).mul(Fa(1,o))),a.sub(La(.5,o)).div(Fa(1,o)),Fa(1,Fa(1,a).mul(Fa(1,a)).div(La(2,o).mul(Fa(1,o))))),l=a.lessThan(o.oneMinus()).select(a.lessThan(o).select(u.x,u.y),u.z);return au(l,1e-6,1)}).setLayout({name:"getAlphaHashThreshold",type:"float",inputs:[{name:"position",type:"vec3"}]});class $p extends Nl{static get type(){return"VertexColorNode"}constructor(e){super(null,"vec4"),this.isVertexColorNode=!0,this.index=e}getAttributeName(){const e=this.index;return"color"+(e>0?e:"")}generate(e){const t=this.getAttributeName(e);let r;return r=!0===e.hasGeometryAttribute(t)?super.generate(e):e.generateConst(this.nodeType,new s(1,1,1,1)),r}serialize(e){super.serialize(e),e.index=this.index}deserialize(e){super.deserialize(e),this.index=e.index}}const Wp=(e=0)=>new $p(e),Hp=un(([e,t])=>Wo(1,e.oneMinus().div(t)).oneMinus()).setLayout({name:"blendBurn",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),qp=un(([e,t])=>Wo(e.div(t.oneMinus()),1)).setLayout({name:"blendDodge",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),jp=un(([e,t])=>e.oneMinus().mul(t.oneMinus()).oneMinus()).setLayout({name:"blendScreen",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),Xp=un(([e,t])=>nu(e.mul(2).mul(t),e.oneMinus().mul(2).mul(t.oneMinus()).oneMinus(),qo(.5,e))).setLayout({name:"blendOverlay",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),Kp=un(([e,t])=>{const r=t.a.add(e.a.mul(t.a.oneMinus()));return En(t.rgb.mul(t.a).add(e.rgb.mul(e.a).mul(t.a.oneMinus())).div(r),r)}).setLayout({name:"blendColor",type:"vec4",inputs:[{name:"base",type:"vec4"},{name:"blend",type:"vec4"}]}),Yp=un(([e])=>En(e.rgb.mul(e.a),e.a),{color:"vec4",return:"vec4"}),Qp=un(([e])=>(cn(e.a.equal(0),()=>En(0)),En(e.rgb.div(e.a),e.a)),{color:"vec4",return:"vec4"});class Zp extends Q{static get type(){return"NodeMaterial"}get type(){return this.constructor.type}set type(e){}constructor(){super(),this.isNodeMaterial=!0,this.fog=!0,this.lights=!1,this.hardwareClipping=!1,this.lightsNode=null,this.envNode=null,this.aoNode=null,this.colorNode=null,this.normalNode=null,this.opacityNode=null,this.backdropNode=null,this.backdropAlphaNode=null,this.alphaTestNode=null,this.maskNode=null,this.maskShadowNode=null,this.positionNode=null,this.geometryNode=null,this.depthNode=null,this.receivedShadowPositionNode=null,this.castShadowPositionNode=null,this.receivedShadowNode=null,this.castShadowNode=null,this.outputNode=null,this.mrtNode=null,this.fragmentNode=null,this.vertexNode=null,this.contextNode=null}_getNodeChildren(){const e=[];for(const t of Object.getOwnPropertyNames(this)){if(!0===t.startsWith("_"))continue;const r=this[t];r&&!0===r.isNode&&e.push({property:t,childNode:r})}return e}customProgramCacheKey(){const e=[];for(const{property:t,childNode:r}of this._getNodeChildren())e.push(Us(t.slice(0,-4)),r.getCacheKey());return this.type+Is(e)}build(e){this.setup(e)}setupObserver(e){return new Bs(e)}setup(e){e.context.setupNormal=()=>Lu(this.setupNormal(e),"NORMAL","vec3"),e.context.setupPositionView=()=>this.setupPositionView(e),e.context.setupModelViewProjection=()=>this.setupModelViewProjection(e);const t=e.renderer,r=t.getRenderTarget();!0===t.contextNode.isContextNode?e.context={...e.context,...t.contextNode.getFlowContextData()}:o('NodeMaterial: "renderer.contextNode" must be an instance of `context()`.'),null!==this.contextNode&&(!0===this.contextNode.isContextNode?e.context={...e.context,...this.contextNode.getFlowContextData()}:o('NodeMaterial: "material.contextNode" must be an instance of `context()`.')),e.addStack();const s=this.setupVertex(e),i=Lu(this.vertexNode||s,"VERTEX");let n;e.context.clipSpace=i,e.stack.outputNode=i,this.setupHardwareClipping(e),null!==this.geometryNode&&(e.stack.outputNode=e.stack.outputNode.bypass(this.geometryNode)),e.addFlow("vertex",e.removeStack()),e.addStack();const a=this.setupClipping(e);if(!0!==this.depthWrite&&!0!==this.depthTest||(null!==r?!0===r.depthBuffer&&this.setupDepth(e):!0===t.depth&&this.setupDepth(e)),null===this.fragmentNode){this.setupDiffuseColor(e),this.setupVariants(e);const s=this.setupLighting(e);null!==a&&e.stack.addToStack(a);const i=En(s,On.a).max(0);n=this.setupOutput(e,i),ia.assign(n);const o=null!==this.outputNode;if(o&&(n=this.outputNode),e.context.getOutput&&(n=e.context.getOutput(n,e)),null!==r){const e=t.getMRT(),r=this.mrtNode;null!==e?(o&&ia.assign(n),n=e,null!==r&&(n=e.merge(r))):null!==r&&(n=r)}}else{let t=this.fragmentNode;!0!==t.isOutputStructNode&&(t=En(t)),n=this.setupOutput(e,t)}e.stack.outputNode=n,e.addFlow("fragment",e.removeStack()),e.observer=this.setupObserver(e)}setupClipping(e){if(null===e.clippingContext)return null;const{unionPlanes:t,intersectionPlanes:r}=e.clippingContext;let s=null;if(t.length>0||r.length>0){const t=e.renderer.currentSamples;this.alphaToCoverage&&t>1?s=new Vp(Vp.ALPHA_TO_COVERAGE):e.stack.addToStack(new Vp)}return s}setupHardwareClipping(e){if(this.hardwareClipping=!1,null===e.clippingContext)return;const t=e.clippingContext.unionPlanes.length;t>0&&t<=8&&e.isAvailable("clipDistance")&&(e.stack.addToStack(new Vp(Vp.HARDWARE)),this.hardwareClipping=!0)}setupDepth(e){const{renderer:t,camera:r}=e;let s=this.depthNode;if(null===s){const e=t.getMRT();e&&e.has("depth")?s=e.get("depth"):!0===t.logarithmicDepthBuffer&&(s=r.isPerspectiveCamera?Bp(Id.z,td,rd):Fp(Id.z,td,rd))}null!==s&&Up.assign(s).toStack()}setupPositionView(){return Ad.mul(Pd).xyz}setupModelViewProjection(){return sd.mul(Id)}setupVertex(e){return e.addStack(),this.setupPosition(e),e.context.position=e.removeStack(),Gh}setupPosition(e){const{object:t,geometry:r}=e;if((r.morphAttributes.position||r.morphAttributes.normal||r.morphAttributes.color)&&mp(t).toStack(),!0===t.isSkinnedMesh&&op(t).toStack(),this.displacementMap){const e=Tc("displacementMap","texture"),t=Tc("displacementScale","float"),r=Tc("displacementBias","float");Pd.addAssign(Wd.normalize().mul(e.x.mul(t).add(r)))}return t.isBatchedMesh&&ip(t).toStack(),t.isInstancedMesh&&t.instanceMatrix&&!0===t.instanceMatrix.isInstancedBufferAttribute&&rp(t).toStack(),null!==this.positionNode&&Pd.assign(Lu(this.positionNode,"POSITION","vec3")),Pd}setupDiffuseColor(e){const{object:t,geometry:r}=e;null!==this.maskNode&&yn(this.maskNode).not().discard();let s=this.colorNode?En(this.colorNode):ih;if(!0===this.vertexColors&&r.hasAttribute("color")&&(s=s.mul(Wp())),t.instanceColor){s=In("vec3","vInstanceColor").mul(s)}if(t.isBatchedMesh&&t._colorsTexture){s=In("vec3","vBatchColor").mul(s)}On.assign(s);const i=this.opacityNode?gn(this.opacityNode):oh;On.a.assign(On.a.mul(i));let n=null;(null!==this.alphaTestNode||this.alphaTest>0)&&(n=null!==this.alphaTestNode?gn(this.alphaTestNode):sh,!0===this.alphaToCoverage?(On.a=lu(n,n.add(ko(On.a)),On.a),On.a.lessThanEqual(0).discard()):On.a.lessThanEqual(n).discard()),!0===this.alphaHash&&On.a.lessThan(zp(Pd)).discard(),e.isOpaque()&&On.a.assign(1)}setupVariants(){}setupOutgoingLight(){return!0===this.lights?vn(0):On.rgb}setupNormal(){return this.normalNode?vn(this.normalNode):mh}setupEnvironment(){let e=null;return this.envNode?e=this.envNode:this.envMap&&(e=this.envMap.isCubeTexture?Tc("envMap","cubeTexture"):Tc("envMap","texture")),e}setupLightMap(e){let t=null;return e.material.lightMap&&(t=new Tp(Oh)),t}setupLights(e){const t=[],r=this.setupEnvironment(e);r&&r.isLightingNode&&t.push(r);const s=this.setupLightMap(e);s&&s.isLightingNode&&t.push(s);let i=this.aoNode;null===i&&e.material.aoMap&&(i=Vh),e.context.getAO&&(i=e.context.getAO(i,e)),i&&t.push(new yp(i));let n=this.lightsNode||e.lightsNode;return t.length>0&&(n=e.renderer.lighting.createNode([...n.getLights(),...t])),n}setupLightingModel(){}setupLighting(e){const{material:t}=e,{backdropNode:r,backdropAlphaNode:s,emissiveNode:i}=this,n=!0===this.lights||null!==this.lightsNode?this.setupLights(e):null;let a=this.setupOutgoingLight(e);if(n&&n.getScope().hasLights){const t=this.setupLightingModel(e)||null;a=xp(n,t,r,s)}else null!==r&&(a=vn(null!==s?nu(a,r,s):r));return(i&&!0===i.isNode||t.emissive&&!0===t.emissive.isColor)&&(kn.assign(vn(i||ah)),a=a.add(kn)),a}setupFog(e,t){const r=e.fogNode;return r&&(ia.assign(t),t=En(r.toVar())),t}setupPremultipliedAlpha(e,t){return Yp(t)}setupOutput(e,t){return!0===this.fog&&(t=this.setupFog(e,t)),!0===this.premultipliedAlpha&&(t=this.setupPremultipliedAlpha(e,t)),t}setDefaultValues(e){for(const t in e){const r=e[t];void 0===this[t]&&(this[t]=r,r&&r.clone&&(this[t]=r.clone()))}const t=Object.getOwnPropertyDescriptors(e.constructor.prototype);for(const e in t)void 0===Object.getOwnPropertyDescriptor(this.constructor.prototype,e)&&void 0!==t[e].get&&Object.defineProperty(this.constructor.prototype,e,t[e])}toJSON(e){const t=void 0===e||"string"==typeof e;t&&(e={textures:{},images:{},nodes:{}});const r=Q.prototype.toJSON.call(this,e);r.inputNodes={};for(const{property:t,childNode:s}of this._getNodeChildren())r.inputNodes[t]=s.toJSON(e).uuid;function s(e){const t=[];for(const r in e){const s=e[r];delete s.metadata,t.push(s)}return t}if(t){const t=s(e.textures),i=s(e.images),n=s(e.nodes);t.length>0&&(r.textures=t),i.length>0&&(r.images=i),n.length>0&&(r.nodes=n)}return r}copy(e){return this.lightsNode=e.lightsNode,this.envNode=e.envNode,this.aoNode=e.aoNode,this.colorNode=e.colorNode,this.normalNode=e.normalNode,this.opacityNode=e.opacityNode,this.backdropNode=e.backdropNode,this.backdropAlphaNode=e.backdropAlphaNode,this.alphaTestNode=e.alphaTestNode,this.maskNode=e.maskNode,this.maskShadowNode=e.maskShadowNode,this.positionNode=e.positionNode,this.geometryNode=e.geometryNode,this.depthNode=e.depthNode,this.receivedShadowPositionNode=e.receivedShadowPositionNode,this.castShadowPositionNode=e.castShadowPositionNode,this.receivedShadowNode=e.receivedShadowNode,this.castShadowNode=e.castShadowNode,this.outputNode=e.outputNode,this.mrtNode=e.mrtNode,this.fragmentNode=e.fragmentNode,this.vertexNode=e.vertexNode,this.contextNode=e.contextNode,super.copy(e)}}const Jp=new Z;class eg extends Zp{static get type(){return"LineBasicNodeMaterial"}constructor(e){super(),this.isLineBasicNodeMaterial=!0,this.setDefaultValues(Jp),this.setValues(e)}}const tg=new J;class rg extends Zp{static get type(){return"LineDashedNodeMaterial"}constructor(e){super(),this.isLineDashedNodeMaterial=!0,this.setDefaultValues(tg),this.dashOffset=0,this.offsetNode=null,this.dashScaleNode=null,this.dashSizeNode=null,this.gapSizeNode=null,this.setValues(e)}setupVariants(){const e=this.offsetNode?gn(this.offsetNode):Dh,t=this.dashScaleNode?gn(this.dashScaleNode):Fh,r=this.dashSizeNode?gn(this.dashSizeNode):Lh,s=this.gapSizeNode?gn(this.gapSizeNode):Ph;na.assign(r),aa.assign(s);const i=Bu(Sl("lineDistance").mul(t));(e?i.add(e):i).mod(na.add(aa)).greaterThan(na).discard()}}const sg=new J;class ig extends Zp{static get type(){return"Line2NodeMaterial"}constructor(e={}){super(),this.isLine2NodeMaterial=!0,this.setDefaultValues(sg),this.vertexColors=e.vertexColors,this.dashOffset=0,this.lineColorNode=null,this.offsetNode=null,this.dashScaleNode=null,this.dashSizeNode=null,this.gapSizeNode=null,this.blending=ee,this._useDash=e.dashed,this._useAlphaToCoverage=!0,this._useWorldUnits=!1,this.setValues(e)}setup(e){const{renderer:t}=e,r=this._useAlphaToCoverage,s=this.vertexColors,i=this._useDash,n=this._useWorldUnits,a=un(({start:e,end:t})=>{const r=sd.element(2).element(2),s=sd.element(3).element(2).mul(-.5).div(r).sub(e.z).div(t.z.sub(e.z));return En(nu(e.xyz,t.xyz,s),t.w)}).setLayout({name:"trimSegment",type:"vec4",inputs:[{name:"start",type:"vec4"},{name:"end",type:"vec4"}]});this.vertexNode=un(()=>{const e=Sl("instanceStart"),t=Sl("instanceEnd"),r=En(Ad.mul(En(e,1))).toVar("start"),s=En(Ad.mul(En(t,1))).toVar("end");if(i){const e=this.dashScaleNode?gn(this.dashScaleNode):Fh,t=this.offsetNode?gn(this.offsetNode):Dh,r=Sl("instanceDistanceStart"),s=Sl("instanceDistanceEnd");let i=Ld.y.lessThan(.5).select(e.mul(r),e.mul(s));i=i.add(t),In("float","lineDistance").assign(i)}n&&(In("vec3","worldStart").assign(r.xyz),In("vec3","worldEnd").assign(s.xyz));const o=Kl.z.div(Kl.w),u=sd.element(2).element(3).equal(-1);cn(u,()=>{cn(r.z.lessThan(0).and(s.z.greaterThan(0)),()=>{s.assign(a({start:r,end:s}))}).ElseIf(s.z.lessThan(0).and(r.z.greaterThanEqual(0)),()=>{r.assign(a({start:s,end:r}))})});const l=sd.mul(r),d=sd.mul(s),c=l.xyz.div(l.w),h=d.xyz.div(d.w),p=h.xy.sub(c.xy).toVar();p.x.assign(p.x.mul(o)),p.assign(p.normalize());const g=En().toVar();if(n){const e=s.xyz.sub(r.xyz).normalize(),t=nu(r.xyz,s.xyz,.5).normalize(),n=e.cross(t).normalize(),a=e.cross(n),o=In("vec4","worldPos");o.assign(Ld.y.lessThan(.5).select(r,s));const u=Bh.mul(.5);o.addAssign(En(Ld.x.lessThan(0).select(n.mul(u),n.mul(u).negate()),0)),i||(o.addAssign(En(Ld.y.lessThan(.5).select(e.mul(u).negate(),e.mul(u)),0)),o.addAssign(En(a.mul(u),0)),cn(Ld.y.greaterThan(1).or(Ld.y.lessThan(0)),()=>{o.subAssign(En(a.mul(2).mul(u),0))})),g.assign(sd.mul(o));const l=vn().toVar();l.assign(Ld.y.lessThan(.5).select(c,h)),g.z.assign(l.z.mul(g.w))}else{const e=bn(p.y,p.x.negate()).toVar("offset");p.x.assign(p.x.div(o)),e.x.assign(e.x.div(o)),e.assign(Ld.x.lessThan(0).select(e.negate(),e)),cn(Ld.y.lessThan(0),()=>{e.assign(e.sub(p))}).ElseIf(Ld.y.greaterThan(1),()=>{e.assign(e.add(p))}),e.assign(e.mul(Bh)),e.assign(e.div(Kl.w.div(Hl))),g.assign(Ld.y.lessThan(.5).select(l,d)),e.assign(e.mul(g.w)),g.assign(g.add(En(e,0,0)))}return g})();const o=un(({p1:e,p2:t,p3:r,p4:s})=>{const i=e.sub(r),n=s.sub(r),a=t.sub(e),o=i.dot(n),u=n.dot(a),l=i.dot(a),d=n.dot(n),c=a.dot(a).mul(d).sub(u.mul(u)),h=o.mul(u).sub(l.mul(d)).div(c).clamp(),p=o.add(u.mul(h)).div(d).clamp();return bn(h,p)});if(this.colorNode=un(()=>{const e=Rl();if(i){const t=this.dashSizeNode?gn(this.dashSizeNode):Lh,r=this.gapSizeNode?gn(this.gapSizeNode):Ph;na.assign(t),aa.assign(r);const s=In("float","lineDistance");e.y.lessThan(-1).or(e.y.greaterThan(1)).discard(),s.mod(na.add(aa)).greaterThan(na).discard()}const a=gn(1).toVar("alpha");if(n){const e=In("vec3","worldStart"),s=In("vec3","worldEnd"),n=In("vec4","worldPos").xyz.normalize().mul(1e5),u=s.sub(e),l=o({p1:e,p2:s,p3:vn(0,0,0),p4:n}),d=e.add(u.mul(l.x)),c=n.mul(l.y),h=d.sub(c).length().div(Bh);if(!i)if(r&&t.currentSamples>0){const e=h.fwidth();a.assign(lu(e.negate().add(.5),e.add(.5),h).oneMinus())}else h.greaterThan(.5).discard()}else if(r&&t.currentSamples>0){const t=e.x,r=e.y.greaterThan(0).select(e.y.sub(1),e.y.add(1)),s=t.mul(t).add(r.mul(r)),i=gn(s.fwidth()).toVar("dlen");cn(e.y.abs().greaterThan(1),()=>{a.assign(lu(i.oneMinus(),i.add(1),s).oneMinus())})}else cn(e.y.abs().greaterThan(1),()=>{const t=e.x,r=e.y.greaterThan(0).select(e.y.sub(1),e.y.add(1));t.mul(t).add(r.mul(r)).greaterThan(1).discard()});let u;if(this.lineColorNode)u=this.lineColorNode;else if(s){const e=Sl("instanceColorStart"),t=Sl("instanceColorEnd");u=Ld.y.lessThan(.5).select(e,t).mul(ih)}else u=ih;return En(u,a)})(),this.transparent){const e=this.opacityNode?gn(this.opacityNode):oh;this.outputNode=En(this.colorNode.rgb.mul(e).add(Ep().rgb.mul(e.oneMinus())),this.colorNode.a)}super.setup(e)}get worldUnits(){return this._useWorldUnits}set worldUnits(e){this._useWorldUnits!==e&&(this._useWorldUnits=e,this.needsUpdate=!0)}get dashed(){return this._useDash}set dashed(e){this._useDash!==e&&(this._useDash=e,this.needsUpdate=!0)}get alphaToCoverage(){return this._useAlphaToCoverage}set alphaToCoverage(e){this._useAlphaToCoverage!==e&&(this._useAlphaToCoverage=e,this.needsUpdate=!0)}}const ng=new te;class ag extends Zp{static get type(){return"MeshNormalNodeMaterial"}constructor(e){super(),this.isMeshNormalNodeMaterial=!0,this.setDefaultValues(ng),this.setValues(e)}setupDiffuseColor(){const e=this.opacityNode?gn(this.opacityNode):oh;On.assign(Gu(En(jc(Xd),e),re))}}const og=un(([e=Ud])=>{const t=e.z.atan(e.x).mul(1/(2*Math.PI)).add(.5),r=e.y.clamp(-1,1).asin().mul(1/Math.PI).add(.5);return bn(t,r)});class ug extends se{constructor(e=1,t={}){super(e,t),this.isCubeRenderTarget=!0}fromEquirectangularTexture(e,t){const r=t.minFilter,s=t.generateMipmaps;t.generateMipmaps=!0,this.texture.type=t.type,this.texture.colorSpace=t.colorSpace,this.texture.generateMipmaps=t.generateMipmaps,this.texture.minFilter=t.minFilter,this.texture.magFilter=t.magFilter;const i=new ie(5,5,5),n=og(Ud),a=new Zp;a.colorNode=Pl(t,n,0),a.side=M,a.blending=ee;const o=new ne(i,a),u=new ae;u.add(o),t.minFilter===K&&(t.minFilter=oe);const l=new ue(1,10,this),d=e.getMRT();return e.setMRT(null),l.update(e,u),e.setMRT(d),t.minFilter=r,t.currentGenerateMipmaps=s,o.geometry.dispose(),o.material.dispose(),this}}const lg=new WeakMap;class dg extends ci{static get type(){return"CubeMapNode"}constructor(e){super("vec3"),this.envNode=e,this._cubeTexture=null,this._cubeTextureNode=gc(null);const t=new P;t.isRenderTargetTexture=!0,this._defaultTexture=t,this.updateBeforeType=Js.RENDER}updateBefore(e){const{renderer:t,material:r}=e,s=this.envNode;if(s.isTextureNode||s.isMaterialReferenceNode){const e=s.isTextureNode?s.value:r[s.property];if(e&&e.isTexture){const r=e.mapping;if(r===le||r===de){if(lg.has(e)){const t=lg.get(e);hg(t,e.mapping),this._cubeTexture=t}else{const r=e.image;if(function(e){return null!=e&&e.height>0}(r)){const s=new ug(r.height);s.fromEquirectangularTexture(t,e),hg(s.texture,e.mapping),this._cubeTexture=s.texture,lg.set(e,s.texture),e.addEventListener("dispose",cg)}else this._cubeTexture=this._defaultTexture}this._cubeTextureNode.value=this._cubeTexture}else this._cubeTextureNode=this.envNode}}}setup(e){return this.updateBefore(e),this._cubeTextureNode}}function cg(e){const t=e.target;t.removeEventListener("dispose",cg);const r=lg.get(t);void 0!==r&&(lg.delete(t),r.dispose())}function hg(e,t){t===le?e.mapping=B:t===de&&(e.mapping=D)}const pg=rn(dg).setParameterLength(1);class gg extends fp{static get type(){return"BasicEnvironmentNode"}constructor(e=null){super(),this.envNode=e}setup(e){e.context.environment=pg(this.envNode)}}class mg extends fp{static get type(){return"BasicLightMapNode"}constructor(e=null){super(),this.lightMapNode=e}setup(e){const t=gn(1/Math.PI);e.context.irradianceLightMap=this.lightMapNode.mul(t)}}class fg{start(e){e.lightsNode.setupLights(e,e.lightsNode.getLightNodes(e)),this.indirect(e)}finish(){}direct(){}directRectArea(){}indirect(){}ambientOcclusion(){}}class yg extends fg{constructor(){super()}indirect({context:e}){const t=e.ambientOcclusion,r=e.reflectedLight,s=e.irradianceLightMap;r.indirectDiffuse.assign(En(0)),s?r.indirectDiffuse.addAssign(s):r.indirectDiffuse.addAssign(En(1,1,1,0)),r.indirectDiffuse.mulAssign(t),r.indirectDiffuse.mulAssign(On.rgb)}finish(e){const{material:t,context:r}=e,s=r.outgoingLight,i=e.context.environment;if(i)switch(t.combine){case pe:s.rgb.assign(nu(s.rgb,s.rgb.mul(i.rgb),ch.mul(hh)));break;case he:s.rgb.assign(nu(s.rgb,i.rgb,ch.mul(hh)));break;case ce:s.rgb.addAssign(i.rgb.mul(ch.mul(hh)));break;default:d("BasicLightingModel: Unsupported .combine value:",t.combine)}}}const bg=new ge;class xg extends Zp{static get type(){return"MeshBasicNodeMaterial"}constructor(e){super(),this.isMeshBasicNodeMaterial=!0,this.lights=!0,this.setDefaultValues(bg),this.setValues(e)}setupNormal(){return zd(qd)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new gg(t):null}setupLightMap(e){let t=null;return e.material.lightMap&&(t=new mg(Oh)),t}setupOutgoingLight(){return On.rgb}setupLightingModel(){return new yg}}const Tg=un(({f0:e,f90:t,dotVH:r})=>{const s=r.mul(-5.55473).sub(6.98316).mul(r).exp2();return e.mul(s.oneMinus()).add(t.mul(s))}),_g=un(e=>e.diffuseColor.mul(1/Math.PI)),vg=un(({dotNH:e})=>sa.mul(gn(.5)).add(1).mul(gn(1/Math.PI)).mul(e.pow(sa))),Ng=un(({lightDirection:e})=>{const t=e.add(Od).normalize(),r=Xd.dot(t).clamp(),s=Od.dot(t).clamp(),i=Tg({f0:ea,f90:1,dotVH:s}),n=gn(.25),a=vg({dotNH:r});return i.mul(n).mul(a)});class Sg extends yg{constructor(e=!0){super(),this.specular=e}direct({lightDirection:e,lightColor:t,reflectedLight:r}){const s=Xd.dot(e).clamp().mul(t);r.directDiffuse.addAssign(s.mul(_g({diffuseColor:On.rgb}))),!0===this.specular&&r.directSpecular.addAssign(s.mul(Ng({lightDirection:e})).mul(ch))}indirect(e){const{ambientOcclusion:t,irradiance:r,reflectedLight:s}=e.context;s.indirectDiffuse.addAssign(r.mul(_g({diffuseColor:On}))),s.indirectDiffuse.mulAssign(t)}}const Rg=new me;class Eg extends Zp{static get type(){return"MeshLambertNodeMaterial"}constructor(e){super(),this.isMeshLambertNodeMaterial=!0,this.lights=!0,this.setDefaultValues(Rg),this.setValues(e)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new gg(t):null}setupLightingModel(){return new Sg(!1)}}const Ag=new fe;class wg extends Zp{static get type(){return"MeshPhongNodeMaterial"}constructor(e){super(),this.isMeshPhongNodeMaterial=!0,this.lights=!0,this.shininessNode=null,this.specularNode=null,this.setDefaultValues(Ag),this.setValues(e)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new gg(t):null}setupLightingModel(){return new Sg}setupVariants(){const e=(this.shininessNode?gn(this.shininessNode):nh).max(1e-4);sa.assign(e);const t=this.specularNode||uh;ea.assign(t)}copy(e){return this.shininessNode=e.shininessNode,this.specularNode=e.specularNode,super.copy(e)}}const Cg=un(e=>{if(!1===e.geometry.hasAttribute("normal"))return gn(0);const t=qd.dFdx().abs().max(qd.dFdy().abs());return t.x.max(t.y).max(t.z)}),Mg=un(e=>{const{roughness:t}=e,r=Cg();let s=t.max(.0525);return s=s.add(r),s=s.min(1),s}),Fg=un(({alpha:e,dotNL:t,dotNV:r})=>{const s=e.pow2(),i=t.mul(s.add(s.oneMinus().mul(r.pow2())).sqrt()),n=r.mul(s.add(s.oneMinus().mul(t.pow2())).sqrt());return Pa(.5,i.add(n).max(so))}).setLayout({name:"V_GGX_SmithCorrelated",type:"float",inputs:[{name:"alpha",type:"float"},{name:"dotNL",type:"float"},{name:"dotNV",type:"float"}]}),Lg=un(({alphaT:e,alphaB:t,dotTV:r,dotBV:s,dotTL:i,dotBL:n,dotNV:a,dotNL:o})=>{const u=o.mul(vn(e.mul(r),t.mul(s),a).length()),l=a.mul(vn(e.mul(i),t.mul(n),o).length());return Pa(.5,u.add(l))}).setLayout({name:"V_GGX_SmithCorrelated_Anisotropic",type:"float",inputs:[{name:"alphaT",type:"float",qualifier:"in"},{name:"alphaB",type:"float",qualifier:"in"},{name:"dotTV",type:"float",qualifier:"in"},{name:"dotBV",type:"float",qualifier:"in"},{name:"dotTL",type:"float",qualifier:"in"},{name:"dotBL",type:"float",qualifier:"in"},{name:"dotNV",type:"float",qualifier:"in"},{name:"dotNL",type:"float",qualifier:"in"}]}),Pg=un(({alpha:e,dotNH:t})=>{const r=e.pow2(),s=t.pow2().mul(r.oneMinus()).oneMinus();return r.div(s.pow2()).mul(1/Math.PI)}).setLayout({name:"D_GGX",type:"float",inputs:[{name:"alpha",type:"float"},{name:"dotNH",type:"float"}]}),Bg=gn(1/Math.PI),Dg=un(({alphaT:e,alphaB:t,dotNH:r,dotTH:s,dotBH:i})=>{const n=e.mul(t),a=vn(t.mul(s),e.mul(i),n.mul(r)),o=a.dot(a),u=n.div(o);return Bg.mul(n.mul(u.pow2()))}).setLayout({name:"D_GGX_Anisotropic",type:"float",inputs:[{name:"alphaT",type:"float",qualifier:"in"},{name:"alphaB",type:"float",qualifier:"in"},{name:"dotNH",type:"float",qualifier:"in"},{name:"dotTH",type:"float",qualifier:"in"},{name:"dotBH",type:"float",qualifier:"in"}]}),Ug=un(({lightDirection:e,f0:t,f90:r,roughness:s,f:i,normalView:n=Xd,USE_IRIDESCENCE:a,USE_ANISOTROPY:o})=>{const u=s.pow2(),l=e.add(Od).normalize(),d=n.dot(e).clamp(),c=n.dot(Od).clamp(),h=n.dot(l).clamp(),p=Od.dot(l).clamp();let g,m,f=Tg({f0:t,f90:r,dotVH:p});if(Ki(a)&&(f=jn.mix(f,i)),Ki(o)){const t=Zn.dot(e),r=Zn.dot(Od),s=Zn.dot(l),i=Jn.dot(e),n=Jn.dot(Od),a=Jn.dot(l);g=Lg({alphaT:Yn,alphaB:u,dotTV:r,dotBV:n,dotTL:t,dotBL:i,dotNV:c,dotNL:d}),m=Dg({alphaT:Yn,alphaB:u,dotNH:h,dotTH:s,dotBH:a})}else g=Fg({alpha:u,dotNL:d,dotNV:c}),m=Pg({alpha:u,dotNH:h});return f.mul(g).mul(m)}),Ig=new Uint16Array([12469,15057,12620,14925,13266,14620,13807,14376,14323,13990,14545,13625,14713,13328,14840,12882,14931,12528,14996,12233,15039,11829,15066,11525,15080,11295,15085,10976,15082,10705,15073,10495,13880,14564,13898,14542,13977,14430,14158,14124,14393,13732,14556,13410,14702,12996,14814,12596,14891,12291,14937,11834,14957,11489,14958,11194,14943,10803,14921,10506,14893,10278,14858,9960,14484,14039,14487,14025,14499,13941,14524,13740,14574,13468,14654,13106,14743,12678,14818,12344,14867,11893,14889,11509,14893,11180,14881,10751,14852,10428,14812,10128,14765,9754,14712,9466,14764,13480,14764,13475,14766,13440,14766,13347,14769,13070,14786,12713,14816,12387,14844,11957,14860,11549,14868,11215,14855,10751,14825,10403,14782,10044,14729,9651,14666,9352,14599,9029,14967,12835,14966,12831,14963,12804,14954,12723,14936,12564,14917,12347,14900,11958,14886,11569,14878,11247,14859,10765,14828,10401,14784,10011,14727,9600,14660,9289,14586,8893,14508,8533,15111,12234,15110,12234,15104,12216,15092,12156,15067,12010,15028,11776,14981,11500,14942,11205,14902,10752,14861,10393,14812,9991,14752,9570,14682,9252,14603,8808,14519,8445,14431,8145,15209,11449,15208,11451,15202,11451,15190,11438,15163,11384,15117,11274,15055,10979,14994,10648,14932,10343,14871,9936,14803,9532,14729,9218,14645,8742,14556,8381,14461,8020,14365,7603,15273,10603,15272,10607,15267,10619,15256,10631,15231,10614,15182,10535,15118,10389,15042,10167,14963,9787,14883,9447,14800,9115,14710,8665,14615,8318,14514,7911,14411,7507,14279,7198,15314,9675,15313,9683,15309,9712,15298,9759,15277,9797,15229,9773,15166,9668,15084,9487,14995,9274,14898,8910,14800,8539,14697,8234,14590,7790,14479,7409,14367,7067,14178,6621,15337,8619,15337,8631,15333,8677,15325,8769,15305,8871,15264,8940,15202,8909,15119,8775,15022,8565,14916,8328,14804,8009,14688,7614,14569,7287,14448,6888,14321,6483,14088,6171,15350,7402,15350,7419,15347,7480,15340,7613,15322,7804,15287,7973,15229,8057,15148,8012,15046,7846,14933,7611,14810,7357,14682,7069,14552,6656,14421,6316,14251,5948,14007,5528,15356,5942,15356,5977,15353,6119,15348,6294,15332,6551,15302,6824,15249,7044,15171,7122,15070,7050,14949,6861,14818,6611,14679,6349,14538,6067,14398,5651,14189,5311,13935,4958,15359,4123,15359,4153,15356,4296,15353,4646,15338,5160,15311,5508,15263,5829,15188,6042,15088,6094,14966,6001,14826,5796,14678,5543,14527,5287,14377,4985,14133,4586,13869,4257,15360,1563,15360,1642,15358,2076,15354,2636,15341,3350,15317,4019,15273,4429,15203,4732,15105,4911,14981,4932,14836,4818,14679,4621,14517,4386,14359,4156,14083,3795,13808,3437,15360,122,15360,137,15358,285,15355,636,15344,1274,15322,2177,15281,2765,15215,3223,15120,3451,14995,3569,14846,3567,14681,3466,14511,3305,14344,3121,14037,2800,13753,2467,15360,0,15360,1,15359,21,15355,89,15346,253,15325,479,15287,796,15225,1148,15133,1492,15008,1749,14856,1882,14685,1886,14506,1783,14324,1608,13996,1398,13702,1183]);let Og=null;const Vg=un(({roughness:e,dotNV:t})=>{null===Og&&(Og=new ye(Ig,16,16,G,be),Og.name="DFG_LUT",Og.minFilter=oe,Og.magFilter=oe,Og.wrapS=xe,Og.wrapT=xe,Og.generateMipmaps=!1,Og.needsUpdate=!0);const r=bn(e,t);return Pl(Og,r).rg}),kg=un(({lightDirection:e,f0:t,f90:r,roughness:s,f:i,USE_IRIDESCENCE:n,USE_ANISOTROPY:a})=>{const o=Ug({lightDirection:e,f0:t,f90:r,roughness:s,f:i,USE_IRIDESCENCE:n,USE_ANISOTROPY:a}),u=Xd.dot(e).clamp(),l=Xd.dot(Od).clamp(),d=Vg({roughness:s,dotNV:l}),c=Vg({roughness:s,dotNV:u}),h=t.mul(d.x).add(r.mul(d.y)),p=t.mul(c.x).add(r.mul(c.y)),g=d.x.add(d.y),m=c.x.add(c.y),f=gn(1).sub(g),y=gn(1).sub(m),b=t.add(t.oneMinus().mul(.047619)),x=h.mul(p).mul(b).div(gn(1).sub(f.mul(y).mul(b).mul(b)).add(so)),T=f.mul(y),_=x.mul(T);return o.add(_)}),Gg=un(e=>{const{dotNV:t,specularColor:r,specularF90:s,roughness:i}=e,n=Vg({dotNV:t,roughness:i});return r.mul(n.x).add(s.mul(n.y))}),zg=un(({f:e,f90:t,dotVH:r})=>{const s=r.oneMinus().saturate(),i=s.mul(s),n=s.mul(i,i).clamp(0,.9999);return e.sub(vn(t).mul(n)).div(n.oneMinus())}).setLayout({name:"Schlick_to_F0",type:"vec3",inputs:[{name:"f",type:"vec3"},{name:"f90",type:"float"},{name:"dotVH",type:"float"}]}),$g=un(({roughness:e,dotNH:t})=>{const r=e.pow2(),s=gn(1).div(r),i=t.pow2().oneMinus().max(.0078125);return gn(2).add(s).mul(i.pow(s.mul(.5))).div(2*Math.PI)}).setLayout({name:"D_Charlie",type:"float",inputs:[{name:"roughness",type:"float"},{name:"dotNH",type:"float"}]}),Wg=un(({dotNV:e,dotNL:t})=>gn(1).div(gn(4).mul(t.add(e).sub(t.mul(e))))).setLayout({name:"V_Neubelt",type:"float",inputs:[{name:"dotNV",type:"float"},{name:"dotNL",type:"float"}]}),Hg=un(({lightDirection:e})=>{const t=e.add(Od).normalize(),r=Xd.dot(e).clamp(),s=Xd.dot(Od).clamp(),i=Xd.dot(t).clamp(),n=$g({roughness:qn,dotNH:i}),a=Wg({dotNV:s,dotNL:r});return Hn.mul(n).mul(a)}),qg=un(({N:e,V:t,roughness:r})=>{const s=e.dot(t).saturate(),i=bn(r,s.oneMinus().sqrt());return i.assign(i.mul(.984375).add(.0078125)),i}).setLayout({name:"LTC_Uv",type:"vec2",inputs:[{name:"N",type:"vec3"},{name:"V",type:"vec3"},{name:"roughness",type:"float"}]}),jg=un(({f:e})=>{const t=e.length();return Ho(t.mul(t).add(e.z).div(t.add(1)),0)}).setLayout({name:"LTC_ClippedSphereFormFactor",type:"float",inputs:[{name:"f",type:"vec3"}]}),Xg=un(({v1:e,v2:t})=>{const r=e.dot(t),s=r.abs().toVar(),i=s.mul(.0145206).add(.4965155).mul(s).add(.8543985).toVar(),n=s.add(4.1616724).mul(s).add(3.417594).toVar(),a=i.div(n),o=r.greaterThan(0).select(a,Ho(r.mul(r).oneMinus(),1e-7).inverseSqrt().mul(.5).sub(a));return e.cross(t).mul(o)}).setLayout({name:"LTC_EdgeVectorFormFactor",type:"vec3",inputs:[{name:"v1",type:"vec3"},{name:"v2",type:"vec3"}]}),Kg=un(({N:e,V:t,P:r,mInv:s,p0:i,p1:n,p2:a,p3:o})=>{const u=n.sub(i).toVar(),l=o.sub(i).toVar(),d=u.cross(l),c=vn().toVar();return cn(d.dot(r.sub(i)).greaterThanEqual(0),()=>{const u=t.sub(e.mul(t.dot(e))).normalize(),l=e.cross(u).negate(),d=s.mul(Fn(u,l,e).transpose()).toVar(),h=d.mul(i.sub(r)).normalize().toVar(),p=d.mul(n.sub(r)).normalize().toVar(),g=d.mul(a.sub(r)).normalize().toVar(),m=d.mul(o.sub(r)).normalize().toVar(),f=vn(0).toVar();f.addAssign(Xg({v1:h,v2:p})),f.addAssign(Xg({v1:p,v2:g})),f.addAssign(Xg({v1:g,v2:m})),f.addAssign(Xg({v1:m,v2:h})),c.assign(vn(jg({f:f})))}),c}).setLayout({name:"LTC_Evaluate",type:"vec3",inputs:[{name:"N",type:"vec3"},{name:"V",type:"vec3"},{name:"P",type:"vec3"},{name:"mInv",type:"mat3"},{name:"p0",type:"vec3"},{name:"p1",type:"vec3"},{name:"p2",type:"vec3"},{name:"p3",type:"vec3"}]}),Yg=un(({P:e,p0:t,p1:r,p2:s,p3:i})=>{const n=r.sub(t).toVar(),a=i.sub(t).toVar(),o=n.cross(a),u=vn().toVar();return cn(o.dot(e.sub(t)).greaterThanEqual(0),()=>{const n=t.sub(e).normalize().toVar(),a=r.sub(e).normalize().toVar(),o=s.sub(e).normalize().toVar(),l=i.sub(e).normalize().toVar(),d=vn(0).toVar();d.addAssign(Xg({v1:n,v2:a})),d.addAssign(Xg({v1:a,v2:o})),d.addAssign(Xg({v1:o,v2:l})),d.addAssign(Xg({v1:l,v2:n})),u.assign(vn(jg({f:d.abs()})))}),u}).setLayout({name:"LTC_Evaluate",type:"vec3",inputs:[{name:"P",type:"vec3"},{name:"p0",type:"vec3"},{name:"p1",type:"vec3"},{name:"p2",type:"vec3"},{name:"p3",type:"vec3"}]}),Qg=1/6,Zg=e=>La(Qg,La(e,La(e,e.negate().add(3)).sub(3)).add(1)),Jg=e=>La(Qg,La(e,La(e,La(3,e).sub(6))).add(4)),em=e=>La(Qg,La(e,La(e,La(-3,e).add(3)).add(3)).add(1)),tm=e=>La(Qg,Zo(e,3)),rm=e=>Zg(e).add(Jg(e)),sm=e=>em(e).add(tm(e)),im=e=>Ma(-1,Jg(e).div(Zg(e).add(Jg(e)))),nm=e=>Ma(1,tm(e).div(em(e).add(tm(e)))),am=(e,t,r)=>{const s=e.uvNode,i=La(s,t.zw).add(.5),n=To(i),a=No(i),o=rm(a.x),u=sm(a.x),l=im(a.x),d=nm(a.x),c=im(a.y),h=nm(a.y),p=bn(n.x.add(l),n.y.add(c)).sub(.5).mul(t.xy),g=bn(n.x.add(d),n.y.add(c)).sub(.5).mul(t.xy),m=bn(n.x.add(l),n.y.add(h)).sub(.5).mul(t.xy),f=bn(n.x.add(d),n.y.add(h)).sub(.5).mul(t.xy),y=rm(a.y).mul(Ma(o.mul(e.sample(p).level(r)),u.mul(e.sample(g).level(r)))),b=sm(a.y).mul(Ma(o.mul(e.sample(m).level(r)),u.mul(e.sample(f).level(r))));return y.add(b)},om=un(([e,t])=>{const r=bn(e.size(mn(t))),s=bn(e.size(mn(t.add(1)))),i=Pa(1,r),n=Pa(1,s),a=am(e,En(i,r),To(t)),o=am(e,En(n,s),_o(t));return No(t).mix(a,o)}),um=un(([e,t])=>{const r=t.mul(Cl(e));return om(e,r)}),lm=un(([e,t,r,s,i])=>{const n=vn(uu(t.negate(),vo(e),Pa(1,s))),a=vn(Lo(i[0].xyz),Lo(i[1].xyz),Lo(i[2].xyz));return vo(n).mul(r.mul(a))}).setLayout({name:"getVolumeTransmissionRay",type:"vec3",inputs:[{name:"n",type:"vec3"},{name:"v",type:"vec3"},{name:"thickness",type:"float"},{name:"ior",type:"float"},{name:"modelMatrix",type:"mat4"}]}),dm=un(([e,t])=>e.mul(au(t.mul(2).sub(2),0,1))).setLayout({name:"applyIorToRoughness",type:"float",inputs:[{name:"roughness",type:"float"},{name:"ior",type:"float"}]}),cm=Sp(),hm=Ep(),pm=un(([e,t,r],{material:s})=>{const i=(s.side===M?cm:hm).sample(e),n=yo(jl.x).mul(dm(t,r));return om(i,n)}),gm=un(([e,t,r])=>(cn(r.notEqual(0),()=>{const s=fo(t).negate().div(r);return go(s.negate().mul(e))}),vn(1))).setLayout({name:"volumeAttenuation",type:"vec3",inputs:[{name:"transmissionDistance",type:"float"},{name:"attenuationColor",type:"vec3"},{name:"attenuationDistance",type:"float"}]}),mm=un(([e,t,r,s,i,n,a,o,u,l,d,c,h,p,g])=>{let m,f;if(g){m=En().toVar(),f=vn().toVar();const i=d.sub(1).mul(g.mul(.025)),n=vn(d.sub(i),d,d.add(i));lp({start:0,end:3},({i:i})=>{const d=n.element(i),g=lm(e,t,c,d,o),y=a.add(g),b=l.mul(u.mul(En(y,1))),x=bn(b.xy.div(b.w)).toVar();x.addAssign(1),x.divAssign(2),x.assign(bn(x.x,x.y.oneMinus()));const T=pm(x,r,d);m.element(i).assign(T.element(i)),m.a.addAssign(T.a),f.element(i).assign(s.element(i).mul(gm(Lo(g),h,p).element(i)))}),m.a.divAssign(3)}else{const i=lm(e,t,c,d,o),n=a.add(i),g=l.mul(u.mul(En(n,1))),y=bn(g.xy.div(g.w)).toVar();y.addAssign(1),y.divAssign(2),y.assign(bn(y.x,y.y.oneMinus())),m=pm(y,r,d),f=s.mul(gm(Lo(i),h,p))}const y=f.rgb.mul(m.rgb),b=e.dot(t).clamp(),x=vn(Gg({dotNV:b,specularColor:i,specularF90:n,roughness:r})),T=f.r.add(f.g,f.b).div(3);return En(x.oneMinus().mul(y),m.a.oneMinus().mul(T).oneMinus())}),fm=Fn(3.2404542,-.969266,.0556434,-1.5371385,1.8760108,-.2040259,-.4985314,.041556,1.0572252),ym=(e,t)=>e.sub(t).div(e.add(t)).pow2(),bm=un(({outsideIOR:e,eta2:t,cosTheta1:r,thinFilmThickness:s,baseF0:i})=>{const n=nu(e,t,lu(0,.03,s)),a=e.div(n).pow2().mul(r.pow2().oneMinus()).oneMinus();cn(a.lessThan(0),()=>vn(1));const o=a.sqrt(),u=ym(n,e),l=Tg({f0:u,f90:1,dotVH:r}),d=l.oneMinus(),c=n.lessThan(e).select(Math.PI,0),h=gn(Math.PI).sub(c),p=(e=>{const t=e.sqrt();return vn(1).add(t).div(vn(1).sub(t))})(i.clamp(0,.9999)),g=ym(p,n.toVec3()),m=Tg({f0:g,f90:1,dotVH:o}),f=vn(p.x.lessThan(n).select(Math.PI,0),p.y.lessThan(n).select(Math.PI,0),p.z.lessThan(n).select(Math.PI,0)),y=n.mul(s,o,2),b=vn(h).add(f),x=l.mul(m).clamp(1e-5,.9999),T=x.sqrt(),_=d.pow2().mul(m).div(vn(1).sub(x)),v=l.add(_).toVar(),N=_.sub(d).toVar();return lp({start:1,end:2,condition:"<=",name:"m"},({m:e})=>{N.mulAssign(T);const t=((e,t)=>{const r=e.mul(2*Math.PI*1e-9),s=vn(54856e-17,44201e-17,52481e-17),i=vn(1681e3,1795300,2208400),n=vn(43278e5,93046e5,66121e5),a=gn(9747e-17*Math.sqrt(2*Math.PI*45282e5)).mul(r.mul(2239900).add(t.x).cos()).mul(r.pow2().mul(-45282e5).exp());let o=s.mul(n.mul(2*Math.PI).sqrt()).mul(i.mul(r).add(t).cos()).mul(r.pow2().negate().mul(n).exp());return o=vn(o.x.add(a),o.y,o.z).div(1.0685e-7),fm.mul(o)})(gn(e).mul(y),gn(e).mul(b)).mul(2);v.addAssign(N.mul(t))}),v.max(vn(0))}).setLayout({name:"evalIridescence",type:"vec3",inputs:[{name:"outsideIOR",type:"float"},{name:"eta2",type:"float"},{name:"cosTheta1",type:"float"},{name:"thinFilmThickness",type:"float"},{name:"baseF0",type:"vec3"}]}),xm=un(({normal:e,viewDir:t,roughness:r})=>{const s=e.dot(t).saturate(),i=r.mul(r),n=r.add(.1).reciprocal(),a=gn(-1.9362).add(r.mul(1.0678)).add(i.mul(.4573)).sub(n.mul(.8469)),o=gn(-.6014).add(r.mul(.5538)).sub(i.mul(.467)).sub(n.mul(.1255));return a.mul(s).add(o).exp().saturate()}),Tm=vn(.04),_m=gn(1);class vm extends fg{constructor(e=!1,t=!1,r=!1,s=!1,i=!1,n=!1){super(),this.clearcoat=e,this.sheen=t,this.iridescence=r,this.anisotropy=s,this.transmission=i,this.dispersion=n,this.clearcoatRadiance=null,this.clearcoatSpecularDirect=null,this.clearcoatSpecularIndirect=null,this.sheenSpecularDirect=null,this.sheenSpecularIndirect=null,this.iridescenceFresnel=null,this.iridescenceF0=null,this.iridescenceF0Dielectric=null,this.iridescenceF0Metallic=null}start(e){if(!0===this.clearcoat&&(this.clearcoatRadiance=vn().toVar("clearcoatRadiance"),this.clearcoatSpecularDirect=vn().toVar("clearcoatSpecularDirect"),this.clearcoatSpecularIndirect=vn().toVar("clearcoatSpecularIndirect")),!0===this.sheen&&(this.sheenSpecularDirect=vn().toVar("sheenSpecularDirect"),this.sheenSpecularIndirect=vn().toVar("sheenSpecularIndirect")),!0===this.iridescence){const e=Xd.dot(Od).clamp(),t=bm({outsideIOR:gn(1),eta2:Xn,cosTheta1:e,thinFilmThickness:Kn,baseF0:ea}),r=bm({outsideIOR:gn(1),eta2:Xn,cosTheta1:e,thinFilmThickness:Kn,baseF0:On.rgb});this.iridescenceFresnel=nu(t,r,zn),this.iridescenceF0Dielectric=zg({f:t,f90:1,dotVH:e}),this.iridescenceF0Metallic=zg({f:r,f90:1,dotVH:e}),this.iridescenceF0=nu(this.iridescenceF0Dielectric,this.iridescenceF0Metallic,zn)}if(!0===this.transmission){const t=Dd,r=ud.sub(Dd).normalize(),s=Kd,i=e.context;i.backdrop=mm(s,r,Gn,Vn,ta,ra,t,Td,nd,sd,ua,da,ha,ca,this.dispersion?pa:null),i.backdropAlpha=la,On.a.mulAssign(nu(1,i.backdrop.a,la))}super.start(e)}computeMultiscattering(e,t,r,s,i=null){const n=Xd.dot(Od).clamp(),a=Vg({roughness:Gn,dotNV:n}),o=i?jn.mix(s,i):s,u=o.mul(a.x).add(r.mul(a.y)),l=a.x.add(a.y).oneMinus(),d=o.add(o.oneMinus().mul(.047619)),c=u.mul(d).div(l.mul(d).oneMinus());e.addAssign(u),t.addAssign(c.mul(l))}direct({lightDirection:e,lightColor:t,reflectedLight:r}){const s=Xd.dot(e).clamp().mul(t).toVar();if(!0===this.sheen){this.sheenSpecularDirect.addAssign(s.mul(Hg({lightDirection:e})));const t=xm({normal:Xd,viewDir:Od,roughness:qn}),r=xm({normal:Xd,viewDir:e,roughness:qn}),i=Hn.r.max(Hn.g).max(Hn.b).mul(t.max(r)).oneMinus();s.mulAssign(i)}if(!0===this.clearcoat){const r=Yd.dot(e).clamp().mul(t);this.clearcoatSpecularDirect.addAssign(r.mul(Ug({lightDirection:e,f0:Tm,f90:_m,roughness:Wn,normalView:Yd})))}r.directDiffuse.addAssign(s.mul(_g({diffuseColor:Vn}))),r.directSpecular.addAssign(s.mul(kg({lightDirection:e,f0:ta,f90:1,roughness:Gn,f:this.iridescenceFresnel,USE_IRIDESCENCE:this.iridescence,USE_ANISOTROPY:this.anisotropy})))}directRectArea({lightColor:e,lightPosition:t,halfWidth:r,halfHeight:s,reflectedLight:i,ltc_1:n,ltc_2:a}){const o=t.add(r).sub(s),u=t.sub(r).sub(s),l=t.sub(r).add(s),d=t.add(r).add(s),c=Xd,h=Od,p=Id.toVar(),g=qg({N:c,V:h,roughness:Gn}),m=n.sample(g).toVar(),f=a.sample(g).toVar(),y=Fn(vn(m.x,0,m.y),vn(0,1,0),vn(m.z,0,m.w)).toVar(),b=ta.mul(f.x).add(ra.sub(ta).mul(f.y)).toVar();if(i.directSpecular.addAssign(e.mul(b).mul(Kg({N:c,V:h,P:p,mInv:y,p0:o,p1:u,p2:l,p3:d}))),i.directDiffuse.addAssign(e.mul(Vn).mul(Kg({N:c,V:h,P:p,mInv:Fn(1,0,0,0,1,0,0,0,1),p0:o,p1:u,p2:l,p3:d}))),!0===this.clearcoat){const t=Yd,r=qg({N:t,V:h,roughness:Wn}),s=n.sample(r),i=a.sample(r),c=Fn(vn(s.x,0,s.y),vn(0,1,0),vn(s.z,0,s.w)),g=Tm.mul(i.x).add(_m.sub(Tm).mul(i.y));this.clearcoatSpecularDirect.addAssign(e.mul(g).mul(Kg({N:t,V:h,P:p,mInv:c,p0:o,p1:u,p2:l,p3:d})))}}indirect(e){this.indirectDiffuse(e),this.indirectSpecular(e),this.ambientOcclusion(e)}indirectDiffuse(e){const{irradiance:t,reflectedLight:r}=e.context,s=t.mul(_g({diffuseColor:Vn})).toVar();if(!0===this.sheen){const e=xm({normal:Xd,viewDir:Od,roughness:qn}),t=Hn.r.max(Hn.g).max(Hn.b).mul(e).oneMinus();s.mulAssign(t)}r.indirectDiffuse.addAssign(s)}indirectSpecular(e){const{radiance:t,iblIrradiance:r,reflectedLight:s}=e.context;if(!0===this.sheen&&this.sheenSpecularIndirect.addAssign(r.mul(Hn,xm({normal:Xd,viewDir:Od,roughness:qn}))),!0===this.clearcoat){const e=Yd.dot(Od).clamp(),t=Gg({dotNV:e,specularColor:Tm,specularF90:_m,roughness:Wn});this.clearcoatSpecularIndirect.addAssign(this.clearcoatRadiance.mul(t))}const i=vn().toVar("singleScatteringDielectric"),n=vn().toVar("multiScatteringDielectric"),a=vn().toVar("singleScatteringMetallic"),o=vn().toVar("multiScatteringMetallic");this.computeMultiscattering(i,n,ra,ea,this.iridescenceF0Dielectric),this.computeMultiscattering(a,o,ra,On.rgb,this.iridescenceF0Metallic);const u=nu(i,a,zn),l=nu(n,o,zn),d=i.add(n),c=Vn.mul(d.oneMinus()),h=r.mul(1/Math.PI),p=t.mul(u).add(l.mul(h)).toVar(),g=c.mul(h).toVar();if(!0===this.sheen){const e=xm({normal:Xd,viewDir:Od,roughness:qn}),t=Hn.r.max(Hn.g).max(Hn.b).mul(e).oneMinus();p.mulAssign(t),g.mulAssign(t)}s.indirectSpecular.addAssign(p),s.indirectDiffuse.addAssign(g)}ambientOcclusion(e){const{ambientOcclusion:t,reflectedLight:r}=e.context,s=Xd.dot(Od).clamp().add(t),i=Gn.mul(-16).oneMinus().negate().exp2(),n=t.sub(s.pow(i).oneMinus()).clamp();!0===this.clearcoat&&this.clearcoatSpecularIndirect.mulAssign(t),!0===this.sheen&&this.sheenSpecularIndirect.mulAssign(t),r.indirectDiffuse.mulAssign(t),r.indirectSpecular.mulAssign(n)}finish({context:e}){const{outgoingLight:t}=e;if(!0===this.clearcoat){const e=Yd.dot(Od).clamp(),r=Tg({dotVH:e,f0:Tm,f90:_m}),s=t.mul($n.mul(r).oneMinus()).add(this.clearcoatSpecularDirect.add(this.clearcoatSpecularIndirect).mul($n));t.assign(s)}if(!0===this.sheen){const e=t.add(this.sheenSpecularDirect,this.sheenSpecularIndirect.mul(1/Math.PI));t.assign(e)}}}const Nm=gn(1),Sm=gn(-2),Rm=gn(.8),Em=gn(-1),Am=gn(.4),wm=gn(2),Cm=gn(.305),Mm=gn(3),Fm=gn(.21),Lm=gn(4),Pm=gn(4),Bm=gn(16),Dm=un(([e])=>{const t=vn(Mo(e)).toVar(),r=gn(-1).toVar();return cn(t.x.greaterThan(t.z),()=>{cn(t.x.greaterThan(t.y),()=>{r.assign(bu(e.x.greaterThan(0),0,3))}).Else(()=>{r.assign(bu(e.y.greaterThan(0),1,4))})}).Else(()=>{cn(t.z.greaterThan(t.y),()=>{r.assign(bu(e.z.greaterThan(0),2,5))}).Else(()=>{r.assign(bu(e.y.greaterThan(0),1,4))})}),r}).setLayout({name:"getFace",type:"float",inputs:[{name:"direction",type:"vec3"}]}),Um=un(([e,t])=>{const r=bn().toVar();return cn(t.equal(0),()=>{r.assign(bn(e.z,e.y).div(Mo(e.x)))}).ElseIf(t.equal(1),()=>{r.assign(bn(e.x.negate(),e.z.negate()).div(Mo(e.y)))}).ElseIf(t.equal(2),()=>{r.assign(bn(e.x.negate(),e.y).div(Mo(e.z)))}).ElseIf(t.equal(3),()=>{r.assign(bn(e.z.negate(),e.y).div(Mo(e.x)))}).ElseIf(t.equal(4),()=>{r.assign(bn(e.x.negate(),e.z).div(Mo(e.y)))}).Else(()=>{r.assign(bn(e.x,e.y).div(Mo(e.z)))}),La(.5,r.add(1))}).setLayout({name:"getUV",type:"vec2",inputs:[{name:"direction",type:"vec3"},{name:"face",type:"float"}]}),Im=un(([e])=>{const t=gn(0).toVar();return cn(e.greaterThanEqual(Rm),()=>{t.assign(Nm.sub(e).mul(Em.sub(Sm)).div(Nm.sub(Rm)).add(Sm))}).ElseIf(e.greaterThanEqual(Am),()=>{t.assign(Rm.sub(e).mul(wm.sub(Em)).div(Rm.sub(Am)).add(Em))}).ElseIf(e.greaterThanEqual(Cm),()=>{t.assign(Am.sub(e).mul(Mm.sub(wm)).div(Am.sub(Cm)).add(wm))}).ElseIf(e.greaterThanEqual(Fm),()=>{t.assign(Cm.sub(e).mul(Lm.sub(Mm)).div(Cm.sub(Fm)).add(Mm))}).Else(()=>{t.assign(gn(-2).mul(yo(La(1.16,e))))}),t}).setLayout({name:"roughnessToMip",type:"float",inputs:[{name:"roughness",type:"float"}]}),Om=un(([e,t])=>{const r=e.toVar();r.assign(La(2,r).sub(1));const s=vn(r,1).toVar();return cn(t.equal(0),()=>{s.assign(s.zyx)}).ElseIf(t.equal(1),()=>{s.assign(s.xzy),s.xz.mulAssign(-1)}).ElseIf(t.equal(2),()=>{s.x.mulAssign(-1)}).ElseIf(t.equal(3),()=>{s.assign(s.zyx),s.xz.mulAssign(-1)}).ElseIf(t.equal(4),()=>{s.assign(s.xzy),s.xy.mulAssign(-1)}).ElseIf(t.equal(5),()=>{s.z.mulAssign(-1)}),s}).setLayout({name:"getDirection",type:"vec3",inputs:[{name:"uv",type:"vec2"},{name:"face",type:"float"}]}),Vm=un(([e,t,r,s,i,n])=>{const a=gn(r),o=vn(t),u=au(Im(a),Sm,n),l=No(u),d=To(u),c=vn(km(e,o,d,s,i,n)).toVar();return cn(l.notEqual(0),()=>{const t=vn(km(e,o,d.add(1),s,i,n)).toVar();c.assign(nu(c,t,l))}),c}),km=un(([e,t,r,s,i,n])=>{const a=gn(r).toVar(),o=vn(t),u=gn(Dm(o)).toVar(),l=gn(Ho(Pm.sub(a),0)).toVar();a.assign(Ho(a,Pm));const d=gn(mo(a)).toVar(),c=bn(Um(o,u).mul(d.sub(2)).add(1)).toVar();return cn(u.greaterThan(2),()=>{c.y.addAssign(d),u.subAssign(3)}),c.x.addAssign(u.mul(d)),c.x.addAssign(l.mul(La(3,Bm))),c.y.addAssign(La(4,mo(n).sub(d))),c.x.mulAssign(s),c.y.mulAssign(i),e.sample(c).grad(bn(),bn())}),Gm=un(({envMap:e,mipInt:t,outputDirection:r,theta:s,axis:i,CUBEUV_TEXEL_WIDTH:n,CUBEUV_TEXEL_HEIGHT:a,CUBEUV_MAX_MIP:o})=>{const u=Ro(s),l=r.mul(u).add(i.cross(r).mul(So(s))).add(i.mul(i.dot(r).mul(u.oneMinus())));return km(e,l,t,n,a,o)}),zm=un(({n:e,latitudinal:t,poleAxis:r,outputDirection:s,weights:i,samples:n,dTheta:a,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c})=>{const h=vn(bu(t,r,Qo(r,s))).toVar();cn(h.equal(vn(0)),()=>{h.assign(vn(s.z,0,s.x.negate()))}),h.assign(vo(h));const p=vn().toVar();return p.addAssign(i.element(0).mul(Gm({theta:0,axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c}))),lp({start:mn(1),end:e},({i:e})=>{cn(e.greaterThanEqual(n),()=>{dp()});const t=gn(a.mul(gn(e))).toVar();p.addAssign(i.element(e).mul(Gm({theta:t.mul(-1),axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c}))),p.addAssign(i.element(e).mul(Gm({theta:t,axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c})))}),En(p,1)}),$m=un(([e])=>{const t=fn(e).toVar();return t.assign(t.shiftLeft(fn(16)).bitOr(t.shiftRight(fn(16)))),t.assign(t.bitAnd(fn(1431655765)).shiftLeft(fn(1)).bitOr(t.bitAnd(fn(2863311530)).shiftRight(fn(1)))),t.assign(t.bitAnd(fn(858993459)).shiftLeft(fn(2)).bitOr(t.bitAnd(fn(3435973836)).shiftRight(fn(2)))),t.assign(t.bitAnd(fn(252645135)).shiftLeft(fn(4)).bitOr(t.bitAnd(fn(4042322160)).shiftRight(fn(4)))),t.assign(t.bitAnd(fn(16711935)).shiftLeft(fn(8)).bitOr(t.bitAnd(fn(4278255360)).shiftRight(fn(8)))),gn(t).mul(2.3283064365386963e-10)}),Wm=un(([e,t])=>bn(gn(e).div(gn(t)),$m(e))),Hm=un(([e,t,r])=>{const s=r.mul(r).toConst(),i=vn(1,0,0).toConst(),n=Qo(t,i).toConst(),a=bo(e.x).toConst(),o=La(2,3.14159265359).mul(e.y).toConst(),u=a.mul(Ro(o)).toConst(),l=a.mul(So(o)).toVar(),d=La(.5,t.z.add(1)).toConst();l.assign(d.oneMinus().mul(bo(u.mul(u).oneMinus())).add(d.mul(l)));const c=i.mul(u).add(n.mul(l)).add(t.mul(bo(Ho(0,u.mul(u).add(l.mul(l)).oneMinus()))));return vo(vn(s.mul(c.x),s.mul(c.y),Ho(0,c.z)))}),qm=un(({roughness:e,mipInt:t,envMap:r,N_immutable:s,GGX_SAMPLES:i,CUBEUV_TEXEL_WIDTH:n,CUBEUV_TEXEL_HEIGHT:a,CUBEUV_MAX_MIP:o})=>{const u=vn(s).toVar(),l=vn(0).toVar(),d=gn(0).toVar();return cn(e.lessThan(.001),()=>{l.assign(km(r,u,t,n,a,o))}).Else(()=>{const s=bu(Mo(u.z).lessThan(.999),vn(0,0,1),vn(1,0,0)),c=vo(Qo(s,u)).toVar(),h=Qo(u,c).toVar();lp({start:fn(0),end:i},({i:s})=>{const p=Wm(s,i),g=Hm(p,vn(0,0,1),e),m=vo(c.mul(g.x).add(h.mul(g.y)).add(u.mul(g.z))),f=vo(m.mul(Yo(u,m).mul(2)).sub(u)),y=Ho(Yo(u,f),0);cn(y.greaterThan(0),()=>{const e=km(r,f,t,n,a,o);l.addAssign(e.mul(y)),d.addAssign(y)})}),cn(d.greaterThan(0),()=>{l.assign(l.div(d))})}),En(l,1)}),jm=[.125,.215,.35,.446,.526,.582],Xm=20,Km=new _e(-1,1,1,-1,0,1),Ym=new ve(90,1),Qm=new e;let Zm=null,Jm=0,ef=0;const tf=new r,rf=new WeakMap,sf=[3,1,5,0,4,2],nf=Om(Rl(),Sl("faceIndex")).normalize(),af=vn(nf.x,nf.y,nf.z);class of{constructor(e){this._renderer=e,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._sizeLods=[],this._sigmas=[],this._lodMeshes=[],this._blurMaterial=null,this._ggxMaterial=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._backgroundBox=null}get _hasInitialized(){return this._renderer.hasInitialized()}fromScene(e,t=0,r=.1,s=100,i={}){const{size:n=256,position:a=tf,renderTarget:o=null}=i;if(this._setSize(n),!1===this._hasInitialized){d('PMREMGenerator: ".fromScene()" called before the backend is initialized. Try using "await renderer.init()" instead.');const n=o||this._allocateTarget();return i.renderTarget=n,this.fromSceneAsync(e,t,r,s,i),n}Zm=this._renderer.getRenderTarget(),Jm=this._renderer.getActiveCubeFace(),ef=this._renderer.getActiveMipmapLevel();const u=o||this._allocateTarget();return u.depthBuffer=!0,this._init(u),this._sceneToCubeUV(e,r,s,u,a),t>0&&this._blur(u,0,0,t),this._applyPMREM(u),this._cleanup(u),u}async fromSceneAsync(e,t=0,r=.1,s=100,i={}){return v('PMREMGenerator: ".fromSceneAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this.fromScene(e,t,r,s,i)}fromEquirectangular(e,t=null){if(!1===this._hasInitialized){d('PMREMGenerator: .fromEquirectangular() called before the backend is initialized. Try using "await renderer.init()" instead.'),this._setSizeFromTexture(e);const r=t||this._allocateTarget();return this.fromEquirectangularAsync(e,r),r}return this._fromTexture(e,t)}async fromEquirectangularAsync(e,t=null){return v('PMREMGenerator: ".fromEquirectangularAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this._fromTexture(e,t)}fromCubemap(e,t=null){if(!1===this._hasInitialized){d("PMREMGenerator: .fromCubemap() called before the backend is initialized. Try using .fromCubemapAsync() instead."),this._setSizeFromTexture(e);const r=t||this._allocateTarget();return this.fromCubemapAsync(e,t),r}return this._fromTexture(e,t)}async fromCubemapAsync(e,t=null){return v('PMREMGenerator: ".fromCubemapAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this._fromTexture(e,t)}async compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=cf(),await this._compileMaterial(this._cubemapMaterial))}async compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=hf(),await this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose(),null!==this._backgroundBox&&(this._backgroundBox.geometry.dispose(),this._backgroundBox.material.dispose())}_setSizeFromTexture(e){e.mapping===B||e.mapping===D?this._setSize(0===e.image.length?16:e.image[0].width||e.image[0].image.width):this._setSize(e.image.width/4)}_setSize(e){this._lodMax=Math.floor(Math.log2(e)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._ggxMaterial&&this._ggxMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let e=0;ee-4?o=jm[a-e+4-1]:0===a&&(o=0),r.push(o);const u=1/(n-2),l=-u,d=1+u,c=[l,l,d,l,d,d,l,l,d,d,l,d],h=6,p=6,g=3,m=2,f=1,y=new Float32Array(g*p*h),b=new Float32Array(m*p*h),x=new Float32Array(f*p*h);for(let e=0;e2?0:-1,s=[t,r,0,t+2/3,r,0,t+2/3,r+1,0,t,r,0,t+2/3,r+1,0,t,r+1,0],i=sf[e];y.set(s,g*p*i),b.set(c,m*p*i);const n=[i,i,i,i,i,i];x.set(n,f*p*i)}const T=new Te;T.setAttribute("position",new Ae(y,g)),T.setAttribute("uv",new Ae(b,m)),T.setAttribute("faceIndex",new Ae(x,f)),s.push(new ne(T,null)),i>4&&i--}return{lodMeshes:s,sizeLods:t,sigmas:r}}(t)),this._blurMaterial=function(e,t,s){const i=Vl(new Array(Xm).fill(0)),n=_a(new r(0,1,0)),a=_a(0),o=gn(Xm),u=_a(0),l=_a(1),d=Pl(),c=_a(0),h=gn(1/t),p=gn(1/s),g=gn(e),m={n:o,latitudinal:u,weights:i,poleAxis:n,outputDirection:af,dTheta:a,samples:l,envMap:d,mipInt:c,CUBEUV_TEXEL_WIDTH:h,CUBEUV_TEXEL_HEIGHT:p,CUBEUV_MAX_MIP:g},f=df("blur");return f.fragmentNode=zm({...m,latitudinal:u.equal(1)}),rf.set(f,m),f}(t,e.width,e.height),this._ggxMaterial=function(e,t,r){const s=Pl(),i=_a(0),n=_a(0),a=gn(1/t),o=gn(1/r),u=gn(e),l={envMap:s,roughness:i,mipInt:n,CUBEUV_TEXEL_WIDTH:a,CUBEUV_TEXEL_HEIGHT:o,CUBEUV_MAX_MIP:u},d=df("ggx");return d.fragmentNode=qm({...l,N_immutable:af,GGX_SAMPLES:fn(512)}),rf.set(d,l),d}(t,e.width,e.height)}}async _compileMaterial(e){const t=new ne(new Te,e);await this._renderer.compile(t,Km)}_sceneToCubeUV(e,t,r,s,i){const n=Ym;n.near=t,n.far=r;const a=[1,1,1,1,-1,1],o=[1,-1,1,-1,1,-1],u=this._renderer,l=u.autoClear;u.getClearColor(Qm),u.autoClear=!1,null===this._backgroundBox&&(this._backgroundBox=new ne(new ie,new ge({name:"PMREM.Background",side:M,depthWrite:!1,depthTest:!1})));const d=this._backgroundBox,c=d.material;let h=!1;const p=e.background;p?p.isColor&&(c.color.copy(p),e.background=null,h=!0):(c.color.copy(Qm),h=!0),u.setRenderTarget(s),u.clear(),h&&u.render(d,n);for(let t=0;t<6;t++){const r=t%3;0===r?(n.up.set(0,a[t],0),n.position.set(i.x,i.y,i.z),n.lookAt(i.x+o[t],i.y,i.z)):1===r?(n.up.set(0,0,a[t]),n.position.set(i.x,i.y,i.z),n.lookAt(i.x,i.y+o[t],i.z)):(n.up.set(0,a[t],0),n.position.set(i.x,i.y,i.z),n.lookAt(i.x,i.y,i.z+o[t]));const l=this._cubeSize;lf(s,r*l,t>2?l:0,l,l),u.render(e,n)}u.autoClear=l,e.background=p}_textureToCubeUV(e,t){const r=this._renderer,s=e.mapping===B||e.mapping===D;s?null===this._cubemapMaterial&&(this._cubemapMaterial=cf(e)):null===this._equirectMaterial&&(this._equirectMaterial=hf(e));const i=s?this._cubemapMaterial:this._equirectMaterial;i.fragmentNode.value=e;const n=this._lodMeshes[0];n.material=i;const a=this._cubeSize;lf(t,0,0,3*a,2*a),r.setRenderTarget(t),r.render(n,Km)}_applyPMREM(e){const t=this._renderer,r=t.autoClear;t.autoClear=!1;const s=this._lodMeshes.length;for(let t=1;tc-4?r-c+4:0),g=4*(this._cubeSize-h);e.texture.frame=(e.texture.frame||0)+1,o.envMap.value=e.texture,o.roughness.value=d,o.mipInt.value=c-t,lf(i,p,g,3*h,2*h),s.setRenderTarget(i),s.render(a,Km),i.texture.frame=(i.texture.frame||0)+1,o.envMap.value=i.texture,o.roughness.value=0,o.mipInt.value=c-r,lf(e,p,g,3*h,2*h),s.setRenderTarget(e),s.render(a,Km)}_blur(e,t,r,s,i){const n=this._pingPongRenderTarget;this._halfBlur(e,n,t,r,s,"latitudinal",i),this._halfBlur(n,e,r,r,s,"longitudinal",i)}_halfBlur(e,t,r,s,i,n,a){const u=this._renderer,l=this._blurMaterial;"latitudinal"!==n&&"longitudinal"!==n&&o("blur direction must be either latitudinal or longitudinal!");const c=this._lodMeshes[s];c.material=l;const h=rf.get(l),p=this._sizeLods[r]-1,g=isFinite(i)?Math.PI/(2*p):2*Math.PI/39,m=i/g,f=isFinite(i)?1+Math.floor(3*m):Xm;f>Xm&&d(`sigmaRadians, ${i}, is too large and will clip, as it requested ${f} samples when the maximum is set to 20`);const y=[];let b=0;for(let e=0;ex-4?s-x+4:0),4*(this._cubeSize-T),3*T,2*T),u.setRenderTarget(t),u.render(c,Km)}}function uf(e,t){const r=new Ne(e,t,{magFilter:oe,minFilter:oe,generateMipmaps:!1,type:be,format:Re,colorSpace:Se});return r.texture.mapping=Ee,r.texture.name="PMREM.cubeUv",r.texture.isPMREMTexture=!0,r.scissorTest=!0,r}function lf(e,t,r,s,i){e.viewport.set(t,r,s,i),e.scissor.set(t,r,s,i)}function df(e){const t=new Zp;return t.depthTest=!1,t.depthWrite=!1,t.blending=ee,t.name=`PMREM_${e}`,t}function cf(e){const t=df("cubemap");return t.fragmentNode=gc(e,af),t}function hf(e){const t=df("equirect");return t.fragmentNode=Pl(e,og(af),0),t}const pf=new WeakMap;function gf(e,t,r){const s=function(e){let t=pf.get(e);void 0===t&&(t=new WeakMap,pf.set(e,t));return t}(t);let i=s.get(e);if((void 0!==i?i.pmremVersion:-1)!==e.pmremVersion){const t=e.image;if(e.isCubeTexture){if(!function(e){if(null==e)return!1;let t=0;const r=6;for(let s=0;s0}(t))return null;i=r.fromEquirectangular(e,i)}i.pmremVersion=e.pmremVersion,s.set(e,i)}return i.texture}class mf extends ci{static get type(){return"PMREMNode"}constructor(e,t=null,r=null){super("vec3"),this._value=e,this._pmrem=null,this.uvNode=t,this.levelNode=r,this._generator=null;const s=new N;s.isRenderTargetTexture=!0,this._texture=Pl(s),this._width=_a(0),this._height=_a(0),this._maxMip=_a(0),this.updateBeforeType=Js.RENDER}set value(e){this._value=e,this._pmrem=null}get value(){return this._value}updateFromTexture(e){const t=function(e){const t=Math.log2(e)-2,r=1/e;return{texelWidth:1/(3*Math.max(Math.pow(2,t),112)),texelHeight:r,maxMip:t}}(e.image.height);this._texture.value=e,this._width.value=t.texelWidth,this._height.value=t.texelHeight,this._maxMip.value=t.maxMip}updateBefore(e){let t=this._pmrem;const r=t?t.pmremVersion:-1,s=this._value;r!==s.pmremVersion&&(t=!0===s.isPMREMTexture?s:gf(s,e.renderer,this._generator),null!==t&&(this._pmrem=t,this.updateFromTexture(t)))}setup(e){null===this._generator&&(this._generator=new of(e.renderer)),this.updateBefore(e);let t=this.uvNode;null===t&&e.context.getUV&&(t=e.context.getUV(this,e)),t=ac.mul(vn(t.x,t.y.negate(),t.z));let r=this.levelNode;return null===r&&e.context.getTextureLevel&&(r=e.context.getTextureLevel(this)),Vm(this._texture,t,r,this._width,this._height,this._maxMip)}dispose(){super.dispose(),null!==this._generator&&this._generator.dispose()}}const ff=rn(mf).setParameterLength(1,3),yf=new WeakMap;class bf extends fp{static get type(){return"EnvironmentNode"}constructor(e=null){super(),this.envNode=e}setup(e){const{material:t}=e;let r=this.envNode;if(r.isTextureNode||r.isMaterialReferenceNode){const e=r.isTextureNode?r.value:t[r.property];let s=yf.get(e);void 0===s&&(s=ff(e),yf.set(e,s)),r=s}const s=!0===t.useAnisotropy||t.anisotropy>0?qc:Xd,i=r.context(xf(Gn,s)).mul(nc),n=r.context(Tf(Kd)).mul(Math.PI).mul(nc),a=al(i),o=al(n);e.context.radiance.addAssign(a),e.context.iblIrradiance.addAssign(o);const u=e.context.lightingModel.clearcoatRadiance;if(u){const e=r.context(xf(Wn,Yd)).mul(nc),t=al(e);u.addAssign(t)}}}const xf=(e,t)=>{let r=null;return{getUV:()=>(null===r&&(r=Od.negate().reflect(t),r=tu(e).mix(r,t).normalize(),r=r.transformDirection(nd)),r),getTextureLevel:()=>e}},Tf=e=>({getUV:()=>e,getTextureLevel:()=>gn(1)}),_f=new we;class vf extends Zp{static get type(){return"MeshStandardNodeMaterial"}constructor(e){super(),this.isMeshStandardNodeMaterial=!0,this.lights=!0,this.emissiveNode=null,this.metalnessNode=null,this.roughnessNode=null,this.setDefaultValues(_f),this.setValues(e)}setupEnvironment(e){let t=super.setupEnvironment(e);return null===t&&e.environmentNode&&(t=e.environmentNode),t?new bf(t):null}setupLightingModel(){return new vm}setupSpecular(){const e=nu(vn(.04),On.rgb,zn);ea.assign(vn(.04)),ta.assign(e),ra.assign(1)}setupVariants(){const e=this.metalnessNode?gn(this.metalnessNode):gh;zn.assign(e);let t=this.roughnessNode?gn(this.roughnessNode):ph;t=Mg({roughness:t}),Gn.assign(t),this.setupSpecular(),Vn.assign(On.rgb.mul(e.oneMinus()))}copy(e){return this.emissiveNode=e.emissiveNode,this.metalnessNode=e.metalnessNode,this.roughnessNode=e.roughnessNode,super.copy(e)}}const Nf=new Ce;class Sf extends vf{static get type(){return"MeshPhysicalNodeMaterial"}constructor(e){super(),this.isMeshPhysicalNodeMaterial=!0,this.clearcoatNode=null,this.clearcoatRoughnessNode=null,this.clearcoatNormalNode=null,this.sheenNode=null,this.sheenRoughnessNode=null,this.iridescenceNode=null,this.iridescenceIORNode=null,this.iridescenceThicknessNode=null,this.specularIntensityNode=null,this.specularColorNode=null,this.iorNode=null,this.transmissionNode=null,this.thicknessNode=null,this.attenuationDistanceNode=null,this.attenuationColorNode=null,this.dispersionNode=null,this.anisotropyNode=null,this.setDefaultValues(Nf),this.setValues(e)}get useClearcoat(){return this.clearcoat>0||null!==this.clearcoatNode}get useIridescence(){return this.iridescence>0||null!==this.iridescenceNode}get useSheen(){return this.sheen>0||null!==this.sheenNode}get useAnisotropy(){return this.anisotropy>0||null!==this.anisotropyNode}get useTransmission(){return this.transmission>0||null!==this.transmissionNode}get useDispersion(){return this.dispersion>0||null!==this.dispersionNode}setupSpecular(){const e=this.iorNode?gn(this.iorNode):wh;ua.assign(e),ea.assign(Wo(Jo(ua.sub(1).div(ua.add(1))).mul(dh),vn(1)).mul(lh)),ta.assign(nu(ea,On.rgb,zn)),ra.assign(nu(lh,1,zn))}setupLightingModel(){return new vm(this.useClearcoat,this.useSheen,this.useIridescence,this.useAnisotropy,this.useTransmission,this.useDispersion)}setupVariants(e){if(super.setupVariants(e),this.useClearcoat){const e=this.clearcoatNode?gn(this.clearcoatNode):fh,t=this.clearcoatRoughnessNode?gn(this.clearcoatRoughnessNode):yh;$n.assign(e),Wn.assign(Mg({roughness:t}))}if(this.useSheen){const e=this.sheenNode?vn(this.sheenNode):Th,t=this.sheenRoughnessNode?gn(this.sheenRoughnessNode):_h;Hn.assign(e),qn.assign(t)}if(this.useIridescence){const e=this.iridescenceNode?gn(this.iridescenceNode):Nh,t=this.iridescenceIORNode?gn(this.iridescenceIORNode):Sh,r=this.iridescenceThicknessNode?gn(this.iridescenceThicknessNode):Rh;jn.assign(e),Xn.assign(t),Kn.assign(r)}if(this.useAnisotropy){const e=(this.anisotropyNode?bn(this.anisotropyNode):vh).toVar();Qn.assign(e.length()),cn(Qn.equal(0),()=>{e.assign(bn(1,0))}).Else(()=>{e.divAssign(bn(Qn)),Qn.assign(Qn.saturate())}),Yn.assign(Qn.pow2().mix(Gn.pow2(),1)),Zn.assign(Wc[0].mul(e.x).add(Wc[1].mul(e.y))),Jn.assign(Wc[1].mul(e.x).sub(Wc[0].mul(e.y)))}if(this.useTransmission){const e=this.transmissionNode?gn(this.transmissionNode):Eh,t=this.thicknessNode?gn(this.thicknessNode):Ah,r=this.attenuationDistanceNode?gn(this.attenuationDistanceNode):Ch,s=this.attenuationColorNode?vn(this.attenuationColorNode):Mh;if(la.assign(e),da.assign(t),ca.assign(r),ha.assign(s),this.useDispersion){const e=this.dispersionNode?gn(this.dispersionNode):Ih;pa.assign(e)}}}setupClearcoatNormal(){return this.clearcoatNormalNode?vn(this.clearcoatNormalNode):bh}setup(e){e.context.setupClearcoatNormal=()=>Lu(this.setupClearcoatNormal(e),"NORMAL","vec3"),super.setup(e)}copy(e){return this.clearcoatNode=e.clearcoatNode,this.clearcoatRoughnessNode=e.clearcoatRoughnessNode,this.clearcoatNormalNode=e.clearcoatNormalNode,this.sheenNode=e.sheenNode,this.sheenRoughnessNode=e.sheenRoughnessNode,this.iridescenceNode=e.iridescenceNode,this.iridescenceIORNode=e.iridescenceIORNode,this.iridescenceThicknessNode=e.iridescenceThicknessNode,this.specularIntensityNode=e.specularIntensityNode,this.specularColorNode=e.specularColorNode,this.iorNode=e.iorNode,this.transmissionNode=e.transmissionNode,this.thicknessNode=e.thicknessNode,this.attenuationDistanceNode=e.attenuationDistanceNode,this.attenuationColorNode=e.attenuationColorNode,this.dispersionNode=e.dispersionNode,this.anisotropyNode=e.anisotropyNode,super.copy(e)}}class Rf extends vm{constructor(e=!1,t=!1,r=!1,s=!1,i=!1,n=!1,a=!1){super(e,t,r,s,i,n),this.useSSS=a}direct({lightDirection:e,lightColor:t,reflectedLight:r},s){if(!0===this.useSSS){const i=s.material,{thicknessColorNode:n,thicknessDistortionNode:a,thicknessAmbientNode:o,thicknessAttenuationNode:u,thicknessPowerNode:l,thicknessScaleNode:d}=i,c=e.add(Xd.mul(a)).normalize(),h=gn(Od.dot(c.negate()).saturate().pow(l).mul(d)),p=vn(h.add(o).mul(n));r.directDiffuse.addAssign(p.mul(u.mul(t)))}super.direct({lightDirection:e,lightColor:t,reflectedLight:r},s)}}class Ef extends Sf{static get type(){return"MeshSSSNodeMaterial"}constructor(e){super(e),this.thicknessColorNode=null,this.thicknessDistortionNode=gn(.1),this.thicknessAmbientNode=gn(0),this.thicknessAttenuationNode=gn(.1),this.thicknessPowerNode=gn(2),this.thicknessScaleNode=gn(10)}get useSSS(){return null!==this.thicknessColorNode}setupLightingModel(){return new Rf(this.useClearcoat,this.useSheen,this.useIridescence,this.useAnisotropy,this.useTransmission,this.useDispersion,this.useSSS)}copy(e){return this.thicknessColorNode=e.thicknessColorNode,this.thicknessDistortionNode=e.thicknessDistortionNode,this.thicknessAmbientNode=e.thicknessAmbientNode,this.thicknessAttenuationNode=e.thicknessAttenuationNode,this.thicknessPowerNode=e.thicknessPowerNode,this.thicknessScaleNode=e.thicknessScaleNode,super.copy(e)}}const Af=un(({normal:e,lightDirection:t,builder:r})=>{const s=e.dot(t),i=bn(s.mul(.5).add(.5),0);if(r.material.gradientMap){const e=Tc("gradientMap","texture").context({getUV:()=>i});return vn(e.r)}{const e=i.fwidth().mul(.5);return nu(vn(.7),vn(1),lu(gn(.7).sub(e.x),gn(.7).add(e.x),i.x))}});class wf extends fg{direct({lightDirection:e,lightColor:t,reflectedLight:r},s){const i=Af({normal:$d,lightDirection:e,builder:s}).mul(t);r.directDiffuse.addAssign(i.mul(_g({diffuseColor:On.rgb})))}indirect(e){const{ambientOcclusion:t,irradiance:r,reflectedLight:s}=e.context;s.indirectDiffuse.addAssign(r.mul(_g({diffuseColor:On}))),s.indirectDiffuse.mulAssign(t)}}const Cf=new Me;class Mf extends Zp{static get type(){return"MeshToonNodeMaterial"}constructor(e){super(),this.isMeshToonNodeMaterial=!0,this.lights=!0,this.setDefaultValues(Cf),this.setValues(e)}setupLightingModel(){return new wf}}const Ff=un(()=>{const e=vn(Od.z,0,Od.x.negate()).normalize(),t=Od.cross(e);return bn(e.dot(Xd),t.dot(Xd)).mul(.495).add(.5)}).once(["NORMAL","VERTEX"])().toVar("matcapUV"),Lf=new Fe;class Pf extends Zp{static get type(){return"MeshMatcapNodeMaterial"}constructor(e){super(),this.isMeshMatcapNodeMaterial=!0,this.setDefaultValues(Lf),this.setValues(e)}setupVariants(e){const t=Ff;let r;r=e.material.matcap?Tc("matcap","texture").context({getUV:()=>t}):vn(nu(.2,.8,t.y)),On.rgb.mulAssign(r.rgb)}}class Bf extends ci{static get type(){return"RotateNode"}constructor(e,t){super(),this.positionNode=e,this.rotationNode=t}getNodeType(e){return this.positionNode.getNodeType(e)}setup(e){const{rotationNode:t,positionNode:r}=this;if("vec2"===this.getNodeType(e)){const e=t.cos(),s=t.sin();return Mn(e,s,s.negate(),e).mul(r)}{const e=t,s=Ln(En(1,0,0,0),En(0,Ro(e.x),So(e.x).negate(),0),En(0,So(e.x),Ro(e.x),0),En(0,0,0,1)),i=Ln(En(Ro(e.y),0,So(e.y),0),En(0,1,0,0),En(So(e.y).negate(),0,Ro(e.y),0),En(0,0,0,1)),n=Ln(En(Ro(e.z),So(e.z).negate(),0,0),En(So(e.z),Ro(e.z),0,0),En(0,0,1,0),En(0,0,0,1));return s.mul(i).mul(n).mul(En(r,1)).xyz}}}const Df=rn(Bf).setParameterLength(2),Uf=new Le;class If extends Zp{static get type(){return"SpriteNodeMaterial"}constructor(e){super(),this.isSpriteNodeMaterial=!0,this._useSizeAttenuation=!0,this.positionNode=null,this.rotationNode=null,this.scaleNode=null,this.transparent=!0,this.setDefaultValues(Uf),this.setValues(e)}setupPositionView(e){const{object:t,camera:r}=e,{positionNode:s,rotationNode:i,scaleNode:n,sizeAttenuation:a}=this,o=Ad.mul(vn(s||0));let u=bn(Td[0].xyz.length(),Td[1].xyz.length());null!==n&&(u=u.mul(bn(n))),r.isPerspectiveCamera&&!1===a&&(u=u.mul(o.z.negate()));let l=Ld.xy;if(t.center&&!0===t.center.isVector2){const e=((e,t,r)=>new $u(e,t,r))("center","vec2",t);l=l.sub(e.sub(.5))}l=l.mul(u);const d=gn(i||xh),c=Df(l,d);return En(o.xy.add(c),o.zw)}copy(e){return this.positionNode=e.positionNode,this.rotationNode=e.rotationNode,this.scaleNode=e.scaleNode,super.copy(e)}get sizeAttenuation(){return this._useSizeAttenuation}set sizeAttenuation(e){this._useSizeAttenuation!==e&&(this._useSizeAttenuation=e,this.needsUpdate=!0)}}const Of=new Pe,Vf=new t;class kf extends If{static get type(){return"PointsNodeMaterial"}constructor(e){super(),this.sizeNode=null,this.isPointsNodeMaterial=!0,this.setDefaultValues(Of),this.setValues(e)}setupPositionView(){const{positionNode:e}=this;return Ad.mul(vn(e||Pd)).xyz}setupVertexSprite(e){const{material:t,camera:r}=e,{rotationNode:s,scaleNode:i,sizeNode:n,sizeAttenuation:a}=this;let o=super.setupVertex(e);if(!0!==t.isNodeMaterial)return o;let u=null!==n?bn(n):Uh;u=u.mul(Hl),r.isPerspectiveCamera&&!0===a&&(u=u.mul(Gf.div(Id.z.negate()))),i&&i.isNode&&(u=u.mul(bn(i)));let l=Ld.xy;if(s&&s.isNode){const e=gn(s);l=Df(l,e)}return l=l.mul(u),l=l.div(Yl.div(2)),l=l.mul(o.w),o=o.add(En(l,0,0)),o}setupVertex(e){return e.object.isPoints?super.setupVertex(e):this.setupVertexSprite(e)}get alphaToCoverage(){return this._useAlphaToCoverage}set alphaToCoverage(e){this._useAlphaToCoverage!==e&&(this._useAlphaToCoverage=e,this.needsUpdate=!0)}}const Gf=_a(1).onFrameUpdate(function({renderer:e}){const t=e.getSize(Vf);this.value=.5*t.y});class zf extends fg{constructor(){super(),this.shadowNode=gn(1).toVar("shadowMask")}direct({lightNode:e}){null!==e.shadowNode&&this.shadowNode.mulAssign(e.shadowNode)}finish({context:e}){On.a.mulAssign(this.shadowNode.oneMinus()),e.outgoingLight.rgb.assign(On.rgb)}}const $f=new Be;class Wf extends Zp{static get type(){return"ShadowNodeMaterial"}constructor(e){super(),this.isShadowNodeMaterial=!0,this.lights=!0,this.transparent=!0,this.setDefaultValues($f),this.setValues(e)}setupLightingModel(){return new zf}}const Hf=Un("vec3"),qf=Un("vec3"),jf=Un("vec3");class Xf extends fg{constructor(){super()}start(e){const{material:t}=e,r=Un("vec3"),s=Un("vec3");cn(ud.sub(Dd).length().greaterThan(Sd.mul(2)),()=>{r.assign(ud),s.assign(Dd)}).Else(()=>{r.assign(Dd),s.assign(ud)});const i=s.sub(r),n=_a("int").onRenderUpdate(({material:e})=>e.steps),a=i.length().div(n).toVar(),o=i.normalize().toVar(),u=gn(0).toVar(),l=vn(1).toVar();t.offsetNode&&u.addAssign(t.offsetNode.mul(a)),lp(n,()=>{const s=r.add(o.mul(u)),i=nd.mul(En(s,1)).xyz;let n;null!==t.depthNode&&(qf.assign(Ip(Lp(i.z,td,rd))),e.context.sceneDepthNode=Ip(t.depthNode).toVar()),e.context.positionWorld=s,e.context.shadowPositionWorld=s,e.context.positionView=i,Hf.assign(0),t.scatteringNode&&(n=t.scatteringNode({positionRay:s})),super.start(e),n&&Hf.mulAssign(n);const d=Hf.mul(.01).negate().mul(a).exp();l.mulAssign(d),u.addAssign(a)}),jf.addAssign(l.saturate().oneMinus())}scatteringLight(e,t){const r=t.context.sceneDepthNode;r?cn(r.greaterThanEqual(qf),()=>{Hf.addAssign(e)}):Hf.addAssign(e)}direct({lightNode:e,lightColor:t},r){if(void 0===e.light.distance)return;const s=t.xyz.toVar();s.mulAssign(e.shadowNode),this.scatteringLight(s,r)}directRectArea({lightColor:e,lightPosition:t,halfWidth:r,halfHeight:s},i){const n=t.add(r).sub(s),a=t.sub(r).sub(s),o=t.sub(r).add(s),u=t.add(r).add(s),l=i.context.positionView,d=e.xyz.mul(Yg({P:l,p0:n,p1:a,p2:o,p3:u})).pow(1.5);this.scatteringLight(d,i)}finish(e){e.context.outgoingLight.assign(jf)}}class Kf extends Zp{static get type(){return"VolumeNodeMaterial"}constructor(e){super(),this.isVolumeNodeMaterial=!0,this.steps=25,this.offsetNode=null,this.scatteringNode=null,this.lights=!0,this.transparent=!0,this.side=M,this.depthTest=!1,this.depthWrite=!1,this.setValues(e)}setupLightingModel(){return new Xf}}class Yf{constructor(e,t,r){this.renderer=e,this.nodes=t,this.info=r,this._context="undefined"!=typeof self?self:null,this._animationLoop=null,this._requestId=null}start(){const e=(t,r)=>{this._requestId=this._context.requestAnimationFrame(e),!0===this.info.autoReset&&this.info.reset(),this.nodes.nodeFrame.update(),this.info.frame=this.nodes.nodeFrame.frameId,this.renderer._inspector.begin(),null!==this._animationLoop&&this._animationLoop(t,r),this.renderer._inspector.finish()};e()}stop(){this._context.cancelAnimationFrame(this._requestId),this._requestId=null}getAnimationLoop(){return this._animationLoop}setAnimationLoop(e){this._animationLoop=e}getContext(){return this._context}setContext(e){this._context=e}dispose(){this.stop()}}class Qf{constructor(){this.weakMaps={}}_getWeakMap(e){const t=e.length;let r=this.weakMaps[t];return void 0===r&&(r=new WeakMap,this.weakMaps[t]=r),r}get(e){let t=this._getWeakMap(e);for(let r=0;r{this.dispose()},this.onGeometryDispose=()=>{this.attributes=null,this.attributesId=null},this.material.addEventListener("dispose",this.onMaterialDispose),this.geometry.addEventListener("dispose",this.onGeometryDispose)}updateClipping(e){this.clippingContext=e}get clippingNeedsUpdate(){return null!==this.clippingContext&&this.clippingContext.cacheKey!==this.clippingContextCacheKey&&(this.clippingContextCacheKey=this.clippingContext.cacheKey,!0)}get hardwareClippingPlanes(){return!0===this.material.hardwareClipping?this.clippingContext.unionClippingCount:0}getNodeBuilderState(){return this._nodeBuilderState||(this._nodeBuilderState=this._nodes.getForRender(this))}getMonitor(){return this._monitor||(this._monitor=this.getNodeBuilderState().observer)}getBindings(){return this._bindings||(this._bindings=this.getNodeBuilderState().createBindings())}getBindingGroup(e){for(const t of this.getBindings())if(t.name===e)return t}getIndex(){return this._geometries.getIndex(this)}getIndirect(){return this._geometries.getIndirect(this)}getIndirectOffset(){return this._geometries.getIndirectOffset(this)}getChainArray(){return[this.object,this.material,this.context,this.lightsNode]}setGeometry(e){this.geometry=e,this.attributes=null,this.attributesId=null}getAttributes(){if(null!==this.attributes)return this.attributes;const e=this.getNodeBuilderState().nodeAttributes,t=this.geometry,r=[],s=new Set,i={};for(const n of e){let e;if(n.node&&n.node.attribute?e=n.node.attribute:(e=t.getAttribute(n.name),i[n.name]=e.id),void 0===e)continue;r.push(e);const a=e.isInterleavedBufferAttribute?e.data:e;s.add(a)}return this.attributes=r,this.attributesId=i,this.vertexBuffers=Array.from(s.values()),r}getVertexBuffers(){return null===this.vertexBuffers&&this.getAttributes(),this.vertexBuffers}getDrawParameters(){const{object:e,material:t,geometry:r,group:s,drawRange:i}=this,n=this.drawParams||(this.drawParams={vertexCount:0,firstVertex:0,instanceCount:0,firstInstance:0}),a=this.getIndex(),o=null!==a;let u=1;if(!0===r.isInstancedBufferGeometry?u=r.instanceCount:void 0!==e.count&&(u=Math.max(0,e.count)),0===u)return null;if(n.instanceCount=u,!0===e.isBatchedMesh)return n;let l=1;!0!==t.wireframe||e.isPoints||e.isLineSegments||e.isLine||e.isLineLoop||(l=2);let d=i.start*l,c=(i.start+i.count)*l;null!==s&&(d=Math.max(d,s.start*l),c=Math.min(c,(s.start+s.count)*l));const h=r.attributes.position;let p=1/0;o?p=a.count:null!=h&&(p=h.count),d=Math.max(d,0),c=Math.min(c,p);const g=c-d;return g<0||g===1/0?null:(n.vertexCount=g,n.firstVertex=d,n)}getGeometryCacheKey(){const{geometry:e}=this;let t="";for(const r of Object.keys(e.attributes).sort()){const s=e.attributes[r];t+=r+",",s.data&&(t+=s.data.stride+","),s.offset&&(t+=s.offset+","),s.itemSize&&(t+=s.itemSize+","),s.normalized&&(t+="n,")}for(const r of Object.keys(e.morphAttributes).sort()){const s=e.morphAttributes[r];t+="morph-"+r+",";for(let e=0,r=s.length;e1||Array.isArray(e.morphTargetInfluences))&&(s+=e.uuid+","),s+=this.context.id+",",s+=e.receiveShadow+",",Us(s)}get needsGeometryUpdate(){if(this.geometry.id!==this.object.geometry.id)return!0;if(null!==this.attributes){const e=this.attributesId;for(const t in e){const r=this.geometry.getAttribute(t);if(void 0===r||e[t]!==r.id)return!0}}return!1}get needsUpdate(){return this.initialNodesCacheKey!==this.getDynamicCacheKey()||this.clippingNeedsUpdate}getDynamicCacheKey(){let e=0;return!0!==this.material.isShadowPassMaterial&&(e=this._nodes.getCacheKey(this.scene,this.lightsNode)),this.camera.isArrayCamera&&(e=Os(e,this.camera.cameras.length)),this.object.receiveShadow&&(e=Os(e,1)),e=Os(e,this.renderer.contextNode.id,this.renderer.contextNode.version),e}getCacheKey(){return this.getMaterialCacheKey()+this.getDynamicCacheKey()}dispose(){this.material.removeEventListener("dispose",this.onMaterialDispose),this.geometry.removeEventListener("dispose",this.onGeometryDispose),this.onDispose()}}const ey=[];class ty{constructor(e,t,r,s,i,n){this.renderer=e,this.nodes=t,this.geometries=r,this.pipelines=s,this.bindings=i,this.info=n,this.chainMaps={}}get(e,t,r,s,i,n,a,o){const u=this.getChainMap(o);ey[0]=e,ey[1]=t,ey[2]=n,ey[3]=i;let l=u.get(ey);return void 0===l?(l=this.createRenderObject(this.nodes,this.geometries,this.renderer,e,t,r,s,i,n,a,o),u.set(ey,l)):(l.camera=s,l.updateClipping(a),l.needsGeometryUpdate&&l.setGeometry(e.geometry),(l.version!==t.version||l.needsUpdate)&&(l.initialCacheKey!==l.getCacheKey()?(l.dispose(),l=this.get(e,t,r,s,i,n,a,o)):l.version=t.version)),ey[0]=null,ey[1]=null,ey[2]=null,ey[3]=null,l}getChainMap(e="default"){return this.chainMaps[e]||(this.chainMaps[e]=new Qf)}dispose(){this.chainMaps={}}createRenderObject(e,t,r,s,i,n,a,o,u,l,d){const c=this.getChainMap(d),h=new Jf(e,t,r,s,i,n,a,o,u,l);return h.onDispose=()=>{this.pipelines.delete(h),this.bindings.deleteForRender(h),this.nodes.delete(h),c.delete(h.getChainArray())},h}}class ry{constructor(){this.data=new WeakMap}get(e){let t=this.data.get(e);return void 0===t&&(t={},this.data.set(e,t)),t}delete(e){let t=null;return this.data.has(e)&&(t=this.data.get(e),this.data.delete(e)),t}has(e){return this.data.has(e)}dispose(){this.data=new WeakMap}}const sy=1,iy=2,ny=3,ay=4,oy=16;class uy extends ry{constructor(e){super(),this.backend=e}delete(e){const t=super.delete(e);return null!==t&&this.backend.destroyAttribute(e),t}update(e,t){const r=this.get(e);if(void 0===r.version)t===sy?this.backend.createAttribute(e):t===iy?this.backend.createIndexAttribute(e):t===ny?this.backend.createStorageAttribute(e):t===ay&&this.backend.createIndirectStorageAttribute(e),r.version=this._getBufferAttribute(e).version;else{const t=this._getBufferAttribute(e);(r.version{this.info.memory.geometries--;const s=t.index,i=e.getAttributes();null!==s&&this.attributes.delete(s);for(const e of i)this.attributes.delete(e);const n=this.wireframes.get(t);void 0!==n&&this.attributes.delete(n),t.removeEventListener("dispose",r),this._geometryDisposeListeners.delete(t)};t.addEventListener("dispose",r),this._geometryDisposeListeners.set(t,r)}updateAttributes(e){const t=e.getAttributes();for(const e of t)e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute?this.updateAttribute(e,ny):this.updateAttribute(e,sy);const r=this.getIndex(e);null!==r&&this.updateAttribute(r,iy);const s=e.geometry.indirect;null!==s&&this.updateAttribute(s,ay)}updateAttribute(e,t){const r=this.info.render.calls;e.isInterleavedBufferAttribute?void 0===this.attributeCall.get(e)?(this.attributes.update(e,t),this.attributeCall.set(e,r)):this.attributeCall.get(e.data)!==r&&(this.attributes.update(e,t),this.attributeCall.set(e.data,r),this.attributeCall.set(e,r)):this.attributeCall.get(e)!==r&&(this.attributes.update(e,t),this.attributeCall.set(e,r))}getIndirect(e){return e.geometry.indirect}getIndirectOffset(e){return e.geometry.indirectOffset}getIndex(e){const{geometry:t,material:r}=e;let s=t.index;if(!0===r.wireframe){const e=this.wireframes;let r=e.get(t);void 0===r?(r=dy(t),e.set(t,r)):r.version!==ly(t)&&(this.attributes.delete(r),r=dy(t),e.set(t,r)),s=r}return s}dispose(){for(const[e,t]of this._geometryDisposeListeners.entries())e.removeEventListener("dispose",t);this._geometryDisposeListeners.clear()}}class hy{constructor(){this.autoReset=!0,this.frame=0,this.calls=0,this.render={calls:0,frameCalls:0,drawCalls:0,triangles:0,points:0,lines:0,timestamp:0},this.compute={calls:0,frameCalls:0,timestamp:0},this.memory={geometries:0,textures:0}}update(e,t,r){this.render.drawCalls++,e.isMesh||e.isSprite?this.render.triangles+=r*(t/3):e.isPoints?this.render.points+=r*t:e.isLineSegments?this.render.lines+=r*(t/2):e.isLine?this.render.lines+=r*(t-1):o("WebGPUInfo: Unknown object type.")}reset(){this.render.drawCalls=0,this.render.frameCalls=0,this.compute.frameCalls=0,this.render.triangles=0,this.render.points=0,this.render.lines=0}dispose(){this.reset(),this.calls=0,this.render.calls=0,this.compute.calls=0,this.render.timestamp=0,this.compute.timestamp=0,this.memory.geometries=0,this.memory.textures=0}}class py{constructor(e){this.cacheKey=e,this.usedTimes=0}}class gy extends py{constructor(e,t,r){super(e),this.vertexProgram=t,this.fragmentProgram=r}}class my extends py{constructor(e,t){super(e),this.computeProgram=t,this.isComputePipeline=!0}}let fy=0;class yy{constructor(e,t,r,s=null,i=null){this.id=fy++,this.code=e,this.stage=t,this.name=r,this.transforms=s,this.attributes=i,this.usedTimes=0}}class by extends ry{constructor(e,t){super(),this.backend=e,this.nodes=t,this.bindings=null,this.caches=new Map,this.programs={vertex:new Map,fragment:new Map,compute:new Map}}getForCompute(e,t){const{backend:r}=this,s=this.get(e);if(this._needsComputeUpdate(e)){const i=s.pipeline;i&&(i.usedTimes--,i.computeProgram.usedTimes--);const n=this.nodes.getForCompute(e);let a=this.programs.compute.get(n.computeShader);void 0===a&&(i&&0===i.computeProgram.usedTimes&&this._releaseProgram(i.computeProgram),a=new yy(n.computeShader,"compute",e.name,n.transforms,n.nodeAttributes),this.programs.compute.set(n.computeShader,a),r.createProgram(a));const o=this._getComputeCacheKey(e,a);let u=this.caches.get(o);void 0===u&&(i&&0===i.usedTimes&&this._releasePipeline(i),u=this._getComputePipeline(e,a,o,t)),u.usedTimes++,a.usedTimes++,s.version=e.version,s.pipeline=u}return s.pipeline}getForRender(e,t=null){const{backend:r}=this,s=this.get(e);if(this._needsRenderUpdate(e)){const i=s.pipeline;i&&(i.usedTimes--,i.vertexProgram.usedTimes--,i.fragmentProgram.usedTimes--);const n=e.getNodeBuilderState(),a=e.material?e.material.name:"";let o=this.programs.vertex.get(n.vertexShader);void 0===o&&(i&&0===i.vertexProgram.usedTimes&&this._releaseProgram(i.vertexProgram),o=new yy(n.vertexShader,"vertex",a),this.programs.vertex.set(n.vertexShader,o),r.createProgram(o));let u=this.programs.fragment.get(n.fragmentShader);void 0===u&&(i&&0===i.fragmentProgram.usedTimes&&this._releaseProgram(i.fragmentProgram),u=new yy(n.fragmentShader,"fragment",a),this.programs.fragment.set(n.fragmentShader,u),r.createProgram(u));const l=this._getRenderCacheKey(e,o,u);let d=this.caches.get(l);void 0===d?(i&&0===i.usedTimes&&this._releasePipeline(i),d=this._getRenderPipeline(e,o,u,l,t)):e.pipeline=d,d.usedTimes++,o.usedTimes++,u.usedTimes++,s.pipeline=d}return s.pipeline}delete(e){const t=this.get(e).pipeline;return t&&(t.usedTimes--,0===t.usedTimes&&this._releasePipeline(t),t.isComputePipeline?(t.computeProgram.usedTimes--,0===t.computeProgram.usedTimes&&this._releaseProgram(t.computeProgram)):(t.fragmentProgram.usedTimes--,t.vertexProgram.usedTimes--,0===t.vertexProgram.usedTimes&&this._releaseProgram(t.vertexProgram),0===t.fragmentProgram.usedTimes&&this._releaseProgram(t.fragmentProgram))),super.delete(e)}dispose(){super.dispose(),this.caches=new Map,this.programs={vertex:new Map,fragment:new Map,compute:new Map}}updateForRender(e){this.getForRender(e)}_getComputePipeline(e,t,r,s){r=r||this._getComputeCacheKey(e,t);let i=this.caches.get(r);return void 0===i&&(i=new my(r,t),this.caches.set(r,i),this.backend.createComputePipeline(i,s)),i}_getRenderPipeline(e,t,r,s,i){s=s||this._getRenderCacheKey(e,t,r);let n=this.caches.get(s);return void 0===n&&(n=new gy(s,t,r),this.caches.set(s,n),e.pipeline=n,this.backend.createRenderPipeline(e,i)),n}_getComputeCacheKey(e,t){return e.id+","+t.id}_getRenderCacheKey(e,t,r){return t.id+","+r.id+","+this.backend.getRenderCacheKey(e)}_releasePipeline(e){this.caches.delete(e.cacheKey)}_releaseProgram(e){const t=e.code,r=e.stage;this.programs[r].delete(t)}_needsComputeUpdate(e){const t=this.get(e);return void 0===t.pipeline||t.version!==e.version}_needsRenderUpdate(e){return void 0===this.get(e).pipeline||this.backend.needsRenderUpdate(e)}}class xy extends ry{constructor(e,t,r,s,i,n){super(),this.backend=e,this.textures=r,this.pipelines=i,this.attributes=s,this.nodes=t,this.info=n,this.pipelines.bindings=this}getForRender(e){const t=e.getBindings();for(const e of t){const r=this.get(e);void 0===r.bindGroup&&(this._init(e),this.backend.createBindings(e,t,0),r.bindGroup=e)}return t}getForCompute(e){const t=this.nodes.getForCompute(e).bindings;for(const e of t){const r=this.get(e);void 0===r.bindGroup&&(this._init(e),this.backend.createBindings(e,t,0),r.bindGroup=e)}return t}updateForCompute(e){this._updateBindings(this.getForCompute(e))}updateForRender(e){this._updateBindings(this.getForRender(e))}deleteForCompute(e){const t=this.nodes.getForCompute(e).bindings;for(const e of t)this.backend.deleteBindGroupData(e),this.delete(e)}deleteForRender(e){const t=e.getBindings();for(const e of t)this.backend.deleteBindGroupData(e),this.delete(e)}_updateBindings(e){for(const t of e)this._update(t,e)}_init(e){for(const t of e.bindings)if(t.isSampledTexture)this.textures.updateTexture(t.texture);else if(t.isSampler)this.textures.updateSampler(t.texture);else if(t.isStorageBuffer){const e=t.attribute,r=e.isIndirectStorageBufferAttribute?ay:ny;this.attributes.update(e,r)}}_update(e,t){const{backend:r}=this;let s=!1,i=!0,n=0,a=0;for(const t of e.bindings){if(!1!==this.nodes.updateGroup(t)){if(t.isStorageBuffer){const e=t.attribute,i=e.isIndirectStorageBufferAttribute?ay:ny,n=r.get(t);this.attributes.update(e,i),n.attribute!==e&&(n.attribute=e,s=!0)}if(t.isUniformBuffer){t.update()&&r.updateBinding(t)}else if(t.isSampledTexture){const e=t.update(),o=t.texture,u=this.textures.get(o);e&&(this.textures.updateTexture(o),t.generation!==u.generation&&(t.generation=u.generation,s=!0,i=!1));if(void 0!==r.get(o).externalTexture||u.isDefaultTexture?i=!1:(n=10*n+o.id,a+=o.version),!0===o.isStorageTexture&&!0===o.mipmapsAutoUpdate){const e=this.get(o);!0===t.store?e.needsMipmap=!0:this.textures.needsMipmaps(o)&&!0===e.needsMipmap&&(this.backend.generateMipmaps(o),e.needsMipmap=!1)}}else if(t.isSampler){if(t.update()){const e=this.textures.updateSampler(t.texture);t.samplerKey!==e&&(t.samplerKey=e,s=!0,i=!1)}}t.isBuffer&&t.updateRanges.length>0&&t.clearUpdateRanges()}}!0===s&&this.backend.updateBindings(e,t,i?n:0,a)}}function Ty(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?e.z-t.z:e.id-t.id}function _y(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?t.z-e.z:e.id-t.id}function vy(e){return(e.transmission>0||e.transmissionNode&&e.transmissionNode.isNode)&&e.side===F&&!1===e.forceSinglePass}class Ny{constructor(e,t,r){this.renderItems=[],this.renderItemsIndex=0,this.opaque=[],this.transparentDoublePass=[],this.transparent=[],this.bundles=[],this.lightsNode=e.getNode(t,r),this.lightsArray=[],this.scene=t,this.camera=r,this.occlusionQueryCount=0}begin(){return this.renderItemsIndex=0,this.opaque.length=0,this.transparentDoublePass.length=0,this.transparent.length=0,this.bundles.length=0,this.lightsArray.length=0,this.occlusionQueryCount=0,this}getNextRenderItem(e,t,r,s,i,n,a){let o=this.renderItems[this.renderItemsIndex];return void 0===o?(o={id:e.id,object:e,geometry:t,material:r,groupOrder:s,renderOrder:e.renderOrder,z:i,group:n,clippingContext:a},this.renderItems[this.renderItemsIndex]=o):(o.id=e.id,o.object=e,o.geometry=t,o.material=r,o.groupOrder=s,o.renderOrder=e.renderOrder,o.z=i,o.group=n,o.clippingContext=a),this.renderItemsIndex++,o}push(e,t,r,s,i,n,a){const o=this.getNextRenderItem(e,t,r,s,i,n,a);!0===e.occlusionTest&&this.occlusionQueryCount++,!0===r.transparent||r.transmission>0||r.transmissionNode&&r.transmissionNode.isNode||r.backdropNode&&r.backdropNode.isNode?(vy(r)&&this.transparentDoublePass.push(o),this.transparent.push(o)):this.opaque.push(o)}unshift(e,t,r,s,i,n,a){const o=this.getNextRenderItem(e,t,r,s,i,n,a);!0===r.transparent||r.transmission>0||r.transmissionNode&&r.transmissionNode.isNode||r.backdropNode&&r.backdropNode.isNode?(vy(r)&&this.transparentDoublePass.unshift(o),this.transparent.unshift(o)):this.opaque.unshift(o)}pushBundle(e){this.bundles.push(e)}pushLight(e){this.lightsArray.push(e)}sort(e,t){this.opaque.length>1&&this.opaque.sort(e||Ty),this.transparentDoublePass.length>1&&this.transparentDoublePass.sort(t||_y),this.transparent.length>1&&this.transparent.sort(t||_y)}finish(){this.lightsNode.setLights(this.lightsArray);for(let e=this.renderItemsIndex,t=this.renderItems.length;e>t,u=a.height>>t;let l=e.depthTexture||i[t];const d=!0===e.depthBuffer||!0===e.stencilBuffer;let c=!1;void 0===l&&d&&(l=new Y,l.format=e.stencilBuffer?Oe:Ve,l.type=e.stencilBuffer?ke:S,l.image.width=o,l.image.height=u,l.image.depth=a.depth,l.renderTarget=e,l.isArrayTexture=!0===e.multiview&&a.depth>1,i[t]=l),r.width===a.width&&a.height===r.height||(c=!0,l&&(l.needsUpdate=!0,l.image.width=o,l.image.height=u,l.image.depth=l.isArrayTexture?l.image.depth:1)),r.width=a.width,r.height=a.height,r.textures=n,r.depthTexture=l||null,r.depth=e.depthBuffer,r.stencil=e.stencilBuffer,r.renderTarget=e,r.sampleCount!==s&&(c=!0,l&&(l.needsUpdate=!0),r.sampleCount=s);const h={sampleCount:s};if(!0!==e.isXRRenderTarget){for(let e=0;e{this._destroyRenderTarget(e)},e.addEventListener("dispose",r.onDispose))}updateTexture(e,t={}){const r=this.get(e);if(!0===r.initialized&&r.version===e.version)return;const s=e.isRenderTargetTexture||e.isDepthTexture||e.isFramebufferTexture,i=this.backend;if(s&&!0===r.initialized&&i.destroyTexture(e),e.isFramebufferTexture){const t=this.renderer.getRenderTarget();e.type=t?t.texture.type:Ge}const{width:n,height:a,depth:o}=this.getSize(e);if(t.width=n,t.height=a,t.depth=o,t.needsMipmaps=this.needsMipmaps(e),t.levels=t.needsMipmaps?this.getMipLevels(e,n,a):1,e.isCubeTexture&&e.mipmaps.length>0&&t.levels++,s||!0===e.isStorageTexture||!0===e.isExternalTexture)i.createTexture(e,t),r.generation=e.version;else if(e.version>0){const s=e.image;if(void 0===s)d("Renderer: Texture marked for update but image is undefined.");else if(!1===s.complete)d("Renderer: Texture marked for update but image is incomplete.");else{if(e.images){const r=[];for(const t of e.images)r.push(t);t.images=r}else t.image=s;void 0!==r.isDefaultTexture&&!0!==r.isDefaultTexture||(i.createTexture(e,t),r.isDefaultTexture=!1,r.generation=e.version),!0===e.source.dataReady&&i.updateTexture(e,t);const n=!0===e.isStorageTexture&&!1===e.mipmapsAutoUpdate;t.needsMipmaps&&0===e.mipmaps.length&&!n&&i.generateMipmaps(e),e.onUpdate&&e.onUpdate(e)}}else i.createDefaultTexture(e),r.isDefaultTexture=!0,r.generation=e.version;!0!==r.initialized&&(r.initialized=!0,r.generation=e.version,this.info.memory.textures++,e.isVideoTexture&&!0===p.enabled&&p.getTransfer(e.colorSpace)!==g&&d("WebGPURenderer: Video textures must use a color space with a sRGB transfer function, e.g. SRGBColorSpace."),r.onDispose=()=>{this._destroyTexture(e)},e.addEventListener("dispose",r.onDispose)),r.version=e.version}updateSampler(e){return this.backend.updateSampler(e)}getSize(e,t=My){let r=e.images?e.images[0]:e.image;return r?(void 0!==r.image&&(r=r.image),"undefined"!=typeof HTMLVideoElement&&r instanceof HTMLVideoElement?(t.width=r.videoWidth||1,t.height=r.videoHeight||1,t.depth=1):"undefined"!=typeof VideoFrame&&r instanceof VideoFrame?(t.width=r.displayWidth||1,t.height=r.displayHeight||1,t.depth=1):(t.width=r.width||1,t.height=r.height||1,t.depth=e.isCubeTexture?6:r.depth||1)):t.width=t.height=t.depth=1,t}getMipLevels(e,t,r){let s;return s=e.mipmaps.length>0?e.mipmaps.length:!0===e.isCompressedTexture?1:Math.floor(Math.log2(Math.max(t,r)))+1,s}needsMipmaps(e){return!0===e.generateMipmaps||e.mipmaps.length>0}_destroyRenderTarget(e){if(!0===this.has(e)){const t=this.get(e),r=t.textures,s=t.depthTexture;e.removeEventListener("dispose",t.onDispose);for(let e=0;e=2)for(let r=0;r{if(this._currentNode=t,!t.isVarNode||!t.isIntent(e)||!0===t.isAssign(e))if("setup"===s)t.build(e);else if("analyze"===s)t.build(e,this);else if("generate"===s){const r=e.getDataFromNode(t,"any").stages,s=r&&r[e.shaderStage];if(t.isVarNode&&s&&1===s.length&&s[0]&&s[0].isStackNode)return;t.build(e,"void")}},n=[...this.nodes];for(const e of n)i(e);this._currentNode=null;const a=this.nodes.filter(e=>-1===n.indexOf(e));for(const e of a)i(e);let o;return o=this.hasOutput(e)?this.outputNode.build(e,...t):super.build(e,...t),ln(r),e.removeActiveStack(this),o}}const Dy=rn(By).setParameterLength(0,1);class Uy extends ui{static get type(){return"StructTypeNode"}constructor(e,t=null){var r;super("struct"),this.membersLayout=(r=e,Object.entries(r).map(([e,t])=>"string"==typeof t?{name:e,type:t,atomic:!1}:{name:e,type:t.type,atomic:t.atomic||!1})),this.name=t,this.isStructLayoutNode=!0}getLength(){const e=Float32Array.BYTES_PER_ELEMENT;let t=1,r=0;for(const s of this.membersLayout){const i=s.type,n=Ws(i),a=Hs(i)/e;t=Math.max(t,a);const o=r%t%a;0!==o&&(r+=a-o),r+=n}return Math.ceil(r/t)*t}getMemberType(e,t){const r=this.membersLayout.find(e=>e.name===t);return r?r.type:"void"}getNodeType(e){return e.getStructTypeFromNode(this,this.membersLayout,this.name).name}setup(e){e.getStructTypeFromNode(this,this.membersLayout,this.name),e.addInclude(this)}generate(e){return this.getNodeType(e)}}class Iy extends ui{static get type(){return"StructNode"}constructor(e,t){super("vec3"),this.structTypeNode=e,this.values=t,this.isStructNode=!0}getNodeType(e){return this.structTypeNode.getNodeType(e)}getMemberType(e,t){return this.structTypeNode.getMemberType(e,t)}_getChildren(){const e=super._getChildren(),t=e.find(e=>e.childNode===this.structTypeNode);return e.splice(e.indexOf(t),1),e.push(t),e}generate(e){const t=e.getVarFromNode(this),r=t.type,s=e.getPropertyName(t);return e.addLineFlowCode(`${s} = ${e.generateStruct(r,this.structTypeNode.membersLayout,this.values)}`,this),t.name}}class Oy extends ui{static get type(){return"OutputStructNode"}constructor(...e){super(),this.members=e,this.isOutputStructNode=!0}getNodeType(){return"OutputType"}generate(e){const t=e.getDataFromNode(this);if(void 0===t.membersLayout){const r=this.members,s=[];for(let t=0;tnew qy(e,"uint","float"),Ky={};class Yy extends ro{static get type(){return"BitcountNode"}constructor(e,t){super(e,t),this.isBitcountNode=!0}_resolveElementType(e,t,r){"int"===r?t.assign(jy(e,"uint")):t.assign(e)}_returnDataNode(e){switch(e){case"uint":return fn;case"int":return mn;case"uvec2":return Tn;case"uvec3":return Sn;case"uvec4":return wn;case"ivec2":return xn;case"ivec3":return Nn;case"ivec4":return An}}_createTrailingZerosBaseLayout(e,t){const r=this._returnDataNode(t);return un(([e])=>{const s=fn(0);this._resolveElementType(e,s,t);const i=gn(s.bitAnd(Po(s))),n=Xy(i).shiftRight(23).sub(127);return r(n)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createLeadingZerosBaseLayout(e,t){const r=this._returnDataNode(t);return un(([e])=>{cn(e.equal(fn(0)),()=>fn(32));const s=fn(0),i=fn(0);return this._resolveElementType(e,s,t),cn(s.shiftRight(16).equal(0),()=>{i.addAssign(16),s.shiftLeftAssign(16)}),cn(s.shiftRight(24).equal(0),()=>{i.addAssign(8),s.shiftLeftAssign(8)}),cn(s.shiftRight(28).equal(0),()=>{i.addAssign(4),s.shiftLeftAssign(4)}),cn(s.shiftRight(30).equal(0),()=>{i.addAssign(2),s.shiftLeftAssign(2)}),cn(s.shiftRight(31).equal(0),()=>{i.addAssign(1)}),r(i)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createOneBitsBaseLayout(e,t){const r=this._returnDataNode(t);return un(([e])=>{const s=fn(0);this._resolveElementType(e,s,t),s.assign(s.sub(s.shiftRight(fn(1)).bitAnd(fn(1431655765)))),s.assign(s.bitAnd(fn(858993459)).add(s.shiftRight(fn(2)).bitAnd(fn(858993459))));const i=s.add(s.shiftRight(fn(4))).bitAnd(fn(252645135)).mul(fn(16843009)).shiftRight(fn(24));return r(i)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createMainLayout(e,t,r,s){const i=this._returnDataNode(t);return un(([e])=>{if(1===r)return i(s(e));{const t=i(0),n=["x","y","z","w"];for(let i=0;id(r))()}}Yy.COUNT_TRAILING_ZEROS="countTrailingZeros",Yy.COUNT_LEADING_ZEROS="countLeadingZeros",Yy.COUNT_ONE_BITS="countOneBits";const Qy=nn(Yy,Yy.COUNT_TRAILING_ZEROS).setParameterLength(1),Zy=nn(Yy,Yy.COUNT_LEADING_ZEROS).setParameterLength(1),Jy=nn(Yy,Yy.COUNT_ONE_BITS).setParameterLength(1),eb=un(([e])=>{const t=e.toUint().mul(747796405).add(2891336453),r=t.shiftRight(t.shiftRight(28).add(4)).bitXor(t).mul(277803737);return r.shiftRight(22).bitXor(r).toFloat().mul(1/2**32)}),tb=(e,t)=>Zo(La(4,e.mul(Fa(1,e))),t);class rb extends ci{static get type(){return"PackFloatNode"}constructor(e,t){super(),this.vectorNode=t,this.encoding=e,this.isPackFloatNode=!0}getNodeType(){return"uint"}generate(e){const t=this.vectorNode.getNodeType(e);return`${e.getFloatPackingMethod(this.encoding)}(${this.vectorNode.build(e,t)})`}}const sb=nn(rb,"snorm").setParameterLength(1),ib=nn(rb,"unorm").setParameterLength(1),nb=nn(rb,"float16").setParameterLength(1);class ab extends ci{static get type(){return"UnpackFloatNode"}constructor(e,t){super(),this.uintNode=t,this.encoding=e,this.isUnpackFloatNode=!0}getNodeType(){return"vec2"}generate(e){const t=this.uintNode.getNodeType(e);return`${e.getFloatUnpackingMethod(this.encoding)}(${this.uintNode.build(e,t)})`}}const ob=nn(ab,"snorm").setParameterLength(1),ub=nn(ab,"unorm").setParameterLength(1),lb=nn(ab,"float16").setParameterLength(1),db=un(([e])=>e.fract().sub(.5).abs()).setLayout({name:"tri",type:"float",inputs:[{name:"x",type:"float"}]}),cb=un(([e])=>vn(db(e.z.add(db(e.y.mul(1)))),db(e.z.add(db(e.x.mul(1)))),db(e.y.add(db(e.x.mul(1)))))).setLayout({name:"tri3",type:"vec3",inputs:[{name:"p",type:"vec3"}]}),hb=un(([e,t,r])=>{const s=vn(e).toVar(),i=gn(1.4).toVar(),n=gn(0).toVar(),a=vn(s).toVar();return lp({start:gn(0),end:gn(3),type:"float",condition:"<="},()=>{const e=vn(cb(a.mul(2))).toVar();s.addAssign(e.add(r.mul(gn(.1).mul(t)))),a.mulAssign(1.8),i.mulAssign(1.5),s.mulAssign(1.2);const o=gn(db(s.z.add(db(s.x.add(db(s.y)))))).toVar();n.addAssign(o.div(i)),a.addAssign(.14)}),n}).setLayout({name:"triNoise3D",type:"float",inputs:[{name:"position",type:"vec3"},{name:"speed",type:"float"},{name:"time",type:"float"}]});class pb extends ui{static get type(){return"FunctionOverloadingNode"}constructor(e=[],...t){super(),this.functionNodes=e,this.parametersNodes=t,this._candidateFn=null,this.global=!0}getNodeType(e){return this.getCandidateFn(e).shaderNode.layout.type}getCandidateFn(e){const t=this.parametersNodes;let r=this._candidateFn;if(null===r){let s=null,i=-1;for(const r of this.functionNodes){const n=r.shaderNode.layout;if(null===n)throw new Error("FunctionOverloadingNode: FunctionNode must be a layout.");const a=n.inputs;if(t.length===a.length){let n=0;for(let r=0;ri&&(s=r,i=n)}}this._candidateFn=r=s}return r}setup(e){return this.getCandidateFn(e)(...this.parametersNodes)}}const gb=rn(pb),mb=e=>(...t)=>gb(e,...t),fb=_a(0).setGroup(ba).onRenderUpdate(e=>e.time),yb=_a(0).setGroup(ba).onRenderUpdate(e=>e.deltaTime),bb=_a(0,"uint").setGroup(ba).onRenderUpdate(e=>e.frameId);const xb=un(([e,t,r=bn(.5)])=>Df(e.sub(r),t).add(r)),Tb=un(([e,t,r=bn(.5)])=>{const s=e.sub(r),i=s.dot(s),n=i.mul(i).mul(t);return e.add(s.mul(n))}),_b=un(({position:e=null,horizontal:t=!0,vertical:r=!1})=>{let s;null!==e?(s=Td.toVar(),s[3][0]=e.x,s[3][1]=e.y,s[3][2]=e.z):s=Td;const i=nd.mul(s);return Ki(t)&&(i[0][0]=Td[0].length(),i[0][1]=0,i[0][2]=0),Ki(r)&&(i[1][0]=0,i[1][1]=Td[1].length(),i[1][2]=0),i[2][0]=0,i[2][1]=0,i[2][2]=1,sd.mul(i).mul(Pd)}),vb=un(([e=null])=>{const t=Ip();return Ip(Cp(e)).sub(t).lessThan(0).select(ql,e)}),Nb=un(([e,t=Rl(),r=gn(0)])=>{const s=e.x,i=e.y,n=r.mod(s.mul(i)).floor(),a=n.mod(s),o=i.sub(n.add(1).div(s).ceil()),u=e.reciprocal(),l=bn(a,o);return t.add(l).mul(u)}),Sb=un(([e,t=null,r=null,s=gn(1),i=Pd,n=Wd])=>{let a=n.abs().normalize();a=a.div(a.dot(vn(1)));const o=i.yz.mul(s),u=i.zx.mul(s),l=i.xy.mul(s),d=e.value,c=null!==t?t.value:d,h=null!==r?r.value:d,p=Pl(d,o).mul(a.x),g=Pl(c,u).mul(a.y),m=Pl(h,l).mul(a.z);return Ma(p,g,m)}),Rb=new je,Eb=new r,Ab=new r,wb=new r,Cb=new a,Mb=new r(0,0,-1),Fb=new s,Lb=new r,Pb=new r,Bb=new s,Db=new t,Ub=new Ne,Ib=ql.flipX();Ub.depthTexture=new Y(1,1);let Ob=!1;class Vb extends Fl{static get type(){return"ReflectorNode"}constructor(e={}){super(e.defaultTexture||Ub.texture,Ib),this._reflectorBaseNode=e.reflector||new kb(this,e),this._depthNode=null,this.setUpdateMatrix(!1)}get reflector(){return this._reflectorBaseNode}get target(){return this._reflectorBaseNode.target}getDepthNode(){if(null===this._depthNode){if(!0!==this._reflectorBaseNode.depth)throw new Error("THREE.ReflectorNode: Depth node can only be requested when the reflector is created with { depth: true }. ");this._depthNode=Zi(new Vb({defaultTexture:Ub.depthTexture,reflector:this._reflectorBaseNode}))}return this._depthNode}setup(e){return e.object.isQuadMesh||this._reflectorBaseNode.build(e),super.setup(e)}clone(){const e=new this.constructor(this.reflectorNode);return e.uvNode=this.uvNode,e.levelNode=this.levelNode,e.biasNode=this.biasNode,e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e._reflectorBaseNode=this._reflectorBaseNode,e}dispose(){super.dispose(),this._reflectorBaseNode.dispose()}}class kb extends ui{static get type(){return"ReflectorBaseNode"}constructor(e,t={}){super();const{target:r=new Xe,resolutionScale:s=1,generateMipmaps:i=!1,bounces:n=!0,depth:a=!1,samples:o=0}=t;this.textureNode=e,this.target=r,this.resolutionScale=s,void 0!==t.resolution&&(v('ReflectorNode: The "resolution" parameter has been renamed to "resolutionScale".'),this.resolutionScale=t.resolution),this.generateMipmaps=i,this.bounces=n,this.depth=a,this.samples=o,this.updateBeforeType=n?Js.RENDER:Js.FRAME,this.virtualCameras=new WeakMap,this.renderTargets=new Map,this.forceUpdate=!1,this.hasOutput=!1}_updateResolution(e,t){const r=this.resolutionScale;t.getDrawingBufferSize(Db),e.setSize(Math.round(Db.width*r),Math.round(Db.height*r))}setup(e){return this._updateResolution(Ub,e.renderer),super.setup(e)}dispose(){super.dispose();for(const e of this.renderTargets.values())e.dispose()}getVirtualCamera(e){let t=this.virtualCameras.get(e);return void 0===t&&(t=e.clone(),this.virtualCameras.set(e,t)),t}getRenderTarget(e){let t=this.renderTargets.get(e);return void 0===t&&(t=new Ne(0,0,{type:be,samples:this.samples}),!0===this.generateMipmaps&&(t.texture.minFilter=Ke,t.texture.generateMipmaps=!0),!0===this.depth&&(t.depthTexture=new Y),this.renderTargets.set(e,t)),t}updateBefore(e){if(!1===this.bounces&&Ob)return!1;Ob=!0;const{scene:t,camera:r,renderer:s,material:i}=e,{target:n}=this,a=this.getVirtualCamera(r),o=this.getRenderTarget(a);s.getDrawingBufferSize(Db),this._updateResolution(o,s),Ab.setFromMatrixPosition(n.matrixWorld),wb.setFromMatrixPosition(r.matrixWorld),Cb.extractRotation(n.matrixWorld),Eb.set(0,0,1),Eb.applyMatrix4(Cb),Lb.subVectors(Ab,wb);let u=!1;if(!0===Lb.dot(Eb)>0&&!1===this.forceUpdate){if(!1===this.hasOutput)return void(Ob=!1);u=!0}Lb.reflect(Eb).negate(),Lb.add(Ab),Cb.extractRotation(r.matrixWorld),Mb.set(0,0,-1),Mb.applyMatrix4(Cb),Mb.add(wb),Pb.subVectors(Ab,Mb),Pb.reflect(Eb).negate(),Pb.add(Ab),a.coordinateSystem=r.coordinateSystem,a.position.copy(Lb),a.up.set(0,1,0),a.up.applyMatrix4(Cb),a.up.reflect(Eb),a.lookAt(Pb),a.near=r.near,a.far=r.far,a.updateMatrixWorld(),a.projectionMatrix.copy(r.projectionMatrix),Rb.setFromNormalAndCoplanarPoint(Eb,Ab),Rb.applyMatrix4(a.matrixWorldInverse),Fb.set(Rb.normal.x,Rb.normal.y,Rb.normal.z,Rb.constant);const l=a.projectionMatrix;Bb.x=(Math.sign(Fb.x)+l.elements[8])/l.elements[0],Bb.y=(Math.sign(Fb.y)+l.elements[9])/l.elements[5],Bb.z=-1,Bb.w=(1+l.elements[10])/l.elements[14],Fb.multiplyScalar(1/Fb.dot(Bb));l.elements[2]=Fb.x,l.elements[6]=Fb.y,l.elements[10]=s.coordinateSystem===h?Fb.z-0:Fb.z+1-0,l.elements[14]=Fb.w,this.textureNode.value=o.texture,!0===this.depth&&(this.textureNode.getDepthNode().value=o.depthTexture),i.visible=!1;const d=s.getRenderTarget(),c=s.getMRT(),p=s.autoClear;s.setMRT(null),s.setRenderTarget(o),s.autoClear=!0;const g=t.name;t.name=(t.name||"Scene")+" [ Reflector ]",u?(s.clear(),this.hasOutput=!1):(s.render(t,a),this.hasOutput=!0),t.name=g,s.setMRT(c),s.setRenderTarget(d),s.autoClear=p,i.visible=!0,Ob=!1,this.forceUpdate=!1}get resolution(){return v('ReflectorNode: The "resolution" property has been renamed to "resolutionScale".'),this.resolutionScale}set resolution(e){v('ReflectorNode: The "resolution" property has been renamed to "resolutionScale".'),this.resolutionScale=e}}const Gb=new _e(-1,1,1,-1,0,1);class zb extends Te{constructor(e=!1){super();const t=!1===e?[0,-1,0,1,2,1]:[0,2,0,0,2,0];this.setAttribute("position",new Ye([-1,3,0,-1,-1,0,3,-1,0],3)),this.setAttribute("uv",new Ye(t,2))}}const $b=new zb;class Wb extends ne{constructor(e=null){super($b,e),this.camera=Gb,this.isQuadMesh=!0}async renderAsync(e){v('QuadMesh: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await e.init(),e.render(this,Gb)}render(e){e.render(this,Gb)}}const Hb=new t;class qb extends Fl{static get type(){return"RTTNode"}constructor(e,t=null,r=null,s={type:be}){const i=new Ne(t,r,s);super(i.texture,Rl()),this.isRTTNode=!0,this.node=e,this.width=t,this.height=r,this.pixelRatio=1,this.renderTarget=i,this.textureNeedsUpdate=!0,this.autoUpdate=!0,this._rttNode=null,this._quadMesh=new Wb(new Zp),this.updateBeforeType=Js.RENDER}get autoResize(){return null===this.width}setup(e){return this._rttNode=this.node.context(e.getSharedContext()),this._quadMesh.material.name="RTT",this._quadMesh.material.needsUpdate=!0,super.setup(e)}setSize(e,t){this.width=e,this.height=t;const r=e*this.pixelRatio,s=t*this.pixelRatio;this.renderTarget.setSize(r,s),this.textureNeedsUpdate=!0}setPixelRatio(e){this.pixelRatio=e,this.setSize(this.width,this.height)}updateBefore({renderer:e}){if(!1===this.textureNeedsUpdate&&!1===this.autoUpdate)return;if(this.textureNeedsUpdate=!1,!0===this.autoResize){const t=e.getPixelRatio(),r=e.getSize(Hb),s=Math.floor(r.width*t),i=Math.floor(r.height*t);s===this.renderTarget.width&&i===this.renderTarget.height||(this.renderTarget.setSize(s,i),this.textureNeedsUpdate=!0)}let t="RTT";this.node.name&&(t=this.node.name+" [ "+t+" ]"),this._quadMesh.material.fragmentNode=this._rttNode,this._quadMesh.name=t;const r=e.getRenderTarget();e.setRenderTarget(this.renderTarget),this._quadMesh.render(e),e.setRenderTarget(r)}clone(){const e=new Fl(this.value,this.uvNode,this.levelNode);return e.sampler=this.sampler,e.referenceNode=this,e}}const jb=(e,...t)=>Zi(new qb(Zi(e),...t)),Xb=un(([e,t,r],s)=>{let i;s.renderer.coordinateSystem===h?(e=bn(e.x,e.y.oneMinus()).mul(2).sub(1),i=En(vn(e,t),1)):i=En(vn(e.x,e.y.oneMinus(),t).mul(2).sub(1),1);const n=En(r.mul(i));return n.xyz.div(n.w)}),Kb=un(([e,t])=>{const r=t.mul(En(e,1)),s=r.xy.div(r.w).mul(.5).add(.5).toVar();return bn(s.x,s.y.oneMinus())}),Yb=un(([e,t,r])=>{const s=Al(Bl(t)),i=xn(e.mul(s)).toVar(),n=Bl(t,i).toVar(),a=Bl(t,i.sub(xn(2,0))).toVar(),o=Bl(t,i.sub(xn(1,0))).toVar(),u=Bl(t,i.add(xn(1,0))).toVar(),l=Bl(t,i.add(xn(2,0))).toVar(),d=Bl(t,i.add(xn(0,2))).toVar(),c=Bl(t,i.add(xn(0,1))).toVar(),h=Bl(t,i.sub(xn(0,1))).toVar(),p=Bl(t,i.sub(xn(0,2))).toVar(),g=Mo(Fa(gn(2).mul(o).sub(a),n)).toVar(),m=Mo(Fa(gn(2).mul(u).sub(l),n)).toVar(),f=Mo(Fa(gn(2).mul(c).sub(d),n)).toVar(),y=Mo(Fa(gn(2).mul(h).sub(p),n)).toVar(),b=Xb(e,n,r).toVar(),x=g.lessThan(m).select(b.sub(Xb(e.sub(bn(gn(1).div(s.x),0)),o,r)),b.negate().add(Xb(e.add(bn(gn(1).div(s.x),0)),u,r))),T=f.lessThan(y).select(b.sub(Xb(e.add(bn(0,gn(1).div(s.y))),c,r)),b.negate().add(Xb(e.sub(bn(0,gn(1).div(s.y))),h,r)));return vo(Qo(x,T))}),Qb=un(([e])=>No(gn(52.9829189).mul(No(Yo(e,bn(.06711056,.00583715)))))).setLayout({name:"interleavedGradientNoise",type:"float",inputs:[{name:"position",type:"vec2"}]}),Zb=un(([e,t,r])=>{const s=gn(2.399963229728653),i=bo(gn(e).add(.5).div(gn(t))),n=gn(e).mul(s).add(r);return bn(Ro(n),So(n)).mul(i)}).setLayout({name:"vogelDiskSample",type:"vec2",inputs:[{name:"sampleIndex",type:"int"},{name:"samplesCount",type:"int"},{name:"phi",type:"float"}]});class Jb extends ui{static get type(){return"SampleNode"}constructor(e,t=null){super(),this.callback=e,this.uvNode=t,this.isSampleNode=!0}setup(){return this.sample(Rl())}sample(e){return this.callback(e)}}class ex extends ui{static get type(){return"EventNode"}constructor(e,t){super("void"),this.eventType=e,this.callback=t,e===ex.OBJECT?this.updateType=Js.OBJECT:e===ex.MATERIAL?this.updateType=Js.RENDER:e===ex.BEFORE_OBJECT?this.updateBeforeType=Js.OBJECT:e===ex.BEFORE_MATERIAL&&(this.updateBeforeType=Js.RENDER)}update(e){this.callback(e)}updateBefore(e){this.callback(e)}}ex.OBJECT="object",ex.MATERIAL="material",ex.BEFORE_OBJECT="beforeObject",ex.BEFORE_MATERIAL="beforeMaterial";const tx=(e,t)=>new ex(e,t).toStack();class rx extends W{constructor(e,t,r=Float32Array){super(ArrayBuffer.isView(e)?e:new r(e*t),t),this.isStorageInstancedBufferAttribute=!0}}class sx extends Ae{constructor(e,t,r=Float32Array){super(ArrayBuffer.isView(e)?e:new r(e*t),t),this.isStorageBufferAttribute=!0}}class ix extends ui{static get type(){return"PointUVNode"}constructor(){super("vec2"),this.isPointUVNode=!0}generate(){return"vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y )"}}const nx=sn(ix),ax=new L,ox=new a,ux=_a(0).setGroup(ba).onRenderUpdate(({scene:e})=>e.backgroundBlurriness),lx=_a(1).setGroup(ba).onRenderUpdate(({scene:e})=>e.backgroundIntensity),dx=_a(new a).setGroup(ba).onRenderUpdate(({scene:e})=>{const t=e.background;return null!==t&&t.isTexture&&t.mapping!==Qe?(ax.copy(e.backgroundRotation),ax.x*=-1,ax.y*=-1,ax.z*=-1,ox.makeRotationFromEuler(ax)):ox.identity(),ox});class cx extends Fl{static get type(){return"StorageTextureNode"}constructor(e,t,r=null){super(e,t),this.storeNode=r,this.mipLevel=0,this.isStorageTextureNode=!0,this.access=ti.WRITE_ONLY}getInputType(){return"storageTexture"}setup(e){super.setup(e);const t=e.getNodeProperties(this);return t.storeNode=this.storeNode,t}setAccess(e){return this.access=e,this}setMipLevel(e){return this.mipLevel=e,this}generate(e,t){let r;return r=null!==this.storeNode?this.generateStore(e):super.generate(e,t),r}toReadWrite(){return this.setAccess(ti.READ_WRITE)}toReadOnly(){return this.setAccess(ti.READ_ONLY)}toWriteOnly(){return this.setAccess(ti.WRITE_ONLY)}generateStore(e){const t=e.getNodeProperties(this),{uvNode:r,storeNode:s,depthNode:i}=t,n=super.generate(e,"property"),a=r.build(e,!0===this.value.is3DTexture?"uvec3":"uvec2"),o=s.build(e,"vec4"),u=i?i.build(e,"int"):null,l=e.generateTextureStore(e,n,a,u,o);e.addLineFlowCode(l,this)}clone(){const e=super.clone();return e.storeNode=this.storeNode,e.mipLevel=this.mipLevel,e.access=this.access,e}}const hx=rn(cx).setParameterLength(1,3),px=un(({texture:e,uv:t})=>{const r=1e-4,s=vn().toVar();return cn(t.x.lessThan(r),()=>{s.assign(vn(1,0,0))}).ElseIf(t.y.lessThan(r),()=>{s.assign(vn(0,1,0))}).ElseIf(t.z.lessThan(r),()=>{s.assign(vn(0,0,1))}).ElseIf(t.x.greaterThan(.9999),()=>{s.assign(vn(-1,0,0))}).ElseIf(t.y.greaterThan(.9999),()=>{s.assign(vn(0,-1,0))}).ElseIf(t.z.greaterThan(.9999),()=>{s.assign(vn(0,0,-1))}).Else(()=>{const r=.01,i=e.sample(t.add(vn(-.01,0,0))).r.sub(e.sample(t.add(vn(r,0,0))).r),n=e.sample(t.add(vn(0,-.01,0))).r.sub(e.sample(t.add(vn(0,r,0))).r),a=e.sample(t.add(vn(0,0,-.01))).r.sub(e.sample(t.add(vn(0,0,r))).r);s.assign(vn(i,n,a))}),s.normalize()});class gx extends Fl{static get type(){return"Texture3DNode"}constructor(e,t=null,r=null){super(e,t,r),this.isTexture3DNode=!0}getInputType(){return"texture3D"}getDefaultUV(){return vn(.5,.5,.5)}setUpdateMatrix(){}generateUV(e,t){return t.build(e,!0===this.sampler?"vec3":"ivec3")}generateOffset(e,t){return t.build(e,"ivec3")}normal(e){return px({texture:this,uv:e})}}const mx=rn(gx).setParameterLength(1,3);class fx extends fc{static get type(){return"UserDataNode"}constructor(e,t,r=null){super(e,t,r),this.userData=r}updateReference(e){return this.reference=null!==this.userData?this.userData:e.object.userData,this.reference}}const yx=new WeakMap;class bx extends ci{static get type(){return"VelocityNode"}constructor(){super("vec2"),this.projectionMatrix=null,this.updateType=Js.OBJECT,this.updateAfterType=Js.OBJECT,this.previousModelWorldMatrix=_a(new a),this.previousProjectionMatrix=_a(new a).setGroup(ba),this.previousCameraViewMatrix=_a(new a)}setProjectionMatrix(e){this.projectionMatrix=e}update({frameId:e,camera:t,object:r}){const s=Tx(r);this.previousModelWorldMatrix.value.copy(s);const i=xx(t);i.frameId!==e&&(i.frameId=e,void 0===i.previousProjectionMatrix?(i.previousProjectionMatrix=new a,i.previousCameraViewMatrix=new a,i.currentProjectionMatrix=new a,i.currentCameraViewMatrix=new a,i.previousProjectionMatrix.copy(this.projectionMatrix||t.projectionMatrix),i.previousCameraViewMatrix.copy(t.matrixWorldInverse)):(i.previousProjectionMatrix.copy(i.currentProjectionMatrix),i.previousCameraViewMatrix.copy(i.currentCameraViewMatrix)),i.currentProjectionMatrix.copy(this.projectionMatrix||t.projectionMatrix),i.currentCameraViewMatrix.copy(t.matrixWorldInverse),this.previousProjectionMatrix.value.copy(i.previousProjectionMatrix),this.previousCameraViewMatrix.value.copy(i.previousCameraViewMatrix))}updateAfter({object:e}){Tx(e).copy(e.matrixWorld)}setup(){const e=null===this.projectionMatrix?sd:_a(this.projectionMatrix),t=this.previousCameraViewMatrix.mul(this.previousModelWorldMatrix),r=e.mul(Ad).mul(Pd),s=this.previousProjectionMatrix.mul(t).mul(Bd),i=r.xy.div(r.w),n=s.xy.div(s.w);return Fa(i,n)}}function xx(e){let t=yx.get(e);return void 0===t&&(t={},yx.set(e,t)),t}function Tx(e,t=0){const r=xx(e);let s=r[t];return void 0===s&&(r[t]=s=new a,r[t].copy(e.matrixWorld)),s}const _x=sn(bx),vx=un(([e])=>Ex(e.rgb)),Nx=un(([e,t=gn(1)])=>t.mix(Ex(e.rgb),e.rgb)),Sx=un(([e,t=gn(1)])=>{const r=Ma(e.r,e.g,e.b).div(3),s=e.r.max(e.g.max(e.b)),i=s.sub(r).mul(t).mul(-3);return nu(e.rgb,s,i)}),Rx=un(([e,t=gn(1)])=>{const r=vn(.57735,.57735,.57735),s=t.cos();return vn(e.rgb.mul(s).add(r.cross(e.rgb).mul(t.sin()).add(r.mul(Yo(r,e.rgb).mul(s.oneMinus())))))}),Ex=(e,t=vn(p.getLuminanceCoefficients(new r)))=>Yo(e,t),Ax=un(([e,t=vn(1),s=vn(0),i=vn(1),n=gn(1),a=vn(p.getLuminanceCoefficients(new r,Se))])=>{const o=e.rgb.dot(vn(a)),u=Ho(e.rgb.mul(t).add(s),0).toVar(),l=u.pow(i).toVar();return cn(u.r.greaterThan(0),()=>{u.r.assign(l.r)}),cn(u.g.greaterThan(0),()=>{u.g.assign(l.g)}),cn(u.b.greaterThan(0),()=>{u.b.assign(l.b)}),u.assign(o.add(u.sub(o).mul(n))),En(u.rgb,e.a)});class wx extends ci{static get type(){return"PosterizeNode"}constructor(e,t){super(),this.sourceNode=e,this.stepsNode=t}setup(){const{sourceNode:e,stepsNode:t}=this;return e.mul(t).floor().div(t)}}const Cx=rn(wx).setParameterLength(2);let Mx=null;class Fx extends vp{static get type(){return"ViewportSharedTextureNode"}constructor(e=ql,t=null){null===Mx&&(Mx=new X),super(e,t,Mx)}getTextureForReference(){return Mx}updateReference(){return this}}const Lx=rn(Fx).setParameterLength(0,2),Px=new t;class Bx extends Fl{static get type(){return"PassTextureNode"}constructor(e,t){super(t),this.passNode=e,this.setUpdateMatrix(!1)}setup(e){return this.passNode.build(e),super.setup(e)}clone(){return new this.constructor(this.passNode,this.value)}}class Dx extends Bx{static get type(){return"PassMultipleTextureNode"}constructor(e,t,r=!1){super(e,null),this.textureName=t,this.previousTexture=r}updateTexture(){this.value=this.previousTexture?this.passNode.getPreviousTexture(this.textureName):this.passNode.getTexture(this.textureName)}setup(e){return this.updateTexture(),super.setup(e)}clone(){const e=new this.constructor(this.passNode,this.textureName,this.previousTexture);return e.uvNode=this.uvNode,e.levelNode=this.levelNode,e.biasNode=this.biasNode,e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e}}class Ux extends ci{static get type(){return"PassNode"}constructor(e,t,r,s={}){super("vec4"),this.scope=e,this.scene=t,this.camera=r,this.options=s,this._pixelRatio=1,this._width=1,this._height=1;const i=new Y;i.isRenderTargetTexture=!0,i.name="depth";const n=new Ne(this._width*this._pixelRatio,this._height*this._pixelRatio,{type:be,...s});n.texture.name="output",n.depthTexture=i,this.renderTarget=n,this.overrideMaterial=null,this.transparent=!0,this.opaque=!0,this.contextNode=null,this._contextNodeCache=null,this._textures={output:n.texture,depth:i},this._textureNodes={},this._linearDepthNodes={},this._viewZNodes={},this._previousTextures={},this._previousTextureNodes={},this._cameraNear=_a(0),this._cameraFar=_a(0),this._mrt=null,this._layers=null,this._resolutionScale=1,this._viewport=null,this._scissor=null,this.isPassNode=!0,this.updateBeforeType=Js.FRAME,this.global=!0}setResolutionScale(e){return this._resolutionScale=e,this}getResolutionScale(){return this._resolutionScale}setResolution(e){return d("PassNode: .setResolution() is deprecated. Use .setResolutionScale() instead."),this.setResolutionScale(e)}getResolution(){return d("PassNode: .getResolution() is deprecated. Use .getResolutionScale() instead."),this.getResolutionScale()}setLayers(e){return this._layers=e,this}getLayers(){return this._layers}setMRT(e){return this._mrt=e,this}getMRT(){return this._mrt}getTexture(e){let t=this._textures[e];if(void 0===t){t=this.renderTarget.texture.clone(),t.name=e,this._textures[e]=t,this.renderTarget.textures.push(t)}return t}getPreviousTexture(e){let t=this._previousTextures[e];return void 0===t&&(t=this.getTexture(e).clone(),this._previousTextures[e]=t),t}toggleTexture(e){const t=this._previousTextures[e];if(void 0!==t){const r=this._textures[e],s=this.renderTarget.textures.indexOf(r);this.renderTarget.textures[s]=t,this._textures[e]=t,this._previousTextures[e]=r,this._textureNodes[e].updateTexture(),this._previousTextureNodes[e].updateTexture()}}getTextureNode(e="output"){let t=this._textureNodes[e];return void 0===t&&(t=new Dx(this,e),t.updateTexture(),this._textureNodes[e]=t),t}getPreviousTextureNode(e="output"){let t=this._previousTextureNodes[e];return void 0===t&&(void 0===this._textureNodes[e]&&this.getTextureNode(e),t=new Dx(this,e,!0),t.updateTexture(),this._previousTextureNodes[e]=t),t}getViewZNode(e="depth"){let t=this._viewZNodes[e];if(void 0===t){const r=this._cameraNear,s=this._cameraFar;this._viewZNodes[e]=t=Pp(this.getTextureNode(e),r,s)}return t}getLinearDepthNode(e="depth"){let t=this._linearDepthNodes[e];if(void 0===t){const r=this._cameraNear,s=this._cameraFar,i=this.getViewZNode(e);this._linearDepthNodes[e]=t=Fp(i,r,s)}return t}async compileAsync(e){const t=e.getRenderTarget(),r=e.getMRT();e.setRenderTarget(this.renderTarget),e.setMRT(this._mrt),await e.compileAsync(this.scene,this.camera),e.setRenderTarget(t),e.setMRT(r)}setup({renderer:e}){return this.renderTarget.samples=void 0===this.options.samples?e.samples:this.options.samples,this.renderTarget.texture.type=e.getOutputBufferType(),this.scope===Ux.COLOR?this.getTextureNode():this.getLinearDepthNode()}updateBefore(e){const{renderer:t}=e,{scene:r}=this;let s,i;const n=t.getOutputRenderTarget();n&&!0===n.isXRRenderTarget?(i=1,s=t.xr.getCamera(),t.xr.updateCamera(s),Px.set(n.width,n.height)):(s=this.camera,i=t.getPixelRatio(),t.getSize(Px)),this._pixelRatio=i,this.setSize(Px.width,Px.height);const a=t.getRenderTarget(),o=t.getMRT(),u=t.autoClear,l=t.transparent,d=t.opaque,c=s.layers.mask,h=t.contextNode,p=r.overrideMaterial;this._cameraNear.value=s.near,this._cameraFar.value=s.far,null!==this._layers&&(s.layers.mask=this._layers.mask);for(const e in this._previousTextures)this.toggleTexture(e);null!==this.overrideMaterial&&(r.overrideMaterial=this.overrideMaterial),t.setRenderTarget(this.renderTarget),t.setMRT(this._mrt),t.autoClear=!0,t.transparent=this.transparent,t.opaque=this.opaque,null!==this.contextNode&&(null!==this._contextNodeCache&&this._contextNodeCache.version===this.version||(this._contextNodeCache={version:this.version,context:Tu({...t.contextNode.getFlowContextData(),...this.contextNode.getFlowContextData()})}),t.contextNode=this._contextNodeCache.context);const g=r.name;r.name=this.name?this.name:r.name,t.render(r,s),r.name=g,r.overrideMaterial=p,t.setRenderTarget(a),t.setMRT(o),t.autoClear=u,t.transparent=l,t.opaque=d,t.contextNode=h,s.layers.mask=c}setSize(e,t){this._width=e,this._height=t;const r=Math.floor(this._width*this._pixelRatio*this._resolutionScale),s=Math.floor(this._height*this._pixelRatio*this._resolutionScale);this.renderTarget.setSize(r,s),null!==this._scissor&&this.renderTarget.scissor.copy(this._scissor),null!==this._viewport&&this.renderTarget.viewport.copy(this._viewport)}setScissor(e,t,r,i){null===e?this._scissor=null:(null===this._scissor&&(this._scissor=new s),e.isVector4?this._scissor.copy(e):this._scissor.set(e,t,r,i),this._scissor.multiplyScalar(this._pixelRatio*this._resolutionScale).floor())}setViewport(e,t,r,i){null===e?this._viewport=null:(null===this._viewport&&(this._viewport=new s),e.isVector4?this._viewport.copy(e):this._viewport.set(e,t,r,i),this._viewport.multiplyScalar(this._pixelRatio*this._resolutionScale).floor())}setPixelRatio(e){this._pixelRatio=e,this.setSize(this._width,this._height)}dispose(){this.renderTarget.dispose()}}Ux.COLOR="color",Ux.DEPTH="depth";class Ix extends Ux{static get type(){return"ToonOutlinePassNode"}constructor(e,t,r,s,i){super(Ux.COLOR,e,t),this.colorNode=r,this.thicknessNode=s,this.alphaNode=i,this._materialCache=new WeakMap,this.name="Outline Pass"}updateBefore(e){const{renderer:t}=e,r=t.getRenderObjectFunction();t.setRenderObjectFunction((e,r,s,i,n,a,o,u)=>{if((n.isMeshToonMaterial||n.isMeshToonNodeMaterial)&&!1===n.wireframe){const l=this._getOutlineMaterial(n);t.renderObject(e,r,s,i,l,a,o,u)}t.renderObject(e,r,s,i,n,a,o,u)}),super.updateBefore(e),t.setRenderObjectFunction(r)}_createMaterial(){const e=new Zp;e.isMeshToonOutlineMaterial=!0,e.name="Toon_Outline",e.side=M;const t=Wd.negate(),r=sd.mul(Ad),s=gn(1),i=r.mul(En(Pd,1)),n=r.mul(En(Pd.add(t),1)),a=vo(i.sub(n));return e.vertexNode=i.add(a.mul(this.thicknessNode).mul(i.w).mul(s)),e.colorNode=En(this.colorNode,this.alphaNode),e}_getOutlineMaterial(e){let t=this._materialCache.get(e);return void 0===t&&(t=this._createMaterial(),this._materialCache.set(e,t)),t}}const Ox=un(([e,t])=>e.mul(t).clamp()).setLayout({name:"linearToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),Vx=un(([e,t])=>(e=e.mul(t)).div(e.add(1)).clamp()).setLayout({name:"reinhardToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),kx=un(([e,t])=>{const r=(e=(e=e.mul(t)).sub(.004).max(0)).mul(e.mul(6.2).add(.5)),s=e.mul(e.mul(6.2).add(1.7)).add(.06);return r.div(s).pow(2.2)}).setLayout({name:"cineonToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),Gx=un(([e])=>{const t=e.mul(e.add(.0245786)).sub(90537e-9),r=e.mul(e.add(.432951).mul(.983729)).add(.238081);return t.div(r)}),zx=un(([e,t])=>{const r=Fn(.59719,.35458,.04823,.076,.90834,.01566,.0284,.13383,.83777),s=Fn(1.60475,-.53108,-.07367,-.10208,1.10813,-.00605,-.00327,-.07276,1.07602);return e=e.mul(t).div(.6),e=r.mul(e),e=Gx(e),(e=s.mul(e)).clamp()}).setLayout({name:"acesFilmicToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),$x=Fn(vn(1.6605,-.1246,-.0182),vn(-.5876,1.1329,-.1006),vn(-.0728,-.0083,1.1187)),Wx=Fn(vn(.6274,.0691,.0164),vn(.3293,.9195,.088),vn(.0433,.0113,.8956)),Hx=un(([e])=>{const t=vn(e).toVar(),r=vn(t.mul(t)).toVar(),s=vn(r.mul(r)).toVar();return gn(15.5).mul(s.mul(r)).sub(La(40.14,s.mul(t))).add(La(31.96,s).sub(La(6.868,r.mul(t))).add(La(.4298,r).add(La(.1191,t).sub(.00232))))}),qx=un(([e,t])=>{const r=vn(e).toVar(),s=Fn(vn(.856627153315983,.137318972929847,.11189821299995),vn(.0951212405381588,.761241990602591,.0767994186031903),vn(.0482516061458583,.101439036467562,.811302368396859)),i=Fn(vn(1.1271005818144368,-.1413297634984383,-.14132976349843826),vn(-.11060664309660323,1.157823702216272,-.11060664309660294),vn(-.016493938717834573,-.016493938717834257,1.2519364065950405)),n=gn(-12.47393),a=gn(4.026069);return r.mulAssign(t),r.assign(Wx.mul(r)),r.assign(s.mul(r)),r.assign(Ho(r,1e-10)),r.assign(yo(r)),r.assign(r.sub(n).div(a.sub(n))),r.assign(au(r,0,1)),r.assign(Hx(r)),r.assign(i.mul(r)),r.assign(Zo(Ho(vn(0),r),vn(2.2))),r.assign($x.mul(r)),r.assign(au(r,0,1)),r}).setLayout({name:"agxToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),jx=un(([e,t])=>{const r=gn(.76),s=gn(.15);e=e.mul(t);const i=Wo(e.r,Wo(e.g,e.b)),n=bu(i.lessThan(.08),i.sub(La(6.25,i.mul(i))),.04);e.subAssign(n);const a=Ho(e.r,Ho(e.g,e.b));cn(a.lessThan(r),()=>e);const o=Fa(1,r),u=Fa(1,o.mul(o).div(a.add(o.sub(r))));e.mulAssign(u.div(a));const l=Fa(1,Pa(1,s.mul(a.sub(u)).add(1)));return nu(e,vn(u),l)}).setLayout({name:"neutralToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]});class Xx extends ui{static get type(){return"CodeNode"}constructor(e="",t=[],r=""){super("code"),this.isCodeNode=!0,this.global=!0,this.code=e,this.includes=t,this.language=r}setIncludes(e){return this.includes=e,this}getIncludes(){return this.includes}generate(e){const t=this.getIncludes(e);for(const r of t)r.build(e);const r=e.getCodeFromNode(this,this.getNodeType(e));return r.code=this.code,r.code}serialize(e){super.serialize(e),e.code=this.code,e.language=this.language}deserialize(e){super.deserialize(e),this.code=e.code,this.language=e.language}}const Kx=rn(Xx).setParameterLength(1,3);class Yx extends Xx{static get type(){return"FunctionNode"}constructor(e="",t=[],r=""){super(e,t,r)}getNodeType(e){return this.getNodeFunction(e).type}getMemberType(e,t){const r=this.getNodeType(e);return e.getStructTypeNode(r).getMemberType(e,t)}getInputs(e){return this.getNodeFunction(e).inputs}getNodeFunction(e){const t=e.getDataFromNode(this);let r=t.nodeFunction;return void 0===r&&(r=e.parser.parseFunction(this.code),t.nodeFunction=r),r}generate(e,t){super.generate(e);const r=this.getNodeFunction(e),s=r.name,i=r.type,n=e.getCodeFromNode(this,i);""!==s&&(n.name=s);const a=e.getPropertyName(n),o=this.getNodeFunction(e).getCode(a);return n.code=o+"\n","property"===t?a:e.format(`${a}()`,i,t)}}const Qx=(e,t=[],r="")=>{for(let e=0;es.call(...e);return i.functionNode=s,i};class Zx extends ui{static get type(){return"ScriptableValueNode"}constructor(e=null){super(),this._value=e,this._cache=null,this.inputType=null,this.outputType=null,this.events=new u,this.isScriptableValueNode=!0}get isScriptableOutputNode(){return null!==this.outputType}set value(e){this._value!==e&&(this._cache&&"URL"===this.inputType&&this.value.value instanceof ArrayBuffer&&(URL.revokeObjectURL(this._cache),this._cache=null),this._value=e,this.events.dispatchEvent({type:"change"}),this.refresh())}get value(){return this._value}refresh(){this.events.dispatchEvent({type:"refresh"})}getValue(){const e=this.value;if(e&&null===this._cache&&"URL"===this.inputType&&e.value instanceof ArrayBuffer)this._cache=URL.createObjectURL(new Blob([e.value]));else if(e&&null!==e.value&&void 0!==e.value&&(("URL"===this.inputType||"String"===this.inputType)&&"string"==typeof e.value||"Number"===this.inputType&&"number"==typeof e.value||"Vector2"===this.inputType&&e.value.isVector2||"Vector3"===this.inputType&&e.value.isVector3||"Vector4"===this.inputType&&e.value.isVector4||"Color"===this.inputType&&e.value.isColor||"Matrix3"===this.inputType&&e.value.isMatrix3||"Matrix4"===this.inputType&&e.value.isMatrix4))return e.value;return this._cache||e}getNodeType(e){return this.value&&this.value.isNode?this.value.getNodeType(e):"float"}setup(){return this.value&&this.value.isNode?this.value:gn()}serialize(e){super.serialize(e),null!==this.value?"ArrayBuffer"===this.inputType?e.value=Ks(this.value):e.value=this.value?this.value.toJSON(e.meta).uuid:null:e.value=null,e.inputType=this.inputType,e.outputType=this.outputType}deserialize(e){super.deserialize(e);let t=null;null!==e.value&&(t="ArrayBuffer"===e.inputType?Ys(e.value):"Texture"===e.inputType?e.meta.textures[e.value]:e.meta.nodes[e.value]||null),this.value=t,this.inputType=e.inputType,this.outputType=e.outputType}}const Jx=rn(Zx).setParameterLength(1);class eT extends Map{get(e,t=null,...r){if(this.has(e))return super.get(e);if(null!==t){const s=t(...r);return this.set(e,s),s}}}class tT{constructor(e){this.scriptableNode=e}get parameters(){return this.scriptableNode.parameters}get layout(){return this.scriptableNode.getLayout()}getInputLayout(e){return this.scriptableNode.getInputLayout(e)}get(e){const t=this.parameters[e];return t?t.getValue():null}}const rT=new eT;class sT extends ui{static get type(){return"ScriptableNode"}constructor(e=null,t={}){super(),this.codeNode=e,this.parameters=t,this._local=new eT,this._output=Jx(null),this._outputs={},this._source=this.source,this._method=null,this._object=null,this._value=null,this._needsOutputUpdate=!0,this.onRefresh=this.onRefresh.bind(this),this.isScriptableNode=!0}get source(){return this.codeNode?this.codeNode.code:""}setLocal(e,t){return this._local.set(e,t)}getLocal(e){return this._local.get(e)}onRefresh(){this._refresh()}getInputLayout(e){for(const t of this.getLayout())if(t.inputType&&(t.id===e||t.name===e))return t}getOutputLayout(e){for(const t of this.getLayout())if(t.outputType&&(t.id===e||t.name===e))return t}setOutput(e,t){const r=this._outputs;return void 0===r[e]?r[e]=Jx(t):r[e].value=t,this}getOutput(e){return this._outputs[e]}getParameter(e){return this.parameters[e]}setParameter(e,t){const r=this.parameters;return t&&t.isScriptableNode?(this.deleteParameter(e),r[e]=t,r[e].getDefaultOutput().events.addEventListener("refresh",this.onRefresh)):t&&t.isScriptableValueNode?(this.deleteParameter(e),r[e]=t,r[e].events.addEventListener("refresh",this.onRefresh)):void 0===r[e]?(r[e]=Jx(t),r[e].events.addEventListener("refresh",this.onRefresh)):r[e].value=t,this}getValue(){return this.getDefaultOutput().getValue()}deleteParameter(e){let t=this.parameters[e];return t&&(t.isScriptableNode&&(t=t.getDefaultOutput()),t.events.removeEventListener("refresh",this.onRefresh)),this}clearParameters(){for(const e of Object.keys(this.parameters))this.deleteParameter(e);return this.needsUpdate=!0,this}call(e,...t){const r=this.getObject()[e];if("function"==typeof r)return r(...t)}async callAsync(e,...t){const r=this.getObject()[e];if("function"==typeof r)return"AsyncFunction"===r.constructor.name?await r(...t):r(...t)}getNodeType(e){return this.getDefaultOutputNode().getNodeType(e)}refresh(e=null){null!==e?this.getOutput(e).refresh():this._refresh()}getObject(){if(this.needsUpdate&&this.dispose(),null!==this._object)return this._object;const e=new tT(this),t=rT.get("THREE"),r=rT.get("TSL"),s=this.getMethod(),i=[e,this._local,rT,()=>this.refresh(),(e,t)=>this.setOutput(e,t),t,r];this._object=s(...i);const n=this._object.layout;if(n&&(!1===n.cache&&this._local.clear(),this._output.outputType=n.outputType||null,Array.isArray(n.elements)))for(const e of n.elements){const t=e.id||e.name;e.inputType&&(void 0===this.getParameter(t)&&this.setParameter(t,null),this.getParameter(t).inputType=e.inputType),e.outputType&&(void 0===this.getOutput(t)&&this.setOutput(t,null),this.getOutput(t).outputType=e.outputType)}return this._object}deserialize(e){super.deserialize(e);for(const e in this.parameters){let t=this.parameters[e];t.isScriptableNode&&(t=t.getDefaultOutput()),t.events.addEventListener("refresh",this.onRefresh)}}getLayout(){return this.getObject().layout}getDefaultOutputNode(){const e=this.getDefaultOutput().value;return e&&e.isNode?e:gn()}getDefaultOutput(){return this._exec()._output}getMethod(){if(this.needsUpdate&&this.dispose(),null!==this._method)return this._method;const e=["layout","init","main","dispose"].join(", "),t="\nreturn { ...output, "+e+" };",r="var "+e+"; var output = {};\n"+this.codeNode.code+t;return this._method=new Function(...["parameters","local","global","refresh","setOutput","THREE","TSL"],r),this._method}dispose(){null!==this._method&&(this._object&&"function"==typeof this._object.dispose&&this._object.dispose(),this._method=null,this._object=null,this._source=null,this._value=null,this._needsOutputUpdate=!0,this._output.value=null,this._outputs={})}setup(){return this.getDefaultOutputNode()}getCacheKey(e){const t=[Us(this.source),this.getDefaultOutputNode().getCacheKey(e)];for(const r in this.parameters)t.push(this.parameters[r].getCacheKey(e));return Is(t)}set needsUpdate(e){!0===e&&this.dispose()}get needsUpdate(){return this.source!==this._source}_exec(){return null===this.codeNode||(!0===this._needsOutputUpdate&&(this._value=this.call("main"),this._needsOutputUpdate=!1),this._output.value=this._value),this}_refresh(){this.needsUpdate=!0,this._exec(),this._output.refresh()}}const iT=rn(sT).setParameterLength(1,2);function nT(e){let t;const r=e.context.getViewZ;return void 0!==r&&(t=r(this)),(t||Id.z).negate()}const aT=un(([e,t],r)=>{const s=nT(r);return lu(e,t,s)}),oT=un(([e],t)=>{const r=nT(t);return e.mul(e,r,r).negate().exp().oneMinus()}),uT=un(([e,t],r)=>{const s=nT(r),i=t.sub(Dd.y).max(0).toConst().mul(s).toConst();return e.mul(e,i,i).negate().exp().oneMinus()}),lT=un(([e,t])=>En(t.toFloat().mix(ia.rgb,e.toVec3()),ia.a));let dT=null,cT=null;class hT extends ui{static get type(){return"RangeNode"}constructor(e=gn(),t=gn()){super(),this.minNode=e,this.maxNode=t}getVectorLength(e){const t=this.getConstNode(this.minNode),r=this.getConstNode(this.maxNode),s=e.getTypeLength(qs(t.value)),i=e.getTypeLength(qs(r.value));return s>i?s:i}getNodeType(e){return e.object.count>1?e.getTypeFromLength(this.getVectorLength(e)):"float"}getConstNode(e){let t=null;if(e.traverse(e=>{!0===e.isConstNode&&(t=e)}),null===t)throw new Error('THREE.TSL: No "ConstNode" found in node graph.');return t}setup(e){const t=e.object;let r=null;if(t.count>1){const i=this.getConstNode(this.minNode),n=this.getConstNode(this.maxNode),a=i.value,o=n.value,u=e.getTypeLength(qs(a)),d=e.getTypeLength(qs(o));dT=dT||new s,cT=cT||new s,dT.setScalar(0),cT.setScalar(0),1===u?dT.setScalar(a):a.isColor?dT.set(a.r,a.g,a.b,1):dT.set(a.x,a.y,a.z||0,a.w||0),1===d?cT.setScalar(o):o.isColor?cT.set(o.r,o.g,o.b,1):cT.set(o.x,o.y,o.z||0,o.w||0);const c=4,h=c*t.count,p=new Float32Array(h);for(let e=0;enew gT(e,t),fT=mT("numWorkgroups","uvec3"),yT=mT("workgroupId","uvec3"),bT=mT("globalId","uvec3"),xT=mT("localId","uvec3"),TT=mT("subgroupSize","uint");class _T extends ui{constructor(e){super(),this.scope=e}generate(e){const{scope:t}=this,{renderer:r}=e;!0===r.backend.isWebGLBackend?e.addFlowCode(`\t// ${t}Barrier \n`):e.addLineFlowCode(`${t}Barrier()`,this)}}const vT=rn(_T);class NT extends li{constructor(e,t){super(e,t),this.isWorkgroupInfoElementNode=!0}generate(e,t){let r;const s=e.context.assign;if(r=super.generate(e),!0!==s){const s=this.getNodeType(e);r=e.format(r,s,t)}return r}}class ST extends ui{constructor(e,t,r=0){super(t),this.bufferType=t,this.bufferCount=r,this.isWorkgroupInfoNode=!0,this.elementType=t,this.scope=e,this.name=""}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setScope(e){return this.scope=e,this}getElementType(){return this.elementType}getInputType(){return`${this.scope}Array`}element(e){return new NT(this,e)}generate(e){const t=""!==this.name?this.name:`${this.scope}Array_${this.id}`;return e.getScopedArray(t,this.scope.toLowerCase(),this.bufferType,this.bufferCount)}}class RT extends ui{static get type(){return"AtomicFunctionNode"}constructor(e,t,r){super("uint"),this.method=e,this.pointerNode=t,this.valueNode=r,this.parents=!0}getInputType(e){return this.pointerNode.getNodeType(e)}getNodeType(e){return this.getInputType(e)}generate(e){const t=e.getNodeProperties(this),r=t.parents,s=this.method,i=this.getNodeType(e),n=this.getInputType(e),a=this.pointerNode,o=this.valueNode,u=[];u.push(`&${a.build(e,n)}`),null!==o&&u.push(o.build(e,n));const l=`${e.getMethod(s,i)}( ${u.join(", ")} )`;if(!(!!r&&(1===r.length&&!0===r[0].isStackNode)))return void 0===t.constNode&&(t.constNode=gl(l,i).toConst()),t.constNode.build(e);e.addLineFlowCode(l,this)}}RT.ATOMIC_LOAD="atomicLoad",RT.ATOMIC_STORE="atomicStore",RT.ATOMIC_ADD="atomicAdd",RT.ATOMIC_SUB="atomicSub",RT.ATOMIC_MAX="atomicMax",RT.ATOMIC_MIN="atomicMin",RT.ATOMIC_AND="atomicAnd",RT.ATOMIC_OR="atomicOr",RT.ATOMIC_XOR="atomicXor";const ET=rn(RT),AT=(e,t,r)=>ET(e,t,r).toStack();class wT extends ci{static get type(){return"SubgroupFunctionNode"}constructor(e,t=null,r=null){super(),this.method=e,this.aNode=t,this.bNode=r}getInputType(e){const t=this.aNode?this.aNode.getNodeType(e):null,r=this.bNode?this.bNode.getNodeType(e):null;return(e.isMatrix(t)?0:e.getTypeLength(t))>(e.isMatrix(r)?0:e.getTypeLength(r))?t:r}getNodeType(e){const t=this.method;return t===wT.SUBGROUP_ELECT?"bool":t===wT.SUBGROUP_BALLOT?"uvec4":this.getInputType(e)}generate(e,t){const r=this.method,s=this.getNodeType(e),i=this.getInputType(e),n=this.aNode,a=this.bNode,o=[];if(r===wT.SUBGROUP_BROADCAST||r===wT.SUBGROUP_SHUFFLE||r===wT.QUAD_BROADCAST){const t=a.getNodeType(e);o.push(n.build(e,s),a.build(e,"float"===t?"int":s))}else r===wT.SUBGROUP_SHUFFLE_XOR||r===wT.SUBGROUP_SHUFFLE_DOWN||r===wT.SUBGROUP_SHUFFLE_UP?o.push(n.build(e,s),a.build(e,"uint")):(null!==n&&o.push(n.build(e,i)),null!==a&&o.push(a.build(e,i)));const u=0===o.length?"()":`( ${o.join(", ")} )`;return e.format(`${e.getMethod(r,s)}${u}`,s,t)}serialize(e){super.serialize(e),e.method=this.method}deserialize(e){super.deserialize(e),this.method=e.method}}wT.SUBGROUP_ELECT="subgroupElect",wT.SUBGROUP_BALLOT="subgroupBallot",wT.SUBGROUP_ADD="subgroupAdd",wT.SUBGROUP_INCLUSIVE_ADD="subgroupInclusiveAdd",wT.SUBGROUP_EXCLUSIVE_AND="subgroupExclusiveAdd",wT.SUBGROUP_MUL="subgroupMul",wT.SUBGROUP_INCLUSIVE_MUL="subgroupInclusiveMul",wT.SUBGROUP_EXCLUSIVE_MUL="subgroupExclusiveMul",wT.SUBGROUP_AND="subgroupAnd",wT.SUBGROUP_OR="subgroupOr",wT.SUBGROUP_XOR="subgroupXor",wT.SUBGROUP_MIN="subgroupMin",wT.SUBGROUP_MAX="subgroupMax",wT.SUBGROUP_ALL="subgroupAll",wT.SUBGROUP_ANY="subgroupAny",wT.SUBGROUP_BROADCAST_FIRST="subgroupBroadcastFirst",wT.QUAD_SWAP_X="quadSwapX",wT.QUAD_SWAP_Y="quadSwapY",wT.QUAD_SWAP_DIAGONAL="quadSwapDiagonal",wT.SUBGROUP_BROADCAST="subgroupBroadcast",wT.SUBGROUP_SHUFFLE="subgroupShuffle",wT.SUBGROUP_SHUFFLE_XOR="subgroupShuffleXor",wT.SUBGROUP_SHUFFLE_UP="subgroupShuffleUp",wT.SUBGROUP_SHUFFLE_DOWN="subgroupShuffleDown",wT.QUAD_BROADCAST="quadBroadcast";const CT=nn(wT,wT.SUBGROUP_ELECT).setParameterLength(0),MT=nn(wT,wT.SUBGROUP_BALLOT).setParameterLength(1),FT=nn(wT,wT.SUBGROUP_ADD).setParameterLength(1),LT=nn(wT,wT.SUBGROUP_INCLUSIVE_ADD).setParameterLength(1),PT=nn(wT,wT.SUBGROUP_EXCLUSIVE_AND).setParameterLength(1),BT=nn(wT,wT.SUBGROUP_MUL).setParameterLength(1),DT=nn(wT,wT.SUBGROUP_INCLUSIVE_MUL).setParameterLength(1),UT=nn(wT,wT.SUBGROUP_EXCLUSIVE_MUL).setParameterLength(1),IT=nn(wT,wT.SUBGROUP_AND).setParameterLength(1),OT=nn(wT,wT.SUBGROUP_OR).setParameterLength(1),VT=nn(wT,wT.SUBGROUP_XOR).setParameterLength(1),kT=nn(wT,wT.SUBGROUP_MIN).setParameterLength(1),GT=nn(wT,wT.SUBGROUP_MAX).setParameterLength(1),zT=nn(wT,wT.SUBGROUP_ALL).setParameterLength(0),$T=nn(wT,wT.SUBGROUP_ANY).setParameterLength(0),WT=nn(wT,wT.SUBGROUP_BROADCAST_FIRST).setParameterLength(2),HT=nn(wT,wT.QUAD_SWAP_X).setParameterLength(1),qT=nn(wT,wT.QUAD_SWAP_Y).setParameterLength(1),jT=nn(wT,wT.QUAD_SWAP_DIAGONAL).setParameterLength(1),XT=nn(wT,wT.SUBGROUP_BROADCAST).setParameterLength(2),KT=nn(wT,wT.SUBGROUP_SHUFFLE).setParameterLength(2),YT=nn(wT,wT.SUBGROUP_SHUFFLE_XOR).setParameterLength(2),QT=nn(wT,wT.SUBGROUP_SHUFFLE_UP).setParameterLength(2),ZT=nn(wT,wT.SUBGROUP_SHUFFLE_DOWN).setParameterLength(2),JT=nn(wT,wT.QUAD_BROADCAST).setParameterLength(1);let e_;function t_(e){e_=e_||new WeakMap;let t=e_.get(e);return void 0===t&&e_.set(e,t={}),t}function r_(e){const t=t_(e);return t.shadowMatrix||(t.shadowMatrix=_a("mat4").setGroup(ba).onRenderUpdate(t=>(!0===e.castShadow&&!1!==t.renderer.shadowMap.enabled||(e.shadow.camera.coordinateSystem!==t.camera.coordinateSystem&&(e.shadow.camera.coordinateSystem=t.camera.coordinateSystem,e.shadow.camera.updateProjectionMatrix()),e.shadow.updateMatrices(e)),e.shadow.matrix)))}function s_(e,t=Dd){const r=r_(e).mul(t);return r.xyz.div(r.w)}function i_(e){const t=t_(e);return t.position||(t.position=_a(new r).setGroup(ba).onRenderUpdate((t,r)=>r.value.setFromMatrixPosition(e.matrixWorld)))}function n_(e){const t=t_(e);return t.targetPosition||(t.targetPosition=_a(new r).setGroup(ba).onRenderUpdate((t,r)=>r.value.setFromMatrixPosition(e.target.matrixWorld)))}function a_(e){const t=t_(e);return t.viewPosition||(t.viewPosition=_a(new r).setGroup(ba).onRenderUpdate(({camera:t},s)=>{s.value=s.value||new r,s.value.setFromMatrixPosition(e.matrixWorld),s.value.applyMatrix4(t.matrixWorldInverse)}))}const o_=e=>nd.transformDirection(i_(e).sub(n_(e))),u_=(e,t)=>{for(const r of t)if(r.isAnalyticLightNode&&r.light.id===e)return r;return null},l_=new WeakMap,d_=[];class c_ extends ui{static get type(){return"LightsNode"}constructor(){super("vec3"),this.totalDiffuseNode=Un("vec3","totalDiffuse"),this.totalSpecularNode=Un("vec3","totalSpecular"),this.outgoingLightNode=Un("vec3","outgoingLight"),this._lights=[],this._lightNodes=null,this._lightNodesHash=null,this.global=!0}customCacheKey(){const e=this._lights;for(let t=0;te.sort((e,t)=>e.id-t.id))(this._lights),i=e.renderer.library;for(const e of s)if(e.isNode)t.push(Zi(e));else{let s=null;if(null!==r&&(s=u_(e.id,r)),null===s){const r=i.getLightNodeClass(e.constructor);if(null===r){d(`LightsNode.setupNodeLights: Light node not found for ${e.constructor.name}`);continue}let s=null;l_.has(e)?s=l_.get(e):(s=new r(e),l_.set(e,s)),t.push(s)}}this._lightNodes=t}setupDirectLight(e,t,r){const{lightingModel:s,reflectedLight:i}=e.context;s.direct({...r,lightNode:t,reflectedLight:i},e)}setupDirectRectAreaLight(e,t,r){const{lightingModel:s,reflectedLight:i}=e.context;s.directRectArea({...r,lightNode:t,reflectedLight:i},e)}setupLights(e,t){for(const r of t)r.build(e)}getLightNodes(e){return null===this._lightNodes&&this.setupLightsNode(e),this._lightNodes}setup(e){const t=e.lightsNode;e.lightsNode=this;let r=this.outgoingLightNode;const s=e.context,i=s.lightingModel,n=e.getNodeProperties(this);if(i){const{totalDiffuseNode:t,totalSpecularNode:a}=this;s.outgoingLight=r;const o=e.addStack();n.nodes=o.nodes,i.start(e);const{backdrop:u,backdropAlpha:l}=s,{directDiffuse:d,directSpecular:c,indirectDiffuse:h,indirectSpecular:p}=s.reflectedLight;let g=d.add(h);null!==u&&(g=vn(null!==l?l.mix(g,u):u)),t.assign(g),a.assign(c.add(p)),r.assign(t.add(a)),i.finish(e),r=r.bypass(e.removeStack())}else n.nodes=[];return e.lightsNode=t,r}setLights(e){return this._lights=e,this._lightNodes=null,this._lightNodesHash=null,this}getLights(){return this._lights}get hasLights(){return this._lights.length>0}}class h_ extends ui{static get type(){return"ShadowBaseNode"}constructor(e){super(),this.light=e,this.updateBeforeType=Js.RENDER,this.isShadowBaseNode=!0}setupShadowPosition({context:e,material:t}){p_.assign(t.receivedShadowPositionNode||e.shadowPositionWorld||Dd)}}const p_=Un("vec3","shadowPositionWorld");function g_(t,r={}){return r.toneMapping=t.toneMapping,r.toneMappingExposure=t.toneMappingExposure,r.outputColorSpace=t.outputColorSpace,r.renderTarget=t.getRenderTarget(),r.activeCubeFace=t.getActiveCubeFace(),r.activeMipmapLevel=t.getActiveMipmapLevel(),r.renderObjectFunction=t.getRenderObjectFunction(),r.pixelRatio=t.getPixelRatio(),r.mrt=t.getMRT(),r.clearColor=t.getClearColor(r.clearColor||new e),r.clearAlpha=t.getClearAlpha(),r.autoClear=t.autoClear,r.scissorTest=t.getScissorTest(),r}function m_(e,t){return t=g_(e,t),e.setMRT(null),e.setRenderObjectFunction(null),e.setClearColor(0,1),e.autoClear=!0,t}function f_(e,t){e.toneMapping=t.toneMapping,e.toneMappingExposure=t.toneMappingExposure,e.outputColorSpace=t.outputColorSpace,e.setRenderTarget(t.renderTarget,t.activeCubeFace,t.activeMipmapLevel),e.setRenderObjectFunction(t.renderObjectFunction),e.setPixelRatio(t.pixelRatio),e.setMRT(t.mrt),e.setClearColor(t.clearColor,t.clearAlpha),e.autoClear=t.autoClear,e.setScissorTest(t.scissorTest)}function y_(e,t={}){return t.background=e.background,t.backgroundNode=e.backgroundNode,t.overrideMaterial=e.overrideMaterial,t}function b_(e,t){return t=y_(e,t),e.background=null,e.backgroundNode=null,e.overrideMaterial=null,t}function x_(e,t){e.background=t.background,e.backgroundNode=t.backgroundNode,e.overrideMaterial=t.overrideMaterial}function T_(e,t,r){return r=b_(t,r=m_(e,r))}function __(e,t,r){f_(e,r),x_(t,r)}var v_=Object.freeze({__proto__:null,resetRendererAndSceneState:T_,resetRendererState:m_,resetSceneState:b_,restoreRendererAndSceneState:__,restoreRendererState:f_,restoreSceneState:x_,saveRendererAndSceneState:function(e,t,r={}){return r=y_(t,r=g_(e,r))},saveRendererState:g_,saveSceneState:y_});const N_=new WeakMap,S_=un(({depthTexture:e,shadowCoord:t,depthLayer:r})=>{let s=Pl(e,t.xy).setName("t_basic");return e.isArrayTexture&&(s=s.depth(r)),s.compare(t.z)}),R_=un(({depthTexture:e,shadowCoord:t,shadow:r,depthLayer:s})=>{const i=(t,r)=>{let i=Pl(e,t);return e.isArrayTexture&&(i=i.depth(s)),i.compare(r)},n=yc("mapSize","vec2",r).setGroup(ba),a=yc("radius","float",r).setGroup(ba),o=bn(1).div(n),u=a.mul(o.x),l=Qb(Xl.xy).mul(6.28318530718);return Ma(i(t.xy.add(Zb(0,5,l).mul(u)),t.z),i(t.xy.add(Zb(1,5,l).mul(u)),t.z),i(t.xy.add(Zb(2,5,l).mul(u)),t.z),i(t.xy.add(Zb(3,5,l).mul(u)),t.z),i(t.xy.add(Zb(4,5,l).mul(u)),t.z)).mul(.2)}),E_=un(({depthTexture:e,shadowCoord:t,shadow:r,depthLayer:s})=>{const i=(t,r)=>{let i=Pl(e,t);return e.isArrayTexture&&(i=i.depth(s)),i.compare(r)},n=yc("mapSize","vec2",r).setGroup(ba),a=bn(1).div(n),o=a.x,u=a.y,l=t.xy,d=No(l.mul(n).add(.5));return l.subAssign(d.mul(a)),Ma(i(l,t.z),i(l.add(bn(o,0)),t.z),i(l.add(bn(0,u)),t.z),i(l.add(a),t.z),nu(i(l.add(bn(o.negate(),0)),t.z),i(l.add(bn(o.mul(2),0)),t.z),d.x),nu(i(l.add(bn(o.negate(),u)),t.z),i(l.add(bn(o.mul(2),u)),t.z),d.x),nu(i(l.add(bn(0,u.negate())),t.z),i(l.add(bn(0,u.mul(2))),t.z),d.y),nu(i(l.add(bn(o,u.negate())),t.z),i(l.add(bn(o,u.mul(2))),t.z),d.y),nu(nu(i(l.add(bn(o.negate(),u.negate())),t.z),i(l.add(bn(o.mul(2),u.negate())),t.z),d.x),nu(i(l.add(bn(o.negate(),u.mul(2))),t.z),i(l.add(bn(o.mul(2),u.mul(2))),t.z),d.x),d.y)).mul(1/9)}),A_=un(({depthTexture:e,shadowCoord:t,depthLayer:r})=>{let s=Pl(e).sample(t.xy);e.isArrayTexture&&(s=s.depth(r)),s=s.rg;const i=s.x,n=Ho(1e-7,s.y.mul(s.y)),a=qo(t.z,i),o=gn(1).toVar();return cn(a.notEqual(1),()=>{const e=t.z.sub(i);let r=n.div(n.add(e.mul(e)));r=au(Fa(r,.3).div(.65)),o.assign(Ho(a,r))}),o}),w_=e=>{let t=N_.get(e);return void 0===t&&(t=new Zp,t.colorNode=En(0,0,0,1),t.isShadowPassMaterial=!0,t.name="ShadowMaterial",t.blending=ee,t.fog=!1,N_.set(e,t)),t},C_=e=>{const t=N_.get(e);void 0!==t&&(t.dispose(),N_.delete(e))},M_=new Qf,F_=[],L_=(e,t,r,s)=>{F_[0]=e,F_[1]=t;let i=M_.get(F_);return void 0!==i&&i.shadowType===r&&i.useVelocity===s||(i=(i,n,a,o,u,l,...d)=>{(!0===i.castShadow||i.receiveShadow&&r===Ze)&&(s&&(Xs(i).useVelocity=!0),i.onBeforeShadow(e,i,a,t.camera,o,n.overrideMaterial,l),e.renderObject(i,n,a,o,u,l,...d),i.onAfterShadow(e,i,a,t.camera,o,n.overrideMaterial,l))},i.shadowType=r,i.useVelocity=s,M_.set(F_,i)),F_[0]=null,F_[1]=null,i},P_=un(({samples:e,radius:t,size:r,shadowPass:s,depthLayer:i})=>{const n=gn(0).toVar("meanVertical"),a=gn(0).toVar("squareMeanVertical"),o=e.lessThanEqual(gn(1)).select(gn(0),gn(2).div(e.sub(1))),u=e.lessThanEqual(gn(1)).select(gn(0),gn(-1));lp({start:mn(0),end:mn(e),type:"int",condition:"<"},({i:e})=>{const l=u.add(gn(e).mul(o));let d=s.sample(Ma(Xl.xy,bn(0,l).mul(t)).div(r));s.value.isArrayTexture&&(d=d.depth(i)),d=d.x,n.addAssign(d),a.addAssign(d.mul(d))}),n.divAssign(e),a.divAssign(e);const l=bo(a.sub(n.mul(n)).max(0));return bn(n,l)}),B_=un(({samples:e,radius:t,size:r,shadowPass:s,depthLayer:i})=>{const n=gn(0).toVar("meanHorizontal"),a=gn(0).toVar("squareMeanHorizontal"),o=e.lessThanEqual(gn(1)).select(gn(0),gn(2).div(e.sub(1))),u=e.lessThanEqual(gn(1)).select(gn(0),gn(-1));lp({start:mn(0),end:mn(e),type:"int",condition:"<"},({i:e})=>{const l=u.add(gn(e).mul(o));let d=s.sample(Ma(Xl.xy,bn(l,0).mul(t)).div(r));s.value.isArrayTexture&&(d=d.depth(i)),n.addAssign(d.x),a.addAssign(Ma(d.y.mul(d.y),d.x.mul(d.x)))}),n.divAssign(e),a.divAssign(e);const l=bo(a.sub(n.mul(n)).max(0));return bn(n,l)}),D_=[S_,R_,E_,A_];let U_;const I_=new Wb;class O_ extends h_{static get type(){return"ShadowNode"}constructor(e,t=null){super(e),this.shadow=t||e.shadow,this.shadowMap=null,this.vsmShadowMapVertical=null,this.vsmShadowMapHorizontal=null,this.vsmMaterialVertical=null,this.vsmMaterialHorizontal=null,this._node=null,this._currentShadowType=null,this._cameraFrameId=new WeakMap,this.isShadowNode=!0,this.depthLayer=0}setupShadowFilter(e,{filterFn:t,depthTexture:r,shadowCoord:s,shadow:i,depthLayer:n}){const a=s.x.greaterThanEqual(0).and(s.x.lessThanEqual(1)).and(s.y.greaterThanEqual(0)).and(s.y.lessThanEqual(1)).and(s.z.lessThanEqual(1)),o=t({depthTexture:r,shadowCoord:s,shadow:i,depthLayer:n});return a.select(o,gn(1))}setupShadowCoord(e,t){const{shadow:r}=this,{renderer:s}=e,i=r.biasNode||yc("bias","float",r).setGroup(ba);let n,a=t;if(r.camera.isOrthographicCamera||!0!==s.logarithmicDepthBuffer)a=a.xyz.div(a.w),n=a.z,s.coordinateSystem===h&&(n=n.mul(2).sub(1));else{const e=a.w;a=a.xy.div(e);const t=yc("near","float",r.camera).setGroup(ba),s=yc("far","float",r.camera).setGroup(ba);n=Bp(e.negate(),t,s)}return a=vn(a.x,a.y.oneMinus(),n.add(i)),a}getShadowFilterFn(e){return D_[e]}setupRenderTarget(e,t){const r=new Y(e.mapSize.width,e.mapSize.height);r.name="ShadowDepthTexture",r.compareFunction=Je;const s=t.createRenderTarget(e.mapSize.width,e.mapSize.height);return s.texture.name="ShadowMap",s.texture.type=e.mapType,s.depthTexture=r,{shadowMap:s,depthTexture:r}}setupShadow(e){const{renderer:t,camera:r}=e,{light:s,shadow:i}=this,{depthTexture:n,shadowMap:a}=this.setupRenderTarget(i,e),o=t.shadowMap.type;if(o===et||o===tt?(n.minFilter=oe,n.magFilter=oe):(n.minFilter=w,n.magFilter=w),i.camera.coordinateSystem=r.coordinateSystem,i.camera.updateProjectionMatrix(),o===Ze&&!0!==i.isPointLightShadow){n.compareFunction=null,a.depth>1?(a._vsmShadowMapVertical||(a._vsmShadowMapVertical=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depth:a.depth,depthBuffer:!1}),a._vsmShadowMapVertical.texture.name="VSMVertical"),this.vsmShadowMapVertical=a._vsmShadowMapVertical,a._vsmShadowMapHorizontal||(a._vsmShadowMapHorizontal=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depth:a.depth,depthBuffer:!1}),a._vsmShadowMapHorizontal.texture.name="VSMHorizontal"),this.vsmShadowMapHorizontal=a._vsmShadowMapHorizontal):(this.vsmShadowMapVertical=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depthBuffer:!1}),this.vsmShadowMapHorizontal=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depthBuffer:!1}));let t=Pl(n);n.isArrayTexture&&(t=t.depth(this.depthLayer));let r=Pl(this.vsmShadowMapVertical.texture);n.isArrayTexture&&(r=r.depth(this.depthLayer));const s=yc("blurSamples","float",i).setGroup(ba),o=yc("radius","float",i).setGroup(ba),u=yc("mapSize","vec2",i).setGroup(ba);let l=this.vsmMaterialVertical||(this.vsmMaterialVertical=new Zp);l.fragmentNode=P_({samples:s,radius:o,size:u,shadowPass:t,depthLayer:this.depthLayer}).context(e.getSharedContext()),l.name="VSMVertical",l=this.vsmMaterialHorizontal||(this.vsmMaterialHorizontal=new Zp),l.fragmentNode=B_({samples:s,radius:o,size:u,shadowPass:r,depthLayer:this.depthLayer}).context(e.getSharedContext()),l.name="VSMHorizontal"}const u=yc("intensity","float",i).setGroup(ba),l=yc("normalBias","float",i).setGroup(ba),d=r_(s).mul(p_.add(Kd.mul(l))),c=this.setupShadowCoord(e,d),h=i.filterNode||this.getShadowFilterFn(t.shadowMap.type)||null;if(null===h)throw new Error("THREE.WebGPURenderer: Shadow map type not supported yet.");const p=o===Ze&&!0!==i.isPointLightShadow?this.vsmShadowMapHorizontal.texture:n,g=this.setupShadowFilter(e,{filterFn:h,shadowTexture:a.texture,depthTexture:p,shadowCoord:c,shadow:i,depthLayer:this.depthLayer});let m,f;!0===t.shadowMap.transmitted&&(a.texture.isCubeTexture?m=gc(a.texture,c.xyz):(m=Pl(a.texture,c),n.isArrayTexture&&(m=m.depth(this.depthLayer)))),f=m?nu(1,g.rgb.mix(m,1),u.mul(m.a)).toVar():nu(1,g,u).toVar(),this.shadowMap=a,this.shadow.map=a;const y=`${this.light.type} Shadow [ ${this.light.name||"ID: "+this.light.id} ]`;return m&&f.toInspector(`${y} / Color`,()=>this.shadowMap.texture.isCubeTexture?gc(this.shadowMap.texture):Pl(this.shadowMap.texture)),f.toInspector(`${y} / Depth`,()=>this.shadowMap.texture.isCubeTexture?gc(this.shadowMap.texture).r.oneMinus():Bl(this.shadowMap.depthTexture,Rl().mul(Al(Pl(this.shadowMap.depthTexture)))).r.oneMinus())}setup(e){if(!1!==e.renderer.shadowMap.enabled)return un(()=>{const t=e.renderer.shadowMap.type;this._currentShadowType!==t&&(this._reset(),this._node=null);let r=this._node;return this.setupShadowPosition(e),null===r&&(this._node=r=this.setupShadow(e),this._currentShadowType=t),e.material.receivedShadowNode&&(r=e.material.receivedShadowNode(r)),r})()}renderShadow(e){const{shadow:t,shadowMap:r,light:s}=this,{renderer:i,scene:n}=e;t.updateMatrices(s),r.setSize(t.mapSize.width,t.mapSize.height,r.depth);const a=n.name;n.name=`Shadow Map [ ${s.name||"ID: "+s.id} ]`,i.render(n,t.camera),n.name=a}updateShadow(e){const{shadowMap:t,light:r,shadow:s}=this,{renderer:i,scene:n,camera:a}=e,o=i.shadowMap.type,u=t.depthTexture.version;this._depthVersionCached=u;const l=s.camera.layers.mask;4294967294&s.camera.layers.mask||(s.camera.layers.mask=a.layers.mask);const d=i.getRenderObjectFunction(),c=i.getMRT(),h=!!c&&c.has("velocity");U_=T_(i,n,U_),n.overrideMaterial=w_(r),i.setRenderObjectFunction(L_(i,s,o,h)),i.setClearColor(0,0),i.setRenderTarget(t),this.renderShadow(e),i.setRenderObjectFunction(d),o===Ze&&!0!==s.isPointLightShadow&&this.vsmPass(i),s.camera.layers.mask=l,__(i,n,U_)}vsmPass(e){const{shadow:t}=this,r=this.shadowMap.depth;this.vsmShadowMapVertical.setSize(t.mapSize.width,t.mapSize.height,r),this.vsmShadowMapHorizontal.setSize(t.mapSize.width,t.mapSize.height,r),e.setRenderTarget(this.vsmShadowMapVertical),I_.material=this.vsmMaterialVertical,I_.render(e),e.setRenderTarget(this.vsmShadowMapHorizontal),I_.material=this.vsmMaterialHorizontal,I_.render(e)}dispose(){this._reset(),super.dispose()}_reset(){this._currentShadowType=null,C_(this.light),this.shadowMap&&(this.shadowMap.dispose(),this.shadowMap=null),null!==this.vsmShadowMapVertical&&(this.vsmShadowMapVertical.dispose(),this.vsmShadowMapVertical=null,this.vsmMaterialVertical.dispose(),this.vsmMaterialVertical=null),null!==this.vsmShadowMapHorizontal&&(this.vsmShadowMapHorizontal.dispose(),this.vsmShadowMapHorizontal=null,this.vsmMaterialHorizontal.dispose(),this.vsmMaterialHorizontal=null)}updateBefore(e){const{shadow:t}=this;let r=t.needsUpdate||t.autoUpdate;r&&(this._cameraFrameId[e.camera]===e.frameId&&(r=!1),this._cameraFrameId[e.camera]=e.frameId),r&&(this.updateShadow(e),this.shadowMap.depthTexture.version===this._depthVersionCached&&(t.needsUpdate=!1))}}const V_=(e,t)=>new O_(e,t),k_=new e,G_=new a,z_=new r,$_=new r,W_=[new r(1,0,0),new r(-1,0,0),new r(0,-1,0),new r(0,1,0),new r(0,0,1),new r(0,0,-1)],H_=[new r(0,-1,0),new r(0,-1,0),new r(0,0,-1),new r(0,0,1),new r(0,-1,0),new r(0,-1,0)],q_=[new r(1,0,0),new r(-1,0,0),new r(0,1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1)],j_=[new r(0,-1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1),new r(0,-1,0),new r(0,-1,0)],X_=un(({depthTexture:e,bd3D:t,dp:r})=>gc(e,t).compare(r)),K_=un(({depthTexture:e,bd3D:t,dp:r,shadow:s})=>{const i=yc("radius","float",s).setGroup(ba),n=yc("mapSize","vec2",s).setGroup(ba),a=i.div(n.x),o=Mo(t),u=vo(Qo(t,o.x.greaterThan(o.z).select(vn(0,1,0),vn(1,0,0)))),l=Qo(t,u),d=Qb(Xl.xy).mul(6.28318530718),c=Zb(0,5,d),h=Zb(1,5,d),p=Zb(2,5,d),g=Zb(3,5,d),m=Zb(4,5,d);return gc(e,t.add(u.mul(c.x).add(l.mul(c.y)).mul(a))).compare(r).add(gc(e,t.add(u.mul(h.x).add(l.mul(h.y)).mul(a))).compare(r)).add(gc(e,t.add(u.mul(p.x).add(l.mul(p.y)).mul(a))).compare(r)).add(gc(e,t.add(u.mul(g.x).add(l.mul(g.y)).mul(a))).compare(r)).add(gc(e,t.add(u.mul(m.x).add(l.mul(m.y)).mul(a))).compare(r)).mul(.2)}),Y_=un(({filterFn:e,depthTexture:t,shadowCoord:r,shadow:s})=>{const i=r.xyz.toConst(),n=i.abs().toConst(),a=n.x.max(n.y).max(n.z),o=_a("float").setGroup(ba).onRenderUpdate(()=>s.camera.near),u=_a("float").setGroup(ba).onRenderUpdate(()=>s.camera.far),l=yc("bias","float",s).setGroup(ba),d=gn(1).toVar();return cn(a.sub(u).lessThanEqual(0).and(a.sub(o).greaterThanEqual(0)),()=>{const r=Lp(a.negate(),o,u);r.addAssign(l);const n=i.normalize();d.assign(e({depthTexture:t,bd3D:n,dp:r,shadow:s}))}),d});class Q_ extends O_{static get type(){return"PointShadowNode"}constructor(e,t=null){super(e,t)}getShadowFilterFn(e){return e===rt?X_:K_}setupShadowCoord(e,t){return t}setupShadowFilter(e,{filterFn:t,depthTexture:r,shadowCoord:s,shadow:i}){return Y_({filterFn:t,depthTexture:r,shadowCoord:s,shadow:i})}setupRenderTarget(e,t){const r=new st(e.mapSize.width);r.name="PointShadowDepthTexture",r.compareFunction=Je;const s=t.createCubeRenderTarget(e.mapSize.width);return s.texture.name="PointShadowMap",s.depthTexture=r,{shadowMap:s,depthTexture:r}}renderShadow(e){const{shadow:t,shadowMap:r,light:s}=this,{renderer:i,scene:n}=e,a=t.camera,o=t.matrix,u=i.coordinateSystem===h,l=u?W_:q_,d=u?H_:j_;r.setSize(t.mapSize.width,t.mapSize.width);const c=i.autoClear,p=i.getClearColor(k_),g=i.getClearAlpha();i.autoClear=!1,i.setClearColor(t.clearColor,t.clearAlpha);for(let e=0;e<6;e++){i.setRenderTarget(r,e),i.clear();const u=s.distance||a.far;u!==a.far&&(a.far=u,a.updateProjectionMatrix()),z_.setFromMatrixPosition(s.matrixWorld),a.position.copy(z_),$_.copy(a.position),$_.add(l[e]),a.up.copy(d[e]),a.lookAt($_),a.updateMatrixWorld(),o.makeTranslation(-z_.x,-z_.y,-z_.z),G_.multiplyMatrices(a.projectionMatrix,a.matrixWorldInverse),t._frustum.setFromProjectionMatrix(G_,a.coordinateSystem,a.reversedDepth);const c=n.name;n.name=`Point Light Shadow [ ${s.name||"ID: "+s.id} ] - Face ${e+1}`,i.render(n,a),n.name=c}i.autoClear=c,i.setClearColor(p,g)}}const Z_=(e,t)=>new Q_(e,t);class J_ extends fp{static get type(){return"AnalyticLightNode"}constructor(t=null){super(),this.light=t,this.color=new e,this.colorNode=t&&t.colorNode||_a(this.color).setGroup(ba),this.baseColorNode=null,this.shadowNode=null,this.shadowColorNode=null,this.isAnalyticLightNode=!0,this.updateType=Js.FRAME,t&&t.shadow&&(this._shadowDisposeListener=()=>{this.disposeShadow()},t.addEventListener("dispose",this._shadowDisposeListener))}dispose(){this._shadowDisposeListener&&this.light.removeEventListener("dispose",this._shadowDisposeListener),super.dispose()}disposeShadow(){null!==this.shadowNode&&(this.shadowNode.dispose(),this.shadowNode=null),this.shadowColorNode=null,null!==this.baseColorNode&&(this.colorNode=this.baseColorNode,this.baseColorNode=null)}getHash(){return this.light.uuid}getLightVector(e){return a_(this.light).sub(e.context.positionView||Id)}setupDirect(){}setupDirectRectArea(){}setupShadowNode(){return V_(this.light)}setupShadow(e){const{renderer:t}=e;if(!1===t.shadowMap.enabled)return;let r=this.shadowColorNode;if(null===r){const e=this.light.shadow.shadowNode;let t;t=void 0!==e?Zi(e):this.setupShadowNode(),this.shadowNode=t,this.shadowColorNode=r=this.colorNode.mul(t),this.baseColorNode=this.colorNode}e.context.getShadow&&(r=e.context.getShadow(this,e)),this.colorNode=r}setup(e){this.colorNode=this.baseColorNode||this.colorNode,this.light.castShadow?e.object.receiveShadow&&this.setupShadow(e):null!==this.shadowNode&&(this.shadowNode.dispose(),this.shadowNode=null,this.shadowColorNode=null);const t=this.setupDirect(e),r=this.setupDirectRectArea(e);t&&e.lightsNode.setupDirectLight(e,this,t),r&&e.lightsNode.setupDirectRectAreaLight(e,this,r)}update(){const{light:e}=this;this.color.copy(e.color).multiplyScalar(e.intensity)}}const ev=un(({lightDistance:e,cutoffDistance:t,decayExponent:r})=>{const s=e.pow(r).max(.01).reciprocal();return t.greaterThan(0).select(s.mul(e.div(t).pow4().oneMinus().clamp().pow2()),s)}),tv=({color:e,lightVector:t,cutoffDistance:r,decayExponent:s})=>{const i=t.normalize(),n=t.length(),a=ev({lightDistance:n,cutoffDistance:r,decayExponent:s});return{lightDirection:i,lightColor:e.mul(a)}};class rv extends J_{static get type(){return"PointLightNode"}constructor(e=null){super(e),this.cutoffDistanceNode=_a(0).setGroup(ba),this.decayExponentNode=_a(2).setGroup(ba)}update(e){const{light:t}=this;super.update(e),this.cutoffDistanceNode.value=t.distance,this.decayExponentNode.value=t.decay}setupShadowNode(){return Z_(this.light)}setupDirect(e){return tv({color:this.colorNode,lightVector:this.getLightVector(e),cutoffDistance:this.cutoffDistanceNode,decayExponent:this.decayExponentNode})}}const sv=un(([e=Rl()])=>{const t=e.mul(2),r=t.x.floor(),s=t.y.floor();return r.add(s).mod(2).sign()}),iv=un(([e=Rl()],{renderer:t,material:r})=>{const s=iu(e.mul(2).sub(1));let i;if(r.alphaToCoverage&&t.currentSamples>0){const e=gn(s.fwidth()).toVar();i=lu(e.oneMinus(),e.add(1),s).oneMinus()}else i=bu(s.greaterThan(1),0,1);return i}),nv=un(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=yn(e).toVar();return bu(n,i,s)}).setLayout({name:"mx_select",type:"float",inputs:[{name:"b",type:"bool"},{name:"t",type:"float"},{name:"f",type:"float"}]}),av=un(([e,t])=>{const r=yn(t).toVar(),s=gn(e).toVar();return bu(r,s.negate(),s)}).setLayout({name:"mx_negate_if",type:"float",inputs:[{name:"val",type:"float"},{name:"b",type:"bool"}]}),ov=un(([e])=>{const t=gn(e).toVar();return mn(To(t))}).setLayout({name:"mx_floor",type:"int",inputs:[{name:"x",type:"float"}]}),uv=un(([e,t])=>{const r=gn(e).toVar();return t.assign(ov(r)),r.sub(gn(t))}),lv=mb([un(([e,t,r,s,i,n])=>{const a=gn(n).toVar(),o=gn(i).toVar(),u=gn(s).toVar(),l=gn(r).toVar(),d=gn(t).toVar(),c=gn(e).toVar(),h=gn(Fa(1,o)).toVar();return Fa(1,a).mul(c.mul(h).add(d.mul(o))).add(a.mul(l.mul(h).add(u.mul(o))))}).setLayout({name:"mx_bilerp_0",type:"float",inputs:[{name:"v0",type:"float"},{name:"v1",type:"float"},{name:"v2",type:"float"},{name:"v3",type:"float"},{name:"s",type:"float"},{name:"t",type:"float"}]}),un(([e,t,r,s,i,n])=>{const a=gn(n).toVar(),o=gn(i).toVar(),u=vn(s).toVar(),l=vn(r).toVar(),d=vn(t).toVar(),c=vn(e).toVar(),h=gn(Fa(1,o)).toVar();return Fa(1,a).mul(c.mul(h).add(d.mul(o))).add(a.mul(l.mul(h).add(u.mul(o))))}).setLayout({name:"mx_bilerp_1",type:"vec3",inputs:[{name:"v0",type:"vec3"},{name:"v1",type:"vec3"},{name:"v2",type:"vec3"},{name:"v3",type:"vec3"},{name:"s",type:"float"},{name:"t",type:"float"}]})]),dv=mb([un(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=gn(d).toVar(),h=gn(l).toVar(),p=gn(u).toVar(),g=gn(o).toVar(),m=gn(a).toVar(),f=gn(n).toVar(),y=gn(i).toVar(),b=gn(s).toVar(),x=gn(r).toVar(),T=gn(t).toVar(),_=gn(e).toVar(),v=gn(Fa(1,p)).toVar(),N=gn(Fa(1,h)).toVar();return gn(Fa(1,c)).toVar().mul(N.mul(_.mul(v).add(T.mul(p))).add(h.mul(x.mul(v).add(b.mul(p))))).add(c.mul(N.mul(y.mul(v).add(f.mul(p))).add(h.mul(m.mul(v).add(g.mul(p))))))}).setLayout({name:"mx_trilerp_0",type:"float",inputs:[{name:"v0",type:"float"},{name:"v1",type:"float"},{name:"v2",type:"float"},{name:"v3",type:"float"},{name:"v4",type:"float"},{name:"v5",type:"float"},{name:"v6",type:"float"},{name:"v7",type:"float"},{name:"s",type:"float"},{name:"t",type:"float"},{name:"r",type:"float"}]}),un(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=gn(d).toVar(),h=gn(l).toVar(),p=gn(u).toVar(),g=vn(o).toVar(),m=vn(a).toVar(),f=vn(n).toVar(),y=vn(i).toVar(),b=vn(s).toVar(),x=vn(r).toVar(),T=vn(t).toVar(),_=vn(e).toVar(),v=gn(Fa(1,p)).toVar(),N=gn(Fa(1,h)).toVar();return gn(Fa(1,c)).toVar().mul(N.mul(_.mul(v).add(T.mul(p))).add(h.mul(x.mul(v).add(b.mul(p))))).add(c.mul(N.mul(y.mul(v).add(f.mul(p))).add(h.mul(m.mul(v).add(g.mul(p))))))}).setLayout({name:"mx_trilerp_1",type:"vec3",inputs:[{name:"v0",type:"vec3"},{name:"v1",type:"vec3"},{name:"v2",type:"vec3"},{name:"v3",type:"vec3"},{name:"v4",type:"vec3"},{name:"v5",type:"vec3"},{name:"v6",type:"vec3"},{name:"v7",type:"vec3"},{name:"s",type:"float"},{name:"t",type:"float"},{name:"r",type:"float"}]})]),cv=un(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=fn(e).toVar(),a=fn(n.bitAnd(fn(7))).toVar(),o=gn(nv(a.lessThan(fn(4)),i,s)).toVar(),u=gn(La(2,nv(a.lessThan(fn(4)),s,i))).toVar();return av(o,yn(a.bitAnd(fn(1)))).add(av(u,yn(a.bitAnd(fn(2)))))}).setLayout({name:"mx_gradient_float_0",type:"float",inputs:[{name:"hash",type:"uint"},{name:"x",type:"float"},{name:"y",type:"float"}]}),hv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=gn(t).toVar(),o=fn(e).toVar(),u=fn(o.bitAnd(fn(15))).toVar(),l=gn(nv(u.lessThan(fn(8)),a,n)).toVar(),d=gn(nv(u.lessThan(fn(4)),n,nv(u.equal(fn(12)).or(u.equal(fn(14))),a,i))).toVar();return av(l,yn(u.bitAnd(fn(1)))).add(av(d,yn(u.bitAnd(fn(2)))))}).setLayout({name:"mx_gradient_float_1",type:"float",inputs:[{name:"hash",type:"uint"},{name:"x",type:"float"},{name:"y",type:"float"},{name:"z",type:"float"}]}),pv=mb([cv,hv]),gv=un(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=Sn(e).toVar();return vn(pv(n.x,i,s),pv(n.y,i,s),pv(n.z,i,s))}).setLayout({name:"mx_gradient_vec3_0",type:"vec3",inputs:[{name:"hash",type:"uvec3"},{name:"x",type:"float"},{name:"y",type:"float"}]}),mv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=gn(t).toVar(),o=Sn(e).toVar();return vn(pv(o.x,a,n,i),pv(o.y,a,n,i),pv(o.z,a,n,i))}).setLayout({name:"mx_gradient_vec3_1",type:"vec3",inputs:[{name:"hash",type:"uvec3"},{name:"x",type:"float"},{name:"y",type:"float"},{name:"z",type:"float"}]}),fv=mb([gv,mv]),yv=un(([e])=>{const t=gn(e).toVar();return La(.6616,t)}).setLayout({name:"mx_gradient_scale2d_0",type:"float",inputs:[{name:"v",type:"float"}]}),bv=un(([e])=>{const t=gn(e).toVar();return La(.982,t)}).setLayout({name:"mx_gradient_scale3d_0",type:"float",inputs:[{name:"v",type:"float"}]}),xv=mb([yv,un(([e])=>{const t=vn(e).toVar();return La(.6616,t)}).setLayout({name:"mx_gradient_scale2d_1",type:"vec3",inputs:[{name:"v",type:"vec3"}]})]),Tv=mb([bv,un(([e])=>{const t=vn(e).toVar();return La(.982,t)}).setLayout({name:"mx_gradient_scale3d_1",type:"vec3",inputs:[{name:"v",type:"vec3"}]})]),_v=un(([e,t])=>{const r=mn(t).toVar(),s=fn(e).toVar();return s.shiftLeft(r).bitOr(s.shiftRight(mn(32).sub(r)))}).setLayout({name:"mx_rotl32",type:"uint",inputs:[{name:"x",type:"uint"},{name:"k",type:"int"}]}),vv=un(([e,t,r])=>{e.subAssign(r),e.bitXorAssign(_v(r,mn(4))),r.addAssign(t),t.subAssign(e),t.bitXorAssign(_v(e,mn(6))),e.addAssign(r),r.subAssign(t),r.bitXorAssign(_v(t,mn(8))),t.addAssign(e),e.subAssign(r),e.bitXorAssign(_v(r,mn(16))),r.addAssign(t),t.subAssign(e),t.bitXorAssign(_v(e,mn(19))),e.addAssign(r),r.subAssign(t),r.bitXorAssign(_v(t,mn(4))),t.addAssign(e)}),Nv=un(([e,t,r])=>{const s=fn(r).toVar(),i=fn(t).toVar(),n=fn(e).toVar();return s.bitXorAssign(i),s.subAssign(_v(i,mn(14))),n.bitXorAssign(s),n.subAssign(_v(s,mn(11))),i.bitXorAssign(n),i.subAssign(_v(n,mn(25))),s.bitXorAssign(i),s.subAssign(_v(i,mn(16))),n.bitXorAssign(s),n.subAssign(_v(s,mn(4))),i.bitXorAssign(n),i.subAssign(_v(n,mn(14))),s.bitXorAssign(i),s.subAssign(_v(i,mn(24))),s}).setLayout({name:"mx_bjfinal",type:"uint",inputs:[{name:"a",type:"uint"},{name:"b",type:"uint"},{name:"c",type:"uint"}]}),Sv=un(([e])=>{const t=fn(e).toVar();return gn(t).div(gn(fn(mn(4294967295))))}).setLayout({name:"mx_bits_to_01",type:"float",inputs:[{name:"bits",type:"uint"}]}),Rv=un(([e])=>{const t=gn(e).toVar();return t.mul(t).mul(t).mul(t.mul(t.mul(6).sub(15)).add(10))}).setLayout({name:"mx_fade",type:"float",inputs:[{name:"t",type:"float"}]}),Ev=mb([un(([e])=>{const t=mn(e).toVar(),r=fn(fn(1)).toVar(),s=fn(fn(mn(3735928559)).add(r.shiftLeft(fn(2))).add(fn(13))).toVar();return Nv(s.add(fn(t)),s,s)}).setLayout({name:"mx_hash_int_0",type:"uint",inputs:[{name:"x",type:"int"}]}),un(([e,t])=>{const r=mn(t).toVar(),s=mn(e).toVar(),i=fn(fn(2)).toVar(),n=fn().toVar(),a=fn().toVar(),o=fn().toVar();return n.assign(a.assign(o.assign(fn(mn(3735928559)).add(i.shiftLeft(fn(2))).add(fn(13))))),n.addAssign(fn(s)),a.addAssign(fn(r)),Nv(n,a,o)}).setLayout({name:"mx_hash_int_1",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"}]}),un(([e,t,r])=>{const s=mn(r).toVar(),i=mn(t).toVar(),n=mn(e).toVar(),a=fn(fn(3)).toVar(),o=fn().toVar(),u=fn().toVar(),l=fn().toVar();return o.assign(u.assign(l.assign(fn(mn(3735928559)).add(a.shiftLeft(fn(2))).add(fn(13))))),o.addAssign(fn(n)),u.addAssign(fn(i)),l.addAssign(fn(s)),Nv(o,u,l)}).setLayout({name:"mx_hash_int_2",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"}]}),un(([e,t,r,s])=>{const i=mn(s).toVar(),n=mn(r).toVar(),a=mn(t).toVar(),o=mn(e).toVar(),u=fn(fn(4)).toVar(),l=fn().toVar(),d=fn().toVar(),c=fn().toVar();return l.assign(d.assign(c.assign(fn(mn(3735928559)).add(u.shiftLeft(fn(2))).add(fn(13))))),l.addAssign(fn(o)),d.addAssign(fn(a)),c.addAssign(fn(n)),vv(l,d,c),l.addAssign(fn(i)),Nv(l,d,c)}).setLayout({name:"mx_hash_int_3",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xx",type:"int"}]}),un(([e,t,r,s,i])=>{const n=mn(i).toVar(),a=mn(s).toVar(),o=mn(r).toVar(),u=mn(t).toVar(),l=mn(e).toVar(),d=fn(fn(5)).toVar(),c=fn().toVar(),h=fn().toVar(),p=fn().toVar();return c.assign(h.assign(p.assign(fn(mn(3735928559)).add(d.shiftLeft(fn(2))).add(fn(13))))),c.addAssign(fn(l)),h.addAssign(fn(u)),p.addAssign(fn(o)),vv(c,h,p),c.addAssign(fn(a)),h.addAssign(fn(n)),Nv(c,h,p)}).setLayout({name:"mx_hash_int_4",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xx",type:"int"},{name:"yy",type:"int"}]})]),Av=mb([un(([e,t])=>{const r=mn(t).toVar(),s=mn(e).toVar(),i=fn(Ev(s,r)).toVar(),n=Sn().toVar();return n.x.assign(i.bitAnd(mn(255))),n.y.assign(i.shiftRight(mn(8)).bitAnd(mn(255))),n.z.assign(i.shiftRight(mn(16)).bitAnd(mn(255))),n}).setLayout({name:"mx_hash_vec3_0",type:"uvec3",inputs:[{name:"x",type:"int"},{name:"y",type:"int"}]}),un(([e,t,r])=>{const s=mn(r).toVar(),i=mn(t).toVar(),n=mn(e).toVar(),a=fn(Ev(n,i,s)).toVar(),o=Sn().toVar();return o.x.assign(a.bitAnd(mn(255))),o.y.assign(a.shiftRight(mn(8)).bitAnd(mn(255))),o.z.assign(a.shiftRight(mn(16)).bitAnd(mn(255))),o}).setLayout({name:"mx_hash_vec3_1",type:"uvec3",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"}]})]),wv=mb([un(([e])=>{const t=bn(e).toVar(),r=mn().toVar(),s=mn().toVar(),i=gn(uv(t.x,r)).toVar(),n=gn(uv(t.y,s)).toVar(),a=gn(Rv(i)).toVar(),o=gn(Rv(n)).toVar(),u=gn(lv(pv(Ev(r,s),i,n),pv(Ev(r.add(mn(1)),s),i.sub(1),n),pv(Ev(r,s.add(mn(1))),i,n.sub(1)),pv(Ev(r.add(mn(1)),s.add(mn(1))),i.sub(1),n.sub(1)),a,o)).toVar();return xv(u)}).setLayout({name:"mx_perlin_noise_float_0",type:"float",inputs:[{name:"p",type:"vec2"}]}),un(([e])=>{const t=vn(e).toVar(),r=mn().toVar(),s=mn().toVar(),i=mn().toVar(),n=gn(uv(t.x,r)).toVar(),a=gn(uv(t.y,s)).toVar(),o=gn(uv(t.z,i)).toVar(),u=gn(Rv(n)).toVar(),l=gn(Rv(a)).toVar(),d=gn(Rv(o)).toVar(),c=gn(dv(pv(Ev(r,s,i),n,a,o),pv(Ev(r.add(mn(1)),s,i),n.sub(1),a,o),pv(Ev(r,s.add(mn(1)),i),n,a.sub(1),o),pv(Ev(r.add(mn(1)),s.add(mn(1)),i),n.sub(1),a.sub(1),o),pv(Ev(r,s,i.add(mn(1))),n,a,o.sub(1)),pv(Ev(r.add(mn(1)),s,i.add(mn(1))),n.sub(1),a,o.sub(1)),pv(Ev(r,s.add(mn(1)),i.add(mn(1))),n,a.sub(1),o.sub(1)),pv(Ev(r.add(mn(1)),s.add(mn(1)),i.add(mn(1))),n.sub(1),a.sub(1),o.sub(1)),u,l,d)).toVar();return Tv(c)}).setLayout({name:"mx_perlin_noise_float_1",type:"float",inputs:[{name:"p",type:"vec3"}]})]),Cv=mb([un(([e])=>{const t=bn(e).toVar(),r=mn().toVar(),s=mn().toVar(),i=gn(uv(t.x,r)).toVar(),n=gn(uv(t.y,s)).toVar(),a=gn(Rv(i)).toVar(),o=gn(Rv(n)).toVar(),u=vn(lv(fv(Av(r,s),i,n),fv(Av(r.add(mn(1)),s),i.sub(1),n),fv(Av(r,s.add(mn(1))),i,n.sub(1)),fv(Av(r.add(mn(1)),s.add(mn(1))),i.sub(1),n.sub(1)),a,o)).toVar();return xv(u)}).setLayout({name:"mx_perlin_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"vec2"}]}),un(([e])=>{const t=vn(e).toVar(),r=mn().toVar(),s=mn().toVar(),i=mn().toVar(),n=gn(uv(t.x,r)).toVar(),a=gn(uv(t.y,s)).toVar(),o=gn(uv(t.z,i)).toVar(),u=gn(Rv(n)).toVar(),l=gn(Rv(a)).toVar(),d=gn(Rv(o)).toVar(),c=vn(dv(fv(Av(r,s,i),n,a,o),fv(Av(r.add(mn(1)),s,i),n.sub(1),a,o),fv(Av(r,s.add(mn(1)),i),n,a.sub(1),o),fv(Av(r.add(mn(1)),s.add(mn(1)),i),n.sub(1),a.sub(1),o),fv(Av(r,s,i.add(mn(1))),n,a,o.sub(1)),fv(Av(r.add(mn(1)),s,i.add(mn(1))),n.sub(1),a,o.sub(1)),fv(Av(r,s.add(mn(1)),i.add(mn(1))),n,a.sub(1),o.sub(1)),fv(Av(r.add(mn(1)),s.add(mn(1)),i.add(mn(1))),n.sub(1),a.sub(1),o.sub(1)),u,l,d)).toVar();return Tv(c)}).setLayout({name:"mx_perlin_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec3"}]})]),Mv=mb([un(([e])=>{const t=gn(e).toVar(),r=mn(ov(t)).toVar();return Sv(Ev(r))}).setLayout({name:"mx_cell_noise_float_0",type:"float",inputs:[{name:"p",type:"float"}]}),un(([e])=>{const t=bn(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar();return Sv(Ev(r,s))}).setLayout({name:"mx_cell_noise_float_1",type:"float",inputs:[{name:"p",type:"vec2"}]}),un(([e])=>{const t=vn(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar(),i=mn(ov(t.z)).toVar();return Sv(Ev(r,s,i))}).setLayout({name:"mx_cell_noise_float_2",type:"float",inputs:[{name:"p",type:"vec3"}]}),un(([e])=>{const t=En(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar(),i=mn(ov(t.z)).toVar(),n=mn(ov(t.w)).toVar();return Sv(Ev(r,s,i,n))}).setLayout({name:"mx_cell_noise_float_3",type:"float",inputs:[{name:"p",type:"vec4"}]})]),Fv=mb([un(([e])=>{const t=gn(e).toVar(),r=mn(ov(t)).toVar();return vn(Sv(Ev(r,mn(0))),Sv(Ev(r,mn(1))),Sv(Ev(r,mn(2))))}).setLayout({name:"mx_cell_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"float"}]}),un(([e])=>{const t=bn(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar();return vn(Sv(Ev(r,s,mn(0))),Sv(Ev(r,s,mn(1))),Sv(Ev(r,s,mn(2))))}).setLayout({name:"mx_cell_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec2"}]}),un(([e])=>{const t=vn(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar(),i=mn(ov(t.z)).toVar();return vn(Sv(Ev(r,s,i,mn(0))),Sv(Ev(r,s,i,mn(1))),Sv(Ev(r,s,i,mn(2))))}).setLayout({name:"mx_cell_noise_vec3_2",type:"vec3",inputs:[{name:"p",type:"vec3"}]}),un(([e])=>{const t=En(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar(),i=mn(ov(t.z)).toVar(),n=mn(ov(t.w)).toVar();return vn(Sv(Ev(r,s,i,n,mn(0))),Sv(Ev(r,s,i,n,mn(1))),Sv(Ev(r,s,i,n,mn(2))))}).setLayout({name:"mx_cell_noise_vec3_3",type:"vec3",inputs:[{name:"p",type:"vec4"}]})]),Lv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=mn(t).toVar(),o=vn(e).toVar(),u=gn(0).toVar(),l=gn(1).toVar();return lp(a,()=>{u.addAssign(l.mul(wv(o))),l.mulAssign(i),o.mulAssign(n)}),u}).setLayout({name:"mx_fractal_noise_float",type:"float",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Pv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=mn(t).toVar(),o=vn(e).toVar(),u=vn(0).toVar(),l=gn(1).toVar();return lp(a,()=>{u.addAssign(l.mul(Cv(o))),l.mulAssign(i),o.mulAssign(n)}),u}).setLayout({name:"mx_fractal_noise_vec3",type:"vec3",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Bv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=mn(t).toVar(),o=vn(e).toVar();return bn(Lv(o,a,n,i),Lv(o.add(vn(mn(19),mn(193),mn(17))),a,n,i))}).setLayout({name:"mx_fractal_noise_vec2",type:"vec2",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Dv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=mn(t).toVar(),o=vn(e).toVar(),u=vn(Pv(o,a,n,i)).toVar(),l=gn(Lv(o.add(vn(mn(19),mn(193),mn(17))),a,n,i)).toVar();return En(u,l)}).setLayout({name:"mx_fractal_noise_vec4",type:"vec4",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Uv=mb([un(([e,t,r,s,i,n,a])=>{const o=mn(a).toVar(),u=gn(n).toVar(),l=mn(i).toVar(),d=mn(s).toVar(),c=mn(r).toVar(),h=mn(t).toVar(),p=bn(e).toVar(),g=vn(Fv(bn(h.add(d),c.add(l)))).toVar(),m=bn(g.x,g.y).toVar();m.subAssign(.5),m.mulAssign(u),m.addAssign(.5);const f=bn(bn(gn(h),gn(c)).add(m)).toVar(),y=bn(f.sub(p)).toVar();return cn(o.equal(mn(2)),()=>Mo(y.x).add(Mo(y.y))),cn(o.equal(mn(3)),()=>Ho(Mo(y.x),Mo(y.y))),Yo(y,y)}).setLayout({name:"mx_worley_distance_0",type:"float",inputs:[{name:"p",type:"vec2"},{name:"x",type:"int"},{name:"y",type:"int"},{name:"xoff",type:"int"},{name:"yoff",type:"int"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),un(([e,t,r,s,i,n,a,o,u])=>{const l=mn(u).toVar(),d=gn(o).toVar(),c=mn(a).toVar(),h=mn(n).toVar(),p=mn(i).toVar(),g=mn(s).toVar(),m=mn(r).toVar(),f=mn(t).toVar(),y=vn(e).toVar(),b=vn(Fv(vn(f.add(p),m.add(h),g.add(c)))).toVar();b.subAssign(.5),b.mulAssign(d),b.addAssign(.5);const x=vn(vn(gn(f),gn(m),gn(g)).add(b)).toVar(),T=vn(x.sub(y)).toVar();return cn(l.equal(mn(2)),()=>Mo(T.x).add(Mo(T.y)).add(Mo(T.z))),cn(l.equal(mn(3)),()=>Ho(Mo(T.x),Mo(T.y),Mo(T.z))),Yo(T,T)}).setLayout({name:"mx_worley_distance_1",type:"float",inputs:[{name:"p",type:"vec3"},{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xoff",type:"int"},{name:"yoff",type:"int"},{name:"zoff",type:"int"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),Iv=un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=bn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=bn(uv(n.x,a),uv(n.y,o)).toVar(),l=gn(1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{const r=gn(Uv(u,e,t,a,o,i,s)).toVar();l.assign(Wo(l,r))})}),cn(s.equal(mn(0)),()=>{l.assign(bo(l))}),l}).setLayout({name:"mx_worley_noise_float_0",type:"float",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),Ov=un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=bn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=bn(uv(n.x,a),uv(n.y,o)).toVar(),l=bn(1e6,1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{const r=gn(Uv(u,e,t,a,o,i,s)).toVar();cn(r.lessThan(l.x),()=>{l.y.assign(l.x),l.x.assign(r)}).ElseIf(r.lessThan(l.y),()=>{l.y.assign(r)})})}),cn(s.equal(mn(0)),()=>{l.assign(bo(l))}),l}).setLayout({name:"mx_worley_noise_vec2_0",type:"vec2",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),Vv=un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=bn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=bn(uv(n.x,a),uv(n.y,o)).toVar(),l=vn(1e6,1e6,1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{const r=gn(Uv(u,e,t,a,o,i,s)).toVar();cn(r.lessThan(l.x),()=>{l.z.assign(l.y),l.y.assign(l.x),l.x.assign(r)}).ElseIf(r.lessThan(l.y),()=>{l.z.assign(l.y),l.y.assign(r)}).ElseIf(r.lessThan(l.z),()=>{l.z.assign(r)})})}),cn(s.equal(mn(0)),()=>{l.assign(bo(l))}),l}).setLayout({name:"mx_worley_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),kv=mb([Iv,un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=vn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=mn().toVar(),l=vn(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=gn(1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{lp({start:-1,end:mn(1),name:"z",condition:"<="},({z:r})=>{const n=gn(Uv(l,e,t,r,a,o,u,i,s)).toVar();d.assign(Wo(d,n))})})}),cn(s.equal(mn(0)),()=>{d.assign(bo(d))}),d}).setLayout({name:"mx_worley_noise_float_1",type:"float",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),Gv=mb([Ov,un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=vn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=mn().toVar(),l=vn(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=bn(1e6,1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{lp({start:-1,end:mn(1),name:"z",condition:"<="},({z:r})=>{const n=gn(Uv(l,e,t,r,a,o,u,i,s)).toVar();cn(n.lessThan(d.x),()=>{d.y.assign(d.x),d.x.assign(n)}).ElseIf(n.lessThan(d.y),()=>{d.y.assign(n)})})})}),cn(s.equal(mn(0)),()=>{d.assign(bo(d))}),d}).setLayout({name:"mx_worley_noise_vec2_1",type:"vec2",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),zv=mb([Vv,un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=vn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=mn().toVar(),l=vn(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=vn(1e6,1e6,1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{lp({start:-1,end:mn(1),name:"z",condition:"<="},({z:r})=>{const n=gn(Uv(l,e,t,r,a,o,u,i,s)).toVar();cn(n.lessThan(d.x),()=>{d.z.assign(d.y),d.y.assign(d.x),d.x.assign(n)}).ElseIf(n.lessThan(d.y),()=>{d.z.assign(d.y),d.y.assign(n)}).ElseIf(n.lessThan(d.z),()=>{d.z.assign(n)})})})}),cn(s.equal(mn(0)),()=>{d.assign(bo(d))}),d}).setLayout({name:"mx_worley_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),$v=un(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=mn(e).toVar(),h=bn(t).toVar(),p=bn(r).toVar(),g=bn(s).toVar(),m=gn(i).toVar(),f=gn(n).toVar(),y=gn(a).toVar(),b=yn(o).toVar(),x=mn(u).toVar(),T=gn(l).toVar(),_=gn(d).toVar(),v=h.mul(p).add(g),N=gn(0).toVar();return cn(c.equal(mn(0)),()=>{N.assign(Cv(v))}),cn(c.equal(mn(1)),()=>{N.assign(Fv(v))}),cn(c.equal(mn(2)),()=>{N.assign(zv(v,m,mn(0)))}),cn(c.equal(mn(3)),()=>{N.assign(Pv(vn(v,0),x,T,_))}),N.assign(N.mul(y.sub(f)).add(f)),cn(b,()=>{N.assign(au(N,f,y))}),N}).setLayout({name:"mx_unifiednoise2d",type:"float",inputs:[{name:"noiseType",type:"int"},{name:"texcoord",type:"vec2"},{name:"freq",type:"vec2"},{name:"offset",type:"vec2"},{name:"jitter",type:"float"},{name:"outmin",type:"float"},{name:"outmax",type:"float"},{name:"clampoutput",type:"bool"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Wv=un(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=mn(e).toVar(),h=vn(t).toVar(),p=vn(r).toVar(),g=vn(s).toVar(),m=gn(i).toVar(),f=gn(n).toVar(),y=gn(a).toVar(),b=yn(o).toVar(),x=mn(u).toVar(),T=gn(l).toVar(),_=gn(d).toVar(),v=h.mul(p).add(g),N=gn(0).toVar();return cn(c.equal(mn(0)),()=>{N.assign(Cv(v))}),cn(c.equal(mn(1)),()=>{N.assign(Fv(v))}),cn(c.equal(mn(2)),()=>{N.assign(zv(v,m,mn(0)))}),cn(c.equal(mn(3)),()=>{N.assign(Pv(v,x,T,_))}),N.assign(N.mul(y.sub(f)).add(f)),cn(b,()=>{N.assign(au(N,f,y))}),N}).setLayout({name:"mx_unifiednoise3d",type:"float",inputs:[{name:"noiseType",type:"int"},{name:"position",type:"vec3"},{name:"freq",type:"vec3"},{name:"offset",type:"vec3"},{name:"jitter",type:"float"},{name:"outmin",type:"float"},{name:"outmax",type:"float"},{name:"clampoutput",type:"bool"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Hv=un(([e])=>{const t=e.y,r=e.z,s=vn().toVar();return cn(t.lessThan(1e-4),()=>{s.assign(vn(r,r,r))}).Else(()=>{let i=e.x;i=i.sub(To(i)).mul(6).toVar();const n=mn(Vo(i)),a=i.sub(gn(n)),o=r.mul(t.oneMinus()),u=r.mul(t.mul(a).oneMinus()),l=r.mul(t.mul(a.oneMinus()).oneMinus());cn(n.equal(mn(0)),()=>{s.assign(vn(r,l,o))}).ElseIf(n.equal(mn(1)),()=>{s.assign(vn(u,r,o))}).ElseIf(n.equal(mn(2)),()=>{s.assign(vn(o,r,l))}).ElseIf(n.equal(mn(3)),()=>{s.assign(vn(o,u,r))}).ElseIf(n.equal(mn(4)),()=>{s.assign(vn(l,o,r))}).Else(()=>{s.assign(vn(r,o,u))})}),s}).setLayout({name:"mx_hsvtorgb",type:"vec3",inputs:[{name:"hsv",type:"vec3"}]}),qv=un(([e])=>{const t=vn(e).toVar(),r=gn(t.x).toVar(),s=gn(t.y).toVar(),i=gn(t.z).toVar(),n=gn(Wo(r,Wo(s,i))).toVar(),a=gn(Ho(r,Ho(s,i))).toVar(),o=gn(a.sub(n)).toVar(),u=gn().toVar(),l=gn().toVar(),d=gn().toVar();return d.assign(a),cn(a.greaterThan(0),()=>{l.assign(o.div(a))}).Else(()=>{l.assign(0)}),cn(l.lessThanEqual(0),()=>{u.assign(0)}).Else(()=>{cn(r.greaterThanEqual(a),()=>{u.assign(s.sub(i).div(o))}).ElseIf(s.greaterThanEqual(a),()=>{u.assign(Ma(2,i.sub(r).div(o)))}).Else(()=>{u.assign(Ma(4,r.sub(s).div(o)))}),u.mulAssign(1/6),cn(u.lessThan(0),()=>{u.addAssign(1)})}),vn(u,l,d)}).setLayout({name:"mx_rgbtohsv",type:"vec3",inputs:[{name:"c",type:"vec3"}]}),jv=un(([e])=>{const t=vn(e).toVar(),r=Rn(Oa(t,vn(.04045))).toVar(),s=vn(t.div(12.92)).toVar(),i=vn(Zo(Ho(t.add(vn(.055)),vn(0)).div(1.055),vn(2.4))).toVar();return nu(s,i,r)}).setLayout({name:"mx_srgb_texture_to_lin_rec709",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Xv=(e,t)=>{e=gn(e),t=gn(t);const r=bn(t.dFdx(),t.dFdy()).length().mul(.7071067811865476);return lu(e.sub(r),e.add(r),t)},Kv=(e,t,r,s)=>nu(e,t,r[s].clamp()),Yv=(e,t,r,s,i)=>nu(e,t,Xv(r,s[i])),Qv=un(([e,t,r])=>{const s=vo(e).toVar(),i=Fa(gn(.5).mul(t.sub(r)),Dd).div(s).toVar(),n=Fa(gn(-.5).mul(t.sub(r)),Dd).div(s).toVar(),a=vn().toVar();a.x=s.x.greaterThan(gn(0)).select(i.x,n.x),a.y=s.y.greaterThan(gn(0)).select(i.y,n.y),a.z=s.z.greaterThan(gn(0)).select(i.z,n.z);const o=Wo(a.x,a.y,a.z).toVar();return Dd.add(s.mul(o)).toVar().sub(r)}),Zv=un(([e,t])=>{const r=e.x,s=e.y,i=e.z;let n=t.element(0).mul(.886227);return n=n.add(t.element(1).mul(1.023328).mul(s)),n=n.add(t.element(2).mul(1.023328).mul(i)),n=n.add(t.element(3).mul(1.023328).mul(r)),n=n.add(t.element(4).mul(.858086).mul(r).mul(s)),n=n.add(t.element(5).mul(.858086).mul(s).mul(i)),n=n.add(t.element(6).mul(i.mul(i).mul(.743125).sub(.247708))),n=n.add(t.element(7).mul(.858086).mul(r).mul(i)),n=n.add(t.element(8).mul(.429043).mul(La(r,r).sub(La(s,s)))),n});var Jv=Object.freeze({__proto__:null,BRDF_GGX:Ug,BRDF_Lambert:_g,BasicPointShadowFilter:X_,BasicShadowFilter:S_,Break:dp,Const:Cu,Continue:()=>gl("continue").toStack(),DFGLUT:Vg,D_GGX:Pg,Discard:ml,EPSILON:so,F_Schlick:Tg,Fn:un,HALF_PI:uo,INFINITY:io,If:cn,Loop:lp,NodeAccess:ti,NodeShaderStage:Zs,NodeType:ei,NodeUpdateType:Js,OnBeforeMaterialUpdate:e=>tx(ex.BEFORE_MATERIAL,e),OnBeforeObjectUpdate:e=>tx(ex.BEFORE_OBJECT,e),OnMaterialUpdate:e=>tx(ex.MATERIAL,e),OnObjectUpdate:e=>tx(ex.OBJECT,e),PCFShadowFilter:R_,PCFSoftShadowFilter:E_,PI:no,PI2:ao,PointShadowFilter:K_,Return:()=>gl("return").toStack(),Schlick_to_F0:zg,ScriptableNodeResources:rT,ShaderNode:Qi,Stack:hn,Switch:(...e)=>_i.Switch(...e),TBNViewMatrix:Wc,TWO_PI:oo,VSMShadowFilter:A_,V_GGX_SmithCorrelated:Fg,Var:wu,VarIntent:Mu,abs:Mo,acesFilmicToneMapping:zx,acos:wo,add:Ma,addMethodChaining:Ni,addNodeElement:function(e){d("TSL: AddNodeElement has been removed in favor of tree-shaking. Trying add",e)},agxToneMapping:qx,all:lo,alphaT:Yn,and:Ga,anisotropy:Qn,anisotropyB:Jn,anisotropyT:Zn,any:co,append:e=>(d("TSL: append() has been renamed to Stack()."),hn(e)),array:Na,arrayBuffer:e=>new xi(e,"ArrayBuffer"),asin:Ao,assign:Ra,atan:Co,atomicAdd:(e,t)=>AT(RT.ATOMIC_ADD,e,t),atomicAnd:(e,t)=>AT(RT.ATOMIC_AND,e,t),atomicFunc:AT,atomicLoad:e=>AT(RT.ATOMIC_LOAD,e,null),atomicMax:(e,t)=>AT(RT.ATOMIC_MAX,e,t),atomicMin:(e,t)=>AT(RT.ATOMIC_MIN,e,t),atomicOr:(e,t)=>AT(RT.ATOMIC_OR,e,t),atomicStore:(e,t)=>AT(RT.ATOMIC_STORE,e,t),atomicSub:(e,t)=>AT(RT.ATOMIC_SUB,e,t),atomicXor:(e,t)=>AT(RT.ATOMIC_XOR,e,t),attenuationColor:ha,attenuationDistance:ca,attribute:Sl,attributeArray:(e,t="float")=>{let r,s;!0===t.isStruct?(r=t.layout.getLength(),s=zs("float")):(r=$s(t),s=zs(t));const i=new sx(e,r,s);return Hh(i,t,e)},backgroundBlurriness:ux,backgroundIntensity:lx,backgroundRotation:dx,batch:ip,bentNormalView:qc,billboarding:_b,bitAnd:Ha,bitNot:qa,bitOr:ja,bitXor:Xa,bitangentGeometry:kc,bitangentLocal:Gc,bitangentView:zc,bitangentWorld:$c,bitcast:jy,blendBurn:Hp,blendColor:Kp,blendDodge:qp,blendOverlay:Xp,blendScreen:jp,blur:zm,bool:yn,buffer:Ul,bufferAttribute:Ju,builtin:Gl,builtinAOContext:Su,builtinShadowContext:Nu,bumpMap:eh,bvec2:_n,bvec3:Rn,bvec4:Cn,bypass:ll,cache:ol,call:Aa,cameraFar:rd,cameraIndex:ed,cameraNear:td,cameraNormalMatrix:od,cameraPosition:ud,cameraProjectionMatrix:sd,cameraProjectionMatrixInverse:id,cameraViewMatrix:nd,cameraViewport:ld,cameraWorldMatrix:ad,cbrt:su,cdl:Ax,ceil:_o,checker:sv,cineonToneMapping:kx,clamp:au,clearcoat:$n,clearcoatNormalView:Yd,clearcoatRoughness:Wn,clipSpace:Fd,code:Kx,color:pn,colorSpaceToWorking:Gu,colorToDirection:e=>Zi(e).mul(2).sub(1),compute:il,computeKernel:sl,computeSkinning:(e,t=null)=>{const r=new ap(e);return r.positionNode=Hh(new W(e.geometry.getAttribute("position").array,3),"vec3").setPBO(!0).toReadOnly().element(Xh).toVar(),r.skinIndexNode=Hh(new W(new Uint32Array(e.geometry.getAttribute("skinIndex").array),4),"uvec4").setPBO(!0).toReadOnly().element(Xh).toVar(),r.skinWeightNode=Hh(new W(e.geometry.getAttribute("skinWeight").array,4),"vec4").setPBO(!0).toReadOnly().element(Xh).toVar(),r.bindMatrixNode=_a(e.bindMatrix,"mat4"),r.bindMatrixInverseNode=_a(e.bindMatrixInverse,"mat4"),r.boneMatricesNode=Ul(e.skeleton.boneMatrices,"mat4",e.skeleton.bones.length),r.toPositionNode=t,Zi(r)},context:Tu,convert:Bn,convertColorSpace:(e,t,r)=>Zi(new Vu(Zi(e),t,r)),convertToTexture:(e,...t)=>e.isSampleNode||e.isTextureNode?e:e.isPassNode?e.getTextureNode():jb(e,...t),cos:Ro,countLeadingZeros:Zy,countOneBits:Jy,countTrailingZeros:Qy,cross:Qo,cubeTexture:gc,cubeTextureBase:pc,dFdx:Do,dFdy:Uo,dashSize:na,debug:xl,decrement:eo,decrementBefore:Za,defaultBuildStages:si,defaultShaderStages:ri,defined:Ki,degrees:po,deltaTime:yb,densityFogFactor:oT,depth:Up,depthPass:(e,t,r)=>new Ux(Ux.DEPTH,e,t,r),determinant:zo,difference:Ko,diffuseColor:On,diffuseContribution:Vn,directPointLight:tv,directionToColor:jc,directionToFaceDirection:zd,dispersion:pa,disposeShadowMaterial:C_,distance:Xo,div:Pa,dot:Yo,drawIndex:Zh,dynamicBufferAttribute:(e,t=null,r=0,s=0)=>Zu(e,t,r,s,x),element:Pn,emissive:kn,equal:Da,equirectUV:og,exp:go,exp2:mo,exponentialHeightFogFactor:uT,expression:gl,faceDirection:Gd,faceForward:du,faceforward:mu,float:gn,floatBitsToInt:e=>new qy(e,"int","float"),floatBitsToUint:Xy,floor:To,fog:lT,fract:No,frameGroup:ya,frameId:bb,frontFacing:kd,fwidth:ko,gain:(e,t)=>e.lessThan(.5)?tb(e.mul(2),t).div(2):Fa(1,tb(La(Fa(1,e),2),t).div(2)),gapSize:aa,getConstNodeType:Yi,getCurrentStack:dn,getDirection:Om,getDistanceAttenuation:ev,getGeometryRoughness:Cg,getNormalFromDepth:Yb,getParallaxCorrectNormal:Qv,getRoughness:Mg,getScreenPosition:Kb,getShIrradianceAt:Zv,getShadowMaterial:w_,getShadowRenderObjectFunction:L_,getTextureIndex:$y,getViewPosition:Xb,ggxConvolution:qm,globalId:bT,glsl:(e,t)=>Kx(e,t,"glsl"),glslFn:(e,t)=>Qx(e,t,"glsl"),grayscale:vx,greaterThan:Oa,greaterThanEqual:ka,hash:eb,highpModelNormalViewMatrix:Md,highpModelViewMatrix:Cd,hue:Rx,increment:Ja,incrementBefore:Qa,inspector:vl,instance:ep,instanceIndex:Xh,instancedArray:(e,t="float")=>{let r,s;!0===t.isStruct?(r=t.layout.getLength(),s=zs("float")):(r=$s(t),s=zs(t));const i=new rx(e,r,s);return Hh(i,t,e)},instancedBufferAttribute:el,instancedDynamicBufferAttribute:tl,instancedMesh:rp,int:mn,intBitsToFloat:e=>new qy(e,"float","int"),interleavedGradientNoise:Qb,inverse:$o,inverseSqrt:xo,inversesqrt:fu,invocationLocalIndex:Qh,invocationSubgroupIndex:Yh,ior:ua,iridescence:jn,iridescenceIOR:Xn,iridescenceThickness:Kn,isolate:al,ivec2:xn,ivec3:Nn,ivec4:An,js:(e,t)=>Kx(e,t,"js"),label:Ru,length:Lo,lengthSq:iu,lessThan:Ia,lessThanEqual:Va,lightPosition:i_,lightProjectionUV:s_,lightShadowMatrix:r_,lightTargetDirection:o_,lightTargetPosition:n_,lightViewPosition:a_,lightingContext:xp,lights:(e=[])=>(new c_).setLights(e),linearDepth:Ip,linearToneMapping:Ox,localId:xT,log:fo,log2:yo,logarithmicDepthToViewZ:(e,t,r)=>{const s=e.mul(fo(r.div(t)));return gn(Math.E).pow(s).mul(t).negate()},luminance:Ex,mat2:Mn,mat3:Fn,mat4:Ln,matcapUV:Ff,materialAO:Vh,materialAlphaTest:sh,materialAnisotropy:vh,materialAnisotropyVector:kh,materialAttenuationColor:Mh,materialAttenuationDistance:Ch,materialClearcoat:fh,materialClearcoatNormal:bh,materialClearcoatRoughness:yh,materialColor:ih,materialDispersion:Ih,materialEmissive:ah,materialEnvIntensity:nc,materialEnvRotation:ac,materialIOR:wh,materialIridescence:Nh,materialIridescenceIOR:Sh,materialIridescenceThickness:Rh,materialLightMap:Oh,materialLineDashOffset:Dh,materialLineDashSize:Lh,materialLineGapSize:Ph,materialLineScale:Fh,materialLineWidth:Bh,materialMetalness:gh,materialNormal:mh,materialOpacity:oh,materialPointSize:Uh,materialReference:Tc,materialReflectivity:hh,materialRefractionRatio:ic,materialRotation:xh,materialRoughness:ph,materialSheen:Th,materialSheenRoughness:_h,materialShininess:nh,materialSpecular:uh,materialSpecularColor:dh,materialSpecularIntensity:lh,materialSpecularStrength:ch,materialThickness:Ah,materialTransmission:Eh,max:Ho,maxMipLevel:Cl,mediumpModelViewMatrix:wd,metalness:zn,min:Wo,mix:nu,mixElement:hu,mod:Ba,modInt:to,modelDirection:xd,modelNormalMatrix:Rd,modelPosition:_d,modelRadius:Sd,modelScale:vd,modelViewMatrix:Ad,modelViewPosition:Nd,modelViewProjection:Gh,modelWorldMatrix:Td,modelWorldMatrixInverse:Ed,morphReference:mp,mrt:Hy,mul:La,mx_aastep:Xv,mx_add:(e,t=gn(0))=>Ma(e,t),mx_atan2:(e=gn(0),t=gn(1))=>Co(e,t),mx_cell_noise_float:(e=Rl())=>Mv(e.convert("vec2|vec3")),mx_contrast:(e,t=1,r=.5)=>gn(e).sub(r).mul(t).add(r),mx_divide:(e,t=gn(1))=>Pa(e,t),mx_fractal_noise_float:(e=Rl(),t=3,r=2,s=.5,i=1)=>Lv(e,mn(t),r,s).mul(i),mx_fractal_noise_vec2:(e=Rl(),t=3,r=2,s=.5,i=1)=>Bv(e,mn(t),r,s).mul(i),mx_fractal_noise_vec3:(e=Rl(),t=3,r=2,s=.5,i=1)=>Pv(e,mn(t),r,s).mul(i),mx_fractal_noise_vec4:(e=Rl(),t=3,r=2,s=.5,i=1)=>Dv(e,mn(t),r,s).mul(i),mx_frame:()=>bb,mx_heighttonormal:(e,t)=>(e=vn(e),t=gn(t),eh(e,t)),mx_hsvtorgb:Hv,mx_ifequal:(e,t,r,s)=>e.equal(t).mix(r,s),mx_ifgreater:(e,t,r,s)=>e.greaterThan(t).mix(r,s),mx_ifgreatereq:(e,t,r,s)=>e.greaterThanEqual(t).mix(r,s),mx_invert:(e,t=gn(1))=>Fa(t,e),mx_modulo:(e,t=gn(1))=>Ba(e,t),mx_multiply:(e,t=gn(1))=>La(e,t),mx_noise_float:(e=Rl(),t=1,r=0)=>wv(e.convert("vec2|vec3")).mul(t).add(r),mx_noise_vec3:(e=Rl(),t=1,r=0)=>Cv(e.convert("vec2|vec3")).mul(t).add(r),mx_noise_vec4:(e=Rl(),t=1,r=0)=>{e=e.convert("vec2|vec3");return En(Cv(e),wv(e.add(bn(19,73)))).mul(t).add(r)},mx_place2d:(e,t=bn(.5,.5),r=bn(1,1),s=gn(0),i=bn(0,0))=>{let n=e;if(t&&(n=n.sub(t)),r&&(n=n.mul(r)),s){const e=s.mul(Math.PI/180),t=e.cos(),r=e.sin();n=bn(n.x.mul(t).sub(n.y.mul(r)),n.x.mul(r).add(n.y.mul(t)))}return t&&(n=n.add(t)),i&&(n=n.add(i)),n},mx_power:(e,t=gn(1))=>Zo(e,t),mx_ramp4:(e,t,r,s,i=Rl())=>{const n=i.x.clamp(),a=i.y.clamp(),o=nu(e,t,n),u=nu(r,s,n);return nu(o,u,a)},mx_ramplr:(e,t,r=Rl())=>Kv(e,t,r,"x"),mx_ramptb:(e,t,r=Rl())=>Kv(e,t,r,"y"),mx_rgbtohsv:qv,mx_rotate2d:(e,t)=>{e=bn(e);const r=(t=gn(t)).mul(Math.PI/180);return Df(e,r)},mx_rotate3d:(e,t,r)=>{e=vn(e),t=gn(t),r=vn(r);const s=t.mul(Math.PI/180),i=r.normalize(),n=s.cos(),a=s.sin(),o=gn(1).sub(n);return e.mul(n).add(i.cross(e).mul(a)).add(i.mul(i.dot(e)).mul(o))},mx_safepower:(e,t=1)=>(e=gn(e)).abs().pow(t).mul(e.sign()),mx_separate:(e,t=null)=>{if("string"==typeof t){const r={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3},s=t.replace(/^out/,"").toLowerCase();if(void 0!==r[s])return e.element(r[s])}if("number"==typeof t)return e.element(t);if("string"==typeof t&&1===t.length){const r={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3};if(void 0!==r[t])return e.element(r[t])}return e},mx_splitlr:(e,t,r,s=Rl())=>Yv(e,t,r,s,"x"),mx_splittb:(e,t,r,s=Rl())=>Yv(e,t,r,s,"y"),mx_srgb_texture_to_lin_rec709:jv,mx_subtract:(e,t=gn(0))=>Fa(e,t),mx_timer:()=>fb,mx_transform_uv:(e=1,t=0,r=Rl())=>r.mul(e).add(t),mx_unifiednoise2d:(e,t=Rl(),r=bn(1,1),s=bn(0,0),i=1,n=0,a=1,o=!1,u=1,l=2,d=.5)=>$v(e,t.convert("vec2|vec3"),r,s,i,n,a,o,u,l,d),mx_unifiednoise3d:(e,t=Rl(),r=bn(1,1),s=bn(0,0),i=1,n=0,a=1,o=!1,u=1,l=2,d=.5)=>Wv(e,t.convert("vec2|vec3"),r,s,i,n,a,o,u,l,d),mx_worley_noise_float:(e=Rl(),t=1)=>kv(e.convert("vec2|vec3"),t,mn(1)),mx_worley_noise_vec2:(e=Rl(),t=1)=>Gv(e.convert("vec2|vec3"),t,mn(1)),mx_worley_noise_vec3:(e=Rl(),t=1)=>zv(e.convert("vec2|vec3"),t,mn(1)),negate:Po,neutralToneMapping:jx,nodeArray:tn,nodeImmutable:sn,nodeObject:Zi,nodeObjectIntent:Ji,nodeObjects:en,nodeProxy:rn,nodeProxyIntent:nn,normalFlat:Hd,normalGeometry:$d,normalLocal:Wd,normalMap:Yc,normalView:Xd,normalViewGeometry:qd,normalWorld:Kd,normalWorldGeometry:jd,normalize:vo,not:$a,notEqual:Ua,numWorkgroups:fT,objectDirection:hd,objectGroup:xa,objectPosition:gd,objectRadius:yd,objectScale:md,objectViewPosition:fd,objectWorldMatrix:pd,oneMinus:Bo,or:za,orthographicDepthToViewZ:(e,t,r)=>t.sub(r).mul(e).sub(t),oscSawtooth:(e=fb)=>e.fract(),oscSine:(e=fb)=>e.add(.75).mul(2*Math.PI).sin().mul(.5).add(.5),oscSquare:(e=fb)=>e.fract().round(),oscTriangle:(e=fb)=>e.add(.5).fract().mul(2).sub(1).abs(),output:ia,outputStruct:Vy,overloadingFn:mb,packHalf2x16:nb,packSnorm2x16:sb,packUnorm2x16:ib,parabola:tb,parallaxDirection:Hc,parallaxUV:(e,t)=>e.sub(Hc.mul(t)),parameter:(e,t)=>new Py(e,t),pass:(e,t,r)=>new Ux(Ux.COLOR,e,t,r),passTexture:(e,t)=>new Bx(e,t),pcurve:(e,t,r)=>Zo(Pa(Zo(e,t),Ma(Zo(e,t),Zo(Fa(1,e),r))),1/t),perspectiveDepthToViewZ:Pp,pmremTexture:ff,pointShadow:Z_,pointUV:nx,pointWidth:oa,positionGeometry:Ld,positionLocal:Pd,positionPrevious:Bd,positionView:Id,positionViewDirection:Od,positionWorld:Dd,positionWorldDirection:Ud,posterize:Cx,pow:Zo,pow2:Jo,pow3:eu,pow4:tu,premultiplyAlpha:Yp,property:Un,quadBroadcast:JT,quadSwapDiagonal:jT,quadSwapX:HT,quadSwapY:qT,radians:ho,rand:cu,range:pT,rangeFogFactor:aT,reciprocal:Oo,reference:yc,referenceBuffer:bc,reflect:jo,reflectVector:lc,reflectView:oc,reflector:e=>new Vb(e),refract:uu,refractVector:dc,refractView:uc,reinhardToneMapping:Vx,remap:cl,remapClamp:hl,renderGroup:ba,renderOutput:yl,rendererReference:Hu,replaceDefaultUV:function(e,t=null){return Tu(t,{getUV:e})},rotate:Df,rotateUV:xb,roughness:Gn,round:Io,rtt:jb,sRGBTransferEOTF:Uu,sRGBTransferOETF:Iu,sample:(e,t=null)=>new Jb(e,Zi(t)),sampler:e=>(!0===e.isNode?e:Pl(e)).convert("sampler"),samplerComparison:e=>(!0===e.isNode?e:Pl(e)).convert("samplerComparison"),saturate:ou,saturation:Nx,screenCoordinate:Xl,screenDPR:Hl,screenSize:jl,screenUV:ql,scriptable:iT,scriptableValue:Jx,select:bu,setCurrentStack:ln,setName:vu,shaderStages:ii,shadow:V_,shadowPositionWorld:p_,shapeCircle:iv,sharedUniformGroup:fa,sheen:Hn,sheenRoughness:qn,shiftLeft:Ka,shiftRight:Ya,shininess:sa,sign:Fo,sin:So,sinc:(e,t)=>So(no.mul(t.mul(e).sub(1))).div(no.mul(t.mul(e).sub(1))),skinning:op,smoothstep:lu,smoothstepElement:pu,specularColor:ea,specularColorBlended:ta,specularF90:ra,spherizeUV:Tb,split:(e,t)=>Zi(new gi(Zi(e),t)),spritesheetUV:Nb,sqrt:bo,stack:Dy,step:qo,stepElement:gu,storage:Hh,storageBarrier:()=>vT("storage").toStack(),storageTexture:hx,string:(e="")=>new xi(e,"string"),struct:(e,t=null)=>{const r=new Uy(e,t),s=(...t)=>{let s=null;if(t.length>0)if(t[0].isNode){s={};const r=Object.keys(e);for(let e=0;emx(e,t).level(r),texture3DLoad:(...e)=>mx(...e).setSampler(!1),textureBarrier:()=>vT("texture").toStack(),textureBicubic:um,textureBicubicLevel:om,textureCubeUV:Vm,textureLevel:(e,t,r)=>Pl(e,t).level(r),textureLoad:Bl,textureSize:Al,textureStore:(e,t,r)=>{let s;return!0===e.isStorageTextureNode?(s=e.clone(),s.uvNode=t,s.storeNode=r):s=hx(e,t,r),null!==r&&s.toStack(),s},thickness:da,time:fb,toneMapping:ju,toneMappingExposure:Xu,toonOutlinePass:(t,r,s=new e(0,0,0),i=.003,n=1)=>Zi(new Ix(t,r,Zi(s),Zi(i),Zi(n))),transformDirection:ru,transformNormal:Qd,transformNormalToView:Zd,transformedClearcoatNormalView:tc,transformedNormalView:Jd,transformedNormalWorld:ec,transmission:la,transpose:Go,triNoise3D:hb,triplanarTexture:(...e)=>Sb(...e),triplanarTextures:Sb,trunc:Vo,uint:fn,uintBitsToFloat:e=>new qy(e,"float","uint"),uniform:_a,uniformArray:Vl,uniformCubeTexture:(e=cc)=>pc(e),uniformFlow:_u,uniformGroup:ma,uniformTexture:(e=Ml)=>Pl(e),unpackHalf2x16:lb,unpackNormal:Xc,unpackSnorm2x16:ob,unpackUnorm2x16:ub,unpremultiplyAlpha:Qp,userData:(e,t,r)=>new fx(e,t,r),uv:Rl,uvec2:Tn,uvec3:Sn,uvec4:wn,varying:Bu,varyingProperty:In,vec2:bn,vec3:vn,vec4:En,vectorComponents:ni,velocity:_x,vertexColor:Wp,vertexIndex:jh,vertexStage:Du,vibrance:Sx,viewZToLogarithmicDepth:Bp,viewZToOrthographicDepth:Fp,viewZToPerspectiveDepth:Lp,viewport:Kl,viewportCoordinate:Ql,viewportDepthTexture:Cp,viewportLinearDepth:Op,viewportMipTexture:Sp,viewportOpaqueMipTexture:Ep,viewportResolution:Jl,viewportSafeUV:vb,viewportSharedTexture:Lx,viewportSize:Yl,viewportTexture:Np,viewportUV:Zl,vogelDiskSample:Zb,wgsl:(e,t)=>Kx(e,t,"wgsl"),wgslFn:(e,t)=>Qx(e,t,"wgsl"),workgroupArray:(e,t)=>new ST("Workgroup",e,t),workgroupBarrier:()=>vT("workgroup").toStack(),workgroupId:yT,workingToColorSpace:ku,xor:Wa});const eN=new Ly;class tN extends ry{constructor(e,t){super(),this.renderer=e,this.nodes=t}update(e,t,r){const s=this.renderer,i=this.nodes.getBackgroundNode(e)||e.background;let n=!1;if(null===i)s._clearColor.getRGB(eN),eN.a=s._clearColor.a;else if(!0===i.isColor)i.getRGB(eN),eN.a=1,n=!0;else if(!0===i.isNode){const u=this.get(e),l=i;eN.copy(s._clearColor);let d=u.backgroundMesh;if(void 0===d){const h=En(l).mul(lx).context({getUV:()=>dx.mul(jd),getTextureLevel:()=>ux}),p=sd.element(3).element(3).equal(1),g=Pa(1,sd.element(1).element(1)).mul(3),m=p.select(Pd.mul(g),Pd),f=Ad.mul(En(m,0));let y=sd.mul(En(f.xyz,1));y=y.setZ(y.w);const b=new Zp;function x(){i.removeEventListener("dispose",x),d.material.dispose(),d.geometry.dispose()}b.name="Background.material",b.side=M,b.depthTest=!1,b.depthWrite=!1,b.allowOverride=!1,b.fog=!1,b.lights=!1,b.vertexNode=y,b.colorNode=h,u.backgroundMeshNode=h,u.backgroundMesh=d=new ne(new it(1,32,32),b),d.frustumCulled=!1,d.name="Background.mesh",i.addEventListener("dispose",x)}const c=l.getCacheKey();u.backgroundCacheKey!==c&&(u.backgroundMeshNode.node=En(l).mul(lx),u.backgroundMeshNode.needsUpdate=!0,d.material.needsUpdate=!0,u.backgroundCacheKey=c),t.unshift(d,d.geometry,d.material,0,0,null,null)}else o("Renderer: Unsupported background configuration.",i);const a=s.xr.getEnvironmentBlendMode();if("additive"===a?eN.set(0,0,0,1):"alpha-blend"===a&&eN.set(0,0,0,0),!0===s.autoClear||!0===n){const T=r.clearColorValue;T.r=eN.r,T.g=eN.g,T.b=eN.b,T.a=eN.a,!0!==s.backend.isWebGLBackend&&!0!==s.alpha||(T.r*=T.a,T.g*=T.a,T.b*=T.a),r.depthClearValue=s._clearDepth,r.stencilClearValue=s._clearStencil,r.clearColor=!0===s.autoClearColor,r.clearDepth=!0===s.autoClearDepth,r.clearStencil=!0===s.autoClearStencil}else r.clearColor=!1,r.clearDepth=!1,r.clearStencil=!1}}let rN=0;class sN{constructor(e="",t=[],r=0,s=[]){this.name=e,this.bindings=t,this.index=r,this.bindingsReference=s,this.id=rN++}}class iN{constructor(e,t,r,s,i,n,a,o,u,l=[]){this.vertexShader=e,this.fragmentShader=t,this.computeShader=r,this.transforms=l,this.nodeAttributes=s,this.bindings=i,this.updateNodes=n,this.updateBeforeNodes=a,this.updateAfterNodes=o,this.observer=u,this.usedTimes=0}createBindings(){const e=[];for(const t of this.bindings){if(!0!==t.bindings[0].groupNode.shared){const r=new sN(t.name,[],t.index,t.bindingsReference);e.push(r);for(const e of t.bindings)r.bindings.push(e.clone())}else e.push(t)}return e}}class nN{constructor(e,t,r=null){this.isNodeAttribute=!0,this.name=e,this.type=t,this.node=r}}class aN{constructor(e,t,r){this.isNodeUniform=!0,this.name=e,this.type=t,this.node=r}get value(){return this.node.value}set value(e){this.node.value=e}get id(){return this.node.id}get groupNode(){return this.node.groupNode}}class oN{constructor(e,t,r=!1,s=null){this.isNodeVar=!0,this.name=e,this.type=t,this.readOnly=r,this.count=s}}class uN extends oN{constructor(e,t,r=null,s=null){super(e,t),this.needsInterpolation=!1,this.isNodeVarying=!0,this.interpolationType=r,this.interpolationSampling=s}}class lN{constructor(e,t,r=""){this.name=e,this.type=t,this.code=r,Object.defineProperty(this,"isNodeCode",{value:!0})}}let dN=0;class cN{constructor(e=null){this.id=dN++,this.nodesData=new WeakMap,this.parent=e}getData(e){let t=this.nodesData.get(e);return void 0===t&&null!==this.parent&&(t=this.parent.getData(e)),t}setData(e,t){this.nodesData.set(e,t)}}class hN{constructor(e,t){this.name=e,this.members=t,this.output=!1}}class pN{constructor(e,t){this.name=e,this.value=t,this.boundary=0,this.itemSize=0,this.offset=0,this.index=-1}setValue(e){this.value=e}getValue(){return this.value}}class gN extends pN{constructor(e,t=0){super(e,t),this.isNumberUniform=!0,this.boundary=4,this.itemSize=1}}class mN extends pN{constructor(e,r=new t){super(e,r),this.isVector2Uniform=!0,this.boundary=8,this.itemSize=2}}class fN extends pN{constructor(e,t=new r){super(e,t),this.isVector3Uniform=!0,this.boundary=16,this.itemSize=3}}class yN extends pN{constructor(e,t=new s){super(e,t),this.isVector4Uniform=!0,this.boundary=16,this.itemSize=4}}class bN extends pN{constructor(t,r=new e){super(t,r),this.isColorUniform=!0,this.boundary=16,this.itemSize=3}}class xN extends pN{constructor(e,t=new i){super(e,t),this.isMatrix2Uniform=!0,this.boundary=8,this.itemSize=4}}class TN extends pN{constructor(e,t=new n){super(e,t),this.isMatrix3Uniform=!0,this.boundary=48,this.itemSize=12}}class _N extends pN{constructor(e,t=new a){super(e,t),this.isMatrix4Uniform=!0,this.boundary=64,this.itemSize=16}}class vN extends gN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class NN extends mN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class SN extends fN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class RN extends yN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class EN extends bN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class AN extends xN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class wN extends TN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class CN extends _N{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}let MN=0;const FN=new WeakMap,LN=new WeakMap,PN=new Map([[Int8Array,"int"],[Int16Array,"int"],[Int32Array,"int"],[Uint8Array,"uint"],[Uint16Array,"uint"],[Uint32Array,"uint"],[Float32Array,"float"]]),BN=e=>/e/g.test(e)?String(e).replace(/\+/g,""):(e=Number(e))+(e%1?"":".0");class DN{constructor(e,t,r){this.object=e,this.material=e&&e.material||null,this.geometry=e&&e.geometry||null,this.renderer=t,this.parser=r,this.scene=null,this.camera=null,this.nodes=[],this.sequentialNodes=[],this.updateNodes=[],this.updateBeforeNodes=[],this.updateAfterNodes=[],this.hashNodes={},this.observer=null,this.lightsNode=null,this.environmentNode=null,this.fogNode=null,this.clippingContext=null,this.vertexShader=null,this.fragmentShader=null,this.computeShader=null,this.flowNodes={vertex:[],fragment:[],compute:[]},this.flowCode={vertex:"",fragment:"",compute:""},this.uniforms={vertex:[],fragment:[],compute:[],index:0},this.structs={vertex:[],fragment:[],compute:[],index:0},this.types={vertex:[],fragment:[],compute:[],index:0},this.bindings={vertex:{},fragment:{},compute:{}},this.bindingsIndexes={},this.bindGroups=null,this.attributes=[],this.bufferAttributes=[],this.varyings=[],this.codes={},this.vars={},this.declarations={},this.flow={code:""},this.chaining=[],this.stack=Dy(),this.stacks=[],this.tab="\t",this.currentFunctionNode=null,this.context={material:this.material},this.cache=new cN,this.globalCache=this.cache,this.flowsData=new WeakMap,this.shaderStage=null,this.buildStage=null,this.subBuildLayers=[],this.activeStacks=[],this.subBuildFn=null,this.fnCall=null,Object.defineProperty(this,"id",{value:MN++})}isFlatShading(){return!0===this.material.flatShading||!1===this.geometry.hasAttribute("normal")}isOpaque(){const e=this.material;return!1===e.transparent&&e.blending===ze&&!1===e.alphaToCoverage}getBindGroupsCache(){let e=LN.get(this.renderer);return void 0===e&&(e=new Qf,LN.set(this.renderer,e)),e}createRenderTarget(e,t,r){return new Ne(e,t,r)}createCubeRenderTarget(e,t){return new ug(e,t)}includes(e){return this.nodes.includes(e)}getOutputStructName(){}_getBindGroup(e,t){const r=this.getBindGroupsCache(),s=[];let i,n=!0;for(const e of t)s.push(e),n=n&&!0!==e.groupNode.shared;return n?(i=r.get(s),void 0===i&&(i=new sN(e,s,this.bindingsIndexes[e].group,s),r.set(s,i))):i=new sN(e,s,this.bindingsIndexes[e].group,s),i}getBindGroupArray(e,t){const r=this.bindings[t];let s=r[e];return void 0===s&&(void 0===this.bindingsIndexes[e]&&(this.bindingsIndexes[e]={binding:0,group:Object.keys(this.bindingsIndexes).length}),r[e]=s=[]),s}getBindings(){let e=this.bindGroups;if(null===e){const t={},r=this.bindings;for(const e of ii)for(const s in r[e]){const i=r[e][s],n=t[s]||(t[s]=[]);for(const e of i)!1===n.includes(e)&&n.push(e)}e=[];for(const r in t){const s=t[r],i=this._getBindGroup(r,s);e.push(i)}this.bindGroups=e}return e}sortBindingGroups(){const e=this.getBindings();e.sort((e,t)=>e.bindings[0].groupNode.order-t.bindings[0].groupNode.order);for(let t=0;t=0?`${Math.round(n)}u`:"0u";if("bool"===i)return n?"true":"false";if("color"===i)return`${this.getType("vec3")}( ${BN(n.r)}, ${BN(n.g)}, ${BN(n.b)} )`;const a=this.getTypeLength(i),o=this.getComponentType(i),u=e=>this.generateConst(o,e);if(2===a)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)} )`;if(3===a)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)}, ${u(n.z)} )`;if(4===a&&"mat2"!==i)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)}, ${u(n.z)}, ${u(n.w)} )`;if(a>=4&&n&&(n.isMatrix2||n.isMatrix3||n.isMatrix4))return`${this.getType(i)}( ${n.elements.map(u).join(", ")} )`;if(a>4)return`${this.getType(i)}()`;throw new Error(`NodeBuilder: Type '${i}' not found in generate constant attempt.`)}getType(e){return"color"===e?"vec3":e}hasGeometryAttribute(e){return this.geometry&&void 0!==this.geometry.getAttribute(e)}getAttribute(e,t){const r=this.attributes;for(const t of r)if(t.name===e)return t;const s=new nN(e,t);return this.registerDeclaration(s),r.push(s),s}getPropertyName(e){return e.name}isVector(e){return/vec\d/.test(e)}isMatrix(e){return/mat\d/.test(e)}isReference(e){return"void"===e||"property"===e||"sampler"===e||"samplerComparison"===e||"texture"===e||"cubeTexture"===e||"storageTexture"===e||"depthTexture"===e||"texture3D"===e}needsToWorkingColorSpace(){return!1}getComponentTypeFromTexture(e){const t=e.type;if(e.isDataTexture){if(t===R)return"int";if(t===S)return"uint"}return"float"}getElementType(e){return"mat2"===e?"vec2":"mat3"===e?"vec3":"mat4"===e?"vec4":this.getComponentType(e)}getComponentType(e){if("float"===(e=this.getVectorType(e))||"bool"===e||"int"===e||"uint"===e)return e;const t=/(b|i|u|)(vec|mat)([2-4])/.exec(e);return null===t?null:"b"===t[1]?"bool":"i"===t[1]?"int":"u"===t[1]?"uint":"float"}getVectorType(e){return"color"===e?"vec3":"texture"===e||"cubeTexture"===e||"storageTexture"===e||"texture3D"===e?"vec4":e}getTypeFromLength(e,t="float"){if(1===e)return t;let r=Gs(e);const s="float"===t?"":t[0];return!0===/mat2/.test(t)&&(r=r.replace("vec","mat")),s+r}getTypeFromArray(e){return PN.get(e.constructor)}isInteger(e){return/int|uint|(i|u)vec/.test(e)}getTypeFromAttribute(e){let t=e;e.isInterleavedBufferAttribute&&(t=e.data);const r=t.array,s=e.itemSize,i=e.normalized;let n;return e instanceof ot||!0===i||(n=this.getTypeFromArray(r)),this.getTypeFromLength(s,n)}getTypeLength(e){const t=this.getVectorType(e),r=/vec([2-4])/.exec(t);return null!==r?Number(r[1]):"float"===t||"bool"===t||"int"===t||"uint"===t?1:!0===/mat2/.test(e)?4:!0===/mat3/.test(e)?9:!0===/mat4/.test(e)?16:0}getVectorFromMatrix(e){return e.replace("mat","vec")}changeComponentType(e,t){return this.getTypeFromLength(this.getTypeLength(e),t)}getIntegerType(e){const t=this.getComponentType(e);return"int"===t||"uint"===t?e:this.changeComponentType(e,"int")}setActiveStack(e){this.activeStacks.push(e)}removeActiveStack(e){if(this.activeStacks[this.activeStacks.length-1]!==e)throw new Error("NodeBuilder: Invalid active stack removal.");this.activeStacks.pop()}getActiveStack(){return this.activeStacks[this.activeStacks.length-1]}getBaseStack(){return this.activeStacks[0]}addStack(){this.stack=Dy(this.stack);const e=dn();return this.stacks.push(e),ln(this.stack),this.stack}removeStack(){const e=this.stack;for(const t of e.nodes){this.getDataFromNode(t).stack=e}return this.stack=e.parent,ln(this.stacks.pop()),e}getDataFromNode(e,t=this.shaderStage,r=null){let s=(r=null===r?e.isGlobal(this)?this.globalCache:this.cache:r).getData(e);void 0===s&&(s={},r.setData(e,s)),void 0===s[t]&&(s[t]={});let i=s[t];const n=s.any?s.any.subBuilds:null,a=this.getClosestSubBuild(n);return a&&(void 0===i.subBuildsCache&&(i.subBuildsCache={}),i=i.subBuildsCache[a]||(i.subBuildsCache[a]={}),i.subBuilds=n),i}getNodeProperties(e,t="any"){const r=this.getDataFromNode(e,t);return r.properties||(r.properties={outputNode:null})}getBufferAttributeFromNode(e,t){const r=this.getDataFromNode(e,"vertex");let s=r.bufferAttribute;if(void 0===s){const i=this.uniforms.index++;s=new nN("nodeAttribute"+i,t,e),this.bufferAttributes.push(s),r.bufferAttribute=s}return s}getStructTypeNode(e,t=this.shaderStage){return this.types[t][e]||null}getStructTypeFromNode(e,t,r=null,s=this.shaderStage){const i=this.getDataFromNode(e,s,this.globalCache);let n=i.structType;if(void 0===n){const a=this.structs.index++;null===r&&(r="StructType"+a),n=new hN(r,t),this.structs[s].push(n),this.types[s][r]=e,i.structType=n}return n}getOutputStructTypeFromNode(e,t){const r=this.getStructTypeFromNode(e,t,"OutputType","fragment");return r.output=!0,r}getUniformFromNode(e,t,r=this.shaderStage,s=null){const i=this.getDataFromNode(e,r,this.globalCache);let n=i.uniform;if(void 0===n){const a=this.uniforms.index++;n=new aN(s||"nodeUniform"+a,t,e),this.uniforms[r].push(n),this.registerDeclaration(n),i.uniform=n}return n}getVarFromNode(e,t=null,r=e.getNodeType(this),s=this.shaderStage,i=!1){const n=this.getDataFromNode(e,s),a=this.getSubBuildProperty("variable",n.subBuilds);let o=n[a];if(void 0===o){const u=i?"_const":"_var",l=this.vars[s]||(this.vars[s]=[]),d=this.vars[u]||(this.vars[u]=0);null===t&&(t=(i?"nodeConst":"nodeVar")+d,this.vars[u]++),"variable"!==a&&(t=this.getSubBuildProperty(t,n.subBuilds));const c=e.getArrayCount(this);o=new oN(t,r,i,c),i||l.push(o),this.registerDeclaration(o),n[a]=o}return o}isDeterministic(e){if(e.isMathNode)return this.isDeterministic(e.aNode)&&(!e.bNode||this.isDeterministic(e.bNode))&&(!e.cNode||this.isDeterministic(e.cNode));if(e.isOperatorNode)return this.isDeterministic(e.aNode)&&(!e.bNode||this.isDeterministic(e.bNode));if(e.isArrayNode){if(null!==e.values)for(const t of e.values)if(!this.isDeterministic(t))return!1;return!0}return!!e.isConstNode}getVaryingFromNode(e,t=null,r=e.getNodeType(this),s=null,i=null){const n=this.getDataFromNode(e,"any"),a=this.getSubBuildProperty("varying",n.subBuilds);let o=n[a];if(void 0===o){const e=this.varyings,u=e.length;null===t&&(t="nodeVarying"+u),"varying"!==a&&(t=this.getSubBuildProperty(t,n.subBuilds)),o=new uN(t,r,s,i),e.push(o),this.registerDeclaration(o),n[a]=o}return o}registerDeclaration(e){const t=this.shaderStage,r=this.declarations[t]||(this.declarations[t]={}),s=this.getPropertyName(e);let i=1,n=s;for(;void 0!==r[n];)n=s+"_"+i++;i>1&&(e.name=n,d(`TSL: Declaration name '${s}' of '${e.type}' already in use. Renamed to '${n}'.`)),r[n]=e}getCodeFromNode(e,t,r=this.shaderStage){const s=this.getDataFromNode(e);let i=s.code;if(void 0===i){const e=this.codes[r]||(this.codes[r]=[]),n=e.length;i=new lN("nodeCode"+n,t),e.push(i),s.code=i}return i}addFlowCodeHierarchy(e,t){const{flowCodes:r,flowCodeBlock:s}=this.getDataFromNode(e);let i=!0,n=t;for(;n;){if(!0===s.get(n)){i=!1;break}n=this.getDataFromNode(n).parentNodeBlock}if(i)for(const e of r)this.addLineFlowCode(e)}addLineFlowCodeBlock(e,t,r){const s=this.getDataFromNode(e),i=s.flowCodes||(s.flowCodes=[]),n=s.flowCodeBlock||(s.flowCodeBlock=new WeakMap);i.push(t),n.set(r,!0)}addLineFlowCode(e,t=null){return""===e||(null!==t&&this.context.nodeBlock&&this.addLineFlowCodeBlock(t,e,this.context.nodeBlock),e=this.tab+e,/;\s*$/.test(e)||(e+=";\n"),this.flow.code+=e),this}addFlowCode(e){return this.flow.code+=e,this}addFlowTab(){return this.tab+="\t",this}removeFlowTab(){return this.tab=this.tab.slice(0,-1),this}getFlowData(e){return this.flowsData.get(e)}flowNode(e){const t=e.getNodeType(this),r=this.flowChildNode(e,t);return this.flowsData.set(e,r),r}addInclude(e){null!==this.currentFunctionNode&&this.currentFunctionNode.includes.push(e)}buildFunctionNode(e){const t=new Yx,r=this.currentFunctionNode;return this.currentFunctionNode=t,t.code=this.buildFunctionCode(e),this.currentFunctionNode=r,t}flowShaderNode(e){const t=e.layout,r={[Symbol.iterator](){let e=0;const t=Object.values(this);return{next:()=>({value:t[e],done:e++>=t.length})}}};for(const e of t.inputs)r[e.name]=new Py(e.type,e.name);e.layout=null;const s=e.call(r),i=this.flowStagesNode(s,t.type);return e.layout=t,i}flowBuildStage(e,t,r=null){const s=this.getBuildStage();this.setBuildStage(t);const i=e.build(this,r);return this.setBuildStage(s),i}flowStagesNode(e,t=null){const r=this.flow,s=this.vars,i=this.declarations,n=this.cache,a=this.buildStage,o=this.stack,u={code:""};this.flow=u,this.vars={},this.declarations={},this.cache=new cN,this.stack=Dy();for(const r of si)this.setBuildStage(r),u.result=e.build(this,t);return u.vars=this.getVars(this.shaderStage),this.flow=r,this.vars=s,this.declarations=i,this.cache=n,this.stack=o,this.setBuildStage(a),u}getFunctionOperator(){return null}buildFunctionCode(){d("Abstract function.")}flowChildNode(e,t=null){const r=this.flow,s={code:""};return this.flow=s,s.result=e.build(this,t),this.flow=r,s}flowNodeFromShaderStage(e,t,r=null,s=null){const i=this.tab,n=this.cache,a=this.shaderStage,o=this.context;this.setShaderStage(e);const u={...this.context};delete u.nodeBlock,this.cache=this.globalCache,this.tab="\t",this.context=u;let l=null;if("generate"===this.buildStage){const i=this.flowChildNode(t,r);null!==s&&(i.code+=`${this.tab+s} = ${i.result};\n`),this.flowCode[e]=this.flowCode[e]+i.code,l=i}else l=t.build(this);return this.setShaderStage(a),this.cache=n,this.tab=i,this.context=o,l}getAttributesArray(){return this.attributes.concat(this.bufferAttributes)}getAttributes(){d("Abstract function.")}getVaryings(){d("Abstract function.")}getVar(e,t,r=null){return`${null!==r?this.generateArrayDeclaration(e,r):this.getType(e)} ${t}`}getVars(e){let t="";const r=this.vars[e];if(void 0!==r)for(const e of r)t+=`${this.getVar(e.type,e.name)}; `;return t}getUniforms(){d("Abstract function.")}getCodes(e){const t=this.codes[e];let r="";if(void 0!==t)for(const e of t)r+=e.code+"\n";return r}getHash(){return this.vertexShader+this.fragmentShader+this.computeShader}setShaderStage(e){this.shaderStage=e}getShaderStage(){return this.shaderStage}setBuildStage(e){this.buildStage=e}getBuildStage(){return this.buildStage}buildCode(){d("Abstract function.")}get subBuild(){return this.subBuildLayers[this.subBuildLayers.length-1]||null}addSubBuild(e){this.subBuildLayers.push(e)}removeSubBuild(){return this.subBuildLayers.pop()}getClosestSubBuild(e){let t;if(t=e&&e.isNode?e.isShaderCallNodeInternal?e.shaderNode.subBuilds:e.isStackNode?[e.subBuild]:this.getDataFromNode(e,"any").subBuilds:e instanceof Set?[...e]:e,!t)return null;const r=this.subBuildLayers;for(let e=t.length-1;e>=0;e--){const s=t[e];if(r.includes(s))return s}return null}getSubBuildOutput(e){return this.getSubBuildProperty("outputNode",e)}getSubBuildProperty(e="",t=null){let r,s;return r=null!==t?this.getClosestSubBuild(t):this.subBuildFn,s=r?e?r+"_"+e:r:e,s}build(){const{object:e,material:t,renderer:r}=this;if(null!==t){let e=r.library.fromMaterial(t);null===e&&(o(`NodeMaterial: Material "${t.type}" is not compatible.`),e=new Zp),e.build(this)}else this.addFlow("compute",e);for(const e of si){this.setBuildStage(e),this.context.position&&this.context.position.isNode&&this.flowNodeFromShaderStage("vertex",this.context.position);for(const t of ii){this.setShaderStage(t);const r=this.flowNodes[t];for(const t of r)"generate"===e?this.flowNode(t):t.build(this)}}return this.setBuildStage(null),this.setShaderStage(null),this.buildCode(),this.buildUpdateNodes(),this}getSharedDataFromNode(e){let t=FN.get(e);return void 0===t&&(t={}),t}getNodeUniform(e,t){const r=this.getSharedDataFromNode(e);let s=r.cache;if(void 0===s){if("float"===t||"int"===t||"uint"===t)s=new vN(e);else if("vec2"===t||"ivec2"===t||"uvec2"===t)s=new NN(e);else if("vec3"===t||"ivec3"===t||"uvec3"===t)s=new SN(e);else if("vec4"===t||"ivec4"===t||"uvec4"===t)s=new RN(e);else if("color"===t)s=new EN(e);else if("mat2"===t)s=new AN(e);else if("mat3"===t)s=new wN(e);else{if("mat4"!==t)throw new Error(`Uniform "${t}" not implemented.`);s=new CN(e)}r.cache=s}return s}format(e,t,r){if((t=this.getVectorType(t))===(r=this.getVectorType(r))||null===r||this.isReference(r))return e;const s=this.getTypeLength(t),i=this.getTypeLength(r);return 16===s&&9===i?`${this.getType(r)}( ${e}[ 0 ].xyz, ${e}[ 1 ].xyz, ${e}[ 2 ].xyz )`:9===s&&4===i?`${this.getType(r)}( ${e}[ 0 ].xy, ${e}[ 1 ].xy )`:s>4||i>4||0===i?e:s===i?`${this.getType(r)}( ${e} )`:s>i?(e="bool"===r?`all( ${e} )`:`${e}.${"xyz".slice(0,i)}`,this.format(e,this.getTypeFromLength(i,this.getComponentType(t)),r)):4===i&&s>1?`${this.getType(r)}( ${this.format(e,t,"vec3")}, 1.0 )`:2===s?`${this.getType(r)}( ${this.format(e,t,"vec2")}, 0.0 )`:(1===s&&i>1&&t!==this.getComponentType(r)&&(e=`${this.getType(this.getComponentType(r))}( ${e} )`),`${this.getType(r)}( ${e} )`)}getSignature(){return`// Three.js r${ut} - Node System\n`}needsPreviousData(){const e=this.renderer.getMRT();return e&&e.has("velocity")||!0===Xs(this.object).useVelocity}}class UN{constructor(){this.time=0,this.deltaTime=0,this.frameId=0,this.renderId=0,this.updateMap=new WeakMap,this.updateBeforeMap=new WeakMap,this.updateAfterMap=new WeakMap,this.renderer=null,this.material=null,this.camera=null,this.object=null,this.scene=null}_getMaps(e,t){let r=e.get(t);return void 0===r&&(r={renderId:0,frameId:0},e.set(t,r)),r}updateBeforeNode(e){const t=e.getUpdateBeforeType(),r=e.updateReference(this);if(t===Js.FRAME){const t=this._getMaps(this.updateBeforeMap,r);if(t.frameId!==this.frameId){const r=t.frameId;t.frameId=this.frameId,!1===e.updateBefore(this)&&(t.frameId=r)}}else if(t===Js.RENDER){const t=this._getMaps(this.updateBeforeMap,r);if(t.renderId!==this.renderId){const r=t.renderId;t.renderId=this.renderId,!1===e.updateBefore(this)&&(t.renderId=r)}}else t===Js.OBJECT&&e.updateBefore(this)}updateAfterNode(e){const t=e.getUpdateAfterType(),r=e.updateReference(this);if(t===Js.FRAME){const t=this._getMaps(this.updateAfterMap,r);t.frameId!==this.frameId&&!1!==e.updateAfter(this)&&(t.frameId=this.frameId)}else if(t===Js.RENDER){const t=this._getMaps(this.updateAfterMap,r);t.renderId!==this.renderId&&!1!==e.updateAfter(this)&&(t.renderId=this.renderId)}else t===Js.OBJECT&&e.updateAfter(this)}updateNode(e){const t=e.getUpdateType(),r=e.updateReference(this);if(t===Js.FRAME){const t=this._getMaps(this.updateMap,r);t.frameId!==this.frameId&&!1!==e.update(this)&&(t.frameId=this.frameId)}else if(t===Js.RENDER){const t=this._getMaps(this.updateMap,r);t.renderId!==this.renderId&&!1!==e.update(this)&&(t.renderId=this.renderId)}else t===Js.OBJECT&&e.update(this)}update(){this.frameId++,void 0===this.lastTime&&(this.lastTime=performance.now()),this.deltaTime=(performance.now()-this.lastTime)/1e3,this.lastTime=performance.now(),this.time+=this.deltaTime}}class IN{constructor(e,t,r=null,s="",i=!1){this.type=e,this.name=t,this.count=r,this.qualifier=s,this.isConst=i}}IN.isNodeFunctionInput=!0;class ON extends J_{static get type(){return"AmbientLightNode"}constructor(e=null){super(e)}setup({context:e}){e.irradiance.addAssign(this.colorNode)}}class VN extends J_{static get type(){return"DirectionalLightNode"}constructor(e=null){super(e)}setupDirect(){const e=this.colorNode;return{lightDirection:o_(this.light),lightColor:e}}}class kN extends J_{static get type(){return"HemisphereLightNode"}constructor(t=null){super(t),this.lightPositionNode=i_(t),this.lightDirectionNode=this.lightPositionNode.normalize(),this.groundColorNode=_a(new e).setGroup(ba)}update(e){const{light:t}=this;super.update(e),this.lightPositionNode.object3d=t,this.groundColorNode.value.copy(t.groundColor).multiplyScalar(t.intensity)}setup(e){const{colorNode:t,groundColorNode:r,lightDirectionNode:s}=this,i=Kd.dot(s).mul(.5).add(.5),n=nu(r,t,i);e.context.irradiance.addAssign(n)}}class GN extends J_{static get type(){return"SpotLightNode"}constructor(e=null){super(e),this.coneCosNode=_a(0).setGroup(ba),this.penumbraCosNode=_a(0).setGroup(ba),this.cutoffDistanceNode=_a(0).setGroup(ba),this.decayExponentNode=_a(0).setGroup(ba),this.colorNode=_a(this.color).setGroup(ba)}update(e){super.update(e);const{light:t}=this;this.coneCosNode.value=Math.cos(t.angle),this.penumbraCosNode.value=Math.cos(t.angle*(1-t.penumbra)),this.cutoffDistanceNode.value=t.distance,this.decayExponentNode.value=t.decay}getSpotAttenuation(e,t){const{coneCosNode:r,penumbraCosNode:s}=this;return lu(r,s,t)}getLightCoord(e){const t=e.getNodeProperties(this);let r=t.projectionUV;return void 0===r&&(r=s_(this.light,e.context.positionWorld),t.projectionUV=r),r}setupDirect(e){const{colorNode:t,cutoffDistanceNode:r,decayExponentNode:s,light:i}=this,n=this.getLightVector(e),a=n.normalize(),o=a.dot(o_(i)),u=this.getSpotAttenuation(e,o),l=n.length(),d=ev({lightDistance:l,cutoffDistance:r,decayExponent:s});let c,h,p=t.mul(u).mul(d);if(i.colorNode?(h=this.getLightCoord(e),c=i.colorNode(h)):i.map&&(h=this.getLightCoord(e),c=Pl(i.map,h.xy).onRenderUpdate(()=>i.map)),c){p=h.mul(2).sub(1).abs().lessThan(1).all().select(p.mul(c),p)}return{lightColor:p,lightDirection:a}}}class zN extends GN{static get type(){return"IESSpotLightNode"}getSpotAttenuation(e,t){const r=this.light.iesMap;let s=null;if(r&&!0===r.isTexture){const e=t.acos().mul(1/Math.PI);s=Pl(r,bn(e,0),0).r}else s=super.getSpotAttenuation(t);return s}}class $N extends J_{static get type(){return"LightProbeNode"}constructor(e=null){super(e);const t=[];for(let e=0;e<9;e++)t.push(new r);this.lightProbe=Vl(t)}update(e){const{light:t}=this;super.update(e);for(let e=0;e<9;e++)this.lightProbe.array[e].copy(t.sh.coefficients[e]).multiplyScalar(t.intensity)}setup(e){const t=Zv(Kd,this.lightProbe);e.context.irradiance.addAssign(t)}}const WN=un(([e,t])=>{const r=e.abs().sub(t);return Lo(Ho(r,0)).add(Wo(Ho(r.x,r.y),0))});class HN extends GN{static get type(){return"ProjectorLightNode"}update(e){super.update(e);const t=this.light;if(this.penumbraCosNode.value=Math.min(Math.cos(t.angle*(1-t.penumbra)),.99999),null===t.aspect){let e=1;null!==t.map&&(e=t.map.width/t.map.height),t.shadow.aspect=e}else t.shadow.aspect=t.aspect}getSpotAttenuation(e){const t=gn(0),r=this.penumbraCosNode,s=r_(this.light).mul(e.context.positionWorld||Dd);return cn(s.w.greaterThan(0),()=>{const e=s.xyz.div(s.w),i=WN(e.xy.sub(bn(.5)),bn(.5)),n=Pa(-1,Fa(1,wo(r)).sub(1));t.assign(ou(i.mul(-2).mul(n)))}),t}}const qN=new a,jN=new a;let XN=null;class KN extends J_{static get type(){return"RectAreaLightNode"}constructor(e=null){super(e),this.halfHeight=_a(new r).setGroup(ba),this.halfWidth=_a(new r).setGroup(ba),this.updateType=Js.RENDER}update(e){super.update(e);const{light:t}=this,r=e.camera.matrixWorldInverse;jN.identity(),qN.copy(t.matrixWorld),qN.premultiply(r),jN.extractRotation(qN),this.halfWidth.value.set(.5*t.width,0,0),this.halfHeight.value.set(0,.5*t.height,0),this.halfWidth.value.applyMatrix4(jN),this.halfHeight.value.applyMatrix4(jN)}setupDirectRectArea(e){let t,r;e.isAvailable("float32Filterable")?(t=Pl(XN.LTC_FLOAT_1),r=Pl(XN.LTC_FLOAT_2)):(t=Pl(XN.LTC_HALF_1),r=Pl(XN.LTC_HALF_2));const{colorNode:s,light:i}=this;return{lightColor:s,lightPosition:a_(i),halfWidth:this.halfWidth,halfHeight:this.halfHeight,ltc_1:t,ltc_2:r}}static setLTC(e){XN=e}}class YN{parseFunction(){d("Abstract function.")}}class QN{constructor(e,t,r="",s=""){this.type=e,this.inputs=t,this.name=r,this.precision=s}getCode(){d("Abstract function.")}}QN.isNodeFunction=!0;const ZN=/^\s*(highp|mediump|lowp)?\s*([a-z_0-9]+)\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)/i,JN=/[a-z_0-9]+/gi,eS="#pragma main";class tS extends QN{constructor(e){const{type:t,inputs:r,name:s,precision:i,inputsCode:n,blockCode:a,headerCode:o}=(e=>{const t=(e=e.trim()).indexOf(eS),r=-1!==t?e.slice(t+12):e,s=r.match(ZN);if(null!==s&&5===s.length){const i=s[4],n=[];let a=null;for(;null!==(a=JN.exec(i));)n.push(a);const o=[];let u=0;for(;u{const r=this.backend.createNodeBuilder(e.object,this.renderer);return r.scene=e.scene,r.material=t,r.camera=e.camera,r.context.material=t,r.lightsNode=e.lightsNode,r.environmentNode=this.getEnvironmentNode(e.scene),r.fogNode=this.getFogNode(e.scene),r.clippingContext=e.clippingContext,this.renderer.getOutputRenderTarget()&&this.renderer.getOutputRenderTarget().multiview&&r.enableMultiview(),r};let n=t(e.material);try{n.build()}catch(e){n=t(new Zp),n.build(),o("TSL: "+e)}r=this._createNodeBuilderState(n),s.set(i,r)}r.usedTimes++,t.nodeBuilderState=r}return r}delete(e){if(e.isRenderObject){const t=this.get(e).nodeBuilderState;t.usedTimes--,0===t.usedTimes&&this.nodeBuilderCache.delete(this.getForRenderCacheKey(e))}return super.delete(e)}getForCompute(e){const t=this.get(e);let r=t.nodeBuilderState;if(void 0===r){const s=this.backend.createNodeBuilder(e,this.renderer);s.build(),r=this._createNodeBuilderState(s),t.nodeBuilderState=r}return r}_createNodeBuilderState(e){return new iN(e.vertexShader,e.fragmentShader,e.computeShader,e.getAttributesArray(),e.getBindings(),e.updateNodes,e.updateBeforeNodes,e.updateAfterNodes,e.observer,e.transforms)}getEnvironmentNode(e){this.updateEnvironment(e);let t=null;if(e.environmentNode&&e.environmentNode.isNode)t=e.environmentNode;else{const r=this.get(e);r.environmentNode&&(t=r.environmentNode)}return t}getBackgroundNode(e){this.updateBackground(e);let t=null;if(e.backgroundNode&&e.backgroundNode.isNode)t=e.backgroundNode;else{const r=this.get(e);r.backgroundNode&&(t=r.backgroundNode)}return t}getFogNode(e){return this.updateFog(e),e.fogNode||this.get(e).fogNode||null}getCacheKey(e,t){iS[0]=e,iS[1]=t;const r=this.renderer.info.calls,s=this.callHashCache.get(iS)||{};if(s.callId!==r){const i=this.getEnvironmentNode(e),n=this.getFogNode(e);t&&nS.push(t.getCacheKey(!0)),i&&nS.push(i.getCacheKey()),n&&nS.push(n.getCacheKey()),nS.push(this.renderer.getOutputRenderTarget()&&this.renderer.getOutputRenderTarget().multiview?1:0),nS.push(this.renderer.shadowMap.enabled?1:0),nS.push(this.renderer.shadowMap.type),s.callId=r,s.cacheKey=Is(nS),this.callHashCache.set(iS,s),nS.length=0}return iS[0]=null,iS[1]=null,s.cacheKey}get isToneMappingState(){return!this.renderer.getRenderTarget()}updateBackground(e){const t=this.get(e),r=e.background;if(r){const s=0===e.backgroundBlurriness&&t.backgroundBlurriness>0||e.backgroundBlurriness>0&&0===t.backgroundBlurriness;if(t.background!==r||s){const i=this.getCacheNode("background",r,()=>{if(!0===r.isCubeTexture||r.mapping===le||r.mapping===de||r.mapping===Ee){if(e.backgroundBlurriness>0||r.mapping===Ee)return ff(r);{let e;return e=!0===r.isCubeTexture?gc(r):Pl(r),pg(e)}}if(!0===r.isTexture)return Pl(r,ql.flipY()).setUpdateMatrix(!0);!0!==r.isColor&&o("WebGPUNodes: Unsupported background configuration.",r)},s);t.backgroundNode=i,t.background=r,t.backgroundBlurriness=e.backgroundBlurriness}}else t.backgroundNode&&(delete t.backgroundNode,delete t.background)}getCacheNode(e,t,r,s=!1){const i=this.cacheLib[e]||(this.cacheLib[e]=new WeakMap);let n=i.get(t);return(void 0===n||s)&&(n=r(),i.set(t,n)),n}updateFog(e){const t=this.get(e),r=e.fog;if(r){if(t.fog!==r){const e=this.getCacheNode("fog",r,()=>{if(r.isFogExp2){const e=yc("color","color",r).setGroup(ba),t=yc("density","float",r).setGroup(ba);return lT(e,oT(t))}if(r.isFog){const e=yc("color","color",r).setGroup(ba),t=yc("near","float",r).setGroup(ba),s=yc("far","float",r).setGroup(ba);return lT(e,aT(t,s))}o("Renderer: Unsupported fog configuration.",r)});t.fogNode=e,t.fog=r}}else delete t.fogNode,delete t.fog}updateEnvironment(e){const t=this.get(e),r=e.environment;if(r){if(t.environment!==r){const e=this.getCacheNode("environment",r,()=>!0===r.isCubeTexture?gc(r):!0===r.isTexture?Pl(r):void o("Nodes: Unsupported environment configuration.",r));t.environmentNode=e,t.environment=r}}else t.environmentNode&&(delete t.environmentNode,delete t.environment)}getNodeFrame(e=this.renderer,t=null,r=null,s=null,i=null){const n=this.nodeFrame;return n.renderer=e,n.scene=t,n.object=r,n.camera=s,n.material=i,n}getNodeFrameForRender(e){return this.getNodeFrame(e.renderer,e.scene,e.object,e.camera,e.material)}getOutputCacheKey(){const e=this.renderer;return e.toneMapping+","+e.currentColorSpace+","+e.xr.isPresenting}hasOutputChange(e){return sS.get(e)!==this.getOutputCacheKey()}getOutputNode(e){const t=this.renderer,r=this.getOutputCacheKey(),s=e.isArrayTexture?mx(e,vn(ql,Gl("gl_ViewID_OVR"))).renderOutput(t.toneMapping,t.currentColorSpace):Pl(e,ql).renderOutput(t.toneMapping,t.currentColorSpace);return sS.set(e,r),s}updateBefore(e){const t=e.getNodeBuilderState();for(const r of t.updateBeforeNodes)this.getNodeFrameForRender(e).updateBeforeNode(r)}updateAfter(e){const t=e.getNodeBuilderState();for(const r of t.updateAfterNodes)this.getNodeFrameForRender(e).updateAfterNode(r)}updateForCompute(e){const t=this.getNodeFrame(),r=this.getForCompute(e);for(const e of r.updateNodes)t.updateNode(e)}updateForRender(e){const t=this.getNodeFrameForRender(e),r=e.getNodeBuilderState();for(const e of r.updateNodes)t.updateNode(e)}needsRefresh(e){const t=this.getNodeFrameForRender(e);return e.getMonitor().needsRefresh(e,t)}dispose(){super.dispose(),this.nodeFrame=new UN,this.nodeBuilderCache=new Map,this.cacheLib={}}}const oS=new je;class uS{constructor(e=null){this.version=0,this.clipIntersection=null,this.cacheKey="",this.shadowPass=!1,this.viewNormalMatrix=new n,this.clippingGroupContexts=new WeakMap,this.intersectionPlanes=[],this.unionPlanes=[],this.parentVersion=null,null!==e&&(this.viewNormalMatrix=e.viewNormalMatrix,this.clippingGroupContexts=e.clippingGroupContexts,this.shadowPass=e.shadowPass,this.viewMatrix=e.viewMatrix)}projectPlanes(e,t,r){const s=e.length;for(let i=0;i0,alpha:!0,depth:t.depth,stencil:t.stencil,framebufferScaleFactor:this.getFramebufferScaleFactor()},i=new XRWebGLLayer(e,s,r);this._glBaseLayer=i,e.updateRenderState({baseLayer:i}),t.setPixelRatio(1),t._setXRLayerSize(i.framebufferWidth,i.framebufferHeight),this._xrRenderTarget=new fS(i.framebufferWidth,i.framebufferHeight,{format:Re,type:Ge,colorSpace:t.outputColorSpace,stencilBuffer:t.stencil,resolveDepthBuffer:!1===i.ignoreDepthValues,resolveStencilBuffer:!1===i.ignoreDepthValues}),this._xrRenderTarget._isOpaqueFramebuffer=!0,this._referenceSpace=await e.requestReferenceSpace(this.getReferenceSpaceType())}this.setFoveation(this.getFoveation()),t._animation.setAnimationLoop(this._onAnimationFrame),t._animation.setContext(e),t._animation.start(),this.isPresenting=!0,this.dispatchEvent({type:"sessionstart"})}}updateCamera(e){const t=this._session;if(null===t)return;const r=e.near,s=e.far,i=this._cameraXR,n=this._cameraL,a=this._cameraR;i.near=a.near=n.near=r,i.far=a.far=n.far=s,i.isMultiViewCamera=this._useMultiview,this._currentDepthNear===i.near&&this._currentDepthFar===i.far||(t.updateRenderState({depthNear:i.near,depthFar:i.far}),this._currentDepthNear=i.near,this._currentDepthFar=i.far),i.layers.mask=6|e.layers.mask,n.layers.mask=-5&i.layers.mask,a.layers.mask=-3&i.layers.mask;const o=e.parent,u=i.cameras;TS(i,o);for(let e=0;e=0&&(r[n]=null,t[n].disconnect(i))}for(let s=0;s=r.length){r.push(i),n=e;break}if(null===r[e]){r[e]=i,n=e;break}}if(-1===n)break}const a=t[n];a&&a.connect(i)}}function SS(e){return"quad"===e.type?this._glBinding.createQuadLayer({transform:new XRRigidTransform(e.translation,e.quaternion),width:e.width/2,height:e.height/2,space:this._referenceSpace,viewPixelWidth:e.pixelwidth,viewPixelHeight:e.pixelheight,clearOnAccess:!1}):this._glBinding.createCylinderLayer({transform:new XRRigidTransform(e.translation,e.quaternion),radius:e.radius,centralAngle:e.centralAngle,aspectRatio:e.aspectRatio,space:this._referenceSpace,viewPixelWidth:e.pixelwidth,viewPixelHeight:e.pixelheight,clearOnAccess:!1})}function RS(e,t){if(void 0===t)return;const r=this._cameraXR,i=this._renderer,n=i.backend,a=this._glBaseLayer,o=this.getReferenceSpace(),u=t.getViewerPose(o);if(this._xrFrame=t,null!==u){const e=u.views;null!==this._glBaseLayer&&n.setXRTarget(a.framebuffer);let t=!1;e.length!==r.cameras.length&&(r.cameras.length=0,t=!0);for(let i=0;i{await this.compileAsync(e,t);const s=this._renderLists.get(e,t),i=this._renderContexts.get(this._renderTarget,this._mrt),n=e.overrideMaterial||r.material,a=this._objects.get(r,n,e,t,s.lightsNode,i,i.clippingContext),{fragmentShader:o,vertexShader:u}=a.getNodeBuilderState();return{fragmentShader:o,vertexShader:u}}}}async init(){return null!==this._initPromise||(this._initPromise=new Promise(async(e,t)=>{let r=this.backend;try{await r.init(this)}catch(e){if(null===this._getFallback)return void t(e);try{this.backend=r=this._getFallback(e),await r.init(this)}catch(e){return void t(e)}}this._nodes=new aS(this,r),this._animation=new Yf(this,this._nodes,this.info),this._attributes=new uy(r),this._background=new tN(this,this._nodes),this._geometries=new cy(this._attributes,this.info),this._textures=new Fy(this,r,this.info),this._pipelines=new by(r,this._nodes),this._bindings=new xy(r,this._nodes,this._textures,this._attributes,this._pipelines,this.info),this._objects=new ty(this,this._nodes,this._geometries,this._pipelines,this._bindings,this.info),this._renderLists=new Ry(this.lighting),this._bundles=new cS,this._renderContexts=new Cy,this._animation.start(),this._initialized=!0,this._inspector.init(),e(this)})),this._initPromise}get domElement(){return this._canvasTarget.domElement}get coordinateSystem(){return this.backend.coordinateSystem}async compileAsync(e,t,r=null){if(!0===this._isDeviceLost)return;!1===this._initialized&&await this.init();const s=this._nodes.nodeFrame,i=s.renderId,n=this._currentRenderContext,a=this._currentRenderObjectFunction,o=this._handleObjectFunction,u=this._compilationPromises,l=!0===e.isScene?e:AS;null===r&&(r=e);const d=this._renderTarget,c=this._renderContexts.get(d,this._mrt),h=this._activeMipmapLevel,p=[];this._currentRenderContext=c,this._currentRenderObjectFunction=this.renderObject,this._handleObjectFunction=this._createObjectPipeline,this._compilationPromises=p,s.renderId++,s.update(),c.depth=this.depth,c.stencil=this.stencil,c.clippingContext||(c.clippingContext=new uS),c.clippingContext.updateGlobal(l,t),l.onBeforeRender(this,e,t,d);const g=this._renderLists.get(e,t);if(g.begin(),this._projectObject(e,t,0,g,c.clippingContext),r!==e&&r.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&g.pushLight(e)}),g.finish(),null!==d){this._textures.updateRenderTarget(d,h);const e=this._textures.get(d);c.textures=e.textures,c.depthTexture=e.depthTexture}else c.textures=null,c.depthTexture=null;r!==e?this._background.update(r,g,c):this._background.update(l,g,c);const m=g.opaque,f=g.transparent,y=g.transparentDoublePass,b=g.lightsNode;!0===this.opaque&&m.length>0&&this._renderObjects(m,t,l,b),!0===this.transparent&&f.length>0&&this._renderTransparents(f,y,t,l,b),s.renderId=i,this._currentRenderContext=n,this._currentRenderObjectFunction=a,this._handleObjectFunction=o,this._compilationPromises=u,await Promise.all(p)}async renderAsync(e,t){v('Renderer: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.render(e,t)}async waitForGPU(){o("Renderer: waitForGPU() has been removed. Read https://github.com/mrdoob/three.js/issues/32012 for more information.")}set inspector(e){null!==this._inspector&&this._inspector.setRenderer(null),this._inspector=e,this._inspector.setRenderer(this)}get inspector(){return this._inspector}set highPrecision(e){const t=this.contextNode.value;!0===e?(t.modelViewMatrix=Cd,t.modelNormalViewMatrix=Md):this.highPrecision&&(delete t.modelViewMatrix,delete t.modelNormalViewMatrix)}get highPrecision(){const e=this.contextNode.value;return e.modelViewMatrix===Cd&&e.modelNormalViewMatrix===Md}setMRT(e){return this._mrt=e,this}getMRT(){return this._mrt}getOutputBufferType(){return this._outputBufferType}getColorBufferType(){return v('Renderer: ".getColorBufferType()" has been renamed to ".getOutputBufferType()".'),this.getOutputBufferType()}_onDeviceLost(e){let t=`THREE.WebGPURenderer: ${e.api} Device Lost:\n\nMessage: ${e.message}`;e.reason&&(t+=`\nReason: ${e.reason}`),o(t),this._isDeviceLost=!0}_renderBundle(e,t,r){const{bundleGroup:s,camera:i,renderList:n}=e,a=this._currentRenderContext,o=this._bundles.get(s,i),u=this.backend.get(o);void 0===u.renderContexts&&(u.renderContexts=new Set);const l=s.version!==u.version,d=!1===u.renderContexts.has(a)||l;if(u.renderContexts.add(a),d){this.backend.beginBundle(a),(void 0===u.renderObjects||l)&&(u.renderObjects=[]),this._currentRenderBundle=o;const{transparentDoublePass:e,transparent:d,opaque:c}=n;!0===this.opaque&&c.length>0&&this._renderObjects(c,i,t,r),!0===this.transparent&&d.length>0&&this._renderTransparents(d,e,i,t,r),this._currentRenderBundle=null,this.backend.finishBundle(a,o),u.version=s.version}else{const{renderObjects:e}=u;for(let t=0,r=e.length;t>=h,g.viewportValue.height>>=h,g.viewportValue.minDepth=_,g.viewportValue.maxDepth=v,g.viewport=!1===g.viewportValue.equals(CS),g.scissorValue.copy(x).multiplyScalar(T).floor(),g.scissor=y._scissorTest&&!1===g.scissorValue.equals(CS),g.scissorValue.width>>=h,g.scissorValue.height>>=h,g.clippingContext||(g.clippingContext=new uS),g.clippingContext.updateGlobal(l,t),l.onBeforeRender(this,e,t,p);const N=t.isArrayCamera?FS:MS;t.isArrayCamera||(LS.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),N.setFromProjectionMatrix(LS,t.coordinateSystem,t.reversedDepth));const S=this._renderLists.get(e,t);if(S.begin(),this._projectObject(e,t,0,S,g.clippingContext),S.finish(),!0===this.sortObjects&&S.sort(this._opaqueSort,this._transparentSort),null!==p){this._textures.updateRenderTarget(p,h);const e=this._textures.get(p);g.textures=e.textures,g.depthTexture=e.depthTexture,g.width=e.width,g.height=e.height,g.renderTarget=p,g.depth=p.depthBuffer,g.stencil=p.stencilBuffer}else g.textures=null,g.depthTexture=null,g.width=wS.width,g.height=wS.height,g.depth=this.depth,g.stencil=this.stencil;g.width>>=h,g.height>>=h,g.activeCubeFace=c,g.activeMipmapLevel=h,g.occlusionQueryCount=S.occlusionQueryCount,g.scissorValue.max(PS.set(0,0,0,0)),g.scissorValue.x+g.scissorValue.width>g.width&&(g.scissorValue.width=Math.max(g.width-g.scissorValue.x,0)),g.scissorValue.y+g.scissorValue.height>g.height&&(g.scissorValue.height=Math.max(g.height-g.scissorValue.y,0)),this._background.update(l,S,g),g.camera=t,this.backend.beginRender(g);const{bundles:R,lightsNode:E,transparentDoublePass:A,transparent:w,opaque:C}=S;return R.length>0&&this._renderBundles(R,l,E),!0===this.opaque&&C.length>0&&this._renderObjects(C,t,l,E),!0===this.transparent&&w.length>0&&this._renderTransparents(w,A,t,l,E),this.backend.finishRender(g),i.renderId=n,this._currentRenderContext=a,this._currentRenderObjectFunction=o,this._handleObjectFunction=u,this._callDepth--,null!==s&&(this.setRenderTarget(d,c,h),this._renderOutput(p)),l.onAfterRender(this,e,t,p),this.inspector.finishRender(this.backend.getTimestampUID(g)),g}_setXRLayerSize(e,t){this._canvasTarget._width=e,this._canvasTarget._height=t,this.setViewport(0,0,e,t)}_renderOutput(e){const t=this._quad;this._nodes.hasOutputChange(e.texture)&&(t.material.fragmentNode=this._nodes.getOutputNode(e.texture),t.material.needsUpdate=!0);const r=this.autoClear,s=this.xr.enabled;this.autoClear=!1,this.xr.enabled=!1,this._renderScene(t,t.camera,!1),this.autoClear=r,this.xr.enabled=s}getMaxAnisotropy(){return this.backend.getMaxAnisotropy()}getActiveCubeFace(){return this._activeCubeFace}getActiveMipmapLevel(){return this._activeMipmapLevel}async setAnimationLoop(e){!1===this._initialized&&await this.init(),this._animation.setAnimationLoop(e)}getAnimationLoop(){return this._animation.getAnimationLoop()}async getArrayBufferAsync(e){return await this.backend.getArrayBufferAsync(e)}getContext(){return this.backend.getContext()}getPixelRatio(){return this._canvasTarget.getPixelRatio()}getDrawingBufferSize(e){return this._canvasTarget.getDrawingBufferSize(e)}getSize(e){return this._canvasTarget.getSize(e)}setPixelRatio(e=1){this._canvasTarget.setPixelRatio(e)}setDrawingBufferSize(e,t,r){this.xr&&this.xr.isPresenting||this._canvasTarget.setDrawingBufferSize(e,t,r)}setSize(e,t,r=!0){this.xr&&this.xr.isPresenting||this._canvasTarget.setSize(e,t,r)}setOpaqueSort(e){this._opaqueSort=e}setTransparentSort(e){this._transparentSort=e}getScissor(e){return this._canvasTarget.getScissor(e)}setScissor(e,t,r,s){this._canvasTarget.setScissor(e,t,r,s)}getScissorTest(){return this._canvasTarget.getScissorTest()}setScissorTest(e){this._canvasTarget.setScissorTest(e),this.backend.setScissorTest(e)}getViewport(e){return this._canvasTarget.getViewport(e)}setViewport(e,t,r,s,i=0,n=1){this._canvasTarget.setViewport(e,t,r,s,i,n)}getClearColor(e){return e.copy(this._clearColor)}setClearColor(e,t=1){this._clearColor.set(e),this._clearColor.a=t}getClearAlpha(){return this._clearColor.a}setClearAlpha(e){this._clearColor.a=e}getClearDepth(){return this._clearDepth}setClearDepth(e){this._clearDepth=e}getClearStencil(){return this._clearStencil}setClearStencil(e){this._clearStencil=e}isOccluded(e){const t=this._currentRenderContext;return t&&this.backend.isOccluded(t,e)}clear(e=!0,t=!0,r=!0){if(!1===this._initialized)throw new Error('Renderer: .clear() called before the backend is initialized. Use "await renderer.init();" before before using this method.');const s=this._renderTarget||this._getFrameBufferTarget();let i=null;if(null!==s){this._textures.updateRenderTarget(s);const e=this._textures.get(s);i=this._renderContexts.get(s),i.textures=e.textures,i.depthTexture=e.depthTexture,i.width=e.width,i.height=e.height,i.renderTarget=s,i.depth=s.depthBuffer,i.stencil=s.stencilBuffer;const t=this.backend.getClearColor();i.clearColorValue.r=t.r,i.clearColorValue.g=t.g,i.clearColorValue.b=t.b,i.clearColorValue.a=t.a,i.activeCubeFace=this.getActiveCubeFace(),i.activeMipmapLevel=this.getActiveMipmapLevel()}this.backend.clear(e,t,r,i),null!==s&&null===this._renderTarget&&this._renderOutput(s)}clearColor(){this.clear(!0,!1,!1)}clearDepth(){this.clear(!1,!0,!1)}clearStencil(){this.clear(!1,!1,!0)}async clearAsync(e=!0,t=!0,r=!0){v('Renderer: "clearAsync()" has been deprecated. Use "clear()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.clear(e,t,r)}async clearColorAsync(){v('Renderer: "clearColorAsync()" has been deprecated. Use "clearColor()" and "await renderer.init();" when creating the renderer.'),this.clear(!0,!1,!1)}async clearDepthAsync(){v('Renderer: "clearDepthAsync()" has been deprecated. Use "clearDepth()" and "await renderer.init();" when creating the renderer.'),this.clear(!1,!0,!1)}async clearStencilAsync(){v('Renderer: "clearStencilAsync()" has been deprecated. Use "clearStencil()" and "await renderer.init();" when creating the renderer.'),this.clear(!1,!1,!0)}get needsFrameBufferTarget(){const e=this.currentToneMapping!==m,t=this.currentColorSpace!==p.workingColorSpace;return e||t}get samples(){return this._samples}get currentSamples(){let e=this._samples;return null!==this._renderTarget?e=this._renderTarget.samples:this.needsFrameBufferTarget&&(e=0),e}get currentToneMapping(){return this.isOutputTarget?this.toneMapping:m}get currentColorSpace(){return this.isOutputTarget?this.outputColorSpace:p.workingColorSpace}get isOutputTarget(){return this._renderTarget===this._outputRenderTarget||null===this._renderTarget}dispose(){!0===this._initialized&&(this.info.dispose(),this.backend.dispose(),this._animation.dispose(),this._objects.dispose(),this._geometries.dispose(),this._pipelines.dispose(),this._nodes.dispose(),this._bindings.dispose(),this._renderLists.dispose(),this._renderContexts.dispose(),this._textures.dispose(),null!==this._frameBufferTarget&&this._frameBufferTarget.dispose(),Object.values(this.backend.timestampQueryPool).forEach(e=>{null!==e&&e.dispose()})),this.setRenderTarget(null),this.setAnimationLoop(null)}setRenderTarget(e,t=0,r=0){this._renderTarget=e,this._activeCubeFace=t,this._activeMipmapLevel=r}getRenderTarget(){return this._renderTarget}setOutputRenderTarget(e){this._outputRenderTarget=e}getOutputRenderTarget(){return this._outputRenderTarget}setCanvasTarget(e){this._canvasTarget.removeEventListener("resize",this._onCanvasTargetResize),this._canvasTarget=e,this._canvasTarget.addEventListener("resize",this._onCanvasTargetResize)}getCanvasTarget(){return this._canvasTarget}_resetXRState(){this.backend.setXRTarget(null),this.setOutputRenderTarget(null),this.setRenderTarget(null),this._frameBufferTarget.dispose(),this._frameBufferTarget=null}setRenderObjectFunction(e){this._renderObjectFunction=e}getRenderObjectFunction(){return this._renderObjectFunction}compute(e,t=null){if(!0===this._isDeviceLost)return;if(!1===this._initialized)return d("Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead."),this.computeAsync(e,t);const r=this._nodes.nodeFrame,s=r.renderId;this.info.calls++,this.info.compute.calls++,this.info.compute.frameCalls++,r.renderId=this.info.calls,this.backend.updateTimeStampUID(e),this.inspector.beginCompute(this.backend.getTimestampUID(e),e);const i=this.backend,n=this._pipelines,a=this._bindings,o=this._nodes,u=Array.isArray(e)?e:[e];if(void 0===u[0]||!0!==u[0].isComputeNode)throw new Error("THREE.Renderer: .compute() expects a ComputeNode.");i.beginCompute(e);for(const r of u){if(!1===n.has(r)){const e=()=>{r.removeEventListener("dispose",e),n.delete(r),a.deleteForCompute(r),o.delete(r)};r.addEventListener("dispose",e);const t=r.onInitFunction;null!==t&&t.call(r,{renderer:this})}o.updateForCompute(r),a.updateForCompute(r);const s=a.getForCompute(r),u=n.getForCompute(r,s);i.compute(e,r,s,u,t)}i.finishCompute(e),r.renderId=s,this.inspector.finishCompute(this.backend.getTimestampUID(e))}async computeAsync(e,t=null){!1===this._initialized&&await this.init(),this.compute(e,t)}async hasFeatureAsync(e){return v('Renderer: "hasFeatureAsync()" has been deprecated. Use "hasFeature()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.hasFeature(e)}async resolveTimestampsAsync(e="render"){return!1===this._initialized&&await this.init(),this.backend.resolveTimestampsAsync(e)}hasFeature(e){if(!1===this._initialized)throw new Error('Renderer: .hasFeature() called before the backend is initialized. Use "await renderer.init();" before before using this method.');return this.backend.hasFeature(e)}hasInitialized(){return this._initialized}async initTextureAsync(e){v('Renderer: "initTextureAsync()" has been deprecated. Use "initTexture()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.initTexture(e)}initTexture(e){if(!1===this._initialized)throw new Error('Renderer: .initTexture() called before the backend is initialized. Use "await renderer.init();" before before using this method.');this._textures.updateTexture(e)}copyFramebufferToTexture(e,t=null){if(null!==t)if(t.isVector2)t=PS.set(t.x,t.y,e.image.width,e.image.height).floor();else{if(!t.isVector4)return void o("Renderer.copyFramebufferToTexture: Invalid rectangle.");t=PS.copy(t).floor()}else t=PS.set(0,0,e.image.width,e.image.height);let r,s=this._currentRenderContext;null!==s?r=s.renderTarget:(r=this._renderTarget||this._getFrameBufferTarget(),null!==r&&(this._textures.updateRenderTarget(r),s=this._textures.get(r))),this._textures.updateTexture(e,{renderTarget:r}),this.backend.copyFramebufferToTexture(e,s,t),this._inspector.copyFramebufferToTexture(e)}copyTextureToTexture(e,t,r=null,s=null,i=0,n=0){this._textures.updateTexture(e),this._textures.updateTexture(t),this.backend.copyTextureToTexture(e,t,r,s,i,n),this._inspector.copyTextureToTexture(e,t)}async readRenderTargetPixelsAsync(e,t,r,s,i,n=0,a=0){return this.backend.copyTextureToBuffer(e.textures[n],t,r,s,i,a)}_projectObject(e,t,r,s,i){if(!1===e.visible)return;if(e.layers.test(t.layers))if(e.isGroup)r=e.renderOrder,e.isClippingGroup&&e.enabled&&(i=i.getGroupContext(e));else if(e.isLOD)!0===e.autoUpdate&&e.update(t);else if(e.isLight)s.pushLight(e);else if(e.isSprite){const n=t.isArrayCamera?FS:MS;if(!e.frustumCulled||n.intersectsSprite(e,t)){!0===this.sortObjects&&PS.setFromMatrixPosition(e.matrixWorld).applyMatrix4(LS);const{geometry:t,material:n}=e;n.visible&&s.push(e,t,n,r,PS.z,null,i)}}else if(e.isLineLoop)o("Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.");else if(e.isMesh||e.isLine||e.isPoints){const n=t.isArrayCamera?FS:MS;if(!e.frustumCulled||n.intersectsObject(e,t)){const{geometry:t,material:n}=e;if(!0===this.sortObjects&&(null===t.boundingSphere&&t.computeBoundingSphere(),PS.copy(t.boundingSphere.center).applyMatrix4(e.matrixWorld).applyMatrix4(LS)),Array.isArray(n)){const a=t.groups;for(let o=0,u=a.length;o0){for(const{material:e}of t)e.side=M;this._renderObjects(t,r,s,i,"backSide");for(const{material:e}of t)e.side=ct;this._renderObjects(e,r,s,i);for(const{material:e}of t)e.side=F}else this._renderObjects(e,r,s,i)}_renderObjects(e,t,r,s,i=null){for(let n=0,a=e.length;n(t.not().discard(),e))(u)}}e.depthNode&&e.depthNode.isNode&&(l=e.depthNode),e.castShadowPositionNode&&e.castShadowPositionNode.isNode?o=e.castShadowPositionNode:e.positionNode&&e.positionNode.isNode&&(o=e.positionNode),r={version:t,colorNode:u,depthNode:l,positionNode:o},this._cacheShadowNodes.set(e,r)}return r}renderObject(e,t,r,s,i,n,a,o=null,u=null){let l,d,c,h,p=!1;if(e.onBeforeRender(this,t,r,s,i,n),!0===i.allowOverride&&null!==t.overrideMaterial){const e=t.overrideMaterial;if(p=!0,l=t.overrideMaterial.colorNode,d=t.overrideMaterial.depthNode,c=t.overrideMaterial.positionNode,h=t.overrideMaterial.side,i.positionNode&&i.positionNode.isNode&&(e.positionNode=i.positionNode),e.alphaTest=i.alphaTest,e.alphaMap=i.alphaMap,e.transparent=i.transparent||i.transmission>0||i.transmissionNode&&i.transmissionNode.isNode||i.backdropNode&&i.backdropNode.isNode,e.isShadowPassMaterial){const{colorNode:t,depthNode:r,positionNode:s}=this._getShadowNodes(i);this.shadowMap.type===Ze?e.side=null!==i.shadowSide?i.shadowSide:i.side:e.side=null!==i.shadowSide?i.shadowSide:BS[i.side],null!==t&&(e.colorNode=t),null!==r&&(e.depthNode=r),null!==s&&(e.positionNode=s)}i=e}!0===i.transparent&&i.side===F&&!1===i.forceSinglePass?(i.side=M,this._handleObjectFunction(e,i,t,r,a,n,o,"backSide"),i.side=ct,this._handleObjectFunction(e,i,t,r,a,n,o,u),i.side=F):this._handleObjectFunction(e,i,t,r,a,n,o,u),p&&(t.overrideMaterial.colorNode=l,t.overrideMaterial.depthNode=d,t.overrideMaterial.positionNode=c,t.overrideMaterial.side=h),e.onAfterRender(this,t,r,s,i,n)}hasCompatibility(e){return this.backend.hasCompatibility(e)}_renderObjectDirect(e,t,r,s,i,n,a,o){const u=this._objects.get(e,t,r,s,i,this._currentRenderContext,a,o);u.drawRange=e.geometry.drawRange,u.group=n;const l=this._nodes.needsRefresh(u);if(l&&(this._nodes.updateBefore(u),this._geometries.updateForRender(u),this._nodes.updateForRender(u),this._bindings.updateForRender(u)),this._pipelines.updateForRender(u),null!==this._currentRenderBundle){this.backend.get(this._currentRenderBundle).renderObjects.push(u),u.bundle=this._currentRenderBundle.bundleGroup}this.backend.draw(u,this.info),l&&this._nodes.updateAfter(u)}_createObjectPipeline(e,t,r,s,i,n,a,o){const u=this._objects.get(e,t,r,s,i,this._currentRenderContext,a,o);u.drawRange=e.geometry.drawRange,u.group=n,this._nodes.updateBefore(u),this._geometries.updateForRender(u),this._nodes.updateForRender(u),this._bindings.updateForRender(u),this._pipelines.getForRender(u,this._compilationPromises),this._nodes.updateAfter(u)}_onCanvasTargetResize(){this._initialized&&this.backend.updateSize()}get compile(){return this.compileAsync}}class US{constructor(e=""){this.name=e,this.visibility=0}setVisibility(e){this.visibility|=e}getVisibility(){return this.visibility}clone(){return Object.assign(new this.constructor,this)}}class IS extends US{constructor(e,t=null){super(e),this.isBuffer=!0,this.bytesPerElement=Float32Array.BYTES_PER_ELEMENT,this._buffer=t,this._updateRanges=[]}get updateRanges(){return this._updateRanges}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}get byteLength(){return(e=this._buffer.byteLength)+(oy-e%oy)%oy;var e}get buffer(){return this._buffer}update(){return!0}}class OS extends IS{constructor(e,t=null){super(e,t),this.isUniformBuffer=!0}}let VS=0;class kS extends OS{constructor(e,t){super("UniformBuffer_"+VS++,e?e.value:null),this.nodeUniform=e,this.groupNode=t,this.isNodeUniformBuffer=!0}set updateRanges(e){this.nodeUniform.updateRanges=e}get updateRanges(){return this.nodeUniform.updateRanges}addUpdateRange(e,t){this.nodeUniform.addUpdateRange(e,t)}clearUpdateRanges(){this.nodeUniform.clearUpdateRanges()}get buffer(){return this.nodeUniform.value}}class GS extends OS{constructor(e){super(e),this.isUniformsGroup=!0,this._values=null,this.uniforms=[],this._updateRangeCache=new Map}addUniformUpdateRange(e){const t=e.index;if(!0!==this._updateRangeCache.has(t)){const r=this.updateRanges,s={start:e.offset,count:e.itemSize};r.push(s),this._updateRangeCache.set(t,s)}}clearUpdateRanges(){this._updateRangeCache.clear(),super.clearUpdateRanges()}addUniform(e){return this.uniforms.push(e),this}removeUniform(e){const t=this.uniforms.indexOf(e);return-1!==t&&this.uniforms.splice(t,1),this}get values(){return null===this._values&&(this._values=Array.from(this.buffer)),this._values}get buffer(){let e=this._buffer;if(null===e){const t=this.byteLength;e=new Float32Array(new ArrayBuffer(t)),this._buffer=e}return e}get byteLength(){const e=this.bytesPerElement;let t=0;for(let r=0,s=this.uniforms.length;r{this.generation=null,this.version=0},this.texture=t,this.version=t?t.version:0,this.generation=null,this.samplerKey="",this.isSampler=!0}set texture(e){this._texture!==e&&(this._texture&&this._texture.removeEventListener("dispose",this._onTextureDispose),this._texture=e,this.generation=null,this.version=0,this._texture&&this._texture.addEventListener("dispose",this._onTextureDispose))}get texture(){return this._texture}update(){const{texture:e,version:t}=this;return t!==e.version&&(this.version=e.version,!0)}clone(){const e=super.clone();return e._texture=null,e._onTextureDispose=()=>{e.generation=null,e.version=0},e.texture=this.texture,e}}let HS=0;class qS extends WS{constructor(e,t){super(e,t),this.id=HS++,this.store=!1,this.mipLevel=0,this.isSampledTexture=!0}}class jS extends qS{constructor(e,t,r,s=null){super(e,t?t.value:null),this.textureNode=t,this.groupNode=r,this.access=s}update(){const{textureNode:e}=this;return this.texture!==e.value?(this.texture=e.value,!0):super.update()}}class XS extends jS{constructor(e,t,r,s=null){super(e,t,r,s),this.isSampledCubeTexture=!0}}class KS extends jS{constructor(e,t,r,s=null){super(e,t,r,s),this.isSampledTexture3D=!0}}const YS={bitcast_int_uint:new Xx("uint tsl_bitcast_int_to_uint ( int x ) { return floatBitsToUint( intBitsToFloat ( x ) ); }"),bitcast_uint_int:new Xx("uint tsl_bitcast_uint_to_int ( uint x ) { return floatBitsToInt( uintBitsToFloat ( x ) ); }")},QS={textureDimensions:"textureSize",equals:"equal",bitcast_float_int:"floatBitsToInt",bitcast_int_float:"intBitsToFloat",bitcast_uint_float:"uintBitsToFloat",bitcast_float_uint:"floatBitsToUint",bitcast_uint_int:"tsl_bitcast_uint_to_int",bitcast_int_uint:"tsl_bitcast_int_to_uint",floatpack_snorm_2x16:"packSnorm2x16",floatpack_unorm_2x16:"packUnorm2x16",floatpack_float16_2x16:"packHalf2x16",floatunpack_snorm_2x16:"unpackSnorm2x16",floatunpack_unorm_2x16:"unpackUnorm2x16",floatunpack_float16_2x16:"unpackHalf2x16"},ZS={low:"lowp",medium:"mediump",high:"highp"},JS={swizzleAssign:!0,storageBuffer:!1},eR={perspective:"smooth",linear:"noperspective"},tR={centroid:"centroid"},rR="\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\nprecision highp sampler3D;\nprecision highp samplerCube;\nprecision highp sampler2DArray;\n\nprecision highp usampler2D;\nprecision highp usampler3D;\nprecision highp usamplerCube;\nprecision highp usampler2DArray;\n\nprecision highp isampler2D;\nprecision highp isampler3D;\nprecision highp isamplerCube;\nprecision highp isampler2DArray;\n\nprecision highp sampler2DShadow;\nprecision highp sampler2DArrayShadow;\nprecision highp samplerCubeShadow;\n";class sR extends DN{constructor(e,t){super(e,t,new rS),this.uniformGroups={},this.transforms=[],this.extensions={},this.builtins={vertex:[],fragment:[],compute:[]}}needsToWorkingColorSpace(e){return!0===e.isVideoTexture&&e.colorSpace!==T}_include(e){const t=YS[e];return t.build(this),this.addInclude(t),t}getMethod(e){return void 0!==YS[e]&&this._include(e),QS[e]||e}getBitcastMethod(e,t){return this.getMethod(`bitcast_${t}_${e}`)}getFloatPackingMethod(e){return this.getMethod(`floatpack_${e}_2x16`)}getFloatUnpackingMethod(e){return this.getMethod(`floatunpack_${e}_2x16`)}getTernary(e,t,r){return`${e} ? ${t} : ${r}`}getOutputStructName(){return""}buildFunctionCode(e){const t=e.layout,r=this.flowShaderNode(e),s=[];for(const e of t.inputs)s.push(this.getType(e.type)+" "+e.name);return`${this.getType(t.type)} ${t.name}( ${s.join(", ")} ) {\n\n\t${r.vars}\n\n${r.code}\n\treturn ${r.result};\n\n}`}setupPBO(e){const t=e.value;if(void 0===t.pbo){const e=t.array,r=t.count*t.itemSize,{itemSize:s}=t,i=t.array.constructor.name.toLowerCase().includes("int");let n=i?Tt:_t;2===s?n=i?Rt:G:3===s?n=i?Et:At:4===s&&(n=i?wt:Re);const a={Float32Array:j,Uint8Array:Ge,Uint16Array:St,Uint32Array:S,Int8Array:Nt,Int16Array:vt,Int32Array:R,Uint8ClampedArray:Ge},o=Math.pow(2,Math.ceil(Math.log2(Math.sqrt(r/s))));let u=Math.ceil(r/s/o);o*u*s0?i:"";t=`${r.name} {\n\t${s} ${e.name}[${n}];\n};\n`}else{const t=e.groupNode.name;if(void 0===s[t]){const e=this.uniformGroups[t];if(void 0!==e){const r=[];for(const t of e.uniforms){const e=t.getType(),s=this.getVectorType(e),i=t.nodeUniform.node.precision;let n=`${s} ${t.name};`;null!==i&&(n=ZS[i]+" "+n),r.push("\t"+n)}s[t]=r}}i=!0}if(!i){const s=e.node.precision;null!==s&&(t=ZS[s]+" "+t),t="uniform "+t,r.push(t)}}let i="";for(const e in s){const t=s[e];i+=this._getGLSLUniformStruct(e,t.join("\n"))+"\n"}return i+=r.join("\n"),i}getTypeFromAttribute(e){let t=super.getTypeFromAttribute(e);if(/^[iu]/.test(t)&&e.gpuType!==R){let r=e;e.isInterleavedBufferAttribute&&(r=e.data);const s=r.array;!1==(s instanceof Uint32Array||s instanceof Int32Array)&&(t=t.slice(1))}return t}getAttributes(e){let t="";if("vertex"===e||"compute"===e){const e=this.getAttributesArray();let r=0;for(const s of e)t+=`layout( location = ${r++} ) in ${s.type} ${s.name};\n`}return t}getStructMembers(e){const t=[];for(const r of e.members)t.push(`\t${r.type} ${r.name};`);return t.join("\n")}getStructs(e){const t=[],r=this.structs[e],s=[];for(const e of r)if(e.output)for(const t of e.members)s.push(`layout( location = ${t.index} ) out ${t.type} ${t.name};`);else{let r="struct "+e.name+" {\n";r+=this.getStructMembers(e),r+="\n};\n",t.push(r)}return 0===s.length&&s.push("layout( location = 0 ) out vec4 fragColor;"),"\n"+s.join("\n")+"\n\n"+t.join("\n")}getVaryings(e){let t="";const r=this.varyings;if("vertex"===e||"compute"===e)for(const s of r){"compute"===e&&(s.needsInterpolation=!0);const r=this.getType(s.type);if(s.needsInterpolation)if(s.interpolationType){t+=`${eR[s.interpolationType]||s.interpolationType} ${tR[s.interpolationSampling]||""} out ${r} ${s.name};\n`}else{t+=`${r.includes("int")||r.includes("uv")||r.includes("iv")?"flat ":""}out ${r} ${s.name};\n`}else t+=`${r} ${s.name};\n`}else if("fragment"===e)for(const e of r)if(e.needsInterpolation){const r=this.getType(e.type);if(e.interpolationType){t+=`${eR[e.interpolationType]||e.interpolationType} ${tR[e.interpolationSampling]||""} in ${r} ${e.name};\n`}else{t+=`${r.includes("int")||r.includes("uv")||r.includes("iv")?"flat ":""}in ${r} ${e.name};\n`}}for(const r of this.builtins[e])t+=`${r};\n`;return t}getVertexIndex(){return"uint( gl_VertexID )"}getInstanceIndex(){return"uint( gl_InstanceID )"}getInvocationLocalIndex(){return`uint( gl_InstanceID ) % ${this.object.workgroupSize.reduce((e,t)=>e*t,1)}u`}getSubgroupSize(){o("GLSLNodeBuilder: WebGLBackend does not support the subgroupSize node")}getInvocationSubgroupIndex(){o("GLSLNodeBuilder: WebGLBackend does not support the invocationSubgroupIndex node")}getSubgroupIndex(){o("GLSLNodeBuilder: WebGLBackend does not support the subgroupIndex node")}getDrawIndex(){return this.renderer.backend.extensions.has("WEBGL_multi_draw")?"uint( gl_DrawID )":null}getFrontFacing(){return"gl_FrontFacing"}getFragCoord(){return"gl_FragCoord.xy"}getFragDepth(){return"gl_FragDepth"}enableExtension(e,t,r=this.shaderStage){const s=this.extensions[r]||(this.extensions[r]=new Map);!1===s.has(e)&&s.set(e,{name:e,behavior:t})}getExtensions(e){const t=[];if("vertex"===e){const t=this.renderer.backend.extensions;this.object.isBatchedMesh&&t.has("WEBGL_multi_draw")&&this.enableExtension("GL_ANGLE_multi_draw","require",e)}const r=this.extensions[e];if(void 0!==r)for(const{name:e,behavior:s}of r.values())t.push(`#extension ${e} : ${s}`);return t.join("\n")}getClipDistance(){return"gl_ClipDistance"}isAvailable(e){let t=JS[e];if(void 0===t){let r;switch(t=!1,e){case"float32Filterable":r="OES_texture_float_linear";break;case"clipDistance":r="WEBGL_clip_cull_distance"}if(void 0!==r){const e=this.renderer.backend.extensions;e.has(r)&&(e.get(r),t=!0)}JS[e]=t}return t}isFlipY(){return!0}enableHardwareClipping(e){this.enableExtension("GL_ANGLE_clip_cull_distance","require"),this.builtins.vertex.push(`out float gl_ClipDistance[ ${e} ]`)}enableMultiview(){this.enableExtension("GL_OVR_multiview2","require","fragment"),this.enableExtension("GL_OVR_multiview2","require","vertex"),this.builtins.vertex.push("layout(num_views = 2) in")}registerTransform(e,t){this.transforms.push({varyingName:e,attributeNode:t})}getTransforms(){const e=this.transforms;let t="";for(let r=0;r0&&(r+="\n"),r+=`\t// flow -> ${n}\n\t`),r+=`${s.code}\n\t`,e===i&&"compute"!==t&&(r+="// result\n\t","vertex"===t?(r+="gl_Position = ",r+=`${s.result};`):"fragment"===t&&(e.outputNode.isOutputStructNode||(r+="fragColor = ",r+=`${s.result};`)))}const n=e[t];n.extensions=this.getExtensions(t),n.uniforms=this.getUniforms(t),n.attributes=this.getAttributes(t),n.varyings=this.getVaryings(t),n.vars=this.getVars(t),n.structs=this.getStructs(t),n.codes=this.getCodes(t),n.transforms=this.getTransforms(t),n.flow=r}null!==this.material?(this.vertexShader=this._getGLSLVertexCode(e.vertex),this.fragmentShader=this._getGLSLFragmentCode(e.fragment)):this.computeShader=this._getGLSLVertexCode(e.compute)}getUniformFromNode(e,t,r,s=null){const i=super.getUniformFromNode(e,t,r,s),n=this.getDataFromNode(e,r,this.globalCache);let a=n.uniformGPU;if(void 0===a){const s=e.groupNode,o=s.name,u=this.getBindGroupArray(o,r);if("texture"===t)a=new jS(i.name,i.node,s),u.push(a);else if("cubeTexture"===t||"cubeDepthTexture"===t)a=new XS(i.name,i.node,s),u.push(a);else if("texture3D"===t)a=new KS(i.name,i.node,s),u.push(a);else if("buffer"===t){i.name=`buffer${e.id}`;const t=this.getSharedDataFromNode(e);let r=t.buffer;void 0===r&&(e.name=`NodeBuffer_${e.id}`,r=new kS(e,s),r.name=e.name,t.buffer=r),u.push(r),a=r}else{let e=this.uniformGroups[o];void 0===e?(e=new $S(o,s),this.uniformGroups[o]=e,u.push(e)):-1===u.indexOf(e)&&u.push(e),a=this.getNodeUniform(i,t);const r=a.name;e.uniforms.some(e=>e.name===r)||e.addUniform(a)}n.uniformGPU=a}return i}}let iR=null,nR=null;class aR{constructor(e={}){this.parameters=Object.assign({},e),this.data=new WeakMap,this.renderer=null,this.domElement=null,this.timestampQueryPool={[Ct.RENDER]:null,[Ct.COMPUTE]:null},this.trackTimestamp=!0===e.trackTimestamp}async init(e){this.renderer=e}get coordinateSystem(){}beginRender(){}finishRender(){}beginCompute(){}finishCompute(){}draw(){}compute(){}createProgram(){}destroyProgram(){}createBindings(){}updateBindings(){}updateBinding(){}createRenderPipeline(){}createComputePipeline(){}needsRenderUpdate(){}getRenderCacheKey(){}createNodeBuilder(){}updateSampler(){}createDefaultTexture(){}createTexture(){}updateTexture(){}generateMipmaps(){}destroyTexture(){}async copyTextureToBuffer(){}copyTextureToTexture(){}copyFramebufferToTexture(){}createAttribute(){}createIndexAttribute(){}createStorageAttribute(){}updateAttribute(){}destroyAttribute(){}getContext(){}updateSize(){}updateViewport(){}updateTimeStampUID(e){const t=this.get(e),r=this.renderer.info.frame;let s;s=!0===e.isComputeNode?"c:"+this.renderer.info.compute.frameCalls:"r:"+this.renderer.info.render.frameCalls,t.timestampUID=s+":"+e.id+":f"+r}getTimestampUID(e){return this.get(e).timestampUID}getTimestampFrames(e){const t=this.timestampQueryPool[e];return t?t.getTimestampFrames():[]}_getQueryPool(e){const t=e.startsWith("c:")?Ct.COMPUTE:Ct.RENDER;return this.timestampQueryPool[t]}getTimestamp(e){return this._getQueryPool(e).getTimestamp(e)}hasTimestamp(e){return this._getQueryPool(e).hasTimestamp(e)}isOccluded(){}async resolveTimestampsAsync(e="render"){if(!this.trackTimestamp)return void v("WebGPURenderer: Timestamp tracking is disabled.");const t=this.timestampQueryPool[e];if(!t)return;const r=await t.resolveQueriesAsync();return this.renderer.info[e].timestamp=r,r}async getArrayBufferAsync(){}async hasFeatureAsync(){}hasFeature(){}getMaxAnisotropy(){}getDrawingBufferSize(){return iR=iR||new t,this.renderer.getDrawingBufferSize(iR)}setScissorTest(){}getClearColor(){const e=this.renderer;return nR=nR||new Ly,e.getClearColor(nR),nR.getRGB(nR),nR}getDomElement(){let e=this.domElement;return null===e&&(e=void 0!==this.parameters.canvas?this.parameters.canvas:Mt(),"setAttribute"in e&&e.setAttribute("data-engine",`three.js r${ut} webgpu`),this.domElement=e),e}hasCompatibility(){return!1}set(e,t){this.data.set(e,t)}get(e){let t=this.data.get(e);return void 0===t&&(t={},this.data.set(e,t)),t}has(e){return this.data.has(e)}delete(e){this.data.delete(e)}deleteBindGroupData(){}dispose(){}}let oR,uR,lR=0;class dR{constructor(e,t){this.buffers=[e.bufferGPU,t],this.type=e.type,this.bufferType=e.bufferType,this.pbo=e.pbo,this.byteLength=e.byteLength,this.bytesPerElement=e.BYTES_PER_ELEMENT,this.version=e.version,this.isInteger=e.isInteger,this.activeBufferIndex=0,this.baseId=e.id}get id(){return`${this.baseId}|${this.activeBufferIndex}`}get bufferGPU(){return this.buffers[this.activeBufferIndex]}get transformBuffer(){return this.buffers[1^this.activeBufferIndex]}switchBuffers(){this.activeBufferIndex^=1}}class cR{constructor(e){this.backend=e}createAttribute(e,t){const r=this.backend,{gl:s}=r,i=e.array,n=e.usage||s.STATIC_DRAW,a=e.isInterleavedBufferAttribute?e.data:e,o=r.get(a);let u,l=o.bufferGPU;if(void 0===l&&(l=this._createBuffer(s,t,i,n),o.bufferGPU=l,o.bufferType=t,o.version=a.version),i instanceof Float32Array)u=s.FLOAT;else if("undefined"!=typeof Float16Array&&i instanceof Float16Array)u=s.HALF_FLOAT;else if(i instanceof Uint16Array)u=e.isFloat16BufferAttribute?s.HALF_FLOAT:s.UNSIGNED_SHORT;else if(i instanceof Int16Array)u=s.SHORT;else if(i instanceof Uint32Array)u=s.UNSIGNED_INT;else if(i instanceof Int32Array)u=s.INT;else if(i instanceof Int8Array)u=s.BYTE;else if(i instanceof Uint8Array)u=s.UNSIGNED_BYTE;else{if(!(i instanceof Uint8ClampedArray))throw new Error("THREE.WebGLBackend: Unsupported buffer data format: "+i);u=s.UNSIGNED_BYTE}let d={bufferGPU:l,bufferType:t,type:u,byteLength:i.byteLength,bytesPerElement:i.BYTES_PER_ELEMENT,version:e.version,pbo:e.pbo,isInteger:u===s.INT||u===s.UNSIGNED_INT||e.gpuType===R,id:lR++};if(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute){const e=this._createBuffer(s,t,i,n);d=new dR(d,e)}r.set(e,d)}updateAttribute(e){const t=this.backend,{gl:r}=t,s=e.array,i=e.isInterleavedBufferAttribute?e.data:e,n=t.get(i),a=n.bufferType,o=e.isInterleavedBufferAttribute?e.data.updateRanges:e.updateRanges;if(r.bindBuffer(a,n.bufferGPU),0===o.length)r.bufferSubData(a,0,s);else{for(let e=0,t=o.length;e0?this.enable(s.SAMPLE_ALPHA_TO_COVERAGE):this.disable(s.SAMPLE_ALPHA_TO_COVERAGE),r>0&&this.currentClippingPlanes!==r){const e=12288;for(let t=0;t<8;t++)t{!function i(){const n=e.clientWaitSync(t,e.SYNC_FLUSH_COMMANDS_BIT,0);if(n===e.WAIT_FAILED)return e.deleteSync(t),void s();n!==e.TIMEOUT_EXPIRED?(e.deleteSync(t),r()):requestAnimationFrame(i)}()})}}let gR,mR,fR,yR=!1;class bR{constructor(e){this.backend=e,this.gl=e.gl,this.extensions=e.extensions,this.defaultTextures={},this._srcFramebuffer=null,this._dstFramebuffer=null,!1===yR&&(this._init(),yR=!0)}_init(){const e=this.gl;gR={[Vr]:e.REPEAT,[xe]:e.CLAMP_TO_EDGE,[Or]:e.MIRRORED_REPEAT},mR={[w]:e.NEAREST,[kr]:e.NEAREST_MIPMAP_NEAREST,[at]:e.NEAREST_MIPMAP_LINEAR,[oe]:e.LINEAR,[nt]:e.LINEAR_MIPMAP_NEAREST,[K]:e.LINEAR_MIPMAP_LINEAR},fR={[qr]:e.NEVER,[Hr]:e.ALWAYS,[A]:e.LESS,[Je]:e.LEQUAL,[Wr]:e.EQUAL,[$r]:e.GEQUAL,[zr]:e.GREATER,[Gr]:e.NOTEQUAL}}getGLTextureType(e){const{gl:t}=this;let r;return r=!0===e.isCubeTexture?t.TEXTURE_CUBE_MAP:!0===e.isArrayTexture||!0===e.isDataArrayTexture||!0===e.isCompressedArrayTexture?t.TEXTURE_2D_ARRAY:!0===e.isData3DTexture?t.TEXTURE_3D:t.TEXTURE_2D,r}getInternalFormat(e,t,r,s,i=!1){const{gl:n,extensions:a}=this;if(null!==e){if(void 0!==n[e])return n[e];d("WebGLBackend: Attempt to use non-existing WebGL internal format '"+e+"'")}let o=t;if(t===n.RED&&(r===n.FLOAT&&(o=n.R32F),r===n.HALF_FLOAT&&(o=n.R16F),r===n.UNSIGNED_BYTE&&(o=n.R8),r===n.UNSIGNED_SHORT&&(o=n.R16),r===n.UNSIGNED_INT&&(o=n.R32UI),r===n.BYTE&&(o=n.R8I),r===n.SHORT&&(o=n.R16I),r===n.INT&&(o=n.R32I)),t===n.RED_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.R8UI),r===n.UNSIGNED_SHORT&&(o=n.R16UI),r===n.UNSIGNED_INT&&(o=n.R32UI),r===n.BYTE&&(o=n.R8I),r===n.SHORT&&(o=n.R16I),r===n.INT&&(o=n.R32I)),t===n.RG&&(r===n.FLOAT&&(o=n.RG32F),r===n.HALF_FLOAT&&(o=n.RG16F),r===n.UNSIGNED_BYTE&&(o=n.RG8),r===n.UNSIGNED_SHORT&&(o=n.RG16),r===n.UNSIGNED_INT&&(o=n.RG32UI),r===n.BYTE&&(o=n.RG8I),r===n.SHORT&&(o=n.RG16I),r===n.INT&&(o=n.RG32I)),t===n.RG_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RG8UI),r===n.UNSIGNED_SHORT&&(o=n.RG16UI),r===n.UNSIGNED_INT&&(o=n.RG32UI),r===n.BYTE&&(o=n.RG8I),r===n.SHORT&&(o=n.RG16I),r===n.INT&&(o=n.RG32I)),t===n.RGB){const e=i?jr:p.getTransfer(s);r===n.FLOAT&&(o=n.RGB32F),r===n.HALF_FLOAT&&(o=n.RGB16F),r===n.UNSIGNED_BYTE&&(o=n.RGB8),r===n.UNSIGNED_SHORT&&(o=n.RGB16),r===n.UNSIGNED_INT&&(o=n.RGB32UI),r===n.BYTE&&(o=n.RGB8I),r===n.SHORT&&(o=n.RGB16I),r===n.INT&&(o=n.RGB32I),r===n.UNSIGNED_BYTE&&(o=e===g?n.SRGB8:n.RGB8),r===n.UNSIGNED_SHORT_5_6_5&&(o=n.RGB565),r===n.UNSIGNED_SHORT_5_5_5_1&&(o=n.RGB5_A1),r===n.UNSIGNED_SHORT_4_4_4_4&&(o=n.RGB4),r===n.UNSIGNED_INT_5_9_9_9_REV&&(o=n.RGB9_E5),r===n.UNSIGNED_INT_10F_11F_11F_REV&&(o=n.R11F_G11F_B10F)}if(t===n.RGB_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RGB8UI),r===n.UNSIGNED_SHORT&&(o=n.RGB16UI),r===n.UNSIGNED_INT&&(o=n.RGB32UI),r===n.BYTE&&(o=n.RGB8I),r===n.SHORT&&(o=n.RGB16I),r===n.INT&&(o=n.RGB32I)),t===n.RGBA){const e=i?jr:p.getTransfer(s);r===n.FLOAT&&(o=n.RGBA32F),r===n.HALF_FLOAT&&(o=n.RGBA16F),r===n.UNSIGNED_BYTE&&(o=n.RGBA8),r===n.UNSIGNED_SHORT&&(o=n.RGBA16),r===n.UNSIGNED_INT&&(o=n.RGBA32UI),r===n.BYTE&&(o=n.RGBA8I),r===n.SHORT&&(o=n.RGBA16I),r===n.INT&&(o=n.RGBA32I),r===n.UNSIGNED_BYTE&&(o=e===g?n.SRGB8_ALPHA8:n.RGBA8),r===n.UNSIGNED_SHORT_4_4_4_4&&(o=n.RGBA4),r===n.UNSIGNED_SHORT_5_5_5_1&&(o=n.RGB5_A1)}return t===n.RGBA_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RGBA8UI),r===n.UNSIGNED_SHORT&&(o=n.RGBA16UI),r===n.UNSIGNED_INT&&(o=n.RGBA32UI),r===n.BYTE&&(o=n.RGBA8I),r===n.SHORT&&(o=n.RGBA16I),r===n.INT&&(o=n.RGBA32I)),t===n.DEPTH_COMPONENT&&(r===n.UNSIGNED_SHORT&&(o=n.DEPTH_COMPONENT16),r===n.UNSIGNED_INT&&(o=n.DEPTH_COMPONENT24),r===n.FLOAT&&(o=n.DEPTH_COMPONENT32F)),t===n.DEPTH_STENCIL&&r===n.UNSIGNED_INT_24_8&&(o=n.DEPTH24_STENCIL8),o!==n.R16F&&o!==n.R32F&&o!==n.RG16F&&o!==n.RG32F&&o!==n.RGBA16F&&o!==n.RGBA32F||a.get("EXT_color_buffer_float"),o}setTextureParameters(e,t){const{gl:r,extensions:s,backend:i}=this,n=p.getPrimaries(p.workingColorSpace),a=t.colorSpace===T?null:p.getPrimaries(t.colorSpace),o=t.colorSpace===T||n===a?r.NONE:r.BROWSER_DEFAULT_WEBGL;r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,t.flipY),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),r.pixelStorei(r.UNPACK_ALIGNMENT,t.unpackAlignment),r.pixelStorei(r.UNPACK_COLORSPACE_CONVERSION_WEBGL,o),r.texParameteri(e,r.TEXTURE_WRAP_S,gR[t.wrapS]),r.texParameteri(e,r.TEXTURE_WRAP_T,gR[t.wrapT]),e!==r.TEXTURE_3D&&e!==r.TEXTURE_2D_ARRAY||t.isArrayTexture||r.texParameteri(e,r.TEXTURE_WRAP_R,gR[t.wrapR]),r.texParameteri(e,r.TEXTURE_MAG_FILTER,mR[t.magFilter]);const u=void 0!==t.mipmaps&&t.mipmaps.length>0,l=t.minFilter===oe&&u?K:t.minFilter;if(r.texParameteri(e,r.TEXTURE_MIN_FILTER,mR[l]),t.compareFunction&&(r.texParameteri(e,r.TEXTURE_COMPARE_MODE,r.COMPARE_REF_TO_TEXTURE),r.texParameteri(e,r.TEXTURE_COMPARE_FUNC,fR[t.compareFunction])),!0===s.has("EXT_texture_filter_anisotropic")){if(t.magFilter===w)return;if(t.minFilter!==at&&t.minFilter!==K)return;if(t.type===j&&!1===s.has("OES_texture_float_linear"))return;if(t.anisotropy>1){const n=s.get("EXT_texture_filter_anisotropic");r.texParameterf(e,n.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(t.anisotropy,i.getMaxAnisotropy()))}}}createDefaultTexture(e){const{gl:t,backend:r,defaultTextures:s}=this,i=this.getGLTextureType(e);let n=s[i];void 0===n&&(n=t.createTexture(),r.state.bindTexture(i,n),t.texParameteri(i,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(i,t.TEXTURE_MAG_FILTER,t.NEAREST),s[i]=n),r.set(e,{textureGPU:n,glTextureType:i})}createTexture(e,t){const{gl:r,backend:s}=this,{levels:i,width:n,height:a,depth:o}=t,u=s.utils.convert(e.format,e.colorSpace),l=s.utils.convert(e.type),d=this.getInternalFormat(e.internalFormat,u,l,e.colorSpace,e.isVideoTexture),c=r.createTexture(),h=this.getGLTextureType(e);s.state.bindTexture(h,c),this.setTextureParameters(h,e),e.isArrayTexture||e.isDataArrayTexture||e.isCompressedArrayTexture?r.texStorage3D(r.TEXTURE_2D_ARRAY,i,d,n,a,o):e.isData3DTexture?r.texStorage3D(r.TEXTURE_3D,i,d,n,a,o):e.isVideoTexture||r.texStorage2D(h,i,d,n,a),s.set(e,{textureGPU:c,glTextureType:h,glFormat:u,glType:l,glInternalFormat:d})}copyBufferToTexture(e,t){const{gl:r,backend:s}=this,{textureGPU:i,glTextureType:n,glFormat:a,glType:o}=s.get(t),{width:u,height:l}=t.source.data;r.bindBuffer(r.PIXEL_UNPACK_BUFFER,e),s.state.bindTexture(n,i),r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,!1),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),r.texSubImage2D(n,0,0,0,u,l,a,o,0),r.bindBuffer(r.PIXEL_UNPACK_BUFFER,null),s.state.unbindTexture()}updateTexture(e,t){const{gl:r}=this,{width:s,height:i}=t,{textureGPU:n,glTextureType:a,glFormat:o,glType:u,glInternalFormat:l}=this.backend.get(e);if(!e.isRenderTargetTexture&&void 0!==n)if(this.backend.state.bindTexture(a,n),this.setTextureParameters(a,e),e.isCompressedTexture){const s=e.mipmaps,i=t.image;for(let t=0;t0){const t=Xr(s.width,s.height,e.format,e.type);for(const i of e.layerUpdates){const e=s.data.subarray(i*t/s.data.BYTES_PER_ELEMENT,(i+1)*t/s.data.BYTES_PER_ELEMENT);r.texSubImage3D(r.TEXTURE_2D_ARRAY,0,0,0,i,s.width,s.height,1,o,u,e)}e.clearLayerUpdates()}else r.texSubImage3D(r.TEXTURE_2D_ARRAY,0,0,0,0,s.width,s.height,s.depth,o,u,s.data)}else if(e.isData3DTexture){const e=t.image;r.texSubImage3D(r.TEXTURE_3D,0,0,0,0,e.width,e.height,e.depth,o,u,e.data)}else if(e.isVideoTexture)e.update(),r.texImage2D(a,0,l,o,u,t.image);else{const n=e.mipmaps;if(n.length>0)for(let e=0,t=n.length;e0,c=t.renderTarget?t.renderTarget.height:this.backend.getDrawingBufferSize().y;if(d){const r=0!==a||0!==o;let d,h;if(!0===e.isDepthTexture?(d=s.DEPTH_BUFFER_BIT,h=s.DEPTH_ATTACHMENT,t.stencil&&(d|=s.STENCIL_BUFFER_BIT)):(d=s.COLOR_BUFFER_BIT,h=s.COLOR_ATTACHMENT0),r){const e=this.backend.get(t.renderTarget),r=e.framebuffers[t.getCacheKey()],h=e.msaaFrameBuffer;i.bindFramebuffer(s.DRAW_FRAMEBUFFER,r),i.bindFramebuffer(s.READ_FRAMEBUFFER,h);const p=c-o-l;s.blitFramebuffer(a,p,a+u,p+l,a,p,a+u,p+l,d,s.NEAREST),i.bindFramebuffer(s.READ_FRAMEBUFFER,r),i.bindTexture(s.TEXTURE_2D,n),s.copyTexSubImage2D(s.TEXTURE_2D,0,0,0,a,p,u,l),i.unbindTexture()}else{const e=s.createFramebuffer();i.bindFramebuffer(s.DRAW_FRAMEBUFFER,e),s.framebufferTexture2D(s.DRAW_FRAMEBUFFER,h,s.TEXTURE_2D,n,0),s.blitFramebuffer(0,0,u,l,0,0,u,l,d,s.NEAREST),s.deleteFramebuffer(e)}}else i.bindTexture(s.TEXTURE_2D,n),s.copyTexSubImage2D(s.TEXTURE_2D,0,0,0,a,c-l-o,u,l),i.unbindTexture();e.generateMipmaps&&this.generateMipmaps(e),this.backend._setFramebuffer(t)}setupRenderBufferStorage(e,t,r,s=!1){const{gl:i}=this,n=t.renderTarget,{depthTexture:a,depthBuffer:o,stencilBuffer:u,width:l,height:d}=n;if(i.bindRenderbuffer(i.RENDERBUFFER,e),o&&!u){let t=i.DEPTH_COMPONENT24;if(!0===s){this.extensions.get("WEBGL_multisampled_render_to_texture").renderbufferStorageMultisampleEXT(i.RENDERBUFFER,n.samples,t,l,d)}else r>0?(a&&a.isDepthTexture&&a.type===i.FLOAT&&(t=i.DEPTH_COMPONENT32F),i.renderbufferStorageMultisample(i.RENDERBUFFER,r,t,l,d)):i.renderbufferStorage(i.RENDERBUFFER,t,l,d);i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_ATTACHMENT,i.RENDERBUFFER,e)}else o&&u&&(r>0?i.renderbufferStorageMultisample(i.RENDERBUFFER,r,i.DEPTH24_STENCIL8,l,d):i.renderbufferStorage(i.RENDERBUFFER,i.DEPTH_STENCIL,l,d),i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_STENCIL_ATTACHMENT,i.RENDERBUFFER,e));i.bindRenderbuffer(i.RENDERBUFFER,null)}async copyTextureToBuffer(e,t,r,s,i,n){const{backend:a,gl:o}=this,{textureGPU:u,glFormat:l,glType:d}=this.backend.get(e),c=o.createFramebuffer();a.state.bindFramebuffer(o.READ_FRAMEBUFFER,c);const h=e.isCubeTexture?o.TEXTURE_CUBE_MAP_POSITIVE_X+n:o.TEXTURE_2D;o.framebufferTexture2D(o.READ_FRAMEBUFFER,o.COLOR_ATTACHMENT0,h,u,0);const p=this._getTypedArrayType(d),g=s*i*this._getBytesPerTexel(d,l),m=o.createBuffer();o.bindBuffer(o.PIXEL_PACK_BUFFER,m),o.bufferData(o.PIXEL_PACK_BUFFER,g,o.STREAM_READ),o.readPixels(t,r,s,i,l,d,0),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),await a.utils._clientWaitAsync();const f=new p(g/p.BYTES_PER_ELEMENT);return o.bindBuffer(o.PIXEL_PACK_BUFFER,m),o.getBufferSubData(o.PIXEL_PACK_BUFFER,0,f),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),a.state.bindFramebuffer(o.READ_FRAMEBUFFER,null),o.deleteFramebuffer(c),f}_getTypedArrayType(e){const{gl:t}=this;if(e===t.UNSIGNED_BYTE)return Uint8Array;if(e===t.UNSIGNED_SHORT_4_4_4_4)return Uint16Array;if(e===t.UNSIGNED_SHORT_5_5_5_1)return Uint16Array;if(e===t.UNSIGNED_SHORT_5_6_5)return Uint16Array;if(e===t.UNSIGNED_SHORT)return Uint16Array;if(e===t.UNSIGNED_INT)return Uint32Array;if(e===t.HALF_FLOAT)return Uint16Array;if(e===t.FLOAT)return Float32Array;throw new Error(`Unsupported WebGL type: ${e}`)}_getBytesPerTexel(e,t){const{gl:r}=this;let s=0;return e===r.UNSIGNED_BYTE&&(s=1),e!==r.UNSIGNED_SHORT_4_4_4_4&&e!==r.UNSIGNED_SHORT_5_5_5_1&&e!==r.UNSIGNED_SHORT_5_6_5&&e!==r.UNSIGNED_SHORT&&e!==r.HALF_FLOAT||(s=2),e!==r.UNSIGNED_INT&&e!==r.FLOAT||(s=4),t===r.RGBA?4*s:t===r.RGB?3*s:t===r.ALPHA?s:void 0}dispose(){const{gl:e}=this;null!==this._srcFramebuffer&&e.deleteFramebuffer(this._srcFramebuffer),null!==this._dstFramebuffer&&e.deleteFramebuffer(this._dstFramebuffer)}}function xR(e){return e.isDataTexture?e.image.data:"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas?e:e.data}class TR{constructor(e){this.backend=e,this.gl=this.backend.gl,this.availableExtensions=this.gl.getSupportedExtensions(),this.extensions={}}get(e){let t=this.extensions[e];return void 0===t&&(t=this.gl.getExtension(e),this.extensions[e]=t),t}has(e){return this.availableExtensions.includes(e)}}class _R{constructor(e){this.backend=e,this.maxAnisotropy=null}getMaxAnisotropy(){if(null!==this.maxAnisotropy)return this.maxAnisotropy;const e=this.backend.gl,t=this.backend.extensions;if(!0===t.has("EXT_texture_filter_anisotropic")){const r=t.get("EXT_texture_filter_anisotropic");this.maxAnisotropy=e.getParameter(r.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else this.maxAnisotropy=0;return this.maxAnisotropy}}const vR={WEBGL_multi_draw:"WEBGL_multi_draw",WEBGL_compressed_texture_astc:"texture-compression-astc",WEBGL_compressed_texture_etc:"texture-compression-etc2",WEBGL_compressed_texture_etc1:"texture-compression-etc1",WEBGL_compressed_texture_pvrtc:"texture-compression-pvrtc",WEBGL_compressed_texture_s3tc:"texture-compression-s3tc",EXT_texture_compression_bptc:"texture-compression-bc",EXT_disjoint_timer_query_webgl2:"timestamp-query",OVR_multiview2:"OVR_multiview2"};class NR{constructor(e){this.gl=e.gl,this.extensions=e.extensions,this.info=e.renderer.info,this.mode=null,this.index=0,this.type=null,this.object=null}render(e,t){const{gl:r,mode:s,object:i,type:n,info:a,index:o}=this;0!==o?r.drawElements(s,t,n,e):r.drawArrays(s,e,t),a.update(i,t,1)}renderInstances(e,t,r){const{gl:s,mode:i,type:n,index:a,object:o,info:u}=this;0!==r&&(0!==a?s.drawElementsInstanced(i,t,n,e,r):s.drawArraysInstanced(i,e,t,r),u.update(o,t,r))}renderMultiDraw(e,t,r){const{extensions:s,mode:i,object:n,info:a}=this;if(0===r)return;const o=s.get("WEBGL_multi_draw");if(null===o)for(let s=0;sthis.maxQueries)return v(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`),null;const t=this.currentQueryIndex;return this.currentQueryIndex+=2,this.queryStates.set(t,"inactive"),this.queryOffsets.set(e,t),t}beginQuery(e){if(!this.trackTimestamp||this.isDisposed)return;const t=this.queryOffsets.get(e);if(null==t)return;if(null!==this.activeQuery)return;const r=this.queries[t];if(r)try{"inactive"===this.queryStates.get(t)&&(this.gl.beginQuery(this.ext.TIME_ELAPSED_EXT,r),this.activeQuery=t,this.queryStates.set(t,"started"))}catch(e){o("Error in beginQuery:",e),this.activeQuery=null,this.queryStates.set(t,"inactive")}}endQuery(e){if(!this.trackTimestamp||this.isDisposed)return;const t=this.queryOffsets.get(e);if(null!=t&&this.activeQuery===t)try{this.gl.endQuery(this.ext.TIME_ELAPSED_EXT),this.queryStates.set(t,"ended"),this.activeQuery=null}catch(e){o("Error in endQuery:",e),this.queryStates.set(t,"inactive"),this.activeQuery=null}}async resolveQueriesAsync(){if(!this.trackTimestamp||this.pendingResolve)return this.lastValue;this.pendingResolve=!0;try{const e=new Map;for(const[t,r]of this.queryOffsets){if("ended"===this.queryStates.get(r)){const s=this.queries[r];e.set(t,this.resolveQuery(s))}}if(0===e.size)return this.lastValue;const t={},r=[];for(const[s,i]of e){const e=s.match(/^(.*):f(\d+)$/),n=parseInt(e[2]);!1===r.includes(n)&&r.push(n),void 0===t[n]&&(t[n]=0);const a=await i;this.timestamps.set(s,a),t[n]+=a}const s=t[r[r.length-1]];return this.lastValue=s,this.frames=r,this.currentQueryIndex=0,this.queryOffsets.clear(),this.queryStates.clear(),this.activeQuery=null,s}catch(e){return o("Error resolving queries:",e),this.lastValue}finally{this.pendingResolve=!1}}async resolveQuery(e){return new Promise(t=>{if(this.isDisposed)return void t(this.lastValue);let r,s=!1;const i=e=>{s||(s=!0,r&&(clearTimeout(r),r=null),t(e))},n=()=>{if(this.isDisposed)i(this.lastValue);else try{if(this.gl.getParameter(this.ext.GPU_DISJOINT_EXT))return void i(this.lastValue);if(!this.gl.getQueryParameter(e,this.gl.QUERY_RESULT_AVAILABLE))return void(r=setTimeout(n,1));const s=this.gl.getQueryParameter(e,this.gl.QUERY_RESULT);t(Number(s)/1e6)}catch(e){o("Error checking query:",e),t(this.lastValue)}};n()})}dispose(){if(!this.isDisposed&&(this.isDisposed=!0,this.trackTimestamp)){for(const e of this.queries)this.gl.deleteQuery(e);this.queries=[],this.queryStates.clear(),this.queryOffsets.clear(),this.lastValue=0,this.activeQuery=null}}}class ER extends aR{constructor(e={}){super(e),this.isWebGLBackend=!0,this.attributeUtils=null,this.extensions=null,this.capabilities=null,this.textureUtils=null,this.bufferRenderer=null,this.gl=null,this.state=null,this.utils=null,this.vaoCache={},this.transformFeedbackCache={},this.discard=!1,this.disjoint=null,this.parallel=null,this._currentContext=null,this._knownBindings=new WeakSet,this._supportsInvalidateFramebuffer="undefined"!=typeof navigator&&/OculusBrowser/g.test(navigator.userAgent),this._xrFramebuffer=null}init(e){super.init(e);const t=this.parameters,r={antialias:e.currentSamples>0,alpha:!0,depth:e.depth,stencil:e.stencil},s=void 0!==t.context?t.context:e.domElement.getContext("webgl2",r);function i(t){t.preventDefault();const r={api:"WebGL",message:t.statusMessage||"Unknown reason",reason:null,originalEvent:t};e.onDeviceLost(r)}this._onContextLost=i,e.domElement.addEventListener("webglcontextlost",i,!1),this.gl=s,this.extensions=new TR(this),this.capabilities=new _R(this),this.attributeUtils=new cR(this),this.textureUtils=new bR(this),this.bufferRenderer=new NR(this),this.state=new hR(this),this.utils=new pR(this),this.extensions.get("EXT_color_buffer_float"),this.extensions.get("WEBGL_clip_cull_distance"),this.extensions.get("OES_texture_float_linear"),this.extensions.get("EXT_color_buffer_half_float"),this.extensions.get("WEBGL_multisampled_render_to_texture"),this.extensions.get("WEBGL_render_shared_exponent"),this.extensions.get("WEBGL_multi_draw"),this.extensions.get("OVR_multiview2"),this.disjoint=this.extensions.get("EXT_disjoint_timer_query_webgl2"),this.parallel=this.extensions.get("KHR_parallel_shader_compile"),this.drawBuffersIndexedExt=this.extensions.get("OES_draw_buffers_indexed")}get coordinateSystem(){return c}async getArrayBufferAsync(e){return await this.attributeUtils.getArrayBufferAsync(e)}async makeXRCompatible(){!0!==this.gl.getContextAttributes().xrCompatible&&await this.gl.makeXRCompatible()}setXRTarget(e){this._xrFramebuffer=e}setXRRenderTargetTextures(e,t,r=null){const s=this.gl;if(this.set(e.texture,{textureGPU:t,glInternalFormat:s.RGBA8}),null!==r){const t=e.stencilBuffer?s.DEPTH24_STENCIL8:s.DEPTH_COMPONENT24;this.set(e.depthTexture,{textureGPU:r,glInternalFormat:t}),!0===this.extensions.has("WEBGL_multisampled_render_to_texture")&&!0===e._autoAllocateDepthBuffer&&!1===e.multiview&&d("WebGLBackend: Render-to-texture extension was disabled because an external texture was provided"),e._autoAllocateDepthBuffer=!1}}initTimestampQuery(e,t){if(!this.disjoint||!this.trackTimestamp)return;this.timestampQueryPool[e]||(this.timestampQueryPool[e]=new RR(this.gl,e,2048));const r=this.timestampQueryPool[e];null!==r.allocateQueriesForContext(t)&&r.beginQuery(t)}prepareTimestampBuffer(e,t){if(!this.disjoint||!this.trackTimestamp)return;this.timestampQueryPool[e].endQuery(t)}getContext(){return this.gl}beginRender(e){const{state:t}=this,r=this.get(e);if(e.viewport)this.updateViewport(e);else{const{width:e,height:r}=this.getDrawingBufferSize();t.viewport(0,0,e,r)}if(e.scissor){const{x:r,y:s,width:i,height:n}=e.scissorValue;t.scissor(r,e.height-n-s,i,n)}this.initTimestampQuery(Ct.RENDER,this.getTimestampUID(e)),r.previousContext=this._currentContext,this._currentContext=e,this._setFramebuffer(e),this.clear(e.clearColor,e.clearDepth,e.clearStencil,e,!1);const s=e.occlusionQueryCount;s>0&&(r.currentOcclusionQueries=r.occlusionQueries,r.currentOcclusionQueryObjects=r.occlusionQueryObjects,r.lastOcclusionObject=null,r.occlusionQueries=new Array(s),r.occlusionQueryObjects=new Array(s),r.occlusionQueryIndex=0)}finishRender(e){const{gl:t,state:r}=this,s=this.get(e),i=s.previousContext;r.resetVertexState();const n=e.occlusionQueryCount;n>0&&(n>s.occlusionQueryIndex&&t.endQuery(t.ANY_SAMPLES_PASSED),this.resolveOccludedAsync(e));const a=e.textures;if(null!==a)for(let e=0;e{let a=0;for(let t=0;t{t.isBatchedMesh?null!==t._multiDrawInstances?(v("WebGLBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."),b.renderMultiDrawInstances(t._multiDrawStarts,t._multiDrawCounts,t._multiDrawCount,t._multiDrawInstances)):this.hasFeature("WEBGL_multi_draw")?b.renderMultiDraw(t._multiDrawStarts,t._multiDrawCounts,t._multiDrawCount):v("WebGLBackend: WEBGL_multi_draw not supported."):T>1?b.renderInstances(_,x,T):b.render(_,x)};if(!0===e.camera.isArrayCamera&&e.camera.cameras.length>0&&!1===e.camera.isMultiViewCamera){const r=this.get(e.camera),s=e.camera.cameras,i=e.getBindingGroup("cameraIndex").bindings[0];if(void 0===r.indexesGPU||r.indexesGPU.length!==s.length){const e=new Uint32Array([0,0,0,0]),t=[];for(let r=0,i=s.length;r{const i=this.parallel,n=()=>{r.getProgramParameter(a,i.COMPLETION_STATUS_KHR)?(this._completeCompile(e,s),t()):requestAnimationFrame(n)};n()});return void t.push(i)}this._completeCompile(e,s)}_handleSource(e,t){const r=e.split("\n"),s=[],i=Math.max(t-6,0),n=Math.min(t+6,r.length);for(let e=i;e":" "} ${i}: ${r[e]}`)}return s.join("\n")}_getShaderErrors(e,t,r){const s=e.getShaderParameter(t,e.COMPILE_STATUS),i=(e.getShaderInfoLog(t)||"").trim();if(s&&""===i)return"";const n=/ERROR: 0:(\d+)/.exec(i);if(n){const s=parseInt(n[1]);return r.toUpperCase()+"\n\n"+i+"\n\n"+this._handleSource(e.getShaderSource(t),s)}return i}_logProgramError(e,t,r){if(this.renderer.debug.checkShaderErrors){const s=this.gl,i=(s.getProgramInfoLog(e)||"").trim();if(!1===s.getProgramParameter(e,s.LINK_STATUS))if("function"==typeof this.renderer.debug.onShaderError)this.renderer.debug.onShaderError(s,e,r,t);else{const n=this._getShaderErrors(s,r,"vertex"),a=this._getShaderErrors(s,t,"fragment");o("THREE.WebGLProgram: Shader Error "+s.getError()+" - VALIDATE_STATUS "+s.getProgramParameter(e,s.VALIDATE_STATUS)+"\n\nProgram Info Log: "+i+"\n"+n+"\n"+a)}else""!==i&&d("WebGLProgram: Program Info Log:",i)}}_completeCompile(e,t){const{state:r,gl:s}=this,i=this.get(t),{programGPU:n,fragmentShader:a,vertexShader:o}=i;!1===s.getProgramParameter(n,s.LINK_STATUS)&&this._logProgramError(n,a,o),r.useProgram(n);const u=e.getBindings();this._setupBindings(u,n),this.set(t,{programGPU:n})}createComputePipeline(e,t){const{state:r,gl:s}=this,i={stage:"fragment",code:"#version 300 es\nprecision highp float;\nvoid main() {}"};this.createProgram(i);const{computeProgram:n}=e,a=s.createProgram(),o=this.get(i).shaderGPU,u=this.get(n).shaderGPU,l=n.transforms,d=[],c=[];for(let e=0;evR[t]===e),r=this.extensions;for(let e=0;e1,h=!0===i.isXRRenderTarget,p=!0===h&&!0===i._hasExternalTextures;let g=n.msaaFrameBuffer,m=n.depthRenderbuffer;const f=this.extensions.get("WEBGL_multisampled_render_to_texture"),y=this.extensions.get("OVR_multiview2"),b=this._useMultisampledExtension(i),x=wy(e);let T;if(l?(n.cubeFramebuffers||(n.cubeFramebuffers={}),T=n.cubeFramebuffers[x]):h&&!1===p?T=this._xrFramebuffer:(n.framebuffers||(n.framebuffers={}),T=n.framebuffers[x]),void 0===T){T=t.createFramebuffer(),r.bindFramebuffer(t.FRAMEBUFFER,T);const s=e.textures,o=[];if(l){n.cubeFramebuffers[x]=T;const{textureGPU:e}=this.get(s[0]),r=this.renderer._activeCubeFace,i=this.renderer._activeMipmapLevel;t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_CUBE_MAP_POSITIVE_X+r,e,i)}else{n.framebuffers[x]=T;for(let r=0;r0&&!1===b&&!i.multiview){if(void 0===g){const s=[];g=t.createFramebuffer(),r.bindFramebuffer(t.FRAMEBUFFER,g);const i=[],l=e.textures;for(let r=0;r0&&!1===this._useMultisampledExtension(s)){const n=i.framebuffers[e.getCacheKey()];let a=t.COLOR_BUFFER_BIT;s.resolveDepthBuffer&&(s.depthBuffer&&(a|=t.DEPTH_BUFFER_BIT),s.stencilBuffer&&s.resolveStencilBuffer&&(a|=t.STENCIL_BUFFER_BIT));const o=i.msaaFrameBuffer,u=i.msaaRenderbuffers,l=e.textures,d=l.length>1;if(r.bindFramebuffer(t.READ_FRAMEBUFFER,o),r.bindFramebuffer(t.DRAW_FRAMEBUFFER,n),d)for(let e=0;e0&&!0===this.extensions.has("WEBGL_multisampled_render_to_texture")&&!1!==e._autoAllocateDepthBuffer}dispose(){null!==this.textureUtils&&this.textureUtils.dispose();const e=this.extensions.get("WEBGL_lose_context");e&&e.loseContext(),this.renderer.domElement.removeEventListener("webglcontextlost",this._onContextLost)}}const AR="point-list",wR="line-list",CR="line-strip",MR="triangle-list",FR="triangle-strip",LR="undefined"!=typeof self&&self.GPUShaderStage?self.GPUShaderStage:{VERTEX:1,FRAGMENT:2,COMPUTE:4},PR="never",BR="less",DR="equal",UR="less-equal",IR="greater",OR="not-equal",VR="greater-equal",kR="always",GR="store",zR="load",$R="clear",WR="ccw",HR="cw",qR="none",jR="back",XR="uint16",KR="uint32",YR="r8unorm",QR="r8snorm",ZR="r8uint",JR="r8sint",eE="r16uint",tE="r16sint",rE="r16float",sE="rg8unorm",iE="rg8snorm",nE="rg8uint",aE="rg8sint",oE="r32uint",uE="r32sint",lE="r32float",dE="rg16uint",cE="rg16sint",hE="rg16float",pE="rgba8unorm",gE="rgba8unorm-srgb",mE="rgba8snorm",fE="rgba8uint",yE="rgba8sint",bE="bgra8unorm",xE="bgra8unorm-srgb",TE="rgb9e5ufloat",_E="rgb10a2unorm",vE="rg11b10ufloat",NE="rg32uint",SE="rg32sint",RE="rg32float",EE="rgba16uint",AE="rgba16sint",wE="rgba16float",CE="rgba32uint",ME="rgba32sint",FE="rgba32float",LE="depth16unorm",PE="depth24plus",BE="depth24plus-stencil8",DE="depth32float",UE="depth32float-stencil8",IE="bc1-rgba-unorm",OE="bc1-rgba-unorm-srgb",VE="bc2-rgba-unorm",kE="bc2-rgba-unorm-srgb",GE="bc3-rgba-unorm",zE="bc3-rgba-unorm-srgb",$E="bc4-r-unorm",WE="bc4-r-snorm",HE="bc5-rg-unorm",qE="bc5-rg-snorm",jE="bc6h-rgb-ufloat",XE="bc6h-rgb-float",KE="bc7-rgba-unorm",YE="bc7-rgba-unorm-srgb",QE="etc2-rgb8unorm",ZE="etc2-rgb8unorm-srgb",JE="etc2-rgb8a1unorm",eA="etc2-rgb8a1unorm-srgb",tA="etc2-rgba8unorm",rA="etc2-rgba8unorm-srgb",sA="eac-r11unorm",iA="eac-r11snorm",nA="eac-rg11unorm",aA="eac-rg11snorm",oA="astc-4x4-unorm",uA="astc-4x4-unorm-srgb",lA="astc-5x4-unorm",dA="astc-5x4-unorm-srgb",cA="astc-5x5-unorm",hA="astc-5x5-unorm-srgb",pA="astc-6x5-unorm",gA="astc-6x5-unorm-srgb",mA="astc-6x6-unorm",fA="astc-6x6-unorm-srgb",yA="astc-8x5-unorm",bA="astc-8x5-unorm-srgb",xA="astc-8x6-unorm",TA="astc-8x6-unorm-srgb",_A="astc-8x8-unorm",vA="astc-8x8-unorm-srgb",NA="astc-10x5-unorm",SA="astc-10x5-unorm-srgb",RA="astc-10x6-unorm",EA="astc-10x6-unorm-srgb",AA="astc-10x8-unorm",wA="astc-10x8-unorm-srgb",CA="astc-10x10-unorm",MA="astc-10x10-unorm-srgb",FA="astc-12x10-unorm",LA="astc-12x10-unorm-srgb",PA="astc-12x12-unorm",BA="astc-12x12-unorm-srgb",DA="clamp-to-edge",UA="repeat",IA="mirror-repeat",OA="linear",VA="nearest",kA="zero",GA="one",zA="src",$A="one-minus-src",WA="src-alpha",HA="one-minus-src-alpha",qA="dst",jA="one-minus-dst",XA="dst-alpha",KA="one-minus-dst-alpha",YA="src-alpha-saturated",QA="constant",ZA="one-minus-constant",JA="add",ew="subtract",tw="reverse-subtract",rw="min",sw="max",iw=0,nw=15,aw="keep",ow="zero",uw="replace",lw="invert",dw="increment-clamp",cw="decrement-clamp",hw="increment-wrap",pw="decrement-wrap",gw="storage",mw="read-only-storage",fw="write-only",yw="read-only",bw="read-write",xw="non-filtering",Tw="comparison",_w="float",vw="unfilterable-float",Nw="depth",Sw="sint",Rw="uint",Ew="2d",Aw="3d",ww="2d",Cw="2d-array",Mw="cube",Fw="3d",Lw="all",Pw="vertex",Bw="instance",Dw={CoreFeaturesAndLimits:"core-features-and-limits",DepthClipControl:"depth-clip-control",Depth32FloatStencil8:"depth32float-stencil8",TextureCompressionBC:"texture-compression-bc",TextureCompressionBCSliced3D:"texture-compression-bc-sliced-3d",TextureCompressionETC2:"texture-compression-etc2",TextureCompressionASTC:"texture-compression-astc",TextureCompressionASTCSliced3D:"texture-compression-astc-sliced-3d",TimestampQuery:"timestamp-query",IndirectFirstInstance:"indirect-first-instance",ShaderF16:"shader-f16",RG11B10UFloat:"rg11b10ufloat-renderable",BGRA8UNormStorage:"bgra8unorm-storage",Float32Filterable:"float32-filterable",Float32Blendable:"float32-blendable",ClipDistances:"clip-distances",DualSourceBlending:"dual-source-blending",Subgroups:"subgroups",TextureFormatsTier1:"texture-formats-tier1",TextureFormatsTier2:"texture-formats-tier2"},Uw={"texture-compression-s3tc":"texture-compression-bc","texture-compression-etc1":"texture-compression-etc2"};class Iw extends WS{constructor(e,t,r){super(e,t?t.value:null),this.textureNode=t,this.groupNode=r}update(){const{textureNode:e}=this;return this.texture!==e.value?(this.texture=e.value,!0):super.update()}}class Ow extends IS{constructor(e,t){super(e,t?t.array:null),this._attribute=t,this.isStorageBuffer=!0}get attribute(){return this._attribute}}let Vw=0;class kw extends Ow{constructor(e,t){super("StorageBuffer_"+Vw++,e?e.value:null),this.nodeUniform=e,this.access=e?e.access:ti.READ_WRITE,this.groupNode=t}get attribute(){return this.nodeUniform.value}get buffer(){return this.nodeUniform.value.array}}class Gw extends ry{constructor(e){super(),this.device=e;this.mipmapSampler=e.createSampler({minFilter:OA}),this.flipYSampler=e.createSampler({minFilter:VA}),this.transferPipelines={},this.flipYPipelines={},this.mipmapVertexShaderModule=e.createShaderModule({label:"mipmapVertex",code:"\nstruct VarysStruct {\n\t@builtin( position ) Position: vec4,\n\t@location( 0 ) vTex : vec2\n};\n\n@vertex\nfn main( @builtin( vertex_index ) vertexIndex : u32 ) -> VarysStruct {\n\n\tvar Varys : VarysStruct;\n\n\tvar pos = array< vec2, 4 >(\n\t\tvec2( -1.0, 1.0 ),\n\t\tvec2( 1.0, 1.0 ),\n\t\tvec2( -1.0, -1.0 ),\n\t\tvec2( 1.0, -1.0 )\n\t);\n\n\tvar tex = array< vec2, 4 >(\n\t\tvec2( 0.0, 0.0 ),\n\t\tvec2( 1.0, 0.0 ),\n\t\tvec2( 0.0, 1.0 ),\n\t\tvec2( 1.0, 1.0 )\n\t);\n\n\tVarys.vTex = tex[ vertexIndex ];\n\tVarys.Position = vec4( pos[ vertexIndex ], 0.0, 1.0 );\n\n\treturn Varys;\n\n}\n"}),this.mipmapFragmentShaderModule=e.createShaderModule({label:"mipmapFragment",code:"\n@group( 0 ) @binding( 0 )\nvar imgSampler : sampler;\n\n@group( 0 ) @binding( 1 )\nvar img : texture_2d;\n\n@fragment\nfn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( img, imgSampler, vTex );\n\n}\n"}),this.flipYFragmentShaderModule=e.createShaderModule({label:"flipYFragment",code:"\n@group( 0 ) @binding( 0 )\nvar imgSampler : sampler;\n\n@group( 0 ) @binding( 1 )\nvar img : texture_2d;\n\n@fragment\nfn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( img, imgSampler, vec2( vTex.x, 1.0 - vTex.y ) );\n\n}\n"})}getTransferPipeline(e){let t=this.transferPipelines[e];return void 0===t&&(t=this.device.createRenderPipeline({label:`mipmap-${e}`,vertex:{module:this.mipmapVertexShaderModule,entryPoint:"main"},fragment:{module:this.mipmapFragmentShaderModule,entryPoint:"main",targets:[{format:e}]},primitive:{topology:FR,stripIndexFormat:KR},layout:"auto"}),this.transferPipelines[e]=t),t}getFlipYPipeline(e){let t=this.flipYPipelines[e];return void 0===t&&(t=this.device.createRenderPipeline({label:`flipY-${e}`,vertex:{module:this.mipmapVertexShaderModule,entryPoint:"main"},fragment:{module:this.flipYFragmentShaderModule,entryPoint:"main",targets:[{format:e}]},primitive:{topology:FR,stripIndexFormat:KR},layout:"auto"}),this.flipYPipelines[e]=t),t}flipY(e,t,r=0){const s=t.format,{width:i,height:n}=t.size,a=this.getTransferPipeline(s),o=this.getFlipYPipeline(s),u=this.device.createTexture({size:{width:i,height:n,depthOrArrayLayers:1},format:s,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),l=e.createView({baseMipLevel:0,mipLevelCount:1,dimension:ww,baseArrayLayer:r}),d=u.createView({baseMipLevel:0,mipLevelCount:1,dimension:ww,baseArrayLayer:0}),c=this.device.createCommandEncoder({}),h=(e,t,r)=>{const s=e.getBindGroupLayout(0),i=this.device.createBindGroup({layout:s,entries:[{binding:0,resource:this.flipYSampler},{binding:1,resource:t}]}),n=c.beginRenderPass({colorAttachments:[{view:r,loadOp:$R,storeOp:GR,clearValue:[0,0,0,0]}]});n.setPipeline(e),n.setBindGroup(0,i),n.draw(4,1,0,0),n.end()};h(a,l,d),h(o,d,l),this.device.queue.submit([c.finish()]),u.destroy()}generateMipmaps(e,t,r=0,s=null){const i=this.get(e);void 0===i.layers&&(i.layers=[]);const n=i.layers[r]||this._mipmapCreateBundles(e,t,r),a=s||this.device.createCommandEncoder({label:"mipmapEncoder"});this._mipmapRunBundles(a,n),null===s&&this.device.queue.submit([a.finish()]),i.layers[r]=n}_mipmapCreateBundles(e,t,r){const s=this.getTransferPipeline(t.format),i=s.getBindGroupLayout(0);let n=e.createView({baseMipLevel:0,mipLevelCount:1,dimension:ww,baseArrayLayer:r});const a=[];for(let o=1;o0)for(let t=0,n=s.length;t0)for(let t=0,n=s.length;t0?e.width:r.size.width,l=a>0?e.height:r.size.height;try{o.queue.copyExternalImageToTexture({source:e,flipY:i},{texture:t,mipLevel:a,origin:{x:0,y:0,z:s},premultipliedAlpha:n},{width:u,height:l,depthOrArrayLayers:1})}catch(e){}}_getPassUtils(){let e=this._passUtils;return null===e&&(this._passUtils=e=new Gw(this.backend.device)),e}_generateMipmaps(e,t,r=0,s=null){this._getPassUtils().generateMipmaps(e,t,r,s)}_flipY(e,t,r=0){this._getPassUtils().flipY(e,t,r)}_copyBufferToTexture(e,t,r,s,i,n=0,a=0){const o=this.backend.device,u=e.data,l=this._getBytesPerTexel(r.format),d=e.width*l;o.queue.writeTexture({texture:t,mipLevel:a,origin:{x:0,y:0,z:s}},u,{offset:e.width*e.height*l*n,bytesPerRow:d},{width:e.width,height:e.height,depthOrArrayLayers:1}),!0===i&&this._flipY(t,r,s)}_copyCompressedBufferToTexture(e,t,r){const s=this.backend.device,i=this._getBlockData(r.format),n=r.size.depthOrArrayLayers>1;for(let a=0;a]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i,jw=/([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi,Xw={f32:"float",i32:"int",u32:"uint",bool:"bool","vec2":"vec2","vec2":"ivec2","vec2":"uvec2","vec2":"bvec2",vec2f:"vec2",vec2i:"ivec2",vec2u:"uvec2",vec2b:"bvec2","vec3":"vec3","vec3":"ivec3","vec3":"uvec3","vec3":"bvec3",vec3f:"vec3",vec3i:"ivec3",vec3u:"uvec3",vec3b:"bvec3","vec4":"vec4","vec4":"ivec4","vec4":"uvec4","vec4":"bvec4",vec4f:"vec4",vec4i:"ivec4",vec4u:"uvec4",vec4b:"bvec4","mat2x2":"mat2",mat2x2f:"mat2","mat3x3":"mat3",mat3x3f:"mat3","mat4x4":"mat4",mat4x4f:"mat4",sampler:"sampler",texture_1d:"texture",texture_2d:"texture",texture_2d_array:"texture",texture_multisampled_2d:"cubeTexture",texture_depth_2d:"depthTexture",texture_depth_2d_array:"depthTexture",texture_depth_multisampled_2d:"depthTexture",texture_depth_cube:"depthTexture",texture_depth_cube_array:"depthTexture",texture_3d:"texture3D",texture_cube:"cubeTexture",texture_cube_array:"cubeTexture",texture_storage_1d:"storageTexture",texture_storage_2d:"storageTexture",texture_storage_2d_array:"storageTexture",texture_storage_3d:"storageTexture"};class Kw extends QN{constructor(e){const{type:t,inputs:r,name:s,inputsCode:i,blockCode:n,outputType:a}=(e=>{const t=(e=e.trim()).match(qw);if(null!==t&&4===t.length){const r=t[2],s=[];let i=null;for(;null!==(i=jw.exec(r));)s.push({name:i[1],type:i[2]});const n=[];for(let e=0;e "+this.outputType:"";return`fn ${e} ( ${this.inputsCode.trim()} ) ${t}`+this.blockCode}}class Yw extends YN{parseFunction(e){return new Kw(e)}}const Qw={[ti.READ_ONLY]:"read",[ti.WRITE_ONLY]:"write",[ti.READ_WRITE]:"read_write"},Zw={[Vr]:"repeat",[xe]:"clamp",[Or]:"mirror"},Jw={vertex:LR.VERTEX,fragment:LR.FRAGMENT,compute:LR.COMPUTE},eC={instance:!0,swizzleAssign:!1,storageBuffer:!0},tC={"^^":"tsl_xor"},rC={float:"f32",int:"i32",uint:"u32",bool:"bool",color:"vec3",vec2:"vec2",ivec2:"vec2",uvec2:"vec2",bvec2:"vec2",vec3:"vec3",ivec3:"vec3",uvec3:"vec3",bvec3:"vec3",vec4:"vec4",ivec4:"vec4",uvec4:"vec4",bvec4:"vec4",mat2:"mat2x2",mat3:"mat3x3",mat4:"mat4x4"},sC={},iC={tsl_xor:new Xx("fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }"),mod_float:new Xx("fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }"),mod_vec2:new Xx("fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }"),mod_vec3:new Xx("fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }"),mod_vec4:new Xx("fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }"),equals_bool:new Xx("fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }"),equals_bvec2:new Xx("fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }"),equals_bvec3:new Xx("fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }"),equals_bvec4:new Xx("fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }"),repeatWrapping_float:new Xx("fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }"),mirrorWrapping_float:new Xx("fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }"),clampWrapping_float:new Xx("fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }"),biquadraticTexture:new Xx("\nfn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, iRes : vec2u, level : u32 ) -> vec4f {\n\n\tlet res = vec2f( iRes );\n\n\tlet uvScaled = coord * res;\n\tlet uvWrapping = ( ( uvScaled % res ) + res ) % res;\n\n\t// https://www.shadertoy.com/view/WtyXRy\n\n\tlet uv = uvWrapping - 0.5;\n\tlet iuv = floor( uv );\n\tlet f = fract( uv );\n\n\tlet rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, level );\n\tlet rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, level );\n\tlet rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, level );\n\tlet rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, level );\n\n\treturn mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );\n\n}\n")},nC={dFdx:"dpdx",dFdy:"- dpdy",mod_float:"tsl_mod_float",mod_vec2:"tsl_mod_vec2",mod_vec3:"tsl_mod_vec3",mod_vec4:"tsl_mod_vec4",equals_bool:"tsl_equals_bool",equals_bvec2:"tsl_equals_bvec2",equals_bvec3:"tsl_equals_bvec3",equals_bvec4:"tsl_equals_bvec4",inversesqrt:"inverseSqrt",bitcast:"bitcast",floatpack_snorm_2x16:"pack2x16snorm",floatpack_unorm_2x16:"pack2x16unorm",floatpack_float16_2x16:"pack2x16float",floatunpack_snorm_2x16:"unpack2x16snorm",floatunpack_unorm_2x16:"unpack2x16unorm",floatunpack_float16_2x16:"unpack2x16float"};let aC="";!0!==("undefined"!=typeof navigator&&/Firefox|Deno/g.test(navigator.userAgent))&&(aC+="diagnostic( off, derivative_uniformity );\n");class oC extends DN{constructor(e,t){super(e,t,new Yw),this.uniformGroups={},this.uniformGroupsBindings={},this.builtins={},this.directives={},this.scopedArrays=new Map}_generateTextureSample(e,t,r,s,i,n=this.shaderStage){return"fragment"===n?s?i?`textureSample( ${t}, ${t}_sampler, ${r}, ${s}, ${i} )`:`textureSample( ${t}, ${t}_sampler, ${r}, ${s} )`:i?`textureSample( ${t}, ${t}_sampler, ${r}, ${i} )`:`textureSample( ${t}, ${t}_sampler, ${r} )`:this.generateTextureSampleLevel(e,t,r,"0",s)}generateTextureSampleLevel(e,t,r,s,i,n){return!1===this.isUnfilterable(e)?n?`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s} )`:this.isFilteredTexture(e)?this.generateFilteredTexture(e,t,r,n,s):this.generateTextureLod(e,t,r,i,n,s)}generateWrapFunction(e){const t=`tsl_coord_${Zw[e.wrapS]}S_${Zw[e.wrapT]}_${e.is3DTexture||e.isData3DTexture?"3d":"2d"}T`;let r=sC[t];if(void 0===r){const s=[],i=e.is3DTexture||e.isData3DTexture?"vec3f":"vec2f";let n=`fn ${t}( coord : ${i} ) -> ${i} {\n\n\treturn ${i}(\n`;const a=(e,t)=>{e===Vr?(s.push(iC.repeatWrapping_float),n+=`\t\ttsl_repeatWrapping_float( coord.${t} )`):e===xe?(s.push(iC.clampWrapping_float),n+=`\t\ttsl_clampWrapping_float( coord.${t} )`):e===Or?(s.push(iC.mirrorWrapping_float),n+=`\t\ttsl_mirrorWrapping_float( coord.${t} )`):(n+=`\t\tcoord.${t}`,d(`WebGPURenderer: Unsupported texture wrap type "${e}" for vertex shader.`))};a(e.wrapS,"x"),n+=",\n",a(e.wrapT,"y"),(e.is3DTexture||e.isData3DTexture)&&(n+=",\n",a(e.wrapR,"z")),n+="\n\t);\n\n}\n",sC[t]=r=new Xx(n,s)}return r.build(this),t}generateArrayDeclaration(e,t){return`array< ${this.getType(e)}, ${t} >`}generateTextureDimension(e,t,r){const s=this.getDataFromNode(e,this.shaderStage,this.globalCache);void 0===s.dimensionsSnippet&&(s.dimensionsSnippet={});let i=s.dimensionsSnippet[r];if(void 0===s.dimensionsSnippet[r]){let n,a;const{primarySamples:o}=this.renderer.backend.utils.getTextureSampleData(e),u=o>1;a=e.is3DTexture||e.isData3DTexture?"vec3":"vec2",n=u||e.isStorageTexture?t:`${t}${r?`, u32( ${r} )`:""}`,i=new Eu(new pl(`textureDimensions( ${n} )`,a)),s.dimensionsSnippet[r]=i,(e.isArrayTexture||e.isDataArrayTexture||e.is3DTexture||e.isData3DTexture)&&(s.arrayLayerCount=new Eu(new pl(`textureNumLayers(${t})`,"u32"))),e.isTextureCube&&(s.cubeFaceCount=new Eu(new pl("6u","u32")))}return i.build(this)}generateFilteredTexture(e,t,r,s,i="0u"){this._include("biquadraticTexture");const n=this.generateWrapFunction(e),a=this.generateTextureDimension(e,t,i);return s&&(r=`${r} + vec2(${s}) / ${a}`),`tsl_biquadraticTexture( ${t}, ${n}( ${r} ), ${a}, u32( ${i} ) )`}generateTextureLod(e,t,r,s,i,n="0u"){if(!0===e.isCubeTexture){i&&(r=`${r} + vec3(${i})`);return`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${e.isDepthTexture?"u32":"f32"}( ${n} ) )`}const a=this.generateWrapFunction(e),o=this.generateTextureDimension(e,t,n),u=e.is3DTexture||e.isData3DTexture?"vec3":"vec2";i&&(r=`${r} + ${u}(${i}) / ${u}( ${o} )`);return r=`${u}( clamp( floor( ${a}( ${r} ) * ${u}( ${o} ) ), ${`${u}( 0 )`}, ${`${u}( ${o} - ${"vec3"===u?"vec3( 1, 1, 1 )":"vec2( 1, 1 )"} )`} ) )`,this.generateTextureLoad(e,t,r,n,s,null)}generateTextureLoad(e,t,r,s,i,n){const a=!0===e.isStorageTexture;let o;return null!==s||a||(s="0u"),n&&(r=`${r} + ${n}`),i?o=a?`textureLoad( ${t}, ${r}, ${i} )`:`textureLoad( ${t}, ${r}, ${i}, u32( ${s} ) )`:a?o=`textureLoad( ${t}, ${r} )`:(o=`textureLoad( ${t}, ${r}, u32( ${s} ) )`,this.renderer.backend.compatibilityMode&&e.isDepthTexture&&(o+=".x")),o}generateTextureStore(e,t,r,s,i){let n;return n=s?`textureStore( ${t}, ${r}, ${s}, ${i} )`:`textureStore( ${t}, ${r}, ${i} )`,n}isSampleCompare(e){return!0===e.isDepthTexture&&null!==e.compareFunction&&this.renderer.hasCompatibility(E.TEXTURE_COMPARE)}isUnfilterable(e){return"float"!==this.getComponentTypeFromTexture(e)||!this.isAvailable("float32Filterable")&&!0===e.isDataTexture&&e.type===j||!1===this.isSampleCompare(e)&&e.minFilter===w&&e.magFilter===w||this.renderer.backend.utils.getTextureSampleData(e).primarySamples>1}generateTexture(e,t,r,s,i,n=this.shaderStage){let a=null;return a=this.isUnfilterable(e)?this.generateTextureLod(e,t,r,s,i,"0",n):this._generateTextureSample(e,t,r,s,i,n),a}generateTextureGrad(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return n?`textureSampleGrad( ${t}, ${t}_sampler, ${r}, ${s[0]}, ${s[1]}, ${n} )`:`textureSampleGrad( ${t}, ${t}_sampler, ${r}, ${s[0]}, ${s[1]} )`;o(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${a} shader.`)}generateTextureCompare(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return!0===e.isDepthTexture&&!0===e.isArrayTexture?n?`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${i}, ${s}, ${n} )`:`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${i}, ${s} )`:n?`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${s} )`;o(`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${a} shader.`)}generateTextureLevel(e,t,r,s,i,n){return!1===this.isUnfilterable(e)?n?`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s} )`:this.isFilteredTexture(e)?this.generateFilteredTexture(e,t,r,n,s):this.generateTextureLod(e,t,r,i,n,s)}generateTextureBias(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return n?`textureSampleBias( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleBias( ${t}, ${t}_sampler, ${r}, ${s} )`;o(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${a} shader.`)}getPropertyName(e,t=this.shaderStage){if(!0===e.isNodeVarying&&!0===e.needsInterpolation){if("vertex"===t)return`varyings.${e.name}`}else if(!0===e.isNodeUniform){const t=e.name,r=e.type;return"texture"===r||"cubeTexture"===r||"cubeDepthTexture"===r||"storageTexture"===r||"texture3D"===r?t:"buffer"===r||"storageBuffer"===r||"indirectStorageBuffer"===r?this.isCustomStruct(e)?t:t+".value":e.groupNode.name+"."+t}return super.getPropertyName(e)}getOutputStructName(){return"output"}getFunctionOperator(e){const t=tC[e];return void 0!==t?(this._include(t),t):null}getNodeAccess(e,t){return"compute"!==t?!0===e.isAtomic?(d("WebGPURenderer: Atomic operations are only supported in compute shaders."),ti.READ_WRITE):ti.READ_ONLY:e.access}getStorageAccess(e,t){return Qw[this.getNodeAccess(e,t)]}getUniformFromNode(e,t,r,s=null){const i=super.getUniformFromNode(e,t,r,s),n=this.getDataFromNode(e,r,this.globalCache);if(void 0===n.uniformGPU){let a;const o=e.groupNode,u=o.name,l=this.getBindGroupArray(u,r);if("texture"===t||"cubeTexture"===t||"cubeDepthTexture"===t||"storageTexture"===t||"texture3D"===t){let s=null;const n=this.getNodeAccess(e,r);"texture"===t||"storageTexture"===t?s=!0===e.value.is3DTexture?new KS(i.name,i.node,o,n):new jS(i.name,i.node,o,n):"cubeTexture"===t||"cubeDepthTexture"===t?s=new XS(i.name,i.node,o,n):"texture3D"===t&&(s=new KS(i.name,i.node,o,n)),s.store=!0===e.isStorageTextureNode,s.mipLevel=s.store?e.mipLevel:0,s.setVisibility(Jw[r]);if(!0===e.value.isCubeTexture||!1===this.isUnfilterable(e.value)&&!1===s.store){const e=new Iw(`${i.name}_sampler`,i.node,o);e.setVisibility(Jw[r]),l.push(e,s),a=[e,s]}else l.push(s),a=[s]}else if("buffer"===t||"storageBuffer"===t||"indirectStorageBuffer"===t){const n=this.getSharedDataFromNode(e);let u=n.buffer;if(void 0===u){u=new("buffer"===t?kS:kw)(e,o),n.buffer=u}u.setVisibility(u.getVisibility()|Jw[r]),l.push(u),a=u,i.name=s||"NodeBuffer_"+i.id}else{let e=this.uniformGroups[u];void 0===e?(e=new $S(u,o),e.setVisibility(Jw[r]),this.uniformGroups[u]=e,l.push(e)):(e.setVisibility(e.getVisibility()|Jw[r]),-1===l.indexOf(e)&&l.push(e)),a=this.getNodeUniform(i,t);const s=a.name;e.uniforms.some(e=>e.name===s)||e.addUniform(a)}n.uniformGPU=a}return i}getBuiltin(e,t,r,s=this.shaderStage){const i=this.builtins[s]||(this.builtins[s]=new Map);return!1===i.has(e)&&i.set(e,{name:e,property:t,type:r}),t}hasBuiltin(e,t=this.shaderStage){return void 0!==this.builtins[t]&&this.builtins[t].has(e)}getVertexIndex(){return"vertex"===this.shaderStage?this.getBuiltin("vertex_index","vertexIndex","u32","attribute"):"vertexIndex"}buildFunctionCode(e){const t=e.layout,r=this.flowShaderNode(e),s=[];for(const e of t.inputs)s.push(e.name+" : "+this.getType(e.type));let i=`fn ${t.name}( ${s.join(", ")} ) -> ${this.getType(t.type)} {\n${r.vars}\n${r.code}\n`;return r.result&&(i+=`\treturn ${r.result};\n`),i+="\n}\n",i}getInstanceIndex(){return"vertex"===this.shaderStage?this.getBuiltin("instance_index","instanceIndex","u32","attribute"):"instanceIndex"}getInvocationLocalIndex(){return this.getBuiltin("local_invocation_index","invocationLocalIndex","u32","attribute")}getSubgroupSize(){return this.enableSubGroups(),this.getBuiltin("subgroup_size","subgroupSize","u32","attribute")}getInvocationSubgroupIndex(){return this.enableSubGroups(),this.getBuiltin("subgroup_invocation_id","invocationSubgroupIndex","u32","attribute")}getSubgroupIndex(){return this.enableSubGroups(),this.getBuiltin("subgroup_id","subgroupIndex","u32","attribute")}getDrawIndex(){return null}getFrontFacing(){return this.getBuiltin("front_facing","isFront","bool")}getFragCoord(){return this.getBuiltin("position","fragCoord","vec4")+".xy"}getFragDepth(){return"output."+this.getBuiltin("frag_depth","depth","f32","output")}getClipDistance(){return"varyings.hw_clip_distances"}isFlipY(){return!1}enableDirective(e,t=this.shaderStage){(this.directives[t]||(this.directives[t]=new Set)).add(e)}getDirectives(e){const t=[],r=this.directives[e];if(void 0!==r)for(const e of r)t.push(`enable ${e};`);return t.join("\n")}enableSubGroups(){this.enableDirective("subgroups")}enableSubgroupsF16(){this.enableDirective("subgroups-f16")}enableClipDistances(){this.enableDirective("clip_distances")}enableShaderF16(){this.enableDirective("f16")}enableDualSourceBlending(){this.enableDirective("dual_source_blending")}enableHardwareClipping(e){this.enableClipDistances(),this.getBuiltin("clip_distances","hw_clip_distances",`array`,"vertex")}getBuiltins(e){const t=[],r=this.builtins[e];if(void 0!==r)for(const{name:e,property:s,type:i}of r.values())t.push(`@builtin( ${e} ) ${s} : ${i}`);return t.join(",\n\t")}getScopedArray(e,t,r,s){return!1===this.scopedArrays.has(e)&&this.scopedArrays.set(e,{name:e,scope:t,bufferType:r,bufferCount:s}),e}getScopedArrays(e){if("compute"!==e)return;const t=[];for(const{name:e,scope:r,bufferType:s,bufferCount:i}of this.scopedArrays.values()){const n=this.getType(s);t.push(`var<${r}> ${e}: array< ${n}, ${i} >;`)}return t.join("\n")}getAttributes(e){const t=[];if("compute"===e&&(this.getBuiltin("global_invocation_id","globalId","vec3","attribute"),this.getBuiltin("workgroup_id","workgroupId","vec3","attribute"),this.getBuiltin("local_invocation_id","localId","vec3","attribute"),this.getBuiltin("num_workgroups","numWorkgroups","vec3","attribute"),this.renderer.hasFeature("subgroups")&&(this.enableDirective("subgroups",e),this.getBuiltin("subgroup_size","subgroupSize","u32","attribute"))),"vertex"===e||"compute"===e){const e=this.getBuiltins("attribute");e&&t.push(e);const r=this.getAttributesArray();for(let e=0,s=r.length;e"),t.push(`\t${s+r.name} : ${i}`)}return e.output&&t.push(`\t${this.getBuiltins("output")}`),t.join(",\n")}getStructs(e){let t="";const r=this.structs[e];if(r.length>0){const e=[];for(const t of r){let r=`struct ${t.name} {\n`;r+=this.getStructMembers(t),r+="\n};",e.push(r)}t="\n"+e.join("\n\n")+"\n"}return t}getVar(e,t,r=null){let s=`var ${t} : `;return s+=null!==r?this.generateArrayDeclaration(e,r):this.getType(e),s}getVars(e){const t=[],r=this.vars[e];if(void 0!==r)for(const e of r)t.push(`\t${this.getVar(e.type,e.name,e.count)};`);return`\n${t.join("\n")}\n`}getVaryings(e){const t=[];if("vertex"===e&&this.getBuiltin("position","builtinClipSpace","vec4","vertex"),"vertex"===e||"fragment"===e){const r=this.varyings,s=this.vars[e];for(let i=0;ir.value.itemSize;return s&&!i}getUniforms(e){const t=this.uniforms[e],r=[],s=[],i=[],n={};for(const i of t){const t=i.groupNode.name,a=this.bindingsIndexes[t];if("texture"===i.type||"cubeTexture"===i.type||"cubeDepthTexture"===i.type||"storageTexture"===i.type||"texture3D"===i.type){const t=i.node.value;let s;(!0===t.isCubeTexture||!1===this.isUnfilterable(t)&&!0!==i.node.isStorageTextureNode)&&(this.isSampleCompare(t)?r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name}_sampler : sampler_comparison;`):r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name}_sampler : sampler;`));let n="";const{primarySamples:o}=this.renderer.backend.utils.getTextureSampleData(t);if(o>1&&(n="_multisampled"),!0===t.isCubeTexture&&!0===t.isDepthTexture)s="texture_depth_cube";else if(!0===t.isCubeTexture)s="texture_cube";else if(!0===t.isDepthTexture)s=this.renderer.backend.compatibilityMode&&null===t.compareFunction?`texture${n}_2d`:`texture_depth${n}_2d${!0===t.isArrayTexture?"_array":""}`;else if(!0===i.node.isStorageTextureNode){const r=Hw(t),n=this.getStorageAccess(i.node,e),a=i.node.value.is3DTexture,o=i.node.value.isArrayTexture;s=`texture_storage_${a?"3d":"2d"+(o?"_array":"")}<${r}, ${n}>`}else if(!0===t.isArrayTexture||!0===t.isDataArrayTexture||!0===t.isCompressedArrayTexture)s="texture_2d_array";else if(!0===t.is3DTexture||!0===t.isData3DTexture)s="texture_3d";else{s=`texture${n}_2d<${this.getComponentTypeFromTexture(t).charAt(0)}32>`}r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name} : ${s};`)}else if("buffer"===i.type||"storageBuffer"===i.type||"indirectStorageBuffer"===i.type){const t=i.node,r=this.getType(t.getNodeType(this)),n=t.bufferCount,o=n>0&&"buffer"===i.type?", "+n:"",u=t.isStorageBufferNode?`storage, ${this.getStorageAccess(t,e)}`:"uniform";if(this.isCustomStruct(i))s.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var<${u}> ${i.name} : ${r};`);else{const e=`\tvalue : array< ${t.isAtomic?`atomic<${r}>`:`${r}`}${o} >`;s.push(this._getWGSLStructBinding(i.name,e,u,a.binding++,a.group))}}else{const e=i.groupNode.name;if(void 0===n[e]){const t=this.uniformGroups[e];if(void 0!==t){const r=[];for(const e of t.uniforms){const t=e.getType(),s=this.getType(this.getVectorType(t));r.push(`\t${e.name} : ${s}`)}let s=this.uniformGroupsBindings[e];void 0===s&&(s={index:a.binding++,id:a.group},this.uniformGroupsBindings[e]=s),n[e]={index:s.index,id:s.id,snippets:r}}}}}for(const e in n){const t=n[e];i.push(this._getWGSLStructBinding(e,t.snippets.join(",\n"),"uniform",t.index,t.id))}return[...r,...s,...i].join("\n")}buildCode(){const e=null!==this.material?{fragment:{},vertex:{}}:{compute:{}};this.sortBindingGroups();for(const t in e){this.shaderStage=t;const r=e[t];r.uniforms=this.getUniforms(t),r.attributes=this.getAttributes(t),r.varyings=this.getVaryings(t),r.structs=this.getStructs(t),r.vars=this.getVars(t),r.codes=this.getCodes(t),r.directives=this.getDirectives(t),r.scopedArrays=this.getScopedArrays(t);let s="// code\n\n";s+=this.flowCode[t];const i=this.flowNodes[t],n=i[i.length-1],a=n.outputNode,o=void 0!==a&&!0===a.isOutputStructNode;for(const e of i){const i=this.getFlowData(e),u=e.name;if(u&&(s.length>0&&(s+="\n"),s+=`\t// flow -> ${u}\n`),s+=`${i.code}\n\t`,e===n&&"compute"!==t)if(s+="// result\n\n\t","vertex"===t)s+=`varyings.builtinClipSpace = ${i.result};`;else if("fragment"===t)if(o)r.returnType=a.getNodeType(this),r.structs+="var output : "+r.returnType+";",s+=`return ${i.result};`;else{let e="\t@location(0) color: vec4";const t=this.getBuiltins("output");t&&(e+=",\n\t"+t),r.returnType="OutputStruct",r.structs+=this._getWGSLStruct("OutputStruct",e),r.structs+="\nvar output : OutputStruct;",s+=`output.color = ${i.result};\n\n\treturn output;`}}r.flow=s}if(this.shaderStage=null,null!==this.material)this.vertexShader=this._getWGSLVertexCode(e.vertex),this.fragmentShader=this._getWGSLFragmentCode(e.fragment);else{const t=this.object.workgroupSize;this.computeShader=this._getWGSLComputeCode(e.compute,t)}}getMethod(e,t=null){let r;return null!==t&&(r=this._getWGSLMethod(e+"_"+t)),void 0===r&&(r=this._getWGSLMethod(e)),r||e}getBitcastMethod(e){return`bitcast<${this.getType(e)}>`}getFloatPackingMethod(e){return this.getMethod(`floatpack_${e}_2x16`)}getFloatUnpackingMethod(e){return this.getMethod(`floatunpack_${e}_2x16`)}getTernary(e,t,r){return`select( ${r}, ${t}, ${e} )`}getType(e){return rC[e]||e}isAvailable(e){let t=eC[e];return void 0===t&&("float32Filterable"===e?t=this.renderer.hasFeature("float32-filterable"):"clipDistance"===e&&(t=this.renderer.hasFeature("clip-distances")),eC[e]=t),t}_getWGSLMethod(e){return void 0!==iC[e]&&this._include(e),nC[e]}_include(e){const t=iC[e];return t.build(this),this.addInclude(t),t}_getWGSLVertexCode(e){return`${this.getSignature()}\n// directives\n${e.directives}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// varyings\n${e.varyings}\nvar varyings : VaryingsStruct;\n\n// codes\n${e.codes}\n\n@vertex\nfn main( ${e.attributes} ) -> VaryingsStruct {\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n\treturn varyings;\n\n}\n`}_getWGSLFragmentCode(e){return`${this.getSignature()}\n// global\n${aC}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// codes\n${e.codes}\n\n@fragment\nfn main( ${e.varyings} ) -> ${e.returnType} {\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n}\n`}_getWGSLComputeCode(e,t){const[r,s,i]=t;return`${this.getSignature()}\n// directives\n${e.directives}\n\n// system\nvar instanceIndex : u32;\n\n// locals\n${e.scopedArrays}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// codes\n${e.codes}\n\n@compute @workgroup_size( ${r}, ${s}, ${i} )\nfn main( ${e.attributes} ) {\n\n\t// system\n\tinstanceIndex = globalId.x\n\t\t+ globalId.y * ( ${r} * numWorkgroups.x )\n\t\t+ globalId.z * ( ${r} * numWorkgroups.x ) * ( ${s} * numWorkgroups.y );\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n}\n`}_getWGSLStruct(e,t){return`\nstruct ${e} {\n${t}\n};`}_getWGSLStructBinding(e,t,r,s=0,i=0){const n=e+"Struct";return`${this._getWGSLStruct(n,t)}\n@binding( ${s} ) @group( ${i} )\nvar<${r}> ${e} : ${n};`}}class uC{constructor(e){this.backend=e}getCurrentDepthStencilFormat(e){let t;return e.depth&&(t=null!==e.depthTexture?this.getTextureFormatGPU(e.depthTexture):e.stencil?BE:PE),t}getTextureFormatGPU(e){return this.backend.get(e).format}getTextureSampleData(e){let t;if(e.isFramebufferTexture)t=1;else if(e.isDepthTexture&&!e.renderTarget){const e=this.backend.renderer,r=e.getRenderTarget();t=r?r.samples:e.currentSamples}else e.renderTarget&&(t=e.renderTarget.samples);t=t||1;const r=t>1&&null!==e.renderTarget&&!0!==e.isDepthTexture&&!0!==e.isFramebufferTexture;return{samples:t,primarySamples:r?1:t,isMSAA:r}}getCurrentColorFormat(e){let t;return t=null!==e.textures?this.getTextureFormatGPU(e.textures[0]):this.getPreferredCanvasFormat(),t}getCurrentColorFormats(e){return null!==e.textures?e.textures.map(e=>this.getTextureFormatGPU(e)):[this.getPreferredCanvasFormat()]}getCurrentColorSpace(e){return null!==e.textures?e.textures[0].colorSpace:this.backend.renderer.outputColorSpace}getPrimitiveTopology(e,t){return e.isPoints?AR:e.isLineSegments||e.isMesh&&!0===t.wireframe?wR:e.isLine?CR:e.isMesh?MR:void 0}getSampleCount(e){return e>=4?4:1}getSampleCountRenderContext(e){return null!==e.textures?this.getSampleCount(e.sampleCount):this.getSampleCount(this.backend.renderer.currentSamples)}getPreferredCanvasFormat(){const e=this.backend.parameters.outputType;if(void 0===e)return navigator.gpu.getPreferredCanvasFormat();if(e===Ge)return bE;if(e===be)return wE;throw new Error("Unsupported output buffer type.")}}const lC=new Map([[Int8Array,["sint8","snorm8"]],[Uint8Array,["uint8","unorm8"]],[Int16Array,["sint16","snorm16"]],[Uint16Array,["uint16","unorm16"]],[Int32Array,["sint32","snorm32"]],[Uint32Array,["uint32","unorm32"]],[Float32Array,["float32"]]]);"undefined"!=typeof Float16Array&&lC.set(Float16Array,["float16"]);const dC=new Map([[ot,["float16"]]]),cC=new Map([[Int32Array,"sint32"],[Int16Array,"sint32"],[Uint32Array,"uint32"],[Uint16Array,"uint32"],[Float32Array,"float32"]]);class hC{constructor(e){this.backend=e}createAttribute(e,t){const r=this._getBufferAttribute(e),s=this.backend,i=s.get(r);let n=i.buffer;if(void 0===n){const a=s.device;let o=r.array;if(!1===e.normalized)if(o.constructor===Int16Array||o.constructor===Int8Array)o=new Int32Array(o);else if((o.constructor===Uint16Array||o.constructor===Uint8Array)&&(o=new Uint32Array(o),t&GPUBufferUsage.INDEX))for(let e=0;e0&&(void 0===n.groups&&(n.groups=[],n.versions=[]),n.versions[r]===s&&(o=n.groups[r])),void 0===o&&(o=this.createBindGroup(e,a),r>0&&(n.groups[r]=o,n.versions[r]=s)),n.group=o}updateBinding(e){const t=this.backend,r=t.device,s=e.buffer,i=t.get(e).buffer,n=e.updateRanges;if(0===n.length)r.queue.writeBuffer(i,0,s,0);else{const e=Kr(s),t=e?1:s.BYTES_PER_ELEMENT;for(let a=0,o=n.length;a1&&(i+=`-${e.texture.depthOrArrayLayers}`),i+=`-${r}-${s}`,a=e[i],void 0===a){const n=Lw;let o;o=t.isSampledCubeTexture?Mw:t.isSampledTexture3D?Fw:t.texture.isArrayTexture||t.texture.isDataArrayTexture||t.texture.isCompressedArrayTexture?Cw:ww,a=e[i]=e.texture.createView({aspect:n,dimension:o,mipLevelCount:r,baseMipLevel:s})}}n.push({binding:i,resource:a})}else if(t.isSampler){const e=r.get(t.texture);n.push({binding:i,resource:e.sampler})}i++}return s.createBindGroup({label:"bindGroup_"+e.name,layout:t,entries:n})}_createLayoutEntries(e){const t=[];let r=0;for(const s of e.bindings){const e=this.backend,i={binding:r,visibility:s.visibility};if(s.isUniformBuffer||s.isStorageBuffer){const e={};s.isStorageBuffer&&(s.visibility&LR.COMPUTE&&(s.access===ti.READ_WRITE||s.access===ti.WRITE_ONLY)?e.type=gw:e.type=mw),i.buffer=e}else if(s.isSampledTexture&&s.store){const e={};e.format=this.backend.get(s.texture).texture.format;const t=s.access;e.access=t===ti.READ_WRITE?bw:t===ti.WRITE_ONLY?fw:yw,s.texture.isArrayTexture?e.viewDimension=Cw:s.texture.is3DTexture&&(e.viewDimension=Fw),i.storageTexture=e}else if(s.isSampledTexture){const t={},{primarySamples:r}=e.utils.getTextureSampleData(s.texture);if(r>1&&(t.multisampled=!0,s.texture.isDepthTexture||(t.sampleType=vw)),s.texture.isDepthTexture)e.compatibilityMode&&null===s.texture.compareFunction?t.sampleType=vw:t.sampleType=Nw;else if(s.texture.isDataTexture||s.texture.isDataArrayTexture||s.texture.isData3DTexture){const e=s.texture.type;e===R?t.sampleType=Sw:e===S?t.sampleType=Rw:e===j&&(this.backend.hasFeature("float32-filterable")?t.sampleType=_w:t.sampleType=vw)}s.isSampledCubeTexture?t.viewDimension=Mw:s.texture.isArrayTexture||s.texture.isDataArrayTexture||s.texture.isCompressedArrayTexture?t.viewDimension=Cw:s.isSampledTexture3D&&(t.viewDimension=Fw),i.texture=t}else if(s.isSampler){const t={};s.texture.isDepthTexture&&(null!==s.texture.compareFunction&&e.hasCompatibility(E.TEXTURE_COMPARE)?t.type=Tw:t.type=xw),i.sampler=t}else o(`WebGPUBindingUtils: Unsupported binding "${s}".`);t.push(i),r++}return t}deleteBindGroupData(e){const{backend:t}=this,r=t.get(e);r.layout&&(r.layout.usedTimes--,0===r.layout.usedTimes&&this._bindGroupLayoutCache.delete(r.layoutKey),r.layout=void 0,r.layoutKey=void 0)}dispose(){this._bindGroupLayoutCache.clear()}}class mC{constructor(e){this.backend=e,this._activePipelines=new WeakMap}setPipeline(e,t){this._activePipelines.get(e)!==t&&(e.setPipeline(t),this._activePipelines.set(e,t))}_getSampleCount(e){return this.backend.utils.getSampleCountRenderContext(e)}createRenderPipeline(e,t){const{object:r,material:s,geometry:i,pipeline:n}=e,{vertexProgram:a,fragmentProgram:u}=n,l=this.backend,d=l.device,c=l.utils,h=l.get(n),p=[];for(const t of e.getBindings()){const e=l.get(t),{layoutGPU:r}=e.layout;p.push(r)}const g=l.attributeUtils.createShaderVertexBuffers(e);let m;s.blending===ee||s.blending===ze&&!1===s.transparent||(m=this._getBlending(s));let f={};!0===s.stencilWrite&&(f={compare:this._getStencilCompare(s),failOp:this._getStencilOperation(s.stencilFail),depthFailOp:this._getStencilOperation(s.stencilZFail),passOp:this._getStencilOperation(s.stencilZPass)});const y=this._getColorWriteMask(s),b=[];if(null!==e.context.textures){const t=e.context.textures,r=e.context.mrt;for(let e=0;e1},layout:d.createPipelineLayout({bindGroupLayouts:p})},E={},A=e.context.depth,w=e.context.stencil;if(!0!==A&&!0!==w||(!0===A&&(E.format=N,E.depthWriteEnabled=s.depthWrite,E.depthCompare=v),!0===w&&(E.stencilFront=f,E.stencilBack={},E.stencilReadMask=s.stencilFuncMask,E.stencilWriteMask=s.stencilWriteMask),!0===s.polygonOffset&&(E.depthBias=s.polygonOffsetUnits,E.depthBiasSlopeScale=s.polygonOffsetFactor,E.depthBiasClamp=0),R.depthStencil=E),d.pushErrorScope("validation"),null===t)h.pipeline=d.createRenderPipeline(R),d.popErrorScope().then(e=>{null!==e&&(h.error=!0,o(e.message))});else{const e=new Promise(async e=>{try{h.pipeline=await d.createRenderPipelineAsync(R)}catch(e){}const t=await d.popErrorScope();null!==t&&(h.error=!0,o(t.message)),e()});t.push(e)}}createBundleEncoder(e,t="renderBundleEncoder"){const r=this.backend,{utils:s,device:i}=r,n=s.getCurrentDepthStencilFormat(e),a={label:t,colorFormats:s.getCurrentColorFormats(e),depthStencilFormat:n,sampleCount:this._getSampleCount(e)};return i.createRenderBundleEncoder(a)}createComputePipeline(e,t){const r=this.backend,s=r.device,i=r.get(e.computeProgram).module,n=r.get(e),a=[];for(const e of t){const t=r.get(e),{layoutGPU:s}=t.layout;a.push(s)}n.pipeline=s.createComputePipeline({compute:i,layout:s.createPipelineLayout({bindGroupLayouts:a})})}_getBlending(e){let t,r;const s=e.blending,i=e.blendSrc,n=e.blendDst,a=e.blendEquation;if(s===ht){const s=null!==e.blendSrcAlpha?e.blendSrcAlpha:i,o=null!==e.blendDstAlpha?e.blendDstAlpha:n,u=null!==e.blendEquationAlpha?e.blendEquationAlpha:a;t={srcFactor:this._getBlendFactor(i),dstFactor:this._getBlendFactor(n),operation:this._getBlendOperation(a)},r={srcFactor:this._getBlendFactor(s),dstFactor:this._getBlendFactor(o),operation:this._getBlendOperation(u)}}else{const i=(e,s,i,n)=>{t={srcFactor:e,dstFactor:s,operation:JA},r={srcFactor:i,dstFactor:n,operation:JA}};if(e.premultipliedAlpha)switch(s){case ze:i(GA,HA,GA,HA);break;case qt:i(GA,GA,GA,GA);break;case Ht:i(kA,$A,kA,GA);break;case Wt:i(qA,HA,kA,GA)}else switch(s){case ze:i(WA,HA,GA,HA);break;case qt:i(WA,GA,GA,GA);break;case Ht:o(`WebGPURenderer: "SubtractiveBlending" requires "${e.isMaterial?"material":"blendMode"}.premultipliedAlpha = true".`);break;case Wt:o(`WebGPURenderer: "MultiplyBlending" requires "${e.isMaterial?"material":"blendMode"}.premultipliedAlpha = true".`)}}if(void 0!==t&&void 0!==r)return{color:t,alpha:r};o("WebGPURenderer: Invalid blending: ",s)}_getBlendFactor(e){let t;switch(e){case pt:t=kA;break;case kt:t=GA;break;case Vt:t=zA;break;case Dt:t=$A;break;case $e:t=WA;break;case We:t=HA;break;case It:t=qA;break;case Bt:t=jA;break;case Ut:t=XA;break;case Pt:t=KA;break;case Ot:t=YA;break;case 211:t=QA;break;case 212:t=ZA;break;default:o("WebGPURenderer: Blend factor not supported.",e)}return t}_getStencilCompare(e){let t;const r=e.stencilFunc;switch(r){case ss:t=PR;break;case rs:t=kR;break;case ts:t=BR;break;case es:t=UR;break;case Jr:t=DR;break;case Zr:t=VR;break;case Qr:t=IR;break;case Yr:t=OR;break;default:o("WebGPURenderer: Invalid stencil function.",r)}return t}_getStencilOperation(e){let t;switch(e){case cs:t=aw;break;case ds:t=ow;break;case ls:t=uw;break;case us:t=lw;break;case os:t=dw;break;case as:t=cw;break;case ns:t=hw;break;case is:t=pw;break;default:o("WebGPURenderer: Invalid stencil operation.",t)}return t}_getBlendOperation(e){let t;switch(e){case He:t=JA;break;case Lt:t=ew;break;case Ft:t=tw;break;case ps:t=rw;break;case hs:t=sw;break;default:o("WebGPUPipelineUtils: Blend equation not supported.",e)}return t}_getPrimitiveState(e,t,r){const s={},i=this.backend.utils;s.topology=i.getPrimitiveTopology(e,r),null!==t.index&&!0===e.isLine&&!0!==e.isLineSegments&&(s.stripIndexFormat=t.index.array instanceof Uint16Array?XR:KR);let n=r.side===M;return e.isMesh&&e.matrixWorld.determinant()<0&&(n=!n),s.frontFace=!0===n?HR:WR,s.cullMode=r.side===F?qR:jR,s}_getColorWriteMask(e){return!0===e.colorWrite?nw:iw}_getDepthCompare(e){let t;if(!1===e.depthTest)t=kR;else{const r=e.depthFunc;switch(r){case er:t=PR;break;case Jt:t=kR;break;case Zt:t=BR;break;case Qt:t=UR;break;case Yt:t=DR;break;case Kt:t=VR;break;case Xt:t=IR;break;case jt:t=OR;break;default:o("WebGPUPipelineUtils: Invalid depth function.",r)}}return t}}class fC extends SR{constructor(e,t,r=2048){super(r),this.device=e,this.type=t,this.querySet=this.device.createQuerySet({type:"timestamp",count:this.maxQueries,label:`queryset_global_timestamp_${t}`});const s=8*this.maxQueries;this.resolveBuffer=this.device.createBuffer({label:`buffer_timestamp_resolve_${t}`,size:s,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),this.resultBuffer=this.device.createBuffer({label:`buffer_timestamp_result_${t}`,size:s,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ})}allocateQueriesForContext(e){if(!this.trackTimestamp||this.isDisposed)return null;if(this.currentQueryIndex+2>this.maxQueries)return v(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`),null;const t=this.currentQueryIndex;return this.currentQueryIndex+=2,this.queryOffsets.set(e,t),t}async resolveQueriesAsync(){if(!this.trackTimestamp||0===this.currentQueryIndex||this.isDisposed)return this.lastValue;if(this.pendingResolve)return this.pendingResolve;this.pendingResolve=this._resolveQueries();try{return await this.pendingResolve}finally{this.pendingResolve=null}}async _resolveQueries(){if(this.isDisposed)return this.lastValue;try{if("unmapped"!==this.resultBuffer.mapState)return this.lastValue;const e=new Map(this.queryOffsets),t=this.currentQueryIndex,r=8*t;this.currentQueryIndex=0,this.queryOffsets.clear();const s=this.device.createCommandEncoder();s.resolveQuerySet(this.querySet,0,t,this.resolveBuffer,0),s.copyBufferToBuffer(this.resolveBuffer,0,this.resultBuffer,0,r);const i=s.finish();if(this.device.queue.submit([i]),"unmapped"!==this.resultBuffer.mapState)return this.lastValue;if(await this.resultBuffer.mapAsync(GPUMapMode.READ,0,r),this.isDisposed)return"mapped"===this.resultBuffer.mapState&&this.resultBuffer.unmap(),this.lastValue;const n=new BigUint64Array(this.resultBuffer.getMappedRange(0,r)),a={},o=[];for(const[t,r]of e){const e=t.match(/^(.*):f(\d+)$/),s=parseInt(e[2]);!1===o.includes(s)&&o.push(s),void 0===a[s]&&(a[s]=0);const i=n[r],u=n[r+1],l=Number(u-i)/1e6;this.timestamps.set(t,l),a[s]+=l}const u=a[o[o.length-1]];return this.resultBuffer.unmap(),this.lastValue=u,this.frames=o,u}catch(e){return o("Error resolving queries:",e),"mapped"===this.resultBuffer.mapState&&this.resultBuffer.unmap(),this.lastValue}}async dispose(){if(!this.isDisposed){if(this.isDisposed=!0,this.pendingResolve)try{await this.pendingResolve}catch(e){o("Error waiting for pending resolve:",e)}if(this.resultBuffer&&"mapped"===this.resultBuffer.mapState)try{this.resultBuffer.unmap()}catch(e){o("Error unmapping buffer:",e)}this.querySet&&(this.querySet.destroy(),this.querySet=null),this.resolveBuffer&&(this.resolveBuffer.destroy(),this.resolveBuffer=null),this.resultBuffer&&(this.resultBuffer.destroy(),this.resultBuffer=null),this.queryOffsets.clear(),this.pendingResolve=null}}}class yC extends aR{constructor(e={}){super(e),this.isWebGPUBackend=!0,this.parameters.alpha=void 0===e.alpha||e.alpha,this.parameters.requiredLimits=void 0===e.requiredLimits?{}:e.requiredLimits,this.compatibilityMode=null,this.device=null,this.defaultRenderPassdescriptor=null,this.utils=new uC(this),this.attributeUtils=new hC(this),this.bindingUtils=new gC(this),this.pipelineUtils=new mC(this),this.textureUtils=new Ww(this),this.occludedResolveCache=new Map;const t="undefined"==typeof navigator||!1===/Android/.test(navigator.userAgent);this._compatibility={[E.TEXTURE_COMPARE]:t}}async init(e){await super.init(e);const t=this.parameters;let r;if(void 0===t.device){const e={powerPreference:t.powerPreference,featureLevel:"compatibility"},s="undefined"!=typeof navigator?await navigator.gpu.requestAdapter(e):null;if(null===s)throw new Error("WebGPUBackend: Unable to create WebGPU adapter.");const i=Object.values(Dw),n=[];for(const e of i)s.features.has(e)&&n.push(e);const a={requiredFeatures:n,requiredLimits:t.requiredLimits};r=await s.requestDevice(a)}else r=t.device;this.compatibilityMode=!r.features.has("core-features-and-limits"),r.lost.then(t=>{if("destroyed"===t.reason)return;const r={api:"WebGPU",message:t.message||"Unknown reason",reason:t.reason||null,originalEvent:t};e.onDeviceLost(r)}),this.device=r,this.trackTimestamp=this.trackTimestamp&&this.hasFeature(Dw.TimestampQuery),this.updateSize()}get context(){const e=this.renderer.getCanvasTarget(),t=this.get(e);let r=t.context;if(void 0===r){const s=this.parameters;r=!0===e.isDefaultCanvasTarget&&void 0!==s.context?s.context:e.domElement.getContext("webgpu"),"setAttribute"in e.domElement&&e.domElement.setAttribute("data-engine",`three.js r${ut} webgpu`);const i=s.alpha?"premultiplied":"opaque",n=s.outputType===be?"extended":"standard";r.configure({device:this.device,format:this.utils.getPreferredCanvasFormat(),usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_SRC,alphaMode:i,toneMapping:{mode:n}}),t.context=r}return r}get coordinateSystem(){return h}async getArrayBufferAsync(e){return await this.attributeUtils.getArrayBufferAsync(e)}getContext(){return this.context}_getDefaultRenderPassDescriptor(){const e=this.renderer,t=e.getCanvasTarget(),r=this.get(t),s=e.currentSamples;let i=r.descriptor;if(void 0===i||r.samples!==s){i={colorAttachments:[{view:null}]},!0!==e.depth&&!0!==e.stencil||(i.depthStencilAttachment={view:this.textureUtils.getDepthBuffer(e.depth,e.stencil).createView()});const t=i.colorAttachments[0];s>0?t.view=this.textureUtils.getColorBuffer().createView():t.resolveTarget=void 0,r.descriptor=i,r.samples=s}const n=i.colorAttachments[0];return s>0?n.resolveTarget=this.context.getCurrentTexture().createView():n.view=this.context.getCurrentTexture().createView(),i}_isRenderCameraDepthArray(e){return e.depthTexture&&e.depthTexture.image.depth>1&&e.camera.isArrayCamera}_getRenderPassDescriptor(e,t={}){const r=e.renderTarget,s=this.get(r);let i=s.descriptors;void 0!==i&&s.width===r.width&&s.height===r.height&&s.samples===r.samples||(i={},s.descriptors=i);const n=e.getCacheKey();let a=i[n];if(void 0===a){const t=e.textures,o=[];let u;const l=this._isRenderCameraDepthArray(e);for(let s=0;s1)if(!0===l){const t=e.camera.cameras;for(let e=0;e0&&(t.currentOcclusionQuerySet&&t.currentOcclusionQuerySet.destroy(),t.currentOcclusionQueryBuffer&&t.currentOcclusionQueryBuffer.destroy(),t.currentOcclusionQuerySet=t.occlusionQuerySet,t.currentOcclusionQueryBuffer=t.occlusionQueryBuffer,t.currentOcclusionQueryObjects=t.occlusionQueryObjects,i=r.createQuerySet({type:"occlusion",count:s,label:`occlusionQuerySet_${e.id}`}),t.occlusionQuerySet=i,t.occlusionQueryIndex=0,t.occlusionQueryObjects=new Array(s),t.lastOcclusionObject=null),n=null===e.textures?this._getDefaultRenderPassDescriptor():this._getRenderPassDescriptor(e,{loadOp:zR}),this.initTimestampQuery(Ct.RENDER,this.getTimestampUID(e),n),n.occlusionQuerySet=i;const a=n.depthStencilAttachment;if(null!==e.textures){const t=n.colorAttachments;for(let r=0;r0&&t.currentPass.executeBundles(t.renderBundles),r>t.occlusionQueryIndex&&t.currentPass.endOcclusionQuery();const s=t.encoder;if(!0===this._isRenderCameraDepthArray(e)){const r=[];for(let e=0;e0){const s=8*r;let i=this.occludedResolveCache.get(s);void 0===i&&(i=this.device.createBuffer({size:s,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),this.occludedResolveCache.set(s,i));const n=this.device.createBuffer({size:s,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});t.encoder.resolveQuerySet(t.occlusionQuerySet,0,r,i,0),t.encoder.copyBufferToBuffer(i,0,n,0,s),t.occlusionQueryBuffer=n,this.resolveOccludedAsync(e)}if(this.device.queue.submit([t.encoder.finish()]),null!==e.textures){const t=e.textures;for(let e=0;eo&&(i[0]=Math.min(a,o),i[1]=Math.ceil(a/o)),n.dispatchSize=i}i=n.dispatchSize}a.dispatchWorkgroups(i[0],i[1]||1,i[2]||1)}finishCompute(e){const t=this.get(e);t.passEncoderGPU.end(),this.device.queue.submit([t.cmdEncoderGPU.finish()])}draw(e,t){const{object:r,material:s,context:i,pipeline:n}=e,a=e.getBindings(),o=this.get(i),u=this.get(n),l=u.pipeline;if(!0===u.error)return;const d=e.getIndex(),c=null!==d,h=e.getDrawParameters();if(null===h)return;const p=(t,r)=>{this.pipelineUtils.setPipeline(t,l),r.pipeline=l;const n=r.bindingGroups;for(let e=0,r=a.length;e{if(p(s,i),!0===r.isBatchedMesh){const e=r._multiDrawStarts,i=r._multiDrawCounts,n=r._multiDrawCount,a=r._multiDrawInstances;null!==a&&v("WebGPUBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection.");for(let o=0;o1?0:o;!0===c?s.drawIndexed(i[o],n,e[o]/d.array.BYTES_PER_ELEMENT,0,u):s.draw(i[o],n,e[o],u),t.update(r,i[o],n)}}else if(!0===c){const{vertexCount:i,instanceCount:n,firstVertex:a}=h,o=e.getIndirect();if(null!==o){const t=this.get(o).buffer,r=e.getIndirectOffset(),i=Array.isArray(r)?r:[r];for(let e=0;e0){const t=this.get(e.camera),s=e.camera.cameras,n=e.getBindingGroup("cameraIndex");if(void 0===t.indexesGPU||t.indexesGPU.length!==s.length){const e=this.get(n),r=[],i=new Uint32Array([0,0,0,0]);for(let t=0,n=s.length;t(d("WebGPURenderer: WebGPU is not available, running under WebGL2 backend."),new ER(e)));super(new t(e),e),this.library=new TC,this.isWebGPURenderer=!0,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}}class vC extends As{constructor(){super(),this.isBundleGroup=!0,this.type="BundleGroup",this.static=!0,this.version=0}set needsUpdate(e){!0===e&&this.version++}}class NC{constructor(e,t=En(0,0,1,1)){this.renderer=e,this.outputNode=t,this.outputColorTransform=!0,this.needsUpdate=!0;const r=new Zp;r.name="RenderPipeline",this._quadMesh=new Wb(r),this._quadMesh.name="Render Pipeline",this._context=null}render(){const e=this.renderer;this._update(),null!==this._context.onBeforeRenderPipeline&&this._context.onBeforeRenderPipeline();const t=e.toneMapping,r=e.outputColorSpace;e.toneMapping=m,e.outputColorSpace=p.workingColorSpace;const s=e.xr.enabled;e.xr.enabled=!1,this._quadMesh.render(e),e.xr.enabled=s,e.toneMapping=t,e.outputColorSpace=r,null!==this._context.onAfterRenderPipeline&&this._context.onAfterRenderPipeline()}get context(){return this._context}dispose(){this._quadMesh.material.dispose()}_update(){if(!0===this.needsUpdate){const e=this.renderer,t=e.toneMapping,r=e.outputColorSpace,s={renderPipeline:this,onBeforeRenderPipeline:null,onAfterRenderPipeline:null};let i=this.outputNode;!0===this.outputColorTransform?(i=i.context(s),i=yl(i,t,r)):(s.toneMapping=t,s.outputColorSpace=r,i=i.context(s)),this._context=s,this._quadMesh.material.fragmentNode=i,this._quadMesh.material.needsUpdate=!0,this.needsUpdate=!1}}async renderAsync(){v('RenderPipeline: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await this.renderer.init(),this.render()}}class SC extends NC{constructor(e,t){v('PostProcessing: "PostProcessing" has been renamed to "RenderPipeline". Please update your code to use "THREE.RenderPipeline" instead.'),super(e,t)}}class RC extends N{constructor(e=1,t=1){super(),this.image={width:e,height:t},this.magFilter=oe,this.minFilter=oe,this.isStorageTexture=!0,this.mipmapsAutoUpdate=!0}setSize(e,t){this.image.width===e&&this.image.height===t||(this.image.width=e,this.image.height=t,this.dispose())}}class EC extends N{constructor(e=1,t=1,r=1){super(),this.isArrayTexture=!1,this.image={width:e,height:t,depth:r},this.magFilter=oe,this.minFilter=oe,this.wrapR=xe,this.isStorageTexture=!0,this.is3DTexture=!0}setSize(e,t,r){this.image.width===e&&this.image.height===t&&this.image.depth===r||(this.image.width=e,this.image.height=t,this.image.depth=r,this.dispose())}}class AC extends N{constructor(e=1,t=1,r=1){super(),this.isArrayTexture=!0,this.image={width:e,height:t,depth:r},this.magFilter=oe,this.minFilter=oe,this.isStorageTexture=!0}setSize(e,t,r){this.image.width===e&&this.image.height===t&&this.image.depth===r||(this.image.width=e,this.image.height=t,this.image.depth=r,this.dispose())}}class wC extends sx{constructor(e,t){super(e,t,Uint32Array),this.isIndirectStorageBufferAttribute=!0}}class CC extends ws{constructor(e){super(e),this.textures={},this.nodes={}}load(e,t,r,s){const i=new Cs(this.manager);i.setPath(this.path),i.setRequestHeader(this.requestHeader),i.setWithCredentials(this.withCredentials),i.load(e,r=>{try{t(this.parse(JSON.parse(r)))}catch(t){s?s(t):o(t),this.manager.itemError(e)}},r,s)}parseNodes(e){const t={};if(void 0!==e){for(const r of e){const{uuid:e,type:s}=r;t[e]=this.createNodeFromType(s),t[e].uuid=e}const r={nodes:t,textures:this.textures};for(const s of e){s.meta=r;t[s.uuid].deserialize(s),delete s.meta}}return t}parse(e){const t=this.createNodeFromType(e.type);t.uuid=e.uuid;const r={nodes:this.parseNodes(e.nodes),textures:this.textures};return e.meta=r,t.deserialize(e),delete e.meta,t}setTextures(e){return this.textures=e,this}setNodes(e){return this.nodes=e,this}createNodeFromType(e){return void 0===this.nodes[e]?(o("NodeLoader: Node type not found:",e),gn()):new this.nodes[e]}}class MC extends Ms{constructor(e){super(e),this.nodes={},this.nodeMaterials={}}parse(e){const t=super.parse(e),r=this.nodes,s=e.inputNodes;for(const e in s){const i=s[e];t[e]=r[i]}return t}setNodes(e){return this.nodes=e,this}setNodeMaterials(e){return this.nodeMaterials=e,this}createMaterialFromType(e){const t=this.nodeMaterials[e];return void 0!==t?new t:super.createMaterialFromType(e)}}class FC extends Fs{constructor(e){super(e),this.nodes={},this.nodeMaterials={},this._nodesJSON=null}setNodes(e){return this.nodes=e,this}setNodeMaterials(e){return this.nodeMaterials=e,this}parse(e,t){this._nodesJSON=e.nodes;const r=super.parse(e,t);return this._nodesJSON=null,r}parseNodes(e,t){if(void 0!==e){const r=new CC;return r.setNodes(this.nodes),r.setTextures(t),r.parseNodes(e)}return{}}parseMaterials(e,t){const r={};if(void 0!==e){const s=this.parseNodes(this._nodesJSON,t),i=new MC;i.setTextures(t),i.setNodes(s),i.setNodeMaterials(this.nodeMaterials);for(let t=0,s=e.length;t0){const{width:r,height:s}=e.context;t.bufferWidth=r,t.bufferHeight=s}t.lights=this.getLightsData(e.lightsNode.getLights()),this.renderObjects.set(e,t)}return t}getAttributesData(e){const t={};for(const r in e){const s=e[r];t[r]={version:s.version}}return t}containsNode(e){const t=e.material;for(const e in t)if(t[e]&&t[e].isNode)return!0;return!!(e.context.modelViewMatrix||e.context.modelNormalViewMatrix||e.context.getAO||e.context.getShadow)}getMaterialData(e){const t={};for(const r of this.refreshUniforms){const s=e[r];null!=s&&("object"==typeof s&&void 0!==s.clone?!0===s.isTexture?t[r]={id:s.id,version:s.version}:t[r]=s.clone():t[r]=s)}return t}equals(e,t){const{object:r,material:s,geometry:i}=e,n=this.getRenderObjectData(e);if(!0!==n.worldMatrix.equals(r.matrixWorld))return n.worldMatrix.copy(r.matrixWorld),!1;const a=n.material;for(const e in a){const t=a[e],r=s[e];if(void 0!==t.equals){if(!1===t.equals(r))return t.copy(r),!1}else if(!0===r.isTexture){if(t.id!==r.id||t.version!==r.version)return t.id=r.id,t.version=r.version,!1}else if(t!==r)return a[e]=r,!1}if(a.transmission>0){const{width:t,height:r}=e.context;if(n.bufferWidth!==t||n.bufferHeight!==r)return n.bufferWidth=t,n.bufferHeight=r,!1}const o=n.geometry,u=i.attributes,l=o.attributes,d=Object.keys(l),c=Object.keys(u);if(o.id!==i.id)return o.id=i.id,!1;if(d.length!==c.length)return n.geometry.attributes=this.getAttributesData(u),!1;for(const e of d){const t=l[e],r=u[e];if(void 0===r)return delete l[e],!1;if(t.version!==r.version)return t.version=r.version,!1}const h=i.index,p=o.indexVersion,g=h?h.version:null;if(p!==g)return o.indexVersion=g,!1;if(o.drawRange.start!==i.drawRange.start||o.drawRange.count!==i.drawRange.count)return o.drawRange.start=i.drawRange.start,o.drawRange.count=i.drawRange.count,!1;if(n.morphTargetInfluences){let e=!1;for(let t=0;t>>16,2246822507),r^=Math.imul(s^s>>>13,3266489909),s=Math.imul(s^s>>>16,2246822507),s^=Math.imul(r^r>>>13,3266489909),4294967296*(2097151&s)+(r>>>0)}const Ds=e=>Ps(e),Us=e=>Ps(e),Is=(...e)=>Ps(e),Os=new Map([[1,"float"],[2,"vec2"],[3,"vec3"],[4,"vec4"],[9,"mat3"],[16,"mat4"]]),Vs=new WeakMap;function ks(e){return Os.get(e)}function Gs(e){if(/[iu]?vec\d/.test(e))return e.startsWith("ivec")?Int32Array:e.startsWith("uvec")?Uint32Array:Float32Array;if(/mat\d/.test(e))return Float32Array;if(/float/.test(e))return Float32Array;if(/uint/.test(e))return Uint32Array;if(/int/.test(e))return Int32Array;throw new Error(`THREE.NodeUtils: Unsupported type: ${e}`)}function zs(e){return/float|int|uint/.test(e)?1:/vec2/.test(e)?2:/vec3/.test(e)?3:/vec4/.test(e)||/mat2/.test(e)?4:/mat3/.test(e)?9:/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function $s(e){return/float|int|uint/.test(e)?1:/vec2/.test(e)?2:/vec3/.test(e)?3:/vec4/.test(e)||/mat2/.test(e)?4:/mat3/.test(e)?12:/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function Ws(e){return/float|int|uint/.test(e)?4:/vec2/.test(e)?8:/vec3/.test(e)||/vec4/.test(e)?16:/mat2/.test(e)?8:/mat3/.test(e)||/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function Hs(e){if(null==e)return null;const t=typeof e;return!0===e.isNode?"node":"number"===t?"float":"boolean"===t?"bool":"string"===t?"string":"function"===t?"shader":!0===e.isVector2?"vec2":!0===e.isVector3?"vec3":!0===e.isVector4?"vec4":!0===e.isMatrix2?"mat2":!0===e.isMatrix3?"mat3":!0===e.isMatrix4?"mat4":!0===e.isColor?"color":e instanceof ArrayBuffer?"ArrayBuffer":null}function qs(o,...u){const l=o?o.slice(-4):void 0;return 1===u.length&&("vec2"===l?u=[u[0],u[0]]:"vec3"===l?u=[u[0],u[0],u[0]]:"vec4"===l&&(u=[u[0],u[0],u[0],u[0]])),"color"===o?new e(...u):"vec2"===l?new t(...u):"vec3"===l?new r(...u):"vec4"===l?new s(...u):"mat2"===l?new i(...u):"mat3"===l?new n(...u):"mat4"===l?new a(...u):"bool"===o?u[0]||!1:"float"===o||"int"===o||"uint"===o?u[0]||0:"string"===o?u[0]||"":"ArrayBuffer"===o?Ks(u[0]):null}function js(e){let t=Vs.get(e);return void 0===t&&(t={},Vs.set(e,t)),t}function Xs(e){let t="";const r=new Uint8Array(e);for(let e=0;ee.charCodeAt(0)).buffer}var Ys=Object.freeze({__proto__:null,arrayBufferToBase64:Xs,base64ToArrayBuffer:Ks,getAlignmentFromType:Ws,getDataFromObject:js,getLengthFromType:zs,getMemoryLengthFromType:$s,getTypeFromLength:ks,getTypedArrayFromType:Gs,getValueFromType:qs,getValueType:Hs,hash:Is,hashArray:Us,hashString:Ds});const Qs={VERTEX:"vertex",FRAGMENT:"fragment"},Zs={NONE:"none",FRAME:"frame",RENDER:"render",OBJECT:"object"},Js={BOOLEAN:"bool",INTEGER:"int",FLOAT:"float",VECTOR2:"vec2",VECTOR3:"vec3",VECTOR4:"vec4",MATRIX2:"mat2",MATRIX3:"mat3",MATRIX4:"mat4"},ei={READ_ONLY:"readOnly",WRITE_ONLY:"writeOnly",READ_WRITE:"readWrite"},ti=["fragment","vertex"],ri=["setup","analyze","generate"],si=[...ti,"compute"],ii=["x","y","z","w"],ni={analyze:"setup",generate:"analyze"};let ai=0;class oi extends u{static get type(){return"Node"}constructor(e=null){super(),this.nodeType=e,this.updateType=Zs.NONE,this.updateBeforeType=Zs.NONE,this.updateAfterType=Zs.NONE,this.uuid=l.generateUUID(),this.version=0,this.name="",this.global=!1,this.parents=!1,this.isNode=!0,this._beforeNodes=null,this._cacheKey=null,this._cacheKeyVersion=0,Object.defineProperty(this,"id",{value:ai++})}set needsUpdate(e){!0===e&&this.version++}get type(){return this.constructor.type}onUpdate(e,t){return this.updateType=t,this.update=e.bind(this),this}onFrameUpdate(e){return this.onUpdate(e,Zs.FRAME)}onRenderUpdate(e){return this.onUpdate(e,Zs.RENDER)}onObjectUpdate(e){return this.onUpdate(e,Zs.OBJECT)}onReference(e){return this.updateReference=e.bind(this),this}updateReference(){return this}isGlobal(){return this.global}*getChildren(){for(const{childNode:e}of this._getChildren())yield e}dispose(){this.dispatchEvent({type:"dispose"})}traverse(e){e(this);for(const t of this.getChildren())t.traverse(e)}_getChildren(e=new Set){const t=[];e.add(this);for(const r of Object.getOwnPropertyNames(this)){const s=this[r];if(!0!==r.startsWith("_")&&!e.has(s))if(!0===Array.isArray(s))for(let e=0;e0&&(e.inputNodes=r)}deserialize(e){if(void 0!==e.inputNodes){const t=e.meta.nodes;for(const r in e.inputNodes)if(Array.isArray(e.inputNodes[r])){const s=[];for(const i of e.inputNodes[r])s.push(t[i]);this[r]=s}else if("object"==typeof e.inputNodes[r]){const s={};for(const i in e.inputNodes[r]){const n=e.inputNodes[r][i];s[i]=t[n]}this[r]=s}else{const s=e.inputNodes[r];this[r]=t[s]}}}toJSON(e){const{uuid:t,type:r}=this,s=void 0===e||"string"==typeof e;s&&(e={textures:{},images:{},nodes:{}});let i=e.nodes[t];function n(e){const t=[];for(const r in e){const s=e[r];delete s.metadata,t.push(s)}return t}if(void 0===i&&(i={uuid:t,type:r,meta:e,metadata:{version:4.7,type:"Node",generator:"Node.toJSON"}},!0!==s&&(e.nodes[i.uuid]=i),this.serialize(i),delete i.meta),s){const t=n(e.textures),r=n(e.images),s=n(e.nodes);t.length>0&&(i.textures=t),r.length>0&&(i.images=r),s.length>0&&(i.nodes=s)}return i}}class ui extends oi{static get type(){return"ArrayElementNode"}constructor(e,t){super(),this.node=e,this.indexNode=t,this.isArrayElementNode=!0}getNodeType(e){return this.node.getElementType(e)}getMemberType(e,t){return this.node.getMemberType(e,t)}generate(e){const t=this.indexNode.getNodeType(e);return`${this.node.build(e)}[ ${this.indexNode.build(e,!e.isVector(t)&&e.isInteger(t)?t:"uint")} ]`}}class li extends oi{static get type(){return"ConvertNode"}constructor(e,t){super(),this.node=e,this.convertTo=t}getNodeType(e){const t=this.node.getNodeType(e);let r=null;for(const s of this.convertTo.split("|"))null!==r&&e.getTypeLength(t)!==e.getTypeLength(s)||(r=s);return r}serialize(e){super.serialize(e),e.convertTo=this.convertTo}deserialize(e){super.deserialize(e),this.convertTo=e.convertTo}generate(e,t){const r=this.node,s=this.getNodeType(e),i=r.build(e,s);return e.format(i,s,t)}}class di extends oi{static get type(){return"TempNode"}constructor(e=null){super(e),this.isTempNode=!0}hasDependencies(e){return e.getDataFromNode(this).usageCount>1}build(e,t){if("generate"===e.getBuildStage()){const r=e.getVectorType(this.getNodeType(e,t)),s=e.getDataFromNode(this);if(void 0!==s.propertyName)return e.format(s.propertyName,r,t);if("void"!==r&&"void"!==t&&this.hasDependencies(e)){const i=super.build(e,r),n=e.getVarFromNode(this,null,r),a=e.getPropertyName(n);return e.addLineFlowCode(`${a} = ${i}`,this),s.snippet=i,s.propertyName=a,e.format(s.propertyName,r,t)}}return super.build(e,t)}}class ci extends di{static get type(){return"JoinNode"}constructor(e=[],t=null){super(t),this.nodes=e}getNodeType(e){return null!==this.nodeType?e.getVectorType(this.nodeType):e.getTypeFromLength(this.nodes.reduce((t,r)=>t+e.getTypeLength(r.getNodeType(e)),0))}generate(e,t){const r=this.getNodeType(e),s=e.getTypeLength(r),i=this.nodes,n=e.getComponentType(r),a=[];let u=0;for(const t of i){if(u>=s){o(`TSL: Length of parameters exceeds maximum length of function '${r}()' type.`);break}let i,l=t.getNodeType(e),d=e.getTypeLength(l);u+d>s&&(o(`TSL: Length of '${r}()' data exceeds maximum length of output type.`),d=s-u,l=e.getTypeFromLength(d)),u+=d,i=t.build(e,l);if(e.getComponentType(l)!==n){const t=e.getTypeFromLength(d,n);i=e.format(i,l,t)}a.push(i)}const l=`${e.getType(r)}( ${a.join(", ")} )`;return e.format(l,r,t)}}const hi=ii.join("");class pi extends oi{static get type(){return"SplitNode"}constructor(e,t="x"){super(),this.node=e,this.components=t,this.isSplitNode=!0}getVectorLength(){let e=this.components.length;for(const t of this.components)e=Math.max(ii.indexOf(t)+1,e);return e}getComponentType(e){return e.getComponentType(this.node.getNodeType(e))}getNodeType(e){return e.getTypeFromLength(this.components.length,this.getComponentType(e))}getScope(){return this.node.getScope()}generate(e,t){const r=this.node,s=e.getTypeLength(r.getNodeType(e));let i=null;if(s>1){let n=null;this.getVectorLength()>=s&&(n=e.getTypeFromLength(this.getVectorLength(),this.getComponentType(e)));const a=r.build(e,n);i=this.components.length===s&&this.components===hi.slice(0,this.components.length)?e.format(a,n,t):e.format(`${a}.${this.components}`,this.getNodeType(e),t)}else i=r.build(e,t);return i}serialize(e){super.serialize(e),e.components=this.components}deserialize(e){super.deserialize(e),this.components=e.components}}class gi extends di{static get type(){return"SetNode"}constructor(e,t,r){super(),this.sourceNode=e,this.components=t,this.targetNode=r}getNodeType(e){return this.sourceNode.getNodeType(e)}generate(e){const{sourceNode:t,components:r,targetNode:s}=this,i=this.getNodeType(e),n=e.getComponentType(s.getNodeType(e)),a=e.getTypeFromLength(r.length,n),o=s.build(e,a),u=t.build(e,i),l=e.getTypeLength(i),d=[];for(let e=0;e(e=>e.replace(/r|s/g,"x").replace(/g|t/g,"y").replace(/b|p/g,"z").replace(/a|q/g,"w"))(e).split("").sort().join("");oi.prototype.assign=function(...e){if(!0!==this.isStackNode)return null!==Ti?Ti.assign(this,...e):o("TSL: No stack defined for assign operation. Make sure the assign is inside a Fn()."),this;{const t=_i.get("assign");return this.addToStack(t(...e))}},oi.prototype.toVarIntent=function(){return this},oi.prototype.get=function(e){return new xi(this,e)};const Si={};function Ri(e,t,r){Si[e]=Si[t]=Si[r]={get(){this._cache=this._cache||{};let t=this._cache[e];return void 0===t&&(t=new pi(this,e),this._cache[e]=t),t},set(t){this[e].assign(Qi(t))}};const s=e.toUpperCase(),i=t.toUpperCase(),n=r.toUpperCase();oi.prototype["set"+s]=oi.prototype["set"+i]=oi.prototype["set"+n]=function(t){const r=Ni(e);return new gi(this,r,Qi(t))},oi.prototype["flip"+s]=oi.prototype["flip"+i]=oi.prototype["flip"+n]=function(){const t=Ni(e);return new mi(this,t)}}const Ei=["x","y","z","w"],Ai=["r","g","b","a"],wi=["s","t","p","q"];for(let e=0;e<4;e++){let t=Ei[e],r=Ai[e],s=wi[e];Ri(t,r,s);for(let i=0;i<4;i++){t=Ei[e]+Ei[i],r=Ai[e]+Ai[i],s=wi[e]+wi[i],Ri(t,r,s);for(let n=0;n<4;n++){t=Ei[e]+Ei[i]+Ei[n],r=Ai[e]+Ai[i]+Ai[n],s=wi[e]+wi[i]+wi[n],Ri(t,r,s);for(let a=0;a<4;a++)t=Ei[e]+Ei[i]+Ei[n]+Ei[a],r=Ai[e]+Ai[i]+Ai[n]+Ai[a],s=wi[e]+wi[i]+wi[n]+wi[a],Ri(t,r,s)}}}for(let e=0;e<32;e++)Si[e]={get(){this._cache=this._cache||{};let t=this._cache[e];return void 0===t&&(t=new ui(this,new bi(e,"uint")),this._cache[e]=t),t},set(t){this[e].assign(Qi(t))}};Object.defineProperties(oi.prototype,Si);const Ci=new WeakMap,Mi=function(e,t=null){for(const r in e)e[r]=Qi(e[r],t);return e},Bi=function(e,t=null){const r=e.length;for(let s=0;su?(o(`TSL: "${r}" parameter length exceeds limit.`),t.slice(0,u)):t}return null===t?n=(...t)=>i(new e(...en(d(t)))):null!==r?(r=Qi(r),n=(...s)=>i(new e(t,...en(d(s)),r))):n=(...r)=>i(new e(t,...en(d(r)))),n.setParameterLength=(...e)=>(1===e.length?a=u=e[0]:2===e.length&&([a,u]=e),n),n.setName=e=>(l=e,n),n},Li=function(e,...t){return new e(...en(t))};class Pi extends oi{constructor(e,t){super(),this.shaderNode=e,this.rawInputs=t,this.isShaderCallNodeInternal=!0}getNodeType(e){return this.shaderNode.nodeType||this.getOutputNode(e).getNodeType(e)}getElementType(e){return this.getOutputNode(e).getElementType(e)}getMemberType(e,t){return this.getOutputNode(e).getMemberType(e,t)}call(e){const{shaderNode:t,rawInputs:r}=this,s=e.getNodeProperties(t),i=e.getClosestSubBuild(t.subBuilds)||"",n=i||"default";if(s[n])return s[n];const a=e.subBuildFn,o=e.fnCall;e.subBuildFn=i,e.fnCall=this;let u=null;if(t.layout){let s=Ci.get(e.constructor);void 0===s&&(s=new WeakMap,Ci.set(e.constructor,s));let i=s.get(t);void 0===i&&(i=Qi(e.buildFunctionNode(t)),s.set(t,i)),e.addInclude(i);const n=r?function(e){let t;Ji(e);t=e[0]&&(e[0].isNode||Object.getPrototypeOf(e[0])!==Object.prototype)?[...e]:e[0];return t}(r):null;u=Qi(i.call(n))}else{const s=new Proxy(e,{get:(e,t,r)=>{let s;return s=Symbol.iterator===t?function*(){yield}:Reflect.get(e,t,r),s}}),i=r?function(e){let t=0;return Ji(e),new Proxy(e,{get:(r,s,i)=>{let n;if("length"===s)return n=e.length,n;if(Symbol.iterator===s)n=function*(){for(const t of e)yield Qi(t)};else{if(e.length>0)if(Object.getPrototypeOf(e[0])===Object.prototype){const r=e[0];n=void 0===r[s]?r[t++]:Reflect.get(r,s,i)}else e[0]instanceof oi&&(n=void 0===e[s]?e[t++]:Reflect.get(e,s,i));else n=Reflect.get(r,s,i);n=Qi(n)}return n}})}(r):null,n=Array.isArray(r)?r.length>0:null!==r,a=t.jsFunc,o=n||a.length>1?a(i,s):a(s);u=Qi(o)}return e.subBuildFn=a,e.fnCall=o,t.once&&(s[n]=u),u}setupOutput(e){return e.addStack(),e.stack.outputNode=this.call(e),e.removeStack()}getOutputNode(e){const t=e.getNodeProperties(this),r=e.getSubBuildOutput(this);return t[r]=t[r]||this.setupOutput(e),t[r].subBuild=e.getClosestSubBuild(this),t[r]}build(e,t=null){let r=null;const s=e.getBuildStage(),i=e.getNodeProperties(this),n=e.getSubBuildOutput(this),a=this.getOutputNode(e),o=e.fnCall;if(e.fnCall=this,"setup"===s){const t=e.getSubBuildProperty("initialized",this);if(!0!==i[t]&&(i[t]=!0,i[n]=this.getOutputNode(e),i[n].build(e),this.shaderNode.subBuilds))for(const t of e.chaining){const r=e.getDataFromNode(t,"any");r.subBuilds=r.subBuilds||new Set;for(const e of this.shaderNode.subBuilds)r.subBuilds.add(e)}r=i[n]}else"analyze"===s?a.build(e,t):"generate"===s&&(r=a.build(e,t)||"");return e.fnCall=o,r}}class Di extends oi{constructor(e,t){super(t),this.jsFunc=e,this.layout=null,this.global=!0,this.once=!1}setLayout(e){return this.layout=e,this}getLayout(){return this.layout}call(e=null){return new Pi(this,e)}setup(){return this.call()}}const Ui=[!1,!0],Ii=[0,1,2,3],Oi=[-1,-2],Vi=[.5,1.5,1/3,1e-6,1e6,Math.PI,2*Math.PI,1/Math.PI,2/Math.PI,1/(2*Math.PI),Math.PI/2],ki=new Map;for(const e of Ui)ki.set(e,new bi(e));const Gi=new Map;for(const e of Ii)Gi.set(e,new bi(e,"uint"));const zi=new Map([...Gi].map(e=>new bi(e.value,"int")));for(const e of Oi)zi.set(e,new bi(e,"int"));const $i=new Map([...zi].map(e=>new bi(e.value)));for(const e of Vi)$i.set(e,new bi(e));for(const e of Vi)$i.set(-e,new bi(-e));const Wi={bool:ki,uint:Gi,ints:zi,float:$i},Hi=new Map([...ki,...$i]),qi=(e,t)=>Hi.has(e)?Hi.get(e):!0===e.isNode?e:new bi(e,t),ji=function(e,t=null){return(...r)=>{for(const t of r)if(void 0===t)return o(`TSL: Invalid parameter for the type "${e}".`),new bi(0,e);if((0===r.length||!["bool","float","int","uint"].includes(e)&&r.every(e=>{const t=typeof e;return"object"!==t&&"function"!==t}))&&(r=[qs(e,...r)]),1===r.length&&null!==t&&t.has(r[0]))return Zi(t.get(r[0]));if(1===r.length){const t=qi(r[0],e);return t.nodeType===e?Zi(t):Zi(new li(t,e))}const s=r.map(e=>qi(e));return Zi(new ci(s,e))}},Xi=e=>"object"==typeof e&&null!==e?e.value:e,Ki=e=>null!=e?e.nodeType||e.convertTo||("string"==typeof e?e:null):null;function Yi(e,t){return new Di(e,t)}const Qi=(e,t=null)=>function(e,t=null){const r=Hs(e);return"node"===r?e:null===t&&("float"===r||"boolean"===r)||r&&"shader"!==r&&"string"!==r?Qi(qi(e,t)):"shader"===r?e.isFn?e:on(e):e}(e,t),Zi=(e,t=null)=>Qi(e,t).toVarIntent(),Ji=(e,t=null)=>new Mi(e,t),en=(e,t=null)=>new Bi(e,t),tn=(e,t=null,r=null,s=null)=>new Fi(e,t,r,s),rn=(e,...t)=>new Li(e,...t),sn=(e,t=null,r=null,s={})=>new Fi(e,t,r,{...s,intent:!0});let nn=0;class an extends oi{constructor(e,t=null){super();let r=null;null!==t&&("object"==typeof t?r=t.return:("string"==typeof t?r=t:o("TSL: Invalid layout type."),t=null)),this.shaderNode=new Yi(e,r),null!==t&&this.setLayout(t),this.isFn=!0}setLayout(e){const t=this.shaderNode.nodeType;if("object"!=typeof e.inputs){const r={name:"fn"+nn++,type:t,inputs:[]};for(const t in e)"return"!==t&&r.inputs.push({name:t,type:e[t]});e=r}return this.shaderNode.setLayout(e),this}getNodeType(e){return this.shaderNode.getNodeType(e)||"float"}call(...e){const t=this.shaderNode.call(e);return"void"===this.shaderNode.nodeType&&t.toStack(),t.toVarIntent()}once(e=null){return this.shaderNode.once=!0,this.shaderNode.subBuilds=e,this}generate(e){const t=this.getNodeType(e);return o('TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".'),e.generateConst(t)}}function on(e,t=null){const r=new an(e,t);return new Proxy(()=>{},{apply:(e,t,s)=>r.call(...s),get:(e,t,s)=>Reflect.get(r,t,s),set:(e,t,s,i)=>Reflect.set(r,t,s,i)})}const un=e=>{Ti=e},ln=()=>Ti,dn=(...e)=>Ti.If(...e);function cn(e){return Ti&&Ti.addToStack(e),e}vi("toStack",cn);const hn=new ji("color"),pn=new ji("float",Wi.float),gn=new ji("int",Wi.ints),mn=new ji("uint",Wi.uint),fn=new ji("bool",Wi.bool),yn=new ji("vec2"),bn=new ji("ivec2"),xn=new ji("uvec2"),Tn=new ji("bvec2"),_n=new ji("vec3"),vn=new ji("ivec3"),Nn=new ji("uvec3"),Sn=new ji("bvec3"),Rn=new ji("vec4"),En=new ji("ivec4"),An=new ji("uvec4"),wn=new ji("bvec4"),Cn=new ji("mat2"),Mn=new ji("mat3"),Bn=new ji("mat4");vi("toColor",hn),vi("toFloat",pn),vi("toInt",gn),vi("toUint",mn),vi("toBool",fn),vi("toVec2",yn),vi("toIVec2",bn),vi("toUVec2",xn),vi("toBVec2",Tn),vi("toVec3",_n),vi("toIVec3",vn),vi("toUVec3",Nn),vi("toBVec3",Sn),vi("toVec4",Rn),vi("toIVec4",En),vi("toUVec4",An),vi("toBVec4",wn),vi("toMat2",Cn),vi("toMat3",Mn),vi("toMat4",Bn);const Fn=tn(ui).setParameterLength(2),Ln=(e,t)=>Qi(new li(Qi(e),t));vi("element",Fn),vi("convert",Ln);vi("append",e=>(d("TSL: .append() has been renamed to .toStack()."),cn(e)));class Pn extends oi{static get type(){return"PropertyNode"}constructor(e,t=null,r=!1){super(e),this.name=t,this.varying=r,this.isPropertyNode=!0,this.global=!0}customCacheKey(){return Ds(this.type+":"+(this.name||"")+":"+(this.varying?"1":"0"))}getHash(e){return this.name||super.getHash(e)}generate(e){let t;return!0===this.varying?(t=e.getVaryingFromNode(this,this.name),t.needsInterpolation=!0):t=e.getVarFromNode(this,this.name),e.getPropertyName(t)}}const Dn=(e,t)=>new Pn(e,t),Un=(e,t)=>new Pn(e,t,!0),In=rn(Pn,"vec4","DiffuseColor"),On=rn(Pn,"vec3","DiffuseContribution"),Vn=rn(Pn,"vec3","EmissiveColor"),kn=rn(Pn,"float","Roughness"),Gn=rn(Pn,"float","Metalness"),zn=rn(Pn,"float","Clearcoat"),$n=rn(Pn,"float","ClearcoatRoughness"),Wn=rn(Pn,"vec3","Sheen"),Hn=rn(Pn,"float","SheenRoughness"),qn=rn(Pn,"float","Iridescence"),jn=rn(Pn,"float","IridescenceIOR"),Xn=rn(Pn,"float","IridescenceThickness"),Kn=rn(Pn,"float","AlphaT"),Yn=rn(Pn,"float","Anisotropy"),Qn=rn(Pn,"vec3","AnisotropyT"),Zn=rn(Pn,"vec3","AnisotropyB"),Jn=rn(Pn,"color","SpecularColor"),ea=rn(Pn,"color","SpecularColorBlended"),ta=rn(Pn,"float","SpecularF90"),ra=rn(Pn,"float","Shininess"),sa=rn(Pn,"vec4","Output"),ia=rn(Pn,"float","dashSize"),na=rn(Pn,"float","gapSize"),aa=rn(Pn,"float","pointWidth"),oa=rn(Pn,"float","IOR"),ua=rn(Pn,"float","Transmission"),la=rn(Pn,"float","Thickness"),da=rn(Pn,"float","AttenuationDistance"),ca=rn(Pn,"color","AttenuationColor"),ha=rn(Pn,"float","Dispersion");class pa extends oi{static get type(){return"UniformGroupNode"}constructor(e,t=!1,r=1){super("string"),this.name=e,this.shared=t,this.order=r,this.isUniformGroup=!0}serialize(e){super.serialize(e),e.name=this.name,e.version=this.version,e.shared=this.shared}deserialize(e){super.deserialize(e),this.name=e.name,this.version=e.version,this.shared=e.shared}}const ga=e=>new pa(e),ma=(e,t=0)=>new pa(e,!0,t),fa=ma("frame"),ya=ma("render"),ba=ga("object");class xa extends fi{static get type(){return"UniformNode"}constructor(e,t=null){super(e,t),this.isUniformNode=!0,this.name="",this.groupNode=ba}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setGroup(e){return this.groupNode=e,this}getGroup(){return this.groupNode}getUniformHash(e){return this.getHash(e)}onUpdate(e,t){return e=e.bind(this),super.onUpdate(t=>{const r=e(t,this);void 0!==r&&(this.value=r)},t)}getInputType(e){let t=super.getInputType(e);return"bool"===t&&(t="uint"),t}generate(e,t){const r=this.getNodeType(e),s=this.getUniformHash(e);let i=e.getNodeFromHash(s);void 0===i&&(e.setHashNode(this,s),i=this);const n=i.getInputType(e),a=e.getUniformFromNode(i,n,e.shaderStage,this.name||e.context.nodeName),o=e.getPropertyName(a);void 0!==e.context.nodeName&&delete e.context.nodeName;let u=o;if("bool"===r){const t=e.getDataFromNode(this);let s=t.propertyName;if(void 0===s){const i=e.getVarFromNode(this,null,"bool");s=e.getPropertyName(i),t.propertyName=s,u=e.format(o,n,r),e.addLineFlowCode(`${s} = ${u}`,this)}u=s}return e.format(u,r,t)}}const Ta=(e,t)=>{const r=Ki(t||e);if(r===e&&(e=qs(r)),e&&!0===e.isNode){let t=e.value;e.traverse(e=>{!0===e.isConstNode&&(t=e.value)}),e=t}return new xa(e,r)};class _a extends di{static get type(){return"ArrayNode"}constructor(e,t,r=null){super(e),this.count=t,this.values=r,this.isArrayNode=!0}getArrayCount(){return this.count}getNodeType(e){return null===this.nodeType?this.values[0].getNodeType(e):this.nodeType}getElementType(e){return this.getNodeType(e)}getMemberType(e,t){return null===this.nodeType?this.values[0].getMemberType(e,t):super.getMemberType(e,t)}generate(e){const t=this.getNodeType(e);return e.generateArray(t,this.count,this.values)}}const va=(...e)=>{let t;if(1===e.length){const r=e[0];t=new _a(null,r.length,r)}else{const r=e[0],s=e[1];t=new _a(r,s)}return Qi(t)};vi("toArray",(e,t)=>va(Array(t).fill(e)));class Na extends di{static get type(){return"AssignNode"}constructor(e,t){super(),this.targetNode=e,this.sourceNode=t,this.isAssignNode=!0}hasDependencies(){return!1}getNodeType(e,t){return"void"!==t?this.targetNode.getNodeType(e):"void"}needsSplitAssign(e){const{targetNode:t}=this;if(!1===e.isAvailable("swizzleAssign")&&t.isSplitNode&&t.components.length>1){const r=e.getTypeLength(t.node.getNodeType(e));return ii.join("").slice(0,r)!==t.components}return!1}setup(e){const{targetNode:t,sourceNode:r}=this,s=t.getScope();e.getDataFromNode(s).assign=!0;const i=e.getNodeProperties(this);i.sourceNode=r,i.targetNode=t.context({assign:!0})}generate(e,t){const{targetNode:r,sourceNode:s}=e.getNodeProperties(this),i=this.needsSplitAssign(e),n=r.build(e),a=r.getNodeType(e),o=s.build(e,a),u=s.getNodeType(e),l=e.getDataFromNode(this);let d;if(!0===l.initialized)"void"!==t&&(d=n);else if(i){const s=e.getVarFromNode(this,null,a),i=e.getPropertyName(s);e.addLineFlowCode(`${i} = ${o}`,this);const u=r.node,l=u.node.context({assign:!0}).build(e);for(let t=0;t{const s=r.type;let i;return i="pointer"===s?"&"+t.build(e):t.build(e,s),i};if(Array.isArray(i)){if(i.length>s.length)o("TSL: The number of provided parameters exceeds the expected number of inputs in 'Fn()'."),i.length=s.length;else if(i.length(t=t.length>1||t[0]&&!0===t[0].isNode?en(t):Ji(t[0]),new Ra(Qi(e),t));vi("call",Ea);const Aa={"==":"equal","!=":"notEqual","<":"lessThan",">":"greaterThan","<=":"lessThanEqual",">=":"greaterThanEqual","%":"mod"};class wa extends di{static get type(){return"OperatorNode"}constructor(e,t,r,...s){if(super(),s.length>0){let i=new wa(e,t,r);for(let t=0;t>"===r||"<<"===r)return e.getIntegerType(n);if("!"===r||"&&"===r||"||"===r||"^^"===r)return"bool";if("=="===r||"!="===r||"<"===r||">"===r||"<="===r||">="===r){const t=Math.max(e.getTypeLength(n),e.getTypeLength(a));return t>1?`bvec${t}`:"bool"}if(e.isMatrix(n)){if("float"===a)return n;if(e.isVector(a))return e.getVectorFromMatrix(n);if(e.isMatrix(a))return n}else if(e.isMatrix(a)){if("float"===n)return a;if(e.isVector(n))return e.getVectorFromMatrix(a)}return e.getTypeLength(a)>e.getTypeLength(n)?a:n}generate(e,t){const r=this.op,{aNode:s,bNode:i}=this,n=this.getNodeType(e,t);let a=null,o=null;"void"!==n?(a=s.getNodeType(e),o=i?i.getNodeType(e):null,"<"===r||">"===r||"<="===r||">="===r||"=="===r||"!="===r?e.isVector(a)?o=a:e.isVector(o)?a=o:a!==o&&(a=o="float"):">>"===r||"<<"===r?(a=n,o=e.changeComponentType(o,"uint")):"%"===r?(a=n,o=e.isInteger(a)&&e.isInteger(o)?o:a):e.isMatrix(a)?"float"===o?o="float":e.isVector(o)?o=e.getVectorFromMatrix(a):e.isMatrix(o)||(a=o=n):a=e.isMatrix(o)?"float"===a?"float":e.isVector(a)?e.getVectorFromMatrix(o):o=n:o=n):a=o=n;const u=s.build(e,a),l=i?i.build(e,o):null,d=e.getFunctionOperator(r);if("void"!==t){const s=e.renderer.coordinateSystem===c;if("=="===r||"!="===r||"<"===r||">"===r||"<="===r||">="===r)return s&&e.isVector(a)?e.format(`${this.getOperatorMethod(e,t)}( ${u}, ${l} )`,n,t):e.format(`( ${u} ${r} ${l} )`,n,t);if("%"===r)return e.isInteger(o)?e.format(`( ${u} % ${l} )`,n,t):e.format(`${this.getOperatorMethod(e,n)}( ${u}, ${l} )`,n,t);if("!"===r||"~"===r)return e.format(`(${r}${u})`,a,t);if(d)return e.format(`${d}( ${u}, ${l} )`,n,t);if(e.isMatrix(a)&&"float"===o)return e.format(`( ${l} ${r} ${u} )`,n,t);if("float"===a&&e.isMatrix(o))return e.format(`${u} ${r} ${l}`,n,t);{let i=`( ${u} ${r} ${l} )`;return!s&&"bool"===n&&e.isVector(a)&&e.isVector(o)&&(i=`all${i}`),e.format(i,n,t)}}if("void"!==a)return d?e.format(`${d}( ${u}, ${l} )`,n,t):e.isMatrix(a)&&"float"===o?e.format(`${l} ${r} ${u}`,n,t):e.format(`${u} ${r} ${l}`,n,t)}serialize(e){super.serialize(e),e.op=this.op}deserialize(e){super.deserialize(e),this.op=e.op}}const Ca=sn(wa,"+").setParameterLength(2,1/0).setName("add"),Ma=sn(wa,"-").setParameterLength(2,1/0).setName("sub"),Ba=sn(wa,"*").setParameterLength(2,1/0).setName("mul"),Fa=sn(wa,"/").setParameterLength(2,1/0).setName("div"),La=sn(wa,"%").setParameterLength(2).setName("mod"),Pa=sn(wa,"==").setParameterLength(2).setName("equal"),Da=sn(wa,"!=").setParameterLength(2).setName("notEqual"),Ua=sn(wa,"<").setParameterLength(2).setName("lessThan"),Ia=sn(wa,">").setParameterLength(2).setName("greaterThan"),Oa=sn(wa,"<=").setParameterLength(2).setName("lessThanEqual"),Va=sn(wa,">=").setParameterLength(2).setName("greaterThanEqual"),ka=sn(wa,"&&").setParameterLength(2,1/0).setName("and"),Ga=sn(wa,"||").setParameterLength(2,1/0).setName("or"),za=sn(wa,"!").setParameterLength(1).setName("not"),$a=sn(wa,"^^").setParameterLength(2).setName("xor"),Wa=sn(wa,"&").setParameterLength(2).setName("bitAnd"),Ha=sn(wa,"~").setParameterLength(1).setName("bitNot"),qa=sn(wa,"|").setParameterLength(2).setName("bitOr"),ja=sn(wa,"^").setParameterLength(2).setName("bitXor"),Xa=sn(wa,"<<").setParameterLength(2).setName("shiftLeft"),Ka=sn(wa,">>").setParameterLength(2).setName("shiftRight"),Ya=on(([e])=>(e.addAssign(1),e)),Qa=on(([e])=>(e.subAssign(1),e)),Za=on(([e])=>{const t=gn(e).toConst();return e.addAssign(1),t}),Ja=on(([e])=>{const t=gn(e).toConst();return e.subAssign(1),t});vi("add",Ca),vi("sub",Ma),vi("mul",Ba),vi("div",Fa),vi("mod",La),vi("equal",Pa),vi("notEqual",Da),vi("lessThan",Ua),vi("greaterThan",Ia),vi("lessThanEqual",Oa),vi("greaterThanEqual",Va),vi("and",ka),vi("or",Ga),vi("not",za),vi("xor",$a),vi("bitAnd",Wa),vi("bitNot",Ha),vi("bitOr",qa),vi("bitXor",ja),vi("shiftLeft",Xa),vi("shiftRight",Ka),vi("incrementBefore",Ya),vi("decrementBefore",Qa),vi("increment",Za),vi("decrement",Ja);const eo=(e,t)=>(d('TSL: "modInt()" is deprecated. Use "mod( int( ... ) )" instead.'),La(gn(e),gn(t)));vi("modInt",eo);class to extends di{static get type(){return"MathNode"}constructor(e,t,r=null,s=null){if(super(),(e===to.MAX||e===to.MIN)&&arguments.length>3){let i=new to(e,t,r);for(let t=2;tn&&i>a?t:n>a?r:a>i?s:t}getNodeType(e){const t=this.method;return t===to.LENGTH||t===to.DISTANCE||t===to.DOT?"float":t===to.CROSS?"vec3":t===to.ALL||t===to.ANY?"bool":t===to.EQUALS?e.changeComponentType(this.aNode.getNodeType(e),"bool"):this.getInputType(e)}setup(e){const{aNode:t,bNode:r,method:s}=this;let i=null;if(s===to.ONE_MINUS)i=Ma(1,t);else if(s===to.RECIPROCAL)i=Fa(1,t);else if(s===to.DIFFERENCE)i=Co(Ma(t,r));else if(s===to.TRANSFORM_DIRECTION){let s=t,n=r;e.isMatrix(s.getNodeType(e))?n=Rn(_n(n),0):s=Rn(_n(s),0);const a=Ba(s,n).xyz;i=_o(a)}return null!==i?i:super.setup(e)}generate(e,t){if(e.getNodeProperties(this).outputNode)return super.generate(e,t);let r=this.method;const s=this.getNodeType(e),i=this.getInputType(e),n=this.aNode,a=this.bNode,o=this.cNode,u=e.renderer.coordinateSystem;if(r===to.NEGATE)return e.format("( - "+n.build(e,i)+" )",s,t);{const l=[];return r===to.CROSS?l.push(n.build(e,s),a.build(e,s)):u===c&&r===to.STEP?l.push(n.build(e,1===e.getTypeLength(n.getNodeType(e))?"float":i),a.build(e,i)):u!==c||r!==to.MIN&&r!==to.MAX?r===to.REFRACT?l.push(n.build(e,i),a.build(e,i),o.build(e,"float")):r===to.MIX?l.push(n.build(e,i),a.build(e,i),o.build(e,1===e.getTypeLength(o.getNodeType(e))?"float":i)):(u===h&&r===to.ATAN&&null!==a&&(r="atan2"),"fragment"===e.shaderStage||r!==to.DFDX&&r!==to.DFDY||(d(`TSL: '${r}' is not supported in the ${e.shaderStage} stage.`),r="/*"+r+"*/"),l.push(n.build(e,i)),null!==a&&l.push(a.build(e,i)),null!==o&&l.push(o.build(e,i))):l.push(n.build(e,i),a.build(e,1===e.getTypeLength(a.getNodeType(e))?"float":i)),e.format(`${e.getMethod(r,s)}( ${l.join(", ")} )`,s,t)}}serialize(e){super.serialize(e),e.method=this.method}deserialize(e){super.deserialize(e),this.method=e.method}}to.ALL="all",to.ANY="any",to.RADIANS="radians",to.DEGREES="degrees",to.EXP="exp",to.EXP2="exp2",to.LOG="log",to.LOG2="log2",to.SQRT="sqrt",to.INVERSE_SQRT="inversesqrt",to.FLOOR="floor",to.CEIL="ceil",to.NORMALIZE="normalize",to.FRACT="fract",to.SIN="sin",to.COS="cos",to.TAN="tan",to.ASIN="asin",to.ACOS="acos",to.ATAN="atan",to.ABS="abs",to.SIGN="sign",to.LENGTH="length",to.NEGATE="negate",to.ONE_MINUS="oneMinus",to.DFDX="dFdx",to.DFDY="dFdy",to.ROUND="round",to.RECIPROCAL="reciprocal",to.TRUNC="trunc",to.FWIDTH="fwidth",to.TRANSPOSE="transpose",to.DETERMINANT="determinant",to.INVERSE="inverse",to.EQUALS="equals",to.MIN="min",to.MAX="max",to.STEP="step",to.REFLECT="reflect",to.DISTANCE="distance",to.DIFFERENCE="difference",to.DOT="dot",to.CROSS="cross",to.POW="pow",to.TRANSFORM_DIRECTION="transformDirection",to.MIX="mix",to.CLAMP="clamp",to.REFRACT="refract",to.SMOOTHSTEP="smoothstep",to.FACEFORWARD="faceforward";const ro=pn(1e-6),so=pn(1e6),io=pn(Math.PI),no=pn(2*Math.PI),ao=pn(2*Math.PI),oo=pn(.5*Math.PI),uo=sn(to,to.ALL).setParameterLength(1),lo=sn(to,to.ANY).setParameterLength(1),co=sn(to,to.RADIANS).setParameterLength(1),ho=sn(to,to.DEGREES).setParameterLength(1),po=sn(to,to.EXP).setParameterLength(1),go=sn(to,to.EXP2).setParameterLength(1),mo=sn(to,to.LOG).setParameterLength(1),fo=sn(to,to.LOG2).setParameterLength(1),yo=sn(to,to.SQRT).setParameterLength(1),bo=sn(to,to.INVERSE_SQRT).setParameterLength(1),xo=sn(to,to.FLOOR).setParameterLength(1),To=sn(to,to.CEIL).setParameterLength(1),_o=sn(to,to.NORMALIZE).setParameterLength(1),vo=sn(to,to.FRACT).setParameterLength(1),No=sn(to,to.SIN).setParameterLength(1),So=sn(to,to.COS).setParameterLength(1),Ro=sn(to,to.TAN).setParameterLength(1),Eo=sn(to,to.ASIN).setParameterLength(1),Ao=sn(to,to.ACOS).setParameterLength(1),wo=sn(to,to.ATAN).setParameterLength(1,2),Co=sn(to,to.ABS).setParameterLength(1),Mo=sn(to,to.SIGN).setParameterLength(1),Bo=sn(to,to.LENGTH).setParameterLength(1),Fo=sn(to,to.NEGATE).setParameterLength(1),Lo=sn(to,to.ONE_MINUS).setParameterLength(1),Po=sn(to,to.DFDX).setParameterLength(1),Do=sn(to,to.DFDY).setParameterLength(1),Uo=sn(to,to.ROUND).setParameterLength(1),Io=sn(to,to.RECIPROCAL).setParameterLength(1),Oo=sn(to,to.TRUNC).setParameterLength(1),Vo=sn(to,to.FWIDTH).setParameterLength(1),ko=sn(to,to.TRANSPOSE).setParameterLength(1),Go=sn(to,to.DETERMINANT).setParameterLength(1),zo=sn(to,to.INVERSE).setParameterLength(1),$o=sn(to,to.MIN).setParameterLength(2,1/0),Wo=sn(to,to.MAX).setParameterLength(2,1/0),Ho=sn(to,to.STEP).setParameterLength(2),qo=sn(to,to.REFLECT).setParameterLength(2),jo=sn(to,to.DISTANCE).setParameterLength(2),Xo=sn(to,to.DIFFERENCE).setParameterLength(2),Ko=sn(to,to.DOT).setParameterLength(2),Yo=sn(to,to.CROSS).setParameterLength(2),Qo=sn(to,to.POW).setParameterLength(2),Zo=e=>Ba(e,e),Jo=e=>Ba(e,e,e),eu=e=>Ba(e,e,e,e),tu=sn(to,to.TRANSFORM_DIRECTION).setParameterLength(2),ru=e=>Ba(Mo(e),Qo(Co(e),1/3)),su=e=>Ko(e,e),iu=sn(to,to.MIX).setParameterLength(3),nu=(e,t=0,r=1)=>Qi(new to(to.CLAMP,Qi(e),Qi(t),Qi(r))),au=e=>nu(e),ou=sn(to,to.REFRACT).setParameterLength(3),uu=sn(to,to.SMOOTHSTEP).setParameterLength(3),lu=sn(to,to.FACEFORWARD).setParameterLength(3),du=on(([e])=>{const t=Ko(e.xy,yn(12.9898,78.233)),r=La(t,io);return vo(No(r).mul(43758.5453))}),cu=(e,t,r)=>iu(t,r,e),hu=(e,t,r)=>uu(t,r,e),pu=(e,t)=>Ho(t,e),gu=lu,mu=bo;vi("all",uo),vi("any",lo),vi("radians",co),vi("degrees",ho),vi("exp",po),vi("exp2",go),vi("log",mo),vi("log2",fo),vi("sqrt",yo),vi("inverseSqrt",bo),vi("floor",xo),vi("ceil",To),vi("normalize",_o),vi("fract",vo),vi("sin",No),vi("cos",So),vi("tan",Ro),vi("asin",Eo),vi("acos",Ao),vi("atan",wo),vi("abs",Co),vi("sign",Mo),vi("length",Bo),vi("lengthSq",su),vi("negate",Fo),vi("oneMinus",Lo),vi("dFdx",Po),vi("dFdy",Do),vi("round",Uo),vi("reciprocal",Io),vi("trunc",Oo),vi("fwidth",Vo),vi("min",$o),vi("max",Wo),vi("step",pu),vi("reflect",qo),vi("distance",jo),vi("dot",Ko),vi("cross",Yo),vi("pow",Qo),vi("pow2",Zo),vi("pow3",Jo),vi("pow4",eu),vi("transformDirection",tu),vi("mix",cu),vi("clamp",nu),vi("refract",ou),vi("smoothstep",hu),vi("faceForward",lu),vi("difference",Xo),vi("saturate",au),vi("cbrt",ru),vi("transpose",ko),vi("determinant",Go),vi("inverse",zo),vi("rand",du);class fu extends oi{static get type(){return"ConditionalNode"}constructor(e,t,r=null){super(),this.condNode=e,this.ifNode=t,this.elseNode=r}getNodeType(e){const{ifNode:t,elseNode:r}=e.getNodeProperties(this);if(void 0===t)return e.flowBuildStage(this,"setup"),this.getNodeType(e);const s=t.getNodeType(e);if(null!==r){const t=r.getNodeType(e);if(e.getTypeLength(t)>e.getTypeLength(s))return t}return s}setup(e){const t=this.condNode,r=this.ifNode.isolate(),s=this.elseNode?this.elseNode.isolate():null,i=e.context.nodeBlock;e.getDataFromNode(r).parentNodeBlock=i,null!==s&&(e.getDataFromNode(s).parentNodeBlock=i);const n=e.context.uniformFlow,a=e.getNodeProperties(this);a.condNode=t,a.ifNode=n?r:r.context({nodeBlock:r}),a.elseNode=s?n?s:s.context({nodeBlock:s}):null}generate(e,t){const r=this.getNodeType(e),s=e.getDataFromNode(this);if(void 0!==s.nodeProperty)return s.nodeProperty;const{condNode:i,ifNode:n,elseNode:a}=e.getNodeProperties(this),o=e.currentFunctionNode,u="void"!==t,l=u?Dn(r).build(e):"";s.nodeProperty=l;const c=i.build(e,"bool");if(e.context.uniformFlow&&null!==a){const s=n.build(e,r),i=a.build(e,r),o=e.getTernary(c,s,i);return e.format(o,r,t)}e.addFlowCode(`\n${e.tab}if ( ${c} ) {\n\n`).addFlowTab();let h=n.build(e,r);if(h&&(u?h=l+" = "+h+";":(h="return "+h+";",null===o&&(d("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values."),h="// "+h))),e.removeFlowTab().addFlowCode(e.tab+"\t"+h+"\n\n"+e.tab+"}"),null!==a){e.addFlowCode(" else {\n\n").addFlowTab();let t=a.build(e,r);t&&(u?t=l+" = "+t+";":(t="return "+t+";",null===o&&(d("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values."),t="// "+t))),e.removeFlowTab().addFlowCode(e.tab+"\t"+t+"\n\n"+e.tab+"}\n\n")}else e.addFlowCode("\n\n");return e.format(l,r,t)}}const yu=tn(fu).setParameterLength(2,3);vi("select",yu);class bu extends oi{static get type(){return"ContextNode"}constructor(e=null,t={}){super(),this.isContextNode=!0,this.node=e,this.value=t}getScope(){return this.node.getScope()}getNodeType(e){return this.node.getNodeType(e)}getFlowContextData(){const e=[];return this.traverse(t=>{!0===t.isContextNode&&e.push(t.value)}),Object.assign({},...e)}getMemberType(e,t){return this.node.getMemberType(e,t)}analyze(e){const t=e.addContext(this.value);this.node.build(e),e.setContext(t)}setup(e){const t=e.addContext(this.value);this.node.build(e),e.setContext(t)}generate(e,t){const r=e.addContext(this.value),s=this.node.build(e,t);return e.setContext(r),s}}const xu=(e=null,t={})=>{let r=e;return null!==r&&!0===r.isNode||(t=r||t,r=null),new bu(r,t)},Tu=e=>xu(e,{uniformFlow:!0}),_u=(e,t)=>xu(e,{nodeName:t});function vu(e,t,r=null){return xu(r,{getShadow:({light:r,shadowColorNode:s})=>t===r?s.mul(e):s})}function Nu(e,t=null){return xu(t,{getAO:(t,{material:r})=>!0===r.transparent?t:null!==t?t.mul(e):e})}function Su(e,t){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),_u(e,t)}vi("context",xu),vi("label",Su),vi("uniformFlow",Tu),vi("setName",_u),vi("builtinShadowContext",(e,t,r)=>vu(t,r,e)),vi("builtinAOContext",(e,t)=>Nu(t,e));class Ru extends oi{static get type(){return"VarNode"}constructor(e,t=null,r=!1){super(),this.node=e,this.name=t,this.global=!0,this.isVarNode=!0,this.readOnly=r,this.parents=!0,this.intent=!1}setIntent(e){return this.intent=e,this}isIntent(e){return!0!==e.getDataFromNode(this).forceDeclaration&&this.intent}getIntent(){return this.intent}getMemberType(e,t){return this.node.getMemberType(e,t)}getElementType(e){return this.node.getElementType(e)}getNodeType(e){return this.node.getNodeType(e)}getArrayCount(e){return this.node.getArrayCount(e)}isAssign(e){return e.getDataFromNode(this).assign}build(...e){const t=e[0];if(!1===this._hasStack(t)&&"setup"===t.buildStage&&(t.context.nodeLoop||t.context.nodeBlock)){let e=!1;if(this.node.isShaderCallNodeInternal&&null===this.node.shaderNode.getLayout()&&t.fnCall&&t.fnCall.shaderNode){if(t.getDataFromNode(this.node.shaderNode).hasLoop){t.getDataFromNode(this).forceDeclaration=!0,e=!0}}const r=t.getBaseStack();e?r.addToStackBefore(this):r.addToStack(this)}return this.isIntent(t)&&!0!==this.isAssign(t)?this.node.build(...e):super.build(...e)}generate(e){const{node:t,name:r,readOnly:s}=this,{renderer:i}=e,n=!0===i.backend.isWebGPUBackend;let a=!1,u=!1;s&&(a=e.isDeterministic(t),u=n?s:a);const l=this.getNodeType(e);if("void"==l){!0!==this.isIntent(e)&&o('TSL: ".toVar()" can not be used with void type.');return t.build(e)}const d=e.getVectorType(l),c=t.build(e,d),h=e.getVarFromNode(this,r,d,void 0,u),p=e.getPropertyName(h);let g=p;if(u)if(n)g=a?`const ${p}`:`let ${p}`;else{const r=t.getArrayCount(e);g=`const ${e.getVar(h.type,p,r)}`}return e.addLineFlowCode(`${g} = ${c}`,this),p}_hasStack(e){return void 0!==e.getDataFromNode(this).stack}}const Eu=tn(Ru),Au=(e,t=null)=>Eu(e,t).toStack(),wu=(e,t=null)=>Eu(e,t,!0).toStack(),Cu=e=>Eu(e).setIntent(!0).toStack();vi("toVar",Au),vi("toConst",wu),vi("toVarIntent",Cu);class Mu extends oi{static get type(){return"SubBuild"}constructor(e,t,r=null){super(r),this.node=e,this.name=t,this.isSubBuildNode=!0}getNodeType(e){if(null!==this.nodeType)return this.nodeType;e.addSubBuild(this.name);const t=this.node.getNodeType(e);return e.removeSubBuild(),t}build(e,...t){e.addSubBuild(this.name);const r=this.node.build(e,...t);return e.removeSubBuild(),r}}const Bu=(e,t,r=null)=>Qi(new Mu(Qi(e),t,r));class Fu extends oi{static get type(){return"VaryingNode"}constructor(e,t=null){super(),this.node=Bu(e,"VERTEX"),this.name=t,this.isVaryingNode=!0,this.interpolationType=null,this.interpolationSampling=null,this.global=!0}setInterpolation(e,t=null){return this.interpolationType=e,this.interpolationSampling=t,this}getHash(e){return this.name||super.getHash(e)}getNodeType(e){return this.node.getNodeType(e)}setupVarying(e){const t=e.getNodeProperties(this);let r=t.varying;if(void 0===r){const s=this.name,i=this.getNodeType(e),n=this.interpolationType,a=this.interpolationSampling;t.varying=r=e.getVaryingFromNode(this,s,i,n,a),t.node=Bu(this.node,"VERTEX")}return r.needsInterpolation||(r.needsInterpolation="fragment"===e.shaderStage),r}setup(e){this.setupVarying(e),e.flowNodeFromShaderStage(Qs.VERTEX,this.node)}analyze(e){this.setupVarying(e),e.flowNodeFromShaderStage(Qs.VERTEX,this.node)}generate(e){const t=e.getSubBuildProperty("property",e.currentStack),r=e.getNodeProperties(this),s=this.setupVarying(e);if(void 0===r[t]){const i=this.getNodeType(e),n=e.getPropertyName(s,Qs.VERTEX);e.flowNodeFromShaderStage(Qs.VERTEX,r.node,i,n),r[t]=n}return e.getPropertyName(s)}}const Lu=tn(Fu).setParameterLength(1,2),Pu=e=>Lu(e);vi("toVarying",Lu),vi("toVertexStage",Pu);const Du=on(([e])=>{const t=e.mul(.9478672986).add(.0521327014).pow(2.4),r=e.mul(.0773993808),s=e.lessThanEqual(.04045);return iu(t,r,s)}).setLayout({name:"sRGBTransferEOTF",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Uu=on(([e])=>{const t=e.pow(.41666).mul(1.055).sub(.055),r=e.mul(12.92),s=e.lessThanEqual(.0031308);return iu(t,r,s)}).setLayout({name:"sRGBTransferOETF",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Iu="WorkingColorSpace";class Ou extends di{static get type(){return"ColorSpaceNode"}constructor(e,t,r){super("vec4"),this.colorNode=e,this.source=t,this.target=r}resolveColorSpace(e,t){return t===Iu?p.workingColorSpace:"OutputColorSpace"===t?e.context.outputColorSpace||e.renderer.outputColorSpace:t}setup(e){const{colorNode:t}=this,r=this.resolveColorSpace(e,this.source),s=this.resolveColorSpace(e,this.target);let i=t;return!1!==p.enabled&&r!==s&&r&&s?(p.getTransfer(r)===g&&(i=Rn(Du(i.rgb),i.a)),p.getPrimaries(r)!==p.getPrimaries(s)&&(i=Rn(Mn(p._getMatrix(new n,r,s)).mul(i.rgb),i.a)),p.getTransfer(s)===g&&(i=Rn(Uu(i.rgb),i.a)),i):i}}const Vu=(e,t)=>Qi(new Ou(Qi(e),Iu,t)),ku=(e,t)=>Qi(new Ou(Qi(e),t,Iu));vi("workingToColorSpace",Vu),vi("colorSpaceToWorking",ku);let Gu=class extends ui{static get type(){return"ReferenceElementNode"}constructor(e,t){super(e,t),this.referenceNode=e,this.isReferenceElementNode=!0}getNodeType(){return this.referenceNode.uniformType}generate(e){const t=super.generate(e),r=this.referenceNode.getNodeType(),s=this.getNodeType();return e.format(t,r,s)}};class zu extends oi{static get type(){return"ReferenceBaseNode"}constructor(e,t,r=null,s=null){super(),this.property=e,this.uniformType=t,this.object=r,this.count=s,this.properties=e.split("."),this.reference=r,this.node=null,this.group=null,this.updateType=Zs.OBJECT}setGroup(e){return this.group=e,this}element(e){return new Gu(this,Qi(e))}setNodeType(e){const t=Ta(null,e);null!==this.group&&t.setGroup(this.group),this.node=t}getNodeType(e){return null===this.node&&(this.updateReference(e),this.updateValue()),this.node.getNodeType(e)}getValueFromReference(e=this.reference){const{properties:t}=this;let r=e[t[0]];for(let e=1;enew $u(e,t,r);class Hu extends di{static get type(){return"ToneMappingNode"}constructor(e,t=ju,r=null){super("vec3"),this._toneMapping=e,this.exposureNode=t,this.colorNode=r}customCacheKey(){return Is(this._toneMapping)}setToneMapping(e){return this._toneMapping=e,this}getToneMapping(){return this._toneMapping}setup(e){const t=this.colorNode||e.context.color,r=this._toneMapping;if(r===m)return t;let s=null;const i=e.renderer.library.getToneMappingFunction(r);return null!==i?s=Rn(i(t.rgb,this.exposureNode),t.a):(o("ToneMappingNode: Unsupported Tone Mapping configuration.",r),s=t),s}}const qu=(e,t,r)=>Qi(new Hu(e,Qi(t),Qi(r))),ju=Wu("toneMappingExposure","float");vi("toneMapping",(e,t,r)=>qu(t,r,e));const Xu=new WeakMap;function Ku(e,t){let r=Xu.get(e);return void 0===r&&(r=new b(e,t),Xu.set(e,r)),r}class Yu extends fi{static get type(){return"BufferAttributeNode"}constructor(e,t=null,r=0,s=0){super(e,t),this.isBufferNode=!0,this.bufferType=t,this.bufferStride=r,this.bufferOffset=s,this.usage=f,this.instanced=!1,this.attribute=null,this.global=!0,e&&!0===e.isBufferAttribute&&e.itemSize<=4&&(this.attribute=e,this.usage=e.usage,this.instanced=e.isInstancedBufferAttribute)}getHash(e){if(0===this.bufferStride&&0===this.bufferOffset){let t=e.globalCache.getData(this.value);return void 0===t&&(t={node:this},e.globalCache.setData(this.value,t)),t.node.uuid}return this.uuid}getNodeType(e){return null===this.bufferType&&(this.bufferType=e.getTypeFromAttribute(this.attribute)),this.bufferType}setup(e){if(null!==this.attribute)return;const t=this.getNodeType(e),r=e.getTypeLength(t),s=this.value,i=this.bufferStride||r,n=this.bufferOffset;let a;a=!0===s.isInterleavedBuffer?s:!0===s.isBufferAttribute?Ku(s.array,i):Ku(s,i);const o=new y(a,r,n);a.setUsage(this.usage),this.attribute=o,this.attribute.isInstancedBufferAttribute=this.instanced}generate(e){const t=this.getNodeType(e),r=e.getBufferAttributeFromNode(this,t),s=e.getPropertyName(r);let i=null;if("vertex"===e.shaderStage||"compute"===e.shaderStage)this.name=s,i=s;else{i=Lu(this).build(e,t)}return i}getInputType(){return"bufferAttribute"}setUsage(e){return this.usage=e,this.attribute&&!0===this.attribute.isBufferAttribute&&(this.attribute.usage=e),this}setInstanced(e){return this.instanced=e,this}}function Qu(e,t=null,r=0,s=0,i=f,n=!1){return"mat3"===t||null===t&&9===e.itemSize?Mn(new Yu(e,"vec3",9,0).setUsage(i).setInstanced(n),new Yu(e,"vec3",9,3).setUsage(i).setInstanced(n),new Yu(e,"vec3",9,6).setUsage(i).setInstanced(n)):"mat4"===t||null===t&&16===e.itemSize?Bn(new Yu(e,"vec4",16,0).setUsage(i).setInstanced(n),new Yu(e,"vec4",16,4).setUsage(i).setInstanced(n),new Yu(e,"vec4",16,8).setUsage(i).setInstanced(n),new Yu(e,"vec4",16,12).setUsage(i).setInstanced(n)):new Yu(e,t,r,s).setUsage(i)}const Zu=(e,t=null,r=0,s=0)=>Qu(e,t,r,s),Ju=(e,t=null,r=0,s=0)=>Qu(e,t,r,s,f,!0),el=(e,t=null,r=0,s=0)=>Qu(e,t,r,s,x,!0);vi("toAttribute",e=>Zu(e.value));class tl extends oi{static get type(){return"ComputeNode"}constructor(e,t){super("void"),this.isComputeNode=!0,this.computeNode=e,this.workgroupSize=t,this.count=null,this.version=1,this.name="",this.updateBeforeType=Zs.OBJECT,this.onInitFunction=null}setCount(e){return this.count=e,this}getCount(){return this.count}dispose(){this.dispatchEvent({type:"dispose"})}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}onInit(e){return this.onInitFunction=e,this}updateBefore({renderer:e}){e.compute(this)}setup(e){const t=this.computeNode.build(e);if(t){e.getNodeProperties(this).outputComputeNode=t.outputNode,t.outputNode=null}return t}generate(e,t){const{shaderStage:r}=e;if("compute"===r){const t=this.computeNode.build(e,"void");""!==t&&e.addLineFlowCode(t,this)}else{const r=e.getNodeProperties(this).outputComputeNode;if(r)return r.build(e,t)}}}const rl=(e,t=[64])=>{(0===t.length||t.length>3)&&o("TSL: compute() workgroupSize must have 1, 2, or 3 elements");for(let e=0;erl(e,r).setCount(t);vi("compute",sl),vi("computeKernel",rl);class il extends oi{static get type(){return"IsolateNode"}constructor(e,t=!0){super(),this.node=e,this.parent=t,this.isIsolateNode=!0}getNodeType(e){const t=e.getCache(),r=e.getCacheFromNode(this,this.parent);e.setCache(r);const s=this.node.getNodeType(e);return e.setCache(t),s}build(e,...t){const r=e.getCache(),s=e.getCacheFromNode(this,this.parent);e.setCache(s);const i=this.node.build(e,...t);return e.setCache(r),i}setParent(e){return this.parent=e,this}getParent(){return this.parent}}const nl=e=>new il(Qi(e));function al(e,t=!0){return d('TSL: "cache()" has been deprecated. Use "isolate()" instead.'),nl(e).setParent(t)}vi("cache",al),vi("isolate",nl);class ol extends oi{static get type(){return"BypassNode"}constructor(e,t){super(),this.isBypassNode=!0,this.outputNode=e,this.callNode=t}getNodeType(e){return this.outputNode.getNodeType(e)}generate(e){const t=this.callNode.build(e,"void");return""!==t&&e.addLineFlowCode(t,this),this.outputNode.build(e)}}const ul=tn(ol).setParameterLength(2);vi("bypass",ul);class ll extends oi{static get type(){return"RemapNode"}constructor(e,t,r,s=pn(0),i=pn(1)){super(),this.node=e,this.inLowNode=t,this.inHighNode=r,this.outLowNode=s,this.outHighNode=i,this.doClamp=!0}setup(){const{node:e,inLowNode:t,inHighNode:r,outLowNode:s,outHighNode:i,doClamp:n}=this;let a=e.sub(t).div(r.sub(t));return!0===n&&(a=a.clamp()),a.mul(i.sub(s)).add(s)}}const dl=tn(ll,null,null,{doClamp:!1}).setParameterLength(3,5),cl=tn(ll).setParameterLength(3,5);vi("remap",dl),vi("remapClamp",cl);class hl extends oi{static get type(){return"ExpressionNode"}constructor(e="",t="void"){super(t),this.snippet=e}generate(e,t){const r=this.getNodeType(e),s=this.snippet;if("void"!==r)return e.format(s,r,t);e.addLineFlowCode(s,this)}}const pl=tn(hl).setParameterLength(1,2),gl=e=>(e?yu(e,pl("discard")):pl("discard")).toStack();vi("discard",gl);class ml extends di{static get type(){return"RenderOutputNode"}constructor(e,t,r){super("vec4"),this.colorNode=e,this._toneMapping=t,this.outputColorSpace=r,this.isRenderOutputNode=!0}setToneMapping(e){return this._toneMapping=e,this}getToneMapping(){return this._toneMapping}setup({context:e}){let t=this.colorNode||e.color;const r=(null!==this._toneMapping?this._toneMapping:e.toneMapping)||m,s=(null!==this.outputColorSpace?this.outputColorSpace:e.outputColorSpace)||T;return r!==m&&(t=t.toneMapping(r)),s!==T&&s!==p.workingColorSpace&&(t=t.workingToColorSpace(s)),t}}const fl=(e,t=null,r=null)=>Qi(new ml(Qi(e),t,r));vi("renderOutput",fl);class yl extends di{static get type(){return"DebugNode"}constructor(e,t=null){super(),this.node=e,this.callback=t}getNodeType(e){return this.node.getNodeType(e)}setup(e){return this.node.build(e)}analyze(e){return this.node.build(e)}generate(e){const t=this.callback,r=this.node.build(e);if(null!==t)t(e,r);else{const t="--- TSL debug - "+e.shaderStage+" shader ---",s="-".repeat(t.length);let i="";i+="// #"+t+"#\n",i+=e.flow.code.replace(/^\t/gm,"")+"\n",i+="/* ... */ "+r+" /* ... */\n",i+="// #"+s+"#\n",_(i)}return r}}const bl=(e,t=null)=>Qi(new yl(Qi(e),t)).toStack();vi("debug",bl);class xl{constructor(){this._renderer=null,this.currentFrame=null}get nodeFrame(){return this._renderer._nodes.nodeFrame}setRenderer(e){return this._renderer=e,this}getRenderer(){return this._renderer}init(){}begin(){}finish(){}inspect(){}computeAsync(){}beginCompute(){}finishCompute(){}beginRender(){}finishRender(){}copyTextureToTexture(){}copyFramebufferToTexture(){}}class Tl extends oi{static get type(){return"InspectorNode"}constructor(e,t="",r=null){super(),this.node=e,this.name=t,this.callback=r,this.updateType=Zs.FRAME,this.isInspectorNode=!0}getName(){return this.name||this.node.name}update(e){e.renderer.inspector.inspect(this)}getNodeType(e){return this.node.getNodeType(e)}setup(e){let t=this.node;return!0===e.context.inspector&&null!==this.callback&&(t=this.callback(t)),!0!==e.renderer.backend.isWebGPUBackend&&e.renderer.inspector.constructor!==xl&&v('TSL: ".toInspector()" is only available with WebGPU.'),t}}function _l(e,t="",r=null){return(e=Qi(e)).before(new Tl(e,t,r))}vi("toInspector",_l);class vl extends oi{static get type(){return"AttributeNode"}constructor(e,t=null){super(t),this.global=!0,this._attributeName=e}getHash(e){return this.getAttributeName(e)}getNodeType(e){let t=this.nodeType;if(null===t){const r=this.getAttributeName(e);if(e.hasGeometryAttribute(r)){const s=e.geometry.getAttribute(r);t=e.getTypeFromAttribute(s)}else t="float"}return t}setAttributeName(e){return this._attributeName=e,this}getAttributeName(){return this._attributeName}generate(e){const t=this.getAttributeName(e),r=this.getNodeType(e);if(!0===e.hasGeometryAttribute(t)){const s=e.geometry.getAttribute(t),i=e.getTypeFromAttribute(s),n=e.getAttribute(t,i);if("vertex"===e.shaderStage)return e.format(n.name,i,r);return Lu(this).build(e,r)}return d(`AttributeNode: Vertex attribute "${t}" not found on geometry.`),e.generateConst(r)}serialize(e){super.serialize(e),e.global=this.global,e._attributeName=this._attributeName}deserialize(e){super.deserialize(e),this.global=e.global,this._attributeName=e._attributeName}}const Nl=(e,t=null)=>new vl(e,t),Sl=(e=0)=>Nl("uv"+(e>0?e:""),"vec2");class Rl extends oi{static get type(){return"TextureSizeNode"}constructor(e,t=null){super("uvec2"),this.isTextureSizeNode=!0,this.textureNode=e,this.levelNode=t}generate(e,t){const r=this.textureNode.build(e,"property"),s=null===this.levelNode?"0":this.levelNode.build(e,"int");return e.format(`${e.getMethod("textureDimensions")}( ${r}, ${s} )`,this.getNodeType(e),t)}}const El=tn(Rl).setParameterLength(1,2);class Al extends xa{static get type(){return"MaxMipLevelNode"}constructor(e){super(0),this._textureNode=e,this.updateType=Zs.FRAME}get textureNode(){return this._textureNode}get texture(){return this._textureNode.value}update(){const e=this.texture,t=e.images,r=t&&t.length>0?t[0]&&t[0].image||t[0]:e.image;if(r&&void 0!==r.width){const{width:e,height:t}=r;this.value=Math.log2(Math.max(e,t))}}}const wl=tn(Al).setParameterLength(1),Cl=new N;class Ml extends xa{static get type(){return"TextureNode"}constructor(e=Cl,t=null,r=null,s=null){super(e),this.isTextureNode=!0,this.uvNode=t,this.levelNode=r,this.biasNode=s,this.compareNode=null,this.depthNode=null,this.gradNode=null,this.offsetNode=null,this.sampler=!0,this.updateMatrix=!1,this.updateType=Zs.NONE,this.referenceNode=null,this._value=e,this._matrixUniform=null,this._flipYUniform=null,this.setUpdateMatrix(null===t)}set value(e){this.referenceNode?this.referenceNode.value=e:this._value=e}get value(){return this.referenceNode?this.referenceNode.value:this._value}getUniformHash(){return this.value.uuid}getNodeType(){return!0===this.value.isDepthTexture?"float":this.value.type===S?"uvec4":this.value.type===R?"ivec4":"vec4"}getInputType(){return"texture"}getDefaultUV(){return Sl(this.value.channel)}updateReference(){return this.value}getTransformedUV(e){return null===this._matrixUniform&&(this._matrixUniform=Ta(this.value.matrix)),this._matrixUniform.mul(_n(e,1)).xy}setUpdateMatrix(e){return this.updateMatrix=e,this}setupUV(e,t){return e.isFlipY()&&(null===this._flipYUniform&&(this._flipYUniform=Ta(!1)),t=t.toVar(),t=this.sampler?this._flipYUniform.select(t.flipY(),t):this._flipYUniform.select(t.setY(gn(El(this,this.levelNode).y).sub(t.y).sub(1)),t)),t}setup(e){const t=e.getNodeProperties(this);t.referenceNode=this.referenceNode;const r=this.value;if(!r||!0!==r.isTexture)throw new Error("THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().");const s=on(()=>{let t=this.uvNode;return null!==t&&!0!==e.context.forceUVContext||!e.context.getUV||(t=e.context.getUV(this,e)),t||(t=this.getDefaultUV()),!0===this.updateMatrix&&(t=this.getTransformedUV(t)),t=this.setupUV(e,t),this.updateType=null!==this._matrixUniform||null!==this._flipYUniform?Zs.OBJECT:Zs.NONE,t})();let i=this.levelNode;null===i&&e.context.getTextureLevel&&(i=e.context.getTextureLevel(this));let n=null,a=null;null!==this.compareNode&&(e.renderer.hasCompatibility(E.TEXTURE_COMPARE)?n=this.compareNode:(null!==this.value.compareFunction&&this.value.compareFunction!==A&&v('TSL: Only "LessCompare" is supported for depth texture comparison fallback.'),a=this.compareNode)),t.uvNode=s,t.levelNode=i,t.biasNode=this.biasNode,t.compareNode=n,t.compareStepNode=a,t.gradNode=this.gradNode,t.depthNode=this.depthNode,t.offsetNode=this.offsetNode}generateUV(e,t){return t.build(e,!0===this.sampler?"vec2":"ivec2")}generateOffset(e,t){return t.build(e,"ivec2")}generateSnippet(e,t,r,s,i,n,a,o,u){const l=this.value;let d;return d=i?e.generateTextureBias(l,t,r,i,n,u):o?e.generateTextureGrad(l,t,r,o,n,u):a?e.generateTextureCompare(l,t,r,a,n,u):!1===this.sampler?e.generateTextureLoad(l,t,r,s,n,u):s?e.generateTextureLevel(l,t,r,s,n,u):e.generateTexture(l,t,r,n,u),d}generate(e,t){const r=this.value,s=e.getNodeProperties(this),i=super.generate(e,"property");if(/^sampler/.test(t))return i+"_sampler";if(e.isReference(t))return i;{const n=e.getDataFromNode(this),a=this.getNodeType(e);let o=n.propertyName;if(void 0===o){const{uvNode:t,levelNode:r,biasNode:u,compareNode:l,compareStepNode:d,depthNode:c,gradNode:h,offsetNode:p}=s,g=this.generateUV(e,t),m=r?r.build(e,"float"):null,f=u?u.build(e,"float"):null,y=c?c.build(e,"int"):null,b=l?l.build(e,"float"):null,x=d?d.build(e,"float"):null,T=h?[h[0].build(e,"vec2"),h[1].build(e,"vec2")]:null,_=p?this.generateOffset(e,p):null,v=e.getVarFromNode(this);o=e.getPropertyName(v);let N=this.generateSnippet(e,i,g,m,f,y,b,T,_);null!==x&&(N=Ho(pl(x,"float"),pl(N,a)).build(e,a)),e.addLineFlowCode(`${o} = ${N}`,this),n.snippet=N,n.propertyName=o}let u=o;return e.needsToWorkingColorSpace(r)&&(u=ku(pl(u,a),r.colorSpace).setup(e).build(e,a)),e.format(u,a,t)}}setSampler(e){return this.sampler=e,this}getSampler(){return this.sampler}sample(e){const t=this.clone();return t.uvNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}load(e){return this.sample(e).setSampler(!1)}blur(e){const t=this.clone();t.biasNode=Qi(e).mul(wl(t)),t.referenceNode=this.getBase();const r=t.value;return!1===t.generateMipmaps&&(r&&!1===r.generateMipmaps||r.minFilter===w||r.magFilter===w)&&(d("TSL: texture().blur() requires mipmaps and sampling. Use .generateMipmaps=true and .minFilter/.magFilter=THREE.LinearFilter in the Texture."),t.biasNode=null),Qi(t)}level(e){const t=this.clone();return t.levelNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}size(e){return El(this,e)}bias(e){const t=this.clone();return t.biasNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}getBase(){return this.referenceNode?this.referenceNode.getBase():this}compare(e){const t=this.clone();return t.compareNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}grad(e,t){const r=this.clone();return r.gradNode=[Qi(e),Qi(t)],r.referenceNode=this.getBase(),Qi(r)}depth(e){const t=this.clone();return t.depthNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}offset(e){const t=this.clone();return t.offsetNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}serialize(e){super.serialize(e),e.value=this.value.toJSON(e.meta).uuid,e.sampler=this.sampler,e.updateMatrix=this.updateMatrix,e.updateType=this.updateType}deserialize(e){super.deserialize(e),this.value=e.meta.textures[e.value],this.sampler=e.sampler,this.updateMatrix=e.updateMatrix,this.updateType=e.updateType}update(){const e=this.value,t=this._matrixUniform;null!==t&&(t.value=e.matrix),!0===e.matrixAutoUpdate&&e.updateMatrix();const r=this._flipYUniform;null!==r&&(r.value=e.image instanceof ImageBitmap&&!0===e.flipY||!0===e.isRenderTargetTexture||!0===e.isFramebufferTexture||!0===e.isDepthTexture)}clone(){const e=new this.constructor(this.value,this.uvNode,this.levelNode,this.biasNode);return e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e}}const Bl=tn(Ml).setParameterLength(1,4).setName("texture"),Fl=(e=Cl,t=null,r=null,s=null)=>{let i;return e&&!0===e.isTextureNode?(i=Qi(e.clone()),i.referenceNode=e.getBase(),null!==t&&(i.uvNode=Qi(t)),null!==r&&(i.levelNode=Qi(r)),null!==s&&(i.biasNode=Qi(s))):i=Bl(e,t,r,s),i},Ll=(...e)=>Fl(...e).setSampler(!1);class Pl extends xa{static get type(){return"BufferNode"}constructor(e,t,r=0){super(e,t),this.isBufferNode=!0,this.bufferType=t,this.bufferCount=r,this.updateRanges=[]}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}getElementType(e){return this.getNodeType(e)}getInputType(){return"buffer"}}const Dl=(e,t,r)=>new Pl(e,t,r);class Ul extends ui{static get type(){return"UniformArrayElementNode"}constructor(e,t){super(e,t),this.isArrayBufferElementNode=!0}generate(e){const t=super.generate(e),r=this.getNodeType(),s=this.node.getPaddedType();return e.format(t,s,r)}}class Il extends Pl{static get type(){return"UniformArrayNode"}constructor(e,t=null){super(null),this.array=e,this.elementType=null===t?Hs(e[0]):t,this.paddedType=this.getPaddedType(),this.updateType=Zs.RENDER,this.isArrayBufferNode=!0}getNodeType(){return this.paddedType}getElementType(){return this.elementType}getPaddedType(){const e=this.elementType;let t="vec4";return"mat2"===e?t="mat2":!0===/mat/.test(e)?t="mat4":"i"===e.charAt(0)?t="ivec4":"u"===e.charAt(0)&&(t="uvec4"),t}update(){const{array:e,value:t}=this,r=this.elementType;if("float"===r||"int"===r||"uint"===r)for(let r=0;rnew Il(e,t);class Vl extends oi{constructor(e){super("float"),this.name=e,this.isBuiltinNode=!0}generate(){return this.name}}const kl=tn(Vl).setParameterLength(1);let Gl,zl;class $l extends oi{static get type(){return"ScreenNode"}constructor(e){super(),this.scope=e,this._output=null,this.isViewportNode=!0}getNodeType(){return this.scope===$l.DPR?"float":this.scope===$l.VIEWPORT?"vec4":"vec2"}getUpdateType(){let e=Zs.NONE;return this.scope!==$l.SIZE&&this.scope!==$l.VIEWPORT&&this.scope!==$l.DPR||(e=Zs.RENDER),this.updateType=e,e}update({renderer:e}){const t=e.getRenderTarget();this.scope===$l.VIEWPORT?null!==t?zl.copy(t.viewport):(e.getViewport(zl),zl.multiplyScalar(e.getPixelRatio())):this.scope===$l.DPR?this._output.value=e.getPixelRatio():null!==t?(Gl.width=t.width,Gl.height=t.height):e.getDrawingBufferSize(Gl)}setup(){const e=this.scope;let r=null;return r=e===$l.SIZE?Ta(Gl||(Gl=new t)):e===$l.VIEWPORT?Ta(zl||(zl=new s)):e===$l.DPR?Ta(1):yn(jl.div(ql)),this._output=r,r}generate(e){if(this.scope===$l.COORDINATE){let t=e.getFragCoord();if(e.isFlipY()){const r=e.getNodeProperties(ql).outputNode.build(e);t=`${e.getType("vec2")}( ${t}.x, ${r}.y - ${t}.y )`}return t}return super.generate(e)}}$l.COORDINATE="coordinate",$l.VIEWPORT="viewport",$l.SIZE="size",$l.UV="uv",$l.DPR="dpr";const Wl=rn($l,$l.DPR),Hl=rn($l,$l.UV),ql=rn($l,$l.SIZE),jl=rn($l,$l.COORDINATE),Xl=rn($l,$l.VIEWPORT),Kl=Xl.zw,Yl=jl.sub(Xl.xy),Ql=Yl.div(Kl),Zl=on(()=>(d('TSL: "viewportResolution" is deprecated. Use "screenSize" instead.'),ql),"vec2").once()(),Jl=Ta(0,"uint").setName("u_cameraIndex").setGroup(ma("cameraIndex")).toVarying("v_cameraIndex"),ed=Ta("float").setName("cameraNear").setGroup(ya).onRenderUpdate(({camera:e})=>e.near),td=Ta("float").setName("cameraFar").setGroup(ya).onRenderUpdate(({camera:e})=>e.far),rd=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.projectionMatrix);t=Ol(r).setGroup(ya).setName("cameraProjectionMatrices").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraProjectionMatrix")}else t=Ta("mat4").setName("cameraProjectionMatrix").setGroup(ya).onRenderUpdate(({camera:e})=>e.projectionMatrix);return t}).once()(),sd=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.projectionMatrixInverse);t=Ol(r).setGroup(ya).setName("cameraProjectionMatricesInverse").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraProjectionMatrixInverse")}else t=Ta("mat4").setName("cameraProjectionMatrixInverse").setGroup(ya).onRenderUpdate(({camera:e})=>e.projectionMatrixInverse);return t}).once()(),id=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.matrixWorldInverse);t=Ol(r).setGroup(ya).setName("cameraViewMatrices").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraViewMatrix")}else t=Ta("mat4").setName("cameraViewMatrix").setGroup(ya).onRenderUpdate(({camera:e})=>e.matrixWorldInverse);return t}).once()(),nd=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.matrixWorld);t=Ol(r).setGroup(ya).setName("cameraWorldMatrices").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraWorldMatrix")}else t=Ta("mat4").setName("cameraWorldMatrix").setGroup(ya).onRenderUpdate(({camera:e})=>e.matrixWorld);return t}).once()(),ad=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.normalMatrix);t=Ol(r).setGroup(ya).setName("cameraNormalMatrices").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraNormalMatrix")}else t=Ta("mat3").setName("cameraNormalMatrix").setGroup(ya).onRenderUpdate(({camera:e})=>e.normalMatrix);return t}).once()(),od=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const s=[];for(let t=0,i=e.cameras.length;t{const r=e.cameras,s=t.array;for(let e=0,t=r.length;et.value.setFromMatrixPosition(e.matrixWorld));return t}).once()(),ud=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.viewport);t=Ol(r,"vec4").setGroup(ya).setName("cameraViewports").element(Jl).toConst("cameraViewport")}else t=Rn(0,0,ql.x,ql.y).toConst("cameraViewport");return t}).once()(),ld=new C;class dd extends oi{static get type(){return"Object3DNode"}constructor(e,t=null){super(),this.scope=e,this.object3d=t,this.updateType=Zs.OBJECT,this.uniformNode=new xa(null)}getNodeType(){const e=this.scope;return e===dd.WORLD_MATRIX?"mat4":e===dd.POSITION||e===dd.VIEW_POSITION||e===dd.DIRECTION||e===dd.SCALE?"vec3":e===dd.RADIUS?"float":void 0}update(e){const t=this.object3d,s=this.uniformNode,i=this.scope;if(i===dd.WORLD_MATRIX)s.value=t.matrixWorld;else if(i===dd.POSITION)s.value=s.value||new r,s.value.setFromMatrixPosition(t.matrixWorld);else if(i===dd.SCALE)s.value=s.value||new r,s.value.setFromMatrixScale(t.matrixWorld);else if(i===dd.DIRECTION)s.value=s.value||new r,t.getWorldDirection(s.value);else if(i===dd.VIEW_POSITION){const i=e.camera;s.value=s.value||new r,s.value.setFromMatrixPosition(t.matrixWorld),s.value.applyMatrix4(i.matrixWorldInverse)}else if(i===dd.RADIUS){const r=e.object.geometry;null===r.boundingSphere&&r.computeBoundingSphere(),ld.copy(r.boundingSphere).applyMatrix4(t.matrixWorld),s.value=ld.radius}}generate(e){const t=this.scope;return t===dd.WORLD_MATRIX?this.uniformNode.nodeType="mat4":t===dd.POSITION||t===dd.VIEW_POSITION||t===dd.DIRECTION||t===dd.SCALE?this.uniformNode.nodeType="vec3":t===dd.RADIUS&&(this.uniformNode.nodeType="float"),this.uniformNode.build(e)}serialize(e){super.serialize(e),e.scope=this.scope}deserialize(e){super.deserialize(e),this.scope=e.scope}}dd.WORLD_MATRIX="worldMatrix",dd.POSITION="position",dd.SCALE="scale",dd.VIEW_POSITION="viewPosition",dd.DIRECTION="direction",dd.RADIUS="radius";const cd=tn(dd,dd.DIRECTION).setParameterLength(1),hd=tn(dd,dd.WORLD_MATRIX).setParameterLength(1),pd=tn(dd,dd.POSITION).setParameterLength(1),gd=tn(dd,dd.SCALE).setParameterLength(1),md=tn(dd,dd.VIEW_POSITION).setParameterLength(1),fd=tn(dd,dd.RADIUS).setParameterLength(1);class yd extends dd{static get type(){return"ModelNode"}constructor(e){super(e)}update(e){this.object3d=e.object,super.update(e)}}const bd=rn(yd,yd.DIRECTION),xd=rn(yd,yd.WORLD_MATRIX),Td=rn(yd,yd.POSITION),_d=rn(yd,yd.SCALE),vd=rn(yd,yd.VIEW_POSITION),Nd=rn(yd,yd.RADIUS),Sd=Ta(new n).onObjectUpdate(({object:e},t)=>t.value.getNormalMatrix(e.matrixWorld)),Rd=Ta(new a).onObjectUpdate(({object:e},t)=>t.value.copy(e.matrixWorld).invert()),Ed=on(e=>e.context.modelViewMatrix||Ad).once()().toVar("modelViewMatrix"),Ad=id.mul(xd),wd=on(e=>(e.context.isHighPrecisionModelViewMatrix=!0,Ta("mat4").onObjectUpdate(({object:e,camera:t})=>e.modelViewMatrix.multiplyMatrices(t.matrixWorldInverse,e.matrixWorld)))).once()().toVar("highpModelViewMatrix"),Cd=on(e=>{const t=e.context.isHighPrecisionModelViewMatrix;return Ta("mat3").onObjectUpdate(({object:e,camera:r})=>(!0!==t&&e.modelViewMatrix.multiplyMatrices(r.matrixWorldInverse,e.matrixWorld),e.normalMatrix.getNormalMatrix(e.modelViewMatrix)))}).once()().toVar("highpModelNormalViewMatrix"),Md=on(e=>"fragment"!==e.shaderStage?(v("TSL: `clipSpace` is only available in fragment stage."),Rn()):e.context.clipSpace.toVarying("v_clipSpace")).once()(),Bd=Nl("position","vec3"),Fd=Bd.toVarying("positionLocal"),Ld=Bd.toVarying("positionPrevious"),Pd=on(e=>xd.mul(Fd).xyz.toVarying(e.getSubBuildProperty("v_positionWorld")),"vec3").once(["POSITION"])(),Dd=on(()=>Fd.transformDirection(xd).toVarying("v_positionWorldDirection").normalize().toVar("positionWorldDirection"),"vec3").once(["POSITION"])(),Ud=on(e=>{if("fragment"===e.shaderStage&&e.material.vertexNode){const e=sd.mul(Md);return e.xyz.div(e.w).toVar("positionView")}return e.context.setupPositionView().toVarying("v_positionView")},"vec3").once(["POSITION","VERTEX"])(),Id=on(e=>{let t;return t=e.camera.isOrthographicCamera?_n(0,0,1):Ud.negate().toVarying("v_positionViewDirection").normalize(),t.toVar("positionViewDirection")},"vec3").once(["POSITION"])();class Od extends oi{static get type(){return"FrontFacingNode"}constructor(){super("bool"),this.isFrontFacingNode=!0}generate(e){if("fragment"!==e.shaderStage)return"true";const{material:t}=e;return t.side===M?"false":e.getFrontFacing()}}const Vd=rn(Od),kd=pn(Vd).mul(2).sub(1),Gd=on(([e],{material:t})=>{const r=t.side;return r===M?e=e.mul(-1):r===B&&(e=e.mul(kd)),e}),zd=Nl("normal","vec3"),$d=on(e=>!1===e.geometry.hasAttribute("normal")?(d('TSL: Vertex attribute "normal" not found on geometry.'),_n(0,1,0)):zd,"vec3").once()().toVar("normalLocal"),Wd=Ud.dFdx().cross(Ud.dFdy()).normalize().toVar("normalFlat"),Hd=on(e=>{let t;return t=e.isFlatShading()?Wd:Qd($d).toVarying("v_normalViewGeometry").normalize(),t},"vec3").once()().toVar("normalViewGeometry"),qd=on(e=>{let t=Hd.transformDirection(id);return!0!==e.isFlatShading()&&(t=t.toVarying("v_normalWorldGeometry")),t.normalize().toVar("normalWorldGeometry")},"vec3").once()(),jd=on(e=>{let t;return"NORMAL"===e.subBuildFn||"VERTEX"===e.subBuildFn?(t=Hd,!0!==e.isFlatShading()&&(t=Gd(t))):t=e.context.setupNormal().context({getUV:null,getTextureLevel:null}),t},"vec3").once(["NORMAL","VERTEX"])().toVar("normalView"),Xd=jd.transformDirection(id).toVar("normalWorld"),Kd=on(({subBuildFn:e,context:t})=>{let r;return r="NORMAL"===e||"VERTEX"===e?jd:t.setupClearcoatNormal().context({getUV:null,getTextureLevel:null}),r},"vec3").once(["NORMAL","VERTEX"])().toVar("clearcoatNormalView"),Yd=on(([e,t=xd])=>{const r=Mn(t),s=e.div(_n(r[0].dot(r[0]),r[1].dot(r[1]),r[2].dot(r[2])));return r.mul(s).xyz}),Qd=on(([e],t)=>{const r=t.context.modelNormalViewMatrix;if(r)return r.transformDirection(e);const s=Sd.mul(e);return id.transformDirection(s)}),Zd=on(()=>(d('TSL: "transformedNormalView" is deprecated. Use "normalView" instead.'),jd)).once(["NORMAL","VERTEX"])(),Jd=on(()=>(d('TSL: "transformedNormalWorld" is deprecated. Use "normalWorld" instead.'),Xd)).once(["NORMAL","VERTEX"])(),ec=on(()=>(d('TSL: "transformedClearcoatNormalView" is deprecated. Use "clearcoatNormalView" instead.'),Kd)).once(["NORMAL","VERTEX"])(),tc=new F,rc=new a,sc=Ta(0).onReference(({material:e})=>e).onObjectUpdate(({material:e})=>e.refractionRatio),ic=Ta(1).onReference(({material:e})=>e).onObjectUpdate(function({material:e,scene:t}){return e.envMap?e.envMapIntensity:t.environmentIntensity}),nc=Ta(new a).onReference(function(e){return e.material}).onObjectUpdate(function({material:e,scene:t}){const r=null!==t.environment&&null===e.envMap?t.environmentRotation:e.envMapRotation;return r?(tc.copy(r),rc.makeRotationFromEuler(tc)):rc.identity(),rc}),ac=Id.negate().reflect(jd),oc=Id.negate().refract(jd,sc),uc=ac.transformDirection(id).toVar("reflectVector"),lc=oc.transformDirection(id).toVar("reflectVector"),dc=new L;class cc extends Ml{static get type(){return"CubeTextureNode"}constructor(e,t=null,r=null,s=null){super(e,t,r,s),this.isCubeTextureNode=!0}getInputType(){return!0===this.value.isDepthTexture?"cubeDepthTexture":"cubeTexture"}getDefaultUV(){const e=this.value;return e.mapping===P?uc:e.mapping===D?lc:(o('CubeTextureNode: Mapping "%s" not supported.',e.mapping),_n(0,0,0))}setUpdateMatrix(){}setupUV(e,t){const r=this.value;return!0===r.isDepthTexture?e.renderer.coordinateSystem===h?_n(t.x,t.y.negate(),t.z):t:(e.renderer.coordinateSystem!==h&&r.isRenderTargetTexture||(t=_n(t.x.negate(),t.yz)),nc.mul(t))}generateUV(e,t){return t.build(e,!0===this.sampler?"vec3":"ivec3")}}const hc=tn(cc).setParameterLength(1,4).setName("cubeTexture"),pc=(e=dc,t=null,r=null,s=null)=>{let i;return e&&!0===e.isCubeTextureNode?(i=Qi(e.clone()),i.referenceNode=e,null!==t&&(i.uvNode=Qi(t)),null!==r&&(i.levelNode=Qi(r)),null!==s&&(i.biasNode=Qi(s))):i=hc(e,t,r,s),i};class gc extends ui{static get type(){return"ReferenceElementNode"}constructor(e,t){super(e,t),this.referenceNode=e,this.isReferenceElementNode=!0}getNodeType(){return this.referenceNode.uniformType}generate(e){const t=super.generate(e),r=this.referenceNode.getNodeType(),s=this.getNodeType();return e.format(t,r,s)}}class mc extends oi{static get type(){return"ReferenceNode"}constructor(e,t,r=null,s=null){super(),this.property=e,this.uniformType=t,this.object=r,this.count=s,this.properties=e.split("."),this.reference=r,this.node=null,this.group=null,this.name=null,this.updateType=Zs.OBJECT}element(e){return new gc(this,Qi(e))}setGroup(e){return this.group=e,this}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setNodeType(e){let t=null;t=null!==this.count?Dl(null,e,this.count):Array.isArray(this.getValueFromReference())?Ol(null,e):"texture"===e?Fl(null):"cubeTexture"===e?pc(null):Ta(null,e),null!==this.group&&t.setGroup(this.group),null!==this.name&&t.setName(this.name),this.node=t}getNodeType(e){return null===this.node&&(this.updateReference(e),this.updateValue()),this.node.getNodeType(e)}getValueFromReference(e=this.reference){const{properties:t}=this;let r=e[t[0]];for(let e=1;enew mc(e,t,r),yc=(e,t,r,s)=>new mc(e,t,s,r);class bc extends mc{static get type(){return"MaterialReferenceNode"}constructor(e,t,r=null){super(e,t,r),this.material=r,this.isMaterialReferenceNode=!0}updateReference(e){return this.reference=null!==this.material?this.material:e.material,this.reference}}const xc=(e,t,r=null)=>new bc(e,t,r),Tc=Sl(),_c=Ud.dFdx(),vc=Ud.dFdy(),Nc=Tc.dFdx(),Sc=Tc.dFdy(),Rc=jd,Ec=vc.cross(Rc),Ac=Rc.cross(_c),wc=Ec.mul(Nc.x).add(Ac.mul(Sc.x)),Cc=Ec.mul(Nc.y).add(Ac.mul(Sc.y)),Mc=wc.dot(wc).max(Cc.dot(Cc)),Bc=Mc.equal(0).select(0,Mc.inverseSqrt()),Fc=wc.mul(Bc).toVar("tangentViewFrame"),Lc=Cc.mul(Bc).toVar("bitangentViewFrame"),Pc=Nl("tangent","vec4"),Dc=Pc.xyz.toVar("tangentLocal"),Uc=on(e=>{let t;return t="VERTEX"===e.subBuildFn||e.geometry.hasAttribute("tangent")?Ed.mul(Rn(Dc,0)).xyz.toVarying("v_tangentView").normalize():Fc,!0!==e.isFlatShading()&&(t=Gd(t)),t},"vec3").once(["NORMAL","VERTEX"])().toVar("tangentView"),Ic=Uc.transformDirection(id).toVarying("v_tangentWorld").normalize().toVar("tangentWorld"),Oc=on(([e,t],r)=>{let s=e.mul(Pc.w).xyz;return"NORMAL"===r.subBuildFn&&!0!==r.isFlatShading()&&(s=s.toVarying(t)),s}).once(["NORMAL"]),Vc=Oc(zd.cross(Pc),"v_bitangentGeometry").normalize().toVar("bitangentGeometry"),kc=Oc($d.cross(Dc),"v_bitangentLocal").normalize().toVar("bitangentLocal"),Gc=on(e=>{let t;return t="VERTEX"===e.subBuildFn||e.geometry.hasAttribute("tangent")?Oc(jd.cross(Uc),"v_bitangentView").normalize():Lc,!0!==e.isFlatShading()&&(t=Gd(t)),t},"vec3").once(["NORMAL","VERTEX"])().toVar("bitangentView"),zc=Oc(Xd.cross(Ic),"v_bitangentWorld").normalize().toVar("bitangentWorld"),$c=Mn(Uc,Gc,jd).toVar("TBNViewMatrix"),Wc=Id.mul($c),Hc=on(()=>{let e=Zn.cross(Id);return e=e.cross(Zn).normalize(),e=iu(e,jd,Yn.mul(kn.oneMinus()).oneMinus().pow2().pow2()).normalize(),e}).once()(),qc=e=>Qi(e).mul(.5).add(.5),jc=e=>_n(e,yo(au(pn(1).sub(Ko(e,e)))));class Xc extends di{static get type(){return"NormalMapNode"}constructor(e,t=null){super("vec3"),this.node=e,this.scaleNode=t,this.normalMapType=U,this.unpackNormalMode=I}setup(e){const{normalMapType:t,scaleNode:r,unpackNormalMode:s}=this;let i=this.node.mul(2).sub(1);if(t===U?s===O?i=jc(i.xy):s===V?i=jc(i.yw):s!==I&&console.error(`THREE.NodeMaterial: Unexpected unpack normal mode: ${s}`):s!==I&&console.error(`THREE.NodeMaterial: Normal map type '${t}' is not compatible with unpack normal mode '${s}'`),null!==r){let t=r;!0===e.isFlatShading()&&(t=Gd(t)),i=_n(i.xy.mul(t),i.z)}let n=null;return t===k?n=Qd(i):t===U?n=$c.mul(i).normalize():(o(`NodeMaterial: Unsupported normal map type: ${t}`),n=jd),n}}const Kc=tn(Xc).setParameterLength(1,2),Yc=on(({textureNode:e,bumpScale:t})=>{const r=t=>e.isolate().context({getUV:e=>t(e.uvNode||Sl()),forceUVContext:!0}),s=pn(r(e=>e));return yn(pn(r(e=>e.add(e.dFdx()))).sub(s),pn(r(e=>e.add(e.dFdy()))).sub(s)).mul(t)}),Qc=on(e=>{const{surf_pos:t,surf_norm:r,dHdxy:s}=e,i=t.dFdx().normalize(),n=r,a=t.dFdy().normalize().cross(n),o=n.cross(i),u=i.dot(a).mul(kd),l=u.sign().mul(s.x.mul(a).add(s.y.mul(o)));return u.abs().mul(r).sub(l).normalize()});class Zc extends di{static get type(){return"BumpMapNode"}constructor(e,t=null){super("vec3"),this.textureNode=e,this.scaleNode=t}setup(){const e=null!==this.scaleNode?this.scaleNode:1,t=Yc({textureNode:this.textureNode,bumpScale:e});return Qc({surf_pos:Ud,surf_norm:jd,dHdxy:t})}}const Jc=tn(Zc).setParameterLength(1,2),eh=new Map;class th extends oi{static get type(){return"MaterialNode"}constructor(e){super(),this.scope=e}getCache(e,t){let r=eh.get(e);return void 0===r&&(r=xc(e,t),eh.set(e,r)),r}getFloat(e){return this.getCache(e,"float")}getColor(e){return this.getCache(e,"color")}getTexture(e){return this.getCache("map"===e?"map":e+"Map","texture")}setup(e){const t=e.context.material,r=this.scope;let s=null;if(r===th.COLOR){const e=void 0!==t.color?this.getColor(r):_n();s=t.map&&!0===t.map.isTexture?e.mul(this.getTexture("map")):e}else if(r===th.OPACITY){const e=this.getFloat(r);s=t.alphaMap&&!0===t.alphaMap.isTexture?e.mul(this.getTexture("alpha")):e}else if(r===th.SPECULAR_STRENGTH)s=t.specularMap&&!0===t.specularMap.isTexture?this.getTexture("specular").r:pn(1);else if(r===th.SPECULAR_INTENSITY){const e=this.getFloat(r);s=t.specularIntensityMap&&!0===t.specularIntensityMap.isTexture?e.mul(this.getTexture(r).a):e}else if(r===th.SPECULAR_COLOR){const e=this.getColor(r);s=t.specularColorMap&&!0===t.specularColorMap.isTexture?e.mul(this.getTexture(r).rgb):e}else if(r===th.ROUGHNESS){const e=this.getFloat(r);s=t.roughnessMap&&!0===t.roughnessMap.isTexture?e.mul(this.getTexture(r).g):e}else if(r===th.METALNESS){const e=this.getFloat(r);s=t.metalnessMap&&!0===t.metalnessMap.isTexture?e.mul(this.getTexture(r).b):e}else if(r===th.EMISSIVE){const e=this.getFloat("emissiveIntensity"),i=this.getColor(r).mul(e);s=t.emissiveMap&&!0===t.emissiveMap.isTexture?i.mul(this.getTexture(r)):i}else if(r===th.NORMAL)t.normalMap?(s=Kc(this.getTexture("normal"),this.getCache("normalScale","vec2")),s.normalMapType=t.normalMapType,t.normalMap.format!=G&&t.normalMap.format!=z&&t.normalMap.format!=$||(s.unpackNormalMode=O)):s=t.bumpMap?Jc(this.getTexture("bump").r,this.getFloat("bumpScale")):jd;else if(r===th.CLEARCOAT){const e=this.getFloat(r);s=t.clearcoatMap&&!0===t.clearcoatMap.isTexture?e.mul(this.getTexture(r).r):e}else if(r===th.CLEARCOAT_ROUGHNESS){const e=this.getFloat(r);s=t.clearcoatRoughnessMap&&!0===t.clearcoatRoughnessMap.isTexture?e.mul(this.getTexture(r).r):e}else if(r===th.CLEARCOAT_NORMAL)s=t.clearcoatNormalMap?Kc(this.getTexture(r),this.getCache(r+"Scale","vec2")):jd;else if(r===th.SHEEN){const e=this.getColor("sheenColor").mul(this.getFloat("sheen"));s=t.sheenColorMap&&!0===t.sheenColorMap.isTexture?e.mul(this.getTexture("sheenColor").rgb):e}else if(r===th.SHEEN_ROUGHNESS){const e=this.getFloat(r);s=t.sheenRoughnessMap&&!0===t.sheenRoughnessMap.isTexture?e.mul(this.getTexture(r).a):e,s=s.clamp(1e-4,1)}else if(r===th.ANISOTROPY)if(t.anisotropyMap&&!0===t.anisotropyMap.isTexture){const e=this.getTexture(r);s=Cn(Vh.x,Vh.y,Vh.y.negate(),Vh.x).mul(e.rg.mul(2).sub(yn(1)).normalize().mul(e.b))}else s=Vh;else if(r===th.IRIDESCENCE_THICKNESS){const e=fc("1","float",t.iridescenceThicknessRange);if(t.iridescenceThicknessMap){const i=fc("0","float",t.iridescenceThicknessRange);s=e.sub(i).mul(this.getTexture(r).g).add(i)}else s=e}else if(r===th.TRANSMISSION){const e=this.getFloat(r);s=t.transmissionMap?e.mul(this.getTexture(r).r):e}else if(r===th.THICKNESS){const e=this.getFloat(r);s=t.thicknessMap?e.mul(this.getTexture(r).g):e}else if(r===th.IOR)s=this.getFloat(r);else if(r===th.LIGHT_MAP)s=this.getTexture(r).rgb.mul(this.getFloat("lightMapIntensity"));else if(r===th.AO)s=this.getTexture(r).r.sub(1).mul(this.getFloat("aoMapIntensity")).add(1);else if(r===th.LINE_DASH_OFFSET)s=t.dashOffset?this.getFloat(r):pn(0);else{const t=this.getNodeType(e);s=this.getCache(r,t)}return s}}th.ALPHA_TEST="alphaTest",th.COLOR="color",th.OPACITY="opacity",th.SHININESS="shininess",th.SPECULAR="specular",th.SPECULAR_STRENGTH="specularStrength",th.SPECULAR_INTENSITY="specularIntensity",th.SPECULAR_COLOR="specularColor",th.REFLECTIVITY="reflectivity",th.ROUGHNESS="roughness",th.METALNESS="metalness",th.NORMAL="normal",th.CLEARCOAT="clearcoat",th.CLEARCOAT_ROUGHNESS="clearcoatRoughness",th.CLEARCOAT_NORMAL="clearcoatNormal",th.EMISSIVE="emissive",th.ROTATION="rotation",th.SHEEN="sheen",th.SHEEN_ROUGHNESS="sheenRoughness",th.ANISOTROPY="anisotropy",th.IRIDESCENCE="iridescence",th.IRIDESCENCE_IOR="iridescenceIOR",th.IRIDESCENCE_THICKNESS="iridescenceThickness",th.IOR="ior",th.TRANSMISSION="transmission",th.THICKNESS="thickness",th.ATTENUATION_DISTANCE="attenuationDistance",th.ATTENUATION_COLOR="attenuationColor",th.LINE_SCALE="scale",th.LINE_DASH_SIZE="dashSize",th.LINE_GAP_SIZE="gapSize",th.LINE_WIDTH="linewidth",th.LINE_DASH_OFFSET="dashOffset",th.POINT_SIZE="size",th.DISPERSION="dispersion",th.LIGHT_MAP="light",th.AO="ao";const rh=rn(th,th.ALPHA_TEST),sh=rn(th,th.COLOR),ih=rn(th,th.SHININESS),nh=rn(th,th.EMISSIVE),ah=rn(th,th.OPACITY),oh=rn(th,th.SPECULAR),uh=rn(th,th.SPECULAR_INTENSITY),lh=rn(th,th.SPECULAR_COLOR),dh=rn(th,th.SPECULAR_STRENGTH),ch=rn(th,th.REFLECTIVITY),hh=rn(th,th.ROUGHNESS),ph=rn(th,th.METALNESS),gh=rn(th,th.NORMAL),mh=rn(th,th.CLEARCOAT),fh=rn(th,th.CLEARCOAT_ROUGHNESS),yh=rn(th,th.CLEARCOAT_NORMAL),bh=rn(th,th.ROTATION),xh=rn(th,th.SHEEN),Th=rn(th,th.SHEEN_ROUGHNESS),_h=rn(th,th.ANISOTROPY),vh=rn(th,th.IRIDESCENCE),Nh=rn(th,th.IRIDESCENCE_IOR),Sh=rn(th,th.IRIDESCENCE_THICKNESS),Rh=rn(th,th.TRANSMISSION),Eh=rn(th,th.THICKNESS),Ah=rn(th,th.IOR),wh=rn(th,th.ATTENUATION_DISTANCE),Ch=rn(th,th.ATTENUATION_COLOR),Mh=rn(th,th.LINE_SCALE),Bh=rn(th,th.LINE_DASH_SIZE),Fh=rn(th,th.LINE_GAP_SIZE),Lh=rn(th,th.LINE_WIDTH),Ph=rn(th,th.LINE_DASH_OFFSET),Dh=rn(th,th.POINT_SIZE),Uh=rn(th,th.DISPERSION),Ih=rn(th,th.LIGHT_MAP),Oh=rn(th,th.AO),Vh=Ta(new t).onReference(function(e){return e.material}).onRenderUpdate(function({material:e}){this.value.set(e.anisotropy*Math.cos(e.anisotropyRotation),e.anisotropy*Math.sin(e.anisotropyRotation))}),kh=on(e=>e.context.setupModelViewProjection(),"vec4").once()().toVarying("v_modelViewProjection");class Gh extends ui{static get type(){return"StorageArrayElementNode"}constructor(e,t){super(e,t),this.isStorageArrayElementNode=!0}set storageBufferNode(e){this.node=e}get storageBufferNode(){return this.node}getMemberType(e,t){const r=this.storageBufferNode.structTypeNode;return r?r.getMemberType(e,t):"void"}setup(e){return!1===e.isAvailable("storageBuffer")&&!0===this.node.isPBO&&e.setupPBO(this.node),super.setup(e)}generate(e,t){let r;const s=e.context.assign;if(r=!1===e.isAvailable("storageBuffer")?!0!==this.node.isPBO||!0===s||!this.node.value.isInstancedBufferAttribute&&"compute"===e.shaderStage?this.node.build(e):e.generatePBO(this):super.generate(e),!0!==s){const s=this.getNodeType(e);r=e.format(r,s,t)}return r}}const zh=tn(Gh).setParameterLength(2);class $h extends Pl{static get type(){return"StorageBufferNode"}constructor(e,t=null,r=0){let s,i=null;t&&t.isStruct?(s="struct",i=t.layout,(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute)&&(r=e.count)):null===t&&(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute)?(s=ks(e.itemSize),r=e.count):s=t,super(e,s,r),this.isStorageBufferNode=!0,this.structTypeNode=i,this.access=ei.READ_WRITE,this.isAtomic=!1,this.isPBO=!1,this._attribute=null,this._varying=null,this.global=!0,!0!==e.isStorageBufferAttribute&&!0!==e.isStorageInstancedBufferAttribute&&(e.isInstancedBufferAttribute?e.isStorageInstancedBufferAttribute=!0:e.isStorageBufferAttribute=!0)}getHash(e){if(0===this.bufferCount){let t=e.globalCache.getData(this.value);return void 0===t&&(t={node:this},e.globalCache.setData(this.value,t)),t.node.uuid}return this.uuid}getInputType(){return this.value.isIndirectStorageBufferAttribute?"indirectStorageBuffer":"storageBuffer"}element(e){return zh(this,e)}setPBO(e){return this.isPBO=e,this}getPBO(){return this.isPBO}setAccess(e){return this.access=e,this}toReadOnly(){return this.setAccess(ei.READ_ONLY)}setAtomic(e){return this.isAtomic=e,this}toAtomic(){return this.setAtomic(!0)}getAttributeData(){return null===this._attribute&&(this._attribute=Zu(this.value),this._varying=Lu(this._attribute)),{attribute:this._attribute,varying:this._varying}}getNodeType(e){if(null!==this.structTypeNode)return this.structTypeNode.getNodeType(e);if(e.isAvailable("storageBuffer")||e.isAvailable("indirectStorageBuffer"))return super.getNodeType(e);const{attribute:t}=this.getAttributeData();return t.getNodeType(e)}getMemberType(e,t){return null!==this.structTypeNode?this.structTypeNode.getMemberType(e,t):"void"}generate(e){if(null!==this.structTypeNode&&this.structTypeNode.build(e),e.isAvailable("storageBuffer")||e.isAvailable("indirectStorageBuffer"))return super.generate(e);const{attribute:t,varying:r}=this.getAttributeData(),s=r.build(e);return e.registerTransform(s,t),s}}const Wh=(e,t=null,r=0)=>new $h(e,t,r);class Hh extends oi{static get type(){return"IndexNode"}constructor(e){super("uint"),this.scope=e,this.isIndexNode=!0}generate(e){const t=this.getNodeType(e),r=this.scope;let s,i;if(r===Hh.VERTEX)s=e.getVertexIndex();else if(r===Hh.INSTANCE)s=e.getInstanceIndex();else if(r===Hh.DRAW)s=e.getDrawIndex();else if(r===Hh.INVOCATION_LOCAL)s=e.getInvocationLocalIndex();else if(r===Hh.INVOCATION_SUBGROUP)s=e.getInvocationSubgroupIndex();else{if(r!==Hh.SUBGROUP)throw new Error("THREE.IndexNode: Unknown scope: "+r);s=e.getSubgroupIndex()}if("vertex"===e.shaderStage||"compute"===e.shaderStage)i=s;else{i=Lu(this).build(e,t)}return i}}Hh.VERTEX="vertex",Hh.INSTANCE="instance",Hh.SUBGROUP="subgroup",Hh.INVOCATION_LOCAL="invocationLocal",Hh.INVOCATION_SUBGROUP="invocationSubgroup",Hh.DRAW="draw";const qh=rn(Hh,Hh.VERTEX),jh=rn(Hh,Hh.INSTANCE),Xh=rn(Hh,Hh.SUBGROUP),Kh=rn(Hh,Hh.INVOCATION_SUBGROUP),Yh=rn(Hh,Hh.INVOCATION_LOCAL),Qh=rn(Hh,Hh.DRAW);class Zh extends oi{static get type(){return"InstanceNode"}constructor(e,t,r=null){super("void"),this.count=e,this.instanceMatrix=t,this.instanceColor=r,this.instanceMatrixNode=null,this.instanceColorNode=null,this.updateType=Zs.FRAME,this.buffer=null,this.bufferColor=null,this.previousInstanceMatrixNode=null}get isStorageMatrix(){const{instanceMatrix:e}=this;return e&&!0===e.isStorageInstancedBufferAttribute}get isStorageColor(){const{instanceColor:e}=this;return e&&!0===e.isStorageInstancedBufferAttribute}setup(e){let{instanceMatrixNode:t,instanceColorNode:r}=this;null===t&&(t=this._createInstanceMatrixNode(!0,e),this.instanceMatrixNode=t);const{instanceColor:s,isStorageColor:i}=this;if(s&&null===r){if(i)r=Wh(s,"vec3",Math.max(s.count,1)).element(jh);else{const e=new W(s.array,3),t=s.usage===x?el:Ju;this.bufferColor=e,r=_n(t(e,"vec3",3,0))}this.instanceColorNode=r}const n=t.mul(Fd).xyz;if(Fd.assign(n),e.needsPreviousData()&&Ld.assign(this.getPreviousInstancedPosition(e)),e.hasGeometryAttribute("normal")){const e=Yd($d,t);$d.assign(e)}null!==this.instanceColorNode&&Un("vec3","vInstanceColor").assign(this.instanceColorNode)}update(e){null!==this.buffer&&!0!==this.isStorageMatrix&&(this.buffer.clearUpdateRanges(),this.buffer.updateRanges.push(...this.instanceMatrix.updateRanges),this.instanceMatrix.version!==this.buffer.version&&(this.buffer.version=this.instanceMatrix.version)),this.instanceColor&&null!==this.bufferColor&&!0!==this.isStorageColor&&(this.bufferColor.clearUpdateRanges(),this.bufferColor.updateRanges.push(...this.instanceColor.updateRanges),this.instanceColor.version!==this.bufferColor.version&&(this.bufferColor.version=this.instanceColor.version)),null!==this.previousInstanceMatrixNode&&e.object.previousInstanceMatrix.array.set(this.instanceMatrix.array)}getPreviousInstancedPosition(e){const t=e.object;return null===this.previousInstanceMatrixNode&&(t.previousInstanceMatrix=this.instanceMatrix.clone(),this.previousInstanceMatrixNode=this._createInstanceMatrixNode(!1,e)),this.previousInstanceMatrixNode.mul(Ld).xyz}_createInstanceMatrixNode(e,t){let r;const{instanceMatrix:s}=this,{count:i}=s;if(this.isStorageMatrix)r=Wh(s,"mat4",Math.max(i,1)).element(jh);else{if(i<=(!0===t.renderer.backend.isWebGPUBackend?1e3:250))r=Dl(s.array,"mat4",Math.max(i,1)).element(jh);else{const t=new H(s.array,16,1);!0===e&&(this.buffer=t);const i=s.usage===x?el:Ju,n=[i(t,"vec4",16,0),i(t,"vec4",16,4),i(t,"vec4",16,8),i(t,"vec4",16,12)];r=Bn(...n)}}return r}}const Jh=tn(Zh).setParameterLength(2,3);class ep extends Zh{static get type(){return"InstancedMeshNode"}constructor(e){const{count:t,instanceMatrix:r,instanceColor:s}=e;super(t,r,s),this.instancedMesh=e}}const tp=tn(ep).setParameterLength(1);class rp extends oi{static get type(){return"BatchNode"}constructor(e){super("void"),this.batchMesh=e,this.batchingIdNode=null}setup(e){null===this.batchingIdNode&&(null===e.getDrawIndex()?this.batchingIdNode=jh:this.batchingIdNode=Qh);const t=on(([e])=>{const t=gn(El(Ll(this.batchMesh._indirectTexture),0).x).toConst(),r=gn(e).mod(t).toConst(),s=gn(e).div(t).toConst();return Ll(this.batchMesh._indirectTexture,bn(r,s)).x}).setLayout({name:"getIndirectIndex",type:"uint",inputs:[{name:"id",type:"int"}]}),r=t(gn(this.batchingIdNode)),s=this.batchMesh._matricesTexture,i=gn(El(Ll(s),0).x).toConst(),n=pn(r).mul(4).toInt().toConst(),a=n.mod(i).toConst(),o=n.div(i).toConst(),u=Bn(Ll(s,bn(a,o)),Ll(s,bn(a.add(1),o)),Ll(s,bn(a.add(2),o)),Ll(s,bn(a.add(3),o))),l=this.batchMesh._colorsTexture;if(null!==l){const e=on(([e])=>{const t=gn(El(Ll(l),0).x).toConst(),r=e,s=r.mod(t).toConst(),i=r.div(t).toConst();return Ll(l,bn(s,i)).rgb}).setLayout({name:"getBatchingColor",type:"vec3",inputs:[{name:"id",type:"int"}]}),t=e(r);Un("vec3","vBatchColor").assign(t)}const d=Mn(u);Fd.assign(u.mul(Fd));const c=$d.div(_n(d[0].dot(d[0]),d[1].dot(d[1]),d[2].dot(d[2]))),h=d.mul(c).xyz;$d.assign(h),e.hasGeometryAttribute("tangent")&&Dc.mulAssign(d)}}const sp=tn(rp).setParameterLength(1),ip=new WeakMap;class np extends oi{static get type(){return"SkinningNode"}constructor(e){super("void"),this.skinnedMesh=e,this.updateType=Zs.OBJECT,this.skinIndexNode=Nl("skinIndex","uvec4"),this.skinWeightNode=Nl("skinWeight","vec4"),this.bindMatrixNode=fc("bindMatrix","mat4"),this.bindMatrixInverseNode=fc("bindMatrixInverse","mat4"),this.boneMatricesNode=yc("skeleton.boneMatrices","mat4",e.skeleton.bones.length),this.positionNode=Fd,this.toPositionNode=Fd,this.previousBoneMatricesNode=null}getSkinnedPosition(e=this.boneMatricesNode,t=this.positionNode){const{skinIndexNode:r,skinWeightNode:s,bindMatrixNode:i,bindMatrixInverseNode:n}=this,a=e.element(r.x),o=e.element(r.y),u=e.element(r.z),l=e.element(r.w),d=i.mul(t),c=Ca(a.mul(s.x).mul(d),o.mul(s.y).mul(d),u.mul(s.z).mul(d),l.mul(s.w).mul(d));return n.mul(c).xyz}getSkinnedNormalAndTangent(e=this.boneMatricesNode,t=$d,r=Dc){const{skinIndexNode:s,skinWeightNode:i,bindMatrixNode:n,bindMatrixInverseNode:a}=this,o=e.element(s.x),u=e.element(s.y),l=e.element(s.z),d=e.element(s.w);let c=Ca(i.x.mul(o),i.y.mul(u),i.z.mul(l),i.w.mul(d));c=a.mul(c).mul(n);return{skinNormal:c.transformDirection(t).xyz,skinTangent:c.transformDirection(r).xyz}}getPreviousSkinnedPosition(e){const t=e.object;return null===this.previousBoneMatricesNode&&(t.skeleton.previousBoneMatrices=new Float32Array(t.skeleton.boneMatrices),this.previousBoneMatricesNode=yc("skeleton.previousBoneMatrices","mat4",t.skeleton.bones.length)),this.getSkinnedPosition(this.previousBoneMatricesNode,Ld)}setup(e){e.needsPreviousData()&&Ld.assign(this.getPreviousSkinnedPosition(e));const t=this.getSkinnedPosition();if(this.toPositionNode&&this.toPositionNode.assign(t),e.hasGeometryAttribute("normal")){const{skinNormal:t,skinTangent:r}=this.getSkinnedNormalAndTangent();$d.assign(t),e.hasGeometryAttribute("tangent")&&Dc.assign(r)}return t}generate(e,t){if("void"!==t)return super.generate(e,t)}update(e){const t=e.object&&e.object.skeleton?e.object.skeleton:this.skinnedMesh.skeleton;ip.get(t)!==e.frameId&&(ip.set(t,e.frameId),null!==this.previousBoneMatricesNode&&(null===t.previousBoneMatrices&&(t.previousBoneMatrices=new Float32Array(t.boneMatrices)),t.previousBoneMatrices.set(t.boneMatrices)),t.update())}}const ap=e=>new np(e);class op extends oi{static get type(){return"LoopNode"}constructor(e=[]){super("void"),this.params=e}getVarName(e){return String.fromCharCode("i".charCodeAt(0)+e)}getProperties(e){const t=e.getNodeProperties(this);if(void 0!==t.stackNode)return t;const r={};for(let e=0,t=this.params.length-1;eNumber(l)?">=":"<")),a)n=`while ( ${l} )`;else{const r={start:u,end:l},s=r.start,i=r.end;let a;const g=()=>h.includes("<")?"+=":"-=";if(null!=p)switch(typeof p){case"function":a=e.flowStagesNode(t.updateNode,"void").code.replace(/\t|;/g,"");break;case"number":a=d+" "+g()+" "+e.generateConst(c,p);break;case"string":a=d+" "+p;break;default:p.isNode?a=d+" "+g()+" "+p.build(e):(o("TSL: 'Loop( { update: ... } )' is not a function, string or number."),a="break /* invalid update */")}else p="int"===c||"uint"===c?h.includes("<")?"++":"--":g()+" 1.",a=d+" "+p;n=`for ( ${e.getVar(c,d)+" = "+s}; ${d+" "+h+" "+i}; ${a} )`}e.addFlowCode((0===s?"\n":"")+e.tab+n+" {\n\n").addFlowTab()}const i=s.build(e,"void");t.returnsNode.build(e,"void"),e.removeFlowTab().addFlowCode("\n"+e.tab+i);for(let t=0,r=this.params.length-1;tnew op(en(e,"int")).toStack(),lp=()=>pl("break").toStack(),dp=new WeakMap,cp=new s,hp=on(({bufferMap:e,influence:t,stride:r,width:s,depth:i,offset:n})=>{const a=gn(qh).mul(r).add(n),o=a.div(s),u=a.sub(o.mul(s));return Ll(e,bn(u,o)).depth(i).xyz.mul(t)});class pp extends oi{static get type(){return"MorphNode"}constructor(e){super("void"),this.mesh=e,this.morphBaseInfluence=Ta(1),this.updateType=Zs.OBJECT}setup(e){const{geometry:r}=e,s=void 0!==r.morphAttributes.position,i=r.hasAttribute("normal")&&void 0!==r.morphAttributes.normal,n=r.morphAttributes.position||r.morphAttributes.normal||r.morphAttributes.color,a=void 0!==n?n.length:0,{texture:o,stride:u,size:l}=function(e){const r=void 0!==e.morphAttributes.position,s=void 0!==e.morphAttributes.normal,i=void 0!==e.morphAttributes.color,n=e.morphAttributes.position||e.morphAttributes.normal||e.morphAttributes.color,a=void 0!==n?n.length:0;let o=dp.get(e);if(void 0===o||o.count!==a){void 0!==o&&o.texture.dispose();const u=e.morphAttributes.position||[],l=e.morphAttributes.normal||[],d=e.morphAttributes.color||[];let c=0;!0===r&&(c=1),!0===s&&(c=2),!0===i&&(c=3);let h=e.attributes.position.count*c,p=1;const g=4096;h>g&&(p=Math.ceil(h/g),h=g);const m=new Float32Array(h*p*4*a),f=new q(m,h,p,a);f.type=j,f.needsUpdate=!0;const y=4*c;for(let x=0;x{const t=pn(0).toVar();this.mesh.count>1&&null!==this.mesh.morphTexture&&void 0!==this.mesh.morphTexture?t.assign(Ll(this.mesh.morphTexture,bn(gn(e).add(1),gn(jh))).r):t.assign(fc("morphTargetInfluences","float").element(e).toVar()),dn(t.notEqual(0),()=>{!0===s&&Fd.addAssign(hp({bufferMap:o,influence:t,stride:u,width:d,depth:e,offset:gn(0)})),!0===i&&$d.addAssign(hp({bufferMap:o,influence:t,stride:u,width:d,depth:e,offset:gn(1)}))})})}update(){const e=this.morphBaseInfluence;this.mesh.geometry.morphTargetsRelative?e.value=1:e.value=1-this.mesh.morphTargetInfluences.reduce((e,t)=>e+t,0)}}const gp=tn(pp).setParameterLength(1);class mp extends oi{static get type(){return"LightingNode"}constructor(){super("vec3"),this.isLightingNode=!0}}class fp extends mp{static get type(){return"AONode"}constructor(e=null){super(),this.aoNode=e}setup(e){e.context.ambientOcclusion.mulAssign(this.aoNode)}}class yp extends bu{static get type(){return"LightingContextNode"}constructor(e,t=null,r=null,s=null){super(e),this.lightingModel=t,this.backdropNode=r,this.backdropAlphaNode=s,this._value=null}getContext(){const{backdropNode:e,backdropAlphaNode:t}=this,r={directDiffuse:_n().toVar("directDiffuse"),directSpecular:_n().toVar("directSpecular"),indirectDiffuse:_n().toVar("indirectDiffuse"),indirectSpecular:_n().toVar("indirectSpecular")};return{radiance:_n().toVar("radiance"),irradiance:_n().toVar("irradiance"),iblIrradiance:_n().toVar("iblIrradiance"),ambientOcclusion:pn(1).toVar("ambientOcclusion"),reflectedLight:r,backdrop:e,backdropAlpha:t}}setup(e){return this.value=this._value||(this._value=this.getContext()),this.value.lightingModel=this.lightingModel||e.context.lightingModel,super.setup(e)}}const bp=tn(yp);class xp extends mp{static get type(){return"IrradianceNode"}constructor(e){super(),this.node=e}setup(e){e.context.irradiance.addAssign(this.node)}}const Tp=new t;class _p extends Ml{static get type(){return"ViewportTextureNode"}constructor(e=Hl,t=null,r=null){let s=null;null===r?(s=new X,s.minFilter=K,r=s):s=r,super(r,e,t),this.generateMipmaps=!1,this.defaultFramebuffer=s,this.isOutputTextureNode=!0,this.updateBeforeType=Zs.RENDER,this._cacheTextures=new WeakMap}getTextureForReference(e=null){let t,r;if(this.referenceNode?(t=this.referenceNode.defaultFramebuffer,r=this.referenceNode._cacheTextures):(t=this.defaultFramebuffer,r=this._cacheTextures),null===e)return t;if(!1===r.has(e)){const s=t.clone();r.set(e,s)}return r.get(e)}updateReference(e){const t=e.renderer.getRenderTarget();return this.value=this.getTextureForReference(t),this.value}updateBefore(e){const t=e.renderer,r=t.getRenderTarget();null===r?t.getDrawingBufferSize(Tp):Tp.set(r.width,r.height);const s=this.getTextureForReference(r);s.image.width===Tp.width&&s.image.height===Tp.height||(s.image.width=Tp.width,s.image.height=Tp.height,s.needsUpdate=!0);const i=s.generateMipmaps;s.generateMipmaps=this.generateMipmaps,t.copyFramebufferToTexture(s),s.generateMipmaps=i}clone(){const e=new this.constructor(this.uvNode,this.levelNode,this.value);return e.generateMipmaps=this.generateMipmaps,e}}const vp=tn(_p).setParameterLength(0,3),Np=tn(_p,null,null,{generateMipmaps:!0}).setParameterLength(0,3),Sp=Np(),Rp=(e=Hl,t=null)=>Sp.sample(e,t);let Ep=null;class Ap extends _p{static get type(){return"ViewportDepthTextureNode"}constructor(e=Hl,t=null){null===Ep&&(Ep=new Y),super(e,t,Ep)}getTextureForReference(){return Ep}}const wp=tn(Ap).setParameterLength(0,2);class Cp extends oi{static get type(){return"ViewportDepthNode"}constructor(e,t=null){super("float"),this.scope=e,this.valueNode=t,this.isViewportDepthNode=!0}generate(e){const{scope:t}=this;return t===Cp.DEPTH_BASE?e.getFragDepth():super.generate(e)}setup({camera:e}){const{scope:t}=this,r=this.valueNode;let s=null;if(t===Cp.DEPTH_BASE)null!==r&&(s=Pp().assign(r));else if(t===Cp.DEPTH)s=e.isPerspectiveCamera?Bp(Ud.z,ed,td):Mp(Ud.z,ed,td);else if(t===Cp.LINEAR_DEPTH)if(null!==r)if(e.isPerspectiveCamera){const e=Fp(r,ed,td);s=Mp(e,ed,td)}else s=r;else s=Mp(Ud.z,ed,td);return s}}Cp.DEPTH_BASE="depthBase",Cp.DEPTH="depth",Cp.LINEAR_DEPTH="linearDepth";const Mp=(e,t,r)=>e.add(t).div(t.sub(r)),Bp=(e,t,r)=>t.add(e).mul(r).div(r.sub(t).mul(e)),Fp=(e,t,r)=>t.mul(r).div(r.sub(t).mul(e).sub(r)),Lp=(e,t,r)=>{t=t.max(1e-6).toVar();const s=fo(e.negate().div(t)),i=fo(r.div(t));return s.div(i)},Pp=tn(Cp,Cp.DEPTH_BASE),Dp=rn(Cp,Cp.DEPTH),Up=tn(Cp,Cp.LINEAR_DEPTH).setParameterLength(0,1),Ip=Up(wp());Dp.assign=e=>Pp(e);class Op extends oi{static get type(){return"ClippingNode"}constructor(e=Op.DEFAULT){super(),this.scope=e}setup(e){super.setup(e);const t=e.clippingContext,{intersectionPlanes:r,unionPlanes:s}=t;return this.hardwareClipping=e.material.hardwareClipping,this.scope===Op.ALPHA_TO_COVERAGE?this.setupAlphaToCoverage(r,s):this.scope===Op.HARDWARE?this.setupHardwareClipping(s,e):this.setupDefault(r,s)}setupAlphaToCoverage(e,t){return on(()=>{const r=pn().toVar("distanceToPlane"),s=pn().toVar("distanceToGradient"),i=pn(1).toVar("clipOpacity"),n=t.length;if(!1===this.hardwareClipping&&n>0){const e=Ol(t).setGroup(ya);up(n,({i:t})=>{const n=e.element(t);r.assign(Ud.dot(n.xyz).negate().add(n.w)),s.assign(r.fwidth().div(2)),i.mulAssign(uu(s.negate(),s,r))})}const a=e.length;if(a>0){const t=Ol(e).setGroup(ya),n=pn(1).toVar("intersectionClipOpacity");up(a,({i:e})=>{const i=t.element(e);r.assign(Ud.dot(i.xyz).negate().add(i.w)),s.assign(r.fwidth().div(2)),n.mulAssign(uu(s.negate(),s,r).oneMinus())}),i.mulAssign(n.oneMinus())}In.a.mulAssign(i),In.a.equal(0).discard()})()}setupDefault(e,t){return on(()=>{const r=t.length;if(!1===this.hardwareClipping&&r>0){const e=Ol(t).setGroup(ya);up(r,({i:t})=>{const r=e.element(t);Ud.dot(r.xyz).greaterThan(r.w).discard()})}const s=e.length;if(s>0){const t=Ol(e).setGroup(ya),r=fn(!0).toVar("clipped");up(s,({i:e})=>{const s=t.element(e);r.assign(Ud.dot(s.xyz).greaterThan(s.w).and(r))}),r.discard()}})()}setupHardwareClipping(e,t){const r=e.length;return t.enableHardwareClipping(r),on(()=>{const s=Ol(e).setGroup(ya),i=kl(t.getClipDistance());up(r,({i:e})=>{const t=s.element(e),r=Ud.dot(t.xyz).sub(t.w).negate();i.element(e).assign(r)})})()}}Op.ALPHA_TO_COVERAGE="alphaToCoverage",Op.DEFAULT="default",Op.HARDWARE="hardware";const Vp=on(([e])=>vo(Ba(1e4,No(Ba(17,e.x).add(Ba(.1,e.y)))).mul(Ca(.1,Co(No(Ba(13,e.y).add(e.x))))))),kp=on(([e])=>Vp(yn(Vp(e.xy),e.z))),Gp=on(([e])=>{const t=Wo(Bo(Po(e.xyz)),Bo(Do(e.xyz))),r=pn(1).div(pn(.05).mul(t)).toVar("pixScale"),s=yn(go(xo(fo(r))),go(To(fo(r)))),i=yn(kp(xo(s.x.mul(e.xyz))),kp(xo(s.y.mul(e.xyz)))),n=vo(fo(r)),a=Ca(Ba(n.oneMinus(),i.x),Ba(n,i.y)),o=$o(n,n.oneMinus()),u=_n(a.mul(a).div(Ba(2,o).mul(Ma(1,o))),a.sub(Ba(.5,o)).div(Ma(1,o)),Ma(1,Ma(1,a).mul(Ma(1,a)).div(Ba(2,o).mul(Ma(1,o))))),l=a.lessThan(o.oneMinus()).select(a.lessThan(o).select(u.x,u.y),u.z);return nu(l,1e-6,1)}).setLayout({name:"getAlphaHashThreshold",type:"float",inputs:[{name:"position",type:"vec3"}]});class zp extends vl{static get type(){return"VertexColorNode"}constructor(e){super(null,"vec4"),this.isVertexColorNode=!0,this.index=e}getAttributeName(){const e=this.index;return"color"+(e>0?e:"")}generate(e){const t=this.getAttributeName(e);let r;return r=!0===e.hasGeometryAttribute(t)?super.generate(e):e.generateConst(this.nodeType,new s(1,1,1,1)),r}serialize(e){super.serialize(e),e.index=this.index}deserialize(e){super.deserialize(e),this.index=e.index}}const $p=(e=0)=>new zp(e),Wp=on(([e,t])=>$o(1,e.oneMinus().div(t)).oneMinus()).setLayout({name:"blendBurn",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),Hp=on(([e,t])=>$o(e.div(t.oneMinus()),1)).setLayout({name:"blendDodge",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),qp=on(([e,t])=>e.oneMinus().mul(t.oneMinus()).oneMinus()).setLayout({name:"blendScreen",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),jp=on(([e,t])=>iu(e.mul(2).mul(t),e.oneMinus().mul(2).mul(t.oneMinus()).oneMinus(),Ho(.5,e))).setLayout({name:"blendOverlay",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),Xp=on(([e,t])=>{const r=t.a.add(e.a.mul(t.a.oneMinus()));return Rn(t.rgb.mul(t.a).add(e.rgb.mul(e.a).mul(t.a.oneMinus())).div(r),r)}).setLayout({name:"blendColor",type:"vec4",inputs:[{name:"base",type:"vec4"},{name:"blend",type:"vec4"}]}),Kp=on(([e])=>Rn(e.rgb.mul(e.a),e.a),{color:"vec4",return:"vec4"}),Yp=on(([e])=>(dn(e.a.equal(0),()=>Rn(0)),Rn(e.rgb.div(e.a),e.a)),{color:"vec4",return:"vec4"});class Qp extends Q{static get type(){return"NodeMaterial"}get type(){return this.constructor.type}set type(e){}constructor(){super(),this.isNodeMaterial=!0,this.fog=!0,this.lights=!1,this.hardwareClipping=!1,this.lightsNode=null,this.envNode=null,this.aoNode=null,this.colorNode=null,this.normalNode=null,this.opacityNode=null,this.backdropNode=null,this.backdropAlphaNode=null,this.alphaTestNode=null,this.maskNode=null,this.maskShadowNode=null,this.positionNode=null,this.geometryNode=null,this.depthNode=null,this.receivedShadowPositionNode=null,this.castShadowPositionNode=null,this.receivedShadowNode=null,this.castShadowNode=null,this.outputNode=null,this.mrtNode=null,this.fragmentNode=null,this.vertexNode=null,this.contextNode=null}_getNodeChildren(){const e=[];for(const t of Object.getOwnPropertyNames(this)){if(!0===t.startsWith("_"))continue;const r=this[t];r&&!0===r.isNode&&e.push({property:t,childNode:r})}return e}customProgramCacheKey(){const e=[];for(const{property:t,childNode:r}of this._getNodeChildren())e.push(Ds(t.slice(0,-4)),r.getCacheKey());return this.type+Us(e)}build(e){this.setup(e)}setupObserver(e){return new Ls(e)}setup(e){e.context.setupNormal=()=>Bu(this.setupNormal(e),"NORMAL","vec3"),e.context.setupPositionView=()=>this.setupPositionView(e),e.context.setupModelViewProjection=()=>this.setupModelViewProjection(e);const t=e.renderer,r=t.getRenderTarget();!0===t.contextNode.isContextNode?e.context={...e.context,...t.contextNode.getFlowContextData()}:o('NodeMaterial: "renderer.contextNode" must be an instance of `context()`.'),null!==this.contextNode&&(!0===this.contextNode.isContextNode?e.context={...e.context,...this.contextNode.getFlowContextData()}:o('NodeMaterial: "material.contextNode" must be an instance of `context()`.')),e.addStack();const s=this.setupVertex(e),i=Bu(this.vertexNode||s,"VERTEX");let n;e.context.clipSpace=i,e.stack.outputNode=i,this.setupHardwareClipping(e),null!==this.geometryNode&&(e.stack.outputNode=e.stack.outputNode.bypass(this.geometryNode)),e.addFlow("vertex",e.removeStack()),e.addStack();const a=this.setupClipping(e);if(!0!==this.depthWrite&&!0!==this.depthTest||(null!==r?!0===r.depthBuffer&&this.setupDepth(e):!0===t.depth&&this.setupDepth(e)),null===this.fragmentNode){this.setupDiffuseColor(e),this.setupVariants(e);const s=this.setupLighting(e);null!==a&&e.stack.addToStack(a);const i=Rn(s,In.a).max(0);n=this.setupOutput(e,i),sa.assign(n);const o=null!==this.outputNode;if(o&&(n=this.outputNode),e.context.getOutput&&(n=e.context.getOutput(n,e)),null!==r){const e=t.getMRT(),r=this.mrtNode;null!==e?(o&&sa.assign(n),n=e,null!==r&&(n=e.merge(r))):null!==r&&(n=r)}}else{let t=this.fragmentNode;!0!==t.isOutputStructNode&&(t=Rn(t)),n=this.setupOutput(e,t)}e.stack.outputNode=n,e.addFlow("fragment",e.removeStack()),e.observer=this.setupObserver(e)}setupClipping(e){if(null===e.clippingContext)return null;const{unionPlanes:t,intersectionPlanes:r}=e.clippingContext;let s=null;if(t.length>0||r.length>0){const t=e.renderer.currentSamples;this.alphaToCoverage&&t>1?s=new Op(Op.ALPHA_TO_COVERAGE):e.stack.addToStack(new Op)}return s}setupHardwareClipping(e){if(this.hardwareClipping=!1,null===e.clippingContext)return;const t=e.clippingContext.unionPlanes.length;t>0&&t<=8&&e.isAvailable("clipDistance")&&(e.stack.addToStack(new Op(Op.HARDWARE)),this.hardwareClipping=!0)}setupDepth(e){const{renderer:t,camera:r}=e;let s=this.depthNode;if(null===s){const e=t.getMRT();e&&e.has("depth")?s=e.get("depth"):!0===t.logarithmicDepthBuffer&&(s=r.isPerspectiveCamera?Lp(Ud.z,ed,td):Mp(Ud.z,ed,td))}null!==s&&Dp.assign(s).toStack()}setupPositionView(){return Ed.mul(Fd).xyz}setupModelViewProjection(){return rd.mul(Ud)}setupVertex(e){return e.addStack(),this.setupPosition(e),e.context.position=e.removeStack(),kh}setupPosition(e){const{object:t,geometry:r}=e;if((r.morphAttributes.position||r.morphAttributes.normal||r.morphAttributes.color)&&gp(t).toStack(),!0===t.isSkinnedMesh&&ap(t).toStack(),this.displacementMap){const e=xc("displacementMap","texture"),t=xc("displacementScale","float"),r=xc("displacementBias","float");Fd.addAssign($d.normalize().mul(e.x.mul(t).add(r)))}return t.isBatchedMesh&&sp(t).toStack(),t.isInstancedMesh&&t.instanceMatrix&&!0===t.instanceMatrix.isInstancedBufferAttribute&&tp(t).toStack(),null!==this.positionNode&&Fd.assign(Bu(this.positionNode,"POSITION","vec3")),Fd}setupDiffuseColor(e){const{object:t,geometry:r}=e;null!==this.maskNode&&fn(this.maskNode).not().discard();let s=this.colorNode?Rn(this.colorNode):sh;if(!0===this.vertexColors&&r.hasAttribute("color")&&(s=s.mul($p())),t.instanceColor){s=Un("vec3","vInstanceColor").mul(s)}if(t.isBatchedMesh&&t._colorsTexture){s=Un("vec3","vBatchColor").mul(s)}In.assign(s);const i=this.opacityNode?pn(this.opacityNode):ah;In.a.assign(In.a.mul(i));let n=null;(null!==this.alphaTestNode||this.alphaTest>0)&&(n=null!==this.alphaTestNode?pn(this.alphaTestNode):rh,!0===this.alphaToCoverage?(In.a=uu(n,n.add(Vo(In.a)),In.a),In.a.lessThanEqual(0).discard()):In.a.lessThanEqual(n).discard()),!0===this.alphaHash&&In.a.lessThan(Gp(Fd)).discard(),e.isOpaque()&&In.a.assign(1)}setupVariants(){}setupOutgoingLight(){return!0===this.lights?_n(0):In.rgb}setupNormal(){return this.normalNode?_n(this.normalNode):gh}setupEnvironment(){let e=null;return this.envNode?e=this.envNode:this.envMap&&(e=this.envMap.isCubeTexture?xc("envMap","cubeTexture"):xc("envMap","texture")),e}setupLightMap(e){let t=null;return e.material.lightMap&&(t=new xp(Ih)),t}setupLights(e){const t=[],r=this.setupEnvironment(e);r&&r.isLightingNode&&t.push(r);const s=this.setupLightMap(e);s&&s.isLightingNode&&t.push(s);let i=this.aoNode;null===i&&e.material.aoMap&&(i=Oh),e.context.getAO&&(i=e.context.getAO(i,e)),i&&t.push(new fp(i));let n=this.lightsNode||e.lightsNode;return t.length>0&&(n=e.renderer.lighting.createNode([...n.getLights(),...t])),n}setupLightingModel(){}setupLighting(e){const{material:t}=e,{backdropNode:r,backdropAlphaNode:s,emissiveNode:i}=this,n=!0===this.lights||null!==this.lightsNode?this.setupLights(e):null;let a=this.setupOutgoingLight(e);if(n&&n.getScope().hasLights){const t=this.setupLightingModel(e)||null;a=bp(n,t,r,s)}else null!==r&&(a=_n(null!==s?iu(a,r,s):r));return(i&&!0===i.isNode||t.emissive&&!0===t.emissive.isColor)&&(Vn.assign(_n(i||nh)),a=a.add(Vn)),a}setupFog(e,t){const r=e.fogNode;return r&&(sa.assign(t),t=Rn(r.toVar())),t}setupPremultipliedAlpha(e,t){return Kp(t)}setupOutput(e,t){return!0===this.fog&&(t=this.setupFog(e,t)),!0===this.premultipliedAlpha&&(t=this.setupPremultipliedAlpha(e,t)),t}setDefaultValues(e){for(const t in e){const r=e[t];void 0===this[t]&&(this[t]=r,r&&r.clone&&(this[t]=r.clone()))}const t=Object.getOwnPropertyDescriptors(e.constructor.prototype);for(const e in t)void 0===Object.getOwnPropertyDescriptor(this.constructor.prototype,e)&&void 0!==t[e].get&&Object.defineProperty(this.constructor.prototype,e,t[e])}toJSON(e){const t=void 0===e||"string"==typeof e;t&&(e={textures:{},images:{},nodes:{}});const r=Q.prototype.toJSON.call(this,e);r.inputNodes={};for(const{property:t,childNode:s}of this._getNodeChildren())r.inputNodes[t]=s.toJSON(e).uuid;function s(e){const t=[];for(const r in e){const s=e[r];delete s.metadata,t.push(s)}return t}if(t){const t=s(e.textures),i=s(e.images),n=s(e.nodes);t.length>0&&(r.textures=t),i.length>0&&(r.images=i),n.length>0&&(r.nodes=n)}return r}copy(e){return this.lightsNode=e.lightsNode,this.envNode=e.envNode,this.aoNode=e.aoNode,this.colorNode=e.colorNode,this.normalNode=e.normalNode,this.opacityNode=e.opacityNode,this.backdropNode=e.backdropNode,this.backdropAlphaNode=e.backdropAlphaNode,this.alphaTestNode=e.alphaTestNode,this.maskNode=e.maskNode,this.maskShadowNode=e.maskShadowNode,this.positionNode=e.positionNode,this.geometryNode=e.geometryNode,this.depthNode=e.depthNode,this.receivedShadowPositionNode=e.receivedShadowPositionNode,this.castShadowPositionNode=e.castShadowPositionNode,this.receivedShadowNode=e.receivedShadowNode,this.castShadowNode=e.castShadowNode,this.outputNode=e.outputNode,this.mrtNode=e.mrtNode,this.fragmentNode=e.fragmentNode,this.vertexNode=e.vertexNode,this.contextNode=e.contextNode,super.copy(e)}}const Zp=new Z;class Jp extends Qp{static get type(){return"LineBasicNodeMaterial"}constructor(e){super(),this.isLineBasicNodeMaterial=!0,this.setDefaultValues(Zp),this.setValues(e)}}const eg=new J;class tg extends Qp{static get type(){return"LineDashedNodeMaterial"}constructor(e){super(),this.isLineDashedNodeMaterial=!0,this.setDefaultValues(eg),this.dashOffset=0,this.offsetNode=null,this.dashScaleNode=null,this.dashSizeNode=null,this.gapSizeNode=null,this.setValues(e)}setupVariants(){const e=this.offsetNode?pn(this.offsetNode):Ph,t=this.dashScaleNode?pn(this.dashScaleNode):Mh,r=this.dashSizeNode?pn(this.dashSizeNode):Bh,s=this.gapSizeNode?pn(this.gapSizeNode):Fh;ia.assign(r),na.assign(s);const i=Lu(Nl("lineDistance").mul(t));(e?i.add(e):i).mod(ia.add(na)).greaterThan(ia).discard()}}const rg=new J;class sg extends Qp{static get type(){return"Line2NodeMaterial"}constructor(e={}){super(),this.isLine2NodeMaterial=!0,this.setDefaultValues(rg),this.vertexColors=e.vertexColors,this.dashOffset=0,this.lineColorNode=null,this.offsetNode=null,this.dashScaleNode=null,this.dashSizeNode=null,this.gapSizeNode=null,this.blending=ee,this._useDash=e.dashed,this._useAlphaToCoverage=!0,this._useWorldUnits=!1,this.setValues(e)}setup(e){const{renderer:t}=e,r=this._useAlphaToCoverage,s=this.vertexColors,i=this._useDash,n=this._useWorldUnits,a=on(({start:e,end:t})=>{const r=rd.element(2).element(2),s=rd.element(3).element(2).mul(-.5).div(r).sub(e.z).div(t.z.sub(e.z));return Rn(iu(e.xyz,t.xyz,s),t.w)}).setLayout({name:"trimSegment",type:"vec4",inputs:[{name:"start",type:"vec4"},{name:"end",type:"vec4"}]});this.vertexNode=on(()=>{const e=Nl("instanceStart"),t=Nl("instanceEnd"),r=Rn(Ed.mul(Rn(e,1))).toVar("start"),s=Rn(Ed.mul(Rn(t,1))).toVar("end");if(i){const e=this.dashScaleNode?pn(this.dashScaleNode):Mh,t=this.offsetNode?pn(this.offsetNode):Ph,r=Nl("instanceDistanceStart"),s=Nl("instanceDistanceEnd");let i=Bd.y.lessThan(.5).select(e.mul(r),e.mul(s));i=i.add(t),Un("float","lineDistance").assign(i)}n&&(Un("vec3","worldStart").assign(r.xyz),Un("vec3","worldEnd").assign(s.xyz));const o=Xl.z.div(Xl.w),u=rd.element(2).element(3).equal(-1);dn(u,()=>{dn(r.z.lessThan(0).and(s.z.greaterThan(0)),()=>{s.assign(a({start:r,end:s}))}).ElseIf(s.z.lessThan(0).and(r.z.greaterThanEqual(0)),()=>{r.assign(a({start:s,end:r}))})});const l=rd.mul(r),d=rd.mul(s),c=l.xyz.div(l.w),h=d.xyz.div(d.w),p=h.xy.sub(c.xy).toVar();p.x.assign(p.x.mul(o)),p.assign(p.normalize());const g=Rn().toVar();if(n){const e=s.xyz.sub(r.xyz).normalize(),t=iu(r.xyz,s.xyz,.5).normalize(),n=e.cross(t).normalize(),a=e.cross(n),o=Un("vec4","worldPos");o.assign(Bd.y.lessThan(.5).select(r,s));const u=Lh.mul(.5);o.addAssign(Rn(Bd.x.lessThan(0).select(n.mul(u),n.mul(u).negate()),0)),i||(o.addAssign(Rn(Bd.y.lessThan(.5).select(e.mul(u).negate(),e.mul(u)),0)),o.addAssign(Rn(a.mul(u),0)),dn(Bd.y.greaterThan(1).or(Bd.y.lessThan(0)),()=>{o.subAssign(Rn(a.mul(2).mul(u),0))})),g.assign(rd.mul(o));const l=_n().toVar();l.assign(Bd.y.lessThan(.5).select(c,h)),g.z.assign(l.z.mul(g.w))}else{const e=yn(p.y,p.x.negate()).toVar("offset");p.x.assign(p.x.div(o)),e.x.assign(e.x.div(o)),e.assign(Bd.x.lessThan(0).select(e.negate(),e)),dn(Bd.y.lessThan(0),()=>{e.assign(e.sub(p))}).ElseIf(Bd.y.greaterThan(1),()=>{e.assign(e.add(p))}),e.assign(e.mul(Lh)),e.assign(e.div(Xl.w.div(Wl))),g.assign(Bd.y.lessThan(.5).select(l,d)),e.assign(e.mul(g.w)),g.assign(g.add(Rn(e,0,0)))}return g})();const o=on(({p1:e,p2:t,p3:r,p4:s})=>{const i=e.sub(r),n=s.sub(r),a=t.sub(e),o=i.dot(n),u=n.dot(a),l=i.dot(a),d=n.dot(n),c=a.dot(a).mul(d).sub(u.mul(u)),h=o.mul(u).sub(l.mul(d)).div(c).clamp(),p=o.add(u.mul(h)).div(d).clamp();return yn(h,p)});if(this.colorNode=on(()=>{const e=Sl();if(i){const t=this.dashSizeNode?pn(this.dashSizeNode):Bh,r=this.gapSizeNode?pn(this.gapSizeNode):Fh;ia.assign(t),na.assign(r);const s=Un("float","lineDistance");e.y.lessThan(-1).or(e.y.greaterThan(1)).discard(),s.mod(ia.add(na)).greaterThan(ia).discard()}const a=pn(1).toVar("alpha");if(n){const e=Un("vec3","worldStart"),s=Un("vec3","worldEnd"),n=Un("vec4","worldPos").xyz.normalize().mul(1e5),u=s.sub(e),l=o({p1:e,p2:s,p3:_n(0,0,0),p4:n}),d=e.add(u.mul(l.x)),c=n.mul(l.y),h=d.sub(c).length().div(Lh);if(!i)if(r&&t.currentSamples>0){const e=h.fwidth();a.assign(uu(e.negate().add(.5),e.add(.5),h).oneMinus())}else h.greaterThan(.5).discard()}else if(r&&t.currentSamples>0){const t=e.x,r=e.y.greaterThan(0).select(e.y.sub(1),e.y.add(1)),s=t.mul(t).add(r.mul(r)),i=pn(s.fwidth()).toVar("dlen");dn(e.y.abs().greaterThan(1),()=>{a.assign(uu(i.oneMinus(),i.add(1),s).oneMinus())})}else dn(e.y.abs().greaterThan(1),()=>{const t=e.x,r=e.y.greaterThan(0).select(e.y.sub(1),e.y.add(1));t.mul(t).add(r.mul(r)).greaterThan(1).discard()});let u;if(this.lineColorNode)u=this.lineColorNode;else if(s){const e=Nl("instanceColorStart"),t=Nl("instanceColorEnd");u=Bd.y.lessThan(.5).select(e,t).mul(sh)}else u=sh;return Rn(u,a)})(),this.transparent){const e=this.opacityNode?pn(this.opacityNode):ah;this.outputNode=Rn(this.colorNode.rgb.mul(e).add(Rp().rgb.mul(e.oneMinus())),this.colorNode.a)}super.setup(e)}get worldUnits(){return this._useWorldUnits}set worldUnits(e){this._useWorldUnits!==e&&(this._useWorldUnits=e,this.needsUpdate=!0)}get dashed(){return this._useDash}set dashed(e){this._useDash!==e&&(this._useDash=e,this.needsUpdate=!0)}get alphaToCoverage(){return this._useAlphaToCoverage}set alphaToCoverage(e){this._useAlphaToCoverage!==e&&(this._useAlphaToCoverage=e,this.needsUpdate=!0)}}const ig=new te;class ng extends Qp{static get type(){return"MeshNormalNodeMaterial"}constructor(e){super(),this.isMeshNormalNodeMaterial=!0,this.setDefaultValues(ig),this.setValues(e)}setupDiffuseColor(){const e=this.opacityNode?pn(this.opacityNode):ah;In.assign(ku(Rn(qc(jd),e),re))}}const ag=on(([e=Dd])=>{const t=e.z.atan(e.x).mul(1/(2*Math.PI)).add(.5),r=e.y.clamp(-1,1).asin().mul(1/Math.PI).add(.5);return yn(t,r)});class og extends se{constructor(e=1,t={}){super(e,e,t),this.isCubeRenderTarget=!0;const r={width:e,height:e,depth:1},s=[r,r,r,r,r,r];this.texture=new L(s),this._setTextureOptions(t),this.texture.isRenderTargetTexture=!0}fromEquirectangularTexture(e,t){const r=t.minFilter,s=t.generateMipmaps;t.generateMipmaps=!0,this.texture.type=t.type,this.texture.colorSpace=t.colorSpace,this.texture.generateMipmaps=t.generateMipmaps,this.texture.minFilter=t.minFilter,this.texture.magFilter=t.magFilter;const i=new ie(5,5,5),n=ag(Dd),a=new Qp;a.colorNode=Fl(t,n,0),a.side=M,a.blending=ee;const o=new ne(i,a),u=new ae;u.add(o),t.minFilter===K&&(t.minFilter=oe);const l=new ue(1,10,this),d=e.getMRT();return e.setMRT(null),l.update(e,u),e.setMRT(d),t.minFilter=r,t.currentGenerateMipmaps=s,o.geometry.dispose(),o.material.dispose(),this}clear(e,t=!0,r=!0,s=!0){const i=e.getRenderTarget();for(let i=0;i<6;i++)e.setRenderTarget(this,i),e.clear(t,r,s);e.setRenderTarget(i)}}const ug=new WeakMap;class lg extends di{static get type(){return"CubeMapNode"}constructor(e){super("vec3"),this.envNode=e,this._cubeTexture=null,this._cubeTextureNode=pc(null);const t=new L;t.isRenderTargetTexture=!0,this._defaultTexture=t,this.updateBeforeType=Zs.RENDER}updateBefore(e){const{renderer:t,material:r}=e,s=this.envNode;if(s.isTextureNode||s.isMaterialReferenceNode){const e=s.isTextureNode?s.value:r[s.property];if(e&&e.isTexture){const r=e.mapping;if(r===le||r===de){if(ug.has(e)){const t=ug.get(e);cg(t,e.mapping),this._cubeTexture=t}else{const r=e.image;if(function(e){return null!=e&&e.height>0}(r)){const s=new og(r.height);s.fromEquirectangularTexture(t,e),cg(s.texture,e.mapping),this._cubeTexture=s.texture,ug.set(e,s.texture),e.addEventListener("dispose",dg)}else this._cubeTexture=this._defaultTexture}this._cubeTextureNode.value=this._cubeTexture}else this._cubeTextureNode=this.envNode}}}setup(e){return this.updateBefore(e),this._cubeTextureNode}}function dg(e){const t=e.target;t.removeEventListener("dispose",dg);const r=ug.get(t);void 0!==r&&(ug.delete(t),r.dispose())}function cg(e,t){t===le?e.mapping=P:t===de&&(e.mapping=D)}const hg=tn(lg).setParameterLength(1);class pg extends mp{static get type(){return"BasicEnvironmentNode"}constructor(e=null){super(),this.envNode=e}setup(e){e.context.environment=hg(this.envNode)}}class gg extends mp{static get type(){return"BasicLightMapNode"}constructor(e=null){super(),this.lightMapNode=e}setup(e){const t=pn(1/Math.PI);e.context.irradianceLightMap=this.lightMapNode.mul(t)}}class mg{start(e){e.lightsNode.setupLights(e,e.lightsNode.getLightNodes(e)),this.indirect(e)}finish(){}direct(){}directRectArea(){}indirect(){}ambientOcclusion(){}}class fg extends mg{constructor(){super()}indirect({context:e}){const t=e.ambientOcclusion,r=e.reflectedLight,s=e.irradianceLightMap;r.indirectDiffuse.assign(Rn(0)),s?r.indirectDiffuse.addAssign(s):r.indirectDiffuse.addAssign(Rn(1,1,1,0)),r.indirectDiffuse.mulAssign(t),r.indirectDiffuse.mulAssign(In.rgb)}finish(e){const{material:t,context:r}=e,s=r.outgoingLight,i=e.context.environment;if(i)switch(t.combine){case pe:s.rgb.assign(iu(s.rgb,s.rgb.mul(i.rgb),dh.mul(ch)));break;case he:s.rgb.assign(iu(s.rgb,i.rgb,dh.mul(ch)));break;case ce:s.rgb.addAssign(i.rgb.mul(dh.mul(ch)));break;default:d("BasicLightingModel: Unsupported .combine value:",t.combine)}}}const yg=new ge;class bg extends Qp{static get type(){return"MeshBasicNodeMaterial"}constructor(e){super(),this.isMeshBasicNodeMaterial=!0,this.lights=!0,this.setDefaultValues(yg),this.setValues(e)}setupNormal(){return Gd(Hd)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new pg(t):null}setupLightMap(e){let t=null;return e.material.lightMap&&(t=new gg(Ih)),t}setupOutgoingLight(){return In.rgb}setupLightingModel(){return new fg}}const xg=on(({f0:e,f90:t,dotVH:r})=>{const s=r.mul(-5.55473).sub(6.98316).mul(r).exp2();return e.mul(s.oneMinus()).add(t.mul(s))}),Tg=on(e=>e.diffuseColor.mul(1/Math.PI)),_g=on(({dotNH:e})=>ra.mul(pn(.5)).add(1).mul(pn(1/Math.PI)).mul(e.pow(ra))),vg=on(({lightDirection:e})=>{const t=e.add(Id).normalize(),r=jd.dot(t).clamp(),s=Id.dot(t).clamp(),i=xg({f0:Jn,f90:1,dotVH:s}),n=pn(.25),a=_g({dotNH:r});return i.mul(n).mul(a)});class Ng extends fg{constructor(e=!0){super(),this.specular=e}direct({lightDirection:e,lightColor:t,reflectedLight:r}){const s=jd.dot(e).clamp().mul(t);r.directDiffuse.addAssign(s.mul(Tg({diffuseColor:In.rgb}))),!0===this.specular&&r.directSpecular.addAssign(s.mul(vg({lightDirection:e})).mul(dh))}indirect(e){const{ambientOcclusion:t,irradiance:r,reflectedLight:s}=e.context;s.indirectDiffuse.addAssign(r.mul(Tg({diffuseColor:In}))),s.indirectDiffuse.mulAssign(t)}}const Sg=new me;class Rg extends Qp{static get type(){return"MeshLambertNodeMaterial"}constructor(e){super(),this.isMeshLambertNodeMaterial=!0,this.lights=!0,this.setDefaultValues(Sg),this.setValues(e)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new pg(t):null}setupLightingModel(){return new Ng(!1)}}const Eg=new fe;class Ag extends Qp{static get type(){return"MeshPhongNodeMaterial"}constructor(e){super(),this.isMeshPhongNodeMaterial=!0,this.lights=!0,this.shininessNode=null,this.specularNode=null,this.setDefaultValues(Eg),this.setValues(e)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new pg(t):null}setupLightingModel(){return new Ng}setupVariants(){const e=(this.shininessNode?pn(this.shininessNode):ih).max(1e-4);ra.assign(e);const t=this.specularNode||oh;Jn.assign(t)}copy(e){return this.shininessNode=e.shininessNode,this.specularNode=e.specularNode,super.copy(e)}}const wg=on(e=>{if(!1===e.geometry.hasAttribute("normal"))return pn(0);const t=Hd.dFdx().abs().max(Hd.dFdy().abs());return t.x.max(t.y).max(t.z)}),Cg=on(e=>{const{roughness:t}=e,r=wg();let s=t.max(.0525);return s=s.add(r),s=s.min(1),s}),Mg=on(({alpha:e,dotNL:t,dotNV:r})=>{const s=e.pow2(),i=t.mul(s.add(s.oneMinus().mul(r.pow2())).sqrt()),n=r.mul(s.add(s.oneMinus().mul(t.pow2())).sqrt());return Fa(.5,i.add(n).max(ro))}).setLayout({name:"V_GGX_SmithCorrelated",type:"float",inputs:[{name:"alpha",type:"float"},{name:"dotNL",type:"float"},{name:"dotNV",type:"float"}]}),Bg=on(({alphaT:e,alphaB:t,dotTV:r,dotBV:s,dotTL:i,dotBL:n,dotNV:a,dotNL:o})=>{const u=o.mul(_n(e.mul(r),t.mul(s),a).length()),l=a.mul(_n(e.mul(i),t.mul(n),o).length());return Fa(.5,u.add(l))}).setLayout({name:"V_GGX_SmithCorrelated_Anisotropic",type:"float",inputs:[{name:"alphaT",type:"float",qualifier:"in"},{name:"alphaB",type:"float",qualifier:"in"},{name:"dotTV",type:"float",qualifier:"in"},{name:"dotBV",type:"float",qualifier:"in"},{name:"dotTL",type:"float",qualifier:"in"},{name:"dotBL",type:"float",qualifier:"in"},{name:"dotNV",type:"float",qualifier:"in"},{name:"dotNL",type:"float",qualifier:"in"}]}),Fg=on(({alpha:e,dotNH:t})=>{const r=e.pow2(),s=t.pow2().mul(r.oneMinus()).oneMinus();return r.div(s.pow2()).mul(1/Math.PI)}).setLayout({name:"D_GGX",type:"float",inputs:[{name:"alpha",type:"float"},{name:"dotNH",type:"float"}]}),Lg=pn(1/Math.PI),Pg=on(({alphaT:e,alphaB:t,dotNH:r,dotTH:s,dotBH:i})=>{const n=e.mul(t),a=_n(t.mul(s),e.mul(i),n.mul(r)),o=a.dot(a),u=n.div(o);return Lg.mul(n.mul(u.pow2()))}).setLayout({name:"D_GGX_Anisotropic",type:"float",inputs:[{name:"alphaT",type:"float",qualifier:"in"},{name:"alphaB",type:"float",qualifier:"in"},{name:"dotNH",type:"float",qualifier:"in"},{name:"dotTH",type:"float",qualifier:"in"},{name:"dotBH",type:"float",qualifier:"in"}]}),Dg=on(({lightDirection:e,f0:t,f90:r,roughness:s,f:i,normalView:n=jd,USE_IRIDESCENCE:a,USE_ANISOTROPY:o})=>{const u=s.pow2(),l=e.add(Id).normalize(),d=n.dot(e).clamp(),c=n.dot(Id).clamp(),h=n.dot(l).clamp(),p=Id.dot(l).clamp();let g,m,f=xg({f0:t,f90:r,dotVH:p});if(Xi(a)&&(f=qn.mix(f,i)),Xi(o)){const t=Qn.dot(e),r=Qn.dot(Id),s=Qn.dot(l),i=Zn.dot(e),n=Zn.dot(Id),a=Zn.dot(l);g=Bg({alphaT:Kn,alphaB:u,dotTV:r,dotBV:n,dotTL:t,dotBL:i,dotNV:c,dotNL:d}),m=Pg({alphaT:Kn,alphaB:u,dotNH:h,dotTH:s,dotBH:a})}else g=Mg({alpha:u,dotNL:d,dotNV:c}),m=Fg({alpha:u,dotNH:h});return f.mul(g).mul(m)}),Ug=new Uint16Array([12469,15057,12620,14925,13266,14620,13807,14376,14323,13990,14545,13625,14713,13328,14840,12882,14931,12528,14996,12233,15039,11829,15066,11525,15080,11295,15085,10976,15082,10705,15073,10495,13880,14564,13898,14542,13977,14430,14158,14124,14393,13732,14556,13410,14702,12996,14814,12596,14891,12291,14937,11834,14957,11489,14958,11194,14943,10803,14921,10506,14893,10278,14858,9960,14484,14039,14487,14025,14499,13941,14524,13740,14574,13468,14654,13106,14743,12678,14818,12344,14867,11893,14889,11509,14893,11180,14881,10751,14852,10428,14812,10128,14765,9754,14712,9466,14764,13480,14764,13475,14766,13440,14766,13347,14769,13070,14786,12713,14816,12387,14844,11957,14860,11549,14868,11215,14855,10751,14825,10403,14782,10044,14729,9651,14666,9352,14599,9029,14967,12835,14966,12831,14963,12804,14954,12723,14936,12564,14917,12347,14900,11958,14886,11569,14878,11247,14859,10765,14828,10401,14784,10011,14727,9600,14660,9289,14586,8893,14508,8533,15111,12234,15110,12234,15104,12216,15092,12156,15067,12010,15028,11776,14981,11500,14942,11205,14902,10752,14861,10393,14812,9991,14752,9570,14682,9252,14603,8808,14519,8445,14431,8145,15209,11449,15208,11451,15202,11451,15190,11438,15163,11384,15117,11274,15055,10979,14994,10648,14932,10343,14871,9936,14803,9532,14729,9218,14645,8742,14556,8381,14461,8020,14365,7603,15273,10603,15272,10607,15267,10619,15256,10631,15231,10614,15182,10535,15118,10389,15042,10167,14963,9787,14883,9447,14800,9115,14710,8665,14615,8318,14514,7911,14411,7507,14279,7198,15314,9675,15313,9683,15309,9712,15298,9759,15277,9797,15229,9773,15166,9668,15084,9487,14995,9274,14898,8910,14800,8539,14697,8234,14590,7790,14479,7409,14367,7067,14178,6621,15337,8619,15337,8631,15333,8677,15325,8769,15305,8871,15264,8940,15202,8909,15119,8775,15022,8565,14916,8328,14804,8009,14688,7614,14569,7287,14448,6888,14321,6483,14088,6171,15350,7402,15350,7419,15347,7480,15340,7613,15322,7804,15287,7973,15229,8057,15148,8012,15046,7846,14933,7611,14810,7357,14682,7069,14552,6656,14421,6316,14251,5948,14007,5528,15356,5942,15356,5977,15353,6119,15348,6294,15332,6551,15302,6824,15249,7044,15171,7122,15070,7050,14949,6861,14818,6611,14679,6349,14538,6067,14398,5651,14189,5311,13935,4958,15359,4123,15359,4153,15356,4296,15353,4646,15338,5160,15311,5508,15263,5829,15188,6042,15088,6094,14966,6001,14826,5796,14678,5543,14527,5287,14377,4985,14133,4586,13869,4257,15360,1563,15360,1642,15358,2076,15354,2636,15341,3350,15317,4019,15273,4429,15203,4732,15105,4911,14981,4932,14836,4818,14679,4621,14517,4386,14359,4156,14083,3795,13808,3437,15360,122,15360,137,15358,285,15355,636,15344,1274,15322,2177,15281,2765,15215,3223,15120,3451,14995,3569,14846,3567,14681,3466,14511,3305,14344,3121,14037,2800,13753,2467,15360,0,15360,1,15359,21,15355,89,15346,253,15325,479,15287,796,15225,1148,15133,1492,15008,1749,14856,1882,14685,1886,14506,1783,14324,1608,13996,1398,13702,1183]);let Ig=null;const Og=on(({roughness:e,dotNV:t})=>{null===Ig&&(Ig=new ye(Ug,16,16,G,be),Ig.name="DFG_LUT",Ig.minFilter=oe,Ig.magFilter=oe,Ig.wrapS=xe,Ig.wrapT=xe,Ig.generateMipmaps=!1,Ig.needsUpdate=!0);const r=yn(e,t);return Fl(Ig,r).rg}),Vg=on(({lightDirection:e,f0:t,f90:r,roughness:s,f:i,USE_IRIDESCENCE:n,USE_ANISOTROPY:a})=>{const o=Dg({lightDirection:e,f0:t,f90:r,roughness:s,f:i,USE_IRIDESCENCE:n,USE_ANISOTROPY:a}),u=jd.dot(e).clamp(),l=jd.dot(Id).clamp(),d=Og({roughness:s,dotNV:l}),c=Og({roughness:s,dotNV:u}),h=t.mul(d.x).add(r.mul(d.y)),p=t.mul(c.x).add(r.mul(c.y)),g=d.x.add(d.y),m=c.x.add(c.y),f=pn(1).sub(g),y=pn(1).sub(m),b=t.add(t.oneMinus().mul(.047619)),x=h.mul(p).mul(b).div(pn(1).sub(f.mul(y).mul(b).mul(b)).add(ro)),T=f.mul(y),_=x.mul(T);return o.add(_)}),kg=on(e=>{const{dotNV:t,specularColor:r,specularF90:s,roughness:i}=e,n=Og({dotNV:t,roughness:i});return r.mul(n.x).add(s.mul(n.y))}),Gg=on(({f:e,f90:t,dotVH:r})=>{const s=r.oneMinus().saturate(),i=s.mul(s),n=s.mul(i,i).clamp(0,.9999);return e.sub(_n(t).mul(n)).div(n.oneMinus())}).setLayout({name:"Schlick_to_F0",type:"vec3",inputs:[{name:"f",type:"vec3"},{name:"f90",type:"float"},{name:"dotVH",type:"float"}]}),zg=on(({roughness:e,dotNH:t})=>{const r=e.pow2(),s=pn(1).div(r),i=t.pow2().oneMinus().max(.0078125);return pn(2).add(s).mul(i.pow(s.mul(.5))).div(2*Math.PI)}).setLayout({name:"D_Charlie",type:"float",inputs:[{name:"roughness",type:"float"},{name:"dotNH",type:"float"}]}),$g=on(({dotNV:e,dotNL:t})=>pn(1).div(pn(4).mul(t.add(e).sub(t.mul(e))))).setLayout({name:"V_Neubelt",type:"float",inputs:[{name:"dotNV",type:"float"},{name:"dotNL",type:"float"}]}),Wg=on(({lightDirection:e})=>{const t=e.add(Id).normalize(),r=jd.dot(e).clamp(),s=jd.dot(Id).clamp(),i=jd.dot(t).clamp(),n=zg({roughness:Hn,dotNH:i}),a=$g({dotNV:s,dotNL:r});return Wn.mul(n).mul(a)}),Hg=on(({N:e,V:t,roughness:r})=>{const s=e.dot(t).saturate(),i=yn(r,s.oneMinus().sqrt());return i.assign(i.mul(.984375).add(.0078125)),i}).setLayout({name:"LTC_Uv",type:"vec2",inputs:[{name:"N",type:"vec3"},{name:"V",type:"vec3"},{name:"roughness",type:"float"}]}),qg=on(({f:e})=>{const t=e.length();return Wo(t.mul(t).add(e.z).div(t.add(1)),0)}).setLayout({name:"LTC_ClippedSphereFormFactor",type:"float",inputs:[{name:"f",type:"vec3"}]}),jg=on(({v1:e,v2:t})=>{const r=e.dot(t),s=r.abs().toVar(),i=s.mul(.0145206).add(.4965155).mul(s).add(.8543985).toVar(),n=s.add(4.1616724).mul(s).add(3.417594).toVar(),a=i.div(n),o=r.greaterThan(0).select(a,Wo(r.mul(r).oneMinus(),1e-7).inverseSqrt().mul(.5).sub(a));return e.cross(t).mul(o)}).setLayout({name:"LTC_EdgeVectorFormFactor",type:"vec3",inputs:[{name:"v1",type:"vec3"},{name:"v2",type:"vec3"}]}),Xg=on(({N:e,V:t,P:r,mInv:s,p0:i,p1:n,p2:a,p3:o})=>{const u=n.sub(i).toVar(),l=o.sub(i).toVar(),d=u.cross(l),c=_n().toVar();return dn(d.dot(r.sub(i)).greaterThanEqual(0),()=>{const u=t.sub(e.mul(t.dot(e))).normalize(),l=e.cross(u).negate(),d=s.mul(Mn(u,l,e).transpose()).toVar(),h=d.mul(i.sub(r)).normalize().toVar(),p=d.mul(n.sub(r)).normalize().toVar(),g=d.mul(a.sub(r)).normalize().toVar(),m=d.mul(o.sub(r)).normalize().toVar(),f=_n(0).toVar();f.addAssign(jg({v1:h,v2:p})),f.addAssign(jg({v1:p,v2:g})),f.addAssign(jg({v1:g,v2:m})),f.addAssign(jg({v1:m,v2:h})),c.assign(_n(qg({f:f})))}),c}).setLayout({name:"LTC_Evaluate",type:"vec3",inputs:[{name:"N",type:"vec3"},{name:"V",type:"vec3"},{name:"P",type:"vec3"},{name:"mInv",type:"mat3"},{name:"p0",type:"vec3"},{name:"p1",type:"vec3"},{name:"p2",type:"vec3"},{name:"p3",type:"vec3"}]}),Kg=on(({P:e,p0:t,p1:r,p2:s,p3:i})=>{const n=r.sub(t).toVar(),a=i.sub(t).toVar(),o=n.cross(a),u=_n().toVar();return dn(o.dot(e.sub(t)).greaterThanEqual(0),()=>{const n=t.sub(e).normalize().toVar(),a=r.sub(e).normalize().toVar(),o=s.sub(e).normalize().toVar(),l=i.sub(e).normalize().toVar(),d=_n(0).toVar();d.addAssign(jg({v1:n,v2:a})),d.addAssign(jg({v1:a,v2:o})),d.addAssign(jg({v1:o,v2:l})),d.addAssign(jg({v1:l,v2:n})),u.assign(_n(qg({f:d.abs()})))}),u}).setLayout({name:"LTC_Evaluate",type:"vec3",inputs:[{name:"P",type:"vec3"},{name:"p0",type:"vec3"},{name:"p1",type:"vec3"},{name:"p2",type:"vec3"},{name:"p3",type:"vec3"}]}),Yg=1/6,Qg=e=>Ba(Yg,Ba(e,Ba(e,e.negate().add(3)).sub(3)).add(1)),Zg=e=>Ba(Yg,Ba(e,Ba(e,Ba(3,e).sub(6))).add(4)),Jg=e=>Ba(Yg,Ba(e,Ba(e,Ba(-3,e).add(3)).add(3)).add(1)),em=e=>Ba(Yg,Qo(e,3)),tm=e=>Qg(e).add(Zg(e)),rm=e=>Jg(e).add(em(e)),sm=e=>Ca(-1,Zg(e).div(Qg(e).add(Zg(e)))),im=e=>Ca(1,em(e).div(Jg(e).add(em(e)))),nm=(e,t,r)=>{const s=e.uvNode,i=Ba(s,t.zw).add(.5),n=xo(i),a=vo(i),o=tm(a.x),u=rm(a.x),l=sm(a.x),d=im(a.x),c=sm(a.y),h=im(a.y),p=yn(n.x.add(l),n.y.add(c)).sub(.5).mul(t.xy),g=yn(n.x.add(d),n.y.add(c)).sub(.5).mul(t.xy),m=yn(n.x.add(l),n.y.add(h)).sub(.5).mul(t.xy),f=yn(n.x.add(d),n.y.add(h)).sub(.5).mul(t.xy),y=tm(a.y).mul(Ca(o.mul(e.sample(p).level(r)),u.mul(e.sample(g).level(r)))),b=rm(a.y).mul(Ca(o.mul(e.sample(m).level(r)),u.mul(e.sample(f).level(r))));return y.add(b)},am=on(([e,t])=>{const r=yn(e.size(gn(t))),s=yn(e.size(gn(t.add(1)))),i=Fa(1,r),n=Fa(1,s),a=nm(e,Rn(i,r),xo(t)),o=nm(e,Rn(n,s),To(t));return vo(t).mix(a,o)}),om=on(([e,t])=>{const r=t.mul(wl(e));return am(e,r)}),um=on(([e,t,r,s,i])=>{const n=_n(ou(t.negate(),_o(e),Fa(1,s))),a=_n(Bo(i[0].xyz),Bo(i[1].xyz),Bo(i[2].xyz));return _o(n).mul(r.mul(a))}).setLayout({name:"getVolumeTransmissionRay",type:"vec3",inputs:[{name:"n",type:"vec3"},{name:"v",type:"vec3"},{name:"thickness",type:"float"},{name:"ior",type:"float"},{name:"modelMatrix",type:"mat4"}]}),lm=on(([e,t])=>e.mul(nu(t.mul(2).sub(2),0,1))).setLayout({name:"applyIorToRoughness",type:"float",inputs:[{name:"roughness",type:"float"},{name:"ior",type:"float"}]}),dm=Np(),cm=Rp(),hm=on(([e,t,r],{material:s})=>{const i=(s.side===M?dm:cm).sample(e),n=fo(ql.x).mul(lm(t,r));return am(i,n)}),pm=on(([e,t,r])=>(dn(r.notEqual(0),()=>{const s=mo(t).negate().div(r);return po(s.negate().mul(e))}),_n(1))).setLayout({name:"volumeAttenuation",type:"vec3",inputs:[{name:"transmissionDistance",type:"float"},{name:"attenuationColor",type:"vec3"},{name:"attenuationDistance",type:"float"}]}),gm=on(([e,t,r,s,i,n,a,o,u,l,d,c,h,p,g])=>{let m,f;if(g){m=Rn().toVar(),f=_n().toVar();const i=d.sub(1).mul(g.mul(.025)),n=_n(d.sub(i),d,d.add(i));up({start:0,end:3},({i:i})=>{const d=n.element(i),g=um(e,t,c,d,o),y=a.add(g),b=l.mul(u.mul(Rn(y,1))),x=yn(b.xy.div(b.w)).toVar();x.addAssign(1),x.divAssign(2),x.assign(yn(x.x,x.y.oneMinus()));const T=hm(x,r,d);m.element(i).assign(T.element(i)),m.a.addAssign(T.a),f.element(i).assign(s.element(i).mul(pm(Bo(g),h,p).element(i)))}),m.a.divAssign(3)}else{const i=um(e,t,c,d,o),n=a.add(i),g=l.mul(u.mul(Rn(n,1))),y=yn(g.xy.div(g.w)).toVar();y.addAssign(1),y.divAssign(2),y.assign(yn(y.x,y.y.oneMinus())),m=hm(y,r,d),f=s.mul(pm(Bo(i),h,p))}const y=f.rgb.mul(m.rgb),b=e.dot(t).clamp(),x=_n(kg({dotNV:b,specularColor:i,specularF90:n,roughness:r})),T=f.r.add(f.g,f.b).div(3);return Rn(x.oneMinus().mul(y),m.a.oneMinus().mul(T).oneMinus())}),mm=Mn(3.2404542,-.969266,.0556434,-1.5371385,1.8760108,-.2040259,-.4985314,.041556,1.0572252),fm=(e,t)=>e.sub(t).div(e.add(t)).pow2(),ym=on(({outsideIOR:e,eta2:t,cosTheta1:r,thinFilmThickness:s,baseF0:i})=>{const n=iu(e,t,uu(0,.03,s)),a=e.div(n).pow2().mul(r.pow2().oneMinus()).oneMinus();dn(a.lessThan(0),()=>_n(1));const o=a.sqrt(),u=fm(n,e),l=xg({f0:u,f90:1,dotVH:r}),d=l.oneMinus(),c=n.lessThan(e).select(Math.PI,0),h=pn(Math.PI).sub(c),p=(e=>{const t=e.sqrt();return _n(1).add(t).div(_n(1).sub(t))})(i.clamp(0,.9999)),g=fm(p,n.toVec3()),m=xg({f0:g,f90:1,dotVH:o}),f=_n(p.x.lessThan(n).select(Math.PI,0),p.y.lessThan(n).select(Math.PI,0),p.z.lessThan(n).select(Math.PI,0)),y=n.mul(s,o,2),b=_n(h).add(f),x=l.mul(m).clamp(1e-5,.9999),T=x.sqrt(),_=d.pow2().mul(m).div(_n(1).sub(x)),v=l.add(_).toVar(),N=_.sub(d).toVar();return up({start:1,end:2,condition:"<=",name:"m"},({m:e})=>{N.mulAssign(T);const t=((e,t)=>{const r=e.mul(2*Math.PI*1e-9),s=_n(54856e-17,44201e-17,52481e-17),i=_n(1681e3,1795300,2208400),n=_n(43278e5,93046e5,66121e5),a=pn(9747e-17*Math.sqrt(2*Math.PI*45282e5)).mul(r.mul(2239900).add(t.x).cos()).mul(r.pow2().mul(-45282e5).exp());let o=s.mul(n.mul(2*Math.PI).sqrt()).mul(i.mul(r).add(t).cos()).mul(r.pow2().negate().mul(n).exp());return o=_n(o.x.add(a),o.y,o.z).div(1.0685e-7),mm.mul(o)})(pn(e).mul(y),pn(e).mul(b)).mul(2);v.addAssign(N.mul(t))}),v.max(_n(0))}).setLayout({name:"evalIridescence",type:"vec3",inputs:[{name:"outsideIOR",type:"float"},{name:"eta2",type:"float"},{name:"cosTheta1",type:"float"},{name:"thinFilmThickness",type:"float"},{name:"baseF0",type:"vec3"}]}),bm=on(({normal:e,viewDir:t,roughness:r})=>{const s=e.dot(t).saturate(),i=r.mul(r),n=r.add(.1).reciprocal(),a=pn(-1.9362).add(r.mul(1.0678)).add(i.mul(.4573)).sub(n.mul(.8469)),o=pn(-.6014).add(r.mul(.5538)).sub(i.mul(.467)).sub(n.mul(.1255));return a.mul(s).add(o).exp().saturate()}),xm=_n(.04),Tm=pn(1);class _m extends mg{constructor(e=!1,t=!1,r=!1,s=!1,i=!1,n=!1){super(),this.clearcoat=e,this.sheen=t,this.iridescence=r,this.anisotropy=s,this.transmission=i,this.dispersion=n,this.clearcoatRadiance=null,this.clearcoatSpecularDirect=null,this.clearcoatSpecularIndirect=null,this.sheenSpecularDirect=null,this.sheenSpecularIndirect=null,this.iridescenceFresnel=null,this.iridescenceF0=null,this.iridescenceF0Dielectric=null,this.iridescenceF0Metallic=null}start(e){if(!0===this.clearcoat&&(this.clearcoatRadiance=_n().toVar("clearcoatRadiance"),this.clearcoatSpecularDirect=_n().toVar("clearcoatSpecularDirect"),this.clearcoatSpecularIndirect=_n().toVar("clearcoatSpecularIndirect")),!0===this.sheen&&(this.sheenSpecularDirect=_n().toVar("sheenSpecularDirect"),this.sheenSpecularIndirect=_n().toVar("sheenSpecularIndirect")),!0===this.iridescence){const e=jd.dot(Id).clamp(),t=ym({outsideIOR:pn(1),eta2:jn,cosTheta1:e,thinFilmThickness:Xn,baseF0:Jn}),r=ym({outsideIOR:pn(1),eta2:jn,cosTheta1:e,thinFilmThickness:Xn,baseF0:In.rgb});this.iridescenceFresnel=iu(t,r,Gn),this.iridescenceF0Dielectric=Gg({f:t,f90:1,dotVH:e}),this.iridescenceF0Metallic=Gg({f:r,f90:1,dotVH:e}),this.iridescenceF0=iu(this.iridescenceF0Dielectric,this.iridescenceF0Metallic,Gn)}if(!0===this.transmission){const t=Pd,r=od.sub(Pd).normalize(),s=Xd,i=e.context;i.backdrop=gm(s,r,kn,On,ea,ta,t,xd,id,rd,oa,la,ca,da,this.dispersion?ha:null),i.backdropAlpha=ua,In.a.mulAssign(iu(1,i.backdrop.a,ua))}super.start(e)}computeMultiscattering(e,t,r,s,i=null){const n=jd.dot(Id).clamp(),a=Og({roughness:kn,dotNV:n}),o=i?qn.mix(s,i):s,u=o.mul(a.x).add(r.mul(a.y)),l=a.x.add(a.y).oneMinus(),d=o.add(o.oneMinus().mul(.047619)),c=u.mul(d).div(l.mul(d).oneMinus());e.addAssign(u),t.addAssign(c.mul(l))}direct({lightDirection:e,lightColor:t,reflectedLight:r}){const s=jd.dot(e).clamp().mul(t).toVar();if(!0===this.sheen){this.sheenSpecularDirect.addAssign(s.mul(Wg({lightDirection:e})));const t=bm({normal:jd,viewDir:Id,roughness:Hn}),r=bm({normal:jd,viewDir:e,roughness:Hn}),i=Wn.r.max(Wn.g).max(Wn.b).mul(t.max(r)).oneMinus();s.mulAssign(i)}if(!0===this.clearcoat){const r=Kd.dot(e).clamp().mul(t);this.clearcoatSpecularDirect.addAssign(r.mul(Dg({lightDirection:e,f0:xm,f90:Tm,roughness:$n,normalView:Kd})))}r.directDiffuse.addAssign(s.mul(Tg({diffuseColor:On}))),r.directSpecular.addAssign(s.mul(Vg({lightDirection:e,f0:ea,f90:1,roughness:kn,f:this.iridescenceFresnel,USE_IRIDESCENCE:this.iridescence,USE_ANISOTROPY:this.anisotropy})))}directRectArea({lightColor:e,lightPosition:t,halfWidth:r,halfHeight:s,reflectedLight:i,ltc_1:n,ltc_2:a}){const o=t.add(r).sub(s),u=t.sub(r).sub(s),l=t.sub(r).add(s),d=t.add(r).add(s),c=jd,h=Id,p=Ud.toVar(),g=Hg({N:c,V:h,roughness:kn}),m=n.sample(g).toVar(),f=a.sample(g).toVar(),y=Mn(_n(m.x,0,m.y),_n(0,1,0),_n(m.z,0,m.w)).toVar(),b=ea.mul(f.x).add(ta.sub(ea).mul(f.y)).toVar();if(i.directSpecular.addAssign(e.mul(b).mul(Xg({N:c,V:h,P:p,mInv:y,p0:o,p1:u,p2:l,p3:d}))),i.directDiffuse.addAssign(e.mul(On).mul(Xg({N:c,V:h,P:p,mInv:Mn(1,0,0,0,1,0,0,0,1),p0:o,p1:u,p2:l,p3:d}))),!0===this.clearcoat){const t=Kd,r=Hg({N:t,V:h,roughness:$n}),s=n.sample(r),i=a.sample(r),c=Mn(_n(s.x,0,s.y),_n(0,1,0),_n(s.z,0,s.w)),g=xm.mul(i.x).add(Tm.sub(xm).mul(i.y));this.clearcoatSpecularDirect.addAssign(e.mul(g).mul(Xg({N:t,V:h,P:p,mInv:c,p0:o,p1:u,p2:l,p3:d})))}}indirect(e){this.indirectDiffuse(e),this.indirectSpecular(e),this.ambientOcclusion(e)}indirectDiffuse(e){const{irradiance:t,reflectedLight:r}=e.context,s=t.mul(Tg({diffuseColor:On})).toVar();if(!0===this.sheen){const e=bm({normal:jd,viewDir:Id,roughness:Hn}),t=Wn.r.max(Wn.g).max(Wn.b).mul(e).oneMinus();s.mulAssign(t)}r.indirectDiffuse.addAssign(s)}indirectSpecular(e){const{radiance:t,iblIrradiance:r,reflectedLight:s}=e.context;if(!0===this.sheen&&this.sheenSpecularIndirect.addAssign(r.mul(Wn,bm({normal:jd,viewDir:Id,roughness:Hn}))),!0===this.clearcoat){const e=Kd.dot(Id).clamp(),t=kg({dotNV:e,specularColor:xm,specularF90:Tm,roughness:$n});this.clearcoatSpecularIndirect.addAssign(this.clearcoatRadiance.mul(t))}const i=_n().toVar("singleScatteringDielectric"),n=_n().toVar("multiScatteringDielectric"),a=_n().toVar("singleScatteringMetallic"),o=_n().toVar("multiScatteringMetallic");this.computeMultiscattering(i,n,ta,Jn,this.iridescenceF0Dielectric),this.computeMultiscattering(a,o,ta,In.rgb,this.iridescenceF0Metallic);const u=iu(i,a,Gn),l=iu(n,o,Gn),d=i.add(n),c=On.mul(d.oneMinus()),h=r.mul(1/Math.PI),p=t.mul(u).add(l.mul(h)).toVar(),g=c.mul(h).toVar();if(!0===this.sheen){const e=bm({normal:jd,viewDir:Id,roughness:Hn}),t=Wn.r.max(Wn.g).max(Wn.b).mul(e).oneMinus();p.mulAssign(t),g.mulAssign(t)}s.indirectSpecular.addAssign(p),s.indirectDiffuse.addAssign(g)}ambientOcclusion(e){const{ambientOcclusion:t,reflectedLight:r}=e.context,s=jd.dot(Id).clamp().add(t),i=kn.mul(-16).oneMinus().negate().exp2(),n=t.sub(s.pow(i).oneMinus()).clamp();!0===this.clearcoat&&this.clearcoatSpecularIndirect.mulAssign(t),!0===this.sheen&&this.sheenSpecularIndirect.mulAssign(t),r.indirectDiffuse.mulAssign(t),r.indirectSpecular.mulAssign(n)}finish({context:e}){const{outgoingLight:t}=e;if(!0===this.clearcoat){const e=Kd.dot(Id).clamp(),r=xg({dotVH:e,f0:xm,f90:Tm}),s=t.mul(zn.mul(r).oneMinus()).add(this.clearcoatSpecularDirect.add(this.clearcoatSpecularIndirect).mul(zn));t.assign(s)}if(!0===this.sheen){const e=t.add(this.sheenSpecularDirect,this.sheenSpecularIndirect.mul(1/Math.PI));t.assign(e)}}}const vm=pn(1),Nm=pn(-2),Sm=pn(.8),Rm=pn(-1),Em=pn(.4),Am=pn(2),wm=pn(.305),Cm=pn(3),Mm=pn(.21),Bm=pn(4),Fm=pn(4),Lm=pn(16),Pm=on(([e])=>{const t=_n(Co(e)).toVar(),r=pn(-1).toVar();return dn(t.x.greaterThan(t.z),()=>{dn(t.x.greaterThan(t.y),()=>{r.assign(yu(e.x.greaterThan(0),0,3))}).Else(()=>{r.assign(yu(e.y.greaterThan(0),1,4))})}).Else(()=>{dn(t.z.greaterThan(t.y),()=>{r.assign(yu(e.z.greaterThan(0),2,5))}).Else(()=>{r.assign(yu(e.y.greaterThan(0),1,4))})}),r}).setLayout({name:"getFace",type:"float",inputs:[{name:"direction",type:"vec3"}]}),Dm=on(([e,t])=>{const r=yn().toVar();return dn(t.equal(0),()=>{r.assign(yn(e.z,e.y).div(Co(e.x)))}).ElseIf(t.equal(1),()=>{r.assign(yn(e.x.negate(),e.z.negate()).div(Co(e.y)))}).ElseIf(t.equal(2),()=>{r.assign(yn(e.x.negate(),e.y).div(Co(e.z)))}).ElseIf(t.equal(3),()=>{r.assign(yn(e.z.negate(),e.y).div(Co(e.x)))}).ElseIf(t.equal(4),()=>{r.assign(yn(e.x.negate(),e.z).div(Co(e.y)))}).Else(()=>{r.assign(yn(e.x,e.y).div(Co(e.z)))}),Ba(.5,r.add(1))}).setLayout({name:"getUV",type:"vec2",inputs:[{name:"direction",type:"vec3"},{name:"face",type:"float"}]}),Um=on(([e])=>{const t=pn(0).toVar();return dn(e.greaterThanEqual(Sm),()=>{t.assign(vm.sub(e).mul(Rm.sub(Nm)).div(vm.sub(Sm)).add(Nm))}).ElseIf(e.greaterThanEqual(Em),()=>{t.assign(Sm.sub(e).mul(Am.sub(Rm)).div(Sm.sub(Em)).add(Rm))}).ElseIf(e.greaterThanEqual(wm),()=>{t.assign(Em.sub(e).mul(Cm.sub(Am)).div(Em.sub(wm)).add(Am))}).ElseIf(e.greaterThanEqual(Mm),()=>{t.assign(wm.sub(e).mul(Bm.sub(Cm)).div(wm.sub(Mm)).add(Cm))}).Else(()=>{t.assign(pn(-2).mul(fo(Ba(1.16,e))))}),t}).setLayout({name:"roughnessToMip",type:"float",inputs:[{name:"roughness",type:"float"}]}),Im=on(([e,t])=>{const r=e.toVar();r.assign(Ba(2,r).sub(1));const s=_n(r,1).toVar();return dn(t.equal(0),()=>{s.assign(s.zyx)}).ElseIf(t.equal(1),()=>{s.assign(s.xzy),s.xz.mulAssign(-1)}).ElseIf(t.equal(2),()=>{s.x.mulAssign(-1)}).ElseIf(t.equal(3),()=>{s.assign(s.zyx),s.xz.mulAssign(-1)}).ElseIf(t.equal(4),()=>{s.assign(s.xzy),s.xy.mulAssign(-1)}).ElseIf(t.equal(5),()=>{s.z.mulAssign(-1)}),s}).setLayout({name:"getDirection",type:"vec3",inputs:[{name:"uv",type:"vec2"},{name:"face",type:"float"}]}),Om=on(([e,t,r,s,i,n])=>{const a=pn(r),o=_n(t),u=nu(Um(a),Nm,n),l=vo(u),d=xo(u),c=_n(Vm(e,o,d,s,i,n)).toVar();return dn(l.notEqual(0),()=>{const t=_n(Vm(e,o,d.add(1),s,i,n)).toVar();c.assign(iu(c,t,l))}),c}),Vm=on(([e,t,r,s,i,n])=>{const a=pn(r).toVar(),o=_n(t),u=pn(Pm(o)).toVar(),l=pn(Wo(Fm.sub(a),0)).toVar();a.assign(Wo(a,Fm));const d=pn(go(a)).toVar(),c=yn(Dm(o,u).mul(d.sub(2)).add(1)).toVar();return dn(u.greaterThan(2),()=>{c.y.addAssign(d),u.subAssign(3)}),c.x.addAssign(u.mul(d)),c.x.addAssign(l.mul(Ba(3,Lm))),c.y.addAssign(Ba(4,go(n).sub(d))),c.x.mulAssign(s),c.y.mulAssign(i),e.sample(c).grad(yn(),yn())}),km=on(({envMap:e,mipInt:t,outputDirection:r,theta:s,axis:i,CUBEUV_TEXEL_WIDTH:n,CUBEUV_TEXEL_HEIGHT:a,CUBEUV_MAX_MIP:o})=>{const u=So(s),l=r.mul(u).add(i.cross(r).mul(No(s))).add(i.mul(i.dot(r).mul(u.oneMinus())));return Vm(e,l,t,n,a,o)}),Gm=on(({n:e,latitudinal:t,poleAxis:r,outputDirection:s,weights:i,samples:n,dTheta:a,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c})=>{const h=_n(yu(t,r,Yo(r,s))).toVar();dn(h.equal(_n(0)),()=>{h.assign(_n(s.z,0,s.x.negate()))}),h.assign(_o(h));const p=_n().toVar();return p.addAssign(i.element(0).mul(km({theta:0,axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c}))),up({start:gn(1),end:e},({i:e})=>{dn(e.greaterThanEqual(n),()=>{lp()});const t=pn(a.mul(pn(e))).toVar();p.addAssign(i.element(e).mul(km({theta:t.mul(-1),axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c}))),p.addAssign(i.element(e).mul(km({theta:t,axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c})))}),Rn(p,1)}),zm=on(([e])=>{const t=mn(e).toVar();return t.assign(t.shiftLeft(mn(16)).bitOr(t.shiftRight(mn(16)))),t.assign(t.bitAnd(mn(1431655765)).shiftLeft(mn(1)).bitOr(t.bitAnd(mn(2863311530)).shiftRight(mn(1)))),t.assign(t.bitAnd(mn(858993459)).shiftLeft(mn(2)).bitOr(t.bitAnd(mn(3435973836)).shiftRight(mn(2)))),t.assign(t.bitAnd(mn(252645135)).shiftLeft(mn(4)).bitOr(t.bitAnd(mn(4042322160)).shiftRight(mn(4)))),t.assign(t.bitAnd(mn(16711935)).shiftLeft(mn(8)).bitOr(t.bitAnd(mn(4278255360)).shiftRight(mn(8)))),pn(t).mul(2.3283064365386963e-10)}),$m=on(([e,t])=>yn(pn(e).div(pn(t)),zm(e))),Wm=on(([e,t,r])=>{const s=r.mul(r).toConst(),i=_n(1,0,0).toConst(),n=Yo(t,i).toConst(),a=yo(e.x).toConst(),o=Ba(2,3.14159265359).mul(e.y).toConst(),u=a.mul(So(o)).toConst(),l=a.mul(No(o)).toVar(),d=Ba(.5,t.z.add(1)).toConst();l.assign(d.oneMinus().mul(yo(u.mul(u).oneMinus())).add(d.mul(l)));const c=i.mul(u).add(n.mul(l)).add(t.mul(yo(Wo(0,u.mul(u).add(l.mul(l)).oneMinus()))));return _o(_n(s.mul(c.x),s.mul(c.y),Wo(0,c.z)))}),Hm=on(({roughness:e,mipInt:t,envMap:r,N_immutable:s,GGX_SAMPLES:i,CUBEUV_TEXEL_WIDTH:n,CUBEUV_TEXEL_HEIGHT:a,CUBEUV_MAX_MIP:o})=>{const u=_n(s).toVar(),l=_n(0).toVar(),d=pn(0).toVar();return dn(e.lessThan(.001),()=>{l.assign(Vm(r,u,t,n,a,o))}).Else(()=>{const s=yu(Co(u.z).lessThan(.999),_n(0,0,1),_n(1,0,0)),c=_o(Yo(s,u)).toVar(),h=Yo(u,c).toVar();up({start:mn(0),end:i},({i:s})=>{const p=$m(s,i),g=Wm(p,_n(0,0,1),e),m=_o(c.mul(g.x).add(h.mul(g.y)).add(u.mul(g.z))),f=_o(m.mul(Ko(u,m).mul(2)).sub(u)),y=Wo(Ko(u,f),0);dn(y.greaterThan(0),()=>{const e=Vm(r,f,t,n,a,o);l.addAssign(e.mul(y)),d.addAssign(y)})}),dn(d.greaterThan(0),()=>{l.assign(l.div(d))})}),Rn(l,1)}),qm=[.125,.215,.35,.446,.526,.582],jm=20,Xm=new _e(-1,1,1,-1,0,1),Km=new ve(90,1),Ym=new e;let Qm=null,Zm=0,Jm=0;const ef=new r,tf=new WeakMap,rf=[3,1,5,0,4,2],sf=Im(Sl(),Nl("faceIndex")).normalize(),nf=_n(sf.x,sf.y,sf.z);class af{constructor(e){this._renderer=e,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._sizeLods=[],this._sigmas=[],this._lodMeshes=[],this._blurMaterial=null,this._ggxMaterial=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._backgroundBox=null}get _hasInitialized(){return this._renderer.hasInitialized()}fromScene(e,t=0,r=.1,s=100,i={}){const{size:n=256,position:a=ef,renderTarget:o=null}=i;if(this._setSize(n),!1===this._hasInitialized){d('PMREMGenerator: ".fromScene()" called before the backend is initialized. Try using "await renderer.init()" instead.');const n=o||this._allocateTarget();return i.renderTarget=n,this.fromSceneAsync(e,t,r,s,i),n}Qm=this._renderer.getRenderTarget(),Zm=this._renderer.getActiveCubeFace(),Jm=this._renderer.getActiveMipmapLevel();const u=o||this._allocateTarget();return u.depthBuffer=!0,this._init(u),this._sceneToCubeUV(e,r,s,u,a),t>0&&this._blur(u,0,0,t),this._applyPMREM(u),this._cleanup(u),u}async fromSceneAsync(e,t=0,r=.1,s=100,i={}){return v('PMREMGenerator: ".fromSceneAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this.fromScene(e,t,r,s,i)}fromEquirectangular(e,t=null){if(!1===this._hasInitialized){d('PMREMGenerator: .fromEquirectangular() called before the backend is initialized. Try using "await renderer.init()" instead.'),this._setSizeFromTexture(e);const r=t||this._allocateTarget();return this.fromEquirectangularAsync(e,r),r}return this._fromTexture(e,t)}async fromEquirectangularAsync(e,t=null){return v('PMREMGenerator: ".fromEquirectangularAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this._fromTexture(e,t)}fromCubemap(e,t=null){if(!1===this._hasInitialized){d("PMREMGenerator: .fromCubemap() called before the backend is initialized. Try using .fromCubemapAsync() instead."),this._setSizeFromTexture(e);const r=t||this._allocateTarget();return this.fromCubemapAsync(e,t),r}return this._fromTexture(e,t)}async fromCubemapAsync(e,t=null){return v('PMREMGenerator: ".fromCubemapAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this._fromTexture(e,t)}async compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=df(),await this._compileMaterial(this._cubemapMaterial))}async compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=cf(),await this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose(),null!==this._backgroundBox&&(this._backgroundBox.geometry.dispose(),this._backgroundBox.material.dispose())}_setSizeFromTexture(e){e.mapping===P||e.mapping===D?this._setSize(0===e.image.length?16:e.image[0].width||e.image[0].image.width):this._setSize(e.image.width/4)}_setSize(e){this._lodMax=Math.floor(Math.log2(e)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._ggxMaterial&&this._ggxMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let e=0;ee-4?o=qm[a-e+4-1]:0===a&&(o=0),r.push(o);const u=1/(n-2),l=-u,d=1+u,c=[l,l,d,l,d,d,l,l,d,d,l,d],h=6,p=6,g=3,m=2,f=1,y=new Float32Array(g*p*h),b=new Float32Array(m*p*h),x=new Float32Array(f*p*h);for(let e=0;e2?0:-1,s=[t,r,0,t+2/3,r,0,t+2/3,r+1,0,t,r,0,t+2/3,r+1,0,t,r+1,0],i=rf[e];y.set(s,g*p*i),b.set(c,m*p*i);const n=[i,i,i,i,i,i];x.set(n,f*p*i)}const T=new Te;T.setAttribute("position",new Ee(y,g)),T.setAttribute("uv",new Ee(b,m)),T.setAttribute("faceIndex",new Ee(x,f)),s.push(new ne(T,null)),i>4&&i--}return{lodMeshes:s,sizeLods:t,sigmas:r}}(t)),this._blurMaterial=function(e,t,s){const i=Ol(new Array(jm).fill(0)),n=Ta(new r(0,1,0)),a=Ta(0),o=pn(jm),u=Ta(0),l=Ta(1),d=Fl(),c=Ta(0),h=pn(1/t),p=pn(1/s),g=pn(e),m={n:o,latitudinal:u,weights:i,poleAxis:n,outputDirection:nf,dTheta:a,samples:l,envMap:d,mipInt:c,CUBEUV_TEXEL_WIDTH:h,CUBEUV_TEXEL_HEIGHT:p,CUBEUV_MAX_MIP:g},f=lf("blur");return f.fragmentNode=Gm({...m,latitudinal:u.equal(1)}),tf.set(f,m),f}(t,e.width,e.height),this._ggxMaterial=function(e,t,r){const s=Fl(),i=Ta(0),n=Ta(0),a=pn(1/t),o=pn(1/r),u=pn(e),l={envMap:s,roughness:i,mipInt:n,CUBEUV_TEXEL_WIDTH:a,CUBEUV_TEXEL_HEIGHT:o,CUBEUV_MAX_MIP:u},d=lf("ggx");return d.fragmentNode=Hm({...l,N_immutable:nf,GGX_SAMPLES:mn(512)}),tf.set(d,l),d}(t,e.width,e.height)}}async _compileMaterial(e){const t=new ne(new Te,e);await this._renderer.compile(t,Xm)}_sceneToCubeUV(e,t,r,s,i){const n=Km;n.near=t,n.far=r;const a=[1,1,1,1,-1,1],o=[1,-1,1,-1,1,-1],u=this._renderer,l=u.autoClear;u.getClearColor(Ym),u.autoClear=!1,null===this._backgroundBox&&(this._backgroundBox=new ne(new ie,new ge({name:"PMREM.Background",side:M,depthWrite:!1,depthTest:!1})));const d=this._backgroundBox,c=d.material;let h=!1;const p=e.background;p?p.isColor&&(c.color.copy(p),e.background=null,h=!0):(c.color.copy(Ym),h=!0),u.setRenderTarget(s),u.clear(),h&&u.render(d,n);for(let t=0;t<6;t++){const r=t%3;0===r?(n.up.set(0,a[t],0),n.position.set(i.x,i.y,i.z),n.lookAt(i.x+o[t],i.y,i.z)):1===r?(n.up.set(0,0,a[t]),n.position.set(i.x,i.y,i.z),n.lookAt(i.x,i.y+o[t],i.z)):(n.up.set(0,a[t],0),n.position.set(i.x,i.y,i.z),n.lookAt(i.x,i.y,i.z+o[t]));const l=this._cubeSize;uf(s,r*l,t>2?l:0,l,l),u.render(e,n)}u.autoClear=l,e.background=p}_textureToCubeUV(e,t){const r=this._renderer,s=e.mapping===P||e.mapping===D;s?null===this._cubemapMaterial&&(this._cubemapMaterial=df(e)):null===this._equirectMaterial&&(this._equirectMaterial=cf(e));const i=s?this._cubemapMaterial:this._equirectMaterial;i.fragmentNode.value=e;const n=this._lodMeshes[0];n.material=i;const a=this._cubeSize;uf(t,0,0,3*a,2*a),r.setRenderTarget(t),r.render(n,Xm)}_applyPMREM(e){const t=this._renderer,r=t.autoClear;t.autoClear=!1;const s=this._lodMeshes.length;for(let t=1;tc-4?r-c+4:0),g=4*(this._cubeSize-h);e.texture.frame=(e.texture.frame||0)+1,o.envMap.value=e.texture,o.roughness.value=d,o.mipInt.value=c-t,uf(i,p,g,3*h,2*h),s.setRenderTarget(i),s.render(a,Xm),i.texture.frame=(i.texture.frame||0)+1,o.envMap.value=i.texture,o.roughness.value=0,o.mipInt.value=c-r,uf(e,p,g,3*h,2*h),s.setRenderTarget(e),s.render(a,Xm)}_blur(e,t,r,s,i){const n=this._pingPongRenderTarget;this._halfBlur(e,n,t,r,s,"latitudinal",i),this._halfBlur(n,e,r,r,s,"longitudinal",i)}_halfBlur(e,t,r,s,i,n,a){const u=this._renderer,l=this._blurMaterial;"latitudinal"!==n&&"longitudinal"!==n&&o("blur direction must be either latitudinal or longitudinal!");const c=this._lodMeshes[s];c.material=l;const h=tf.get(l),p=this._sizeLods[r]-1,g=isFinite(i)?Math.PI/(2*p):2*Math.PI/39,m=i/g,f=isFinite(i)?1+Math.floor(3*m):jm;f>jm&&d(`sigmaRadians, ${i}, is too large and will clip, as it requested ${f} samples when the maximum is set to 20`);const y=[];let b=0;for(let e=0;ex-4?s-x+4:0),4*(this._cubeSize-T),3*T,2*T),u.setRenderTarget(t),u.render(c,Xm)}}function of(e,t){const r=new se(e,t,{magFilter:oe,minFilter:oe,generateMipmaps:!1,type:be,format:Se,colorSpace:Ne});return r.texture.mapping=Re,r.texture.name="PMREM.cubeUv",r.texture.isPMREMTexture=!0,r.scissorTest=!0,r}function uf(e,t,r,s,i){e.viewport.set(t,r,s,i),e.scissor.set(t,r,s,i)}function lf(e){const t=new Qp;return t.depthTest=!1,t.depthWrite=!1,t.blending=ee,t.name=`PMREM_${e}`,t}function df(e){const t=lf("cubemap");return t.fragmentNode=pc(e,nf),t}function cf(e){const t=lf("equirect");return t.fragmentNode=Fl(e,ag(nf),0),t}const hf=new WeakMap;function pf(e,t,r){const s=function(e){let t=hf.get(e);void 0===t&&(t=new WeakMap,hf.set(e,t));return t}(t);let i=s.get(e);if((void 0!==i?i.pmremVersion:-1)!==e.pmremVersion){const t=e.image;if(e.isCubeTexture){if(!function(e){if(null==e)return!1;let t=0;const r=6;for(let s=0;s0}(t))return null;i=r.fromEquirectangular(e,i)}i.pmremVersion=e.pmremVersion,s.set(e,i)}return i.texture}class gf extends di{static get type(){return"PMREMNode"}constructor(e,t=null,r=null){super("vec3"),this._value=e,this._pmrem=null,this.uvNode=t,this.levelNode=r,this._generator=null;const s=new N;s.isRenderTargetTexture=!0,this._texture=Fl(s),this._width=Ta(0),this._height=Ta(0),this._maxMip=Ta(0),this.updateBeforeType=Zs.RENDER}set value(e){this._value=e,this._pmrem=null}get value(){return this._value}updateFromTexture(e){const t=function(e){const t=Math.log2(e)-2,r=1/e;return{texelWidth:1/(3*Math.max(Math.pow(2,t),112)),texelHeight:r,maxMip:t}}(e.image.height);this._texture.value=e,this._width.value=t.texelWidth,this._height.value=t.texelHeight,this._maxMip.value=t.maxMip}updateBefore(e){let t=this._pmrem;const r=t?t.pmremVersion:-1,s=this._value;r!==s.pmremVersion&&(t=!0===s.isPMREMTexture?s:pf(s,e.renderer,this._generator),null!==t&&(this._pmrem=t,this.updateFromTexture(t)))}setup(e){null===this._generator&&(this._generator=new af(e.renderer)),this.updateBefore(e);let t=this.uvNode;null===t&&e.context.getUV&&(t=e.context.getUV(this,e)),t=nc.mul(_n(t.x,t.y.negate(),t.z));let r=this.levelNode;return null===r&&e.context.getTextureLevel&&(r=e.context.getTextureLevel(this)),Om(this._texture,t,r,this._width,this._height,this._maxMip)}dispose(){super.dispose(),null!==this._generator&&this._generator.dispose()}}const mf=tn(gf).setParameterLength(1,3),ff=new WeakMap;class yf extends mp{static get type(){return"EnvironmentNode"}constructor(e=null){super(),this.envNode=e}setup(e){const{material:t}=e;let r=this.envNode;if(r.isTextureNode||r.isMaterialReferenceNode){const e=r.isTextureNode?r.value:t[r.property];let s=ff.get(e);void 0===s&&(s=mf(e),ff.set(e,s)),r=s}const s=!0===t.useAnisotropy||t.anisotropy>0?Hc:jd,i=r.context(bf(kn,s)).mul(ic),n=r.context(xf(Xd)).mul(Math.PI).mul(ic),a=nl(i),o=nl(n);e.context.radiance.addAssign(a),e.context.iblIrradiance.addAssign(o);const u=e.context.lightingModel.clearcoatRadiance;if(u){const e=r.context(bf($n,Kd)).mul(ic),t=nl(e);u.addAssign(t)}}}const bf=(e,t)=>{let r=null;return{getUV:()=>(null===r&&(r=Id.negate().reflect(t),r=eu(e).mix(r,t).normalize(),r=r.transformDirection(id)),r),getTextureLevel:()=>e}},xf=e=>({getUV:()=>e,getTextureLevel:()=>pn(1)}),Tf=new Ae;class _f extends Qp{static get type(){return"MeshStandardNodeMaterial"}constructor(e){super(),this.isMeshStandardNodeMaterial=!0,this.lights=!0,this.emissiveNode=null,this.metalnessNode=null,this.roughnessNode=null,this.setDefaultValues(Tf),this.setValues(e)}setupEnvironment(e){let t=super.setupEnvironment(e);return null===t&&e.environmentNode&&(t=e.environmentNode),t?new yf(t):null}setupLightingModel(){return new _m}setupSpecular(){const e=iu(_n(.04),In.rgb,Gn);Jn.assign(_n(.04)),ea.assign(e),ta.assign(1)}setupVariants(){const e=this.metalnessNode?pn(this.metalnessNode):ph;Gn.assign(e);let t=this.roughnessNode?pn(this.roughnessNode):hh;t=Cg({roughness:t}),kn.assign(t),this.setupSpecular(),On.assign(In.rgb.mul(e.oneMinus()))}copy(e){return this.emissiveNode=e.emissiveNode,this.metalnessNode=e.metalnessNode,this.roughnessNode=e.roughnessNode,super.copy(e)}}const vf=new we;class Nf extends _f{static get type(){return"MeshPhysicalNodeMaterial"}constructor(e){super(),this.isMeshPhysicalNodeMaterial=!0,this.clearcoatNode=null,this.clearcoatRoughnessNode=null,this.clearcoatNormalNode=null,this.sheenNode=null,this.sheenRoughnessNode=null,this.iridescenceNode=null,this.iridescenceIORNode=null,this.iridescenceThicknessNode=null,this.specularIntensityNode=null,this.specularColorNode=null,this.iorNode=null,this.transmissionNode=null,this.thicknessNode=null,this.attenuationDistanceNode=null,this.attenuationColorNode=null,this.dispersionNode=null,this.anisotropyNode=null,this.setDefaultValues(vf),this.setValues(e)}get useClearcoat(){return this.clearcoat>0||null!==this.clearcoatNode}get useIridescence(){return this.iridescence>0||null!==this.iridescenceNode}get useSheen(){return this.sheen>0||null!==this.sheenNode}get useAnisotropy(){return this.anisotropy>0||null!==this.anisotropyNode}get useTransmission(){return this.transmission>0||null!==this.transmissionNode}get useDispersion(){return this.dispersion>0||null!==this.dispersionNode}setupSpecular(){const e=this.iorNode?pn(this.iorNode):Ah;oa.assign(e),Jn.assign($o(Zo(oa.sub(1).div(oa.add(1))).mul(lh),_n(1)).mul(uh)),ea.assign(iu(Jn,In.rgb,Gn)),ta.assign(iu(uh,1,Gn))}setupLightingModel(){return new _m(this.useClearcoat,this.useSheen,this.useIridescence,this.useAnisotropy,this.useTransmission,this.useDispersion)}setupVariants(e){if(super.setupVariants(e),this.useClearcoat){const e=this.clearcoatNode?pn(this.clearcoatNode):mh,t=this.clearcoatRoughnessNode?pn(this.clearcoatRoughnessNode):fh;zn.assign(e),$n.assign(Cg({roughness:t}))}if(this.useSheen){const e=this.sheenNode?_n(this.sheenNode):xh,t=this.sheenRoughnessNode?pn(this.sheenRoughnessNode):Th;Wn.assign(e),Hn.assign(t)}if(this.useIridescence){const e=this.iridescenceNode?pn(this.iridescenceNode):vh,t=this.iridescenceIORNode?pn(this.iridescenceIORNode):Nh,r=this.iridescenceThicknessNode?pn(this.iridescenceThicknessNode):Sh;qn.assign(e),jn.assign(t),Xn.assign(r)}if(this.useAnisotropy){const e=(this.anisotropyNode?yn(this.anisotropyNode):_h).toVar();Yn.assign(e.length()),dn(Yn.equal(0),()=>{e.assign(yn(1,0))}).Else(()=>{e.divAssign(yn(Yn)),Yn.assign(Yn.saturate())}),Kn.assign(Yn.pow2().mix(kn.pow2(),1)),Qn.assign($c[0].mul(e.x).add($c[1].mul(e.y))),Zn.assign($c[1].mul(e.x).sub($c[0].mul(e.y)))}if(this.useTransmission){const e=this.transmissionNode?pn(this.transmissionNode):Rh,t=this.thicknessNode?pn(this.thicknessNode):Eh,r=this.attenuationDistanceNode?pn(this.attenuationDistanceNode):wh,s=this.attenuationColorNode?_n(this.attenuationColorNode):Ch;if(ua.assign(e),la.assign(t),da.assign(r),ca.assign(s),this.useDispersion){const e=this.dispersionNode?pn(this.dispersionNode):Uh;ha.assign(e)}}}setupClearcoatNormal(){return this.clearcoatNormalNode?_n(this.clearcoatNormalNode):yh}setup(e){e.context.setupClearcoatNormal=()=>Bu(this.setupClearcoatNormal(e),"NORMAL","vec3"),super.setup(e)}copy(e){return this.clearcoatNode=e.clearcoatNode,this.clearcoatRoughnessNode=e.clearcoatRoughnessNode,this.clearcoatNormalNode=e.clearcoatNormalNode,this.sheenNode=e.sheenNode,this.sheenRoughnessNode=e.sheenRoughnessNode,this.iridescenceNode=e.iridescenceNode,this.iridescenceIORNode=e.iridescenceIORNode,this.iridescenceThicknessNode=e.iridescenceThicknessNode,this.specularIntensityNode=e.specularIntensityNode,this.specularColorNode=e.specularColorNode,this.iorNode=e.iorNode,this.transmissionNode=e.transmissionNode,this.thicknessNode=e.thicknessNode,this.attenuationDistanceNode=e.attenuationDistanceNode,this.attenuationColorNode=e.attenuationColorNode,this.dispersionNode=e.dispersionNode,this.anisotropyNode=e.anisotropyNode,super.copy(e)}}class Sf extends _m{constructor(e=!1,t=!1,r=!1,s=!1,i=!1,n=!1,a=!1){super(e,t,r,s,i,n),this.useSSS=a}direct({lightDirection:e,lightColor:t,reflectedLight:r},s){if(!0===this.useSSS){const i=s.material,{thicknessColorNode:n,thicknessDistortionNode:a,thicknessAmbientNode:o,thicknessAttenuationNode:u,thicknessPowerNode:l,thicknessScaleNode:d}=i,c=e.add(jd.mul(a)).normalize(),h=pn(Id.dot(c.negate()).saturate().pow(l).mul(d)),p=_n(h.add(o).mul(n));r.directDiffuse.addAssign(p.mul(u.mul(t)))}super.direct({lightDirection:e,lightColor:t,reflectedLight:r},s)}}class Rf extends Nf{static get type(){return"MeshSSSNodeMaterial"}constructor(e){super(e),this.thicknessColorNode=null,this.thicknessDistortionNode=pn(.1),this.thicknessAmbientNode=pn(0),this.thicknessAttenuationNode=pn(.1),this.thicknessPowerNode=pn(2),this.thicknessScaleNode=pn(10)}get useSSS(){return null!==this.thicknessColorNode}setupLightingModel(){return new Sf(this.useClearcoat,this.useSheen,this.useIridescence,this.useAnisotropy,this.useTransmission,this.useDispersion,this.useSSS)}copy(e){return this.thicknessColorNode=e.thicknessColorNode,this.thicknessDistortionNode=e.thicknessDistortionNode,this.thicknessAmbientNode=e.thicknessAmbientNode,this.thicknessAttenuationNode=e.thicknessAttenuationNode,this.thicknessPowerNode=e.thicknessPowerNode,this.thicknessScaleNode=e.thicknessScaleNode,super.copy(e)}}const Ef=on(({normal:e,lightDirection:t,builder:r})=>{const s=e.dot(t),i=yn(s.mul(.5).add(.5),0);if(r.material.gradientMap){const e=xc("gradientMap","texture").context({getUV:()=>i});return _n(e.r)}{const e=i.fwidth().mul(.5);return iu(_n(.7),_n(1),uu(pn(.7).sub(e.x),pn(.7).add(e.x),i.x))}});class Af extends mg{direct({lightDirection:e,lightColor:t,reflectedLight:r},s){const i=Ef({normal:zd,lightDirection:e,builder:s}).mul(t);r.directDiffuse.addAssign(i.mul(Tg({diffuseColor:In.rgb})))}indirect(e){const{ambientOcclusion:t,irradiance:r,reflectedLight:s}=e.context;s.indirectDiffuse.addAssign(r.mul(Tg({diffuseColor:In}))),s.indirectDiffuse.mulAssign(t)}}const wf=new Ce;class Cf extends Qp{static get type(){return"MeshToonNodeMaterial"}constructor(e){super(),this.isMeshToonNodeMaterial=!0,this.lights=!0,this.setDefaultValues(wf),this.setValues(e)}setupLightingModel(){return new Af}}const Mf=on(()=>{const e=_n(Id.z,0,Id.x.negate()).normalize(),t=Id.cross(e);return yn(e.dot(jd),t.dot(jd)).mul(.495).add(.5)}).once(["NORMAL","VERTEX"])().toVar("matcapUV"),Bf=new Me;class Ff extends Qp{static get type(){return"MeshMatcapNodeMaterial"}constructor(e){super(),this.isMeshMatcapNodeMaterial=!0,this.setDefaultValues(Bf),this.setValues(e)}setupVariants(e){const t=Mf;let r;r=e.material.matcap?xc("matcap","texture").context({getUV:()=>t}):_n(iu(.2,.8,t.y)),In.rgb.mulAssign(r.rgb)}}class Lf extends di{static get type(){return"RotateNode"}constructor(e,t){super(),this.positionNode=e,this.rotationNode=t}getNodeType(e){return this.positionNode.getNodeType(e)}setup(e){const{rotationNode:t,positionNode:r}=this;if("vec2"===this.getNodeType(e)){const e=t.cos(),s=t.sin();return Cn(e,s,s.negate(),e).mul(r)}{const e=t,s=Bn(Rn(1,0,0,0),Rn(0,So(e.x),No(e.x).negate(),0),Rn(0,No(e.x),So(e.x),0),Rn(0,0,0,1)),i=Bn(Rn(So(e.y),0,No(e.y),0),Rn(0,1,0,0),Rn(No(e.y).negate(),0,So(e.y),0),Rn(0,0,0,1)),n=Bn(Rn(So(e.z),No(e.z).negate(),0,0),Rn(No(e.z),So(e.z),0,0),Rn(0,0,1,0),Rn(0,0,0,1));return s.mul(i).mul(n).mul(Rn(r,1)).xyz}}}const Pf=tn(Lf).setParameterLength(2),Df=new Be;class Uf extends Qp{static get type(){return"SpriteNodeMaterial"}constructor(e){super(),this.isSpriteNodeMaterial=!0,this._useSizeAttenuation=!0,this.positionNode=null,this.rotationNode=null,this.scaleNode=null,this.transparent=!0,this.setDefaultValues(Df),this.setValues(e)}setupPositionView(e){const{object:t,camera:r}=e,{positionNode:s,rotationNode:i,scaleNode:n,sizeAttenuation:a}=this,o=Ed.mul(_n(s||0));let u=yn(xd[0].xyz.length(),xd[1].xyz.length());null!==n&&(u=u.mul(yn(n))),r.isPerspectiveCamera&&!1===a&&(u=u.mul(o.z.negate()));let l=Bd.xy;if(t.center&&!0===t.center.isVector2){const e=((e,t,r)=>new zu(e,t,r))("center","vec2",t);l=l.sub(e.sub(.5))}l=l.mul(u);const d=pn(i||bh),c=Pf(l,d);return Rn(o.xy.add(c),o.zw)}copy(e){return this.positionNode=e.positionNode,this.rotationNode=e.rotationNode,this.scaleNode=e.scaleNode,super.copy(e)}get sizeAttenuation(){return this._useSizeAttenuation}set sizeAttenuation(e){this._useSizeAttenuation!==e&&(this._useSizeAttenuation=e,this.needsUpdate=!0)}}const If=new Fe,Of=new t;class Vf extends Uf{static get type(){return"PointsNodeMaterial"}constructor(e){super(),this.sizeNode=null,this.isPointsNodeMaterial=!0,this.setDefaultValues(If),this.setValues(e)}setupPositionView(){const{positionNode:e}=this;return Ed.mul(_n(e||Fd)).xyz}setupVertexSprite(e){const{material:t,camera:r}=e,{rotationNode:s,scaleNode:i,sizeNode:n,sizeAttenuation:a}=this;let o=super.setupVertex(e);if(!0!==t.isNodeMaterial)return o;let u=null!==n?yn(n):Dh;u=u.mul(Wl),r.isPerspectiveCamera&&!0===a&&(u=u.mul(kf.div(Ud.z.negate()))),i&&i.isNode&&(u=u.mul(yn(i)));let l=Bd.xy;if(s&&s.isNode){const e=pn(s);l=Pf(l,e)}return l=l.mul(u),l=l.div(Kl.div(2)),l=l.mul(o.w),o=o.add(Rn(l,0,0)),o}setupVertex(e){return e.object.isPoints?super.setupVertex(e):this.setupVertexSprite(e)}get alphaToCoverage(){return this._useAlphaToCoverage}set alphaToCoverage(e){this._useAlphaToCoverage!==e&&(this._useAlphaToCoverage=e,this.needsUpdate=!0)}}const kf=Ta(1).onFrameUpdate(function({renderer:e}){const t=e.getSize(Of);this.value=.5*t.y});class Gf extends mg{constructor(){super(),this.shadowNode=pn(1).toVar("shadowMask")}direct({lightNode:e}){null!==e.shadowNode&&this.shadowNode.mulAssign(e.shadowNode)}finish({context:e}){In.a.mulAssign(this.shadowNode.oneMinus()),e.outgoingLight.rgb.assign(In.rgb)}}const zf=new Le;class $f extends Qp{static get type(){return"ShadowNodeMaterial"}constructor(e){super(),this.isShadowNodeMaterial=!0,this.lights=!0,this.transparent=!0,this.setDefaultValues(zf),this.setValues(e)}setupLightingModel(){return new Gf}}const Wf=Dn("vec3"),Hf=Dn("vec3"),qf=Dn("vec3");class jf extends mg{constructor(){super()}start(e){const{material:t}=e,r=Dn("vec3"),s=Dn("vec3");dn(od.sub(Pd).length().greaterThan(Nd.mul(2)),()=>{r.assign(od),s.assign(Pd)}).Else(()=>{r.assign(Pd),s.assign(od)});const i=s.sub(r),n=Ta("int").onRenderUpdate(({material:e})=>e.steps),a=i.length().div(n).toVar(),o=i.normalize().toVar(),u=pn(0).toVar(),l=_n(1).toVar();t.offsetNode&&u.addAssign(t.offsetNode.mul(a)),up(n,()=>{const s=r.add(o.mul(u)),i=id.mul(Rn(s,1)).xyz;let n;null!==t.depthNode&&(Hf.assign(Up(Bp(i.z,ed,td))),e.context.sceneDepthNode=Up(t.depthNode).toVar()),e.context.positionWorld=s,e.context.shadowPositionWorld=s,e.context.positionView=i,Wf.assign(0),t.scatteringNode&&(n=t.scatteringNode({positionRay:s})),super.start(e),n&&Wf.mulAssign(n);const d=Wf.mul(.01).negate().mul(a).exp();l.mulAssign(d),u.addAssign(a)}),qf.addAssign(l.saturate().oneMinus())}scatteringLight(e,t){const r=t.context.sceneDepthNode;r?dn(r.greaterThanEqual(Hf),()=>{Wf.addAssign(e)}):Wf.addAssign(e)}direct({lightNode:e,lightColor:t},r){if(void 0===e.light.distance)return;const s=t.xyz.toVar();s.mulAssign(e.shadowNode),this.scatteringLight(s,r)}directRectArea({lightColor:e,lightPosition:t,halfWidth:r,halfHeight:s},i){const n=t.add(r).sub(s),a=t.sub(r).sub(s),o=t.sub(r).add(s),u=t.add(r).add(s),l=i.context.positionView,d=e.xyz.mul(Kg({P:l,p0:n,p1:a,p2:o,p3:u})).pow(1.5);this.scatteringLight(d,i)}finish(e){e.context.outgoingLight.assign(qf)}}class Xf extends Qp{static get type(){return"VolumeNodeMaterial"}constructor(e){super(),this.isVolumeNodeMaterial=!0,this.steps=25,this.offsetNode=null,this.scatteringNode=null,this.lights=!0,this.transparent=!0,this.side=M,this.depthTest=!1,this.depthWrite=!1,this.setValues(e)}setupLightingModel(){return new jf}}class Kf{constructor(e,t,r){this.renderer=e,this.nodes=t,this.info=r,this._context="undefined"!=typeof self?self:null,this._animationLoop=null,this._requestId=null}start(){const e=(t,r)=>{this._requestId=this._context.requestAnimationFrame(e),!0===this.info.autoReset&&this.info.reset(),this.nodes.nodeFrame.update(),this.info.frame=this.nodes.nodeFrame.frameId,this.renderer._inspector.begin(),null!==this._animationLoop&&this._animationLoop(t,r),this.renderer._inspector.finish()};e()}stop(){this._context.cancelAnimationFrame(this._requestId),this._requestId=null}getAnimationLoop(){return this._animationLoop}setAnimationLoop(e){this._animationLoop=e}getContext(){return this._context}setContext(e){this._context=e}dispose(){this.stop()}}class Yf{constructor(){this.weakMaps={}}_getWeakMap(e){const t=e.length;let r=this.weakMaps[t];return void 0===r&&(r=new WeakMap,this.weakMaps[t]=r),r}get(e){let t=this._getWeakMap(e);for(let r=0;r{this.dispose()},this.onGeometryDispose=()=>{this.attributes=null,this.attributesId=null},this.material.addEventListener("dispose",this.onMaterialDispose),this.geometry.addEventListener("dispose",this.onGeometryDispose)}updateClipping(e){this.clippingContext=e}get clippingNeedsUpdate(){return null!==this.clippingContext&&this.clippingContext.cacheKey!==this.clippingContextCacheKey&&(this.clippingContextCacheKey=this.clippingContext.cacheKey,!0)}get hardwareClippingPlanes(){return!0===this.material.hardwareClipping?this.clippingContext.unionClippingCount:0}getNodeBuilderState(){return this._nodeBuilderState||(this._nodeBuilderState=this._nodes.getForRender(this))}getMonitor(){return this._monitor||(this._monitor=this.getNodeBuilderState().observer)}getBindings(){return this._bindings||(this._bindings=this.getNodeBuilderState().createBindings())}getBindingGroup(e){for(const t of this.getBindings())if(t.name===e)return t}getIndex(){return this._geometries.getIndex(this)}getIndirect(){return this._geometries.getIndirect(this)}getIndirectOffset(){return this._geometries.getIndirectOffset(this)}getChainArray(){return[this.object,this.material,this.context,this.lightsNode]}setGeometry(e){this.geometry=e,this.attributes=null,this.attributesId=null}getAttributes(){if(null!==this.attributes)return this.attributes;const e=this.getNodeBuilderState().nodeAttributes,t=this.geometry,r=[],s=new Set,i={};for(const n of e){let e;if(n.node&&n.node.attribute?e=n.node.attribute:(e=t.getAttribute(n.name),i[n.name]=e.id),void 0===e)continue;r.push(e);const a=e.isInterleavedBufferAttribute?e.data:e;s.add(a)}return this.attributes=r,this.attributesId=i,this.vertexBuffers=Array.from(s.values()),r}getVertexBuffers(){return null===this.vertexBuffers&&this.getAttributes(),this.vertexBuffers}getDrawParameters(){const{object:e,material:t,geometry:r,group:s,drawRange:i}=this,n=this.drawParams||(this.drawParams={vertexCount:0,firstVertex:0,instanceCount:0,firstInstance:0}),a=this.getIndex(),o=null!==a;let u=1;if(!0===r.isInstancedBufferGeometry?u=r.instanceCount:void 0!==e.count&&(u=Math.max(0,e.count)),0===u)return null;if(n.instanceCount=u,!0===e.isBatchedMesh)return n;let l=1;!0!==t.wireframe||e.isPoints||e.isLineSegments||e.isLine||e.isLineLoop||(l=2);let d=i.start*l,c=(i.start+i.count)*l;null!==s&&(d=Math.max(d,s.start*l),c=Math.min(c,(s.start+s.count)*l));const h=r.attributes.position;let p=1/0;o?p=a.count:null!=h&&(p=h.count),d=Math.max(d,0),c=Math.min(c,p);const g=c-d;return g<0||g===1/0?null:(n.vertexCount=g,n.firstVertex=d,n)}getGeometryCacheKey(){const{geometry:e}=this;let t="";for(const r of Object.keys(e.attributes).sort()){const s=e.attributes[r];t+=r+",",s.data&&(t+=s.data.stride+","),s.offset&&(t+=s.offset+","),s.itemSize&&(t+=s.itemSize+","),s.normalized&&(t+="n,")}for(const r of Object.keys(e.morphAttributes).sort()){const s=e.morphAttributes[r];t+="morph-"+r+",";for(let e=0,r=s.length;e1||Array.isArray(e.morphTargetInfluences))&&(s+=e.uuid+","),s+=this.context.id+",",s+=e.receiveShadow+",",Ds(s)}get needsGeometryUpdate(){if(this.geometry.id!==this.object.geometry.id)return!0;if(null!==this.attributes){const e=this.attributesId;for(const t in e){const r=this.geometry.getAttribute(t);if(void 0===r||e[t]!==r.id)return!0}}return!1}get needsUpdate(){return this.initialNodesCacheKey!==this.getDynamicCacheKey()||this.clippingNeedsUpdate}getDynamicCacheKey(){let e=0;return!0!==this.material.isShadowPassMaterial&&(e=this._nodes.getCacheKey(this.scene,this.lightsNode)),this.camera.isArrayCamera&&(e=Is(e,this.camera.cameras.length)),this.object.receiveShadow&&(e=Is(e,1)),e=Is(e,this.renderer.contextNode.id,this.renderer.contextNode.version),e}getCacheKey(){return this.getMaterialCacheKey()+this.getDynamicCacheKey()}dispose(){this.material.removeEventListener("dispose",this.onMaterialDispose),this.geometry.removeEventListener("dispose",this.onGeometryDispose),this.onDispose()}}const Jf=[];class ey{constructor(e,t,r,s,i,n){this.renderer=e,this.nodes=t,this.geometries=r,this.pipelines=s,this.bindings=i,this.info=n,this.chainMaps={}}get(e,t,r,s,i,n,a,o){const u=this.getChainMap(o);Jf[0]=e,Jf[1]=t,Jf[2]=n,Jf[3]=i;let l=u.get(Jf);return void 0===l?(l=this.createRenderObject(this.nodes,this.geometries,this.renderer,e,t,r,s,i,n,a,o),u.set(Jf,l)):(l.camera=s,l.updateClipping(a),l.needsGeometryUpdate&&l.setGeometry(e.geometry),(l.version!==t.version||l.needsUpdate)&&(l.initialCacheKey!==l.getCacheKey()?(l.dispose(),l=this.get(e,t,r,s,i,n,a,o)):l.version=t.version)),Jf[0]=null,Jf[1]=null,Jf[2]=null,Jf[3]=null,l}getChainMap(e="default"){return this.chainMaps[e]||(this.chainMaps[e]=new Yf)}dispose(){this.chainMaps={}}createRenderObject(e,t,r,s,i,n,a,o,u,l,d){const c=this.getChainMap(d),h=new Zf(e,t,r,s,i,n,a,o,u,l);return h.onDispose=()=>{this.pipelines.delete(h),this.bindings.deleteForRender(h),this.nodes.delete(h),c.delete(h.getChainArray())},h}}class ty{constructor(){this.data=new WeakMap}get(e){let t=this.data.get(e);return void 0===t&&(t={},this.data.set(e,t)),t}delete(e){let t=null;return this.data.has(e)&&(t=this.data.get(e),this.data.delete(e)),t}has(e){return this.data.has(e)}dispose(){this.data=new WeakMap}}const ry=1,sy=2,iy=3,ny=4,ay=16;class oy extends ty{constructor(e){super(),this.backend=e}delete(e){const t=super.delete(e);return null!==t&&this.backend.destroyAttribute(e),t}update(e,t){const r=this.get(e);if(void 0===r.version)t===ry?this.backend.createAttribute(e):t===sy?this.backend.createIndexAttribute(e):t===iy?this.backend.createStorageAttribute(e):t===ny&&this.backend.createIndirectStorageAttribute(e),r.version=this._getBufferAttribute(e).version;else{const t=this._getBufferAttribute(e);(r.version{this.info.memory.geometries--;const s=t.index,i=e.getAttributes();null!==s&&this.attributes.delete(s);for(const e of i)this.attributes.delete(e);const n=this.wireframes.get(t);void 0!==n&&this.attributes.delete(n),t.removeEventListener("dispose",r),this._geometryDisposeListeners.delete(t)};t.addEventListener("dispose",r),this._geometryDisposeListeners.set(t,r)}updateAttributes(e){const t=e.getAttributes();for(const e of t)e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute?this.updateAttribute(e,iy):this.updateAttribute(e,ry);const r=this.getIndex(e);null!==r&&this.updateAttribute(r,sy);const s=e.geometry.indirect;null!==s&&this.updateAttribute(s,ny)}updateAttribute(e,t){const r=this.info.render.calls;e.isInterleavedBufferAttribute?void 0===this.attributeCall.get(e)?(this.attributes.update(e,t),this.attributeCall.set(e,r)):this.attributeCall.get(e.data)!==r&&(this.attributes.update(e,t),this.attributeCall.set(e.data,r),this.attributeCall.set(e,r)):this.attributeCall.get(e)!==r&&(this.attributes.update(e,t),this.attributeCall.set(e,r))}getIndirect(e){return e.geometry.indirect}getIndirectOffset(e){return e.geometry.indirectOffset}getIndex(e){const{geometry:t,material:r}=e;let s=t.index;if(!0===r.wireframe){const e=this.wireframes;let r=e.get(t);void 0===r?(r=dy(t),e.set(t,r)):r.version===uy(t)&&r.__id===ly(t)||(this.attributes.delete(r),r=dy(t),e.set(t,r)),s=r}return s}dispose(){for(const[e,t]of this._geometryDisposeListeners.entries())e.removeEventListener("dispose",t);this._geometryDisposeListeners.clear()}}class hy{constructor(){this.autoReset=!0,this.frame=0,this.calls=0,this.render={calls:0,frameCalls:0,drawCalls:0,triangles:0,points:0,lines:0,timestamp:0},this.compute={calls:0,frameCalls:0,timestamp:0},this.memory={geometries:0,textures:0}}update(e,t,r){this.render.drawCalls++,e.isMesh||e.isSprite?this.render.triangles+=r*(t/3):e.isPoints?this.render.points+=r*t:e.isLineSegments?this.render.lines+=r*(t/2):e.isLine?this.render.lines+=r*(t-1):o("WebGPUInfo: Unknown object type.")}reset(){this.render.drawCalls=0,this.render.frameCalls=0,this.compute.frameCalls=0,this.render.triangles=0,this.render.points=0,this.render.lines=0}dispose(){this.reset(),this.calls=0,this.render.calls=0,this.compute.calls=0,this.render.timestamp=0,this.compute.timestamp=0,this.memory.geometries=0,this.memory.textures=0}}class py{constructor(e){this.cacheKey=e,this.usedTimes=0}}class gy extends py{constructor(e,t,r){super(e),this.vertexProgram=t,this.fragmentProgram=r}}class my extends py{constructor(e,t){super(e),this.computeProgram=t,this.isComputePipeline=!0}}let fy=0;class yy{constructor(e,t,r,s=null,i=null){this.id=fy++,this.code=e,this.stage=t,this.name=r,this.transforms=s,this.attributes=i,this.usedTimes=0}}class by extends ty{constructor(e,t){super(),this.backend=e,this.nodes=t,this.bindings=null,this.caches=new Map,this.programs={vertex:new Map,fragment:new Map,compute:new Map}}getForCompute(e,t){const{backend:r}=this,s=this.get(e);if(this._needsComputeUpdate(e)){const i=s.pipeline;i&&(i.usedTimes--,i.computeProgram.usedTimes--);const n=this.nodes.getForCompute(e);let a=this.programs.compute.get(n.computeShader);void 0===a&&(i&&0===i.computeProgram.usedTimes&&this._releaseProgram(i.computeProgram),a=new yy(n.computeShader,"compute",e.name,n.transforms,n.nodeAttributes),this.programs.compute.set(n.computeShader,a),r.createProgram(a));const o=this._getComputeCacheKey(e,a);let u=this.caches.get(o);void 0===u&&(i&&0===i.usedTimes&&this._releasePipeline(i),u=this._getComputePipeline(e,a,o,t)),u.usedTimes++,a.usedTimes++,s.version=e.version,s.pipeline=u}return s.pipeline}getForRender(e,t=null){const{backend:r}=this,s=this.get(e);if(this._needsRenderUpdate(e)){const i=s.pipeline;i&&(i.usedTimes--,i.vertexProgram.usedTimes--,i.fragmentProgram.usedTimes--);const n=e.getNodeBuilderState(),a=e.material?e.material.name:"";let o=this.programs.vertex.get(n.vertexShader);void 0===o&&(i&&0===i.vertexProgram.usedTimes&&this._releaseProgram(i.vertexProgram),o=new yy(n.vertexShader,"vertex",a),this.programs.vertex.set(n.vertexShader,o),r.createProgram(o));let u=this.programs.fragment.get(n.fragmentShader);void 0===u&&(i&&0===i.fragmentProgram.usedTimes&&this._releaseProgram(i.fragmentProgram),u=new yy(n.fragmentShader,"fragment",a),this.programs.fragment.set(n.fragmentShader,u),r.createProgram(u));const l=this._getRenderCacheKey(e,o,u);let d=this.caches.get(l);void 0===d?(i&&0===i.usedTimes&&this._releasePipeline(i),d=this._getRenderPipeline(e,o,u,l,t)):e.pipeline=d,d.usedTimes++,o.usedTimes++,u.usedTimes++,s.pipeline=d}return s.pipeline}delete(e){const t=this.get(e).pipeline;return t&&(t.usedTimes--,0===t.usedTimes&&this._releasePipeline(t),t.isComputePipeline?(t.computeProgram.usedTimes--,0===t.computeProgram.usedTimes&&this._releaseProgram(t.computeProgram)):(t.fragmentProgram.usedTimes--,t.vertexProgram.usedTimes--,0===t.vertexProgram.usedTimes&&this._releaseProgram(t.vertexProgram),0===t.fragmentProgram.usedTimes&&this._releaseProgram(t.fragmentProgram))),super.delete(e)}dispose(){super.dispose(),this.caches=new Map,this.programs={vertex:new Map,fragment:new Map,compute:new Map}}updateForRender(e){this.getForRender(e)}_getComputePipeline(e,t,r,s){r=r||this._getComputeCacheKey(e,t);let i=this.caches.get(r);return void 0===i&&(i=new my(r,t),this.caches.set(r,i),this.backend.createComputePipeline(i,s)),i}_getRenderPipeline(e,t,r,s,i){s=s||this._getRenderCacheKey(e,t,r);let n=this.caches.get(s);return void 0===n&&(n=new gy(s,t,r),this.caches.set(s,n),e.pipeline=n,this.backend.createRenderPipeline(e,i)),n}_getComputeCacheKey(e,t){return e.id+","+t.id}_getRenderCacheKey(e,t,r){return t.id+","+r.id+","+this.backend.getRenderCacheKey(e)}_releasePipeline(e){this.caches.delete(e.cacheKey)}_releaseProgram(e){const t=e.code,r=e.stage;this.programs[r].delete(t)}_needsComputeUpdate(e){const t=this.get(e);return void 0===t.pipeline||t.version!==e.version}_needsRenderUpdate(e){return void 0===this.get(e).pipeline||this.backend.needsRenderUpdate(e)}}class xy extends ty{constructor(e,t,r,s,i,n){super(),this.backend=e,this.textures=r,this.pipelines=i,this.attributes=s,this.nodes=t,this.info=n,this.pipelines.bindings=this}getForRender(e){const t=e.getBindings();for(const e of t){const r=this.get(e);void 0===r.bindGroup&&(this._init(e),this.backend.createBindings(e,t,0),r.bindGroup=e)}return t}getForCompute(e){const t=this.nodes.getForCompute(e).bindings;for(const e of t){const r=this.get(e);void 0===r.bindGroup&&(this._init(e),this.backend.createBindings(e,t,0),r.bindGroup=e)}return t}updateForCompute(e){this._updateBindings(this.getForCompute(e))}updateForRender(e){this._updateBindings(this.getForRender(e))}deleteForCompute(e){const t=this.nodes.getForCompute(e).bindings;for(const e of t)this.backend.deleteBindGroupData(e),this.delete(e)}deleteForRender(e){const t=e.getBindings();for(const e of t)this.backend.deleteBindGroupData(e),this.delete(e)}_updateBindings(e){for(const t of e)this._update(t,e)}_init(e){for(const t of e.bindings)if(t.isSampledTexture)this.textures.updateTexture(t.texture);else if(t.isSampler)this.textures.updateSampler(t.texture);else if(t.isStorageBuffer){const e=t.attribute,r=e.isIndirectStorageBufferAttribute?ny:iy;this.attributes.update(e,r)}}_update(e,t){const{backend:r}=this;let s=!1,i=!0,n=0,a=0;for(const t of e.bindings){if(!1!==this.nodes.updateGroup(t)){if(t.isStorageBuffer){const e=t.attribute,i=e.isIndirectStorageBufferAttribute?ny:iy,n=r.get(t);this.attributes.update(e,i),n.attribute!==e&&(n.attribute=e,s=!0)}if(t.isUniformBuffer){t.update()&&r.updateBinding(t)}else if(t.isSampledTexture){const e=t.update(),o=t.texture,u=this.textures.get(o);e&&(this.textures.updateTexture(o),t.generation!==u.generation&&(t.generation=u.generation,s=!0,i=!1));if(void 0!==r.get(o).externalTexture||u.isDefaultTexture?i=!1:(n=10*n+o.id,a+=o.version),!0===o.isStorageTexture&&!0===o.mipmapsAutoUpdate){const e=this.get(o);!0===t.store?e.needsMipmap=!0:this.textures.needsMipmaps(o)&&!0===e.needsMipmap&&(this.backend.generateMipmaps(o),e.needsMipmap=!1)}}else if(t.isSampler){if(t.update()){const e=this.textures.updateSampler(t.texture);t.samplerKey!==e&&(t.samplerKey=e,s=!0,i=!1)}}t.isBuffer&&t.updateRanges.length>0&&t.clearUpdateRanges()}}!0===s&&this.backend.updateBindings(e,t,i?n:0,a)}}function Ty(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?e.z-t.z:e.id-t.id}function _y(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?t.z-e.z:e.id-t.id}function vy(e){return(e.transmission>0||e.transmissionNode&&e.transmissionNode.isNode)&&e.side===B&&!1===e.forceSinglePass}class Ny{constructor(e,t,r){this.renderItems=[],this.renderItemsIndex=0,this.opaque=[],this.transparentDoublePass=[],this.transparent=[],this.bundles=[],this.lightsNode=e.getNode(t,r),this.lightsArray=[],this.scene=t,this.camera=r,this.occlusionQueryCount=0}begin(){return this.renderItemsIndex=0,this.opaque.length=0,this.transparentDoublePass.length=0,this.transparent.length=0,this.bundles.length=0,this.lightsArray.length=0,this.occlusionQueryCount=0,this}getNextRenderItem(e,t,r,s,i,n,a){let o=this.renderItems[this.renderItemsIndex];return void 0===o?(o={id:e.id,object:e,geometry:t,material:r,groupOrder:s,renderOrder:e.renderOrder,z:i,group:n,clippingContext:a},this.renderItems[this.renderItemsIndex]=o):(o.id=e.id,o.object=e,o.geometry=t,o.material=r,o.groupOrder=s,o.renderOrder=e.renderOrder,o.z=i,o.group=n,o.clippingContext=a),this.renderItemsIndex++,o}push(e,t,r,s,i,n,a){const o=this.getNextRenderItem(e,t,r,s,i,n,a);!0===e.occlusionTest&&this.occlusionQueryCount++,!0===r.transparent||r.transmission>0||r.transmissionNode&&r.transmissionNode.isNode||r.backdropNode&&r.backdropNode.isNode?(vy(r)&&this.transparentDoublePass.push(o),this.transparent.push(o)):this.opaque.push(o)}unshift(e,t,r,s,i,n,a){const o=this.getNextRenderItem(e,t,r,s,i,n,a);!0===r.transparent||r.transmission>0||r.transmissionNode&&r.transmissionNode.isNode||r.backdropNode&&r.backdropNode.isNode?(vy(r)&&this.transparentDoublePass.unshift(o),this.transparent.unshift(o)):this.opaque.unshift(o)}pushBundle(e){this.bundles.push(e)}pushLight(e){this.lightsArray.push(e)}sort(e,t){this.opaque.length>1&&this.opaque.sort(e||Ty),this.transparentDoublePass.length>1&&this.transparentDoublePass.sort(t||_y),this.transparent.length>1&&this.transparent.sort(t||_y)}finish(){this.lightsNode.setLights(this.lightsArray);for(let e=this.renderItemsIndex,t=this.renderItems.length;e>t,u=a.height>>t;let l=e.depthTexture||i[t];const d=!0===e.depthBuffer||!0===e.stencilBuffer;let c=!1;void 0===l&&d&&(l=new Y,l.format=e.stencilBuffer?Ie:Oe,l.type=e.stencilBuffer?Ve:S,l.image.width=o,l.image.height=u,l.image.depth=a.depth,l.renderTarget=e,l.isArrayTexture=!0===e.multiview&&a.depth>1,i[t]=l),r.width===a.width&&a.height===r.height||(c=!0,l&&(l.needsUpdate=!0,l.image.width=o,l.image.height=u,l.image.depth=l.isArrayTexture?l.image.depth:1)),r.width=a.width,r.height=a.height,r.textures=n,r.depthTexture=l||null,r.depth=e.depthBuffer,r.stencil=e.stencilBuffer,r.renderTarget=e,r.sampleCount!==s&&(c=!0,l&&(l.needsUpdate=!0),r.sampleCount=s);const h={sampleCount:s};if(!0!==e.isXRRenderTarget){for(let e=0;e{this._destroyRenderTarget(e)},e.addEventListener("dispose",r.onDispose))}updateTexture(e,t={}){const r=this.get(e);if(!0===r.initialized&&r.version===e.version)return;const s=e.isRenderTargetTexture||e.isDepthTexture||e.isFramebufferTexture,i=this.backend;if(s&&!0===r.initialized&&i.destroyTexture(e),e.isFramebufferTexture){const t=this.renderer.getRenderTarget();e.type=t?t.texture.type:ke}const{width:n,height:a,depth:o}=this.getSize(e);if(t.width=n,t.height=a,t.depth=o,t.needsMipmaps=this.needsMipmaps(e),t.levels=t.needsMipmaps?this.getMipLevels(e,n,a):1,e.isCubeTexture&&e.mipmaps.length>0&&t.levels++,s||!0===e.isStorageTexture||!0===e.isExternalTexture)i.createTexture(e,t),r.generation=e.version;else if(e.version>0){const s=e.image;if(void 0===s)d("Renderer: Texture marked for update but image is undefined.");else if(!1===s.complete)d("Renderer: Texture marked for update but image is incomplete.");else{if(e.images){const r=[];for(const t of e.images)r.push(t);t.images=r}else t.image=s;void 0!==r.isDefaultTexture&&!0!==r.isDefaultTexture||(i.createTexture(e,t),r.isDefaultTexture=!1,r.generation=e.version),!0===e.source.dataReady&&i.updateTexture(e,t);const n=!0===e.isStorageTexture&&!1===e.mipmapsAutoUpdate;t.needsMipmaps&&0===e.mipmaps.length&&!n&&i.generateMipmaps(e),e.onUpdate&&e.onUpdate(e)}}else i.createDefaultTexture(e),r.isDefaultTexture=!0,r.generation=e.version;!0!==r.initialized&&(r.initialized=!0,r.generation=e.version,this.info.memory.textures++,e.isVideoTexture&&!0===p.enabled&&p.getTransfer(e.colorSpace)!==g&&d("WebGPURenderer: Video textures must use a color space with a sRGB transfer function, e.g. SRGBColorSpace."),r.onDispose=()=>{this._destroyTexture(e)},e.addEventListener("dispose",r.onDispose)),r.version=e.version}updateSampler(e){return this.backend.updateSampler(e)}getSize(e,t=My){let r=e.images?e.images[0]:e.image;return r?(void 0!==r.image&&(r=r.image),"undefined"!=typeof HTMLVideoElement&&r instanceof HTMLVideoElement?(t.width=r.videoWidth||1,t.height=r.videoHeight||1,t.depth=1):"undefined"!=typeof VideoFrame&&r instanceof VideoFrame?(t.width=r.displayWidth||1,t.height=r.displayHeight||1,t.depth=1):(t.width=r.width||1,t.height=r.height||1,t.depth=e.isCubeTexture?6:r.depth||1)):t.width=t.height=t.depth=1,t}getMipLevels(e,t,r){let s;return s=e.mipmaps.length>0?e.mipmaps.length:!0===e.isCompressedTexture?1:Math.floor(Math.log2(Math.max(t,r)))+1,s}needsMipmaps(e){return!0===e.generateMipmaps||e.mipmaps.length>0}_destroyRenderTarget(e){if(!0===this.has(e)){const t=this.get(e),r=t.textures,s=t.depthTexture;e.removeEventListener("dispose",t.onDispose);for(let e=0;e=2)for(let r=0;r{if(this._currentNode=t,!t.isVarNode||!t.isIntent(e)||!0===t.isAssign(e))if("setup"===s)t.build(e);else if("analyze"===s)t.build(e,this);else if("generate"===s){const r=e.getDataFromNode(t,"any").stages,s=r&&r[e.shaderStage];if(t.isVarNode&&s&&1===s.length&&s[0]&&s[0].isStackNode)return;t.build(e,"void")}},n=[...this.nodes];for(const e of n)i(e);this._currentNode=null;const a=this.nodes.filter(e=>-1===n.indexOf(e));for(const e of a)i(e);let o;return o=this.hasOutput(e)?this.outputNode.build(e,...t):super.build(e,...t),un(r),e.removeActiveStack(this),o}}const Dy=tn(Py).setParameterLength(0,1);class Uy extends oi{static get type(){return"StructTypeNode"}constructor(e,t=null){var r;super("struct"),this.membersLayout=(r=e,Object.entries(r).map(([e,t])=>"string"==typeof t?{name:e,type:t,atomic:!1}:{name:e,type:t.type,atomic:t.atomic||!1})),this.name=t,this.isStructLayoutNode=!0}getLength(){const e=Float32Array.BYTES_PER_ELEMENT;let t=1,r=0;for(const s of this.membersLayout){const i=s.type,n=$s(i),a=Ws(i)/e;t=Math.max(t,a);const o=r%t%a;0!==o&&(r+=a-o),r+=n}return Math.ceil(r/t)*t}getMemberType(e,t){const r=this.membersLayout.find(e=>e.name===t);return r?r.type:"void"}getNodeType(e){return e.getStructTypeFromNode(this,this.membersLayout,this.name).name}setup(e){e.getStructTypeFromNode(this,this.membersLayout,this.name),e.addInclude(this)}generate(e){return this.getNodeType(e)}}class Iy extends oi{static get type(){return"StructNode"}constructor(e,t){super("vec3"),this.structTypeNode=e,this.values=t,this.isStructNode=!0}getNodeType(e){return this.structTypeNode.getNodeType(e)}getMemberType(e,t){return this.structTypeNode.getMemberType(e,t)}_getChildren(){const e=super._getChildren(),t=e.find(e=>e.childNode===this.structTypeNode);return e.splice(e.indexOf(t),1),e.push(t),e}generate(e){const t=e.getVarFromNode(this),r=t.type,s=e.getPropertyName(t);return e.addLineFlowCode(`${s} = ${e.generateStruct(r,this.structTypeNode.membersLayout,this.values)}`,this),t.name}}class Oy extends oi{static get type(){return"OutputStructNode"}constructor(...e){super(),this.members=e,this.isOutputStructNode=!0}getNodeType(){return"OutputType"}generate(e){const t=e.getDataFromNode(this);if(void 0===t.membersLayout){const r=this.members,s=[];for(let t=0;tnew qy(e,"uint","float"),Ky={};class Yy extends to{static get type(){return"BitcountNode"}constructor(e,t){super(e,t),this.isBitcountNode=!0}_resolveElementType(e,t,r){"int"===r?t.assign(jy(e,"uint")):t.assign(e)}_returnDataNode(e){switch(e){case"uint":return mn;case"int":return gn;case"uvec2":return xn;case"uvec3":return Nn;case"uvec4":return An;case"ivec2":return bn;case"ivec3":return vn;case"ivec4":return En}}_createTrailingZerosBaseLayout(e,t){const r=this._returnDataNode(t);return on(([e])=>{const s=mn(0);this._resolveElementType(e,s,t);const i=pn(s.bitAnd(Fo(s))),n=Xy(i).shiftRight(23).sub(127);return r(n)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createLeadingZerosBaseLayout(e,t){const r=this._returnDataNode(t);return on(([e])=>{dn(e.equal(mn(0)),()=>mn(32));const s=mn(0),i=mn(0);return this._resolveElementType(e,s,t),dn(s.shiftRight(16).equal(0),()=>{i.addAssign(16),s.shiftLeftAssign(16)}),dn(s.shiftRight(24).equal(0),()=>{i.addAssign(8),s.shiftLeftAssign(8)}),dn(s.shiftRight(28).equal(0),()=>{i.addAssign(4),s.shiftLeftAssign(4)}),dn(s.shiftRight(30).equal(0),()=>{i.addAssign(2),s.shiftLeftAssign(2)}),dn(s.shiftRight(31).equal(0),()=>{i.addAssign(1)}),r(i)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createOneBitsBaseLayout(e,t){const r=this._returnDataNode(t);return on(([e])=>{const s=mn(0);this._resolveElementType(e,s,t),s.assign(s.sub(s.shiftRight(mn(1)).bitAnd(mn(1431655765)))),s.assign(s.bitAnd(mn(858993459)).add(s.shiftRight(mn(2)).bitAnd(mn(858993459))));const i=s.add(s.shiftRight(mn(4))).bitAnd(mn(252645135)).mul(mn(16843009)).shiftRight(mn(24));return r(i)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createMainLayout(e,t,r,s){const i=this._returnDataNode(t);return on(([e])=>{if(1===r)return i(s(e));{const t=i(0),n=["x","y","z","w"];for(let i=0;id(r))()}}Yy.COUNT_TRAILING_ZEROS="countTrailingZeros",Yy.COUNT_LEADING_ZEROS="countLeadingZeros",Yy.COUNT_ONE_BITS="countOneBits";const Qy=sn(Yy,Yy.COUNT_TRAILING_ZEROS).setParameterLength(1),Zy=sn(Yy,Yy.COUNT_LEADING_ZEROS).setParameterLength(1),Jy=sn(Yy,Yy.COUNT_ONE_BITS).setParameterLength(1),eb=on(([e])=>{const t=e.toUint().mul(747796405).add(2891336453),r=t.shiftRight(t.shiftRight(28).add(4)).bitXor(t).mul(277803737);return r.shiftRight(22).bitXor(r).toFloat().mul(1/2**32)}),tb=(e,t)=>Qo(Ba(4,e.mul(Ma(1,e))),t);class rb extends di{static get type(){return"PackFloatNode"}constructor(e,t){super(),this.vectorNode=t,this.encoding=e,this.isPackFloatNode=!0}getNodeType(){return"uint"}generate(e){const t=this.vectorNode.getNodeType(e);return`${e.getFloatPackingMethod(this.encoding)}(${this.vectorNode.build(e,t)})`}}const sb=sn(rb,"snorm").setParameterLength(1),ib=sn(rb,"unorm").setParameterLength(1),nb=sn(rb,"float16").setParameterLength(1);class ab extends di{static get type(){return"UnpackFloatNode"}constructor(e,t){super(),this.uintNode=t,this.encoding=e,this.isUnpackFloatNode=!0}getNodeType(){return"vec2"}generate(e){const t=this.uintNode.getNodeType(e);return`${e.getFloatUnpackingMethod(this.encoding)}(${this.uintNode.build(e,t)})`}}const ob=sn(ab,"snorm").setParameterLength(1),ub=sn(ab,"unorm").setParameterLength(1),lb=sn(ab,"float16").setParameterLength(1),db=on(([e])=>e.fract().sub(.5).abs()).setLayout({name:"tri",type:"float",inputs:[{name:"x",type:"float"}]}),cb=on(([e])=>_n(db(e.z.add(db(e.y.mul(1)))),db(e.z.add(db(e.x.mul(1)))),db(e.y.add(db(e.x.mul(1)))))).setLayout({name:"tri3",type:"vec3",inputs:[{name:"p",type:"vec3"}]}),hb=on(([e,t,r])=>{const s=_n(e).toVar(),i=pn(1.4).toVar(),n=pn(0).toVar(),a=_n(s).toVar();return up({start:pn(0),end:pn(3),type:"float",condition:"<="},()=>{const e=_n(cb(a.mul(2))).toVar();s.addAssign(e.add(r.mul(pn(.1).mul(t)))),a.mulAssign(1.8),i.mulAssign(1.5),s.mulAssign(1.2);const o=pn(db(s.z.add(db(s.x.add(db(s.y)))))).toVar();n.addAssign(o.div(i)),a.addAssign(.14)}),n}).setLayout({name:"triNoise3D",type:"float",inputs:[{name:"position",type:"vec3"},{name:"speed",type:"float"},{name:"time",type:"float"}]});class pb extends oi{static get type(){return"FunctionOverloadingNode"}constructor(e=[],...t){super(),this.functionNodes=e,this.parametersNodes=t,this._candidateFn=null,this.global=!0}getNodeType(e){return this.getCandidateFn(e).shaderNode.layout.type}getCandidateFn(e){const t=this.parametersNodes;let r=this._candidateFn;if(null===r){let s=null,i=-1;for(const r of this.functionNodes){const n=r.shaderNode.layout;if(null===n)throw new Error("FunctionOverloadingNode: FunctionNode must be a layout.");const a=n.inputs;if(t.length===a.length){let n=0;for(let r=0;ri&&(s=r,i=n)}}this._candidateFn=r=s}return r}setup(e){return this.getCandidateFn(e)(...this.parametersNodes)}}const gb=tn(pb),mb=e=>(...t)=>gb(e,...t),fb=Ta(0).setGroup(ya).onRenderUpdate(e=>e.time),yb=Ta(0).setGroup(ya).onRenderUpdate(e=>e.deltaTime),bb=Ta(0,"uint").setGroup(ya).onRenderUpdate(e=>e.frameId);const xb=on(([e,t,r=yn(.5)])=>Pf(e.sub(r),t).add(r)),Tb=on(([e,t,r=yn(.5)])=>{const s=e.sub(r),i=s.dot(s),n=i.mul(i).mul(t);return e.add(s.mul(n))}),_b=on(({position:e=null,horizontal:t=!0,vertical:r=!1})=>{let s;null!==e?(s=xd.toVar(),s[3][0]=e.x,s[3][1]=e.y,s[3][2]=e.z):s=xd;const i=id.mul(s);return Xi(t)&&(i[0][0]=xd[0].length(),i[0][1]=0,i[0][2]=0),Xi(r)&&(i[1][0]=0,i[1][1]=xd[1].length(),i[1][2]=0),i[2][0]=0,i[2][1]=0,i[2][2]=1,rd.mul(i).mul(Fd)}),vb=on(([e=null])=>{const t=Up();return Up(wp(e)).sub(t).lessThan(0).select(Hl,e)}),Nb=on(([e,t=Sl(),r=pn(0)])=>{const s=e.x,i=e.y,n=r.mod(s.mul(i)).floor(),a=n.mod(s),o=i.sub(n.add(1).div(s).ceil()),u=e.reciprocal(),l=yn(a,o);return t.add(l).mul(u)}),Sb=on(([e,t=null,r=null,s=pn(1),i=Fd,n=$d])=>{let a=n.abs().normalize();a=a.div(a.dot(_n(1)));const o=i.yz.mul(s),u=i.zx.mul(s),l=i.xy.mul(s),d=e.value,c=null!==t?t.value:d,h=null!==r?r.value:d,p=Fl(d,o).mul(a.x),g=Fl(c,u).mul(a.y),m=Fl(h,l).mul(a.z);return Ca(p,g,m)}),Rb=new qe,Eb=new r,Ab=new r,wb=new r,Cb=new a,Mb=new r(0,0,-1),Bb=new s,Fb=new r,Lb=new r,Pb=new s,Db=new t,Ub=new se,Ib=Hl.flipX();Ub.depthTexture=new Y(1,1);let Ob=!1;class Vb extends Ml{static get type(){return"ReflectorNode"}constructor(e={}){super(e.defaultTexture||Ub.texture,Ib),this._reflectorBaseNode=e.reflector||new kb(this,e),this._depthNode=null,this.setUpdateMatrix(!1)}get reflector(){return this._reflectorBaseNode}get target(){return this._reflectorBaseNode.target}getDepthNode(){if(null===this._depthNode){if(!0!==this._reflectorBaseNode.depth)throw new Error("THREE.ReflectorNode: Depth node can only be requested when the reflector is created with { depth: true }. ");this._depthNode=Qi(new Vb({defaultTexture:Ub.depthTexture,reflector:this._reflectorBaseNode}))}return this._depthNode}setup(e){return e.object.isQuadMesh||this._reflectorBaseNode.build(e),super.setup(e)}clone(){const e=new this.constructor(this.reflectorNode);return e.uvNode=this.uvNode,e.levelNode=this.levelNode,e.biasNode=this.biasNode,e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e._reflectorBaseNode=this._reflectorBaseNode,e}dispose(){super.dispose(),this._reflectorBaseNode.dispose()}}class kb extends oi{static get type(){return"ReflectorBaseNode"}constructor(e,t={}){super();const{target:r=new je,resolutionScale:s=1,generateMipmaps:i=!1,bounces:n=!0,depth:a=!1,samples:o=0}=t;this.textureNode=e,this.target=r,this.resolutionScale=s,void 0!==t.resolution&&(v('ReflectorNode: The "resolution" parameter has been renamed to "resolutionScale".'),this.resolutionScale=t.resolution),this.generateMipmaps=i,this.bounces=n,this.depth=a,this.samples=o,this.updateBeforeType=n?Zs.RENDER:Zs.FRAME,this.virtualCameras=new WeakMap,this.renderTargets=new Map,this.forceUpdate=!1,this.hasOutput=!1}_updateResolution(e,t){const r=this.resolutionScale;t.getDrawingBufferSize(Db),e.setSize(Math.round(Db.width*r),Math.round(Db.height*r))}setup(e){return this._updateResolution(Ub,e.renderer),super.setup(e)}dispose(){super.dispose();for(const e of this.renderTargets.values())e.dispose()}getVirtualCamera(e){let t=this.virtualCameras.get(e);return void 0===t&&(t=e.clone(),this.virtualCameras.set(e,t)),t}getRenderTarget(e){let t=this.renderTargets.get(e);return void 0===t&&(t=new se(0,0,{type:be,samples:this.samples}),!0===this.generateMipmaps&&(t.texture.minFilter=Xe,t.texture.generateMipmaps=!0),!0===this.depth&&(t.depthTexture=new Y),this.renderTargets.set(e,t)),t}updateBefore(e){if(!1===this.bounces&&Ob)return!1;Ob=!0;const{scene:t,camera:r,renderer:s,material:i}=e,{target:n}=this,a=this.getVirtualCamera(r),o=this.getRenderTarget(a);s.getDrawingBufferSize(Db),this._updateResolution(o,s),Ab.setFromMatrixPosition(n.matrixWorld),wb.setFromMatrixPosition(r.matrixWorld),Cb.extractRotation(n.matrixWorld),Eb.set(0,0,1),Eb.applyMatrix4(Cb),Fb.subVectors(Ab,wb);let u=!1;if(!0===Fb.dot(Eb)>0&&!1===this.forceUpdate){if(!1===this.hasOutput)return void(Ob=!1);u=!0}Fb.reflect(Eb).negate(),Fb.add(Ab),Cb.extractRotation(r.matrixWorld),Mb.set(0,0,-1),Mb.applyMatrix4(Cb),Mb.add(wb),Lb.subVectors(Ab,Mb),Lb.reflect(Eb).negate(),Lb.add(Ab),a.coordinateSystem=r.coordinateSystem,a.position.copy(Fb),a.up.set(0,1,0),a.up.applyMatrix4(Cb),a.up.reflect(Eb),a.lookAt(Lb),a.near=r.near,a.far=r.far,a.updateMatrixWorld(),a.projectionMatrix.copy(r.projectionMatrix),Rb.setFromNormalAndCoplanarPoint(Eb,Ab),Rb.applyMatrix4(a.matrixWorldInverse),Bb.set(Rb.normal.x,Rb.normal.y,Rb.normal.z,Rb.constant);const l=a.projectionMatrix;Pb.x=(Math.sign(Bb.x)+l.elements[8])/l.elements[0],Pb.y=(Math.sign(Bb.y)+l.elements[9])/l.elements[5],Pb.z=-1,Pb.w=(1+l.elements[10])/l.elements[14],Bb.multiplyScalar(1/Bb.dot(Pb));l.elements[2]=Bb.x,l.elements[6]=Bb.y,l.elements[10]=s.coordinateSystem===h?Bb.z-0:Bb.z+1-0,l.elements[14]=Bb.w,this.textureNode.value=o.texture,!0===this.depth&&(this.textureNode.getDepthNode().value=o.depthTexture),i.visible=!1;const d=s.getRenderTarget(),c=s.getMRT(),p=s.autoClear;s.setMRT(null),s.setRenderTarget(o),s.autoClear=!0;const g=t.name;t.name=(t.name||"Scene")+" [ Reflector ]",u?(s.clear(),this.hasOutput=!1):(s.render(t,a),this.hasOutput=!0),t.name=g,s.setMRT(c),s.setRenderTarget(d),s.autoClear=p,i.visible=!0,Ob=!1,this.forceUpdate=!1}get resolution(){return v('ReflectorNode: The "resolution" property has been renamed to "resolutionScale".'),this.resolutionScale}set resolution(e){v('ReflectorNode: The "resolution" property has been renamed to "resolutionScale".'),this.resolutionScale=e}}const Gb=new _e(-1,1,1,-1,0,1);class zb extends Te{constructor(e=!1){super();const t=!1===e?[0,-1,0,1,2,1]:[0,2,0,0,2,0];this.setAttribute("position",new Ke([-1,3,0,-1,-1,0,3,-1,0],3)),this.setAttribute("uv",new Ke(t,2))}}const $b=new zb;class Wb extends ne{constructor(e=null){super($b,e),this.camera=Gb,this.isQuadMesh=!0}async renderAsync(e){v('QuadMesh: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await e.init(),e.render(this,Gb)}render(e){e.render(this,Gb)}}const Hb=new t;class qb extends Ml{static get type(){return"RTTNode"}constructor(e,t=null,r=null,s={type:be}){const i=new se(t,r,s);super(i.texture,Sl()),this.isRTTNode=!0,this.node=e,this.width=t,this.height=r,this.pixelRatio=1,this.renderTarget=i,this.textureNeedsUpdate=!0,this.autoUpdate=!0,this._rttNode=null,this._quadMesh=new Wb(new Qp),this.updateBeforeType=Zs.RENDER}get autoResize(){return null===this.width}setup(e){return this._rttNode=this.node.context(e.getSharedContext()),this._quadMesh.material.name="RTT",this._quadMesh.material.needsUpdate=!0,super.setup(e)}setSize(e,t){this.width=e,this.height=t;const r=e*this.pixelRatio,s=t*this.pixelRatio;this.renderTarget.setSize(r,s),this.textureNeedsUpdate=!0}setPixelRatio(e){this.pixelRatio=e,this.setSize(this.width,this.height)}updateBefore({renderer:e}){if(!1===this.textureNeedsUpdate&&!1===this.autoUpdate)return;if(this.textureNeedsUpdate=!1,!0===this.autoResize){const t=e.getPixelRatio(),r=e.getSize(Hb),s=Math.floor(r.width*t),i=Math.floor(r.height*t);s===this.renderTarget.width&&i===this.renderTarget.height||(this.renderTarget.setSize(s,i),this.textureNeedsUpdate=!0)}let t="RTT";this.node.name&&(t=this.node.name+" [ "+t+" ]"),this._quadMesh.material.fragmentNode=this._rttNode,this._quadMesh.name=t;const r=e.getRenderTarget();e.setRenderTarget(this.renderTarget),this._quadMesh.render(e),e.setRenderTarget(r)}clone(){const e=new Ml(this.value,this.uvNode,this.levelNode);return e.sampler=this.sampler,e.referenceNode=this,e}}const jb=(e,...t)=>Qi(new qb(Qi(e),...t)),Xb=on(([e,t,r],s)=>{let i;s.renderer.coordinateSystem===h?(e=yn(e.x,e.y.oneMinus()).mul(2).sub(1),i=Rn(_n(e,t),1)):i=Rn(_n(e.x,e.y.oneMinus(),t).mul(2).sub(1),1);const n=Rn(r.mul(i));return n.xyz.div(n.w)}),Kb=on(([e,t])=>{const r=t.mul(Rn(e,1)),s=r.xy.div(r.w).mul(.5).add(.5).toVar();return yn(s.x,s.y.oneMinus())}),Yb=on(([e,t,r])=>{const s=El(Ll(t)),i=bn(e.mul(s)).toVar(),n=Ll(t,i).toVar(),a=Ll(t,i.sub(bn(2,0))).toVar(),o=Ll(t,i.sub(bn(1,0))).toVar(),u=Ll(t,i.add(bn(1,0))).toVar(),l=Ll(t,i.add(bn(2,0))).toVar(),d=Ll(t,i.add(bn(0,2))).toVar(),c=Ll(t,i.add(bn(0,1))).toVar(),h=Ll(t,i.sub(bn(0,1))).toVar(),p=Ll(t,i.sub(bn(0,2))).toVar(),g=Co(Ma(pn(2).mul(o).sub(a),n)).toVar(),m=Co(Ma(pn(2).mul(u).sub(l),n)).toVar(),f=Co(Ma(pn(2).mul(c).sub(d),n)).toVar(),y=Co(Ma(pn(2).mul(h).sub(p),n)).toVar(),b=Xb(e,n,r).toVar(),x=g.lessThan(m).select(b.sub(Xb(e.sub(yn(pn(1).div(s.x),0)),o,r)),b.negate().add(Xb(e.add(yn(pn(1).div(s.x),0)),u,r))),T=f.lessThan(y).select(b.sub(Xb(e.add(yn(0,pn(1).div(s.y))),c,r)),b.negate().add(Xb(e.sub(yn(0,pn(1).div(s.y))),h,r)));return _o(Yo(x,T))}),Qb=on(([e])=>vo(pn(52.9829189).mul(vo(Ko(e,yn(.06711056,.00583715)))))).setLayout({name:"interleavedGradientNoise",type:"float",inputs:[{name:"position",type:"vec2"}]}),Zb=on(([e,t,r])=>{const s=pn(2.399963229728653),i=yo(pn(e).add(.5).div(pn(t))),n=pn(e).mul(s).add(r);return yn(So(n),No(n)).mul(i)}).setLayout({name:"vogelDiskSample",type:"vec2",inputs:[{name:"sampleIndex",type:"int"},{name:"samplesCount",type:"int"},{name:"phi",type:"float"}]});class Jb extends oi{static get type(){return"SampleNode"}constructor(e,t=null){super(),this.callback=e,this.uvNode=t,this.isSampleNode=!0}setup(){return this.sample(Sl())}sample(e){return this.callback(e)}}class ex extends oi{static get type(){return"EventNode"}constructor(e,t){super("void"),this.eventType=e,this.callback=t,e===ex.OBJECT?this.updateType=Zs.OBJECT:e===ex.MATERIAL?this.updateType=Zs.RENDER:e===ex.BEFORE_OBJECT?this.updateBeforeType=Zs.OBJECT:e===ex.BEFORE_MATERIAL&&(this.updateBeforeType=Zs.RENDER)}update(e){this.callback(e)}updateBefore(e){this.callback(e)}}ex.OBJECT="object",ex.MATERIAL="material",ex.BEFORE_OBJECT="beforeObject",ex.BEFORE_MATERIAL="beforeMaterial";const tx=(e,t)=>new ex(e,t).toStack();class rx extends W{constructor(e,t,r=Float32Array){super(ArrayBuffer.isView(e)?e:new r(e*t),t),this.isStorageInstancedBufferAttribute=!0}}class sx extends Ee{constructor(e,t,r=Float32Array){super(ArrayBuffer.isView(e)?e:new r(e*t),t),this.isStorageBufferAttribute=!0}}class ix extends oi{static get type(){return"PointUVNode"}constructor(){super("vec2"),this.isPointUVNode=!0}generate(){return"vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y )"}}const nx=rn(ix),ax=new F,ox=new a,ux=Ta(0).setGroup(ya).onRenderUpdate(({scene:e})=>e.backgroundBlurriness),lx=Ta(1).setGroup(ya).onRenderUpdate(({scene:e})=>e.backgroundIntensity),dx=Ta(new a).setGroup(ya).onRenderUpdate(({scene:e})=>{const t=e.background;return null!==t&&t.isTexture&&t.mapping!==Ye?(ax.copy(e.backgroundRotation),ax.x*=-1,ax.y*=-1,ax.z*=-1,ox.makeRotationFromEuler(ax)):ox.identity(),ox});class cx extends Ml{static get type(){return"StorageTextureNode"}constructor(e,t,r=null){super(e,t),this.storeNode=r,this.mipLevel=0,this.isStorageTextureNode=!0,this.access=ei.WRITE_ONLY}getInputType(){return"storageTexture"}setup(e){super.setup(e);const t=e.getNodeProperties(this);return t.storeNode=this.storeNode,t}setAccess(e){return this.access=e,this}setMipLevel(e){return this.mipLevel=e,this}generate(e,t){let r;return r=null!==this.storeNode?this.generateStore(e):super.generate(e,t),r}toReadWrite(){return this.setAccess(ei.READ_WRITE)}toReadOnly(){return this.setAccess(ei.READ_ONLY)}toWriteOnly(){return this.setAccess(ei.WRITE_ONLY)}generateStore(e){const t=e.getNodeProperties(this),{uvNode:r,storeNode:s,depthNode:i}=t,n=super.generate(e,"property"),a=r.build(e,!0===this.value.is3DTexture?"uvec3":"uvec2"),o=s.build(e,"vec4"),u=i?i.build(e,"int"):null,l=e.generateTextureStore(e,n,a,u,o);e.addLineFlowCode(l,this)}clone(){const e=super.clone();return e.storeNode=this.storeNode,e.mipLevel=this.mipLevel,e.access=this.access,e}}const hx=tn(cx).setParameterLength(1,3),px=on(({texture:e,uv:t})=>{const r=1e-4,s=_n().toVar();return dn(t.x.lessThan(r),()=>{s.assign(_n(1,0,0))}).ElseIf(t.y.lessThan(r),()=>{s.assign(_n(0,1,0))}).ElseIf(t.z.lessThan(r),()=>{s.assign(_n(0,0,1))}).ElseIf(t.x.greaterThan(.9999),()=>{s.assign(_n(-1,0,0))}).ElseIf(t.y.greaterThan(.9999),()=>{s.assign(_n(0,-1,0))}).ElseIf(t.z.greaterThan(.9999),()=>{s.assign(_n(0,0,-1))}).Else(()=>{const r=.01,i=e.sample(t.add(_n(-.01,0,0))).r.sub(e.sample(t.add(_n(r,0,0))).r),n=e.sample(t.add(_n(0,-.01,0))).r.sub(e.sample(t.add(_n(0,r,0))).r),a=e.sample(t.add(_n(0,0,-.01))).r.sub(e.sample(t.add(_n(0,0,r))).r);s.assign(_n(i,n,a))}),s.normalize()});class gx extends Ml{static get type(){return"Texture3DNode"}constructor(e,t=null,r=null){super(e,t,r),this.isTexture3DNode=!0}getInputType(){return"texture3D"}getDefaultUV(){return _n(.5,.5,.5)}setUpdateMatrix(){}generateUV(e,t){return t.build(e,!0===this.sampler?"vec3":"ivec3")}generateOffset(e,t){return t.build(e,"ivec3")}normal(e){return px({texture:this,uv:e})}}const mx=tn(gx).setParameterLength(1,3);class fx extends mc{static get type(){return"UserDataNode"}constructor(e,t,r=null){super(e,t,r),this.userData=r}updateReference(e){return this.reference=null!==this.userData?this.userData:e.object.userData,this.reference}}const yx=new WeakMap;class bx extends di{static get type(){return"VelocityNode"}constructor(){super("vec2"),this.projectionMatrix=null,this.updateType=Zs.OBJECT,this.updateAfterType=Zs.OBJECT,this.previousModelWorldMatrix=Ta(new a),this.previousProjectionMatrix=Ta(new a).setGroup(ya),this.previousCameraViewMatrix=Ta(new a)}setProjectionMatrix(e){this.projectionMatrix=e}update({frameId:e,camera:t,object:r}){const s=Tx(r);this.previousModelWorldMatrix.value.copy(s);const i=xx(t);i.frameId!==e&&(i.frameId=e,void 0===i.previousProjectionMatrix?(i.previousProjectionMatrix=new a,i.previousCameraViewMatrix=new a,i.currentProjectionMatrix=new a,i.currentCameraViewMatrix=new a,i.previousProjectionMatrix.copy(this.projectionMatrix||t.projectionMatrix),i.previousCameraViewMatrix.copy(t.matrixWorldInverse)):(i.previousProjectionMatrix.copy(i.currentProjectionMatrix),i.previousCameraViewMatrix.copy(i.currentCameraViewMatrix)),i.currentProjectionMatrix.copy(this.projectionMatrix||t.projectionMatrix),i.currentCameraViewMatrix.copy(t.matrixWorldInverse),this.previousProjectionMatrix.value.copy(i.previousProjectionMatrix),this.previousCameraViewMatrix.value.copy(i.previousCameraViewMatrix))}updateAfter({object:e}){Tx(e).copy(e.matrixWorld)}setup(){const e=null===this.projectionMatrix?rd:Ta(this.projectionMatrix),t=this.previousCameraViewMatrix.mul(this.previousModelWorldMatrix),r=e.mul(Ed).mul(Fd),s=this.previousProjectionMatrix.mul(t).mul(Ld),i=r.xy.div(r.w),n=s.xy.div(s.w);return Ma(i,n)}}function xx(e){let t=yx.get(e);return void 0===t&&(t={},yx.set(e,t)),t}function Tx(e,t=0){const r=xx(e);let s=r[t];return void 0===s&&(r[t]=s=new a,r[t].copy(e.matrixWorld)),s}const _x=rn(bx),vx=on(([e])=>Ex(e.rgb)),Nx=on(([e,t=pn(1)])=>t.mix(Ex(e.rgb),e.rgb)),Sx=on(([e,t=pn(1)])=>{const r=Ca(e.r,e.g,e.b).div(3),s=e.r.max(e.g.max(e.b)),i=s.sub(r).mul(t).mul(-3);return iu(e.rgb,s,i)}),Rx=on(([e,t=pn(1)])=>{const r=_n(.57735,.57735,.57735),s=t.cos();return _n(e.rgb.mul(s).add(r.cross(e.rgb).mul(t.sin()).add(r.mul(Ko(r,e.rgb).mul(s.oneMinus())))))}),Ex=(e,t=_n(p.getLuminanceCoefficients(new r)))=>Ko(e,t),Ax=on(([e,t=_n(1),s=_n(0),i=_n(1),n=pn(1),a=_n(p.getLuminanceCoefficients(new r,Ne))])=>{const o=e.rgb.dot(_n(a)),u=Wo(e.rgb.mul(t).add(s),0).toVar(),l=u.pow(i).toVar();return dn(u.r.greaterThan(0),()=>{u.r.assign(l.r)}),dn(u.g.greaterThan(0),()=>{u.g.assign(l.g)}),dn(u.b.greaterThan(0),()=>{u.b.assign(l.b)}),u.assign(o.add(u.sub(o).mul(n))),Rn(u.rgb,e.a)});class wx extends di{static get type(){return"PosterizeNode"}constructor(e,t){super(),this.sourceNode=e,this.stepsNode=t}setup(){const{sourceNode:e,stepsNode:t}=this;return e.mul(t).floor().div(t)}}const Cx=tn(wx).setParameterLength(2);let Mx=null;class Bx extends _p{static get type(){return"ViewportSharedTextureNode"}constructor(e=Hl,t=null){null===Mx&&(Mx=new X),super(e,t,Mx)}getTextureForReference(){return Mx}updateReference(){return this}}const Fx=tn(Bx).setParameterLength(0,2),Lx=new t;class Px extends Ml{static get type(){return"PassTextureNode"}constructor(e,t){super(t),this.passNode=e,this.setUpdateMatrix(!1)}setup(e){return this.passNode.build(e),super.setup(e)}clone(){return new this.constructor(this.passNode,this.value)}}class Dx extends Px{static get type(){return"PassMultipleTextureNode"}constructor(e,t,r=!1){super(e,null),this.textureName=t,this.previousTexture=r}updateTexture(){this.value=this.previousTexture?this.passNode.getPreviousTexture(this.textureName):this.passNode.getTexture(this.textureName)}setup(e){return this.updateTexture(),super.setup(e)}clone(){const e=new this.constructor(this.passNode,this.textureName,this.previousTexture);return e.uvNode=this.uvNode,e.levelNode=this.levelNode,e.biasNode=this.biasNode,e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e}}class Ux extends di{static get type(){return"PassNode"}constructor(e,t,r,s={}){super("vec4"),this.scope=e,this.scene=t,this.camera=r,this.options=s,this._pixelRatio=1,this._width=1,this._height=1;const i=new Y;i.isRenderTargetTexture=!0,i.name="depth";const n=new se(this._width*this._pixelRatio,this._height*this._pixelRatio,{type:be,...s});n.texture.name="output",n.depthTexture=i,this.renderTarget=n,this.overrideMaterial=null,this.transparent=!0,this.opaque=!0,this.contextNode=null,this._contextNodeCache=null,this._textures={output:n.texture,depth:i},this._textureNodes={},this._linearDepthNodes={},this._viewZNodes={},this._previousTextures={},this._previousTextureNodes={},this._cameraNear=Ta(0),this._cameraFar=Ta(0),this._mrt=null,this._layers=null,this._resolutionScale=1,this._viewport=null,this._scissor=null,this.isPassNode=!0,this.updateBeforeType=Zs.FRAME,this.global=!0}setResolutionScale(e){return this._resolutionScale=e,this}getResolutionScale(){return this._resolutionScale}setResolution(e){return d("PassNode: .setResolution() is deprecated. Use .setResolutionScale() instead."),this.setResolutionScale(e)}getResolution(){return d("PassNode: .getResolution() is deprecated. Use .getResolutionScale() instead."),this.getResolutionScale()}setLayers(e){return this._layers=e,this}getLayers(){return this._layers}setMRT(e){return this._mrt=e,this}getMRT(){return this._mrt}getTexture(e){let t=this._textures[e];if(void 0===t){t=this.renderTarget.texture.clone(),t.name=e,this._textures[e]=t,this.renderTarget.textures.push(t)}return t}getPreviousTexture(e){let t=this._previousTextures[e];return void 0===t&&(t=this.getTexture(e).clone(),this._previousTextures[e]=t),t}toggleTexture(e){const t=this._previousTextures[e];if(void 0!==t){const r=this._textures[e],s=this.renderTarget.textures.indexOf(r);this.renderTarget.textures[s]=t,this._textures[e]=t,this._previousTextures[e]=r,this._textureNodes[e].updateTexture(),this._previousTextureNodes[e].updateTexture()}}getTextureNode(e="output"){let t=this._textureNodes[e];return void 0===t&&(t=new Dx(this,e),t.updateTexture(),this._textureNodes[e]=t),t}getPreviousTextureNode(e="output"){let t=this._previousTextureNodes[e];return void 0===t&&(void 0===this._textureNodes[e]&&this.getTextureNode(e),t=new Dx(this,e,!0),t.updateTexture(),this._previousTextureNodes[e]=t),t}getViewZNode(e="depth"){let t=this._viewZNodes[e];if(void 0===t){const r=this._cameraNear,s=this._cameraFar;this._viewZNodes[e]=t=Fp(this.getTextureNode(e),r,s)}return t}getLinearDepthNode(e="depth"){let t=this._linearDepthNodes[e];if(void 0===t){const r=this._cameraNear,s=this._cameraFar,i=this.getViewZNode(e);this._linearDepthNodes[e]=t=Mp(i,r,s)}return t}async compileAsync(e){const t=e.getRenderTarget(),r=e.getMRT();e.setRenderTarget(this.renderTarget),e.setMRT(this._mrt),await e.compileAsync(this.scene,this.camera),e.setRenderTarget(t),e.setMRT(r)}setup({renderer:e}){return this.renderTarget.samples=void 0===this.options.samples?e.samples:this.options.samples,this.renderTarget.texture.type=e.getOutputBufferType(),this.scope===Ux.COLOR?this.getTextureNode():this.getLinearDepthNode()}updateBefore(e){const{renderer:t}=e,{scene:r}=this;let s,i;const n=t.getOutputRenderTarget();n&&!0===n.isXRRenderTarget?(i=1,s=t.xr.getCamera(),t.xr.updateCamera(s),Lx.set(n.width,n.height)):(s=this.camera,i=t.getPixelRatio(),t.getSize(Lx)),this._pixelRatio=i,this.setSize(Lx.width,Lx.height);const a=t.getRenderTarget(),o=t.getMRT(),u=t.autoClear,l=t.transparent,d=t.opaque,c=s.layers.mask,h=t.contextNode,p=r.overrideMaterial;this._cameraNear.value=s.near,this._cameraFar.value=s.far,null!==this._layers&&(s.layers.mask=this._layers.mask);for(const e in this._previousTextures)this.toggleTexture(e);null!==this.overrideMaterial&&(r.overrideMaterial=this.overrideMaterial),t.setRenderTarget(this.renderTarget),t.setMRT(this._mrt),t.autoClear=!0,t.transparent=this.transparent,t.opaque=this.opaque,null!==this.contextNode&&(null!==this._contextNodeCache&&this._contextNodeCache.version===this.version||(this._contextNodeCache={version:this.version,context:xu({...t.contextNode.getFlowContextData(),...this.contextNode.getFlowContextData()})}),t.contextNode=this._contextNodeCache.context);const g=r.name;r.name=this.name?this.name:r.name,t.render(r,s),r.name=g,r.overrideMaterial=p,t.setRenderTarget(a),t.setMRT(o),t.autoClear=u,t.transparent=l,t.opaque=d,t.contextNode=h,s.layers.mask=c}setSize(e,t){this._width=e,this._height=t;const r=Math.floor(this._width*this._pixelRatio*this._resolutionScale),s=Math.floor(this._height*this._pixelRatio*this._resolutionScale);this.renderTarget.setSize(r,s),null!==this._scissor&&this.renderTarget.scissor.copy(this._scissor),null!==this._viewport&&this.renderTarget.viewport.copy(this._viewport)}setScissor(e,t,r,i){null===e?this._scissor=null:(null===this._scissor&&(this._scissor=new s),e.isVector4?this._scissor.copy(e):this._scissor.set(e,t,r,i),this._scissor.multiplyScalar(this._pixelRatio*this._resolutionScale).floor())}setViewport(e,t,r,i){null===e?this._viewport=null:(null===this._viewport&&(this._viewport=new s),e.isVector4?this._viewport.copy(e):this._viewport.set(e,t,r,i),this._viewport.multiplyScalar(this._pixelRatio*this._resolutionScale).floor())}setPixelRatio(e){this._pixelRatio=e,this.setSize(this._width,this._height)}dispose(){this.renderTarget.dispose()}}Ux.COLOR="color",Ux.DEPTH="depth";class Ix extends Ux{static get type(){return"ToonOutlinePassNode"}constructor(e,t,r,s,i){super(Ux.COLOR,e,t),this.colorNode=r,this.thicknessNode=s,this.alphaNode=i,this._materialCache=new WeakMap,this.name="Outline Pass"}updateBefore(e){const{renderer:t}=e,r=t.getRenderObjectFunction();t.setRenderObjectFunction((e,r,s,i,n,a,o,u)=>{if((n.isMeshToonMaterial||n.isMeshToonNodeMaterial)&&!1===n.wireframe){const l=this._getOutlineMaterial(n);t.renderObject(e,r,s,i,l,a,o,u)}t.renderObject(e,r,s,i,n,a,o,u)}),super.updateBefore(e),t.setRenderObjectFunction(r)}_createMaterial(){const e=new Qp;e.isMeshToonOutlineMaterial=!0,e.name="Toon_Outline",e.side=M;const t=$d.negate(),r=rd.mul(Ed),s=pn(1),i=r.mul(Rn(Fd,1)),n=r.mul(Rn(Fd.add(t),1)),a=_o(i.sub(n));return e.vertexNode=i.add(a.mul(this.thicknessNode).mul(i.w).mul(s)),e.colorNode=Rn(this.colorNode,this.alphaNode),e}_getOutlineMaterial(e){let t=this._materialCache.get(e);return void 0===t&&(t=this._createMaterial(),this._materialCache.set(e,t)),t}}const Ox=on(([e,t])=>e.mul(t).clamp()).setLayout({name:"linearToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),Vx=on(([e,t])=>(e=e.mul(t)).div(e.add(1)).clamp()).setLayout({name:"reinhardToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),kx=on(([e,t])=>{const r=(e=(e=e.mul(t)).sub(.004).max(0)).mul(e.mul(6.2).add(.5)),s=e.mul(e.mul(6.2).add(1.7)).add(.06);return r.div(s).pow(2.2)}).setLayout({name:"cineonToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),Gx=on(([e])=>{const t=e.mul(e.add(.0245786)).sub(90537e-9),r=e.mul(e.add(.432951).mul(.983729)).add(.238081);return t.div(r)}),zx=on(([e,t])=>{const r=Mn(.59719,.35458,.04823,.076,.90834,.01566,.0284,.13383,.83777),s=Mn(1.60475,-.53108,-.07367,-.10208,1.10813,-.00605,-.00327,-.07276,1.07602);return e=e.mul(t).div(.6),e=r.mul(e),e=Gx(e),(e=s.mul(e)).clamp()}).setLayout({name:"acesFilmicToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),$x=Mn(_n(1.6605,-.1246,-.0182),_n(-.5876,1.1329,-.1006),_n(-.0728,-.0083,1.1187)),Wx=Mn(_n(.6274,.0691,.0164),_n(.3293,.9195,.088),_n(.0433,.0113,.8956)),Hx=on(([e])=>{const t=_n(e).toVar(),r=_n(t.mul(t)).toVar(),s=_n(r.mul(r)).toVar();return pn(15.5).mul(s.mul(r)).sub(Ba(40.14,s.mul(t))).add(Ba(31.96,s).sub(Ba(6.868,r.mul(t))).add(Ba(.4298,r).add(Ba(.1191,t).sub(.00232))))}),qx=on(([e,t])=>{const r=_n(e).toVar(),s=Mn(_n(.856627153315983,.137318972929847,.11189821299995),_n(.0951212405381588,.761241990602591,.0767994186031903),_n(.0482516061458583,.101439036467562,.811302368396859)),i=Mn(_n(1.1271005818144368,-.1413297634984383,-.14132976349843826),_n(-.11060664309660323,1.157823702216272,-.11060664309660294),_n(-.016493938717834573,-.016493938717834257,1.2519364065950405)),n=pn(-12.47393),a=pn(4.026069);return r.mulAssign(t),r.assign(Wx.mul(r)),r.assign(s.mul(r)),r.assign(Wo(r,1e-10)),r.assign(fo(r)),r.assign(r.sub(n).div(a.sub(n))),r.assign(nu(r,0,1)),r.assign(Hx(r)),r.assign(i.mul(r)),r.assign(Qo(Wo(_n(0),r),_n(2.2))),r.assign($x.mul(r)),r.assign(nu(r,0,1)),r}).setLayout({name:"agxToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),jx=on(([e,t])=>{const r=pn(.76),s=pn(.15);e=e.mul(t);const i=$o(e.r,$o(e.g,e.b)),n=yu(i.lessThan(.08),i.sub(Ba(6.25,i.mul(i))),.04);e.subAssign(n);const a=Wo(e.r,Wo(e.g,e.b));dn(a.lessThan(r),()=>e);const o=Ma(1,r),u=Ma(1,o.mul(o).div(a.add(o.sub(r))));e.mulAssign(u.div(a));const l=Ma(1,Fa(1,s.mul(a.sub(u)).add(1)));return iu(e,_n(u),l)}).setLayout({name:"neutralToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]});class Xx extends oi{static get type(){return"CodeNode"}constructor(e="",t=[],r=""){super("code"),this.isCodeNode=!0,this.global=!0,this.code=e,this.includes=t,this.language=r}setIncludes(e){return this.includes=e,this}getIncludes(){return this.includes}generate(e){const t=this.getIncludes(e);for(const r of t)r.build(e);const r=e.getCodeFromNode(this,this.getNodeType(e));return r.code=this.code,r.code}serialize(e){super.serialize(e),e.code=this.code,e.language=this.language}deserialize(e){super.deserialize(e),this.code=e.code,this.language=e.language}}const Kx=tn(Xx).setParameterLength(1,3);class Yx extends Xx{static get type(){return"FunctionNode"}constructor(e="",t=[],r=""){super(e,t,r)}getNodeType(e){return this.getNodeFunction(e).type}getMemberType(e,t){const r=this.getNodeType(e);return e.getStructTypeNode(r).getMemberType(e,t)}getInputs(e){return this.getNodeFunction(e).inputs}getNodeFunction(e){const t=e.getDataFromNode(this);let r=t.nodeFunction;return void 0===r&&(r=e.parser.parseFunction(this.code),t.nodeFunction=r),r}generate(e,t){super.generate(e);const r=this.getNodeFunction(e),s=r.name,i=r.type,n=e.getCodeFromNode(this,i);""!==s&&(n.name=s);const a=e.getPropertyName(n),o=this.getNodeFunction(e).getCode(a);return n.code=o+"\n","property"===t?a:e.format(`${a}()`,i,t)}}const Qx=(e,t=[],r="")=>{for(let e=0;es.call(...e);return i.functionNode=s,i};class Zx extends oi{static get type(){return"ScriptableValueNode"}constructor(e=null){super(),this._value=e,this._cache=null,this.inputType=null,this.outputType=null,this.events=new u,this.isScriptableValueNode=!0}get isScriptableOutputNode(){return null!==this.outputType}set value(e){this._value!==e&&(this._cache&&"URL"===this.inputType&&this.value.value instanceof ArrayBuffer&&(URL.revokeObjectURL(this._cache),this._cache=null),this._value=e,this.events.dispatchEvent({type:"change"}),this.refresh())}get value(){return this._value}refresh(){this.events.dispatchEvent({type:"refresh"})}getValue(){const e=this.value;if(e&&null===this._cache&&"URL"===this.inputType&&e.value instanceof ArrayBuffer)this._cache=URL.createObjectURL(new Blob([e.value]));else if(e&&null!==e.value&&void 0!==e.value&&(("URL"===this.inputType||"String"===this.inputType)&&"string"==typeof e.value||"Number"===this.inputType&&"number"==typeof e.value||"Vector2"===this.inputType&&e.value.isVector2||"Vector3"===this.inputType&&e.value.isVector3||"Vector4"===this.inputType&&e.value.isVector4||"Color"===this.inputType&&e.value.isColor||"Matrix3"===this.inputType&&e.value.isMatrix3||"Matrix4"===this.inputType&&e.value.isMatrix4))return e.value;return this._cache||e}getNodeType(e){return this.value&&this.value.isNode?this.value.getNodeType(e):"float"}setup(){return this.value&&this.value.isNode?this.value:pn()}serialize(e){super.serialize(e),null!==this.value?"ArrayBuffer"===this.inputType?e.value=Xs(this.value):e.value=this.value?this.value.toJSON(e.meta).uuid:null:e.value=null,e.inputType=this.inputType,e.outputType=this.outputType}deserialize(e){super.deserialize(e);let t=null;null!==e.value&&(t="ArrayBuffer"===e.inputType?Ks(e.value):"Texture"===e.inputType?e.meta.textures[e.value]:e.meta.nodes[e.value]||null),this.value=t,this.inputType=e.inputType,this.outputType=e.outputType}}const Jx=tn(Zx).setParameterLength(1);class eT extends Map{get(e,t=null,...r){if(this.has(e))return super.get(e);if(null!==t){const s=t(...r);return this.set(e,s),s}}}class tT{constructor(e){this.scriptableNode=e}get parameters(){return this.scriptableNode.parameters}get layout(){return this.scriptableNode.getLayout()}getInputLayout(e){return this.scriptableNode.getInputLayout(e)}get(e){const t=this.parameters[e];return t?t.getValue():null}}const rT=new eT;class sT extends oi{static get type(){return"ScriptableNode"}constructor(e=null,t={}){super(),this.codeNode=e,this.parameters=t,this._local=new eT,this._output=Jx(null),this._outputs={},this._source=this.source,this._method=null,this._object=null,this._value=null,this._needsOutputUpdate=!0,this.onRefresh=this.onRefresh.bind(this),this.isScriptableNode=!0}get source(){return this.codeNode?this.codeNode.code:""}setLocal(e,t){return this._local.set(e,t)}getLocal(e){return this._local.get(e)}onRefresh(){this._refresh()}getInputLayout(e){for(const t of this.getLayout())if(t.inputType&&(t.id===e||t.name===e))return t}getOutputLayout(e){for(const t of this.getLayout())if(t.outputType&&(t.id===e||t.name===e))return t}setOutput(e,t){const r=this._outputs;return void 0===r[e]?r[e]=Jx(t):r[e].value=t,this}getOutput(e){return this._outputs[e]}getParameter(e){return this.parameters[e]}setParameter(e,t){const r=this.parameters;return t&&t.isScriptableNode?(this.deleteParameter(e),r[e]=t,r[e].getDefaultOutput().events.addEventListener("refresh",this.onRefresh)):t&&t.isScriptableValueNode?(this.deleteParameter(e),r[e]=t,r[e].events.addEventListener("refresh",this.onRefresh)):void 0===r[e]?(r[e]=Jx(t),r[e].events.addEventListener("refresh",this.onRefresh)):r[e].value=t,this}getValue(){return this.getDefaultOutput().getValue()}deleteParameter(e){let t=this.parameters[e];return t&&(t.isScriptableNode&&(t=t.getDefaultOutput()),t.events.removeEventListener("refresh",this.onRefresh)),this}clearParameters(){for(const e of Object.keys(this.parameters))this.deleteParameter(e);return this.needsUpdate=!0,this}call(e,...t){const r=this.getObject()[e];if("function"==typeof r)return r(...t)}async callAsync(e,...t){const r=this.getObject()[e];if("function"==typeof r)return"AsyncFunction"===r.constructor.name?await r(...t):r(...t)}getNodeType(e){return this.getDefaultOutputNode().getNodeType(e)}refresh(e=null){null!==e?this.getOutput(e).refresh():this._refresh()}getObject(){if(this.needsUpdate&&this.dispose(),null!==this._object)return this._object;const e=new tT(this),t=rT.get("THREE"),r=rT.get("TSL"),s=this.getMethod(),i=[e,this._local,rT,()=>this.refresh(),(e,t)=>this.setOutput(e,t),t,r];this._object=s(...i);const n=this._object.layout;if(n&&(!1===n.cache&&this._local.clear(),this._output.outputType=n.outputType||null,Array.isArray(n.elements)))for(const e of n.elements){const t=e.id||e.name;e.inputType&&(void 0===this.getParameter(t)&&this.setParameter(t,null),this.getParameter(t).inputType=e.inputType),e.outputType&&(void 0===this.getOutput(t)&&this.setOutput(t,null),this.getOutput(t).outputType=e.outputType)}return this._object}deserialize(e){super.deserialize(e);for(const e in this.parameters){let t=this.parameters[e];t.isScriptableNode&&(t=t.getDefaultOutput()),t.events.addEventListener("refresh",this.onRefresh)}}getLayout(){return this.getObject().layout}getDefaultOutputNode(){const e=this.getDefaultOutput().value;return e&&e.isNode?e:pn()}getDefaultOutput(){return this._exec()._output}getMethod(){if(this.needsUpdate&&this.dispose(),null!==this._method)return this._method;const e=["layout","init","main","dispose"].join(", "),t="\nreturn { ...output, "+e+" };",r="var "+e+"; var output = {};\n"+this.codeNode.code+t;return this._method=new Function(...["parameters","local","global","refresh","setOutput","THREE","TSL"],r),this._method}dispose(){null!==this._method&&(this._object&&"function"==typeof this._object.dispose&&this._object.dispose(),this._method=null,this._object=null,this._source=null,this._value=null,this._needsOutputUpdate=!0,this._output.value=null,this._outputs={})}setup(){return this.getDefaultOutputNode()}getCacheKey(e){const t=[Ds(this.source),this.getDefaultOutputNode().getCacheKey(e)];for(const r in this.parameters)t.push(this.parameters[r].getCacheKey(e));return Us(t)}set needsUpdate(e){!0===e&&this.dispose()}get needsUpdate(){return this.source!==this._source}_exec(){return null===this.codeNode||(!0===this._needsOutputUpdate&&(this._value=this.call("main"),this._needsOutputUpdate=!1),this._output.value=this._value),this}_refresh(){this.needsUpdate=!0,this._exec(),this._output.refresh()}}const iT=tn(sT).setParameterLength(1,2);function nT(e){let t;const r=e.context.getViewZ;return void 0!==r&&(t=r(this)),(t||Ud.z).negate()}const aT=on(([e,t],r)=>{const s=nT(r);return uu(e,t,s)}),oT=on(([e],t)=>{const r=nT(t);return e.mul(e,r,r).negate().exp().oneMinus()}),uT=on(([e,t],r)=>{const s=nT(r),i=t.sub(Pd.y).max(0).toConst().mul(s).toConst();return e.mul(e,i,i).negate().exp().oneMinus()}),lT=on(([e,t])=>Rn(t.toFloat().mix(sa.rgb,e.toVec3()),sa.a));let dT=null,cT=null;class hT extends oi{static get type(){return"RangeNode"}constructor(e=pn(),t=pn()){super(),this.minNode=e,this.maxNode=t}getVectorLength(e){const t=this.getConstNode(this.minNode),r=this.getConstNode(this.maxNode),s=e.getTypeLength(Hs(t.value)),i=e.getTypeLength(Hs(r.value));return s>i?s:i}getNodeType(e){return e.object.count>1?e.getTypeFromLength(this.getVectorLength(e)):"float"}getConstNode(e){let t=null;if(e.traverse(e=>{!0===e.isConstNode&&(t=e)}),null===t)throw new Error('THREE.TSL: No "ConstNode" found in node graph.');return t}setup(e){const t=e.object;let r=null;if(t.count>1){const i=this.getConstNode(this.minNode),n=this.getConstNode(this.maxNode),a=i.value,o=n.value,u=e.getTypeLength(Hs(a)),d=e.getTypeLength(Hs(o));dT=dT||new s,cT=cT||new s,dT.setScalar(0),cT.setScalar(0),1===u?dT.setScalar(a):a.isColor?dT.set(a.r,a.g,a.b,1):dT.set(a.x,a.y,a.z||0,a.w||0),1===d?cT.setScalar(o):o.isColor?cT.set(o.r,o.g,o.b,1):cT.set(o.x,o.y,o.z||0,o.w||0);const c=4,h=c*t.count,p=new Float32Array(h);for(let e=0;enew gT(e,t),fT=mT("numWorkgroups","uvec3"),yT=mT("workgroupId","uvec3"),bT=mT("globalId","uvec3"),xT=mT("localId","uvec3"),TT=mT("subgroupSize","uint");class _T extends oi{constructor(e){super(),this.scope=e}generate(e){const{scope:t}=this,{renderer:r}=e;!0===r.backend.isWebGLBackend?e.addFlowCode(`\t// ${t}Barrier \n`):e.addLineFlowCode(`${t}Barrier()`,this)}}const vT=tn(_T);class NT extends ui{constructor(e,t){super(e,t),this.isWorkgroupInfoElementNode=!0}generate(e,t){let r;const s=e.context.assign;if(r=super.generate(e),!0!==s){const s=this.getNodeType(e);r=e.format(r,s,t)}return r}}class ST extends oi{constructor(e,t,r=0){super(t),this.bufferType=t,this.bufferCount=r,this.isWorkgroupInfoNode=!0,this.elementType=t,this.scope=e,this.name=""}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setScope(e){return this.scope=e,this}getElementType(){return this.elementType}getInputType(){return`${this.scope}Array`}element(e){return new NT(this,e)}generate(e){const t=""!==this.name?this.name:`${this.scope}Array_${this.id}`;return e.getScopedArray(t,this.scope.toLowerCase(),this.bufferType,this.bufferCount)}}class RT extends oi{static get type(){return"AtomicFunctionNode"}constructor(e,t,r){super("uint"),this.method=e,this.pointerNode=t,this.valueNode=r,this.parents=!0}getInputType(e){return this.pointerNode.getNodeType(e)}getNodeType(e){return this.getInputType(e)}generate(e){const t=e.getNodeProperties(this),r=t.parents,s=this.method,i=this.getNodeType(e),n=this.getInputType(e),a=this.pointerNode,o=this.valueNode,u=[];u.push(`&${a.build(e,n)}`),null!==o&&u.push(o.build(e,n));const l=`${e.getMethod(s,i)}( ${u.join(", ")} )`;if(!(!!r&&(1===r.length&&!0===r[0].isStackNode)))return void 0===t.constNode&&(t.constNode=pl(l,i).toConst()),t.constNode.build(e);e.addLineFlowCode(l,this)}}RT.ATOMIC_LOAD="atomicLoad",RT.ATOMIC_STORE="atomicStore",RT.ATOMIC_ADD="atomicAdd",RT.ATOMIC_SUB="atomicSub",RT.ATOMIC_MAX="atomicMax",RT.ATOMIC_MIN="atomicMin",RT.ATOMIC_AND="atomicAnd",RT.ATOMIC_OR="atomicOr",RT.ATOMIC_XOR="atomicXor";const ET=tn(RT),AT=(e,t,r)=>ET(e,t,r).toStack();class wT extends di{static get type(){return"SubgroupFunctionNode"}constructor(e,t=null,r=null){super(),this.method=e,this.aNode=t,this.bNode=r}getInputType(e){const t=this.aNode?this.aNode.getNodeType(e):null,r=this.bNode?this.bNode.getNodeType(e):null;return(e.isMatrix(t)?0:e.getTypeLength(t))>(e.isMatrix(r)?0:e.getTypeLength(r))?t:r}getNodeType(e){const t=this.method;return t===wT.SUBGROUP_ELECT?"bool":t===wT.SUBGROUP_BALLOT?"uvec4":this.getInputType(e)}generate(e,t){const r=this.method,s=this.getNodeType(e),i=this.getInputType(e),n=this.aNode,a=this.bNode,o=[];if(r===wT.SUBGROUP_BROADCAST||r===wT.SUBGROUP_SHUFFLE||r===wT.QUAD_BROADCAST){const t=a.getNodeType(e);o.push(n.build(e,s),a.build(e,"float"===t?"int":s))}else r===wT.SUBGROUP_SHUFFLE_XOR||r===wT.SUBGROUP_SHUFFLE_DOWN||r===wT.SUBGROUP_SHUFFLE_UP?o.push(n.build(e,s),a.build(e,"uint")):(null!==n&&o.push(n.build(e,i)),null!==a&&o.push(a.build(e,i)));const u=0===o.length?"()":`( ${o.join(", ")} )`;return e.format(`${e.getMethod(r,s)}${u}`,s,t)}serialize(e){super.serialize(e),e.method=this.method}deserialize(e){super.deserialize(e),this.method=e.method}}wT.SUBGROUP_ELECT="subgroupElect",wT.SUBGROUP_BALLOT="subgroupBallot",wT.SUBGROUP_ADD="subgroupAdd",wT.SUBGROUP_INCLUSIVE_ADD="subgroupInclusiveAdd",wT.SUBGROUP_EXCLUSIVE_AND="subgroupExclusiveAdd",wT.SUBGROUP_MUL="subgroupMul",wT.SUBGROUP_INCLUSIVE_MUL="subgroupInclusiveMul",wT.SUBGROUP_EXCLUSIVE_MUL="subgroupExclusiveMul",wT.SUBGROUP_AND="subgroupAnd",wT.SUBGROUP_OR="subgroupOr",wT.SUBGROUP_XOR="subgroupXor",wT.SUBGROUP_MIN="subgroupMin",wT.SUBGROUP_MAX="subgroupMax",wT.SUBGROUP_ALL="subgroupAll",wT.SUBGROUP_ANY="subgroupAny",wT.SUBGROUP_BROADCAST_FIRST="subgroupBroadcastFirst",wT.QUAD_SWAP_X="quadSwapX",wT.QUAD_SWAP_Y="quadSwapY",wT.QUAD_SWAP_DIAGONAL="quadSwapDiagonal",wT.SUBGROUP_BROADCAST="subgroupBroadcast",wT.SUBGROUP_SHUFFLE="subgroupShuffle",wT.SUBGROUP_SHUFFLE_XOR="subgroupShuffleXor",wT.SUBGROUP_SHUFFLE_UP="subgroupShuffleUp",wT.SUBGROUP_SHUFFLE_DOWN="subgroupShuffleDown",wT.QUAD_BROADCAST="quadBroadcast";const CT=sn(wT,wT.SUBGROUP_ELECT).setParameterLength(0),MT=sn(wT,wT.SUBGROUP_BALLOT).setParameterLength(1),BT=sn(wT,wT.SUBGROUP_ADD).setParameterLength(1),FT=sn(wT,wT.SUBGROUP_INCLUSIVE_ADD).setParameterLength(1),LT=sn(wT,wT.SUBGROUP_EXCLUSIVE_AND).setParameterLength(1),PT=sn(wT,wT.SUBGROUP_MUL).setParameterLength(1),DT=sn(wT,wT.SUBGROUP_INCLUSIVE_MUL).setParameterLength(1),UT=sn(wT,wT.SUBGROUP_EXCLUSIVE_MUL).setParameterLength(1),IT=sn(wT,wT.SUBGROUP_AND).setParameterLength(1),OT=sn(wT,wT.SUBGROUP_OR).setParameterLength(1),VT=sn(wT,wT.SUBGROUP_XOR).setParameterLength(1),kT=sn(wT,wT.SUBGROUP_MIN).setParameterLength(1),GT=sn(wT,wT.SUBGROUP_MAX).setParameterLength(1),zT=sn(wT,wT.SUBGROUP_ALL).setParameterLength(0),$T=sn(wT,wT.SUBGROUP_ANY).setParameterLength(0),WT=sn(wT,wT.SUBGROUP_BROADCAST_FIRST).setParameterLength(2),HT=sn(wT,wT.QUAD_SWAP_X).setParameterLength(1),qT=sn(wT,wT.QUAD_SWAP_Y).setParameterLength(1),jT=sn(wT,wT.QUAD_SWAP_DIAGONAL).setParameterLength(1),XT=sn(wT,wT.SUBGROUP_BROADCAST).setParameterLength(2),KT=sn(wT,wT.SUBGROUP_SHUFFLE).setParameterLength(2),YT=sn(wT,wT.SUBGROUP_SHUFFLE_XOR).setParameterLength(2),QT=sn(wT,wT.SUBGROUP_SHUFFLE_UP).setParameterLength(2),ZT=sn(wT,wT.SUBGROUP_SHUFFLE_DOWN).setParameterLength(2),JT=sn(wT,wT.QUAD_BROADCAST).setParameterLength(1);let e_;function t_(e){e_=e_||new WeakMap;let t=e_.get(e);return void 0===t&&e_.set(e,t={}),t}function r_(e){const t=t_(e);return t.shadowMatrix||(t.shadowMatrix=Ta("mat4").setGroup(ya).onRenderUpdate(t=>(!0===e.castShadow&&!1!==t.renderer.shadowMap.enabled||(e.shadow.camera.coordinateSystem!==t.camera.coordinateSystem&&(e.shadow.camera.coordinateSystem=t.camera.coordinateSystem,e.shadow.camera.updateProjectionMatrix()),e.shadow.updateMatrices(e)),e.shadow.matrix)))}function s_(e,t=Pd){const r=r_(e).mul(t);return r.xyz.div(r.w)}function i_(e){const t=t_(e);return t.position||(t.position=Ta(new r).setGroup(ya).onRenderUpdate((t,r)=>r.value.setFromMatrixPosition(e.matrixWorld)))}function n_(e){const t=t_(e);return t.targetPosition||(t.targetPosition=Ta(new r).setGroup(ya).onRenderUpdate((t,r)=>r.value.setFromMatrixPosition(e.target.matrixWorld)))}function a_(e){const t=t_(e);return t.viewPosition||(t.viewPosition=Ta(new r).setGroup(ya).onRenderUpdate(({camera:t},s)=>{s.value=s.value||new r,s.value.setFromMatrixPosition(e.matrixWorld),s.value.applyMatrix4(t.matrixWorldInverse)}))}const o_=e=>id.transformDirection(i_(e).sub(n_(e))),u_=(e,t)=>{for(const r of t)if(r.isAnalyticLightNode&&r.light.id===e)return r;return null},l_=new WeakMap,d_=[];class c_ extends oi{static get type(){return"LightsNode"}constructor(){super("vec3"),this.totalDiffuseNode=Dn("vec3","totalDiffuse"),this.totalSpecularNode=Dn("vec3","totalSpecular"),this.outgoingLightNode=Dn("vec3","outgoingLight"),this._lights=[],this._lightNodes=null,this._lightNodesHash=null,this.global=!0}customCacheKey(){const e=this._lights;for(let t=0;te.sort((e,t)=>e.id-t.id))(this._lights),i=e.renderer.library;for(const e of s)if(e.isNode)t.push(Qi(e));else{let s=null;if(null!==r&&(s=u_(e.id,r)),null===s){const r=i.getLightNodeClass(e.constructor);if(null===r){d(`LightsNode.setupNodeLights: Light node not found for ${e.constructor.name}`);continue}let s=null;l_.has(e)?s=l_.get(e):(s=new r(e),l_.set(e,s)),t.push(s)}}this._lightNodes=t}setupDirectLight(e,t,r){const{lightingModel:s,reflectedLight:i}=e.context;s.direct({...r,lightNode:t,reflectedLight:i},e)}setupDirectRectAreaLight(e,t,r){const{lightingModel:s,reflectedLight:i}=e.context;s.directRectArea({...r,lightNode:t,reflectedLight:i},e)}setupLights(e,t){for(const r of t)r.build(e)}getLightNodes(e){return null===this._lightNodes&&this.setupLightsNode(e),this._lightNodes}setup(e){const t=e.lightsNode;e.lightsNode=this;let r=this.outgoingLightNode;const s=e.context,i=s.lightingModel,n=e.getNodeProperties(this);if(i){const{totalDiffuseNode:t,totalSpecularNode:a}=this;s.outgoingLight=r;const o=e.addStack();n.nodes=o.nodes,i.start(e);const{backdrop:u,backdropAlpha:l}=s,{directDiffuse:d,directSpecular:c,indirectDiffuse:h,indirectSpecular:p}=s.reflectedLight;let g=d.add(h);null!==u&&(g=_n(null!==l?l.mix(g,u):u)),t.assign(g),a.assign(c.add(p)),r.assign(t.add(a)),i.finish(e),r=r.bypass(e.removeStack())}else n.nodes=[];return e.lightsNode=t,r}setLights(e){return this._lights=e,this._lightNodes=null,this._lightNodesHash=null,this}getLights(){return this._lights}get hasLights(){return this._lights.length>0}}class h_ extends oi{static get type(){return"ShadowBaseNode"}constructor(e){super(),this.light=e,this.updateBeforeType=Zs.RENDER,this.isShadowBaseNode=!0}setupShadowPosition({context:e,material:t}){p_.assign(t.receivedShadowPositionNode||e.shadowPositionWorld||Pd)}}const p_=Dn("vec3","shadowPositionWorld");function g_(t,r={}){return r.toneMapping=t.toneMapping,r.toneMappingExposure=t.toneMappingExposure,r.outputColorSpace=t.outputColorSpace,r.renderTarget=t.getRenderTarget(),r.activeCubeFace=t.getActiveCubeFace(),r.activeMipmapLevel=t.getActiveMipmapLevel(),r.renderObjectFunction=t.getRenderObjectFunction(),r.pixelRatio=t.getPixelRatio(),r.mrt=t.getMRT(),r.clearColor=t.getClearColor(r.clearColor||new e),r.clearAlpha=t.getClearAlpha(),r.autoClear=t.autoClear,r.scissorTest=t.getScissorTest(),r}function m_(e,t){return t=g_(e,t),e.setMRT(null),e.setRenderObjectFunction(null),e.setClearColor(0,1),e.autoClear=!0,t}function f_(e,t){e.toneMapping=t.toneMapping,e.toneMappingExposure=t.toneMappingExposure,e.outputColorSpace=t.outputColorSpace,e.setRenderTarget(t.renderTarget,t.activeCubeFace,t.activeMipmapLevel),e.setRenderObjectFunction(t.renderObjectFunction),e.setPixelRatio(t.pixelRatio),e.setMRT(t.mrt),e.setClearColor(t.clearColor,t.clearAlpha),e.autoClear=t.autoClear,e.setScissorTest(t.scissorTest)}function y_(e,t={}){return t.background=e.background,t.backgroundNode=e.backgroundNode,t.overrideMaterial=e.overrideMaterial,t}function b_(e,t){return t=y_(e,t),e.background=null,e.backgroundNode=null,e.overrideMaterial=null,t}function x_(e,t){e.background=t.background,e.backgroundNode=t.backgroundNode,e.overrideMaterial=t.overrideMaterial}function T_(e,t,r){return r=b_(t,r=m_(e,r))}function __(e,t,r){f_(e,r),x_(t,r)}var v_=Object.freeze({__proto__:null,resetRendererAndSceneState:T_,resetRendererState:m_,resetSceneState:b_,restoreRendererAndSceneState:__,restoreRendererState:f_,restoreSceneState:x_,saveRendererAndSceneState:function(e,t,r={}){return r=y_(t,r=g_(e,r))},saveRendererState:g_,saveSceneState:y_});const N_=new WeakMap,S_=on(({depthTexture:e,shadowCoord:t,depthLayer:r})=>{let s=Fl(e,t.xy).setName("t_basic");return e.isArrayTexture&&(s=s.depth(r)),s.compare(t.z)}),R_=on(({depthTexture:e,shadowCoord:t,shadow:r,depthLayer:s})=>{const i=(t,r)=>{let i=Fl(e,t);return e.isArrayTexture&&(i=i.depth(s)),i.compare(r)},n=fc("mapSize","vec2",r).setGroup(ya),a=fc("radius","float",r).setGroup(ya),o=yn(1).div(n),u=a.mul(o.x),l=Qb(jl.xy).mul(6.28318530718);return Ca(i(t.xy.add(Zb(0,5,l).mul(u)),t.z),i(t.xy.add(Zb(1,5,l).mul(u)),t.z),i(t.xy.add(Zb(2,5,l).mul(u)),t.z),i(t.xy.add(Zb(3,5,l).mul(u)),t.z),i(t.xy.add(Zb(4,5,l).mul(u)),t.z)).mul(.2)}),E_=on(({depthTexture:e,shadowCoord:t,shadow:r,depthLayer:s})=>{const i=(t,r)=>{let i=Fl(e,t);return e.isArrayTexture&&(i=i.depth(s)),i.compare(r)},n=fc("mapSize","vec2",r).setGroup(ya),a=yn(1).div(n),o=a.x,u=a.y,l=t.xy,d=vo(l.mul(n).add(.5));return l.subAssign(d.mul(a)),Ca(i(l,t.z),i(l.add(yn(o,0)),t.z),i(l.add(yn(0,u)),t.z),i(l.add(a),t.z),iu(i(l.add(yn(o.negate(),0)),t.z),i(l.add(yn(o.mul(2),0)),t.z),d.x),iu(i(l.add(yn(o.negate(),u)),t.z),i(l.add(yn(o.mul(2),u)),t.z),d.x),iu(i(l.add(yn(0,u.negate())),t.z),i(l.add(yn(0,u.mul(2))),t.z),d.y),iu(i(l.add(yn(o,u.negate())),t.z),i(l.add(yn(o,u.mul(2))),t.z),d.y),iu(iu(i(l.add(yn(o.negate(),u.negate())),t.z),i(l.add(yn(o.mul(2),u.negate())),t.z),d.x),iu(i(l.add(yn(o.negate(),u.mul(2))),t.z),i(l.add(yn(o.mul(2),u.mul(2))),t.z),d.x),d.y)).mul(1/9)}),A_=on(({depthTexture:e,shadowCoord:t,depthLayer:r})=>{let s=Fl(e).sample(t.xy);e.isArrayTexture&&(s=s.depth(r)),s=s.rg;const i=s.x,n=Wo(1e-7,s.y.mul(s.y)),a=Ho(t.z,i),o=pn(1).toVar();return dn(a.notEqual(1),()=>{const e=t.z.sub(i);let r=n.div(n.add(e.mul(e)));r=nu(Ma(r,.3).div(.65)),o.assign(Wo(a,r))}),o}),w_=e=>{let t=N_.get(e);return void 0===t&&(t=new Qp,t.colorNode=Rn(0,0,0,1),t.isShadowPassMaterial=!0,t.name="ShadowMaterial",t.blending=ee,t.fog=!1,N_.set(e,t)),t},C_=e=>{const t=N_.get(e);void 0!==t&&(t.dispose(),N_.delete(e))},M_=new Yf,B_=[],F_=(e,t,r,s)=>{B_[0]=e,B_[1]=t;let i=M_.get(B_);return void 0!==i&&i.shadowType===r&&i.useVelocity===s||(i=(i,n,a,o,u,l,...d)=>{(!0===i.castShadow||i.receiveShadow&&r===Qe)&&(s&&(js(i).useVelocity=!0),i.onBeforeShadow(e,i,a,t.camera,o,n.overrideMaterial,l),e.renderObject(i,n,a,o,u,l,...d),i.onAfterShadow(e,i,a,t.camera,o,n.overrideMaterial,l))},i.shadowType=r,i.useVelocity=s,M_.set(B_,i)),B_[0]=null,B_[1]=null,i},L_=on(({samples:e,radius:t,size:r,shadowPass:s,depthLayer:i})=>{const n=pn(0).toVar("meanVertical"),a=pn(0).toVar("squareMeanVertical"),o=e.lessThanEqual(pn(1)).select(pn(0),pn(2).div(e.sub(1))),u=e.lessThanEqual(pn(1)).select(pn(0),pn(-1));up({start:gn(0),end:gn(e),type:"int",condition:"<"},({i:e})=>{const l=u.add(pn(e).mul(o));let d=s.sample(Ca(jl.xy,yn(0,l).mul(t)).div(r));s.value.isArrayTexture&&(d=d.depth(i)),d=d.x,n.addAssign(d),a.addAssign(d.mul(d))}),n.divAssign(e),a.divAssign(e);const l=yo(a.sub(n.mul(n)).max(0));return yn(n,l)}),P_=on(({samples:e,radius:t,size:r,shadowPass:s,depthLayer:i})=>{const n=pn(0).toVar("meanHorizontal"),a=pn(0).toVar("squareMeanHorizontal"),o=e.lessThanEqual(pn(1)).select(pn(0),pn(2).div(e.sub(1))),u=e.lessThanEqual(pn(1)).select(pn(0),pn(-1));up({start:gn(0),end:gn(e),type:"int",condition:"<"},({i:e})=>{const l=u.add(pn(e).mul(o));let d=s.sample(Ca(jl.xy,yn(l,0).mul(t)).div(r));s.value.isArrayTexture&&(d=d.depth(i)),n.addAssign(d.x),a.addAssign(Ca(d.y.mul(d.y),d.x.mul(d.x)))}),n.divAssign(e),a.divAssign(e);const l=yo(a.sub(n.mul(n)).max(0));return yn(n,l)}),D_=[S_,R_,E_,A_];let U_;const I_=new Wb;class O_ extends h_{static get type(){return"ShadowNode"}constructor(e,t=null){super(e),this.shadow=t||e.shadow,this.shadowMap=null,this.vsmShadowMapVertical=null,this.vsmShadowMapHorizontal=null,this.vsmMaterialVertical=null,this.vsmMaterialHorizontal=null,this._node=null,this._currentShadowType=null,this._cameraFrameId=new WeakMap,this.isShadowNode=!0,this.depthLayer=0}setupShadowFilter(e,{filterFn:t,depthTexture:r,shadowCoord:s,shadow:i,depthLayer:n}){const a=s.x.greaterThanEqual(0).and(s.x.lessThanEqual(1)).and(s.y.greaterThanEqual(0)).and(s.y.lessThanEqual(1)).and(s.z.lessThanEqual(1)),o=t({depthTexture:r,shadowCoord:s,shadow:i,depthLayer:n});return a.select(o,pn(1))}setupShadowCoord(e,t){const{shadow:r}=this,{renderer:s}=e,i=r.biasNode||fc("bias","float",r).setGroup(ya);let n,a=t;if(r.camera.isOrthographicCamera||!0!==s.logarithmicDepthBuffer)a=a.xyz.div(a.w),n=a.z,s.coordinateSystem===h&&(n=n.mul(2).sub(1));else{const e=a.w;a=a.xy.div(e);const t=fc("near","float",r.camera).setGroup(ya),s=fc("far","float",r.camera).setGroup(ya);n=Lp(e.negate(),t,s)}return a=_n(a.x,a.y.oneMinus(),n.add(i)),a}getShadowFilterFn(e){return D_[e]}setupRenderTarget(e,t){const r=new Y(e.mapSize.width,e.mapSize.height);r.name="ShadowDepthTexture",r.compareFunction=Ze;const s=t.createRenderTarget(e.mapSize.width,e.mapSize.height);return s.texture.name="ShadowMap",s.texture.type=e.mapType,s.depthTexture=r,{shadowMap:s,depthTexture:r}}setupShadow(e){const{renderer:t,camera:r}=e,{light:s,shadow:i}=this,{depthTexture:n,shadowMap:a}=this.setupRenderTarget(i,e),o=t.shadowMap.type;if(o===Je||o===et?(n.minFilter=oe,n.magFilter=oe):(n.minFilter=w,n.magFilter=w),i.camera.coordinateSystem=r.coordinateSystem,i.camera.updateProjectionMatrix(),o===Qe&&!0!==i.isPointLightShadow){n.compareFunction=null,a.depth>1?(a._vsmShadowMapVertical||(a._vsmShadowMapVertical=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depth:a.depth,depthBuffer:!1}),a._vsmShadowMapVertical.texture.name="VSMVertical"),this.vsmShadowMapVertical=a._vsmShadowMapVertical,a._vsmShadowMapHorizontal||(a._vsmShadowMapHorizontal=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depth:a.depth,depthBuffer:!1}),a._vsmShadowMapHorizontal.texture.name="VSMHorizontal"),this.vsmShadowMapHorizontal=a._vsmShadowMapHorizontal):(this.vsmShadowMapVertical=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depthBuffer:!1}),this.vsmShadowMapHorizontal=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depthBuffer:!1}));let t=Fl(n);n.isArrayTexture&&(t=t.depth(this.depthLayer));let r=Fl(this.vsmShadowMapVertical.texture);n.isArrayTexture&&(r=r.depth(this.depthLayer));const s=fc("blurSamples","float",i).setGroup(ya),o=fc("radius","float",i).setGroup(ya),u=fc("mapSize","vec2",i).setGroup(ya);let l=this.vsmMaterialVertical||(this.vsmMaterialVertical=new Qp);l.fragmentNode=L_({samples:s,radius:o,size:u,shadowPass:t,depthLayer:this.depthLayer}).context(e.getSharedContext()),l.name="VSMVertical",l=this.vsmMaterialHorizontal||(this.vsmMaterialHorizontal=new Qp),l.fragmentNode=P_({samples:s,radius:o,size:u,shadowPass:r,depthLayer:this.depthLayer}).context(e.getSharedContext()),l.name="VSMHorizontal"}const u=fc("intensity","float",i).setGroup(ya),l=fc("normalBias","float",i).setGroup(ya),d=r_(s).mul(p_.add(Xd.mul(l))),c=this.setupShadowCoord(e,d),h=i.filterNode||this.getShadowFilterFn(t.shadowMap.type)||null;if(null===h)throw new Error("THREE.WebGPURenderer: Shadow map type not supported yet.");const p=o===Qe&&!0!==i.isPointLightShadow?this.vsmShadowMapHorizontal.texture:n,g=this.setupShadowFilter(e,{filterFn:h,shadowTexture:a.texture,depthTexture:p,shadowCoord:c,shadow:i,depthLayer:this.depthLayer});let m,f;!0===t.shadowMap.transmitted&&(a.texture.isCubeTexture?m=pc(a.texture,c.xyz):(m=Fl(a.texture,c),n.isArrayTexture&&(m=m.depth(this.depthLayer)))),f=m?iu(1,g.rgb.mix(m,1),u.mul(m.a)).toVar():iu(1,g,u).toVar(),this.shadowMap=a,this.shadow.map=a;const y=`${this.light.type} Shadow [ ${this.light.name||"ID: "+this.light.id} ]`;return m&&f.toInspector(`${y} / Color`,()=>this.shadowMap.texture.isCubeTexture?pc(this.shadowMap.texture):Fl(this.shadowMap.texture)),f.toInspector(`${y} / Depth`,()=>this.shadowMap.texture.isCubeTexture?pc(this.shadowMap.texture).r.oneMinus():Ll(this.shadowMap.depthTexture,Sl().mul(El(Fl(this.shadowMap.depthTexture)))).r.oneMinus())}setup(e){if(!1!==e.renderer.shadowMap.enabled)return on(()=>{const t=e.renderer.shadowMap.type;this._currentShadowType!==t&&(this._reset(),this._node=null);let r=this._node;return this.setupShadowPosition(e),null===r&&(this._node=r=this.setupShadow(e),this._currentShadowType=t),e.material.receivedShadowNode&&(r=e.material.receivedShadowNode(r)),r})()}renderShadow(e){const{shadow:t,shadowMap:r,light:s}=this,{renderer:i,scene:n}=e;t.updateMatrices(s),r.setSize(t.mapSize.width,t.mapSize.height,r.depth);const a=n.name;n.name=`Shadow Map [ ${s.name||"ID: "+s.id} ]`,i.render(n,t.camera),n.name=a}updateShadow(e){const{shadowMap:t,light:r,shadow:s}=this,{renderer:i,scene:n,camera:a}=e,o=i.shadowMap.type,u=t.depthTexture.version;this._depthVersionCached=u;const l=s.camera.layers.mask;4294967294&s.camera.layers.mask||(s.camera.layers.mask=a.layers.mask);const d=i.getRenderObjectFunction(),c=i.getMRT(),h=!!c&&c.has("velocity");U_=T_(i,n,U_),n.overrideMaterial=w_(r),i.setRenderObjectFunction(F_(i,s,o,h)),i.setClearColor(0,0),i.setRenderTarget(t),this.renderShadow(e),i.setRenderObjectFunction(d),o===Qe&&!0!==s.isPointLightShadow&&this.vsmPass(i),s.camera.layers.mask=l,__(i,n,U_)}vsmPass(e){const{shadow:t}=this,r=this.shadowMap.depth;this.vsmShadowMapVertical.setSize(t.mapSize.width,t.mapSize.height,r),this.vsmShadowMapHorizontal.setSize(t.mapSize.width,t.mapSize.height,r),e.setRenderTarget(this.vsmShadowMapVertical),I_.material=this.vsmMaterialVertical,I_.render(e),e.setRenderTarget(this.vsmShadowMapHorizontal),I_.material=this.vsmMaterialHorizontal,I_.render(e)}dispose(){this._reset(),super.dispose()}_reset(){this._currentShadowType=null,C_(this.light),this.shadowMap&&(this.shadowMap.dispose(),this.shadowMap=null),null!==this.vsmShadowMapVertical&&(this.vsmShadowMapVertical.dispose(),this.vsmShadowMapVertical=null,this.vsmMaterialVertical.dispose(),this.vsmMaterialVertical=null),null!==this.vsmShadowMapHorizontal&&(this.vsmShadowMapHorizontal.dispose(),this.vsmShadowMapHorizontal=null,this.vsmMaterialHorizontal.dispose(),this.vsmMaterialHorizontal=null)}updateBefore(e){const{shadow:t}=this;let r=t.needsUpdate||t.autoUpdate;r&&(this._cameraFrameId[e.camera]===e.frameId&&(r=!1),this._cameraFrameId[e.camera]=e.frameId),r&&(this.updateShadow(e),this.shadowMap.depthTexture.version===this._depthVersionCached&&(t.needsUpdate=!1))}}const V_=(e,t)=>new O_(e,t),k_=new e,G_=new a,z_=new r,$_=new r,W_=[new r(1,0,0),new r(-1,0,0),new r(0,-1,0),new r(0,1,0),new r(0,0,1),new r(0,0,-1)],H_=[new r(0,-1,0),new r(0,-1,0),new r(0,0,-1),new r(0,0,1),new r(0,-1,0),new r(0,-1,0)],q_=[new r(1,0,0),new r(-1,0,0),new r(0,1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1)],j_=[new r(0,-1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1),new r(0,-1,0),new r(0,-1,0)],X_=on(({depthTexture:e,bd3D:t,dp:r})=>pc(e,t).compare(r)),K_=on(({depthTexture:e,bd3D:t,dp:r,shadow:s})=>{const i=fc("radius","float",s).setGroup(ya),n=fc("mapSize","vec2",s).setGroup(ya),a=i.div(n.x),o=Co(t),u=_o(Yo(t,o.x.greaterThan(o.z).select(_n(0,1,0),_n(1,0,0)))),l=Yo(t,u),d=Qb(jl.xy).mul(6.28318530718),c=Zb(0,5,d),h=Zb(1,5,d),p=Zb(2,5,d),g=Zb(3,5,d),m=Zb(4,5,d);return pc(e,t.add(u.mul(c.x).add(l.mul(c.y)).mul(a))).compare(r).add(pc(e,t.add(u.mul(h.x).add(l.mul(h.y)).mul(a))).compare(r)).add(pc(e,t.add(u.mul(p.x).add(l.mul(p.y)).mul(a))).compare(r)).add(pc(e,t.add(u.mul(g.x).add(l.mul(g.y)).mul(a))).compare(r)).add(pc(e,t.add(u.mul(m.x).add(l.mul(m.y)).mul(a))).compare(r)).mul(.2)}),Y_=on(({filterFn:e,depthTexture:t,shadowCoord:r,shadow:s})=>{const i=r.xyz.toConst(),n=i.abs().toConst(),a=n.x.max(n.y).max(n.z),o=Ta("float").setGroup(ya).onRenderUpdate(()=>s.camera.near),u=Ta("float").setGroup(ya).onRenderUpdate(()=>s.camera.far),l=fc("bias","float",s).setGroup(ya),d=pn(1).toVar();return dn(a.sub(u).lessThanEqual(0).and(a.sub(o).greaterThanEqual(0)),()=>{const r=Bp(a.negate(),o,u);r.addAssign(l);const n=i.normalize();d.assign(e({depthTexture:t,bd3D:n,dp:r,shadow:s}))}),d});class Q_ extends O_{static get type(){return"PointShadowNode"}constructor(e,t=null){super(e,t)}getShadowFilterFn(e){return e===tt?X_:K_}setupShadowCoord(e,t){return t}setupShadowFilter(e,{filterFn:t,depthTexture:r,shadowCoord:s,shadow:i}){return Y_({filterFn:t,depthTexture:r,shadowCoord:s,shadow:i})}setupRenderTarget(e,t){const r=new rt(e.mapSize.width);r.name="PointShadowDepthTexture",r.compareFunction=Ze;const s=t.createCubeRenderTarget(e.mapSize.width);return s.texture.name="PointShadowMap",s.depthTexture=r,{shadowMap:s,depthTexture:r}}renderShadow(e){const{shadow:t,shadowMap:r,light:s}=this,{renderer:i,scene:n}=e,a=t.camera,o=t.matrix,u=i.coordinateSystem===h,l=u?W_:q_,d=u?H_:j_;r.setSize(t.mapSize.width,t.mapSize.width);const c=i.autoClear,p=i.getClearColor(k_),g=i.getClearAlpha();i.autoClear=!1,i.setClearColor(t.clearColor,t.clearAlpha);for(let e=0;e<6;e++){i.setRenderTarget(r,e),i.clear();const u=s.distance||a.far;u!==a.far&&(a.far=u,a.updateProjectionMatrix()),z_.setFromMatrixPosition(s.matrixWorld),a.position.copy(z_),$_.copy(a.position),$_.add(l[e]),a.up.copy(d[e]),a.lookAt($_),a.updateMatrixWorld(),o.makeTranslation(-z_.x,-z_.y,-z_.z),G_.multiplyMatrices(a.projectionMatrix,a.matrixWorldInverse),t._frustum.setFromProjectionMatrix(G_,a.coordinateSystem,a.reversedDepth);const c=n.name;n.name=`Point Light Shadow [ ${s.name||"ID: "+s.id} ] - Face ${e+1}`,i.render(n,a),n.name=c}i.autoClear=c,i.setClearColor(p,g)}}const Z_=(e,t)=>new Q_(e,t);class J_ extends mp{static get type(){return"AnalyticLightNode"}constructor(t=null){super(),this.light=t,this.color=new e,this.colorNode=t&&t.colorNode||Ta(this.color).setGroup(ya),this.baseColorNode=null,this.shadowNode=null,this.shadowColorNode=null,this.isAnalyticLightNode=!0,this.updateType=Zs.FRAME,t&&t.shadow&&(this._shadowDisposeListener=()=>{this.disposeShadow()},t.addEventListener("dispose",this._shadowDisposeListener))}dispose(){this._shadowDisposeListener&&this.light.removeEventListener("dispose",this._shadowDisposeListener),super.dispose()}disposeShadow(){null!==this.shadowNode&&(this.shadowNode.dispose(),this.shadowNode=null),this.shadowColorNode=null,null!==this.baseColorNode&&(this.colorNode=this.baseColorNode,this.baseColorNode=null)}getHash(){return this.light.uuid}getLightVector(e){return a_(this.light).sub(e.context.positionView||Ud)}setupDirect(){}setupDirectRectArea(){}setupShadowNode(){return V_(this.light)}setupShadow(e){const{renderer:t}=e;if(!1===t.shadowMap.enabled)return;let r=this.shadowColorNode;if(null===r){const e=this.light.shadow.shadowNode;let t;t=void 0!==e?Qi(e):this.setupShadowNode(),this.shadowNode=t,this.shadowColorNode=r=this.colorNode.mul(t),this.baseColorNode=this.colorNode}e.context.getShadow&&(r=e.context.getShadow(this,e)),this.colorNode=r}setup(e){this.colorNode=this.baseColorNode||this.colorNode,this.light.castShadow?e.object.receiveShadow&&this.setupShadow(e):null!==this.shadowNode&&(this.shadowNode.dispose(),this.shadowNode=null,this.shadowColorNode=null);const t=this.setupDirect(e),r=this.setupDirectRectArea(e);t&&e.lightsNode.setupDirectLight(e,this,t),r&&e.lightsNode.setupDirectRectAreaLight(e,this,r)}update(){const{light:e}=this;this.color.copy(e.color).multiplyScalar(e.intensity)}}const ev=on(({lightDistance:e,cutoffDistance:t,decayExponent:r})=>{const s=e.pow(r).max(.01).reciprocal();return t.greaterThan(0).select(s.mul(e.div(t).pow4().oneMinus().clamp().pow2()),s)}),tv=({color:e,lightVector:t,cutoffDistance:r,decayExponent:s})=>{const i=t.normalize(),n=t.length(),a=ev({lightDistance:n,cutoffDistance:r,decayExponent:s});return{lightDirection:i,lightColor:e.mul(a)}};class rv extends J_{static get type(){return"PointLightNode"}constructor(e=null){super(e),this.cutoffDistanceNode=Ta(0).setGroup(ya),this.decayExponentNode=Ta(2).setGroup(ya)}update(e){const{light:t}=this;super.update(e),this.cutoffDistanceNode.value=t.distance,this.decayExponentNode.value=t.decay}setupShadowNode(){return Z_(this.light)}setupDirect(e){return tv({color:this.colorNode,lightVector:this.getLightVector(e),cutoffDistance:this.cutoffDistanceNode,decayExponent:this.decayExponentNode})}}const sv=on(([e=Sl()])=>{const t=e.mul(2),r=t.x.floor(),s=t.y.floor();return r.add(s).mod(2).sign()}),iv=on(([e=Sl()],{renderer:t,material:r})=>{const s=su(e.mul(2).sub(1));let i;if(r.alphaToCoverage&&t.currentSamples>0){const e=pn(s.fwidth()).toVar();i=uu(e.oneMinus(),e.add(1),s).oneMinus()}else i=yu(s.greaterThan(1),0,1);return i}),nv=on(([e,t,r])=>{const s=pn(r).toVar(),i=pn(t).toVar(),n=fn(e).toVar();return yu(n,i,s)}).setLayout({name:"mx_select",type:"float",inputs:[{name:"b",type:"bool"},{name:"t",type:"float"},{name:"f",type:"float"}]}),av=on(([e,t])=>{const r=fn(t).toVar(),s=pn(e).toVar();return yu(r,s.negate(),s)}).setLayout({name:"mx_negate_if",type:"float",inputs:[{name:"val",type:"float"},{name:"b",type:"bool"}]}),ov=on(([e])=>{const t=pn(e).toVar();return gn(xo(t))}).setLayout({name:"mx_floor",type:"int",inputs:[{name:"x",type:"float"}]}),uv=on(([e,t])=>{const r=pn(e).toVar();return t.assign(ov(r)),r.sub(pn(t))}),lv=mb([on(([e,t,r,s,i,n])=>{const a=pn(n).toVar(),o=pn(i).toVar(),u=pn(s).toVar(),l=pn(r).toVar(),d=pn(t).toVar(),c=pn(e).toVar(),h=pn(Ma(1,o)).toVar();return Ma(1,a).mul(c.mul(h).add(d.mul(o))).add(a.mul(l.mul(h).add(u.mul(o))))}).setLayout({name:"mx_bilerp_0",type:"float",inputs:[{name:"v0",type:"float"},{name:"v1",type:"float"},{name:"v2",type:"float"},{name:"v3",type:"float"},{name:"s",type:"float"},{name:"t",type:"float"}]}),on(([e,t,r,s,i,n])=>{const a=pn(n).toVar(),o=pn(i).toVar(),u=_n(s).toVar(),l=_n(r).toVar(),d=_n(t).toVar(),c=_n(e).toVar(),h=pn(Ma(1,o)).toVar();return Ma(1,a).mul(c.mul(h).add(d.mul(o))).add(a.mul(l.mul(h).add(u.mul(o))))}).setLayout({name:"mx_bilerp_1",type:"vec3",inputs:[{name:"v0",type:"vec3"},{name:"v1",type:"vec3"},{name:"v2",type:"vec3"},{name:"v3",type:"vec3"},{name:"s",type:"float"},{name:"t",type:"float"}]})]),dv=mb([on(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=pn(d).toVar(),h=pn(l).toVar(),p=pn(u).toVar(),g=pn(o).toVar(),m=pn(a).toVar(),f=pn(n).toVar(),y=pn(i).toVar(),b=pn(s).toVar(),x=pn(r).toVar(),T=pn(t).toVar(),_=pn(e).toVar(),v=pn(Ma(1,p)).toVar(),N=pn(Ma(1,h)).toVar();return pn(Ma(1,c)).toVar().mul(N.mul(_.mul(v).add(T.mul(p))).add(h.mul(x.mul(v).add(b.mul(p))))).add(c.mul(N.mul(y.mul(v).add(f.mul(p))).add(h.mul(m.mul(v).add(g.mul(p))))))}).setLayout({name:"mx_trilerp_0",type:"float",inputs:[{name:"v0",type:"float"},{name:"v1",type:"float"},{name:"v2",type:"float"},{name:"v3",type:"float"},{name:"v4",type:"float"},{name:"v5",type:"float"},{name:"v6",type:"float"},{name:"v7",type:"float"},{name:"s",type:"float"},{name:"t",type:"float"},{name:"r",type:"float"}]}),on(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=pn(d).toVar(),h=pn(l).toVar(),p=pn(u).toVar(),g=_n(o).toVar(),m=_n(a).toVar(),f=_n(n).toVar(),y=_n(i).toVar(),b=_n(s).toVar(),x=_n(r).toVar(),T=_n(t).toVar(),_=_n(e).toVar(),v=pn(Ma(1,p)).toVar(),N=pn(Ma(1,h)).toVar();return pn(Ma(1,c)).toVar().mul(N.mul(_.mul(v).add(T.mul(p))).add(h.mul(x.mul(v).add(b.mul(p))))).add(c.mul(N.mul(y.mul(v).add(f.mul(p))).add(h.mul(m.mul(v).add(g.mul(p))))))}).setLayout({name:"mx_trilerp_1",type:"vec3",inputs:[{name:"v0",type:"vec3"},{name:"v1",type:"vec3"},{name:"v2",type:"vec3"},{name:"v3",type:"vec3"},{name:"v4",type:"vec3"},{name:"v5",type:"vec3"},{name:"v6",type:"vec3"},{name:"v7",type:"vec3"},{name:"s",type:"float"},{name:"t",type:"float"},{name:"r",type:"float"}]})]),cv=on(([e,t,r])=>{const s=pn(r).toVar(),i=pn(t).toVar(),n=mn(e).toVar(),a=mn(n.bitAnd(mn(7))).toVar(),o=pn(nv(a.lessThan(mn(4)),i,s)).toVar(),u=pn(Ba(2,nv(a.lessThan(mn(4)),s,i))).toVar();return av(o,fn(a.bitAnd(mn(1)))).add(av(u,fn(a.bitAnd(mn(2)))))}).setLayout({name:"mx_gradient_float_0",type:"float",inputs:[{name:"hash",type:"uint"},{name:"x",type:"float"},{name:"y",type:"float"}]}),hv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=pn(t).toVar(),o=mn(e).toVar(),u=mn(o.bitAnd(mn(15))).toVar(),l=pn(nv(u.lessThan(mn(8)),a,n)).toVar(),d=pn(nv(u.lessThan(mn(4)),n,nv(u.equal(mn(12)).or(u.equal(mn(14))),a,i))).toVar();return av(l,fn(u.bitAnd(mn(1)))).add(av(d,fn(u.bitAnd(mn(2)))))}).setLayout({name:"mx_gradient_float_1",type:"float",inputs:[{name:"hash",type:"uint"},{name:"x",type:"float"},{name:"y",type:"float"},{name:"z",type:"float"}]}),pv=mb([cv,hv]),gv=on(([e,t,r])=>{const s=pn(r).toVar(),i=pn(t).toVar(),n=Nn(e).toVar();return _n(pv(n.x,i,s),pv(n.y,i,s),pv(n.z,i,s))}).setLayout({name:"mx_gradient_vec3_0",type:"vec3",inputs:[{name:"hash",type:"uvec3"},{name:"x",type:"float"},{name:"y",type:"float"}]}),mv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=pn(t).toVar(),o=Nn(e).toVar();return _n(pv(o.x,a,n,i),pv(o.y,a,n,i),pv(o.z,a,n,i))}).setLayout({name:"mx_gradient_vec3_1",type:"vec3",inputs:[{name:"hash",type:"uvec3"},{name:"x",type:"float"},{name:"y",type:"float"},{name:"z",type:"float"}]}),fv=mb([gv,mv]),yv=on(([e])=>{const t=pn(e).toVar();return Ba(.6616,t)}).setLayout({name:"mx_gradient_scale2d_0",type:"float",inputs:[{name:"v",type:"float"}]}),bv=on(([e])=>{const t=pn(e).toVar();return Ba(.982,t)}).setLayout({name:"mx_gradient_scale3d_0",type:"float",inputs:[{name:"v",type:"float"}]}),xv=mb([yv,on(([e])=>{const t=_n(e).toVar();return Ba(.6616,t)}).setLayout({name:"mx_gradient_scale2d_1",type:"vec3",inputs:[{name:"v",type:"vec3"}]})]),Tv=mb([bv,on(([e])=>{const t=_n(e).toVar();return Ba(.982,t)}).setLayout({name:"mx_gradient_scale3d_1",type:"vec3",inputs:[{name:"v",type:"vec3"}]})]),_v=on(([e,t])=>{const r=gn(t).toVar(),s=mn(e).toVar();return s.shiftLeft(r).bitOr(s.shiftRight(gn(32).sub(r)))}).setLayout({name:"mx_rotl32",type:"uint",inputs:[{name:"x",type:"uint"},{name:"k",type:"int"}]}),vv=on(([e,t,r])=>{e.subAssign(r),e.bitXorAssign(_v(r,gn(4))),r.addAssign(t),t.subAssign(e),t.bitXorAssign(_v(e,gn(6))),e.addAssign(r),r.subAssign(t),r.bitXorAssign(_v(t,gn(8))),t.addAssign(e),e.subAssign(r),e.bitXorAssign(_v(r,gn(16))),r.addAssign(t),t.subAssign(e),t.bitXorAssign(_v(e,gn(19))),e.addAssign(r),r.subAssign(t),r.bitXorAssign(_v(t,gn(4))),t.addAssign(e)}),Nv=on(([e,t,r])=>{const s=mn(r).toVar(),i=mn(t).toVar(),n=mn(e).toVar();return s.bitXorAssign(i),s.subAssign(_v(i,gn(14))),n.bitXorAssign(s),n.subAssign(_v(s,gn(11))),i.bitXorAssign(n),i.subAssign(_v(n,gn(25))),s.bitXorAssign(i),s.subAssign(_v(i,gn(16))),n.bitXorAssign(s),n.subAssign(_v(s,gn(4))),i.bitXorAssign(n),i.subAssign(_v(n,gn(14))),s.bitXorAssign(i),s.subAssign(_v(i,gn(24))),s}).setLayout({name:"mx_bjfinal",type:"uint",inputs:[{name:"a",type:"uint"},{name:"b",type:"uint"},{name:"c",type:"uint"}]}),Sv=on(([e])=>{const t=mn(e).toVar();return pn(t).div(pn(mn(gn(4294967295))))}).setLayout({name:"mx_bits_to_01",type:"float",inputs:[{name:"bits",type:"uint"}]}),Rv=on(([e])=>{const t=pn(e).toVar();return t.mul(t).mul(t).mul(t.mul(t.mul(6).sub(15)).add(10))}).setLayout({name:"mx_fade",type:"float",inputs:[{name:"t",type:"float"}]}),Ev=mb([on(([e])=>{const t=gn(e).toVar(),r=mn(mn(1)).toVar(),s=mn(mn(gn(3735928559)).add(r.shiftLeft(mn(2))).add(mn(13))).toVar();return Nv(s.add(mn(t)),s,s)}).setLayout({name:"mx_hash_int_0",type:"uint",inputs:[{name:"x",type:"int"}]}),on(([e,t])=>{const r=gn(t).toVar(),s=gn(e).toVar(),i=mn(mn(2)).toVar(),n=mn().toVar(),a=mn().toVar(),o=mn().toVar();return n.assign(a.assign(o.assign(mn(gn(3735928559)).add(i.shiftLeft(mn(2))).add(mn(13))))),n.addAssign(mn(s)),a.addAssign(mn(r)),Nv(n,a,o)}).setLayout({name:"mx_hash_int_1",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"}]}),on(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=gn(e).toVar(),a=mn(mn(3)).toVar(),o=mn().toVar(),u=mn().toVar(),l=mn().toVar();return o.assign(u.assign(l.assign(mn(gn(3735928559)).add(a.shiftLeft(mn(2))).add(mn(13))))),o.addAssign(mn(n)),u.addAssign(mn(i)),l.addAssign(mn(s)),Nv(o,u,l)}).setLayout({name:"mx_hash_int_2",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"}]}),on(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=gn(t).toVar(),o=gn(e).toVar(),u=mn(mn(4)).toVar(),l=mn().toVar(),d=mn().toVar(),c=mn().toVar();return l.assign(d.assign(c.assign(mn(gn(3735928559)).add(u.shiftLeft(mn(2))).add(mn(13))))),l.addAssign(mn(o)),d.addAssign(mn(a)),c.addAssign(mn(n)),vv(l,d,c),l.addAssign(mn(i)),Nv(l,d,c)}).setLayout({name:"mx_hash_int_3",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xx",type:"int"}]}),on(([e,t,r,s,i])=>{const n=gn(i).toVar(),a=gn(s).toVar(),o=gn(r).toVar(),u=gn(t).toVar(),l=gn(e).toVar(),d=mn(mn(5)).toVar(),c=mn().toVar(),h=mn().toVar(),p=mn().toVar();return c.assign(h.assign(p.assign(mn(gn(3735928559)).add(d.shiftLeft(mn(2))).add(mn(13))))),c.addAssign(mn(l)),h.addAssign(mn(u)),p.addAssign(mn(o)),vv(c,h,p),c.addAssign(mn(a)),h.addAssign(mn(n)),Nv(c,h,p)}).setLayout({name:"mx_hash_int_4",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xx",type:"int"},{name:"yy",type:"int"}]})]),Av=mb([on(([e,t])=>{const r=gn(t).toVar(),s=gn(e).toVar(),i=mn(Ev(s,r)).toVar(),n=Nn().toVar();return n.x.assign(i.bitAnd(gn(255))),n.y.assign(i.shiftRight(gn(8)).bitAnd(gn(255))),n.z.assign(i.shiftRight(gn(16)).bitAnd(gn(255))),n}).setLayout({name:"mx_hash_vec3_0",type:"uvec3",inputs:[{name:"x",type:"int"},{name:"y",type:"int"}]}),on(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=gn(e).toVar(),a=mn(Ev(n,i,s)).toVar(),o=Nn().toVar();return o.x.assign(a.bitAnd(gn(255))),o.y.assign(a.shiftRight(gn(8)).bitAnd(gn(255))),o.z.assign(a.shiftRight(gn(16)).bitAnd(gn(255))),o}).setLayout({name:"mx_hash_vec3_1",type:"uvec3",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"}]})]),wv=mb([on(([e])=>{const t=yn(e).toVar(),r=gn().toVar(),s=gn().toVar(),i=pn(uv(t.x,r)).toVar(),n=pn(uv(t.y,s)).toVar(),a=pn(Rv(i)).toVar(),o=pn(Rv(n)).toVar(),u=pn(lv(pv(Ev(r,s),i,n),pv(Ev(r.add(gn(1)),s),i.sub(1),n),pv(Ev(r,s.add(gn(1))),i,n.sub(1)),pv(Ev(r.add(gn(1)),s.add(gn(1))),i.sub(1),n.sub(1)),a,o)).toVar();return xv(u)}).setLayout({name:"mx_perlin_noise_float_0",type:"float",inputs:[{name:"p",type:"vec2"}]}),on(([e])=>{const t=_n(e).toVar(),r=gn().toVar(),s=gn().toVar(),i=gn().toVar(),n=pn(uv(t.x,r)).toVar(),a=pn(uv(t.y,s)).toVar(),o=pn(uv(t.z,i)).toVar(),u=pn(Rv(n)).toVar(),l=pn(Rv(a)).toVar(),d=pn(Rv(o)).toVar(),c=pn(dv(pv(Ev(r,s,i),n,a,o),pv(Ev(r.add(gn(1)),s,i),n.sub(1),a,o),pv(Ev(r,s.add(gn(1)),i),n,a.sub(1),o),pv(Ev(r.add(gn(1)),s.add(gn(1)),i),n.sub(1),a.sub(1),o),pv(Ev(r,s,i.add(gn(1))),n,a,o.sub(1)),pv(Ev(r.add(gn(1)),s,i.add(gn(1))),n.sub(1),a,o.sub(1)),pv(Ev(r,s.add(gn(1)),i.add(gn(1))),n,a.sub(1),o.sub(1)),pv(Ev(r.add(gn(1)),s.add(gn(1)),i.add(gn(1))),n.sub(1),a.sub(1),o.sub(1)),u,l,d)).toVar();return Tv(c)}).setLayout({name:"mx_perlin_noise_float_1",type:"float",inputs:[{name:"p",type:"vec3"}]})]),Cv=mb([on(([e])=>{const t=yn(e).toVar(),r=gn().toVar(),s=gn().toVar(),i=pn(uv(t.x,r)).toVar(),n=pn(uv(t.y,s)).toVar(),a=pn(Rv(i)).toVar(),o=pn(Rv(n)).toVar(),u=_n(lv(fv(Av(r,s),i,n),fv(Av(r.add(gn(1)),s),i.sub(1),n),fv(Av(r,s.add(gn(1))),i,n.sub(1)),fv(Av(r.add(gn(1)),s.add(gn(1))),i.sub(1),n.sub(1)),a,o)).toVar();return xv(u)}).setLayout({name:"mx_perlin_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"vec2"}]}),on(([e])=>{const t=_n(e).toVar(),r=gn().toVar(),s=gn().toVar(),i=gn().toVar(),n=pn(uv(t.x,r)).toVar(),a=pn(uv(t.y,s)).toVar(),o=pn(uv(t.z,i)).toVar(),u=pn(Rv(n)).toVar(),l=pn(Rv(a)).toVar(),d=pn(Rv(o)).toVar(),c=_n(dv(fv(Av(r,s,i),n,a,o),fv(Av(r.add(gn(1)),s,i),n.sub(1),a,o),fv(Av(r,s.add(gn(1)),i),n,a.sub(1),o),fv(Av(r.add(gn(1)),s.add(gn(1)),i),n.sub(1),a.sub(1),o),fv(Av(r,s,i.add(gn(1))),n,a,o.sub(1)),fv(Av(r.add(gn(1)),s,i.add(gn(1))),n.sub(1),a,o.sub(1)),fv(Av(r,s.add(gn(1)),i.add(gn(1))),n,a.sub(1),o.sub(1)),fv(Av(r.add(gn(1)),s.add(gn(1)),i.add(gn(1))),n.sub(1),a.sub(1),o.sub(1)),u,l,d)).toVar();return Tv(c)}).setLayout({name:"mx_perlin_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec3"}]})]),Mv=mb([on(([e])=>{const t=pn(e).toVar(),r=gn(ov(t)).toVar();return Sv(Ev(r))}).setLayout({name:"mx_cell_noise_float_0",type:"float",inputs:[{name:"p",type:"float"}]}),on(([e])=>{const t=yn(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar();return Sv(Ev(r,s))}).setLayout({name:"mx_cell_noise_float_1",type:"float",inputs:[{name:"p",type:"vec2"}]}),on(([e])=>{const t=_n(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar(),i=gn(ov(t.z)).toVar();return Sv(Ev(r,s,i))}).setLayout({name:"mx_cell_noise_float_2",type:"float",inputs:[{name:"p",type:"vec3"}]}),on(([e])=>{const t=Rn(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar(),i=gn(ov(t.z)).toVar(),n=gn(ov(t.w)).toVar();return Sv(Ev(r,s,i,n))}).setLayout({name:"mx_cell_noise_float_3",type:"float",inputs:[{name:"p",type:"vec4"}]})]),Bv=mb([on(([e])=>{const t=pn(e).toVar(),r=gn(ov(t)).toVar();return _n(Sv(Ev(r,gn(0))),Sv(Ev(r,gn(1))),Sv(Ev(r,gn(2))))}).setLayout({name:"mx_cell_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"float"}]}),on(([e])=>{const t=yn(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar();return _n(Sv(Ev(r,s,gn(0))),Sv(Ev(r,s,gn(1))),Sv(Ev(r,s,gn(2))))}).setLayout({name:"mx_cell_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec2"}]}),on(([e])=>{const t=_n(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar(),i=gn(ov(t.z)).toVar();return _n(Sv(Ev(r,s,i,gn(0))),Sv(Ev(r,s,i,gn(1))),Sv(Ev(r,s,i,gn(2))))}).setLayout({name:"mx_cell_noise_vec3_2",type:"vec3",inputs:[{name:"p",type:"vec3"}]}),on(([e])=>{const t=Rn(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar(),i=gn(ov(t.z)).toVar(),n=gn(ov(t.w)).toVar();return _n(Sv(Ev(r,s,i,n,gn(0))),Sv(Ev(r,s,i,n,gn(1))),Sv(Ev(r,s,i,n,gn(2))))}).setLayout({name:"mx_cell_noise_vec3_3",type:"vec3",inputs:[{name:"p",type:"vec4"}]})]),Fv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=gn(t).toVar(),o=_n(e).toVar(),u=pn(0).toVar(),l=pn(1).toVar();return up(a,()=>{u.addAssign(l.mul(wv(o))),l.mulAssign(i),o.mulAssign(n)}),u}).setLayout({name:"mx_fractal_noise_float",type:"float",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Lv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=gn(t).toVar(),o=_n(e).toVar(),u=_n(0).toVar(),l=pn(1).toVar();return up(a,()=>{u.addAssign(l.mul(Cv(o))),l.mulAssign(i),o.mulAssign(n)}),u}).setLayout({name:"mx_fractal_noise_vec3",type:"vec3",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Pv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=gn(t).toVar(),o=_n(e).toVar();return yn(Fv(o,a,n,i),Fv(o.add(_n(gn(19),gn(193),gn(17))),a,n,i))}).setLayout({name:"mx_fractal_noise_vec2",type:"vec2",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Dv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=gn(t).toVar(),o=_n(e).toVar(),u=_n(Lv(o,a,n,i)).toVar(),l=pn(Fv(o.add(_n(gn(19),gn(193),gn(17))),a,n,i)).toVar();return Rn(u,l)}).setLayout({name:"mx_fractal_noise_vec4",type:"vec4",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Uv=mb([on(([e,t,r,s,i,n,a])=>{const o=gn(a).toVar(),u=pn(n).toVar(),l=gn(i).toVar(),d=gn(s).toVar(),c=gn(r).toVar(),h=gn(t).toVar(),p=yn(e).toVar(),g=_n(Bv(yn(h.add(d),c.add(l)))).toVar(),m=yn(g.x,g.y).toVar();m.subAssign(.5),m.mulAssign(u),m.addAssign(.5);const f=yn(yn(pn(h),pn(c)).add(m)).toVar(),y=yn(f.sub(p)).toVar();return dn(o.equal(gn(2)),()=>Co(y.x).add(Co(y.y))),dn(o.equal(gn(3)),()=>Wo(Co(y.x),Co(y.y))),Ko(y,y)}).setLayout({name:"mx_worley_distance_0",type:"float",inputs:[{name:"p",type:"vec2"},{name:"x",type:"int"},{name:"y",type:"int"},{name:"xoff",type:"int"},{name:"yoff",type:"int"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),on(([e,t,r,s,i,n,a,o,u])=>{const l=gn(u).toVar(),d=pn(o).toVar(),c=gn(a).toVar(),h=gn(n).toVar(),p=gn(i).toVar(),g=gn(s).toVar(),m=gn(r).toVar(),f=gn(t).toVar(),y=_n(e).toVar(),b=_n(Bv(_n(f.add(p),m.add(h),g.add(c)))).toVar();b.subAssign(.5),b.mulAssign(d),b.addAssign(.5);const x=_n(_n(pn(f),pn(m),pn(g)).add(b)).toVar(),T=_n(x.sub(y)).toVar();return dn(l.equal(gn(2)),()=>Co(T.x).add(Co(T.y)).add(Co(T.z))),dn(l.equal(gn(3)),()=>Wo(Co(T.x),Co(T.y),Co(T.z))),Ko(T,T)}).setLayout({name:"mx_worley_distance_1",type:"float",inputs:[{name:"p",type:"vec3"},{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xoff",type:"int"},{name:"yoff",type:"int"},{name:"zoff",type:"int"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),Iv=on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=yn(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=yn(uv(n.x,a),uv(n.y,o)).toVar(),l=pn(1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{const r=pn(Uv(u,e,t,a,o,i,s)).toVar();l.assign($o(l,r))})}),dn(s.equal(gn(0)),()=>{l.assign(yo(l))}),l}).setLayout({name:"mx_worley_noise_float_0",type:"float",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),Ov=on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=yn(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=yn(uv(n.x,a),uv(n.y,o)).toVar(),l=yn(1e6,1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{const r=pn(Uv(u,e,t,a,o,i,s)).toVar();dn(r.lessThan(l.x),()=>{l.y.assign(l.x),l.x.assign(r)}).ElseIf(r.lessThan(l.y),()=>{l.y.assign(r)})})}),dn(s.equal(gn(0)),()=>{l.assign(yo(l))}),l}).setLayout({name:"mx_worley_noise_vec2_0",type:"vec2",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),Vv=on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=yn(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=yn(uv(n.x,a),uv(n.y,o)).toVar(),l=_n(1e6,1e6,1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{const r=pn(Uv(u,e,t,a,o,i,s)).toVar();dn(r.lessThan(l.x),()=>{l.z.assign(l.y),l.y.assign(l.x),l.x.assign(r)}).ElseIf(r.lessThan(l.y),()=>{l.z.assign(l.y),l.y.assign(r)}).ElseIf(r.lessThan(l.z),()=>{l.z.assign(r)})})}),dn(s.equal(gn(0)),()=>{l.assign(yo(l))}),l}).setLayout({name:"mx_worley_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),kv=mb([Iv,on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=_n(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=gn().toVar(),l=_n(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=pn(1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{up({start:-1,end:gn(1),name:"z",condition:"<="},({z:r})=>{const n=pn(Uv(l,e,t,r,a,o,u,i,s)).toVar();d.assign($o(d,n))})})}),dn(s.equal(gn(0)),()=>{d.assign(yo(d))}),d}).setLayout({name:"mx_worley_noise_float_1",type:"float",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),Gv=mb([Ov,on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=_n(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=gn().toVar(),l=_n(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=yn(1e6,1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{up({start:-1,end:gn(1),name:"z",condition:"<="},({z:r})=>{const n=pn(Uv(l,e,t,r,a,o,u,i,s)).toVar();dn(n.lessThan(d.x),()=>{d.y.assign(d.x),d.x.assign(n)}).ElseIf(n.lessThan(d.y),()=>{d.y.assign(n)})})})}),dn(s.equal(gn(0)),()=>{d.assign(yo(d))}),d}).setLayout({name:"mx_worley_noise_vec2_1",type:"vec2",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),zv=mb([Vv,on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=_n(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=gn().toVar(),l=_n(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=_n(1e6,1e6,1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{up({start:-1,end:gn(1),name:"z",condition:"<="},({z:r})=>{const n=pn(Uv(l,e,t,r,a,o,u,i,s)).toVar();dn(n.lessThan(d.x),()=>{d.z.assign(d.y),d.y.assign(d.x),d.x.assign(n)}).ElseIf(n.lessThan(d.y),()=>{d.z.assign(d.y),d.y.assign(n)}).ElseIf(n.lessThan(d.z),()=>{d.z.assign(n)})})})}),dn(s.equal(gn(0)),()=>{d.assign(yo(d))}),d}).setLayout({name:"mx_worley_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),$v=on(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=gn(e).toVar(),h=yn(t).toVar(),p=yn(r).toVar(),g=yn(s).toVar(),m=pn(i).toVar(),f=pn(n).toVar(),y=pn(a).toVar(),b=fn(o).toVar(),x=gn(u).toVar(),T=pn(l).toVar(),_=pn(d).toVar(),v=h.mul(p).add(g),N=pn(0).toVar();return dn(c.equal(gn(0)),()=>{N.assign(Cv(v))}),dn(c.equal(gn(1)),()=>{N.assign(Bv(v))}),dn(c.equal(gn(2)),()=>{N.assign(zv(v,m,gn(0)))}),dn(c.equal(gn(3)),()=>{N.assign(Lv(_n(v,0),x,T,_))}),N.assign(N.mul(y.sub(f)).add(f)),dn(b,()=>{N.assign(nu(N,f,y))}),N}).setLayout({name:"mx_unifiednoise2d",type:"float",inputs:[{name:"noiseType",type:"int"},{name:"texcoord",type:"vec2"},{name:"freq",type:"vec2"},{name:"offset",type:"vec2"},{name:"jitter",type:"float"},{name:"outmin",type:"float"},{name:"outmax",type:"float"},{name:"clampoutput",type:"bool"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Wv=on(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=gn(e).toVar(),h=_n(t).toVar(),p=_n(r).toVar(),g=_n(s).toVar(),m=pn(i).toVar(),f=pn(n).toVar(),y=pn(a).toVar(),b=fn(o).toVar(),x=gn(u).toVar(),T=pn(l).toVar(),_=pn(d).toVar(),v=h.mul(p).add(g),N=pn(0).toVar();return dn(c.equal(gn(0)),()=>{N.assign(Cv(v))}),dn(c.equal(gn(1)),()=>{N.assign(Bv(v))}),dn(c.equal(gn(2)),()=>{N.assign(zv(v,m,gn(0)))}),dn(c.equal(gn(3)),()=>{N.assign(Lv(v,x,T,_))}),N.assign(N.mul(y.sub(f)).add(f)),dn(b,()=>{N.assign(nu(N,f,y))}),N}).setLayout({name:"mx_unifiednoise3d",type:"float",inputs:[{name:"noiseType",type:"int"},{name:"position",type:"vec3"},{name:"freq",type:"vec3"},{name:"offset",type:"vec3"},{name:"jitter",type:"float"},{name:"outmin",type:"float"},{name:"outmax",type:"float"},{name:"clampoutput",type:"bool"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Hv=on(([e])=>{const t=e.y,r=e.z,s=_n().toVar();return dn(t.lessThan(1e-4),()=>{s.assign(_n(r,r,r))}).Else(()=>{let i=e.x;i=i.sub(xo(i)).mul(6).toVar();const n=gn(Oo(i)),a=i.sub(pn(n)),o=r.mul(t.oneMinus()),u=r.mul(t.mul(a).oneMinus()),l=r.mul(t.mul(a.oneMinus()).oneMinus());dn(n.equal(gn(0)),()=>{s.assign(_n(r,l,o))}).ElseIf(n.equal(gn(1)),()=>{s.assign(_n(u,r,o))}).ElseIf(n.equal(gn(2)),()=>{s.assign(_n(o,r,l))}).ElseIf(n.equal(gn(3)),()=>{s.assign(_n(o,u,r))}).ElseIf(n.equal(gn(4)),()=>{s.assign(_n(l,o,r))}).Else(()=>{s.assign(_n(r,o,u))})}),s}).setLayout({name:"mx_hsvtorgb",type:"vec3",inputs:[{name:"hsv",type:"vec3"}]}),qv=on(([e])=>{const t=_n(e).toVar(),r=pn(t.x).toVar(),s=pn(t.y).toVar(),i=pn(t.z).toVar(),n=pn($o(r,$o(s,i))).toVar(),a=pn(Wo(r,Wo(s,i))).toVar(),o=pn(a.sub(n)).toVar(),u=pn().toVar(),l=pn().toVar(),d=pn().toVar();return d.assign(a),dn(a.greaterThan(0),()=>{l.assign(o.div(a))}).Else(()=>{l.assign(0)}),dn(l.lessThanEqual(0),()=>{u.assign(0)}).Else(()=>{dn(r.greaterThanEqual(a),()=>{u.assign(s.sub(i).div(o))}).ElseIf(s.greaterThanEqual(a),()=>{u.assign(Ca(2,i.sub(r).div(o)))}).Else(()=>{u.assign(Ca(4,r.sub(s).div(o)))}),u.mulAssign(1/6),dn(u.lessThan(0),()=>{u.addAssign(1)})}),_n(u,l,d)}).setLayout({name:"mx_rgbtohsv",type:"vec3",inputs:[{name:"c",type:"vec3"}]}),jv=on(([e])=>{const t=_n(e).toVar(),r=Sn(Ia(t,_n(.04045))).toVar(),s=_n(t.div(12.92)).toVar(),i=_n(Qo(Wo(t.add(_n(.055)),_n(0)).div(1.055),_n(2.4))).toVar();return iu(s,i,r)}).setLayout({name:"mx_srgb_texture_to_lin_rec709",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Xv=(e,t)=>{e=pn(e),t=pn(t);const r=yn(t.dFdx(),t.dFdy()).length().mul(.7071067811865476);return uu(e.sub(r),e.add(r),t)},Kv=(e,t,r,s)=>iu(e,t,r[s].clamp()),Yv=(e,t,r,s,i)=>iu(e,t,Xv(r,s[i])),Qv=on(([e,t,r])=>{const s=_o(e).toVar(),i=Ma(pn(.5).mul(t.sub(r)),Pd).div(s).toVar(),n=Ma(pn(-.5).mul(t.sub(r)),Pd).div(s).toVar(),a=_n().toVar();a.x=s.x.greaterThan(pn(0)).select(i.x,n.x),a.y=s.y.greaterThan(pn(0)).select(i.y,n.y),a.z=s.z.greaterThan(pn(0)).select(i.z,n.z);const o=$o(a.x,a.y,a.z).toVar();return Pd.add(s.mul(o)).toVar().sub(r)}),Zv=on(([e,t])=>{const r=e.x,s=e.y,i=e.z;let n=t.element(0).mul(.886227);return n=n.add(t.element(1).mul(1.023328).mul(s)),n=n.add(t.element(2).mul(1.023328).mul(i)),n=n.add(t.element(3).mul(1.023328).mul(r)),n=n.add(t.element(4).mul(.858086).mul(r).mul(s)),n=n.add(t.element(5).mul(.858086).mul(s).mul(i)),n=n.add(t.element(6).mul(i.mul(i).mul(.743125).sub(.247708))),n=n.add(t.element(7).mul(.858086).mul(r).mul(i)),n=n.add(t.element(8).mul(.429043).mul(Ba(r,r).sub(Ba(s,s)))),n});var Jv=Object.freeze({__proto__:null,BRDF_GGX:Dg,BRDF_Lambert:Tg,BasicPointShadowFilter:X_,BasicShadowFilter:S_,Break:lp,Const:wu,Continue:()=>pl("continue").toStack(),DFGLUT:Og,D_GGX:Fg,Discard:gl,EPSILON:ro,F_Schlick:xg,Fn:on,HALF_PI:oo,INFINITY:so,If:dn,Loop:up,NodeAccess:ei,NodeShaderStage:Qs,NodeType:Js,NodeUpdateType:Zs,OnBeforeMaterialUpdate:e=>tx(ex.BEFORE_MATERIAL,e),OnBeforeObjectUpdate:e=>tx(ex.BEFORE_OBJECT,e),OnMaterialUpdate:e=>tx(ex.MATERIAL,e),OnObjectUpdate:e=>tx(ex.OBJECT,e),PCFShadowFilter:R_,PCFSoftShadowFilter:E_,PI:io,PI2:no,PointShadowFilter:K_,Return:()=>pl("return").toStack(),Schlick_to_F0:Gg,ScriptableNodeResources:rT,ShaderNode:Yi,Stack:cn,Switch:(...e)=>Ti.Switch(...e),TBNViewMatrix:$c,TWO_PI:ao,VSMShadowFilter:A_,V_GGX_SmithCorrelated:Mg,Var:Au,VarIntent:Cu,abs:Co,acesFilmicToneMapping:zx,acos:Ao,add:Ca,addMethodChaining:vi,addNodeElement:function(e){d("TSL: AddNodeElement has been removed in favor of tree-shaking. Trying add",e)},agxToneMapping:qx,all:uo,alphaT:Kn,and:ka,anisotropy:Yn,anisotropyB:Zn,anisotropyT:Qn,any:lo,append:e=>(d("TSL: append() has been renamed to Stack()."),cn(e)),array:va,arrayBuffer:e=>new bi(e,"ArrayBuffer"),asin:Eo,assign:Sa,atan:wo,atomicAdd:(e,t)=>AT(RT.ATOMIC_ADD,e,t),atomicAnd:(e,t)=>AT(RT.ATOMIC_AND,e,t),atomicFunc:AT,atomicLoad:e=>AT(RT.ATOMIC_LOAD,e,null),atomicMax:(e,t)=>AT(RT.ATOMIC_MAX,e,t),atomicMin:(e,t)=>AT(RT.ATOMIC_MIN,e,t),atomicOr:(e,t)=>AT(RT.ATOMIC_OR,e,t),atomicStore:(e,t)=>AT(RT.ATOMIC_STORE,e,t),atomicSub:(e,t)=>AT(RT.ATOMIC_SUB,e,t),atomicXor:(e,t)=>AT(RT.ATOMIC_XOR,e,t),attenuationColor:ca,attenuationDistance:da,attribute:Nl,attributeArray:(e,t="float")=>{let r,s;!0===t.isStruct?(r=t.layout.getLength(),s=Gs("float")):(r=zs(t),s=Gs(t));const i=new sx(e,r,s);return Wh(i,t,e)},backgroundBlurriness:ux,backgroundIntensity:lx,backgroundRotation:dx,batch:sp,bentNormalView:Hc,billboarding:_b,bitAnd:Wa,bitNot:Ha,bitOr:qa,bitXor:ja,bitangentGeometry:Vc,bitangentLocal:kc,bitangentView:Gc,bitangentWorld:zc,bitcast:jy,blendBurn:Wp,blendColor:Xp,blendDodge:Hp,blendOverlay:jp,blendScreen:qp,blur:Gm,bool:fn,buffer:Dl,bufferAttribute:Zu,builtin:kl,builtinAOContext:Nu,builtinShadowContext:vu,bumpMap:Jc,bvec2:Tn,bvec3:Sn,bvec4:wn,bypass:ul,cache:al,call:Ea,cameraFar:td,cameraIndex:Jl,cameraNear:ed,cameraNormalMatrix:ad,cameraPosition:od,cameraProjectionMatrix:rd,cameraProjectionMatrixInverse:sd,cameraViewMatrix:id,cameraViewport:ud,cameraWorldMatrix:nd,cbrt:ru,cdl:Ax,ceil:To,checker:sv,cineonToneMapping:kx,clamp:nu,clearcoat:zn,clearcoatNormalView:Kd,clearcoatRoughness:$n,clipSpace:Md,code:Kx,color:hn,colorSpaceToWorking:ku,colorToDirection:e=>Qi(e).mul(2).sub(1),compute:sl,computeKernel:rl,computeSkinning:(e,t=null)=>{const r=new np(e);return r.positionNode=Wh(new W(e.geometry.getAttribute("position").array,3),"vec3").setPBO(!0).toReadOnly().element(jh).toVar(),r.skinIndexNode=Wh(new W(new Uint32Array(e.geometry.getAttribute("skinIndex").array),4),"uvec4").setPBO(!0).toReadOnly().element(jh).toVar(),r.skinWeightNode=Wh(new W(e.geometry.getAttribute("skinWeight").array,4),"vec4").setPBO(!0).toReadOnly().element(jh).toVar(),r.bindMatrixNode=Ta(e.bindMatrix,"mat4"),r.bindMatrixInverseNode=Ta(e.bindMatrixInverse,"mat4"),r.boneMatricesNode=Dl(e.skeleton.boneMatrices,"mat4",e.skeleton.bones.length),r.toPositionNode=t,Qi(r)},context:xu,convert:Ln,convertColorSpace:(e,t,r)=>Qi(new Ou(Qi(e),t,r)),convertToTexture:(e,...t)=>e.isSampleNode||e.isTextureNode?e:e.isPassNode?e.getTextureNode():jb(e,...t),cos:So,countLeadingZeros:Zy,countOneBits:Jy,countTrailingZeros:Qy,cross:Yo,cubeTexture:pc,cubeTextureBase:hc,dFdx:Po,dFdy:Do,dashSize:ia,debug:bl,decrement:Ja,decrementBefore:Qa,defaultBuildStages:ri,defaultShaderStages:ti,defined:Xi,degrees:ho,deltaTime:yb,densityFogFactor:oT,depth:Dp,depthPass:(e,t,r)=>new Ux(Ux.DEPTH,e,t,r),determinant:Go,difference:Xo,diffuseColor:In,diffuseContribution:On,directPointLight:tv,directionToColor:qc,directionToFaceDirection:Gd,dispersion:ha,disposeShadowMaterial:C_,distance:jo,div:Fa,dot:Ko,drawIndex:Qh,dynamicBufferAttribute:(e,t=null,r=0,s=0)=>Qu(e,t,r,s,x),element:Fn,emissive:Vn,equal:Pa,equirectUV:ag,exp:po,exp2:go,exponentialHeightFogFactor:uT,expression:pl,faceDirection:kd,faceForward:lu,faceforward:gu,float:pn,floatBitsToInt:e=>new qy(e,"int","float"),floatBitsToUint:Xy,floor:xo,fog:lT,fract:vo,frameGroup:fa,frameId:bb,frontFacing:Vd,fwidth:Vo,gain:(e,t)=>e.lessThan(.5)?tb(e.mul(2),t).div(2):Ma(1,tb(Ba(Ma(1,e),2),t).div(2)),gapSize:na,getConstNodeType:Ki,getCurrentStack:ln,getDirection:Im,getDistanceAttenuation:ev,getGeometryRoughness:wg,getNormalFromDepth:Yb,getParallaxCorrectNormal:Qv,getRoughness:Cg,getScreenPosition:Kb,getShIrradianceAt:Zv,getShadowMaterial:w_,getShadowRenderObjectFunction:F_,getTextureIndex:$y,getViewPosition:Xb,ggxConvolution:Hm,globalId:bT,glsl:(e,t)=>Kx(e,t,"glsl"),glslFn:(e,t)=>Qx(e,t,"glsl"),grayscale:vx,greaterThan:Ia,greaterThanEqual:Va,hash:eb,highpModelNormalViewMatrix:Cd,highpModelViewMatrix:wd,hue:Rx,increment:Za,incrementBefore:Ya,inspector:_l,instance:Jh,instanceIndex:jh,instancedArray:(e,t="float")=>{let r,s;!0===t.isStruct?(r=t.layout.getLength(),s=Gs("float")):(r=zs(t),s=Gs(t));const i=new rx(e,r,s);return Wh(i,t,e)},instancedBufferAttribute:Ju,instancedDynamicBufferAttribute:el,instancedMesh:tp,int:gn,intBitsToFloat:e=>new qy(e,"float","int"),interleavedGradientNoise:Qb,inverse:zo,inverseSqrt:bo,inversesqrt:mu,invocationLocalIndex:Yh,invocationSubgroupIndex:Kh,ior:oa,iridescence:qn,iridescenceIOR:jn,iridescenceThickness:Xn,isolate:nl,ivec2:bn,ivec3:vn,ivec4:En,js:(e,t)=>Kx(e,t,"js"),label:Su,length:Bo,lengthSq:su,lessThan:Ua,lessThanEqual:Oa,lightPosition:i_,lightProjectionUV:s_,lightShadowMatrix:r_,lightTargetDirection:o_,lightTargetPosition:n_,lightViewPosition:a_,lightingContext:bp,lights:(e=[])=>(new c_).setLights(e),linearDepth:Up,linearToneMapping:Ox,localId:xT,log:mo,log2:fo,logarithmicDepthToViewZ:(e,t,r)=>{const s=e.mul(mo(r.div(t)));return pn(Math.E).pow(s).mul(t).negate()},luminance:Ex,mat2:Cn,mat3:Mn,mat4:Bn,matcapUV:Mf,materialAO:Oh,materialAlphaTest:rh,materialAnisotropy:_h,materialAnisotropyVector:Vh,materialAttenuationColor:Ch,materialAttenuationDistance:wh,materialClearcoat:mh,materialClearcoatNormal:yh,materialClearcoatRoughness:fh,materialColor:sh,materialDispersion:Uh,materialEmissive:nh,materialEnvIntensity:ic,materialEnvRotation:nc,materialIOR:Ah,materialIridescence:vh,materialIridescenceIOR:Nh,materialIridescenceThickness:Sh,materialLightMap:Ih,materialLineDashOffset:Ph,materialLineDashSize:Bh,materialLineGapSize:Fh,materialLineScale:Mh,materialLineWidth:Lh,materialMetalness:ph,materialNormal:gh,materialOpacity:ah,materialPointSize:Dh,materialReference:xc,materialReflectivity:ch,materialRefractionRatio:sc,materialRotation:bh,materialRoughness:hh,materialSheen:xh,materialSheenRoughness:Th,materialShininess:ih,materialSpecular:oh,materialSpecularColor:lh,materialSpecularIntensity:uh,materialSpecularStrength:dh,materialThickness:Eh,materialTransmission:Rh,max:Wo,maxMipLevel:wl,mediumpModelViewMatrix:Ad,metalness:Gn,min:$o,mix:iu,mixElement:cu,mod:La,modInt:eo,modelDirection:bd,modelNormalMatrix:Sd,modelPosition:Td,modelRadius:Nd,modelScale:_d,modelViewMatrix:Ed,modelViewPosition:vd,modelViewProjection:kh,modelWorldMatrix:xd,modelWorldMatrixInverse:Rd,morphReference:gp,mrt:Hy,mul:Ba,mx_aastep:Xv,mx_add:(e,t=pn(0))=>Ca(e,t),mx_atan2:(e=pn(0),t=pn(1))=>wo(e,t),mx_cell_noise_float:(e=Sl())=>Mv(e.convert("vec2|vec3")),mx_contrast:(e,t=1,r=.5)=>pn(e).sub(r).mul(t).add(r),mx_divide:(e,t=pn(1))=>Fa(e,t),mx_fractal_noise_float:(e=Sl(),t=3,r=2,s=.5,i=1)=>Fv(e,gn(t),r,s).mul(i),mx_fractal_noise_vec2:(e=Sl(),t=3,r=2,s=.5,i=1)=>Pv(e,gn(t),r,s).mul(i),mx_fractal_noise_vec3:(e=Sl(),t=3,r=2,s=.5,i=1)=>Lv(e,gn(t),r,s).mul(i),mx_fractal_noise_vec4:(e=Sl(),t=3,r=2,s=.5,i=1)=>Dv(e,gn(t),r,s).mul(i),mx_frame:()=>bb,mx_heighttonormal:(e,t)=>(e=_n(e),t=pn(t),Jc(e,t)),mx_hsvtorgb:Hv,mx_ifequal:(e,t,r,s)=>e.equal(t).mix(r,s),mx_ifgreater:(e,t,r,s)=>e.greaterThan(t).mix(r,s),mx_ifgreatereq:(e,t,r,s)=>e.greaterThanEqual(t).mix(r,s),mx_invert:(e,t=pn(1))=>Ma(t,e),mx_modulo:(e,t=pn(1))=>La(e,t),mx_multiply:(e,t=pn(1))=>Ba(e,t),mx_noise_float:(e=Sl(),t=1,r=0)=>wv(e.convert("vec2|vec3")).mul(t).add(r),mx_noise_vec3:(e=Sl(),t=1,r=0)=>Cv(e.convert("vec2|vec3")).mul(t).add(r),mx_noise_vec4:(e=Sl(),t=1,r=0)=>{e=e.convert("vec2|vec3");return Rn(Cv(e),wv(e.add(yn(19,73)))).mul(t).add(r)},mx_place2d:(e,t=yn(.5,.5),r=yn(1,1),s=pn(0),i=yn(0,0))=>{let n=e;if(t&&(n=n.sub(t)),r&&(n=n.mul(r)),s){const e=s.mul(Math.PI/180),t=e.cos(),r=e.sin();n=yn(n.x.mul(t).sub(n.y.mul(r)),n.x.mul(r).add(n.y.mul(t)))}return t&&(n=n.add(t)),i&&(n=n.add(i)),n},mx_power:(e,t=pn(1))=>Qo(e,t),mx_ramp4:(e,t,r,s,i=Sl())=>{const n=i.x.clamp(),a=i.y.clamp(),o=iu(e,t,n),u=iu(r,s,n);return iu(o,u,a)},mx_ramplr:(e,t,r=Sl())=>Kv(e,t,r,"x"),mx_ramptb:(e,t,r=Sl())=>Kv(e,t,r,"y"),mx_rgbtohsv:qv,mx_rotate2d:(e,t)=>{e=yn(e);const r=(t=pn(t)).mul(Math.PI/180);return Pf(e,r)},mx_rotate3d:(e,t,r)=>{e=_n(e),t=pn(t),r=_n(r);const s=t.mul(Math.PI/180),i=r.normalize(),n=s.cos(),a=s.sin(),o=pn(1).sub(n);return e.mul(n).add(i.cross(e).mul(a)).add(i.mul(i.dot(e)).mul(o))},mx_safepower:(e,t=1)=>(e=pn(e)).abs().pow(t).mul(e.sign()),mx_separate:(e,t=null)=>{if("string"==typeof t){const r={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3},s=t.replace(/^out/,"").toLowerCase();if(void 0!==r[s])return e.element(r[s])}if("number"==typeof t)return e.element(t);if("string"==typeof t&&1===t.length){const r={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3};if(void 0!==r[t])return e.element(r[t])}return e},mx_splitlr:(e,t,r,s=Sl())=>Yv(e,t,r,s,"x"),mx_splittb:(e,t,r,s=Sl())=>Yv(e,t,r,s,"y"),mx_srgb_texture_to_lin_rec709:jv,mx_subtract:(e,t=pn(0))=>Ma(e,t),mx_timer:()=>fb,mx_transform_uv:(e=1,t=0,r=Sl())=>r.mul(e).add(t),mx_unifiednoise2d:(e,t=Sl(),r=yn(1,1),s=yn(0,0),i=1,n=0,a=1,o=!1,u=1,l=2,d=.5)=>$v(e,t.convert("vec2|vec3"),r,s,i,n,a,o,u,l,d),mx_unifiednoise3d:(e,t=Sl(),r=yn(1,1),s=yn(0,0),i=1,n=0,a=1,o=!1,u=1,l=2,d=.5)=>Wv(e,t.convert("vec2|vec3"),r,s,i,n,a,o,u,l,d),mx_worley_noise_float:(e=Sl(),t=1)=>kv(e.convert("vec2|vec3"),t,gn(1)),mx_worley_noise_vec2:(e=Sl(),t=1)=>Gv(e.convert("vec2|vec3"),t,gn(1)),mx_worley_noise_vec3:(e=Sl(),t=1)=>zv(e.convert("vec2|vec3"),t,gn(1)),negate:Fo,neutralToneMapping:jx,nodeArray:en,nodeImmutable:rn,nodeObject:Qi,nodeObjectIntent:Zi,nodeObjects:Ji,nodeProxy:tn,nodeProxyIntent:sn,normalFlat:Wd,normalGeometry:zd,normalLocal:$d,normalMap:Kc,normalView:jd,normalViewGeometry:Hd,normalWorld:Xd,normalWorldGeometry:qd,normalize:_o,not:za,notEqual:Da,numWorkgroups:fT,objectDirection:cd,objectGroup:ba,objectPosition:pd,objectRadius:fd,objectScale:gd,objectViewPosition:md,objectWorldMatrix:hd,oneMinus:Lo,or:Ga,orthographicDepthToViewZ:(e,t,r)=>t.sub(r).mul(e).sub(t),oscSawtooth:(e=fb)=>e.fract(),oscSine:(e=fb)=>e.add(.75).mul(2*Math.PI).sin().mul(.5).add(.5),oscSquare:(e=fb)=>e.fract().round(),oscTriangle:(e=fb)=>e.add(.5).fract().mul(2).sub(1).abs(),output:sa,outputStruct:Vy,overloadingFn:mb,packHalf2x16:nb,packSnorm2x16:sb,packUnorm2x16:ib,parabola:tb,parallaxDirection:Wc,parallaxUV:(e,t)=>e.sub(Wc.mul(t)),parameter:(e,t)=>new Ly(e,t),pass:(e,t,r)=>new Ux(Ux.COLOR,e,t,r),passTexture:(e,t)=>new Px(e,t),pcurve:(e,t,r)=>Qo(Fa(Qo(e,t),Ca(Qo(e,t),Qo(Ma(1,e),r))),1/t),perspectiveDepthToViewZ:Fp,pmremTexture:mf,pointShadow:Z_,pointUV:nx,pointWidth:aa,positionGeometry:Bd,positionLocal:Fd,positionPrevious:Ld,positionView:Ud,positionViewDirection:Id,positionWorld:Pd,positionWorldDirection:Dd,posterize:Cx,pow:Qo,pow2:Zo,pow3:Jo,pow4:eu,premultiplyAlpha:Kp,property:Dn,quadBroadcast:JT,quadSwapDiagonal:jT,quadSwapX:HT,quadSwapY:qT,radians:co,rand:du,range:pT,rangeFogFactor:aT,reciprocal:Io,reference:fc,referenceBuffer:yc,reflect:qo,reflectVector:uc,reflectView:ac,reflector:e=>new Vb(e),refract:ou,refractVector:lc,refractView:oc,reinhardToneMapping:Vx,remap:dl,remapClamp:cl,renderGroup:ya,renderOutput:fl,rendererReference:Wu,replaceDefaultUV:function(e,t=null){return xu(t,{getUV:e})},rotate:Pf,rotateUV:xb,roughness:kn,round:Uo,rtt:jb,sRGBTransferEOTF:Du,sRGBTransferOETF:Uu,sample:(e,t=null)=>new Jb(e,Qi(t)),sampler:e=>(!0===e.isNode?e:Fl(e)).convert("sampler"),samplerComparison:e=>(!0===e.isNode?e:Fl(e)).convert("samplerComparison"),saturate:au,saturation:Nx,screenCoordinate:jl,screenDPR:Wl,screenSize:ql,screenUV:Hl,scriptable:iT,scriptableValue:Jx,select:yu,setCurrentStack:un,setName:_u,shaderStages:si,shadow:V_,shadowPositionWorld:p_,shapeCircle:iv,sharedUniformGroup:ma,sheen:Wn,sheenRoughness:Hn,shiftLeft:Xa,shiftRight:Ka,shininess:ra,sign:Mo,sin:No,sinc:(e,t)=>No(io.mul(t.mul(e).sub(1))).div(io.mul(t.mul(e).sub(1))),skinning:ap,smoothstep:uu,smoothstepElement:hu,specularColor:Jn,specularColorBlended:ea,specularF90:ta,spherizeUV:Tb,split:(e,t)=>Qi(new pi(Qi(e),t)),spritesheetUV:Nb,sqrt:yo,stack:Dy,step:Ho,stepElement:pu,storage:Wh,storageBarrier:()=>vT("storage").toStack(),storageTexture:hx,string:(e="")=>new bi(e,"string"),struct:(e,t=null)=>{const r=new Uy(e,t),s=(...t)=>{let s=null;if(t.length>0)if(t[0].isNode){s={};const r=Object.keys(e);for(let e=0;emx(e,t).level(r),texture3DLoad:(...e)=>mx(...e).setSampler(!1),textureBarrier:()=>vT("texture").toStack(),textureBicubic:om,textureBicubicLevel:am,textureCubeUV:Om,textureLevel:(e,t,r)=>Fl(e,t).level(r),textureLoad:Ll,textureSize:El,textureStore:(e,t,r)=>{let s;return!0===e.isStorageTextureNode?(s=e.clone(),s.uvNode=t,s.storeNode=r):s=hx(e,t,r),null!==r&&s.toStack(),s},thickness:la,time:fb,toneMapping:qu,toneMappingExposure:ju,toonOutlinePass:(t,r,s=new e(0,0,0),i=.003,n=1)=>Qi(new Ix(t,r,Qi(s),Qi(i),Qi(n))),transformDirection:tu,transformNormal:Yd,transformNormalToView:Qd,transformedClearcoatNormalView:ec,transformedNormalView:Zd,transformedNormalWorld:Jd,transmission:ua,transpose:ko,triNoise3D:hb,triplanarTexture:(...e)=>Sb(...e),triplanarTextures:Sb,trunc:Oo,uint:mn,uintBitsToFloat:e=>new qy(e,"float","uint"),uniform:Ta,uniformArray:Ol,uniformCubeTexture:(e=dc)=>hc(e),uniformFlow:Tu,uniformGroup:ga,uniformTexture:(e=Cl)=>Fl(e),unpackHalf2x16:lb,unpackNormal:jc,unpackSnorm2x16:ob,unpackUnorm2x16:ub,unpremultiplyAlpha:Yp,userData:(e,t,r)=>new fx(e,t,r),uv:Sl,uvec2:xn,uvec3:Nn,uvec4:An,varying:Lu,varyingProperty:Un,vec2:yn,vec3:_n,vec4:Rn,vectorComponents:ii,velocity:_x,vertexColor:$p,vertexIndex:qh,vertexStage:Pu,vibrance:Sx,viewZToLogarithmicDepth:Lp,viewZToOrthographicDepth:Mp,viewZToPerspectiveDepth:Bp,viewport:Xl,viewportCoordinate:Yl,viewportDepthTexture:wp,viewportLinearDepth:Ip,viewportMipTexture:Np,viewportOpaqueMipTexture:Rp,viewportResolution:Zl,viewportSafeUV:vb,viewportSharedTexture:Fx,viewportSize:Kl,viewportTexture:vp,viewportUV:Ql,vogelDiskSample:Zb,wgsl:(e,t)=>Kx(e,t,"wgsl"),wgslFn:(e,t)=>Qx(e,t,"wgsl"),workgroupArray:(e,t)=>new ST("Workgroup",e,t),workgroupBarrier:()=>vT("workgroup").toStack(),workgroupId:yT,workingToColorSpace:Vu,xor:$a});const eN=new Fy;class tN extends ty{constructor(e,t){super(),this.renderer=e,this.nodes=t}update(e,t,r){const s=this.renderer,i=this.nodes.getBackgroundNode(e)||e.background;let n=!1;if(null===i)s._clearColor.getRGB(eN),eN.a=s._clearColor.a;else if(!0===i.isColor)i.getRGB(eN),eN.a=1,n=!0;else if(!0===i.isNode){const u=this.get(e),l=i;eN.copy(s._clearColor);let d=u.backgroundMesh;if(void 0===d){const h=Rn(l).mul(lx).context({getUV:()=>dx.mul(qd),getTextureLevel:()=>ux}),p=rd.element(3).element(3).equal(1),g=Fa(1,rd.element(1).element(1)).mul(3),m=p.select(Fd.mul(g),Fd),f=Ed.mul(Rn(m,0));let y=rd.mul(Rn(f.xyz,1));y=y.setZ(y.w);const b=new Qp;function x(){i.removeEventListener("dispose",x),d.material.dispose(),d.geometry.dispose()}b.name="Background.material",b.side=M,b.depthTest=!1,b.depthWrite=!1,b.allowOverride=!1,b.fog=!1,b.lights=!1,b.vertexNode=y,b.colorNode=h,u.backgroundMeshNode=h,u.backgroundMesh=d=new ne(new st(1,32,32),b),d.frustumCulled=!1,d.name="Background.mesh",i.addEventListener("dispose",x)}const c=l.getCacheKey();u.backgroundCacheKey!==c&&(u.backgroundMeshNode.node=Rn(l).mul(lx),u.backgroundMeshNode.needsUpdate=!0,d.material.needsUpdate=!0,u.backgroundCacheKey=c),t.unshift(d,d.geometry,d.material,0,0,null,null)}else o("Renderer: Unsupported background configuration.",i);const a=s.xr.getEnvironmentBlendMode();if("additive"===a?eN.set(0,0,0,1):"alpha-blend"===a&&eN.set(0,0,0,0),!0===s.autoClear||!0===n){const T=r.clearColorValue;T.r=eN.r,T.g=eN.g,T.b=eN.b,T.a=eN.a,!0!==s.backend.isWebGLBackend&&!0!==s.alpha||(T.r*=T.a,T.g*=T.a,T.b*=T.a),r.depthClearValue=s._clearDepth,r.stencilClearValue=s._clearStencil,r.clearColor=!0===s.autoClearColor,r.clearDepth=!0===s.autoClearDepth,r.clearStencil=!0===s.autoClearStencil}else r.clearColor=!1,r.clearDepth=!1,r.clearStencil=!1}}let rN=0;class sN{constructor(e="",t=[],r=0){this.name=e,this.bindings=t,this.index=r,this.id=rN++}}class iN{constructor(e,t,r,s,i,n,a,o,u,l=[]){this.vertexShader=e,this.fragmentShader=t,this.computeShader=r,this.transforms=l,this.nodeAttributes=s,this.bindings=i,this.updateNodes=n,this.updateBeforeNodes=a,this.updateAfterNodes=o,this.observer=u,this.usedTimes=0}createBindings(){const e=[];for(const t of this.bindings){if(!0!==t.bindings[0].groupNode.shared){const r=new sN(t.name,[],t.index);e.push(r);for(const e of t.bindings)r.bindings.push(e.clone())}else e.push(t)}return e}}class nN{constructor(e,t,r=null){this.isNodeAttribute=!0,this.name=e,this.type=t,this.node=r}}class aN{constructor(e,t,r){this.isNodeUniform=!0,this.name=e,this.type=t,this.node=r}get value(){return this.node.value}set value(e){this.node.value=e}get id(){return this.node.id}get groupNode(){return this.node.groupNode}}class oN{constructor(e,t,r=!1,s=null){this.isNodeVar=!0,this.name=e,this.type=t,this.readOnly=r,this.count=s}}class uN extends oN{constructor(e,t,r=null,s=null){super(e,t),this.needsInterpolation=!1,this.isNodeVarying=!0,this.interpolationType=r,this.interpolationSampling=s}}class lN{constructor(e,t,r=""){this.name=e,this.type=t,this.code=r,Object.defineProperty(this,"isNodeCode",{value:!0})}}let dN=0;class cN{constructor(e=null){this.id=dN++,this.nodesData=new WeakMap,this.parent=e}getData(e){let t=this.nodesData.get(e);return void 0===t&&null!==this.parent&&(t=this.parent.getData(e)),t}setData(e,t){this.nodesData.set(e,t)}}class hN{constructor(e,t){this.name=e,this.members=t,this.output=!1}}class pN{constructor(e,t){this.name=e,this.value=t,this.boundary=0,this.itemSize=0,this.offset=0,this.index=-1}setValue(e){this.value=e}getValue(){return this.value}}class gN extends pN{constructor(e,t=0){super(e,t),this.isNumberUniform=!0,this.boundary=4,this.itemSize=1}}class mN extends pN{constructor(e,r=new t){super(e,r),this.isVector2Uniform=!0,this.boundary=8,this.itemSize=2}}class fN extends pN{constructor(e,t=new r){super(e,t),this.isVector3Uniform=!0,this.boundary=16,this.itemSize=3}}class yN extends pN{constructor(e,t=new s){super(e,t),this.isVector4Uniform=!0,this.boundary=16,this.itemSize=4}}class bN extends pN{constructor(t,r=new e){super(t,r),this.isColorUniform=!0,this.boundary=16,this.itemSize=3}}class xN extends pN{constructor(e,t=new i){super(e,t),this.isMatrix2Uniform=!0,this.boundary=8,this.itemSize=4}}class TN extends pN{constructor(e,t=new n){super(e,t),this.isMatrix3Uniform=!0,this.boundary=48,this.itemSize=12}}class _N extends pN{constructor(e,t=new a){super(e,t),this.isMatrix4Uniform=!0,this.boundary=64,this.itemSize=16}}class vN extends gN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class NN extends mN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class SN extends fN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class RN extends yN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class EN extends bN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class AN extends xN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class wN extends TN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class CN extends _N{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}let MN=0;const BN=new WeakMap,FN=new WeakMap,LN=new Map([[Int8Array,"int"],[Int16Array,"int"],[Int32Array,"int"],[Uint8Array,"uint"],[Uint16Array,"uint"],[Uint32Array,"uint"],[Float32Array,"float"]]),PN=e=>/e/g.test(e)?String(e).replace(/\+/g,""):(e=Number(e))+(e%1?"":".0");class DN{constructor(e,t,r){this.object=e,this.material=e&&e.material||null,this.geometry=e&&e.geometry||null,this.renderer=t,this.parser=r,this.scene=null,this.camera=null,this.nodes=[],this.sequentialNodes=[],this.updateNodes=[],this.updateBeforeNodes=[],this.updateAfterNodes=[],this.hashNodes={},this.observer=null,this.lightsNode=null,this.environmentNode=null,this.fogNode=null,this.clippingContext=null,this.vertexShader=null,this.fragmentShader=null,this.computeShader=null,this.flowNodes={vertex:[],fragment:[],compute:[]},this.flowCode={vertex:"",fragment:"",compute:""},this.uniforms={vertex:[],fragment:[],compute:[],index:0},this.structs={vertex:[],fragment:[],compute:[],index:0},this.types={vertex:[],fragment:[],compute:[],index:0},this.bindings={vertex:{},fragment:{},compute:{}},this.bindingsIndexes={},this.bindGroups=null,this.attributes=[],this.bufferAttributes=[],this.varyings=[],this.codes={},this.vars={},this.declarations={},this.flow={code:""},this.chaining=[],this.stack=Dy(),this.stacks=[],this.tab="\t",this.currentFunctionNode=null,this.context={material:this.material},this.cache=new cN,this.globalCache=this.cache,this.flowsData=new WeakMap,this.shaderStage=null,this.buildStage=null,this.subBuildLayers=[],this.activeStacks=[],this.subBuildFn=null,this.fnCall=null,Object.defineProperty(this,"id",{value:MN++})}isFlatShading(){return!0===this.material.flatShading||!1===this.geometry.hasAttribute("normal")}isOpaque(){const e=this.material;return!1===e.transparent&&e.blending===Ge&&!1===e.alphaToCoverage}getBindGroupsCache(){let e=FN.get(this.renderer);return void 0===e&&(e=new Yf,FN.set(this.renderer,e)),e}createRenderTarget(e,t,r){return new se(e,t,r)}createCubeRenderTarget(e,t){return new og(e,t)}includes(e){return this.nodes.includes(e)}getOutputStructName(){}_getBindGroup(e,t){const r=this.getBindGroupsCache(),s=[];let i,n=!0;for(const e of t)s.push(e),n=n&&e.groupNode.shared;return n?(i=r.get(s),void 0===i&&(i=new sN(e,s,this.bindingsIndexes[e].group),r.set(s,i))):i=new sN(e,s,this.bindingsIndexes[e].group),i}getBindGroupArray(e,t){const r=this.bindings[t];let s=r[e];return void 0===s&&(void 0===this.bindingsIndexes[e]&&(this.bindingsIndexes[e]={binding:0,group:Object.keys(this.bindingsIndexes).length}),r[e]=s=[]),s}getBindings(){let e=this.bindGroups;if(null===e){const t={},r=this.bindings;for(const e of si)for(const s in r[e]){const i=r[e][s],n=t[s]||(t[s]=[]);for(const e of i)!1===n.includes(e)&&n.push(e)}e=[];for(const r in t){const s=t[r],i=this._getBindGroup(r,s);e.push(i)}this.bindGroups=e}return e}sortBindingGroups(){const e=this.getBindings();e.sort((e,t)=>e.bindings[0].groupNode.order-t.bindings[0].groupNode.order);for(let t=0;t=0?`${Math.round(n)}u`:"0u";if("bool"===i)return n?"true":"false";if("color"===i)return`${this.getType("vec3")}( ${PN(n.r)}, ${PN(n.g)}, ${PN(n.b)} )`;const a=this.getTypeLength(i),o=this.getComponentType(i),u=e=>this.generateConst(o,e);if(2===a)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)} )`;if(3===a)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)}, ${u(n.z)} )`;if(4===a&&"mat2"!==i)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)}, ${u(n.z)}, ${u(n.w)} )`;if(a>=4&&n&&(n.isMatrix2||n.isMatrix3||n.isMatrix4))return`${this.getType(i)}( ${n.elements.map(u).join(", ")} )`;if(a>4)return`${this.getType(i)}()`;throw new Error(`NodeBuilder: Type '${i}' not found in generate constant attempt.`)}getType(e){return"color"===e?"vec3":e}hasGeometryAttribute(e){return this.geometry&&void 0!==this.geometry.getAttribute(e)}getAttribute(e,t){const r=this.attributes;for(const t of r)if(t.name===e)return t;const s=new nN(e,t);return this.registerDeclaration(s),r.push(s),s}getPropertyName(e){return e.name}isVector(e){return/vec\d/.test(e)}isMatrix(e){return/mat\d/.test(e)}isReference(e){return"void"===e||"property"===e||"sampler"===e||"samplerComparison"===e||"texture"===e||"cubeTexture"===e||"storageTexture"===e||"depthTexture"===e||"texture3D"===e}needsToWorkingColorSpace(){return!1}getComponentTypeFromTexture(e){const t=e.type;if(e.isDataTexture){if(t===R)return"int";if(t===S)return"uint"}return"float"}getElementType(e){return"mat2"===e?"vec2":"mat3"===e?"vec3":"mat4"===e?"vec4":this.getComponentType(e)}getComponentType(e){if("float"===(e=this.getVectorType(e))||"bool"===e||"int"===e||"uint"===e)return e;const t=/(b|i|u|)(vec|mat)([2-4])/.exec(e);return null===t?null:"b"===t[1]?"bool":"i"===t[1]?"int":"u"===t[1]?"uint":"float"}getVectorType(e){return"color"===e?"vec3":"texture"===e||"cubeTexture"===e||"storageTexture"===e||"texture3D"===e?"vec4":e}getTypeFromLength(e,t="float"){if(1===e)return t;let r=ks(e);const s="float"===t?"":t[0];return!0===/mat2/.test(t)&&(r=r.replace("vec","mat")),s+r}getTypeFromArray(e){return LN.get(e.constructor)}isInteger(e){return/int|uint|(i|u)vec/.test(e)}getTypeFromAttribute(e){let t=e;e.isInterleavedBufferAttribute&&(t=e.data);const r=t.array,s=e.itemSize,i=e.normalized;let n;return e instanceof at||!0===i||(n=this.getTypeFromArray(r)),this.getTypeFromLength(s,n)}getTypeLength(e){const t=this.getVectorType(e),r=/vec([2-4])/.exec(t);return null!==r?Number(r[1]):"float"===t||"bool"===t||"int"===t||"uint"===t?1:!0===/mat2/.test(e)?4:!0===/mat3/.test(e)?9:!0===/mat4/.test(e)?16:0}getVectorFromMatrix(e){return e.replace("mat","vec")}changeComponentType(e,t){return this.getTypeFromLength(this.getTypeLength(e),t)}getIntegerType(e){const t=this.getComponentType(e);return"int"===t||"uint"===t?e:this.changeComponentType(e,"int")}setActiveStack(e){this.activeStacks.push(e)}removeActiveStack(e){if(this.activeStacks[this.activeStacks.length-1]!==e)throw new Error("NodeBuilder: Invalid active stack removal.");this.activeStacks.pop()}getActiveStack(){return this.activeStacks[this.activeStacks.length-1]}getBaseStack(){return this.activeStacks[0]}addStack(){this.stack=Dy(this.stack);const e=ln();return this.stacks.push(e),un(this.stack),this.stack}removeStack(){const e=this.stack;for(const t of e.nodes){this.getDataFromNode(t).stack=e}return this.stack=e.parent,un(this.stacks.pop()),e}getDataFromNode(e,t=this.shaderStage,r=null){let s=(r=null===r?e.isGlobal(this)?this.globalCache:this.cache:r).getData(e);void 0===s&&(s={},r.setData(e,s)),void 0===s[t]&&(s[t]={});let i=s[t];const n=s.any?s.any.subBuilds:null,a=this.getClosestSubBuild(n);return a&&(void 0===i.subBuildsCache&&(i.subBuildsCache={}),i=i.subBuildsCache[a]||(i.subBuildsCache[a]={}),i.subBuilds=n),i}getNodeProperties(e,t="any"){const r=this.getDataFromNode(e,t);return r.properties||(r.properties={outputNode:null})}getBufferAttributeFromNode(e,t){const r=this.getDataFromNode(e,"vertex");let s=r.bufferAttribute;if(void 0===s){const i=this.uniforms.index++;s=new nN("nodeAttribute"+i,t,e),this.bufferAttributes.push(s),r.bufferAttribute=s}return s}getStructTypeNode(e,t=this.shaderStage){return this.types[t][e]||null}getStructTypeFromNode(e,t,r=null,s=this.shaderStage){const i=this.getDataFromNode(e,s,this.globalCache);let n=i.structType;if(void 0===n){const a=this.structs.index++;null===r&&(r="StructType"+a),n=new hN(r,t),this.structs[s].push(n),this.types[s][r]=e,i.structType=n}return n}getOutputStructTypeFromNode(e,t){const r=this.getStructTypeFromNode(e,t,"OutputType","fragment");return r.output=!0,r}getUniformFromNode(e,t,r=this.shaderStage,s=null){const i=this.getDataFromNode(e,r,this.globalCache);let n=i.uniform;if(void 0===n){const a=this.uniforms.index++;n=new aN(s||"nodeUniform"+a,t,e),this.uniforms[r].push(n),this.registerDeclaration(n),i.uniform=n}return n}getVarFromNode(e,t=null,r=e.getNodeType(this),s=this.shaderStage,i=!1){const n=this.getDataFromNode(e,s),a=this.getSubBuildProperty("variable",n.subBuilds);let o=n[a];if(void 0===o){const u=i?"_const":"_var",l=this.vars[s]||(this.vars[s]=[]),d=this.vars[u]||(this.vars[u]=0);null===t&&(t=(i?"nodeConst":"nodeVar")+d,this.vars[u]++),"variable"!==a&&(t=this.getSubBuildProperty(t,n.subBuilds));const c=e.getArrayCount(this);o=new oN(t,r,i,c),i||l.push(o),this.registerDeclaration(o),n[a]=o}return o}isDeterministic(e){if(e.isMathNode)return this.isDeterministic(e.aNode)&&(!e.bNode||this.isDeterministic(e.bNode))&&(!e.cNode||this.isDeterministic(e.cNode));if(e.isOperatorNode)return this.isDeterministic(e.aNode)&&(!e.bNode||this.isDeterministic(e.bNode));if(e.isArrayNode){if(null!==e.values)for(const t of e.values)if(!this.isDeterministic(t))return!1;return!0}return!!e.isConstNode}getVaryingFromNode(e,t=null,r=e.getNodeType(this),s=null,i=null){const n=this.getDataFromNode(e,"any"),a=this.getSubBuildProperty("varying",n.subBuilds);let o=n[a];if(void 0===o){const e=this.varyings,u=e.length;null===t&&(t="nodeVarying"+u),"varying"!==a&&(t=this.getSubBuildProperty(t,n.subBuilds)),o=new uN(t,r,s,i),e.push(o),this.registerDeclaration(o),n[a]=o}return o}registerDeclaration(e){const t=this.shaderStage,r=this.declarations[t]||(this.declarations[t]={}),s=this.getPropertyName(e);let i=1,n=s;for(;void 0!==r[n];)n=s+"_"+i++;i>1&&(e.name=n,d(`TSL: Declaration name '${s}' of '${e.type}' already in use. Renamed to '${n}'.`)),r[n]=e}getCodeFromNode(e,t,r=this.shaderStage){const s=this.getDataFromNode(e);let i=s.code;if(void 0===i){const e=this.codes[r]||(this.codes[r]=[]),n=e.length;i=new lN("nodeCode"+n,t),e.push(i),s.code=i}return i}addFlowCodeHierarchy(e,t){const{flowCodes:r,flowCodeBlock:s}=this.getDataFromNode(e);let i=!0,n=t;for(;n;){if(!0===s.get(n)){i=!1;break}n=this.getDataFromNode(n).parentNodeBlock}if(i)for(const e of r)this.addLineFlowCode(e)}addLineFlowCodeBlock(e,t,r){const s=this.getDataFromNode(e),i=s.flowCodes||(s.flowCodes=[]),n=s.flowCodeBlock||(s.flowCodeBlock=new WeakMap);i.push(t),n.set(r,!0)}addLineFlowCode(e,t=null){return""===e||(null!==t&&this.context.nodeBlock&&this.addLineFlowCodeBlock(t,e,this.context.nodeBlock),e=this.tab+e,/;\s*$/.test(e)||(e+=";\n"),this.flow.code+=e),this}addFlowCode(e){return this.flow.code+=e,this}addFlowTab(){return this.tab+="\t",this}removeFlowTab(){return this.tab=this.tab.slice(0,-1),this}getFlowData(e){return this.flowsData.get(e)}flowNode(e){const t=e.getNodeType(this),r=this.flowChildNode(e,t);return this.flowsData.set(e,r),r}addInclude(e){null!==this.currentFunctionNode&&this.currentFunctionNode.includes.push(e)}buildFunctionNode(e){const t=new Yx,r=this.currentFunctionNode;return this.currentFunctionNode=t,t.code=this.buildFunctionCode(e),this.currentFunctionNode=r,t}flowShaderNode(e){const t=e.layout,r={[Symbol.iterator](){let e=0;const t=Object.values(this);return{next:()=>({value:t[e],done:e++>=t.length})}}};for(const e of t.inputs)r[e.name]=new Ly(e.type,e.name);e.layout=null;const s=e.call(r),i=this.flowStagesNode(s,t.type);return e.layout=t,i}flowBuildStage(e,t,r=null){const s=this.getBuildStage();this.setBuildStage(t);const i=e.build(this,r);return this.setBuildStage(s),i}flowStagesNode(e,t=null){const r=this.flow,s=this.vars,i=this.declarations,n=this.cache,a=this.buildStage,o=this.stack,u={code:""};this.flow=u,this.vars={},this.declarations={},this.cache=new cN,this.stack=Dy();for(const r of ri)this.setBuildStage(r),u.result=e.build(this,t);return u.vars=this.getVars(this.shaderStage),this.flow=r,this.vars=s,this.declarations=i,this.cache=n,this.stack=o,this.setBuildStage(a),u}getFunctionOperator(){return null}buildFunctionCode(){d("Abstract function.")}flowChildNode(e,t=null){const r=this.flow,s={code:""};return this.flow=s,s.result=e.build(this,t),this.flow=r,s}flowNodeFromShaderStage(e,t,r=null,s=null){const i=this.tab,n=this.cache,a=this.shaderStage,o=this.context;this.setShaderStage(e);const u={...this.context};delete u.nodeBlock,this.cache=this.globalCache,this.tab="\t",this.context=u;let l=null;if("generate"===this.buildStage){const i=this.flowChildNode(t,r);null!==s&&(i.code+=`${this.tab+s} = ${i.result};\n`),this.flowCode[e]=this.flowCode[e]+i.code,l=i}else l=t.build(this);return this.setShaderStage(a),this.cache=n,this.tab=i,this.context=o,l}getAttributesArray(){return this.attributes.concat(this.bufferAttributes)}getAttributes(){d("Abstract function.")}getVaryings(){d("Abstract function.")}getVar(e,t,r=null){return`${null!==r?this.generateArrayDeclaration(e,r):this.getType(e)} ${t}`}getVars(e){let t="";const r=this.vars[e];if(void 0!==r)for(const e of r)t+=`${this.getVar(e.type,e.name)}; `;return t}getUniforms(){d("Abstract function.")}getCodes(e){const t=this.codes[e];let r="";if(void 0!==t)for(const e of t)r+=e.code+"\n";return r}getHash(){return this.vertexShader+this.fragmentShader+this.computeShader}setShaderStage(e){this.shaderStage=e}getShaderStage(){return this.shaderStage}setBuildStage(e){this.buildStage=e}getBuildStage(){return this.buildStage}buildCode(){d("Abstract function.")}get subBuild(){return this.subBuildLayers[this.subBuildLayers.length-1]||null}addSubBuild(e){this.subBuildLayers.push(e)}removeSubBuild(){return this.subBuildLayers.pop()}getClosestSubBuild(e){let t;if(t=e&&e.isNode?e.isShaderCallNodeInternal?e.shaderNode.subBuilds:e.isStackNode?[e.subBuild]:this.getDataFromNode(e,"any").subBuilds:e instanceof Set?[...e]:e,!t)return null;const r=this.subBuildLayers;for(let e=t.length-1;e>=0;e--){const s=t[e];if(r.includes(s))return s}return null}getSubBuildOutput(e){return this.getSubBuildProperty("outputNode",e)}getSubBuildProperty(e="",t=null){let r,s;return r=null!==t?this.getClosestSubBuild(t):this.subBuildFn,s=r?e?r+"_"+e:r:e,s}build(){const{object:e,material:t,renderer:r}=this;if(null!==t){let e=r.library.fromMaterial(t);null===e&&(o(`NodeMaterial: Material "${t.type}" is not compatible.`),e=new Qp),e.build(this)}else this.addFlow("compute",e);for(const e of ri){this.setBuildStage(e),this.context.position&&this.context.position.isNode&&this.flowNodeFromShaderStage("vertex",this.context.position);for(const t of si){this.setShaderStage(t);const r=this.flowNodes[t];for(const t of r)"generate"===e?this.flowNode(t):t.build(this)}}return this.setBuildStage(null),this.setShaderStage(null),this.buildCode(),this.buildUpdateNodes(),this}getSharedDataFromNode(e){let t=BN.get(e);return void 0===t&&(t={}),t}getNodeUniform(e,t){const r=this.getSharedDataFromNode(e);let s=r.cache;if(void 0===s){if("float"===t||"int"===t||"uint"===t)s=new vN(e);else if("vec2"===t||"ivec2"===t||"uvec2"===t)s=new NN(e);else if("vec3"===t||"ivec3"===t||"uvec3"===t)s=new SN(e);else if("vec4"===t||"ivec4"===t||"uvec4"===t)s=new RN(e);else if("color"===t)s=new EN(e);else if("mat2"===t)s=new AN(e);else if("mat3"===t)s=new wN(e);else{if("mat4"!==t)throw new Error(`Uniform "${t}" not implemented.`);s=new CN(e)}r.cache=s}return s}format(e,t,r){if((t=this.getVectorType(t))===(r=this.getVectorType(r))||null===r||this.isReference(r))return e;const s=this.getTypeLength(t),i=this.getTypeLength(r);return 16===s&&9===i?`${this.getType(r)}( ${e}[ 0 ].xyz, ${e}[ 1 ].xyz, ${e}[ 2 ].xyz )`:9===s&&4===i?`${this.getType(r)}( ${e}[ 0 ].xy, ${e}[ 1 ].xy )`:s>4||i>4||0===i?e:s===i?`${this.getType(r)}( ${e} )`:s>i?(e="bool"===r?`all( ${e} )`:`${e}.${"xyz".slice(0,i)}`,this.format(e,this.getTypeFromLength(i,this.getComponentType(t)),r)):4===i&&s>1?`${this.getType(r)}( ${this.format(e,t,"vec3")}, 1.0 )`:2===s?`${this.getType(r)}( ${this.format(e,t,"vec2")}, 0.0 )`:(1===s&&i>1&&t!==this.getComponentType(r)&&(e=`${this.getType(this.getComponentType(r))}( ${e} )`),`${this.getType(r)}( ${e} )`)}getSignature(){return`// Three.js r${ot} - Node System\n`}needsPreviousData(){const e=this.renderer.getMRT();return e&&e.has("velocity")||!0===js(this.object).useVelocity}}class UN{constructor(){this.time=0,this.deltaTime=0,this.frameId=0,this.renderId=0,this.updateMap=new WeakMap,this.updateBeforeMap=new WeakMap,this.updateAfterMap=new WeakMap,this.renderer=null,this.material=null,this.camera=null,this.object=null,this.scene=null}_getMaps(e,t){let r=e.get(t);return void 0===r&&(r={renderId:0,frameId:0},e.set(t,r)),r}updateBeforeNode(e){const t=e.getUpdateBeforeType(),r=e.updateReference(this);if(t===Zs.FRAME){const t=this._getMaps(this.updateBeforeMap,r);if(t.frameId!==this.frameId){const r=t.frameId;t.frameId=this.frameId,!1===e.updateBefore(this)&&(t.frameId=r)}}else if(t===Zs.RENDER){const t=this._getMaps(this.updateBeforeMap,r);if(t.renderId!==this.renderId){const r=t.renderId;t.renderId=this.renderId,!1===e.updateBefore(this)&&(t.renderId=r)}}else t===Zs.OBJECT&&e.updateBefore(this)}updateAfterNode(e){const t=e.getUpdateAfterType(),r=e.updateReference(this);if(t===Zs.FRAME){const t=this._getMaps(this.updateAfterMap,r);t.frameId!==this.frameId&&!1!==e.updateAfter(this)&&(t.frameId=this.frameId)}else if(t===Zs.RENDER){const t=this._getMaps(this.updateAfterMap,r);t.renderId!==this.renderId&&!1!==e.updateAfter(this)&&(t.renderId=this.renderId)}else t===Zs.OBJECT&&e.updateAfter(this)}updateNode(e){const t=e.getUpdateType(),r=e.updateReference(this);if(t===Zs.FRAME){const t=this._getMaps(this.updateMap,r);t.frameId!==this.frameId&&!1!==e.update(this)&&(t.frameId=this.frameId)}else if(t===Zs.RENDER){const t=this._getMaps(this.updateMap,r);t.renderId!==this.renderId&&!1!==e.update(this)&&(t.renderId=this.renderId)}else t===Zs.OBJECT&&e.update(this)}update(){this.frameId++,void 0===this.lastTime&&(this.lastTime=performance.now()),this.deltaTime=(performance.now()-this.lastTime)/1e3,this.lastTime=performance.now(),this.time+=this.deltaTime}}class IN{constructor(e,t,r=null,s="",i=!1){this.type=e,this.name=t,this.count=r,this.qualifier=s,this.isConst=i}}IN.isNodeFunctionInput=!0;class ON extends J_{static get type(){return"AmbientLightNode"}constructor(e=null){super(e)}setup({context:e}){e.irradiance.addAssign(this.colorNode)}}class VN extends J_{static get type(){return"DirectionalLightNode"}constructor(e=null){super(e)}setupDirect(){const e=this.colorNode;return{lightDirection:o_(this.light),lightColor:e}}}class kN extends J_{static get type(){return"HemisphereLightNode"}constructor(t=null){super(t),this.lightPositionNode=i_(t),this.lightDirectionNode=this.lightPositionNode.normalize(),this.groundColorNode=Ta(new e).setGroup(ya)}update(e){const{light:t}=this;super.update(e),this.lightPositionNode.object3d=t,this.groundColorNode.value.copy(t.groundColor).multiplyScalar(t.intensity)}setup(e){const{colorNode:t,groundColorNode:r,lightDirectionNode:s}=this,i=Xd.dot(s).mul(.5).add(.5),n=iu(r,t,i);e.context.irradiance.addAssign(n)}}class GN extends J_{static get type(){return"SpotLightNode"}constructor(e=null){super(e),this.coneCosNode=Ta(0).setGroup(ya),this.penumbraCosNode=Ta(0).setGroup(ya),this.cutoffDistanceNode=Ta(0).setGroup(ya),this.decayExponentNode=Ta(0).setGroup(ya),this.colorNode=Ta(this.color).setGroup(ya)}update(e){super.update(e);const{light:t}=this;this.coneCosNode.value=Math.cos(t.angle),this.penumbraCosNode.value=Math.cos(t.angle*(1-t.penumbra)),this.cutoffDistanceNode.value=t.distance,this.decayExponentNode.value=t.decay}getSpotAttenuation(e,t){const{coneCosNode:r,penumbraCosNode:s}=this;return uu(r,s,t)}getLightCoord(e){const t=e.getNodeProperties(this);let r=t.projectionUV;return void 0===r&&(r=s_(this.light,e.context.positionWorld),t.projectionUV=r),r}setupDirect(e){const{colorNode:t,cutoffDistanceNode:r,decayExponentNode:s,light:i}=this,n=this.getLightVector(e),a=n.normalize(),o=a.dot(o_(i)),u=this.getSpotAttenuation(e,o),l=n.length(),d=ev({lightDistance:l,cutoffDistance:r,decayExponent:s});let c,h,p=t.mul(u).mul(d);if(i.colorNode?(h=this.getLightCoord(e),c=i.colorNode(h)):i.map&&(h=this.getLightCoord(e),c=Fl(i.map,h.xy).onRenderUpdate(()=>i.map)),c){p=h.mul(2).sub(1).abs().lessThan(1).all().select(p.mul(c),p)}return{lightColor:p,lightDirection:a}}}class zN extends GN{static get type(){return"IESSpotLightNode"}getSpotAttenuation(e,t){const r=this.light.iesMap;let s=null;if(r&&!0===r.isTexture){const e=t.acos().mul(1/Math.PI);s=Fl(r,yn(e,0),0).r}else s=super.getSpotAttenuation(t);return s}}class $N extends J_{static get type(){return"LightProbeNode"}constructor(e=null){super(e);const t=[];for(let e=0;e<9;e++)t.push(new r);this.lightProbe=Ol(t)}update(e){const{light:t}=this;super.update(e);for(let e=0;e<9;e++)this.lightProbe.array[e].copy(t.sh.coefficients[e]).multiplyScalar(t.intensity)}setup(e){const t=Zv(Xd,this.lightProbe);e.context.irradiance.addAssign(t)}}const WN=on(([e,t])=>{const r=e.abs().sub(t);return Bo(Wo(r,0)).add($o(Wo(r.x,r.y),0))});class HN extends GN{static get type(){return"ProjectorLightNode"}update(e){super.update(e);const t=this.light;if(this.penumbraCosNode.value=Math.min(Math.cos(t.angle*(1-t.penumbra)),.99999),null===t.aspect){let e=1;null!==t.map&&(e=t.map.width/t.map.height),t.shadow.aspect=e}else t.shadow.aspect=t.aspect}getSpotAttenuation(e){const t=pn(0),r=this.penumbraCosNode,s=r_(this.light).mul(e.context.positionWorld||Pd);return dn(s.w.greaterThan(0),()=>{const e=s.xyz.div(s.w),i=WN(e.xy.sub(yn(.5)),yn(.5)),n=Fa(-1,Ma(1,Ao(r)).sub(1));t.assign(au(i.mul(-2).mul(n)))}),t}}const qN=new a,jN=new a;let XN=null;class KN extends J_{static get type(){return"RectAreaLightNode"}constructor(e=null){super(e),this.halfHeight=Ta(new r).setGroup(ya),this.halfWidth=Ta(new r).setGroup(ya),this.updateType=Zs.RENDER}update(e){super.update(e);const{light:t}=this,r=e.camera.matrixWorldInverse;jN.identity(),qN.copy(t.matrixWorld),qN.premultiply(r),jN.extractRotation(qN),this.halfWidth.value.set(.5*t.width,0,0),this.halfHeight.value.set(0,.5*t.height,0),this.halfWidth.value.applyMatrix4(jN),this.halfHeight.value.applyMatrix4(jN)}setupDirectRectArea(e){let t,r;e.isAvailable("float32Filterable")?(t=Fl(XN.LTC_FLOAT_1),r=Fl(XN.LTC_FLOAT_2)):(t=Fl(XN.LTC_HALF_1),r=Fl(XN.LTC_HALF_2));const{colorNode:s,light:i}=this;return{lightColor:s,lightPosition:a_(i),halfWidth:this.halfWidth,halfHeight:this.halfHeight,ltc_1:t,ltc_2:r}}static setLTC(e){XN=e}}class YN{parseFunction(){d("Abstract function.")}}class QN{constructor(e,t,r="",s=""){this.type=e,this.inputs=t,this.name=r,this.precision=s}getCode(){d("Abstract function.")}}QN.isNodeFunction=!0;const ZN=/^\s*(highp|mediump|lowp)?\s*([a-z_0-9]+)\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)/i,JN=/[a-z_0-9]+/gi,eS="#pragma main";class tS extends QN{constructor(e){const{type:t,inputs:r,name:s,precision:i,inputsCode:n,blockCode:a,headerCode:o}=(e=>{const t=(e=e.trim()).indexOf(eS),r=-1!==t?e.slice(t+12):e,s=r.match(ZN);if(null!==s&&5===s.length){const i=s[4],n=[];let a=null;for(;null!==(a=JN.exec(i));)n.push(a);const o=[];let u=0;for(;u{const r=this.backend.createNodeBuilder(e.object,this.renderer);return r.scene=e.scene,r.material=t,r.camera=e.camera,r.context.material=t,r.lightsNode=e.lightsNode,r.environmentNode=this.getEnvironmentNode(e.scene),r.fogNode=this.getFogNode(e.scene),r.clippingContext=e.clippingContext,this.renderer.getOutputRenderTarget()&&this.renderer.getOutputRenderTarget().multiview&&r.enableMultiview(),r};let n=t(e.material);try{n.build()}catch(e){n=t(new Qp),n.build(),o("TSL: "+e)}r=this._createNodeBuilderState(n),s.set(i,r)}r.usedTimes++,t.nodeBuilderState=r}return r}delete(e){if(e.isRenderObject){const t=this.get(e).nodeBuilderState;t.usedTimes--,0===t.usedTimes&&this.nodeBuilderCache.delete(this.getForRenderCacheKey(e))}return super.delete(e)}getForCompute(e){const t=this.get(e);let r=t.nodeBuilderState;if(void 0===r){const s=this.backend.createNodeBuilder(e,this.renderer);s.build(),r=this._createNodeBuilderState(s),t.nodeBuilderState=r}return r}_createNodeBuilderState(e){return new iN(e.vertexShader,e.fragmentShader,e.computeShader,e.getAttributesArray(),e.getBindings(),e.updateNodes,e.updateBeforeNodes,e.updateAfterNodes,e.observer,e.transforms)}getEnvironmentNode(e){this.updateEnvironment(e);let t=null;if(e.environmentNode&&e.environmentNode.isNode)t=e.environmentNode;else{const r=this.get(e);r.environmentNode&&(t=r.environmentNode)}return t}getBackgroundNode(e){this.updateBackground(e);let t=null;if(e.backgroundNode&&e.backgroundNode.isNode)t=e.backgroundNode;else{const r=this.get(e);r.backgroundNode&&(t=r.backgroundNode)}return t}getFogNode(e){return this.updateFog(e),e.fogNode||this.get(e).fogNode||null}getCacheKey(e,t){iS[0]=e,iS[1]=t;const r=this.renderer.info.calls,s=this.callHashCache.get(iS)||{};if(s.callId!==r){const i=this.getEnvironmentNode(e),n=this.getFogNode(e);t&&nS.push(t.getCacheKey(!0)),i&&nS.push(i.getCacheKey()),n&&nS.push(n.getCacheKey()),nS.push(this.renderer.getOutputRenderTarget()&&this.renderer.getOutputRenderTarget().multiview?1:0),nS.push(this.renderer.shadowMap.enabled?1:0),nS.push(this.renderer.shadowMap.type),s.callId=r,s.cacheKey=Us(nS),this.callHashCache.set(iS,s),nS.length=0}return iS[0]=null,iS[1]=null,s.cacheKey}get isToneMappingState(){return!this.renderer.getRenderTarget()}updateBackground(e){const t=this.get(e),r=e.background;if(r){const s=0===e.backgroundBlurriness&&t.backgroundBlurriness>0||e.backgroundBlurriness>0&&0===t.backgroundBlurriness;if(t.background!==r||s){const i=this.getCacheNode("background",r,()=>{if(!0===r.isCubeTexture||r.mapping===le||r.mapping===de||r.mapping===Re){if(e.backgroundBlurriness>0||r.mapping===Re)return mf(r);{let e;return e=!0===r.isCubeTexture?pc(r):Fl(r),hg(e)}}if(!0===r.isTexture)return Fl(r,Hl.flipY()).setUpdateMatrix(!0);!0!==r.isColor&&o("WebGPUNodes: Unsupported background configuration.",r)},s);t.backgroundNode=i,t.background=r,t.backgroundBlurriness=e.backgroundBlurriness}}else t.backgroundNode&&(delete t.backgroundNode,delete t.background)}getCacheNode(e,t,r,s=!1){const i=this.cacheLib[e]||(this.cacheLib[e]=new WeakMap);let n=i.get(t);return(void 0===n||s)&&(n=r(),i.set(t,n)),n}updateFog(e){const t=this.get(e),r=e.fog;if(r){if(t.fog!==r){const e=this.getCacheNode("fog",r,()=>{if(r.isFogExp2){const e=fc("color","color",r).setGroup(ya),t=fc("density","float",r).setGroup(ya);return lT(e,oT(t))}if(r.isFog){const e=fc("color","color",r).setGroup(ya),t=fc("near","float",r).setGroup(ya),s=fc("far","float",r).setGroup(ya);return lT(e,aT(t,s))}o("Renderer: Unsupported fog configuration.",r)});t.fogNode=e,t.fog=r}}else delete t.fogNode,delete t.fog}updateEnvironment(e){const t=this.get(e),r=e.environment;if(r){if(t.environment!==r){const e=this.getCacheNode("environment",r,()=>!0===r.isCubeTexture?pc(r):!0===r.isTexture?Fl(r):void o("Nodes: Unsupported environment configuration.",r));t.environmentNode=e,t.environment=r}}else t.environmentNode&&(delete t.environmentNode,delete t.environment)}getNodeFrame(e=this.renderer,t=null,r=null,s=null,i=null){const n=this.nodeFrame;return n.renderer=e,n.scene=t,n.object=r,n.camera=s,n.material=i,n}getNodeFrameForRender(e){return this.getNodeFrame(e.renderer,e.scene,e.object,e.camera,e.material)}getOutputCacheKey(){const e=this.renderer;return e.toneMapping+","+e.currentColorSpace+","+e.xr.isPresenting}hasOutputChange(e){return sS.get(e)!==this.getOutputCacheKey()}getOutputNode(e){const t=this.renderer,r=this.getOutputCacheKey(),s=e.isArrayTexture?mx(e,_n(Hl,kl("gl_ViewID_OVR"))).renderOutput(t.toneMapping,t.currentColorSpace):Fl(e,Hl).renderOutput(t.toneMapping,t.currentColorSpace);return sS.set(e,r),s}updateBefore(e){const t=e.getNodeBuilderState();for(const r of t.updateBeforeNodes)this.getNodeFrameForRender(e).updateBeforeNode(r)}updateAfter(e){const t=e.getNodeBuilderState();for(const r of t.updateAfterNodes)this.getNodeFrameForRender(e).updateAfterNode(r)}updateForCompute(e){const t=this.getNodeFrame(),r=this.getForCompute(e);for(const e of r.updateNodes)t.updateNode(e)}updateForRender(e){const t=this.getNodeFrameForRender(e),r=e.getNodeBuilderState();for(const e of r.updateNodes)t.updateNode(e)}needsRefresh(e){const t=this.getNodeFrameForRender(e);return e.getMonitor().needsRefresh(e,t)}dispose(){super.dispose(),this.nodeFrame=new UN,this.nodeBuilderCache=new Map,this.cacheLib={}}}const oS=new qe;class uS{constructor(e=null){this.version=0,this.clipIntersection=null,this.cacheKey="",this.shadowPass=!1,this.viewNormalMatrix=new n,this.clippingGroupContexts=new WeakMap,this.intersectionPlanes=[],this.unionPlanes=[],this.parentVersion=null,null!==e&&(this.viewNormalMatrix=e.viewNormalMatrix,this.clippingGroupContexts=e.clippingGroupContexts,this.shadowPass=e.shadowPass,this.viewMatrix=e.viewMatrix)}projectPlanes(e,t,r){const s=e.length;for(let i=0;i0,alpha:!0,depth:t.depth,stencil:t.stencil,framebufferScaleFactor:this.getFramebufferScaleFactor()},i=new XRWebGLLayer(e,s,r);this._glBaseLayer=i,e.updateRenderState({baseLayer:i}),t.setPixelRatio(1),t._setXRLayerSize(i.framebufferWidth,i.framebufferHeight),this._xrRenderTarget=new fS(i.framebufferWidth,i.framebufferHeight,{format:Se,type:ke,colorSpace:t.outputColorSpace,stencilBuffer:t.stencil,resolveDepthBuffer:!1===i.ignoreDepthValues,resolveStencilBuffer:!1===i.ignoreDepthValues}),this._xrRenderTarget._isOpaqueFramebuffer=!0,this._referenceSpace=await e.requestReferenceSpace(this.getReferenceSpaceType())}this.setFoveation(this.getFoveation()),t._animation.setAnimationLoop(this._onAnimationFrame),t._animation.setContext(e),t._animation.start(),this.isPresenting=!0,this.dispatchEvent({type:"sessionstart"})}}updateCamera(e){const t=this._session;if(null===t)return;const r=e.near,s=e.far,i=this._cameraXR,n=this._cameraL,a=this._cameraR;i.near=a.near=n.near=r,i.far=a.far=n.far=s,i.isMultiViewCamera=this._useMultiview,this._currentDepthNear===i.near&&this._currentDepthFar===i.far||(t.updateRenderState({depthNear:i.near,depthFar:i.far}),this._currentDepthNear=i.near,this._currentDepthFar=i.far),i.layers.mask=6|e.layers.mask,n.layers.mask=-5&i.layers.mask,a.layers.mask=-3&i.layers.mask;const o=e.parent,u=i.cameras;TS(i,o);for(let e=0;e=0&&(r[n]=null,t[n].disconnect(i))}for(let s=0;s=r.length){r.push(i),n=e;break}if(null===r[e]){r[e]=i,n=e;break}}if(-1===n)break}const a=t[n];a&&a.connect(i)}}function SS(e){return"quad"===e.type?this._glBinding.createQuadLayer({transform:new XRRigidTransform(e.translation,e.quaternion),width:e.width/2,height:e.height/2,space:this._referenceSpace,viewPixelWidth:e.pixelwidth,viewPixelHeight:e.pixelheight,clearOnAccess:!1}):this._glBinding.createCylinderLayer({transform:new XRRigidTransform(e.translation,e.quaternion),radius:e.radius,centralAngle:e.centralAngle,aspectRatio:e.aspectRatio,space:this._referenceSpace,viewPixelWidth:e.pixelwidth,viewPixelHeight:e.pixelheight,clearOnAccess:!1})}function RS(e,t){if(void 0===t)return;const r=this._cameraXR,i=this._renderer,n=i.backend,a=this._glBaseLayer,o=this.getReferenceSpace(),u=t.getViewerPose(o);if(this._xrFrame=t,null!==u){const e=u.views;null!==this._glBaseLayer&&n.setXRTarget(a.framebuffer);let t=!1;e.length!==r.cameras.length&&(r.cameras.length=0,t=!0);for(let i=0;i{await this.compileAsync(e,t);const s=this._renderLists.get(e,t),i=this._renderContexts.get(this._renderTarget,this._mrt),n=e.overrideMaterial||r.material,a=this._objects.get(r,n,e,t,s.lightsNode,i,i.clippingContext),{fragmentShader:o,vertexShader:u}=a.getNodeBuilderState();return{fragmentShader:o,vertexShader:u}}}}async init(){return null!==this._initPromise||(this._initPromise=new Promise(async(e,t)=>{let r=this.backend;try{await r.init(this)}catch(e){if(null===this._getFallback)return void t(e);try{this.backend=r=this._getFallback(e),await r.init(this)}catch(e){return void t(e)}}this._nodes=new aS(this,r),this._animation=new Kf(this,this._nodes,this.info),this._attributes=new oy(r),this._background=new tN(this,this._nodes),this._geometries=new cy(this._attributes,this.info),this._textures=new By(this,r,this.info),this._pipelines=new by(r,this._nodes),this._bindings=new xy(r,this._nodes,this._textures,this._attributes,this._pipelines,this.info),this._objects=new ey(this,this._nodes,this._geometries,this._pipelines,this._bindings,this.info),this._renderLists=new Ry(this.lighting),this._bundles=new cS,this._renderContexts=new Cy,this._animation.start(),this._initialized=!0,this._inspector.init(),e(this)})),this._initPromise}get domElement(){return this._canvasTarget.domElement}get coordinateSystem(){return this.backend.coordinateSystem}async compileAsync(e,t,r=null){if(!0===this._isDeviceLost)return;!1===this._initialized&&await this.init();const s=this._nodes.nodeFrame,i=s.renderId,n=this._currentRenderContext,a=this._currentRenderObjectFunction,o=this._handleObjectFunction,u=this._compilationPromises,l=!0===e.isScene?e:AS;null===r&&(r=e);const d=this._renderTarget,c=this._renderContexts.get(d,this._mrt),h=this._activeMipmapLevel,p=[];this._currentRenderContext=c,this._currentRenderObjectFunction=this.renderObject,this._handleObjectFunction=this._createObjectPipeline,this._compilationPromises=p,s.renderId++,s.update(),c.depth=this.depth,c.stencil=this.stencil,c.clippingContext||(c.clippingContext=new uS),c.clippingContext.updateGlobal(l,t),l.onBeforeRender(this,e,t,d);const g=this._renderLists.get(e,t);if(g.begin(),this._projectObject(e,t,0,g,c.clippingContext),r!==e&&r.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&g.pushLight(e)}),g.finish(),null!==d){this._textures.updateRenderTarget(d,h);const e=this._textures.get(d);c.textures=e.textures,c.depthTexture=e.depthTexture}else c.textures=null,c.depthTexture=null;r!==e?this._background.update(r,g,c):this._background.update(l,g,c);const m=g.opaque,f=g.transparent,y=g.transparentDoublePass,b=g.lightsNode;!0===this.opaque&&m.length>0&&this._renderObjects(m,t,l,b),!0===this.transparent&&f.length>0&&this._renderTransparents(f,y,t,l,b),s.renderId=i,this._currentRenderContext=n,this._currentRenderObjectFunction=a,this._handleObjectFunction=o,this._compilationPromises=u,await Promise.all(p)}async renderAsync(e,t){v('Renderer: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.render(e,t)}async waitForGPU(){o("Renderer: waitForGPU() has been removed. Read https://github.com/mrdoob/three.js/issues/32012 for more information.")}set inspector(e){null!==this._inspector&&this._inspector.setRenderer(null),this._inspector=e,this._inspector.setRenderer(this)}get inspector(){return this._inspector}set highPrecision(e){const t=this.contextNode.value;!0===e?(t.modelViewMatrix=wd,t.modelNormalViewMatrix=Cd):this.highPrecision&&(delete t.modelViewMatrix,delete t.modelNormalViewMatrix)}get highPrecision(){const e=this.contextNode.value;return e.modelViewMatrix===wd&&e.modelNormalViewMatrix===Cd}setMRT(e){return this._mrt=e,this}getMRT(){return this._mrt}getOutputBufferType(){return this._outputBufferType}getColorBufferType(){return v('Renderer: ".getColorBufferType()" has been renamed to ".getOutputBufferType()".'),this.getOutputBufferType()}_onDeviceLost(e){let t=`THREE.WebGPURenderer: ${e.api} Device Lost:\n\nMessage: ${e.message}`;e.reason&&(t+=`\nReason: ${e.reason}`),o(t),this._isDeviceLost=!0}_renderBundle(e,t,r){const{bundleGroup:s,camera:i,renderList:n}=e,a=this._currentRenderContext,o=this._bundles.get(s,i),u=this.backend.get(o);void 0===u.renderContexts&&(u.renderContexts=new Set);const l=s.version!==u.version,d=!1===u.renderContexts.has(a)||l;if(u.renderContexts.add(a),d){this.backend.beginBundle(a),(void 0===u.renderObjects||l)&&(u.renderObjects=[]),this._currentRenderBundle=o;const{transparentDoublePass:e,transparent:d,opaque:c}=n;!0===this.opaque&&c.length>0&&this._renderObjects(c,i,t,r),!0===this.transparent&&d.length>0&&this._renderTransparents(d,e,i,t,r),this._currentRenderBundle=null,this.backend.finishBundle(a,o),u.version=s.version}else{const{renderObjects:e}=u;for(let t=0,r=e.length;t>=h,g.viewportValue.height>>=h,g.viewportValue.minDepth=_,g.viewportValue.maxDepth=v,g.viewport=!1===g.viewportValue.equals(CS),g.scissorValue.copy(x).multiplyScalar(T).floor(),g.scissor=y._scissorTest&&!1===g.scissorValue.equals(CS),g.scissorValue.width>>=h,g.scissorValue.height>>=h,g.clippingContext||(g.clippingContext=new uS),g.clippingContext.updateGlobal(l,t),l.onBeforeRender(this,e,t,p);const N=t.isArrayCamera?BS:MS;t.isArrayCamera||(FS.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),N.setFromProjectionMatrix(FS,t.coordinateSystem,t.reversedDepth));const S=this._renderLists.get(e,t);if(S.begin(),this._projectObject(e,t,0,S,g.clippingContext),S.finish(),!0===this.sortObjects&&S.sort(this._opaqueSort,this._transparentSort),null!==p){this._textures.updateRenderTarget(p,h);const e=this._textures.get(p);g.textures=e.textures,g.depthTexture=e.depthTexture,g.width=e.width,g.height=e.height,g.renderTarget=p,g.depth=p.depthBuffer,g.stencil=p.stencilBuffer}else g.textures=null,g.depthTexture=null,g.width=wS.width,g.height=wS.height,g.depth=this.depth,g.stencil=this.stencil;g.width>>=h,g.height>>=h,g.activeCubeFace=c,g.activeMipmapLevel=h,g.occlusionQueryCount=S.occlusionQueryCount,g.scissorValue.max(LS.set(0,0,0,0)),g.scissorValue.x+g.scissorValue.width>g.width&&(g.scissorValue.width=Math.max(g.width-g.scissorValue.x,0)),g.scissorValue.y+g.scissorValue.height>g.height&&(g.scissorValue.height=Math.max(g.height-g.scissorValue.y,0)),this._background.update(l,S,g),g.camera=t,this.backend.beginRender(g);const{bundles:R,lightsNode:E,transparentDoublePass:A,transparent:w,opaque:C}=S;return R.length>0&&this._renderBundles(R,l,E),!0===this.opaque&&C.length>0&&this._renderObjects(C,t,l,E),!0===this.transparent&&w.length>0&&this._renderTransparents(w,A,t,l,E),this.backend.finishRender(g),i.renderId=n,this._currentRenderContext=a,this._currentRenderObjectFunction=o,this._handleObjectFunction=u,this._callDepth--,null!==s&&(this.setRenderTarget(d,c,h),this._renderOutput(p)),l.onAfterRender(this,e,t,p),this.inspector.finishRender(this.backend.getTimestampUID(g)),g}_setXRLayerSize(e,t){this._canvasTarget._width=e,this._canvasTarget._height=t,this.setViewport(0,0,e,t)}_renderOutput(e){const t=this._quad;this._nodes.hasOutputChange(e.texture)&&(t.material.fragmentNode=this._nodes.getOutputNode(e.texture),t.material.needsUpdate=!0);const r=this.autoClear,s=this.xr.enabled;this.autoClear=!1,this.xr.enabled=!1,this._renderScene(t,t.camera,!1),this.autoClear=r,this.xr.enabled=s}getMaxAnisotropy(){return this.backend.getMaxAnisotropy()}getActiveCubeFace(){return this._activeCubeFace}getActiveMipmapLevel(){return this._activeMipmapLevel}async setAnimationLoop(e){!1===this._initialized&&await this.init(),this._animation.setAnimationLoop(e)}getAnimationLoop(){return this._animation.getAnimationLoop()}async getArrayBufferAsync(e){return await this.backend.getArrayBufferAsync(e)}getContext(){return this.backend.getContext()}getPixelRatio(){return this._canvasTarget.getPixelRatio()}getDrawingBufferSize(e){return this._canvasTarget.getDrawingBufferSize(e)}getSize(e){return this._canvasTarget.getSize(e)}setPixelRatio(e=1){this._canvasTarget.setPixelRatio(e)}setDrawingBufferSize(e,t,r){this.xr&&this.xr.isPresenting||this._canvasTarget.setDrawingBufferSize(e,t,r)}setSize(e,t,r=!0){this.xr&&this.xr.isPresenting||this._canvasTarget.setSize(e,t,r)}setOpaqueSort(e){this._opaqueSort=e}setTransparentSort(e){this._transparentSort=e}getScissor(e){return this._canvasTarget.getScissor(e)}setScissor(e,t,r,s){this._canvasTarget.setScissor(e,t,r,s)}getScissorTest(){return this._canvasTarget.getScissorTest()}setScissorTest(e){this._canvasTarget.setScissorTest(e),this.backend.setScissorTest(e)}getViewport(e){return this._canvasTarget.getViewport(e)}setViewport(e,t,r,s,i=0,n=1){this._canvasTarget.setViewport(e,t,r,s,i,n)}getClearColor(e){return e.copy(this._clearColor)}setClearColor(e,t=1){this._clearColor.set(e),this._clearColor.a=t}getClearAlpha(){return this._clearColor.a}setClearAlpha(e){this._clearColor.a=e}getClearDepth(){return this._clearDepth}setClearDepth(e){this._clearDepth=e}getClearStencil(){return this._clearStencil}setClearStencil(e){this._clearStencil=e}isOccluded(e){const t=this._currentRenderContext;return t&&this.backend.isOccluded(t,e)}clear(e=!0,t=!0,r=!0){if(!1===this._initialized)throw new Error('Renderer: .clear() called before the backend is initialized. Use "await renderer.init();" before before using this method.');const s=this._renderTarget||this._getFrameBufferTarget();let i=null;if(null!==s){this._textures.updateRenderTarget(s);const e=this._textures.get(s);i=this._renderContexts.get(s),i.textures=e.textures,i.depthTexture=e.depthTexture,i.width=e.width,i.height=e.height,i.renderTarget=s,i.depth=s.depthBuffer,i.stencil=s.stencilBuffer;const t=this.backend.getClearColor();i.clearColorValue.r=t.r,i.clearColorValue.g=t.g,i.clearColorValue.b=t.b,i.clearColorValue.a=t.a,i.activeCubeFace=this.getActiveCubeFace(),i.activeMipmapLevel=this.getActiveMipmapLevel()}this.backend.clear(e,t,r,i),null!==s&&null===this._renderTarget&&this._renderOutput(s)}clearColor(){this.clear(!0,!1,!1)}clearDepth(){this.clear(!1,!0,!1)}clearStencil(){this.clear(!1,!1,!0)}async clearAsync(e=!0,t=!0,r=!0){v('Renderer: "clearAsync()" has been deprecated. Use "clear()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.clear(e,t,r)}async clearColorAsync(){v('Renderer: "clearColorAsync()" has been deprecated. Use "clearColor()" and "await renderer.init();" when creating the renderer.'),this.clear(!0,!1,!1)}async clearDepthAsync(){v('Renderer: "clearDepthAsync()" has been deprecated. Use "clearDepth()" and "await renderer.init();" when creating the renderer.'),this.clear(!1,!0,!1)}async clearStencilAsync(){v('Renderer: "clearStencilAsync()" has been deprecated. Use "clearStencil()" and "await renderer.init();" when creating the renderer.'),this.clear(!1,!1,!0)}get needsFrameBufferTarget(){const e=this.currentToneMapping!==m,t=this.currentColorSpace!==p.workingColorSpace;return e||t}get samples(){return this._samples}get currentSamples(){let e=this._samples;return null!==this._renderTarget?e=this._renderTarget.samples:this.needsFrameBufferTarget&&(e=0),e}get currentToneMapping(){return this.isOutputTarget?this.toneMapping:m}get currentColorSpace(){return this.isOutputTarget?this.outputColorSpace:p.workingColorSpace}get isOutputTarget(){return this._renderTarget===this._outputRenderTarget||null===this._renderTarget}dispose(){!0===this._initialized&&(this.info.dispose(),this.backend.dispose(),this._animation.dispose(),this._objects.dispose(),this._geometries.dispose(),this._pipelines.dispose(),this._nodes.dispose(),this._bindings.dispose(),this._renderLists.dispose(),this._renderContexts.dispose(),this._textures.dispose(),null!==this._frameBufferTarget&&this._frameBufferTarget.dispose(),Object.values(this.backend.timestampQueryPool).forEach(e=>{null!==e&&e.dispose()})),this.setRenderTarget(null),this.setAnimationLoop(null)}setRenderTarget(e,t=0,r=0){this._renderTarget=e,this._activeCubeFace=t,this._activeMipmapLevel=r}getRenderTarget(){return this._renderTarget}setOutputRenderTarget(e){this._outputRenderTarget=e}getOutputRenderTarget(){return this._outputRenderTarget}setCanvasTarget(e){this._canvasTarget.removeEventListener("resize",this._onCanvasTargetResize),this._canvasTarget=e,this._canvasTarget.addEventListener("resize",this._onCanvasTargetResize)}getCanvasTarget(){return this._canvasTarget}_resetXRState(){this.backend.setXRTarget(null),this.setOutputRenderTarget(null),this.setRenderTarget(null),this._frameBufferTarget.dispose(),this._frameBufferTarget=null}setRenderObjectFunction(e){this._renderObjectFunction=e}getRenderObjectFunction(){return this._renderObjectFunction}compute(e,t=null){if(!0===this._isDeviceLost)return;if(!1===this._initialized)return d("Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead."),this.computeAsync(e,t);const r=this._nodes.nodeFrame,s=r.renderId;this.info.calls++,this.info.compute.calls++,this.info.compute.frameCalls++,r.renderId=this.info.calls,this.backend.updateTimeStampUID(e),this.inspector.beginCompute(this.backend.getTimestampUID(e),e);const i=this.backend,n=this._pipelines,a=this._bindings,o=this._nodes,u=Array.isArray(e)?e:[e];if(void 0===u[0]||!0!==u[0].isComputeNode)throw new Error("THREE.Renderer: .compute() expects a ComputeNode.");i.beginCompute(e);for(const r of u){if(!1===n.has(r)){const e=()=>{r.removeEventListener("dispose",e),n.delete(r),a.deleteForCompute(r),o.delete(r)};r.addEventListener("dispose",e);const t=r.onInitFunction;null!==t&&t.call(r,{renderer:this})}o.updateForCompute(r),a.updateForCompute(r);const s=a.getForCompute(r),u=n.getForCompute(r,s);i.compute(e,r,s,u,t)}i.finishCompute(e),r.renderId=s,this.inspector.finishCompute(this.backend.getTimestampUID(e))}async computeAsync(e,t=null){!1===this._initialized&&await this.init(),this.compute(e,t)}async hasFeatureAsync(e){return v('Renderer: "hasFeatureAsync()" has been deprecated. Use "hasFeature()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.hasFeature(e)}async resolveTimestampsAsync(e="render"){return!1===this._initialized&&await this.init(),this.backend.resolveTimestampsAsync(e)}hasFeature(e){if(!1===this._initialized)throw new Error('Renderer: .hasFeature() called before the backend is initialized. Use "await renderer.init();" before before using this method.');return this.backend.hasFeature(e)}hasInitialized(){return this._initialized}async initTextureAsync(e){v('Renderer: "initTextureAsync()" has been deprecated. Use "initTexture()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.initTexture(e)}initTexture(e){if(!1===this._initialized)throw new Error('Renderer: .initTexture() called before the backend is initialized. Use "await renderer.init();" before before using this method.');this._textures.updateTexture(e)}initRenderTarget(e){if(!1===this._initialized)throw new Error('Renderer: .initRenderTarget() called before the backend is initialized. Use "await renderer.init();" before before using this method.');this._textures.updateRenderTarget(e);const t=this._textures.get(e),r=this._renderContexts.get(e);r.textures=t.textures,r.depthTexture=t.depthTexture,r.width=t.width,r.height=t.height,r.renderTarget=e,r.depth=e.depthBuffer,r.stencil=e.stencilBuffer,this.backend.initRenderTarget(r)}copyFramebufferToTexture(e,t=null){if(null!==t)if(t.isVector2)t=LS.set(t.x,t.y,e.image.width,e.image.height).floor();else{if(!t.isVector4)return void o("Renderer.copyFramebufferToTexture: Invalid rectangle.");t=LS.copy(t).floor()}else t=LS.set(0,0,e.image.width,e.image.height);let r,s=this._currentRenderContext;null!==s?r=s.renderTarget:(r=this._renderTarget||this._getFrameBufferTarget(),null!==r&&(this._textures.updateRenderTarget(r),s=this._textures.get(r))),this._textures.updateTexture(e,{renderTarget:r}),this.backend.copyFramebufferToTexture(e,s,t),this._inspector.copyFramebufferToTexture(e)}copyTextureToTexture(e,t,r=null,s=null,i=0,n=0){this._textures.updateTexture(e),this._textures.updateTexture(t),this.backend.copyTextureToTexture(e,t,r,s,i,n),this._inspector.copyTextureToTexture(e,t)}async readRenderTargetPixelsAsync(e,t,r,s,i,n=0,a=0){return this.backend.copyTextureToBuffer(e.textures[n],t,r,s,i,a)}_projectObject(e,t,r,s,i){if(!1===e.visible)return;if(e.layers.test(t.layers))if(e.isGroup)r=e.renderOrder,e.isClippingGroup&&e.enabled&&(i=i.getGroupContext(e));else if(e.isLOD)!0===e.autoUpdate&&e.update(t);else if(e.isLight)s.pushLight(e);else if(e.isSprite){const n=t.isArrayCamera?BS:MS;if(!e.frustumCulled||n.intersectsSprite(e,t)){!0===this.sortObjects&&LS.setFromMatrixPosition(e.matrixWorld).applyMatrix4(FS);const{geometry:t,material:n}=e;n.visible&&s.push(e,t,n,r,LS.z,null,i)}}else if(e.isLineLoop)o("Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.");else if(e.isMesh||e.isLine||e.isPoints){const n=t.isArrayCamera?BS:MS;if(!e.frustumCulled||n.intersectsObject(e,t)){const{geometry:t,material:n}=e;if(!0===this.sortObjects&&(null===t.boundingSphere&&t.computeBoundingSphere(),LS.copy(t.boundingSphere.center).applyMatrix4(e.matrixWorld).applyMatrix4(FS)),Array.isArray(n)){const a=t.groups;for(let o=0,u=a.length;o0){for(const{material:e}of t)e.side=M;this._renderObjects(t,r,s,i,"backSide");for(const{material:e}of t)e.side=dt;this._renderObjects(e,r,s,i);for(const{material:e}of t)e.side=B}else this._renderObjects(e,r,s,i)}_renderObjects(e,t,r,s,i=null){for(let n=0,a=e.length;n(t.not().discard(),e))(u)}}e.depthNode&&e.depthNode.isNode&&(l=e.depthNode),e.castShadowPositionNode&&e.castShadowPositionNode.isNode?o=e.castShadowPositionNode:e.positionNode&&e.positionNode.isNode&&(o=e.positionNode),r={version:t,colorNode:u,depthNode:l,positionNode:o},this._cacheShadowNodes.set(e,r)}return r}renderObject(e,t,r,s,i,n,a,o=null,u=null){let l,d,c,h,p=!1;if(e.onBeforeRender(this,t,r,s,i,n),!0===i.allowOverride&&null!==t.overrideMaterial){const e=t.overrideMaterial;if(p=!0,l=e.isNodeMaterial?e.colorNode:null,d=e.isNodeMaterial?e.depthNode:null,c=e.isNodeMaterial?e.positionNode:null,h=t.overrideMaterial.side,i.positionNode&&i.positionNode.isNode&&(e.positionNode=i.positionNode),e.alphaTest=i.alphaTest,e.alphaMap=i.alphaMap,e.transparent=i.transparent||i.transmission>0||i.transmissionNode&&i.transmissionNode.isNode||i.backdropNode&&i.backdropNode.isNode,e.isShadowPassMaterial){const{colorNode:t,depthNode:r,positionNode:s}=this._getShadowNodes(i);this.shadowMap.type===Qe?e.side=null!==i.shadowSide?i.shadowSide:i.side:e.side=null!==i.shadowSide?i.shadowSide:PS[i.side],null!==t&&(e.colorNode=t),null!==r&&(e.depthNode=r),null!==s&&(e.positionNode=s)}i=e}!0===i.transparent&&i.side===B&&!1===i.forceSinglePass?(i.side=M,this._handleObjectFunction(e,i,t,r,a,n,o,"backSide"),i.side=dt,this._handleObjectFunction(e,i,t,r,a,n,o,u),i.side=B):this._handleObjectFunction(e,i,t,r,a,n,o,u),p&&(t.overrideMaterial.colorNode=l,t.overrideMaterial.depthNode=d,t.overrideMaterial.positionNode=c,t.overrideMaterial.side=h),e.onAfterRender(this,t,r,s,i,n)}hasCompatibility(e){return this.backend.hasCompatibility(e)}_renderObjectDirect(e,t,r,s,i,n,a,o){const u=this._objects.get(e,t,r,s,i,this._currentRenderContext,a,o);if(u.drawRange=e.geometry.drawRange,u.group=n,null!==this._currentRenderBundle){this.backend.get(this._currentRenderBundle).renderObjects.push(u),u.bundle=this._currentRenderBundle.bundleGroup}const l=this._nodes.needsRefresh(u);l&&(this._nodes.updateBefore(u),this._geometries.updateForRender(u),this._nodes.updateForRender(u),this._bindings.updateForRender(u)),this._pipelines.updateForRender(u),this.backend.draw(u,this.info),l&&this._nodes.updateAfter(u)}_createObjectPipeline(e,t,r,s,i,n,a,o){const u=this._objects.get(e,t,r,s,i,this._currentRenderContext,a,o);u.drawRange=e.geometry.drawRange,u.group=n,this._nodes.updateBefore(u),this._geometries.updateForRender(u),this._nodes.updateForRender(u),this._bindings.updateForRender(u),this._pipelines.getForRender(u,this._compilationPromises),this._nodes.updateAfter(u)}_onCanvasTargetResize(){this._initialized&&this.backend.updateSize()}get compile(){return this.compileAsync}}class US{constructor(e=""){this.name=e,this.visibility=0}setVisibility(e){this.visibility|=e}getVisibility(){return this.visibility}clone(){return Object.assign(new this.constructor,this)}}class IS extends US{constructor(e,t=null){super(e),this.isBuffer=!0,this.bytesPerElement=Float32Array.BYTES_PER_ELEMENT,this._buffer=t,this._updateRanges=[]}get updateRanges(){return this._updateRanges}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}get byteLength(){return(e=this._buffer.byteLength)+(ay-e%ay)%ay;var e}get buffer(){return this._buffer}update(){return!0}}class OS extends IS{constructor(e,t=null){super(e,t),this.isUniformBuffer=!0}}let VS=0;class kS extends OS{constructor(e,t){super("UniformBuffer_"+VS++,e?e.value:null),this.nodeUniform=e,this.groupNode=t,this.isNodeUniformBuffer=!0}set updateRanges(e){this.nodeUniform.updateRanges=e}get updateRanges(){return this.nodeUniform.updateRanges}addUpdateRange(e,t){this.nodeUniform.addUpdateRange(e,t)}clearUpdateRanges(){this.nodeUniform.clearUpdateRanges()}get buffer(){return this.nodeUniform.value}}class GS extends OS{constructor(e){super(e),this.isUniformsGroup=!0,this._values=null,this.uniforms=[],this._updateRangeCache=new Map}addUniformUpdateRange(e){const t=e.index;if(!0!==this._updateRangeCache.has(t)){const r=this.updateRanges,s={start:e.offset,count:e.itemSize};r.push(s),this._updateRangeCache.set(t,s)}}clearUpdateRanges(){this._updateRangeCache.clear(),super.clearUpdateRanges()}addUniform(e){return this.uniforms.push(e),this}removeUniform(e){const t=this.uniforms.indexOf(e);return-1!==t&&this.uniforms.splice(t,1),this}get values(){return null===this._values&&(this._values=Array.from(this.buffer)),this._values}get buffer(){let e=this._buffer;if(null===e){const t=this.byteLength;e=new Float32Array(new ArrayBuffer(t)),this._buffer=e}return e}get byteLength(){const e=this.bytesPerElement;let t=0;for(let r=0,s=this.uniforms.length;r{this.generation=null,this.version=0},this.texture=t,this.version=t?t.version:0,this.generation=null,this.samplerKey="",this.isSampler=!0}set texture(e){this._texture!==e&&(this._texture&&this._texture.removeEventListener("dispose",this._onTextureDispose),this._texture=e,this.generation=null,this.version=0,this._texture&&this._texture.addEventListener("dispose",this._onTextureDispose))}get texture(){return this._texture}update(){const{texture:e,version:t}=this;return t!==e.version&&(this.version=e.version,!0)}clone(){const e=super.clone();return e._texture=null,e._onTextureDispose=()=>{e.generation=null,e.version=0},e.texture=this.texture,e}}let HS=0;class qS extends WS{constructor(e,t){super(e,t),this.id=HS++,this.store=!1,this.mipLevel=0,this.isSampledTexture=!0}}class jS extends qS{constructor(e,t,r,s=null){super(e,t?t.value:null),this.textureNode=t,this.groupNode=r,this.access=s}update(){const{textureNode:e}=this;return this.texture!==e.value?(this.texture=e.value,!0):super.update()}}class XS extends jS{constructor(e,t,r,s=null){super(e,t,r,s),this.isSampledCubeTexture=!0}}class KS extends jS{constructor(e,t,r,s=null){super(e,t,r,s),this.isSampledTexture3D=!0}}const YS={bitcast_int_uint:new Xx("uint tsl_bitcast_int_to_uint ( int x ) { return floatBitsToUint( intBitsToFloat ( x ) ); }"),bitcast_uint_int:new Xx("uint tsl_bitcast_uint_to_int ( uint x ) { return floatBitsToInt( uintBitsToFloat ( x ) ); }")},QS={textureDimensions:"textureSize",equals:"equal",bitcast_float_int:"floatBitsToInt",bitcast_int_float:"intBitsToFloat",bitcast_uint_float:"uintBitsToFloat",bitcast_float_uint:"floatBitsToUint",bitcast_uint_int:"tsl_bitcast_uint_to_int",bitcast_int_uint:"tsl_bitcast_int_to_uint",floatpack_snorm_2x16:"packSnorm2x16",floatpack_unorm_2x16:"packUnorm2x16",floatpack_float16_2x16:"packHalf2x16",floatunpack_snorm_2x16:"unpackSnorm2x16",floatunpack_unorm_2x16:"unpackUnorm2x16",floatunpack_float16_2x16:"unpackHalf2x16"},ZS={low:"lowp",medium:"mediump",high:"highp"},JS={swizzleAssign:!0,storageBuffer:!1},eR={perspective:"smooth",linear:"noperspective"},tR={centroid:"centroid"},rR="\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\nprecision highp sampler3D;\nprecision highp samplerCube;\nprecision highp sampler2DArray;\n\nprecision highp usampler2D;\nprecision highp usampler3D;\nprecision highp usamplerCube;\nprecision highp usampler2DArray;\n\nprecision highp isampler2D;\nprecision highp isampler3D;\nprecision highp isamplerCube;\nprecision highp isampler2DArray;\n\nprecision highp sampler2DShadow;\nprecision highp sampler2DArrayShadow;\nprecision highp samplerCubeShadow;\n";class sR extends DN{constructor(e,t){super(e,t,new rS),this.uniformGroups={},this.transforms=[],this.extensions={},this.builtins={vertex:[],fragment:[],compute:[]}}needsToWorkingColorSpace(e){return!0===e.isVideoTexture&&e.colorSpace!==T}_include(e){const t=YS[e];return t.build(this),this.addInclude(t),t}getMethod(e){return void 0!==YS[e]&&this._include(e),QS[e]||e}getBitcastMethod(e,t){return this.getMethod(`bitcast_${t}_${e}`)}getFloatPackingMethod(e){return this.getMethod(`floatpack_${e}_2x16`)}getFloatUnpackingMethod(e){return this.getMethod(`floatunpack_${e}_2x16`)}getTernary(e,t,r){return`${e} ? ${t} : ${r}`}getOutputStructName(){return""}buildFunctionCode(e){const t=e.layout,r=this.flowShaderNode(e),s=[];for(const e of t.inputs)s.push(this.getType(e.type)+" "+e.name);return`${this.getType(t.type)} ${t.name}( ${s.join(", ")} ) {\n\n\t${r.vars}\n\n${r.code}\n\treturn ${r.result};\n\n}`}setupPBO(e){const t=e.value;if(void 0===t.pbo){const e=t.array,r=t.count*t.itemSize,{itemSize:s}=t,i=t.array.constructor.name.toLowerCase().includes("int");let n=i?xt:Tt;2===s?n=i?St:G:3===s?n=i?Rt:Et:4===s&&(n=i?At:Se);const a={Float32Array:j,Uint8Array:ke,Uint16Array:Nt,Uint32Array:S,Int8Array:vt,Int16Array:_t,Int32Array:R,Uint8ClampedArray:ke},o=Math.pow(2,Math.ceil(Math.log2(Math.sqrt(r/s))));let u=Math.ceil(r/s/o);o*u*s0?i:"";t=`${r.name} {\n\t${s} ${e.name}[${n}];\n};\n`}else{const t=e.groupNode.name;if(void 0===s[t]){const e=this.uniformGroups[t];if(void 0!==e){const r=[];for(const t of e.uniforms){const e=t.getType(),s=this.getVectorType(e),i=t.nodeUniform.node.precision;let n=`${s} ${t.name};`;null!==i&&(n=ZS[i]+" "+n),r.push("\t"+n)}s[t]=r}}i=!0}if(!i){const s=e.node.precision;null!==s&&(t=ZS[s]+" "+t),t="uniform "+t,r.push(t)}}let i="";for(const e in s){const t=s[e];i+=this._getGLSLUniformStruct(e,t.join("\n"))+"\n"}return i+=r.join("\n"),i}getTypeFromAttribute(e){let t=super.getTypeFromAttribute(e);if(/^[iu]/.test(t)&&e.gpuType!==R){let r=e;e.isInterleavedBufferAttribute&&(r=e.data);const s=r.array;!1==(s instanceof Uint32Array||s instanceof Int32Array)&&(t=t.slice(1))}return t}getAttributes(e){let t="";if("vertex"===e||"compute"===e){const e=this.getAttributesArray();let r=0;for(const s of e)t+=`layout( location = ${r++} ) in ${s.type} ${s.name};\n`}return t}getStructMembers(e){const t=[];for(const r of e.members)t.push(`\t${r.type} ${r.name};`);return t.join("\n")}getStructs(e){const t=[],r=this.structs[e],s=[];for(const e of r)if(e.output)for(const t of e.members)s.push(`layout( location = ${t.index} ) out ${t.type} ${t.name};`);else{let r="struct "+e.name+" {\n";r+=this.getStructMembers(e),r+="\n};\n",t.push(r)}return 0===s.length&&s.push("layout( location = 0 ) out vec4 fragColor;"),"\n"+s.join("\n")+"\n\n"+t.join("\n")}getVaryings(e){let t="";const r=this.varyings;if("vertex"===e||"compute"===e)for(const s of r){"compute"===e&&(s.needsInterpolation=!0);const r=this.getType(s.type);if(s.needsInterpolation)if(s.interpolationType){t+=`${eR[s.interpolationType]||s.interpolationType} ${tR[s.interpolationSampling]||""} out ${r} ${s.name};\n`}else{t+=`${r.includes("int")||r.includes("uv")||r.includes("iv")?"flat ":""}out ${r} ${s.name};\n`}else t+=`${r} ${s.name};\n`}else if("fragment"===e)for(const e of r)if(e.needsInterpolation){const r=this.getType(e.type);if(e.interpolationType){t+=`${eR[e.interpolationType]||e.interpolationType} ${tR[e.interpolationSampling]||""} in ${r} ${e.name};\n`}else{t+=`${r.includes("int")||r.includes("uv")||r.includes("iv")?"flat ":""}in ${r} ${e.name};\n`}}for(const r of this.builtins[e])t+=`${r};\n`;return t}getVertexIndex(){return"uint( gl_VertexID )"}getInstanceIndex(){return"uint( gl_InstanceID )"}getInvocationLocalIndex(){return`uint( gl_InstanceID ) % ${this.object.workgroupSize.reduce((e,t)=>e*t,1)}u`}getSubgroupSize(){o("GLSLNodeBuilder: WebGLBackend does not support the subgroupSize node")}getInvocationSubgroupIndex(){o("GLSLNodeBuilder: WebGLBackend does not support the invocationSubgroupIndex node")}getSubgroupIndex(){o("GLSLNodeBuilder: WebGLBackend does not support the subgroupIndex node")}getDrawIndex(){return this.renderer.backend.extensions.has("WEBGL_multi_draw")?"uint( gl_DrawID )":null}getFrontFacing(){return"gl_FrontFacing"}getFragCoord(){return"gl_FragCoord.xy"}getFragDepth(){return"gl_FragDepth"}enableExtension(e,t,r=this.shaderStage){const s=this.extensions[r]||(this.extensions[r]=new Map);!1===s.has(e)&&s.set(e,{name:e,behavior:t})}getExtensions(e){const t=[];if("vertex"===e){const t=this.renderer.backend.extensions;this.object.isBatchedMesh&&t.has("WEBGL_multi_draw")&&this.enableExtension("GL_ANGLE_multi_draw","require",e)}const r=this.extensions[e];if(void 0!==r)for(const{name:e,behavior:s}of r.values())t.push(`#extension ${e} : ${s}`);return t.join("\n")}getClipDistance(){return"gl_ClipDistance"}isAvailable(e){let t=JS[e];if(void 0===t){let r;switch(t=!1,e){case"float32Filterable":r="OES_texture_float_linear";break;case"clipDistance":r="WEBGL_clip_cull_distance"}if(void 0!==r){const e=this.renderer.backend.extensions;e.has(r)&&(e.get(r),t=!0)}JS[e]=t}return t}isFlipY(){return!0}enableHardwareClipping(e){this.enableExtension("GL_ANGLE_clip_cull_distance","require"),this.builtins.vertex.push(`out float gl_ClipDistance[ ${e} ]`)}enableMultiview(){this.enableExtension("GL_OVR_multiview2","require","fragment"),this.enableExtension("GL_OVR_multiview2","require","vertex"),this.builtins.vertex.push("layout(num_views = 2) in")}registerTransform(e,t){this.transforms.push({varyingName:e,attributeNode:t})}getTransforms(){const e=this.transforms;let t="";for(let r=0;r0&&(r+="\n"),r+=`\t// flow -> ${n}\n\t`),r+=`${s.code}\n\t`,e===i&&"compute"!==t&&(r+="// result\n\t","vertex"===t?(r+="gl_Position = ",r+=`${s.result};`):"fragment"===t&&(e.outputNode.isOutputStructNode||(r+="fragColor = ",r+=`${s.result};`)))}const n=e[t];n.extensions=this.getExtensions(t),n.uniforms=this.getUniforms(t),n.attributes=this.getAttributes(t),n.varyings=this.getVaryings(t),n.vars=this.getVars(t),n.structs=this.getStructs(t),n.codes=this.getCodes(t),n.transforms=this.getTransforms(t),n.flow=r}null!==this.material?(this.vertexShader=this._getGLSLVertexCode(e.vertex),this.fragmentShader=this._getGLSLFragmentCode(e.fragment)):this.computeShader=this._getGLSLVertexCode(e.compute)}getUniformFromNode(e,t,r,s=null){const i=super.getUniformFromNode(e,t,r,s),n=this.getDataFromNode(e,r,this.globalCache);let a=n.uniformGPU;if(void 0===a){const s=e.groupNode,o=s.name,u=this.getBindGroupArray(o,r);if("texture"===t)a=new jS(i.name,i.node,s),u.push(a);else if("cubeTexture"===t||"cubeDepthTexture"===t)a=new XS(i.name,i.node,s),u.push(a);else if("texture3D"===t)a=new KS(i.name,i.node,s),u.push(a);else if("buffer"===t){i.name=`buffer${e.id}`;const t=this.getSharedDataFromNode(e);let r=t.buffer;void 0===r&&(e.name=`NodeBuffer_${e.id}`,r=new kS(e,s),r.name=e.name,t.buffer=r),u.push(r),a=r}else{let e=this.uniformGroups[o];void 0===e?(e=new $S(o,s),this.uniformGroups[o]=e,u.push(e)):-1===u.indexOf(e)&&u.push(e),a=this.getNodeUniform(i,t);const r=a.name;e.uniforms.some(e=>e.name===r)||e.addUniform(a)}n.uniformGPU=a}return i}}let iR=null,nR=null;class aR{constructor(e={}){this.parameters=Object.assign({},e),this.data=new WeakMap,this.renderer=null,this.domElement=null,this.timestampQueryPool={[wt.RENDER]:null,[wt.COMPUTE]:null},this.trackTimestamp=!0===e.trackTimestamp}async init(e){this.renderer=e}get coordinateSystem(){}beginRender(){}finishRender(){}beginCompute(){}finishCompute(){}draw(){}compute(){}createProgram(){}destroyProgram(){}createBindings(){}updateBindings(){}updateBinding(){}createRenderPipeline(){}createComputePipeline(){}needsRenderUpdate(){}getRenderCacheKey(){}createNodeBuilder(){}updateSampler(){}createDefaultTexture(){}createTexture(){}updateTexture(){}generateMipmaps(){}destroyTexture(){}async copyTextureToBuffer(){}copyTextureToTexture(){}copyFramebufferToTexture(){}createAttribute(){}createIndexAttribute(){}createStorageAttribute(){}updateAttribute(){}destroyAttribute(){}getContext(){}updateSize(){}updateViewport(){}updateTimeStampUID(e){const t=this.get(e),r=this.renderer.info.frame;let s;s=!0===e.isComputeNode?"c:"+this.renderer.info.compute.frameCalls:"r:"+this.renderer.info.render.frameCalls,t.timestampUID=s+":"+e.id+":f"+r}getTimestampUID(e){return this.get(e).timestampUID}getTimestampFrames(e){const t=this.timestampQueryPool[e];return t?t.getTimestampFrames():[]}_getQueryPool(e){const t=e.startsWith("c:")?wt.COMPUTE:wt.RENDER;return this.timestampQueryPool[t]}getTimestamp(e){return this._getQueryPool(e).getTimestamp(e)}hasTimestamp(e){return this._getQueryPool(e).hasTimestamp(e)}isOccluded(){}async resolveTimestampsAsync(e="render"){if(!this.trackTimestamp)return void v("WebGPURenderer: Timestamp tracking is disabled.");const t=this.timestampQueryPool[e];if(!t)return;const r=await t.resolveQueriesAsync();return this.renderer.info[e].timestamp=r,r}async getArrayBufferAsync(){}async hasFeatureAsync(){}hasFeature(){}getMaxAnisotropy(){}getDrawingBufferSize(){return iR=iR||new t,this.renderer.getDrawingBufferSize(iR)}setScissorTest(){}getClearColor(){const e=this.renderer;return nR=nR||new Fy,e.getClearColor(nR),nR.getRGB(nR),nR}getDomElement(){let e=this.domElement;return null===e&&(e=void 0!==this.parameters.canvas?this.parameters.canvas:Ct(),"setAttribute"in e&&e.setAttribute("data-engine",`three.js r${ot} webgpu`),this.domElement=e),e}hasCompatibility(){return!1}initRenderTarget(){}set(e,t){this.data.set(e,t)}get(e){let t=this.data.get(e);return void 0===t&&(t={},this.data.set(e,t)),t}has(e){return this.data.has(e)}delete(e){this.data.delete(e)}deleteBindGroupData(){}dispose(){}}let oR,uR,lR=0;class dR{constructor(e,t){this.buffers=[e.bufferGPU,t],this.type=e.type,this.bufferType=e.bufferType,this.pbo=e.pbo,this.byteLength=e.byteLength,this.bytesPerElement=e.BYTES_PER_ELEMENT,this.version=e.version,this.isInteger=e.isInteger,this.activeBufferIndex=0,this.baseId=e.id}get id(){return`${this.baseId}|${this.activeBufferIndex}`}get bufferGPU(){return this.buffers[this.activeBufferIndex]}get transformBuffer(){return this.buffers[1^this.activeBufferIndex]}switchBuffers(){this.activeBufferIndex^=1}}class cR{constructor(e){this.backend=e}createAttribute(e,t){const r=this.backend,{gl:s}=r,i=e.array,n=e.usage||s.STATIC_DRAW,a=e.isInterleavedBufferAttribute?e.data:e,o=r.get(a);let u,l=o.bufferGPU;if(void 0===l&&(l=this._createBuffer(s,t,i,n),o.bufferGPU=l,o.bufferType=t,o.version=a.version),i instanceof Float32Array)u=s.FLOAT;else if("undefined"!=typeof Float16Array&&i instanceof Float16Array)u=s.HALF_FLOAT;else if(i instanceof Uint16Array)u=e.isFloat16BufferAttribute?s.HALF_FLOAT:s.UNSIGNED_SHORT;else if(i instanceof Int16Array)u=s.SHORT;else if(i instanceof Uint32Array)u=s.UNSIGNED_INT;else if(i instanceof Int32Array)u=s.INT;else if(i instanceof Int8Array)u=s.BYTE;else if(i instanceof Uint8Array)u=s.UNSIGNED_BYTE;else{if(!(i instanceof Uint8ClampedArray))throw new Error("THREE.WebGLBackend: Unsupported buffer data format: "+i);u=s.UNSIGNED_BYTE}let d={bufferGPU:l,bufferType:t,type:u,byteLength:i.byteLength,bytesPerElement:i.BYTES_PER_ELEMENT,version:e.version,pbo:e.pbo,isInteger:u===s.INT||u===s.UNSIGNED_INT||e.gpuType===R,id:lR++};if(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute){const e=this._createBuffer(s,t,i,n);d=new dR(d,e)}r.set(e,d)}updateAttribute(e){const t=this.backend,{gl:r}=t,s=e.array,i=e.isInterleavedBufferAttribute?e.data:e,n=t.get(i),a=n.bufferType,o=e.isInterleavedBufferAttribute?e.data.updateRanges:e.updateRanges;if(r.bindBuffer(a,n.bufferGPU),0===o.length)r.bufferSubData(a,0,s);else{for(let e=0,t=o.length;e0?this.enable(s.SAMPLE_ALPHA_TO_COVERAGE):this.disable(s.SAMPLE_ALPHA_TO_COVERAGE),r>0&&this.currentClippingPlanes!==r){const e=12288;for(let t=0;t<8;t++)t{!function i(){const n=e.clientWaitSync(t,e.SYNC_FLUSH_COMMANDS_BIT,0);if(n===e.WAIT_FAILED)return e.deleteSync(t),void s();n!==e.TIMEOUT_EXPIRED?(e.deleteSync(t),r()):requestAnimationFrame(i)}()})}}let gR,mR,fR,yR=!1;class bR{constructor(e){this.backend=e,this.gl=e.gl,this.extensions=e.extensions,this.defaultTextures={},this._srcFramebuffer=null,this._dstFramebuffer=null,!1===yR&&(this._init(),yR=!0)}_init(){const e=this.gl;gR={[Or]:e.REPEAT,[xe]:e.CLAMP_TO_EDGE,[Ir]:e.MIRRORED_REPEAT},mR={[w]:e.NEAREST,[Vr]:e.NEAREST_MIPMAP_NEAREST,[nt]:e.NEAREST_MIPMAP_LINEAR,[oe]:e.LINEAR,[it]:e.LINEAR_MIPMAP_NEAREST,[K]:e.LINEAR_MIPMAP_LINEAR},fR={[Hr]:e.NEVER,[Wr]:e.ALWAYS,[A]:e.LESS,[Ze]:e.LEQUAL,[$r]:e.EQUAL,[zr]:e.GEQUAL,[Gr]:e.GREATER,[kr]:e.NOTEQUAL}}getGLTextureType(e){const{gl:t}=this;let r;return r=!0===e.isCubeTexture?t.TEXTURE_CUBE_MAP:!0===e.isArrayTexture||!0===e.isDataArrayTexture||!0===e.isCompressedArrayTexture?t.TEXTURE_2D_ARRAY:!0===e.isData3DTexture?t.TEXTURE_3D:t.TEXTURE_2D,r}getInternalFormat(e,t,r,s,i=!1){const{gl:n,extensions:a}=this;if(null!==e){if(void 0!==n[e])return n[e];d("WebGLBackend: Attempt to use non-existing WebGL internal format '"+e+"'")}let o=t;if(t===n.RED&&(r===n.FLOAT&&(o=n.R32F),r===n.HALF_FLOAT&&(o=n.R16F),r===n.UNSIGNED_BYTE&&(o=n.R8),r===n.UNSIGNED_SHORT&&(o=n.R16),r===n.UNSIGNED_INT&&(o=n.R32UI),r===n.BYTE&&(o=n.R8I),r===n.SHORT&&(o=n.R16I),r===n.INT&&(o=n.R32I)),t===n.RED_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.R8UI),r===n.UNSIGNED_SHORT&&(o=n.R16UI),r===n.UNSIGNED_INT&&(o=n.R32UI),r===n.BYTE&&(o=n.R8I),r===n.SHORT&&(o=n.R16I),r===n.INT&&(o=n.R32I)),t===n.RG&&(r===n.FLOAT&&(o=n.RG32F),r===n.HALF_FLOAT&&(o=n.RG16F),r===n.UNSIGNED_BYTE&&(o=n.RG8),r===n.UNSIGNED_SHORT&&(o=n.RG16),r===n.UNSIGNED_INT&&(o=n.RG32UI),r===n.BYTE&&(o=n.RG8I),r===n.SHORT&&(o=n.RG16I),r===n.INT&&(o=n.RG32I)),t===n.RG_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RG8UI),r===n.UNSIGNED_SHORT&&(o=n.RG16UI),r===n.UNSIGNED_INT&&(o=n.RG32UI),r===n.BYTE&&(o=n.RG8I),r===n.SHORT&&(o=n.RG16I),r===n.INT&&(o=n.RG32I)),t===n.RGB){const e=i?qr:p.getTransfer(s);r===n.FLOAT&&(o=n.RGB32F),r===n.HALF_FLOAT&&(o=n.RGB16F),r===n.UNSIGNED_BYTE&&(o=n.RGB8),r===n.UNSIGNED_SHORT&&(o=n.RGB16),r===n.UNSIGNED_INT&&(o=n.RGB32UI),r===n.BYTE&&(o=n.RGB8I),r===n.SHORT&&(o=n.RGB16I),r===n.INT&&(o=n.RGB32I),r===n.UNSIGNED_BYTE&&(o=e===g?n.SRGB8:n.RGB8),r===n.UNSIGNED_SHORT_5_6_5&&(o=n.RGB565),r===n.UNSIGNED_SHORT_5_5_5_1&&(o=n.RGB5_A1),r===n.UNSIGNED_SHORT_4_4_4_4&&(o=n.RGB4),r===n.UNSIGNED_INT_5_9_9_9_REV&&(o=n.RGB9_E5),r===n.UNSIGNED_INT_10F_11F_11F_REV&&(o=n.R11F_G11F_B10F)}if(t===n.RGB_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RGB8UI),r===n.UNSIGNED_SHORT&&(o=n.RGB16UI),r===n.UNSIGNED_INT&&(o=n.RGB32UI),r===n.BYTE&&(o=n.RGB8I),r===n.SHORT&&(o=n.RGB16I),r===n.INT&&(o=n.RGB32I)),t===n.RGBA){const e=i?qr:p.getTransfer(s);r===n.FLOAT&&(o=n.RGBA32F),r===n.HALF_FLOAT&&(o=n.RGBA16F),r===n.UNSIGNED_BYTE&&(o=n.RGBA8),r===n.UNSIGNED_SHORT&&(o=n.RGBA16),r===n.UNSIGNED_INT&&(o=n.RGBA32UI),r===n.BYTE&&(o=n.RGBA8I),r===n.SHORT&&(o=n.RGBA16I),r===n.INT&&(o=n.RGBA32I),r===n.UNSIGNED_BYTE&&(o=e===g?n.SRGB8_ALPHA8:n.RGBA8),r===n.UNSIGNED_SHORT_4_4_4_4&&(o=n.RGBA4),r===n.UNSIGNED_SHORT_5_5_5_1&&(o=n.RGB5_A1)}return t===n.RGBA_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RGBA8UI),r===n.UNSIGNED_SHORT&&(o=n.RGBA16UI),r===n.UNSIGNED_INT&&(o=n.RGBA32UI),r===n.BYTE&&(o=n.RGBA8I),r===n.SHORT&&(o=n.RGBA16I),r===n.INT&&(o=n.RGBA32I)),t===n.DEPTH_COMPONENT&&(r===n.UNSIGNED_SHORT&&(o=n.DEPTH_COMPONENT16),r===n.UNSIGNED_INT&&(o=n.DEPTH_COMPONENT24),r===n.FLOAT&&(o=n.DEPTH_COMPONENT32F)),t===n.DEPTH_STENCIL&&r===n.UNSIGNED_INT_24_8&&(o=n.DEPTH24_STENCIL8),o!==n.R16F&&o!==n.R32F&&o!==n.RG16F&&o!==n.RG32F&&o!==n.RGBA16F&&o!==n.RGBA32F||a.get("EXT_color_buffer_float"),o}setTextureParameters(e,t){const{gl:r,extensions:s,backend:i}=this,n=p.getPrimaries(p.workingColorSpace),a=t.colorSpace===T?null:p.getPrimaries(t.colorSpace),o=t.colorSpace===T||n===a?r.NONE:r.BROWSER_DEFAULT_WEBGL;r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,t.flipY),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),r.pixelStorei(r.UNPACK_ALIGNMENT,t.unpackAlignment),r.pixelStorei(r.UNPACK_COLORSPACE_CONVERSION_WEBGL,o),r.texParameteri(e,r.TEXTURE_WRAP_S,gR[t.wrapS]),r.texParameteri(e,r.TEXTURE_WRAP_T,gR[t.wrapT]),e!==r.TEXTURE_3D&&e!==r.TEXTURE_2D_ARRAY||t.isArrayTexture||r.texParameteri(e,r.TEXTURE_WRAP_R,gR[t.wrapR]),r.texParameteri(e,r.TEXTURE_MAG_FILTER,mR[t.magFilter]);const u=void 0!==t.mipmaps&&t.mipmaps.length>0,l=t.minFilter===oe&&u?K:t.minFilter;if(r.texParameteri(e,r.TEXTURE_MIN_FILTER,mR[l]),t.compareFunction&&(r.texParameteri(e,r.TEXTURE_COMPARE_MODE,r.COMPARE_REF_TO_TEXTURE),r.texParameteri(e,r.TEXTURE_COMPARE_FUNC,fR[t.compareFunction])),!0===s.has("EXT_texture_filter_anisotropic")){if(t.magFilter===w)return;if(t.minFilter!==nt&&t.minFilter!==K)return;if(t.type===j&&!1===s.has("OES_texture_float_linear"))return;if(t.anisotropy>1){const n=s.get("EXT_texture_filter_anisotropic");r.texParameterf(e,n.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(t.anisotropy,i.getMaxAnisotropy()))}}}createDefaultTexture(e){const{gl:t,backend:r,defaultTextures:s}=this,i=this.getGLTextureType(e);let n=s[i];void 0===n&&(n=t.createTexture(),r.state.bindTexture(i,n),t.texParameteri(i,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(i,t.TEXTURE_MAG_FILTER,t.NEAREST),s[i]=n),r.set(e,{textureGPU:n,glTextureType:i})}createTexture(e,t){const{gl:r,backend:s}=this,{levels:i,width:n,height:a,depth:o}=t,u=s.utils.convert(e.format,e.colorSpace),l=s.utils.convert(e.type),d=this.getInternalFormat(e.internalFormat,u,l,e.colorSpace,e.isVideoTexture),c=r.createTexture(),h=this.getGLTextureType(e);s.state.bindTexture(h,c),this.setTextureParameters(h,e),e.isArrayTexture||e.isDataArrayTexture||e.isCompressedArrayTexture?r.texStorage3D(r.TEXTURE_2D_ARRAY,i,d,n,a,o):e.isData3DTexture?r.texStorage3D(r.TEXTURE_3D,i,d,n,a,o):e.isVideoTexture||r.texStorage2D(h,i,d,n,a),s.set(e,{textureGPU:c,glTextureType:h,glFormat:u,glType:l,glInternalFormat:d})}copyBufferToTexture(e,t){const{gl:r,backend:s}=this,{textureGPU:i,glTextureType:n,glFormat:a,glType:o}=s.get(t),{width:u,height:l}=t.source.data;r.bindBuffer(r.PIXEL_UNPACK_BUFFER,e),s.state.bindTexture(n,i),r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,!1),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),r.texSubImage2D(n,0,0,0,u,l,a,o,0),r.bindBuffer(r.PIXEL_UNPACK_BUFFER,null),s.state.unbindTexture()}updateTexture(e,t){const{gl:r}=this,{width:s,height:i}=t,{textureGPU:n,glTextureType:a,glFormat:o,glType:u,glInternalFormat:l}=this.backend.get(e);if(!e.isRenderTargetTexture&&void 0!==n)if(this.backend.state.bindTexture(a,n),this.setTextureParameters(a,e),e.isCompressedTexture){const s=e.mipmaps,i=t.image;for(let t=0;t0){const t=jr(s.width,s.height,e.format,e.type);for(const i of e.layerUpdates){const e=s.data.subarray(i*t/s.data.BYTES_PER_ELEMENT,(i+1)*t/s.data.BYTES_PER_ELEMENT);r.texSubImage3D(r.TEXTURE_2D_ARRAY,0,0,0,i,s.width,s.height,1,o,u,e)}e.clearLayerUpdates()}else r.texSubImage3D(r.TEXTURE_2D_ARRAY,0,0,0,0,s.width,s.height,s.depth,o,u,s.data)}else if(e.isData3DTexture){const e=t.image;r.texSubImage3D(r.TEXTURE_3D,0,0,0,0,e.width,e.height,e.depth,o,u,e.data)}else if(e.isVideoTexture)e.update(),r.texImage2D(a,0,l,o,u,t.image);else{const n=e.mipmaps;if(n.length>0)for(let e=0,t=n.length;e0,c=t.renderTarget?t.renderTarget.height:this.backend.getDrawingBufferSize().y;if(d){const r=0!==a||0!==o;let d,h;if(!0===e.isDepthTexture?(d=s.DEPTH_BUFFER_BIT,h=s.DEPTH_ATTACHMENT,t.stencil&&(d|=s.STENCIL_BUFFER_BIT)):(d=s.COLOR_BUFFER_BIT,h=s.COLOR_ATTACHMENT0),r){const e=this.backend.get(t.renderTarget),r=e.framebuffers[t.getCacheKey()],h=e.msaaFrameBuffer;i.bindFramebuffer(s.DRAW_FRAMEBUFFER,r),i.bindFramebuffer(s.READ_FRAMEBUFFER,h);const p=c-o-l;s.blitFramebuffer(a,p,a+u,p+l,a,p,a+u,p+l,d,s.NEAREST),i.bindFramebuffer(s.READ_FRAMEBUFFER,r),i.bindTexture(s.TEXTURE_2D,n),s.copyTexSubImage2D(s.TEXTURE_2D,0,0,0,a,p,u,l),i.unbindTexture()}else{const e=s.createFramebuffer();i.bindFramebuffer(s.DRAW_FRAMEBUFFER,e),s.framebufferTexture2D(s.DRAW_FRAMEBUFFER,h,s.TEXTURE_2D,n,0),s.blitFramebuffer(0,0,u,l,0,0,u,l,d,s.NEAREST),s.deleteFramebuffer(e)}}else i.bindTexture(s.TEXTURE_2D,n),s.copyTexSubImage2D(s.TEXTURE_2D,0,0,0,a,c-l-o,u,l),i.unbindTexture();e.generateMipmaps&&this.generateMipmaps(e),this.backend._setFramebuffer(t)}setupRenderBufferStorage(e,t,r,s=!1){const{gl:i}=this,n=t.renderTarget,{depthTexture:a,depthBuffer:o,stencilBuffer:u,width:l,height:d}=n;if(i.bindRenderbuffer(i.RENDERBUFFER,e),o&&!u){let t=i.DEPTH_COMPONENT24;if(!0===s){this.extensions.get("WEBGL_multisampled_render_to_texture").renderbufferStorageMultisampleEXT(i.RENDERBUFFER,n.samples,t,l,d)}else r>0?(a&&a.isDepthTexture&&a.type===i.FLOAT&&(t=i.DEPTH_COMPONENT32F),i.renderbufferStorageMultisample(i.RENDERBUFFER,r,t,l,d)):i.renderbufferStorage(i.RENDERBUFFER,t,l,d);i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_ATTACHMENT,i.RENDERBUFFER,e)}else o&&u&&(r>0?i.renderbufferStorageMultisample(i.RENDERBUFFER,r,i.DEPTH24_STENCIL8,l,d):i.renderbufferStorage(i.RENDERBUFFER,i.DEPTH_STENCIL,l,d),i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_STENCIL_ATTACHMENT,i.RENDERBUFFER,e));i.bindRenderbuffer(i.RENDERBUFFER,null)}async copyTextureToBuffer(e,t,r,s,i,n){const{backend:a,gl:o}=this,{textureGPU:u,glFormat:l,glType:d}=this.backend.get(e),c=o.createFramebuffer();a.state.bindFramebuffer(o.READ_FRAMEBUFFER,c);const h=e.isCubeTexture?o.TEXTURE_CUBE_MAP_POSITIVE_X+n:o.TEXTURE_2D;o.framebufferTexture2D(o.READ_FRAMEBUFFER,o.COLOR_ATTACHMENT0,h,u,0);const p=this._getTypedArrayType(d),g=s*i*this._getBytesPerTexel(d,l),m=o.createBuffer();o.bindBuffer(o.PIXEL_PACK_BUFFER,m),o.bufferData(o.PIXEL_PACK_BUFFER,g,o.STREAM_READ),o.readPixels(t,r,s,i,l,d,0),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),await a.utils._clientWaitAsync();const f=new p(g/p.BYTES_PER_ELEMENT);return o.bindBuffer(o.PIXEL_PACK_BUFFER,m),o.getBufferSubData(o.PIXEL_PACK_BUFFER,0,f),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),a.state.bindFramebuffer(o.READ_FRAMEBUFFER,null),o.deleteFramebuffer(c),f}_getTypedArrayType(e){const{gl:t}=this;if(e===t.UNSIGNED_BYTE)return Uint8Array;if(e===t.UNSIGNED_SHORT_4_4_4_4)return Uint16Array;if(e===t.UNSIGNED_SHORT_5_5_5_1)return Uint16Array;if(e===t.UNSIGNED_SHORT_5_6_5)return Uint16Array;if(e===t.UNSIGNED_SHORT)return Uint16Array;if(e===t.UNSIGNED_INT)return Uint32Array;if(e===t.HALF_FLOAT)return Uint16Array;if(e===t.FLOAT)return Float32Array;throw new Error(`Unsupported WebGL type: ${e}`)}_getBytesPerTexel(e,t){const{gl:r}=this;let s=0;return e===r.UNSIGNED_BYTE&&(s=1),e!==r.UNSIGNED_SHORT_4_4_4_4&&e!==r.UNSIGNED_SHORT_5_5_5_1&&e!==r.UNSIGNED_SHORT_5_6_5&&e!==r.UNSIGNED_SHORT&&e!==r.HALF_FLOAT||(s=2),e!==r.UNSIGNED_INT&&e!==r.FLOAT||(s=4),t===r.RGBA?4*s:t===r.RGB?3*s:t===r.ALPHA?s:void 0}dispose(){const{gl:e}=this;null!==this._srcFramebuffer&&e.deleteFramebuffer(this._srcFramebuffer),null!==this._dstFramebuffer&&e.deleteFramebuffer(this._dstFramebuffer)}}function xR(e){return e.isDataTexture?e.image.data:"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas?e:e.data}class TR{constructor(e){this.backend=e,this.gl=this.backend.gl,this.availableExtensions=this.gl.getSupportedExtensions(),this.extensions={}}get(e){let t=this.extensions[e];return void 0===t&&(t=this.gl.getExtension(e),this.extensions[e]=t),t}has(e){return this.availableExtensions.includes(e)}}class _R{constructor(e){this.backend=e,this.maxAnisotropy=null}getMaxAnisotropy(){if(null!==this.maxAnisotropy)return this.maxAnisotropy;const e=this.backend.gl,t=this.backend.extensions;if(!0===t.has("EXT_texture_filter_anisotropic")){const r=t.get("EXT_texture_filter_anisotropic");this.maxAnisotropy=e.getParameter(r.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else this.maxAnisotropy=0;return this.maxAnisotropy}}const vR={WEBGL_multi_draw:"WEBGL_multi_draw",WEBGL_compressed_texture_astc:"texture-compression-astc",WEBGL_compressed_texture_etc:"texture-compression-etc2",WEBGL_compressed_texture_etc1:"texture-compression-etc1",WEBGL_compressed_texture_pvrtc:"texture-compression-pvrtc",WEBGL_compressed_texture_s3tc:"texture-compression-s3tc",EXT_texture_compression_bptc:"texture-compression-bc",EXT_disjoint_timer_query_webgl2:"timestamp-query",OVR_multiview2:"OVR_multiview2"};class NR{constructor(e){this.gl=e.gl,this.extensions=e.extensions,this.info=e.renderer.info,this.mode=null,this.index=0,this.type=null,this.object=null}render(e,t){const{gl:r,mode:s,object:i,type:n,info:a,index:o}=this;0!==o?r.drawElements(s,t,n,e):r.drawArrays(s,e,t),a.update(i,t,1)}renderInstances(e,t,r){const{gl:s,mode:i,type:n,index:a,object:o,info:u}=this;0!==r&&(0!==a?s.drawElementsInstanced(i,t,n,e,r):s.drawArraysInstanced(i,e,t,r),u.update(o,t,r))}renderMultiDraw(e,t,r){const{extensions:s,mode:i,object:n,info:a}=this;if(0===r)return;const o=s.get("WEBGL_multi_draw");if(null===o)for(let s=0;sthis.maxQueries)return v(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`),null;const t=this.currentQueryIndex;return this.currentQueryIndex+=2,this.queryStates.set(t,"inactive"),this.queryOffsets.set(e,t),t}beginQuery(e){if(!this.trackTimestamp||this.isDisposed)return;const t=this.queryOffsets.get(e);if(null==t)return;if(null!==this.activeQuery)return;const r=this.queries[t];if(r)try{"inactive"===this.queryStates.get(t)&&(this.gl.beginQuery(this.ext.TIME_ELAPSED_EXT,r),this.activeQuery=t,this.queryStates.set(t,"started"))}catch(e){o("Error in beginQuery:",e),this.activeQuery=null,this.queryStates.set(t,"inactive")}}endQuery(e){if(!this.trackTimestamp||this.isDisposed)return;const t=this.queryOffsets.get(e);if(null!=t&&this.activeQuery===t)try{this.gl.endQuery(this.ext.TIME_ELAPSED_EXT),this.queryStates.set(t,"ended"),this.activeQuery=null}catch(e){o("Error in endQuery:",e),this.queryStates.set(t,"inactive"),this.activeQuery=null}}async resolveQueriesAsync(){if(!this.trackTimestamp||this.pendingResolve)return this.lastValue;this.pendingResolve=!0;try{const e=new Map;for(const[t,r]of this.queryOffsets){if("ended"===this.queryStates.get(r)){const s=this.queries[r];e.set(t,this.resolveQuery(s))}}if(0===e.size)return this.lastValue;const t={},r=[];for(const[s,i]of e){const e=s.match(/^(.*):f(\d+)$/),n=parseInt(e[2]);!1===r.includes(n)&&r.push(n),void 0===t[n]&&(t[n]=0);const a=await i;this.timestamps.set(s,a),t[n]+=a}const s=t[r[r.length-1]];return this.lastValue=s,this.frames=r,this.currentQueryIndex=0,this.queryOffsets.clear(),this.queryStates.clear(),this.activeQuery=null,s}catch(e){return o("Error resolving queries:",e),this.lastValue}finally{this.pendingResolve=!1}}async resolveQuery(e){return new Promise(t=>{if(this.isDisposed)return void t(this.lastValue);let r,s=!1;const i=e=>{s||(s=!0,r&&(clearTimeout(r),r=null),t(e))},n=()=>{if(this.isDisposed)i(this.lastValue);else try{if(this.gl.getParameter(this.ext.GPU_DISJOINT_EXT))return void i(this.lastValue);if(!this.gl.getQueryParameter(e,this.gl.QUERY_RESULT_AVAILABLE))return void(r=setTimeout(n,1));const s=this.gl.getQueryParameter(e,this.gl.QUERY_RESULT);t(Number(s)/1e6)}catch(e){o("Error checking query:",e),t(this.lastValue)}};n()})}dispose(){if(!this.isDisposed&&(this.isDisposed=!0,this.trackTimestamp)){for(const e of this.queries)this.gl.deleteQuery(e);this.queries=[],this.queryStates.clear(),this.queryOffsets.clear(),this.lastValue=0,this.activeQuery=null}}}class ER extends aR{constructor(e={}){super(e),this.isWebGLBackend=!0,this.attributeUtils=null,this.extensions=null,this.capabilities=null,this.textureUtils=null,this.bufferRenderer=null,this.gl=null,this.state=null,this.utils=null,this.vaoCache={},this.transformFeedbackCache={},this.discard=!1,this.disjoint=null,this.parallel=null,this._currentContext=null,this._knownBindings=new WeakSet,this._supportsInvalidateFramebuffer="undefined"!=typeof navigator&&/OculusBrowser/g.test(navigator.userAgent),this._xrFramebuffer=null}init(e){super.init(e);const t=this.parameters,r={antialias:e.currentSamples>0,alpha:!0,depth:e.depth,stencil:e.stencil},s=void 0!==t.context?t.context:e.domElement.getContext("webgl2",r);function i(t){t.preventDefault();const r={api:"WebGL",message:t.statusMessage||"Unknown reason",reason:null,originalEvent:t};e.onDeviceLost(r)}this._onContextLost=i,e.domElement.addEventListener("webglcontextlost",i,!1),this.gl=s,this.extensions=new TR(this),this.capabilities=new _R(this),this.attributeUtils=new cR(this),this.textureUtils=new bR(this),this.bufferRenderer=new NR(this),this.state=new hR(this),this.utils=new pR(this),this.extensions.get("EXT_color_buffer_float"),this.extensions.get("WEBGL_clip_cull_distance"),this.extensions.get("OES_texture_float_linear"),this.extensions.get("EXT_color_buffer_half_float"),this.extensions.get("WEBGL_multisampled_render_to_texture"),this.extensions.get("WEBGL_render_shared_exponent"),this.extensions.get("WEBGL_multi_draw"),this.extensions.get("OVR_multiview2"),this.disjoint=this.extensions.get("EXT_disjoint_timer_query_webgl2"),this.parallel=this.extensions.get("KHR_parallel_shader_compile"),this.drawBuffersIndexedExt=this.extensions.get("OES_draw_buffers_indexed")}get coordinateSystem(){return c}async getArrayBufferAsync(e){return await this.attributeUtils.getArrayBufferAsync(e)}async makeXRCompatible(){!0!==this.gl.getContextAttributes().xrCompatible&&await this.gl.makeXRCompatible()}setXRTarget(e){this._xrFramebuffer=e}setXRRenderTargetTextures(e,t,r=null){const s=this.gl;if(this.set(e.texture,{textureGPU:t,glInternalFormat:s.RGBA8}),null!==r){const t=e.stencilBuffer?s.DEPTH24_STENCIL8:s.DEPTH_COMPONENT24;this.set(e.depthTexture,{textureGPU:r,glInternalFormat:t}),!0===this.extensions.has("WEBGL_multisampled_render_to_texture")&&!0===e._autoAllocateDepthBuffer&&!1===e.multiview&&d("WebGLBackend: Render-to-texture extension was disabled because an external texture was provided"),e._autoAllocateDepthBuffer=!1}}initTimestampQuery(e,t){if(!this.disjoint||!this.trackTimestamp)return;this.timestampQueryPool[e]||(this.timestampQueryPool[e]=new RR(this.gl,e,2048));const r=this.timestampQueryPool[e];null!==r.allocateQueriesForContext(t)&&r.beginQuery(t)}prepareTimestampBuffer(e,t){if(!this.disjoint||!this.trackTimestamp)return;this.timestampQueryPool[e].endQuery(t)}getContext(){return this.gl}beginRender(e){const{state:t}=this,r=this.get(e);if(e.viewport)this.updateViewport(e);else{const{width:e,height:r}=this.getDrawingBufferSize();t.viewport(0,0,e,r)}if(e.scissor)this.updateScissor(e);else{const{width:e,height:r}=this.getDrawingBufferSize();t.scissor(0,0,e,r)}this.initTimestampQuery(wt.RENDER,this.getTimestampUID(e)),r.previousContext=this._currentContext,this._currentContext=e,this._setFramebuffer(e),this.clear(e.clearColor,e.clearDepth,e.clearStencil,e,!1);const s=e.occlusionQueryCount;s>0&&(r.currentOcclusionQueries=r.occlusionQueries,r.currentOcclusionQueryObjects=r.occlusionQueryObjects,r.lastOcclusionObject=null,r.occlusionQueries=new Array(s),r.occlusionQueryObjects=new Array(s),r.occlusionQueryIndex=0)}finishRender(e){const{gl:t,state:r}=this,s=this.get(e),i=s.previousContext;r.resetVertexState();const n=e.occlusionQueryCount;n>0&&(n>s.occlusionQueryIndex&&t.endQuery(t.ANY_SAMPLES_PASSED),this.resolveOccludedAsync(e));const a=e.textures;if(null!==a)for(let e=0;e{let a=0;for(let t=0;t{t.isBatchedMesh?null!==t._multiDrawInstances?(v("WebGLBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."),b.renderMultiDrawInstances(t._multiDrawStarts,t._multiDrawCounts,t._multiDrawCount,t._multiDrawInstances)):this.hasFeature("WEBGL_multi_draw")?b.renderMultiDraw(t._multiDrawStarts,t._multiDrawCounts,t._multiDrawCount):v("WebGLBackend: WEBGL_multi_draw not supported."):T>1?b.renderInstances(_,x,T):b.render(_,x)};if(!0===e.camera.isArrayCamera&&e.camera.cameras.length>0&&!1===e.camera.isMultiViewCamera){const r=this.get(e.camera),s=e.camera.cameras,i=e.getBindingGroup("cameraIndex").bindings[0];if(void 0===r.indexesGPU||r.indexesGPU.length!==s.length){const e=new Uint32Array([0,0,0,0]),t=[];for(let r=0,i=s.length;r{const i=this.parallel,n=()=>{r.getProgramParameter(a,i.COMPLETION_STATUS_KHR)?(this._completeCompile(e,s),t()):requestAnimationFrame(n)};n()});return void t.push(i)}this._completeCompile(e,s)}_handleSource(e,t){const r=e.split("\n"),s=[],i=Math.max(t-6,0),n=Math.min(t+6,r.length);for(let e=i;e":" "} ${i}: ${r[e]}`)}return s.join("\n")}_getShaderErrors(e,t,r){const s=e.getShaderParameter(t,e.COMPILE_STATUS),i=(e.getShaderInfoLog(t)||"").trim();if(s&&""===i)return"";const n=/ERROR: 0:(\d+)/.exec(i);if(n){const s=parseInt(n[1]);return r.toUpperCase()+"\n\n"+i+"\n\n"+this._handleSource(e.getShaderSource(t),s)}return i}_logProgramError(e,t,r){if(this.renderer.debug.checkShaderErrors){const s=this.gl,i=(s.getProgramInfoLog(e)||"").trim();if(!1===s.getProgramParameter(e,s.LINK_STATUS))if("function"==typeof this.renderer.debug.onShaderError)this.renderer.debug.onShaderError(s,e,r,t);else{const n=this._getShaderErrors(s,r,"vertex"),a=this._getShaderErrors(s,t,"fragment");o("THREE.WebGLProgram: Shader Error "+s.getError()+" - VALIDATE_STATUS "+s.getProgramParameter(e,s.VALIDATE_STATUS)+"\n\nProgram Info Log: "+i+"\n"+n+"\n"+a)}else""!==i&&d("WebGLProgram: Program Info Log:",i)}}_completeCompile(e,t){const{state:r,gl:s}=this,i=this.get(t),{programGPU:n,fragmentShader:a,vertexShader:o}=i;!1===s.getProgramParameter(n,s.LINK_STATUS)&&this._logProgramError(n,a,o),r.useProgram(n);const u=e.getBindings();this._setupBindings(u,n),this.set(t,{programGPU:n})}createComputePipeline(e,t){const{state:r,gl:s}=this,i={stage:"fragment",code:"#version 300 es\nprecision highp float;\nvoid main() {}"};this.createProgram(i);const{computeProgram:n}=e,a=s.createProgram(),o=this.get(i).shaderGPU,u=this.get(n).shaderGPU,l=n.transforms,d=[],c=[];for(let e=0;evR[t]===e),r=this.extensions;for(let e=0;e1,h=!0===i.isXRRenderTarget,p=!0===h&&!0===i._hasExternalTextures;let g=n.msaaFrameBuffer,m=n.depthRenderbuffer;const f=this.extensions.get("WEBGL_multisampled_render_to_texture"),y=this.extensions.get("OVR_multiview2"),b=this._useMultisampledExtension(i),x=wy(e);let T;if(l?(n.cubeFramebuffers||(n.cubeFramebuffers={}),T=n.cubeFramebuffers[x]):h&&!1===p?T=this._xrFramebuffer:(n.framebuffers||(n.framebuffers={}),T=n.framebuffers[x]),void 0===T){T=t.createFramebuffer(),r.bindFramebuffer(t.FRAMEBUFFER,T);const s=e.textures,o=[];if(l){n.cubeFramebuffers[x]=T;const{textureGPU:e}=this.get(s[0]),r=this.renderer._activeCubeFace,i=this.renderer._activeMipmapLevel;t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_CUBE_MAP_POSITIVE_X+r,e,i)}else{n.framebuffers[x]=T;for(let r=0;r0&&!1===b&&!i.multiview){if(void 0===g){const s=[];g=t.createFramebuffer(),r.bindFramebuffer(t.FRAMEBUFFER,g);const i=[],l=e.textures;for(let r=0;r0&&!1===this._useMultisampledExtension(s)){const n=i.framebuffers[e.getCacheKey()];let a=t.COLOR_BUFFER_BIT;s.resolveDepthBuffer&&(s.depthBuffer&&(a|=t.DEPTH_BUFFER_BIT),s.stencilBuffer&&s.resolveStencilBuffer&&(a|=t.STENCIL_BUFFER_BIT));const o=i.msaaFrameBuffer,u=i.msaaRenderbuffers,l=e.textures,d=l.length>1;if(r.bindFramebuffer(t.READ_FRAMEBUFFER,o),r.bindFramebuffer(t.DRAW_FRAMEBUFFER,n),d)for(let e=0;e0&&!0===this.extensions.has("WEBGL_multisampled_render_to_texture")&&!1!==e._autoAllocateDepthBuffer}dispose(){null!==this.textureUtils&&this.textureUtils.dispose();const e=this.extensions.get("WEBGL_lose_context");e&&e.loseContext(),this.renderer.domElement.removeEventListener("webglcontextlost",this._onContextLost)}}const AR="point-list",wR="line-list",CR="line-strip",MR="triangle-list",BR="undefined"!=typeof self&&self.GPUShaderStage?self.GPUShaderStage:{VERTEX:1,FRAGMENT:2,COMPUTE:4},FR="never",LR="less",PR="equal",DR="less-equal",UR="greater",IR="not-equal",OR="greater-equal",VR="always",kR="store",GR="load",zR="clear",$R="ccw",WR="cw",HR="none",qR="back",jR="uint16",XR="uint32",KR="r8unorm",YR="r8snorm",QR="r8uint",ZR="r8sint",JR="r16uint",eE="r16sint",tE="r16float",rE="rg8unorm",sE="rg8snorm",iE="rg8uint",nE="rg8sint",aE="r32uint",oE="r32sint",uE="r32float",lE="rg16uint",dE="rg16sint",cE="rg16float",hE="rgba8unorm",pE="rgba8unorm-srgb",gE="rgba8snorm",mE="rgba8uint",fE="rgba8sint",yE="bgra8unorm",bE="bgra8unorm-srgb",xE="rgb9e5ufloat",TE="rgb10a2unorm",_E="rg11b10ufloat",vE="rg32uint",NE="rg32sint",SE="rg32float",RE="rgba16uint",EE="rgba16sint",AE="rgba16float",wE="rgba32uint",CE="rgba32sint",ME="rgba32float",BE="depth16unorm",FE="depth24plus",LE="depth24plus-stencil8",PE="depth32float",DE="depth32float-stencil8",UE="bc1-rgba-unorm",IE="bc1-rgba-unorm-srgb",OE="bc2-rgba-unorm",VE="bc2-rgba-unorm-srgb",kE="bc3-rgba-unorm",GE="bc3-rgba-unorm-srgb",zE="bc4-r-unorm",$E="bc4-r-snorm",WE="bc5-rg-unorm",HE="bc5-rg-snorm",qE="bc6h-rgb-ufloat",jE="bc6h-rgb-float",XE="bc7-rgba-unorm",KE="bc7-rgba-unorm-srgb",YE="etc2-rgb8unorm",QE="etc2-rgb8unorm-srgb",ZE="etc2-rgb8a1unorm",JE="etc2-rgb8a1unorm-srgb",eA="etc2-rgba8unorm",tA="etc2-rgba8unorm-srgb",rA="eac-r11unorm",sA="eac-r11snorm",iA="eac-rg11unorm",nA="eac-rg11snorm",aA="astc-4x4-unorm",oA="astc-4x4-unorm-srgb",uA="astc-5x4-unorm",lA="astc-5x4-unorm-srgb",dA="astc-5x5-unorm",cA="astc-5x5-unorm-srgb",hA="astc-6x5-unorm",pA="astc-6x5-unorm-srgb",gA="astc-6x6-unorm",mA="astc-6x6-unorm-srgb",fA="astc-8x5-unorm",yA="astc-8x5-unorm-srgb",bA="astc-8x6-unorm",xA="astc-8x6-unorm-srgb",TA="astc-8x8-unorm",_A="astc-8x8-unorm-srgb",vA="astc-10x5-unorm",NA="astc-10x5-unorm-srgb",SA="astc-10x6-unorm",RA="astc-10x6-unorm-srgb",EA="astc-10x8-unorm",AA="astc-10x8-unorm-srgb",wA="astc-10x10-unorm",CA="astc-10x10-unorm-srgb",MA="astc-12x10-unorm",BA="astc-12x10-unorm-srgb",FA="astc-12x12-unorm",LA="astc-12x12-unorm-srgb",PA="clamp-to-edge",DA="repeat",UA="mirror-repeat",IA="linear",OA="nearest",VA="zero",kA="one",GA="src",zA="one-minus-src",$A="src-alpha",WA="one-minus-src-alpha",HA="dst",qA="one-minus-dst",jA="dst-alpha",XA="one-minus-dst-alpha",KA="src-alpha-saturated",YA="constant",QA="one-minus-constant",ZA="add",JA="subtract",ew="reverse-subtract",tw="min",rw="max",sw=0,iw=15,nw="keep",aw="zero",ow="replace",uw="invert",lw="increment-clamp",dw="decrement-clamp",cw="increment-wrap",hw="decrement-wrap",pw="storage",gw="read-only-storage",mw="write-only",fw="read-only",yw="read-write",bw="non-filtering",xw="comparison",Tw="float",_w="unfilterable-float",vw="depth",Nw="sint",Sw="uint",Rw="2d",Ew="3d",Aw="2d",ww="2d-array",Cw="cube",Mw="3d",Bw="all",Fw="vertex",Lw="instance",Pw={CoreFeaturesAndLimits:"core-features-and-limits",DepthClipControl:"depth-clip-control",Depth32FloatStencil8:"depth32float-stencil8",TextureCompressionBC:"texture-compression-bc",TextureCompressionBCSliced3D:"texture-compression-bc-sliced-3d",TextureCompressionETC2:"texture-compression-etc2",TextureCompressionASTC:"texture-compression-astc",TextureCompressionASTCSliced3D:"texture-compression-astc-sliced-3d",TimestampQuery:"timestamp-query",IndirectFirstInstance:"indirect-first-instance",ShaderF16:"shader-f16",RG11B10UFloat:"rg11b10ufloat-renderable",BGRA8UNormStorage:"bgra8unorm-storage",Float32Filterable:"float32-filterable",Float32Blendable:"float32-blendable",ClipDistances:"clip-distances",DualSourceBlending:"dual-source-blending",Subgroups:"subgroups",TextureFormatsTier1:"texture-formats-tier1",TextureFormatsTier2:"texture-formats-tier2"},Dw={"texture-compression-s3tc":"texture-compression-bc","texture-compression-etc1":"texture-compression-etc2"};class Uw extends WS{constructor(e,t,r){super(e,t?t.value:null),this.textureNode=t,this.groupNode=r}update(){const{textureNode:e}=this;return this.texture!==e.value?(this.texture=e.value,!0):super.update()}}class Iw extends IS{constructor(e,t){super(e,t?t.array:null),this._attribute=t,this.isStorageBuffer=!0}get attribute(){return this._attribute}}let Ow=0;class Vw extends Iw{constructor(e,t){super("StorageBuffer_"+Ow++,e?e.value:null),this.nodeUniform=e,this.access=e?e.access:ei.READ_WRITE,this.groupNode=t}get attribute(){return this.nodeUniform.value}get buffer(){return this.nodeUniform.value.array}}class kw extends ty{constructor(e){super(),this.device=e;this.mipmapSampler=e.createSampler({minFilter:IA}),this.flipYSampler=e.createSampler({minFilter:OA}),this.flipUniformBuffer=e.createBuffer({size:4,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),e.queue.writeBuffer(this.flipUniformBuffer,0,new Uint32Array([1])),this.noFlipUniformBuffer=e.createBuffer({size:4,usage:GPUBufferUsage.UNIFORM}),this.transferPipelines={},this.mipmapShaderModule=e.createShaderModule({label:"mipmap",code:"\nstruct VarysStruct {\n\t@builtin( position ) Position: vec4f,\n\t@location( 0 ) vTex : vec2f,\n\t@location( 1 ) @interpolate(flat, either) vBaseArrayLayer: u32,\n};\n\n@group( 0 ) @binding ( 2 )\nvar flipY: u32;\n\n@vertex\nfn mainVS(\n\t\t@builtin( vertex_index ) vertexIndex : u32,\n\t\t@builtin( instance_index ) instanceIndex : u32 ) -> VarysStruct {\n\n\tvar Varys : VarysStruct;\n\n\tvar pos = array(\n\t\tvec2f( -1, -1 ),\n\t\tvec2f( -1, 3 ),\n\t\tvec2f( 3, -1 ),\n\t);\n\n\tlet p = pos[ vertexIndex ];\n\tlet mult = select( vec2f( 0.5, -0.5 ), vec2f( 0.5, 0.5 ), flipY != 0 );\n\tVarys.vTex = p * vec2f( 0.5, -0.5 ) + vec2f( 0.5 );\n\tVarys.Position = vec4f( p, 0, 1 );\n\tVarys.vBaseArrayLayer = instanceIndex;\n\n\treturn Varys;\n\n}\n\n@group( 0 ) @binding( 0 )\nvar imgSampler : sampler;\n\n@group( 0 ) @binding( 1 )\nvar img2d : texture_2d;\n\n@fragment\nfn main_2d( Varys: VarysStruct ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( img2d, imgSampler, Varys.vTex );\n\n}\n\n@group( 0 ) @binding( 1 )\nvar img2dArray : texture_2d_array;\n\n@fragment\nfn main_2d_array( Varys: VarysStruct ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( img2dArray, imgSampler, Varys.vTex, Varys.vBaseArrayLayer );\n\n}\n\nconst faceMat = array(\n mat3x3f( 0, 0, -2, 0, -2, 0, 1, 1, 1 ), // pos-x\n mat3x3f( 0, 0, 2, 0, -2, 0, -1, 1, -1 ), // neg-x\n mat3x3f( 2, 0, 0, 0, 0, 2, -1, 1, -1 ), // pos-y\n mat3x3f( 2, 0, 0, 0, 0, -2, -1, -1, 1 ), // neg-y\n mat3x3f( 2, 0, 0, 0, -2, 0, -1, 1, 1 ), // pos-z\n mat3x3f( -2, 0, 0, 0, -2, 0, 1, 1, -1 ), // neg-z\n);\n\n@group( 0 ) @binding( 1 )\nvar imgCube : texture_cube;\n\n@fragment\nfn main_cube( Varys: VarysStruct ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( imgCube, imgSampler, faceMat[ Varys.vBaseArrayLayer ] * vec3f( fract( Varys.vTex ), 1 ) );\n\n}\n\n@group( 0 ) @binding( 1 )\nvar imgCubeArray : texture_cube_array;\n\n@fragment\nfn main_cube_array( Varys: VarysStruct ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( imgCubeArray, imgSampler, faceMat[ Varys.vBaseArrayLayer % 6 ] * vec3f( fract( Varys.vTex ), 1 ), Varys.vBaseArrayLayer );\n\n}\n"})}getTransferPipeline(e,t){const r=`${e}-${t=t||"2d-array"}`;let s=this.transferPipelines[r];return void 0===s&&(s=this.device.createRenderPipeline({label:`mipmap-${e}-${t}`,vertex:{module:this.mipmapShaderModule},fragment:{module:this.mipmapShaderModule,entryPoint:`main_${t.replace("-","_")}`,targets:[{format:e}]},layout:"auto"}),this.transferPipelines[e]=s),s}flipY(e,t,r=0){const s=t.format,{width:i,height:n}=t.size,a=this.device.createTexture({size:{width:i,height:n},format:s,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),o=this.getTransferPipeline(s,e.textureBindingViewDimension),u=this.getTransferPipeline(s,a.textureBindingViewDimension),l=this.device.createCommandEncoder({}),d=(e,t,r,s,i,n)=>{const a=e.getBindGroupLayout(0),o=this.device.createBindGroup({layout:a,entries:[{binding:0,resource:this.flipYSampler},{binding:1,resource:t.createView({dimension:t.textureBindingViewDimension||"2d-array",baseMipLevel:0,mipLevelCount:1})},{binding:2,resource:{buffer:n?this.flipUniformBuffer:this.noFlipUniformBuffer}}]}),u=l.beginRenderPass({colorAttachments:[{view:s.createView({dimension:"2d",baseMipLevel:0,mipLevelCount:1,baseArrayLayer:i,arrayLayerCount:1}),loadOp:zR,storeOp:kR}]});u.setPipeline(e),u.setBindGroup(0,o),u.draw(3,1,0,r),u.end()};d(o,e,r,a,0,!1),d(u,a,0,e,r,!0),this.device.queue.submit([l.finish()]),a.destroy()}generateMipmaps(e,t=null){const r=this.get(e),s=r.layers||this._mipmapCreateBundles(e),i=t||this.device.createCommandEncoder({label:"mipmapEncoder"});this._mipmapRunBundles(i,s),null===t&&this.device.queue.submit([i.finish()]),r.layers=s}_mipmapCreateBundles(e){const t=e.textureBindingViewDimension||"2d-array",r=this.getTransferPipeline(e.format,t),s=r.getBindGroupLayout(0),i=[];for(let n=1;n0)for(let t=0,n=s.length;t0)for(let t=0,n=s.length;t0?e.width:r.size.width,l=a>0?e.height:r.size.height;try{o.queue.copyExternalImageToTexture({source:e,flipY:i},{texture:t,mipLevel:a,origin:{x:0,y:0,z:s},premultipliedAlpha:n},{width:u,height:l,depthOrArrayLayers:1})}catch(e){}}_getPassUtils(){let e=this._passUtils;return null===e&&(this._passUtils=e=new kw(this.backend.device)),e}_generateMipmaps(e,t,r=0,s=null){this._getPassUtils().generateMipmaps(e,t,r,s)}_flipY(e,t,r=0){this._getPassUtils().flipY(e,t,r)}_copyBufferToTexture(e,t,r,s,i,n=0,a=0){const o=this.backend.device,u=e.data,l=this._getBytesPerTexel(r.format),d=e.width*l;o.queue.writeTexture({texture:t,mipLevel:a,origin:{x:0,y:0,z:s}},u,{offset:e.width*e.height*l*n,bytesPerRow:d},{width:e.width,height:e.height,depthOrArrayLayers:1}),!0===i&&this._flipY(t,r,s)}_copyCompressedBufferToTexture(e,t,r){const s=this.backend.device,i=this._getBlockData(r.format),n=r.size.depthOrArrayLayers>1;for(let a=0;a]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i,qw=/([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi,jw={f32:"float",i32:"int",u32:"uint",bool:"bool","vec2":"vec2","vec2":"ivec2","vec2":"uvec2","vec2":"bvec2",vec2f:"vec2",vec2i:"ivec2",vec2u:"uvec2",vec2b:"bvec2","vec3":"vec3","vec3":"ivec3","vec3":"uvec3","vec3":"bvec3",vec3f:"vec3",vec3i:"ivec3",vec3u:"uvec3",vec3b:"bvec3","vec4":"vec4","vec4":"ivec4","vec4":"uvec4","vec4":"bvec4",vec4f:"vec4",vec4i:"ivec4",vec4u:"uvec4",vec4b:"bvec4","mat2x2":"mat2",mat2x2f:"mat2","mat3x3":"mat3",mat3x3f:"mat3","mat4x4":"mat4",mat4x4f:"mat4",sampler:"sampler",texture_1d:"texture",texture_2d:"texture",texture_2d_array:"texture",texture_multisampled_2d:"cubeTexture",texture_depth_2d:"depthTexture",texture_depth_2d_array:"depthTexture",texture_depth_multisampled_2d:"depthTexture",texture_depth_cube:"depthTexture",texture_depth_cube_array:"depthTexture",texture_3d:"texture3D",texture_cube:"cubeTexture",texture_cube_array:"cubeTexture",texture_storage_1d:"storageTexture",texture_storage_2d:"storageTexture",texture_storage_2d_array:"storageTexture",texture_storage_3d:"storageTexture"};class Xw extends QN{constructor(e){const{type:t,inputs:r,name:s,inputsCode:i,blockCode:n,outputType:a}=(e=>{const t=(e=e.trim()).match(Hw);if(null!==t&&4===t.length){const r=t[2],s=[];let i=null;for(;null!==(i=qw.exec(r));)s.push({name:i[1],type:i[2]});const n=[];for(let e=0;e "+this.outputType:"";return`fn ${e} ( ${this.inputsCode.trim()} ) ${t}`+this.blockCode}}class Kw extends YN{parseFunction(e){return new Xw(e)}}const Yw={[ei.READ_ONLY]:"read",[ei.WRITE_ONLY]:"write",[ei.READ_WRITE]:"read_write"},Qw={[Or]:"repeat",[xe]:"clamp",[Ir]:"mirror"},Zw={vertex:BR.VERTEX,fragment:BR.FRAGMENT,compute:BR.COMPUTE},Jw={instance:!0,swizzleAssign:!1,storageBuffer:!0},eC={"^^":"tsl_xor"},tC={float:"f32",int:"i32",uint:"u32",bool:"bool",color:"vec3",vec2:"vec2",ivec2:"vec2",uvec2:"vec2",bvec2:"vec2",vec3:"vec3",ivec3:"vec3",uvec3:"vec3",bvec3:"vec3",vec4:"vec4",ivec4:"vec4",uvec4:"vec4",bvec4:"vec4",mat2:"mat2x2",mat3:"mat3x3",mat4:"mat4x4"},rC={},sC={tsl_xor:new Xx("fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }"),mod_float:new Xx("fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }"),mod_vec2:new Xx("fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }"),mod_vec3:new Xx("fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }"),mod_vec4:new Xx("fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }"),equals_bool:new Xx("fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }"),equals_bvec2:new Xx("fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }"),equals_bvec3:new Xx("fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }"),equals_bvec4:new Xx("fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }"),repeatWrapping_float:new Xx("fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }"),mirrorWrapping_float:new Xx("fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }"),clampWrapping_float:new Xx("fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }"),biquadraticTexture:new Xx("\nfn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, iRes : vec2u, level : u32 ) -> vec4f {\n\n\tlet res = vec2f( iRes );\n\n\tlet uvScaled = coord * res;\n\tlet uvWrapping = ( ( uvScaled % res ) + res ) % res;\n\n\t// https://www.shadertoy.com/view/WtyXRy\n\n\tlet uv = uvWrapping - 0.5;\n\tlet iuv = floor( uv );\n\tlet f = fract( uv );\n\n\tlet rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, level );\n\tlet rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, level );\n\tlet rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, level );\n\tlet rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, level );\n\n\treturn mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );\n\n}\n")},iC={dFdx:"dpdx",dFdy:"- dpdy",mod_float:"tsl_mod_float",mod_vec2:"tsl_mod_vec2",mod_vec3:"tsl_mod_vec3",mod_vec4:"tsl_mod_vec4",equals_bool:"tsl_equals_bool",equals_bvec2:"tsl_equals_bvec2",equals_bvec3:"tsl_equals_bvec3",equals_bvec4:"tsl_equals_bvec4",inversesqrt:"inverseSqrt",bitcast:"bitcast",floatpack_snorm_2x16:"pack2x16snorm",floatpack_unorm_2x16:"pack2x16unorm",floatpack_float16_2x16:"pack2x16float",floatunpack_snorm_2x16:"unpack2x16snorm",floatunpack_unorm_2x16:"unpack2x16unorm",floatunpack_float16_2x16:"unpack2x16float"};let nC="";!0!==("undefined"!=typeof navigator&&/Firefox|Deno/g.test(navigator.userAgent))&&(nC+="diagnostic( off, derivative_uniformity );\n");class aC extends DN{constructor(e,t){super(e,t,new Kw),this.uniformGroups={},this.uniformGroupsBindings={},this.builtins={},this.directives={},this.scopedArrays=new Map}_generateTextureSample(e,t,r,s,i,n=this.shaderStage){return"fragment"===n?s?i?`textureSample( ${t}, ${t}_sampler, ${r}, ${s}, ${i} )`:`textureSample( ${t}, ${t}_sampler, ${r}, ${s} )`:i?`textureSample( ${t}, ${t}_sampler, ${r}, ${i} )`:`textureSample( ${t}, ${t}_sampler, ${r} )`:this.generateTextureSampleLevel(e,t,r,"0",s)}generateTextureSampleLevel(e,t,r,s,i,n){return!1===this.isUnfilterable(e)?n?`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s} )`:this.isFilteredTexture(e)?this.generateFilteredTexture(e,t,r,n,s):this.generateTextureLod(e,t,r,i,n,s)}generateWrapFunction(e){const t=`tsl_coord_${Qw[e.wrapS]}S_${Qw[e.wrapT]}_${e.is3DTexture||e.isData3DTexture?"3d":"2d"}T`;let r=rC[t];if(void 0===r){const s=[],i=e.is3DTexture||e.isData3DTexture?"vec3f":"vec2f";let n=`fn ${t}( coord : ${i} ) -> ${i} {\n\n\treturn ${i}(\n`;const a=(e,t)=>{e===Or?(s.push(sC.repeatWrapping_float),n+=`\t\ttsl_repeatWrapping_float( coord.${t} )`):e===xe?(s.push(sC.clampWrapping_float),n+=`\t\ttsl_clampWrapping_float( coord.${t} )`):e===Ir?(s.push(sC.mirrorWrapping_float),n+=`\t\ttsl_mirrorWrapping_float( coord.${t} )`):(n+=`\t\tcoord.${t}`,d(`WebGPURenderer: Unsupported texture wrap type "${e}" for vertex shader.`))};a(e.wrapS,"x"),n+=",\n",a(e.wrapT,"y"),(e.is3DTexture||e.isData3DTexture)&&(n+=",\n",a(e.wrapR,"z")),n+="\n\t);\n\n}\n",rC[t]=r=new Xx(n,s)}return r.build(this),t}generateArrayDeclaration(e,t){return`array< ${this.getType(e)}, ${t} >`}generateTextureDimension(e,t,r){const s=this.getDataFromNode(e,this.shaderStage,this.globalCache);void 0===s.dimensionsSnippet&&(s.dimensionsSnippet={});let i=s.dimensionsSnippet[r];if(void 0===s.dimensionsSnippet[r]){let n,a;const{primarySamples:o}=this.renderer.backend.utils.getTextureSampleData(e),u=o>1;a=e.is3DTexture||e.isData3DTexture?"vec3":"vec2",n=u||e.isStorageTexture?t:`${t}${r?`, u32( ${r} )`:""}`,i=new Ru(new hl(`textureDimensions( ${n} )`,a)),s.dimensionsSnippet[r]=i,(e.isArrayTexture||e.isDataArrayTexture||e.is3DTexture||e.isData3DTexture)&&(s.arrayLayerCount=new Ru(new hl(`textureNumLayers(${t})`,"u32"))),e.isTextureCube&&(s.cubeFaceCount=new Ru(new hl("6u","u32")))}return i.build(this)}generateFilteredTexture(e,t,r,s,i="0u"){this._include("biquadraticTexture");const n=this.generateWrapFunction(e),a=this.generateTextureDimension(e,t,i);return s&&(r=`${r} + vec2(${s}) / ${a}`),`tsl_biquadraticTexture( ${t}, ${n}( ${r} ), ${a}, u32( ${i} ) )`}generateTextureLod(e,t,r,s,i,n="0u"){if(!0===e.isCubeTexture){i&&(r=`${r} + vec3(${i})`);return`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${e.isDepthTexture?"u32":"f32"}( ${n} ) )`}const a=this.generateWrapFunction(e),o=this.generateTextureDimension(e,t,n),u=e.is3DTexture||e.isData3DTexture?"vec3":"vec2";i&&(r=`${r} + ${u}(${i}) / ${u}( ${o} )`);return r=`${u}( clamp( floor( ${a}( ${r} ) * ${u}( ${o} ) ), ${`${u}( 0 )`}, ${`${u}( ${o} - ${"vec3"===u?"vec3( 1, 1, 1 )":"vec2( 1, 1 )"} )`} ) )`,this.generateTextureLoad(e,t,r,n,s,null)}generateTextureLoad(e,t,r,s,i,n){const a=!0===e.isStorageTexture;let o;return null!==s||a||(s="0u"),n&&(r=`${r} + ${n}`),i?o=a?`textureLoad( ${t}, ${r}, ${i} )`:`textureLoad( ${t}, ${r}, ${i}, u32( ${s} ) )`:a?o=`textureLoad( ${t}, ${r} )`:(o=`textureLoad( ${t}, ${r}, u32( ${s} ) )`,this.renderer.backend.compatibilityMode&&e.isDepthTexture&&(o+=".x")),o}generateTextureStore(e,t,r,s,i){let n;return n=s?`textureStore( ${t}, ${r}, ${s}, ${i} )`:`textureStore( ${t}, ${r}, ${i} )`,n}isSampleCompare(e){return!0===e.isDepthTexture&&null!==e.compareFunction&&this.renderer.hasCompatibility(E.TEXTURE_COMPARE)}isUnfilterable(e){return"float"!==this.getComponentTypeFromTexture(e)||!this.isAvailable("float32Filterable")&&!0===e.isDataTexture&&e.type===j||!1===this.isSampleCompare(e)&&e.minFilter===w&&e.magFilter===w||this.renderer.backend.utils.getTextureSampleData(e).primarySamples>1}generateTexture(e,t,r,s,i,n=this.shaderStage){let a=null;return a=this.isUnfilterable(e)?this.generateTextureLod(e,t,r,s,i,"0",n):this._generateTextureSample(e,t,r,s,i,n),a}generateTextureGrad(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return n?`textureSampleGrad( ${t}, ${t}_sampler, ${r}, ${s[0]}, ${s[1]}, ${n} )`:`textureSampleGrad( ${t}, ${t}_sampler, ${r}, ${s[0]}, ${s[1]} )`;o(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${a} shader.`)}generateTextureCompare(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return!0===e.isDepthTexture&&!0===e.isArrayTexture?n?`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${i}, ${s}, ${n} )`:`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${i}, ${s} )`:n?`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${s} )`;o(`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${a} shader.`)}generateTextureLevel(e,t,r,s,i,n){return!1===this.isUnfilterable(e)?n?`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s} )`:this.isFilteredTexture(e)?this.generateFilteredTexture(e,t,r,n,s):this.generateTextureLod(e,t,r,i,n,s)}generateTextureBias(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return n?`textureSampleBias( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleBias( ${t}, ${t}_sampler, ${r}, ${s} )`;o(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${a} shader.`)}getPropertyName(e,t=this.shaderStage){if(!0===e.isNodeVarying&&!0===e.needsInterpolation){if("vertex"===t)return`varyings.${e.name}`}else if(!0===e.isNodeUniform){const t=e.name,r=e.type;return"texture"===r||"cubeTexture"===r||"cubeDepthTexture"===r||"storageTexture"===r||"texture3D"===r?t:"buffer"===r||"storageBuffer"===r||"indirectStorageBuffer"===r?this.isCustomStruct(e)?t:t+".value":e.groupNode.name+"."+t}return super.getPropertyName(e)}getOutputStructName(){return"output"}getFunctionOperator(e){const t=eC[e];return void 0!==t?(this._include(t),t):null}getNodeAccess(e,t){return"compute"!==t?!0===e.isAtomic?(d("WebGPURenderer: Atomic operations are only supported in compute shaders."),ei.READ_WRITE):ei.READ_ONLY:e.access}getStorageAccess(e,t){return Yw[this.getNodeAccess(e,t)]}getUniformFromNode(e,t,r,s=null){const i=super.getUniformFromNode(e,t,r,s),n=this.getDataFromNode(e,r,this.globalCache);if(void 0===n.uniformGPU){let a;const o=e.groupNode,u=o.name,l=this.getBindGroupArray(u,r);if("texture"===t||"cubeTexture"===t||"cubeDepthTexture"===t||"storageTexture"===t||"texture3D"===t){let s=null;const n=this.getNodeAccess(e,r);"texture"===t||"storageTexture"===t?s=!0===e.value.is3DTexture?new KS(i.name,i.node,o,n):new jS(i.name,i.node,o,n):"cubeTexture"===t||"cubeDepthTexture"===t?s=new XS(i.name,i.node,o,n):"texture3D"===t&&(s=new KS(i.name,i.node,o,n)),s.store=!0===e.isStorageTextureNode,s.mipLevel=s.store?e.mipLevel:0,s.setVisibility(Zw[r]);if(!0===e.value.isCubeTexture||!1===this.isUnfilterable(e.value)&&!1===s.store){const e=new Uw(`${i.name}_sampler`,i.node,o);e.setVisibility(Zw[r]),l.push(e,s),a=[e,s]}else l.push(s),a=[s]}else if("buffer"===t||"storageBuffer"===t||"indirectStorageBuffer"===t){const n=this.getSharedDataFromNode(e);let u=n.buffer;if(void 0===u){u=new("buffer"===t?kS:Vw)(e,o),n.buffer=u}u.setVisibility(u.getVisibility()|Zw[r]),l.push(u),a=u,i.name=s||"NodeBuffer_"+i.id}else{let e=this.uniformGroups[u];void 0===e?(e=new $S(u,o),e.setVisibility(Zw[r]),this.uniformGroups[u]=e,l.push(e)):(e.setVisibility(e.getVisibility()|Zw[r]),-1===l.indexOf(e)&&l.push(e)),a=this.getNodeUniform(i,t);const s=a.name;e.uniforms.some(e=>e.name===s)||e.addUniform(a)}n.uniformGPU=a}return i}getBuiltin(e,t,r,s=this.shaderStage){const i=this.builtins[s]||(this.builtins[s]=new Map);return!1===i.has(e)&&i.set(e,{name:e,property:t,type:r}),t}hasBuiltin(e,t=this.shaderStage){return void 0!==this.builtins[t]&&this.builtins[t].has(e)}getVertexIndex(){return"vertex"===this.shaderStage?this.getBuiltin("vertex_index","vertexIndex","u32","attribute"):"vertexIndex"}buildFunctionCode(e){const t=e.layout,r=this.flowShaderNode(e),s=[];for(const e of t.inputs)s.push(e.name+" : "+this.getType(e.type));let i=`fn ${t.name}( ${s.join(", ")} ) -> ${this.getType(t.type)} {\n${r.vars}\n${r.code}\n`;return r.result&&(i+=`\treturn ${r.result};\n`),i+="\n}\n",i}getInstanceIndex(){return"vertex"===this.shaderStage?this.getBuiltin("instance_index","instanceIndex","u32","attribute"):"instanceIndex"}getInvocationLocalIndex(){return this.getBuiltin("local_invocation_index","invocationLocalIndex","u32","attribute")}getSubgroupSize(){return this.enableSubGroups(),this.getBuiltin("subgroup_size","subgroupSize","u32","attribute")}getInvocationSubgroupIndex(){return this.enableSubGroups(),this.getBuiltin("subgroup_invocation_id","invocationSubgroupIndex","u32","attribute")}getSubgroupIndex(){return this.enableSubGroups(),this.getBuiltin("subgroup_id","subgroupIndex","u32","attribute")}getDrawIndex(){return null}getFrontFacing(){return this.getBuiltin("front_facing","isFront","bool")}getFragCoord(){return this.getBuiltin("position","fragCoord","vec4")+".xy"}getFragDepth(){return"output."+this.getBuiltin("frag_depth","depth","f32","output")}getClipDistance(){return"varyings.hw_clip_distances"}isFlipY(){return!1}enableDirective(e,t=this.shaderStage){(this.directives[t]||(this.directives[t]=new Set)).add(e)}getDirectives(e){const t=[],r=this.directives[e];if(void 0!==r)for(const e of r)t.push(`enable ${e};`);return t.join("\n")}enableSubGroups(){this.enableDirective("subgroups")}enableSubgroupsF16(){this.enableDirective("subgroups-f16")}enableClipDistances(){this.enableDirective("clip_distances")}enableShaderF16(){this.enableDirective("f16")}enableDualSourceBlending(){this.enableDirective("dual_source_blending")}enableHardwareClipping(e){this.enableClipDistances(),this.getBuiltin("clip_distances","hw_clip_distances",`array`,"vertex")}getBuiltins(e){const t=[],r=this.builtins[e];if(void 0!==r)for(const{name:e,property:s,type:i}of r.values())t.push(`@builtin( ${e} ) ${s} : ${i}`);return t.join(",\n\t")}getScopedArray(e,t,r,s){return!1===this.scopedArrays.has(e)&&this.scopedArrays.set(e,{name:e,scope:t,bufferType:r,bufferCount:s}),e}getScopedArrays(e){if("compute"!==e)return;const t=[];for(const{name:e,scope:r,bufferType:s,bufferCount:i}of this.scopedArrays.values()){const n=this.getType(s);t.push(`var<${r}> ${e}: array< ${n}, ${i} >;`)}return t.join("\n")}getAttributes(e){const t=[];if("compute"===e&&(this.getBuiltin("global_invocation_id","globalId","vec3","attribute"),this.getBuiltin("workgroup_id","workgroupId","vec3","attribute"),this.getBuiltin("local_invocation_id","localId","vec3","attribute"),this.getBuiltin("num_workgroups","numWorkgroups","vec3","attribute"),this.renderer.hasFeature("subgroups")&&(this.enableDirective("subgroups",e),this.getBuiltin("subgroup_size","subgroupSize","u32","attribute"))),"vertex"===e||"compute"===e){const e=this.getBuiltins("attribute");e&&t.push(e);const r=this.getAttributesArray();for(let e=0,s=r.length;e"),t.push(`\t${s+r.name} : ${i}`)}return e.output&&t.push(`\t${this.getBuiltins("output")}`),t.join(",\n")}getStructs(e){let t="";const r=this.structs[e];if(r.length>0){const e=[];for(const t of r){let r=`struct ${t.name} {\n`;r+=this.getStructMembers(t),r+="\n};",e.push(r)}t="\n"+e.join("\n\n")+"\n"}return t}getVar(e,t,r=null){let s=`var ${t} : `;return s+=null!==r?this.generateArrayDeclaration(e,r):this.getType(e),s}getVars(e){const t=[],r=this.vars[e];if(void 0!==r)for(const e of r)t.push(`\t${this.getVar(e.type,e.name,e.count)};`);return`\n${t.join("\n")}\n`}getVaryings(e){const t=[];if("vertex"===e&&this.getBuiltin("position","builtinClipSpace","vec4","vertex"),"vertex"===e||"fragment"===e){const r=this.varyings,s=this.vars[e];for(let i=0;ir.value.itemSize;return s&&!i}getUniforms(e){const t=this.uniforms[e],r=[],s=[],i=[],n={};for(const i of t){const t=i.groupNode.name,a=this.bindingsIndexes[t];if("texture"===i.type||"cubeTexture"===i.type||"cubeDepthTexture"===i.type||"storageTexture"===i.type||"texture3D"===i.type){const t=i.node.value;let s;(!0===t.isCubeTexture||!1===this.isUnfilterable(t)&&!0!==i.node.isStorageTextureNode)&&(this.isSampleCompare(t)?r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name}_sampler : sampler_comparison;`):r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name}_sampler : sampler;`));let n="";const{primarySamples:o}=this.renderer.backend.utils.getTextureSampleData(t);if(o>1&&(n="_multisampled"),!0===t.isCubeTexture&&!0===t.isDepthTexture)s="texture_depth_cube";else if(!0===t.isCubeTexture)s="texture_cube";else if(!0===t.isDepthTexture)s=this.renderer.backend.compatibilityMode&&null===t.compareFunction?`texture${n}_2d`:`texture_depth${n}_2d${!0===t.isArrayTexture?"_array":""}`;else if(!0===i.node.isStorageTextureNode){const r=Ww(t),n=this.getStorageAccess(i.node,e),a=i.node.value.is3DTexture,o=i.node.value.isArrayTexture;s=`texture_storage_${a?"3d":"2d"+(o?"_array":"")}<${r}, ${n}>`}else if(!0===t.isArrayTexture||!0===t.isDataArrayTexture||!0===t.isCompressedArrayTexture)s="texture_2d_array";else if(!0===t.is3DTexture||!0===t.isData3DTexture)s="texture_3d";else{s=`texture${n}_2d<${this.getComponentTypeFromTexture(t).charAt(0)}32>`}r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name} : ${s};`)}else if("buffer"===i.type||"storageBuffer"===i.type||"indirectStorageBuffer"===i.type){const t=i.node,r=this.getType(t.getNodeType(this)),n=t.bufferCount,o=n>0&&"buffer"===i.type?", "+n:"",u=t.isStorageBufferNode?`storage, ${this.getStorageAccess(t,e)}`:"uniform";if(this.isCustomStruct(i))s.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var<${u}> ${i.name} : ${r};`);else{const e=`\tvalue : array< ${t.isAtomic?`atomic<${r}>`:`${r}`}${o} >`;s.push(this._getWGSLStructBinding(i.name,e,u,a.binding++,a.group))}}else{const e=i.groupNode.name;if(void 0===n[e]){const t=this.uniformGroups[e];if(void 0!==t){const r=[];for(const e of t.uniforms){const t=e.getType(),s=this.getType(this.getVectorType(t));r.push(`\t${e.name} : ${s}`)}let s=this.uniformGroupsBindings[e];void 0===s&&(s={index:a.binding++,id:a.group},this.uniformGroupsBindings[e]=s),n[e]={index:s.index,id:s.id,snippets:r}}}}}for(const e in n){const t=n[e];i.push(this._getWGSLStructBinding(e,t.snippets.join(",\n"),"uniform",t.index,t.id))}return[...r,...s,...i].join("\n")}buildCode(){const e=null!==this.material?{fragment:{},vertex:{}}:{compute:{}};this.sortBindingGroups();for(const t in e){this.shaderStage=t;const r=e[t];r.uniforms=this.getUniforms(t),r.attributes=this.getAttributes(t),r.varyings=this.getVaryings(t),r.structs=this.getStructs(t),r.vars=this.getVars(t),r.codes=this.getCodes(t),r.directives=this.getDirectives(t),r.scopedArrays=this.getScopedArrays(t);let s="// code\n\n";s+=this.flowCode[t];const i=this.flowNodes[t],n=i[i.length-1],a=n.outputNode,o=void 0!==a&&!0===a.isOutputStructNode;for(const e of i){const i=this.getFlowData(e),u=e.name;if(u&&(s.length>0&&(s+="\n"),s+=`\t// flow -> ${u}\n`),s+=`${i.code}\n\t`,e===n&&"compute"!==t)if(s+="// result\n\n\t","vertex"===t)s+=`varyings.builtinClipSpace = ${i.result};`;else if("fragment"===t)if(o)r.returnType=a.getNodeType(this),r.structs+="var output : "+r.returnType+";",s+=`return ${i.result};`;else{let e="\t@location(0) color: vec4";const t=this.getBuiltins("output");t&&(e+=",\n\t"+t),r.returnType="OutputStruct",r.structs+=this._getWGSLStruct("OutputStruct",e),r.structs+="\nvar output : OutputStruct;",s+=`output.color = ${i.result};\n\n\treturn output;`}}r.flow=s}if(this.shaderStage=null,null!==this.material)this.vertexShader=this._getWGSLVertexCode(e.vertex),this.fragmentShader=this._getWGSLFragmentCode(e.fragment);else{const t=this.object.workgroupSize;this.computeShader=this._getWGSLComputeCode(e.compute,t)}}getMethod(e,t=null){let r;return null!==t&&(r=this._getWGSLMethod(e+"_"+t)),void 0===r&&(r=this._getWGSLMethod(e)),r||e}getBitcastMethod(e){return`bitcast<${this.getType(e)}>`}getFloatPackingMethod(e){return this.getMethod(`floatpack_${e}_2x16`)}getFloatUnpackingMethod(e){return this.getMethod(`floatunpack_${e}_2x16`)}getTernary(e,t,r){return`select( ${r}, ${t}, ${e} )`}getType(e){return tC[e]||e}isAvailable(e){let t=Jw[e];return void 0===t&&("float32Filterable"===e?t=this.renderer.hasFeature("float32-filterable"):"clipDistance"===e&&(t=this.renderer.hasFeature("clip-distances")),Jw[e]=t),t}_getWGSLMethod(e){return void 0!==sC[e]&&this._include(e),iC[e]}_include(e){const t=sC[e];return t.build(this),this.addInclude(t),t}_getWGSLVertexCode(e){return`${this.getSignature()}\n// directives\n${e.directives}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// varyings\n${e.varyings}\nvar varyings : VaryingsStruct;\n\n// codes\n${e.codes}\n\n@vertex\nfn main( ${e.attributes} ) -> VaryingsStruct {\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n\treturn varyings;\n\n}\n`}_getWGSLFragmentCode(e){return`${this.getSignature()}\n// global\n${nC}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// codes\n${e.codes}\n\n@fragment\nfn main( ${e.varyings} ) -> ${e.returnType} {\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n}\n`}_getWGSLComputeCode(e,t){const[r,s,i]=t;return`${this.getSignature()}\n// directives\n${e.directives}\n\n// system\nvar instanceIndex : u32;\n\n// locals\n${e.scopedArrays}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// codes\n${e.codes}\n\n@compute @workgroup_size( ${r}, ${s}, ${i} )\nfn main( ${e.attributes} ) {\n\n\t// system\n\tinstanceIndex = globalId.x\n\t\t+ globalId.y * ( ${r} * numWorkgroups.x )\n\t\t+ globalId.z * ( ${r} * numWorkgroups.x ) * ( ${s} * numWorkgroups.y );\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n}\n`}_getWGSLStruct(e,t){return`\nstruct ${e} {\n${t}\n};`}_getWGSLStructBinding(e,t,r,s=0,i=0){const n=e+"Struct";return`${this._getWGSLStruct(n,t)}\n@binding( ${s} ) @group( ${i} )\nvar<${r}> ${e} : ${n};`}}class oC{constructor(e){this.backend=e}getCurrentDepthStencilFormat(e){let t;return e.depth&&(t=null!==e.depthTexture?this.getTextureFormatGPU(e.depthTexture):e.stencil?LE:FE),t}getTextureFormatGPU(e){return this.backend.get(e).format}getTextureSampleData(e){let t;if(e.isFramebufferTexture)t=1;else if(e.isDepthTexture&&!e.renderTarget){const e=this.backend.renderer,r=e.getRenderTarget();t=r?r.samples:e.currentSamples}else e.renderTarget&&(t=e.renderTarget.samples);t=t||1;const r=t>1&&null!==e.renderTarget&&!0!==e.isDepthTexture&&!0!==e.isFramebufferTexture;return{samples:t,primarySamples:r?1:t,isMSAA:r}}getCurrentColorFormat(e){let t;return t=null!==e.textures?this.getTextureFormatGPU(e.textures[0]):this.getPreferredCanvasFormat(),t}getCurrentColorFormats(e){return null!==e.textures?e.textures.map(e=>this.getTextureFormatGPU(e)):[this.getPreferredCanvasFormat()]}getCurrentColorSpace(e){return null!==e.textures?e.textures[0].colorSpace:this.backend.renderer.outputColorSpace}getPrimitiveTopology(e,t){return e.isPoints?AR:e.isLineSegments||e.isMesh&&!0===t.wireframe?wR:e.isLine?CR:e.isMesh?MR:void 0}getSampleCount(e){return e>=4?4:1}getSampleCountRenderContext(e){return null!==e.textures?this.getSampleCount(e.sampleCount):this.getSampleCount(this.backend.renderer.currentSamples)}getPreferredCanvasFormat(){const e=this.backend.parameters.outputType;if(void 0===e)return navigator.gpu.getPreferredCanvasFormat();if(e===ke)return yE;if(e===be)return AE;throw new Error("Unsupported output buffer type.")}}const uC=new Map([[Int8Array,["sint8","snorm8"]],[Uint8Array,["uint8","unorm8"]],[Int16Array,["sint16","snorm16"]],[Uint16Array,["uint16","unorm16"]],[Int32Array,["sint32","snorm32"]],[Uint32Array,["uint32","unorm32"]],[Float32Array,["float32"]]]);"undefined"!=typeof Float16Array&&uC.set(Float16Array,["float16"]);const lC=new Map([[at,["float16"]]]),dC=new Map([[Int32Array,"sint32"],[Int16Array,"sint32"],[Uint32Array,"uint32"],[Uint16Array,"uint32"],[Float32Array,"float32"]]);class cC{constructor(e){this.backend=e}createAttribute(e,t){const r=this._getBufferAttribute(e),s=this.backend,i=s.get(r);let n=i.buffer;if(void 0===n){const a=s.device;let o=r.array;if(!1===e.normalized)if(o.constructor===Int16Array||o.constructor===Int8Array)o=new Int32Array(o);else if((o.constructor===Uint16Array||o.constructor===Uint8Array)&&(o=new Uint32Array(o),t&GPUBufferUsage.INDEX))for(let e=0;e0&&(void 0===n.groups&&(n.groups=[],n.versions=[]),n.versions[r]===s&&(o=n.groups[r])),void 0===o&&(o=this.createBindGroup(e,a),r>0&&(n.groups[r]=o,n.versions[r]=s)),n.group=o}updateBinding(e){const t=this.backend,r=t.device,s=e.buffer,i=t.get(e).buffer,n=e.updateRanges;if(0===n.length)r.queue.writeBuffer(i,0,s,0);else{const e=Xr(s),t=e?1:s.BYTES_PER_ELEMENT;for(let a=0,o=n.length;a1&&(i+=`-${e.texture.depthOrArrayLayers}`),i+=`-${r}-${s}`,a=e[i],void 0===a){const n=Bw;let o;o=t.isSampledCubeTexture?Cw:t.isSampledTexture3D?Mw:t.texture.isArrayTexture||t.texture.isDataArrayTexture||t.texture.isCompressedArrayTexture?ww:Aw,a=e[i]=e.texture.createView({aspect:n,dimension:o,mipLevelCount:r,baseMipLevel:s})}}n.push({binding:i,resource:a})}else if(t.isSampler){const e=r.get(t.texture);n.push({binding:i,resource:e.sampler})}i++}return s.createBindGroup({label:"bindGroup_"+e.name,layout:t,entries:n})}_createLayoutEntries(e){const t=[];let r=0;for(const s of e.bindings){const e=this.backend,i={binding:r,visibility:s.visibility};if(s.isUniformBuffer||s.isStorageBuffer){const e={};s.isStorageBuffer&&(s.visibility&BR.COMPUTE&&(s.access===ei.READ_WRITE||s.access===ei.WRITE_ONLY)?e.type=pw:e.type=gw),i.buffer=e}else if(s.isSampledTexture&&s.store){const e={};e.format=this.backend.get(s.texture).texture.format;const t=s.access;e.access=t===ei.READ_WRITE?yw:t===ei.WRITE_ONLY?mw:fw,s.texture.isArrayTexture?e.viewDimension=ww:s.texture.is3DTexture&&(e.viewDimension=Mw),i.storageTexture=e}else if(s.isSampledTexture){const t={},{primarySamples:r}=e.utils.getTextureSampleData(s.texture);if(r>1&&(t.multisampled=!0,s.texture.isDepthTexture||(t.sampleType=_w)),s.texture.isDepthTexture)e.compatibilityMode&&null===s.texture.compareFunction?t.sampleType=_w:t.sampleType=vw;else if(s.texture.isDataTexture||s.texture.isDataArrayTexture||s.texture.isData3DTexture){const e=s.texture.type;e===R?t.sampleType=Nw:e===S?t.sampleType=Sw:e===j&&(this.backend.hasFeature("float32-filterable")?t.sampleType=Tw:t.sampleType=_w)}s.isSampledCubeTexture?t.viewDimension=Cw:s.texture.isArrayTexture||s.texture.isDataArrayTexture||s.texture.isCompressedArrayTexture?t.viewDimension=ww:s.isSampledTexture3D&&(t.viewDimension=Mw),i.texture=t}else if(s.isSampler){const t={};s.texture.isDepthTexture&&(null!==s.texture.compareFunction&&e.hasCompatibility(E.TEXTURE_COMPARE)?t.type=xw:t.type=bw),i.sampler=t}else o(`WebGPUBindingUtils: Unsupported binding "${s}".`);t.push(i),r++}return t}deleteBindGroupData(e){const{backend:t}=this,r=t.get(e);r.layout&&(r.layout.usedTimes--,0===r.layout.usedTimes&&this._bindGroupLayoutCache.delete(r.layoutKey),r.layout=void 0,r.layoutKey=void 0)}dispose(){this._bindGroupLayoutCache.clear()}}class gC{constructor(e){this.backend=e,this._activePipelines=new WeakMap}setPipeline(e,t){this._activePipelines.get(e)!==t&&(e.setPipeline(t),this._activePipelines.set(e,t))}_getSampleCount(e){return this.backend.utils.getSampleCountRenderContext(e)}createRenderPipeline(e,t){const{object:r,material:s,geometry:i,pipeline:n}=e,{vertexProgram:a,fragmentProgram:u}=n,l=this.backend,d=l.device,c=l.utils,h=l.get(n),p=[];for(const t of e.getBindings()){const e=l.get(t),{layoutGPU:r}=e.layout;p.push(r)}const g=l.attributeUtils.createShaderVertexBuffers(e);let m;s.blending===ee||s.blending===Ge&&!1===s.transparent||(m=this._getBlending(s));let f={};!0===s.stencilWrite&&(f={compare:this._getStencilCompare(s),failOp:this._getStencilOperation(s.stencilFail),depthFailOp:this._getStencilOperation(s.stencilZFail),passOp:this._getStencilOperation(s.stencilZPass)});const y=this._getColorWriteMask(s),b=[];if(null!==e.context.textures){const t=e.context.textures,r=e.context.mrt;for(let e=0;e1},layout:d.createPipelineLayout({bindGroupLayouts:p})},E={},A=e.context.depth,w=e.context.stencil;if(!0!==A&&!0!==w||(!0===A&&(E.format=N,E.depthWriteEnabled=s.depthWrite,E.depthCompare=v),!0===w&&(E.stencilFront=f,E.stencilBack={},E.stencilReadMask=s.stencilFuncMask,E.stencilWriteMask=s.stencilWriteMask),!0===s.polygonOffset&&(E.depthBias=s.polygonOffsetUnits,E.depthBiasSlopeScale=s.polygonOffsetFactor,E.depthBiasClamp=0),R.depthStencil=E),d.pushErrorScope("validation"),null===t)h.pipeline=d.createRenderPipeline(R),d.popErrorScope().then(e=>{null!==e&&(h.error=!0,o(e.message))});else{const e=new Promise(async e=>{try{h.pipeline=await d.createRenderPipelineAsync(R)}catch(e){}const t=await d.popErrorScope();null!==t&&(h.error=!0,o(t.message)),e()});t.push(e)}}createBundleEncoder(e,t="renderBundleEncoder"){const r=this.backend,{utils:s,device:i}=r,n=s.getCurrentDepthStencilFormat(e),a={label:t,colorFormats:s.getCurrentColorFormats(e),depthStencilFormat:n,sampleCount:this._getSampleCount(e)};return i.createRenderBundleEncoder(a)}createComputePipeline(e,t){const r=this.backend,s=r.device,i=r.get(e.computeProgram).module,n=r.get(e),a=[];for(const e of t){const t=r.get(e),{layoutGPU:s}=t.layout;a.push(s)}n.pipeline=s.createComputePipeline({compute:i,layout:s.createPipelineLayout({bindGroupLayouts:a})})}_getBlending(e){let t,r;const s=e.blending,i=e.blendSrc,n=e.blendDst,a=e.blendEquation;if(s===ct){const s=null!==e.blendSrcAlpha?e.blendSrcAlpha:i,o=null!==e.blendDstAlpha?e.blendDstAlpha:n,u=null!==e.blendEquationAlpha?e.blendEquationAlpha:a;t={srcFactor:this._getBlendFactor(i),dstFactor:this._getBlendFactor(n),operation:this._getBlendOperation(a)},r={srcFactor:this._getBlendFactor(s),dstFactor:this._getBlendFactor(o),operation:this._getBlendOperation(u)}}else{const i=(e,s,i,n)=>{t={srcFactor:e,dstFactor:s,operation:ZA},r={srcFactor:i,dstFactor:n,operation:ZA}};if(e.premultipliedAlpha)switch(s){case Ge:i(kA,WA,kA,WA);break;case Ht:i(kA,kA,kA,kA);break;case Wt:i(VA,zA,VA,kA);break;case $t:i(HA,WA,VA,kA)}else switch(s){case Ge:i($A,WA,kA,WA);break;case Ht:i($A,kA,kA,kA);break;case Wt:o(`WebGPURenderer: "SubtractiveBlending" requires "${e.isMaterial?"material":"blendMode"}.premultipliedAlpha = true".`);break;case $t:o(`WebGPURenderer: "MultiplyBlending" requires "${e.isMaterial?"material":"blendMode"}.premultipliedAlpha = true".`)}}if(void 0!==t&&void 0!==r)return{color:t,alpha:r};o("WebGPURenderer: Invalid blending: ",s)}_getBlendFactor(e){let t;switch(e){case ht:t=VA;break;case Vt:t=kA;break;case Ot:t=GA;break;case Pt:t=zA;break;case ze:t=$A;break;case $e:t=WA;break;case Ut:t=HA;break;case Lt:t=qA;break;case Dt:t=jA;break;case Ft:t=XA;break;case It:t=KA;break;case 211:t=YA;break;case 212:t=QA;break;default:o("WebGPURenderer: Blend factor not supported.",e)}return t}_getStencilCompare(e){let t;const r=e.stencilFunc;switch(r){case rs:t=FR;break;case ts:t=VR;break;case es:t=LR;break;case Jr:t=DR;break;case Zr:t=PR;break;case Qr:t=OR;break;case Yr:t=UR;break;case Kr:t=IR;break;default:o("WebGPURenderer: Invalid stencil function.",r)}return t}_getStencilOperation(e){let t;switch(e){case ds:t=nw;break;case ls:t=aw;break;case us:t=ow;break;case os:t=uw;break;case as:t=lw;break;case ns:t=dw;break;case is:t=cw;break;case ss:t=hw;break;default:o("WebGPURenderer: Invalid stencil operation.",t)}return t}_getBlendOperation(e){let t;switch(e){case We:t=ZA;break;case Bt:t=JA;break;case Mt:t=ew;break;case hs:t=tw;break;case cs:t=rw;break;default:o("WebGPUPipelineUtils: Blend equation not supported.",e)}return t}_getPrimitiveState(e,t,r){const s={},i=this.backend.utils;s.topology=i.getPrimitiveTopology(e,r),null!==t.index&&!0===e.isLine&&!0!==e.isLineSegments&&(s.stripIndexFormat=t.index.array instanceof Uint16Array?jR:XR);let n=r.side===M;return e.isMesh&&e.matrixWorld.determinant()<0&&(n=!n),s.frontFace=!0===n?WR:$R,s.cullMode=r.side===B?HR:qR,s}_getColorWriteMask(e){return!0===e.colorWrite?iw:sw}_getDepthCompare(e){let t;if(!1===e.depthTest)t=VR;else{const r=e.depthFunc;switch(r){case Jt:t=FR;break;case Zt:t=VR;break;case Qt:t=LR;break;case Yt:t=DR;break;case Kt:t=PR;break;case Xt:t=OR;break;case jt:t=UR;break;case qt:t=IR;break;default:o("WebGPUPipelineUtils: Invalid depth function.",r)}}return t}}class mC extends SR{constructor(e,t,r=2048){super(r),this.device=e,this.type=t,this.querySet=this.device.createQuerySet({type:"timestamp",count:this.maxQueries,label:`queryset_global_timestamp_${t}`});const s=8*this.maxQueries;this.resolveBuffer=this.device.createBuffer({label:`buffer_timestamp_resolve_${t}`,size:s,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),this.resultBuffer=this.device.createBuffer({label:`buffer_timestamp_result_${t}`,size:s,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ})}allocateQueriesForContext(e){if(!this.trackTimestamp||this.isDisposed)return null;if(this.currentQueryIndex+2>this.maxQueries)return v(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`),null;const t=this.currentQueryIndex;return this.currentQueryIndex+=2,this.queryOffsets.set(e,t),t}async resolveQueriesAsync(){if(!this.trackTimestamp||0===this.currentQueryIndex||this.isDisposed)return this.lastValue;if(this.pendingResolve)return this.pendingResolve;this.pendingResolve=this._resolveQueries();try{return await this.pendingResolve}finally{this.pendingResolve=null}}async _resolveQueries(){if(this.isDisposed)return this.lastValue;try{if("unmapped"!==this.resultBuffer.mapState)return this.lastValue;const e=new Map(this.queryOffsets),t=this.currentQueryIndex,r=8*t;this.currentQueryIndex=0,this.queryOffsets.clear();const s=this.device.createCommandEncoder();s.resolveQuerySet(this.querySet,0,t,this.resolveBuffer,0),s.copyBufferToBuffer(this.resolveBuffer,0,this.resultBuffer,0,r);const i=s.finish();if(this.device.queue.submit([i]),"unmapped"!==this.resultBuffer.mapState)return this.lastValue;if(await this.resultBuffer.mapAsync(GPUMapMode.READ,0,r),this.isDisposed)return"mapped"===this.resultBuffer.mapState&&this.resultBuffer.unmap(),this.lastValue;const n=new BigUint64Array(this.resultBuffer.getMappedRange(0,r)),a={},o=[];for(const[t,r]of e){const e=t.match(/^(.*):f(\d+)$/),s=parseInt(e[2]);!1===o.includes(s)&&o.push(s),void 0===a[s]&&(a[s]=0);const i=n[r],u=n[r+1],l=Number(u-i)/1e6;this.timestamps.set(t,l),a[s]+=l}const u=a[o[o.length-1]];return this.resultBuffer.unmap(),this.lastValue=u,this.frames=o,u}catch(e){return o("Error resolving queries:",e),"mapped"===this.resultBuffer.mapState&&this.resultBuffer.unmap(),this.lastValue}}async dispose(){if(!this.isDisposed){if(this.isDisposed=!0,this.pendingResolve)try{await this.pendingResolve}catch(e){o("Error waiting for pending resolve:",e)}if(this.resultBuffer&&"mapped"===this.resultBuffer.mapState)try{this.resultBuffer.unmap()}catch(e){o("Error unmapping buffer:",e)}this.querySet&&(this.querySet.destroy(),this.querySet=null),this.resolveBuffer&&(this.resolveBuffer.destroy(),this.resolveBuffer=null),this.resultBuffer&&(this.resultBuffer.destroy(),this.resultBuffer=null),this.queryOffsets.clear(),this.pendingResolve=null}}}class fC extends aR{constructor(e={}){super(e),this.isWebGPUBackend=!0,this.parameters.alpha=void 0===e.alpha||e.alpha,this.parameters.requiredLimits=void 0===e.requiredLimits?{}:e.requiredLimits,this.compatibilityMode=null,this.device=null,this.defaultRenderPassdescriptor=null,this.utils=new oC(this),this.attributeUtils=new cC(this),this.bindingUtils=new pC(this),this.pipelineUtils=new gC(this),this.textureUtils=new $w(this),this.occludedResolveCache=new Map;const t="undefined"==typeof navigator||!1===/Android/.test(navigator.userAgent);this._compatibility={[E.TEXTURE_COMPARE]:t}}async init(e){await super.init(e);const t=this.parameters;let r;if(void 0===t.device){const e={powerPreference:t.powerPreference,featureLevel:"compatibility"},s="undefined"!=typeof navigator?await navigator.gpu.requestAdapter(e):null;if(null===s)throw new Error("WebGPUBackend: Unable to create WebGPU adapter.");const i=Object.values(Pw),n=[];for(const e of i)s.features.has(e)&&n.push(e);const a={requiredFeatures:n,requiredLimits:t.requiredLimits};r=await s.requestDevice(a)}else r=t.device;this.compatibilityMode=!r.features.has("core-features-and-limits"),this.compatibilityMode&&(e._samples=0),r.lost.then(t=>{if("destroyed"===t.reason)return;const r={api:"WebGPU",message:t.message||"Unknown reason",reason:t.reason||null,originalEvent:t};e.onDeviceLost(r)}),this.device=r,this.trackTimestamp=this.trackTimestamp&&this.hasFeature(Pw.TimestampQuery),this.updateSize()}get context(){const e=this.renderer.getCanvasTarget(),t=this.get(e);let r=t.context;if(void 0===r){const s=this.parameters;r=!0===e.isDefaultCanvasTarget&&void 0!==s.context?s.context:e.domElement.getContext("webgpu"),"setAttribute"in e.domElement&&e.domElement.setAttribute("data-engine",`three.js r${ot} webgpu`);const i=s.alpha?"premultiplied":"opaque",n=s.outputType===be?"extended":"standard";r.configure({device:this.device,format:this.utils.getPreferredCanvasFormat(),usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_SRC,alphaMode:i,toneMapping:{mode:n}}),t.context=r}return r}get coordinateSystem(){return h}async getArrayBufferAsync(e){return await this.attributeUtils.getArrayBufferAsync(e)}getContext(){return this.context}_getDefaultRenderPassDescriptor(){const e=this.renderer,t=e.getCanvasTarget(),r=this.get(t),s=e.currentSamples;let i=r.descriptor;if(void 0===i||r.samples!==s){i={colorAttachments:[{view:null}]},!0!==e.depth&&!0!==e.stencil||(i.depthStencilAttachment={view:this.textureUtils.getDepthBuffer(e.depth,e.stencil).createView()});const t=i.colorAttachments[0];s>0?t.view=this.textureUtils.getColorBuffer().createView():t.resolveTarget=void 0,r.descriptor=i,r.samples=s}const n=i.colorAttachments[0];return s>0?n.resolveTarget=this.context.getCurrentTexture().createView():n.view=this.context.getCurrentTexture().createView(),i}_isRenderCameraDepthArray(e){return e.depthTexture&&e.depthTexture.image.depth>1&&e.camera.isArrayCamera}_getRenderPassDescriptor(e,t={}){const r=e.renderTarget,s=this.get(r);let i=s.descriptors;void 0!==i&&s.width===r.width&&s.height===r.height&&s.samples===r.samples||(i={},s.descriptors=i);const n=e.getCacheKey();let a=i[n];if(void 0===a){const t=e.textures,o=[];let u;const l=this._isRenderCameraDepthArray(e);for(let s=0;s1)if(!0===l){const t=e.camera.cameras;for(let e=0;e0&&(t.currentOcclusionQuerySet&&t.currentOcclusionQuerySet.destroy(),t.currentOcclusionQueryBuffer&&t.currentOcclusionQueryBuffer.destroy(),t.currentOcclusionQuerySet=t.occlusionQuerySet,t.currentOcclusionQueryBuffer=t.occlusionQueryBuffer,t.currentOcclusionQueryObjects=t.occlusionQueryObjects,i=r.createQuerySet({type:"occlusion",count:s,label:`occlusionQuerySet_${e.id}`}),t.occlusionQuerySet=i,t.occlusionQueryIndex=0,t.occlusionQueryObjects=new Array(s),t.lastOcclusionObject=null),n=null===e.textures?this._getDefaultRenderPassDescriptor():this._getRenderPassDescriptor(e,{loadOp:GR}),this.initTimestampQuery(wt.RENDER,this.getTimestampUID(e),n),n.occlusionQuerySet=i;const a=n.depthStencilAttachment;if(null!==e.textures){const t=n.colorAttachments;for(let r=0;r0&&t.currentPass.executeBundles(t.renderBundles),r>t.occlusionQueryIndex&&t.currentPass.endOcclusionQuery();const s=t.encoder;if(!0===this._isRenderCameraDepthArray(e)){const r=[];for(let e=0;e0){const s=8*r;let i=this.occludedResolveCache.get(s);void 0===i&&(i=this.device.createBuffer({size:s,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),this.occludedResolveCache.set(s,i));const n=this.device.createBuffer({size:s,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});t.encoder.resolveQuerySet(t.occlusionQuerySet,0,r,i,0),t.encoder.copyBufferToBuffer(i,0,n,0,s),t.occlusionQueryBuffer=n,this.resolveOccludedAsync(e)}if(this.device.queue.submit([t.encoder.finish()]),null!==e.textures){const t=e.textures;for(let e=0;eo&&(i[0]=Math.min(a,o),i[1]=Math.ceil(a/o)),n.dispatchSize=i}i=n.dispatchSize}a.dispatchWorkgroups(i[0],i[1]||1,i[2]||1)}finishCompute(e){const t=this.get(e);t.passEncoderGPU.end(),this.device.queue.submit([t.cmdEncoderGPU.finish()])}draw(e,t){const{object:r,material:s,context:i,pipeline:n}=e,a=e.getBindings(),o=this.get(i),u=this.get(n),l=u.pipeline;if(!0===u.error)return;const d=e.getIndex(),c=null!==d,h=e.getDrawParameters();if(null===h)return;const p=(t,r)=>{this.pipelineUtils.setPipeline(t,l),r.pipeline=l;const n=r.bindingGroups;for(let e=0,r=a.length;e{if(p(s,i),!0===r.isBatchedMesh){const e=r._multiDrawStarts,i=r._multiDrawCounts,n=r._multiDrawCount,a=r._multiDrawInstances;null!==a&&v("WebGPUBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection.");for(let o=0;o1?0:o;!0===c?s.drawIndexed(i[o],n,e[o]/d.array.BYTES_PER_ELEMENT,0,u):s.draw(i[o],n,e[o],u),t.update(r,i[o],n)}}else if(!0===c){const{vertexCount:i,instanceCount:n,firstVertex:a}=h,o=e.getIndirect();if(null!==o){const t=this.get(o).buffer,r=e.getIndirectOffset(),i=Array.isArray(r)?r:[r];for(let e=0;e0){const t=this.get(e.camera),s=e.camera.cameras,n=e.getBindingGroup("cameraIndex");if(void 0===t.indexesGPU||t.indexesGPU.length!==s.length){const e=this.get(n),r=[],i=new Uint32Array([0,0,0,0]);for(let t=0,n=s.length;t(d("WebGPURenderer: WebGPU is not available, running under WebGL2 backend."),new ER(e)));super(new t(e),e),this.library=new xC,this.isWebGPURenderer=!0,"undefined"!=typeof __THREE_DEVTOOLS__&&__THREE_DEVTOOLS__.dispatchEvent(new CustomEvent("observe",{detail:this}))}}class _C extends Es{constructor(){super(),this.isBundleGroup=!0,this.type="BundleGroup",this.static=!0,this.version=0}set needsUpdate(e){!0===e&&this.version++}}class vC{constructor(e,t=Rn(0,0,1,1)){this.renderer=e,this.outputNode=t,this.outputColorTransform=!0,this.needsUpdate=!0;const r=new Qp;r.name="RenderPipeline",this._quadMesh=new Wb(r),this._quadMesh.name="Render Pipeline",this._context=null}render(){const e=this.renderer;this._update(),null!==this._context.onBeforeRenderPipeline&&this._context.onBeforeRenderPipeline();const t=e.toneMapping,r=e.outputColorSpace;e.toneMapping=m,e.outputColorSpace=p.workingColorSpace;const s=e.xr.enabled;e.xr.enabled=!1,this._quadMesh.render(e),e.xr.enabled=s,e.toneMapping=t,e.outputColorSpace=r,null!==this._context.onAfterRenderPipeline&&this._context.onAfterRenderPipeline()}get context(){return this._context}dispose(){this._quadMesh.material.dispose()}_update(){if(!0===this.needsUpdate){const e=this.renderer,t=e.toneMapping,r=e.outputColorSpace,s={renderPipeline:this,onBeforeRenderPipeline:null,onAfterRenderPipeline:null};let i=this.outputNode;!0===this.outputColorTransform?(i=i.context(s),i=fl(i,t,r)):(s.toneMapping=t,s.outputColorSpace=r,i=i.context(s)),this._context=s,this._quadMesh.material.fragmentNode=i,this._quadMesh.material.needsUpdate=!0,this.needsUpdate=!1}}async renderAsync(){v('RenderPipeline: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await this.renderer.init(),this.render()}}class NC extends vC{constructor(e,t){v('PostProcessing: "PostProcessing" has been renamed to "RenderPipeline". Please update your code to use "THREE.RenderPipeline" instead.'),super(e,t)}}class SC extends N{constructor(e=1,t=1){super(),this.image={width:e,height:t},this.magFilter=oe,this.minFilter=oe,this.isStorageTexture=!0,this.mipmapsAutoUpdate=!0}setSize(e,t){this.image.width===e&&this.image.height===t||(this.image.width=e,this.image.height=t,this.dispose())}}class RC extends N{constructor(e=1,t=1,r=1){super(),this.isArrayTexture=!1,this.image={width:e,height:t,depth:r},this.magFilter=oe,this.minFilter=oe,this.wrapR=xe,this.isStorageTexture=!0,this.is3DTexture=!0}setSize(e,t,r){this.image.width===e&&this.image.height===t&&this.image.depth===r||(this.image.width=e,this.image.height=t,this.image.depth=r,this.dispose())}}class EC extends N{constructor(e=1,t=1,r=1){super(),this.isArrayTexture=!0,this.image={width:e,height:t,depth:r},this.magFilter=oe,this.minFilter=oe,this.isStorageTexture=!0}setSize(e,t,r){this.image.width===e&&this.image.height===t&&this.image.depth===r||(this.image.width=e,this.image.height=t,this.image.depth=r,this.dispose())}}class AC extends sx{constructor(e,t){super(e,t,Uint32Array),this.isIndirectStorageBufferAttribute=!0}}class wC extends As{constructor(e){super(e),this.textures={},this.nodes={}}load(e,t,r,s){const i=new ws(this.manager);i.setPath(this.path),i.setRequestHeader(this.requestHeader),i.setWithCredentials(this.withCredentials),i.load(e,r=>{try{t(this.parse(JSON.parse(r)))}catch(t){s?s(t):o(t),this.manager.itemError(e)}},r,s)}parseNodes(e){const t={};if(void 0!==e){for(const r of e){const{uuid:e,type:s}=r;t[e]=this.createNodeFromType(s),t[e].uuid=e}const r={nodes:t,textures:this.textures};for(const s of e){s.meta=r;t[s.uuid].deserialize(s),delete s.meta}}return t}parse(e){const t=this.createNodeFromType(e.type);t.uuid=e.uuid;const r={nodes:this.parseNodes(e.nodes),textures:this.textures};return e.meta=r,t.deserialize(e),delete e.meta,t}setTextures(e){return this.textures=e,this}setNodes(e){return this.nodes=e,this}createNodeFromType(e){return void 0===this.nodes[e]?(o("NodeLoader: Node type not found:",e),pn()):new this.nodes[e]}}class CC extends Cs{constructor(e){super(e),this.nodes={},this.nodeMaterials={}}parse(e){const t=super.parse(e),r=this.nodes,s=e.inputNodes;for(const e in s){const i=s[e];t[e]=r[i]}return t}setNodes(e){return this.nodes=e,this}setNodeMaterials(e){return this.nodeMaterials=e,this}createMaterialFromType(e){const t=this.nodeMaterials[e];return void 0!==t?new t:super.createMaterialFromType(e)}}class MC extends Ms{constructor(e){super(e),this.nodes={},this.nodeMaterials={},this._nodesJSON=null}setNodes(e){return this.nodes=e,this}setNodeMaterials(e){return this.nodeMaterials=e,this}parse(e,t){this._nodesJSON=e.nodes;const r=super.parse(e,t);return this._nodesJSON=null,r}parseNodes(e,t){if(void 0!==e){const r=new wC;return r.setNodes(this.nodes),r.setTextures(t),r.parseNodes(e)}return{}}parseMaterials(e,t){const r={};if(void 0!==e){const s=this.parseNodes(this._nodesJSON,t),i=new CC;i.setTextures(t),i.setNodes(s),i.setNodeMaterials(this.nodeMaterials);for(let t=0,s=e.length;t { } else { - // Use getUV context to avoid side effects from nodes overwriting getUV in the context (e.g. EnvironmentNode) + // Use custom context to avoid side effects from nodes overwriting getUV, getTextureLevel in the context (e.g. EnvironmentNode) - node = builder.context.setupNormal().context( { getUV: null } ); + node = builder.context.setupNormal().context( { getUV: null, getTextureLevel: null } ); } @@ -14295,9 +14295,9 @@ const clearcoatNormalView = /*@__PURE__*/ ( Fn( ( { subBuildFn, context } ) => { } else { - // Use getUV context to avoid side effects from nodes overwriting getUV in the context (e.g. EnvironmentNode) + // Use custom context to avoid side effects from nodes overwriting getUV, getTextureLevel in the context (e.g. EnvironmentNode) - node = context.setupClearcoatNormal().context( { getUV: null } ); + node = context.setupClearcoatNormal().context( { getUV: null, getTextureLevel: null } ); } @@ -22115,15 +22115,13 @@ const equirectUV = /*@__PURE__*/ Fn( ( [ dir = positionWorldDirection ] ) => { } ); -// @TODO: Consider rename WebGLCubeRenderTarget to just CubeRenderTarget - /** * This class represents a cube render target. It is a special version * of `WebGLCubeRenderTarget` which is compatible with `WebGPURenderer`. * - * @augments WebGLCubeRenderTarget + * @augments RenderTarget */ -class CubeRenderTarget extends WebGLCubeRenderTarget { +class CubeRenderTarget extends RenderTarget { /** * Constructs a new cube render target. @@ -22133,7 +22131,7 @@ class CubeRenderTarget extends WebGLCubeRenderTarget { */ constructor( size = 1, options = {} ) { - super( size, options ); + super( size, size, options ); /** * This flag can be used for type testing. @@ -22144,6 +22142,27 @@ class CubeRenderTarget extends WebGLCubeRenderTarget { */ this.isCubeRenderTarget = true; + const image = { width: size, height: size, depth: 1 }; + const images = [ image, image, image, image, image, image ]; + + /** + * Overwritten with a different texture type. + * + * @type {DataArrayTexture} + */ + this.texture = new CubeTexture( images ); + this._setTextureOptions( options ); + + // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, + // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. + + // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped + // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture + // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). + + this.texture.isRenderTargetTexture = true; + } /** @@ -22203,6 +22222,30 @@ class CubeRenderTarget extends WebGLCubeRenderTarget { } + /** + * Clears this cube render target. + * + * @param {Renderer} renderer - The renderer. + * @param {boolean} [color=true] - Whether the color buffer should be cleared or not. + * @param {boolean} [depth=true] - Whether the depth buffer should be cleared or not. + * @param {boolean} [stencil=true] - Whether the stencil buffer should be cleared or not. + */ + clear( renderer, color = true, depth = true, stencil = true ) { + + const currentRenderTarget = renderer.getRenderTarget(); + + for ( let i = 0; i < 6; i ++ ) { + + renderer.setRenderTarget( this, i ); + + renderer.clear( color, depth, stencil ); + + } + + renderer.setRenderTarget( currentRenderTarget ); + + } + } const _cache$1 = new WeakMap(); @@ -30025,6 +30068,20 @@ function getWireframeVersion( geometry ) { } +/** + * Returns the wireframe ID for the given geometry. + * + * @private + * @function + * @param {BufferGeometry} geometry - The geometry. + * @return {number} The ID. + */ +function getWireframeId( geometry ) { + + return ( geometry.index !== null ) ? geometry.index.id : geometry.attributes.position.id; + +} + /** * Returns a wireframe index attribute for the given geometry. * @@ -30072,6 +30129,7 @@ function getWireframeIndex( geometry ) { const attribute = new ( arrayNeedsUint32( indices ) ? Uint32BufferAttribute : Uint16BufferAttribute )( indices, 1 ); attribute.version = getWireframeVersion( geometry ); + attribute.__id = getWireframeId( geometry ); return attribute; @@ -30354,7 +30412,7 @@ class Geometries extends DataMap { wireframes.set( geometry, wireframeAttribute ); - } else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) ) { + } else if ( wireframeAttribute.version !== getWireframeVersion( geometry ) || wireframeAttribute.__id !== getWireframeId( geometry ) ) { this.attributes.delete( wireframeAttribute ); @@ -47982,9 +48040,8 @@ class BindGroup { * @param {string} name - The bind group's name. * @param {Array} bindings - An array of bindings. * @param {number} index - The group index. - * @param {Array} bindingsReference - An array of reference bindings. */ - constructor( name = '', bindings = [], index = 0, bindingsReference = [] ) { + constructor( name = '', bindings = [], index = 0 ) { /** * The bind group's name. @@ -48007,13 +48064,6 @@ class BindGroup { */ this.index = index; - /** - * An array of reference bindings. - * - * @type {Array} - */ - this.bindingsReference = bindingsReference; - /** * The group's ID. * @@ -48151,7 +48201,7 @@ class NodeBuilderState { if ( shared !== true ) { - const bindingsGroup = new BindGroup( instanceGroup.name, [], instanceGroup.index, instanceGroup.bindingsReference ); + const bindingsGroup = new BindGroup( instanceGroup.name, [], instanceGroup.index ); bindings.push( bindingsGroup ); for ( const instanceBinding of instanceGroup.bindings ) { @@ -49888,7 +49938,7 @@ class NodeBuilder { bindingsArray.push( binding ); - sharedGroup = sharedGroup && binding.groupNode.shared !== true; + sharedGroup = sharedGroup && binding.groupNode.shared; } @@ -49902,7 +49952,7 @@ class NodeBuilder { if ( bindGroup === undefined ) { - bindGroup = new BindGroup( groupName, bindingsArray, this.bindingsIndexes[ groupName ].group, bindingsArray ); + bindGroup = new BindGroup( groupName, bindingsArray, this.bindingsIndexes[ groupName ].group ); bindGroupsCache.set( bindingsArray, bindGroup ); @@ -49910,7 +49960,7 @@ class NodeBuilder { } else { - bindGroup = new BindGroup( groupName, bindingsArray, this.bindingsIndexes[ groupName ].group, bindingsArray ); + bindGroup = new BindGroup( groupName, bindingsArray, this.bindingsIndexes[ groupName ].group ); } @@ -59868,6 +59918,37 @@ class Renderer { } + /** + * Initializes the given render target. + * + * @param {RenderTarget} renderTarget - The render target to intialize. + */ + initRenderTarget( renderTarget ) { + + if ( this._initialized === false ) { + + throw new Error( 'Renderer: .initRenderTarget() called before the backend is initialized. Use "await renderer.init();" before before using this method.' ); + + } + + this._textures.updateRenderTarget( renderTarget ); + + const renderTargetData = this._textures.get( renderTarget ); + + const renderContext = this._renderContexts.get( renderTarget ); + + renderContext.textures = renderTargetData.textures; + renderContext.depthTexture = renderTargetData.depthTexture; + renderContext.width = renderTargetData.width; + renderContext.height = renderTargetData.height; + renderContext.renderTarget = renderTarget; + renderContext.depth = renderTarget.depthBuffer; + renderContext.stencil = renderTarget.stencilBuffer; + + this.backend.initRenderTarget( renderContext ); + + } + /** * Copies the current bound framebuffer into the given texture. * @@ -60343,9 +60424,9 @@ class Renderer { materialOverride = true; // store original nodes - materialColorNode = scene.overrideMaterial.colorNode; - materialDepthNode = scene.overrideMaterial.depthNode; - materialPositionNode = scene.overrideMaterial.positionNode; + materialColorNode = ( overrideMaterial.isNodeMaterial ) ? overrideMaterial.colorNode : null; + materialDepthNode = ( overrideMaterial.isNodeMaterial ) ? overrideMaterial.depthNode : null; + materialPositionNode = ( overrideMaterial.isNodeMaterial ) ? overrideMaterial.positionNode : null; materialSide = scene.overrideMaterial.side; if ( material.positionNode && material.positionNode.isNode ) { @@ -60452,6 +60533,16 @@ class Renderer { renderObject.drawRange = object.geometry.drawRange; renderObject.group = group; + if ( this._currentRenderBundle !== null ) { + + const renderBundleData = this.backend.get( this._currentRenderBundle ); + + renderBundleData.renderObjects.push( renderObject ); + + renderObject.bundle = this._currentRenderBundle.bundleGroup; + + } + // const needsRefresh = this._nodes.needsRefresh( renderObject ); @@ -60471,16 +60562,6 @@ class Renderer { // - if ( this._currentRenderBundle !== null ) { - - const renderBundleData = this.backend.get( this._currentRenderBundle ); - - renderBundleData.renderObjects.push( renderObject ); - - renderObject.bundle = this._currentRenderBundle.bundleGroup; - - } - this.backend.draw( renderObject, this.info ); if ( needsRefresh ) this._nodes.updateAfter( renderObject ); @@ -62581,7 +62662,17 @@ ${ flowData.code } } else if ( uniform.type === 'cubeDepthTexture' ) { - snippet = `samplerCubeShadow ${ uniform.name };`; + const texture = uniform.node.value; + + if ( texture.compareFunction ) { + + snippet = `samplerCubeShadow ${ uniform.name };`; + + } else { + + snippet = `samplerCube ${ uniform.name };`; + + } } else if ( uniform.type === 'buffer' ) { @@ -64181,6 +64272,14 @@ class Backend { } + /** + * Initializes the render target defined in the given render context. + * + * @abstract + * @param {RenderContext} renderContext - The render context. + */ + initRenderTarget( /*renderContext*/ ) {} + /** * Sets a dictionary for the given object into the * internal data structure. @@ -68744,9 +68843,12 @@ class WebGLBackend extends Backend { if ( renderContext.scissor ) { - const { x, y, width, height } = renderContext.scissorValue; + this.updateScissor( renderContext ); + + } else { - state.scissor( x, renderContext.height - height - y, width, height ); + const { width, height } = this.getDrawingBufferSize(); + state.scissor( 0, 0, width, height ); } @@ -68843,6 +68945,17 @@ class WebGLBackend extends Backend { } + if ( previousContext.scissor ) { + + this.updateScissor( previousContext ); + + } else { + + const { width, height } = this.getDrawingBufferSize(); + state.scissor( 0, 0, width, height ); + + } + } this.prepareTimestampBuffer( TimestampQuery.RENDER, this.getTimestampUID( renderContext ) ); @@ -68944,6 +69057,20 @@ class WebGLBackend extends Backend { } + /** + * Updates the scissor with the values from the given render context. + * + * @param {RenderContext} renderContext - The render context. + */ + updateScissor( renderContext ) { + + const { state } = this; + const { x, y, width, height } = renderContext.scissorValue; + + state.scissor( x, renderContext.height - height - y, width, height ); + + } + /** * Defines the scissor test. * @@ -70309,6 +70436,21 @@ class WebGLBackend extends Backend { } + /** + * Initializes the render target defined in the given render context. + * + * @param {RenderContext} renderContext - The render context. + */ + initRenderTarget( renderContext ) { + + const { gl, state } = this; + + this._setFramebuffer( renderContext ); + + state.bindFramebuffer( gl.FRAMEBUFFER, null ); + + } + /** * Configures the active framebuffer from the given render context. * @@ -70327,7 +70469,7 @@ class WebGLBackend extends Backend { const renderTargetContextData = this.get( renderTarget ); const { samples, depthBuffer, stencilBuffer } = renderTarget; - const isCube = renderTarget.isWebGLCubeRenderTarget === true; + const isCube = renderTarget.isCubeRenderTarget === true; const isRenderTarget3D = renderTarget.isRenderTarget3D === true; const isRenderTargetArray = renderTarget.depth > 1; const isXRRenderTarget = renderTarget.isXRRenderTarget === true; @@ -70991,9 +71133,7 @@ const GPUPrimitiveTopology = { PointList: 'point-list', LineList: 'line-list', LineStrip: 'line-strip', - TriangleList: 'triangle-list', - TriangleStrip: 'triangle-strip', -}; + TriangleList: 'triangle-list'}; const GPUShaderStage = ( typeof self !== 'undefined' && self.GPUShaderStage ) ? self.GPUShaderStage : { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 }; @@ -71483,65 +71623,88 @@ class WebGPUTexturePassUtils extends DataMap { */ this.device = device; - const mipmapVertexSource = ` + const mipmapSource = ` struct VarysStruct { - @builtin( position ) Position: vec4, - @location( 0 ) vTex : vec2 + @builtin( position ) Position: vec4f, + @location( 0 ) vTex : vec2f, + @location( 1 ) @interpolate(flat, either) vBaseArrayLayer: u32, }; +@group( 0 ) @binding ( 2 ) +var flipY: u32; + @vertex -fn main( @builtin( vertex_index ) vertexIndex : u32 ) -> VarysStruct { +fn mainVS( + @builtin( vertex_index ) vertexIndex : u32, + @builtin( instance_index ) instanceIndex : u32 ) -> VarysStruct { var Varys : VarysStruct; - var pos = array< vec2, 4 >( - vec2( -1.0, 1.0 ), - vec2( 1.0, 1.0 ), - vec2( -1.0, -1.0 ), - vec2( 1.0, -1.0 ) + var pos = array( + vec2f( -1, -1 ), + vec2f( -1, 3 ), + vec2f( 3, -1 ), ); - var tex = array< vec2, 4 >( - vec2( 0.0, 0.0 ), - vec2( 1.0, 0.0 ), - vec2( 0.0, 1.0 ), - vec2( 1.0, 1.0 ) - ); - - Varys.vTex = tex[ vertexIndex ]; - Varys.Position = vec4( pos[ vertexIndex ], 0.0, 1.0 ); + let p = pos[ vertexIndex ]; + let mult = select( vec2f( 0.5, -0.5 ), vec2f( 0.5, 0.5 ), flipY != 0 ); + Varys.vTex = p * vec2f( 0.5, -0.5 ) + vec2f( 0.5 ); + Varys.Position = vec4f( p, 0, 1 ); + Varys.vBaseArrayLayer = instanceIndex; return Varys; } -`; - const mipmapFragmentSource = ` @group( 0 ) @binding( 0 ) var imgSampler : sampler; @group( 0 ) @binding( 1 ) -var img : texture_2d; +var img2d : texture_2d; @fragment -fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { +fn main_2d( Varys: VarysStruct ) -> @location( 0 ) vec4 { - return textureSample( img, imgSampler, vTex ); + return textureSample( img2d, imgSampler, Varys.vTex ); } -`; - const flipYFragmentSource = ` -@group( 0 ) @binding( 0 ) -var imgSampler : sampler; +@group( 0 ) @binding( 1 ) +var img2dArray : texture_2d_array; + +@fragment +fn main_2d_array( Varys: VarysStruct ) -> @location( 0 ) vec4 { + + return textureSample( img2dArray, imgSampler, Varys.vTex, Varys.vBaseArrayLayer ); + +} + +const faceMat = array( + mat3x3f( 0, 0, -2, 0, -2, 0, 1, 1, 1 ), // pos-x + mat3x3f( 0, 0, 2, 0, -2, 0, -1, 1, -1 ), // neg-x + mat3x3f( 2, 0, 0, 0, 0, 2, -1, 1, -1 ), // pos-y + mat3x3f( 2, 0, 0, 0, 0, -2, -1, -1, 1 ), // neg-y + mat3x3f( 2, 0, 0, 0, -2, 0, -1, 1, 1 ), // pos-z + mat3x3f( -2, 0, 0, 0, -2, 0, 1, 1, -1 ), // neg-z +); + +@group( 0 ) @binding( 1 ) +var imgCube : texture_cube; + +@fragment +fn main_cube( Varys: VarysStruct ) -> @location( 0 ) vec4 { + + return textureSample( imgCube, imgSampler, faceMat[ Varys.vBaseArrayLayer ] * vec3f( fract( Varys.vTex ), 1 ) ); + +} @group( 0 ) @binding( 1 ) -var img : texture_2d; +var imgCubeArray : texture_cube_array; @fragment -fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { +fn main_cube_array( Varys: VarysStruct ) -> @location( 0 ) vec4 { - return textureSample( img, imgSampler, vec2( vTex.x, 1.0 - vTex.y ) ); + return textureSample( imgCubeArray, imgSampler, faceMat[ Varys.vBaseArrayLayer % 6 ] * vec3f( fract( Varys.vTex ), 1 ), Varys.vBaseArrayLayer ); } `; @@ -71561,49 +71724,40 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { this.flipYSampler = device.createSampler( { minFilter: GPUFilterMode.Nearest } ); //@TODO?: Consider using textureLoad() /** - * A cache for GPU render pipelines used for copy/transfer passes. - * Every texture format requires a unique pipeline. - * - * @type {Object} + * flip uniform buffer + * @type {GPUBuffer} */ - this.transferPipelines = {}; - - /** - * A cache for GPU render pipelines used for flipY passes. - * Every texture format requires a unique pipeline. - * - * @type {Object} - */ - this.flipYPipelines = {}; + this.flipUniformBuffer = device.createBuffer( { + size: 4, + usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST + } ); + device.queue.writeBuffer( this.flipUniformBuffer, 0, new Uint32Array( [ 1 ] ) ); /** - * The mipmap vertex shader module. - * - * @type {GPUShaderModule} + * no flip uniform buffer + * @type {GPUBuffer} */ - this.mipmapVertexShaderModule = device.createShaderModule( { - label: 'mipmapVertex', - code: mipmapVertexSource + this.noFlipUniformBuffer = device.createBuffer( { + size: 4, + usage: GPUBufferUsage.UNIFORM } ); /** - * The mipmap fragment shader module. + * A cache for GPU render pipelines used for copy/transfer passes. + * Every texture format and textureBindingViewDimension combo requires a unique pipeline. * - * @type {GPUShaderModule} + * @type {Object} */ - this.mipmapFragmentShaderModule = device.createShaderModule( { - label: 'mipmapFragment', - code: mipmapFragmentSource - } ); + this.transferPipelines = {}; /** - * The flipY fragment shader module. + * The mipmap shader module. * * @type {GPUShaderModule} */ - this.flipYFragmentShaderModule = device.createShaderModule( { - label: 'flipYFragment', - code: flipYFragmentSource + this.mipmapShaderModule = device.createShaderModule( { + label: 'mipmap', + code: mipmapSource } ); } @@ -71613,29 +71767,27 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { * requires a unique render pipeline for each texture format. * * @param {string} format - The GPU texture format + * @param {string?} textureBindingViewDimension - The GPU texture binding view dimension * @return {GPURenderPipeline} The GPU render pipeline. */ - getTransferPipeline( format ) { + getTransferPipeline( format, textureBindingViewDimension ) { - let pipeline = this.transferPipelines[ format ]; + textureBindingViewDimension = textureBindingViewDimension || '2d-array'; + const key = `${ format }-${ textureBindingViewDimension }`; + let pipeline = this.transferPipelines[ key ]; if ( pipeline === undefined ) { pipeline = this.device.createRenderPipeline( { - label: `mipmap-${ format }`, + label: `mipmap-${ format }-${ textureBindingViewDimension }`, vertex: { - module: this.mipmapVertexShaderModule, - entryPoint: 'main' + module: this.mipmapShaderModule, }, fragment: { - module: this.mipmapFragmentShaderModule, - entryPoint: 'main', + module: this.mipmapShaderModule, + entryPoint: `main_${ textureBindingViewDimension.replace( '-', '_' ) }`, targets: [ { format } ] }, - primitive: { - topology: GPUPrimitiveTopology.TriangleStrip, - stripIndexFormat: GPUIndexFormat.Uint32 - }, layout: 'auto' } ); @@ -71647,45 +71799,6 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { } - /** - * Returns a render pipeline for the flipY render pass. The pass - * requires a unique render pipeline for each texture format. - * - * @param {string} format - The GPU texture format - * @return {GPURenderPipeline} The GPU render pipeline. - */ - getFlipYPipeline( format ) { - - let pipeline = this.flipYPipelines[ format ]; - - if ( pipeline === undefined ) { - - pipeline = this.device.createRenderPipeline( { - label: `flipY-${ format }`, - vertex: { - module: this.mipmapVertexShaderModule, - entryPoint: 'main' - }, - fragment: { - module: this.flipYFragmentShaderModule, - entryPoint: 'main', - targets: [ { format } ] - }, - primitive: { - topology: GPUPrimitiveTopology.TriangleStrip, - stripIndexFormat: GPUIndexFormat.Uint32 - }, - layout: 'auto' - } ); - - this.flipYPipelines[ format ] = pipeline; - - } - - return pipeline; - - } - /** * Flip the contents of the given GPU texture along its vertical axis. * @@ -71698,32 +71811,18 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { const format = textureGPUDescriptor.format; const { width, height } = textureGPUDescriptor.size; - const transferPipeline = this.getTransferPipeline( format ); - const flipYPipeline = this.getFlipYPipeline( format ); - const tempTexture = this.device.createTexture( { - size: { width, height, depthOrArrayLayers: 1 }, + size: { width, height }, format, usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING } ); - const srcView = textureGPU.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); - - const dstView = tempTexture.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer: 0 - } ); + const copyTransferPipeline = this.getTransferPipeline( format, textureGPU.textureBindingViewDimension ); + const flipTransferPipeline = this.getTransferPipeline( format, tempTexture.textureBindingViewDimension ); const commandEncoder = this.device.createCommandEncoder( {} ); - const pass = ( pipeline, sourceView, destinationView ) => { + const pass = ( pipeline, sourceTexture, sourceArrayLayer, destinationTexture, destinationArrayLayer, flipY ) => { const bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static. @@ -71734,28 +71833,40 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { resource: this.flipYSampler }, { binding: 1, - resource: sourceView + resource: sourceTexture.createView( { + dimension: sourceTexture.textureBindingViewDimension || '2d-array', + baseMipLevel: 0, + mipLevelCount: 1, + } ), + }, { + binding: 2, + resource: { buffer: flipY ? this.flipUniformBuffer : this.noFlipUniformBuffer } } ] } ); const passEncoder = commandEncoder.beginRenderPass( { colorAttachments: [ { - view: destinationView, + view: destinationTexture.createView( { + dimension: '2d', + baseMipLevel: 0, + mipLevelCount: 1, + baseArrayLayer: destinationArrayLayer, + arrayLayerCount: 1, + } ), loadOp: GPULoadOp.Clear, storeOp: GPUStoreOp.Store, - clearValue: [ 0, 0, 0, 0 ] } ] } ); passEncoder.setPipeline( pipeline ); passEncoder.setBindGroup( 0, bindGroup ); - passEncoder.draw( 4, 1, 0, 0 ); + passEncoder.draw( 3, 1, 0, sourceArrayLayer ); passEncoder.end(); }; - pass( transferPipeline, srcView, dstView ); - pass( flipYPipeline, dstView, srcView ); + pass( copyTransferPipeline, textureGPU, baseArrayLayer, tempTexture, 0, false ); + pass( flipTransferPipeline, tempTexture, 0, textureGPU, baseArrayLayer, true ); this.device.queue.submit( [ commandEncoder.finish() ] ); @@ -71767,21 +71878,13 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { * Generates mipmaps for the given GPU texture. * * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureGPUDescriptor - The texture descriptor. - * @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. * @param {?GPUCommandEncoder} [encoder=null] - An optional command encoder used to generate mipmaps. */ - generateMipmaps( textureGPU, textureGPUDescriptor, baseArrayLayer = 0, encoder = null ) { + generateMipmaps( textureGPU, encoder = null ) { const textureData = this.get( textureGPU ); - if ( textureData.layers === undefined ) { - - textureData.layers = []; - - } - - const passes = textureData.layers[ baseArrayLayer ] || this._mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ); + const passes = textureData.layers || this._mipmapCreateBundles( textureGPU ); const commandEncoder = encoder || this.device.createCommandEncoder( { label: 'mipmapEncoder' } ); @@ -71789,7 +71892,7 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { if ( encoder === null ) this.device.queue.submit( [ commandEncoder.finish() ] ); - textureData.layers[ baseArrayLayer ] = passes; + textureData.layers = passes; } @@ -71798,68 +71901,67 @@ fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { * are managed as render bundles to improve performance. * * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureGPUDescriptor - The texture descriptor. - * @param {number} baseArrayLayer - The index of the first array layer accessible to the texture view. * @return {Array} An array of render bundles. */ - _mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ) { + _mipmapCreateBundles( textureGPU ) { - const pipeline = this.getTransferPipeline( textureGPUDescriptor.format ); + const textureBindingViewDimension = textureGPU.textureBindingViewDimension || '2d-array'; + const pipeline = this.getTransferPipeline( textureGPU.format, textureBindingViewDimension ); const bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static. - let srcView = textureGPU.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); - const passes = []; - for ( let i = 1; i < textureGPUDescriptor.mipLevelCount; i ++ ) { - - const bindGroup = this.device.createBindGroup( { - layout: bindGroupLayout, - entries: [ { - binding: 0, - resource: this.mipmapSampler - }, { - binding: 1, - resource: srcView - } ] - } ); - - const dstView = textureGPU.createView( { - baseMipLevel: i, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); + for ( let baseMipLevel = 1; baseMipLevel < textureGPU.mipLevelCount; baseMipLevel ++ ) { + + for ( let baseArrayLayer = 0; baseArrayLayer < textureGPU.depthOrArrayLayers; baseArrayLayer ++ ) { + + const bindGroup = this.device.createBindGroup( { + layout: bindGroupLayout, + entries: [ { + binding: 0, + resource: this.mipmapSampler + }, { + binding: 1, + resource: textureGPU.createView( { + dimension: textureBindingViewDimension, + baseMipLevel: baseMipLevel - 1, + mipLevelCount: 1, + } ), + }, { + binding: 2, + resource: { buffer: this.noFlipUniformBuffer } + } ] + } ); - const passDescriptor = { - colorAttachments: [ { - view: dstView, - loadOp: GPULoadOp.Clear, - storeOp: GPUStoreOp.Store, - clearValue: [ 0, 0, 0, 0 ] - } ] - }; + const passDescriptor = { + colorAttachments: [ { + view: textureGPU.createView( { + dimension: '2d', + baseMipLevel, + mipLevelCount: 1, + baseArrayLayer, + arrayLayerCount: 1, + } ), + loadOp: GPULoadOp.Clear, + storeOp: GPUStoreOp.Store, + } ] + }; - const passEncoder = this.device.createRenderBundleEncoder( { - colorFormats: [ textureGPUDescriptor.format ] - } ); + const passEncoder = this.device.createRenderBundleEncoder( { + colorFormats: [ textureGPU.format ] + } ); - passEncoder.setPipeline( pipeline ); - passEncoder.setBindGroup( 0, bindGroup ); - passEncoder.draw( 4, 1, 0, 0 ); + passEncoder.setPipeline( pipeline ); + passEncoder.setBindGroup( 0, bindGroup ); + passEncoder.draw( 3, 1, 0, baseArrayLayer ); - passes.push( { - renderBundles: [ passEncoder.finish() ], - passDescriptor - } ); + passes.push( { + renderBundles: [ passEncoder.finish() ], + passDescriptor + } ); - srcView = dstView; + } } @@ -72242,25 +72344,7 @@ class WebGPUTextureUtils { const textureData = this.backend.get( texture ); - if ( texture.isCubeTexture ) { - - for ( let i = 0; i < 6; i ++ ) { - - this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i, encoder ); - - } - - } else { - - const depth = texture.image.depth || 1; - - for ( let i = 0; i < depth; i ++ ) { - - this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i, encoder ); - - } - - } + this._generateMipmaps( textureData.texture, encoder ); } @@ -78701,6 +78785,12 @@ class WebGPUBackend extends Backend { this.compatibilityMode = ! device.features.has( 'core-features-and-limits' ); + if ( this.compatibilityMode ) { + + renderer._samples = 0; + + } + device.lost.then( ( info ) => { if ( info.reason === 'destroyed' ) return; @@ -82179,4 +82269,4 @@ class ClippingGroup extends Group { } -export { ACESFilmicToneMapping, AONode, AddEquation, AddOperation, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightNode, AnalyticLightNode, ArrayCamera, ArrayElementNode, ArrayNode, AssignNode, AtomicFunctionNode, AttributeNode, BackSide, BarrierNode, BasicEnvironmentNode, BasicLightMapNode, BasicShadowMap, BatchNode, BitcastNode, BitcountNode, BlendMode, BoxGeometry, BufferAttribute, BufferAttributeNode, BufferGeometry, BufferNode, BuiltinNode, BumpMapNode, BundleGroup, BypassNode, ByteType, CanvasTarget, CineonToneMapping, ClampToEdgeWrapping, ClippingGroup, ClippingNode, CodeNode, Color, ColorManagement, ColorSpaceNode, Compatibility, ComputeBuiltinNode, ComputeNode, ConditionalNode, ConstNode, ContextNode, ConvertNode, CubeCamera, CubeDepthTexture, CubeMapNode, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureNode, CubeUVReflectionMapping, CullFaceBack, CullFaceFront, CullFaceNone, CustomBlending, CylinderGeometry, DataArrayTexture, DataTexture, DebugNode, DecrementStencilOp, DecrementWrapStencilOp, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightNode, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicDrawUsage, EnvironmentNode, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, EventNode, ExpressionNode, FileLoader, FlipNode, Float16BufferAttribute, Float32BufferAttribute, FloatType, FramebufferTexture, FrontFacingNode, FrontSide, Frustum, FrustumArray, FunctionCallNode, FunctionNode, FunctionOverloadingNode, GLSLNodeParser, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, Group, HalfFloatType, HemisphereLight, HemisphereLightNode, IESSpotLight, IESSpotLightNode, IncrementStencilOp, IncrementWrapStencilOp, IndexNode, IndirectStorageBufferAttribute, InputNode, InspectorBase, InspectorNode, InstanceNode, InstancedBufferAttribute, InstancedInterleavedBuffer, InstancedMeshNode, IntType, InterleavedBuffer, InterleavedBufferAttribute, InvertStencilOp, IrradianceNode, IsolateNode, JoinNode, KeepStencilOp, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, LightProbe, LightProbeNode, Lighting, LightingContextNode, LightingModel, LightingNode, LightsNode, Line2NodeMaterial, LineBasicMaterial, LineBasicNodeMaterial, LineDashedMaterial, LineDashedNodeMaterial, LinearFilter, LinearMipMapLinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoopNode, MRTNode, Material, MaterialBlending, MaterialLoader, MaterialNode, MaterialReferenceNode, MathNode, MathUtils, Matrix2, Matrix3, Matrix4, MaxEquation, MaxMipLevelNode, MemberNode, Mesh, MeshBasicMaterial, MeshBasicNodeMaterial, MeshLambertMaterial, MeshLambertNodeMaterial, MeshMatcapMaterial, MeshMatcapNodeMaterial, MeshNormalMaterial, MeshNormalNodeMaterial, MeshPhongMaterial, MeshPhongNodeMaterial, MeshPhysicalMaterial, MeshPhysicalNodeMaterial, MeshSSSNodeMaterial, MeshStandardMaterial, MeshStandardNodeMaterial, MeshToonMaterial, MeshToonNodeMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, ModelNode, MorphNode, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoNormalPacking, NoToneMapping, Node, NodeAccess, NodeAttribute, NodeBuilder, NodeCache, NodeCode, NodeFrame, NodeFunctionInput, NodeLoader, NodeMaterial, NodeMaterialLoader, NodeMaterialObserver, NodeObjectLoader, NodeShaderStage, NodeType, NodeUniform, NodeUpdateType, NodeUtils, NodeVar, NodeVarying, NormalBlending, NormalGAPacking, NormalMapNode, NormalRGPacking, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, Object3D, Object3DNode, ObjectLoader, ObjectSpaceNormalMap, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OperatorNode, OrthographicCamera, OutputStructNode, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, PMREMNode, PackFloatNode, ParameterNode, PassNode, PerspectiveCamera, PhongLightingModel, PhysicalLightingModel, Plane, PlaneGeometry, PointLight, PointLightNode, PointShadowNode, PointUVNode, PointsMaterial, PointsNodeMaterial, PostProcessing, PosterizeNode, ProjectorLight, ProjectorLightNode, PropertyNode, QuadMesh, Quaternion, R11_EAC_Format, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RG11_EAC_Format, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGBIntegerFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RTTNode, RangeNode, RectAreaLight, RectAreaLightNode, RedFormat, RedIntegerFormat, ReferenceBaseNode, ReferenceNode, ReflectorNode, ReinhardToneMapping, RemapNode, RenderOutputNode, RenderPipeline, RenderTarget, RendererReferenceNode, RendererUtils, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RotateNode, SIGNED_R11_EAC_Format, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SIGNED_RG11_EAC_Format, SRGBColorSpace, SRGBTransfer, SampleNode, Scene, ScreenNode, ScriptableNode, ScriptableValueNode, SetNode, ShadowBaseNode, ShadowMaterial, ShadowNode, ShadowNodeMaterial, ShortType, SkinningNode, Sphere, SphereGeometry, SplitNode, SpotLight, SpotLightNode, SpriteMaterial, SpriteNodeMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StackNode, StaticDrawUsage, StorageArrayElementNode, StorageBufferAttribute, StorageBufferNode, StorageInstancedBufferAttribute, StorageTexture, StorageTextureNode, StructNode, StructTypeNode, SubBuildNode, SubgroupFunctionNode, SubtractEquation, SubtractiveBlending, TSL, TangentSpaceNormalMap, TempNode, Texture, Texture3DNode, TextureNode, TextureSizeNode, TimestampQuery, ToneMappingNode, ToonOutlinePassNode, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, UniformArrayNode, UniformGroupNode, UniformNode, UnpackFloatNode, UnsignedByteType, UnsignedInt101111Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, UserDataNode, VSMShadowMap, VarNode, VaryingNode, Vector2, Vector3, Vector4, VelocityNode, VertexColorNode, ViewportDepthNode, ViewportDepthTextureNode, ViewportSharedTextureNode, ViewportTextureNode, VolumeNodeMaterial, WebGLCoordinateSystem, WebGLCubeRenderTarget, WebGPUCoordinateSystem, WebGPURenderer, WebXRController, WorkgroupInfoNode, ZeroFactor, ZeroStencilOp, createCanvasElement, defaultBuildStages, defaultShaderStages, error, log$1 as log, shaderStages, vectorComponents, warn, warnOnce }; +export { ACESFilmicToneMapping, AONode, AddEquation, AddOperation, AdditiveBlending, AgXToneMapping, AlphaFormat, AlwaysCompare, AlwaysDepth, AlwaysStencilFunc, AmbientLight, AmbientLightNode, AnalyticLightNode, ArrayCamera, ArrayElementNode, ArrayNode, AssignNode, AtomicFunctionNode, AttributeNode, BackSide, BarrierNode, BasicEnvironmentNode, BasicLightMapNode, BasicShadowMap, BatchNode, BitcastNode, BitcountNode, BlendMode, BoxGeometry, BufferAttribute, BufferAttributeNode, BufferGeometry, BufferNode, BuiltinNode, BumpMapNode, BundleGroup, BypassNode, ByteType, CanvasTarget, CineonToneMapping, ClampToEdgeWrapping, ClippingGroup, ClippingNode, CodeNode, Color, ColorManagement, ColorSpaceNode, Compatibility, ComputeBuiltinNode, ComputeNode, ConditionalNode, ConstNode, ContextNode, ConvertNode, CubeCamera, CubeDepthTexture, CubeMapNode, CubeReflectionMapping, CubeRefractionMapping, CubeTexture, CubeTextureNode, CubeUVReflectionMapping, CullFaceBack, CullFaceFront, CullFaceNone, CustomBlending, CylinderGeometry, DataArrayTexture, DataTexture, DebugNode, DecrementStencilOp, DecrementWrapStencilOp, DepthFormat, DepthStencilFormat, DepthTexture, DirectionalLight, DirectionalLightNode, DoubleSide, DstAlphaFactor, DstColorFactor, DynamicDrawUsage, EnvironmentNode, EqualCompare, EqualDepth, EqualStencilFunc, EquirectangularReflectionMapping, EquirectangularRefractionMapping, Euler, EventDispatcher, EventNode, ExpressionNode, FileLoader, FlipNode, Float16BufferAttribute, Float32BufferAttribute, FloatType, FramebufferTexture, FrontFacingNode, FrontSide, Frustum, FrustumArray, FunctionCallNode, FunctionNode, FunctionOverloadingNode, GLSLNodeParser, GreaterCompare, GreaterDepth, GreaterEqualCompare, GreaterEqualDepth, GreaterEqualStencilFunc, GreaterStencilFunc, Group, HalfFloatType, HemisphereLight, HemisphereLightNode, IESSpotLight, IESSpotLightNode, IncrementStencilOp, IncrementWrapStencilOp, IndexNode, IndirectStorageBufferAttribute, InputNode, InspectorBase, InspectorNode, InstanceNode, InstancedBufferAttribute, InstancedInterleavedBuffer, InstancedMeshNode, IntType, InterleavedBuffer, InterleavedBufferAttribute, InvertStencilOp, IrradianceNode, IsolateNode, JoinNode, KeepStencilOp, LessCompare, LessDepth, LessEqualCompare, LessEqualDepth, LessEqualStencilFunc, LessStencilFunc, LightProbe, LightProbeNode, Lighting, LightingContextNode, LightingModel, LightingNode, LightsNode, Line2NodeMaterial, LineBasicMaterial, LineBasicNodeMaterial, LineDashedMaterial, LineDashedNodeMaterial, LinearFilter, LinearMipMapLinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, LinearSRGBColorSpace, LinearToneMapping, LinearTransfer, Loader, LoopNode, MRTNode, Material, MaterialBlending, MaterialLoader, MaterialNode, MaterialReferenceNode, MathNode, MathUtils, Matrix2, Matrix3, Matrix4, MaxEquation, MaxMipLevelNode, MemberNode, Mesh, MeshBasicMaterial, MeshBasicNodeMaterial, MeshLambertMaterial, MeshLambertNodeMaterial, MeshMatcapMaterial, MeshMatcapNodeMaterial, MeshNormalMaterial, MeshNormalNodeMaterial, MeshPhongMaterial, MeshPhongNodeMaterial, MeshPhysicalMaterial, MeshPhysicalNodeMaterial, MeshSSSNodeMaterial, MeshStandardMaterial, MeshStandardNodeMaterial, MeshToonMaterial, MeshToonNodeMaterial, MinEquation, MirroredRepeatWrapping, MixOperation, ModelNode, MorphNode, MultiplyBlending, MultiplyOperation, NearestFilter, NearestMipmapLinearFilter, NearestMipmapNearestFilter, NeutralToneMapping, NeverCompare, NeverDepth, NeverStencilFunc, NoBlending, NoColorSpace, NoNormalPacking, NoToneMapping, Node, NodeAccess, NodeAttribute, NodeBuilder, NodeCache, NodeCode, NodeFrame, NodeFunctionInput, NodeLoader, NodeMaterial, NodeMaterialLoader, NodeMaterialObserver, NodeObjectLoader, NodeShaderStage, NodeType, NodeUniform, NodeUpdateType, NodeUtils, NodeVar, NodeVarying, NormalBlending, NormalGAPacking, NormalMapNode, NormalRGPacking, NotEqualCompare, NotEqualDepth, NotEqualStencilFunc, Object3D, Object3DNode, ObjectLoader, ObjectSpaceNormalMap, OneFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcAlphaFactor, OneMinusSrcColorFactor, OperatorNode, OrthographicCamera, OutputStructNode, PCFShadowMap, PCFSoftShadowMap, PMREMGenerator, PMREMNode, PackFloatNode, ParameterNode, PassNode, PerspectiveCamera, PhongLightingModel, PhysicalLightingModel, Plane, PlaneGeometry, PointLight, PointLightNode, PointShadowNode, PointUVNode, PointsMaterial, PointsNodeMaterial, PostProcessing, PosterizeNode, ProjectorLight, ProjectorLightNode, PropertyNode, QuadMesh, Quaternion, R11_EAC_Format, RED_GREEN_RGTC2_Format, RED_RGTC1_Format, REVISION, RG11_EAC_Format, RGBAFormat, RGBAIntegerFormat, RGBA_ASTC_10x10_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_BPTC_Format, RGBA_ETC2_EAC_Format, RGBA_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGBFormat, RGBIntegerFormat, RGB_ETC1_Format, RGB_ETC2_Format, RGB_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGB_S3TC_DXT1_Format, RGFormat, RGIntegerFormat, RTTNode, RangeNode, RectAreaLight, RectAreaLightNode, RedFormat, RedIntegerFormat, ReferenceBaseNode, ReferenceNode, ReflectorNode, ReinhardToneMapping, RemapNode, RenderOutputNode, RenderPipeline, RenderTarget, RendererReferenceNode, RendererUtils, RepeatWrapping, ReplaceStencilOp, ReverseSubtractEquation, RotateNode, SIGNED_R11_EAC_Format, SIGNED_RED_GREEN_RGTC2_Format, SIGNED_RED_RGTC1_Format, SIGNED_RG11_EAC_Format, SRGBColorSpace, SRGBTransfer, SampleNode, Scene, ScreenNode, ScriptableNode, ScriptableValueNode, SetNode, ShadowBaseNode, ShadowMaterial, ShadowNode, ShadowNodeMaterial, ShortType, SkinningNode, Sphere, SphereGeometry, SplitNode, SpotLight, SpotLightNode, SpriteMaterial, SpriteNodeMaterial, SrcAlphaFactor, SrcAlphaSaturateFactor, SrcColorFactor, StackNode, StaticDrawUsage, StorageArrayElementNode, StorageBufferAttribute, StorageBufferNode, StorageInstancedBufferAttribute, StorageTexture, StorageTextureNode, StructNode, StructTypeNode, SubBuildNode, SubgroupFunctionNode, SubtractEquation, SubtractiveBlending, TSL, TangentSpaceNormalMap, TempNode, Texture, Texture3DNode, TextureNode, TextureSizeNode, TimestampQuery, ToneMappingNode, ToonOutlinePassNode, UVMapping, Uint16BufferAttribute, Uint32BufferAttribute, UniformArrayNode, UniformGroupNode, UniformNode, UnpackFloatNode, UnsignedByteType, UnsignedInt101111Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedIntType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedShortType, UserDataNode, VSMShadowMap, VarNode, VaryingNode, Vector2, Vector3, Vector4, VelocityNode, VertexColorNode, ViewportDepthNode, ViewportDepthTextureNode, ViewportSharedTextureNode, ViewportTextureNode, VolumeNodeMaterial, WebGLCoordinateSystem, WebGPUCoordinateSystem, WebGPURenderer, WebXRController, WorkgroupInfoNode, ZeroFactor, ZeroStencilOp, createCanvasElement, defaultBuildStages, defaultShaderStages, error, log$1 as log, shaderStages, vectorComponents, warn, warnOnce }; diff --git a/build/three.webgpu.nodes.min.js b/build/three.webgpu.nodes.min.js index 1e88f5342e338b..7f40c6e08db6e1 100644 --- a/build/three.webgpu.nodes.min.js +++ b/build/three.webgpu.nodes.min.js @@ -3,4 +3,4 @@ * Copyright 2010-2026 Three.js Authors * SPDX-License-Identifier: MIT */ -import{Color as e,Vector2 as t,Vector3 as r,Vector4 as s,Matrix2 as i,Matrix3 as n,Matrix4 as a,error as o,EventDispatcher as u,MathUtils as l,warn as d,WebGLCoordinateSystem as c,WebGPUCoordinateSystem as h,ColorManagement as p,SRGBTransfer as g,NoToneMapping as m,StaticDrawUsage as f,InterleavedBufferAttribute as y,InterleavedBuffer as b,DynamicDrawUsage as x,NoColorSpace as T,log as _,warnOnce as v,Texture as N,UnsignedIntType as S,IntType as R,Compatibility as E,LessCompare as A,NearestFilter as w,Sphere as C,BackSide as M,DoubleSide as F,Euler as L,CubeTexture as P,CubeReflectionMapping as B,CubeRefractionMapping as D,TangentSpaceNormalMap as U,NoNormalPacking as I,NormalRGPacking as O,NormalGAPacking as V,ObjectSpaceNormalMap as k,RGFormat as G,RED_GREEN_RGTC2_Format as z,RG11_EAC_Format as $,InstancedBufferAttribute as W,InstancedInterleavedBuffer as H,DataArrayTexture as q,FloatType as j,FramebufferTexture as X,LinearMipmapLinearFilter as K,DepthTexture as Y,Material as Q,LineBasicMaterial as Z,LineDashedMaterial as J,NoBlending as ee,MeshNormalMaterial as te,SRGBColorSpace as re,WebGLCubeRenderTarget as se,BoxGeometry as ie,Mesh as ne,Scene as ae,LinearFilter as oe,CubeCamera as ue,EquirectangularReflectionMapping as le,EquirectangularRefractionMapping as de,AddOperation as ce,MixOperation as he,MultiplyOperation as pe,MeshBasicMaterial as ge,MeshLambertMaterial as me,MeshPhongMaterial as fe,DataTexture as ye,HalfFloatType as be,ClampToEdgeWrapping as xe,BufferGeometry as Te,OrthographicCamera as _e,PerspectiveCamera as ve,RenderTarget as Ne,LinearSRGBColorSpace as Se,RGBAFormat as Re,CubeUVReflectionMapping as Ee,BufferAttribute as Ae,MeshStandardMaterial as we,MeshPhysicalMaterial as Ce,MeshToonMaterial as Me,MeshMatcapMaterial as Fe,SpriteMaterial as Le,PointsMaterial as Pe,ShadowMaterial as Be,Uint32BufferAttribute as De,Uint16BufferAttribute as Ue,arrayNeedsUint32 as Ie,DepthStencilFormat as Oe,DepthFormat as Ve,UnsignedInt248Type as ke,UnsignedByteType as Ge,NormalBlending as ze,SrcAlphaFactor as $e,OneMinusSrcAlphaFactor as We,AddEquation as He,MaterialBlending as qe,Plane as je,Object3D as Xe,LinearMipMapLinearFilter as Ke,Float32BufferAttribute as Ye,UVMapping as Qe,VSMShadowMap as Ze,LessEqualCompare as Je,PCFShadowMap as et,PCFSoftShadowMap as tt,BasicShadowMap as rt,CubeDepthTexture as st,SphereGeometry as it,LinearMipmapNearestFilter as nt,NearestMipmapLinearFilter as at,Float16BufferAttribute as ot,REVISION as ut,ArrayCamera as lt,PlaneGeometry as dt,FrontSide as ct,CustomBlending as ht,ZeroFactor as pt,CylinderGeometry as gt,Quaternion as mt,WebXRController as ft,RAD2DEG as yt,FrustumArray as bt,Frustum as xt,RedIntegerFormat as Tt,RedFormat as _t,ShortType as vt,ByteType as Nt,UnsignedShortType as St,RGIntegerFormat as Rt,RGBIntegerFormat as Et,RGBFormat as At,RGBAIntegerFormat as wt,TimestampQuery as Ct,createCanvasElement as Mt,ReverseSubtractEquation as Ft,SubtractEquation as Lt,OneMinusDstAlphaFactor as Pt,OneMinusDstColorFactor as Bt,OneMinusSrcColorFactor as Dt,DstAlphaFactor as Ut,DstColorFactor as It,SrcAlphaSaturateFactor as Ot,SrcColorFactor as Vt,OneFactor as kt,CullFaceNone as Gt,CullFaceBack as zt,CullFaceFront as $t,MultiplyBlending as Wt,SubtractiveBlending as Ht,AdditiveBlending as qt,NotEqualDepth as jt,GreaterDepth as Xt,GreaterEqualDepth as Kt,EqualDepth as Yt,LessEqualDepth as Qt,LessDepth as Zt,AlwaysDepth as Jt,NeverDepth as er,UnsignedShort4444Type as tr,UnsignedShort5551Type as rr,UnsignedInt5999Type as sr,UnsignedInt101111Type as ir,AlphaFormat as nr,RGB_S3TC_DXT1_Format as ar,RGBA_S3TC_DXT1_Format as or,RGBA_S3TC_DXT3_Format as ur,RGBA_S3TC_DXT5_Format as lr,RGB_PVRTC_4BPPV1_Format as dr,RGB_PVRTC_2BPPV1_Format as cr,RGBA_PVRTC_4BPPV1_Format as hr,RGBA_PVRTC_2BPPV1_Format as pr,RGB_ETC1_Format as gr,RGB_ETC2_Format as mr,RGBA_ETC2_EAC_Format as fr,R11_EAC_Format as yr,SIGNED_R11_EAC_Format as br,SIGNED_RG11_EAC_Format as xr,RGBA_ASTC_4x4_Format as Tr,RGBA_ASTC_5x4_Format as _r,RGBA_ASTC_5x5_Format as vr,RGBA_ASTC_6x5_Format as Nr,RGBA_ASTC_6x6_Format as Sr,RGBA_ASTC_8x5_Format as Rr,RGBA_ASTC_8x6_Format as Er,RGBA_ASTC_8x8_Format as Ar,RGBA_ASTC_10x5_Format as wr,RGBA_ASTC_10x6_Format as Cr,RGBA_ASTC_10x8_Format as Mr,RGBA_ASTC_10x10_Format as Fr,RGBA_ASTC_12x10_Format as Lr,RGBA_ASTC_12x12_Format as Pr,RGBA_BPTC_Format as Br,RED_RGTC1_Format as Dr,SIGNED_RED_RGTC1_Format as Ur,SIGNED_RED_GREEN_RGTC2_Format as Ir,MirroredRepeatWrapping as Or,RepeatWrapping as Vr,NearestMipmapNearestFilter as kr,NotEqualCompare as Gr,GreaterCompare as zr,GreaterEqualCompare as $r,EqualCompare as Wr,AlwaysCompare as Hr,NeverCompare as qr,LinearTransfer as jr,getByteLength as Xr,isTypedArray as Kr,NotEqualStencilFunc as Yr,GreaterStencilFunc as Qr,GreaterEqualStencilFunc as Zr,EqualStencilFunc as Jr,LessEqualStencilFunc as es,LessStencilFunc as ts,AlwaysStencilFunc as rs,NeverStencilFunc as ss,DecrementWrapStencilOp as is,IncrementWrapStencilOp as ns,DecrementStencilOp as as,IncrementStencilOp as os,InvertStencilOp as us,ReplaceStencilOp as ls,ZeroStencilOp as ds,KeepStencilOp as cs,MaxEquation as hs,MinEquation as ps,SpotLight as gs,PointLight as ms,DirectionalLight as fs,RectAreaLight as ys,AmbientLight as bs,HemisphereLight as xs,LightProbe as Ts,LinearToneMapping as _s,ReinhardToneMapping as vs,CineonToneMapping as Ns,ACESFilmicToneMapping as Ss,AgXToneMapping as Rs,NeutralToneMapping as Es,Group as As,Loader as ws,FileLoader as Cs,MaterialLoader as Ms,ObjectLoader as Fs}from"./three.core.min.js";export{AdditiveAnimationBlendMode,AnimationAction,AnimationClip,AnimationLoader,AnimationMixer,AnimationObjectGroup,AnimationUtils,ArcCurve,ArrowHelper,AttachedBindMode,Audio,AudioAnalyser,AudioContext,AudioListener,AudioLoader,AxesHelper,BasicDepthPacking,BatchedMesh,BezierInterpolant,Bone,BooleanKeyframeTrack,Box2,Box3,Box3Helper,BoxHelper,BufferGeometryLoader,Cache,Camera,CameraHelper,CanvasTexture,CapsuleGeometry,CatmullRomCurve3,CircleGeometry,Clock,ColorKeyframeTrack,CompressedArrayTexture,CompressedCubeTexture,CompressedTexture,CompressedTextureLoader,ConeGeometry,ConstantAlphaFactor,ConstantColorFactor,Controls,CubeTextureLoader,CubicBezierCurve,CubicBezierCurve3,CubicInterpolant,CullFaceFrontBack,Curve,CurvePath,CustomToneMapping,Cylindrical,Data3DTexture,DataTextureLoader,DataUtils,DefaultLoadingManager,DetachedBindMode,DirectionalLightHelper,DiscreteInterpolant,DodecahedronGeometry,DynamicCopyUsage,DynamicReadUsage,EdgesGeometry,EllipseCurve,ExternalTexture,ExtrudeGeometry,Fog,FogExp2,GLBufferAttribute,GLSL1,GLSL3,GridHelper,HemisphereLightHelper,IcosahedronGeometry,ImageBitmapLoader,ImageLoader,ImageUtils,InstancedBufferGeometry,InstancedMesh,Int16BufferAttribute,Int32BufferAttribute,Int8BufferAttribute,Interpolant,InterpolateBezier,InterpolateDiscrete,InterpolateLinear,InterpolateSmooth,InterpolationSamplingMode,InterpolationSamplingType,KeyframeTrack,LOD,LatheGeometry,Layers,Light,Line,Line3,LineCurve,LineCurve3,LineLoop,LineSegments,LinearInterpolant,LinearMipMapNearestFilter,LoaderUtils,LoadingManager,LoopOnce,LoopPingPong,LoopRepeat,MOUSE,MeshDepthMaterial,MeshDistanceMaterial,NearestMipMapLinearFilter,NearestMipMapNearestFilter,NormalAnimationBlendMode,NumberKeyframeTrack,OctahedronGeometry,OneMinusConstantAlphaFactor,OneMinusConstantColorFactor,Path,PlaneHelper,PointLightHelper,Points,PolarGridHelper,PolyhedronGeometry,PositionalAudio,PropertyBinding,PropertyMixer,QuadraticBezierCurve,QuadraticBezierCurve3,QuaternionKeyframeTrack,QuaternionLinearInterpolant,RGBADepthPacking,RGBDepthPacking,RGB_BPTC_SIGNED_Format,RGB_BPTC_UNSIGNED_Format,RGDepthPacking,RawShaderMaterial,Ray,Raycaster,RenderTarget3D,RingGeometry,ShaderMaterial,Shape,ShapeGeometry,ShapePath,ShapeUtils,Skeleton,SkeletonHelper,SkinnedMesh,Source,Spherical,SphericalHarmonics3,SplineCurve,SpotLightHelper,Sprite,StaticCopyUsage,StaticReadUsage,StereoCamera,StreamCopyUsage,StreamDrawUsage,StreamReadUsage,StringKeyframeTrack,TOUCH,TetrahedronGeometry,TextureLoader,TextureUtils,Timer,TorusGeometry,TorusKnotGeometry,Triangle,TriangleFanDrawMode,TriangleStripDrawMode,TrianglesDrawMode,TubeGeometry,Uint8BufferAttribute,Uint8ClampedBufferAttribute,Uniform,UniformsGroup,VectorKeyframeTrack,VideoFrameTexture,VideoTexture,WebGL3DRenderTarget,WebGLArrayRenderTarget,WebGLRenderTarget,WireframeGeometry,WrapAroundEnding,ZeroCurvatureEnding,ZeroSlopeEnding,getConsoleFunction,setConsoleFunction}from"./three.core.min.js";const Ls=["alphaMap","alphaTest","anisotropy","anisotropyMap","anisotropyRotation","aoMap","aoMapIntensity","attenuationColor","attenuationDistance","bumpMap","clearcoat","clearcoatMap","clearcoatNormalMap","clearcoatNormalScale","clearcoatRoughness","color","dispersion","displacementMap","emissive","emissiveIntensity","emissiveMap","envMap","envMapIntensity","gradientMap","ior","iridescence","iridescenceIOR","iridescenceMap","iridescenceThicknessMap","lightMap","lightMapIntensity","map","matcap","metalness","metalnessMap","normalMap","normalScale","opacity","roughness","roughnessMap","sheen","sheenColor","sheenColorMap","sheenRoughnessMap","shininess","specular","specularColor","specularColorMap","specularIntensity","specularIntensityMap","specularMap","thickness","transmission","transmissionMap"],Ps=new WeakMap;class Bs{constructor(e){this.renderObjects=new WeakMap,this.hasNode=this.containsNode(e),this.hasAnimation=!0===e.object.isSkinnedMesh,this.refreshUniforms=Ls,this.renderId=0}firstInitialization(e){return!1===this.renderObjects.has(e)&&(this.getRenderObjectData(e),!0)}needsVelocity(e){const t=e.getMRT();return null!==t&&t.has("velocity")}getRenderObjectData(e){let t=this.renderObjects.get(e);if(void 0===t){const{geometry:r,material:s,object:i}=e;if(t={material:this.getMaterialData(s),geometry:{id:r.id,attributes:this.getAttributesData(r.attributes),indexVersion:r.index?r.index.version:null,drawRange:{start:r.drawRange.start,count:r.drawRange.count}},worldMatrix:i.matrixWorld.clone()},i.center&&(t.center=i.center.clone()),i.morphTargetInfluences&&(t.morphTargetInfluences=i.morphTargetInfluences.slice()),null!==e.bundle&&(t.version=e.bundle.version),t.material.transmission>0){const{width:r,height:s}=e.context;t.bufferWidth=r,t.bufferHeight=s}t.lights=this.getLightsData(e.lightsNode.getLights()),this.renderObjects.set(e,t)}return t}getAttributesData(e){const t={};for(const r in e){const s=e[r];t[r]={version:s.version}}return t}containsNode(e){const t=e.material;for(const e in t)if(t[e]&&t[e].isNode)return!0;return!!(e.context.modelViewMatrix||e.context.modelNormalViewMatrix||e.context.getAO||e.context.getShadow)}getMaterialData(e){const t={};for(const r of this.refreshUniforms){const s=e[r];null!=s&&("object"==typeof s&&void 0!==s.clone?!0===s.isTexture?t[r]={id:s.id,version:s.version}:t[r]=s.clone():t[r]=s)}return t}equals(e,t){const{object:r,material:s,geometry:i}=e,n=this.getRenderObjectData(e);if(!0!==n.worldMatrix.equals(r.matrixWorld))return n.worldMatrix.copy(r.matrixWorld),!1;const a=n.material;for(const e in a){const t=a[e],r=s[e];if(void 0!==t.equals){if(!1===t.equals(r))return t.copy(r),!1}else if(!0===r.isTexture){if(t.id!==r.id||t.version!==r.version)return t.id=r.id,t.version=r.version,!1}else if(t!==r)return a[e]=r,!1}if(a.transmission>0){const{width:t,height:r}=e.context;if(n.bufferWidth!==t||n.bufferHeight!==r)return n.bufferWidth=t,n.bufferHeight=r,!1}const o=n.geometry,u=i.attributes,l=o.attributes,d=Object.keys(l),c=Object.keys(u);if(o.id!==i.id)return o.id=i.id,!1;if(d.length!==c.length)return n.geometry.attributes=this.getAttributesData(u),!1;for(const e of d){const t=l[e],r=u[e];if(void 0===r)return delete l[e],!1;if(t.version!==r.version)return t.version=r.version,!1}const h=i.index,p=o.indexVersion,g=h?h.version:null;if(p!==g)return o.indexVersion=g,!1;if(o.drawRange.start!==i.drawRange.start||o.drawRange.count!==i.drawRange.count)return o.drawRange.start=i.drawRange.start,o.drawRange.count=i.drawRange.count,!1;if(n.morphTargetInfluences){let e=!1;for(let t=0;t>>16,2246822507),r^=Math.imul(s^s>>>13,3266489909),s=Math.imul(s^s>>>16,2246822507),s^=Math.imul(r^r>>>13,3266489909),4294967296*(2097151&s)+(r>>>0)}const Us=e=>Ds(e),Is=e=>Ds(e),Os=(...e)=>Ds(e),Vs=new Map([[1,"float"],[2,"vec2"],[3,"vec3"],[4,"vec4"],[9,"mat3"],[16,"mat4"]]),ks=new WeakMap;function Gs(e){return Vs.get(e)}function zs(e){if(/[iu]?vec\d/.test(e))return e.startsWith("ivec")?Int32Array:e.startsWith("uvec")?Uint32Array:Float32Array;if(/mat\d/.test(e))return Float32Array;if(/float/.test(e))return Float32Array;if(/uint/.test(e))return Uint32Array;if(/int/.test(e))return Int32Array;throw new Error(`THREE.NodeUtils: Unsupported type: ${e}`)}function $s(e){return/float|int|uint/.test(e)?1:/vec2/.test(e)?2:/vec3/.test(e)?3:/vec4/.test(e)||/mat2/.test(e)?4:/mat3/.test(e)?9:/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function Ws(e){return/float|int|uint/.test(e)?1:/vec2/.test(e)?2:/vec3/.test(e)?3:/vec4/.test(e)||/mat2/.test(e)?4:/mat3/.test(e)?12:/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function Hs(e){return/float|int|uint/.test(e)?4:/vec2/.test(e)?8:/vec3/.test(e)||/vec4/.test(e)?16:/mat2/.test(e)?8:/mat3/.test(e)||/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function qs(e){if(null==e)return null;const t=typeof e;return!0===e.isNode?"node":"number"===t?"float":"boolean"===t?"bool":"string"===t?"string":"function"===t?"shader":!0===e.isVector2?"vec2":!0===e.isVector3?"vec3":!0===e.isVector4?"vec4":!0===e.isMatrix2?"mat2":!0===e.isMatrix3?"mat3":!0===e.isMatrix4?"mat4":!0===e.isColor?"color":e instanceof ArrayBuffer?"ArrayBuffer":null}function js(o,...u){const l=o?o.slice(-4):void 0;return 1===u.length&&("vec2"===l?u=[u[0],u[0]]:"vec3"===l?u=[u[0],u[0],u[0]]:"vec4"===l&&(u=[u[0],u[0],u[0],u[0]])),"color"===o?new e(...u):"vec2"===l?new t(...u):"vec3"===l?new r(...u):"vec4"===l?new s(...u):"mat2"===l?new i(...u):"mat3"===l?new n(...u):"mat4"===l?new a(...u):"bool"===o?u[0]||!1:"float"===o||"int"===o||"uint"===o?u[0]||0:"string"===o?u[0]||"":"ArrayBuffer"===o?Ys(u[0]):null}function Xs(e){let t=ks.get(e);return void 0===t&&(t={},ks.set(e,t)),t}function Ks(e){let t="";const r=new Uint8Array(e);for(let e=0;ee.charCodeAt(0)).buffer}var Qs=Object.freeze({__proto__:null,arrayBufferToBase64:Ks,base64ToArrayBuffer:Ys,getAlignmentFromType:Hs,getDataFromObject:Xs,getLengthFromType:$s,getMemoryLengthFromType:Ws,getTypeFromLength:Gs,getTypedArrayFromType:zs,getValueFromType:js,getValueType:qs,hash:Os,hashArray:Is,hashString:Us});const Zs={VERTEX:"vertex",FRAGMENT:"fragment"},Js={NONE:"none",FRAME:"frame",RENDER:"render",OBJECT:"object"},ei={BOOLEAN:"bool",INTEGER:"int",FLOAT:"float",VECTOR2:"vec2",VECTOR3:"vec3",VECTOR4:"vec4",MATRIX2:"mat2",MATRIX3:"mat3",MATRIX4:"mat4"},ti={READ_ONLY:"readOnly",WRITE_ONLY:"writeOnly",READ_WRITE:"readWrite"},ri=["fragment","vertex"],si=["setup","analyze","generate"],ii=[...ri,"compute"],ni=["x","y","z","w"],ai={analyze:"setup",generate:"analyze"};let oi=0;class ui extends u{static get type(){return"Node"}constructor(e=null){super(),this.nodeType=e,this.updateType=Js.NONE,this.updateBeforeType=Js.NONE,this.updateAfterType=Js.NONE,this.uuid=l.generateUUID(),this.version=0,this.name="",this.global=!1,this.parents=!1,this.isNode=!0,this._beforeNodes=null,this._cacheKey=null,this._cacheKeyVersion=0,Object.defineProperty(this,"id",{value:oi++})}set needsUpdate(e){!0===e&&this.version++}get type(){return this.constructor.type}onUpdate(e,t){return this.updateType=t,this.update=e.bind(this),this}onFrameUpdate(e){return this.onUpdate(e,Js.FRAME)}onRenderUpdate(e){return this.onUpdate(e,Js.RENDER)}onObjectUpdate(e){return this.onUpdate(e,Js.OBJECT)}onReference(e){return this.updateReference=e.bind(this),this}updateReference(){return this}isGlobal(){return this.global}*getChildren(){for(const{childNode:e}of this._getChildren())yield e}dispose(){this.dispatchEvent({type:"dispose"})}traverse(e){e(this);for(const t of this.getChildren())t.traverse(e)}_getChildren(e=new Set){const t=[];e.add(this);for(const r of Object.getOwnPropertyNames(this)){const s=this[r];if(!0!==r.startsWith("_")&&!e.has(s))if(!0===Array.isArray(s))for(let e=0;e0&&(e.inputNodes=r)}deserialize(e){if(void 0!==e.inputNodes){const t=e.meta.nodes;for(const r in e.inputNodes)if(Array.isArray(e.inputNodes[r])){const s=[];for(const i of e.inputNodes[r])s.push(t[i]);this[r]=s}else if("object"==typeof e.inputNodes[r]){const s={};for(const i in e.inputNodes[r]){const n=e.inputNodes[r][i];s[i]=t[n]}this[r]=s}else{const s=e.inputNodes[r];this[r]=t[s]}}}toJSON(e){const{uuid:t,type:r}=this,s=void 0===e||"string"==typeof e;s&&(e={textures:{},images:{},nodes:{}});let i=e.nodes[t];function n(e){const t=[];for(const r in e){const s=e[r];delete s.metadata,t.push(s)}return t}if(void 0===i&&(i={uuid:t,type:r,meta:e,metadata:{version:4.7,type:"Node",generator:"Node.toJSON"}},!0!==s&&(e.nodes[i.uuid]=i),this.serialize(i),delete i.meta),s){const t=n(e.textures),r=n(e.images),s=n(e.nodes);t.length>0&&(i.textures=t),r.length>0&&(i.images=r),s.length>0&&(i.nodes=s)}return i}}class li extends ui{static get type(){return"ArrayElementNode"}constructor(e,t){super(),this.node=e,this.indexNode=t,this.isArrayElementNode=!0}getNodeType(e){return this.node.getElementType(e)}getMemberType(e,t){return this.node.getMemberType(e,t)}generate(e){const t=this.indexNode.getNodeType(e);return`${this.node.build(e)}[ ${this.indexNode.build(e,!e.isVector(t)&&e.isInteger(t)?t:"uint")} ]`}}class di extends ui{static get type(){return"ConvertNode"}constructor(e,t){super(),this.node=e,this.convertTo=t}getNodeType(e){const t=this.node.getNodeType(e);let r=null;for(const s of this.convertTo.split("|"))null!==r&&e.getTypeLength(t)!==e.getTypeLength(s)||(r=s);return r}serialize(e){super.serialize(e),e.convertTo=this.convertTo}deserialize(e){super.deserialize(e),this.convertTo=e.convertTo}generate(e,t){const r=this.node,s=this.getNodeType(e),i=r.build(e,s);return e.format(i,s,t)}}class ci extends ui{static get type(){return"TempNode"}constructor(e=null){super(e),this.isTempNode=!0}hasDependencies(e){return e.getDataFromNode(this).usageCount>1}build(e,t){if("generate"===e.getBuildStage()){const r=e.getVectorType(this.getNodeType(e,t)),s=e.getDataFromNode(this);if(void 0!==s.propertyName)return e.format(s.propertyName,r,t);if("void"!==r&&"void"!==t&&this.hasDependencies(e)){const i=super.build(e,r),n=e.getVarFromNode(this,null,r),a=e.getPropertyName(n);return e.addLineFlowCode(`${a} = ${i}`,this),s.snippet=i,s.propertyName=a,e.format(s.propertyName,r,t)}}return super.build(e,t)}}class hi extends ci{static get type(){return"JoinNode"}constructor(e=[],t=null){super(t),this.nodes=e}getNodeType(e){return null!==this.nodeType?e.getVectorType(this.nodeType):e.getTypeFromLength(this.nodes.reduce((t,r)=>t+e.getTypeLength(r.getNodeType(e)),0))}generate(e,t){const r=this.getNodeType(e),s=e.getTypeLength(r),i=this.nodes,n=e.getComponentType(r),a=[];let u=0;for(const t of i){if(u>=s){o(`TSL: Length of parameters exceeds maximum length of function '${r}()' type.`);break}let i,l=t.getNodeType(e),d=e.getTypeLength(l);u+d>s&&(o(`TSL: Length of '${r}()' data exceeds maximum length of output type.`),d=s-u,l=e.getTypeFromLength(d)),u+=d,i=t.build(e,l);if(e.getComponentType(l)!==n){const t=e.getTypeFromLength(d,n);i=e.format(i,l,t)}a.push(i)}const l=`${e.getType(r)}( ${a.join(", ")} )`;return e.format(l,r,t)}}const pi=ni.join("");class gi extends ui{static get type(){return"SplitNode"}constructor(e,t="x"){super(),this.node=e,this.components=t,this.isSplitNode=!0}getVectorLength(){let e=this.components.length;for(const t of this.components)e=Math.max(ni.indexOf(t)+1,e);return e}getComponentType(e){return e.getComponentType(this.node.getNodeType(e))}getNodeType(e){return e.getTypeFromLength(this.components.length,this.getComponentType(e))}getScope(){return this.node.getScope()}generate(e,t){const r=this.node,s=e.getTypeLength(r.getNodeType(e));let i=null;if(s>1){let n=null;this.getVectorLength()>=s&&(n=e.getTypeFromLength(this.getVectorLength(),this.getComponentType(e)));const a=r.build(e,n);i=this.components.length===s&&this.components===pi.slice(0,this.components.length)?e.format(a,n,t):e.format(`${a}.${this.components}`,this.getNodeType(e),t)}else i=r.build(e,t);return i}serialize(e){super.serialize(e),e.components=this.components}deserialize(e){super.deserialize(e),this.components=e.components}}class mi extends ci{static get type(){return"SetNode"}constructor(e,t,r){super(),this.sourceNode=e,this.components=t,this.targetNode=r}getNodeType(e){return this.sourceNode.getNodeType(e)}generate(e){const{sourceNode:t,components:r,targetNode:s}=this,i=this.getNodeType(e),n=e.getComponentType(s.getNodeType(e)),a=e.getTypeFromLength(r.length,n),o=s.build(e,a),u=t.build(e,i),l=e.getTypeLength(i),d=[];for(let e=0;e(e=>e.replace(/r|s/g,"x").replace(/g|t/g,"y").replace(/b|p/g,"z").replace(/a|q/g,"w"))(e).split("").sort().join("");ui.prototype.assign=function(...e){if(!0!==this.isStackNode)return null!==_i?_i.assign(this,...e):o("TSL: No stack defined for assign operation. Make sure the assign is inside a Fn()."),this;{const t=vi.get("assign");return this.addToStack(t(...e))}},ui.prototype.toVarIntent=function(){return this},ui.prototype.get=function(e){return new Ti(this,e)};const Ri={};function Ei(e,t,r){Ri[e]=Ri[t]=Ri[r]={get(){this._cache=this._cache||{};let t=this._cache[e];return void 0===t&&(t=new gi(this,e),this._cache[e]=t),t},set(t){this[e].assign(Zi(t))}};const s=e.toUpperCase(),i=t.toUpperCase(),n=r.toUpperCase();ui.prototype["set"+s]=ui.prototype["set"+i]=ui.prototype["set"+n]=function(t){const r=Si(e);return new mi(this,r,Zi(t))},ui.prototype["flip"+s]=ui.prototype["flip"+i]=ui.prototype["flip"+n]=function(){const t=Si(e);return new fi(this,t)}}const Ai=["x","y","z","w"],wi=["r","g","b","a"],Ci=["s","t","p","q"];for(let e=0;e<4;e++){let t=Ai[e],r=wi[e],s=Ci[e];Ei(t,r,s);for(let i=0;i<4;i++){t=Ai[e]+Ai[i],r=wi[e]+wi[i],s=Ci[e]+Ci[i],Ei(t,r,s);for(let n=0;n<4;n++){t=Ai[e]+Ai[i]+Ai[n],r=wi[e]+wi[i]+wi[n],s=Ci[e]+Ci[i]+Ci[n],Ei(t,r,s);for(let a=0;a<4;a++)t=Ai[e]+Ai[i]+Ai[n]+Ai[a],r=wi[e]+wi[i]+wi[n]+wi[a],s=Ci[e]+Ci[i]+Ci[n]+Ci[a],Ei(t,r,s)}}}for(let e=0;e<32;e++)Ri[e]={get(){this._cache=this._cache||{};let t=this._cache[e];return void 0===t&&(t=new li(this,new xi(e,"uint")),this._cache[e]=t),t},set(t){this[e].assign(Zi(t))}};Object.defineProperties(ui.prototype,Ri);const Mi=new WeakMap,Fi=function(e,t=null){for(const r in e)e[r]=Zi(e[r],t);return e},Li=function(e,t=null){const r=e.length;for(let s=0;su?(o(`TSL: "${r}" parameter length exceeds limit.`),t.slice(0,u)):t}return null===t?n=(...t)=>i(new e(...tn(d(t)))):null!==r?(r=Zi(r),n=(...s)=>i(new e(t,...tn(d(s)),r))):n=(...r)=>i(new e(t,...tn(d(r)))),n.setParameterLength=(...e)=>(1===e.length?a=u=e[0]:2===e.length&&([a,u]=e),n),n.setName=e=>(l=e,n),n},Bi=function(e,...t){return new e(...tn(t))};class Di extends ui{constructor(e,t){super(),this.shaderNode=e,this.rawInputs=t,this.isShaderCallNodeInternal=!0}getNodeType(e){return this.shaderNode.nodeType||this.getOutputNode(e).getNodeType(e)}getElementType(e){return this.getOutputNode(e).getElementType(e)}getMemberType(e,t){return this.getOutputNode(e).getMemberType(e,t)}call(e){const{shaderNode:t,rawInputs:r}=this,s=e.getNodeProperties(t),i=e.getClosestSubBuild(t.subBuilds)||"",n=i||"default";if(s[n])return s[n];const a=e.subBuildFn,o=e.fnCall;e.subBuildFn=i,e.fnCall=this;let u=null;if(t.layout){let s=Mi.get(e.constructor);void 0===s&&(s=new WeakMap,Mi.set(e.constructor,s));let i=s.get(t);void 0===i&&(i=Zi(e.buildFunctionNode(t)),s.set(t,i)),e.addInclude(i);const n=r?function(e){let t;en(e);t=e[0]&&(e[0].isNode||Object.getPrototypeOf(e[0])!==Object.prototype)?[...e]:e[0];return t}(r):null;u=Zi(i.call(n))}else{const s=new Proxy(e,{get:(e,t,r)=>{let s;return s=Symbol.iterator===t?function*(){yield}:Reflect.get(e,t,r),s}}),i=r?function(e){let t=0;return en(e),new Proxy(e,{get:(r,s,i)=>{let n;if("length"===s)return n=e.length,n;if(Symbol.iterator===s)n=function*(){for(const t of e)yield Zi(t)};else{if(e.length>0)if(Object.getPrototypeOf(e[0])===Object.prototype){const r=e[0];n=void 0===r[s]?r[t++]:Reflect.get(r,s,i)}else e[0]instanceof ui&&(n=void 0===e[s]?e[t++]:Reflect.get(e,s,i));else n=Reflect.get(r,s,i);n=Zi(n)}return n}})}(r):null,n=Array.isArray(r)?r.length>0:null!==r,a=t.jsFunc,o=n||a.length>1?a(i,s):a(s);u=Zi(o)}return e.subBuildFn=a,e.fnCall=o,t.once&&(s[n]=u),u}setupOutput(e){return e.addStack(),e.stack.outputNode=this.call(e),e.removeStack()}getOutputNode(e){const t=e.getNodeProperties(this),r=e.getSubBuildOutput(this);return t[r]=t[r]||this.setupOutput(e),t[r].subBuild=e.getClosestSubBuild(this),t[r]}build(e,t=null){let r=null;const s=e.getBuildStage(),i=e.getNodeProperties(this),n=e.getSubBuildOutput(this),a=this.getOutputNode(e),o=e.fnCall;if(e.fnCall=this,"setup"===s){const t=e.getSubBuildProperty("initialized",this);if(!0!==i[t]&&(i[t]=!0,i[n]=this.getOutputNode(e),i[n].build(e),this.shaderNode.subBuilds))for(const t of e.chaining){const r=e.getDataFromNode(t,"any");r.subBuilds=r.subBuilds||new Set;for(const e of this.shaderNode.subBuilds)r.subBuilds.add(e)}r=i[n]}else"analyze"===s?a.build(e,t):"generate"===s&&(r=a.build(e,t)||"");return e.fnCall=o,r}}class Ui extends ui{constructor(e,t){super(t),this.jsFunc=e,this.layout=null,this.global=!0,this.once=!1}setLayout(e){return this.layout=e,this}getLayout(){return this.layout}call(e=null){return new Di(this,e)}setup(){return this.call()}}const Ii=[!1,!0],Oi=[0,1,2,3],Vi=[-1,-2],ki=[.5,1.5,1/3,1e-6,1e6,Math.PI,2*Math.PI,1/Math.PI,2/Math.PI,1/(2*Math.PI),Math.PI/2],Gi=new Map;for(const e of Ii)Gi.set(e,new xi(e));const zi=new Map;for(const e of Oi)zi.set(e,new xi(e,"uint"));const $i=new Map([...zi].map(e=>new xi(e.value,"int")));for(const e of Vi)$i.set(e,new xi(e,"int"));const Wi=new Map([...$i].map(e=>new xi(e.value)));for(const e of ki)Wi.set(e,new xi(e));for(const e of ki)Wi.set(-e,new xi(-e));const Hi={bool:Gi,uint:zi,ints:$i,float:Wi},qi=new Map([...Gi,...Wi]),ji=(e,t)=>qi.has(e)?qi.get(e):!0===e.isNode?e:new xi(e,t),Xi=function(e,t=null){return(...r)=>{for(const t of r)if(void 0===t)return o(`TSL: Invalid parameter for the type "${e}".`),new xi(0,e);if((0===r.length||!["bool","float","int","uint"].includes(e)&&r.every(e=>{const t=typeof e;return"object"!==t&&"function"!==t}))&&(r=[js(e,...r)]),1===r.length&&null!==t&&t.has(r[0]))return Ji(t.get(r[0]));if(1===r.length){const t=ji(r[0],e);return t.nodeType===e?Ji(t):Ji(new di(t,e))}const s=r.map(e=>ji(e));return Ji(new hi(s,e))}},Ki=e=>"object"==typeof e&&null!==e?e.value:e,Yi=e=>null!=e?e.nodeType||e.convertTo||("string"==typeof e?e:null):null;function Qi(e,t){return new Ui(e,t)}const Zi=(e,t=null)=>function(e,t=null){const r=qs(e);return"node"===r?e:null===t&&("float"===r||"boolean"===r)||r&&"shader"!==r&&"string"!==r?Zi(ji(e,t)):"shader"===r?e.isFn?e:un(e):e}(e,t),Ji=(e,t=null)=>Zi(e,t).toVarIntent(),en=(e,t=null)=>new Fi(e,t),tn=(e,t=null)=>new Li(e,t),rn=(e,t=null,r=null,s=null)=>new Pi(e,t,r,s),sn=(e,...t)=>new Bi(e,...t),nn=(e,t=null,r=null,s={})=>new Pi(e,t,r,{...s,intent:!0});let an=0;class on extends ui{constructor(e,t=null){super();let r=null;null!==t&&("object"==typeof t?r=t.return:("string"==typeof t?r=t:o("TSL: Invalid layout type."),t=null)),this.shaderNode=new Qi(e,r),null!==t&&this.setLayout(t),this.isFn=!0}setLayout(e){const t=this.shaderNode.nodeType;if("object"!=typeof e.inputs){const r={name:"fn"+an++,type:t,inputs:[]};for(const t in e)"return"!==t&&r.inputs.push({name:t,type:e[t]});e=r}return this.shaderNode.setLayout(e),this}getNodeType(e){return this.shaderNode.getNodeType(e)||"float"}call(...e){const t=this.shaderNode.call(e);return"void"===this.shaderNode.nodeType&&t.toStack(),t.toVarIntent()}once(e=null){return this.shaderNode.once=!0,this.shaderNode.subBuilds=e,this}generate(e){const t=this.getNodeType(e);return o('TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".'),e.generateConst(t)}}function un(e,t=null){const r=new on(e,t);return new Proxy(()=>{},{apply:(e,t,s)=>r.call(...s),get:(e,t,s)=>Reflect.get(r,t,s),set:(e,t,s,i)=>Reflect.set(r,t,s,i)})}const ln=e=>{_i=e},dn=()=>_i,cn=(...e)=>_i.If(...e);function hn(e){return _i&&_i.addToStack(e),e}Ni("toStack",hn);const pn=new Xi("color"),gn=new Xi("float",Hi.float),mn=new Xi("int",Hi.ints),fn=new Xi("uint",Hi.uint),yn=new Xi("bool",Hi.bool),bn=new Xi("vec2"),xn=new Xi("ivec2"),Tn=new Xi("uvec2"),_n=new Xi("bvec2"),vn=new Xi("vec3"),Nn=new Xi("ivec3"),Sn=new Xi("uvec3"),Rn=new Xi("bvec3"),En=new Xi("vec4"),An=new Xi("ivec4"),wn=new Xi("uvec4"),Cn=new Xi("bvec4"),Mn=new Xi("mat2"),Fn=new Xi("mat3"),Ln=new Xi("mat4");Ni("toColor",pn),Ni("toFloat",gn),Ni("toInt",mn),Ni("toUint",fn),Ni("toBool",yn),Ni("toVec2",bn),Ni("toIVec2",xn),Ni("toUVec2",Tn),Ni("toBVec2",_n),Ni("toVec3",vn),Ni("toIVec3",Nn),Ni("toUVec3",Sn),Ni("toBVec3",Rn),Ni("toVec4",En),Ni("toIVec4",An),Ni("toUVec4",wn),Ni("toBVec4",Cn),Ni("toMat2",Mn),Ni("toMat3",Fn),Ni("toMat4",Ln);const Pn=rn(li).setParameterLength(2),Bn=(e,t)=>Zi(new di(Zi(e),t));Ni("element",Pn),Ni("convert",Bn);Ni("append",e=>(d("TSL: .append() has been renamed to .toStack()."),hn(e)));class Dn extends ui{static get type(){return"PropertyNode"}constructor(e,t=null,r=!1){super(e),this.name=t,this.varying=r,this.isPropertyNode=!0,this.global=!0}customCacheKey(){return Us(this.type+":"+(this.name||"")+":"+(this.varying?"1":"0"))}getHash(e){return this.name||super.getHash(e)}generate(e){let t;return!0===this.varying?(t=e.getVaryingFromNode(this,this.name),t.needsInterpolation=!0):t=e.getVarFromNode(this,this.name),e.getPropertyName(t)}}const Un=(e,t)=>new Dn(e,t),In=(e,t)=>new Dn(e,t,!0),On=sn(Dn,"vec4","DiffuseColor"),Vn=sn(Dn,"vec3","DiffuseContribution"),kn=sn(Dn,"vec3","EmissiveColor"),Gn=sn(Dn,"float","Roughness"),zn=sn(Dn,"float","Metalness"),$n=sn(Dn,"float","Clearcoat"),Wn=sn(Dn,"float","ClearcoatRoughness"),Hn=sn(Dn,"vec3","Sheen"),qn=sn(Dn,"float","SheenRoughness"),jn=sn(Dn,"float","Iridescence"),Xn=sn(Dn,"float","IridescenceIOR"),Kn=sn(Dn,"float","IridescenceThickness"),Yn=sn(Dn,"float","AlphaT"),Qn=sn(Dn,"float","Anisotropy"),Zn=sn(Dn,"vec3","AnisotropyT"),Jn=sn(Dn,"vec3","AnisotropyB"),ea=sn(Dn,"color","SpecularColor"),ta=sn(Dn,"color","SpecularColorBlended"),ra=sn(Dn,"float","SpecularF90"),sa=sn(Dn,"float","Shininess"),ia=sn(Dn,"vec4","Output"),na=sn(Dn,"float","dashSize"),aa=sn(Dn,"float","gapSize"),oa=sn(Dn,"float","pointWidth"),ua=sn(Dn,"float","IOR"),la=sn(Dn,"float","Transmission"),da=sn(Dn,"float","Thickness"),ca=sn(Dn,"float","AttenuationDistance"),ha=sn(Dn,"color","AttenuationColor"),pa=sn(Dn,"float","Dispersion");class ga extends ui{static get type(){return"UniformGroupNode"}constructor(e,t=!1,r=1){super("string"),this.name=e,this.shared=t,this.order=r,this.isUniformGroup=!0}serialize(e){super.serialize(e),e.name=this.name,e.version=this.version,e.shared=this.shared}deserialize(e){super.deserialize(e),this.name=e.name,this.version=e.version,this.shared=e.shared}}const ma=e=>new ga(e),fa=(e,t=0)=>new ga(e,!0,t),ya=fa("frame"),ba=fa("render"),xa=ma("object");class Ta extends yi{static get type(){return"UniformNode"}constructor(e,t=null){super(e,t),this.isUniformNode=!0,this.name="",this.groupNode=xa}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setGroup(e){return this.groupNode=e,this}getGroup(){return this.groupNode}getUniformHash(e){return this.getHash(e)}onUpdate(e,t){return e=e.bind(this),super.onUpdate(t=>{const r=e(t,this);void 0!==r&&(this.value=r)},t)}getInputType(e){let t=super.getInputType(e);return"bool"===t&&(t="uint"),t}generate(e,t){const r=this.getNodeType(e),s=this.getUniformHash(e);let i=e.getNodeFromHash(s);void 0===i&&(e.setHashNode(this,s),i=this);const n=i.getInputType(e),a=e.getUniformFromNode(i,n,e.shaderStage,this.name||e.context.nodeName),o=e.getPropertyName(a);void 0!==e.context.nodeName&&delete e.context.nodeName;let u=o;if("bool"===r){const t=e.getDataFromNode(this);let s=t.propertyName;if(void 0===s){const i=e.getVarFromNode(this,null,"bool");s=e.getPropertyName(i),t.propertyName=s,u=e.format(o,n,r),e.addLineFlowCode(`${s} = ${u}`,this)}u=s}return e.format(u,r,t)}}const _a=(e,t)=>{const r=Yi(t||e);if(r===e&&(e=js(r)),e&&!0===e.isNode){let t=e.value;e.traverse(e=>{!0===e.isConstNode&&(t=e.value)}),e=t}return new Ta(e,r)};class va extends ci{static get type(){return"ArrayNode"}constructor(e,t,r=null){super(e),this.count=t,this.values=r,this.isArrayNode=!0}getArrayCount(){return this.count}getNodeType(e){return null===this.nodeType?this.values[0].getNodeType(e):this.nodeType}getElementType(e){return this.getNodeType(e)}getMemberType(e,t){return null===this.nodeType?this.values[0].getMemberType(e,t):super.getMemberType(e,t)}generate(e){const t=this.getNodeType(e);return e.generateArray(t,this.count,this.values)}}const Na=(...e)=>{let t;if(1===e.length){const r=e[0];t=new va(null,r.length,r)}else{const r=e[0],s=e[1];t=new va(r,s)}return Zi(t)};Ni("toArray",(e,t)=>Na(Array(t).fill(e)));class Sa extends ci{static get type(){return"AssignNode"}constructor(e,t){super(),this.targetNode=e,this.sourceNode=t,this.isAssignNode=!0}hasDependencies(){return!1}getNodeType(e,t){return"void"!==t?this.targetNode.getNodeType(e):"void"}needsSplitAssign(e){const{targetNode:t}=this;if(!1===e.isAvailable("swizzleAssign")&&t.isSplitNode&&t.components.length>1){const r=e.getTypeLength(t.node.getNodeType(e));return ni.join("").slice(0,r)!==t.components}return!1}setup(e){const{targetNode:t,sourceNode:r}=this,s=t.getScope();e.getDataFromNode(s).assign=!0;const i=e.getNodeProperties(this);i.sourceNode=r,i.targetNode=t.context({assign:!0})}generate(e,t){const{targetNode:r,sourceNode:s}=e.getNodeProperties(this),i=this.needsSplitAssign(e),n=r.build(e),a=r.getNodeType(e),o=s.build(e,a),u=s.getNodeType(e),l=e.getDataFromNode(this);let d;if(!0===l.initialized)"void"!==t&&(d=n);else if(i){const s=e.getVarFromNode(this,null,a),i=e.getPropertyName(s);e.addLineFlowCode(`${i} = ${o}`,this);const u=r.node,l=u.node.context({assign:!0}).build(e);for(let t=0;t{const s=r.type;let i;return i="pointer"===s?"&"+t.build(e):t.build(e,s),i};if(Array.isArray(i)){if(i.length>s.length)o("TSL: The number of provided parameters exceeds the expected number of inputs in 'Fn()'."),i.length=s.length;else if(i.length(t=t.length>1||t[0]&&!0===t[0].isNode?tn(t):en(t[0]),new Ea(Zi(e),t));Ni("call",Aa);const wa={"==":"equal","!=":"notEqual","<":"lessThan",">":"greaterThan","<=":"lessThanEqual",">=":"greaterThanEqual","%":"mod"};class Ca extends ci{static get type(){return"OperatorNode"}constructor(e,t,r,...s){if(super(),s.length>0){let i=new Ca(e,t,r);for(let t=0;t>"===r||"<<"===r)return e.getIntegerType(n);if("!"===r||"&&"===r||"||"===r||"^^"===r)return"bool";if("=="===r||"!="===r||"<"===r||">"===r||"<="===r||">="===r){const t=Math.max(e.getTypeLength(n),e.getTypeLength(a));return t>1?`bvec${t}`:"bool"}if(e.isMatrix(n)){if("float"===a)return n;if(e.isVector(a))return e.getVectorFromMatrix(n);if(e.isMatrix(a))return n}else if(e.isMatrix(a)){if("float"===n)return a;if(e.isVector(n))return e.getVectorFromMatrix(a)}return e.getTypeLength(a)>e.getTypeLength(n)?a:n}generate(e,t){const r=this.op,{aNode:s,bNode:i}=this,n=this.getNodeType(e,t);let a=null,o=null;"void"!==n?(a=s.getNodeType(e),o=i?i.getNodeType(e):null,"<"===r||">"===r||"<="===r||">="===r||"=="===r||"!="===r?e.isVector(a)?o=a:e.isVector(o)?a=o:a!==o&&(a=o="float"):">>"===r||"<<"===r?(a=n,o=e.changeComponentType(o,"uint")):"%"===r?(a=n,o=e.isInteger(a)&&e.isInteger(o)?o:a):e.isMatrix(a)?"float"===o?o="float":e.isVector(o)?o=e.getVectorFromMatrix(a):e.isMatrix(o)||(a=o=n):a=e.isMatrix(o)?"float"===a?"float":e.isVector(a)?e.getVectorFromMatrix(o):o=n:o=n):a=o=n;const u=s.build(e,a),l=i?i.build(e,o):null,d=e.getFunctionOperator(r);if("void"!==t){const s=e.renderer.coordinateSystem===c;if("=="===r||"!="===r||"<"===r||">"===r||"<="===r||">="===r)return s&&e.isVector(a)?e.format(`${this.getOperatorMethod(e,t)}( ${u}, ${l} )`,n,t):e.format(`( ${u} ${r} ${l} )`,n,t);if("%"===r)return e.isInteger(o)?e.format(`( ${u} % ${l} )`,n,t):e.format(`${this.getOperatorMethod(e,n)}( ${u}, ${l} )`,n,t);if("!"===r||"~"===r)return e.format(`(${r}${u})`,a,t);if(d)return e.format(`${d}( ${u}, ${l} )`,n,t);if(e.isMatrix(a)&&"float"===o)return e.format(`( ${l} ${r} ${u} )`,n,t);if("float"===a&&e.isMatrix(o))return e.format(`${u} ${r} ${l}`,n,t);{let i=`( ${u} ${r} ${l} )`;return!s&&"bool"===n&&e.isVector(a)&&e.isVector(o)&&(i=`all${i}`),e.format(i,n,t)}}if("void"!==a)return d?e.format(`${d}( ${u}, ${l} )`,n,t):e.isMatrix(a)&&"float"===o?e.format(`${l} ${r} ${u}`,n,t):e.format(`${u} ${r} ${l}`,n,t)}serialize(e){super.serialize(e),e.op=this.op}deserialize(e){super.deserialize(e),this.op=e.op}}const Ma=nn(Ca,"+").setParameterLength(2,1/0).setName("add"),Fa=nn(Ca,"-").setParameterLength(2,1/0).setName("sub"),La=nn(Ca,"*").setParameterLength(2,1/0).setName("mul"),Pa=nn(Ca,"/").setParameterLength(2,1/0).setName("div"),Ba=nn(Ca,"%").setParameterLength(2).setName("mod"),Da=nn(Ca,"==").setParameterLength(2).setName("equal"),Ua=nn(Ca,"!=").setParameterLength(2).setName("notEqual"),Ia=nn(Ca,"<").setParameterLength(2).setName("lessThan"),Oa=nn(Ca,">").setParameterLength(2).setName("greaterThan"),Va=nn(Ca,"<=").setParameterLength(2).setName("lessThanEqual"),ka=nn(Ca,">=").setParameterLength(2).setName("greaterThanEqual"),Ga=nn(Ca,"&&").setParameterLength(2,1/0).setName("and"),za=nn(Ca,"||").setParameterLength(2,1/0).setName("or"),$a=nn(Ca,"!").setParameterLength(1).setName("not"),Wa=nn(Ca,"^^").setParameterLength(2).setName("xor"),Ha=nn(Ca,"&").setParameterLength(2).setName("bitAnd"),qa=nn(Ca,"~").setParameterLength(1).setName("bitNot"),ja=nn(Ca,"|").setParameterLength(2).setName("bitOr"),Xa=nn(Ca,"^").setParameterLength(2).setName("bitXor"),Ka=nn(Ca,"<<").setParameterLength(2).setName("shiftLeft"),Ya=nn(Ca,">>").setParameterLength(2).setName("shiftRight"),Qa=un(([e])=>(e.addAssign(1),e)),Za=un(([e])=>(e.subAssign(1),e)),Ja=un(([e])=>{const t=mn(e).toConst();return e.addAssign(1),t}),eo=un(([e])=>{const t=mn(e).toConst();return e.subAssign(1),t});Ni("add",Ma),Ni("sub",Fa),Ni("mul",La),Ni("div",Pa),Ni("mod",Ba),Ni("equal",Da),Ni("notEqual",Ua),Ni("lessThan",Ia),Ni("greaterThan",Oa),Ni("lessThanEqual",Va),Ni("greaterThanEqual",ka),Ni("and",Ga),Ni("or",za),Ni("not",$a),Ni("xor",Wa),Ni("bitAnd",Ha),Ni("bitNot",qa),Ni("bitOr",ja),Ni("bitXor",Xa),Ni("shiftLeft",Ka),Ni("shiftRight",Ya),Ni("incrementBefore",Qa),Ni("decrementBefore",Za),Ni("increment",Ja),Ni("decrement",eo);const to=(e,t)=>(d('TSL: "modInt()" is deprecated. Use "mod( int( ... ) )" instead.'),Ba(mn(e),mn(t)));Ni("modInt",to);class ro extends ci{static get type(){return"MathNode"}constructor(e,t,r=null,s=null){if(super(),(e===ro.MAX||e===ro.MIN)&&arguments.length>3){let i=new ro(e,t,r);for(let t=2;tn&&i>a?t:n>a?r:a>i?s:t}getNodeType(e){const t=this.method;return t===ro.LENGTH||t===ro.DISTANCE||t===ro.DOT?"float":t===ro.CROSS?"vec3":t===ro.ALL||t===ro.ANY?"bool":t===ro.EQUALS?e.changeComponentType(this.aNode.getNodeType(e),"bool"):this.getInputType(e)}setup(e){const{aNode:t,bNode:r,method:s}=this;let i=null;if(s===ro.ONE_MINUS)i=Fa(1,t);else if(s===ro.RECIPROCAL)i=Pa(1,t);else if(s===ro.DIFFERENCE)i=Mo(Fa(t,r));else if(s===ro.TRANSFORM_DIRECTION){let s=t,n=r;e.isMatrix(s.getNodeType(e))?n=En(vn(n),0):s=En(vn(s),0);const a=La(s,n).xyz;i=vo(a)}return null!==i?i:super.setup(e)}generate(e,t){if(e.getNodeProperties(this).outputNode)return super.generate(e,t);let r=this.method;const s=this.getNodeType(e),i=this.getInputType(e),n=this.aNode,a=this.bNode,o=this.cNode,u=e.renderer.coordinateSystem;if(r===ro.NEGATE)return e.format("( - "+n.build(e,i)+" )",s,t);{const l=[];return r===ro.CROSS?l.push(n.build(e,s),a.build(e,s)):u===c&&r===ro.STEP?l.push(n.build(e,1===e.getTypeLength(n.getNodeType(e))?"float":i),a.build(e,i)):u!==c||r!==ro.MIN&&r!==ro.MAX?r===ro.REFRACT?l.push(n.build(e,i),a.build(e,i),o.build(e,"float")):r===ro.MIX?l.push(n.build(e,i),a.build(e,i),o.build(e,1===e.getTypeLength(o.getNodeType(e))?"float":i)):(u===h&&r===ro.ATAN&&null!==a&&(r="atan2"),"fragment"===e.shaderStage||r!==ro.DFDX&&r!==ro.DFDY||(d(`TSL: '${r}' is not supported in the ${e.shaderStage} stage.`),r="/*"+r+"*/"),l.push(n.build(e,i)),null!==a&&l.push(a.build(e,i)),null!==o&&l.push(o.build(e,i))):l.push(n.build(e,i),a.build(e,1===e.getTypeLength(a.getNodeType(e))?"float":i)),e.format(`${e.getMethod(r,s)}( ${l.join(", ")} )`,s,t)}}serialize(e){super.serialize(e),e.method=this.method}deserialize(e){super.deserialize(e),this.method=e.method}}ro.ALL="all",ro.ANY="any",ro.RADIANS="radians",ro.DEGREES="degrees",ro.EXP="exp",ro.EXP2="exp2",ro.LOG="log",ro.LOG2="log2",ro.SQRT="sqrt",ro.INVERSE_SQRT="inversesqrt",ro.FLOOR="floor",ro.CEIL="ceil",ro.NORMALIZE="normalize",ro.FRACT="fract",ro.SIN="sin",ro.COS="cos",ro.TAN="tan",ro.ASIN="asin",ro.ACOS="acos",ro.ATAN="atan",ro.ABS="abs",ro.SIGN="sign",ro.LENGTH="length",ro.NEGATE="negate",ro.ONE_MINUS="oneMinus",ro.DFDX="dFdx",ro.DFDY="dFdy",ro.ROUND="round",ro.RECIPROCAL="reciprocal",ro.TRUNC="trunc",ro.FWIDTH="fwidth",ro.TRANSPOSE="transpose",ro.DETERMINANT="determinant",ro.INVERSE="inverse",ro.EQUALS="equals",ro.MIN="min",ro.MAX="max",ro.STEP="step",ro.REFLECT="reflect",ro.DISTANCE="distance",ro.DIFFERENCE="difference",ro.DOT="dot",ro.CROSS="cross",ro.POW="pow",ro.TRANSFORM_DIRECTION="transformDirection",ro.MIX="mix",ro.CLAMP="clamp",ro.REFRACT="refract",ro.SMOOTHSTEP="smoothstep",ro.FACEFORWARD="faceforward";const so=gn(1e-6),io=gn(1e6),no=gn(Math.PI),ao=gn(2*Math.PI),oo=gn(2*Math.PI),uo=gn(.5*Math.PI),lo=nn(ro,ro.ALL).setParameterLength(1),co=nn(ro,ro.ANY).setParameterLength(1),ho=nn(ro,ro.RADIANS).setParameterLength(1),po=nn(ro,ro.DEGREES).setParameterLength(1),go=nn(ro,ro.EXP).setParameterLength(1),mo=nn(ro,ro.EXP2).setParameterLength(1),fo=nn(ro,ro.LOG).setParameterLength(1),yo=nn(ro,ro.LOG2).setParameterLength(1),bo=nn(ro,ro.SQRT).setParameterLength(1),xo=nn(ro,ro.INVERSE_SQRT).setParameterLength(1),To=nn(ro,ro.FLOOR).setParameterLength(1),_o=nn(ro,ro.CEIL).setParameterLength(1),vo=nn(ro,ro.NORMALIZE).setParameterLength(1),No=nn(ro,ro.FRACT).setParameterLength(1),So=nn(ro,ro.SIN).setParameterLength(1),Ro=nn(ro,ro.COS).setParameterLength(1),Eo=nn(ro,ro.TAN).setParameterLength(1),Ao=nn(ro,ro.ASIN).setParameterLength(1),wo=nn(ro,ro.ACOS).setParameterLength(1),Co=nn(ro,ro.ATAN).setParameterLength(1,2),Mo=nn(ro,ro.ABS).setParameterLength(1),Fo=nn(ro,ro.SIGN).setParameterLength(1),Lo=nn(ro,ro.LENGTH).setParameterLength(1),Po=nn(ro,ro.NEGATE).setParameterLength(1),Bo=nn(ro,ro.ONE_MINUS).setParameterLength(1),Do=nn(ro,ro.DFDX).setParameterLength(1),Uo=nn(ro,ro.DFDY).setParameterLength(1),Io=nn(ro,ro.ROUND).setParameterLength(1),Oo=nn(ro,ro.RECIPROCAL).setParameterLength(1),Vo=nn(ro,ro.TRUNC).setParameterLength(1),ko=nn(ro,ro.FWIDTH).setParameterLength(1),Go=nn(ro,ro.TRANSPOSE).setParameterLength(1),zo=nn(ro,ro.DETERMINANT).setParameterLength(1),$o=nn(ro,ro.INVERSE).setParameterLength(1),Wo=nn(ro,ro.MIN).setParameterLength(2,1/0),Ho=nn(ro,ro.MAX).setParameterLength(2,1/0),qo=nn(ro,ro.STEP).setParameterLength(2),jo=nn(ro,ro.REFLECT).setParameterLength(2),Xo=nn(ro,ro.DISTANCE).setParameterLength(2),Ko=nn(ro,ro.DIFFERENCE).setParameterLength(2),Yo=nn(ro,ro.DOT).setParameterLength(2),Qo=nn(ro,ro.CROSS).setParameterLength(2),Zo=nn(ro,ro.POW).setParameterLength(2),Jo=e=>La(e,e),eu=e=>La(e,e,e),tu=e=>La(e,e,e,e),ru=nn(ro,ro.TRANSFORM_DIRECTION).setParameterLength(2),su=e=>La(Fo(e),Zo(Mo(e),1/3)),iu=e=>Yo(e,e),nu=nn(ro,ro.MIX).setParameterLength(3),au=(e,t=0,r=1)=>Zi(new ro(ro.CLAMP,Zi(e),Zi(t),Zi(r))),ou=e=>au(e),uu=nn(ro,ro.REFRACT).setParameterLength(3),lu=nn(ro,ro.SMOOTHSTEP).setParameterLength(3),du=nn(ro,ro.FACEFORWARD).setParameterLength(3),cu=un(([e])=>{const t=Yo(e.xy,bn(12.9898,78.233)),r=Ba(t,no);return No(So(r).mul(43758.5453))}),hu=(e,t,r)=>nu(t,r,e),pu=(e,t,r)=>lu(t,r,e),gu=(e,t)=>qo(t,e),mu=du,fu=xo;Ni("all",lo),Ni("any",co),Ni("radians",ho),Ni("degrees",po),Ni("exp",go),Ni("exp2",mo),Ni("log",fo),Ni("log2",yo),Ni("sqrt",bo),Ni("inverseSqrt",xo),Ni("floor",To),Ni("ceil",_o),Ni("normalize",vo),Ni("fract",No),Ni("sin",So),Ni("cos",Ro),Ni("tan",Eo),Ni("asin",Ao),Ni("acos",wo),Ni("atan",Co),Ni("abs",Mo),Ni("sign",Fo),Ni("length",Lo),Ni("lengthSq",iu),Ni("negate",Po),Ni("oneMinus",Bo),Ni("dFdx",Do),Ni("dFdy",Uo),Ni("round",Io),Ni("reciprocal",Oo),Ni("trunc",Vo),Ni("fwidth",ko),Ni("min",Wo),Ni("max",Ho),Ni("step",gu),Ni("reflect",jo),Ni("distance",Xo),Ni("dot",Yo),Ni("cross",Qo),Ni("pow",Zo),Ni("pow2",Jo),Ni("pow3",eu),Ni("pow4",tu),Ni("transformDirection",ru),Ni("mix",hu),Ni("clamp",au),Ni("refract",uu),Ni("smoothstep",pu),Ni("faceForward",du),Ni("difference",Ko),Ni("saturate",ou),Ni("cbrt",su),Ni("transpose",Go),Ni("determinant",zo),Ni("inverse",$o),Ni("rand",cu);class yu extends ui{static get type(){return"ConditionalNode"}constructor(e,t,r=null){super(),this.condNode=e,this.ifNode=t,this.elseNode=r}getNodeType(e){const{ifNode:t,elseNode:r}=e.getNodeProperties(this);if(void 0===t)return e.flowBuildStage(this,"setup"),this.getNodeType(e);const s=t.getNodeType(e);if(null!==r){const t=r.getNodeType(e);if(e.getTypeLength(t)>e.getTypeLength(s))return t}return s}setup(e){const t=this.condNode,r=this.ifNode.isolate(),s=this.elseNode?this.elseNode.isolate():null,i=e.context.nodeBlock;e.getDataFromNode(r).parentNodeBlock=i,null!==s&&(e.getDataFromNode(s).parentNodeBlock=i);const n=e.context.uniformFlow,a=e.getNodeProperties(this);a.condNode=t,a.ifNode=n?r:r.context({nodeBlock:r}),a.elseNode=s?n?s:s.context({nodeBlock:s}):null}generate(e,t){const r=this.getNodeType(e),s=e.getDataFromNode(this);if(void 0!==s.nodeProperty)return s.nodeProperty;const{condNode:i,ifNode:n,elseNode:a}=e.getNodeProperties(this),o=e.currentFunctionNode,u="void"!==t,l=u?Un(r).build(e):"";s.nodeProperty=l;const c=i.build(e,"bool");if(e.context.uniformFlow&&null!==a){const s=n.build(e,r),i=a.build(e,r),o=e.getTernary(c,s,i);return e.format(o,r,t)}e.addFlowCode(`\n${e.tab}if ( ${c} ) {\n\n`).addFlowTab();let h=n.build(e,r);if(h&&(u?h=l+" = "+h+";":(h="return "+h+";",null===o&&(d("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values."),h="// "+h))),e.removeFlowTab().addFlowCode(e.tab+"\t"+h+"\n\n"+e.tab+"}"),null!==a){e.addFlowCode(" else {\n\n").addFlowTab();let t=a.build(e,r);t&&(u?t=l+" = "+t+";":(t="return "+t+";",null===o&&(d("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values."),t="// "+t))),e.removeFlowTab().addFlowCode(e.tab+"\t"+t+"\n\n"+e.tab+"}\n\n")}else e.addFlowCode("\n\n");return e.format(l,r,t)}}const bu=rn(yu).setParameterLength(2,3);Ni("select",bu);class xu extends ui{static get type(){return"ContextNode"}constructor(e=null,t={}){super(),this.isContextNode=!0,this.node=e,this.value=t}getScope(){return this.node.getScope()}getNodeType(e){return this.node.getNodeType(e)}getFlowContextData(){const e=[];return this.traverse(t=>{!0===t.isContextNode&&e.push(t.value)}),Object.assign({},...e)}getMemberType(e,t){return this.node.getMemberType(e,t)}analyze(e){const t=e.addContext(this.value);this.node.build(e),e.setContext(t)}setup(e){const t=e.addContext(this.value);this.node.build(e),e.setContext(t)}generate(e,t){const r=e.addContext(this.value),s=this.node.build(e,t);return e.setContext(r),s}}const Tu=(e=null,t={})=>{let r=e;return null!==r&&!0===r.isNode||(t=r||t,r=null),new xu(r,t)},_u=e=>Tu(e,{uniformFlow:!0}),vu=(e,t)=>Tu(e,{nodeName:t});function Nu(e,t,r=null){return Tu(r,{getShadow:({light:r,shadowColorNode:s})=>t===r?s.mul(e):s})}function Su(e,t=null){return Tu(t,{getAO:(t,{material:r})=>!0===r.transparent?t:null!==t?t.mul(e):e})}function Ru(e,t){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),vu(e,t)}Ni("context",Tu),Ni("label",Ru),Ni("uniformFlow",_u),Ni("setName",vu),Ni("builtinShadowContext",(e,t,r)=>Nu(t,r,e)),Ni("builtinAOContext",(e,t)=>Su(t,e));class Eu extends ui{static get type(){return"VarNode"}constructor(e,t=null,r=!1){super(),this.node=e,this.name=t,this.global=!0,this.isVarNode=!0,this.readOnly=r,this.parents=!0,this.intent=!1}setIntent(e){return this.intent=e,this}isIntent(e){return!0!==e.getDataFromNode(this).forceDeclaration&&this.intent}getIntent(){return this.intent}getMemberType(e,t){return this.node.getMemberType(e,t)}getElementType(e){return this.node.getElementType(e)}getNodeType(e){return this.node.getNodeType(e)}getArrayCount(e){return this.node.getArrayCount(e)}isAssign(e){return e.getDataFromNode(this).assign}build(...e){const t=e[0];if(!1===this._hasStack(t)&&"setup"===t.buildStage&&(t.context.nodeLoop||t.context.nodeBlock)){let e=!1;if(this.node.isShaderCallNodeInternal&&null===this.node.shaderNode.getLayout()&&t.fnCall&&t.fnCall.shaderNode){if(t.getDataFromNode(this.node.shaderNode).hasLoop){t.getDataFromNode(this).forceDeclaration=!0,e=!0}}const r=t.getBaseStack();e?r.addToStackBefore(this):r.addToStack(this)}return this.isIntent(t)&&!0!==this.isAssign(t)?this.node.build(...e):super.build(...e)}generate(e){const{node:t,name:r,readOnly:s}=this,{renderer:i}=e,n=!0===i.backend.isWebGPUBackend;let a=!1,u=!1;s&&(a=e.isDeterministic(t),u=n?s:a);const l=this.getNodeType(e);if("void"==l){!0!==this.isIntent(e)&&o('TSL: ".toVar()" can not be used with void type.');return t.build(e)}const d=e.getVectorType(l),c=t.build(e,d),h=e.getVarFromNode(this,r,d,void 0,u),p=e.getPropertyName(h);let g=p;if(u)if(n)g=a?`const ${p}`:`let ${p}`;else{const r=t.getArrayCount(e);g=`const ${e.getVar(h.type,p,r)}`}return e.addLineFlowCode(`${g} = ${c}`,this),p}_hasStack(e){return void 0!==e.getDataFromNode(this).stack}}const Au=rn(Eu),wu=(e,t=null)=>Au(e,t).toStack(),Cu=(e,t=null)=>Au(e,t,!0).toStack(),Mu=e=>Au(e).setIntent(!0).toStack();Ni("toVar",wu),Ni("toConst",Cu),Ni("toVarIntent",Mu);class Fu extends ui{static get type(){return"SubBuild"}constructor(e,t,r=null){super(r),this.node=e,this.name=t,this.isSubBuildNode=!0}getNodeType(e){if(null!==this.nodeType)return this.nodeType;e.addSubBuild(this.name);const t=this.node.getNodeType(e);return e.removeSubBuild(),t}build(e,...t){e.addSubBuild(this.name);const r=this.node.build(e,...t);return e.removeSubBuild(),r}}const Lu=(e,t,r=null)=>Zi(new Fu(Zi(e),t,r));class Pu extends ui{static get type(){return"VaryingNode"}constructor(e,t=null){super(),this.node=Lu(e,"VERTEX"),this.name=t,this.isVaryingNode=!0,this.interpolationType=null,this.interpolationSampling=null,this.global=!0}setInterpolation(e,t=null){return this.interpolationType=e,this.interpolationSampling=t,this}getHash(e){return this.name||super.getHash(e)}getNodeType(e){return this.node.getNodeType(e)}setupVarying(e){const t=e.getNodeProperties(this);let r=t.varying;if(void 0===r){const s=this.name,i=this.getNodeType(e),n=this.interpolationType,a=this.interpolationSampling;t.varying=r=e.getVaryingFromNode(this,s,i,n,a),t.node=Lu(this.node,"VERTEX")}return r.needsInterpolation||(r.needsInterpolation="fragment"===e.shaderStage),r}setup(e){this.setupVarying(e),e.flowNodeFromShaderStage(Zs.VERTEX,this.node)}analyze(e){this.setupVarying(e),e.flowNodeFromShaderStage(Zs.VERTEX,this.node)}generate(e){const t=e.getSubBuildProperty("property",e.currentStack),r=e.getNodeProperties(this),s=this.setupVarying(e);if(void 0===r[t]){const i=this.getNodeType(e),n=e.getPropertyName(s,Zs.VERTEX);e.flowNodeFromShaderStage(Zs.VERTEX,r.node,i,n),r[t]=n}return e.getPropertyName(s)}}const Bu=rn(Pu).setParameterLength(1,2),Du=e=>Bu(e);Ni("toVarying",Bu),Ni("toVertexStage",Du);const Uu=un(([e])=>{const t=e.mul(.9478672986).add(.0521327014).pow(2.4),r=e.mul(.0773993808),s=e.lessThanEqual(.04045);return nu(t,r,s)}).setLayout({name:"sRGBTransferEOTF",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Iu=un(([e])=>{const t=e.pow(.41666).mul(1.055).sub(.055),r=e.mul(12.92),s=e.lessThanEqual(.0031308);return nu(t,r,s)}).setLayout({name:"sRGBTransferOETF",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Ou="WorkingColorSpace";class Vu extends ci{static get type(){return"ColorSpaceNode"}constructor(e,t,r){super("vec4"),this.colorNode=e,this.source=t,this.target=r}resolveColorSpace(e,t){return t===Ou?p.workingColorSpace:"OutputColorSpace"===t?e.context.outputColorSpace||e.renderer.outputColorSpace:t}setup(e){const{colorNode:t}=this,r=this.resolveColorSpace(e,this.source),s=this.resolveColorSpace(e,this.target);let i=t;return!1!==p.enabled&&r!==s&&r&&s?(p.getTransfer(r)===g&&(i=En(Uu(i.rgb),i.a)),p.getPrimaries(r)!==p.getPrimaries(s)&&(i=En(Fn(p._getMatrix(new n,r,s)).mul(i.rgb),i.a)),p.getTransfer(s)===g&&(i=En(Iu(i.rgb),i.a)),i):i}}const ku=(e,t)=>Zi(new Vu(Zi(e),Ou,t)),Gu=(e,t)=>Zi(new Vu(Zi(e),t,Ou));Ni("workingToColorSpace",ku),Ni("colorSpaceToWorking",Gu);let zu=class extends li{static get type(){return"ReferenceElementNode"}constructor(e,t){super(e,t),this.referenceNode=e,this.isReferenceElementNode=!0}getNodeType(){return this.referenceNode.uniformType}generate(e){const t=super.generate(e),r=this.referenceNode.getNodeType(),s=this.getNodeType();return e.format(t,r,s)}};class $u extends ui{static get type(){return"ReferenceBaseNode"}constructor(e,t,r=null,s=null){super(),this.property=e,this.uniformType=t,this.object=r,this.count=s,this.properties=e.split("."),this.reference=r,this.node=null,this.group=null,this.updateType=Js.OBJECT}setGroup(e){return this.group=e,this}element(e){return new zu(this,Zi(e))}setNodeType(e){const t=_a(null,e);null!==this.group&&t.setGroup(this.group),this.node=t}getNodeType(e){return null===this.node&&(this.updateReference(e),this.updateValue()),this.node.getNodeType(e)}getValueFromReference(e=this.reference){const{properties:t}=this;let r=e[t[0]];for(let e=1;enew Wu(e,t,r);class qu extends ci{static get type(){return"ToneMappingNode"}constructor(e,t=Xu,r=null){super("vec3"),this._toneMapping=e,this.exposureNode=t,this.colorNode=r}customCacheKey(){return Os(this._toneMapping)}setToneMapping(e){return this._toneMapping=e,this}getToneMapping(){return this._toneMapping}setup(e){const t=this.colorNode||e.context.color,r=this._toneMapping;if(r===m)return t;let s=null;const i=e.renderer.library.getToneMappingFunction(r);return null!==i?s=En(i(t.rgb,this.exposureNode),t.a):(o("ToneMappingNode: Unsupported Tone Mapping configuration.",r),s=t),s}}const ju=(e,t,r)=>Zi(new qu(e,Zi(t),Zi(r))),Xu=Hu("toneMappingExposure","float");Ni("toneMapping",(e,t,r)=>ju(t,r,e));const Ku=new WeakMap;function Yu(e,t){let r=Ku.get(e);return void 0===r&&(r=new b(e,t),Ku.set(e,r)),r}class Qu extends yi{static get type(){return"BufferAttributeNode"}constructor(e,t=null,r=0,s=0){super(e,t),this.isBufferNode=!0,this.bufferType=t,this.bufferStride=r,this.bufferOffset=s,this.usage=f,this.instanced=!1,this.attribute=null,this.global=!0,e&&!0===e.isBufferAttribute&&e.itemSize<=4&&(this.attribute=e,this.usage=e.usage,this.instanced=e.isInstancedBufferAttribute)}getHash(e){if(0===this.bufferStride&&0===this.bufferOffset){let t=e.globalCache.getData(this.value);return void 0===t&&(t={node:this},e.globalCache.setData(this.value,t)),t.node.uuid}return this.uuid}getNodeType(e){return null===this.bufferType&&(this.bufferType=e.getTypeFromAttribute(this.attribute)),this.bufferType}setup(e){if(null!==this.attribute)return;const t=this.getNodeType(e),r=e.getTypeLength(t),s=this.value,i=this.bufferStride||r,n=this.bufferOffset;let a;a=!0===s.isInterleavedBuffer?s:!0===s.isBufferAttribute?Yu(s.array,i):Yu(s,i);const o=new y(a,r,n);a.setUsage(this.usage),this.attribute=o,this.attribute.isInstancedBufferAttribute=this.instanced}generate(e){const t=this.getNodeType(e),r=e.getBufferAttributeFromNode(this,t),s=e.getPropertyName(r);let i=null;if("vertex"===e.shaderStage||"compute"===e.shaderStage)this.name=s,i=s;else{i=Bu(this).build(e,t)}return i}getInputType(){return"bufferAttribute"}setUsage(e){return this.usage=e,this.attribute&&!0===this.attribute.isBufferAttribute&&(this.attribute.usage=e),this}setInstanced(e){return this.instanced=e,this}}function Zu(e,t=null,r=0,s=0,i=f,n=!1){return"mat3"===t||null===t&&9===e.itemSize?Fn(new Qu(e,"vec3",9,0).setUsage(i).setInstanced(n),new Qu(e,"vec3",9,3).setUsage(i).setInstanced(n),new Qu(e,"vec3",9,6).setUsage(i).setInstanced(n)):"mat4"===t||null===t&&16===e.itemSize?Ln(new Qu(e,"vec4",16,0).setUsage(i).setInstanced(n),new Qu(e,"vec4",16,4).setUsage(i).setInstanced(n),new Qu(e,"vec4",16,8).setUsage(i).setInstanced(n),new Qu(e,"vec4",16,12).setUsage(i).setInstanced(n)):new Qu(e,t,r,s).setUsage(i)}const Ju=(e,t=null,r=0,s=0)=>Zu(e,t,r,s),el=(e,t=null,r=0,s=0)=>Zu(e,t,r,s,f,!0),tl=(e,t=null,r=0,s=0)=>Zu(e,t,r,s,x,!0);Ni("toAttribute",e=>Ju(e.value));class rl extends ui{static get type(){return"ComputeNode"}constructor(e,t){super("void"),this.isComputeNode=!0,this.computeNode=e,this.workgroupSize=t,this.count=null,this.version=1,this.name="",this.updateBeforeType=Js.OBJECT,this.onInitFunction=null}setCount(e){return this.count=e,this}getCount(){return this.count}dispose(){this.dispatchEvent({type:"dispose"})}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}onInit(e){return this.onInitFunction=e,this}updateBefore({renderer:e}){e.compute(this)}setup(e){const t=this.computeNode.build(e);if(t){e.getNodeProperties(this).outputComputeNode=t.outputNode,t.outputNode=null}return t}generate(e,t){const{shaderStage:r}=e;if("compute"===r){const t=this.computeNode.build(e,"void");""!==t&&e.addLineFlowCode(t,this)}else{const r=e.getNodeProperties(this).outputComputeNode;if(r)return r.build(e,t)}}}const sl=(e,t=[64])=>{(0===t.length||t.length>3)&&o("TSL: compute() workgroupSize must have 1, 2, or 3 elements");for(let e=0;esl(e,r).setCount(t);Ni("compute",il),Ni("computeKernel",sl);class nl extends ui{static get type(){return"IsolateNode"}constructor(e,t=!0){super(),this.node=e,this.parent=t,this.isIsolateNode=!0}getNodeType(e){const t=e.getCache(),r=e.getCacheFromNode(this,this.parent);e.setCache(r);const s=this.node.getNodeType(e);return e.setCache(t),s}build(e,...t){const r=e.getCache(),s=e.getCacheFromNode(this,this.parent);e.setCache(s);const i=this.node.build(e,...t);return e.setCache(r),i}setParent(e){return this.parent=e,this}getParent(){return this.parent}}const al=e=>new nl(Zi(e));function ol(e,t=!0){return d('TSL: "cache()" has been deprecated. Use "isolate()" instead.'),al(e).setParent(t)}Ni("cache",ol),Ni("isolate",al);class ul extends ui{static get type(){return"BypassNode"}constructor(e,t){super(),this.isBypassNode=!0,this.outputNode=e,this.callNode=t}getNodeType(e){return this.outputNode.getNodeType(e)}generate(e){const t=this.callNode.build(e,"void");return""!==t&&e.addLineFlowCode(t,this),this.outputNode.build(e)}}const ll=rn(ul).setParameterLength(2);Ni("bypass",ll);class dl extends ui{static get type(){return"RemapNode"}constructor(e,t,r,s=gn(0),i=gn(1)){super(),this.node=e,this.inLowNode=t,this.inHighNode=r,this.outLowNode=s,this.outHighNode=i,this.doClamp=!0}setup(){const{node:e,inLowNode:t,inHighNode:r,outLowNode:s,outHighNode:i,doClamp:n}=this;let a=e.sub(t).div(r.sub(t));return!0===n&&(a=a.clamp()),a.mul(i.sub(s)).add(s)}}const cl=rn(dl,null,null,{doClamp:!1}).setParameterLength(3,5),hl=rn(dl).setParameterLength(3,5);Ni("remap",cl),Ni("remapClamp",hl);class pl extends ui{static get type(){return"ExpressionNode"}constructor(e="",t="void"){super(t),this.snippet=e}generate(e,t){const r=this.getNodeType(e),s=this.snippet;if("void"!==r)return e.format(s,r,t);e.addLineFlowCode(s,this)}}const gl=rn(pl).setParameterLength(1,2),ml=e=>(e?bu(e,gl("discard")):gl("discard")).toStack();Ni("discard",ml);class fl extends ci{static get type(){return"RenderOutputNode"}constructor(e,t,r){super("vec4"),this.colorNode=e,this._toneMapping=t,this.outputColorSpace=r,this.isRenderOutputNode=!0}setToneMapping(e){return this._toneMapping=e,this}getToneMapping(){return this._toneMapping}setup({context:e}){let t=this.colorNode||e.color;const r=(null!==this._toneMapping?this._toneMapping:e.toneMapping)||m,s=(null!==this.outputColorSpace?this.outputColorSpace:e.outputColorSpace)||T;return r!==m&&(t=t.toneMapping(r)),s!==T&&s!==p.workingColorSpace&&(t=t.workingToColorSpace(s)),t}}const yl=(e,t=null,r=null)=>Zi(new fl(Zi(e),t,r));Ni("renderOutput",yl);class bl extends ci{static get type(){return"DebugNode"}constructor(e,t=null){super(),this.node=e,this.callback=t}getNodeType(e){return this.node.getNodeType(e)}setup(e){return this.node.build(e)}analyze(e){return this.node.build(e)}generate(e){const t=this.callback,r=this.node.build(e);if(null!==t)t(e,r);else{const t="--- TSL debug - "+e.shaderStage+" shader ---",s="-".repeat(t.length);let i="";i+="// #"+t+"#\n",i+=e.flow.code.replace(/^\t/gm,"")+"\n",i+="/* ... */ "+r+" /* ... */\n",i+="// #"+s+"#\n",_(i)}return r}}const xl=(e,t=null)=>Zi(new bl(Zi(e),t)).toStack();Ni("debug",xl);class Tl{constructor(){this._renderer=null,this.currentFrame=null}get nodeFrame(){return this._renderer._nodes.nodeFrame}setRenderer(e){return this._renderer=e,this}getRenderer(){return this._renderer}init(){}begin(){}finish(){}inspect(){}computeAsync(){}beginCompute(){}finishCompute(){}beginRender(){}finishRender(){}copyTextureToTexture(){}copyFramebufferToTexture(){}}class _l extends ui{static get type(){return"InspectorNode"}constructor(e,t="",r=null){super(),this.node=e,this.name=t,this.callback=r,this.updateType=Js.FRAME,this.isInspectorNode=!0}getName(){return this.name||this.node.name}update(e){e.renderer.inspector.inspect(this)}getNodeType(e){return this.node.getNodeType(e)}setup(e){let t=this.node;return!0===e.context.inspector&&null!==this.callback&&(t=this.callback(t)),!0!==e.renderer.backend.isWebGPUBackend&&e.renderer.inspector.constructor!==Tl&&v('TSL: ".toInspector()" is only available with WebGPU.'),t}}function vl(e,t="",r=null){return(e=Zi(e)).before(new _l(e,t,r))}Ni("toInspector",vl);class Nl extends ui{static get type(){return"AttributeNode"}constructor(e,t=null){super(t),this.global=!0,this._attributeName=e}getHash(e){return this.getAttributeName(e)}getNodeType(e){let t=this.nodeType;if(null===t){const r=this.getAttributeName(e);if(e.hasGeometryAttribute(r)){const s=e.geometry.getAttribute(r);t=e.getTypeFromAttribute(s)}else t="float"}return t}setAttributeName(e){return this._attributeName=e,this}getAttributeName(){return this._attributeName}generate(e){const t=this.getAttributeName(e),r=this.getNodeType(e);if(!0===e.hasGeometryAttribute(t)){const s=e.geometry.getAttribute(t),i=e.getTypeFromAttribute(s),n=e.getAttribute(t,i);if("vertex"===e.shaderStage)return e.format(n.name,i,r);return Bu(this).build(e,r)}return d(`AttributeNode: Vertex attribute "${t}" not found on geometry.`),e.generateConst(r)}serialize(e){super.serialize(e),e.global=this.global,e._attributeName=this._attributeName}deserialize(e){super.deserialize(e),this.global=e.global,this._attributeName=e._attributeName}}const Sl=(e,t=null)=>new Nl(e,t),Rl=(e=0)=>Sl("uv"+(e>0?e:""),"vec2");class El extends ui{static get type(){return"TextureSizeNode"}constructor(e,t=null){super("uvec2"),this.isTextureSizeNode=!0,this.textureNode=e,this.levelNode=t}generate(e,t){const r=this.textureNode.build(e,"property"),s=null===this.levelNode?"0":this.levelNode.build(e,"int");return e.format(`${e.getMethod("textureDimensions")}( ${r}, ${s} )`,this.getNodeType(e),t)}}const Al=rn(El).setParameterLength(1,2);class wl extends Ta{static get type(){return"MaxMipLevelNode"}constructor(e){super(0),this._textureNode=e,this.updateType=Js.FRAME}get textureNode(){return this._textureNode}get texture(){return this._textureNode.value}update(){const e=this.texture,t=e.images,r=t&&t.length>0?t[0]&&t[0].image||t[0]:e.image;if(r&&void 0!==r.width){const{width:e,height:t}=r;this.value=Math.log2(Math.max(e,t))}}}const Cl=rn(wl).setParameterLength(1),Ml=new N;class Fl extends Ta{static get type(){return"TextureNode"}constructor(e=Ml,t=null,r=null,s=null){super(e),this.isTextureNode=!0,this.uvNode=t,this.levelNode=r,this.biasNode=s,this.compareNode=null,this.depthNode=null,this.gradNode=null,this.offsetNode=null,this.sampler=!0,this.updateMatrix=!1,this.updateType=Js.NONE,this.referenceNode=null,this._value=e,this._matrixUniform=null,this._flipYUniform=null,this.setUpdateMatrix(null===t)}set value(e){this.referenceNode?this.referenceNode.value=e:this._value=e}get value(){return this.referenceNode?this.referenceNode.value:this._value}getUniformHash(){return this.value.uuid}getNodeType(){return!0===this.value.isDepthTexture?"float":this.value.type===S?"uvec4":this.value.type===R?"ivec4":"vec4"}getInputType(){return"texture"}getDefaultUV(){return Rl(this.value.channel)}updateReference(){return this.value}getTransformedUV(e){return null===this._matrixUniform&&(this._matrixUniform=_a(this.value.matrix)),this._matrixUniform.mul(vn(e,1)).xy}setUpdateMatrix(e){return this.updateMatrix=e,this}setupUV(e,t){return e.isFlipY()&&(null===this._flipYUniform&&(this._flipYUniform=_a(!1)),t=t.toVar(),t=this.sampler?this._flipYUniform.select(t.flipY(),t):this._flipYUniform.select(t.setY(mn(Al(this,this.levelNode).y).sub(t.y).sub(1)),t)),t}setup(e){const t=e.getNodeProperties(this);t.referenceNode=this.referenceNode;const r=this.value;if(!r||!0!==r.isTexture)throw new Error("THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().");const s=un(()=>{let t=this.uvNode;return null!==t&&!0!==e.context.forceUVContext||!e.context.getUV||(t=e.context.getUV(this,e)),t||(t=this.getDefaultUV()),!0===this.updateMatrix&&(t=this.getTransformedUV(t)),t=this.setupUV(e,t),this.updateType=null!==this._matrixUniform||null!==this._flipYUniform?Js.OBJECT:Js.NONE,t})();let i=this.levelNode;null===i&&e.context.getTextureLevel&&(i=e.context.getTextureLevel(this));let n=null,a=null;null!==this.compareNode&&(e.renderer.hasCompatibility(E.TEXTURE_COMPARE)?n=this.compareNode:(null!==this.value.compareFunction&&this.value.compareFunction!==A&&v('TSL: Only "LessCompare" is supported for depth texture comparison fallback.'),a=this.compareNode)),t.uvNode=s,t.levelNode=i,t.biasNode=this.biasNode,t.compareNode=n,t.compareStepNode=a,t.gradNode=this.gradNode,t.depthNode=this.depthNode,t.offsetNode=this.offsetNode}generateUV(e,t){return t.build(e,!0===this.sampler?"vec2":"ivec2")}generateOffset(e,t){return t.build(e,"ivec2")}generateSnippet(e,t,r,s,i,n,a,o,u){const l=this.value;let d;return d=i?e.generateTextureBias(l,t,r,i,n,u):o?e.generateTextureGrad(l,t,r,o,n,u):a?e.generateTextureCompare(l,t,r,a,n,u):!1===this.sampler?e.generateTextureLoad(l,t,r,s,n,u):s?e.generateTextureLevel(l,t,r,s,n,u):e.generateTexture(l,t,r,n,u),d}generate(e,t){const r=this.value,s=e.getNodeProperties(this),i=super.generate(e,"property");if(/^sampler/.test(t))return i+"_sampler";if(e.isReference(t))return i;{const n=e.getDataFromNode(this),a=this.getNodeType(e);let o=n.propertyName;if(void 0===o){const{uvNode:t,levelNode:r,biasNode:u,compareNode:l,compareStepNode:d,depthNode:c,gradNode:h,offsetNode:p}=s,g=this.generateUV(e,t),m=r?r.build(e,"float"):null,f=u?u.build(e,"float"):null,y=c?c.build(e,"int"):null,b=l?l.build(e,"float"):null,x=d?d.build(e,"float"):null,T=h?[h[0].build(e,"vec2"),h[1].build(e,"vec2")]:null,_=p?this.generateOffset(e,p):null,v=e.getVarFromNode(this);o=e.getPropertyName(v);let N=this.generateSnippet(e,i,g,m,f,y,b,T,_);null!==x&&(N=qo(gl(x,"float"),gl(N,a)).build(e,a)),e.addLineFlowCode(`${o} = ${N}`,this),n.snippet=N,n.propertyName=o}let u=o;return e.needsToWorkingColorSpace(r)&&(u=Gu(gl(u,a),r.colorSpace).setup(e).build(e,a)),e.format(u,a,t)}}setSampler(e){return this.sampler=e,this}getSampler(){return this.sampler}sample(e){const t=this.clone();return t.uvNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}load(e){return this.sample(e).setSampler(!1)}blur(e){const t=this.clone();t.biasNode=Zi(e).mul(Cl(t)),t.referenceNode=this.getBase();const r=t.value;return!1===t.generateMipmaps&&(r&&!1===r.generateMipmaps||r.minFilter===w||r.magFilter===w)&&(d("TSL: texture().blur() requires mipmaps and sampling. Use .generateMipmaps=true and .minFilter/.magFilter=THREE.LinearFilter in the Texture."),t.biasNode=null),Zi(t)}level(e){const t=this.clone();return t.levelNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}size(e){return Al(this,e)}bias(e){const t=this.clone();return t.biasNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}getBase(){return this.referenceNode?this.referenceNode.getBase():this}compare(e){const t=this.clone();return t.compareNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}grad(e,t){const r=this.clone();return r.gradNode=[Zi(e),Zi(t)],r.referenceNode=this.getBase(),Zi(r)}depth(e){const t=this.clone();return t.depthNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}offset(e){const t=this.clone();return t.offsetNode=Zi(e),t.referenceNode=this.getBase(),Zi(t)}serialize(e){super.serialize(e),e.value=this.value.toJSON(e.meta).uuid,e.sampler=this.sampler,e.updateMatrix=this.updateMatrix,e.updateType=this.updateType}deserialize(e){super.deserialize(e),this.value=e.meta.textures[e.value],this.sampler=e.sampler,this.updateMatrix=e.updateMatrix,this.updateType=e.updateType}update(){const e=this.value,t=this._matrixUniform;null!==t&&(t.value=e.matrix),!0===e.matrixAutoUpdate&&e.updateMatrix();const r=this._flipYUniform;null!==r&&(r.value=e.image instanceof ImageBitmap&&!0===e.flipY||!0===e.isRenderTargetTexture||!0===e.isFramebufferTexture||!0===e.isDepthTexture)}clone(){const e=new this.constructor(this.value,this.uvNode,this.levelNode,this.biasNode);return e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e}}const Ll=rn(Fl).setParameterLength(1,4).setName("texture"),Pl=(e=Ml,t=null,r=null,s=null)=>{let i;return e&&!0===e.isTextureNode?(i=Zi(e.clone()),i.referenceNode=e.getBase(),null!==t&&(i.uvNode=Zi(t)),null!==r&&(i.levelNode=Zi(r)),null!==s&&(i.biasNode=Zi(s))):i=Ll(e,t,r,s),i},Bl=(...e)=>Pl(...e).setSampler(!1);class Dl extends Ta{static get type(){return"BufferNode"}constructor(e,t,r=0){super(e,t),this.isBufferNode=!0,this.bufferType=t,this.bufferCount=r,this.updateRanges=[]}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}getElementType(e){return this.getNodeType(e)}getInputType(){return"buffer"}}const Ul=(e,t,r)=>new Dl(e,t,r);class Il extends li{static get type(){return"UniformArrayElementNode"}constructor(e,t){super(e,t),this.isArrayBufferElementNode=!0}generate(e){const t=super.generate(e),r=this.getNodeType(),s=this.node.getPaddedType();return e.format(t,s,r)}}class Ol extends Dl{static get type(){return"UniformArrayNode"}constructor(e,t=null){super(null),this.array=e,this.elementType=null===t?qs(e[0]):t,this.paddedType=this.getPaddedType(),this.updateType=Js.RENDER,this.isArrayBufferNode=!0}getNodeType(){return this.paddedType}getElementType(){return this.elementType}getPaddedType(){const e=this.elementType;let t="vec4";return"mat2"===e?t="mat2":!0===/mat/.test(e)?t="mat4":"i"===e.charAt(0)?t="ivec4":"u"===e.charAt(0)&&(t="uvec4"),t}update(){const{array:e,value:t}=this,r=this.elementType;if("float"===r||"int"===r||"uint"===r)for(let r=0;rnew Ol(e,t);class kl extends ui{constructor(e){super("float"),this.name=e,this.isBuiltinNode=!0}generate(){return this.name}}const Gl=rn(kl).setParameterLength(1);let zl,$l;class Wl extends ui{static get type(){return"ScreenNode"}constructor(e){super(),this.scope=e,this._output=null,this.isViewportNode=!0}getNodeType(){return this.scope===Wl.DPR?"float":this.scope===Wl.VIEWPORT?"vec4":"vec2"}getUpdateType(){let e=Js.NONE;return this.scope!==Wl.SIZE&&this.scope!==Wl.VIEWPORT&&this.scope!==Wl.DPR||(e=Js.RENDER),this.updateType=e,e}update({renderer:e}){const t=e.getRenderTarget();this.scope===Wl.VIEWPORT?null!==t?$l.copy(t.viewport):(e.getViewport($l),$l.multiplyScalar(e.getPixelRatio())):this.scope===Wl.DPR?this._output.value=e.getPixelRatio():null!==t?(zl.width=t.width,zl.height=t.height):e.getDrawingBufferSize(zl)}setup(){const e=this.scope;let r=null;return r=e===Wl.SIZE?_a(zl||(zl=new t)):e===Wl.VIEWPORT?_a($l||($l=new s)):e===Wl.DPR?_a(1):bn(Xl.div(jl)),this._output=r,r}generate(e){if(this.scope===Wl.COORDINATE){let t=e.getFragCoord();if(e.isFlipY()){const r=e.getNodeProperties(jl).outputNode.build(e);t=`${e.getType("vec2")}( ${t}.x, ${r}.y - ${t}.y )`}return t}return super.generate(e)}}Wl.COORDINATE="coordinate",Wl.VIEWPORT="viewport",Wl.SIZE="size",Wl.UV="uv",Wl.DPR="dpr";const Hl=sn(Wl,Wl.DPR),ql=sn(Wl,Wl.UV),jl=sn(Wl,Wl.SIZE),Xl=sn(Wl,Wl.COORDINATE),Kl=sn(Wl,Wl.VIEWPORT),Yl=Kl.zw,Ql=Xl.sub(Kl.xy),Zl=Ql.div(Yl),Jl=un(()=>(d('TSL: "viewportResolution" is deprecated. Use "screenSize" instead.'),jl),"vec2").once()(),ed=_a(0,"uint").setName("u_cameraIndex").setGroup(fa("cameraIndex")).toVarying("v_cameraIndex"),td=_a("float").setName("cameraNear").setGroup(ba).onRenderUpdate(({camera:e})=>e.near),rd=_a("float").setName("cameraFar").setGroup(ba).onRenderUpdate(({camera:e})=>e.far),sd=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.projectionMatrix);t=Vl(r).setGroup(ba).setName("cameraProjectionMatrices").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraProjectionMatrix")}else t=_a("mat4").setName("cameraProjectionMatrix").setGroup(ba).onRenderUpdate(({camera:e})=>e.projectionMatrix);return t}).once()(),id=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.projectionMatrixInverse);t=Vl(r).setGroup(ba).setName("cameraProjectionMatricesInverse").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraProjectionMatrixInverse")}else t=_a("mat4").setName("cameraProjectionMatrixInverse").setGroup(ba).onRenderUpdate(({camera:e})=>e.projectionMatrixInverse);return t}).once()(),nd=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.matrixWorldInverse);t=Vl(r).setGroup(ba).setName("cameraViewMatrices").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraViewMatrix")}else t=_a("mat4").setName("cameraViewMatrix").setGroup(ba).onRenderUpdate(({camera:e})=>e.matrixWorldInverse);return t}).once()(),ad=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.matrixWorld);t=Vl(r).setGroup(ba).setName("cameraWorldMatrices").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraWorldMatrix")}else t=_a("mat4").setName("cameraWorldMatrix").setGroup(ba).onRenderUpdate(({camera:e})=>e.matrixWorld);return t}).once()(),od=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.normalMatrix);t=Vl(r).setGroup(ba).setName("cameraNormalMatrices").element(e.isMultiViewCamera?Gl("gl_ViewID_OVR"):ed).toConst("cameraNormalMatrix")}else t=_a("mat3").setName("cameraNormalMatrix").setGroup(ba).onRenderUpdate(({camera:e})=>e.normalMatrix);return t}).once()(),ud=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const s=[];for(let t=0,i=e.cameras.length;t{const r=e.cameras,s=t.array;for(let e=0,t=r.length;et.value.setFromMatrixPosition(e.matrixWorld));return t}).once()(),ld=un(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.viewport);t=Vl(r,"vec4").setGroup(ba).setName("cameraViewports").element(ed).toConst("cameraViewport")}else t=En(0,0,jl.x,jl.y).toConst("cameraViewport");return t}).once()(),dd=new C;class cd extends ui{static get type(){return"Object3DNode"}constructor(e,t=null){super(),this.scope=e,this.object3d=t,this.updateType=Js.OBJECT,this.uniformNode=new Ta(null)}getNodeType(){const e=this.scope;return e===cd.WORLD_MATRIX?"mat4":e===cd.POSITION||e===cd.VIEW_POSITION||e===cd.DIRECTION||e===cd.SCALE?"vec3":e===cd.RADIUS?"float":void 0}update(e){const t=this.object3d,s=this.uniformNode,i=this.scope;if(i===cd.WORLD_MATRIX)s.value=t.matrixWorld;else if(i===cd.POSITION)s.value=s.value||new r,s.value.setFromMatrixPosition(t.matrixWorld);else if(i===cd.SCALE)s.value=s.value||new r,s.value.setFromMatrixScale(t.matrixWorld);else if(i===cd.DIRECTION)s.value=s.value||new r,t.getWorldDirection(s.value);else if(i===cd.VIEW_POSITION){const i=e.camera;s.value=s.value||new r,s.value.setFromMatrixPosition(t.matrixWorld),s.value.applyMatrix4(i.matrixWorldInverse)}else if(i===cd.RADIUS){const r=e.object.geometry;null===r.boundingSphere&&r.computeBoundingSphere(),dd.copy(r.boundingSphere).applyMatrix4(t.matrixWorld),s.value=dd.radius}}generate(e){const t=this.scope;return t===cd.WORLD_MATRIX?this.uniformNode.nodeType="mat4":t===cd.POSITION||t===cd.VIEW_POSITION||t===cd.DIRECTION||t===cd.SCALE?this.uniformNode.nodeType="vec3":t===cd.RADIUS&&(this.uniformNode.nodeType="float"),this.uniformNode.build(e)}serialize(e){super.serialize(e),e.scope=this.scope}deserialize(e){super.deserialize(e),this.scope=e.scope}}cd.WORLD_MATRIX="worldMatrix",cd.POSITION="position",cd.SCALE="scale",cd.VIEW_POSITION="viewPosition",cd.DIRECTION="direction",cd.RADIUS="radius";const hd=rn(cd,cd.DIRECTION).setParameterLength(1),pd=rn(cd,cd.WORLD_MATRIX).setParameterLength(1),gd=rn(cd,cd.POSITION).setParameterLength(1),md=rn(cd,cd.SCALE).setParameterLength(1),fd=rn(cd,cd.VIEW_POSITION).setParameterLength(1),yd=rn(cd,cd.RADIUS).setParameterLength(1);class bd extends cd{static get type(){return"ModelNode"}constructor(e){super(e)}update(e){this.object3d=e.object,super.update(e)}}const xd=sn(bd,bd.DIRECTION),Td=sn(bd,bd.WORLD_MATRIX),_d=sn(bd,bd.POSITION),vd=sn(bd,bd.SCALE),Nd=sn(bd,bd.VIEW_POSITION),Sd=sn(bd,bd.RADIUS),Rd=_a(new n).onObjectUpdate(({object:e},t)=>t.value.getNormalMatrix(e.matrixWorld)),Ed=_a(new a).onObjectUpdate(({object:e},t)=>t.value.copy(e.matrixWorld).invert()),Ad=un(e=>e.context.modelViewMatrix||wd).once()().toVar("modelViewMatrix"),wd=nd.mul(Td),Cd=un(e=>(e.context.isHighPrecisionModelViewMatrix=!0,_a("mat4").onObjectUpdate(({object:e,camera:t})=>e.modelViewMatrix.multiplyMatrices(t.matrixWorldInverse,e.matrixWorld)))).once()().toVar("highpModelViewMatrix"),Md=un(e=>{const t=e.context.isHighPrecisionModelViewMatrix;return _a("mat3").onObjectUpdate(({object:e,camera:r})=>(!0!==t&&e.modelViewMatrix.multiplyMatrices(r.matrixWorldInverse,e.matrixWorld),e.normalMatrix.getNormalMatrix(e.modelViewMatrix)))}).once()().toVar("highpModelNormalViewMatrix"),Fd=un(e=>"fragment"!==e.shaderStage?(v("TSL: `clipSpace` is only available in fragment stage."),En()):e.context.clipSpace.toVarying("v_clipSpace")).once()(),Ld=Sl("position","vec3"),Pd=Ld.toVarying("positionLocal"),Bd=Ld.toVarying("positionPrevious"),Dd=un(e=>Td.mul(Pd).xyz.toVarying(e.getSubBuildProperty("v_positionWorld")),"vec3").once(["POSITION"])(),Ud=un(()=>Pd.transformDirection(Td).toVarying("v_positionWorldDirection").normalize().toVar("positionWorldDirection"),"vec3").once(["POSITION"])(),Id=un(e=>{if("fragment"===e.shaderStage&&e.material.vertexNode){const e=id.mul(Fd);return e.xyz.div(e.w).toVar("positionView")}return e.context.setupPositionView().toVarying("v_positionView")},"vec3").once(["POSITION","VERTEX"])(),Od=un(e=>{let t;return t=e.camera.isOrthographicCamera?vn(0,0,1):Id.negate().toVarying("v_positionViewDirection").normalize(),t.toVar("positionViewDirection")},"vec3").once(["POSITION"])();class Vd extends ui{static get type(){return"FrontFacingNode"}constructor(){super("bool"),this.isFrontFacingNode=!0}generate(e){if("fragment"!==e.shaderStage)return"true";const{material:t}=e;return t.side===M?"false":e.getFrontFacing()}}const kd=sn(Vd),Gd=gn(kd).mul(2).sub(1),zd=un(([e],{material:t})=>{const r=t.side;return r===M?e=e.mul(-1):r===F&&(e=e.mul(Gd)),e}),$d=Sl("normal","vec3"),Wd=un(e=>!1===e.geometry.hasAttribute("normal")?(d('TSL: Vertex attribute "normal" not found on geometry.'),vn(0,1,0)):$d,"vec3").once()().toVar("normalLocal"),Hd=Id.dFdx().cross(Id.dFdy()).normalize().toVar("normalFlat"),qd=un(e=>{let t;return t=e.isFlatShading()?Hd:Zd(Wd).toVarying("v_normalViewGeometry").normalize(),t},"vec3").once()().toVar("normalViewGeometry"),jd=un(e=>{let t=qd.transformDirection(nd);return!0!==e.isFlatShading()&&(t=t.toVarying("v_normalWorldGeometry")),t.normalize().toVar("normalWorldGeometry")},"vec3").once()(),Xd=un(e=>{let t;return"NORMAL"===e.subBuildFn||"VERTEX"===e.subBuildFn?(t=qd,!0!==e.isFlatShading()&&(t=zd(t))):t=e.context.setupNormal().context({getUV:null}),t},"vec3").once(["NORMAL","VERTEX"])().toVar("normalView"),Kd=Xd.transformDirection(nd).toVar("normalWorld"),Yd=un(({subBuildFn:e,context:t})=>{let r;return r="NORMAL"===e||"VERTEX"===e?Xd:t.setupClearcoatNormal().context({getUV:null}),r},"vec3").once(["NORMAL","VERTEX"])().toVar("clearcoatNormalView"),Qd=un(([e,t=Td])=>{const r=Fn(t),s=e.div(vn(r[0].dot(r[0]),r[1].dot(r[1]),r[2].dot(r[2])));return r.mul(s).xyz}),Zd=un(([e],t)=>{const r=t.context.modelNormalViewMatrix;if(r)return r.transformDirection(e);const s=Rd.mul(e);return nd.transformDirection(s)}),Jd=un(()=>(d('TSL: "transformedNormalView" is deprecated. Use "normalView" instead.'),Xd)).once(["NORMAL","VERTEX"])(),ec=un(()=>(d('TSL: "transformedNormalWorld" is deprecated. Use "normalWorld" instead.'),Kd)).once(["NORMAL","VERTEX"])(),tc=un(()=>(d('TSL: "transformedClearcoatNormalView" is deprecated. Use "clearcoatNormalView" instead.'),Yd)).once(["NORMAL","VERTEX"])(),rc=new L,sc=new a,ic=_a(0).onReference(({material:e})=>e).onObjectUpdate(({material:e})=>e.refractionRatio),nc=_a(1).onReference(({material:e})=>e).onObjectUpdate(function({material:e,scene:t}){return e.envMap?e.envMapIntensity:t.environmentIntensity}),ac=_a(new a).onReference(function(e){return e.material}).onObjectUpdate(function({material:e,scene:t}){const r=null!==t.environment&&null===e.envMap?t.environmentRotation:e.envMapRotation;return r?(rc.copy(r),sc.makeRotationFromEuler(rc)):sc.identity(),sc}),oc=Od.negate().reflect(Xd),uc=Od.negate().refract(Xd,ic),lc=oc.transformDirection(nd).toVar("reflectVector"),dc=uc.transformDirection(nd).toVar("reflectVector"),cc=new P;class hc extends Fl{static get type(){return"CubeTextureNode"}constructor(e,t=null,r=null,s=null){super(e,t,r,s),this.isCubeTextureNode=!0}getInputType(){return!0===this.value.isDepthTexture?"cubeDepthTexture":"cubeTexture"}getDefaultUV(){const e=this.value;return e.mapping===B?lc:e.mapping===D?dc:(o('CubeTextureNode: Mapping "%s" not supported.',e.mapping),vn(0,0,0))}setUpdateMatrix(){}setupUV(e,t){const r=this.value;return!0===r.isDepthTexture?e.renderer.coordinateSystem===h?vn(t.x,t.y.negate(),t.z):t:(e.renderer.coordinateSystem!==h&&r.isRenderTargetTexture||(t=vn(t.x.negate(),t.yz)),ac.mul(t))}generateUV(e,t){return t.build(e,!0===this.sampler?"vec3":"ivec3")}}const pc=rn(hc).setParameterLength(1,4).setName("cubeTexture"),gc=(e=cc,t=null,r=null,s=null)=>{let i;return e&&!0===e.isCubeTextureNode?(i=Zi(e.clone()),i.referenceNode=e,null!==t&&(i.uvNode=Zi(t)),null!==r&&(i.levelNode=Zi(r)),null!==s&&(i.biasNode=Zi(s))):i=pc(e,t,r,s),i};class mc extends li{static get type(){return"ReferenceElementNode"}constructor(e,t){super(e,t),this.referenceNode=e,this.isReferenceElementNode=!0}getNodeType(){return this.referenceNode.uniformType}generate(e){const t=super.generate(e),r=this.referenceNode.getNodeType(),s=this.getNodeType();return e.format(t,r,s)}}class fc extends ui{static get type(){return"ReferenceNode"}constructor(e,t,r=null,s=null){super(),this.property=e,this.uniformType=t,this.object=r,this.count=s,this.properties=e.split("."),this.reference=r,this.node=null,this.group=null,this.name=null,this.updateType=Js.OBJECT}element(e){return new mc(this,Zi(e))}setGroup(e){return this.group=e,this}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setNodeType(e){let t=null;t=null!==this.count?Ul(null,e,this.count):Array.isArray(this.getValueFromReference())?Vl(null,e):"texture"===e?Pl(null):"cubeTexture"===e?gc(null):_a(null,e),null!==this.group&&t.setGroup(this.group),null!==this.name&&t.setName(this.name),this.node=t}getNodeType(e){return null===this.node&&(this.updateReference(e),this.updateValue()),this.node.getNodeType(e)}getValueFromReference(e=this.reference){const{properties:t}=this;let r=e[t[0]];for(let e=1;enew fc(e,t,r),bc=(e,t,r,s)=>new fc(e,t,s,r);class xc extends fc{static get type(){return"MaterialReferenceNode"}constructor(e,t,r=null){super(e,t,r),this.material=r,this.isMaterialReferenceNode=!0}updateReference(e){return this.reference=null!==this.material?this.material:e.material,this.reference}}const Tc=(e,t,r=null)=>new xc(e,t,r),_c=Rl(),vc=Id.dFdx(),Nc=Id.dFdy(),Sc=_c.dFdx(),Rc=_c.dFdy(),Ec=Xd,Ac=Nc.cross(Ec),wc=Ec.cross(vc),Cc=Ac.mul(Sc.x).add(wc.mul(Rc.x)),Mc=Ac.mul(Sc.y).add(wc.mul(Rc.y)),Fc=Cc.dot(Cc).max(Mc.dot(Mc)),Lc=Fc.equal(0).select(0,Fc.inverseSqrt()),Pc=Cc.mul(Lc).toVar("tangentViewFrame"),Bc=Mc.mul(Lc).toVar("bitangentViewFrame"),Dc=Sl("tangent","vec4"),Uc=Dc.xyz.toVar("tangentLocal"),Ic=un(e=>{let t;return t="VERTEX"===e.subBuildFn||e.geometry.hasAttribute("tangent")?Ad.mul(En(Uc,0)).xyz.toVarying("v_tangentView").normalize():Pc,!0!==e.isFlatShading()&&(t=zd(t)),t},"vec3").once(["NORMAL","VERTEX"])().toVar("tangentView"),Oc=Ic.transformDirection(nd).toVarying("v_tangentWorld").normalize().toVar("tangentWorld"),Vc=un(([e,t],r)=>{let s=e.mul(Dc.w).xyz;return"NORMAL"===r.subBuildFn&&!0!==r.isFlatShading()&&(s=s.toVarying(t)),s}).once(["NORMAL"]),kc=Vc($d.cross(Dc),"v_bitangentGeometry").normalize().toVar("bitangentGeometry"),Gc=Vc(Wd.cross(Uc),"v_bitangentLocal").normalize().toVar("bitangentLocal"),zc=un(e=>{let t;return t="VERTEX"===e.subBuildFn||e.geometry.hasAttribute("tangent")?Vc(Xd.cross(Ic),"v_bitangentView").normalize():Bc,!0!==e.isFlatShading()&&(t=zd(t)),t},"vec3").once(["NORMAL","VERTEX"])().toVar("bitangentView"),$c=Vc(Kd.cross(Oc),"v_bitangentWorld").normalize().toVar("bitangentWorld"),Wc=Fn(Ic,zc,Xd).toVar("TBNViewMatrix"),Hc=Od.mul(Wc),qc=un(()=>{let e=Jn.cross(Od);return e=e.cross(Jn).normalize(),e=nu(e,Xd,Qn.mul(Gn.oneMinus()).oneMinus().pow2().pow2()).normalize(),e}).once()(),jc=e=>Zi(e).mul(.5).add(.5),Xc=e=>vn(e,bo(ou(gn(1).sub(Yo(e,e)))));class Kc extends ci{static get type(){return"NormalMapNode"}constructor(e,t=null){super("vec3"),this.node=e,this.scaleNode=t,this.normalMapType=U,this.unpackNormalMode=I}setup(e){const{normalMapType:t,scaleNode:r,unpackNormalMode:s}=this;let i=this.node.mul(2).sub(1);if(t===U?s===O?i=Xc(i.xy):s===V?i=Xc(i.yw):s!==I&&console.error(`THREE.NodeMaterial: Unexpected unpack normal mode: ${s}`):s!==I&&console.error(`THREE.NodeMaterial: Normal map type '${t}' is not compatible with unpack normal mode '${s}'`),null!==r){let t=r;!0===e.isFlatShading()&&(t=zd(t)),i=vn(i.xy.mul(t),i.z)}let n=null;return t===k?n=Zd(i):t===U?n=Wc.mul(i).normalize():(o(`NodeMaterial: Unsupported normal map type: ${t}`),n=Xd),n}}const Yc=rn(Kc).setParameterLength(1,2),Qc=un(({textureNode:e,bumpScale:t})=>{const r=t=>e.isolate().context({getUV:e=>t(e.uvNode||Rl()),forceUVContext:!0}),s=gn(r(e=>e));return bn(gn(r(e=>e.add(e.dFdx()))).sub(s),gn(r(e=>e.add(e.dFdy()))).sub(s)).mul(t)}),Zc=un(e=>{const{surf_pos:t,surf_norm:r,dHdxy:s}=e,i=t.dFdx().normalize(),n=r,a=t.dFdy().normalize().cross(n),o=n.cross(i),u=i.dot(a).mul(Gd),l=u.sign().mul(s.x.mul(a).add(s.y.mul(o)));return u.abs().mul(r).sub(l).normalize()});class Jc extends ci{static get type(){return"BumpMapNode"}constructor(e,t=null){super("vec3"),this.textureNode=e,this.scaleNode=t}setup(){const e=null!==this.scaleNode?this.scaleNode:1,t=Qc({textureNode:this.textureNode,bumpScale:e});return Zc({surf_pos:Id,surf_norm:Xd,dHdxy:t})}}const eh=rn(Jc).setParameterLength(1,2),th=new Map;class rh extends ui{static get type(){return"MaterialNode"}constructor(e){super(),this.scope=e}getCache(e,t){let r=th.get(e);return void 0===r&&(r=Tc(e,t),th.set(e,r)),r}getFloat(e){return this.getCache(e,"float")}getColor(e){return this.getCache(e,"color")}getTexture(e){return this.getCache("map"===e?"map":e+"Map","texture")}setup(e){const t=e.context.material,r=this.scope;let s=null;if(r===rh.COLOR){const e=void 0!==t.color?this.getColor(r):vn();s=t.map&&!0===t.map.isTexture?e.mul(this.getTexture("map")):e}else if(r===rh.OPACITY){const e=this.getFloat(r);s=t.alphaMap&&!0===t.alphaMap.isTexture?e.mul(this.getTexture("alpha")):e}else if(r===rh.SPECULAR_STRENGTH)s=t.specularMap&&!0===t.specularMap.isTexture?this.getTexture("specular").r:gn(1);else if(r===rh.SPECULAR_INTENSITY){const e=this.getFloat(r);s=t.specularIntensityMap&&!0===t.specularIntensityMap.isTexture?e.mul(this.getTexture(r).a):e}else if(r===rh.SPECULAR_COLOR){const e=this.getColor(r);s=t.specularColorMap&&!0===t.specularColorMap.isTexture?e.mul(this.getTexture(r).rgb):e}else if(r===rh.ROUGHNESS){const e=this.getFloat(r);s=t.roughnessMap&&!0===t.roughnessMap.isTexture?e.mul(this.getTexture(r).g):e}else if(r===rh.METALNESS){const e=this.getFloat(r);s=t.metalnessMap&&!0===t.metalnessMap.isTexture?e.mul(this.getTexture(r).b):e}else if(r===rh.EMISSIVE){const e=this.getFloat("emissiveIntensity"),i=this.getColor(r).mul(e);s=t.emissiveMap&&!0===t.emissiveMap.isTexture?i.mul(this.getTexture(r)):i}else if(r===rh.NORMAL)t.normalMap?(s=Yc(this.getTexture("normal"),this.getCache("normalScale","vec2")),s.normalMapType=t.normalMapType,t.normalMap.format!=G&&t.normalMap.format!=z&&t.normalMap.format!=$||(s.unpackNormalMode=O)):s=t.bumpMap?eh(this.getTexture("bump").r,this.getFloat("bumpScale")):Xd;else if(r===rh.CLEARCOAT){const e=this.getFloat(r);s=t.clearcoatMap&&!0===t.clearcoatMap.isTexture?e.mul(this.getTexture(r).r):e}else if(r===rh.CLEARCOAT_ROUGHNESS){const e=this.getFloat(r);s=t.clearcoatRoughnessMap&&!0===t.clearcoatRoughnessMap.isTexture?e.mul(this.getTexture(r).r):e}else if(r===rh.CLEARCOAT_NORMAL)s=t.clearcoatNormalMap?Yc(this.getTexture(r),this.getCache(r+"Scale","vec2")):Xd;else if(r===rh.SHEEN){const e=this.getColor("sheenColor").mul(this.getFloat("sheen"));s=t.sheenColorMap&&!0===t.sheenColorMap.isTexture?e.mul(this.getTexture("sheenColor").rgb):e}else if(r===rh.SHEEN_ROUGHNESS){const e=this.getFloat(r);s=t.sheenRoughnessMap&&!0===t.sheenRoughnessMap.isTexture?e.mul(this.getTexture(r).a):e,s=s.clamp(1e-4,1)}else if(r===rh.ANISOTROPY)if(t.anisotropyMap&&!0===t.anisotropyMap.isTexture){const e=this.getTexture(r);s=Mn(kh.x,kh.y,kh.y.negate(),kh.x).mul(e.rg.mul(2).sub(bn(1)).normalize().mul(e.b))}else s=kh;else if(r===rh.IRIDESCENCE_THICKNESS){const e=yc("1","float",t.iridescenceThicknessRange);if(t.iridescenceThicknessMap){const i=yc("0","float",t.iridescenceThicknessRange);s=e.sub(i).mul(this.getTexture(r).g).add(i)}else s=e}else if(r===rh.TRANSMISSION){const e=this.getFloat(r);s=t.transmissionMap?e.mul(this.getTexture(r).r):e}else if(r===rh.THICKNESS){const e=this.getFloat(r);s=t.thicknessMap?e.mul(this.getTexture(r).g):e}else if(r===rh.IOR)s=this.getFloat(r);else if(r===rh.LIGHT_MAP)s=this.getTexture(r).rgb.mul(this.getFloat("lightMapIntensity"));else if(r===rh.AO)s=this.getTexture(r).r.sub(1).mul(this.getFloat("aoMapIntensity")).add(1);else if(r===rh.LINE_DASH_OFFSET)s=t.dashOffset?this.getFloat(r):gn(0);else{const t=this.getNodeType(e);s=this.getCache(r,t)}return s}}rh.ALPHA_TEST="alphaTest",rh.COLOR="color",rh.OPACITY="opacity",rh.SHININESS="shininess",rh.SPECULAR="specular",rh.SPECULAR_STRENGTH="specularStrength",rh.SPECULAR_INTENSITY="specularIntensity",rh.SPECULAR_COLOR="specularColor",rh.REFLECTIVITY="reflectivity",rh.ROUGHNESS="roughness",rh.METALNESS="metalness",rh.NORMAL="normal",rh.CLEARCOAT="clearcoat",rh.CLEARCOAT_ROUGHNESS="clearcoatRoughness",rh.CLEARCOAT_NORMAL="clearcoatNormal",rh.EMISSIVE="emissive",rh.ROTATION="rotation",rh.SHEEN="sheen",rh.SHEEN_ROUGHNESS="sheenRoughness",rh.ANISOTROPY="anisotropy",rh.IRIDESCENCE="iridescence",rh.IRIDESCENCE_IOR="iridescenceIOR",rh.IRIDESCENCE_THICKNESS="iridescenceThickness",rh.IOR="ior",rh.TRANSMISSION="transmission",rh.THICKNESS="thickness",rh.ATTENUATION_DISTANCE="attenuationDistance",rh.ATTENUATION_COLOR="attenuationColor",rh.LINE_SCALE="scale",rh.LINE_DASH_SIZE="dashSize",rh.LINE_GAP_SIZE="gapSize",rh.LINE_WIDTH="linewidth",rh.LINE_DASH_OFFSET="dashOffset",rh.POINT_SIZE="size",rh.DISPERSION="dispersion",rh.LIGHT_MAP="light",rh.AO="ao";const sh=sn(rh,rh.ALPHA_TEST),ih=sn(rh,rh.COLOR),nh=sn(rh,rh.SHININESS),ah=sn(rh,rh.EMISSIVE),oh=sn(rh,rh.OPACITY),uh=sn(rh,rh.SPECULAR),lh=sn(rh,rh.SPECULAR_INTENSITY),dh=sn(rh,rh.SPECULAR_COLOR),ch=sn(rh,rh.SPECULAR_STRENGTH),hh=sn(rh,rh.REFLECTIVITY),ph=sn(rh,rh.ROUGHNESS),gh=sn(rh,rh.METALNESS),mh=sn(rh,rh.NORMAL),fh=sn(rh,rh.CLEARCOAT),yh=sn(rh,rh.CLEARCOAT_ROUGHNESS),bh=sn(rh,rh.CLEARCOAT_NORMAL),xh=sn(rh,rh.ROTATION),Th=sn(rh,rh.SHEEN),_h=sn(rh,rh.SHEEN_ROUGHNESS),vh=sn(rh,rh.ANISOTROPY),Nh=sn(rh,rh.IRIDESCENCE),Sh=sn(rh,rh.IRIDESCENCE_IOR),Rh=sn(rh,rh.IRIDESCENCE_THICKNESS),Eh=sn(rh,rh.TRANSMISSION),Ah=sn(rh,rh.THICKNESS),wh=sn(rh,rh.IOR),Ch=sn(rh,rh.ATTENUATION_DISTANCE),Mh=sn(rh,rh.ATTENUATION_COLOR),Fh=sn(rh,rh.LINE_SCALE),Lh=sn(rh,rh.LINE_DASH_SIZE),Ph=sn(rh,rh.LINE_GAP_SIZE),Bh=sn(rh,rh.LINE_WIDTH),Dh=sn(rh,rh.LINE_DASH_OFFSET),Uh=sn(rh,rh.POINT_SIZE),Ih=sn(rh,rh.DISPERSION),Oh=sn(rh,rh.LIGHT_MAP),Vh=sn(rh,rh.AO),kh=_a(new t).onReference(function(e){return e.material}).onRenderUpdate(function({material:e}){this.value.set(e.anisotropy*Math.cos(e.anisotropyRotation),e.anisotropy*Math.sin(e.anisotropyRotation))}),Gh=un(e=>e.context.setupModelViewProjection(),"vec4").once()().toVarying("v_modelViewProjection");class zh extends li{static get type(){return"StorageArrayElementNode"}constructor(e,t){super(e,t),this.isStorageArrayElementNode=!0}set storageBufferNode(e){this.node=e}get storageBufferNode(){return this.node}getMemberType(e,t){const r=this.storageBufferNode.structTypeNode;return r?r.getMemberType(e,t):"void"}setup(e){return!1===e.isAvailable("storageBuffer")&&!0===this.node.isPBO&&e.setupPBO(this.node),super.setup(e)}generate(e,t){let r;const s=e.context.assign;if(r=!1===e.isAvailable("storageBuffer")?!0!==this.node.isPBO||!0===s||!this.node.value.isInstancedBufferAttribute&&"compute"===e.shaderStage?this.node.build(e):e.generatePBO(this):super.generate(e),!0!==s){const s=this.getNodeType(e);r=e.format(r,s,t)}return r}}const $h=rn(zh).setParameterLength(2);class Wh extends Dl{static get type(){return"StorageBufferNode"}constructor(e,t=null,r=0){let s,i=null;t&&t.isStruct?(s="struct",i=t.layout,(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute)&&(r=e.count)):null===t&&(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute)?(s=Gs(e.itemSize),r=e.count):s=t,super(e,s,r),this.isStorageBufferNode=!0,this.structTypeNode=i,this.access=ti.READ_WRITE,this.isAtomic=!1,this.isPBO=!1,this._attribute=null,this._varying=null,this.global=!0,!0!==e.isStorageBufferAttribute&&!0!==e.isStorageInstancedBufferAttribute&&(e.isInstancedBufferAttribute?e.isStorageInstancedBufferAttribute=!0:e.isStorageBufferAttribute=!0)}getHash(e){if(0===this.bufferCount){let t=e.globalCache.getData(this.value);return void 0===t&&(t={node:this},e.globalCache.setData(this.value,t)),t.node.uuid}return this.uuid}getInputType(){return this.value.isIndirectStorageBufferAttribute?"indirectStorageBuffer":"storageBuffer"}element(e){return $h(this,e)}setPBO(e){return this.isPBO=e,this}getPBO(){return this.isPBO}setAccess(e){return this.access=e,this}toReadOnly(){return this.setAccess(ti.READ_ONLY)}setAtomic(e){return this.isAtomic=e,this}toAtomic(){return this.setAtomic(!0)}getAttributeData(){return null===this._attribute&&(this._attribute=Ju(this.value),this._varying=Bu(this._attribute)),{attribute:this._attribute,varying:this._varying}}getNodeType(e){if(null!==this.structTypeNode)return this.structTypeNode.getNodeType(e);if(e.isAvailable("storageBuffer")||e.isAvailable("indirectStorageBuffer"))return super.getNodeType(e);const{attribute:t}=this.getAttributeData();return t.getNodeType(e)}getMemberType(e,t){return null!==this.structTypeNode?this.structTypeNode.getMemberType(e,t):"void"}generate(e){if(null!==this.structTypeNode&&this.structTypeNode.build(e),e.isAvailable("storageBuffer")||e.isAvailable("indirectStorageBuffer"))return super.generate(e);const{attribute:t,varying:r}=this.getAttributeData(),s=r.build(e);return e.registerTransform(s,t),s}}const Hh=(e,t=null,r=0)=>new Wh(e,t,r);class qh extends ui{static get type(){return"IndexNode"}constructor(e){super("uint"),this.scope=e,this.isIndexNode=!0}generate(e){const t=this.getNodeType(e),r=this.scope;let s,i;if(r===qh.VERTEX)s=e.getVertexIndex();else if(r===qh.INSTANCE)s=e.getInstanceIndex();else if(r===qh.DRAW)s=e.getDrawIndex();else if(r===qh.INVOCATION_LOCAL)s=e.getInvocationLocalIndex();else if(r===qh.INVOCATION_SUBGROUP)s=e.getInvocationSubgroupIndex();else{if(r!==qh.SUBGROUP)throw new Error("THREE.IndexNode: Unknown scope: "+r);s=e.getSubgroupIndex()}if("vertex"===e.shaderStage||"compute"===e.shaderStage)i=s;else{i=Bu(this).build(e,t)}return i}}qh.VERTEX="vertex",qh.INSTANCE="instance",qh.SUBGROUP="subgroup",qh.INVOCATION_LOCAL="invocationLocal",qh.INVOCATION_SUBGROUP="invocationSubgroup",qh.DRAW="draw";const jh=sn(qh,qh.VERTEX),Xh=sn(qh,qh.INSTANCE),Kh=sn(qh,qh.SUBGROUP),Yh=sn(qh,qh.INVOCATION_SUBGROUP),Qh=sn(qh,qh.INVOCATION_LOCAL),Zh=sn(qh,qh.DRAW);class Jh extends ui{static get type(){return"InstanceNode"}constructor(e,t,r=null){super("void"),this.count=e,this.instanceMatrix=t,this.instanceColor=r,this.instanceMatrixNode=null,this.instanceColorNode=null,this.updateType=Js.FRAME,this.buffer=null,this.bufferColor=null,this.previousInstanceMatrixNode=null}get isStorageMatrix(){const{instanceMatrix:e}=this;return e&&!0===e.isStorageInstancedBufferAttribute}get isStorageColor(){const{instanceColor:e}=this;return e&&!0===e.isStorageInstancedBufferAttribute}setup(e){let{instanceMatrixNode:t,instanceColorNode:r}=this;null===t&&(t=this._createInstanceMatrixNode(!0,e),this.instanceMatrixNode=t);const{instanceColor:s,isStorageColor:i}=this;if(s&&null===r){if(i)r=Hh(s,"vec3",Math.max(s.count,1)).element(Xh);else{const e=new W(s.array,3),t=s.usage===x?tl:el;this.bufferColor=e,r=vn(t(e,"vec3",3,0))}this.instanceColorNode=r}const n=t.mul(Pd).xyz;if(Pd.assign(n),e.needsPreviousData()&&Bd.assign(this.getPreviousInstancedPosition(e)),e.hasGeometryAttribute("normal")){const e=Qd(Wd,t);Wd.assign(e)}null!==this.instanceColorNode&&In("vec3","vInstanceColor").assign(this.instanceColorNode)}update(e){null!==this.buffer&&!0!==this.isStorageMatrix&&(this.buffer.clearUpdateRanges(),this.buffer.updateRanges.push(...this.instanceMatrix.updateRanges),this.instanceMatrix.version!==this.buffer.version&&(this.buffer.version=this.instanceMatrix.version)),this.instanceColor&&null!==this.bufferColor&&!0!==this.isStorageColor&&(this.bufferColor.clearUpdateRanges(),this.bufferColor.updateRanges.push(...this.instanceColor.updateRanges),this.instanceColor.version!==this.bufferColor.version&&(this.bufferColor.version=this.instanceColor.version)),null!==this.previousInstanceMatrixNode&&e.object.previousInstanceMatrix.array.set(this.instanceMatrix.array)}getPreviousInstancedPosition(e){const t=e.object;return null===this.previousInstanceMatrixNode&&(t.previousInstanceMatrix=this.instanceMatrix.clone(),this.previousInstanceMatrixNode=this._createInstanceMatrixNode(!1,e)),this.previousInstanceMatrixNode.mul(Bd).xyz}_createInstanceMatrixNode(e,t){let r;const{instanceMatrix:s}=this,{count:i}=s;if(this.isStorageMatrix)r=Hh(s,"mat4",Math.max(i,1)).element(Xh);else{if(i<=(!0===t.renderer.backend.isWebGPUBackend?1e3:250))r=Ul(s.array,"mat4",Math.max(i,1)).element(Xh);else{const t=new H(s.array,16,1);!0===e&&(this.buffer=t);const i=s.usage===x?tl:el,n=[i(t,"vec4",16,0),i(t,"vec4",16,4),i(t,"vec4",16,8),i(t,"vec4",16,12)];r=Ln(...n)}}return r}}const ep=rn(Jh).setParameterLength(2,3);class tp extends Jh{static get type(){return"InstancedMeshNode"}constructor(e){const{count:t,instanceMatrix:r,instanceColor:s}=e;super(t,r,s),this.instancedMesh=e}}const rp=rn(tp).setParameterLength(1);class sp extends ui{static get type(){return"BatchNode"}constructor(e){super("void"),this.batchMesh=e,this.batchingIdNode=null}setup(e){null===this.batchingIdNode&&(null===e.getDrawIndex()?this.batchingIdNode=Xh:this.batchingIdNode=Zh);const t=un(([e])=>{const t=mn(Al(Bl(this.batchMesh._indirectTexture),0).x).toConst(),r=mn(e).mod(t).toConst(),s=mn(e).div(t).toConst();return Bl(this.batchMesh._indirectTexture,xn(r,s)).x}).setLayout({name:"getIndirectIndex",type:"uint",inputs:[{name:"id",type:"int"}]}),r=t(mn(this.batchingIdNode)),s=this.batchMesh._matricesTexture,i=mn(Al(Bl(s),0).x).toConst(),n=gn(r).mul(4).toInt().toConst(),a=n.mod(i).toConst(),o=n.div(i).toConst(),u=Ln(Bl(s,xn(a,o)),Bl(s,xn(a.add(1),o)),Bl(s,xn(a.add(2),o)),Bl(s,xn(a.add(3),o))),l=this.batchMesh._colorsTexture;if(null!==l){const e=un(([e])=>{const t=mn(Al(Bl(l),0).x).toConst(),r=e,s=r.mod(t).toConst(),i=r.div(t).toConst();return Bl(l,xn(s,i)).rgb}).setLayout({name:"getBatchingColor",type:"vec3",inputs:[{name:"id",type:"int"}]}),t=e(r);In("vec3","vBatchColor").assign(t)}const d=Fn(u);Pd.assign(u.mul(Pd));const c=Wd.div(vn(d[0].dot(d[0]),d[1].dot(d[1]),d[2].dot(d[2]))),h=d.mul(c).xyz;Wd.assign(h),e.hasGeometryAttribute("tangent")&&Uc.mulAssign(d)}}const ip=rn(sp).setParameterLength(1),np=new WeakMap;class ap extends ui{static get type(){return"SkinningNode"}constructor(e){super("void"),this.skinnedMesh=e,this.updateType=Js.OBJECT,this.skinIndexNode=Sl("skinIndex","uvec4"),this.skinWeightNode=Sl("skinWeight","vec4"),this.bindMatrixNode=yc("bindMatrix","mat4"),this.bindMatrixInverseNode=yc("bindMatrixInverse","mat4"),this.boneMatricesNode=bc("skeleton.boneMatrices","mat4",e.skeleton.bones.length),this.positionNode=Pd,this.toPositionNode=Pd,this.previousBoneMatricesNode=null}getSkinnedPosition(e=this.boneMatricesNode,t=this.positionNode){const{skinIndexNode:r,skinWeightNode:s,bindMatrixNode:i,bindMatrixInverseNode:n}=this,a=e.element(r.x),o=e.element(r.y),u=e.element(r.z),l=e.element(r.w),d=i.mul(t),c=Ma(a.mul(s.x).mul(d),o.mul(s.y).mul(d),u.mul(s.z).mul(d),l.mul(s.w).mul(d));return n.mul(c).xyz}getSkinnedNormalAndTangent(e=this.boneMatricesNode,t=Wd,r=Uc){const{skinIndexNode:s,skinWeightNode:i,bindMatrixNode:n,bindMatrixInverseNode:a}=this,o=e.element(s.x),u=e.element(s.y),l=e.element(s.z),d=e.element(s.w);let c=Ma(i.x.mul(o),i.y.mul(u),i.z.mul(l),i.w.mul(d));c=a.mul(c).mul(n);return{skinNormal:c.transformDirection(t).xyz,skinTangent:c.transformDirection(r).xyz}}getPreviousSkinnedPosition(e){const t=e.object;return null===this.previousBoneMatricesNode&&(t.skeleton.previousBoneMatrices=new Float32Array(t.skeleton.boneMatrices),this.previousBoneMatricesNode=bc("skeleton.previousBoneMatrices","mat4",t.skeleton.bones.length)),this.getSkinnedPosition(this.previousBoneMatricesNode,Bd)}setup(e){e.needsPreviousData()&&Bd.assign(this.getPreviousSkinnedPosition(e));const t=this.getSkinnedPosition();if(this.toPositionNode&&this.toPositionNode.assign(t),e.hasGeometryAttribute("normal")){const{skinNormal:t,skinTangent:r}=this.getSkinnedNormalAndTangent();Wd.assign(t),e.hasGeometryAttribute("tangent")&&Uc.assign(r)}return t}generate(e,t){if("void"!==t)return super.generate(e,t)}update(e){const t=e.object&&e.object.skeleton?e.object.skeleton:this.skinnedMesh.skeleton;np.get(t)!==e.frameId&&(np.set(t,e.frameId),null!==this.previousBoneMatricesNode&&(null===t.previousBoneMatrices&&(t.previousBoneMatrices=new Float32Array(t.boneMatrices)),t.previousBoneMatrices.set(t.boneMatrices)),t.update())}}const op=e=>new ap(e);class up extends ui{static get type(){return"LoopNode"}constructor(e=[]){super("void"),this.params=e}getVarName(e){return String.fromCharCode("i".charCodeAt(0)+e)}getProperties(e){const t=e.getNodeProperties(this);if(void 0!==t.stackNode)return t;const r={};for(let e=0,t=this.params.length-1;eNumber(l)?">=":"<")),a)n=`while ( ${l} )`;else{const r={start:u,end:l},s=r.start,i=r.end;let a;const g=()=>h.includes("<")?"+=":"-=";if(null!=p)switch(typeof p){case"function":a=e.flowStagesNode(t.updateNode,"void").code.replace(/\t|;/g,"");break;case"number":a=d+" "+g()+" "+e.generateConst(c,p);break;case"string":a=d+" "+p;break;default:p.isNode?a=d+" "+g()+" "+p.build(e):(o("TSL: 'Loop( { update: ... } )' is not a function, string or number."),a="break /* invalid update */")}else p="int"===c||"uint"===c?h.includes("<")?"++":"--":g()+" 1.",a=d+" "+p;n=`for ( ${e.getVar(c,d)+" = "+s}; ${d+" "+h+" "+i}; ${a} )`}e.addFlowCode((0===s?"\n":"")+e.tab+n+" {\n\n").addFlowTab()}const i=s.build(e,"void");t.returnsNode.build(e,"void"),e.removeFlowTab().addFlowCode("\n"+e.tab+i);for(let t=0,r=this.params.length-1;tnew up(tn(e,"int")).toStack(),dp=()=>gl("break").toStack(),cp=new WeakMap,hp=new s,pp=un(({bufferMap:e,influence:t,stride:r,width:s,depth:i,offset:n})=>{const a=mn(jh).mul(r).add(n),o=a.div(s),u=a.sub(o.mul(s));return Bl(e,xn(u,o)).depth(i).xyz.mul(t)});class gp extends ui{static get type(){return"MorphNode"}constructor(e){super("void"),this.mesh=e,this.morphBaseInfluence=_a(1),this.updateType=Js.OBJECT}setup(e){const{geometry:r}=e,s=void 0!==r.morphAttributes.position,i=r.hasAttribute("normal")&&void 0!==r.morphAttributes.normal,n=r.morphAttributes.position||r.morphAttributes.normal||r.morphAttributes.color,a=void 0!==n?n.length:0,{texture:o,stride:u,size:l}=function(e){const r=void 0!==e.morphAttributes.position,s=void 0!==e.morphAttributes.normal,i=void 0!==e.morphAttributes.color,n=e.morphAttributes.position||e.morphAttributes.normal||e.morphAttributes.color,a=void 0!==n?n.length:0;let o=cp.get(e);if(void 0===o||o.count!==a){void 0!==o&&o.texture.dispose();const u=e.morphAttributes.position||[],l=e.morphAttributes.normal||[],d=e.morphAttributes.color||[];let c=0;!0===r&&(c=1),!0===s&&(c=2),!0===i&&(c=3);let h=e.attributes.position.count*c,p=1;const g=4096;h>g&&(p=Math.ceil(h/g),h=g);const m=new Float32Array(h*p*4*a),f=new q(m,h,p,a);f.type=j,f.needsUpdate=!0;const y=4*c;for(let x=0;x{const t=gn(0).toVar();this.mesh.count>1&&null!==this.mesh.morphTexture&&void 0!==this.mesh.morphTexture?t.assign(Bl(this.mesh.morphTexture,xn(mn(e).add(1),mn(Xh))).r):t.assign(yc("morphTargetInfluences","float").element(e).toVar()),cn(t.notEqual(0),()=>{!0===s&&Pd.addAssign(pp({bufferMap:o,influence:t,stride:u,width:d,depth:e,offset:mn(0)})),!0===i&&Wd.addAssign(pp({bufferMap:o,influence:t,stride:u,width:d,depth:e,offset:mn(1)}))})})}update(){const e=this.morphBaseInfluence;this.mesh.geometry.morphTargetsRelative?e.value=1:e.value=1-this.mesh.morphTargetInfluences.reduce((e,t)=>e+t,0)}}const mp=rn(gp).setParameterLength(1);class fp extends ui{static get type(){return"LightingNode"}constructor(){super("vec3"),this.isLightingNode=!0}}class yp extends fp{static get type(){return"AONode"}constructor(e=null){super(),this.aoNode=e}setup(e){e.context.ambientOcclusion.mulAssign(this.aoNode)}}class bp extends xu{static get type(){return"LightingContextNode"}constructor(e,t=null,r=null,s=null){super(e),this.lightingModel=t,this.backdropNode=r,this.backdropAlphaNode=s,this._value=null}getContext(){const{backdropNode:e,backdropAlphaNode:t}=this,r={directDiffuse:vn().toVar("directDiffuse"),directSpecular:vn().toVar("directSpecular"),indirectDiffuse:vn().toVar("indirectDiffuse"),indirectSpecular:vn().toVar("indirectSpecular")};return{radiance:vn().toVar("radiance"),irradiance:vn().toVar("irradiance"),iblIrradiance:vn().toVar("iblIrradiance"),ambientOcclusion:gn(1).toVar("ambientOcclusion"),reflectedLight:r,backdrop:e,backdropAlpha:t}}setup(e){return this.value=this._value||(this._value=this.getContext()),this.value.lightingModel=this.lightingModel||e.context.lightingModel,super.setup(e)}}const xp=rn(bp);class Tp extends fp{static get type(){return"IrradianceNode"}constructor(e){super(),this.node=e}setup(e){e.context.irradiance.addAssign(this.node)}}const _p=new t;class vp extends Fl{static get type(){return"ViewportTextureNode"}constructor(e=ql,t=null,r=null){let s=null;null===r?(s=new X,s.minFilter=K,r=s):s=r,super(r,e,t),this.generateMipmaps=!1,this.defaultFramebuffer=s,this.isOutputTextureNode=!0,this.updateBeforeType=Js.RENDER,this._cacheTextures=new WeakMap}getTextureForReference(e=null){let t,r;if(this.referenceNode?(t=this.referenceNode.defaultFramebuffer,r=this.referenceNode._cacheTextures):(t=this.defaultFramebuffer,r=this._cacheTextures),null===e)return t;if(!1===r.has(e)){const s=t.clone();r.set(e,s)}return r.get(e)}updateReference(e){const t=e.renderer.getRenderTarget();return this.value=this.getTextureForReference(t),this.value}updateBefore(e){const t=e.renderer,r=t.getRenderTarget();null===r?t.getDrawingBufferSize(_p):_p.set(r.width,r.height);const s=this.getTextureForReference(r);s.image.width===_p.width&&s.image.height===_p.height||(s.image.width=_p.width,s.image.height=_p.height,s.needsUpdate=!0);const i=s.generateMipmaps;s.generateMipmaps=this.generateMipmaps,t.copyFramebufferToTexture(s),s.generateMipmaps=i}clone(){const e=new this.constructor(this.uvNode,this.levelNode,this.value);return e.generateMipmaps=this.generateMipmaps,e}}const Np=rn(vp).setParameterLength(0,3),Sp=rn(vp,null,null,{generateMipmaps:!0}).setParameterLength(0,3),Rp=Sp(),Ep=(e=ql,t=null)=>Rp.sample(e,t);let Ap=null;class wp extends vp{static get type(){return"ViewportDepthTextureNode"}constructor(e=ql,t=null){null===Ap&&(Ap=new Y),super(e,t,Ap)}getTextureForReference(){return Ap}}const Cp=rn(wp).setParameterLength(0,2);class Mp extends ui{static get type(){return"ViewportDepthNode"}constructor(e,t=null){super("float"),this.scope=e,this.valueNode=t,this.isViewportDepthNode=!0}generate(e){const{scope:t}=this;return t===Mp.DEPTH_BASE?e.getFragDepth():super.generate(e)}setup({camera:e}){const{scope:t}=this,r=this.valueNode;let s=null;if(t===Mp.DEPTH_BASE)null!==r&&(s=Dp().assign(r));else if(t===Mp.DEPTH)s=e.isPerspectiveCamera?Lp(Id.z,td,rd):Fp(Id.z,td,rd);else if(t===Mp.LINEAR_DEPTH)if(null!==r)if(e.isPerspectiveCamera){const e=Pp(r,td,rd);s=Fp(e,td,rd)}else s=r;else s=Fp(Id.z,td,rd);return s}}Mp.DEPTH_BASE="depthBase",Mp.DEPTH="depth",Mp.LINEAR_DEPTH="linearDepth";const Fp=(e,t,r)=>e.add(t).div(t.sub(r)),Lp=(e,t,r)=>t.add(e).mul(r).div(r.sub(t).mul(e)),Pp=(e,t,r)=>t.mul(r).div(r.sub(t).mul(e).sub(r)),Bp=(e,t,r)=>{t=t.max(1e-6).toVar();const s=yo(e.negate().div(t)),i=yo(r.div(t));return s.div(i)},Dp=rn(Mp,Mp.DEPTH_BASE),Up=sn(Mp,Mp.DEPTH),Ip=rn(Mp,Mp.LINEAR_DEPTH).setParameterLength(0,1),Op=Ip(Cp());Up.assign=e=>Dp(e);class Vp extends ui{static get type(){return"ClippingNode"}constructor(e=Vp.DEFAULT){super(),this.scope=e}setup(e){super.setup(e);const t=e.clippingContext,{intersectionPlanes:r,unionPlanes:s}=t;return this.hardwareClipping=e.material.hardwareClipping,this.scope===Vp.ALPHA_TO_COVERAGE?this.setupAlphaToCoverage(r,s):this.scope===Vp.HARDWARE?this.setupHardwareClipping(s,e):this.setupDefault(r,s)}setupAlphaToCoverage(e,t){return un(()=>{const r=gn().toVar("distanceToPlane"),s=gn().toVar("distanceToGradient"),i=gn(1).toVar("clipOpacity"),n=t.length;if(!1===this.hardwareClipping&&n>0){const e=Vl(t).setGroup(ba);lp(n,({i:t})=>{const n=e.element(t);r.assign(Id.dot(n.xyz).negate().add(n.w)),s.assign(r.fwidth().div(2)),i.mulAssign(lu(s.negate(),s,r))})}const a=e.length;if(a>0){const t=Vl(e).setGroup(ba),n=gn(1).toVar("intersectionClipOpacity");lp(a,({i:e})=>{const i=t.element(e);r.assign(Id.dot(i.xyz).negate().add(i.w)),s.assign(r.fwidth().div(2)),n.mulAssign(lu(s.negate(),s,r).oneMinus())}),i.mulAssign(n.oneMinus())}On.a.mulAssign(i),On.a.equal(0).discard()})()}setupDefault(e,t){return un(()=>{const r=t.length;if(!1===this.hardwareClipping&&r>0){const e=Vl(t).setGroup(ba);lp(r,({i:t})=>{const r=e.element(t);Id.dot(r.xyz).greaterThan(r.w).discard()})}const s=e.length;if(s>0){const t=Vl(e).setGroup(ba),r=yn(!0).toVar("clipped");lp(s,({i:e})=>{const s=t.element(e);r.assign(Id.dot(s.xyz).greaterThan(s.w).and(r))}),r.discard()}})()}setupHardwareClipping(e,t){const r=e.length;return t.enableHardwareClipping(r),un(()=>{const s=Vl(e).setGroup(ba),i=Gl(t.getClipDistance());lp(r,({i:e})=>{const t=s.element(e),r=Id.dot(t.xyz).sub(t.w).negate();i.element(e).assign(r)})})()}}Vp.ALPHA_TO_COVERAGE="alphaToCoverage",Vp.DEFAULT="default",Vp.HARDWARE="hardware";const kp=un(([e])=>No(La(1e4,So(La(17,e.x).add(La(.1,e.y)))).mul(Ma(.1,Mo(So(La(13,e.y).add(e.x))))))),Gp=un(([e])=>kp(bn(kp(e.xy),e.z))),zp=un(([e])=>{const t=Ho(Lo(Do(e.xyz)),Lo(Uo(e.xyz))),r=gn(1).div(gn(.05).mul(t)).toVar("pixScale"),s=bn(mo(To(yo(r))),mo(_o(yo(r)))),i=bn(Gp(To(s.x.mul(e.xyz))),Gp(To(s.y.mul(e.xyz)))),n=No(yo(r)),a=Ma(La(n.oneMinus(),i.x),La(n,i.y)),o=Wo(n,n.oneMinus()),u=vn(a.mul(a).div(La(2,o).mul(Fa(1,o))),a.sub(La(.5,o)).div(Fa(1,o)),Fa(1,Fa(1,a).mul(Fa(1,a)).div(La(2,o).mul(Fa(1,o))))),l=a.lessThan(o.oneMinus()).select(a.lessThan(o).select(u.x,u.y),u.z);return au(l,1e-6,1)}).setLayout({name:"getAlphaHashThreshold",type:"float",inputs:[{name:"position",type:"vec3"}]});class $p extends Nl{static get type(){return"VertexColorNode"}constructor(e){super(null,"vec4"),this.isVertexColorNode=!0,this.index=e}getAttributeName(){const e=this.index;return"color"+(e>0?e:"")}generate(e){const t=this.getAttributeName(e);let r;return r=!0===e.hasGeometryAttribute(t)?super.generate(e):e.generateConst(this.nodeType,new s(1,1,1,1)),r}serialize(e){super.serialize(e),e.index=this.index}deserialize(e){super.deserialize(e),this.index=e.index}}const Wp=(e=0)=>new $p(e),Hp=un(([e,t])=>Wo(1,e.oneMinus().div(t)).oneMinus()).setLayout({name:"blendBurn",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),qp=un(([e,t])=>Wo(e.div(t.oneMinus()),1)).setLayout({name:"blendDodge",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),jp=un(([e,t])=>e.oneMinus().mul(t.oneMinus()).oneMinus()).setLayout({name:"blendScreen",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),Xp=un(([e,t])=>nu(e.mul(2).mul(t),e.oneMinus().mul(2).mul(t.oneMinus()).oneMinus(),qo(.5,e))).setLayout({name:"blendOverlay",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),Kp=un(([e,t])=>{const r=t.a.add(e.a.mul(t.a.oneMinus()));return En(t.rgb.mul(t.a).add(e.rgb.mul(e.a).mul(t.a.oneMinus())).div(r),r)}).setLayout({name:"blendColor",type:"vec4",inputs:[{name:"base",type:"vec4"},{name:"blend",type:"vec4"}]}),Yp=un(([e])=>En(e.rgb.mul(e.a),e.a),{color:"vec4",return:"vec4"}),Qp=un(([e])=>(cn(e.a.equal(0),()=>En(0)),En(e.rgb.div(e.a),e.a)),{color:"vec4",return:"vec4"});class Zp extends Q{static get type(){return"NodeMaterial"}get type(){return this.constructor.type}set type(e){}constructor(){super(),this.isNodeMaterial=!0,this.fog=!0,this.lights=!1,this.hardwareClipping=!1,this.lightsNode=null,this.envNode=null,this.aoNode=null,this.colorNode=null,this.normalNode=null,this.opacityNode=null,this.backdropNode=null,this.backdropAlphaNode=null,this.alphaTestNode=null,this.maskNode=null,this.maskShadowNode=null,this.positionNode=null,this.geometryNode=null,this.depthNode=null,this.receivedShadowPositionNode=null,this.castShadowPositionNode=null,this.receivedShadowNode=null,this.castShadowNode=null,this.outputNode=null,this.mrtNode=null,this.fragmentNode=null,this.vertexNode=null,this.contextNode=null}_getNodeChildren(){const e=[];for(const t of Object.getOwnPropertyNames(this)){if(!0===t.startsWith("_"))continue;const r=this[t];r&&!0===r.isNode&&e.push({property:t,childNode:r})}return e}customProgramCacheKey(){const e=[];for(const{property:t,childNode:r}of this._getNodeChildren())e.push(Us(t.slice(0,-4)),r.getCacheKey());return this.type+Is(e)}build(e){this.setup(e)}setupObserver(e){return new Bs(e)}setup(e){e.context.setupNormal=()=>Lu(this.setupNormal(e),"NORMAL","vec3"),e.context.setupPositionView=()=>this.setupPositionView(e),e.context.setupModelViewProjection=()=>this.setupModelViewProjection(e);const t=e.renderer,r=t.getRenderTarget();!0===t.contextNode.isContextNode?e.context={...e.context,...t.contextNode.getFlowContextData()}:o('NodeMaterial: "renderer.contextNode" must be an instance of `context()`.'),null!==this.contextNode&&(!0===this.contextNode.isContextNode?e.context={...e.context,...this.contextNode.getFlowContextData()}:o('NodeMaterial: "material.contextNode" must be an instance of `context()`.')),e.addStack();const s=this.setupVertex(e),i=Lu(this.vertexNode||s,"VERTEX");let n;e.context.clipSpace=i,e.stack.outputNode=i,this.setupHardwareClipping(e),null!==this.geometryNode&&(e.stack.outputNode=e.stack.outputNode.bypass(this.geometryNode)),e.addFlow("vertex",e.removeStack()),e.addStack();const a=this.setupClipping(e);if(!0!==this.depthWrite&&!0!==this.depthTest||(null!==r?!0===r.depthBuffer&&this.setupDepth(e):!0===t.depth&&this.setupDepth(e)),null===this.fragmentNode){this.setupDiffuseColor(e),this.setupVariants(e);const s=this.setupLighting(e);null!==a&&e.stack.addToStack(a);const i=En(s,On.a).max(0);n=this.setupOutput(e,i),ia.assign(n);const o=null!==this.outputNode;if(o&&(n=this.outputNode),e.context.getOutput&&(n=e.context.getOutput(n,e)),null!==r){const e=t.getMRT(),r=this.mrtNode;null!==e?(o&&ia.assign(n),n=e,null!==r&&(n=e.merge(r))):null!==r&&(n=r)}}else{let t=this.fragmentNode;!0!==t.isOutputStructNode&&(t=En(t)),n=this.setupOutput(e,t)}e.stack.outputNode=n,e.addFlow("fragment",e.removeStack()),e.observer=this.setupObserver(e)}setupClipping(e){if(null===e.clippingContext)return null;const{unionPlanes:t,intersectionPlanes:r}=e.clippingContext;let s=null;if(t.length>0||r.length>0){const t=e.renderer.currentSamples;this.alphaToCoverage&&t>1?s=new Vp(Vp.ALPHA_TO_COVERAGE):e.stack.addToStack(new Vp)}return s}setupHardwareClipping(e){if(this.hardwareClipping=!1,null===e.clippingContext)return;const t=e.clippingContext.unionPlanes.length;t>0&&t<=8&&e.isAvailable("clipDistance")&&(e.stack.addToStack(new Vp(Vp.HARDWARE)),this.hardwareClipping=!0)}setupDepth(e){const{renderer:t,camera:r}=e;let s=this.depthNode;if(null===s){const e=t.getMRT();e&&e.has("depth")?s=e.get("depth"):!0===t.logarithmicDepthBuffer&&(s=r.isPerspectiveCamera?Bp(Id.z,td,rd):Fp(Id.z,td,rd))}null!==s&&Up.assign(s).toStack()}setupPositionView(){return Ad.mul(Pd).xyz}setupModelViewProjection(){return sd.mul(Id)}setupVertex(e){return e.addStack(),this.setupPosition(e),e.context.position=e.removeStack(),Gh}setupPosition(e){const{object:t,geometry:r}=e;if((r.morphAttributes.position||r.morphAttributes.normal||r.morphAttributes.color)&&mp(t).toStack(),!0===t.isSkinnedMesh&&op(t).toStack(),this.displacementMap){const e=Tc("displacementMap","texture"),t=Tc("displacementScale","float"),r=Tc("displacementBias","float");Pd.addAssign(Wd.normalize().mul(e.x.mul(t).add(r)))}return t.isBatchedMesh&&ip(t).toStack(),t.isInstancedMesh&&t.instanceMatrix&&!0===t.instanceMatrix.isInstancedBufferAttribute&&rp(t).toStack(),null!==this.positionNode&&Pd.assign(Lu(this.positionNode,"POSITION","vec3")),Pd}setupDiffuseColor(e){const{object:t,geometry:r}=e;null!==this.maskNode&&yn(this.maskNode).not().discard();let s=this.colorNode?En(this.colorNode):ih;if(!0===this.vertexColors&&r.hasAttribute("color")&&(s=s.mul(Wp())),t.instanceColor){s=In("vec3","vInstanceColor").mul(s)}if(t.isBatchedMesh&&t._colorsTexture){s=In("vec3","vBatchColor").mul(s)}On.assign(s);const i=this.opacityNode?gn(this.opacityNode):oh;On.a.assign(On.a.mul(i));let n=null;(null!==this.alphaTestNode||this.alphaTest>0)&&(n=null!==this.alphaTestNode?gn(this.alphaTestNode):sh,!0===this.alphaToCoverage?(On.a=lu(n,n.add(ko(On.a)),On.a),On.a.lessThanEqual(0).discard()):On.a.lessThanEqual(n).discard()),!0===this.alphaHash&&On.a.lessThan(zp(Pd)).discard(),e.isOpaque()&&On.a.assign(1)}setupVariants(){}setupOutgoingLight(){return!0===this.lights?vn(0):On.rgb}setupNormal(){return this.normalNode?vn(this.normalNode):mh}setupEnvironment(){let e=null;return this.envNode?e=this.envNode:this.envMap&&(e=this.envMap.isCubeTexture?Tc("envMap","cubeTexture"):Tc("envMap","texture")),e}setupLightMap(e){let t=null;return e.material.lightMap&&(t=new Tp(Oh)),t}setupLights(e){const t=[],r=this.setupEnvironment(e);r&&r.isLightingNode&&t.push(r);const s=this.setupLightMap(e);s&&s.isLightingNode&&t.push(s);let i=this.aoNode;null===i&&e.material.aoMap&&(i=Vh),e.context.getAO&&(i=e.context.getAO(i,e)),i&&t.push(new yp(i));let n=this.lightsNode||e.lightsNode;return t.length>0&&(n=e.renderer.lighting.createNode([...n.getLights(),...t])),n}setupLightingModel(){}setupLighting(e){const{material:t}=e,{backdropNode:r,backdropAlphaNode:s,emissiveNode:i}=this,n=!0===this.lights||null!==this.lightsNode?this.setupLights(e):null;let a=this.setupOutgoingLight(e);if(n&&n.getScope().hasLights){const t=this.setupLightingModel(e)||null;a=xp(n,t,r,s)}else null!==r&&(a=vn(null!==s?nu(a,r,s):r));return(i&&!0===i.isNode||t.emissive&&!0===t.emissive.isColor)&&(kn.assign(vn(i||ah)),a=a.add(kn)),a}setupFog(e,t){const r=e.fogNode;return r&&(ia.assign(t),t=En(r.toVar())),t}setupPremultipliedAlpha(e,t){return Yp(t)}setupOutput(e,t){return!0===this.fog&&(t=this.setupFog(e,t)),!0===this.premultipliedAlpha&&(t=this.setupPremultipliedAlpha(e,t)),t}setDefaultValues(e){for(const t in e){const r=e[t];void 0===this[t]&&(this[t]=r,r&&r.clone&&(this[t]=r.clone()))}const t=Object.getOwnPropertyDescriptors(e.constructor.prototype);for(const e in t)void 0===Object.getOwnPropertyDescriptor(this.constructor.prototype,e)&&void 0!==t[e].get&&Object.defineProperty(this.constructor.prototype,e,t[e])}toJSON(e){const t=void 0===e||"string"==typeof e;t&&(e={textures:{},images:{},nodes:{}});const r=Q.prototype.toJSON.call(this,e);r.inputNodes={};for(const{property:t,childNode:s}of this._getNodeChildren())r.inputNodes[t]=s.toJSON(e).uuid;function s(e){const t=[];for(const r in e){const s=e[r];delete s.metadata,t.push(s)}return t}if(t){const t=s(e.textures),i=s(e.images),n=s(e.nodes);t.length>0&&(r.textures=t),i.length>0&&(r.images=i),n.length>0&&(r.nodes=n)}return r}copy(e){return this.lightsNode=e.lightsNode,this.envNode=e.envNode,this.aoNode=e.aoNode,this.colorNode=e.colorNode,this.normalNode=e.normalNode,this.opacityNode=e.opacityNode,this.backdropNode=e.backdropNode,this.backdropAlphaNode=e.backdropAlphaNode,this.alphaTestNode=e.alphaTestNode,this.maskNode=e.maskNode,this.maskShadowNode=e.maskShadowNode,this.positionNode=e.positionNode,this.geometryNode=e.geometryNode,this.depthNode=e.depthNode,this.receivedShadowPositionNode=e.receivedShadowPositionNode,this.castShadowPositionNode=e.castShadowPositionNode,this.receivedShadowNode=e.receivedShadowNode,this.castShadowNode=e.castShadowNode,this.outputNode=e.outputNode,this.mrtNode=e.mrtNode,this.fragmentNode=e.fragmentNode,this.vertexNode=e.vertexNode,this.contextNode=e.contextNode,super.copy(e)}}const Jp=new Z;class eg extends Zp{static get type(){return"LineBasicNodeMaterial"}constructor(e){super(),this.isLineBasicNodeMaterial=!0,this.setDefaultValues(Jp),this.setValues(e)}}const tg=new J;class rg extends Zp{static get type(){return"LineDashedNodeMaterial"}constructor(e){super(),this.isLineDashedNodeMaterial=!0,this.setDefaultValues(tg),this.dashOffset=0,this.offsetNode=null,this.dashScaleNode=null,this.dashSizeNode=null,this.gapSizeNode=null,this.setValues(e)}setupVariants(){const e=this.offsetNode?gn(this.offsetNode):Dh,t=this.dashScaleNode?gn(this.dashScaleNode):Fh,r=this.dashSizeNode?gn(this.dashSizeNode):Lh,s=this.gapSizeNode?gn(this.gapSizeNode):Ph;na.assign(r),aa.assign(s);const i=Bu(Sl("lineDistance").mul(t));(e?i.add(e):i).mod(na.add(aa)).greaterThan(na).discard()}}const sg=new J;class ig extends Zp{static get type(){return"Line2NodeMaterial"}constructor(e={}){super(),this.isLine2NodeMaterial=!0,this.setDefaultValues(sg),this.vertexColors=e.vertexColors,this.dashOffset=0,this.lineColorNode=null,this.offsetNode=null,this.dashScaleNode=null,this.dashSizeNode=null,this.gapSizeNode=null,this.blending=ee,this._useDash=e.dashed,this._useAlphaToCoverage=!0,this._useWorldUnits=!1,this.setValues(e)}setup(e){const{renderer:t}=e,r=this._useAlphaToCoverage,s=this.vertexColors,i=this._useDash,n=this._useWorldUnits,a=un(({start:e,end:t})=>{const r=sd.element(2).element(2),s=sd.element(3).element(2).mul(-.5).div(r).sub(e.z).div(t.z.sub(e.z));return En(nu(e.xyz,t.xyz,s),t.w)}).setLayout({name:"trimSegment",type:"vec4",inputs:[{name:"start",type:"vec4"},{name:"end",type:"vec4"}]});this.vertexNode=un(()=>{const e=Sl("instanceStart"),t=Sl("instanceEnd"),r=En(Ad.mul(En(e,1))).toVar("start"),s=En(Ad.mul(En(t,1))).toVar("end");if(i){const e=this.dashScaleNode?gn(this.dashScaleNode):Fh,t=this.offsetNode?gn(this.offsetNode):Dh,r=Sl("instanceDistanceStart"),s=Sl("instanceDistanceEnd");let i=Ld.y.lessThan(.5).select(e.mul(r),e.mul(s));i=i.add(t),In("float","lineDistance").assign(i)}n&&(In("vec3","worldStart").assign(r.xyz),In("vec3","worldEnd").assign(s.xyz));const o=Kl.z.div(Kl.w),u=sd.element(2).element(3).equal(-1);cn(u,()=>{cn(r.z.lessThan(0).and(s.z.greaterThan(0)),()=>{s.assign(a({start:r,end:s}))}).ElseIf(s.z.lessThan(0).and(r.z.greaterThanEqual(0)),()=>{r.assign(a({start:s,end:r}))})});const l=sd.mul(r),d=sd.mul(s),c=l.xyz.div(l.w),h=d.xyz.div(d.w),p=h.xy.sub(c.xy).toVar();p.x.assign(p.x.mul(o)),p.assign(p.normalize());const g=En().toVar();if(n){const e=s.xyz.sub(r.xyz).normalize(),t=nu(r.xyz,s.xyz,.5).normalize(),n=e.cross(t).normalize(),a=e.cross(n),o=In("vec4","worldPos");o.assign(Ld.y.lessThan(.5).select(r,s));const u=Bh.mul(.5);o.addAssign(En(Ld.x.lessThan(0).select(n.mul(u),n.mul(u).negate()),0)),i||(o.addAssign(En(Ld.y.lessThan(.5).select(e.mul(u).negate(),e.mul(u)),0)),o.addAssign(En(a.mul(u),0)),cn(Ld.y.greaterThan(1).or(Ld.y.lessThan(0)),()=>{o.subAssign(En(a.mul(2).mul(u),0))})),g.assign(sd.mul(o));const l=vn().toVar();l.assign(Ld.y.lessThan(.5).select(c,h)),g.z.assign(l.z.mul(g.w))}else{const e=bn(p.y,p.x.negate()).toVar("offset");p.x.assign(p.x.div(o)),e.x.assign(e.x.div(o)),e.assign(Ld.x.lessThan(0).select(e.negate(),e)),cn(Ld.y.lessThan(0),()=>{e.assign(e.sub(p))}).ElseIf(Ld.y.greaterThan(1),()=>{e.assign(e.add(p))}),e.assign(e.mul(Bh)),e.assign(e.div(Kl.w.div(Hl))),g.assign(Ld.y.lessThan(.5).select(l,d)),e.assign(e.mul(g.w)),g.assign(g.add(En(e,0,0)))}return g})();const o=un(({p1:e,p2:t,p3:r,p4:s})=>{const i=e.sub(r),n=s.sub(r),a=t.sub(e),o=i.dot(n),u=n.dot(a),l=i.dot(a),d=n.dot(n),c=a.dot(a).mul(d).sub(u.mul(u)),h=o.mul(u).sub(l.mul(d)).div(c).clamp(),p=o.add(u.mul(h)).div(d).clamp();return bn(h,p)});if(this.colorNode=un(()=>{const e=Rl();if(i){const t=this.dashSizeNode?gn(this.dashSizeNode):Lh,r=this.gapSizeNode?gn(this.gapSizeNode):Ph;na.assign(t),aa.assign(r);const s=In("float","lineDistance");e.y.lessThan(-1).or(e.y.greaterThan(1)).discard(),s.mod(na.add(aa)).greaterThan(na).discard()}const a=gn(1).toVar("alpha");if(n){const e=In("vec3","worldStart"),s=In("vec3","worldEnd"),n=In("vec4","worldPos").xyz.normalize().mul(1e5),u=s.sub(e),l=o({p1:e,p2:s,p3:vn(0,0,0),p4:n}),d=e.add(u.mul(l.x)),c=n.mul(l.y),h=d.sub(c).length().div(Bh);if(!i)if(r&&t.currentSamples>0){const e=h.fwidth();a.assign(lu(e.negate().add(.5),e.add(.5),h).oneMinus())}else h.greaterThan(.5).discard()}else if(r&&t.currentSamples>0){const t=e.x,r=e.y.greaterThan(0).select(e.y.sub(1),e.y.add(1)),s=t.mul(t).add(r.mul(r)),i=gn(s.fwidth()).toVar("dlen");cn(e.y.abs().greaterThan(1),()=>{a.assign(lu(i.oneMinus(),i.add(1),s).oneMinus())})}else cn(e.y.abs().greaterThan(1),()=>{const t=e.x,r=e.y.greaterThan(0).select(e.y.sub(1),e.y.add(1));t.mul(t).add(r.mul(r)).greaterThan(1).discard()});let u;if(this.lineColorNode)u=this.lineColorNode;else if(s){const e=Sl("instanceColorStart"),t=Sl("instanceColorEnd");u=Ld.y.lessThan(.5).select(e,t).mul(ih)}else u=ih;return En(u,a)})(),this.transparent){const e=this.opacityNode?gn(this.opacityNode):oh;this.outputNode=En(this.colorNode.rgb.mul(e).add(Ep().rgb.mul(e.oneMinus())),this.colorNode.a)}super.setup(e)}get worldUnits(){return this._useWorldUnits}set worldUnits(e){this._useWorldUnits!==e&&(this._useWorldUnits=e,this.needsUpdate=!0)}get dashed(){return this._useDash}set dashed(e){this._useDash!==e&&(this._useDash=e,this.needsUpdate=!0)}get alphaToCoverage(){return this._useAlphaToCoverage}set alphaToCoverage(e){this._useAlphaToCoverage!==e&&(this._useAlphaToCoverage=e,this.needsUpdate=!0)}}const ng=new te;class ag extends Zp{static get type(){return"MeshNormalNodeMaterial"}constructor(e){super(),this.isMeshNormalNodeMaterial=!0,this.setDefaultValues(ng),this.setValues(e)}setupDiffuseColor(){const e=this.opacityNode?gn(this.opacityNode):oh;On.assign(Gu(En(jc(Xd),e),re))}}const og=un(([e=Ud])=>{const t=e.z.atan(e.x).mul(1/(2*Math.PI)).add(.5),r=e.y.clamp(-1,1).asin().mul(1/Math.PI).add(.5);return bn(t,r)});class ug extends se{constructor(e=1,t={}){super(e,t),this.isCubeRenderTarget=!0}fromEquirectangularTexture(e,t){const r=t.minFilter,s=t.generateMipmaps;t.generateMipmaps=!0,this.texture.type=t.type,this.texture.colorSpace=t.colorSpace,this.texture.generateMipmaps=t.generateMipmaps,this.texture.minFilter=t.minFilter,this.texture.magFilter=t.magFilter;const i=new ie(5,5,5),n=og(Ud),a=new Zp;a.colorNode=Pl(t,n,0),a.side=M,a.blending=ee;const o=new ne(i,a),u=new ae;u.add(o),t.minFilter===K&&(t.minFilter=oe);const l=new ue(1,10,this),d=e.getMRT();return e.setMRT(null),l.update(e,u),e.setMRT(d),t.minFilter=r,t.currentGenerateMipmaps=s,o.geometry.dispose(),o.material.dispose(),this}}const lg=new WeakMap;class dg extends ci{static get type(){return"CubeMapNode"}constructor(e){super("vec3"),this.envNode=e,this._cubeTexture=null,this._cubeTextureNode=gc(null);const t=new P;t.isRenderTargetTexture=!0,this._defaultTexture=t,this.updateBeforeType=Js.RENDER}updateBefore(e){const{renderer:t,material:r}=e,s=this.envNode;if(s.isTextureNode||s.isMaterialReferenceNode){const e=s.isTextureNode?s.value:r[s.property];if(e&&e.isTexture){const r=e.mapping;if(r===le||r===de){if(lg.has(e)){const t=lg.get(e);hg(t,e.mapping),this._cubeTexture=t}else{const r=e.image;if(function(e){return null!=e&&e.height>0}(r)){const s=new ug(r.height);s.fromEquirectangularTexture(t,e),hg(s.texture,e.mapping),this._cubeTexture=s.texture,lg.set(e,s.texture),e.addEventListener("dispose",cg)}else this._cubeTexture=this._defaultTexture}this._cubeTextureNode.value=this._cubeTexture}else this._cubeTextureNode=this.envNode}}}setup(e){return this.updateBefore(e),this._cubeTextureNode}}function cg(e){const t=e.target;t.removeEventListener("dispose",cg);const r=lg.get(t);void 0!==r&&(lg.delete(t),r.dispose())}function hg(e,t){t===le?e.mapping=B:t===de&&(e.mapping=D)}const pg=rn(dg).setParameterLength(1);class gg extends fp{static get type(){return"BasicEnvironmentNode"}constructor(e=null){super(),this.envNode=e}setup(e){e.context.environment=pg(this.envNode)}}class mg extends fp{static get type(){return"BasicLightMapNode"}constructor(e=null){super(),this.lightMapNode=e}setup(e){const t=gn(1/Math.PI);e.context.irradianceLightMap=this.lightMapNode.mul(t)}}class fg{start(e){e.lightsNode.setupLights(e,e.lightsNode.getLightNodes(e)),this.indirect(e)}finish(){}direct(){}directRectArea(){}indirect(){}ambientOcclusion(){}}class yg extends fg{constructor(){super()}indirect({context:e}){const t=e.ambientOcclusion,r=e.reflectedLight,s=e.irradianceLightMap;r.indirectDiffuse.assign(En(0)),s?r.indirectDiffuse.addAssign(s):r.indirectDiffuse.addAssign(En(1,1,1,0)),r.indirectDiffuse.mulAssign(t),r.indirectDiffuse.mulAssign(On.rgb)}finish(e){const{material:t,context:r}=e,s=r.outgoingLight,i=e.context.environment;if(i)switch(t.combine){case pe:s.rgb.assign(nu(s.rgb,s.rgb.mul(i.rgb),ch.mul(hh)));break;case he:s.rgb.assign(nu(s.rgb,i.rgb,ch.mul(hh)));break;case ce:s.rgb.addAssign(i.rgb.mul(ch.mul(hh)));break;default:d("BasicLightingModel: Unsupported .combine value:",t.combine)}}}const bg=new ge;class xg extends Zp{static get type(){return"MeshBasicNodeMaterial"}constructor(e){super(),this.isMeshBasicNodeMaterial=!0,this.lights=!0,this.setDefaultValues(bg),this.setValues(e)}setupNormal(){return zd(qd)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new gg(t):null}setupLightMap(e){let t=null;return e.material.lightMap&&(t=new mg(Oh)),t}setupOutgoingLight(){return On.rgb}setupLightingModel(){return new yg}}const Tg=un(({f0:e,f90:t,dotVH:r})=>{const s=r.mul(-5.55473).sub(6.98316).mul(r).exp2();return e.mul(s.oneMinus()).add(t.mul(s))}),_g=un(e=>e.diffuseColor.mul(1/Math.PI)),vg=un(({dotNH:e})=>sa.mul(gn(.5)).add(1).mul(gn(1/Math.PI)).mul(e.pow(sa))),Ng=un(({lightDirection:e})=>{const t=e.add(Od).normalize(),r=Xd.dot(t).clamp(),s=Od.dot(t).clamp(),i=Tg({f0:ea,f90:1,dotVH:s}),n=gn(.25),a=vg({dotNH:r});return i.mul(n).mul(a)});class Sg extends yg{constructor(e=!0){super(),this.specular=e}direct({lightDirection:e,lightColor:t,reflectedLight:r}){const s=Xd.dot(e).clamp().mul(t);r.directDiffuse.addAssign(s.mul(_g({diffuseColor:On.rgb}))),!0===this.specular&&r.directSpecular.addAssign(s.mul(Ng({lightDirection:e})).mul(ch))}indirect(e){const{ambientOcclusion:t,irradiance:r,reflectedLight:s}=e.context;s.indirectDiffuse.addAssign(r.mul(_g({diffuseColor:On}))),s.indirectDiffuse.mulAssign(t)}}const Rg=new me;class Eg extends Zp{static get type(){return"MeshLambertNodeMaterial"}constructor(e){super(),this.isMeshLambertNodeMaterial=!0,this.lights=!0,this.setDefaultValues(Rg),this.setValues(e)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new gg(t):null}setupLightingModel(){return new Sg(!1)}}const Ag=new fe;class wg extends Zp{static get type(){return"MeshPhongNodeMaterial"}constructor(e){super(),this.isMeshPhongNodeMaterial=!0,this.lights=!0,this.shininessNode=null,this.specularNode=null,this.setDefaultValues(Ag),this.setValues(e)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new gg(t):null}setupLightingModel(){return new Sg}setupVariants(){const e=(this.shininessNode?gn(this.shininessNode):nh).max(1e-4);sa.assign(e);const t=this.specularNode||uh;ea.assign(t)}copy(e){return this.shininessNode=e.shininessNode,this.specularNode=e.specularNode,super.copy(e)}}const Cg=un(e=>{if(!1===e.geometry.hasAttribute("normal"))return gn(0);const t=qd.dFdx().abs().max(qd.dFdy().abs());return t.x.max(t.y).max(t.z)}),Mg=un(e=>{const{roughness:t}=e,r=Cg();let s=t.max(.0525);return s=s.add(r),s=s.min(1),s}),Fg=un(({alpha:e,dotNL:t,dotNV:r})=>{const s=e.pow2(),i=t.mul(s.add(s.oneMinus().mul(r.pow2())).sqrt()),n=r.mul(s.add(s.oneMinus().mul(t.pow2())).sqrt());return Pa(.5,i.add(n).max(so))}).setLayout({name:"V_GGX_SmithCorrelated",type:"float",inputs:[{name:"alpha",type:"float"},{name:"dotNL",type:"float"},{name:"dotNV",type:"float"}]}),Lg=un(({alphaT:e,alphaB:t,dotTV:r,dotBV:s,dotTL:i,dotBL:n,dotNV:a,dotNL:o})=>{const u=o.mul(vn(e.mul(r),t.mul(s),a).length()),l=a.mul(vn(e.mul(i),t.mul(n),o).length());return Pa(.5,u.add(l))}).setLayout({name:"V_GGX_SmithCorrelated_Anisotropic",type:"float",inputs:[{name:"alphaT",type:"float",qualifier:"in"},{name:"alphaB",type:"float",qualifier:"in"},{name:"dotTV",type:"float",qualifier:"in"},{name:"dotBV",type:"float",qualifier:"in"},{name:"dotTL",type:"float",qualifier:"in"},{name:"dotBL",type:"float",qualifier:"in"},{name:"dotNV",type:"float",qualifier:"in"},{name:"dotNL",type:"float",qualifier:"in"}]}),Pg=un(({alpha:e,dotNH:t})=>{const r=e.pow2(),s=t.pow2().mul(r.oneMinus()).oneMinus();return r.div(s.pow2()).mul(1/Math.PI)}).setLayout({name:"D_GGX",type:"float",inputs:[{name:"alpha",type:"float"},{name:"dotNH",type:"float"}]}),Bg=gn(1/Math.PI),Dg=un(({alphaT:e,alphaB:t,dotNH:r,dotTH:s,dotBH:i})=>{const n=e.mul(t),a=vn(t.mul(s),e.mul(i),n.mul(r)),o=a.dot(a),u=n.div(o);return Bg.mul(n.mul(u.pow2()))}).setLayout({name:"D_GGX_Anisotropic",type:"float",inputs:[{name:"alphaT",type:"float",qualifier:"in"},{name:"alphaB",type:"float",qualifier:"in"},{name:"dotNH",type:"float",qualifier:"in"},{name:"dotTH",type:"float",qualifier:"in"},{name:"dotBH",type:"float",qualifier:"in"}]}),Ug=un(({lightDirection:e,f0:t,f90:r,roughness:s,f:i,normalView:n=Xd,USE_IRIDESCENCE:a,USE_ANISOTROPY:o})=>{const u=s.pow2(),l=e.add(Od).normalize(),d=n.dot(e).clamp(),c=n.dot(Od).clamp(),h=n.dot(l).clamp(),p=Od.dot(l).clamp();let g,m,f=Tg({f0:t,f90:r,dotVH:p});if(Ki(a)&&(f=jn.mix(f,i)),Ki(o)){const t=Zn.dot(e),r=Zn.dot(Od),s=Zn.dot(l),i=Jn.dot(e),n=Jn.dot(Od),a=Jn.dot(l);g=Lg({alphaT:Yn,alphaB:u,dotTV:r,dotBV:n,dotTL:t,dotBL:i,dotNV:c,dotNL:d}),m=Dg({alphaT:Yn,alphaB:u,dotNH:h,dotTH:s,dotBH:a})}else g=Fg({alpha:u,dotNL:d,dotNV:c}),m=Pg({alpha:u,dotNH:h});return f.mul(g).mul(m)}),Ig=new Uint16Array([12469,15057,12620,14925,13266,14620,13807,14376,14323,13990,14545,13625,14713,13328,14840,12882,14931,12528,14996,12233,15039,11829,15066,11525,15080,11295,15085,10976,15082,10705,15073,10495,13880,14564,13898,14542,13977,14430,14158,14124,14393,13732,14556,13410,14702,12996,14814,12596,14891,12291,14937,11834,14957,11489,14958,11194,14943,10803,14921,10506,14893,10278,14858,9960,14484,14039,14487,14025,14499,13941,14524,13740,14574,13468,14654,13106,14743,12678,14818,12344,14867,11893,14889,11509,14893,11180,14881,10751,14852,10428,14812,10128,14765,9754,14712,9466,14764,13480,14764,13475,14766,13440,14766,13347,14769,13070,14786,12713,14816,12387,14844,11957,14860,11549,14868,11215,14855,10751,14825,10403,14782,10044,14729,9651,14666,9352,14599,9029,14967,12835,14966,12831,14963,12804,14954,12723,14936,12564,14917,12347,14900,11958,14886,11569,14878,11247,14859,10765,14828,10401,14784,10011,14727,9600,14660,9289,14586,8893,14508,8533,15111,12234,15110,12234,15104,12216,15092,12156,15067,12010,15028,11776,14981,11500,14942,11205,14902,10752,14861,10393,14812,9991,14752,9570,14682,9252,14603,8808,14519,8445,14431,8145,15209,11449,15208,11451,15202,11451,15190,11438,15163,11384,15117,11274,15055,10979,14994,10648,14932,10343,14871,9936,14803,9532,14729,9218,14645,8742,14556,8381,14461,8020,14365,7603,15273,10603,15272,10607,15267,10619,15256,10631,15231,10614,15182,10535,15118,10389,15042,10167,14963,9787,14883,9447,14800,9115,14710,8665,14615,8318,14514,7911,14411,7507,14279,7198,15314,9675,15313,9683,15309,9712,15298,9759,15277,9797,15229,9773,15166,9668,15084,9487,14995,9274,14898,8910,14800,8539,14697,8234,14590,7790,14479,7409,14367,7067,14178,6621,15337,8619,15337,8631,15333,8677,15325,8769,15305,8871,15264,8940,15202,8909,15119,8775,15022,8565,14916,8328,14804,8009,14688,7614,14569,7287,14448,6888,14321,6483,14088,6171,15350,7402,15350,7419,15347,7480,15340,7613,15322,7804,15287,7973,15229,8057,15148,8012,15046,7846,14933,7611,14810,7357,14682,7069,14552,6656,14421,6316,14251,5948,14007,5528,15356,5942,15356,5977,15353,6119,15348,6294,15332,6551,15302,6824,15249,7044,15171,7122,15070,7050,14949,6861,14818,6611,14679,6349,14538,6067,14398,5651,14189,5311,13935,4958,15359,4123,15359,4153,15356,4296,15353,4646,15338,5160,15311,5508,15263,5829,15188,6042,15088,6094,14966,6001,14826,5796,14678,5543,14527,5287,14377,4985,14133,4586,13869,4257,15360,1563,15360,1642,15358,2076,15354,2636,15341,3350,15317,4019,15273,4429,15203,4732,15105,4911,14981,4932,14836,4818,14679,4621,14517,4386,14359,4156,14083,3795,13808,3437,15360,122,15360,137,15358,285,15355,636,15344,1274,15322,2177,15281,2765,15215,3223,15120,3451,14995,3569,14846,3567,14681,3466,14511,3305,14344,3121,14037,2800,13753,2467,15360,0,15360,1,15359,21,15355,89,15346,253,15325,479,15287,796,15225,1148,15133,1492,15008,1749,14856,1882,14685,1886,14506,1783,14324,1608,13996,1398,13702,1183]);let Og=null;const Vg=un(({roughness:e,dotNV:t})=>{null===Og&&(Og=new ye(Ig,16,16,G,be),Og.name="DFG_LUT",Og.minFilter=oe,Og.magFilter=oe,Og.wrapS=xe,Og.wrapT=xe,Og.generateMipmaps=!1,Og.needsUpdate=!0);const r=bn(e,t);return Pl(Og,r).rg}),kg=un(({lightDirection:e,f0:t,f90:r,roughness:s,f:i,USE_IRIDESCENCE:n,USE_ANISOTROPY:a})=>{const o=Ug({lightDirection:e,f0:t,f90:r,roughness:s,f:i,USE_IRIDESCENCE:n,USE_ANISOTROPY:a}),u=Xd.dot(e).clamp(),l=Xd.dot(Od).clamp(),d=Vg({roughness:s,dotNV:l}),c=Vg({roughness:s,dotNV:u}),h=t.mul(d.x).add(r.mul(d.y)),p=t.mul(c.x).add(r.mul(c.y)),g=d.x.add(d.y),m=c.x.add(c.y),f=gn(1).sub(g),y=gn(1).sub(m),b=t.add(t.oneMinus().mul(.047619)),x=h.mul(p).mul(b).div(gn(1).sub(f.mul(y).mul(b).mul(b)).add(so)),T=f.mul(y),_=x.mul(T);return o.add(_)}),Gg=un(e=>{const{dotNV:t,specularColor:r,specularF90:s,roughness:i}=e,n=Vg({dotNV:t,roughness:i});return r.mul(n.x).add(s.mul(n.y))}),zg=un(({f:e,f90:t,dotVH:r})=>{const s=r.oneMinus().saturate(),i=s.mul(s),n=s.mul(i,i).clamp(0,.9999);return e.sub(vn(t).mul(n)).div(n.oneMinus())}).setLayout({name:"Schlick_to_F0",type:"vec3",inputs:[{name:"f",type:"vec3"},{name:"f90",type:"float"},{name:"dotVH",type:"float"}]}),$g=un(({roughness:e,dotNH:t})=>{const r=e.pow2(),s=gn(1).div(r),i=t.pow2().oneMinus().max(.0078125);return gn(2).add(s).mul(i.pow(s.mul(.5))).div(2*Math.PI)}).setLayout({name:"D_Charlie",type:"float",inputs:[{name:"roughness",type:"float"},{name:"dotNH",type:"float"}]}),Wg=un(({dotNV:e,dotNL:t})=>gn(1).div(gn(4).mul(t.add(e).sub(t.mul(e))))).setLayout({name:"V_Neubelt",type:"float",inputs:[{name:"dotNV",type:"float"},{name:"dotNL",type:"float"}]}),Hg=un(({lightDirection:e})=>{const t=e.add(Od).normalize(),r=Xd.dot(e).clamp(),s=Xd.dot(Od).clamp(),i=Xd.dot(t).clamp(),n=$g({roughness:qn,dotNH:i}),a=Wg({dotNV:s,dotNL:r});return Hn.mul(n).mul(a)}),qg=un(({N:e,V:t,roughness:r})=>{const s=e.dot(t).saturate(),i=bn(r,s.oneMinus().sqrt());return i.assign(i.mul(.984375).add(.0078125)),i}).setLayout({name:"LTC_Uv",type:"vec2",inputs:[{name:"N",type:"vec3"},{name:"V",type:"vec3"},{name:"roughness",type:"float"}]}),jg=un(({f:e})=>{const t=e.length();return Ho(t.mul(t).add(e.z).div(t.add(1)),0)}).setLayout({name:"LTC_ClippedSphereFormFactor",type:"float",inputs:[{name:"f",type:"vec3"}]}),Xg=un(({v1:e,v2:t})=>{const r=e.dot(t),s=r.abs().toVar(),i=s.mul(.0145206).add(.4965155).mul(s).add(.8543985).toVar(),n=s.add(4.1616724).mul(s).add(3.417594).toVar(),a=i.div(n),o=r.greaterThan(0).select(a,Ho(r.mul(r).oneMinus(),1e-7).inverseSqrt().mul(.5).sub(a));return e.cross(t).mul(o)}).setLayout({name:"LTC_EdgeVectorFormFactor",type:"vec3",inputs:[{name:"v1",type:"vec3"},{name:"v2",type:"vec3"}]}),Kg=un(({N:e,V:t,P:r,mInv:s,p0:i,p1:n,p2:a,p3:o})=>{const u=n.sub(i).toVar(),l=o.sub(i).toVar(),d=u.cross(l),c=vn().toVar();return cn(d.dot(r.sub(i)).greaterThanEqual(0),()=>{const u=t.sub(e.mul(t.dot(e))).normalize(),l=e.cross(u).negate(),d=s.mul(Fn(u,l,e).transpose()).toVar(),h=d.mul(i.sub(r)).normalize().toVar(),p=d.mul(n.sub(r)).normalize().toVar(),g=d.mul(a.sub(r)).normalize().toVar(),m=d.mul(o.sub(r)).normalize().toVar(),f=vn(0).toVar();f.addAssign(Xg({v1:h,v2:p})),f.addAssign(Xg({v1:p,v2:g})),f.addAssign(Xg({v1:g,v2:m})),f.addAssign(Xg({v1:m,v2:h})),c.assign(vn(jg({f:f})))}),c}).setLayout({name:"LTC_Evaluate",type:"vec3",inputs:[{name:"N",type:"vec3"},{name:"V",type:"vec3"},{name:"P",type:"vec3"},{name:"mInv",type:"mat3"},{name:"p0",type:"vec3"},{name:"p1",type:"vec3"},{name:"p2",type:"vec3"},{name:"p3",type:"vec3"}]}),Yg=un(({P:e,p0:t,p1:r,p2:s,p3:i})=>{const n=r.sub(t).toVar(),a=i.sub(t).toVar(),o=n.cross(a),u=vn().toVar();return cn(o.dot(e.sub(t)).greaterThanEqual(0),()=>{const n=t.sub(e).normalize().toVar(),a=r.sub(e).normalize().toVar(),o=s.sub(e).normalize().toVar(),l=i.sub(e).normalize().toVar(),d=vn(0).toVar();d.addAssign(Xg({v1:n,v2:a})),d.addAssign(Xg({v1:a,v2:o})),d.addAssign(Xg({v1:o,v2:l})),d.addAssign(Xg({v1:l,v2:n})),u.assign(vn(jg({f:d.abs()})))}),u}).setLayout({name:"LTC_Evaluate",type:"vec3",inputs:[{name:"P",type:"vec3"},{name:"p0",type:"vec3"},{name:"p1",type:"vec3"},{name:"p2",type:"vec3"},{name:"p3",type:"vec3"}]}),Qg=1/6,Zg=e=>La(Qg,La(e,La(e,e.negate().add(3)).sub(3)).add(1)),Jg=e=>La(Qg,La(e,La(e,La(3,e).sub(6))).add(4)),em=e=>La(Qg,La(e,La(e,La(-3,e).add(3)).add(3)).add(1)),tm=e=>La(Qg,Zo(e,3)),rm=e=>Zg(e).add(Jg(e)),sm=e=>em(e).add(tm(e)),im=e=>Ma(-1,Jg(e).div(Zg(e).add(Jg(e)))),nm=e=>Ma(1,tm(e).div(em(e).add(tm(e)))),am=(e,t,r)=>{const s=e.uvNode,i=La(s,t.zw).add(.5),n=To(i),a=No(i),o=rm(a.x),u=sm(a.x),l=im(a.x),d=nm(a.x),c=im(a.y),h=nm(a.y),p=bn(n.x.add(l),n.y.add(c)).sub(.5).mul(t.xy),g=bn(n.x.add(d),n.y.add(c)).sub(.5).mul(t.xy),m=bn(n.x.add(l),n.y.add(h)).sub(.5).mul(t.xy),f=bn(n.x.add(d),n.y.add(h)).sub(.5).mul(t.xy),y=rm(a.y).mul(Ma(o.mul(e.sample(p).level(r)),u.mul(e.sample(g).level(r)))),b=sm(a.y).mul(Ma(o.mul(e.sample(m).level(r)),u.mul(e.sample(f).level(r))));return y.add(b)},om=un(([e,t])=>{const r=bn(e.size(mn(t))),s=bn(e.size(mn(t.add(1)))),i=Pa(1,r),n=Pa(1,s),a=am(e,En(i,r),To(t)),o=am(e,En(n,s),_o(t));return No(t).mix(a,o)}),um=un(([e,t])=>{const r=t.mul(Cl(e));return om(e,r)}),lm=un(([e,t,r,s,i])=>{const n=vn(uu(t.negate(),vo(e),Pa(1,s))),a=vn(Lo(i[0].xyz),Lo(i[1].xyz),Lo(i[2].xyz));return vo(n).mul(r.mul(a))}).setLayout({name:"getVolumeTransmissionRay",type:"vec3",inputs:[{name:"n",type:"vec3"},{name:"v",type:"vec3"},{name:"thickness",type:"float"},{name:"ior",type:"float"},{name:"modelMatrix",type:"mat4"}]}),dm=un(([e,t])=>e.mul(au(t.mul(2).sub(2),0,1))).setLayout({name:"applyIorToRoughness",type:"float",inputs:[{name:"roughness",type:"float"},{name:"ior",type:"float"}]}),cm=Sp(),hm=Ep(),pm=un(([e,t,r],{material:s})=>{const i=(s.side===M?cm:hm).sample(e),n=yo(jl.x).mul(dm(t,r));return om(i,n)}),gm=un(([e,t,r])=>(cn(r.notEqual(0),()=>{const s=fo(t).negate().div(r);return go(s.negate().mul(e))}),vn(1))).setLayout({name:"volumeAttenuation",type:"vec3",inputs:[{name:"transmissionDistance",type:"float"},{name:"attenuationColor",type:"vec3"},{name:"attenuationDistance",type:"float"}]}),mm=un(([e,t,r,s,i,n,a,o,u,l,d,c,h,p,g])=>{let m,f;if(g){m=En().toVar(),f=vn().toVar();const i=d.sub(1).mul(g.mul(.025)),n=vn(d.sub(i),d,d.add(i));lp({start:0,end:3},({i:i})=>{const d=n.element(i),g=lm(e,t,c,d,o),y=a.add(g),b=l.mul(u.mul(En(y,1))),x=bn(b.xy.div(b.w)).toVar();x.addAssign(1),x.divAssign(2),x.assign(bn(x.x,x.y.oneMinus()));const T=pm(x,r,d);m.element(i).assign(T.element(i)),m.a.addAssign(T.a),f.element(i).assign(s.element(i).mul(gm(Lo(g),h,p).element(i)))}),m.a.divAssign(3)}else{const i=lm(e,t,c,d,o),n=a.add(i),g=l.mul(u.mul(En(n,1))),y=bn(g.xy.div(g.w)).toVar();y.addAssign(1),y.divAssign(2),y.assign(bn(y.x,y.y.oneMinus())),m=pm(y,r,d),f=s.mul(gm(Lo(i),h,p))}const y=f.rgb.mul(m.rgb),b=e.dot(t).clamp(),x=vn(Gg({dotNV:b,specularColor:i,specularF90:n,roughness:r})),T=f.r.add(f.g,f.b).div(3);return En(x.oneMinus().mul(y),m.a.oneMinus().mul(T).oneMinus())}),fm=Fn(3.2404542,-.969266,.0556434,-1.5371385,1.8760108,-.2040259,-.4985314,.041556,1.0572252),ym=(e,t)=>e.sub(t).div(e.add(t)).pow2(),bm=un(({outsideIOR:e,eta2:t,cosTheta1:r,thinFilmThickness:s,baseF0:i})=>{const n=nu(e,t,lu(0,.03,s)),a=e.div(n).pow2().mul(r.pow2().oneMinus()).oneMinus();cn(a.lessThan(0),()=>vn(1));const o=a.sqrt(),u=ym(n,e),l=Tg({f0:u,f90:1,dotVH:r}),d=l.oneMinus(),c=n.lessThan(e).select(Math.PI,0),h=gn(Math.PI).sub(c),p=(e=>{const t=e.sqrt();return vn(1).add(t).div(vn(1).sub(t))})(i.clamp(0,.9999)),g=ym(p,n.toVec3()),m=Tg({f0:g,f90:1,dotVH:o}),f=vn(p.x.lessThan(n).select(Math.PI,0),p.y.lessThan(n).select(Math.PI,0),p.z.lessThan(n).select(Math.PI,0)),y=n.mul(s,o,2),b=vn(h).add(f),x=l.mul(m).clamp(1e-5,.9999),T=x.sqrt(),_=d.pow2().mul(m).div(vn(1).sub(x)),v=l.add(_).toVar(),N=_.sub(d).toVar();return lp({start:1,end:2,condition:"<=",name:"m"},({m:e})=>{N.mulAssign(T);const t=((e,t)=>{const r=e.mul(2*Math.PI*1e-9),s=vn(54856e-17,44201e-17,52481e-17),i=vn(1681e3,1795300,2208400),n=vn(43278e5,93046e5,66121e5),a=gn(9747e-17*Math.sqrt(2*Math.PI*45282e5)).mul(r.mul(2239900).add(t.x).cos()).mul(r.pow2().mul(-45282e5).exp());let o=s.mul(n.mul(2*Math.PI).sqrt()).mul(i.mul(r).add(t).cos()).mul(r.pow2().negate().mul(n).exp());return o=vn(o.x.add(a),o.y,o.z).div(1.0685e-7),fm.mul(o)})(gn(e).mul(y),gn(e).mul(b)).mul(2);v.addAssign(N.mul(t))}),v.max(vn(0))}).setLayout({name:"evalIridescence",type:"vec3",inputs:[{name:"outsideIOR",type:"float"},{name:"eta2",type:"float"},{name:"cosTheta1",type:"float"},{name:"thinFilmThickness",type:"float"},{name:"baseF0",type:"vec3"}]}),xm=un(({normal:e,viewDir:t,roughness:r})=>{const s=e.dot(t).saturate(),i=r.mul(r),n=r.add(.1).reciprocal(),a=gn(-1.9362).add(r.mul(1.0678)).add(i.mul(.4573)).sub(n.mul(.8469)),o=gn(-.6014).add(r.mul(.5538)).sub(i.mul(.467)).sub(n.mul(.1255));return a.mul(s).add(o).exp().saturate()}),Tm=vn(.04),_m=gn(1);class vm extends fg{constructor(e=!1,t=!1,r=!1,s=!1,i=!1,n=!1){super(),this.clearcoat=e,this.sheen=t,this.iridescence=r,this.anisotropy=s,this.transmission=i,this.dispersion=n,this.clearcoatRadiance=null,this.clearcoatSpecularDirect=null,this.clearcoatSpecularIndirect=null,this.sheenSpecularDirect=null,this.sheenSpecularIndirect=null,this.iridescenceFresnel=null,this.iridescenceF0=null,this.iridescenceF0Dielectric=null,this.iridescenceF0Metallic=null}start(e){if(!0===this.clearcoat&&(this.clearcoatRadiance=vn().toVar("clearcoatRadiance"),this.clearcoatSpecularDirect=vn().toVar("clearcoatSpecularDirect"),this.clearcoatSpecularIndirect=vn().toVar("clearcoatSpecularIndirect")),!0===this.sheen&&(this.sheenSpecularDirect=vn().toVar("sheenSpecularDirect"),this.sheenSpecularIndirect=vn().toVar("sheenSpecularIndirect")),!0===this.iridescence){const e=Xd.dot(Od).clamp(),t=bm({outsideIOR:gn(1),eta2:Xn,cosTheta1:e,thinFilmThickness:Kn,baseF0:ea}),r=bm({outsideIOR:gn(1),eta2:Xn,cosTheta1:e,thinFilmThickness:Kn,baseF0:On.rgb});this.iridescenceFresnel=nu(t,r,zn),this.iridescenceF0Dielectric=zg({f:t,f90:1,dotVH:e}),this.iridescenceF0Metallic=zg({f:r,f90:1,dotVH:e}),this.iridescenceF0=nu(this.iridescenceF0Dielectric,this.iridescenceF0Metallic,zn)}if(!0===this.transmission){const t=Dd,r=ud.sub(Dd).normalize(),s=Kd,i=e.context;i.backdrop=mm(s,r,Gn,Vn,ta,ra,t,Td,nd,sd,ua,da,ha,ca,this.dispersion?pa:null),i.backdropAlpha=la,On.a.mulAssign(nu(1,i.backdrop.a,la))}super.start(e)}computeMultiscattering(e,t,r,s,i=null){const n=Xd.dot(Od).clamp(),a=Vg({roughness:Gn,dotNV:n}),o=i?jn.mix(s,i):s,u=o.mul(a.x).add(r.mul(a.y)),l=a.x.add(a.y).oneMinus(),d=o.add(o.oneMinus().mul(.047619)),c=u.mul(d).div(l.mul(d).oneMinus());e.addAssign(u),t.addAssign(c.mul(l))}direct({lightDirection:e,lightColor:t,reflectedLight:r}){const s=Xd.dot(e).clamp().mul(t).toVar();if(!0===this.sheen){this.sheenSpecularDirect.addAssign(s.mul(Hg({lightDirection:e})));const t=xm({normal:Xd,viewDir:Od,roughness:qn}),r=xm({normal:Xd,viewDir:e,roughness:qn}),i=Hn.r.max(Hn.g).max(Hn.b).mul(t.max(r)).oneMinus();s.mulAssign(i)}if(!0===this.clearcoat){const r=Yd.dot(e).clamp().mul(t);this.clearcoatSpecularDirect.addAssign(r.mul(Ug({lightDirection:e,f0:Tm,f90:_m,roughness:Wn,normalView:Yd})))}r.directDiffuse.addAssign(s.mul(_g({diffuseColor:Vn}))),r.directSpecular.addAssign(s.mul(kg({lightDirection:e,f0:ta,f90:1,roughness:Gn,f:this.iridescenceFresnel,USE_IRIDESCENCE:this.iridescence,USE_ANISOTROPY:this.anisotropy})))}directRectArea({lightColor:e,lightPosition:t,halfWidth:r,halfHeight:s,reflectedLight:i,ltc_1:n,ltc_2:a}){const o=t.add(r).sub(s),u=t.sub(r).sub(s),l=t.sub(r).add(s),d=t.add(r).add(s),c=Xd,h=Od,p=Id.toVar(),g=qg({N:c,V:h,roughness:Gn}),m=n.sample(g).toVar(),f=a.sample(g).toVar(),y=Fn(vn(m.x,0,m.y),vn(0,1,0),vn(m.z,0,m.w)).toVar(),b=ta.mul(f.x).add(ra.sub(ta).mul(f.y)).toVar();if(i.directSpecular.addAssign(e.mul(b).mul(Kg({N:c,V:h,P:p,mInv:y,p0:o,p1:u,p2:l,p3:d}))),i.directDiffuse.addAssign(e.mul(Vn).mul(Kg({N:c,V:h,P:p,mInv:Fn(1,0,0,0,1,0,0,0,1),p0:o,p1:u,p2:l,p3:d}))),!0===this.clearcoat){const t=Yd,r=qg({N:t,V:h,roughness:Wn}),s=n.sample(r),i=a.sample(r),c=Fn(vn(s.x,0,s.y),vn(0,1,0),vn(s.z,0,s.w)),g=Tm.mul(i.x).add(_m.sub(Tm).mul(i.y));this.clearcoatSpecularDirect.addAssign(e.mul(g).mul(Kg({N:t,V:h,P:p,mInv:c,p0:o,p1:u,p2:l,p3:d})))}}indirect(e){this.indirectDiffuse(e),this.indirectSpecular(e),this.ambientOcclusion(e)}indirectDiffuse(e){const{irradiance:t,reflectedLight:r}=e.context,s=t.mul(_g({diffuseColor:Vn})).toVar();if(!0===this.sheen){const e=xm({normal:Xd,viewDir:Od,roughness:qn}),t=Hn.r.max(Hn.g).max(Hn.b).mul(e).oneMinus();s.mulAssign(t)}r.indirectDiffuse.addAssign(s)}indirectSpecular(e){const{radiance:t,iblIrradiance:r,reflectedLight:s}=e.context;if(!0===this.sheen&&this.sheenSpecularIndirect.addAssign(r.mul(Hn,xm({normal:Xd,viewDir:Od,roughness:qn}))),!0===this.clearcoat){const e=Yd.dot(Od).clamp(),t=Gg({dotNV:e,specularColor:Tm,specularF90:_m,roughness:Wn});this.clearcoatSpecularIndirect.addAssign(this.clearcoatRadiance.mul(t))}const i=vn().toVar("singleScatteringDielectric"),n=vn().toVar("multiScatteringDielectric"),a=vn().toVar("singleScatteringMetallic"),o=vn().toVar("multiScatteringMetallic");this.computeMultiscattering(i,n,ra,ea,this.iridescenceF0Dielectric),this.computeMultiscattering(a,o,ra,On.rgb,this.iridescenceF0Metallic);const u=nu(i,a,zn),l=nu(n,o,zn),d=i.add(n),c=Vn.mul(d.oneMinus()),h=r.mul(1/Math.PI),p=t.mul(u).add(l.mul(h)).toVar(),g=c.mul(h).toVar();if(!0===this.sheen){const e=xm({normal:Xd,viewDir:Od,roughness:qn}),t=Hn.r.max(Hn.g).max(Hn.b).mul(e).oneMinus();p.mulAssign(t),g.mulAssign(t)}s.indirectSpecular.addAssign(p),s.indirectDiffuse.addAssign(g)}ambientOcclusion(e){const{ambientOcclusion:t,reflectedLight:r}=e.context,s=Xd.dot(Od).clamp().add(t),i=Gn.mul(-16).oneMinus().negate().exp2(),n=t.sub(s.pow(i).oneMinus()).clamp();!0===this.clearcoat&&this.clearcoatSpecularIndirect.mulAssign(t),!0===this.sheen&&this.sheenSpecularIndirect.mulAssign(t),r.indirectDiffuse.mulAssign(t),r.indirectSpecular.mulAssign(n)}finish({context:e}){const{outgoingLight:t}=e;if(!0===this.clearcoat){const e=Yd.dot(Od).clamp(),r=Tg({dotVH:e,f0:Tm,f90:_m}),s=t.mul($n.mul(r).oneMinus()).add(this.clearcoatSpecularDirect.add(this.clearcoatSpecularIndirect).mul($n));t.assign(s)}if(!0===this.sheen){const e=t.add(this.sheenSpecularDirect,this.sheenSpecularIndirect.mul(1/Math.PI));t.assign(e)}}}const Nm=gn(1),Sm=gn(-2),Rm=gn(.8),Em=gn(-1),Am=gn(.4),wm=gn(2),Cm=gn(.305),Mm=gn(3),Fm=gn(.21),Lm=gn(4),Pm=gn(4),Bm=gn(16),Dm=un(([e])=>{const t=vn(Mo(e)).toVar(),r=gn(-1).toVar();return cn(t.x.greaterThan(t.z),()=>{cn(t.x.greaterThan(t.y),()=>{r.assign(bu(e.x.greaterThan(0),0,3))}).Else(()=>{r.assign(bu(e.y.greaterThan(0),1,4))})}).Else(()=>{cn(t.z.greaterThan(t.y),()=>{r.assign(bu(e.z.greaterThan(0),2,5))}).Else(()=>{r.assign(bu(e.y.greaterThan(0),1,4))})}),r}).setLayout({name:"getFace",type:"float",inputs:[{name:"direction",type:"vec3"}]}),Um=un(([e,t])=>{const r=bn().toVar();return cn(t.equal(0),()=>{r.assign(bn(e.z,e.y).div(Mo(e.x)))}).ElseIf(t.equal(1),()=>{r.assign(bn(e.x.negate(),e.z.negate()).div(Mo(e.y)))}).ElseIf(t.equal(2),()=>{r.assign(bn(e.x.negate(),e.y).div(Mo(e.z)))}).ElseIf(t.equal(3),()=>{r.assign(bn(e.z.negate(),e.y).div(Mo(e.x)))}).ElseIf(t.equal(4),()=>{r.assign(bn(e.x.negate(),e.z).div(Mo(e.y)))}).Else(()=>{r.assign(bn(e.x,e.y).div(Mo(e.z)))}),La(.5,r.add(1))}).setLayout({name:"getUV",type:"vec2",inputs:[{name:"direction",type:"vec3"},{name:"face",type:"float"}]}),Im=un(([e])=>{const t=gn(0).toVar();return cn(e.greaterThanEqual(Rm),()=>{t.assign(Nm.sub(e).mul(Em.sub(Sm)).div(Nm.sub(Rm)).add(Sm))}).ElseIf(e.greaterThanEqual(Am),()=>{t.assign(Rm.sub(e).mul(wm.sub(Em)).div(Rm.sub(Am)).add(Em))}).ElseIf(e.greaterThanEqual(Cm),()=>{t.assign(Am.sub(e).mul(Mm.sub(wm)).div(Am.sub(Cm)).add(wm))}).ElseIf(e.greaterThanEqual(Fm),()=>{t.assign(Cm.sub(e).mul(Lm.sub(Mm)).div(Cm.sub(Fm)).add(Mm))}).Else(()=>{t.assign(gn(-2).mul(yo(La(1.16,e))))}),t}).setLayout({name:"roughnessToMip",type:"float",inputs:[{name:"roughness",type:"float"}]}),Om=un(([e,t])=>{const r=e.toVar();r.assign(La(2,r).sub(1));const s=vn(r,1).toVar();return cn(t.equal(0),()=>{s.assign(s.zyx)}).ElseIf(t.equal(1),()=>{s.assign(s.xzy),s.xz.mulAssign(-1)}).ElseIf(t.equal(2),()=>{s.x.mulAssign(-1)}).ElseIf(t.equal(3),()=>{s.assign(s.zyx),s.xz.mulAssign(-1)}).ElseIf(t.equal(4),()=>{s.assign(s.xzy),s.xy.mulAssign(-1)}).ElseIf(t.equal(5),()=>{s.z.mulAssign(-1)}),s}).setLayout({name:"getDirection",type:"vec3",inputs:[{name:"uv",type:"vec2"},{name:"face",type:"float"}]}),Vm=un(([e,t,r,s,i,n])=>{const a=gn(r),o=vn(t),u=au(Im(a),Sm,n),l=No(u),d=To(u),c=vn(km(e,o,d,s,i,n)).toVar();return cn(l.notEqual(0),()=>{const t=vn(km(e,o,d.add(1),s,i,n)).toVar();c.assign(nu(c,t,l))}),c}),km=un(([e,t,r,s,i,n])=>{const a=gn(r).toVar(),o=vn(t),u=gn(Dm(o)).toVar(),l=gn(Ho(Pm.sub(a),0)).toVar();a.assign(Ho(a,Pm));const d=gn(mo(a)).toVar(),c=bn(Um(o,u).mul(d.sub(2)).add(1)).toVar();return cn(u.greaterThan(2),()=>{c.y.addAssign(d),u.subAssign(3)}),c.x.addAssign(u.mul(d)),c.x.addAssign(l.mul(La(3,Bm))),c.y.addAssign(La(4,mo(n).sub(d))),c.x.mulAssign(s),c.y.mulAssign(i),e.sample(c).grad(bn(),bn())}),Gm=un(({envMap:e,mipInt:t,outputDirection:r,theta:s,axis:i,CUBEUV_TEXEL_WIDTH:n,CUBEUV_TEXEL_HEIGHT:a,CUBEUV_MAX_MIP:o})=>{const u=Ro(s),l=r.mul(u).add(i.cross(r).mul(So(s))).add(i.mul(i.dot(r).mul(u.oneMinus())));return km(e,l,t,n,a,o)}),zm=un(({n:e,latitudinal:t,poleAxis:r,outputDirection:s,weights:i,samples:n,dTheta:a,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c})=>{const h=vn(bu(t,r,Qo(r,s))).toVar();cn(h.equal(vn(0)),()=>{h.assign(vn(s.z,0,s.x.negate()))}),h.assign(vo(h));const p=vn().toVar();return p.addAssign(i.element(0).mul(Gm({theta:0,axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c}))),lp({start:mn(1),end:e},({i:e})=>{cn(e.greaterThanEqual(n),()=>{dp()});const t=gn(a.mul(gn(e))).toVar();p.addAssign(i.element(e).mul(Gm({theta:t.mul(-1),axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c}))),p.addAssign(i.element(e).mul(Gm({theta:t,axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c})))}),En(p,1)}),$m=un(([e])=>{const t=fn(e).toVar();return t.assign(t.shiftLeft(fn(16)).bitOr(t.shiftRight(fn(16)))),t.assign(t.bitAnd(fn(1431655765)).shiftLeft(fn(1)).bitOr(t.bitAnd(fn(2863311530)).shiftRight(fn(1)))),t.assign(t.bitAnd(fn(858993459)).shiftLeft(fn(2)).bitOr(t.bitAnd(fn(3435973836)).shiftRight(fn(2)))),t.assign(t.bitAnd(fn(252645135)).shiftLeft(fn(4)).bitOr(t.bitAnd(fn(4042322160)).shiftRight(fn(4)))),t.assign(t.bitAnd(fn(16711935)).shiftLeft(fn(8)).bitOr(t.bitAnd(fn(4278255360)).shiftRight(fn(8)))),gn(t).mul(2.3283064365386963e-10)}),Wm=un(([e,t])=>bn(gn(e).div(gn(t)),$m(e))),Hm=un(([e,t,r])=>{const s=r.mul(r).toConst(),i=vn(1,0,0).toConst(),n=Qo(t,i).toConst(),a=bo(e.x).toConst(),o=La(2,3.14159265359).mul(e.y).toConst(),u=a.mul(Ro(o)).toConst(),l=a.mul(So(o)).toVar(),d=La(.5,t.z.add(1)).toConst();l.assign(d.oneMinus().mul(bo(u.mul(u).oneMinus())).add(d.mul(l)));const c=i.mul(u).add(n.mul(l)).add(t.mul(bo(Ho(0,u.mul(u).add(l.mul(l)).oneMinus()))));return vo(vn(s.mul(c.x),s.mul(c.y),Ho(0,c.z)))}),qm=un(({roughness:e,mipInt:t,envMap:r,N_immutable:s,GGX_SAMPLES:i,CUBEUV_TEXEL_WIDTH:n,CUBEUV_TEXEL_HEIGHT:a,CUBEUV_MAX_MIP:o})=>{const u=vn(s).toVar(),l=vn(0).toVar(),d=gn(0).toVar();return cn(e.lessThan(.001),()=>{l.assign(km(r,u,t,n,a,o))}).Else(()=>{const s=bu(Mo(u.z).lessThan(.999),vn(0,0,1),vn(1,0,0)),c=vo(Qo(s,u)).toVar(),h=Qo(u,c).toVar();lp({start:fn(0),end:i},({i:s})=>{const p=Wm(s,i),g=Hm(p,vn(0,0,1),e),m=vo(c.mul(g.x).add(h.mul(g.y)).add(u.mul(g.z))),f=vo(m.mul(Yo(u,m).mul(2)).sub(u)),y=Ho(Yo(u,f),0);cn(y.greaterThan(0),()=>{const e=km(r,f,t,n,a,o);l.addAssign(e.mul(y)),d.addAssign(y)})}),cn(d.greaterThan(0),()=>{l.assign(l.div(d))})}),En(l,1)}),jm=[.125,.215,.35,.446,.526,.582],Xm=20,Km=new _e(-1,1,1,-1,0,1),Ym=new ve(90,1),Qm=new e;let Zm=null,Jm=0,ef=0;const tf=new r,rf=new WeakMap,sf=[3,1,5,0,4,2],nf=Om(Rl(),Sl("faceIndex")).normalize(),af=vn(nf.x,nf.y,nf.z);class of{constructor(e){this._renderer=e,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._sizeLods=[],this._sigmas=[],this._lodMeshes=[],this._blurMaterial=null,this._ggxMaterial=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._backgroundBox=null}get _hasInitialized(){return this._renderer.hasInitialized()}fromScene(e,t=0,r=.1,s=100,i={}){const{size:n=256,position:a=tf,renderTarget:o=null}=i;if(this._setSize(n),!1===this._hasInitialized){d('PMREMGenerator: ".fromScene()" called before the backend is initialized. Try using "await renderer.init()" instead.');const n=o||this._allocateTarget();return i.renderTarget=n,this.fromSceneAsync(e,t,r,s,i),n}Zm=this._renderer.getRenderTarget(),Jm=this._renderer.getActiveCubeFace(),ef=this._renderer.getActiveMipmapLevel();const u=o||this._allocateTarget();return u.depthBuffer=!0,this._init(u),this._sceneToCubeUV(e,r,s,u,a),t>0&&this._blur(u,0,0,t),this._applyPMREM(u),this._cleanup(u),u}async fromSceneAsync(e,t=0,r=.1,s=100,i={}){return v('PMREMGenerator: ".fromSceneAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this.fromScene(e,t,r,s,i)}fromEquirectangular(e,t=null){if(!1===this._hasInitialized){d('PMREMGenerator: .fromEquirectangular() called before the backend is initialized. Try using "await renderer.init()" instead.'),this._setSizeFromTexture(e);const r=t||this._allocateTarget();return this.fromEquirectangularAsync(e,r),r}return this._fromTexture(e,t)}async fromEquirectangularAsync(e,t=null){return v('PMREMGenerator: ".fromEquirectangularAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this._fromTexture(e,t)}fromCubemap(e,t=null){if(!1===this._hasInitialized){d("PMREMGenerator: .fromCubemap() called before the backend is initialized. Try using .fromCubemapAsync() instead."),this._setSizeFromTexture(e);const r=t||this._allocateTarget();return this.fromCubemapAsync(e,t),r}return this._fromTexture(e,t)}async fromCubemapAsync(e,t=null){return v('PMREMGenerator: ".fromCubemapAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this._fromTexture(e,t)}async compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=cf(),await this._compileMaterial(this._cubemapMaterial))}async compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=hf(),await this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose(),null!==this._backgroundBox&&(this._backgroundBox.geometry.dispose(),this._backgroundBox.material.dispose())}_setSizeFromTexture(e){e.mapping===B||e.mapping===D?this._setSize(0===e.image.length?16:e.image[0].width||e.image[0].image.width):this._setSize(e.image.width/4)}_setSize(e){this._lodMax=Math.floor(Math.log2(e)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._ggxMaterial&&this._ggxMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let e=0;ee-4?o=jm[a-e+4-1]:0===a&&(o=0),r.push(o);const u=1/(n-2),l=-u,d=1+u,c=[l,l,d,l,d,d,l,l,d,d,l,d],h=6,p=6,g=3,m=2,f=1,y=new Float32Array(g*p*h),b=new Float32Array(m*p*h),x=new Float32Array(f*p*h);for(let e=0;e2?0:-1,s=[t,r,0,t+2/3,r,0,t+2/3,r+1,0,t,r,0,t+2/3,r+1,0,t,r+1,0],i=sf[e];y.set(s,g*p*i),b.set(c,m*p*i);const n=[i,i,i,i,i,i];x.set(n,f*p*i)}const T=new Te;T.setAttribute("position",new Ae(y,g)),T.setAttribute("uv",new Ae(b,m)),T.setAttribute("faceIndex",new Ae(x,f)),s.push(new ne(T,null)),i>4&&i--}return{lodMeshes:s,sizeLods:t,sigmas:r}}(t)),this._blurMaterial=function(e,t,s){const i=Vl(new Array(Xm).fill(0)),n=_a(new r(0,1,0)),a=_a(0),o=gn(Xm),u=_a(0),l=_a(1),d=Pl(),c=_a(0),h=gn(1/t),p=gn(1/s),g=gn(e),m={n:o,latitudinal:u,weights:i,poleAxis:n,outputDirection:af,dTheta:a,samples:l,envMap:d,mipInt:c,CUBEUV_TEXEL_WIDTH:h,CUBEUV_TEXEL_HEIGHT:p,CUBEUV_MAX_MIP:g},f=df("blur");return f.fragmentNode=zm({...m,latitudinal:u.equal(1)}),rf.set(f,m),f}(t,e.width,e.height),this._ggxMaterial=function(e,t,r){const s=Pl(),i=_a(0),n=_a(0),a=gn(1/t),o=gn(1/r),u=gn(e),l={envMap:s,roughness:i,mipInt:n,CUBEUV_TEXEL_WIDTH:a,CUBEUV_TEXEL_HEIGHT:o,CUBEUV_MAX_MIP:u},d=df("ggx");return d.fragmentNode=qm({...l,N_immutable:af,GGX_SAMPLES:fn(512)}),rf.set(d,l),d}(t,e.width,e.height)}}async _compileMaterial(e){const t=new ne(new Te,e);await this._renderer.compile(t,Km)}_sceneToCubeUV(e,t,r,s,i){const n=Ym;n.near=t,n.far=r;const a=[1,1,1,1,-1,1],o=[1,-1,1,-1,1,-1],u=this._renderer,l=u.autoClear;u.getClearColor(Qm),u.autoClear=!1,null===this._backgroundBox&&(this._backgroundBox=new ne(new ie,new ge({name:"PMREM.Background",side:M,depthWrite:!1,depthTest:!1})));const d=this._backgroundBox,c=d.material;let h=!1;const p=e.background;p?p.isColor&&(c.color.copy(p),e.background=null,h=!0):(c.color.copy(Qm),h=!0),u.setRenderTarget(s),u.clear(),h&&u.render(d,n);for(let t=0;t<6;t++){const r=t%3;0===r?(n.up.set(0,a[t],0),n.position.set(i.x,i.y,i.z),n.lookAt(i.x+o[t],i.y,i.z)):1===r?(n.up.set(0,0,a[t]),n.position.set(i.x,i.y,i.z),n.lookAt(i.x,i.y+o[t],i.z)):(n.up.set(0,a[t],0),n.position.set(i.x,i.y,i.z),n.lookAt(i.x,i.y,i.z+o[t]));const l=this._cubeSize;lf(s,r*l,t>2?l:0,l,l),u.render(e,n)}u.autoClear=l,e.background=p}_textureToCubeUV(e,t){const r=this._renderer,s=e.mapping===B||e.mapping===D;s?null===this._cubemapMaterial&&(this._cubemapMaterial=cf(e)):null===this._equirectMaterial&&(this._equirectMaterial=hf(e));const i=s?this._cubemapMaterial:this._equirectMaterial;i.fragmentNode.value=e;const n=this._lodMeshes[0];n.material=i;const a=this._cubeSize;lf(t,0,0,3*a,2*a),r.setRenderTarget(t),r.render(n,Km)}_applyPMREM(e){const t=this._renderer,r=t.autoClear;t.autoClear=!1;const s=this._lodMeshes.length;for(let t=1;tc-4?r-c+4:0),g=4*(this._cubeSize-h);e.texture.frame=(e.texture.frame||0)+1,o.envMap.value=e.texture,o.roughness.value=d,o.mipInt.value=c-t,lf(i,p,g,3*h,2*h),s.setRenderTarget(i),s.render(a,Km),i.texture.frame=(i.texture.frame||0)+1,o.envMap.value=i.texture,o.roughness.value=0,o.mipInt.value=c-r,lf(e,p,g,3*h,2*h),s.setRenderTarget(e),s.render(a,Km)}_blur(e,t,r,s,i){const n=this._pingPongRenderTarget;this._halfBlur(e,n,t,r,s,"latitudinal",i),this._halfBlur(n,e,r,r,s,"longitudinal",i)}_halfBlur(e,t,r,s,i,n,a){const u=this._renderer,l=this._blurMaterial;"latitudinal"!==n&&"longitudinal"!==n&&o("blur direction must be either latitudinal or longitudinal!");const c=this._lodMeshes[s];c.material=l;const h=rf.get(l),p=this._sizeLods[r]-1,g=isFinite(i)?Math.PI/(2*p):2*Math.PI/39,m=i/g,f=isFinite(i)?1+Math.floor(3*m):Xm;f>Xm&&d(`sigmaRadians, ${i}, is too large and will clip, as it requested ${f} samples when the maximum is set to 20`);const y=[];let b=0;for(let e=0;ex-4?s-x+4:0),4*(this._cubeSize-T),3*T,2*T),u.setRenderTarget(t),u.render(c,Km)}}function uf(e,t){const r=new Ne(e,t,{magFilter:oe,minFilter:oe,generateMipmaps:!1,type:be,format:Re,colorSpace:Se});return r.texture.mapping=Ee,r.texture.name="PMREM.cubeUv",r.texture.isPMREMTexture=!0,r.scissorTest=!0,r}function lf(e,t,r,s,i){e.viewport.set(t,r,s,i),e.scissor.set(t,r,s,i)}function df(e){const t=new Zp;return t.depthTest=!1,t.depthWrite=!1,t.blending=ee,t.name=`PMREM_${e}`,t}function cf(e){const t=df("cubemap");return t.fragmentNode=gc(e,af),t}function hf(e){const t=df("equirect");return t.fragmentNode=Pl(e,og(af),0),t}const pf=new WeakMap;function gf(e,t,r){const s=function(e){let t=pf.get(e);void 0===t&&(t=new WeakMap,pf.set(e,t));return t}(t);let i=s.get(e);if((void 0!==i?i.pmremVersion:-1)!==e.pmremVersion){const t=e.image;if(e.isCubeTexture){if(!function(e){if(null==e)return!1;let t=0;const r=6;for(let s=0;s0}(t))return null;i=r.fromEquirectangular(e,i)}i.pmremVersion=e.pmremVersion,s.set(e,i)}return i.texture}class mf extends ci{static get type(){return"PMREMNode"}constructor(e,t=null,r=null){super("vec3"),this._value=e,this._pmrem=null,this.uvNode=t,this.levelNode=r,this._generator=null;const s=new N;s.isRenderTargetTexture=!0,this._texture=Pl(s),this._width=_a(0),this._height=_a(0),this._maxMip=_a(0),this.updateBeforeType=Js.RENDER}set value(e){this._value=e,this._pmrem=null}get value(){return this._value}updateFromTexture(e){const t=function(e){const t=Math.log2(e)-2,r=1/e;return{texelWidth:1/(3*Math.max(Math.pow(2,t),112)),texelHeight:r,maxMip:t}}(e.image.height);this._texture.value=e,this._width.value=t.texelWidth,this._height.value=t.texelHeight,this._maxMip.value=t.maxMip}updateBefore(e){let t=this._pmrem;const r=t?t.pmremVersion:-1,s=this._value;r!==s.pmremVersion&&(t=!0===s.isPMREMTexture?s:gf(s,e.renderer,this._generator),null!==t&&(this._pmrem=t,this.updateFromTexture(t)))}setup(e){null===this._generator&&(this._generator=new of(e.renderer)),this.updateBefore(e);let t=this.uvNode;null===t&&e.context.getUV&&(t=e.context.getUV(this,e)),t=ac.mul(vn(t.x,t.y.negate(),t.z));let r=this.levelNode;return null===r&&e.context.getTextureLevel&&(r=e.context.getTextureLevel(this)),Vm(this._texture,t,r,this._width,this._height,this._maxMip)}dispose(){super.dispose(),null!==this._generator&&this._generator.dispose()}}const ff=rn(mf).setParameterLength(1,3),yf=new WeakMap;class bf extends fp{static get type(){return"EnvironmentNode"}constructor(e=null){super(),this.envNode=e}setup(e){const{material:t}=e;let r=this.envNode;if(r.isTextureNode||r.isMaterialReferenceNode){const e=r.isTextureNode?r.value:t[r.property];let s=yf.get(e);void 0===s&&(s=ff(e),yf.set(e,s)),r=s}const s=!0===t.useAnisotropy||t.anisotropy>0?qc:Xd,i=r.context(xf(Gn,s)).mul(nc),n=r.context(Tf(Kd)).mul(Math.PI).mul(nc),a=al(i),o=al(n);e.context.radiance.addAssign(a),e.context.iblIrradiance.addAssign(o);const u=e.context.lightingModel.clearcoatRadiance;if(u){const e=r.context(xf(Wn,Yd)).mul(nc),t=al(e);u.addAssign(t)}}}const xf=(e,t)=>{let r=null;return{getUV:()=>(null===r&&(r=Od.negate().reflect(t),r=tu(e).mix(r,t).normalize(),r=r.transformDirection(nd)),r),getTextureLevel:()=>e}},Tf=e=>({getUV:()=>e,getTextureLevel:()=>gn(1)}),_f=new we;class vf extends Zp{static get type(){return"MeshStandardNodeMaterial"}constructor(e){super(),this.isMeshStandardNodeMaterial=!0,this.lights=!0,this.emissiveNode=null,this.metalnessNode=null,this.roughnessNode=null,this.setDefaultValues(_f),this.setValues(e)}setupEnvironment(e){let t=super.setupEnvironment(e);return null===t&&e.environmentNode&&(t=e.environmentNode),t?new bf(t):null}setupLightingModel(){return new vm}setupSpecular(){const e=nu(vn(.04),On.rgb,zn);ea.assign(vn(.04)),ta.assign(e),ra.assign(1)}setupVariants(){const e=this.metalnessNode?gn(this.metalnessNode):gh;zn.assign(e);let t=this.roughnessNode?gn(this.roughnessNode):ph;t=Mg({roughness:t}),Gn.assign(t),this.setupSpecular(),Vn.assign(On.rgb.mul(e.oneMinus()))}copy(e){return this.emissiveNode=e.emissiveNode,this.metalnessNode=e.metalnessNode,this.roughnessNode=e.roughnessNode,super.copy(e)}}const Nf=new Ce;class Sf extends vf{static get type(){return"MeshPhysicalNodeMaterial"}constructor(e){super(),this.isMeshPhysicalNodeMaterial=!0,this.clearcoatNode=null,this.clearcoatRoughnessNode=null,this.clearcoatNormalNode=null,this.sheenNode=null,this.sheenRoughnessNode=null,this.iridescenceNode=null,this.iridescenceIORNode=null,this.iridescenceThicknessNode=null,this.specularIntensityNode=null,this.specularColorNode=null,this.iorNode=null,this.transmissionNode=null,this.thicknessNode=null,this.attenuationDistanceNode=null,this.attenuationColorNode=null,this.dispersionNode=null,this.anisotropyNode=null,this.setDefaultValues(Nf),this.setValues(e)}get useClearcoat(){return this.clearcoat>0||null!==this.clearcoatNode}get useIridescence(){return this.iridescence>0||null!==this.iridescenceNode}get useSheen(){return this.sheen>0||null!==this.sheenNode}get useAnisotropy(){return this.anisotropy>0||null!==this.anisotropyNode}get useTransmission(){return this.transmission>0||null!==this.transmissionNode}get useDispersion(){return this.dispersion>0||null!==this.dispersionNode}setupSpecular(){const e=this.iorNode?gn(this.iorNode):wh;ua.assign(e),ea.assign(Wo(Jo(ua.sub(1).div(ua.add(1))).mul(dh),vn(1)).mul(lh)),ta.assign(nu(ea,On.rgb,zn)),ra.assign(nu(lh,1,zn))}setupLightingModel(){return new vm(this.useClearcoat,this.useSheen,this.useIridescence,this.useAnisotropy,this.useTransmission,this.useDispersion)}setupVariants(e){if(super.setupVariants(e),this.useClearcoat){const e=this.clearcoatNode?gn(this.clearcoatNode):fh,t=this.clearcoatRoughnessNode?gn(this.clearcoatRoughnessNode):yh;$n.assign(e),Wn.assign(Mg({roughness:t}))}if(this.useSheen){const e=this.sheenNode?vn(this.sheenNode):Th,t=this.sheenRoughnessNode?gn(this.sheenRoughnessNode):_h;Hn.assign(e),qn.assign(t)}if(this.useIridescence){const e=this.iridescenceNode?gn(this.iridescenceNode):Nh,t=this.iridescenceIORNode?gn(this.iridescenceIORNode):Sh,r=this.iridescenceThicknessNode?gn(this.iridescenceThicknessNode):Rh;jn.assign(e),Xn.assign(t),Kn.assign(r)}if(this.useAnisotropy){const e=(this.anisotropyNode?bn(this.anisotropyNode):vh).toVar();Qn.assign(e.length()),cn(Qn.equal(0),()=>{e.assign(bn(1,0))}).Else(()=>{e.divAssign(bn(Qn)),Qn.assign(Qn.saturate())}),Yn.assign(Qn.pow2().mix(Gn.pow2(),1)),Zn.assign(Wc[0].mul(e.x).add(Wc[1].mul(e.y))),Jn.assign(Wc[1].mul(e.x).sub(Wc[0].mul(e.y)))}if(this.useTransmission){const e=this.transmissionNode?gn(this.transmissionNode):Eh,t=this.thicknessNode?gn(this.thicknessNode):Ah,r=this.attenuationDistanceNode?gn(this.attenuationDistanceNode):Ch,s=this.attenuationColorNode?vn(this.attenuationColorNode):Mh;if(la.assign(e),da.assign(t),ca.assign(r),ha.assign(s),this.useDispersion){const e=this.dispersionNode?gn(this.dispersionNode):Ih;pa.assign(e)}}}setupClearcoatNormal(){return this.clearcoatNormalNode?vn(this.clearcoatNormalNode):bh}setup(e){e.context.setupClearcoatNormal=()=>Lu(this.setupClearcoatNormal(e),"NORMAL","vec3"),super.setup(e)}copy(e){return this.clearcoatNode=e.clearcoatNode,this.clearcoatRoughnessNode=e.clearcoatRoughnessNode,this.clearcoatNormalNode=e.clearcoatNormalNode,this.sheenNode=e.sheenNode,this.sheenRoughnessNode=e.sheenRoughnessNode,this.iridescenceNode=e.iridescenceNode,this.iridescenceIORNode=e.iridescenceIORNode,this.iridescenceThicknessNode=e.iridescenceThicknessNode,this.specularIntensityNode=e.specularIntensityNode,this.specularColorNode=e.specularColorNode,this.iorNode=e.iorNode,this.transmissionNode=e.transmissionNode,this.thicknessNode=e.thicknessNode,this.attenuationDistanceNode=e.attenuationDistanceNode,this.attenuationColorNode=e.attenuationColorNode,this.dispersionNode=e.dispersionNode,this.anisotropyNode=e.anisotropyNode,super.copy(e)}}class Rf extends vm{constructor(e=!1,t=!1,r=!1,s=!1,i=!1,n=!1,a=!1){super(e,t,r,s,i,n),this.useSSS=a}direct({lightDirection:e,lightColor:t,reflectedLight:r},s){if(!0===this.useSSS){const i=s.material,{thicknessColorNode:n,thicknessDistortionNode:a,thicknessAmbientNode:o,thicknessAttenuationNode:u,thicknessPowerNode:l,thicknessScaleNode:d}=i,c=e.add(Xd.mul(a)).normalize(),h=gn(Od.dot(c.negate()).saturate().pow(l).mul(d)),p=vn(h.add(o).mul(n));r.directDiffuse.addAssign(p.mul(u.mul(t)))}super.direct({lightDirection:e,lightColor:t,reflectedLight:r},s)}}class Ef extends Sf{static get type(){return"MeshSSSNodeMaterial"}constructor(e){super(e),this.thicknessColorNode=null,this.thicknessDistortionNode=gn(.1),this.thicknessAmbientNode=gn(0),this.thicknessAttenuationNode=gn(.1),this.thicknessPowerNode=gn(2),this.thicknessScaleNode=gn(10)}get useSSS(){return null!==this.thicknessColorNode}setupLightingModel(){return new Rf(this.useClearcoat,this.useSheen,this.useIridescence,this.useAnisotropy,this.useTransmission,this.useDispersion,this.useSSS)}copy(e){return this.thicknessColorNode=e.thicknessColorNode,this.thicknessDistortionNode=e.thicknessDistortionNode,this.thicknessAmbientNode=e.thicknessAmbientNode,this.thicknessAttenuationNode=e.thicknessAttenuationNode,this.thicknessPowerNode=e.thicknessPowerNode,this.thicknessScaleNode=e.thicknessScaleNode,super.copy(e)}}const Af=un(({normal:e,lightDirection:t,builder:r})=>{const s=e.dot(t),i=bn(s.mul(.5).add(.5),0);if(r.material.gradientMap){const e=Tc("gradientMap","texture").context({getUV:()=>i});return vn(e.r)}{const e=i.fwidth().mul(.5);return nu(vn(.7),vn(1),lu(gn(.7).sub(e.x),gn(.7).add(e.x),i.x))}});class wf extends fg{direct({lightDirection:e,lightColor:t,reflectedLight:r},s){const i=Af({normal:$d,lightDirection:e,builder:s}).mul(t);r.directDiffuse.addAssign(i.mul(_g({diffuseColor:On.rgb})))}indirect(e){const{ambientOcclusion:t,irradiance:r,reflectedLight:s}=e.context;s.indirectDiffuse.addAssign(r.mul(_g({diffuseColor:On}))),s.indirectDiffuse.mulAssign(t)}}const Cf=new Me;class Mf extends Zp{static get type(){return"MeshToonNodeMaterial"}constructor(e){super(),this.isMeshToonNodeMaterial=!0,this.lights=!0,this.setDefaultValues(Cf),this.setValues(e)}setupLightingModel(){return new wf}}const Ff=un(()=>{const e=vn(Od.z,0,Od.x.negate()).normalize(),t=Od.cross(e);return bn(e.dot(Xd),t.dot(Xd)).mul(.495).add(.5)}).once(["NORMAL","VERTEX"])().toVar("matcapUV"),Lf=new Fe;class Pf extends Zp{static get type(){return"MeshMatcapNodeMaterial"}constructor(e){super(),this.isMeshMatcapNodeMaterial=!0,this.setDefaultValues(Lf),this.setValues(e)}setupVariants(e){const t=Ff;let r;r=e.material.matcap?Tc("matcap","texture").context({getUV:()=>t}):vn(nu(.2,.8,t.y)),On.rgb.mulAssign(r.rgb)}}class Bf extends ci{static get type(){return"RotateNode"}constructor(e,t){super(),this.positionNode=e,this.rotationNode=t}getNodeType(e){return this.positionNode.getNodeType(e)}setup(e){const{rotationNode:t,positionNode:r}=this;if("vec2"===this.getNodeType(e)){const e=t.cos(),s=t.sin();return Mn(e,s,s.negate(),e).mul(r)}{const e=t,s=Ln(En(1,0,0,0),En(0,Ro(e.x),So(e.x).negate(),0),En(0,So(e.x),Ro(e.x),0),En(0,0,0,1)),i=Ln(En(Ro(e.y),0,So(e.y),0),En(0,1,0,0),En(So(e.y).negate(),0,Ro(e.y),0),En(0,0,0,1)),n=Ln(En(Ro(e.z),So(e.z).negate(),0,0),En(So(e.z),Ro(e.z),0,0),En(0,0,1,0),En(0,0,0,1));return s.mul(i).mul(n).mul(En(r,1)).xyz}}}const Df=rn(Bf).setParameterLength(2),Uf=new Le;class If extends Zp{static get type(){return"SpriteNodeMaterial"}constructor(e){super(),this.isSpriteNodeMaterial=!0,this._useSizeAttenuation=!0,this.positionNode=null,this.rotationNode=null,this.scaleNode=null,this.transparent=!0,this.setDefaultValues(Uf),this.setValues(e)}setupPositionView(e){const{object:t,camera:r}=e,{positionNode:s,rotationNode:i,scaleNode:n,sizeAttenuation:a}=this,o=Ad.mul(vn(s||0));let u=bn(Td[0].xyz.length(),Td[1].xyz.length());null!==n&&(u=u.mul(bn(n))),r.isPerspectiveCamera&&!1===a&&(u=u.mul(o.z.negate()));let l=Ld.xy;if(t.center&&!0===t.center.isVector2){const e=((e,t,r)=>new $u(e,t,r))("center","vec2",t);l=l.sub(e.sub(.5))}l=l.mul(u);const d=gn(i||xh),c=Df(l,d);return En(o.xy.add(c),o.zw)}copy(e){return this.positionNode=e.positionNode,this.rotationNode=e.rotationNode,this.scaleNode=e.scaleNode,super.copy(e)}get sizeAttenuation(){return this._useSizeAttenuation}set sizeAttenuation(e){this._useSizeAttenuation!==e&&(this._useSizeAttenuation=e,this.needsUpdate=!0)}}const Of=new Pe,Vf=new t;class kf extends If{static get type(){return"PointsNodeMaterial"}constructor(e){super(),this.sizeNode=null,this.isPointsNodeMaterial=!0,this.setDefaultValues(Of),this.setValues(e)}setupPositionView(){const{positionNode:e}=this;return Ad.mul(vn(e||Pd)).xyz}setupVertexSprite(e){const{material:t,camera:r}=e,{rotationNode:s,scaleNode:i,sizeNode:n,sizeAttenuation:a}=this;let o=super.setupVertex(e);if(!0!==t.isNodeMaterial)return o;let u=null!==n?bn(n):Uh;u=u.mul(Hl),r.isPerspectiveCamera&&!0===a&&(u=u.mul(Gf.div(Id.z.negate()))),i&&i.isNode&&(u=u.mul(bn(i)));let l=Ld.xy;if(s&&s.isNode){const e=gn(s);l=Df(l,e)}return l=l.mul(u),l=l.div(Yl.div(2)),l=l.mul(o.w),o=o.add(En(l,0,0)),o}setupVertex(e){return e.object.isPoints?super.setupVertex(e):this.setupVertexSprite(e)}get alphaToCoverage(){return this._useAlphaToCoverage}set alphaToCoverage(e){this._useAlphaToCoverage!==e&&(this._useAlphaToCoverage=e,this.needsUpdate=!0)}}const Gf=_a(1).onFrameUpdate(function({renderer:e}){const t=e.getSize(Vf);this.value=.5*t.y});class zf extends fg{constructor(){super(),this.shadowNode=gn(1).toVar("shadowMask")}direct({lightNode:e}){null!==e.shadowNode&&this.shadowNode.mulAssign(e.shadowNode)}finish({context:e}){On.a.mulAssign(this.shadowNode.oneMinus()),e.outgoingLight.rgb.assign(On.rgb)}}const $f=new Be;class Wf extends Zp{static get type(){return"ShadowNodeMaterial"}constructor(e){super(),this.isShadowNodeMaterial=!0,this.lights=!0,this.transparent=!0,this.setDefaultValues($f),this.setValues(e)}setupLightingModel(){return new zf}}const Hf=Un("vec3"),qf=Un("vec3"),jf=Un("vec3");class Xf extends fg{constructor(){super()}start(e){const{material:t}=e,r=Un("vec3"),s=Un("vec3");cn(ud.sub(Dd).length().greaterThan(Sd.mul(2)),()=>{r.assign(ud),s.assign(Dd)}).Else(()=>{r.assign(Dd),s.assign(ud)});const i=s.sub(r),n=_a("int").onRenderUpdate(({material:e})=>e.steps),a=i.length().div(n).toVar(),o=i.normalize().toVar(),u=gn(0).toVar(),l=vn(1).toVar();t.offsetNode&&u.addAssign(t.offsetNode.mul(a)),lp(n,()=>{const s=r.add(o.mul(u)),i=nd.mul(En(s,1)).xyz;let n;null!==t.depthNode&&(qf.assign(Ip(Lp(i.z,td,rd))),e.context.sceneDepthNode=Ip(t.depthNode).toVar()),e.context.positionWorld=s,e.context.shadowPositionWorld=s,e.context.positionView=i,Hf.assign(0),t.scatteringNode&&(n=t.scatteringNode({positionRay:s})),super.start(e),n&&Hf.mulAssign(n);const d=Hf.mul(.01).negate().mul(a).exp();l.mulAssign(d),u.addAssign(a)}),jf.addAssign(l.saturate().oneMinus())}scatteringLight(e,t){const r=t.context.sceneDepthNode;r?cn(r.greaterThanEqual(qf),()=>{Hf.addAssign(e)}):Hf.addAssign(e)}direct({lightNode:e,lightColor:t},r){if(void 0===e.light.distance)return;const s=t.xyz.toVar();s.mulAssign(e.shadowNode),this.scatteringLight(s,r)}directRectArea({lightColor:e,lightPosition:t,halfWidth:r,halfHeight:s},i){const n=t.add(r).sub(s),a=t.sub(r).sub(s),o=t.sub(r).add(s),u=t.add(r).add(s),l=i.context.positionView,d=e.xyz.mul(Yg({P:l,p0:n,p1:a,p2:o,p3:u})).pow(1.5);this.scatteringLight(d,i)}finish(e){e.context.outgoingLight.assign(jf)}}class Kf extends Zp{static get type(){return"VolumeNodeMaterial"}constructor(e){super(),this.isVolumeNodeMaterial=!0,this.steps=25,this.offsetNode=null,this.scatteringNode=null,this.lights=!0,this.transparent=!0,this.side=M,this.depthTest=!1,this.depthWrite=!1,this.setValues(e)}setupLightingModel(){return new Xf}}class Yf{constructor(e,t,r){this.renderer=e,this.nodes=t,this.info=r,this._context="undefined"!=typeof self?self:null,this._animationLoop=null,this._requestId=null}start(){const e=(t,r)=>{this._requestId=this._context.requestAnimationFrame(e),!0===this.info.autoReset&&this.info.reset(),this.nodes.nodeFrame.update(),this.info.frame=this.nodes.nodeFrame.frameId,this.renderer._inspector.begin(),null!==this._animationLoop&&this._animationLoop(t,r),this.renderer._inspector.finish()};e()}stop(){this._context.cancelAnimationFrame(this._requestId),this._requestId=null}getAnimationLoop(){return this._animationLoop}setAnimationLoop(e){this._animationLoop=e}getContext(){return this._context}setContext(e){this._context=e}dispose(){this.stop()}}class Qf{constructor(){this.weakMaps={}}_getWeakMap(e){const t=e.length;let r=this.weakMaps[t];return void 0===r&&(r=new WeakMap,this.weakMaps[t]=r),r}get(e){let t=this._getWeakMap(e);for(let r=0;r{this.dispose()},this.onGeometryDispose=()=>{this.attributes=null,this.attributesId=null},this.material.addEventListener("dispose",this.onMaterialDispose),this.geometry.addEventListener("dispose",this.onGeometryDispose)}updateClipping(e){this.clippingContext=e}get clippingNeedsUpdate(){return null!==this.clippingContext&&this.clippingContext.cacheKey!==this.clippingContextCacheKey&&(this.clippingContextCacheKey=this.clippingContext.cacheKey,!0)}get hardwareClippingPlanes(){return!0===this.material.hardwareClipping?this.clippingContext.unionClippingCount:0}getNodeBuilderState(){return this._nodeBuilderState||(this._nodeBuilderState=this._nodes.getForRender(this))}getMonitor(){return this._monitor||(this._monitor=this.getNodeBuilderState().observer)}getBindings(){return this._bindings||(this._bindings=this.getNodeBuilderState().createBindings())}getBindingGroup(e){for(const t of this.getBindings())if(t.name===e)return t}getIndex(){return this._geometries.getIndex(this)}getIndirect(){return this._geometries.getIndirect(this)}getIndirectOffset(){return this._geometries.getIndirectOffset(this)}getChainArray(){return[this.object,this.material,this.context,this.lightsNode]}setGeometry(e){this.geometry=e,this.attributes=null,this.attributesId=null}getAttributes(){if(null!==this.attributes)return this.attributes;const e=this.getNodeBuilderState().nodeAttributes,t=this.geometry,r=[],s=new Set,i={};for(const n of e){let e;if(n.node&&n.node.attribute?e=n.node.attribute:(e=t.getAttribute(n.name),i[n.name]=e.id),void 0===e)continue;r.push(e);const a=e.isInterleavedBufferAttribute?e.data:e;s.add(a)}return this.attributes=r,this.attributesId=i,this.vertexBuffers=Array.from(s.values()),r}getVertexBuffers(){return null===this.vertexBuffers&&this.getAttributes(),this.vertexBuffers}getDrawParameters(){const{object:e,material:t,geometry:r,group:s,drawRange:i}=this,n=this.drawParams||(this.drawParams={vertexCount:0,firstVertex:0,instanceCount:0,firstInstance:0}),a=this.getIndex(),o=null!==a;let u=1;if(!0===r.isInstancedBufferGeometry?u=r.instanceCount:void 0!==e.count&&(u=Math.max(0,e.count)),0===u)return null;if(n.instanceCount=u,!0===e.isBatchedMesh)return n;let l=1;!0!==t.wireframe||e.isPoints||e.isLineSegments||e.isLine||e.isLineLoop||(l=2);let d=i.start*l,c=(i.start+i.count)*l;null!==s&&(d=Math.max(d,s.start*l),c=Math.min(c,(s.start+s.count)*l));const h=r.attributes.position;let p=1/0;o?p=a.count:null!=h&&(p=h.count),d=Math.max(d,0),c=Math.min(c,p);const g=c-d;return g<0||g===1/0?null:(n.vertexCount=g,n.firstVertex=d,n)}getGeometryCacheKey(){const{geometry:e}=this;let t="";for(const r of Object.keys(e.attributes).sort()){const s=e.attributes[r];t+=r+",",s.data&&(t+=s.data.stride+","),s.offset&&(t+=s.offset+","),s.itemSize&&(t+=s.itemSize+","),s.normalized&&(t+="n,")}for(const r of Object.keys(e.morphAttributes).sort()){const s=e.morphAttributes[r];t+="morph-"+r+",";for(let e=0,r=s.length;e1||Array.isArray(e.morphTargetInfluences))&&(s+=e.uuid+","),s+=this.context.id+",",s+=e.receiveShadow+",",Us(s)}get needsGeometryUpdate(){if(this.geometry.id!==this.object.geometry.id)return!0;if(null!==this.attributes){const e=this.attributesId;for(const t in e){const r=this.geometry.getAttribute(t);if(void 0===r||e[t]!==r.id)return!0}}return!1}get needsUpdate(){return this.initialNodesCacheKey!==this.getDynamicCacheKey()||this.clippingNeedsUpdate}getDynamicCacheKey(){let e=0;return!0!==this.material.isShadowPassMaterial&&(e=this._nodes.getCacheKey(this.scene,this.lightsNode)),this.camera.isArrayCamera&&(e=Os(e,this.camera.cameras.length)),this.object.receiveShadow&&(e=Os(e,1)),e=Os(e,this.renderer.contextNode.id,this.renderer.contextNode.version),e}getCacheKey(){return this.getMaterialCacheKey()+this.getDynamicCacheKey()}dispose(){this.material.removeEventListener("dispose",this.onMaterialDispose),this.geometry.removeEventListener("dispose",this.onGeometryDispose),this.onDispose()}}const ey=[];class ty{constructor(e,t,r,s,i,n){this.renderer=e,this.nodes=t,this.geometries=r,this.pipelines=s,this.bindings=i,this.info=n,this.chainMaps={}}get(e,t,r,s,i,n,a,o){const u=this.getChainMap(o);ey[0]=e,ey[1]=t,ey[2]=n,ey[3]=i;let l=u.get(ey);return void 0===l?(l=this.createRenderObject(this.nodes,this.geometries,this.renderer,e,t,r,s,i,n,a,o),u.set(ey,l)):(l.camera=s,l.updateClipping(a),l.needsGeometryUpdate&&l.setGeometry(e.geometry),(l.version!==t.version||l.needsUpdate)&&(l.initialCacheKey!==l.getCacheKey()?(l.dispose(),l=this.get(e,t,r,s,i,n,a,o)):l.version=t.version)),ey[0]=null,ey[1]=null,ey[2]=null,ey[3]=null,l}getChainMap(e="default"){return this.chainMaps[e]||(this.chainMaps[e]=new Qf)}dispose(){this.chainMaps={}}createRenderObject(e,t,r,s,i,n,a,o,u,l,d){const c=this.getChainMap(d),h=new Jf(e,t,r,s,i,n,a,o,u,l);return h.onDispose=()=>{this.pipelines.delete(h),this.bindings.deleteForRender(h),this.nodes.delete(h),c.delete(h.getChainArray())},h}}class ry{constructor(){this.data=new WeakMap}get(e){let t=this.data.get(e);return void 0===t&&(t={},this.data.set(e,t)),t}delete(e){let t=null;return this.data.has(e)&&(t=this.data.get(e),this.data.delete(e)),t}has(e){return this.data.has(e)}dispose(){this.data=new WeakMap}}const sy=1,iy=2,ny=3,ay=4,oy=16;class uy extends ry{constructor(e){super(),this.backend=e}delete(e){const t=super.delete(e);return null!==t&&this.backend.destroyAttribute(e),t}update(e,t){const r=this.get(e);if(void 0===r.version)t===sy?this.backend.createAttribute(e):t===iy?this.backend.createIndexAttribute(e):t===ny?this.backend.createStorageAttribute(e):t===ay&&this.backend.createIndirectStorageAttribute(e),r.version=this._getBufferAttribute(e).version;else{const t=this._getBufferAttribute(e);(r.version{this.info.memory.geometries--;const s=t.index,i=e.getAttributes();null!==s&&this.attributes.delete(s);for(const e of i)this.attributes.delete(e);const n=this.wireframes.get(t);void 0!==n&&this.attributes.delete(n),t.removeEventListener("dispose",r),this._geometryDisposeListeners.delete(t)};t.addEventListener("dispose",r),this._geometryDisposeListeners.set(t,r)}updateAttributes(e){const t=e.getAttributes();for(const e of t)e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute?this.updateAttribute(e,ny):this.updateAttribute(e,sy);const r=this.getIndex(e);null!==r&&this.updateAttribute(r,iy);const s=e.geometry.indirect;null!==s&&this.updateAttribute(s,ay)}updateAttribute(e,t){const r=this.info.render.calls;e.isInterleavedBufferAttribute?void 0===this.attributeCall.get(e)?(this.attributes.update(e,t),this.attributeCall.set(e,r)):this.attributeCall.get(e.data)!==r&&(this.attributes.update(e,t),this.attributeCall.set(e.data,r),this.attributeCall.set(e,r)):this.attributeCall.get(e)!==r&&(this.attributes.update(e,t),this.attributeCall.set(e,r))}getIndirect(e){return e.geometry.indirect}getIndirectOffset(e){return e.geometry.indirectOffset}getIndex(e){const{geometry:t,material:r}=e;let s=t.index;if(!0===r.wireframe){const e=this.wireframes;let r=e.get(t);void 0===r?(r=dy(t),e.set(t,r)):r.version!==ly(t)&&(this.attributes.delete(r),r=dy(t),e.set(t,r)),s=r}return s}dispose(){for(const[e,t]of this._geometryDisposeListeners.entries())e.removeEventListener("dispose",t);this._geometryDisposeListeners.clear()}}class hy{constructor(){this.autoReset=!0,this.frame=0,this.calls=0,this.render={calls:0,frameCalls:0,drawCalls:0,triangles:0,points:0,lines:0,timestamp:0},this.compute={calls:0,frameCalls:0,timestamp:0},this.memory={geometries:0,textures:0}}update(e,t,r){this.render.drawCalls++,e.isMesh||e.isSprite?this.render.triangles+=r*(t/3):e.isPoints?this.render.points+=r*t:e.isLineSegments?this.render.lines+=r*(t/2):e.isLine?this.render.lines+=r*(t-1):o("WebGPUInfo: Unknown object type.")}reset(){this.render.drawCalls=0,this.render.frameCalls=0,this.compute.frameCalls=0,this.render.triangles=0,this.render.points=0,this.render.lines=0}dispose(){this.reset(),this.calls=0,this.render.calls=0,this.compute.calls=0,this.render.timestamp=0,this.compute.timestamp=0,this.memory.geometries=0,this.memory.textures=0}}class py{constructor(e){this.cacheKey=e,this.usedTimes=0}}class gy extends py{constructor(e,t,r){super(e),this.vertexProgram=t,this.fragmentProgram=r}}class my extends py{constructor(e,t){super(e),this.computeProgram=t,this.isComputePipeline=!0}}let fy=0;class yy{constructor(e,t,r,s=null,i=null){this.id=fy++,this.code=e,this.stage=t,this.name=r,this.transforms=s,this.attributes=i,this.usedTimes=0}}class by extends ry{constructor(e,t){super(),this.backend=e,this.nodes=t,this.bindings=null,this.caches=new Map,this.programs={vertex:new Map,fragment:new Map,compute:new Map}}getForCompute(e,t){const{backend:r}=this,s=this.get(e);if(this._needsComputeUpdate(e)){const i=s.pipeline;i&&(i.usedTimes--,i.computeProgram.usedTimes--);const n=this.nodes.getForCompute(e);let a=this.programs.compute.get(n.computeShader);void 0===a&&(i&&0===i.computeProgram.usedTimes&&this._releaseProgram(i.computeProgram),a=new yy(n.computeShader,"compute",e.name,n.transforms,n.nodeAttributes),this.programs.compute.set(n.computeShader,a),r.createProgram(a));const o=this._getComputeCacheKey(e,a);let u=this.caches.get(o);void 0===u&&(i&&0===i.usedTimes&&this._releasePipeline(i),u=this._getComputePipeline(e,a,o,t)),u.usedTimes++,a.usedTimes++,s.version=e.version,s.pipeline=u}return s.pipeline}getForRender(e,t=null){const{backend:r}=this,s=this.get(e);if(this._needsRenderUpdate(e)){const i=s.pipeline;i&&(i.usedTimes--,i.vertexProgram.usedTimes--,i.fragmentProgram.usedTimes--);const n=e.getNodeBuilderState(),a=e.material?e.material.name:"";let o=this.programs.vertex.get(n.vertexShader);void 0===o&&(i&&0===i.vertexProgram.usedTimes&&this._releaseProgram(i.vertexProgram),o=new yy(n.vertexShader,"vertex",a),this.programs.vertex.set(n.vertexShader,o),r.createProgram(o));let u=this.programs.fragment.get(n.fragmentShader);void 0===u&&(i&&0===i.fragmentProgram.usedTimes&&this._releaseProgram(i.fragmentProgram),u=new yy(n.fragmentShader,"fragment",a),this.programs.fragment.set(n.fragmentShader,u),r.createProgram(u));const l=this._getRenderCacheKey(e,o,u);let d=this.caches.get(l);void 0===d?(i&&0===i.usedTimes&&this._releasePipeline(i),d=this._getRenderPipeline(e,o,u,l,t)):e.pipeline=d,d.usedTimes++,o.usedTimes++,u.usedTimes++,s.pipeline=d}return s.pipeline}delete(e){const t=this.get(e).pipeline;return t&&(t.usedTimes--,0===t.usedTimes&&this._releasePipeline(t),t.isComputePipeline?(t.computeProgram.usedTimes--,0===t.computeProgram.usedTimes&&this._releaseProgram(t.computeProgram)):(t.fragmentProgram.usedTimes--,t.vertexProgram.usedTimes--,0===t.vertexProgram.usedTimes&&this._releaseProgram(t.vertexProgram),0===t.fragmentProgram.usedTimes&&this._releaseProgram(t.fragmentProgram))),super.delete(e)}dispose(){super.dispose(),this.caches=new Map,this.programs={vertex:new Map,fragment:new Map,compute:new Map}}updateForRender(e){this.getForRender(e)}_getComputePipeline(e,t,r,s){r=r||this._getComputeCacheKey(e,t);let i=this.caches.get(r);return void 0===i&&(i=new my(r,t),this.caches.set(r,i),this.backend.createComputePipeline(i,s)),i}_getRenderPipeline(e,t,r,s,i){s=s||this._getRenderCacheKey(e,t,r);let n=this.caches.get(s);return void 0===n&&(n=new gy(s,t,r),this.caches.set(s,n),e.pipeline=n,this.backend.createRenderPipeline(e,i)),n}_getComputeCacheKey(e,t){return e.id+","+t.id}_getRenderCacheKey(e,t,r){return t.id+","+r.id+","+this.backend.getRenderCacheKey(e)}_releasePipeline(e){this.caches.delete(e.cacheKey)}_releaseProgram(e){const t=e.code,r=e.stage;this.programs[r].delete(t)}_needsComputeUpdate(e){const t=this.get(e);return void 0===t.pipeline||t.version!==e.version}_needsRenderUpdate(e){return void 0===this.get(e).pipeline||this.backend.needsRenderUpdate(e)}}class xy extends ry{constructor(e,t,r,s,i,n){super(),this.backend=e,this.textures=r,this.pipelines=i,this.attributes=s,this.nodes=t,this.info=n,this.pipelines.bindings=this}getForRender(e){const t=e.getBindings();for(const e of t){const r=this.get(e);void 0===r.bindGroup&&(this._init(e),this.backend.createBindings(e,t,0),r.bindGroup=e)}return t}getForCompute(e){const t=this.nodes.getForCompute(e).bindings;for(const e of t){const r=this.get(e);void 0===r.bindGroup&&(this._init(e),this.backend.createBindings(e,t,0),r.bindGroup=e)}return t}updateForCompute(e){this._updateBindings(this.getForCompute(e))}updateForRender(e){this._updateBindings(this.getForRender(e))}deleteForCompute(e){const t=this.nodes.getForCompute(e).bindings;for(const e of t)this.backend.deleteBindGroupData(e),this.delete(e)}deleteForRender(e){const t=e.getBindings();for(const e of t)this.backend.deleteBindGroupData(e),this.delete(e)}_updateBindings(e){for(const t of e)this._update(t,e)}_init(e){for(const t of e.bindings)if(t.isSampledTexture)this.textures.updateTexture(t.texture);else if(t.isSampler)this.textures.updateSampler(t.texture);else if(t.isStorageBuffer){const e=t.attribute,r=e.isIndirectStorageBufferAttribute?ay:ny;this.attributes.update(e,r)}}_update(e,t){const{backend:r}=this;let s=!1,i=!0,n=0,a=0;for(const t of e.bindings){if(!1!==this.nodes.updateGroup(t)){if(t.isStorageBuffer){const e=t.attribute,i=e.isIndirectStorageBufferAttribute?ay:ny,n=r.get(t);this.attributes.update(e,i),n.attribute!==e&&(n.attribute=e,s=!0)}if(t.isUniformBuffer){t.update()&&r.updateBinding(t)}else if(t.isSampledTexture){const e=t.update(),o=t.texture,u=this.textures.get(o);e&&(this.textures.updateTexture(o),t.generation!==u.generation&&(t.generation=u.generation,s=!0,i=!1));if(void 0!==r.get(o).externalTexture||u.isDefaultTexture?i=!1:(n=10*n+o.id,a+=o.version),!0===o.isStorageTexture&&!0===o.mipmapsAutoUpdate){const e=this.get(o);!0===t.store?e.needsMipmap=!0:this.textures.needsMipmaps(o)&&!0===e.needsMipmap&&(this.backend.generateMipmaps(o),e.needsMipmap=!1)}}else if(t.isSampler){if(t.update()){const e=this.textures.updateSampler(t.texture);t.samplerKey!==e&&(t.samplerKey=e,s=!0,i=!1)}}t.isBuffer&&t.updateRanges.length>0&&t.clearUpdateRanges()}}!0===s&&this.backend.updateBindings(e,t,i?n:0,a)}}function Ty(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?e.z-t.z:e.id-t.id}function _y(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?t.z-e.z:e.id-t.id}function vy(e){return(e.transmission>0||e.transmissionNode&&e.transmissionNode.isNode)&&e.side===F&&!1===e.forceSinglePass}class Ny{constructor(e,t,r){this.renderItems=[],this.renderItemsIndex=0,this.opaque=[],this.transparentDoublePass=[],this.transparent=[],this.bundles=[],this.lightsNode=e.getNode(t,r),this.lightsArray=[],this.scene=t,this.camera=r,this.occlusionQueryCount=0}begin(){return this.renderItemsIndex=0,this.opaque.length=0,this.transparentDoublePass.length=0,this.transparent.length=0,this.bundles.length=0,this.lightsArray.length=0,this.occlusionQueryCount=0,this}getNextRenderItem(e,t,r,s,i,n,a){let o=this.renderItems[this.renderItemsIndex];return void 0===o?(o={id:e.id,object:e,geometry:t,material:r,groupOrder:s,renderOrder:e.renderOrder,z:i,group:n,clippingContext:a},this.renderItems[this.renderItemsIndex]=o):(o.id=e.id,o.object=e,o.geometry=t,o.material=r,o.groupOrder=s,o.renderOrder=e.renderOrder,o.z=i,o.group=n,o.clippingContext=a),this.renderItemsIndex++,o}push(e,t,r,s,i,n,a){const o=this.getNextRenderItem(e,t,r,s,i,n,a);!0===e.occlusionTest&&this.occlusionQueryCount++,!0===r.transparent||r.transmission>0||r.transmissionNode&&r.transmissionNode.isNode||r.backdropNode&&r.backdropNode.isNode?(vy(r)&&this.transparentDoublePass.push(o),this.transparent.push(o)):this.opaque.push(o)}unshift(e,t,r,s,i,n,a){const o=this.getNextRenderItem(e,t,r,s,i,n,a);!0===r.transparent||r.transmission>0||r.transmissionNode&&r.transmissionNode.isNode||r.backdropNode&&r.backdropNode.isNode?(vy(r)&&this.transparentDoublePass.unshift(o),this.transparent.unshift(o)):this.opaque.unshift(o)}pushBundle(e){this.bundles.push(e)}pushLight(e){this.lightsArray.push(e)}sort(e,t){this.opaque.length>1&&this.opaque.sort(e||Ty),this.transparentDoublePass.length>1&&this.transparentDoublePass.sort(t||_y),this.transparent.length>1&&this.transparent.sort(t||_y)}finish(){this.lightsNode.setLights(this.lightsArray);for(let e=this.renderItemsIndex,t=this.renderItems.length;e>t,u=a.height>>t;let l=e.depthTexture||i[t];const d=!0===e.depthBuffer||!0===e.stencilBuffer;let c=!1;void 0===l&&d&&(l=new Y,l.format=e.stencilBuffer?Oe:Ve,l.type=e.stencilBuffer?ke:S,l.image.width=o,l.image.height=u,l.image.depth=a.depth,l.renderTarget=e,l.isArrayTexture=!0===e.multiview&&a.depth>1,i[t]=l),r.width===a.width&&a.height===r.height||(c=!0,l&&(l.needsUpdate=!0,l.image.width=o,l.image.height=u,l.image.depth=l.isArrayTexture?l.image.depth:1)),r.width=a.width,r.height=a.height,r.textures=n,r.depthTexture=l||null,r.depth=e.depthBuffer,r.stencil=e.stencilBuffer,r.renderTarget=e,r.sampleCount!==s&&(c=!0,l&&(l.needsUpdate=!0),r.sampleCount=s);const h={sampleCount:s};if(!0!==e.isXRRenderTarget){for(let e=0;e{this._destroyRenderTarget(e)},e.addEventListener("dispose",r.onDispose))}updateTexture(e,t={}){const r=this.get(e);if(!0===r.initialized&&r.version===e.version)return;const s=e.isRenderTargetTexture||e.isDepthTexture||e.isFramebufferTexture,i=this.backend;if(s&&!0===r.initialized&&i.destroyTexture(e),e.isFramebufferTexture){const t=this.renderer.getRenderTarget();e.type=t?t.texture.type:Ge}const{width:n,height:a,depth:o}=this.getSize(e);if(t.width=n,t.height=a,t.depth=o,t.needsMipmaps=this.needsMipmaps(e),t.levels=t.needsMipmaps?this.getMipLevels(e,n,a):1,e.isCubeTexture&&e.mipmaps.length>0&&t.levels++,s||!0===e.isStorageTexture||!0===e.isExternalTexture)i.createTexture(e,t),r.generation=e.version;else if(e.version>0){const s=e.image;if(void 0===s)d("Renderer: Texture marked for update but image is undefined.");else if(!1===s.complete)d("Renderer: Texture marked for update but image is incomplete.");else{if(e.images){const r=[];for(const t of e.images)r.push(t);t.images=r}else t.image=s;void 0!==r.isDefaultTexture&&!0!==r.isDefaultTexture||(i.createTexture(e,t),r.isDefaultTexture=!1,r.generation=e.version),!0===e.source.dataReady&&i.updateTexture(e,t);const n=!0===e.isStorageTexture&&!1===e.mipmapsAutoUpdate;t.needsMipmaps&&0===e.mipmaps.length&&!n&&i.generateMipmaps(e),e.onUpdate&&e.onUpdate(e)}}else i.createDefaultTexture(e),r.isDefaultTexture=!0,r.generation=e.version;!0!==r.initialized&&(r.initialized=!0,r.generation=e.version,this.info.memory.textures++,e.isVideoTexture&&!0===p.enabled&&p.getTransfer(e.colorSpace)!==g&&d("WebGPURenderer: Video textures must use a color space with a sRGB transfer function, e.g. SRGBColorSpace."),r.onDispose=()=>{this._destroyTexture(e)},e.addEventListener("dispose",r.onDispose)),r.version=e.version}updateSampler(e){return this.backend.updateSampler(e)}getSize(e,t=My){let r=e.images?e.images[0]:e.image;return r?(void 0!==r.image&&(r=r.image),"undefined"!=typeof HTMLVideoElement&&r instanceof HTMLVideoElement?(t.width=r.videoWidth||1,t.height=r.videoHeight||1,t.depth=1):"undefined"!=typeof VideoFrame&&r instanceof VideoFrame?(t.width=r.displayWidth||1,t.height=r.displayHeight||1,t.depth=1):(t.width=r.width||1,t.height=r.height||1,t.depth=e.isCubeTexture?6:r.depth||1)):t.width=t.height=t.depth=1,t}getMipLevels(e,t,r){let s;return s=e.mipmaps.length>0?e.mipmaps.length:!0===e.isCompressedTexture?1:Math.floor(Math.log2(Math.max(t,r)))+1,s}needsMipmaps(e){return!0===e.generateMipmaps||e.mipmaps.length>0}_destroyRenderTarget(e){if(!0===this.has(e)){const t=this.get(e),r=t.textures,s=t.depthTexture;e.removeEventListener("dispose",t.onDispose);for(let e=0;e=2)for(let r=0;r{if(this._currentNode=t,!t.isVarNode||!t.isIntent(e)||!0===t.isAssign(e))if("setup"===s)t.build(e);else if("analyze"===s)t.build(e,this);else if("generate"===s){const r=e.getDataFromNode(t,"any").stages,s=r&&r[e.shaderStage];if(t.isVarNode&&s&&1===s.length&&s[0]&&s[0].isStackNode)return;t.build(e,"void")}},n=[...this.nodes];for(const e of n)i(e);this._currentNode=null;const a=this.nodes.filter(e=>-1===n.indexOf(e));for(const e of a)i(e);let o;return o=this.hasOutput(e)?this.outputNode.build(e,...t):super.build(e,...t),ln(r),e.removeActiveStack(this),o}}const Dy=rn(By).setParameterLength(0,1);class Uy extends ui{static get type(){return"StructTypeNode"}constructor(e,t=null){var r;super("struct"),this.membersLayout=(r=e,Object.entries(r).map(([e,t])=>"string"==typeof t?{name:e,type:t,atomic:!1}:{name:e,type:t.type,atomic:t.atomic||!1})),this.name=t,this.isStructLayoutNode=!0}getLength(){const e=Float32Array.BYTES_PER_ELEMENT;let t=1,r=0;for(const s of this.membersLayout){const i=s.type,n=Ws(i),a=Hs(i)/e;t=Math.max(t,a);const o=r%t%a;0!==o&&(r+=a-o),r+=n}return Math.ceil(r/t)*t}getMemberType(e,t){const r=this.membersLayout.find(e=>e.name===t);return r?r.type:"void"}getNodeType(e){return e.getStructTypeFromNode(this,this.membersLayout,this.name).name}setup(e){e.getStructTypeFromNode(this,this.membersLayout,this.name),e.addInclude(this)}generate(e){return this.getNodeType(e)}}class Iy extends ui{static get type(){return"StructNode"}constructor(e,t){super("vec3"),this.structTypeNode=e,this.values=t,this.isStructNode=!0}getNodeType(e){return this.structTypeNode.getNodeType(e)}getMemberType(e,t){return this.structTypeNode.getMemberType(e,t)}_getChildren(){const e=super._getChildren(),t=e.find(e=>e.childNode===this.structTypeNode);return e.splice(e.indexOf(t),1),e.push(t),e}generate(e){const t=e.getVarFromNode(this),r=t.type,s=e.getPropertyName(t);return e.addLineFlowCode(`${s} = ${e.generateStruct(r,this.structTypeNode.membersLayout,this.values)}`,this),t.name}}class Oy extends ui{static get type(){return"OutputStructNode"}constructor(...e){super(),this.members=e,this.isOutputStructNode=!0}getNodeType(){return"OutputType"}generate(e){const t=e.getDataFromNode(this);if(void 0===t.membersLayout){const r=this.members,s=[];for(let t=0;tnew qy(e,"uint","float"),Ky={};class Yy extends ro{static get type(){return"BitcountNode"}constructor(e,t){super(e,t),this.isBitcountNode=!0}_resolveElementType(e,t,r){"int"===r?t.assign(jy(e,"uint")):t.assign(e)}_returnDataNode(e){switch(e){case"uint":return fn;case"int":return mn;case"uvec2":return Tn;case"uvec3":return Sn;case"uvec4":return wn;case"ivec2":return xn;case"ivec3":return Nn;case"ivec4":return An}}_createTrailingZerosBaseLayout(e,t){const r=this._returnDataNode(t);return un(([e])=>{const s=fn(0);this._resolveElementType(e,s,t);const i=gn(s.bitAnd(Po(s))),n=Xy(i).shiftRight(23).sub(127);return r(n)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createLeadingZerosBaseLayout(e,t){const r=this._returnDataNode(t);return un(([e])=>{cn(e.equal(fn(0)),()=>fn(32));const s=fn(0),i=fn(0);return this._resolveElementType(e,s,t),cn(s.shiftRight(16).equal(0),()=>{i.addAssign(16),s.shiftLeftAssign(16)}),cn(s.shiftRight(24).equal(0),()=>{i.addAssign(8),s.shiftLeftAssign(8)}),cn(s.shiftRight(28).equal(0),()=>{i.addAssign(4),s.shiftLeftAssign(4)}),cn(s.shiftRight(30).equal(0),()=>{i.addAssign(2),s.shiftLeftAssign(2)}),cn(s.shiftRight(31).equal(0),()=>{i.addAssign(1)}),r(i)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createOneBitsBaseLayout(e,t){const r=this._returnDataNode(t);return un(([e])=>{const s=fn(0);this._resolveElementType(e,s,t),s.assign(s.sub(s.shiftRight(fn(1)).bitAnd(fn(1431655765)))),s.assign(s.bitAnd(fn(858993459)).add(s.shiftRight(fn(2)).bitAnd(fn(858993459))));const i=s.add(s.shiftRight(fn(4))).bitAnd(fn(252645135)).mul(fn(16843009)).shiftRight(fn(24));return r(i)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createMainLayout(e,t,r,s){const i=this._returnDataNode(t);return un(([e])=>{if(1===r)return i(s(e));{const t=i(0),n=["x","y","z","w"];for(let i=0;id(r))()}}Yy.COUNT_TRAILING_ZEROS="countTrailingZeros",Yy.COUNT_LEADING_ZEROS="countLeadingZeros",Yy.COUNT_ONE_BITS="countOneBits";const Qy=nn(Yy,Yy.COUNT_TRAILING_ZEROS).setParameterLength(1),Zy=nn(Yy,Yy.COUNT_LEADING_ZEROS).setParameterLength(1),Jy=nn(Yy,Yy.COUNT_ONE_BITS).setParameterLength(1),eb=un(([e])=>{const t=e.toUint().mul(747796405).add(2891336453),r=t.shiftRight(t.shiftRight(28).add(4)).bitXor(t).mul(277803737);return r.shiftRight(22).bitXor(r).toFloat().mul(1/2**32)}),tb=(e,t)=>Zo(La(4,e.mul(Fa(1,e))),t);class rb extends ci{static get type(){return"PackFloatNode"}constructor(e,t){super(),this.vectorNode=t,this.encoding=e,this.isPackFloatNode=!0}getNodeType(){return"uint"}generate(e){const t=this.vectorNode.getNodeType(e);return`${e.getFloatPackingMethod(this.encoding)}(${this.vectorNode.build(e,t)})`}}const sb=nn(rb,"snorm").setParameterLength(1),ib=nn(rb,"unorm").setParameterLength(1),nb=nn(rb,"float16").setParameterLength(1);class ab extends ci{static get type(){return"UnpackFloatNode"}constructor(e,t){super(),this.uintNode=t,this.encoding=e,this.isUnpackFloatNode=!0}getNodeType(){return"vec2"}generate(e){const t=this.uintNode.getNodeType(e);return`${e.getFloatUnpackingMethod(this.encoding)}(${this.uintNode.build(e,t)})`}}const ob=nn(ab,"snorm").setParameterLength(1),ub=nn(ab,"unorm").setParameterLength(1),lb=nn(ab,"float16").setParameterLength(1),db=un(([e])=>e.fract().sub(.5).abs()).setLayout({name:"tri",type:"float",inputs:[{name:"x",type:"float"}]}),cb=un(([e])=>vn(db(e.z.add(db(e.y.mul(1)))),db(e.z.add(db(e.x.mul(1)))),db(e.y.add(db(e.x.mul(1)))))).setLayout({name:"tri3",type:"vec3",inputs:[{name:"p",type:"vec3"}]}),hb=un(([e,t,r])=>{const s=vn(e).toVar(),i=gn(1.4).toVar(),n=gn(0).toVar(),a=vn(s).toVar();return lp({start:gn(0),end:gn(3),type:"float",condition:"<="},()=>{const e=vn(cb(a.mul(2))).toVar();s.addAssign(e.add(r.mul(gn(.1).mul(t)))),a.mulAssign(1.8),i.mulAssign(1.5),s.mulAssign(1.2);const o=gn(db(s.z.add(db(s.x.add(db(s.y)))))).toVar();n.addAssign(o.div(i)),a.addAssign(.14)}),n}).setLayout({name:"triNoise3D",type:"float",inputs:[{name:"position",type:"vec3"},{name:"speed",type:"float"},{name:"time",type:"float"}]});class pb extends ui{static get type(){return"FunctionOverloadingNode"}constructor(e=[],...t){super(),this.functionNodes=e,this.parametersNodes=t,this._candidateFn=null,this.global=!0}getNodeType(e){return this.getCandidateFn(e).shaderNode.layout.type}getCandidateFn(e){const t=this.parametersNodes;let r=this._candidateFn;if(null===r){let s=null,i=-1;for(const r of this.functionNodes){const n=r.shaderNode.layout;if(null===n)throw new Error("FunctionOverloadingNode: FunctionNode must be a layout.");const a=n.inputs;if(t.length===a.length){let n=0;for(let r=0;ri&&(s=r,i=n)}}this._candidateFn=r=s}return r}setup(e){return this.getCandidateFn(e)(...this.parametersNodes)}}const gb=rn(pb),mb=e=>(...t)=>gb(e,...t),fb=_a(0).setGroup(ba).onRenderUpdate(e=>e.time),yb=_a(0).setGroup(ba).onRenderUpdate(e=>e.deltaTime),bb=_a(0,"uint").setGroup(ba).onRenderUpdate(e=>e.frameId);const xb=un(([e,t,r=bn(.5)])=>Df(e.sub(r),t).add(r)),Tb=un(([e,t,r=bn(.5)])=>{const s=e.sub(r),i=s.dot(s),n=i.mul(i).mul(t);return e.add(s.mul(n))}),_b=un(({position:e=null,horizontal:t=!0,vertical:r=!1})=>{let s;null!==e?(s=Td.toVar(),s[3][0]=e.x,s[3][1]=e.y,s[3][2]=e.z):s=Td;const i=nd.mul(s);return Ki(t)&&(i[0][0]=Td[0].length(),i[0][1]=0,i[0][2]=0),Ki(r)&&(i[1][0]=0,i[1][1]=Td[1].length(),i[1][2]=0),i[2][0]=0,i[2][1]=0,i[2][2]=1,sd.mul(i).mul(Pd)}),vb=un(([e=null])=>{const t=Ip();return Ip(Cp(e)).sub(t).lessThan(0).select(ql,e)}),Nb=un(([e,t=Rl(),r=gn(0)])=>{const s=e.x,i=e.y,n=r.mod(s.mul(i)).floor(),a=n.mod(s),o=i.sub(n.add(1).div(s).ceil()),u=e.reciprocal(),l=bn(a,o);return t.add(l).mul(u)}),Sb=un(([e,t=null,r=null,s=gn(1),i=Pd,n=Wd])=>{let a=n.abs().normalize();a=a.div(a.dot(vn(1)));const o=i.yz.mul(s),u=i.zx.mul(s),l=i.xy.mul(s),d=e.value,c=null!==t?t.value:d,h=null!==r?r.value:d,p=Pl(d,o).mul(a.x),g=Pl(c,u).mul(a.y),m=Pl(h,l).mul(a.z);return Ma(p,g,m)}),Rb=new je,Eb=new r,Ab=new r,wb=new r,Cb=new a,Mb=new r(0,0,-1),Fb=new s,Lb=new r,Pb=new r,Bb=new s,Db=new t,Ub=new Ne,Ib=ql.flipX();Ub.depthTexture=new Y(1,1);let Ob=!1;class Vb extends Fl{static get type(){return"ReflectorNode"}constructor(e={}){super(e.defaultTexture||Ub.texture,Ib),this._reflectorBaseNode=e.reflector||new kb(this,e),this._depthNode=null,this.setUpdateMatrix(!1)}get reflector(){return this._reflectorBaseNode}get target(){return this._reflectorBaseNode.target}getDepthNode(){if(null===this._depthNode){if(!0!==this._reflectorBaseNode.depth)throw new Error("THREE.ReflectorNode: Depth node can only be requested when the reflector is created with { depth: true }. ");this._depthNode=Zi(new Vb({defaultTexture:Ub.depthTexture,reflector:this._reflectorBaseNode}))}return this._depthNode}setup(e){return e.object.isQuadMesh||this._reflectorBaseNode.build(e),super.setup(e)}clone(){const e=new this.constructor(this.reflectorNode);return e.uvNode=this.uvNode,e.levelNode=this.levelNode,e.biasNode=this.biasNode,e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e._reflectorBaseNode=this._reflectorBaseNode,e}dispose(){super.dispose(),this._reflectorBaseNode.dispose()}}class kb extends ui{static get type(){return"ReflectorBaseNode"}constructor(e,t={}){super();const{target:r=new Xe,resolutionScale:s=1,generateMipmaps:i=!1,bounces:n=!0,depth:a=!1,samples:o=0}=t;this.textureNode=e,this.target=r,this.resolutionScale=s,void 0!==t.resolution&&(v('ReflectorNode: The "resolution" parameter has been renamed to "resolutionScale".'),this.resolutionScale=t.resolution),this.generateMipmaps=i,this.bounces=n,this.depth=a,this.samples=o,this.updateBeforeType=n?Js.RENDER:Js.FRAME,this.virtualCameras=new WeakMap,this.renderTargets=new Map,this.forceUpdate=!1,this.hasOutput=!1}_updateResolution(e,t){const r=this.resolutionScale;t.getDrawingBufferSize(Db),e.setSize(Math.round(Db.width*r),Math.round(Db.height*r))}setup(e){return this._updateResolution(Ub,e.renderer),super.setup(e)}dispose(){super.dispose();for(const e of this.renderTargets.values())e.dispose()}getVirtualCamera(e){let t=this.virtualCameras.get(e);return void 0===t&&(t=e.clone(),this.virtualCameras.set(e,t)),t}getRenderTarget(e){let t=this.renderTargets.get(e);return void 0===t&&(t=new Ne(0,0,{type:be,samples:this.samples}),!0===this.generateMipmaps&&(t.texture.minFilter=Ke,t.texture.generateMipmaps=!0),!0===this.depth&&(t.depthTexture=new Y),this.renderTargets.set(e,t)),t}updateBefore(e){if(!1===this.bounces&&Ob)return!1;Ob=!0;const{scene:t,camera:r,renderer:s,material:i}=e,{target:n}=this,a=this.getVirtualCamera(r),o=this.getRenderTarget(a);s.getDrawingBufferSize(Db),this._updateResolution(o,s),Ab.setFromMatrixPosition(n.matrixWorld),wb.setFromMatrixPosition(r.matrixWorld),Cb.extractRotation(n.matrixWorld),Eb.set(0,0,1),Eb.applyMatrix4(Cb),Lb.subVectors(Ab,wb);let u=!1;if(!0===Lb.dot(Eb)>0&&!1===this.forceUpdate){if(!1===this.hasOutput)return void(Ob=!1);u=!0}Lb.reflect(Eb).negate(),Lb.add(Ab),Cb.extractRotation(r.matrixWorld),Mb.set(0,0,-1),Mb.applyMatrix4(Cb),Mb.add(wb),Pb.subVectors(Ab,Mb),Pb.reflect(Eb).negate(),Pb.add(Ab),a.coordinateSystem=r.coordinateSystem,a.position.copy(Lb),a.up.set(0,1,0),a.up.applyMatrix4(Cb),a.up.reflect(Eb),a.lookAt(Pb),a.near=r.near,a.far=r.far,a.updateMatrixWorld(),a.projectionMatrix.copy(r.projectionMatrix),Rb.setFromNormalAndCoplanarPoint(Eb,Ab),Rb.applyMatrix4(a.matrixWorldInverse),Fb.set(Rb.normal.x,Rb.normal.y,Rb.normal.z,Rb.constant);const l=a.projectionMatrix;Bb.x=(Math.sign(Fb.x)+l.elements[8])/l.elements[0],Bb.y=(Math.sign(Fb.y)+l.elements[9])/l.elements[5],Bb.z=-1,Bb.w=(1+l.elements[10])/l.elements[14],Fb.multiplyScalar(1/Fb.dot(Bb));l.elements[2]=Fb.x,l.elements[6]=Fb.y,l.elements[10]=s.coordinateSystem===h?Fb.z-0:Fb.z+1-0,l.elements[14]=Fb.w,this.textureNode.value=o.texture,!0===this.depth&&(this.textureNode.getDepthNode().value=o.depthTexture),i.visible=!1;const d=s.getRenderTarget(),c=s.getMRT(),p=s.autoClear;s.setMRT(null),s.setRenderTarget(o),s.autoClear=!0;const g=t.name;t.name=(t.name||"Scene")+" [ Reflector ]",u?(s.clear(),this.hasOutput=!1):(s.render(t,a),this.hasOutput=!0),t.name=g,s.setMRT(c),s.setRenderTarget(d),s.autoClear=p,i.visible=!0,Ob=!1,this.forceUpdate=!1}get resolution(){return v('ReflectorNode: The "resolution" property has been renamed to "resolutionScale".'),this.resolutionScale}set resolution(e){v('ReflectorNode: The "resolution" property has been renamed to "resolutionScale".'),this.resolutionScale=e}}const Gb=new _e(-1,1,1,-1,0,1);class zb extends Te{constructor(e=!1){super();const t=!1===e?[0,-1,0,1,2,1]:[0,2,0,0,2,0];this.setAttribute("position",new Ye([-1,3,0,-1,-1,0,3,-1,0],3)),this.setAttribute("uv",new Ye(t,2))}}const $b=new zb;class Wb extends ne{constructor(e=null){super($b,e),this.camera=Gb,this.isQuadMesh=!0}async renderAsync(e){v('QuadMesh: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await e.init(),e.render(this,Gb)}render(e){e.render(this,Gb)}}const Hb=new t;class qb extends Fl{static get type(){return"RTTNode"}constructor(e,t=null,r=null,s={type:be}){const i=new Ne(t,r,s);super(i.texture,Rl()),this.isRTTNode=!0,this.node=e,this.width=t,this.height=r,this.pixelRatio=1,this.renderTarget=i,this.textureNeedsUpdate=!0,this.autoUpdate=!0,this._rttNode=null,this._quadMesh=new Wb(new Zp),this.updateBeforeType=Js.RENDER}get autoResize(){return null===this.width}setup(e){return this._rttNode=this.node.context(e.getSharedContext()),this._quadMesh.material.name="RTT",this._quadMesh.material.needsUpdate=!0,super.setup(e)}setSize(e,t){this.width=e,this.height=t;const r=e*this.pixelRatio,s=t*this.pixelRatio;this.renderTarget.setSize(r,s),this.textureNeedsUpdate=!0}setPixelRatio(e){this.pixelRatio=e,this.setSize(this.width,this.height)}updateBefore({renderer:e}){if(!1===this.textureNeedsUpdate&&!1===this.autoUpdate)return;if(this.textureNeedsUpdate=!1,!0===this.autoResize){const t=e.getPixelRatio(),r=e.getSize(Hb),s=Math.floor(r.width*t),i=Math.floor(r.height*t);s===this.renderTarget.width&&i===this.renderTarget.height||(this.renderTarget.setSize(s,i),this.textureNeedsUpdate=!0)}let t="RTT";this.node.name&&(t=this.node.name+" [ "+t+" ]"),this._quadMesh.material.fragmentNode=this._rttNode,this._quadMesh.name=t;const r=e.getRenderTarget();e.setRenderTarget(this.renderTarget),this._quadMesh.render(e),e.setRenderTarget(r)}clone(){const e=new Fl(this.value,this.uvNode,this.levelNode);return e.sampler=this.sampler,e.referenceNode=this,e}}const jb=(e,...t)=>Zi(new qb(Zi(e),...t)),Xb=un(([e,t,r],s)=>{let i;s.renderer.coordinateSystem===h?(e=bn(e.x,e.y.oneMinus()).mul(2).sub(1),i=En(vn(e,t),1)):i=En(vn(e.x,e.y.oneMinus(),t).mul(2).sub(1),1);const n=En(r.mul(i));return n.xyz.div(n.w)}),Kb=un(([e,t])=>{const r=t.mul(En(e,1)),s=r.xy.div(r.w).mul(.5).add(.5).toVar();return bn(s.x,s.y.oneMinus())}),Yb=un(([e,t,r])=>{const s=Al(Bl(t)),i=xn(e.mul(s)).toVar(),n=Bl(t,i).toVar(),a=Bl(t,i.sub(xn(2,0))).toVar(),o=Bl(t,i.sub(xn(1,0))).toVar(),u=Bl(t,i.add(xn(1,0))).toVar(),l=Bl(t,i.add(xn(2,0))).toVar(),d=Bl(t,i.add(xn(0,2))).toVar(),c=Bl(t,i.add(xn(0,1))).toVar(),h=Bl(t,i.sub(xn(0,1))).toVar(),p=Bl(t,i.sub(xn(0,2))).toVar(),g=Mo(Fa(gn(2).mul(o).sub(a),n)).toVar(),m=Mo(Fa(gn(2).mul(u).sub(l),n)).toVar(),f=Mo(Fa(gn(2).mul(c).sub(d),n)).toVar(),y=Mo(Fa(gn(2).mul(h).sub(p),n)).toVar(),b=Xb(e,n,r).toVar(),x=g.lessThan(m).select(b.sub(Xb(e.sub(bn(gn(1).div(s.x),0)),o,r)),b.negate().add(Xb(e.add(bn(gn(1).div(s.x),0)),u,r))),T=f.lessThan(y).select(b.sub(Xb(e.add(bn(0,gn(1).div(s.y))),c,r)),b.negate().add(Xb(e.sub(bn(0,gn(1).div(s.y))),h,r)));return vo(Qo(x,T))}),Qb=un(([e])=>No(gn(52.9829189).mul(No(Yo(e,bn(.06711056,.00583715)))))).setLayout({name:"interleavedGradientNoise",type:"float",inputs:[{name:"position",type:"vec2"}]}),Zb=un(([e,t,r])=>{const s=gn(2.399963229728653),i=bo(gn(e).add(.5).div(gn(t))),n=gn(e).mul(s).add(r);return bn(Ro(n),So(n)).mul(i)}).setLayout({name:"vogelDiskSample",type:"vec2",inputs:[{name:"sampleIndex",type:"int"},{name:"samplesCount",type:"int"},{name:"phi",type:"float"}]});class Jb extends ui{static get type(){return"SampleNode"}constructor(e,t=null){super(),this.callback=e,this.uvNode=t,this.isSampleNode=!0}setup(){return this.sample(Rl())}sample(e){return this.callback(e)}}class ex extends ui{static get type(){return"EventNode"}constructor(e,t){super("void"),this.eventType=e,this.callback=t,e===ex.OBJECT?this.updateType=Js.OBJECT:e===ex.MATERIAL?this.updateType=Js.RENDER:e===ex.BEFORE_OBJECT?this.updateBeforeType=Js.OBJECT:e===ex.BEFORE_MATERIAL&&(this.updateBeforeType=Js.RENDER)}update(e){this.callback(e)}updateBefore(e){this.callback(e)}}ex.OBJECT="object",ex.MATERIAL="material",ex.BEFORE_OBJECT="beforeObject",ex.BEFORE_MATERIAL="beforeMaterial";const tx=(e,t)=>new ex(e,t).toStack();class rx extends W{constructor(e,t,r=Float32Array){super(ArrayBuffer.isView(e)?e:new r(e*t),t),this.isStorageInstancedBufferAttribute=!0}}class sx extends Ae{constructor(e,t,r=Float32Array){super(ArrayBuffer.isView(e)?e:new r(e*t),t),this.isStorageBufferAttribute=!0}}class ix extends ui{static get type(){return"PointUVNode"}constructor(){super("vec2"),this.isPointUVNode=!0}generate(){return"vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y )"}}const nx=sn(ix),ax=new L,ox=new a,ux=_a(0).setGroup(ba).onRenderUpdate(({scene:e})=>e.backgroundBlurriness),lx=_a(1).setGroup(ba).onRenderUpdate(({scene:e})=>e.backgroundIntensity),dx=_a(new a).setGroup(ba).onRenderUpdate(({scene:e})=>{const t=e.background;return null!==t&&t.isTexture&&t.mapping!==Qe?(ax.copy(e.backgroundRotation),ax.x*=-1,ax.y*=-1,ax.z*=-1,ox.makeRotationFromEuler(ax)):ox.identity(),ox});class cx extends Fl{static get type(){return"StorageTextureNode"}constructor(e,t,r=null){super(e,t),this.storeNode=r,this.mipLevel=0,this.isStorageTextureNode=!0,this.access=ti.WRITE_ONLY}getInputType(){return"storageTexture"}setup(e){super.setup(e);const t=e.getNodeProperties(this);return t.storeNode=this.storeNode,t}setAccess(e){return this.access=e,this}setMipLevel(e){return this.mipLevel=e,this}generate(e,t){let r;return r=null!==this.storeNode?this.generateStore(e):super.generate(e,t),r}toReadWrite(){return this.setAccess(ti.READ_WRITE)}toReadOnly(){return this.setAccess(ti.READ_ONLY)}toWriteOnly(){return this.setAccess(ti.WRITE_ONLY)}generateStore(e){const t=e.getNodeProperties(this),{uvNode:r,storeNode:s,depthNode:i}=t,n=super.generate(e,"property"),a=r.build(e,!0===this.value.is3DTexture?"uvec3":"uvec2"),o=s.build(e,"vec4"),u=i?i.build(e,"int"):null,l=e.generateTextureStore(e,n,a,u,o);e.addLineFlowCode(l,this)}clone(){const e=super.clone();return e.storeNode=this.storeNode,e.mipLevel=this.mipLevel,e.access=this.access,e}}const hx=rn(cx).setParameterLength(1,3),px=un(({texture:e,uv:t})=>{const r=1e-4,s=vn().toVar();return cn(t.x.lessThan(r),()=>{s.assign(vn(1,0,0))}).ElseIf(t.y.lessThan(r),()=>{s.assign(vn(0,1,0))}).ElseIf(t.z.lessThan(r),()=>{s.assign(vn(0,0,1))}).ElseIf(t.x.greaterThan(.9999),()=>{s.assign(vn(-1,0,0))}).ElseIf(t.y.greaterThan(.9999),()=>{s.assign(vn(0,-1,0))}).ElseIf(t.z.greaterThan(.9999),()=>{s.assign(vn(0,0,-1))}).Else(()=>{const r=.01,i=e.sample(t.add(vn(-.01,0,0))).r.sub(e.sample(t.add(vn(r,0,0))).r),n=e.sample(t.add(vn(0,-.01,0))).r.sub(e.sample(t.add(vn(0,r,0))).r),a=e.sample(t.add(vn(0,0,-.01))).r.sub(e.sample(t.add(vn(0,0,r))).r);s.assign(vn(i,n,a))}),s.normalize()});class gx extends Fl{static get type(){return"Texture3DNode"}constructor(e,t=null,r=null){super(e,t,r),this.isTexture3DNode=!0}getInputType(){return"texture3D"}getDefaultUV(){return vn(.5,.5,.5)}setUpdateMatrix(){}generateUV(e,t){return t.build(e,!0===this.sampler?"vec3":"ivec3")}generateOffset(e,t){return t.build(e,"ivec3")}normal(e){return px({texture:this,uv:e})}}const mx=rn(gx).setParameterLength(1,3);class fx extends fc{static get type(){return"UserDataNode"}constructor(e,t,r=null){super(e,t,r),this.userData=r}updateReference(e){return this.reference=null!==this.userData?this.userData:e.object.userData,this.reference}}const yx=new WeakMap;class bx extends ci{static get type(){return"VelocityNode"}constructor(){super("vec2"),this.projectionMatrix=null,this.updateType=Js.OBJECT,this.updateAfterType=Js.OBJECT,this.previousModelWorldMatrix=_a(new a),this.previousProjectionMatrix=_a(new a).setGroup(ba),this.previousCameraViewMatrix=_a(new a)}setProjectionMatrix(e){this.projectionMatrix=e}update({frameId:e,camera:t,object:r}){const s=Tx(r);this.previousModelWorldMatrix.value.copy(s);const i=xx(t);i.frameId!==e&&(i.frameId=e,void 0===i.previousProjectionMatrix?(i.previousProjectionMatrix=new a,i.previousCameraViewMatrix=new a,i.currentProjectionMatrix=new a,i.currentCameraViewMatrix=new a,i.previousProjectionMatrix.copy(this.projectionMatrix||t.projectionMatrix),i.previousCameraViewMatrix.copy(t.matrixWorldInverse)):(i.previousProjectionMatrix.copy(i.currentProjectionMatrix),i.previousCameraViewMatrix.copy(i.currentCameraViewMatrix)),i.currentProjectionMatrix.copy(this.projectionMatrix||t.projectionMatrix),i.currentCameraViewMatrix.copy(t.matrixWorldInverse),this.previousProjectionMatrix.value.copy(i.previousProjectionMatrix),this.previousCameraViewMatrix.value.copy(i.previousCameraViewMatrix))}updateAfter({object:e}){Tx(e).copy(e.matrixWorld)}setup(){const e=null===this.projectionMatrix?sd:_a(this.projectionMatrix),t=this.previousCameraViewMatrix.mul(this.previousModelWorldMatrix),r=e.mul(Ad).mul(Pd),s=this.previousProjectionMatrix.mul(t).mul(Bd),i=r.xy.div(r.w),n=s.xy.div(s.w);return Fa(i,n)}}function xx(e){let t=yx.get(e);return void 0===t&&(t={},yx.set(e,t)),t}function Tx(e,t=0){const r=xx(e);let s=r[t];return void 0===s&&(r[t]=s=new a,r[t].copy(e.matrixWorld)),s}const _x=sn(bx),vx=un(([e])=>Ex(e.rgb)),Nx=un(([e,t=gn(1)])=>t.mix(Ex(e.rgb),e.rgb)),Sx=un(([e,t=gn(1)])=>{const r=Ma(e.r,e.g,e.b).div(3),s=e.r.max(e.g.max(e.b)),i=s.sub(r).mul(t).mul(-3);return nu(e.rgb,s,i)}),Rx=un(([e,t=gn(1)])=>{const r=vn(.57735,.57735,.57735),s=t.cos();return vn(e.rgb.mul(s).add(r.cross(e.rgb).mul(t.sin()).add(r.mul(Yo(r,e.rgb).mul(s.oneMinus())))))}),Ex=(e,t=vn(p.getLuminanceCoefficients(new r)))=>Yo(e,t),Ax=un(([e,t=vn(1),s=vn(0),i=vn(1),n=gn(1),a=vn(p.getLuminanceCoefficients(new r,Se))])=>{const o=e.rgb.dot(vn(a)),u=Ho(e.rgb.mul(t).add(s),0).toVar(),l=u.pow(i).toVar();return cn(u.r.greaterThan(0),()=>{u.r.assign(l.r)}),cn(u.g.greaterThan(0),()=>{u.g.assign(l.g)}),cn(u.b.greaterThan(0),()=>{u.b.assign(l.b)}),u.assign(o.add(u.sub(o).mul(n))),En(u.rgb,e.a)});class wx extends ci{static get type(){return"PosterizeNode"}constructor(e,t){super(),this.sourceNode=e,this.stepsNode=t}setup(){const{sourceNode:e,stepsNode:t}=this;return e.mul(t).floor().div(t)}}const Cx=rn(wx).setParameterLength(2);let Mx=null;class Fx extends vp{static get type(){return"ViewportSharedTextureNode"}constructor(e=ql,t=null){null===Mx&&(Mx=new X),super(e,t,Mx)}getTextureForReference(){return Mx}updateReference(){return this}}const Lx=rn(Fx).setParameterLength(0,2),Px=new t;class Bx extends Fl{static get type(){return"PassTextureNode"}constructor(e,t){super(t),this.passNode=e,this.setUpdateMatrix(!1)}setup(e){return this.passNode.build(e),super.setup(e)}clone(){return new this.constructor(this.passNode,this.value)}}class Dx extends Bx{static get type(){return"PassMultipleTextureNode"}constructor(e,t,r=!1){super(e,null),this.textureName=t,this.previousTexture=r}updateTexture(){this.value=this.previousTexture?this.passNode.getPreviousTexture(this.textureName):this.passNode.getTexture(this.textureName)}setup(e){return this.updateTexture(),super.setup(e)}clone(){const e=new this.constructor(this.passNode,this.textureName,this.previousTexture);return e.uvNode=this.uvNode,e.levelNode=this.levelNode,e.biasNode=this.biasNode,e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e}}class Ux extends ci{static get type(){return"PassNode"}constructor(e,t,r,s={}){super("vec4"),this.scope=e,this.scene=t,this.camera=r,this.options=s,this._pixelRatio=1,this._width=1,this._height=1;const i=new Y;i.isRenderTargetTexture=!0,i.name="depth";const n=new Ne(this._width*this._pixelRatio,this._height*this._pixelRatio,{type:be,...s});n.texture.name="output",n.depthTexture=i,this.renderTarget=n,this.overrideMaterial=null,this.transparent=!0,this.opaque=!0,this.contextNode=null,this._contextNodeCache=null,this._textures={output:n.texture,depth:i},this._textureNodes={},this._linearDepthNodes={},this._viewZNodes={},this._previousTextures={},this._previousTextureNodes={},this._cameraNear=_a(0),this._cameraFar=_a(0),this._mrt=null,this._layers=null,this._resolutionScale=1,this._viewport=null,this._scissor=null,this.isPassNode=!0,this.updateBeforeType=Js.FRAME,this.global=!0}setResolutionScale(e){return this._resolutionScale=e,this}getResolutionScale(){return this._resolutionScale}setResolution(e){return d("PassNode: .setResolution() is deprecated. Use .setResolutionScale() instead."),this.setResolutionScale(e)}getResolution(){return d("PassNode: .getResolution() is deprecated. Use .getResolutionScale() instead."),this.getResolutionScale()}setLayers(e){return this._layers=e,this}getLayers(){return this._layers}setMRT(e){return this._mrt=e,this}getMRT(){return this._mrt}getTexture(e){let t=this._textures[e];if(void 0===t){t=this.renderTarget.texture.clone(),t.name=e,this._textures[e]=t,this.renderTarget.textures.push(t)}return t}getPreviousTexture(e){let t=this._previousTextures[e];return void 0===t&&(t=this.getTexture(e).clone(),this._previousTextures[e]=t),t}toggleTexture(e){const t=this._previousTextures[e];if(void 0!==t){const r=this._textures[e],s=this.renderTarget.textures.indexOf(r);this.renderTarget.textures[s]=t,this._textures[e]=t,this._previousTextures[e]=r,this._textureNodes[e].updateTexture(),this._previousTextureNodes[e].updateTexture()}}getTextureNode(e="output"){let t=this._textureNodes[e];return void 0===t&&(t=new Dx(this,e),t.updateTexture(),this._textureNodes[e]=t),t}getPreviousTextureNode(e="output"){let t=this._previousTextureNodes[e];return void 0===t&&(void 0===this._textureNodes[e]&&this.getTextureNode(e),t=new Dx(this,e,!0),t.updateTexture(),this._previousTextureNodes[e]=t),t}getViewZNode(e="depth"){let t=this._viewZNodes[e];if(void 0===t){const r=this._cameraNear,s=this._cameraFar;this._viewZNodes[e]=t=Pp(this.getTextureNode(e),r,s)}return t}getLinearDepthNode(e="depth"){let t=this._linearDepthNodes[e];if(void 0===t){const r=this._cameraNear,s=this._cameraFar,i=this.getViewZNode(e);this._linearDepthNodes[e]=t=Fp(i,r,s)}return t}async compileAsync(e){const t=e.getRenderTarget(),r=e.getMRT();e.setRenderTarget(this.renderTarget),e.setMRT(this._mrt),await e.compileAsync(this.scene,this.camera),e.setRenderTarget(t),e.setMRT(r)}setup({renderer:e}){return this.renderTarget.samples=void 0===this.options.samples?e.samples:this.options.samples,this.renderTarget.texture.type=e.getOutputBufferType(),this.scope===Ux.COLOR?this.getTextureNode():this.getLinearDepthNode()}updateBefore(e){const{renderer:t}=e,{scene:r}=this;let s,i;const n=t.getOutputRenderTarget();n&&!0===n.isXRRenderTarget?(i=1,s=t.xr.getCamera(),t.xr.updateCamera(s),Px.set(n.width,n.height)):(s=this.camera,i=t.getPixelRatio(),t.getSize(Px)),this._pixelRatio=i,this.setSize(Px.width,Px.height);const a=t.getRenderTarget(),o=t.getMRT(),u=t.autoClear,l=t.transparent,d=t.opaque,c=s.layers.mask,h=t.contextNode,p=r.overrideMaterial;this._cameraNear.value=s.near,this._cameraFar.value=s.far,null!==this._layers&&(s.layers.mask=this._layers.mask);for(const e in this._previousTextures)this.toggleTexture(e);null!==this.overrideMaterial&&(r.overrideMaterial=this.overrideMaterial),t.setRenderTarget(this.renderTarget),t.setMRT(this._mrt),t.autoClear=!0,t.transparent=this.transparent,t.opaque=this.opaque,null!==this.contextNode&&(null!==this._contextNodeCache&&this._contextNodeCache.version===this.version||(this._contextNodeCache={version:this.version,context:Tu({...t.contextNode.getFlowContextData(),...this.contextNode.getFlowContextData()})}),t.contextNode=this._contextNodeCache.context);const g=r.name;r.name=this.name?this.name:r.name,t.render(r,s),r.name=g,r.overrideMaterial=p,t.setRenderTarget(a),t.setMRT(o),t.autoClear=u,t.transparent=l,t.opaque=d,t.contextNode=h,s.layers.mask=c}setSize(e,t){this._width=e,this._height=t;const r=Math.floor(this._width*this._pixelRatio*this._resolutionScale),s=Math.floor(this._height*this._pixelRatio*this._resolutionScale);this.renderTarget.setSize(r,s),null!==this._scissor&&this.renderTarget.scissor.copy(this._scissor),null!==this._viewport&&this.renderTarget.viewport.copy(this._viewport)}setScissor(e,t,r,i){null===e?this._scissor=null:(null===this._scissor&&(this._scissor=new s),e.isVector4?this._scissor.copy(e):this._scissor.set(e,t,r,i),this._scissor.multiplyScalar(this._pixelRatio*this._resolutionScale).floor())}setViewport(e,t,r,i){null===e?this._viewport=null:(null===this._viewport&&(this._viewport=new s),e.isVector4?this._viewport.copy(e):this._viewport.set(e,t,r,i),this._viewport.multiplyScalar(this._pixelRatio*this._resolutionScale).floor())}setPixelRatio(e){this._pixelRatio=e,this.setSize(this._width,this._height)}dispose(){this.renderTarget.dispose()}}Ux.COLOR="color",Ux.DEPTH="depth";class Ix extends Ux{static get type(){return"ToonOutlinePassNode"}constructor(e,t,r,s,i){super(Ux.COLOR,e,t),this.colorNode=r,this.thicknessNode=s,this.alphaNode=i,this._materialCache=new WeakMap,this.name="Outline Pass"}updateBefore(e){const{renderer:t}=e,r=t.getRenderObjectFunction();t.setRenderObjectFunction((e,r,s,i,n,a,o,u)=>{if((n.isMeshToonMaterial||n.isMeshToonNodeMaterial)&&!1===n.wireframe){const l=this._getOutlineMaterial(n);t.renderObject(e,r,s,i,l,a,o,u)}t.renderObject(e,r,s,i,n,a,o,u)}),super.updateBefore(e),t.setRenderObjectFunction(r)}_createMaterial(){const e=new Zp;e.isMeshToonOutlineMaterial=!0,e.name="Toon_Outline",e.side=M;const t=Wd.negate(),r=sd.mul(Ad),s=gn(1),i=r.mul(En(Pd,1)),n=r.mul(En(Pd.add(t),1)),a=vo(i.sub(n));return e.vertexNode=i.add(a.mul(this.thicknessNode).mul(i.w).mul(s)),e.colorNode=En(this.colorNode,this.alphaNode),e}_getOutlineMaterial(e){let t=this._materialCache.get(e);return void 0===t&&(t=this._createMaterial(),this._materialCache.set(e,t)),t}}const Ox=un(([e,t])=>e.mul(t).clamp()).setLayout({name:"linearToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),Vx=un(([e,t])=>(e=e.mul(t)).div(e.add(1)).clamp()).setLayout({name:"reinhardToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),kx=un(([e,t])=>{const r=(e=(e=e.mul(t)).sub(.004).max(0)).mul(e.mul(6.2).add(.5)),s=e.mul(e.mul(6.2).add(1.7)).add(.06);return r.div(s).pow(2.2)}).setLayout({name:"cineonToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),Gx=un(([e])=>{const t=e.mul(e.add(.0245786)).sub(90537e-9),r=e.mul(e.add(.432951).mul(.983729)).add(.238081);return t.div(r)}),zx=un(([e,t])=>{const r=Fn(.59719,.35458,.04823,.076,.90834,.01566,.0284,.13383,.83777),s=Fn(1.60475,-.53108,-.07367,-.10208,1.10813,-.00605,-.00327,-.07276,1.07602);return e=e.mul(t).div(.6),e=r.mul(e),e=Gx(e),(e=s.mul(e)).clamp()}).setLayout({name:"acesFilmicToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),$x=Fn(vn(1.6605,-.1246,-.0182),vn(-.5876,1.1329,-.1006),vn(-.0728,-.0083,1.1187)),Wx=Fn(vn(.6274,.0691,.0164),vn(.3293,.9195,.088),vn(.0433,.0113,.8956)),Hx=un(([e])=>{const t=vn(e).toVar(),r=vn(t.mul(t)).toVar(),s=vn(r.mul(r)).toVar();return gn(15.5).mul(s.mul(r)).sub(La(40.14,s.mul(t))).add(La(31.96,s).sub(La(6.868,r.mul(t))).add(La(.4298,r).add(La(.1191,t).sub(.00232))))}),qx=un(([e,t])=>{const r=vn(e).toVar(),s=Fn(vn(.856627153315983,.137318972929847,.11189821299995),vn(.0951212405381588,.761241990602591,.0767994186031903),vn(.0482516061458583,.101439036467562,.811302368396859)),i=Fn(vn(1.1271005818144368,-.1413297634984383,-.14132976349843826),vn(-.11060664309660323,1.157823702216272,-.11060664309660294),vn(-.016493938717834573,-.016493938717834257,1.2519364065950405)),n=gn(-12.47393),a=gn(4.026069);return r.mulAssign(t),r.assign(Wx.mul(r)),r.assign(s.mul(r)),r.assign(Ho(r,1e-10)),r.assign(yo(r)),r.assign(r.sub(n).div(a.sub(n))),r.assign(au(r,0,1)),r.assign(Hx(r)),r.assign(i.mul(r)),r.assign(Zo(Ho(vn(0),r),vn(2.2))),r.assign($x.mul(r)),r.assign(au(r,0,1)),r}).setLayout({name:"agxToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),jx=un(([e,t])=>{const r=gn(.76),s=gn(.15);e=e.mul(t);const i=Wo(e.r,Wo(e.g,e.b)),n=bu(i.lessThan(.08),i.sub(La(6.25,i.mul(i))),.04);e.subAssign(n);const a=Ho(e.r,Ho(e.g,e.b));cn(a.lessThan(r),()=>e);const o=Fa(1,r),u=Fa(1,o.mul(o).div(a.add(o.sub(r))));e.mulAssign(u.div(a));const l=Fa(1,Pa(1,s.mul(a.sub(u)).add(1)));return nu(e,vn(u),l)}).setLayout({name:"neutralToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]});class Xx extends ui{static get type(){return"CodeNode"}constructor(e="",t=[],r=""){super("code"),this.isCodeNode=!0,this.global=!0,this.code=e,this.includes=t,this.language=r}setIncludes(e){return this.includes=e,this}getIncludes(){return this.includes}generate(e){const t=this.getIncludes(e);for(const r of t)r.build(e);const r=e.getCodeFromNode(this,this.getNodeType(e));return r.code=this.code,r.code}serialize(e){super.serialize(e),e.code=this.code,e.language=this.language}deserialize(e){super.deserialize(e),this.code=e.code,this.language=e.language}}const Kx=rn(Xx).setParameterLength(1,3);class Yx extends Xx{static get type(){return"FunctionNode"}constructor(e="",t=[],r=""){super(e,t,r)}getNodeType(e){return this.getNodeFunction(e).type}getMemberType(e,t){const r=this.getNodeType(e);return e.getStructTypeNode(r).getMemberType(e,t)}getInputs(e){return this.getNodeFunction(e).inputs}getNodeFunction(e){const t=e.getDataFromNode(this);let r=t.nodeFunction;return void 0===r&&(r=e.parser.parseFunction(this.code),t.nodeFunction=r),r}generate(e,t){super.generate(e);const r=this.getNodeFunction(e),s=r.name,i=r.type,n=e.getCodeFromNode(this,i);""!==s&&(n.name=s);const a=e.getPropertyName(n),o=this.getNodeFunction(e).getCode(a);return n.code=o+"\n","property"===t?a:e.format(`${a}()`,i,t)}}const Qx=(e,t=[],r="")=>{for(let e=0;es.call(...e);return i.functionNode=s,i};class Zx extends ui{static get type(){return"ScriptableValueNode"}constructor(e=null){super(),this._value=e,this._cache=null,this.inputType=null,this.outputType=null,this.events=new u,this.isScriptableValueNode=!0}get isScriptableOutputNode(){return null!==this.outputType}set value(e){this._value!==e&&(this._cache&&"URL"===this.inputType&&this.value.value instanceof ArrayBuffer&&(URL.revokeObjectURL(this._cache),this._cache=null),this._value=e,this.events.dispatchEvent({type:"change"}),this.refresh())}get value(){return this._value}refresh(){this.events.dispatchEvent({type:"refresh"})}getValue(){const e=this.value;if(e&&null===this._cache&&"URL"===this.inputType&&e.value instanceof ArrayBuffer)this._cache=URL.createObjectURL(new Blob([e.value]));else if(e&&null!==e.value&&void 0!==e.value&&(("URL"===this.inputType||"String"===this.inputType)&&"string"==typeof e.value||"Number"===this.inputType&&"number"==typeof e.value||"Vector2"===this.inputType&&e.value.isVector2||"Vector3"===this.inputType&&e.value.isVector3||"Vector4"===this.inputType&&e.value.isVector4||"Color"===this.inputType&&e.value.isColor||"Matrix3"===this.inputType&&e.value.isMatrix3||"Matrix4"===this.inputType&&e.value.isMatrix4))return e.value;return this._cache||e}getNodeType(e){return this.value&&this.value.isNode?this.value.getNodeType(e):"float"}setup(){return this.value&&this.value.isNode?this.value:gn()}serialize(e){super.serialize(e),null!==this.value?"ArrayBuffer"===this.inputType?e.value=Ks(this.value):e.value=this.value?this.value.toJSON(e.meta).uuid:null:e.value=null,e.inputType=this.inputType,e.outputType=this.outputType}deserialize(e){super.deserialize(e);let t=null;null!==e.value&&(t="ArrayBuffer"===e.inputType?Ys(e.value):"Texture"===e.inputType?e.meta.textures[e.value]:e.meta.nodes[e.value]||null),this.value=t,this.inputType=e.inputType,this.outputType=e.outputType}}const Jx=rn(Zx).setParameterLength(1);class eT extends Map{get(e,t=null,...r){if(this.has(e))return super.get(e);if(null!==t){const s=t(...r);return this.set(e,s),s}}}class tT{constructor(e){this.scriptableNode=e}get parameters(){return this.scriptableNode.parameters}get layout(){return this.scriptableNode.getLayout()}getInputLayout(e){return this.scriptableNode.getInputLayout(e)}get(e){const t=this.parameters[e];return t?t.getValue():null}}const rT=new eT;class sT extends ui{static get type(){return"ScriptableNode"}constructor(e=null,t={}){super(),this.codeNode=e,this.parameters=t,this._local=new eT,this._output=Jx(null),this._outputs={},this._source=this.source,this._method=null,this._object=null,this._value=null,this._needsOutputUpdate=!0,this.onRefresh=this.onRefresh.bind(this),this.isScriptableNode=!0}get source(){return this.codeNode?this.codeNode.code:""}setLocal(e,t){return this._local.set(e,t)}getLocal(e){return this._local.get(e)}onRefresh(){this._refresh()}getInputLayout(e){for(const t of this.getLayout())if(t.inputType&&(t.id===e||t.name===e))return t}getOutputLayout(e){for(const t of this.getLayout())if(t.outputType&&(t.id===e||t.name===e))return t}setOutput(e,t){const r=this._outputs;return void 0===r[e]?r[e]=Jx(t):r[e].value=t,this}getOutput(e){return this._outputs[e]}getParameter(e){return this.parameters[e]}setParameter(e,t){const r=this.parameters;return t&&t.isScriptableNode?(this.deleteParameter(e),r[e]=t,r[e].getDefaultOutput().events.addEventListener("refresh",this.onRefresh)):t&&t.isScriptableValueNode?(this.deleteParameter(e),r[e]=t,r[e].events.addEventListener("refresh",this.onRefresh)):void 0===r[e]?(r[e]=Jx(t),r[e].events.addEventListener("refresh",this.onRefresh)):r[e].value=t,this}getValue(){return this.getDefaultOutput().getValue()}deleteParameter(e){let t=this.parameters[e];return t&&(t.isScriptableNode&&(t=t.getDefaultOutput()),t.events.removeEventListener("refresh",this.onRefresh)),this}clearParameters(){for(const e of Object.keys(this.parameters))this.deleteParameter(e);return this.needsUpdate=!0,this}call(e,...t){const r=this.getObject()[e];if("function"==typeof r)return r(...t)}async callAsync(e,...t){const r=this.getObject()[e];if("function"==typeof r)return"AsyncFunction"===r.constructor.name?await r(...t):r(...t)}getNodeType(e){return this.getDefaultOutputNode().getNodeType(e)}refresh(e=null){null!==e?this.getOutput(e).refresh():this._refresh()}getObject(){if(this.needsUpdate&&this.dispose(),null!==this._object)return this._object;const e=new tT(this),t=rT.get("THREE"),r=rT.get("TSL"),s=this.getMethod(),i=[e,this._local,rT,()=>this.refresh(),(e,t)=>this.setOutput(e,t),t,r];this._object=s(...i);const n=this._object.layout;if(n&&(!1===n.cache&&this._local.clear(),this._output.outputType=n.outputType||null,Array.isArray(n.elements)))for(const e of n.elements){const t=e.id||e.name;e.inputType&&(void 0===this.getParameter(t)&&this.setParameter(t,null),this.getParameter(t).inputType=e.inputType),e.outputType&&(void 0===this.getOutput(t)&&this.setOutput(t,null),this.getOutput(t).outputType=e.outputType)}return this._object}deserialize(e){super.deserialize(e);for(const e in this.parameters){let t=this.parameters[e];t.isScriptableNode&&(t=t.getDefaultOutput()),t.events.addEventListener("refresh",this.onRefresh)}}getLayout(){return this.getObject().layout}getDefaultOutputNode(){const e=this.getDefaultOutput().value;return e&&e.isNode?e:gn()}getDefaultOutput(){return this._exec()._output}getMethod(){if(this.needsUpdate&&this.dispose(),null!==this._method)return this._method;const e=["layout","init","main","dispose"].join(", "),t="\nreturn { ...output, "+e+" };",r="var "+e+"; var output = {};\n"+this.codeNode.code+t;return this._method=new Function(...["parameters","local","global","refresh","setOutput","THREE","TSL"],r),this._method}dispose(){null!==this._method&&(this._object&&"function"==typeof this._object.dispose&&this._object.dispose(),this._method=null,this._object=null,this._source=null,this._value=null,this._needsOutputUpdate=!0,this._output.value=null,this._outputs={})}setup(){return this.getDefaultOutputNode()}getCacheKey(e){const t=[Us(this.source),this.getDefaultOutputNode().getCacheKey(e)];for(const r in this.parameters)t.push(this.parameters[r].getCacheKey(e));return Is(t)}set needsUpdate(e){!0===e&&this.dispose()}get needsUpdate(){return this.source!==this._source}_exec(){return null===this.codeNode||(!0===this._needsOutputUpdate&&(this._value=this.call("main"),this._needsOutputUpdate=!1),this._output.value=this._value),this}_refresh(){this.needsUpdate=!0,this._exec(),this._output.refresh()}}const iT=rn(sT).setParameterLength(1,2);function nT(e){let t;const r=e.context.getViewZ;return void 0!==r&&(t=r(this)),(t||Id.z).negate()}const aT=un(([e,t],r)=>{const s=nT(r);return lu(e,t,s)}),oT=un(([e],t)=>{const r=nT(t);return e.mul(e,r,r).negate().exp().oneMinus()}),uT=un(([e,t],r)=>{const s=nT(r),i=t.sub(Dd.y).max(0).toConst().mul(s).toConst();return e.mul(e,i,i).negate().exp().oneMinus()}),lT=un(([e,t])=>En(t.toFloat().mix(ia.rgb,e.toVec3()),ia.a));let dT=null,cT=null;class hT extends ui{static get type(){return"RangeNode"}constructor(e=gn(),t=gn()){super(),this.minNode=e,this.maxNode=t}getVectorLength(e){const t=this.getConstNode(this.minNode),r=this.getConstNode(this.maxNode),s=e.getTypeLength(qs(t.value)),i=e.getTypeLength(qs(r.value));return s>i?s:i}getNodeType(e){return e.object.count>1?e.getTypeFromLength(this.getVectorLength(e)):"float"}getConstNode(e){let t=null;if(e.traverse(e=>{!0===e.isConstNode&&(t=e)}),null===t)throw new Error('THREE.TSL: No "ConstNode" found in node graph.');return t}setup(e){const t=e.object;let r=null;if(t.count>1){const i=this.getConstNode(this.minNode),n=this.getConstNode(this.maxNode),a=i.value,o=n.value,u=e.getTypeLength(qs(a)),d=e.getTypeLength(qs(o));dT=dT||new s,cT=cT||new s,dT.setScalar(0),cT.setScalar(0),1===u?dT.setScalar(a):a.isColor?dT.set(a.r,a.g,a.b,1):dT.set(a.x,a.y,a.z||0,a.w||0),1===d?cT.setScalar(o):o.isColor?cT.set(o.r,o.g,o.b,1):cT.set(o.x,o.y,o.z||0,o.w||0);const c=4,h=c*t.count,p=new Float32Array(h);for(let e=0;enew gT(e,t),fT=mT("numWorkgroups","uvec3"),yT=mT("workgroupId","uvec3"),bT=mT("globalId","uvec3"),xT=mT("localId","uvec3"),TT=mT("subgroupSize","uint");class _T extends ui{constructor(e){super(),this.scope=e}generate(e){const{scope:t}=this,{renderer:r}=e;!0===r.backend.isWebGLBackend?e.addFlowCode(`\t// ${t}Barrier \n`):e.addLineFlowCode(`${t}Barrier()`,this)}}const vT=rn(_T);class NT extends li{constructor(e,t){super(e,t),this.isWorkgroupInfoElementNode=!0}generate(e,t){let r;const s=e.context.assign;if(r=super.generate(e),!0!==s){const s=this.getNodeType(e);r=e.format(r,s,t)}return r}}class ST extends ui{constructor(e,t,r=0){super(t),this.bufferType=t,this.bufferCount=r,this.isWorkgroupInfoNode=!0,this.elementType=t,this.scope=e,this.name=""}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setScope(e){return this.scope=e,this}getElementType(){return this.elementType}getInputType(){return`${this.scope}Array`}element(e){return new NT(this,e)}generate(e){const t=""!==this.name?this.name:`${this.scope}Array_${this.id}`;return e.getScopedArray(t,this.scope.toLowerCase(),this.bufferType,this.bufferCount)}}class RT extends ui{static get type(){return"AtomicFunctionNode"}constructor(e,t,r){super("uint"),this.method=e,this.pointerNode=t,this.valueNode=r,this.parents=!0}getInputType(e){return this.pointerNode.getNodeType(e)}getNodeType(e){return this.getInputType(e)}generate(e){const t=e.getNodeProperties(this),r=t.parents,s=this.method,i=this.getNodeType(e),n=this.getInputType(e),a=this.pointerNode,o=this.valueNode,u=[];u.push(`&${a.build(e,n)}`),null!==o&&u.push(o.build(e,n));const l=`${e.getMethod(s,i)}( ${u.join(", ")} )`;if(!(!!r&&(1===r.length&&!0===r[0].isStackNode)))return void 0===t.constNode&&(t.constNode=gl(l,i).toConst()),t.constNode.build(e);e.addLineFlowCode(l,this)}}RT.ATOMIC_LOAD="atomicLoad",RT.ATOMIC_STORE="atomicStore",RT.ATOMIC_ADD="atomicAdd",RT.ATOMIC_SUB="atomicSub",RT.ATOMIC_MAX="atomicMax",RT.ATOMIC_MIN="atomicMin",RT.ATOMIC_AND="atomicAnd",RT.ATOMIC_OR="atomicOr",RT.ATOMIC_XOR="atomicXor";const ET=rn(RT),AT=(e,t,r)=>ET(e,t,r).toStack();class wT extends ci{static get type(){return"SubgroupFunctionNode"}constructor(e,t=null,r=null){super(),this.method=e,this.aNode=t,this.bNode=r}getInputType(e){const t=this.aNode?this.aNode.getNodeType(e):null,r=this.bNode?this.bNode.getNodeType(e):null;return(e.isMatrix(t)?0:e.getTypeLength(t))>(e.isMatrix(r)?0:e.getTypeLength(r))?t:r}getNodeType(e){const t=this.method;return t===wT.SUBGROUP_ELECT?"bool":t===wT.SUBGROUP_BALLOT?"uvec4":this.getInputType(e)}generate(e,t){const r=this.method,s=this.getNodeType(e),i=this.getInputType(e),n=this.aNode,a=this.bNode,o=[];if(r===wT.SUBGROUP_BROADCAST||r===wT.SUBGROUP_SHUFFLE||r===wT.QUAD_BROADCAST){const t=a.getNodeType(e);o.push(n.build(e,s),a.build(e,"float"===t?"int":s))}else r===wT.SUBGROUP_SHUFFLE_XOR||r===wT.SUBGROUP_SHUFFLE_DOWN||r===wT.SUBGROUP_SHUFFLE_UP?o.push(n.build(e,s),a.build(e,"uint")):(null!==n&&o.push(n.build(e,i)),null!==a&&o.push(a.build(e,i)));const u=0===o.length?"()":`( ${o.join(", ")} )`;return e.format(`${e.getMethod(r,s)}${u}`,s,t)}serialize(e){super.serialize(e),e.method=this.method}deserialize(e){super.deserialize(e),this.method=e.method}}wT.SUBGROUP_ELECT="subgroupElect",wT.SUBGROUP_BALLOT="subgroupBallot",wT.SUBGROUP_ADD="subgroupAdd",wT.SUBGROUP_INCLUSIVE_ADD="subgroupInclusiveAdd",wT.SUBGROUP_EXCLUSIVE_AND="subgroupExclusiveAdd",wT.SUBGROUP_MUL="subgroupMul",wT.SUBGROUP_INCLUSIVE_MUL="subgroupInclusiveMul",wT.SUBGROUP_EXCLUSIVE_MUL="subgroupExclusiveMul",wT.SUBGROUP_AND="subgroupAnd",wT.SUBGROUP_OR="subgroupOr",wT.SUBGROUP_XOR="subgroupXor",wT.SUBGROUP_MIN="subgroupMin",wT.SUBGROUP_MAX="subgroupMax",wT.SUBGROUP_ALL="subgroupAll",wT.SUBGROUP_ANY="subgroupAny",wT.SUBGROUP_BROADCAST_FIRST="subgroupBroadcastFirst",wT.QUAD_SWAP_X="quadSwapX",wT.QUAD_SWAP_Y="quadSwapY",wT.QUAD_SWAP_DIAGONAL="quadSwapDiagonal",wT.SUBGROUP_BROADCAST="subgroupBroadcast",wT.SUBGROUP_SHUFFLE="subgroupShuffle",wT.SUBGROUP_SHUFFLE_XOR="subgroupShuffleXor",wT.SUBGROUP_SHUFFLE_UP="subgroupShuffleUp",wT.SUBGROUP_SHUFFLE_DOWN="subgroupShuffleDown",wT.QUAD_BROADCAST="quadBroadcast";const CT=nn(wT,wT.SUBGROUP_ELECT).setParameterLength(0),MT=nn(wT,wT.SUBGROUP_BALLOT).setParameterLength(1),FT=nn(wT,wT.SUBGROUP_ADD).setParameterLength(1),LT=nn(wT,wT.SUBGROUP_INCLUSIVE_ADD).setParameterLength(1),PT=nn(wT,wT.SUBGROUP_EXCLUSIVE_AND).setParameterLength(1),BT=nn(wT,wT.SUBGROUP_MUL).setParameterLength(1),DT=nn(wT,wT.SUBGROUP_INCLUSIVE_MUL).setParameterLength(1),UT=nn(wT,wT.SUBGROUP_EXCLUSIVE_MUL).setParameterLength(1),IT=nn(wT,wT.SUBGROUP_AND).setParameterLength(1),OT=nn(wT,wT.SUBGROUP_OR).setParameterLength(1),VT=nn(wT,wT.SUBGROUP_XOR).setParameterLength(1),kT=nn(wT,wT.SUBGROUP_MIN).setParameterLength(1),GT=nn(wT,wT.SUBGROUP_MAX).setParameterLength(1),zT=nn(wT,wT.SUBGROUP_ALL).setParameterLength(0),$T=nn(wT,wT.SUBGROUP_ANY).setParameterLength(0),WT=nn(wT,wT.SUBGROUP_BROADCAST_FIRST).setParameterLength(2),HT=nn(wT,wT.QUAD_SWAP_X).setParameterLength(1),qT=nn(wT,wT.QUAD_SWAP_Y).setParameterLength(1),jT=nn(wT,wT.QUAD_SWAP_DIAGONAL).setParameterLength(1),XT=nn(wT,wT.SUBGROUP_BROADCAST).setParameterLength(2),KT=nn(wT,wT.SUBGROUP_SHUFFLE).setParameterLength(2),YT=nn(wT,wT.SUBGROUP_SHUFFLE_XOR).setParameterLength(2),QT=nn(wT,wT.SUBGROUP_SHUFFLE_UP).setParameterLength(2),ZT=nn(wT,wT.SUBGROUP_SHUFFLE_DOWN).setParameterLength(2),JT=nn(wT,wT.QUAD_BROADCAST).setParameterLength(1);let e_;function t_(e){e_=e_||new WeakMap;let t=e_.get(e);return void 0===t&&e_.set(e,t={}),t}function r_(e){const t=t_(e);return t.shadowMatrix||(t.shadowMatrix=_a("mat4").setGroup(ba).onRenderUpdate(t=>(!0===e.castShadow&&!1!==t.renderer.shadowMap.enabled||(e.shadow.camera.coordinateSystem!==t.camera.coordinateSystem&&(e.shadow.camera.coordinateSystem=t.camera.coordinateSystem,e.shadow.camera.updateProjectionMatrix()),e.shadow.updateMatrices(e)),e.shadow.matrix)))}function s_(e,t=Dd){const r=r_(e).mul(t);return r.xyz.div(r.w)}function i_(e){const t=t_(e);return t.position||(t.position=_a(new r).setGroup(ba).onRenderUpdate((t,r)=>r.value.setFromMatrixPosition(e.matrixWorld)))}function n_(e){const t=t_(e);return t.targetPosition||(t.targetPosition=_a(new r).setGroup(ba).onRenderUpdate((t,r)=>r.value.setFromMatrixPosition(e.target.matrixWorld)))}function a_(e){const t=t_(e);return t.viewPosition||(t.viewPosition=_a(new r).setGroup(ba).onRenderUpdate(({camera:t},s)=>{s.value=s.value||new r,s.value.setFromMatrixPosition(e.matrixWorld),s.value.applyMatrix4(t.matrixWorldInverse)}))}const o_=e=>nd.transformDirection(i_(e).sub(n_(e))),u_=(e,t)=>{for(const r of t)if(r.isAnalyticLightNode&&r.light.id===e)return r;return null},l_=new WeakMap,d_=[];class c_ extends ui{static get type(){return"LightsNode"}constructor(){super("vec3"),this.totalDiffuseNode=Un("vec3","totalDiffuse"),this.totalSpecularNode=Un("vec3","totalSpecular"),this.outgoingLightNode=Un("vec3","outgoingLight"),this._lights=[],this._lightNodes=null,this._lightNodesHash=null,this.global=!0}customCacheKey(){const e=this._lights;for(let t=0;te.sort((e,t)=>e.id-t.id))(this._lights),i=e.renderer.library;for(const e of s)if(e.isNode)t.push(Zi(e));else{let s=null;if(null!==r&&(s=u_(e.id,r)),null===s){const r=i.getLightNodeClass(e.constructor);if(null===r){d(`LightsNode.setupNodeLights: Light node not found for ${e.constructor.name}`);continue}let s=null;l_.has(e)?s=l_.get(e):(s=new r(e),l_.set(e,s)),t.push(s)}}this._lightNodes=t}setupDirectLight(e,t,r){const{lightingModel:s,reflectedLight:i}=e.context;s.direct({...r,lightNode:t,reflectedLight:i},e)}setupDirectRectAreaLight(e,t,r){const{lightingModel:s,reflectedLight:i}=e.context;s.directRectArea({...r,lightNode:t,reflectedLight:i},e)}setupLights(e,t){for(const r of t)r.build(e)}getLightNodes(e){return null===this._lightNodes&&this.setupLightsNode(e),this._lightNodes}setup(e){const t=e.lightsNode;e.lightsNode=this;let r=this.outgoingLightNode;const s=e.context,i=s.lightingModel,n=e.getNodeProperties(this);if(i){const{totalDiffuseNode:t,totalSpecularNode:a}=this;s.outgoingLight=r;const o=e.addStack();n.nodes=o.nodes,i.start(e);const{backdrop:u,backdropAlpha:l}=s,{directDiffuse:d,directSpecular:c,indirectDiffuse:h,indirectSpecular:p}=s.reflectedLight;let g=d.add(h);null!==u&&(g=vn(null!==l?l.mix(g,u):u)),t.assign(g),a.assign(c.add(p)),r.assign(t.add(a)),i.finish(e),r=r.bypass(e.removeStack())}else n.nodes=[];return e.lightsNode=t,r}setLights(e){return this._lights=e,this._lightNodes=null,this._lightNodesHash=null,this}getLights(){return this._lights}get hasLights(){return this._lights.length>0}}class h_ extends ui{static get type(){return"ShadowBaseNode"}constructor(e){super(),this.light=e,this.updateBeforeType=Js.RENDER,this.isShadowBaseNode=!0}setupShadowPosition({context:e,material:t}){p_.assign(t.receivedShadowPositionNode||e.shadowPositionWorld||Dd)}}const p_=Un("vec3","shadowPositionWorld");function g_(t,r={}){return r.toneMapping=t.toneMapping,r.toneMappingExposure=t.toneMappingExposure,r.outputColorSpace=t.outputColorSpace,r.renderTarget=t.getRenderTarget(),r.activeCubeFace=t.getActiveCubeFace(),r.activeMipmapLevel=t.getActiveMipmapLevel(),r.renderObjectFunction=t.getRenderObjectFunction(),r.pixelRatio=t.getPixelRatio(),r.mrt=t.getMRT(),r.clearColor=t.getClearColor(r.clearColor||new e),r.clearAlpha=t.getClearAlpha(),r.autoClear=t.autoClear,r.scissorTest=t.getScissorTest(),r}function m_(e,t){return t=g_(e,t),e.setMRT(null),e.setRenderObjectFunction(null),e.setClearColor(0,1),e.autoClear=!0,t}function f_(e,t){e.toneMapping=t.toneMapping,e.toneMappingExposure=t.toneMappingExposure,e.outputColorSpace=t.outputColorSpace,e.setRenderTarget(t.renderTarget,t.activeCubeFace,t.activeMipmapLevel),e.setRenderObjectFunction(t.renderObjectFunction),e.setPixelRatio(t.pixelRatio),e.setMRT(t.mrt),e.setClearColor(t.clearColor,t.clearAlpha),e.autoClear=t.autoClear,e.setScissorTest(t.scissorTest)}function y_(e,t={}){return t.background=e.background,t.backgroundNode=e.backgroundNode,t.overrideMaterial=e.overrideMaterial,t}function b_(e,t){return t=y_(e,t),e.background=null,e.backgroundNode=null,e.overrideMaterial=null,t}function x_(e,t){e.background=t.background,e.backgroundNode=t.backgroundNode,e.overrideMaterial=t.overrideMaterial}function T_(e,t,r){return r=b_(t,r=m_(e,r))}function __(e,t,r){f_(e,r),x_(t,r)}var v_=Object.freeze({__proto__:null,resetRendererAndSceneState:T_,resetRendererState:m_,resetSceneState:b_,restoreRendererAndSceneState:__,restoreRendererState:f_,restoreSceneState:x_,saveRendererAndSceneState:function(e,t,r={}){return r=y_(t,r=g_(e,r))},saveRendererState:g_,saveSceneState:y_});const N_=new WeakMap,S_=un(({depthTexture:e,shadowCoord:t,depthLayer:r})=>{let s=Pl(e,t.xy).setName("t_basic");return e.isArrayTexture&&(s=s.depth(r)),s.compare(t.z)}),R_=un(({depthTexture:e,shadowCoord:t,shadow:r,depthLayer:s})=>{const i=(t,r)=>{let i=Pl(e,t);return e.isArrayTexture&&(i=i.depth(s)),i.compare(r)},n=yc("mapSize","vec2",r).setGroup(ba),a=yc("radius","float",r).setGroup(ba),o=bn(1).div(n),u=a.mul(o.x),l=Qb(Xl.xy).mul(6.28318530718);return Ma(i(t.xy.add(Zb(0,5,l).mul(u)),t.z),i(t.xy.add(Zb(1,5,l).mul(u)),t.z),i(t.xy.add(Zb(2,5,l).mul(u)),t.z),i(t.xy.add(Zb(3,5,l).mul(u)),t.z),i(t.xy.add(Zb(4,5,l).mul(u)),t.z)).mul(.2)}),E_=un(({depthTexture:e,shadowCoord:t,shadow:r,depthLayer:s})=>{const i=(t,r)=>{let i=Pl(e,t);return e.isArrayTexture&&(i=i.depth(s)),i.compare(r)},n=yc("mapSize","vec2",r).setGroup(ba),a=bn(1).div(n),o=a.x,u=a.y,l=t.xy,d=No(l.mul(n).add(.5));return l.subAssign(d.mul(a)),Ma(i(l,t.z),i(l.add(bn(o,0)),t.z),i(l.add(bn(0,u)),t.z),i(l.add(a),t.z),nu(i(l.add(bn(o.negate(),0)),t.z),i(l.add(bn(o.mul(2),0)),t.z),d.x),nu(i(l.add(bn(o.negate(),u)),t.z),i(l.add(bn(o.mul(2),u)),t.z),d.x),nu(i(l.add(bn(0,u.negate())),t.z),i(l.add(bn(0,u.mul(2))),t.z),d.y),nu(i(l.add(bn(o,u.negate())),t.z),i(l.add(bn(o,u.mul(2))),t.z),d.y),nu(nu(i(l.add(bn(o.negate(),u.negate())),t.z),i(l.add(bn(o.mul(2),u.negate())),t.z),d.x),nu(i(l.add(bn(o.negate(),u.mul(2))),t.z),i(l.add(bn(o.mul(2),u.mul(2))),t.z),d.x),d.y)).mul(1/9)}),A_=un(({depthTexture:e,shadowCoord:t,depthLayer:r})=>{let s=Pl(e).sample(t.xy);e.isArrayTexture&&(s=s.depth(r)),s=s.rg;const i=s.x,n=Ho(1e-7,s.y.mul(s.y)),a=qo(t.z,i),o=gn(1).toVar();return cn(a.notEqual(1),()=>{const e=t.z.sub(i);let r=n.div(n.add(e.mul(e)));r=au(Fa(r,.3).div(.65)),o.assign(Ho(a,r))}),o}),w_=e=>{let t=N_.get(e);return void 0===t&&(t=new Zp,t.colorNode=En(0,0,0,1),t.isShadowPassMaterial=!0,t.name="ShadowMaterial",t.blending=ee,t.fog=!1,N_.set(e,t)),t},C_=e=>{const t=N_.get(e);void 0!==t&&(t.dispose(),N_.delete(e))},M_=new Qf,F_=[],L_=(e,t,r,s)=>{F_[0]=e,F_[1]=t;let i=M_.get(F_);return void 0!==i&&i.shadowType===r&&i.useVelocity===s||(i=(i,n,a,o,u,l,...d)=>{(!0===i.castShadow||i.receiveShadow&&r===Ze)&&(s&&(Xs(i).useVelocity=!0),i.onBeforeShadow(e,i,a,t.camera,o,n.overrideMaterial,l),e.renderObject(i,n,a,o,u,l,...d),i.onAfterShadow(e,i,a,t.camera,o,n.overrideMaterial,l))},i.shadowType=r,i.useVelocity=s,M_.set(F_,i)),F_[0]=null,F_[1]=null,i},P_=un(({samples:e,radius:t,size:r,shadowPass:s,depthLayer:i})=>{const n=gn(0).toVar("meanVertical"),a=gn(0).toVar("squareMeanVertical"),o=e.lessThanEqual(gn(1)).select(gn(0),gn(2).div(e.sub(1))),u=e.lessThanEqual(gn(1)).select(gn(0),gn(-1));lp({start:mn(0),end:mn(e),type:"int",condition:"<"},({i:e})=>{const l=u.add(gn(e).mul(o));let d=s.sample(Ma(Xl.xy,bn(0,l).mul(t)).div(r));s.value.isArrayTexture&&(d=d.depth(i)),d=d.x,n.addAssign(d),a.addAssign(d.mul(d))}),n.divAssign(e),a.divAssign(e);const l=bo(a.sub(n.mul(n)).max(0));return bn(n,l)}),B_=un(({samples:e,radius:t,size:r,shadowPass:s,depthLayer:i})=>{const n=gn(0).toVar("meanHorizontal"),a=gn(0).toVar("squareMeanHorizontal"),o=e.lessThanEqual(gn(1)).select(gn(0),gn(2).div(e.sub(1))),u=e.lessThanEqual(gn(1)).select(gn(0),gn(-1));lp({start:mn(0),end:mn(e),type:"int",condition:"<"},({i:e})=>{const l=u.add(gn(e).mul(o));let d=s.sample(Ma(Xl.xy,bn(l,0).mul(t)).div(r));s.value.isArrayTexture&&(d=d.depth(i)),n.addAssign(d.x),a.addAssign(Ma(d.y.mul(d.y),d.x.mul(d.x)))}),n.divAssign(e),a.divAssign(e);const l=bo(a.sub(n.mul(n)).max(0));return bn(n,l)}),D_=[S_,R_,E_,A_];let U_;const I_=new Wb;class O_ extends h_{static get type(){return"ShadowNode"}constructor(e,t=null){super(e),this.shadow=t||e.shadow,this.shadowMap=null,this.vsmShadowMapVertical=null,this.vsmShadowMapHorizontal=null,this.vsmMaterialVertical=null,this.vsmMaterialHorizontal=null,this._node=null,this._currentShadowType=null,this._cameraFrameId=new WeakMap,this.isShadowNode=!0,this.depthLayer=0}setupShadowFilter(e,{filterFn:t,depthTexture:r,shadowCoord:s,shadow:i,depthLayer:n}){const a=s.x.greaterThanEqual(0).and(s.x.lessThanEqual(1)).and(s.y.greaterThanEqual(0)).and(s.y.lessThanEqual(1)).and(s.z.lessThanEqual(1)),o=t({depthTexture:r,shadowCoord:s,shadow:i,depthLayer:n});return a.select(o,gn(1))}setupShadowCoord(e,t){const{shadow:r}=this,{renderer:s}=e,i=r.biasNode||yc("bias","float",r).setGroup(ba);let n,a=t;if(r.camera.isOrthographicCamera||!0!==s.logarithmicDepthBuffer)a=a.xyz.div(a.w),n=a.z,s.coordinateSystem===h&&(n=n.mul(2).sub(1));else{const e=a.w;a=a.xy.div(e);const t=yc("near","float",r.camera).setGroup(ba),s=yc("far","float",r.camera).setGroup(ba);n=Bp(e.negate(),t,s)}return a=vn(a.x,a.y.oneMinus(),n.add(i)),a}getShadowFilterFn(e){return D_[e]}setupRenderTarget(e,t){const r=new Y(e.mapSize.width,e.mapSize.height);r.name="ShadowDepthTexture",r.compareFunction=Je;const s=t.createRenderTarget(e.mapSize.width,e.mapSize.height);return s.texture.name="ShadowMap",s.texture.type=e.mapType,s.depthTexture=r,{shadowMap:s,depthTexture:r}}setupShadow(e){const{renderer:t,camera:r}=e,{light:s,shadow:i}=this,{depthTexture:n,shadowMap:a}=this.setupRenderTarget(i,e),o=t.shadowMap.type;if(o===et||o===tt?(n.minFilter=oe,n.magFilter=oe):(n.minFilter=w,n.magFilter=w),i.camera.coordinateSystem=r.coordinateSystem,i.camera.updateProjectionMatrix(),o===Ze&&!0!==i.isPointLightShadow){n.compareFunction=null,a.depth>1?(a._vsmShadowMapVertical||(a._vsmShadowMapVertical=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depth:a.depth,depthBuffer:!1}),a._vsmShadowMapVertical.texture.name="VSMVertical"),this.vsmShadowMapVertical=a._vsmShadowMapVertical,a._vsmShadowMapHorizontal||(a._vsmShadowMapHorizontal=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depth:a.depth,depthBuffer:!1}),a._vsmShadowMapHorizontal.texture.name="VSMHorizontal"),this.vsmShadowMapHorizontal=a._vsmShadowMapHorizontal):(this.vsmShadowMapVertical=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depthBuffer:!1}),this.vsmShadowMapHorizontal=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depthBuffer:!1}));let t=Pl(n);n.isArrayTexture&&(t=t.depth(this.depthLayer));let r=Pl(this.vsmShadowMapVertical.texture);n.isArrayTexture&&(r=r.depth(this.depthLayer));const s=yc("blurSamples","float",i).setGroup(ba),o=yc("radius","float",i).setGroup(ba),u=yc("mapSize","vec2",i).setGroup(ba);let l=this.vsmMaterialVertical||(this.vsmMaterialVertical=new Zp);l.fragmentNode=P_({samples:s,radius:o,size:u,shadowPass:t,depthLayer:this.depthLayer}).context(e.getSharedContext()),l.name="VSMVertical",l=this.vsmMaterialHorizontal||(this.vsmMaterialHorizontal=new Zp),l.fragmentNode=B_({samples:s,radius:o,size:u,shadowPass:r,depthLayer:this.depthLayer}).context(e.getSharedContext()),l.name="VSMHorizontal"}const u=yc("intensity","float",i).setGroup(ba),l=yc("normalBias","float",i).setGroup(ba),d=r_(s).mul(p_.add(Kd.mul(l))),c=this.setupShadowCoord(e,d),h=i.filterNode||this.getShadowFilterFn(t.shadowMap.type)||null;if(null===h)throw new Error("THREE.WebGPURenderer: Shadow map type not supported yet.");const p=o===Ze&&!0!==i.isPointLightShadow?this.vsmShadowMapHorizontal.texture:n,g=this.setupShadowFilter(e,{filterFn:h,shadowTexture:a.texture,depthTexture:p,shadowCoord:c,shadow:i,depthLayer:this.depthLayer});let m,f;!0===t.shadowMap.transmitted&&(a.texture.isCubeTexture?m=gc(a.texture,c.xyz):(m=Pl(a.texture,c),n.isArrayTexture&&(m=m.depth(this.depthLayer)))),f=m?nu(1,g.rgb.mix(m,1),u.mul(m.a)).toVar():nu(1,g,u).toVar(),this.shadowMap=a,this.shadow.map=a;const y=`${this.light.type} Shadow [ ${this.light.name||"ID: "+this.light.id} ]`;return m&&f.toInspector(`${y} / Color`,()=>this.shadowMap.texture.isCubeTexture?gc(this.shadowMap.texture):Pl(this.shadowMap.texture)),f.toInspector(`${y} / Depth`,()=>this.shadowMap.texture.isCubeTexture?gc(this.shadowMap.texture).r.oneMinus():Bl(this.shadowMap.depthTexture,Rl().mul(Al(Pl(this.shadowMap.depthTexture)))).r.oneMinus())}setup(e){if(!1!==e.renderer.shadowMap.enabled)return un(()=>{const t=e.renderer.shadowMap.type;this._currentShadowType!==t&&(this._reset(),this._node=null);let r=this._node;return this.setupShadowPosition(e),null===r&&(this._node=r=this.setupShadow(e),this._currentShadowType=t),e.material.receivedShadowNode&&(r=e.material.receivedShadowNode(r)),r})()}renderShadow(e){const{shadow:t,shadowMap:r,light:s}=this,{renderer:i,scene:n}=e;t.updateMatrices(s),r.setSize(t.mapSize.width,t.mapSize.height,r.depth);const a=n.name;n.name=`Shadow Map [ ${s.name||"ID: "+s.id} ]`,i.render(n,t.camera),n.name=a}updateShadow(e){const{shadowMap:t,light:r,shadow:s}=this,{renderer:i,scene:n,camera:a}=e,o=i.shadowMap.type,u=t.depthTexture.version;this._depthVersionCached=u;const l=s.camera.layers.mask;4294967294&s.camera.layers.mask||(s.camera.layers.mask=a.layers.mask);const d=i.getRenderObjectFunction(),c=i.getMRT(),h=!!c&&c.has("velocity");U_=T_(i,n,U_),n.overrideMaterial=w_(r),i.setRenderObjectFunction(L_(i,s,o,h)),i.setClearColor(0,0),i.setRenderTarget(t),this.renderShadow(e),i.setRenderObjectFunction(d),o===Ze&&!0!==s.isPointLightShadow&&this.vsmPass(i),s.camera.layers.mask=l,__(i,n,U_)}vsmPass(e){const{shadow:t}=this,r=this.shadowMap.depth;this.vsmShadowMapVertical.setSize(t.mapSize.width,t.mapSize.height,r),this.vsmShadowMapHorizontal.setSize(t.mapSize.width,t.mapSize.height,r),e.setRenderTarget(this.vsmShadowMapVertical),I_.material=this.vsmMaterialVertical,I_.render(e),e.setRenderTarget(this.vsmShadowMapHorizontal),I_.material=this.vsmMaterialHorizontal,I_.render(e)}dispose(){this._reset(),super.dispose()}_reset(){this._currentShadowType=null,C_(this.light),this.shadowMap&&(this.shadowMap.dispose(),this.shadowMap=null),null!==this.vsmShadowMapVertical&&(this.vsmShadowMapVertical.dispose(),this.vsmShadowMapVertical=null,this.vsmMaterialVertical.dispose(),this.vsmMaterialVertical=null),null!==this.vsmShadowMapHorizontal&&(this.vsmShadowMapHorizontal.dispose(),this.vsmShadowMapHorizontal=null,this.vsmMaterialHorizontal.dispose(),this.vsmMaterialHorizontal=null)}updateBefore(e){const{shadow:t}=this;let r=t.needsUpdate||t.autoUpdate;r&&(this._cameraFrameId[e.camera]===e.frameId&&(r=!1),this._cameraFrameId[e.camera]=e.frameId),r&&(this.updateShadow(e),this.shadowMap.depthTexture.version===this._depthVersionCached&&(t.needsUpdate=!1))}}const V_=(e,t)=>new O_(e,t),k_=new e,G_=new a,z_=new r,$_=new r,W_=[new r(1,0,0),new r(-1,0,0),new r(0,-1,0),new r(0,1,0),new r(0,0,1),new r(0,0,-1)],H_=[new r(0,-1,0),new r(0,-1,0),new r(0,0,-1),new r(0,0,1),new r(0,-1,0),new r(0,-1,0)],q_=[new r(1,0,0),new r(-1,0,0),new r(0,1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1)],j_=[new r(0,-1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1),new r(0,-1,0),new r(0,-1,0)],X_=un(({depthTexture:e,bd3D:t,dp:r})=>gc(e,t).compare(r)),K_=un(({depthTexture:e,bd3D:t,dp:r,shadow:s})=>{const i=yc("radius","float",s).setGroup(ba),n=yc("mapSize","vec2",s).setGroup(ba),a=i.div(n.x),o=Mo(t),u=vo(Qo(t,o.x.greaterThan(o.z).select(vn(0,1,0),vn(1,0,0)))),l=Qo(t,u),d=Qb(Xl.xy).mul(6.28318530718),c=Zb(0,5,d),h=Zb(1,5,d),p=Zb(2,5,d),g=Zb(3,5,d),m=Zb(4,5,d);return gc(e,t.add(u.mul(c.x).add(l.mul(c.y)).mul(a))).compare(r).add(gc(e,t.add(u.mul(h.x).add(l.mul(h.y)).mul(a))).compare(r)).add(gc(e,t.add(u.mul(p.x).add(l.mul(p.y)).mul(a))).compare(r)).add(gc(e,t.add(u.mul(g.x).add(l.mul(g.y)).mul(a))).compare(r)).add(gc(e,t.add(u.mul(m.x).add(l.mul(m.y)).mul(a))).compare(r)).mul(.2)}),Y_=un(({filterFn:e,depthTexture:t,shadowCoord:r,shadow:s})=>{const i=r.xyz.toConst(),n=i.abs().toConst(),a=n.x.max(n.y).max(n.z),o=_a("float").setGroup(ba).onRenderUpdate(()=>s.camera.near),u=_a("float").setGroup(ba).onRenderUpdate(()=>s.camera.far),l=yc("bias","float",s).setGroup(ba),d=gn(1).toVar();return cn(a.sub(u).lessThanEqual(0).and(a.sub(o).greaterThanEqual(0)),()=>{const r=Lp(a.negate(),o,u);r.addAssign(l);const n=i.normalize();d.assign(e({depthTexture:t,bd3D:n,dp:r,shadow:s}))}),d});class Q_ extends O_{static get type(){return"PointShadowNode"}constructor(e,t=null){super(e,t)}getShadowFilterFn(e){return e===rt?X_:K_}setupShadowCoord(e,t){return t}setupShadowFilter(e,{filterFn:t,depthTexture:r,shadowCoord:s,shadow:i}){return Y_({filterFn:t,depthTexture:r,shadowCoord:s,shadow:i})}setupRenderTarget(e,t){const r=new st(e.mapSize.width);r.name="PointShadowDepthTexture",r.compareFunction=Je;const s=t.createCubeRenderTarget(e.mapSize.width);return s.texture.name="PointShadowMap",s.depthTexture=r,{shadowMap:s,depthTexture:r}}renderShadow(e){const{shadow:t,shadowMap:r,light:s}=this,{renderer:i,scene:n}=e,a=t.camera,o=t.matrix,u=i.coordinateSystem===h,l=u?W_:q_,d=u?H_:j_;r.setSize(t.mapSize.width,t.mapSize.width);const c=i.autoClear,p=i.getClearColor(k_),g=i.getClearAlpha();i.autoClear=!1,i.setClearColor(t.clearColor,t.clearAlpha);for(let e=0;e<6;e++){i.setRenderTarget(r,e),i.clear();const u=s.distance||a.far;u!==a.far&&(a.far=u,a.updateProjectionMatrix()),z_.setFromMatrixPosition(s.matrixWorld),a.position.copy(z_),$_.copy(a.position),$_.add(l[e]),a.up.copy(d[e]),a.lookAt($_),a.updateMatrixWorld(),o.makeTranslation(-z_.x,-z_.y,-z_.z),G_.multiplyMatrices(a.projectionMatrix,a.matrixWorldInverse),t._frustum.setFromProjectionMatrix(G_,a.coordinateSystem,a.reversedDepth);const c=n.name;n.name=`Point Light Shadow [ ${s.name||"ID: "+s.id} ] - Face ${e+1}`,i.render(n,a),n.name=c}i.autoClear=c,i.setClearColor(p,g)}}const Z_=(e,t)=>new Q_(e,t);class J_ extends fp{static get type(){return"AnalyticLightNode"}constructor(t=null){super(),this.light=t,this.color=new e,this.colorNode=t&&t.colorNode||_a(this.color).setGroup(ba),this.baseColorNode=null,this.shadowNode=null,this.shadowColorNode=null,this.isAnalyticLightNode=!0,this.updateType=Js.FRAME,t&&t.shadow&&(this._shadowDisposeListener=()=>{this.disposeShadow()},t.addEventListener("dispose",this._shadowDisposeListener))}dispose(){this._shadowDisposeListener&&this.light.removeEventListener("dispose",this._shadowDisposeListener),super.dispose()}disposeShadow(){null!==this.shadowNode&&(this.shadowNode.dispose(),this.shadowNode=null),this.shadowColorNode=null,null!==this.baseColorNode&&(this.colorNode=this.baseColorNode,this.baseColorNode=null)}getHash(){return this.light.uuid}getLightVector(e){return a_(this.light).sub(e.context.positionView||Id)}setupDirect(){}setupDirectRectArea(){}setupShadowNode(){return V_(this.light)}setupShadow(e){const{renderer:t}=e;if(!1===t.shadowMap.enabled)return;let r=this.shadowColorNode;if(null===r){const e=this.light.shadow.shadowNode;let t;t=void 0!==e?Zi(e):this.setupShadowNode(),this.shadowNode=t,this.shadowColorNode=r=this.colorNode.mul(t),this.baseColorNode=this.colorNode}e.context.getShadow&&(r=e.context.getShadow(this,e)),this.colorNode=r}setup(e){this.colorNode=this.baseColorNode||this.colorNode,this.light.castShadow?e.object.receiveShadow&&this.setupShadow(e):null!==this.shadowNode&&(this.shadowNode.dispose(),this.shadowNode=null,this.shadowColorNode=null);const t=this.setupDirect(e),r=this.setupDirectRectArea(e);t&&e.lightsNode.setupDirectLight(e,this,t),r&&e.lightsNode.setupDirectRectAreaLight(e,this,r)}update(){const{light:e}=this;this.color.copy(e.color).multiplyScalar(e.intensity)}}const ev=un(({lightDistance:e,cutoffDistance:t,decayExponent:r})=>{const s=e.pow(r).max(.01).reciprocal();return t.greaterThan(0).select(s.mul(e.div(t).pow4().oneMinus().clamp().pow2()),s)}),tv=({color:e,lightVector:t,cutoffDistance:r,decayExponent:s})=>{const i=t.normalize(),n=t.length(),a=ev({lightDistance:n,cutoffDistance:r,decayExponent:s});return{lightDirection:i,lightColor:e.mul(a)}};class rv extends J_{static get type(){return"PointLightNode"}constructor(e=null){super(e),this.cutoffDistanceNode=_a(0).setGroup(ba),this.decayExponentNode=_a(2).setGroup(ba)}update(e){const{light:t}=this;super.update(e),this.cutoffDistanceNode.value=t.distance,this.decayExponentNode.value=t.decay}setupShadowNode(){return Z_(this.light)}setupDirect(e){return tv({color:this.colorNode,lightVector:this.getLightVector(e),cutoffDistance:this.cutoffDistanceNode,decayExponent:this.decayExponentNode})}}const sv=un(([e=Rl()])=>{const t=e.mul(2),r=t.x.floor(),s=t.y.floor();return r.add(s).mod(2).sign()}),iv=un(([e=Rl()],{renderer:t,material:r})=>{const s=iu(e.mul(2).sub(1));let i;if(r.alphaToCoverage&&t.currentSamples>0){const e=gn(s.fwidth()).toVar();i=lu(e.oneMinus(),e.add(1),s).oneMinus()}else i=bu(s.greaterThan(1),0,1);return i}),nv=un(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=yn(e).toVar();return bu(n,i,s)}).setLayout({name:"mx_select",type:"float",inputs:[{name:"b",type:"bool"},{name:"t",type:"float"},{name:"f",type:"float"}]}),av=un(([e,t])=>{const r=yn(t).toVar(),s=gn(e).toVar();return bu(r,s.negate(),s)}).setLayout({name:"mx_negate_if",type:"float",inputs:[{name:"val",type:"float"},{name:"b",type:"bool"}]}),ov=un(([e])=>{const t=gn(e).toVar();return mn(To(t))}).setLayout({name:"mx_floor",type:"int",inputs:[{name:"x",type:"float"}]}),uv=un(([e,t])=>{const r=gn(e).toVar();return t.assign(ov(r)),r.sub(gn(t))}),lv=mb([un(([e,t,r,s,i,n])=>{const a=gn(n).toVar(),o=gn(i).toVar(),u=gn(s).toVar(),l=gn(r).toVar(),d=gn(t).toVar(),c=gn(e).toVar(),h=gn(Fa(1,o)).toVar();return Fa(1,a).mul(c.mul(h).add(d.mul(o))).add(a.mul(l.mul(h).add(u.mul(o))))}).setLayout({name:"mx_bilerp_0",type:"float",inputs:[{name:"v0",type:"float"},{name:"v1",type:"float"},{name:"v2",type:"float"},{name:"v3",type:"float"},{name:"s",type:"float"},{name:"t",type:"float"}]}),un(([e,t,r,s,i,n])=>{const a=gn(n).toVar(),o=gn(i).toVar(),u=vn(s).toVar(),l=vn(r).toVar(),d=vn(t).toVar(),c=vn(e).toVar(),h=gn(Fa(1,o)).toVar();return Fa(1,a).mul(c.mul(h).add(d.mul(o))).add(a.mul(l.mul(h).add(u.mul(o))))}).setLayout({name:"mx_bilerp_1",type:"vec3",inputs:[{name:"v0",type:"vec3"},{name:"v1",type:"vec3"},{name:"v2",type:"vec3"},{name:"v3",type:"vec3"},{name:"s",type:"float"},{name:"t",type:"float"}]})]),dv=mb([un(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=gn(d).toVar(),h=gn(l).toVar(),p=gn(u).toVar(),g=gn(o).toVar(),m=gn(a).toVar(),f=gn(n).toVar(),y=gn(i).toVar(),b=gn(s).toVar(),x=gn(r).toVar(),T=gn(t).toVar(),_=gn(e).toVar(),v=gn(Fa(1,p)).toVar(),N=gn(Fa(1,h)).toVar();return gn(Fa(1,c)).toVar().mul(N.mul(_.mul(v).add(T.mul(p))).add(h.mul(x.mul(v).add(b.mul(p))))).add(c.mul(N.mul(y.mul(v).add(f.mul(p))).add(h.mul(m.mul(v).add(g.mul(p))))))}).setLayout({name:"mx_trilerp_0",type:"float",inputs:[{name:"v0",type:"float"},{name:"v1",type:"float"},{name:"v2",type:"float"},{name:"v3",type:"float"},{name:"v4",type:"float"},{name:"v5",type:"float"},{name:"v6",type:"float"},{name:"v7",type:"float"},{name:"s",type:"float"},{name:"t",type:"float"},{name:"r",type:"float"}]}),un(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=gn(d).toVar(),h=gn(l).toVar(),p=gn(u).toVar(),g=vn(o).toVar(),m=vn(a).toVar(),f=vn(n).toVar(),y=vn(i).toVar(),b=vn(s).toVar(),x=vn(r).toVar(),T=vn(t).toVar(),_=vn(e).toVar(),v=gn(Fa(1,p)).toVar(),N=gn(Fa(1,h)).toVar();return gn(Fa(1,c)).toVar().mul(N.mul(_.mul(v).add(T.mul(p))).add(h.mul(x.mul(v).add(b.mul(p))))).add(c.mul(N.mul(y.mul(v).add(f.mul(p))).add(h.mul(m.mul(v).add(g.mul(p))))))}).setLayout({name:"mx_trilerp_1",type:"vec3",inputs:[{name:"v0",type:"vec3"},{name:"v1",type:"vec3"},{name:"v2",type:"vec3"},{name:"v3",type:"vec3"},{name:"v4",type:"vec3"},{name:"v5",type:"vec3"},{name:"v6",type:"vec3"},{name:"v7",type:"vec3"},{name:"s",type:"float"},{name:"t",type:"float"},{name:"r",type:"float"}]})]),cv=un(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=fn(e).toVar(),a=fn(n.bitAnd(fn(7))).toVar(),o=gn(nv(a.lessThan(fn(4)),i,s)).toVar(),u=gn(La(2,nv(a.lessThan(fn(4)),s,i))).toVar();return av(o,yn(a.bitAnd(fn(1)))).add(av(u,yn(a.bitAnd(fn(2)))))}).setLayout({name:"mx_gradient_float_0",type:"float",inputs:[{name:"hash",type:"uint"},{name:"x",type:"float"},{name:"y",type:"float"}]}),hv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=gn(t).toVar(),o=fn(e).toVar(),u=fn(o.bitAnd(fn(15))).toVar(),l=gn(nv(u.lessThan(fn(8)),a,n)).toVar(),d=gn(nv(u.lessThan(fn(4)),n,nv(u.equal(fn(12)).or(u.equal(fn(14))),a,i))).toVar();return av(l,yn(u.bitAnd(fn(1)))).add(av(d,yn(u.bitAnd(fn(2)))))}).setLayout({name:"mx_gradient_float_1",type:"float",inputs:[{name:"hash",type:"uint"},{name:"x",type:"float"},{name:"y",type:"float"},{name:"z",type:"float"}]}),pv=mb([cv,hv]),gv=un(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=Sn(e).toVar();return vn(pv(n.x,i,s),pv(n.y,i,s),pv(n.z,i,s))}).setLayout({name:"mx_gradient_vec3_0",type:"vec3",inputs:[{name:"hash",type:"uvec3"},{name:"x",type:"float"},{name:"y",type:"float"}]}),mv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=gn(t).toVar(),o=Sn(e).toVar();return vn(pv(o.x,a,n,i),pv(o.y,a,n,i),pv(o.z,a,n,i))}).setLayout({name:"mx_gradient_vec3_1",type:"vec3",inputs:[{name:"hash",type:"uvec3"},{name:"x",type:"float"},{name:"y",type:"float"},{name:"z",type:"float"}]}),fv=mb([gv,mv]),yv=un(([e])=>{const t=gn(e).toVar();return La(.6616,t)}).setLayout({name:"mx_gradient_scale2d_0",type:"float",inputs:[{name:"v",type:"float"}]}),bv=un(([e])=>{const t=gn(e).toVar();return La(.982,t)}).setLayout({name:"mx_gradient_scale3d_0",type:"float",inputs:[{name:"v",type:"float"}]}),xv=mb([yv,un(([e])=>{const t=vn(e).toVar();return La(.6616,t)}).setLayout({name:"mx_gradient_scale2d_1",type:"vec3",inputs:[{name:"v",type:"vec3"}]})]),Tv=mb([bv,un(([e])=>{const t=vn(e).toVar();return La(.982,t)}).setLayout({name:"mx_gradient_scale3d_1",type:"vec3",inputs:[{name:"v",type:"vec3"}]})]),_v=un(([e,t])=>{const r=mn(t).toVar(),s=fn(e).toVar();return s.shiftLeft(r).bitOr(s.shiftRight(mn(32).sub(r)))}).setLayout({name:"mx_rotl32",type:"uint",inputs:[{name:"x",type:"uint"},{name:"k",type:"int"}]}),vv=un(([e,t,r])=>{e.subAssign(r),e.bitXorAssign(_v(r,mn(4))),r.addAssign(t),t.subAssign(e),t.bitXorAssign(_v(e,mn(6))),e.addAssign(r),r.subAssign(t),r.bitXorAssign(_v(t,mn(8))),t.addAssign(e),e.subAssign(r),e.bitXorAssign(_v(r,mn(16))),r.addAssign(t),t.subAssign(e),t.bitXorAssign(_v(e,mn(19))),e.addAssign(r),r.subAssign(t),r.bitXorAssign(_v(t,mn(4))),t.addAssign(e)}),Nv=un(([e,t,r])=>{const s=fn(r).toVar(),i=fn(t).toVar(),n=fn(e).toVar();return s.bitXorAssign(i),s.subAssign(_v(i,mn(14))),n.bitXorAssign(s),n.subAssign(_v(s,mn(11))),i.bitXorAssign(n),i.subAssign(_v(n,mn(25))),s.bitXorAssign(i),s.subAssign(_v(i,mn(16))),n.bitXorAssign(s),n.subAssign(_v(s,mn(4))),i.bitXorAssign(n),i.subAssign(_v(n,mn(14))),s.bitXorAssign(i),s.subAssign(_v(i,mn(24))),s}).setLayout({name:"mx_bjfinal",type:"uint",inputs:[{name:"a",type:"uint"},{name:"b",type:"uint"},{name:"c",type:"uint"}]}),Sv=un(([e])=>{const t=fn(e).toVar();return gn(t).div(gn(fn(mn(4294967295))))}).setLayout({name:"mx_bits_to_01",type:"float",inputs:[{name:"bits",type:"uint"}]}),Rv=un(([e])=>{const t=gn(e).toVar();return t.mul(t).mul(t).mul(t.mul(t.mul(6).sub(15)).add(10))}).setLayout({name:"mx_fade",type:"float",inputs:[{name:"t",type:"float"}]}),Ev=mb([un(([e])=>{const t=mn(e).toVar(),r=fn(fn(1)).toVar(),s=fn(fn(mn(3735928559)).add(r.shiftLeft(fn(2))).add(fn(13))).toVar();return Nv(s.add(fn(t)),s,s)}).setLayout({name:"mx_hash_int_0",type:"uint",inputs:[{name:"x",type:"int"}]}),un(([e,t])=>{const r=mn(t).toVar(),s=mn(e).toVar(),i=fn(fn(2)).toVar(),n=fn().toVar(),a=fn().toVar(),o=fn().toVar();return n.assign(a.assign(o.assign(fn(mn(3735928559)).add(i.shiftLeft(fn(2))).add(fn(13))))),n.addAssign(fn(s)),a.addAssign(fn(r)),Nv(n,a,o)}).setLayout({name:"mx_hash_int_1",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"}]}),un(([e,t,r])=>{const s=mn(r).toVar(),i=mn(t).toVar(),n=mn(e).toVar(),a=fn(fn(3)).toVar(),o=fn().toVar(),u=fn().toVar(),l=fn().toVar();return o.assign(u.assign(l.assign(fn(mn(3735928559)).add(a.shiftLeft(fn(2))).add(fn(13))))),o.addAssign(fn(n)),u.addAssign(fn(i)),l.addAssign(fn(s)),Nv(o,u,l)}).setLayout({name:"mx_hash_int_2",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"}]}),un(([e,t,r,s])=>{const i=mn(s).toVar(),n=mn(r).toVar(),a=mn(t).toVar(),o=mn(e).toVar(),u=fn(fn(4)).toVar(),l=fn().toVar(),d=fn().toVar(),c=fn().toVar();return l.assign(d.assign(c.assign(fn(mn(3735928559)).add(u.shiftLeft(fn(2))).add(fn(13))))),l.addAssign(fn(o)),d.addAssign(fn(a)),c.addAssign(fn(n)),vv(l,d,c),l.addAssign(fn(i)),Nv(l,d,c)}).setLayout({name:"mx_hash_int_3",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xx",type:"int"}]}),un(([e,t,r,s,i])=>{const n=mn(i).toVar(),a=mn(s).toVar(),o=mn(r).toVar(),u=mn(t).toVar(),l=mn(e).toVar(),d=fn(fn(5)).toVar(),c=fn().toVar(),h=fn().toVar(),p=fn().toVar();return c.assign(h.assign(p.assign(fn(mn(3735928559)).add(d.shiftLeft(fn(2))).add(fn(13))))),c.addAssign(fn(l)),h.addAssign(fn(u)),p.addAssign(fn(o)),vv(c,h,p),c.addAssign(fn(a)),h.addAssign(fn(n)),Nv(c,h,p)}).setLayout({name:"mx_hash_int_4",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xx",type:"int"},{name:"yy",type:"int"}]})]),Av=mb([un(([e,t])=>{const r=mn(t).toVar(),s=mn(e).toVar(),i=fn(Ev(s,r)).toVar(),n=Sn().toVar();return n.x.assign(i.bitAnd(mn(255))),n.y.assign(i.shiftRight(mn(8)).bitAnd(mn(255))),n.z.assign(i.shiftRight(mn(16)).bitAnd(mn(255))),n}).setLayout({name:"mx_hash_vec3_0",type:"uvec3",inputs:[{name:"x",type:"int"},{name:"y",type:"int"}]}),un(([e,t,r])=>{const s=mn(r).toVar(),i=mn(t).toVar(),n=mn(e).toVar(),a=fn(Ev(n,i,s)).toVar(),o=Sn().toVar();return o.x.assign(a.bitAnd(mn(255))),o.y.assign(a.shiftRight(mn(8)).bitAnd(mn(255))),o.z.assign(a.shiftRight(mn(16)).bitAnd(mn(255))),o}).setLayout({name:"mx_hash_vec3_1",type:"uvec3",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"}]})]),wv=mb([un(([e])=>{const t=bn(e).toVar(),r=mn().toVar(),s=mn().toVar(),i=gn(uv(t.x,r)).toVar(),n=gn(uv(t.y,s)).toVar(),a=gn(Rv(i)).toVar(),o=gn(Rv(n)).toVar(),u=gn(lv(pv(Ev(r,s),i,n),pv(Ev(r.add(mn(1)),s),i.sub(1),n),pv(Ev(r,s.add(mn(1))),i,n.sub(1)),pv(Ev(r.add(mn(1)),s.add(mn(1))),i.sub(1),n.sub(1)),a,o)).toVar();return xv(u)}).setLayout({name:"mx_perlin_noise_float_0",type:"float",inputs:[{name:"p",type:"vec2"}]}),un(([e])=>{const t=vn(e).toVar(),r=mn().toVar(),s=mn().toVar(),i=mn().toVar(),n=gn(uv(t.x,r)).toVar(),a=gn(uv(t.y,s)).toVar(),o=gn(uv(t.z,i)).toVar(),u=gn(Rv(n)).toVar(),l=gn(Rv(a)).toVar(),d=gn(Rv(o)).toVar(),c=gn(dv(pv(Ev(r,s,i),n,a,o),pv(Ev(r.add(mn(1)),s,i),n.sub(1),a,o),pv(Ev(r,s.add(mn(1)),i),n,a.sub(1),o),pv(Ev(r.add(mn(1)),s.add(mn(1)),i),n.sub(1),a.sub(1),o),pv(Ev(r,s,i.add(mn(1))),n,a,o.sub(1)),pv(Ev(r.add(mn(1)),s,i.add(mn(1))),n.sub(1),a,o.sub(1)),pv(Ev(r,s.add(mn(1)),i.add(mn(1))),n,a.sub(1),o.sub(1)),pv(Ev(r.add(mn(1)),s.add(mn(1)),i.add(mn(1))),n.sub(1),a.sub(1),o.sub(1)),u,l,d)).toVar();return Tv(c)}).setLayout({name:"mx_perlin_noise_float_1",type:"float",inputs:[{name:"p",type:"vec3"}]})]),Cv=mb([un(([e])=>{const t=bn(e).toVar(),r=mn().toVar(),s=mn().toVar(),i=gn(uv(t.x,r)).toVar(),n=gn(uv(t.y,s)).toVar(),a=gn(Rv(i)).toVar(),o=gn(Rv(n)).toVar(),u=vn(lv(fv(Av(r,s),i,n),fv(Av(r.add(mn(1)),s),i.sub(1),n),fv(Av(r,s.add(mn(1))),i,n.sub(1)),fv(Av(r.add(mn(1)),s.add(mn(1))),i.sub(1),n.sub(1)),a,o)).toVar();return xv(u)}).setLayout({name:"mx_perlin_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"vec2"}]}),un(([e])=>{const t=vn(e).toVar(),r=mn().toVar(),s=mn().toVar(),i=mn().toVar(),n=gn(uv(t.x,r)).toVar(),a=gn(uv(t.y,s)).toVar(),o=gn(uv(t.z,i)).toVar(),u=gn(Rv(n)).toVar(),l=gn(Rv(a)).toVar(),d=gn(Rv(o)).toVar(),c=vn(dv(fv(Av(r,s,i),n,a,o),fv(Av(r.add(mn(1)),s,i),n.sub(1),a,o),fv(Av(r,s.add(mn(1)),i),n,a.sub(1),o),fv(Av(r.add(mn(1)),s.add(mn(1)),i),n.sub(1),a.sub(1),o),fv(Av(r,s,i.add(mn(1))),n,a,o.sub(1)),fv(Av(r.add(mn(1)),s,i.add(mn(1))),n.sub(1),a,o.sub(1)),fv(Av(r,s.add(mn(1)),i.add(mn(1))),n,a.sub(1),o.sub(1)),fv(Av(r.add(mn(1)),s.add(mn(1)),i.add(mn(1))),n.sub(1),a.sub(1),o.sub(1)),u,l,d)).toVar();return Tv(c)}).setLayout({name:"mx_perlin_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec3"}]})]),Mv=mb([un(([e])=>{const t=gn(e).toVar(),r=mn(ov(t)).toVar();return Sv(Ev(r))}).setLayout({name:"mx_cell_noise_float_0",type:"float",inputs:[{name:"p",type:"float"}]}),un(([e])=>{const t=bn(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar();return Sv(Ev(r,s))}).setLayout({name:"mx_cell_noise_float_1",type:"float",inputs:[{name:"p",type:"vec2"}]}),un(([e])=>{const t=vn(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar(),i=mn(ov(t.z)).toVar();return Sv(Ev(r,s,i))}).setLayout({name:"mx_cell_noise_float_2",type:"float",inputs:[{name:"p",type:"vec3"}]}),un(([e])=>{const t=En(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar(),i=mn(ov(t.z)).toVar(),n=mn(ov(t.w)).toVar();return Sv(Ev(r,s,i,n))}).setLayout({name:"mx_cell_noise_float_3",type:"float",inputs:[{name:"p",type:"vec4"}]})]),Fv=mb([un(([e])=>{const t=gn(e).toVar(),r=mn(ov(t)).toVar();return vn(Sv(Ev(r,mn(0))),Sv(Ev(r,mn(1))),Sv(Ev(r,mn(2))))}).setLayout({name:"mx_cell_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"float"}]}),un(([e])=>{const t=bn(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar();return vn(Sv(Ev(r,s,mn(0))),Sv(Ev(r,s,mn(1))),Sv(Ev(r,s,mn(2))))}).setLayout({name:"mx_cell_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec2"}]}),un(([e])=>{const t=vn(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar(),i=mn(ov(t.z)).toVar();return vn(Sv(Ev(r,s,i,mn(0))),Sv(Ev(r,s,i,mn(1))),Sv(Ev(r,s,i,mn(2))))}).setLayout({name:"mx_cell_noise_vec3_2",type:"vec3",inputs:[{name:"p",type:"vec3"}]}),un(([e])=>{const t=En(e).toVar(),r=mn(ov(t.x)).toVar(),s=mn(ov(t.y)).toVar(),i=mn(ov(t.z)).toVar(),n=mn(ov(t.w)).toVar();return vn(Sv(Ev(r,s,i,n,mn(0))),Sv(Ev(r,s,i,n,mn(1))),Sv(Ev(r,s,i,n,mn(2))))}).setLayout({name:"mx_cell_noise_vec3_3",type:"vec3",inputs:[{name:"p",type:"vec4"}]})]),Lv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=mn(t).toVar(),o=vn(e).toVar(),u=gn(0).toVar(),l=gn(1).toVar();return lp(a,()=>{u.addAssign(l.mul(wv(o))),l.mulAssign(i),o.mulAssign(n)}),u}).setLayout({name:"mx_fractal_noise_float",type:"float",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Pv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=mn(t).toVar(),o=vn(e).toVar(),u=vn(0).toVar(),l=gn(1).toVar();return lp(a,()=>{u.addAssign(l.mul(Cv(o))),l.mulAssign(i),o.mulAssign(n)}),u}).setLayout({name:"mx_fractal_noise_vec3",type:"vec3",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Bv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=mn(t).toVar(),o=vn(e).toVar();return bn(Lv(o,a,n,i),Lv(o.add(vn(mn(19),mn(193),mn(17))),a,n,i))}).setLayout({name:"mx_fractal_noise_vec2",type:"vec2",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Dv=un(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=mn(t).toVar(),o=vn(e).toVar(),u=vn(Pv(o,a,n,i)).toVar(),l=gn(Lv(o.add(vn(mn(19),mn(193),mn(17))),a,n,i)).toVar();return En(u,l)}).setLayout({name:"mx_fractal_noise_vec4",type:"vec4",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Uv=mb([un(([e,t,r,s,i,n,a])=>{const o=mn(a).toVar(),u=gn(n).toVar(),l=mn(i).toVar(),d=mn(s).toVar(),c=mn(r).toVar(),h=mn(t).toVar(),p=bn(e).toVar(),g=vn(Fv(bn(h.add(d),c.add(l)))).toVar(),m=bn(g.x,g.y).toVar();m.subAssign(.5),m.mulAssign(u),m.addAssign(.5);const f=bn(bn(gn(h),gn(c)).add(m)).toVar(),y=bn(f.sub(p)).toVar();return cn(o.equal(mn(2)),()=>Mo(y.x).add(Mo(y.y))),cn(o.equal(mn(3)),()=>Ho(Mo(y.x),Mo(y.y))),Yo(y,y)}).setLayout({name:"mx_worley_distance_0",type:"float",inputs:[{name:"p",type:"vec2"},{name:"x",type:"int"},{name:"y",type:"int"},{name:"xoff",type:"int"},{name:"yoff",type:"int"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),un(([e,t,r,s,i,n,a,o,u])=>{const l=mn(u).toVar(),d=gn(o).toVar(),c=mn(a).toVar(),h=mn(n).toVar(),p=mn(i).toVar(),g=mn(s).toVar(),m=mn(r).toVar(),f=mn(t).toVar(),y=vn(e).toVar(),b=vn(Fv(vn(f.add(p),m.add(h),g.add(c)))).toVar();b.subAssign(.5),b.mulAssign(d),b.addAssign(.5);const x=vn(vn(gn(f),gn(m),gn(g)).add(b)).toVar(),T=vn(x.sub(y)).toVar();return cn(l.equal(mn(2)),()=>Mo(T.x).add(Mo(T.y)).add(Mo(T.z))),cn(l.equal(mn(3)),()=>Ho(Mo(T.x),Mo(T.y),Mo(T.z))),Yo(T,T)}).setLayout({name:"mx_worley_distance_1",type:"float",inputs:[{name:"p",type:"vec3"},{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xoff",type:"int"},{name:"yoff",type:"int"},{name:"zoff",type:"int"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),Iv=un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=bn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=bn(uv(n.x,a),uv(n.y,o)).toVar(),l=gn(1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{const r=gn(Uv(u,e,t,a,o,i,s)).toVar();l.assign(Wo(l,r))})}),cn(s.equal(mn(0)),()=>{l.assign(bo(l))}),l}).setLayout({name:"mx_worley_noise_float_0",type:"float",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),Ov=un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=bn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=bn(uv(n.x,a),uv(n.y,o)).toVar(),l=bn(1e6,1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{const r=gn(Uv(u,e,t,a,o,i,s)).toVar();cn(r.lessThan(l.x),()=>{l.y.assign(l.x),l.x.assign(r)}).ElseIf(r.lessThan(l.y),()=>{l.y.assign(r)})})}),cn(s.equal(mn(0)),()=>{l.assign(bo(l))}),l}).setLayout({name:"mx_worley_noise_vec2_0",type:"vec2",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),Vv=un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=bn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=bn(uv(n.x,a),uv(n.y,o)).toVar(),l=vn(1e6,1e6,1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{const r=gn(Uv(u,e,t,a,o,i,s)).toVar();cn(r.lessThan(l.x),()=>{l.z.assign(l.y),l.y.assign(l.x),l.x.assign(r)}).ElseIf(r.lessThan(l.y),()=>{l.z.assign(l.y),l.y.assign(r)}).ElseIf(r.lessThan(l.z),()=>{l.z.assign(r)})})}),cn(s.equal(mn(0)),()=>{l.assign(bo(l))}),l}).setLayout({name:"mx_worley_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),kv=mb([Iv,un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=vn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=mn().toVar(),l=vn(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=gn(1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{lp({start:-1,end:mn(1),name:"z",condition:"<="},({z:r})=>{const n=gn(Uv(l,e,t,r,a,o,u,i,s)).toVar();d.assign(Wo(d,n))})})}),cn(s.equal(mn(0)),()=>{d.assign(bo(d))}),d}).setLayout({name:"mx_worley_noise_float_1",type:"float",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),Gv=mb([Ov,un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=vn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=mn().toVar(),l=vn(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=bn(1e6,1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{lp({start:-1,end:mn(1),name:"z",condition:"<="},({z:r})=>{const n=gn(Uv(l,e,t,r,a,o,u,i,s)).toVar();cn(n.lessThan(d.x),()=>{d.y.assign(d.x),d.x.assign(n)}).ElseIf(n.lessThan(d.y),()=>{d.y.assign(n)})})})}),cn(s.equal(mn(0)),()=>{d.assign(bo(d))}),d}).setLayout({name:"mx_worley_noise_vec2_1",type:"vec2",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),zv=mb([Vv,un(([e,t,r])=>{const s=mn(r).toVar(),i=gn(t).toVar(),n=vn(e).toVar(),a=mn().toVar(),o=mn().toVar(),u=mn().toVar(),l=vn(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=vn(1e6,1e6,1e6).toVar();return lp({start:-1,end:mn(1),name:"x",condition:"<="},({x:e})=>{lp({start:-1,end:mn(1),name:"y",condition:"<="},({y:t})=>{lp({start:-1,end:mn(1),name:"z",condition:"<="},({z:r})=>{const n=gn(Uv(l,e,t,r,a,o,u,i,s)).toVar();cn(n.lessThan(d.x),()=>{d.z.assign(d.y),d.y.assign(d.x),d.x.assign(n)}).ElseIf(n.lessThan(d.y),()=>{d.z.assign(d.y),d.y.assign(n)}).ElseIf(n.lessThan(d.z),()=>{d.z.assign(n)})})})}),cn(s.equal(mn(0)),()=>{d.assign(bo(d))}),d}).setLayout({name:"mx_worley_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),$v=un(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=mn(e).toVar(),h=bn(t).toVar(),p=bn(r).toVar(),g=bn(s).toVar(),m=gn(i).toVar(),f=gn(n).toVar(),y=gn(a).toVar(),b=yn(o).toVar(),x=mn(u).toVar(),T=gn(l).toVar(),_=gn(d).toVar(),v=h.mul(p).add(g),N=gn(0).toVar();return cn(c.equal(mn(0)),()=>{N.assign(Cv(v))}),cn(c.equal(mn(1)),()=>{N.assign(Fv(v))}),cn(c.equal(mn(2)),()=>{N.assign(zv(v,m,mn(0)))}),cn(c.equal(mn(3)),()=>{N.assign(Pv(vn(v,0),x,T,_))}),N.assign(N.mul(y.sub(f)).add(f)),cn(b,()=>{N.assign(au(N,f,y))}),N}).setLayout({name:"mx_unifiednoise2d",type:"float",inputs:[{name:"noiseType",type:"int"},{name:"texcoord",type:"vec2"},{name:"freq",type:"vec2"},{name:"offset",type:"vec2"},{name:"jitter",type:"float"},{name:"outmin",type:"float"},{name:"outmax",type:"float"},{name:"clampoutput",type:"bool"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Wv=un(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=mn(e).toVar(),h=vn(t).toVar(),p=vn(r).toVar(),g=vn(s).toVar(),m=gn(i).toVar(),f=gn(n).toVar(),y=gn(a).toVar(),b=yn(o).toVar(),x=mn(u).toVar(),T=gn(l).toVar(),_=gn(d).toVar(),v=h.mul(p).add(g),N=gn(0).toVar();return cn(c.equal(mn(0)),()=>{N.assign(Cv(v))}),cn(c.equal(mn(1)),()=>{N.assign(Fv(v))}),cn(c.equal(mn(2)),()=>{N.assign(zv(v,m,mn(0)))}),cn(c.equal(mn(3)),()=>{N.assign(Pv(v,x,T,_))}),N.assign(N.mul(y.sub(f)).add(f)),cn(b,()=>{N.assign(au(N,f,y))}),N}).setLayout({name:"mx_unifiednoise3d",type:"float",inputs:[{name:"noiseType",type:"int"},{name:"position",type:"vec3"},{name:"freq",type:"vec3"},{name:"offset",type:"vec3"},{name:"jitter",type:"float"},{name:"outmin",type:"float"},{name:"outmax",type:"float"},{name:"clampoutput",type:"bool"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Hv=un(([e])=>{const t=e.y,r=e.z,s=vn().toVar();return cn(t.lessThan(1e-4),()=>{s.assign(vn(r,r,r))}).Else(()=>{let i=e.x;i=i.sub(To(i)).mul(6).toVar();const n=mn(Vo(i)),a=i.sub(gn(n)),o=r.mul(t.oneMinus()),u=r.mul(t.mul(a).oneMinus()),l=r.mul(t.mul(a.oneMinus()).oneMinus());cn(n.equal(mn(0)),()=>{s.assign(vn(r,l,o))}).ElseIf(n.equal(mn(1)),()=>{s.assign(vn(u,r,o))}).ElseIf(n.equal(mn(2)),()=>{s.assign(vn(o,r,l))}).ElseIf(n.equal(mn(3)),()=>{s.assign(vn(o,u,r))}).ElseIf(n.equal(mn(4)),()=>{s.assign(vn(l,o,r))}).Else(()=>{s.assign(vn(r,o,u))})}),s}).setLayout({name:"mx_hsvtorgb",type:"vec3",inputs:[{name:"hsv",type:"vec3"}]}),qv=un(([e])=>{const t=vn(e).toVar(),r=gn(t.x).toVar(),s=gn(t.y).toVar(),i=gn(t.z).toVar(),n=gn(Wo(r,Wo(s,i))).toVar(),a=gn(Ho(r,Ho(s,i))).toVar(),o=gn(a.sub(n)).toVar(),u=gn().toVar(),l=gn().toVar(),d=gn().toVar();return d.assign(a),cn(a.greaterThan(0),()=>{l.assign(o.div(a))}).Else(()=>{l.assign(0)}),cn(l.lessThanEqual(0),()=>{u.assign(0)}).Else(()=>{cn(r.greaterThanEqual(a),()=>{u.assign(s.sub(i).div(o))}).ElseIf(s.greaterThanEqual(a),()=>{u.assign(Ma(2,i.sub(r).div(o)))}).Else(()=>{u.assign(Ma(4,r.sub(s).div(o)))}),u.mulAssign(1/6),cn(u.lessThan(0),()=>{u.addAssign(1)})}),vn(u,l,d)}).setLayout({name:"mx_rgbtohsv",type:"vec3",inputs:[{name:"c",type:"vec3"}]}),jv=un(([e])=>{const t=vn(e).toVar(),r=Rn(Oa(t,vn(.04045))).toVar(),s=vn(t.div(12.92)).toVar(),i=vn(Zo(Ho(t.add(vn(.055)),vn(0)).div(1.055),vn(2.4))).toVar();return nu(s,i,r)}).setLayout({name:"mx_srgb_texture_to_lin_rec709",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Xv=(e,t)=>{e=gn(e),t=gn(t);const r=bn(t.dFdx(),t.dFdy()).length().mul(.7071067811865476);return lu(e.sub(r),e.add(r),t)},Kv=(e,t,r,s)=>nu(e,t,r[s].clamp()),Yv=(e,t,r,s,i)=>nu(e,t,Xv(r,s[i])),Qv=un(([e,t,r])=>{const s=vo(e).toVar(),i=Fa(gn(.5).mul(t.sub(r)),Dd).div(s).toVar(),n=Fa(gn(-.5).mul(t.sub(r)),Dd).div(s).toVar(),a=vn().toVar();a.x=s.x.greaterThan(gn(0)).select(i.x,n.x),a.y=s.y.greaterThan(gn(0)).select(i.y,n.y),a.z=s.z.greaterThan(gn(0)).select(i.z,n.z);const o=Wo(a.x,a.y,a.z).toVar();return Dd.add(s.mul(o)).toVar().sub(r)}),Zv=un(([e,t])=>{const r=e.x,s=e.y,i=e.z;let n=t.element(0).mul(.886227);return n=n.add(t.element(1).mul(1.023328).mul(s)),n=n.add(t.element(2).mul(1.023328).mul(i)),n=n.add(t.element(3).mul(1.023328).mul(r)),n=n.add(t.element(4).mul(.858086).mul(r).mul(s)),n=n.add(t.element(5).mul(.858086).mul(s).mul(i)),n=n.add(t.element(6).mul(i.mul(i).mul(.743125).sub(.247708))),n=n.add(t.element(7).mul(.858086).mul(r).mul(i)),n=n.add(t.element(8).mul(.429043).mul(La(r,r).sub(La(s,s)))),n});var Jv=Object.freeze({__proto__:null,BRDF_GGX:Ug,BRDF_Lambert:_g,BasicPointShadowFilter:X_,BasicShadowFilter:S_,Break:dp,Const:Cu,Continue:()=>gl("continue").toStack(),DFGLUT:Vg,D_GGX:Pg,Discard:ml,EPSILON:so,F_Schlick:Tg,Fn:un,HALF_PI:uo,INFINITY:io,If:cn,Loop:lp,NodeAccess:ti,NodeShaderStage:Zs,NodeType:ei,NodeUpdateType:Js,OnBeforeMaterialUpdate:e=>tx(ex.BEFORE_MATERIAL,e),OnBeforeObjectUpdate:e=>tx(ex.BEFORE_OBJECT,e),OnMaterialUpdate:e=>tx(ex.MATERIAL,e),OnObjectUpdate:e=>tx(ex.OBJECT,e),PCFShadowFilter:R_,PCFSoftShadowFilter:E_,PI:no,PI2:ao,PointShadowFilter:K_,Return:()=>gl("return").toStack(),Schlick_to_F0:zg,ScriptableNodeResources:rT,ShaderNode:Qi,Stack:hn,Switch:(...e)=>_i.Switch(...e),TBNViewMatrix:Wc,TWO_PI:oo,VSMShadowFilter:A_,V_GGX_SmithCorrelated:Fg,Var:wu,VarIntent:Mu,abs:Mo,acesFilmicToneMapping:zx,acos:wo,add:Ma,addMethodChaining:Ni,addNodeElement:function(e){d("TSL: AddNodeElement has been removed in favor of tree-shaking. Trying add",e)},agxToneMapping:qx,all:lo,alphaT:Yn,and:Ga,anisotropy:Qn,anisotropyB:Jn,anisotropyT:Zn,any:co,append:e=>(d("TSL: append() has been renamed to Stack()."),hn(e)),array:Na,arrayBuffer:e=>new xi(e,"ArrayBuffer"),asin:Ao,assign:Ra,atan:Co,atomicAdd:(e,t)=>AT(RT.ATOMIC_ADD,e,t),atomicAnd:(e,t)=>AT(RT.ATOMIC_AND,e,t),atomicFunc:AT,atomicLoad:e=>AT(RT.ATOMIC_LOAD,e,null),atomicMax:(e,t)=>AT(RT.ATOMIC_MAX,e,t),atomicMin:(e,t)=>AT(RT.ATOMIC_MIN,e,t),atomicOr:(e,t)=>AT(RT.ATOMIC_OR,e,t),atomicStore:(e,t)=>AT(RT.ATOMIC_STORE,e,t),atomicSub:(e,t)=>AT(RT.ATOMIC_SUB,e,t),atomicXor:(e,t)=>AT(RT.ATOMIC_XOR,e,t),attenuationColor:ha,attenuationDistance:ca,attribute:Sl,attributeArray:(e,t="float")=>{let r,s;!0===t.isStruct?(r=t.layout.getLength(),s=zs("float")):(r=$s(t),s=zs(t));const i=new sx(e,r,s);return Hh(i,t,e)},backgroundBlurriness:ux,backgroundIntensity:lx,backgroundRotation:dx,batch:ip,bentNormalView:qc,billboarding:_b,bitAnd:Ha,bitNot:qa,bitOr:ja,bitXor:Xa,bitangentGeometry:kc,bitangentLocal:Gc,bitangentView:zc,bitangentWorld:$c,bitcast:jy,blendBurn:Hp,blendColor:Kp,blendDodge:qp,blendOverlay:Xp,blendScreen:jp,blur:zm,bool:yn,buffer:Ul,bufferAttribute:Ju,builtin:Gl,builtinAOContext:Su,builtinShadowContext:Nu,bumpMap:eh,bvec2:_n,bvec3:Rn,bvec4:Cn,bypass:ll,cache:ol,call:Aa,cameraFar:rd,cameraIndex:ed,cameraNear:td,cameraNormalMatrix:od,cameraPosition:ud,cameraProjectionMatrix:sd,cameraProjectionMatrixInverse:id,cameraViewMatrix:nd,cameraViewport:ld,cameraWorldMatrix:ad,cbrt:su,cdl:Ax,ceil:_o,checker:sv,cineonToneMapping:kx,clamp:au,clearcoat:$n,clearcoatNormalView:Yd,clearcoatRoughness:Wn,clipSpace:Fd,code:Kx,color:pn,colorSpaceToWorking:Gu,colorToDirection:e=>Zi(e).mul(2).sub(1),compute:il,computeKernel:sl,computeSkinning:(e,t=null)=>{const r=new ap(e);return r.positionNode=Hh(new W(e.geometry.getAttribute("position").array,3),"vec3").setPBO(!0).toReadOnly().element(Xh).toVar(),r.skinIndexNode=Hh(new W(new Uint32Array(e.geometry.getAttribute("skinIndex").array),4),"uvec4").setPBO(!0).toReadOnly().element(Xh).toVar(),r.skinWeightNode=Hh(new W(e.geometry.getAttribute("skinWeight").array,4),"vec4").setPBO(!0).toReadOnly().element(Xh).toVar(),r.bindMatrixNode=_a(e.bindMatrix,"mat4"),r.bindMatrixInverseNode=_a(e.bindMatrixInverse,"mat4"),r.boneMatricesNode=Ul(e.skeleton.boneMatrices,"mat4",e.skeleton.bones.length),r.toPositionNode=t,Zi(r)},context:Tu,convert:Bn,convertColorSpace:(e,t,r)=>Zi(new Vu(Zi(e),t,r)),convertToTexture:(e,...t)=>e.isSampleNode||e.isTextureNode?e:e.isPassNode?e.getTextureNode():jb(e,...t),cos:Ro,countLeadingZeros:Zy,countOneBits:Jy,countTrailingZeros:Qy,cross:Qo,cubeTexture:gc,cubeTextureBase:pc,dFdx:Do,dFdy:Uo,dashSize:na,debug:xl,decrement:eo,decrementBefore:Za,defaultBuildStages:si,defaultShaderStages:ri,defined:Ki,degrees:po,deltaTime:yb,densityFogFactor:oT,depth:Up,depthPass:(e,t,r)=>new Ux(Ux.DEPTH,e,t,r),determinant:zo,difference:Ko,diffuseColor:On,diffuseContribution:Vn,directPointLight:tv,directionToColor:jc,directionToFaceDirection:zd,dispersion:pa,disposeShadowMaterial:C_,distance:Xo,div:Pa,dot:Yo,drawIndex:Zh,dynamicBufferAttribute:(e,t=null,r=0,s=0)=>Zu(e,t,r,s,x),element:Pn,emissive:kn,equal:Da,equirectUV:og,exp:go,exp2:mo,exponentialHeightFogFactor:uT,expression:gl,faceDirection:Gd,faceForward:du,faceforward:mu,float:gn,floatBitsToInt:e=>new qy(e,"int","float"),floatBitsToUint:Xy,floor:To,fog:lT,fract:No,frameGroup:ya,frameId:bb,frontFacing:kd,fwidth:ko,gain:(e,t)=>e.lessThan(.5)?tb(e.mul(2),t).div(2):Fa(1,tb(La(Fa(1,e),2),t).div(2)),gapSize:aa,getConstNodeType:Yi,getCurrentStack:dn,getDirection:Om,getDistanceAttenuation:ev,getGeometryRoughness:Cg,getNormalFromDepth:Yb,getParallaxCorrectNormal:Qv,getRoughness:Mg,getScreenPosition:Kb,getShIrradianceAt:Zv,getShadowMaterial:w_,getShadowRenderObjectFunction:L_,getTextureIndex:$y,getViewPosition:Xb,ggxConvolution:qm,globalId:bT,glsl:(e,t)=>Kx(e,t,"glsl"),glslFn:(e,t)=>Qx(e,t,"glsl"),grayscale:vx,greaterThan:Oa,greaterThanEqual:ka,hash:eb,highpModelNormalViewMatrix:Md,highpModelViewMatrix:Cd,hue:Rx,increment:Ja,incrementBefore:Qa,inspector:vl,instance:ep,instanceIndex:Xh,instancedArray:(e,t="float")=>{let r,s;!0===t.isStruct?(r=t.layout.getLength(),s=zs("float")):(r=$s(t),s=zs(t));const i=new rx(e,r,s);return Hh(i,t,e)},instancedBufferAttribute:el,instancedDynamicBufferAttribute:tl,instancedMesh:rp,int:mn,intBitsToFloat:e=>new qy(e,"float","int"),interleavedGradientNoise:Qb,inverse:$o,inverseSqrt:xo,inversesqrt:fu,invocationLocalIndex:Qh,invocationSubgroupIndex:Yh,ior:ua,iridescence:jn,iridescenceIOR:Xn,iridescenceThickness:Kn,isolate:al,ivec2:xn,ivec3:Nn,ivec4:An,js:(e,t)=>Kx(e,t,"js"),label:Ru,length:Lo,lengthSq:iu,lessThan:Ia,lessThanEqual:Va,lightPosition:i_,lightProjectionUV:s_,lightShadowMatrix:r_,lightTargetDirection:o_,lightTargetPosition:n_,lightViewPosition:a_,lightingContext:xp,lights:(e=[])=>(new c_).setLights(e),linearDepth:Ip,linearToneMapping:Ox,localId:xT,log:fo,log2:yo,logarithmicDepthToViewZ:(e,t,r)=>{const s=e.mul(fo(r.div(t)));return gn(Math.E).pow(s).mul(t).negate()},luminance:Ex,mat2:Mn,mat3:Fn,mat4:Ln,matcapUV:Ff,materialAO:Vh,materialAlphaTest:sh,materialAnisotropy:vh,materialAnisotropyVector:kh,materialAttenuationColor:Mh,materialAttenuationDistance:Ch,materialClearcoat:fh,materialClearcoatNormal:bh,materialClearcoatRoughness:yh,materialColor:ih,materialDispersion:Ih,materialEmissive:ah,materialEnvIntensity:nc,materialEnvRotation:ac,materialIOR:wh,materialIridescence:Nh,materialIridescenceIOR:Sh,materialIridescenceThickness:Rh,materialLightMap:Oh,materialLineDashOffset:Dh,materialLineDashSize:Lh,materialLineGapSize:Ph,materialLineScale:Fh,materialLineWidth:Bh,materialMetalness:gh,materialNormal:mh,materialOpacity:oh,materialPointSize:Uh,materialReference:Tc,materialReflectivity:hh,materialRefractionRatio:ic,materialRotation:xh,materialRoughness:ph,materialSheen:Th,materialSheenRoughness:_h,materialShininess:nh,materialSpecular:uh,materialSpecularColor:dh,materialSpecularIntensity:lh,materialSpecularStrength:ch,materialThickness:Ah,materialTransmission:Eh,max:Ho,maxMipLevel:Cl,mediumpModelViewMatrix:wd,metalness:zn,min:Wo,mix:nu,mixElement:hu,mod:Ba,modInt:to,modelDirection:xd,modelNormalMatrix:Rd,modelPosition:_d,modelRadius:Sd,modelScale:vd,modelViewMatrix:Ad,modelViewPosition:Nd,modelViewProjection:Gh,modelWorldMatrix:Td,modelWorldMatrixInverse:Ed,morphReference:mp,mrt:Hy,mul:La,mx_aastep:Xv,mx_add:(e,t=gn(0))=>Ma(e,t),mx_atan2:(e=gn(0),t=gn(1))=>Co(e,t),mx_cell_noise_float:(e=Rl())=>Mv(e.convert("vec2|vec3")),mx_contrast:(e,t=1,r=.5)=>gn(e).sub(r).mul(t).add(r),mx_divide:(e,t=gn(1))=>Pa(e,t),mx_fractal_noise_float:(e=Rl(),t=3,r=2,s=.5,i=1)=>Lv(e,mn(t),r,s).mul(i),mx_fractal_noise_vec2:(e=Rl(),t=3,r=2,s=.5,i=1)=>Bv(e,mn(t),r,s).mul(i),mx_fractal_noise_vec3:(e=Rl(),t=3,r=2,s=.5,i=1)=>Pv(e,mn(t),r,s).mul(i),mx_fractal_noise_vec4:(e=Rl(),t=3,r=2,s=.5,i=1)=>Dv(e,mn(t),r,s).mul(i),mx_frame:()=>bb,mx_heighttonormal:(e,t)=>(e=vn(e),t=gn(t),eh(e,t)),mx_hsvtorgb:Hv,mx_ifequal:(e,t,r,s)=>e.equal(t).mix(r,s),mx_ifgreater:(e,t,r,s)=>e.greaterThan(t).mix(r,s),mx_ifgreatereq:(e,t,r,s)=>e.greaterThanEqual(t).mix(r,s),mx_invert:(e,t=gn(1))=>Fa(t,e),mx_modulo:(e,t=gn(1))=>Ba(e,t),mx_multiply:(e,t=gn(1))=>La(e,t),mx_noise_float:(e=Rl(),t=1,r=0)=>wv(e.convert("vec2|vec3")).mul(t).add(r),mx_noise_vec3:(e=Rl(),t=1,r=0)=>Cv(e.convert("vec2|vec3")).mul(t).add(r),mx_noise_vec4:(e=Rl(),t=1,r=0)=>{e=e.convert("vec2|vec3");return En(Cv(e),wv(e.add(bn(19,73)))).mul(t).add(r)},mx_place2d:(e,t=bn(.5,.5),r=bn(1,1),s=gn(0),i=bn(0,0))=>{let n=e;if(t&&(n=n.sub(t)),r&&(n=n.mul(r)),s){const e=s.mul(Math.PI/180),t=e.cos(),r=e.sin();n=bn(n.x.mul(t).sub(n.y.mul(r)),n.x.mul(r).add(n.y.mul(t)))}return t&&(n=n.add(t)),i&&(n=n.add(i)),n},mx_power:(e,t=gn(1))=>Zo(e,t),mx_ramp4:(e,t,r,s,i=Rl())=>{const n=i.x.clamp(),a=i.y.clamp(),o=nu(e,t,n),u=nu(r,s,n);return nu(o,u,a)},mx_ramplr:(e,t,r=Rl())=>Kv(e,t,r,"x"),mx_ramptb:(e,t,r=Rl())=>Kv(e,t,r,"y"),mx_rgbtohsv:qv,mx_rotate2d:(e,t)=>{e=bn(e);const r=(t=gn(t)).mul(Math.PI/180);return Df(e,r)},mx_rotate3d:(e,t,r)=>{e=vn(e),t=gn(t),r=vn(r);const s=t.mul(Math.PI/180),i=r.normalize(),n=s.cos(),a=s.sin(),o=gn(1).sub(n);return e.mul(n).add(i.cross(e).mul(a)).add(i.mul(i.dot(e)).mul(o))},mx_safepower:(e,t=1)=>(e=gn(e)).abs().pow(t).mul(e.sign()),mx_separate:(e,t=null)=>{if("string"==typeof t){const r={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3},s=t.replace(/^out/,"").toLowerCase();if(void 0!==r[s])return e.element(r[s])}if("number"==typeof t)return e.element(t);if("string"==typeof t&&1===t.length){const r={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3};if(void 0!==r[t])return e.element(r[t])}return e},mx_splitlr:(e,t,r,s=Rl())=>Yv(e,t,r,s,"x"),mx_splittb:(e,t,r,s=Rl())=>Yv(e,t,r,s,"y"),mx_srgb_texture_to_lin_rec709:jv,mx_subtract:(e,t=gn(0))=>Fa(e,t),mx_timer:()=>fb,mx_transform_uv:(e=1,t=0,r=Rl())=>r.mul(e).add(t),mx_unifiednoise2d:(e,t=Rl(),r=bn(1,1),s=bn(0,0),i=1,n=0,a=1,o=!1,u=1,l=2,d=.5)=>$v(e,t.convert("vec2|vec3"),r,s,i,n,a,o,u,l,d),mx_unifiednoise3d:(e,t=Rl(),r=bn(1,1),s=bn(0,0),i=1,n=0,a=1,o=!1,u=1,l=2,d=.5)=>Wv(e,t.convert("vec2|vec3"),r,s,i,n,a,o,u,l,d),mx_worley_noise_float:(e=Rl(),t=1)=>kv(e.convert("vec2|vec3"),t,mn(1)),mx_worley_noise_vec2:(e=Rl(),t=1)=>Gv(e.convert("vec2|vec3"),t,mn(1)),mx_worley_noise_vec3:(e=Rl(),t=1)=>zv(e.convert("vec2|vec3"),t,mn(1)),negate:Po,neutralToneMapping:jx,nodeArray:tn,nodeImmutable:sn,nodeObject:Zi,nodeObjectIntent:Ji,nodeObjects:en,nodeProxy:rn,nodeProxyIntent:nn,normalFlat:Hd,normalGeometry:$d,normalLocal:Wd,normalMap:Yc,normalView:Xd,normalViewGeometry:qd,normalWorld:Kd,normalWorldGeometry:jd,normalize:vo,not:$a,notEqual:Ua,numWorkgroups:fT,objectDirection:hd,objectGroup:xa,objectPosition:gd,objectRadius:yd,objectScale:md,objectViewPosition:fd,objectWorldMatrix:pd,oneMinus:Bo,or:za,orthographicDepthToViewZ:(e,t,r)=>t.sub(r).mul(e).sub(t),oscSawtooth:(e=fb)=>e.fract(),oscSine:(e=fb)=>e.add(.75).mul(2*Math.PI).sin().mul(.5).add(.5),oscSquare:(e=fb)=>e.fract().round(),oscTriangle:(e=fb)=>e.add(.5).fract().mul(2).sub(1).abs(),output:ia,outputStruct:Vy,overloadingFn:mb,packHalf2x16:nb,packSnorm2x16:sb,packUnorm2x16:ib,parabola:tb,parallaxDirection:Hc,parallaxUV:(e,t)=>e.sub(Hc.mul(t)),parameter:(e,t)=>new Py(e,t),pass:(e,t,r)=>new Ux(Ux.COLOR,e,t,r),passTexture:(e,t)=>new Bx(e,t),pcurve:(e,t,r)=>Zo(Pa(Zo(e,t),Ma(Zo(e,t),Zo(Fa(1,e),r))),1/t),perspectiveDepthToViewZ:Pp,pmremTexture:ff,pointShadow:Z_,pointUV:nx,pointWidth:oa,positionGeometry:Ld,positionLocal:Pd,positionPrevious:Bd,positionView:Id,positionViewDirection:Od,positionWorld:Dd,positionWorldDirection:Ud,posterize:Cx,pow:Zo,pow2:Jo,pow3:eu,pow4:tu,premultiplyAlpha:Yp,property:Un,quadBroadcast:JT,quadSwapDiagonal:jT,quadSwapX:HT,quadSwapY:qT,radians:ho,rand:cu,range:pT,rangeFogFactor:aT,reciprocal:Oo,reference:yc,referenceBuffer:bc,reflect:jo,reflectVector:lc,reflectView:oc,reflector:e=>new Vb(e),refract:uu,refractVector:dc,refractView:uc,reinhardToneMapping:Vx,remap:cl,remapClamp:hl,renderGroup:ba,renderOutput:yl,rendererReference:Hu,replaceDefaultUV:function(e,t=null){return Tu(t,{getUV:e})},rotate:Df,rotateUV:xb,roughness:Gn,round:Io,rtt:jb,sRGBTransferEOTF:Uu,sRGBTransferOETF:Iu,sample:(e,t=null)=>new Jb(e,Zi(t)),sampler:e=>(!0===e.isNode?e:Pl(e)).convert("sampler"),samplerComparison:e=>(!0===e.isNode?e:Pl(e)).convert("samplerComparison"),saturate:ou,saturation:Nx,screenCoordinate:Xl,screenDPR:Hl,screenSize:jl,screenUV:ql,scriptable:iT,scriptableValue:Jx,select:bu,setCurrentStack:ln,setName:vu,shaderStages:ii,shadow:V_,shadowPositionWorld:p_,shapeCircle:iv,sharedUniformGroup:fa,sheen:Hn,sheenRoughness:qn,shiftLeft:Ka,shiftRight:Ya,shininess:sa,sign:Fo,sin:So,sinc:(e,t)=>So(no.mul(t.mul(e).sub(1))).div(no.mul(t.mul(e).sub(1))),skinning:op,smoothstep:lu,smoothstepElement:pu,specularColor:ea,specularColorBlended:ta,specularF90:ra,spherizeUV:Tb,split:(e,t)=>Zi(new gi(Zi(e),t)),spritesheetUV:Nb,sqrt:bo,stack:Dy,step:qo,stepElement:gu,storage:Hh,storageBarrier:()=>vT("storage").toStack(),storageTexture:hx,string:(e="")=>new xi(e,"string"),struct:(e,t=null)=>{const r=new Uy(e,t),s=(...t)=>{let s=null;if(t.length>0)if(t[0].isNode){s={};const r=Object.keys(e);for(let e=0;emx(e,t).level(r),texture3DLoad:(...e)=>mx(...e).setSampler(!1),textureBarrier:()=>vT("texture").toStack(),textureBicubic:um,textureBicubicLevel:om,textureCubeUV:Vm,textureLevel:(e,t,r)=>Pl(e,t).level(r),textureLoad:Bl,textureSize:Al,textureStore:(e,t,r)=>{let s;return!0===e.isStorageTextureNode?(s=e.clone(),s.uvNode=t,s.storeNode=r):s=hx(e,t,r),null!==r&&s.toStack(),s},thickness:da,time:fb,toneMapping:ju,toneMappingExposure:Xu,toonOutlinePass:(t,r,s=new e(0,0,0),i=.003,n=1)=>Zi(new Ix(t,r,Zi(s),Zi(i),Zi(n))),transformDirection:ru,transformNormal:Qd,transformNormalToView:Zd,transformedClearcoatNormalView:tc,transformedNormalView:Jd,transformedNormalWorld:ec,transmission:la,transpose:Go,triNoise3D:hb,triplanarTexture:(...e)=>Sb(...e),triplanarTextures:Sb,trunc:Vo,uint:fn,uintBitsToFloat:e=>new qy(e,"float","uint"),uniform:_a,uniformArray:Vl,uniformCubeTexture:(e=cc)=>pc(e),uniformFlow:_u,uniformGroup:ma,uniformTexture:(e=Ml)=>Pl(e),unpackHalf2x16:lb,unpackNormal:Xc,unpackSnorm2x16:ob,unpackUnorm2x16:ub,unpremultiplyAlpha:Qp,userData:(e,t,r)=>new fx(e,t,r),uv:Rl,uvec2:Tn,uvec3:Sn,uvec4:wn,varying:Bu,varyingProperty:In,vec2:bn,vec3:vn,vec4:En,vectorComponents:ni,velocity:_x,vertexColor:Wp,vertexIndex:jh,vertexStage:Du,vibrance:Sx,viewZToLogarithmicDepth:Bp,viewZToOrthographicDepth:Fp,viewZToPerspectiveDepth:Lp,viewport:Kl,viewportCoordinate:Ql,viewportDepthTexture:Cp,viewportLinearDepth:Op,viewportMipTexture:Sp,viewportOpaqueMipTexture:Ep,viewportResolution:Jl,viewportSafeUV:vb,viewportSharedTexture:Lx,viewportSize:Yl,viewportTexture:Np,viewportUV:Zl,vogelDiskSample:Zb,wgsl:(e,t)=>Kx(e,t,"wgsl"),wgslFn:(e,t)=>Qx(e,t,"wgsl"),workgroupArray:(e,t)=>new ST("Workgroup",e,t),workgroupBarrier:()=>vT("workgroup").toStack(),workgroupId:yT,workingToColorSpace:ku,xor:Wa});const eN=new Ly;class tN extends ry{constructor(e,t){super(),this.renderer=e,this.nodes=t}update(e,t,r){const s=this.renderer,i=this.nodes.getBackgroundNode(e)||e.background;let n=!1;if(null===i)s._clearColor.getRGB(eN),eN.a=s._clearColor.a;else if(!0===i.isColor)i.getRGB(eN),eN.a=1,n=!0;else if(!0===i.isNode){const u=this.get(e),l=i;eN.copy(s._clearColor);let d=u.backgroundMesh;if(void 0===d){const h=En(l).mul(lx).context({getUV:()=>dx.mul(jd),getTextureLevel:()=>ux}),p=sd.element(3).element(3).equal(1),g=Pa(1,sd.element(1).element(1)).mul(3),m=p.select(Pd.mul(g),Pd),f=Ad.mul(En(m,0));let y=sd.mul(En(f.xyz,1));y=y.setZ(y.w);const b=new Zp;function x(){i.removeEventListener("dispose",x),d.material.dispose(),d.geometry.dispose()}b.name="Background.material",b.side=M,b.depthTest=!1,b.depthWrite=!1,b.allowOverride=!1,b.fog=!1,b.lights=!1,b.vertexNode=y,b.colorNode=h,u.backgroundMeshNode=h,u.backgroundMesh=d=new ne(new it(1,32,32),b),d.frustumCulled=!1,d.name="Background.mesh",i.addEventListener("dispose",x)}const c=l.getCacheKey();u.backgroundCacheKey!==c&&(u.backgroundMeshNode.node=En(l).mul(lx),u.backgroundMeshNode.needsUpdate=!0,d.material.needsUpdate=!0,u.backgroundCacheKey=c),t.unshift(d,d.geometry,d.material,0,0,null,null)}else o("Renderer: Unsupported background configuration.",i);const a=s.xr.getEnvironmentBlendMode();if("additive"===a?eN.set(0,0,0,1):"alpha-blend"===a&&eN.set(0,0,0,0),!0===s.autoClear||!0===n){const T=r.clearColorValue;T.r=eN.r,T.g=eN.g,T.b=eN.b,T.a=eN.a,!0!==s.backend.isWebGLBackend&&!0!==s.alpha||(T.r*=T.a,T.g*=T.a,T.b*=T.a),r.depthClearValue=s._clearDepth,r.stencilClearValue=s._clearStencil,r.clearColor=!0===s.autoClearColor,r.clearDepth=!0===s.autoClearDepth,r.clearStencil=!0===s.autoClearStencil}else r.clearColor=!1,r.clearDepth=!1,r.clearStencil=!1}}let rN=0;class sN{constructor(e="",t=[],r=0,s=[]){this.name=e,this.bindings=t,this.index=r,this.bindingsReference=s,this.id=rN++}}class iN{constructor(e,t,r,s,i,n,a,o,u,l=[]){this.vertexShader=e,this.fragmentShader=t,this.computeShader=r,this.transforms=l,this.nodeAttributes=s,this.bindings=i,this.updateNodes=n,this.updateBeforeNodes=a,this.updateAfterNodes=o,this.observer=u,this.usedTimes=0}createBindings(){const e=[];for(const t of this.bindings){if(!0!==t.bindings[0].groupNode.shared){const r=new sN(t.name,[],t.index,t.bindingsReference);e.push(r);for(const e of t.bindings)r.bindings.push(e.clone())}else e.push(t)}return e}}class nN{constructor(e,t,r=null){this.isNodeAttribute=!0,this.name=e,this.type=t,this.node=r}}class aN{constructor(e,t,r){this.isNodeUniform=!0,this.name=e,this.type=t,this.node=r}get value(){return this.node.value}set value(e){this.node.value=e}get id(){return this.node.id}get groupNode(){return this.node.groupNode}}class oN{constructor(e,t,r=!1,s=null){this.isNodeVar=!0,this.name=e,this.type=t,this.readOnly=r,this.count=s}}class uN extends oN{constructor(e,t,r=null,s=null){super(e,t),this.needsInterpolation=!1,this.isNodeVarying=!0,this.interpolationType=r,this.interpolationSampling=s}}class lN{constructor(e,t,r=""){this.name=e,this.type=t,this.code=r,Object.defineProperty(this,"isNodeCode",{value:!0})}}let dN=0;class cN{constructor(e=null){this.id=dN++,this.nodesData=new WeakMap,this.parent=e}getData(e){let t=this.nodesData.get(e);return void 0===t&&null!==this.parent&&(t=this.parent.getData(e)),t}setData(e,t){this.nodesData.set(e,t)}}class hN{constructor(e,t){this.name=e,this.members=t,this.output=!1}}class pN{constructor(e,t){this.name=e,this.value=t,this.boundary=0,this.itemSize=0,this.offset=0,this.index=-1}setValue(e){this.value=e}getValue(){return this.value}}class gN extends pN{constructor(e,t=0){super(e,t),this.isNumberUniform=!0,this.boundary=4,this.itemSize=1}}class mN extends pN{constructor(e,r=new t){super(e,r),this.isVector2Uniform=!0,this.boundary=8,this.itemSize=2}}class fN extends pN{constructor(e,t=new r){super(e,t),this.isVector3Uniform=!0,this.boundary=16,this.itemSize=3}}class yN extends pN{constructor(e,t=new s){super(e,t),this.isVector4Uniform=!0,this.boundary=16,this.itemSize=4}}class bN extends pN{constructor(t,r=new e){super(t,r),this.isColorUniform=!0,this.boundary=16,this.itemSize=3}}class xN extends pN{constructor(e,t=new i){super(e,t),this.isMatrix2Uniform=!0,this.boundary=8,this.itemSize=4}}class TN extends pN{constructor(e,t=new n){super(e,t),this.isMatrix3Uniform=!0,this.boundary=48,this.itemSize=12}}class _N extends pN{constructor(e,t=new a){super(e,t),this.isMatrix4Uniform=!0,this.boundary=64,this.itemSize=16}}class vN extends gN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class NN extends mN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class SN extends fN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class RN extends yN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class EN extends bN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class AN extends xN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class wN extends TN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class CN extends _N{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}let MN=0;const FN=new WeakMap,LN=new WeakMap,PN=new Map([[Int8Array,"int"],[Int16Array,"int"],[Int32Array,"int"],[Uint8Array,"uint"],[Uint16Array,"uint"],[Uint32Array,"uint"],[Float32Array,"float"]]),BN=e=>/e/g.test(e)?String(e).replace(/\+/g,""):(e=Number(e))+(e%1?"":".0");class DN{constructor(e,t,r){this.object=e,this.material=e&&e.material||null,this.geometry=e&&e.geometry||null,this.renderer=t,this.parser=r,this.scene=null,this.camera=null,this.nodes=[],this.sequentialNodes=[],this.updateNodes=[],this.updateBeforeNodes=[],this.updateAfterNodes=[],this.hashNodes={},this.observer=null,this.lightsNode=null,this.environmentNode=null,this.fogNode=null,this.clippingContext=null,this.vertexShader=null,this.fragmentShader=null,this.computeShader=null,this.flowNodes={vertex:[],fragment:[],compute:[]},this.flowCode={vertex:"",fragment:"",compute:""},this.uniforms={vertex:[],fragment:[],compute:[],index:0},this.structs={vertex:[],fragment:[],compute:[],index:0},this.types={vertex:[],fragment:[],compute:[],index:0},this.bindings={vertex:{},fragment:{},compute:{}},this.bindingsIndexes={},this.bindGroups=null,this.attributes=[],this.bufferAttributes=[],this.varyings=[],this.codes={},this.vars={},this.declarations={},this.flow={code:""},this.chaining=[],this.stack=Dy(),this.stacks=[],this.tab="\t",this.currentFunctionNode=null,this.context={material:this.material},this.cache=new cN,this.globalCache=this.cache,this.flowsData=new WeakMap,this.shaderStage=null,this.buildStage=null,this.subBuildLayers=[],this.activeStacks=[],this.subBuildFn=null,this.fnCall=null,Object.defineProperty(this,"id",{value:MN++})}isFlatShading(){return!0===this.material.flatShading||!1===this.geometry.hasAttribute("normal")}isOpaque(){const e=this.material;return!1===e.transparent&&e.blending===ze&&!1===e.alphaToCoverage}getBindGroupsCache(){let e=LN.get(this.renderer);return void 0===e&&(e=new Qf,LN.set(this.renderer,e)),e}createRenderTarget(e,t,r){return new Ne(e,t,r)}createCubeRenderTarget(e,t){return new ug(e,t)}includes(e){return this.nodes.includes(e)}getOutputStructName(){}_getBindGroup(e,t){const r=this.getBindGroupsCache(),s=[];let i,n=!0;for(const e of t)s.push(e),n=n&&!0!==e.groupNode.shared;return n?(i=r.get(s),void 0===i&&(i=new sN(e,s,this.bindingsIndexes[e].group,s),r.set(s,i))):i=new sN(e,s,this.bindingsIndexes[e].group,s),i}getBindGroupArray(e,t){const r=this.bindings[t];let s=r[e];return void 0===s&&(void 0===this.bindingsIndexes[e]&&(this.bindingsIndexes[e]={binding:0,group:Object.keys(this.bindingsIndexes).length}),r[e]=s=[]),s}getBindings(){let e=this.bindGroups;if(null===e){const t={},r=this.bindings;for(const e of ii)for(const s in r[e]){const i=r[e][s],n=t[s]||(t[s]=[]);for(const e of i)!1===n.includes(e)&&n.push(e)}e=[];for(const r in t){const s=t[r],i=this._getBindGroup(r,s);e.push(i)}this.bindGroups=e}return e}sortBindingGroups(){const e=this.getBindings();e.sort((e,t)=>e.bindings[0].groupNode.order-t.bindings[0].groupNode.order);for(let t=0;t=0?`${Math.round(n)}u`:"0u";if("bool"===i)return n?"true":"false";if("color"===i)return`${this.getType("vec3")}( ${BN(n.r)}, ${BN(n.g)}, ${BN(n.b)} )`;const a=this.getTypeLength(i),o=this.getComponentType(i),u=e=>this.generateConst(o,e);if(2===a)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)} )`;if(3===a)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)}, ${u(n.z)} )`;if(4===a&&"mat2"!==i)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)}, ${u(n.z)}, ${u(n.w)} )`;if(a>=4&&n&&(n.isMatrix2||n.isMatrix3||n.isMatrix4))return`${this.getType(i)}( ${n.elements.map(u).join(", ")} )`;if(a>4)return`${this.getType(i)}()`;throw new Error(`NodeBuilder: Type '${i}' not found in generate constant attempt.`)}getType(e){return"color"===e?"vec3":e}hasGeometryAttribute(e){return this.geometry&&void 0!==this.geometry.getAttribute(e)}getAttribute(e,t){const r=this.attributes;for(const t of r)if(t.name===e)return t;const s=new nN(e,t);return this.registerDeclaration(s),r.push(s),s}getPropertyName(e){return e.name}isVector(e){return/vec\d/.test(e)}isMatrix(e){return/mat\d/.test(e)}isReference(e){return"void"===e||"property"===e||"sampler"===e||"samplerComparison"===e||"texture"===e||"cubeTexture"===e||"storageTexture"===e||"depthTexture"===e||"texture3D"===e}needsToWorkingColorSpace(){return!1}getComponentTypeFromTexture(e){const t=e.type;if(e.isDataTexture){if(t===R)return"int";if(t===S)return"uint"}return"float"}getElementType(e){return"mat2"===e?"vec2":"mat3"===e?"vec3":"mat4"===e?"vec4":this.getComponentType(e)}getComponentType(e){if("float"===(e=this.getVectorType(e))||"bool"===e||"int"===e||"uint"===e)return e;const t=/(b|i|u|)(vec|mat)([2-4])/.exec(e);return null===t?null:"b"===t[1]?"bool":"i"===t[1]?"int":"u"===t[1]?"uint":"float"}getVectorType(e){return"color"===e?"vec3":"texture"===e||"cubeTexture"===e||"storageTexture"===e||"texture3D"===e?"vec4":e}getTypeFromLength(e,t="float"){if(1===e)return t;let r=Gs(e);const s="float"===t?"":t[0];return!0===/mat2/.test(t)&&(r=r.replace("vec","mat")),s+r}getTypeFromArray(e){return PN.get(e.constructor)}isInteger(e){return/int|uint|(i|u)vec/.test(e)}getTypeFromAttribute(e){let t=e;e.isInterleavedBufferAttribute&&(t=e.data);const r=t.array,s=e.itemSize,i=e.normalized;let n;return e instanceof ot||!0===i||(n=this.getTypeFromArray(r)),this.getTypeFromLength(s,n)}getTypeLength(e){const t=this.getVectorType(e),r=/vec([2-4])/.exec(t);return null!==r?Number(r[1]):"float"===t||"bool"===t||"int"===t||"uint"===t?1:!0===/mat2/.test(e)?4:!0===/mat3/.test(e)?9:!0===/mat4/.test(e)?16:0}getVectorFromMatrix(e){return e.replace("mat","vec")}changeComponentType(e,t){return this.getTypeFromLength(this.getTypeLength(e),t)}getIntegerType(e){const t=this.getComponentType(e);return"int"===t||"uint"===t?e:this.changeComponentType(e,"int")}setActiveStack(e){this.activeStacks.push(e)}removeActiveStack(e){if(this.activeStacks[this.activeStacks.length-1]!==e)throw new Error("NodeBuilder: Invalid active stack removal.");this.activeStacks.pop()}getActiveStack(){return this.activeStacks[this.activeStacks.length-1]}getBaseStack(){return this.activeStacks[0]}addStack(){this.stack=Dy(this.stack);const e=dn();return this.stacks.push(e),ln(this.stack),this.stack}removeStack(){const e=this.stack;for(const t of e.nodes){this.getDataFromNode(t).stack=e}return this.stack=e.parent,ln(this.stacks.pop()),e}getDataFromNode(e,t=this.shaderStage,r=null){let s=(r=null===r?e.isGlobal(this)?this.globalCache:this.cache:r).getData(e);void 0===s&&(s={},r.setData(e,s)),void 0===s[t]&&(s[t]={});let i=s[t];const n=s.any?s.any.subBuilds:null,a=this.getClosestSubBuild(n);return a&&(void 0===i.subBuildsCache&&(i.subBuildsCache={}),i=i.subBuildsCache[a]||(i.subBuildsCache[a]={}),i.subBuilds=n),i}getNodeProperties(e,t="any"){const r=this.getDataFromNode(e,t);return r.properties||(r.properties={outputNode:null})}getBufferAttributeFromNode(e,t){const r=this.getDataFromNode(e,"vertex");let s=r.bufferAttribute;if(void 0===s){const i=this.uniforms.index++;s=new nN("nodeAttribute"+i,t,e),this.bufferAttributes.push(s),r.bufferAttribute=s}return s}getStructTypeNode(e,t=this.shaderStage){return this.types[t][e]||null}getStructTypeFromNode(e,t,r=null,s=this.shaderStage){const i=this.getDataFromNode(e,s,this.globalCache);let n=i.structType;if(void 0===n){const a=this.structs.index++;null===r&&(r="StructType"+a),n=new hN(r,t),this.structs[s].push(n),this.types[s][r]=e,i.structType=n}return n}getOutputStructTypeFromNode(e,t){const r=this.getStructTypeFromNode(e,t,"OutputType","fragment");return r.output=!0,r}getUniformFromNode(e,t,r=this.shaderStage,s=null){const i=this.getDataFromNode(e,r,this.globalCache);let n=i.uniform;if(void 0===n){const a=this.uniforms.index++;n=new aN(s||"nodeUniform"+a,t,e),this.uniforms[r].push(n),this.registerDeclaration(n),i.uniform=n}return n}getVarFromNode(e,t=null,r=e.getNodeType(this),s=this.shaderStage,i=!1){const n=this.getDataFromNode(e,s),a=this.getSubBuildProperty("variable",n.subBuilds);let o=n[a];if(void 0===o){const u=i?"_const":"_var",l=this.vars[s]||(this.vars[s]=[]),d=this.vars[u]||(this.vars[u]=0);null===t&&(t=(i?"nodeConst":"nodeVar")+d,this.vars[u]++),"variable"!==a&&(t=this.getSubBuildProperty(t,n.subBuilds));const c=e.getArrayCount(this);o=new oN(t,r,i,c),i||l.push(o),this.registerDeclaration(o),n[a]=o}return o}isDeterministic(e){if(e.isMathNode)return this.isDeterministic(e.aNode)&&(!e.bNode||this.isDeterministic(e.bNode))&&(!e.cNode||this.isDeterministic(e.cNode));if(e.isOperatorNode)return this.isDeterministic(e.aNode)&&(!e.bNode||this.isDeterministic(e.bNode));if(e.isArrayNode){if(null!==e.values)for(const t of e.values)if(!this.isDeterministic(t))return!1;return!0}return!!e.isConstNode}getVaryingFromNode(e,t=null,r=e.getNodeType(this),s=null,i=null){const n=this.getDataFromNode(e,"any"),a=this.getSubBuildProperty("varying",n.subBuilds);let o=n[a];if(void 0===o){const e=this.varyings,u=e.length;null===t&&(t="nodeVarying"+u),"varying"!==a&&(t=this.getSubBuildProperty(t,n.subBuilds)),o=new uN(t,r,s,i),e.push(o),this.registerDeclaration(o),n[a]=o}return o}registerDeclaration(e){const t=this.shaderStage,r=this.declarations[t]||(this.declarations[t]={}),s=this.getPropertyName(e);let i=1,n=s;for(;void 0!==r[n];)n=s+"_"+i++;i>1&&(e.name=n,d(`TSL: Declaration name '${s}' of '${e.type}' already in use. Renamed to '${n}'.`)),r[n]=e}getCodeFromNode(e,t,r=this.shaderStage){const s=this.getDataFromNode(e);let i=s.code;if(void 0===i){const e=this.codes[r]||(this.codes[r]=[]),n=e.length;i=new lN("nodeCode"+n,t),e.push(i),s.code=i}return i}addFlowCodeHierarchy(e,t){const{flowCodes:r,flowCodeBlock:s}=this.getDataFromNode(e);let i=!0,n=t;for(;n;){if(!0===s.get(n)){i=!1;break}n=this.getDataFromNode(n).parentNodeBlock}if(i)for(const e of r)this.addLineFlowCode(e)}addLineFlowCodeBlock(e,t,r){const s=this.getDataFromNode(e),i=s.flowCodes||(s.flowCodes=[]),n=s.flowCodeBlock||(s.flowCodeBlock=new WeakMap);i.push(t),n.set(r,!0)}addLineFlowCode(e,t=null){return""===e||(null!==t&&this.context.nodeBlock&&this.addLineFlowCodeBlock(t,e,this.context.nodeBlock),e=this.tab+e,/;\s*$/.test(e)||(e+=";\n"),this.flow.code+=e),this}addFlowCode(e){return this.flow.code+=e,this}addFlowTab(){return this.tab+="\t",this}removeFlowTab(){return this.tab=this.tab.slice(0,-1),this}getFlowData(e){return this.flowsData.get(e)}flowNode(e){const t=e.getNodeType(this),r=this.flowChildNode(e,t);return this.flowsData.set(e,r),r}addInclude(e){null!==this.currentFunctionNode&&this.currentFunctionNode.includes.push(e)}buildFunctionNode(e){const t=new Yx,r=this.currentFunctionNode;return this.currentFunctionNode=t,t.code=this.buildFunctionCode(e),this.currentFunctionNode=r,t}flowShaderNode(e){const t=e.layout,r={[Symbol.iterator](){let e=0;const t=Object.values(this);return{next:()=>({value:t[e],done:e++>=t.length})}}};for(const e of t.inputs)r[e.name]=new Py(e.type,e.name);e.layout=null;const s=e.call(r),i=this.flowStagesNode(s,t.type);return e.layout=t,i}flowBuildStage(e,t,r=null){const s=this.getBuildStage();this.setBuildStage(t);const i=e.build(this,r);return this.setBuildStage(s),i}flowStagesNode(e,t=null){const r=this.flow,s=this.vars,i=this.declarations,n=this.cache,a=this.buildStage,o=this.stack,u={code:""};this.flow=u,this.vars={},this.declarations={},this.cache=new cN,this.stack=Dy();for(const r of si)this.setBuildStage(r),u.result=e.build(this,t);return u.vars=this.getVars(this.shaderStage),this.flow=r,this.vars=s,this.declarations=i,this.cache=n,this.stack=o,this.setBuildStage(a),u}getFunctionOperator(){return null}buildFunctionCode(){d("Abstract function.")}flowChildNode(e,t=null){const r=this.flow,s={code:""};return this.flow=s,s.result=e.build(this,t),this.flow=r,s}flowNodeFromShaderStage(e,t,r=null,s=null){const i=this.tab,n=this.cache,a=this.shaderStage,o=this.context;this.setShaderStage(e);const u={...this.context};delete u.nodeBlock,this.cache=this.globalCache,this.tab="\t",this.context=u;let l=null;if("generate"===this.buildStage){const i=this.flowChildNode(t,r);null!==s&&(i.code+=`${this.tab+s} = ${i.result};\n`),this.flowCode[e]=this.flowCode[e]+i.code,l=i}else l=t.build(this);return this.setShaderStage(a),this.cache=n,this.tab=i,this.context=o,l}getAttributesArray(){return this.attributes.concat(this.bufferAttributes)}getAttributes(){d("Abstract function.")}getVaryings(){d("Abstract function.")}getVar(e,t,r=null){return`${null!==r?this.generateArrayDeclaration(e,r):this.getType(e)} ${t}`}getVars(e){let t="";const r=this.vars[e];if(void 0!==r)for(const e of r)t+=`${this.getVar(e.type,e.name)}; `;return t}getUniforms(){d("Abstract function.")}getCodes(e){const t=this.codes[e];let r="";if(void 0!==t)for(const e of t)r+=e.code+"\n";return r}getHash(){return this.vertexShader+this.fragmentShader+this.computeShader}setShaderStage(e){this.shaderStage=e}getShaderStage(){return this.shaderStage}setBuildStage(e){this.buildStage=e}getBuildStage(){return this.buildStage}buildCode(){d("Abstract function.")}get subBuild(){return this.subBuildLayers[this.subBuildLayers.length-1]||null}addSubBuild(e){this.subBuildLayers.push(e)}removeSubBuild(){return this.subBuildLayers.pop()}getClosestSubBuild(e){let t;if(t=e&&e.isNode?e.isShaderCallNodeInternal?e.shaderNode.subBuilds:e.isStackNode?[e.subBuild]:this.getDataFromNode(e,"any").subBuilds:e instanceof Set?[...e]:e,!t)return null;const r=this.subBuildLayers;for(let e=t.length-1;e>=0;e--){const s=t[e];if(r.includes(s))return s}return null}getSubBuildOutput(e){return this.getSubBuildProperty("outputNode",e)}getSubBuildProperty(e="",t=null){let r,s;return r=null!==t?this.getClosestSubBuild(t):this.subBuildFn,s=r?e?r+"_"+e:r:e,s}build(){const{object:e,material:t,renderer:r}=this;if(null!==t){let e=r.library.fromMaterial(t);null===e&&(o(`NodeMaterial: Material "${t.type}" is not compatible.`),e=new Zp),e.build(this)}else this.addFlow("compute",e);for(const e of si){this.setBuildStage(e),this.context.position&&this.context.position.isNode&&this.flowNodeFromShaderStage("vertex",this.context.position);for(const t of ii){this.setShaderStage(t);const r=this.flowNodes[t];for(const t of r)"generate"===e?this.flowNode(t):t.build(this)}}return this.setBuildStage(null),this.setShaderStage(null),this.buildCode(),this.buildUpdateNodes(),this}getSharedDataFromNode(e){let t=FN.get(e);return void 0===t&&(t={}),t}getNodeUniform(e,t){const r=this.getSharedDataFromNode(e);let s=r.cache;if(void 0===s){if("float"===t||"int"===t||"uint"===t)s=new vN(e);else if("vec2"===t||"ivec2"===t||"uvec2"===t)s=new NN(e);else if("vec3"===t||"ivec3"===t||"uvec3"===t)s=new SN(e);else if("vec4"===t||"ivec4"===t||"uvec4"===t)s=new RN(e);else if("color"===t)s=new EN(e);else if("mat2"===t)s=new AN(e);else if("mat3"===t)s=new wN(e);else{if("mat4"!==t)throw new Error(`Uniform "${t}" not implemented.`);s=new CN(e)}r.cache=s}return s}format(e,t,r){if((t=this.getVectorType(t))===(r=this.getVectorType(r))||null===r||this.isReference(r))return e;const s=this.getTypeLength(t),i=this.getTypeLength(r);return 16===s&&9===i?`${this.getType(r)}( ${e}[ 0 ].xyz, ${e}[ 1 ].xyz, ${e}[ 2 ].xyz )`:9===s&&4===i?`${this.getType(r)}( ${e}[ 0 ].xy, ${e}[ 1 ].xy )`:s>4||i>4||0===i?e:s===i?`${this.getType(r)}( ${e} )`:s>i?(e="bool"===r?`all( ${e} )`:`${e}.${"xyz".slice(0,i)}`,this.format(e,this.getTypeFromLength(i,this.getComponentType(t)),r)):4===i&&s>1?`${this.getType(r)}( ${this.format(e,t,"vec3")}, 1.0 )`:2===s?`${this.getType(r)}( ${this.format(e,t,"vec2")}, 0.0 )`:(1===s&&i>1&&t!==this.getComponentType(r)&&(e=`${this.getType(this.getComponentType(r))}( ${e} )`),`${this.getType(r)}( ${e} )`)}getSignature(){return`// Three.js r${ut} - Node System\n`}needsPreviousData(){const e=this.renderer.getMRT();return e&&e.has("velocity")||!0===Xs(this.object).useVelocity}}class UN{constructor(){this.time=0,this.deltaTime=0,this.frameId=0,this.renderId=0,this.updateMap=new WeakMap,this.updateBeforeMap=new WeakMap,this.updateAfterMap=new WeakMap,this.renderer=null,this.material=null,this.camera=null,this.object=null,this.scene=null}_getMaps(e,t){let r=e.get(t);return void 0===r&&(r={renderId:0,frameId:0},e.set(t,r)),r}updateBeforeNode(e){const t=e.getUpdateBeforeType(),r=e.updateReference(this);if(t===Js.FRAME){const t=this._getMaps(this.updateBeforeMap,r);if(t.frameId!==this.frameId){const r=t.frameId;t.frameId=this.frameId,!1===e.updateBefore(this)&&(t.frameId=r)}}else if(t===Js.RENDER){const t=this._getMaps(this.updateBeforeMap,r);if(t.renderId!==this.renderId){const r=t.renderId;t.renderId=this.renderId,!1===e.updateBefore(this)&&(t.renderId=r)}}else t===Js.OBJECT&&e.updateBefore(this)}updateAfterNode(e){const t=e.getUpdateAfterType(),r=e.updateReference(this);if(t===Js.FRAME){const t=this._getMaps(this.updateAfterMap,r);t.frameId!==this.frameId&&!1!==e.updateAfter(this)&&(t.frameId=this.frameId)}else if(t===Js.RENDER){const t=this._getMaps(this.updateAfterMap,r);t.renderId!==this.renderId&&!1!==e.updateAfter(this)&&(t.renderId=this.renderId)}else t===Js.OBJECT&&e.updateAfter(this)}updateNode(e){const t=e.getUpdateType(),r=e.updateReference(this);if(t===Js.FRAME){const t=this._getMaps(this.updateMap,r);t.frameId!==this.frameId&&!1!==e.update(this)&&(t.frameId=this.frameId)}else if(t===Js.RENDER){const t=this._getMaps(this.updateMap,r);t.renderId!==this.renderId&&!1!==e.update(this)&&(t.renderId=this.renderId)}else t===Js.OBJECT&&e.update(this)}update(){this.frameId++,void 0===this.lastTime&&(this.lastTime=performance.now()),this.deltaTime=(performance.now()-this.lastTime)/1e3,this.lastTime=performance.now(),this.time+=this.deltaTime}}class IN{constructor(e,t,r=null,s="",i=!1){this.type=e,this.name=t,this.count=r,this.qualifier=s,this.isConst=i}}IN.isNodeFunctionInput=!0;class ON extends J_{static get type(){return"AmbientLightNode"}constructor(e=null){super(e)}setup({context:e}){e.irradiance.addAssign(this.colorNode)}}class VN extends J_{static get type(){return"DirectionalLightNode"}constructor(e=null){super(e)}setupDirect(){const e=this.colorNode;return{lightDirection:o_(this.light),lightColor:e}}}class kN extends J_{static get type(){return"HemisphereLightNode"}constructor(t=null){super(t),this.lightPositionNode=i_(t),this.lightDirectionNode=this.lightPositionNode.normalize(),this.groundColorNode=_a(new e).setGroup(ba)}update(e){const{light:t}=this;super.update(e),this.lightPositionNode.object3d=t,this.groundColorNode.value.copy(t.groundColor).multiplyScalar(t.intensity)}setup(e){const{colorNode:t,groundColorNode:r,lightDirectionNode:s}=this,i=Kd.dot(s).mul(.5).add(.5),n=nu(r,t,i);e.context.irradiance.addAssign(n)}}class GN extends J_{static get type(){return"SpotLightNode"}constructor(e=null){super(e),this.coneCosNode=_a(0).setGroup(ba),this.penumbraCosNode=_a(0).setGroup(ba),this.cutoffDistanceNode=_a(0).setGroup(ba),this.decayExponentNode=_a(0).setGroup(ba),this.colorNode=_a(this.color).setGroup(ba)}update(e){super.update(e);const{light:t}=this;this.coneCosNode.value=Math.cos(t.angle),this.penumbraCosNode.value=Math.cos(t.angle*(1-t.penumbra)),this.cutoffDistanceNode.value=t.distance,this.decayExponentNode.value=t.decay}getSpotAttenuation(e,t){const{coneCosNode:r,penumbraCosNode:s}=this;return lu(r,s,t)}getLightCoord(e){const t=e.getNodeProperties(this);let r=t.projectionUV;return void 0===r&&(r=s_(this.light,e.context.positionWorld),t.projectionUV=r),r}setupDirect(e){const{colorNode:t,cutoffDistanceNode:r,decayExponentNode:s,light:i}=this,n=this.getLightVector(e),a=n.normalize(),o=a.dot(o_(i)),u=this.getSpotAttenuation(e,o),l=n.length(),d=ev({lightDistance:l,cutoffDistance:r,decayExponent:s});let c,h,p=t.mul(u).mul(d);if(i.colorNode?(h=this.getLightCoord(e),c=i.colorNode(h)):i.map&&(h=this.getLightCoord(e),c=Pl(i.map,h.xy).onRenderUpdate(()=>i.map)),c){p=h.mul(2).sub(1).abs().lessThan(1).all().select(p.mul(c),p)}return{lightColor:p,lightDirection:a}}}class zN extends GN{static get type(){return"IESSpotLightNode"}getSpotAttenuation(e,t){const r=this.light.iesMap;let s=null;if(r&&!0===r.isTexture){const e=t.acos().mul(1/Math.PI);s=Pl(r,bn(e,0),0).r}else s=super.getSpotAttenuation(t);return s}}class $N extends J_{static get type(){return"LightProbeNode"}constructor(e=null){super(e);const t=[];for(let e=0;e<9;e++)t.push(new r);this.lightProbe=Vl(t)}update(e){const{light:t}=this;super.update(e);for(let e=0;e<9;e++)this.lightProbe.array[e].copy(t.sh.coefficients[e]).multiplyScalar(t.intensity)}setup(e){const t=Zv(Kd,this.lightProbe);e.context.irradiance.addAssign(t)}}const WN=un(([e,t])=>{const r=e.abs().sub(t);return Lo(Ho(r,0)).add(Wo(Ho(r.x,r.y),0))});class HN extends GN{static get type(){return"ProjectorLightNode"}update(e){super.update(e);const t=this.light;if(this.penumbraCosNode.value=Math.min(Math.cos(t.angle*(1-t.penumbra)),.99999),null===t.aspect){let e=1;null!==t.map&&(e=t.map.width/t.map.height),t.shadow.aspect=e}else t.shadow.aspect=t.aspect}getSpotAttenuation(e){const t=gn(0),r=this.penumbraCosNode,s=r_(this.light).mul(e.context.positionWorld||Dd);return cn(s.w.greaterThan(0),()=>{const e=s.xyz.div(s.w),i=WN(e.xy.sub(bn(.5)),bn(.5)),n=Pa(-1,Fa(1,wo(r)).sub(1));t.assign(ou(i.mul(-2).mul(n)))}),t}}const qN=new a,jN=new a;let XN=null;class KN extends J_{static get type(){return"RectAreaLightNode"}constructor(e=null){super(e),this.halfHeight=_a(new r).setGroup(ba),this.halfWidth=_a(new r).setGroup(ba),this.updateType=Js.RENDER}update(e){super.update(e);const{light:t}=this,r=e.camera.matrixWorldInverse;jN.identity(),qN.copy(t.matrixWorld),qN.premultiply(r),jN.extractRotation(qN),this.halfWidth.value.set(.5*t.width,0,0),this.halfHeight.value.set(0,.5*t.height,0),this.halfWidth.value.applyMatrix4(jN),this.halfHeight.value.applyMatrix4(jN)}setupDirectRectArea(e){let t,r;e.isAvailable("float32Filterable")?(t=Pl(XN.LTC_FLOAT_1),r=Pl(XN.LTC_FLOAT_2)):(t=Pl(XN.LTC_HALF_1),r=Pl(XN.LTC_HALF_2));const{colorNode:s,light:i}=this;return{lightColor:s,lightPosition:a_(i),halfWidth:this.halfWidth,halfHeight:this.halfHeight,ltc_1:t,ltc_2:r}}static setLTC(e){XN=e}}class YN{parseFunction(){d("Abstract function.")}}class QN{constructor(e,t,r="",s=""){this.type=e,this.inputs=t,this.name=r,this.precision=s}getCode(){d("Abstract function.")}}QN.isNodeFunction=!0;const ZN=/^\s*(highp|mediump|lowp)?\s*([a-z_0-9]+)\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)/i,JN=/[a-z_0-9]+/gi,eS="#pragma main";class tS extends QN{constructor(e){const{type:t,inputs:r,name:s,precision:i,inputsCode:n,blockCode:a,headerCode:o}=(e=>{const t=(e=e.trim()).indexOf(eS),r=-1!==t?e.slice(t+12):e,s=r.match(ZN);if(null!==s&&5===s.length){const i=s[4],n=[];let a=null;for(;null!==(a=JN.exec(i));)n.push(a);const o=[];let u=0;for(;u{const r=this.backend.createNodeBuilder(e.object,this.renderer);return r.scene=e.scene,r.material=t,r.camera=e.camera,r.context.material=t,r.lightsNode=e.lightsNode,r.environmentNode=this.getEnvironmentNode(e.scene),r.fogNode=this.getFogNode(e.scene),r.clippingContext=e.clippingContext,this.renderer.getOutputRenderTarget()&&this.renderer.getOutputRenderTarget().multiview&&r.enableMultiview(),r};let n=t(e.material);try{n.build()}catch(e){n=t(new Zp),n.build(),o("TSL: "+e)}r=this._createNodeBuilderState(n),s.set(i,r)}r.usedTimes++,t.nodeBuilderState=r}return r}delete(e){if(e.isRenderObject){const t=this.get(e).nodeBuilderState;t.usedTimes--,0===t.usedTimes&&this.nodeBuilderCache.delete(this.getForRenderCacheKey(e))}return super.delete(e)}getForCompute(e){const t=this.get(e);let r=t.nodeBuilderState;if(void 0===r){const s=this.backend.createNodeBuilder(e,this.renderer);s.build(),r=this._createNodeBuilderState(s),t.nodeBuilderState=r}return r}_createNodeBuilderState(e){return new iN(e.vertexShader,e.fragmentShader,e.computeShader,e.getAttributesArray(),e.getBindings(),e.updateNodes,e.updateBeforeNodes,e.updateAfterNodes,e.observer,e.transforms)}getEnvironmentNode(e){this.updateEnvironment(e);let t=null;if(e.environmentNode&&e.environmentNode.isNode)t=e.environmentNode;else{const r=this.get(e);r.environmentNode&&(t=r.environmentNode)}return t}getBackgroundNode(e){this.updateBackground(e);let t=null;if(e.backgroundNode&&e.backgroundNode.isNode)t=e.backgroundNode;else{const r=this.get(e);r.backgroundNode&&(t=r.backgroundNode)}return t}getFogNode(e){return this.updateFog(e),e.fogNode||this.get(e).fogNode||null}getCacheKey(e,t){iS[0]=e,iS[1]=t;const r=this.renderer.info.calls,s=this.callHashCache.get(iS)||{};if(s.callId!==r){const i=this.getEnvironmentNode(e),n=this.getFogNode(e);t&&nS.push(t.getCacheKey(!0)),i&&nS.push(i.getCacheKey()),n&&nS.push(n.getCacheKey()),nS.push(this.renderer.getOutputRenderTarget()&&this.renderer.getOutputRenderTarget().multiview?1:0),nS.push(this.renderer.shadowMap.enabled?1:0),nS.push(this.renderer.shadowMap.type),s.callId=r,s.cacheKey=Is(nS),this.callHashCache.set(iS,s),nS.length=0}return iS[0]=null,iS[1]=null,s.cacheKey}get isToneMappingState(){return!this.renderer.getRenderTarget()}updateBackground(e){const t=this.get(e),r=e.background;if(r){const s=0===e.backgroundBlurriness&&t.backgroundBlurriness>0||e.backgroundBlurriness>0&&0===t.backgroundBlurriness;if(t.background!==r||s){const i=this.getCacheNode("background",r,()=>{if(!0===r.isCubeTexture||r.mapping===le||r.mapping===de||r.mapping===Ee){if(e.backgroundBlurriness>0||r.mapping===Ee)return ff(r);{let e;return e=!0===r.isCubeTexture?gc(r):Pl(r),pg(e)}}if(!0===r.isTexture)return Pl(r,ql.flipY()).setUpdateMatrix(!0);!0!==r.isColor&&o("WebGPUNodes: Unsupported background configuration.",r)},s);t.backgroundNode=i,t.background=r,t.backgroundBlurriness=e.backgroundBlurriness}}else t.backgroundNode&&(delete t.backgroundNode,delete t.background)}getCacheNode(e,t,r,s=!1){const i=this.cacheLib[e]||(this.cacheLib[e]=new WeakMap);let n=i.get(t);return(void 0===n||s)&&(n=r(),i.set(t,n)),n}updateFog(e){const t=this.get(e),r=e.fog;if(r){if(t.fog!==r){const e=this.getCacheNode("fog",r,()=>{if(r.isFogExp2){const e=yc("color","color",r).setGroup(ba),t=yc("density","float",r).setGroup(ba);return lT(e,oT(t))}if(r.isFog){const e=yc("color","color",r).setGroup(ba),t=yc("near","float",r).setGroup(ba),s=yc("far","float",r).setGroup(ba);return lT(e,aT(t,s))}o("Renderer: Unsupported fog configuration.",r)});t.fogNode=e,t.fog=r}}else delete t.fogNode,delete t.fog}updateEnvironment(e){const t=this.get(e),r=e.environment;if(r){if(t.environment!==r){const e=this.getCacheNode("environment",r,()=>!0===r.isCubeTexture?gc(r):!0===r.isTexture?Pl(r):void o("Nodes: Unsupported environment configuration.",r));t.environmentNode=e,t.environment=r}}else t.environmentNode&&(delete t.environmentNode,delete t.environment)}getNodeFrame(e=this.renderer,t=null,r=null,s=null,i=null){const n=this.nodeFrame;return n.renderer=e,n.scene=t,n.object=r,n.camera=s,n.material=i,n}getNodeFrameForRender(e){return this.getNodeFrame(e.renderer,e.scene,e.object,e.camera,e.material)}getOutputCacheKey(){const e=this.renderer;return e.toneMapping+","+e.currentColorSpace+","+e.xr.isPresenting}hasOutputChange(e){return sS.get(e)!==this.getOutputCacheKey()}getOutputNode(e){const t=this.renderer,r=this.getOutputCacheKey(),s=e.isArrayTexture?mx(e,vn(ql,Gl("gl_ViewID_OVR"))).renderOutput(t.toneMapping,t.currentColorSpace):Pl(e,ql).renderOutput(t.toneMapping,t.currentColorSpace);return sS.set(e,r),s}updateBefore(e){const t=e.getNodeBuilderState();for(const r of t.updateBeforeNodes)this.getNodeFrameForRender(e).updateBeforeNode(r)}updateAfter(e){const t=e.getNodeBuilderState();for(const r of t.updateAfterNodes)this.getNodeFrameForRender(e).updateAfterNode(r)}updateForCompute(e){const t=this.getNodeFrame(),r=this.getForCompute(e);for(const e of r.updateNodes)t.updateNode(e)}updateForRender(e){const t=this.getNodeFrameForRender(e),r=e.getNodeBuilderState();for(const e of r.updateNodes)t.updateNode(e)}needsRefresh(e){const t=this.getNodeFrameForRender(e);return e.getMonitor().needsRefresh(e,t)}dispose(){super.dispose(),this.nodeFrame=new UN,this.nodeBuilderCache=new Map,this.cacheLib={}}}const oS=new je;class uS{constructor(e=null){this.version=0,this.clipIntersection=null,this.cacheKey="",this.shadowPass=!1,this.viewNormalMatrix=new n,this.clippingGroupContexts=new WeakMap,this.intersectionPlanes=[],this.unionPlanes=[],this.parentVersion=null,null!==e&&(this.viewNormalMatrix=e.viewNormalMatrix,this.clippingGroupContexts=e.clippingGroupContexts,this.shadowPass=e.shadowPass,this.viewMatrix=e.viewMatrix)}projectPlanes(e,t,r){const s=e.length;for(let i=0;i0,alpha:!0,depth:t.depth,stencil:t.stencil,framebufferScaleFactor:this.getFramebufferScaleFactor()},i=new XRWebGLLayer(e,s,r);this._glBaseLayer=i,e.updateRenderState({baseLayer:i}),t.setPixelRatio(1),t._setXRLayerSize(i.framebufferWidth,i.framebufferHeight),this._xrRenderTarget=new fS(i.framebufferWidth,i.framebufferHeight,{format:Re,type:Ge,colorSpace:t.outputColorSpace,stencilBuffer:t.stencil,resolveDepthBuffer:!1===i.ignoreDepthValues,resolveStencilBuffer:!1===i.ignoreDepthValues}),this._xrRenderTarget._isOpaqueFramebuffer=!0,this._referenceSpace=await e.requestReferenceSpace(this.getReferenceSpaceType())}this.setFoveation(this.getFoveation()),t._animation.setAnimationLoop(this._onAnimationFrame),t._animation.setContext(e),t._animation.start(),this.isPresenting=!0,this.dispatchEvent({type:"sessionstart"})}}updateCamera(e){const t=this._session;if(null===t)return;const r=e.near,s=e.far,i=this._cameraXR,n=this._cameraL,a=this._cameraR;i.near=a.near=n.near=r,i.far=a.far=n.far=s,i.isMultiViewCamera=this._useMultiview,this._currentDepthNear===i.near&&this._currentDepthFar===i.far||(t.updateRenderState({depthNear:i.near,depthFar:i.far}),this._currentDepthNear=i.near,this._currentDepthFar=i.far),i.layers.mask=6|e.layers.mask,n.layers.mask=-5&i.layers.mask,a.layers.mask=-3&i.layers.mask;const o=e.parent,u=i.cameras;TS(i,o);for(let e=0;e=0&&(r[n]=null,t[n].disconnect(i))}for(let s=0;s=r.length){r.push(i),n=e;break}if(null===r[e]){r[e]=i,n=e;break}}if(-1===n)break}const a=t[n];a&&a.connect(i)}}function SS(e){return"quad"===e.type?this._glBinding.createQuadLayer({transform:new XRRigidTransform(e.translation,e.quaternion),width:e.width/2,height:e.height/2,space:this._referenceSpace,viewPixelWidth:e.pixelwidth,viewPixelHeight:e.pixelheight,clearOnAccess:!1}):this._glBinding.createCylinderLayer({transform:new XRRigidTransform(e.translation,e.quaternion),radius:e.radius,centralAngle:e.centralAngle,aspectRatio:e.aspectRatio,space:this._referenceSpace,viewPixelWidth:e.pixelwidth,viewPixelHeight:e.pixelheight,clearOnAccess:!1})}function RS(e,t){if(void 0===t)return;const r=this._cameraXR,i=this._renderer,n=i.backend,a=this._glBaseLayer,o=this.getReferenceSpace(),u=t.getViewerPose(o);if(this._xrFrame=t,null!==u){const e=u.views;null!==this._glBaseLayer&&n.setXRTarget(a.framebuffer);let t=!1;e.length!==r.cameras.length&&(r.cameras.length=0,t=!0);for(let i=0;i{await this.compileAsync(e,t);const s=this._renderLists.get(e,t),i=this._renderContexts.get(this._renderTarget,this._mrt),n=e.overrideMaterial||r.material,a=this._objects.get(r,n,e,t,s.lightsNode,i,i.clippingContext),{fragmentShader:o,vertexShader:u}=a.getNodeBuilderState();return{fragmentShader:o,vertexShader:u}}}}async init(){return null!==this._initPromise||(this._initPromise=new Promise(async(e,t)=>{let r=this.backend;try{await r.init(this)}catch(e){if(null===this._getFallback)return void t(e);try{this.backend=r=this._getFallback(e),await r.init(this)}catch(e){return void t(e)}}this._nodes=new aS(this,r),this._animation=new Yf(this,this._nodes,this.info),this._attributes=new uy(r),this._background=new tN(this,this._nodes),this._geometries=new cy(this._attributes,this.info),this._textures=new Fy(this,r,this.info),this._pipelines=new by(r,this._nodes),this._bindings=new xy(r,this._nodes,this._textures,this._attributes,this._pipelines,this.info),this._objects=new ty(this,this._nodes,this._geometries,this._pipelines,this._bindings,this.info),this._renderLists=new Ry(this.lighting),this._bundles=new cS,this._renderContexts=new Cy,this._animation.start(),this._initialized=!0,this._inspector.init(),e(this)})),this._initPromise}get domElement(){return this._canvasTarget.domElement}get coordinateSystem(){return this.backend.coordinateSystem}async compileAsync(e,t,r=null){if(!0===this._isDeviceLost)return;!1===this._initialized&&await this.init();const s=this._nodes.nodeFrame,i=s.renderId,n=this._currentRenderContext,a=this._currentRenderObjectFunction,o=this._handleObjectFunction,u=this._compilationPromises,l=!0===e.isScene?e:AS;null===r&&(r=e);const d=this._renderTarget,c=this._renderContexts.get(d,this._mrt),h=this._activeMipmapLevel,p=[];this._currentRenderContext=c,this._currentRenderObjectFunction=this.renderObject,this._handleObjectFunction=this._createObjectPipeline,this._compilationPromises=p,s.renderId++,s.update(),c.depth=this.depth,c.stencil=this.stencil,c.clippingContext||(c.clippingContext=new uS),c.clippingContext.updateGlobal(l,t),l.onBeforeRender(this,e,t,d);const g=this._renderLists.get(e,t);if(g.begin(),this._projectObject(e,t,0,g,c.clippingContext),r!==e&&r.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&g.pushLight(e)}),g.finish(),null!==d){this._textures.updateRenderTarget(d,h);const e=this._textures.get(d);c.textures=e.textures,c.depthTexture=e.depthTexture}else c.textures=null,c.depthTexture=null;r!==e?this._background.update(r,g,c):this._background.update(l,g,c);const m=g.opaque,f=g.transparent,y=g.transparentDoublePass,b=g.lightsNode;!0===this.opaque&&m.length>0&&this._renderObjects(m,t,l,b),!0===this.transparent&&f.length>0&&this._renderTransparents(f,y,t,l,b),s.renderId=i,this._currentRenderContext=n,this._currentRenderObjectFunction=a,this._handleObjectFunction=o,this._compilationPromises=u,await Promise.all(p)}async renderAsync(e,t){v('Renderer: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.render(e,t)}async waitForGPU(){o("Renderer: waitForGPU() has been removed. Read https://github.com/mrdoob/three.js/issues/32012 for more information.")}set inspector(e){null!==this._inspector&&this._inspector.setRenderer(null),this._inspector=e,this._inspector.setRenderer(this)}get inspector(){return this._inspector}set highPrecision(e){const t=this.contextNode.value;!0===e?(t.modelViewMatrix=Cd,t.modelNormalViewMatrix=Md):this.highPrecision&&(delete t.modelViewMatrix,delete t.modelNormalViewMatrix)}get highPrecision(){const e=this.contextNode.value;return e.modelViewMatrix===Cd&&e.modelNormalViewMatrix===Md}setMRT(e){return this._mrt=e,this}getMRT(){return this._mrt}getOutputBufferType(){return this._outputBufferType}getColorBufferType(){return v('Renderer: ".getColorBufferType()" has been renamed to ".getOutputBufferType()".'),this.getOutputBufferType()}_onDeviceLost(e){let t=`THREE.WebGPURenderer: ${e.api} Device Lost:\n\nMessage: ${e.message}`;e.reason&&(t+=`\nReason: ${e.reason}`),o(t),this._isDeviceLost=!0}_renderBundle(e,t,r){const{bundleGroup:s,camera:i,renderList:n}=e,a=this._currentRenderContext,o=this._bundles.get(s,i),u=this.backend.get(o);void 0===u.renderContexts&&(u.renderContexts=new Set);const l=s.version!==u.version,d=!1===u.renderContexts.has(a)||l;if(u.renderContexts.add(a),d){this.backend.beginBundle(a),(void 0===u.renderObjects||l)&&(u.renderObjects=[]),this._currentRenderBundle=o;const{transparentDoublePass:e,transparent:d,opaque:c}=n;!0===this.opaque&&c.length>0&&this._renderObjects(c,i,t,r),!0===this.transparent&&d.length>0&&this._renderTransparents(d,e,i,t,r),this._currentRenderBundle=null,this.backend.finishBundle(a,o),u.version=s.version}else{const{renderObjects:e}=u;for(let t=0,r=e.length;t>=h,g.viewportValue.height>>=h,g.viewportValue.minDepth=_,g.viewportValue.maxDepth=v,g.viewport=!1===g.viewportValue.equals(CS),g.scissorValue.copy(x).multiplyScalar(T).floor(),g.scissor=y._scissorTest&&!1===g.scissorValue.equals(CS),g.scissorValue.width>>=h,g.scissorValue.height>>=h,g.clippingContext||(g.clippingContext=new uS),g.clippingContext.updateGlobal(l,t),l.onBeforeRender(this,e,t,p);const N=t.isArrayCamera?FS:MS;t.isArrayCamera||(LS.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),N.setFromProjectionMatrix(LS,t.coordinateSystem,t.reversedDepth));const S=this._renderLists.get(e,t);if(S.begin(),this._projectObject(e,t,0,S,g.clippingContext),S.finish(),!0===this.sortObjects&&S.sort(this._opaqueSort,this._transparentSort),null!==p){this._textures.updateRenderTarget(p,h);const e=this._textures.get(p);g.textures=e.textures,g.depthTexture=e.depthTexture,g.width=e.width,g.height=e.height,g.renderTarget=p,g.depth=p.depthBuffer,g.stencil=p.stencilBuffer}else g.textures=null,g.depthTexture=null,g.width=wS.width,g.height=wS.height,g.depth=this.depth,g.stencil=this.stencil;g.width>>=h,g.height>>=h,g.activeCubeFace=c,g.activeMipmapLevel=h,g.occlusionQueryCount=S.occlusionQueryCount,g.scissorValue.max(PS.set(0,0,0,0)),g.scissorValue.x+g.scissorValue.width>g.width&&(g.scissorValue.width=Math.max(g.width-g.scissorValue.x,0)),g.scissorValue.y+g.scissorValue.height>g.height&&(g.scissorValue.height=Math.max(g.height-g.scissorValue.y,0)),this._background.update(l,S,g),g.camera=t,this.backend.beginRender(g);const{bundles:R,lightsNode:E,transparentDoublePass:A,transparent:w,opaque:C}=S;return R.length>0&&this._renderBundles(R,l,E),!0===this.opaque&&C.length>0&&this._renderObjects(C,t,l,E),!0===this.transparent&&w.length>0&&this._renderTransparents(w,A,t,l,E),this.backend.finishRender(g),i.renderId=n,this._currentRenderContext=a,this._currentRenderObjectFunction=o,this._handleObjectFunction=u,this._callDepth--,null!==s&&(this.setRenderTarget(d,c,h),this._renderOutput(p)),l.onAfterRender(this,e,t,p),this.inspector.finishRender(this.backend.getTimestampUID(g)),g}_setXRLayerSize(e,t){this._canvasTarget._width=e,this._canvasTarget._height=t,this.setViewport(0,0,e,t)}_renderOutput(e){const t=this._quad;this._nodes.hasOutputChange(e.texture)&&(t.material.fragmentNode=this._nodes.getOutputNode(e.texture),t.material.needsUpdate=!0);const r=this.autoClear,s=this.xr.enabled;this.autoClear=!1,this.xr.enabled=!1,this._renderScene(t,t.camera,!1),this.autoClear=r,this.xr.enabled=s}getMaxAnisotropy(){return this.backend.getMaxAnisotropy()}getActiveCubeFace(){return this._activeCubeFace}getActiveMipmapLevel(){return this._activeMipmapLevel}async setAnimationLoop(e){!1===this._initialized&&await this.init(),this._animation.setAnimationLoop(e)}getAnimationLoop(){return this._animation.getAnimationLoop()}async getArrayBufferAsync(e){return await this.backend.getArrayBufferAsync(e)}getContext(){return this.backend.getContext()}getPixelRatio(){return this._canvasTarget.getPixelRatio()}getDrawingBufferSize(e){return this._canvasTarget.getDrawingBufferSize(e)}getSize(e){return this._canvasTarget.getSize(e)}setPixelRatio(e=1){this._canvasTarget.setPixelRatio(e)}setDrawingBufferSize(e,t,r){this.xr&&this.xr.isPresenting||this._canvasTarget.setDrawingBufferSize(e,t,r)}setSize(e,t,r=!0){this.xr&&this.xr.isPresenting||this._canvasTarget.setSize(e,t,r)}setOpaqueSort(e){this._opaqueSort=e}setTransparentSort(e){this._transparentSort=e}getScissor(e){return this._canvasTarget.getScissor(e)}setScissor(e,t,r,s){this._canvasTarget.setScissor(e,t,r,s)}getScissorTest(){return this._canvasTarget.getScissorTest()}setScissorTest(e){this._canvasTarget.setScissorTest(e),this.backend.setScissorTest(e)}getViewport(e){return this._canvasTarget.getViewport(e)}setViewport(e,t,r,s,i=0,n=1){this._canvasTarget.setViewport(e,t,r,s,i,n)}getClearColor(e){return e.copy(this._clearColor)}setClearColor(e,t=1){this._clearColor.set(e),this._clearColor.a=t}getClearAlpha(){return this._clearColor.a}setClearAlpha(e){this._clearColor.a=e}getClearDepth(){return this._clearDepth}setClearDepth(e){this._clearDepth=e}getClearStencil(){return this._clearStencil}setClearStencil(e){this._clearStencil=e}isOccluded(e){const t=this._currentRenderContext;return t&&this.backend.isOccluded(t,e)}clear(e=!0,t=!0,r=!0){if(!1===this._initialized)throw new Error('Renderer: .clear() called before the backend is initialized. Use "await renderer.init();" before before using this method.');const s=this._renderTarget||this._getFrameBufferTarget();let i=null;if(null!==s){this._textures.updateRenderTarget(s);const e=this._textures.get(s);i=this._renderContexts.get(s),i.textures=e.textures,i.depthTexture=e.depthTexture,i.width=e.width,i.height=e.height,i.renderTarget=s,i.depth=s.depthBuffer,i.stencil=s.stencilBuffer;const t=this.backend.getClearColor();i.clearColorValue.r=t.r,i.clearColorValue.g=t.g,i.clearColorValue.b=t.b,i.clearColorValue.a=t.a,i.activeCubeFace=this.getActiveCubeFace(),i.activeMipmapLevel=this.getActiveMipmapLevel()}this.backend.clear(e,t,r,i),null!==s&&null===this._renderTarget&&this._renderOutput(s)}clearColor(){this.clear(!0,!1,!1)}clearDepth(){this.clear(!1,!0,!1)}clearStencil(){this.clear(!1,!1,!0)}async clearAsync(e=!0,t=!0,r=!0){v('Renderer: "clearAsync()" has been deprecated. Use "clear()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.clear(e,t,r)}async clearColorAsync(){v('Renderer: "clearColorAsync()" has been deprecated. Use "clearColor()" and "await renderer.init();" when creating the renderer.'),this.clear(!0,!1,!1)}async clearDepthAsync(){v('Renderer: "clearDepthAsync()" has been deprecated. Use "clearDepth()" and "await renderer.init();" when creating the renderer.'),this.clear(!1,!0,!1)}async clearStencilAsync(){v('Renderer: "clearStencilAsync()" has been deprecated. Use "clearStencil()" and "await renderer.init();" when creating the renderer.'),this.clear(!1,!1,!0)}get needsFrameBufferTarget(){const e=this.currentToneMapping!==m,t=this.currentColorSpace!==p.workingColorSpace;return e||t}get samples(){return this._samples}get currentSamples(){let e=this._samples;return null!==this._renderTarget?e=this._renderTarget.samples:this.needsFrameBufferTarget&&(e=0),e}get currentToneMapping(){return this.isOutputTarget?this.toneMapping:m}get currentColorSpace(){return this.isOutputTarget?this.outputColorSpace:p.workingColorSpace}get isOutputTarget(){return this._renderTarget===this._outputRenderTarget||null===this._renderTarget}dispose(){!0===this._initialized&&(this.info.dispose(),this.backend.dispose(),this._animation.dispose(),this._objects.dispose(),this._geometries.dispose(),this._pipelines.dispose(),this._nodes.dispose(),this._bindings.dispose(),this._renderLists.dispose(),this._renderContexts.dispose(),this._textures.dispose(),null!==this._frameBufferTarget&&this._frameBufferTarget.dispose(),Object.values(this.backend.timestampQueryPool).forEach(e=>{null!==e&&e.dispose()})),this.setRenderTarget(null),this.setAnimationLoop(null)}setRenderTarget(e,t=0,r=0){this._renderTarget=e,this._activeCubeFace=t,this._activeMipmapLevel=r}getRenderTarget(){return this._renderTarget}setOutputRenderTarget(e){this._outputRenderTarget=e}getOutputRenderTarget(){return this._outputRenderTarget}setCanvasTarget(e){this._canvasTarget.removeEventListener("resize",this._onCanvasTargetResize),this._canvasTarget=e,this._canvasTarget.addEventListener("resize",this._onCanvasTargetResize)}getCanvasTarget(){return this._canvasTarget}_resetXRState(){this.backend.setXRTarget(null),this.setOutputRenderTarget(null),this.setRenderTarget(null),this._frameBufferTarget.dispose(),this._frameBufferTarget=null}setRenderObjectFunction(e){this._renderObjectFunction=e}getRenderObjectFunction(){return this._renderObjectFunction}compute(e,t=null){if(!0===this._isDeviceLost)return;if(!1===this._initialized)return d("Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead."),this.computeAsync(e,t);const r=this._nodes.nodeFrame,s=r.renderId;this.info.calls++,this.info.compute.calls++,this.info.compute.frameCalls++,r.renderId=this.info.calls,this.backend.updateTimeStampUID(e),this.inspector.beginCompute(this.backend.getTimestampUID(e),e);const i=this.backend,n=this._pipelines,a=this._bindings,o=this._nodes,u=Array.isArray(e)?e:[e];if(void 0===u[0]||!0!==u[0].isComputeNode)throw new Error("THREE.Renderer: .compute() expects a ComputeNode.");i.beginCompute(e);for(const r of u){if(!1===n.has(r)){const e=()=>{r.removeEventListener("dispose",e),n.delete(r),a.deleteForCompute(r),o.delete(r)};r.addEventListener("dispose",e);const t=r.onInitFunction;null!==t&&t.call(r,{renderer:this})}o.updateForCompute(r),a.updateForCompute(r);const s=a.getForCompute(r),u=n.getForCompute(r,s);i.compute(e,r,s,u,t)}i.finishCompute(e),r.renderId=s,this.inspector.finishCompute(this.backend.getTimestampUID(e))}async computeAsync(e,t=null){!1===this._initialized&&await this.init(),this.compute(e,t)}async hasFeatureAsync(e){return v('Renderer: "hasFeatureAsync()" has been deprecated. Use "hasFeature()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.hasFeature(e)}async resolveTimestampsAsync(e="render"){return!1===this._initialized&&await this.init(),this.backend.resolveTimestampsAsync(e)}hasFeature(e){if(!1===this._initialized)throw new Error('Renderer: .hasFeature() called before the backend is initialized. Use "await renderer.init();" before before using this method.');return this.backend.hasFeature(e)}hasInitialized(){return this._initialized}async initTextureAsync(e){v('Renderer: "initTextureAsync()" has been deprecated. Use "initTexture()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.initTexture(e)}initTexture(e){if(!1===this._initialized)throw new Error('Renderer: .initTexture() called before the backend is initialized. Use "await renderer.init();" before before using this method.');this._textures.updateTexture(e)}copyFramebufferToTexture(e,t=null){if(null!==t)if(t.isVector2)t=PS.set(t.x,t.y,e.image.width,e.image.height).floor();else{if(!t.isVector4)return void o("Renderer.copyFramebufferToTexture: Invalid rectangle.");t=PS.copy(t).floor()}else t=PS.set(0,0,e.image.width,e.image.height);let r,s=this._currentRenderContext;null!==s?r=s.renderTarget:(r=this._renderTarget||this._getFrameBufferTarget(),null!==r&&(this._textures.updateRenderTarget(r),s=this._textures.get(r))),this._textures.updateTexture(e,{renderTarget:r}),this.backend.copyFramebufferToTexture(e,s,t),this._inspector.copyFramebufferToTexture(e)}copyTextureToTexture(e,t,r=null,s=null,i=0,n=0){this._textures.updateTexture(e),this._textures.updateTexture(t),this.backend.copyTextureToTexture(e,t,r,s,i,n),this._inspector.copyTextureToTexture(e,t)}async readRenderTargetPixelsAsync(e,t,r,s,i,n=0,a=0){return this.backend.copyTextureToBuffer(e.textures[n],t,r,s,i,a)}_projectObject(e,t,r,s,i){if(!1===e.visible)return;if(e.layers.test(t.layers))if(e.isGroup)r=e.renderOrder,e.isClippingGroup&&e.enabled&&(i=i.getGroupContext(e));else if(e.isLOD)!0===e.autoUpdate&&e.update(t);else if(e.isLight)s.pushLight(e);else if(e.isSprite){const n=t.isArrayCamera?FS:MS;if(!e.frustumCulled||n.intersectsSprite(e,t)){!0===this.sortObjects&&PS.setFromMatrixPosition(e.matrixWorld).applyMatrix4(LS);const{geometry:t,material:n}=e;n.visible&&s.push(e,t,n,r,PS.z,null,i)}}else if(e.isLineLoop)o("Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.");else if(e.isMesh||e.isLine||e.isPoints){const n=t.isArrayCamera?FS:MS;if(!e.frustumCulled||n.intersectsObject(e,t)){const{geometry:t,material:n}=e;if(!0===this.sortObjects&&(null===t.boundingSphere&&t.computeBoundingSphere(),PS.copy(t.boundingSphere.center).applyMatrix4(e.matrixWorld).applyMatrix4(LS)),Array.isArray(n)){const a=t.groups;for(let o=0,u=a.length;o0){for(const{material:e}of t)e.side=M;this._renderObjects(t,r,s,i,"backSide");for(const{material:e}of t)e.side=ct;this._renderObjects(e,r,s,i);for(const{material:e}of t)e.side=F}else this._renderObjects(e,r,s,i)}_renderObjects(e,t,r,s,i=null){for(let n=0,a=e.length;n(t.not().discard(),e))(u)}}e.depthNode&&e.depthNode.isNode&&(l=e.depthNode),e.castShadowPositionNode&&e.castShadowPositionNode.isNode?o=e.castShadowPositionNode:e.positionNode&&e.positionNode.isNode&&(o=e.positionNode),r={version:t,colorNode:u,depthNode:l,positionNode:o},this._cacheShadowNodes.set(e,r)}return r}renderObject(e,t,r,s,i,n,a,o=null,u=null){let l,d,c,h,p=!1;if(e.onBeforeRender(this,t,r,s,i,n),!0===i.allowOverride&&null!==t.overrideMaterial){const e=t.overrideMaterial;if(p=!0,l=t.overrideMaterial.colorNode,d=t.overrideMaterial.depthNode,c=t.overrideMaterial.positionNode,h=t.overrideMaterial.side,i.positionNode&&i.positionNode.isNode&&(e.positionNode=i.positionNode),e.alphaTest=i.alphaTest,e.alphaMap=i.alphaMap,e.transparent=i.transparent||i.transmission>0||i.transmissionNode&&i.transmissionNode.isNode||i.backdropNode&&i.backdropNode.isNode,e.isShadowPassMaterial){const{colorNode:t,depthNode:r,positionNode:s}=this._getShadowNodes(i);this.shadowMap.type===Ze?e.side=null!==i.shadowSide?i.shadowSide:i.side:e.side=null!==i.shadowSide?i.shadowSide:BS[i.side],null!==t&&(e.colorNode=t),null!==r&&(e.depthNode=r),null!==s&&(e.positionNode=s)}i=e}!0===i.transparent&&i.side===F&&!1===i.forceSinglePass?(i.side=M,this._handleObjectFunction(e,i,t,r,a,n,o,"backSide"),i.side=ct,this._handleObjectFunction(e,i,t,r,a,n,o,u),i.side=F):this._handleObjectFunction(e,i,t,r,a,n,o,u),p&&(t.overrideMaterial.colorNode=l,t.overrideMaterial.depthNode=d,t.overrideMaterial.positionNode=c,t.overrideMaterial.side=h),e.onAfterRender(this,t,r,s,i,n)}hasCompatibility(e){return this.backend.hasCompatibility(e)}_renderObjectDirect(e,t,r,s,i,n,a,o){const u=this._objects.get(e,t,r,s,i,this._currentRenderContext,a,o);u.drawRange=e.geometry.drawRange,u.group=n;const l=this._nodes.needsRefresh(u);if(l&&(this._nodes.updateBefore(u),this._geometries.updateForRender(u),this._nodes.updateForRender(u),this._bindings.updateForRender(u)),this._pipelines.updateForRender(u),null!==this._currentRenderBundle){this.backend.get(this._currentRenderBundle).renderObjects.push(u),u.bundle=this._currentRenderBundle.bundleGroup}this.backend.draw(u,this.info),l&&this._nodes.updateAfter(u)}_createObjectPipeline(e,t,r,s,i,n,a,o){const u=this._objects.get(e,t,r,s,i,this._currentRenderContext,a,o);u.drawRange=e.geometry.drawRange,u.group=n,this._nodes.updateBefore(u),this._geometries.updateForRender(u),this._nodes.updateForRender(u),this._bindings.updateForRender(u),this._pipelines.getForRender(u,this._compilationPromises),this._nodes.updateAfter(u)}_onCanvasTargetResize(){this._initialized&&this.backend.updateSize()}get compile(){return this.compileAsync}}class US{constructor(e=""){this.name=e,this.visibility=0}setVisibility(e){this.visibility|=e}getVisibility(){return this.visibility}clone(){return Object.assign(new this.constructor,this)}}class IS extends US{constructor(e,t=null){super(e),this.isBuffer=!0,this.bytesPerElement=Float32Array.BYTES_PER_ELEMENT,this._buffer=t,this._updateRanges=[]}get updateRanges(){return this._updateRanges}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}get byteLength(){return(e=this._buffer.byteLength)+(oy-e%oy)%oy;var e}get buffer(){return this._buffer}update(){return!0}}class OS extends IS{constructor(e,t=null){super(e,t),this.isUniformBuffer=!0}}let VS=0;class kS extends OS{constructor(e,t){super("UniformBuffer_"+VS++,e?e.value:null),this.nodeUniform=e,this.groupNode=t,this.isNodeUniformBuffer=!0}set updateRanges(e){this.nodeUniform.updateRanges=e}get updateRanges(){return this.nodeUniform.updateRanges}addUpdateRange(e,t){this.nodeUniform.addUpdateRange(e,t)}clearUpdateRanges(){this.nodeUniform.clearUpdateRanges()}get buffer(){return this.nodeUniform.value}}class GS extends OS{constructor(e){super(e),this.isUniformsGroup=!0,this._values=null,this.uniforms=[],this._updateRangeCache=new Map}addUniformUpdateRange(e){const t=e.index;if(!0!==this._updateRangeCache.has(t)){const r=this.updateRanges,s={start:e.offset,count:e.itemSize};r.push(s),this._updateRangeCache.set(t,s)}}clearUpdateRanges(){this._updateRangeCache.clear(),super.clearUpdateRanges()}addUniform(e){return this.uniforms.push(e),this}removeUniform(e){const t=this.uniforms.indexOf(e);return-1!==t&&this.uniforms.splice(t,1),this}get values(){return null===this._values&&(this._values=Array.from(this.buffer)),this._values}get buffer(){let e=this._buffer;if(null===e){const t=this.byteLength;e=new Float32Array(new ArrayBuffer(t)),this._buffer=e}return e}get byteLength(){const e=this.bytesPerElement;let t=0;for(let r=0,s=this.uniforms.length;r{this.generation=null,this.version=0},this.texture=t,this.version=t?t.version:0,this.generation=null,this.samplerKey="",this.isSampler=!0}set texture(e){this._texture!==e&&(this._texture&&this._texture.removeEventListener("dispose",this._onTextureDispose),this._texture=e,this.generation=null,this.version=0,this._texture&&this._texture.addEventListener("dispose",this._onTextureDispose))}get texture(){return this._texture}update(){const{texture:e,version:t}=this;return t!==e.version&&(this.version=e.version,!0)}clone(){const e=super.clone();return e._texture=null,e._onTextureDispose=()=>{e.generation=null,e.version=0},e.texture=this.texture,e}}let HS=0;class qS extends WS{constructor(e,t){super(e,t),this.id=HS++,this.store=!1,this.mipLevel=0,this.isSampledTexture=!0}}class jS extends qS{constructor(e,t,r,s=null){super(e,t?t.value:null),this.textureNode=t,this.groupNode=r,this.access=s}update(){const{textureNode:e}=this;return this.texture!==e.value?(this.texture=e.value,!0):super.update()}}class XS extends jS{constructor(e,t,r,s=null){super(e,t,r,s),this.isSampledCubeTexture=!0}}class KS extends jS{constructor(e,t,r,s=null){super(e,t,r,s),this.isSampledTexture3D=!0}}const YS={bitcast_int_uint:new Xx("uint tsl_bitcast_int_to_uint ( int x ) { return floatBitsToUint( intBitsToFloat ( x ) ); }"),bitcast_uint_int:new Xx("uint tsl_bitcast_uint_to_int ( uint x ) { return floatBitsToInt( uintBitsToFloat ( x ) ); }")},QS={textureDimensions:"textureSize",equals:"equal",bitcast_float_int:"floatBitsToInt",bitcast_int_float:"intBitsToFloat",bitcast_uint_float:"uintBitsToFloat",bitcast_float_uint:"floatBitsToUint",bitcast_uint_int:"tsl_bitcast_uint_to_int",bitcast_int_uint:"tsl_bitcast_int_to_uint",floatpack_snorm_2x16:"packSnorm2x16",floatpack_unorm_2x16:"packUnorm2x16",floatpack_float16_2x16:"packHalf2x16",floatunpack_snorm_2x16:"unpackSnorm2x16",floatunpack_unorm_2x16:"unpackUnorm2x16",floatunpack_float16_2x16:"unpackHalf2x16"},ZS={low:"lowp",medium:"mediump",high:"highp"},JS={swizzleAssign:!0,storageBuffer:!1},eR={perspective:"smooth",linear:"noperspective"},tR={centroid:"centroid"},rR="\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\nprecision highp sampler3D;\nprecision highp samplerCube;\nprecision highp sampler2DArray;\n\nprecision highp usampler2D;\nprecision highp usampler3D;\nprecision highp usamplerCube;\nprecision highp usampler2DArray;\n\nprecision highp isampler2D;\nprecision highp isampler3D;\nprecision highp isamplerCube;\nprecision highp isampler2DArray;\n\nprecision highp sampler2DShadow;\nprecision highp sampler2DArrayShadow;\nprecision highp samplerCubeShadow;\n";class sR extends DN{constructor(e,t){super(e,t,new rS),this.uniformGroups={},this.transforms=[],this.extensions={},this.builtins={vertex:[],fragment:[],compute:[]}}needsToWorkingColorSpace(e){return!0===e.isVideoTexture&&e.colorSpace!==T}_include(e){const t=YS[e];return t.build(this),this.addInclude(t),t}getMethod(e){return void 0!==YS[e]&&this._include(e),QS[e]||e}getBitcastMethod(e,t){return this.getMethod(`bitcast_${t}_${e}`)}getFloatPackingMethod(e){return this.getMethod(`floatpack_${e}_2x16`)}getFloatUnpackingMethod(e){return this.getMethod(`floatunpack_${e}_2x16`)}getTernary(e,t,r){return`${e} ? ${t} : ${r}`}getOutputStructName(){return""}buildFunctionCode(e){const t=e.layout,r=this.flowShaderNode(e),s=[];for(const e of t.inputs)s.push(this.getType(e.type)+" "+e.name);return`${this.getType(t.type)} ${t.name}( ${s.join(", ")} ) {\n\n\t${r.vars}\n\n${r.code}\n\treturn ${r.result};\n\n}`}setupPBO(e){const t=e.value;if(void 0===t.pbo){const e=t.array,r=t.count*t.itemSize,{itemSize:s}=t,i=t.array.constructor.name.toLowerCase().includes("int");let n=i?Tt:_t;2===s?n=i?Rt:G:3===s?n=i?Et:At:4===s&&(n=i?wt:Re);const a={Float32Array:j,Uint8Array:Ge,Uint16Array:St,Uint32Array:S,Int8Array:Nt,Int16Array:vt,Int32Array:R,Uint8ClampedArray:Ge},o=Math.pow(2,Math.ceil(Math.log2(Math.sqrt(r/s))));let u=Math.ceil(r/s/o);o*u*s0?i:"";t=`${r.name} {\n\t${s} ${e.name}[${n}];\n};\n`}else{const t=e.groupNode.name;if(void 0===s[t]){const e=this.uniformGroups[t];if(void 0!==e){const r=[];for(const t of e.uniforms){const e=t.getType(),s=this.getVectorType(e),i=t.nodeUniform.node.precision;let n=`${s} ${t.name};`;null!==i&&(n=ZS[i]+" "+n),r.push("\t"+n)}s[t]=r}}i=!0}if(!i){const s=e.node.precision;null!==s&&(t=ZS[s]+" "+t),t="uniform "+t,r.push(t)}}let i="";for(const e in s){const t=s[e];i+=this._getGLSLUniformStruct(e,t.join("\n"))+"\n"}return i+=r.join("\n"),i}getTypeFromAttribute(e){let t=super.getTypeFromAttribute(e);if(/^[iu]/.test(t)&&e.gpuType!==R){let r=e;e.isInterleavedBufferAttribute&&(r=e.data);const s=r.array;!1==(s instanceof Uint32Array||s instanceof Int32Array)&&(t=t.slice(1))}return t}getAttributes(e){let t="";if("vertex"===e||"compute"===e){const e=this.getAttributesArray();let r=0;for(const s of e)t+=`layout( location = ${r++} ) in ${s.type} ${s.name};\n`}return t}getStructMembers(e){const t=[];for(const r of e.members)t.push(`\t${r.type} ${r.name};`);return t.join("\n")}getStructs(e){const t=[],r=this.structs[e],s=[];for(const e of r)if(e.output)for(const t of e.members)s.push(`layout( location = ${t.index} ) out ${t.type} ${t.name};`);else{let r="struct "+e.name+" {\n";r+=this.getStructMembers(e),r+="\n};\n",t.push(r)}return 0===s.length&&s.push("layout( location = 0 ) out vec4 fragColor;"),"\n"+s.join("\n")+"\n\n"+t.join("\n")}getVaryings(e){let t="";const r=this.varyings;if("vertex"===e||"compute"===e)for(const s of r){"compute"===e&&(s.needsInterpolation=!0);const r=this.getType(s.type);if(s.needsInterpolation)if(s.interpolationType){t+=`${eR[s.interpolationType]||s.interpolationType} ${tR[s.interpolationSampling]||""} out ${r} ${s.name};\n`}else{t+=`${r.includes("int")||r.includes("uv")||r.includes("iv")?"flat ":""}out ${r} ${s.name};\n`}else t+=`${r} ${s.name};\n`}else if("fragment"===e)for(const e of r)if(e.needsInterpolation){const r=this.getType(e.type);if(e.interpolationType){t+=`${eR[e.interpolationType]||e.interpolationType} ${tR[e.interpolationSampling]||""} in ${r} ${e.name};\n`}else{t+=`${r.includes("int")||r.includes("uv")||r.includes("iv")?"flat ":""}in ${r} ${e.name};\n`}}for(const r of this.builtins[e])t+=`${r};\n`;return t}getVertexIndex(){return"uint( gl_VertexID )"}getInstanceIndex(){return"uint( gl_InstanceID )"}getInvocationLocalIndex(){return`uint( gl_InstanceID ) % ${this.object.workgroupSize.reduce((e,t)=>e*t,1)}u`}getSubgroupSize(){o("GLSLNodeBuilder: WebGLBackend does not support the subgroupSize node")}getInvocationSubgroupIndex(){o("GLSLNodeBuilder: WebGLBackend does not support the invocationSubgroupIndex node")}getSubgroupIndex(){o("GLSLNodeBuilder: WebGLBackend does not support the subgroupIndex node")}getDrawIndex(){return this.renderer.backend.extensions.has("WEBGL_multi_draw")?"uint( gl_DrawID )":null}getFrontFacing(){return"gl_FrontFacing"}getFragCoord(){return"gl_FragCoord.xy"}getFragDepth(){return"gl_FragDepth"}enableExtension(e,t,r=this.shaderStage){const s=this.extensions[r]||(this.extensions[r]=new Map);!1===s.has(e)&&s.set(e,{name:e,behavior:t})}getExtensions(e){const t=[];if("vertex"===e){const t=this.renderer.backend.extensions;this.object.isBatchedMesh&&t.has("WEBGL_multi_draw")&&this.enableExtension("GL_ANGLE_multi_draw","require",e)}const r=this.extensions[e];if(void 0!==r)for(const{name:e,behavior:s}of r.values())t.push(`#extension ${e} : ${s}`);return t.join("\n")}getClipDistance(){return"gl_ClipDistance"}isAvailable(e){let t=JS[e];if(void 0===t){let r;switch(t=!1,e){case"float32Filterable":r="OES_texture_float_linear";break;case"clipDistance":r="WEBGL_clip_cull_distance"}if(void 0!==r){const e=this.renderer.backend.extensions;e.has(r)&&(e.get(r),t=!0)}JS[e]=t}return t}isFlipY(){return!0}enableHardwareClipping(e){this.enableExtension("GL_ANGLE_clip_cull_distance","require"),this.builtins.vertex.push(`out float gl_ClipDistance[ ${e} ]`)}enableMultiview(){this.enableExtension("GL_OVR_multiview2","require","fragment"),this.enableExtension("GL_OVR_multiview2","require","vertex"),this.builtins.vertex.push("layout(num_views = 2) in")}registerTransform(e,t){this.transforms.push({varyingName:e,attributeNode:t})}getTransforms(){const e=this.transforms;let t="";for(let r=0;r0&&(r+="\n"),r+=`\t// flow -> ${n}\n\t`),r+=`${s.code}\n\t`,e===i&&"compute"!==t&&(r+="// result\n\t","vertex"===t?(r+="gl_Position = ",r+=`${s.result};`):"fragment"===t&&(e.outputNode.isOutputStructNode||(r+="fragColor = ",r+=`${s.result};`)))}const n=e[t];n.extensions=this.getExtensions(t),n.uniforms=this.getUniforms(t),n.attributes=this.getAttributes(t),n.varyings=this.getVaryings(t),n.vars=this.getVars(t),n.structs=this.getStructs(t),n.codes=this.getCodes(t),n.transforms=this.getTransforms(t),n.flow=r}null!==this.material?(this.vertexShader=this._getGLSLVertexCode(e.vertex),this.fragmentShader=this._getGLSLFragmentCode(e.fragment)):this.computeShader=this._getGLSLVertexCode(e.compute)}getUniformFromNode(e,t,r,s=null){const i=super.getUniformFromNode(e,t,r,s),n=this.getDataFromNode(e,r,this.globalCache);let a=n.uniformGPU;if(void 0===a){const s=e.groupNode,o=s.name,u=this.getBindGroupArray(o,r);if("texture"===t)a=new jS(i.name,i.node,s),u.push(a);else if("cubeTexture"===t||"cubeDepthTexture"===t)a=new XS(i.name,i.node,s),u.push(a);else if("texture3D"===t)a=new KS(i.name,i.node,s),u.push(a);else if("buffer"===t){i.name=`buffer${e.id}`;const t=this.getSharedDataFromNode(e);let r=t.buffer;void 0===r&&(e.name=`NodeBuffer_${e.id}`,r=new kS(e,s),r.name=e.name,t.buffer=r),u.push(r),a=r}else{let e=this.uniformGroups[o];void 0===e?(e=new $S(o,s),this.uniformGroups[o]=e,u.push(e)):-1===u.indexOf(e)&&u.push(e),a=this.getNodeUniform(i,t);const r=a.name;e.uniforms.some(e=>e.name===r)||e.addUniform(a)}n.uniformGPU=a}return i}}let iR=null,nR=null;class aR{constructor(e={}){this.parameters=Object.assign({},e),this.data=new WeakMap,this.renderer=null,this.domElement=null,this.timestampQueryPool={[Ct.RENDER]:null,[Ct.COMPUTE]:null},this.trackTimestamp=!0===e.trackTimestamp}async init(e){this.renderer=e}get coordinateSystem(){}beginRender(){}finishRender(){}beginCompute(){}finishCompute(){}draw(){}compute(){}createProgram(){}destroyProgram(){}createBindings(){}updateBindings(){}updateBinding(){}createRenderPipeline(){}createComputePipeline(){}needsRenderUpdate(){}getRenderCacheKey(){}createNodeBuilder(){}updateSampler(){}createDefaultTexture(){}createTexture(){}updateTexture(){}generateMipmaps(){}destroyTexture(){}async copyTextureToBuffer(){}copyTextureToTexture(){}copyFramebufferToTexture(){}createAttribute(){}createIndexAttribute(){}createStorageAttribute(){}updateAttribute(){}destroyAttribute(){}getContext(){}updateSize(){}updateViewport(){}updateTimeStampUID(e){const t=this.get(e),r=this.renderer.info.frame;let s;s=!0===e.isComputeNode?"c:"+this.renderer.info.compute.frameCalls:"r:"+this.renderer.info.render.frameCalls,t.timestampUID=s+":"+e.id+":f"+r}getTimestampUID(e){return this.get(e).timestampUID}getTimestampFrames(e){const t=this.timestampQueryPool[e];return t?t.getTimestampFrames():[]}_getQueryPool(e){const t=e.startsWith("c:")?Ct.COMPUTE:Ct.RENDER;return this.timestampQueryPool[t]}getTimestamp(e){return this._getQueryPool(e).getTimestamp(e)}hasTimestamp(e){return this._getQueryPool(e).hasTimestamp(e)}isOccluded(){}async resolveTimestampsAsync(e="render"){if(!this.trackTimestamp)return void v("WebGPURenderer: Timestamp tracking is disabled.");const t=this.timestampQueryPool[e];if(!t)return;const r=await t.resolveQueriesAsync();return this.renderer.info[e].timestamp=r,r}async getArrayBufferAsync(){}async hasFeatureAsync(){}hasFeature(){}getMaxAnisotropy(){}getDrawingBufferSize(){return iR=iR||new t,this.renderer.getDrawingBufferSize(iR)}setScissorTest(){}getClearColor(){const e=this.renderer;return nR=nR||new Ly,e.getClearColor(nR),nR.getRGB(nR),nR}getDomElement(){let e=this.domElement;return null===e&&(e=void 0!==this.parameters.canvas?this.parameters.canvas:Mt(),"setAttribute"in e&&e.setAttribute("data-engine",`three.js r${ut} webgpu`),this.domElement=e),e}hasCompatibility(){return!1}set(e,t){this.data.set(e,t)}get(e){let t=this.data.get(e);return void 0===t&&(t={},this.data.set(e,t)),t}has(e){return this.data.has(e)}delete(e){this.data.delete(e)}deleteBindGroupData(){}dispose(){}}let oR,uR,lR=0;class dR{constructor(e,t){this.buffers=[e.bufferGPU,t],this.type=e.type,this.bufferType=e.bufferType,this.pbo=e.pbo,this.byteLength=e.byteLength,this.bytesPerElement=e.BYTES_PER_ELEMENT,this.version=e.version,this.isInteger=e.isInteger,this.activeBufferIndex=0,this.baseId=e.id}get id(){return`${this.baseId}|${this.activeBufferIndex}`}get bufferGPU(){return this.buffers[this.activeBufferIndex]}get transformBuffer(){return this.buffers[1^this.activeBufferIndex]}switchBuffers(){this.activeBufferIndex^=1}}class cR{constructor(e){this.backend=e}createAttribute(e,t){const r=this.backend,{gl:s}=r,i=e.array,n=e.usage||s.STATIC_DRAW,a=e.isInterleavedBufferAttribute?e.data:e,o=r.get(a);let u,l=o.bufferGPU;if(void 0===l&&(l=this._createBuffer(s,t,i,n),o.bufferGPU=l,o.bufferType=t,o.version=a.version),i instanceof Float32Array)u=s.FLOAT;else if("undefined"!=typeof Float16Array&&i instanceof Float16Array)u=s.HALF_FLOAT;else if(i instanceof Uint16Array)u=e.isFloat16BufferAttribute?s.HALF_FLOAT:s.UNSIGNED_SHORT;else if(i instanceof Int16Array)u=s.SHORT;else if(i instanceof Uint32Array)u=s.UNSIGNED_INT;else if(i instanceof Int32Array)u=s.INT;else if(i instanceof Int8Array)u=s.BYTE;else if(i instanceof Uint8Array)u=s.UNSIGNED_BYTE;else{if(!(i instanceof Uint8ClampedArray))throw new Error("THREE.WebGLBackend: Unsupported buffer data format: "+i);u=s.UNSIGNED_BYTE}let d={bufferGPU:l,bufferType:t,type:u,byteLength:i.byteLength,bytesPerElement:i.BYTES_PER_ELEMENT,version:e.version,pbo:e.pbo,isInteger:u===s.INT||u===s.UNSIGNED_INT||e.gpuType===R,id:lR++};if(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute){const e=this._createBuffer(s,t,i,n);d=new dR(d,e)}r.set(e,d)}updateAttribute(e){const t=this.backend,{gl:r}=t,s=e.array,i=e.isInterleavedBufferAttribute?e.data:e,n=t.get(i),a=n.bufferType,o=e.isInterleavedBufferAttribute?e.data.updateRanges:e.updateRanges;if(r.bindBuffer(a,n.bufferGPU),0===o.length)r.bufferSubData(a,0,s);else{for(let e=0,t=o.length;e0?this.enable(s.SAMPLE_ALPHA_TO_COVERAGE):this.disable(s.SAMPLE_ALPHA_TO_COVERAGE),r>0&&this.currentClippingPlanes!==r){const e=12288;for(let t=0;t<8;t++)t{!function i(){const n=e.clientWaitSync(t,e.SYNC_FLUSH_COMMANDS_BIT,0);if(n===e.WAIT_FAILED)return e.deleteSync(t),void s();n!==e.TIMEOUT_EXPIRED?(e.deleteSync(t),r()):requestAnimationFrame(i)}()})}}let gR,mR,fR,yR=!1;class bR{constructor(e){this.backend=e,this.gl=e.gl,this.extensions=e.extensions,this.defaultTextures={},this._srcFramebuffer=null,this._dstFramebuffer=null,!1===yR&&(this._init(),yR=!0)}_init(){const e=this.gl;gR={[Vr]:e.REPEAT,[xe]:e.CLAMP_TO_EDGE,[Or]:e.MIRRORED_REPEAT},mR={[w]:e.NEAREST,[kr]:e.NEAREST_MIPMAP_NEAREST,[at]:e.NEAREST_MIPMAP_LINEAR,[oe]:e.LINEAR,[nt]:e.LINEAR_MIPMAP_NEAREST,[K]:e.LINEAR_MIPMAP_LINEAR},fR={[qr]:e.NEVER,[Hr]:e.ALWAYS,[A]:e.LESS,[Je]:e.LEQUAL,[Wr]:e.EQUAL,[$r]:e.GEQUAL,[zr]:e.GREATER,[Gr]:e.NOTEQUAL}}getGLTextureType(e){const{gl:t}=this;let r;return r=!0===e.isCubeTexture?t.TEXTURE_CUBE_MAP:!0===e.isArrayTexture||!0===e.isDataArrayTexture||!0===e.isCompressedArrayTexture?t.TEXTURE_2D_ARRAY:!0===e.isData3DTexture?t.TEXTURE_3D:t.TEXTURE_2D,r}getInternalFormat(e,t,r,s,i=!1){const{gl:n,extensions:a}=this;if(null!==e){if(void 0!==n[e])return n[e];d("WebGLBackend: Attempt to use non-existing WebGL internal format '"+e+"'")}let o=t;if(t===n.RED&&(r===n.FLOAT&&(o=n.R32F),r===n.HALF_FLOAT&&(o=n.R16F),r===n.UNSIGNED_BYTE&&(o=n.R8),r===n.UNSIGNED_SHORT&&(o=n.R16),r===n.UNSIGNED_INT&&(o=n.R32UI),r===n.BYTE&&(o=n.R8I),r===n.SHORT&&(o=n.R16I),r===n.INT&&(o=n.R32I)),t===n.RED_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.R8UI),r===n.UNSIGNED_SHORT&&(o=n.R16UI),r===n.UNSIGNED_INT&&(o=n.R32UI),r===n.BYTE&&(o=n.R8I),r===n.SHORT&&(o=n.R16I),r===n.INT&&(o=n.R32I)),t===n.RG&&(r===n.FLOAT&&(o=n.RG32F),r===n.HALF_FLOAT&&(o=n.RG16F),r===n.UNSIGNED_BYTE&&(o=n.RG8),r===n.UNSIGNED_SHORT&&(o=n.RG16),r===n.UNSIGNED_INT&&(o=n.RG32UI),r===n.BYTE&&(o=n.RG8I),r===n.SHORT&&(o=n.RG16I),r===n.INT&&(o=n.RG32I)),t===n.RG_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RG8UI),r===n.UNSIGNED_SHORT&&(o=n.RG16UI),r===n.UNSIGNED_INT&&(o=n.RG32UI),r===n.BYTE&&(o=n.RG8I),r===n.SHORT&&(o=n.RG16I),r===n.INT&&(o=n.RG32I)),t===n.RGB){const e=i?jr:p.getTransfer(s);r===n.FLOAT&&(o=n.RGB32F),r===n.HALF_FLOAT&&(o=n.RGB16F),r===n.UNSIGNED_BYTE&&(o=n.RGB8),r===n.UNSIGNED_SHORT&&(o=n.RGB16),r===n.UNSIGNED_INT&&(o=n.RGB32UI),r===n.BYTE&&(o=n.RGB8I),r===n.SHORT&&(o=n.RGB16I),r===n.INT&&(o=n.RGB32I),r===n.UNSIGNED_BYTE&&(o=e===g?n.SRGB8:n.RGB8),r===n.UNSIGNED_SHORT_5_6_5&&(o=n.RGB565),r===n.UNSIGNED_SHORT_5_5_5_1&&(o=n.RGB5_A1),r===n.UNSIGNED_SHORT_4_4_4_4&&(o=n.RGB4),r===n.UNSIGNED_INT_5_9_9_9_REV&&(o=n.RGB9_E5),r===n.UNSIGNED_INT_10F_11F_11F_REV&&(o=n.R11F_G11F_B10F)}if(t===n.RGB_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RGB8UI),r===n.UNSIGNED_SHORT&&(o=n.RGB16UI),r===n.UNSIGNED_INT&&(o=n.RGB32UI),r===n.BYTE&&(o=n.RGB8I),r===n.SHORT&&(o=n.RGB16I),r===n.INT&&(o=n.RGB32I)),t===n.RGBA){const e=i?jr:p.getTransfer(s);r===n.FLOAT&&(o=n.RGBA32F),r===n.HALF_FLOAT&&(o=n.RGBA16F),r===n.UNSIGNED_BYTE&&(o=n.RGBA8),r===n.UNSIGNED_SHORT&&(o=n.RGBA16),r===n.UNSIGNED_INT&&(o=n.RGBA32UI),r===n.BYTE&&(o=n.RGBA8I),r===n.SHORT&&(o=n.RGBA16I),r===n.INT&&(o=n.RGBA32I),r===n.UNSIGNED_BYTE&&(o=e===g?n.SRGB8_ALPHA8:n.RGBA8),r===n.UNSIGNED_SHORT_4_4_4_4&&(o=n.RGBA4),r===n.UNSIGNED_SHORT_5_5_5_1&&(o=n.RGB5_A1)}return t===n.RGBA_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RGBA8UI),r===n.UNSIGNED_SHORT&&(o=n.RGBA16UI),r===n.UNSIGNED_INT&&(o=n.RGBA32UI),r===n.BYTE&&(o=n.RGBA8I),r===n.SHORT&&(o=n.RGBA16I),r===n.INT&&(o=n.RGBA32I)),t===n.DEPTH_COMPONENT&&(r===n.UNSIGNED_SHORT&&(o=n.DEPTH_COMPONENT16),r===n.UNSIGNED_INT&&(o=n.DEPTH_COMPONENT24),r===n.FLOAT&&(o=n.DEPTH_COMPONENT32F)),t===n.DEPTH_STENCIL&&r===n.UNSIGNED_INT_24_8&&(o=n.DEPTH24_STENCIL8),o!==n.R16F&&o!==n.R32F&&o!==n.RG16F&&o!==n.RG32F&&o!==n.RGBA16F&&o!==n.RGBA32F||a.get("EXT_color_buffer_float"),o}setTextureParameters(e,t){const{gl:r,extensions:s,backend:i}=this,n=p.getPrimaries(p.workingColorSpace),a=t.colorSpace===T?null:p.getPrimaries(t.colorSpace),o=t.colorSpace===T||n===a?r.NONE:r.BROWSER_DEFAULT_WEBGL;r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,t.flipY),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),r.pixelStorei(r.UNPACK_ALIGNMENT,t.unpackAlignment),r.pixelStorei(r.UNPACK_COLORSPACE_CONVERSION_WEBGL,o),r.texParameteri(e,r.TEXTURE_WRAP_S,gR[t.wrapS]),r.texParameteri(e,r.TEXTURE_WRAP_T,gR[t.wrapT]),e!==r.TEXTURE_3D&&e!==r.TEXTURE_2D_ARRAY||t.isArrayTexture||r.texParameteri(e,r.TEXTURE_WRAP_R,gR[t.wrapR]),r.texParameteri(e,r.TEXTURE_MAG_FILTER,mR[t.magFilter]);const u=void 0!==t.mipmaps&&t.mipmaps.length>0,l=t.minFilter===oe&&u?K:t.minFilter;if(r.texParameteri(e,r.TEXTURE_MIN_FILTER,mR[l]),t.compareFunction&&(r.texParameteri(e,r.TEXTURE_COMPARE_MODE,r.COMPARE_REF_TO_TEXTURE),r.texParameteri(e,r.TEXTURE_COMPARE_FUNC,fR[t.compareFunction])),!0===s.has("EXT_texture_filter_anisotropic")){if(t.magFilter===w)return;if(t.minFilter!==at&&t.minFilter!==K)return;if(t.type===j&&!1===s.has("OES_texture_float_linear"))return;if(t.anisotropy>1){const n=s.get("EXT_texture_filter_anisotropic");r.texParameterf(e,n.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(t.anisotropy,i.getMaxAnisotropy()))}}}createDefaultTexture(e){const{gl:t,backend:r,defaultTextures:s}=this,i=this.getGLTextureType(e);let n=s[i];void 0===n&&(n=t.createTexture(),r.state.bindTexture(i,n),t.texParameteri(i,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(i,t.TEXTURE_MAG_FILTER,t.NEAREST),s[i]=n),r.set(e,{textureGPU:n,glTextureType:i})}createTexture(e,t){const{gl:r,backend:s}=this,{levels:i,width:n,height:a,depth:o}=t,u=s.utils.convert(e.format,e.colorSpace),l=s.utils.convert(e.type),d=this.getInternalFormat(e.internalFormat,u,l,e.colorSpace,e.isVideoTexture),c=r.createTexture(),h=this.getGLTextureType(e);s.state.bindTexture(h,c),this.setTextureParameters(h,e),e.isArrayTexture||e.isDataArrayTexture||e.isCompressedArrayTexture?r.texStorage3D(r.TEXTURE_2D_ARRAY,i,d,n,a,o):e.isData3DTexture?r.texStorage3D(r.TEXTURE_3D,i,d,n,a,o):e.isVideoTexture||r.texStorage2D(h,i,d,n,a),s.set(e,{textureGPU:c,glTextureType:h,glFormat:u,glType:l,glInternalFormat:d})}copyBufferToTexture(e,t){const{gl:r,backend:s}=this,{textureGPU:i,glTextureType:n,glFormat:a,glType:o}=s.get(t),{width:u,height:l}=t.source.data;r.bindBuffer(r.PIXEL_UNPACK_BUFFER,e),s.state.bindTexture(n,i),r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,!1),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),r.texSubImage2D(n,0,0,0,u,l,a,o,0),r.bindBuffer(r.PIXEL_UNPACK_BUFFER,null),s.state.unbindTexture()}updateTexture(e,t){const{gl:r}=this,{width:s,height:i}=t,{textureGPU:n,glTextureType:a,glFormat:o,glType:u,glInternalFormat:l}=this.backend.get(e);if(!e.isRenderTargetTexture&&void 0!==n)if(this.backend.state.bindTexture(a,n),this.setTextureParameters(a,e),e.isCompressedTexture){const s=e.mipmaps,i=t.image;for(let t=0;t0){const t=Xr(s.width,s.height,e.format,e.type);for(const i of e.layerUpdates){const e=s.data.subarray(i*t/s.data.BYTES_PER_ELEMENT,(i+1)*t/s.data.BYTES_PER_ELEMENT);r.texSubImage3D(r.TEXTURE_2D_ARRAY,0,0,0,i,s.width,s.height,1,o,u,e)}e.clearLayerUpdates()}else r.texSubImage3D(r.TEXTURE_2D_ARRAY,0,0,0,0,s.width,s.height,s.depth,o,u,s.data)}else if(e.isData3DTexture){const e=t.image;r.texSubImage3D(r.TEXTURE_3D,0,0,0,0,e.width,e.height,e.depth,o,u,e.data)}else if(e.isVideoTexture)e.update(),r.texImage2D(a,0,l,o,u,t.image);else{const n=e.mipmaps;if(n.length>0)for(let e=0,t=n.length;e0,c=t.renderTarget?t.renderTarget.height:this.backend.getDrawingBufferSize().y;if(d){const r=0!==a||0!==o;let d,h;if(!0===e.isDepthTexture?(d=s.DEPTH_BUFFER_BIT,h=s.DEPTH_ATTACHMENT,t.stencil&&(d|=s.STENCIL_BUFFER_BIT)):(d=s.COLOR_BUFFER_BIT,h=s.COLOR_ATTACHMENT0),r){const e=this.backend.get(t.renderTarget),r=e.framebuffers[t.getCacheKey()],h=e.msaaFrameBuffer;i.bindFramebuffer(s.DRAW_FRAMEBUFFER,r),i.bindFramebuffer(s.READ_FRAMEBUFFER,h);const p=c-o-l;s.blitFramebuffer(a,p,a+u,p+l,a,p,a+u,p+l,d,s.NEAREST),i.bindFramebuffer(s.READ_FRAMEBUFFER,r),i.bindTexture(s.TEXTURE_2D,n),s.copyTexSubImage2D(s.TEXTURE_2D,0,0,0,a,p,u,l),i.unbindTexture()}else{const e=s.createFramebuffer();i.bindFramebuffer(s.DRAW_FRAMEBUFFER,e),s.framebufferTexture2D(s.DRAW_FRAMEBUFFER,h,s.TEXTURE_2D,n,0),s.blitFramebuffer(0,0,u,l,0,0,u,l,d,s.NEAREST),s.deleteFramebuffer(e)}}else i.bindTexture(s.TEXTURE_2D,n),s.copyTexSubImage2D(s.TEXTURE_2D,0,0,0,a,c-l-o,u,l),i.unbindTexture();e.generateMipmaps&&this.generateMipmaps(e),this.backend._setFramebuffer(t)}setupRenderBufferStorage(e,t,r,s=!1){const{gl:i}=this,n=t.renderTarget,{depthTexture:a,depthBuffer:o,stencilBuffer:u,width:l,height:d}=n;if(i.bindRenderbuffer(i.RENDERBUFFER,e),o&&!u){let t=i.DEPTH_COMPONENT24;if(!0===s){this.extensions.get("WEBGL_multisampled_render_to_texture").renderbufferStorageMultisampleEXT(i.RENDERBUFFER,n.samples,t,l,d)}else r>0?(a&&a.isDepthTexture&&a.type===i.FLOAT&&(t=i.DEPTH_COMPONENT32F),i.renderbufferStorageMultisample(i.RENDERBUFFER,r,t,l,d)):i.renderbufferStorage(i.RENDERBUFFER,t,l,d);i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_ATTACHMENT,i.RENDERBUFFER,e)}else o&&u&&(r>0?i.renderbufferStorageMultisample(i.RENDERBUFFER,r,i.DEPTH24_STENCIL8,l,d):i.renderbufferStorage(i.RENDERBUFFER,i.DEPTH_STENCIL,l,d),i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_STENCIL_ATTACHMENT,i.RENDERBUFFER,e));i.bindRenderbuffer(i.RENDERBUFFER,null)}async copyTextureToBuffer(e,t,r,s,i,n){const{backend:a,gl:o}=this,{textureGPU:u,glFormat:l,glType:d}=this.backend.get(e),c=o.createFramebuffer();a.state.bindFramebuffer(o.READ_FRAMEBUFFER,c);const h=e.isCubeTexture?o.TEXTURE_CUBE_MAP_POSITIVE_X+n:o.TEXTURE_2D;o.framebufferTexture2D(o.READ_FRAMEBUFFER,o.COLOR_ATTACHMENT0,h,u,0);const p=this._getTypedArrayType(d),g=s*i*this._getBytesPerTexel(d,l),m=o.createBuffer();o.bindBuffer(o.PIXEL_PACK_BUFFER,m),o.bufferData(o.PIXEL_PACK_BUFFER,g,o.STREAM_READ),o.readPixels(t,r,s,i,l,d,0),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),await a.utils._clientWaitAsync();const f=new p(g/p.BYTES_PER_ELEMENT);return o.bindBuffer(o.PIXEL_PACK_BUFFER,m),o.getBufferSubData(o.PIXEL_PACK_BUFFER,0,f),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),a.state.bindFramebuffer(o.READ_FRAMEBUFFER,null),o.deleteFramebuffer(c),f}_getTypedArrayType(e){const{gl:t}=this;if(e===t.UNSIGNED_BYTE)return Uint8Array;if(e===t.UNSIGNED_SHORT_4_4_4_4)return Uint16Array;if(e===t.UNSIGNED_SHORT_5_5_5_1)return Uint16Array;if(e===t.UNSIGNED_SHORT_5_6_5)return Uint16Array;if(e===t.UNSIGNED_SHORT)return Uint16Array;if(e===t.UNSIGNED_INT)return Uint32Array;if(e===t.HALF_FLOAT)return Uint16Array;if(e===t.FLOAT)return Float32Array;throw new Error(`Unsupported WebGL type: ${e}`)}_getBytesPerTexel(e,t){const{gl:r}=this;let s=0;return e===r.UNSIGNED_BYTE&&(s=1),e!==r.UNSIGNED_SHORT_4_4_4_4&&e!==r.UNSIGNED_SHORT_5_5_5_1&&e!==r.UNSIGNED_SHORT_5_6_5&&e!==r.UNSIGNED_SHORT&&e!==r.HALF_FLOAT||(s=2),e!==r.UNSIGNED_INT&&e!==r.FLOAT||(s=4),t===r.RGBA?4*s:t===r.RGB?3*s:t===r.ALPHA?s:void 0}dispose(){const{gl:e}=this;null!==this._srcFramebuffer&&e.deleteFramebuffer(this._srcFramebuffer),null!==this._dstFramebuffer&&e.deleteFramebuffer(this._dstFramebuffer)}}function xR(e){return e.isDataTexture?e.image.data:"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas?e:e.data}class TR{constructor(e){this.backend=e,this.gl=this.backend.gl,this.availableExtensions=this.gl.getSupportedExtensions(),this.extensions={}}get(e){let t=this.extensions[e];return void 0===t&&(t=this.gl.getExtension(e),this.extensions[e]=t),t}has(e){return this.availableExtensions.includes(e)}}class _R{constructor(e){this.backend=e,this.maxAnisotropy=null}getMaxAnisotropy(){if(null!==this.maxAnisotropy)return this.maxAnisotropy;const e=this.backend.gl,t=this.backend.extensions;if(!0===t.has("EXT_texture_filter_anisotropic")){const r=t.get("EXT_texture_filter_anisotropic");this.maxAnisotropy=e.getParameter(r.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else this.maxAnisotropy=0;return this.maxAnisotropy}}const vR={WEBGL_multi_draw:"WEBGL_multi_draw",WEBGL_compressed_texture_astc:"texture-compression-astc",WEBGL_compressed_texture_etc:"texture-compression-etc2",WEBGL_compressed_texture_etc1:"texture-compression-etc1",WEBGL_compressed_texture_pvrtc:"texture-compression-pvrtc",WEBGL_compressed_texture_s3tc:"texture-compression-s3tc",EXT_texture_compression_bptc:"texture-compression-bc",EXT_disjoint_timer_query_webgl2:"timestamp-query",OVR_multiview2:"OVR_multiview2"};class NR{constructor(e){this.gl=e.gl,this.extensions=e.extensions,this.info=e.renderer.info,this.mode=null,this.index=0,this.type=null,this.object=null}render(e,t){const{gl:r,mode:s,object:i,type:n,info:a,index:o}=this;0!==o?r.drawElements(s,t,n,e):r.drawArrays(s,e,t),a.update(i,t,1)}renderInstances(e,t,r){const{gl:s,mode:i,type:n,index:a,object:o,info:u}=this;0!==r&&(0!==a?s.drawElementsInstanced(i,t,n,e,r):s.drawArraysInstanced(i,e,t,r),u.update(o,t,r))}renderMultiDraw(e,t,r){const{extensions:s,mode:i,object:n,info:a}=this;if(0===r)return;const o=s.get("WEBGL_multi_draw");if(null===o)for(let s=0;sthis.maxQueries)return v(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`),null;const t=this.currentQueryIndex;return this.currentQueryIndex+=2,this.queryStates.set(t,"inactive"),this.queryOffsets.set(e,t),t}beginQuery(e){if(!this.trackTimestamp||this.isDisposed)return;const t=this.queryOffsets.get(e);if(null==t)return;if(null!==this.activeQuery)return;const r=this.queries[t];if(r)try{"inactive"===this.queryStates.get(t)&&(this.gl.beginQuery(this.ext.TIME_ELAPSED_EXT,r),this.activeQuery=t,this.queryStates.set(t,"started"))}catch(e){o("Error in beginQuery:",e),this.activeQuery=null,this.queryStates.set(t,"inactive")}}endQuery(e){if(!this.trackTimestamp||this.isDisposed)return;const t=this.queryOffsets.get(e);if(null!=t&&this.activeQuery===t)try{this.gl.endQuery(this.ext.TIME_ELAPSED_EXT),this.queryStates.set(t,"ended"),this.activeQuery=null}catch(e){o("Error in endQuery:",e),this.queryStates.set(t,"inactive"),this.activeQuery=null}}async resolveQueriesAsync(){if(!this.trackTimestamp||this.pendingResolve)return this.lastValue;this.pendingResolve=!0;try{const e=new Map;for(const[t,r]of this.queryOffsets){if("ended"===this.queryStates.get(r)){const s=this.queries[r];e.set(t,this.resolveQuery(s))}}if(0===e.size)return this.lastValue;const t={},r=[];for(const[s,i]of e){const e=s.match(/^(.*):f(\d+)$/),n=parseInt(e[2]);!1===r.includes(n)&&r.push(n),void 0===t[n]&&(t[n]=0);const a=await i;this.timestamps.set(s,a),t[n]+=a}const s=t[r[r.length-1]];return this.lastValue=s,this.frames=r,this.currentQueryIndex=0,this.queryOffsets.clear(),this.queryStates.clear(),this.activeQuery=null,s}catch(e){return o("Error resolving queries:",e),this.lastValue}finally{this.pendingResolve=!1}}async resolveQuery(e){return new Promise(t=>{if(this.isDisposed)return void t(this.lastValue);let r,s=!1;const i=e=>{s||(s=!0,r&&(clearTimeout(r),r=null),t(e))},n=()=>{if(this.isDisposed)i(this.lastValue);else try{if(this.gl.getParameter(this.ext.GPU_DISJOINT_EXT))return void i(this.lastValue);if(!this.gl.getQueryParameter(e,this.gl.QUERY_RESULT_AVAILABLE))return void(r=setTimeout(n,1));const s=this.gl.getQueryParameter(e,this.gl.QUERY_RESULT);t(Number(s)/1e6)}catch(e){o("Error checking query:",e),t(this.lastValue)}};n()})}dispose(){if(!this.isDisposed&&(this.isDisposed=!0,this.trackTimestamp)){for(const e of this.queries)this.gl.deleteQuery(e);this.queries=[],this.queryStates.clear(),this.queryOffsets.clear(),this.lastValue=0,this.activeQuery=null}}}class ER extends aR{constructor(e={}){super(e),this.isWebGLBackend=!0,this.attributeUtils=null,this.extensions=null,this.capabilities=null,this.textureUtils=null,this.bufferRenderer=null,this.gl=null,this.state=null,this.utils=null,this.vaoCache={},this.transformFeedbackCache={},this.discard=!1,this.disjoint=null,this.parallel=null,this._currentContext=null,this._knownBindings=new WeakSet,this._supportsInvalidateFramebuffer="undefined"!=typeof navigator&&/OculusBrowser/g.test(navigator.userAgent),this._xrFramebuffer=null}init(e){super.init(e);const t=this.parameters,r={antialias:e.currentSamples>0,alpha:!0,depth:e.depth,stencil:e.stencil},s=void 0!==t.context?t.context:e.domElement.getContext("webgl2",r);function i(t){t.preventDefault();const r={api:"WebGL",message:t.statusMessage||"Unknown reason",reason:null,originalEvent:t};e.onDeviceLost(r)}this._onContextLost=i,e.domElement.addEventListener("webglcontextlost",i,!1),this.gl=s,this.extensions=new TR(this),this.capabilities=new _R(this),this.attributeUtils=new cR(this),this.textureUtils=new bR(this),this.bufferRenderer=new NR(this),this.state=new hR(this),this.utils=new pR(this),this.extensions.get("EXT_color_buffer_float"),this.extensions.get("WEBGL_clip_cull_distance"),this.extensions.get("OES_texture_float_linear"),this.extensions.get("EXT_color_buffer_half_float"),this.extensions.get("WEBGL_multisampled_render_to_texture"),this.extensions.get("WEBGL_render_shared_exponent"),this.extensions.get("WEBGL_multi_draw"),this.extensions.get("OVR_multiview2"),this.disjoint=this.extensions.get("EXT_disjoint_timer_query_webgl2"),this.parallel=this.extensions.get("KHR_parallel_shader_compile"),this.drawBuffersIndexedExt=this.extensions.get("OES_draw_buffers_indexed")}get coordinateSystem(){return c}async getArrayBufferAsync(e){return await this.attributeUtils.getArrayBufferAsync(e)}async makeXRCompatible(){!0!==this.gl.getContextAttributes().xrCompatible&&await this.gl.makeXRCompatible()}setXRTarget(e){this._xrFramebuffer=e}setXRRenderTargetTextures(e,t,r=null){const s=this.gl;if(this.set(e.texture,{textureGPU:t,glInternalFormat:s.RGBA8}),null!==r){const t=e.stencilBuffer?s.DEPTH24_STENCIL8:s.DEPTH_COMPONENT24;this.set(e.depthTexture,{textureGPU:r,glInternalFormat:t}),!0===this.extensions.has("WEBGL_multisampled_render_to_texture")&&!0===e._autoAllocateDepthBuffer&&!1===e.multiview&&d("WebGLBackend: Render-to-texture extension was disabled because an external texture was provided"),e._autoAllocateDepthBuffer=!1}}initTimestampQuery(e,t){if(!this.disjoint||!this.trackTimestamp)return;this.timestampQueryPool[e]||(this.timestampQueryPool[e]=new RR(this.gl,e,2048));const r=this.timestampQueryPool[e];null!==r.allocateQueriesForContext(t)&&r.beginQuery(t)}prepareTimestampBuffer(e,t){if(!this.disjoint||!this.trackTimestamp)return;this.timestampQueryPool[e].endQuery(t)}getContext(){return this.gl}beginRender(e){const{state:t}=this,r=this.get(e);if(e.viewport)this.updateViewport(e);else{const{width:e,height:r}=this.getDrawingBufferSize();t.viewport(0,0,e,r)}if(e.scissor){const{x:r,y:s,width:i,height:n}=e.scissorValue;t.scissor(r,e.height-n-s,i,n)}this.initTimestampQuery(Ct.RENDER,this.getTimestampUID(e)),r.previousContext=this._currentContext,this._currentContext=e,this._setFramebuffer(e),this.clear(e.clearColor,e.clearDepth,e.clearStencil,e,!1);const s=e.occlusionQueryCount;s>0&&(r.currentOcclusionQueries=r.occlusionQueries,r.currentOcclusionQueryObjects=r.occlusionQueryObjects,r.lastOcclusionObject=null,r.occlusionQueries=new Array(s),r.occlusionQueryObjects=new Array(s),r.occlusionQueryIndex=0)}finishRender(e){const{gl:t,state:r}=this,s=this.get(e),i=s.previousContext;r.resetVertexState();const n=e.occlusionQueryCount;n>0&&(n>s.occlusionQueryIndex&&t.endQuery(t.ANY_SAMPLES_PASSED),this.resolveOccludedAsync(e));const a=e.textures;if(null!==a)for(let e=0;e{let a=0;for(let t=0;t{t.isBatchedMesh?null!==t._multiDrawInstances?(v("WebGLBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."),b.renderMultiDrawInstances(t._multiDrawStarts,t._multiDrawCounts,t._multiDrawCount,t._multiDrawInstances)):this.hasFeature("WEBGL_multi_draw")?b.renderMultiDraw(t._multiDrawStarts,t._multiDrawCounts,t._multiDrawCount):v("WebGLBackend: WEBGL_multi_draw not supported."):T>1?b.renderInstances(_,x,T):b.render(_,x)};if(!0===e.camera.isArrayCamera&&e.camera.cameras.length>0&&!1===e.camera.isMultiViewCamera){const r=this.get(e.camera),s=e.camera.cameras,i=e.getBindingGroup("cameraIndex").bindings[0];if(void 0===r.indexesGPU||r.indexesGPU.length!==s.length){const e=new Uint32Array([0,0,0,0]),t=[];for(let r=0,i=s.length;r{const i=this.parallel,n=()=>{r.getProgramParameter(a,i.COMPLETION_STATUS_KHR)?(this._completeCompile(e,s),t()):requestAnimationFrame(n)};n()});return void t.push(i)}this._completeCompile(e,s)}_handleSource(e,t){const r=e.split("\n"),s=[],i=Math.max(t-6,0),n=Math.min(t+6,r.length);for(let e=i;e":" "} ${i}: ${r[e]}`)}return s.join("\n")}_getShaderErrors(e,t,r){const s=e.getShaderParameter(t,e.COMPILE_STATUS),i=(e.getShaderInfoLog(t)||"").trim();if(s&&""===i)return"";const n=/ERROR: 0:(\d+)/.exec(i);if(n){const s=parseInt(n[1]);return r.toUpperCase()+"\n\n"+i+"\n\n"+this._handleSource(e.getShaderSource(t),s)}return i}_logProgramError(e,t,r){if(this.renderer.debug.checkShaderErrors){const s=this.gl,i=(s.getProgramInfoLog(e)||"").trim();if(!1===s.getProgramParameter(e,s.LINK_STATUS))if("function"==typeof this.renderer.debug.onShaderError)this.renderer.debug.onShaderError(s,e,r,t);else{const n=this._getShaderErrors(s,r,"vertex"),a=this._getShaderErrors(s,t,"fragment");o("THREE.WebGLProgram: Shader Error "+s.getError()+" - VALIDATE_STATUS "+s.getProgramParameter(e,s.VALIDATE_STATUS)+"\n\nProgram Info Log: "+i+"\n"+n+"\n"+a)}else""!==i&&d("WebGLProgram: Program Info Log:",i)}}_completeCompile(e,t){const{state:r,gl:s}=this,i=this.get(t),{programGPU:n,fragmentShader:a,vertexShader:o}=i;!1===s.getProgramParameter(n,s.LINK_STATUS)&&this._logProgramError(n,a,o),r.useProgram(n);const u=e.getBindings();this._setupBindings(u,n),this.set(t,{programGPU:n})}createComputePipeline(e,t){const{state:r,gl:s}=this,i={stage:"fragment",code:"#version 300 es\nprecision highp float;\nvoid main() {}"};this.createProgram(i);const{computeProgram:n}=e,a=s.createProgram(),o=this.get(i).shaderGPU,u=this.get(n).shaderGPU,l=n.transforms,d=[],c=[];for(let e=0;evR[t]===e),r=this.extensions;for(let e=0;e1,h=!0===i.isXRRenderTarget,p=!0===h&&!0===i._hasExternalTextures;let g=n.msaaFrameBuffer,m=n.depthRenderbuffer;const f=this.extensions.get("WEBGL_multisampled_render_to_texture"),y=this.extensions.get("OVR_multiview2"),b=this._useMultisampledExtension(i),x=wy(e);let T;if(l?(n.cubeFramebuffers||(n.cubeFramebuffers={}),T=n.cubeFramebuffers[x]):h&&!1===p?T=this._xrFramebuffer:(n.framebuffers||(n.framebuffers={}),T=n.framebuffers[x]),void 0===T){T=t.createFramebuffer(),r.bindFramebuffer(t.FRAMEBUFFER,T);const s=e.textures,o=[];if(l){n.cubeFramebuffers[x]=T;const{textureGPU:e}=this.get(s[0]),r=this.renderer._activeCubeFace,i=this.renderer._activeMipmapLevel;t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_CUBE_MAP_POSITIVE_X+r,e,i)}else{n.framebuffers[x]=T;for(let r=0;r0&&!1===b&&!i.multiview){if(void 0===g){const s=[];g=t.createFramebuffer(),r.bindFramebuffer(t.FRAMEBUFFER,g);const i=[],l=e.textures;for(let r=0;r0&&!1===this._useMultisampledExtension(s)){const n=i.framebuffers[e.getCacheKey()];let a=t.COLOR_BUFFER_BIT;s.resolveDepthBuffer&&(s.depthBuffer&&(a|=t.DEPTH_BUFFER_BIT),s.stencilBuffer&&s.resolveStencilBuffer&&(a|=t.STENCIL_BUFFER_BIT));const o=i.msaaFrameBuffer,u=i.msaaRenderbuffers,l=e.textures,d=l.length>1;if(r.bindFramebuffer(t.READ_FRAMEBUFFER,o),r.bindFramebuffer(t.DRAW_FRAMEBUFFER,n),d)for(let e=0;e0&&!0===this.extensions.has("WEBGL_multisampled_render_to_texture")&&!1!==e._autoAllocateDepthBuffer}dispose(){null!==this.textureUtils&&this.textureUtils.dispose();const e=this.extensions.get("WEBGL_lose_context");e&&e.loseContext(),this.renderer.domElement.removeEventListener("webglcontextlost",this._onContextLost)}}const AR="point-list",wR="line-list",CR="line-strip",MR="triangle-list",FR="triangle-strip",LR="undefined"!=typeof self&&self.GPUShaderStage?self.GPUShaderStage:{VERTEX:1,FRAGMENT:2,COMPUTE:4},PR="never",BR="less",DR="equal",UR="less-equal",IR="greater",OR="not-equal",VR="greater-equal",kR="always",GR="store",zR="load",$R="clear",WR="ccw",HR="cw",qR="none",jR="back",XR="uint16",KR="uint32",YR="r8unorm",QR="r8snorm",ZR="r8uint",JR="r8sint",eE="r16uint",tE="r16sint",rE="r16float",sE="rg8unorm",iE="rg8snorm",nE="rg8uint",aE="rg8sint",oE="r32uint",uE="r32sint",lE="r32float",dE="rg16uint",cE="rg16sint",hE="rg16float",pE="rgba8unorm",gE="rgba8unorm-srgb",mE="rgba8snorm",fE="rgba8uint",yE="rgba8sint",bE="bgra8unorm",xE="bgra8unorm-srgb",TE="rgb9e5ufloat",_E="rgb10a2unorm",vE="rg11b10ufloat",NE="rg32uint",SE="rg32sint",RE="rg32float",EE="rgba16uint",AE="rgba16sint",wE="rgba16float",CE="rgba32uint",ME="rgba32sint",FE="rgba32float",LE="depth16unorm",PE="depth24plus",BE="depth24plus-stencil8",DE="depth32float",UE="depth32float-stencil8",IE="bc1-rgba-unorm",OE="bc1-rgba-unorm-srgb",VE="bc2-rgba-unorm",kE="bc2-rgba-unorm-srgb",GE="bc3-rgba-unorm",zE="bc3-rgba-unorm-srgb",$E="bc4-r-unorm",WE="bc4-r-snorm",HE="bc5-rg-unorm",qE="bc5-rg-snorm",jE="bc6h-rgb-ufloat",XE="bc6h-rgb-float",KE="bc7-rgba-unorm",YE="bc7-rgba-unorm-srgb",QE="etc2-rgb8unorm",ZE="etc2-rgb8unorm-srgb",JE="etc2-rgb8a1unorm",eA="etc2-rgb8a1unorm-srgb",tA="etc2-rgba8unorm",rA="etc2-rgba8unorm-srgb",sA="eac-r11unorm",iA="eac-r11snorm",nA="eac-rg11unorm",aA="eac-rg11snorm",oA="astc-4x4-unorm",uA="astc-4x4-unorm-srgb",lA="astc-5x4-unorm",dA="astc-5x4-unorm-srgb",cA="astc-5x5-unorm",hA="astc-5x5-unorm-srgb",pA="astc-6x5-unorm",gA="astc-6x5-unorm-srgb",mA="astc-6x6-unorm",fA="astc-6x6-unorm-srgb",yA="astc-8x5-unorm",bA="astc-8x5-unorm-srgb",xA="astc-8x6-unorm",TA="astc-8x6-unorm-srgb",_A="astc-8x8-unorm",vA="astc-8x8-unorm-srgb",NA="astc-10x5-unorm",SA="astc-10x5-unorm-srgb",RA="astc-10x6-unorm",EA="astc-10x6-unorm-srgb",AA="astc-10x8-unorm",wA="astc-10x8-unorm-srgb",CA="astc-10x10-unorm",MA="astc-10x10-unorm-srgb",FA="astc-12x10-unorm",LA="astc-12x10-unorm-srgb",PA="astc-12x12-unorm",BA="astc-12x12-unorm-srgb",DA="clamp-to-edge",UA="repeat",IA="mirror-repeat",OA="linear",VA="nearest",kA="zero",GA="one",zA="src",$A="one-minus-src",WA="src-alpha",HA="one-minus-src-alpha",qA="dst",jA="one-minus-dst",XA="dst-alpha",KA="one-minus-dst-alpha",YA="src-alpha-saturated",QA="constant",ZA="one-minus-constant",JA="add",ew="subtract",tw="reverse-subtract",rw="min",sw="max",iw=0,nw=15,aw="keep",ow="zero",uw="replace",lw="invert",dw="increment-clamp",cw="decrement-clamp",hw="increment-wrap",pw="decrement-wrap",gw="storage",mw="read-only-storage",fw="write-only",yw="read-only",bw="read-write",xw="non-filtering",Tw="comparison",_w="float",vw="unfilterable-float",Nw="depth",Sw="sint",Rw="uint",Ew="2d",Aw="3d",ww="2d",Cw="2d-array",Mw="cube",Fw="3d",Lw="all",Pw="vertex",Bw="instance",Dw={CoreFeaturesAndLimits:"core-features-and-limits",DepthClipControl:"depth-clip-control",Depth32FloatStencil8:"depth32float-stencil8",TextureCompressionBC:"texture-compression-bc",TextureCompressionBCSliced3D:"texture-compression-bc-sliced-3d",TextureCompressionETC2:"texture-compression-etc2",TextureCompressionASTC:"texture-compression-astc",TextureCompressionASTCSliced3D:"texture-compression-astc-sliced-3d",TimestampQuery:"timestamp-query",IndirectFirstInstance:"indirect-first-instance",ShaderF16:"shader-f16",RG11B10UFloat:"rg11b10ufloat-renderable",BGRA8UNormStorage:"bgra8unorm-storage",Float32Filterable:"float32-filterable",Float32Blendable:"float32-blendable",ClipDistances:"clip-distances",DualSourceBlending:"dual-source-blending",Subgroups:"subgroups",TextureFormatsTier1:"texture-formats-tier1",TextureFormatsTier2:"texture-formats-tier2"},Uw={"texture-compression-s3tc":"texture-compression-bc","texture-compression-etc1":"texture-compression-etc2"};class Iw extends WS{constructor(e,t,r){super(e,t?t.value:null),this.textureNode=t,this.groupNode=r}update(){const{textureNode:e}=this;return this.texture!==e.value?(this.texture=e.value,!0):super.update()}}class Ow extends IS{constructor(e,t){super(e,t?t.array:null),this._attribute=t,this.isStorageBuffer=!0}get attribute(){return this._attribute}}let Vw=0;class kw extends Ow{constructor(e,t){super("StorageBuffer_"+Vw++,e?e.value:null),this.nodeUniform=e,this.access=e?e.access:ti.READ_WRITE,this.groupNode=t}get attribute(){return this.nodeUniform.value}get buffer(){return this.nodeUniform.value.array}}class Gw extends ry{constructor(e){super(),this.device=e;this.mipmapSampler=e.createSampler({minFilter:OA}),this.flipYSampler=e.createSampler({minFilter:VA}),this.transferPipelines={},this.flipYPipelines={},this.mipmapVertexShaderModule=e.createShaderModule({label:"mipmapVertex",code:"\nstruct VarysStruct {\n\t@builtin( position ) Position: vec4,\n\t@location( 0 ) vTex : vec2\n};\n\n@vertex\nfn main( @builtin( vertex_index ) vertexIndex : u32 ) -> VarysStruct {\n\n\tvar Varys : VarysStruct;\n\n\tvar pos = array< vec2, 4 >(\n\t\tvec2( -1.0, 1.0 ),\n\t\tvec2( 1.0, 1.0 ),\n\t\tvec2( -1.0, -1.0 ),\n\t\tvec2( 1.0, -1.0 )\n\t);\n\n\tvar tex = array< vec2, 4 >(\n\t\tvec2( 0.0, 0.0 ),\n\t\tvec2( 1.0, 0.0 ),\n\t\tvec2( 0.0, 1.0 ),\n\t\tvec2( 1.0, 1.0 )\n\t);\n\n\tVarys.vTex = tex[ vertexIndex ];\n\tVarys.Position = vec4( pos[ vertexIndex ], 0.0, 1.0 );\n\n\treturn Varys;\n\n}\n"}),this.mipmapFragmentShaderModule=e.createShaderModule({label:"mipmapFragment",code:"\n@group( 0 ) @binding( 0 )\nvar imgSampler : sampler;\n\n@group( 0 ) @binding( 1 )\nvar img : texture_2d;\n\n@fragment\nfn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( img, imgSampler, vTex );\n\n}\n"}),this.flipYFragmentShaderModule=e.createShaderModule({label:"flipYFragment",code:"\n@group( 0 ) @binding( 0 )\nvar imgSampler : sampler;\n\n@group( 0 ) @binding( 1 )\nvar img : texture_2d;\n\n@fragment\nfn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( img, imgSampler, vec2( vTex.x, 1.0 - vTex.y ) );\n\n}\n"})}getTransferPipeline(e){let t=this.transferPipelines[e];return void 0===t&&(t=this.device.createRenderPipeline({label:`mipmap-${e}`,vertex:{module:this.mipmapVertexShaderModule,entryPoint:"main"},fragment:{module:this.mipmapFragmentShaderModule,entryPoint:"main",targets:[{format:e}]},primitive:{topology:FR,stripIndexFormat:KR},layout:"auto"}),this.transferPipelines[e]=t),t}getFlipYPipeline(e){let t=this.flipYPipelines[e];return void 0===t&&(t=this.device.createRenderPipeline({label:`flipY-${e}`,vertex:{module:this.mipmapVertexShaderModule,entryPoint:"main"},fragment:{module:this.flipYFragmentShaderModule,entryPoint:"main",targets:[{format:e}]},primitive:{topology:FR,stripIndexFormat:KR},layout:"auto"}),this.flipYPipelines[e]=t),t}flipY(e,t,r=0){const s=t.format,{width:i,height:n}=t.size,a=this.getTransferPipeline(s),o=this.getFlipYPipeline(s),u=this.device.createTexture({size:{width:i,height:n,depthOrArrayLayers:1},format:s,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),l=e.createView({baseMipLevel:0,mipLevelCount:1,dimension:ww,baseArrayLayer:r}),d=u.createView({baseMipLevel:0,mipLevelCount:1,dimension:ww,baseArrayLayer:0}),c=this.device.createCommandEncoder({}),h=(e,t,r)=>{const s=e.getBindGroupLayout(0),i=this.device.createBindGroup({layout:s,entries:[{binding:0,resource:this.flipYSampler},{binding:1,resource:t}]}),n=c.beginRenderPass({colorAttachments:[{view:r,loadOp:$R,storeOp:GR,clearValue:[0,0,0,0]}]});n.setPipeline(e),n.setBindGroup(0,i),n.draw(4,1,0,0),n.end()};h(a,l,d),h(o,d,l),this.device.queue.submit([c.finish()]),u.destroy()}generateMipmaps(e,t,r=0,s=null){const i=this.get(e);void 0===i.layers&&(i.layers=[]);const n=i.layers[r]||this._mipmapCreateBundles(e,t,r),a=s||this.device.createCommandEncoder({label:"mipmapEncoder"});this._mipmapRunBundles(a,n),null===s&&this.device.queue.submit([a.finish()]),i.layers[r]=n}_mipmapCreateBundles(e,t,r){const s=this.getTransferPipeline(t.format),i=s.getBindGroupLayout(0);let n=e.createView({baseMipLevel:0,mipLevelCount:1,dimension:ww,baseArrayLayer:r});const a=[];for(let o=1;o0)for(let t=0,n=s.length;t0)for(let t=0,n=s.length;t0?e.width:r.size.width,l=a>0?e.height:r.size.height;try{o.queue.copyExternalImageToTexture({source:e,flipY:i},{texture:t,mipLevel:a,origin:{x:0,y:0,z:s},premultipliedAlpha:n},{width:u,height:l,depthOrArrayLayers:1})}catch(e){}}_getPassUtils(){let e=this._passUtils;return null===e&&(this._passUtils=e=new Gw(this.backend.device)),e}_generateMipmaps(e,t,r=0,s=null){this._getPassUtils().generateMipmaps(e,t,r,s)}_flipY(e,t,r=0){this._getPassUtils().flipY(e,t,r)}_copyBufferToTexture(e,t,r,s,i,n=0,a=0){const o=this.backend.device,u=e.data,l=this._getBytesPerTexel(r.format),d=e.width*l;o.queue.writeTexture({texture:t,mipLevel:a,origin:{x:0,y:0,z:s}},u,{offset:e.width*e.height*l*n,bytesPerRow:d},{width:e.width,height:e.height,depthOrArrayLayers:1}),!0===i&&this._flipY(t,r,s)}_copyCompressedBufferToTexture(e,t,r){const s=this.backend.device,i=this._getBlockData(r.format),n=r.size.depthOrArrayLayers>1;for(let a=0;a]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i,jw=/([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi,Xw={f32:"float",i32:"int",u32:"uint",bool:"bool","vec2":"vec2","vec2":"ivec2","vec2":"uvec2","vec2":"bvec2",vec2f:"vec2",vec2i:"ivec2",vec2u:"uvec2",vec2b:"bvec2","vec3":"vec3","vec3":"ivec3","vec3":"uvec3","vec3":"bvec3",vec3f:"vec3",vec3i:"ivec3",vec3u:"uvec3",vec3b:"bvec3","vec4":"vec4","vec4":"ivec4","vec4":"uvec4","vec4":"bvec4",vec4f:"vec4",vec4i:"ivec4",vec4u:"uvec4",vec4b:"bvec4","mat2x2":"mat2",mat2x2f:"mat2","mat3x3":"mat3",mat3x3f:"mat3","mat4x4":"mat4",mat4x4f:"mat4",sampler:"sampler",texture_1d:"texture",texture_2d:"texture",texture_2d_array:"texture",texture_multisampled_2d:"cubeTexture",texture_depth_2d:"depthTexture",texture_depth_2d_array:"depthTexture",texture_depth_multisampled_2d:"depthTexture",texture_depth_cube:"depthTexture",texture_depth_cube_array:"depthTexture",texture_3d:"texture3D",texture_cube:"cubeTexture",texture_cube_array:"cubeTexture",texture_storage_1d:"storageTexture",texture_storage_2d:"storageTexture",texture_storage_2d_array:"storageTexture",texture_storage_3d:"storageTexture"};class Kw extends QN{constructor(e){const{type:t,inputs:r,name:s,inputsCode:i,blockCode:n,outputType:a}=(e=>{const t=(e=e.trim()).match(qw);if(null!==t&&4===t.length){const r=t[2],s=[];let i=null;for(;null!==(i=jw.exec(r));)s.push({name:i[1],type:i[2]});const n=[];for(let e=0;e "+this.outputType:"";return`fn ${e} ( ${this.inputsCode.trim()} ) ${t}`+this.blockCode}}class Yw extends YN{parseFunction(e){return new Kw(e)}}const Qw={[ti.READ_ONLY]:"read",[ti.WRITE_ONLY]:"write",[ti.READ_WRITE]:"read_write"},Zw={[Vr]:"repeat",[xe]:"clamp",[Or]:"mirror"},Jw={vertex:LR.VERTEX,fragment:LR.FRAGMENT,compute:LR.COMPUTE},eC={instance:!0,swizzleAssign:!1,storageBuffer:!0},tC={"^^":"tsl_xor"},rC={float:"f32",int:"i32",uint:"u32",bool:"bool",color:"vec3",vec2:"vec2",ivec2:"vec2",uvec2:"vec2",bvec2:"vec2",vec3:"vec3",ivec3:"vec3",uvec3:"vec3",bvec3:"vec3",vec4:"vec4",ivec4:"vec4",uvec4:"vec4",bvec4:"vec4",mat2:"mat2x2",mat3:"mat3x3",mat4:"mat4x4"},sC={},iC={tsl_xor:new Xx("fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }"),mod_float:new Xx("fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }"),mod_vec2:new Xx("fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }"),mod_vec3:new Xx("fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }"),mod_vec4:new Xx("fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }"),equals_bool:new Xx("fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }"),equals_bvec2:new Xx("fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }"),equals_bvec3:new Xx("fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }"),equals_bvec4:new Xx("fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }"),repeatWrapping_float:new Xx("fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }"),mirrorWrapping_float:new Xx("fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }"),clampWrapping_float:new Xx("fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }"),biquadraticTexture:new Xx("\nfn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, iRes : vec2u, level : u32 ) -> vec4f {\n\n\tlet res = vec2f( iRes );\n\n\tlet uvScaled = coord * res;\n\tlet uvWrapping = ( ( uvScaled % res ) + res ) % res;\n\n\t// https://www.shadertoy.com/view/WtyXRy\n\n\tlet uv = uvWrapping - 0.5;\n\tlet iuv = floor( uv );\n\tlet f = fract( uv );\n\n\tlet rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, level );\n\tlet rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, level );\n\tlet rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, level );\n\tlet rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, level );\n\n\treturn mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );\n\n}\n")},nC={dFdx:"dpdx",dFdy:"- dpdy",mod_float:"tsl_mod_float",mod_vec2:"tsl_mod_vec2",mod_vec3:"tsl_mod_vec3",mod_vec4:"tsl_mod_vec4",equals_bool:"tsl_equals_bool",equals_bvec2:"tsl_equals_bvec2",equals_bvec3:"tsl_equals_bvec3",equals_bvec4:"tsl_equals_bvec4",inversesqrt:"inverseSqrt",bitcast:"bitcast",floatpack_snorm_2x16:"pack2x16snorm",floatpack_unorm_2x16:"pack2x16unorm",floatpack_float16_2x16:"pack2x16float",floatunpack_snorm_2x16:"unpack2x16snorm",floatunpack_unorm_2x16:"unpack2x16unorm",floatunpack_float16_2x16:"unpack2x16float"};let aC="";!0!==("undefined"!=typeof navigator&&/Firefox|Deno/g.test(navigator.userAgent))&&(aC+="diagnostic( off, derivative_uniformity );\n");class oC extends DN{constructor(e,t){super(e,t,new Yw),this.uniformGroups={},this.uniformGroupsBindings={},this.builtins={},this.directives={},this.scopedArrays=new Map}_generateTextureSample(e,t,r,s,i,n=this.shaderStage){return"fragment"===n?s?i?`textureSample( ${t}, ${t}_sampler, ${r}, ${s}, ${i} )`:`textureSample( ${t}, ${t}_sampler, ${r}, ${s} )`:i?`textureSample( ${t}, ${t}_sampler, ${r}, ${i} )`:`textureSample( ${t}, ${t}_sampler, ${r} )`:this.generateTextureSampleLevel(e,t,r,"0",s)}generateTextureSampleLevel(e,t,r,s,i,n){return!1===this.isUnfilterable(e)?n?`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s} )`:this.isFilteredTexture(e)?this.generateFilteredTexture(e,t,r,n,s):this.generateTextureLod(e,t,r,i,n,s)}generateWrapFunction(e){const t=`tsl_coord_${Zw[e.wrapS]}S_${Zw[e.wrapT]}_${e.is3DTexture||e.isData3DTexture?"3d":"2d"}T`;let r=sC[t];if(void 0===r){const s=[],i=e.is3DTexture||e.isData3DTexture?"vec3f":"vec2f";let n=`fn ${t}( coord : ${i} ) -> ${i} {\n\n\treturn ${i}(\n`;const a=(e,t)=>{e===Vr?(s.push(iC.repeatWrapping_float),n+=`\t\ttsl_repeatWrapping_float( coord.${t} )`):e===xe?(s.push(iC.clampWrapping_float),n+=`\t\ttsl_clampWrapping_float( coord.${t} )`):e===Or?(s.push(iC.mirrorWrapping_float),n+=`\t\ttsl_mirrorWrapping_float( coord.${t} )`):(n+=`\t\tcoord.${t}`,d(`WebGPURenderer: Unsupported texture wrap type "${e}" for vertex shader.`))};a(e.wrapS,"x"),n+=",\n",a(e.wrapT,"y"),(e.is3DTexture||e.isData3DTexture)&&(n+=",\n",a(e.wrapR,"z")),n+="\n\t);\n\n}\n",sC[t]=r=new Xx(n,s)}return r.build(this),t}generateArrayDeclaration(e,t){return`array< ${this.getType(e)}, ${t} >`}generateTextureDimension(e,t,r){const s=this.getDataFromNode(e,this.shaderStage,this.globalCache);void 0===s.dimensionsSnippet&&(s.dimensionsSnippet={});let i=s.dimensionsSnippet[r];if(void 0===s.dimensionsSnippet[r]){let n,a;const{primarySamples:o}=this.renderer.backend.utils.getTextureSampleData(e),u=o>1;a=e.is3DTexture||e.isData3DTexture?"vec3":"vec2",n=u||e.isStorageTexture?t:`${t}${r?`, u32( ${r} )`:""}`,i=new Eu(new pl(`textureDimensions( ${n} )`,a)),s.dimensionsSnippet[r]=i,(e.isArrayTexture||e.isDataArrayTexture||e.is3DTexture||e.isData3DTexture)&&(s.arrayLayerCount=new Eu(new pl(`textureNumLayers(${t})`,"u32"))),e.isTextureCube&&(s.cubeFaceCount=new Eu(new pl("6u","u32")))}return i.build(this)}generateFilteredTexture(e,t,r,s,i="0u"){this._include("biquadraticTexture");const n=this.generateWrapFunction(e),a=this.generateTextureDimension(e,t,i);return s&&(r=`${r} + vec2(${s}) / ${a}`),`tsl_biquadraticTexture( ${t}, ${n}( ${r} ), ${a}, u32( ${i} ) )`}generateTextureLod(e,t,r,s,i,n="0u"){if(!0===e.isCubeTexture){i&&(r=`${r} + vec3(${i})`);return`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${e.isDepthTexture?"u32":"f32"}( ${n} ) )`}const a=this.generateWrapFunction(e),o=this.generateTextureDimension(e,t,n),u=e.is3DTexture||e.isData3DTexture?"vec3":"vec2";i&&(r=`${r} + ${u}(${i}) / ${u}( ${o} )`);return r=`${u}( clamp( floor( ${a}( ${r} ) * ${u}( ${o} ) ), ${`${u}( 0 )`}, ${`${u}( ${o} - ${"vec3"===u?"vec3( 1, 1, 1 )":"vec2( 1, 1 )"} )`} ) )`,this.generateTextureLoad(e,t,r,n,s,null)}generateTextureLoad(e,t,r,s,i,n){const a=!0===e.isStorageTexture;let o;return null!==s||a||(s="0u"),n&&(r=`${r} + ${n}`),i?o=a?`textureLoad( ${t}, ${r}, ${i} )`:`textureLoad( ${t}, ${r}, ${i}, u32( ${s} ) )`:a?o=`textureLoad( ${t}, ${r} )`:(o=`textureLoad( ${t}, ${r}, u32( ${s} ) )`,this.renderer.backend.compatibilityMode&&e.isDepthTexture&&(o+=".x")),o}generateTextureStore(e,t,r,s,i){let n;return n=s?`textureStore( ${t}, ${r}, ${s}, ${i} )`:`textureStore( ${t}, ${r}, ${i} )`,n}isSampleCompare(e){return!0===e.isDepthTexture&&null!==e.compareFunction&&this.renderer.hasCompatibility(E.TEXTURE_COMPARE)}isUnfilterable(e){return"float"!==this.getComponentTypeFromTexture(e)||!this.isAvailable("float32Filterable")&&!0===e.isDataTexture&&e.type===j||!1===this.isSampleCompare(e)&&e.minFilter===w&&e.magFilter===w||this.renderer.backend.utils.getTextureSampleData(e).primarySamples>1}generateTexture(e,t,r,s,i,n=this.shaderStage){let a=null;return a=this.isUnfilterable(e)?this.generateTextureLod(e,t,r,s,i,"0",n):this._generateTextureSample(e,t,r,s,i,n),a}generateTextureGrad(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return n?`textureSampleGrad( ${t}, ${t}_sampler, ${r}, ${s[0]}, ${s[1]}, ${n} )`:`textureSampleGrad( ${t}, ${t}_sampler, ${r}, ${s[0]}, ${s[1]} )`;o(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${a} shader.`)}generateTextureCompare(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return!0===e.isDepthTexture&&!0===e.isArrayTexture?n?`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${i}, ${s}, ${n} )`:`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${i}, ${s} )`:n?`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${s} )`;o(`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${a} shader.`)}generateTextureLevel(e,t,r,s,i,n){return!1===this.isUnfilterable(e)?n?`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s} )`:this.isFilteredTexture(e)?this.generateFilteredTexture(e,t,r,n,s):this.generateTextureLod(e,t,r,i,n,s)}generateTextureBias(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return n?`textureSampleBias( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleBias( ${t}, ${t}_sampler, ${r}, ${s} )`;o(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${a} shader.`)}getPropertyName(e,t=this.shaderStage){if(!0===e.isNodeVarying&&!0===e.needsInterpolation){if("vertex"===t)return`varyings.${e.name}`}else if(!0===e.isNodeUniform){const t=e.name,r=e.type;return"texture"===r||"cubeTexture"===r||"cubeDepthTexture"===r||"storageTexture"===r||"texture3D"===r?t:"buffer"===r||"storageBuffer"===r||"indirectStorageBuffer"===r?this.isCustomStruct(e)?t:t+".value":e.groupNode.name+"."+t}return super.getPropertyName(e)}getOutputStructName(){return"output"}getFunctionOperator(e){const t=tC[e];return void 0!==t?(this._include(t),t):null}getNodeAccess(e,t){return"compute"!==t?!0===e.isAtomic?(d("WebGPURenderer: Atomic operations are only supported in compute shaders."),ti.READ_WRITE):ti.READ_ONLY:e.access}getStorageAccess(e,t){return Qw[this.getNodeAccess(e,t)]}getUniformFromNode(e,t,r,s=null){const i=super.getUniformFromNode(e,t,r,s),n=this.getDataFromNode(e,r,this.globalCache);if(void 0===n.uniformGPU){let a;const o=e.groupNode,u=o.name,l=this.getBindGroupArray(u,r);if("texture"===t||"cubeTexture"===t||"cubeDepthTexture"===t||"storageTexture"===t||"texture3D"===t){let s=null;const n=this.getNodeAccess(e,r);"texture"===t||"storageTexture"===t?s=!0===e.value.is3DTexture?new KS(i.name,i.node,o,n):new jS(i.name,i.node,o,n):"cubeTexture"===t||"cubeDepthTexture"===t?s=new XS(i.name,i.node,o,n):"texture3D"===t&&(s=new KS(i.name,i.node,o,n)),s.store=!0===e.isStorageTextureNode,s.mipLevel=s.store?e.mipLevel:0,s.setVisibility(Jw[r]);if(!0===e.value.isCubeTexture||!1===this.isUnfilterable(e.value)&&!1===s.store){const e=new Iw(`${i.name}_sampler`,i.node,o);e.setVisibility(Jw[r]),l.push(e,s),a=[e,s]}else l.push(s),a=[s]}else if("buffer"===t||"storageBuffer"===t||"indirectStorageBuffer"===t){const n=this.getSharedDataFromNode(e);let u=n.buffer;if(void 0===u){u=new("buffer"===t?kS:kw)(e,o),n.buffer=u}u.setVisibility(u.getVisibility()|Jw[r]),l.push(u),a=u,i.name=s||"NodeBuffer_"+i.id}else{let e=this.uniformGroups[u];void 0===e?(e=new $S(u,o),e.setVisibility(Jw[r]),this.uniformGroups[u]=e,l.push(e)):(e.setVisibility(e.getVisibility()|Jw[r]),-1===l.indexOf(e)&&l.push(e)),a=this.getNodeUniform(i,t);const s=a.name;e.uniforms.some(e=>e.name===s)||e.addUniform(a)}n.uniformGPU=a}return i}getBuiltin(e,t,r,s=this.shaderStage){const i=this.builtins[s]||(this.builtins[s]=new Map);return!1===i.has(e)&&i.set(e,{name:e,property:t,type:r}),t}hasBuiltin(e,t=this.shaderStage){return void 0!==this.builtins[t]&&this.builtins[t].has(e)}getVertexIndex(){return"vertex"===this.shaderStage?this.getBuiltin("vertex_index","vertexIndex","u32","attribute"):"vertexIndex"}buildFunctionCode(e){const t=e.layout,r=this.flowShaderNode(e),s=[];for(const e of t.inputs)s.push(e.name+" : "+this.getType(e.type));let i=`fn ${t.name}( ${s.join(", ")} ) -> ${this.getType(t.type)} {\n${r.vars}\n${r.code}\n`;return r.result&&(i+=`\treturn ${r.result};\n`),i+="\n}\n",i}getInstanceIndex(){return"vertex"===this.shaderStage?this.getBuiltin("instance_index","instanceIndex","u32","attribute"):"instanceIndex"}getInvocationLocalIndex(){return this.getBuiltin("local_invocation_index","invocationLocalIndex","u32","attribute")}getSubgroupSize(){return this.enableSubGroups(),this.getBuiltin("subgroup_size","subgroupSize","u32","attribute")}getInvocationSubgroupIndex(){return this.enableSubGroups(),this.getBuiltin("subgroup_invocation_id","invocationSubgroupIndex","u32","attribute")}getSubgroupIndex(){return this.enableSubGroups(),this.getBuiltin("subgroup_id","subgroupIndex","u32","attribute")}getDrawIndex(){return null}getFrontFacing(){return this.getBuiltin("front_facing","isFront","bool")}getFragCoord(){return this.getBuiltin("position","fragCoord","vec4")+".xy"}getFragDepth(){return"output."+this.getBuiltin("frag_depth","depth","f32","output")}getClipDistance(){return"varyings.hw_clip_distances"}isFlipY(){return!1}enableDirective(e,t=this.shaderStage){(this.directives[t]||(this.directives[t]=new Set)).add(e)}getDirectives(e){const t=[],r=this.directives[e];if(void 0!==r)for(const e of r)t.push(`enable ${e};`);return t.join("\n")}enableSubGroups(){this.enableDirective("subgroups")}enableSubgroupsF16(){this.enableDirective("subgroups-f16")}enableClipDistances(){this.enableDirective("clip_distances")}enableShaderF16(){this.enableDirective("f16")}enableDualSourceBlending(){this.enableDirective("dual_source_blending")}enableHardwareClipping(e){this.enableClipDistances(),this.getBuiltin("clip_distances","hw_clip_distances",`array`,"vertex")}getBuiltins(e){const t=[],r=this.builtins[e];if(void 0!==r)for(const{name:e,property:s,type:i}of r.values())t.push(`@builtin( ${e} ) ${s} : ${i}`);return t.join(",\n\t")}getScopedArray(e,t,r,s){return!1===this.scopedArrays.has(e)&&this.scopedArrays.set(e,{name:e,scope:t,bufferType:r,bufferCount:s}),e}getScopedArrays(e){if("compute"!==e)return;const t=[];for(const{name:e,scope:r,bufferType:s,bufferCount:i}of this.scopedArrays.values()){const n=this.getType(s);t.push(`var<${r}> ${e}: array< ${n}, ${i} >;`)}return t.join("\n")}getAttributes(e){const t=[];if("compute"===e&&(this.getBuiltin("global_invocation_id","globalId","vec3","attribute"),this.getBuiltin("workgroup_id","workgroupId","vec3","attribute"),this.getBuiltin("local_invocation_id","localId","vec3","attribute"),this.getBuiltin("num_workgroups","numWorkgroups","vec3","attribute"),this.renderer.hasFeature("subgroups")&&(this.enableDirective("subgroups",e),this.getBuiltin("subgroup_size","subgroupSize","u32","attribute"))),"vertex"===e||"compute"===e){const e=this.getBuiltins("attribute");e&&t.push(e);const r=this.getAttributesArray();for(let e=0,s=r.length;e"),t.push(`\t${s+r.name} : ${i}`)}return e.output&&t.push(`\t${this.getBuiltins("output")}`),t.join(",\n")}getStructs(e){let t="";const r=this.structs[e];if(r.length>0){const e=[];for(const t of r){let r=`struct ${t.name} {\n`;r+=this.getStructMembers(t),r+="\n};",e.push(r)}t="\n"+e.join("\n\n")+"\n"}return t}getVar(e,t,r=null){let s=`var ${t} : `;return s+=null!==r?this.generateArrayDeclaration(e,r):this.getType(e),s}getVars(e){const t=[],r=this.vars[e];if(void 0!==r)for(const e of r)t.push(`\t${this.getVar(e.type,e.name,e.count)};`);return`\n${t.join("\n")}\n`}getVaryings(e){const t=[];if("vertex"===e&&this.getBuiltin("position","builtinClipSpace","vec4","vertex"),"vertex"===e||"fragment"===e){const r=this.varyings,s=this.vars[e];for(let i=0;ir.value.itemSize;return s&&!i}getUniforms(e){const t=this.uniforms[e],r=[],s=[],i=[],n={};for(const i of t){const t=i.groupNode.name,a=this.bindingsIndexes[t];if("texture"===i.type||"cubeTexture"===i.type||"cubeDepthTexture"===i.type||"storageTexture"===i.type||"texture3D"===i.type){const t=i.node.value;let s;(!0===t.isCubeTexture||!1===this.isUnfilterable(t)&&!0!==i.node.isStorageTextureNode)&&(this.isSampleCompare(t)?r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name}_sampler : sampler_comparison;`):r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name}_sampler : sampler;`));let n="";const{primarySamples:o}=this.renderer.backend.utils.getTextureSampleData(t);if(o>1&&(n="_multisampled"),!0===t.isCubeTexture&&!0===t.isDepthTexture)s="texture_depth_cube";else if(!0===t.isCubeTexture)s="texture_cube";else if(!0===t.isDepthTexture)s=this.renderer.backend.compatibilityMode&&null===t.compareFunction?`texture${n}_2d`:`texture_depth${n}_2d${!0===t.isArrayTexture?"_array":""}`;else if(!0===i.node.isStorageTextureNode){const r=Hw(t),n=this.getStorageAccess(i.node,e),a=i.node.value.is3DTexture,o=i.node.value.isArrayTexture;s=`texture_storage_${a?"3d":"2d"+(o?"_array":"")}<${r}, ${n}>`}else if(!0===t.isArrayTexture||!0===t.isDataArrayTexture||!0===t.isCompressedArrayTexture)s="texture_2d_array";else if(!0===t.is3DTexture||!0===t.isData3DTexture)s="texture_3d";else{s=`texture${n}_2d<${this.getComponentTypeFromTexture(t).charAt(0)}32>`}r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name} : ${s};`)}else if("buffer"===i.type||"storageBuffer"===i.type||"indirectStorageBuffer"===i.type){const t=i.node,r=this.getType(t.getNodeType(this)),n=t.bufferCount,o=n>0&&"buffer"===i.type?", "+n:"",u=t.isStorageBufferNode?`storage, ${this.getStorageAccess(t,e)}`:"uniform";if(this.isCustomStruct(i))s.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var<${u}> ${i.name} : ${r};`);else{const e=`\tvalue : array< ${t.isAtomic?`atomic<${r}>`:`${r}`}${o} >`;s.push(this._getWGSLStructBinding(i.name,e,u,a.binding++,a.group))}}else{const e=i.groupNode.name;if(void 0===n[e]){const t=this.uniformGroups[e];if(void 0!==t){const r=[];for(const e of t.uniforms){const t=e.getType(),s=this.getType(this.getVectorType(t));r.push(`\t${e.name} : ${s}`)}let s=this.uniformGroupsBindings[e];void 0===s&&(s={index:a.binding++,id:a.group},this.uniformGroupsBindings[e]=s),n[e]={index:s.index,id:s.id,snippets:r}}}}}for(const e in n){const t=n[e];i.push(this._getWGSLStructBinding(e,t.snippets.join(",\n"),"uniform",t.index,t.id))}return[...r,...s,...i].join("\n")}buildCode(){const e=null!==this.material?{fragment:{},vertex:{}}:{compute:{}};this.sortBindingGroups();for(const t in e){this.shaderStage=t;const r=e[t];r.uniforms=this.getUniforms(t),r.attributes=this.getAttributes(t),r.varyings=this.getVaryings(t),r.structs=this.getStructs(t),r.vars=this.getVars(t),r.codes=this.getCodes(t),r.directives=this.getDirectives(t),r.scopedArrays=this.getScopedArrays(t);let s="// code\n\n";s+=this.flowCode[t];const i=this.flowNodes[t],n=i[i.length-1],a=n.outputNode,o=void 0!==a&&!0===a.isOutputStructNode;for(const e of i){const i=this.getFlowData(e),u=e.name;if(u&&(s.length>0&&(s+="\n"),s+=`\t// flow -> ${u}\n`),s+=`${i.code}\n\t`,e===n&&"compute"!==t)if(s+="// result\n\n\t","vertex"===t)s+=`varyings.builtinClipSpace = ${i.result};`;else if("fragment"===t)if(o)r.returnType=a.getNodeType(this),r.structs+="var output : "+r.returnType+";",s+=`return ${i.result};`;else{let e="\t@location(0) color: vec4";const t=this.getBuiltins("output");t&&(e+=",\n\t"+t),r.returnType="OutputStruct",r.structs+=this._getWGSLStruct("OutputStruct",e),r.structs+="\nvar output : OutputStruct;",s+=`output.color = ${i.result};\n\n\treturn output;`}}r.flow=s}if(this.shaderStage=null,null!==this.material)this.vertexShader=this._getWGSLVertexCode(e.vertex),this.fragmentShader=this._getWGSLFragmentCode(e.fragment);else{const t=this.object.workgroupSize;this.computeShader=this._getWGSLComputeCode(e.compute,t)}}getMethod(e,t=null){let r;return null!==t&&(r=this._getWGSLMethod(e+"_"+t)),void 0===r&&(r=this._getWGSLMethod(e)),r||e}getBitcastMethod(e){return`bitcast<${this.getType(e)}>`}getFloatPackingMethod(e){return this.getMethod(`floatpack_${e}_2x16`)}getFloatUnpackingMethod(e){return this.getMethod(`floatunpack_${e}_2x16`)}getTernary(e,t,r){return`select( ${r}, ${t}, ${e} )`}getType(e){return rC[e]||e}isAvailable(e){let t=eC[e];return void 0===t&&("float32Filterable"===e?t=this.renderer.hasFeature("float32-filterable"):"clipDistance"===e&&(t=this.renderer.hasFeature("clip-distances")),eC[e]=t),t}_getWGSLMethod(e){return void 0!==iC[e]&&this._include(e),nC[e]}_include(e){const t=iC[e];return t.build(this),this.addInclude(t),t}_getWGSLVertexCode(e){return`${this.getSignature()}\n// directives\n${e.directives}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// varyings\n${e.varyings}\nvar varyings : VaryingsStruct;\n\n// codes\n${e.codes}\n\n@vertex\nfn main( ${e.attributes} ) -> VaryingsStruct {\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n\treturn varyings;\n\n}\n`}_getWGSLFragmentCode(e){return`${this.getSignature()}\n// global\n${aC}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// codes\n${e.codes}\n\n@fragment\nfn main( ${e.varyings} ) -> ${e.returnType} {\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n}\n`}_getWGSLComputeCode(e,t){const[r,s,i]=t;return`${this.getSignature()}\n// directives\n${e.directives}\n\n// system\nvar instanceIndex : u32;\n\n// locals\n${e.scopedArrays}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// codes\n${e.codes}\n\n@compute @workgroup_size( ${r}, ${s}, ${i} )\nfn main( ${e.attributes} ) {\n\n\t// system\n\tinstanceIndex = globalId.x\n\t\t+ globalId.y * ( ${r} * numWorkgroups.x )\n\t\t+ globalId.z * ( ${r} * numWorkgroups.x ) * ( ${s} * numWorkgroups.y );\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n}\n`}_getWGSLStruct(e,t){return`\nstruct ${e} {\n${t}\n};`}_getWGSLStructBinding(e,t,r,s=0,i=0){const n=e+"Struct";return`${this._getWGSLStruct(n,t)}\n@binding( ${s} ) @group( ${i} )\nvar<${r}> ${e} : ${n};`}}class uC{constructor(e){this.backend=e}getCurrentDepthStencilFormat(e){let t;return e.depth&&(t=null!==e.depthTexture?this.getTextureFormatGPU(e.depthTexture):e.stencil?BE:PE),t}getTextureFormatGPU(e){return this.backend.get(e).format}getTextureSampleData(e){let t;if(e.isFramebufferTexture)t=1;else if(e.isDepthTexture&&!e.renderTarget){const e=this.backend.renderer,r=e.getRenderTarget();t=r?r.samples:e.currentSamples}else e.renderTarget&&(t=e.renderTarget.samples);t=t||1;const r=t>1&&null!==e.renderTarget&&!0!==e.isDepthTexture&&!0!==e.isFramebufferTexture;return{samples:t,primarySamples:r?1:t,isMSAA:r}}getCurrentColorFormat(e){let t;return t=null!==e.textures?this.getTextureFormatGPU(e.textures[0]):this.getPreferredCanvasFormat(),t}getCurrentColorFormats(e){return null!==e.textures?e.textures.map(e=>this.getTextureFormatGPU(e)):[this.getPreferredCanvasFormat()]}getCurrentColorSpace(e){return null!==e.textures?e.textures[0].colorSpace:this.backend.renderer.outputColorSpace}getPrimitiveTopology(e,t){return e.isPoints?AR:e.isLineSegments||e.isMesh&&!0===t.wireframe?wR:e.isLine?CR:e.isMesh?MR:void 0}getSampleCount(e){return e>=4?4:1}getSampleCountRenderContext(e){return null!==e.textures?this.getSampleCount(e.sampleCount):this.getSampleCount(this.backend.renderer.currentSamples)}getPreferredCanvasFormat(){const e=this.backend.parameters.outputType;if(void 0===e)return navigator.gpu.getPreferredCanvasFormat();if(e===Ge)return bE;if(e===be)return wE;throw new Error("Unsupported output buffer type.")}}const lC=new Map([[Int8Array,["sint8","snorm8"]],[Uint8Array,["uint8","unorm8"]],[Int16Array,["sint16","snorm16"]],[Uint16Array,["uint16","unorm16"]],[Int32Array,["sint32","snorm32"]],[Uint32Array,["uint32","unorm32"]],[Float32Array,["float32"]]]);"undefined"!=typeof Float16Array&&lC.set(Float16Array,["float16"]);const dC=new Map([[ot,["float16"]]]),cC=new Map([[Int32Array,"sint32"],[Int16Array,"sint32"],[Uint32Array,"uint32"],[Uint16Array,"uint32"],[Float32Array,"float32"]]);class hC{constructor(e){this.backend=e}createAttribute(e,t){const r=this._getBufferAttribute(e),s=this.backend,i=s.get(r);let n=i.buffer;if(void 0===n){const a=s.device;let o=r.array;if(!1===e.normalized)if(o.constructor===Int16Array||o.constructor===Int8Array)o=new Int32Array(o);else if((o.constructor===Uint16Array||o.constructor===Uint8Array)&&(o=new Uint32Array(o),t&GPUBufferUsage.INDEX))for(let e=0;e0&&(void 0===n.groups&&(n.groups=[],n.versions=[]),n.versions[r]===s&&(o=n.groups[r])),void 0===o&&(o=this.createBindGroup(e,a),r>0&&(n.groups[r]=o,n.versions[r]=s)),n.group=o}updateBinding(e){const t=this.backend,r=t.device,s=e.buffer,i=t.get(e).buffer,n=e.updateRanges;if(0===n.length)r.queue.writeBuffer(i,0,s,0);else{const e=Kr(s),t=e?1:s.BYTES_PER_ELEMENT;for(let a=0,o=n.length;a1&&(i+=`-${e.texture.depthOrArrayLayers}`),i+=`-${r}-${s}`,a=e[i],void 0===a){const n=Lw;let o;o=t.isSampledCubeTexture?Mw:t.isSampledTexture3D?Fw:t.texture.isArrayTexture||t.texture.isDataArrayTexture||t.texture.isCompressedArrayTexture?Cw:ww,a=e[i]=e.texture.createView({aspect:n,dimension:o,mipLevelCount:r,baseMipLevel:s})}}n.push({binding:i,resource:a})}else if(t.isSampler){const e=r.get(t.texture);n.push({binding:i,resource:e.sampler})}i++}return s.createBindGroup({label:"bindGroup_"+e.name,layout:t,entries:n})}_createLayoutEntries(e){const t=[];let r=0;for(const s of e.bindings){const e=this.backend,i={binding:r,visibility:s.visibility};if(s.isUniformBuffer||s.isStorageBuffer){const e={};s.isStorageBuffer&&(s.visibility&LR.COMPUTE&&(s.access===ti.READ_WRITE||s.access===ti.WRITE_ONLY)?e.type=gw:e.type=mw),i.buffer=e}else if(s.isSampledTexture&&s.store){const e={};e.format=this.backend.get(s.texture).texture.format;const t=s.access;e.access=t===ti.READ_WRITE?bw:t===ti.WRITE_ONLY?fw:yw,s.texture.isArrayTexture?e.viewDimension=Cw:s.texture.is3DTexture&&(e.viewDimension=Fw),i.storageTexture=e}else if(s.isSampledTexture){const t={},{primarySamples:r}=e.utils.getTextureSampleData(s.texture);if(r>1&&(t.multisampled=!0,s.texture.isDepthTexture||(t.sampleType=vw)),s.texture.isDepthTexture)e.compatibilityMode&&null===s.texture.compareFunction?t.sampleType=vw:t.sampleType=Nw;else if(s.texture.isDataTexture||s.texture.isDataArrayTexture||s.texture.isData3DTexture){const e=s.texture.type;e===R?t.sampleType=Sw:e===S?t.sampleType=Rw:e===j&&(this.backend.hasFeature("float32-filterable")?t.sampleType=_w:t.sampleType=vw)}s.isSampledCubeTexture?t.viewDimension=Mw:s.texture.isArrayTexture||s.texture.isDataArrayTexture||s.texture.isCompressedArrayTexture?t.viewDimension=Cw:s.isSampledTexture3D&&(t.viewDimension=Fw),i.texture=t}else if(s.isSampler){const t={};s.texture.isDepthTexture&&(null!==s.texture.compareFunction&&e.hasCompatibility(E.TEXTURE_COMPARE)?t.type=Tw:t.type=xw),i.sampler=t}else o(`WebGPUBindingUtils: Unsupported binding "${s}".`);t.push(i),r++}return t}deleteBindGroupData(e){const{backend:t}=this,r=t.get(e);r.layout&&(r.layout.usedTimes--,0===r.layout.usedTimes&&this._bindGroupLayoutCache.delete(r.layoutKey),r.layout=void 0,r.layoutKey=void 0)}dispose(){this._bindGroupLayoutCache.clear()}}class mC{constructor(e){this.backend=e,this._activePipelines=new WeakMap}setPipeline(e,t){this._activePipelines.get(e)!==t&&(e.setPipeline(t),this._activePipelines.set(e,t))}_getSampleCount(e){return this.backend.utils.getSampleCountRenderContext(e)}createRenderPipeline(e,t){const{object:r,material:s,geometry:i,pipeline:n}=e,{vertexProgram:a,fragmentProgram:u}=n,l=this.backend,d=l.device,c=l.utils,h=l.get(n),p=[];for(const t of e.getBindings()){const e=l.get(t),{layoutGPU:r}=e.layout;p.push(r)}const g=l.attributeUtils.createShaderVertexBuffers(e);let m;s.blending===ee||s.blending===ze&&!1===s.transparent||(m=this._getBlending(s));let f={};!0===s.stencilWrite&&(f={compare:this._getStencilCompare(s),failOp:this._getStencilOperation(s.stencilFail),depthFailOp:this._getStencilOperation(s.stencilZFail),passOp:this._getStencilOperation(s.stencilZPass)});const y=this._getColorWriteMask(s),b=[];if(null!==e.context.textures){const t=e.context.textures,r=e.context.mrt;for(let e=0;e1},layout:d.createPipelineLayout({bindGroupLayouts:p})},E={},A=e.context.depth,w=e.context.stencil;if(!0!==A&&!0!==w||(!0===A&&(E.format=N,E.depthWriteEnabled=s.depthWrite,E.depthCompare=v),!0===w&&(E.stencilFront=f,E.stencilBack={},E.stencilReadMask=s.stencilFuncMask,E.stencilWriteMask=s.stencilWriteMask),!0===s.polygonOffset&&(E.depthBias=s.polygonOffsetUnits,E.depthBiasSlopeScale=s.polygonOffsetFactor,E.depthBiasClamp=0),R.depthStencil=E),d.pushErrorScope("validation"),null===t)h.pipeline=d.createRenderPipeline(R),d.popErrorScope().then(e=>{null!==e&&(h.error=!0,o(e.message))});else{const e=new Promise(async e=>{try{h.pipeline=await d.createRenderPipelineAsync(R)}catch(e){}const t=await d.popErrorScope();null!==t&&(h.error=!0,o(t.message)),e()});t.push(e)}}createBundleEncoder(e,t="renderBundleEncoder"){const r=this.backend,{utils:s,device:i}=r,n=s.getCurrentDepthStencilFormat(e),a={label:t,colorFormats:s.getCurrentColorFormats(e),depthStencilFormat:n,sampleCount:this._getSampleCount(e)};return i.createRenderBundleEncoder(a)}createComputePipeline(e,t){const r=this.backend,s=r.device,i=r.get(e.computeProgram).module,n=r.get(e),a=[];for(const e of t){const t=r.get(e),{layoutGPU:s}=t.layout;a.push(s)}n.pipeline=s.createComputePipeline({compute:i,layout:s.createPipelineLayout({bindGroupLayouts:a})})}_getBlending(e){let t,r;const s=e.blending,i=e.blendSrc,n=e.blendDst,a=e.blendEquation;if(s===ht){const s=null!==e.blendSrcAlpha?e.blendSrcAlpha:i,o=null!==e.blendDstAlpha?e.blendDstAlpha:n,u=null!==e.blendEquationAlpha?e.blendEquationAlpha:a;t={srcFactor:this._getBlendFactor(i),dstFactor:this._getBlendFactor(n),operation:this._getBlendOperation(a)},r={srcFactor:this._getBlendFactor(s),dstFactor:this._getBlendFactor(o),operation:this._getBlendOperation(u)}}else{const i=(e,s,i,n)=>{t={srcFactor:e,dstFactor:s,operation:JA},r={srcFactor:i,dstFactor:n,operation:JA}};if(e.premultipliedAlpha)switch(s){case ze:i(GA,HA,GA,HA);break;case qt:i(GA,GA,GA,GA);break;case Ht:i(kA,$A,kA,GA);break;case Wt:i(qA,HA,kA,GA)}else switch(s){case ze:i(WA,HA,GA,HA);break;case qt:i(WA,GA,GA,GA);break;case Ht:o(`WebGPURenderer: "SubtractiveBlending" requires "${e.isMaterial?"material":"blendMode"}.premultipliedAlpha = true".`);break;case Wt:o(`WebGPURenderer: "MultiplyBlending" requires "${e.isMaterial?"material":"blendMode"}.premultipliedAlpha = true".`)}}if(void 0!==t&&void 0!==r)return{color:t,alpha:r};o("WebGPURenderer: Invalid blending: ",s)}_getBlendFactor(e){let t;switch(e){case pt:t=kA;break;case kt:t=GA;break;case Vt:t=zA;break;case Dt:t=$A;break;case $e:t=WA;break;case We:t=HA;break;case It:t=qA;break;case Bt:t=jA;break;case Ut:t=XA;break;case Pt:t=KA;break;case Ot:t=YA;break;case 211:t=QA;break;case 212:t=ZA;break;default:o("WebGPURenderer: Blend factor not supported.",e)}return t}_getStencilCompare(e){let t;const r=e.stencilFunc;switch(r){case ss:t=PR;break;case rs:t=kR;break;case ts:t=BR;break;case es:t=UR;break;case Jr:t=DR;break;case Zr:t=VR;break;case Qr:t=IR;break;case Yr:t=OR;break;default:o("WebGPURenderer: Invalid stencil function.",r)}return t}_getStencilOperation(e){let t;switch(e){case cs:t=aw;break;case ds:t=ow;break;case ls:t=uw;break;case us:t=lw;break;case os:t=dw;break;case as:t=cw;break;case ns:t=hw;break;case is:t=pw;break;default:o("WebGPURenderer: Invalid stencil operation.",t)}return t}_getBlendOperation(e){let t;switch(e){case He:t=JA;break;case Lt:t=ew;break;case Ft:t=tw;break;case ps:t=rw;break;case hs:t=sw;break;default:o("WebGPUPipelineUtils: Blend equation not supported.",e)}return t}_getPrimitiveState(e,t,r){const s={},i=this.backend.utils;s.topology=i.getPrimitiveTopology(e,r),null!==t.index&&!0===e.isLine&&!0!==e.isLineSegments&&(s.stripIndexFormat=t.index.array instanceof Uint16Array?XR:KR);let n=r.side===M;return e.isMesh&&e.matrixWorld.determinant()<0&&(n=!n),s.frontFace=!0===n?HR:WR,s.cullMode=r.side===F?qR:jR,s}_getColorWriteMask(e){return!0===e.colorWrite?nw:iw}_getDepthCompare(e){let t;if(!1===e.depthTest)t=kR;else{const r=e.depthFunc;switch(r){case er:t=PR;break;case Jt:t=kR;break;case Zt:t=BR;break;case Qt:t=UR;break;case Yt:t=DR;break;case Kt:t=VR;break;case Xt:t=IR;break;case jt:t=OR;break;default:o("WebGPUPipelineUtils: Invalid depth function.",r)}}return t}}class fC extends SR{constructor(e,t,r=2048){super(r),this.device=e,this.type=t,this.querySet=this.device.createQuerySet({type:"timestamp",count:this.maxQueries,label:`queryset_global_timestamp_${t}`});const s=8*this.maxQueries;this.resolveBuffer=this.device.createBuffer({label:`buffer_timestamp_resolve_${t}`,size:s,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),this.resultBuffer=this.device.createBuffer({label:`buffer_timestamp_result_${t}`,size:s,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ})}allocateQueriesForContext(e){if(!this.trackTimestamp||this.isDisposed)return null;if(this.currentQueryIndex+2>this.maxQueries)return v(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`),null;const t=this.currentQueryIndex;return this.currentQueryIndex+=2,this.queryOffsets.set(e,t),t}async resolveQueriesAsync(){if(!this.trackTimestamp||0===this.currentQueryIndex||this.isDisposed)return this.lastValue;if(this.pendingResolve)return this.pendingResolve;this.pendingResolve=this._resolveQueries();try{return await this.pendingResolve}finally{this.pendingResolve=null}}async _resolveQueries(){if(this.isDisposed)return this.lastValue;try{if("unmapped"!==this.resultBuffer.mapState)return this.lastValue;const e=new Map(this.queryOffsets),t=this.currentQueryIndex,r=8*t;this.currentQueryIndex=0,this.queryOffsets.clear();const s=this.device.createCommandEncoder();s.resolveQuerySet(this.querySet,0,t,this.resolveBuffer,0),s.copyBufferToBuffer(this.resolveBuffer,0,this.resultBuffer,0,r);const i=s.finish();if(this.device.queue.submit([i]),"unmapped"!==this.resultBuffer.mapState)return this.lastValue;if(await this.resultBuffer.mapAsync(GPUMapMode.READ,0,r),this.isDisposed)return"mapped"===this.resultBuffer.mapState&&this.resultBuffer.unmap(),this.lastValue;const n=new BigUint64Array(this.resultBuffer.getMappedRange(0,r)),a={},o=[];for(const[t,r]of e){const e=t.match(/^(.*):f(\d+)$/),s=parseInt(e[2]);!1===o.includes(s)&&o.push(s),void 0===a[s]&&(a[s]=0);const i=n[r],u=n[r+1],l=Number(u-i)/1e6;this.timestamps.set(t,l),a[s]+=l}const u=a[o[o.length-1]];return this.resultBuffer.unmap(),this.lastValue=u,this.frames=o,u}catch(e){return o("Error resolving queries:",e),"mapped"===this.resultBuffer.mapState&&this.resultBuffer.unmap(),this.lastValue}}async dispose(){if(!this.isDisposed){if(this.isDisposed=!0,this.pendingResolve)try{await this.pendingResolve}catch(e){o("Error waiting for pending resolve:",e)}if(this.resultBuffer&&"mapped"===this.resultBuffer.mapState)try{this.resultBuffer.unmap()}catch(e){o("Error unmapping buffer:",e)}this.querySet&&(this.querySet.destroy(),this.querySet=null),this.resolveBuffer&&(this.resolveBuffer.destroy(),this.resolveBuffer=null),this.resultBuffer&&(this.resultBuffer.destroy(),this.resultBuffer=null),this.queryOffsets.clear(),this.pendingResolve=null}}}class yC extends aR{constructor(e={}){super(e),this.isWebGPUBackend=!0,this.parameters.alpha=void 0===e.alpha||e.alpha,this.parameters.requiredLimits=void 0===e.requiredLimits?{}:e.requiredLimits,this.compatibilityMode=null,this.device=null,this.defaultRenderPassdescriptor=null,this.utils=new uC(this),this.attributeUtils=new hC(this),this.bindingUtils=new gC(this),this.pipelineUtils=new mC(this),this.textureUtils=new Ww(this),this.occludedResolveCache=new Map;const t="undefined"==typeof navigator||!1===/Android/.test(navigator.userAgent);this._compatibility={[E.TEXTURE_COMPARE]:t}}async init(e){await super.init(e);const t=this.parameters;let r;if(void 0===t.device){const e={powerPreference:t.powerPreference,featureLevel:"compatibility"},s="undefined"!=typeof navigator?await navigator.gpu.requestAdapter(e):null;if(null===s)throw new Error("WebGPUBackend: Unable to create WebGPU adapter.");const i=Object.values(Dw),n=[];for(const e of i)s.features.has(e)&&n.push(e);const a={requiredFeatures:n,requiredLimits:t.requiredLimits};r=await s.requestDevice(a)}else r=t.device;this.compatibilityMode=!r.features.has("core-features-and-limits"),r.lost.then(t=>{if("destroyed"===t.reason)return;const r={api:"WebGPU",message:t.message||"Unknown reason",reason:t.reason||null,originalEvent:t};e.onDeviceLost(r)}),this.device=r,this.trackTimestamp=this.trackTimestamp&&this.hasFeature(Dw.TimestampQuery),this.updateSize()}get context(){const e=this.renderer.getCanvasTarget(),t=this.get(e);let r=t.context;if(void 0===r){const s=this.parameters;r=!0===e.isDefaultCanvasTarget&&void 0!==s.context?s.context:e.domElement.getContext("webgpu"),"setAttribute"in e.domElement&&e.domElement.setAttribute("data-engine",`three.js r${ut} webgpu`);const i=s.alpha?"premultiplied":"opaque",n=s.outputType===be?"extended":"standard";r.configure({device:this.device,format:this.utils.getPreferredCanvasFormat(),usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_SRC,alphaMode:i,toneMapping:{mode:n}}),t.context=r}return r}get coordinateSystem(){return h}async getArrayBufferAsync(e){return await this.attributeUtils.getArrayBufferAsync(e)}getContext(){return this.context}_getDefaultRenderPassDescriptor(){const e=this.renderer,t=e.getCanvasTarget(),r=this.get(t),s=e.currentSamples;let i=r.descriptor;if(void 0===i||r.samples!==s){i={colorAttachments:[{view:null}]},!0!==e.depth&&!0!==e.stencil||(i.depthStencilAttachment={view:this.textureUtils.getDepthBuffer(e.depth,e.stencil).createView()});const t=i.colorAttachments[0];s>0?t.view=this.textureUtils.getColorBuffer().createView():t.resolveTarget=void 0,r.descriptor=i,r.samples=s}const n=i.colorAttachments[0];return s>0?n.resolveTarget=this.context.getCurrentTexture().createView():n.view=this.context.getCurrentTexture().createView(),i}_isRenderCameraDepthArray(e){return e.depthTexture&&e.depthTexture.image.depth>1&&e.camera.isArrayCamera}_getRenderPassDescriptor(e,t={}){const r=e.renderTarget,s=this.get(r);let i=s.descriptors;void 0!==i&&s.width===r.width&&s.height===r.height&&s.samples===r.samples||(i={},s.descriptors=i);const n=e.getCacheKey();let a=i[n];if(void 0===a){const t=e.textures,o=[];let u;const l=this._isRenderCameraDepthArray(e);for(let s=0;s1)if(!0===l){const t=e.camera.cameras;for(let e=0;e0&&(t.currentOcclusionQuerySet&&t.currentOcclusionQuerySet.destroy(),t.currentOcclusionQueryBuffer&&t.currentOcclusionQueryBuffer.destroy(),t.currentOcclusionQuerySet=t.occlusionQuerySet,t.currentOcclusionQueryBuffer=t.occlusionQueryBuffer,t.currentOcclusionQueryObjects=t.occlusionQueryObjects,i=r.createQuerySet({type:"occlusion",count:s,label:`occlusionQuerySet_${e.id}`}),t.occlusionQuerySet=i,t.occlusionQueryIndex=0,t.occlusionQueryObjects=new Array(s),t.lastOcclusionObject=null),n=null===e.textures?this._getDefaultRenderPassDescriptor():this._getRenderPassDescriptor(e,{loadOp:zR}),this.initTimestampQuery(Ct.RENDER,this.getTimestampUID(e),n),n.occlusionQuerySet=i;const a=n.depthStencilAttachment;if(null!==e.textures){const t=n.colorAttachments;for(let r=0;r0&&t.currentPass.executeBundles(t.renderBundles),r>t.occlusionQueryIndex&&t.currentPass.endOcclusionQuery();const s=t.encoder;if(!0===this._isRenderCameraDepthArray(e)){const r=[];for(let e=0;e0){const s=8*r;let i=this.occludedResolveCache.get(s);void 0===i&&(i=this.device.createBuffer({size:s,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),this.occludedResolveCache.set(s,i));const n=this.device.createBuffer({size:s,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});t.encoder.resolveQuerySet(t.occlusionQuerySet,0,r,i,0),t.encoder.copyBufferToBuffer(i,0,n,0,s),t.occlusionQueryBuffer=n,this.resolveOccludedAsync(e)}if(this.device.queue.submit([t.encoder.finish()]),null!==e.textures){const t=e.textures;for(let e=0;eo&&(i[0]=Math.min(a,o),i[1]=Math.ceil(a/o)),n.dispatchSize=i}i=n.dispatchSize}a.dispatchWorkgroups(i[0],i[1]||1,i[2]||1)}finishCompute(e){const t=this.get(e);t.passEncoderGPU.end(),this.device.queue.submit([t.cmdEncoderGPU.finish()])}draw(e,t){const{object:r,material:s,context:i,pipeline:n}=e,a=e.getBindings(),o=this.get(i),u=this.get(n),l=u.pipeline;if(!0===u.error)return;const d=e.getIndex(),c=null!==d,h=e.getDrawParameters();if(null===h)return;const p=(t,r)=>{this.pipelineUtils.setPipeline(t,l),r.pipeline=l;const n=r.bindingGroups;for(let e=0,r=a.length;e{if(p(s,i),!0===r.isBatchedMesh){const e=r._multiDrawStarts,i=r._multiDrawCounts,n=r._multiDrawCount,a=r._multiDrawInstances;null!==a&&v("WebGPUBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection.");for(let o=0;o1?0:o;!0===c?s.drawIndexed(i[o],n,e[o]/d.array.BYTES_PER_ELEMENT,0,u):s.draw(i[o],n,e[o],u),t.update(r,i[o],n)}}else if(!0===c){const{vertexCount:i,instanceCount:n,firstVertex:a}=h,o=e.getIndirect();if(null!==o){const t=this.get(o).buffer,r=e.getIndirectOffset(),i=Array.isArray(r)?r:[r];for(let e=0;e0){const t=this.get(e.camera),s=e.camera.cameras,n=e.getBindingGroup("cameraIndex");if(void 0===t.indexesGPU||t.indexesGPU.length!==s.length){const e=this.get(n),r=[],i=new Uint32Array([0,0,0,0]);for(let t=0,n=s.length;t(d("WebGPURenderer: WebGPU is not available, running under WebGL2 backend."),new ER(e)));super(new t(e),e),this.library=new TC,this.isWebGPURenderer=!0}}class vC extends As{constructor(){super(),this.isBundleGroup=!0,this.type="BundleGroup",this.static=!0,this.version=0}set needsUpdate(e){!0===e&&this.version++}}class NC{constructor(e,t=En(0,0,1,1)){this.renderer=e,this.outputNode=t,this.outputColorTransform=!0,this.needsUpdate=!0;const r=new Zp;r.name="RenderPipeline",this._quadMesh=new Wb(r),this._quadMesh.name="Render Pipeline",this._context=null}render(){const e=this.renderer;this._update(),null!==this._context.onBeforeRenderPipeline&&this._context.onBeforeRenderPipeline();const t=e.toneMapping,r=e.outputColorSpace;e.toneMapping=m,e.outputColorSpace=p.workingColorSpace;const s=e.xr.enabled;e.xr.enabled=!1,this._quadMesh.render(e),e.xr.enabled=s,e.toneMapping=t,e.outputColorSpace=r,null!==this._context.onAfterRenderPipeline&&this._context.onAfterRenderPipeline()}get context(){return this._context}dispose(){this._quadMesh.material.dispose()}_update(){if(!0===this.needsUpdate){const e=this.renderer,t=e.toneMapping,r=e.outputColorSpace,s={renderPipeline:this,onBeforeRenderPipeline:null,onAfterRenderPipeline:null};let i=this.outputNode;!0===this.outputColorTransform?(i=i.context(s),i=yl(i,t,r)):(s.toneMapping=t,s.outputColorSpace=r,i=i.context(s)),this._context=s,this._quadMesh.material.fragmentNode=i,this._quadMesh.material.needsUpdate=!0,this.needsUpdate=!1}}async renderAsync(){v('RenderPipeline: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await this.renderer.init(),this.render()}}class SC extends NC{constructor(e,t){v('PostProcessing: "PostProcessing" has been renamed to "RenderPipeline". Please update your code to use "THREE.RenderPipeline" instead.'),super(e,t)}}class RC extends N{constructor(e=1,t=1){super(),this.image={width:e,height:t},this.magFilter=oe,this.minFilter=oe,this.isStorageTexture=!0,this.mipmapsAutoUpdate=!0}setSize(e,t){this.image.width===e&&this.image.height===t||(this.image.width=e,this.image.height=t,this.dispose())}}class EC extends sx{constructor(e,t){super(e,t,Uint32Array),this.isIndirectStorageBufferAttribute=!0}}class AC extends ws{constructor(e){super(e),this.textures={},this.nodes={}}load(e,t,r,s){const i=new Cs(this.manager);i.setPath(this.path),i.setRequestHeader(this.requestHeader),i.setWithCredentials(this.withCredentials),i.load(e,r=>{try{t(this.parse(JSON.parse(r)))}catch(t){s?s(t):o(t),this.manager.itemError(e)}},r,s)}parseNodes(e){const t={};if(void 0!==e){for(const r of e){const{uuid:e,type:s}=r;t[e]=this.createNodeFromType(s),t[e].uuid=e}const r={nodes:t,textures:this.textures};for(const s of e){s.meta=r;t[s.uuid].deserialize(s),delete s.meta}}return t}parse(e){const t=this.createNodeFromType(e.type);t.uuid=e.uuid;const r={nodes:this.parseNodes(e.nodes),textures:this.textures};return e.meta=r,t.deserialize(e),delete e.meta,t}setTextures(e){return this.textures=e,this}setNodes(e){return this.nodes=e,this}createNodeFromType(e){return void 0===this.nodes[e]?(o("NodeLoader: Node type not found:",e),gn()):new this.nodes[e]}}class wC extends Ms{constructor(e){super(e),this.nodes={},this.nodeMaterials={}}parse(e){const t=super.parse(e),r=this.nodes,s=e.inputNodes;for(const e in s){const i=s[e];t[e]=r[i]}return t}setNodes(e){return this.nodes=e,this}setNodeMaterials(e){return this.nodeMaterials=e,this}createMaterialFromType(e){const t=this.nodeMaterials[e];return void 0!==t?new t:super.createMaterialFromType(e)}}class CC extends Fs{constructor(e){super(e),this.nodes={},this.nodeMaterials={},this._nodesJSON=null}setNodes(e){return this.nodes=e,this}setNodeMaterials(e){return this.nodeMaterials=e,this}parse(e,t){this._nodesJSON=e.nodes;const r=super.parse(e,t);return this._nodesJSON=null,r}parseNodes(e,t){if(void 0!==e){const r=new AC;return r.setNodes(this.nodes),r.setTextures(t),r.parseNodes(e)}return{}}parseMaterials(e,t){const r={};if(void 0!==e){const s=this.parseNodes(this._nodesJSON,t),i=new wC;i.setTextures(t),i.setNodes(s),i.setNodeMaterials(this.nodeMaterials);for(let t=0,s=e.length;t0){const{width:r,height:s}=e.context;t.bufferWidth=r,t.bufferHeight=s}t.lights=this.getLightsData(e.lightsNode.getLights()),this.renderObjects.set(e,t)}return t}getAttributesData(e){const t={};for(const r in e){const s=e[r];t[r]={version:s.version}}return t}containsNode(e){const t=e.material;for(const e in t)if(t[e]&&t[e].isNode)return!0;return!!(e.context.modelViewMatrix||e.context.modelNormalViewMatrix||e.context.getAO||e.context.getShadow)}getMaterialData(e){const t={};for(const r of this.refreshUniforms){const s=e[r];null!=s&&("object"==typeof s&&void 0!==s.clone?!0===s.isTexture?t[r]={id:s.id,version:s.version}:t[r]=s.clone():t[r]=s)}return t}equals(e,t){const{object:r,material:s,geometry:i}=e,n=this.getRenderObjectData(e);if(!0!==n.worldMatrix.equals(r.matrixWorld))return n.worldMatrix.copy(r.matrixWorld),!1;const a=n.material;for(const e in a){const t=a[e],r=s[e];if(void 0!==t.equals){if(!1===t.equals(r))return t.copy(r),!1}else if(!0===r.isTexture){if(t.id!==r.id||t.version!==r.version)return t.id=r.id,t.version=r.version,!1}else if(t!==r)return a[e]=r,!1}if(a.transmission>0){const{width:t,height:r}=e.context;if(n.bufferWidth!==t||n.bufferHeight!==r)return n.bufferWidth=t,n.bufferHeight=r,!1}const o=n.geometry,u=i.attributes,l=o.attributes,d=Object.keys(l),c=Object.keys(u);if(o.id!==i.id)return o.id=i.id,!1;if(d.length!==c.length)return n.geometry.attributes=this.getAttributesData(u),!1;for(const e of d){const t=l[e],r=u[e];if(void 0===r)return delete l[e],!1;if(t.version!==r.version)return t.version=r.version,!1}const h=i.index,p=o.indexVersion,g=h?h.version:null;if(p!==g)return o.indexVersion=g,!1;if(o.drawRange.start!==i.drawRange.start||o.drawRange.count!==i.drawRange.count)return o.drawRange.start=i.drawRange.start,o.drawRange.count=i.drawRange.count,!1;if(n.morphTargetInfluences){let e=!1;for(let t=0;t>>16,2246822507),r^=Math.imul(s^s>>>13,3266489909),s=Math.imul(s^s>>>16,2246822507),s^=Math.imul(r^r>>>13,3266489909),4294967296*(2097151&s)+(r>>>0)}const Ds=e=>Ps(e),Us=e=>Ps(e),Is=(...e)=>Ps(e),Os=new Map([[1,"float"],[2,"vec2"],[3,"vec3"],[4,"vec4"],[9,"mat3"],[16,"mat4"]]),Vs=new WeakMap;function ks(e){return Os.get(e)}function Gs(e){if(/[iu]?vec\d/.test(e))return e.startsWith("ivec")?Int32Array:e.startsWith("uvec")?Uint32Array:Float32Array;if(/mat\d/.test(e))return Float32Array;if(/float/.test(e))return Float32Array;if(/uint/.test(e))return Uint32Array;if(/int/.test(e))return Int32Array;throw new Error(`THREE.NodeUtils: Unsupported type: ${e}`)}function zs(e){return/float|int|uint/.test(e)?1:/vec2/.test(e)?2:/vec3/.test(e)?3:/vec4/.test(e)||/mat2/.test(e)?4:/mat3/.test(e)?9:/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function $s(e){return/float|int|uint/.test(e)?1:/vec2/.test(e)?2:/vec3/.test(e)?3:/vec4/.test(e)||/mat2/.test(e)?4:/mat3/.test(e)?12:/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function Ws(e){return/float|int|uint/.test(e)?4:/vec2/.test(e)?8:/vec3/.test(e)||/vec4/.test(e)?16:/mat2/.test(e)?8:/mat3/.test(e)||/mat4/.test(e)?16:void o("TSL: Unsupported type:",e)}function Hs(e){if(null==e)return null;const t=typeof e;return!0===e.isNode?"node":"number"===t?"float":"boolean"===t?"bool":"string"===t?"string":"function"===t?"shader":!0===e.isVector2?"vec2":!0===e.isVector3?"vec3":!0===e.isVector4?"vec4":!0===e.isMatrix2?"mat2":!0===e.isMatrix3?"mat3":!0===e.isMatrix4?"mat4":!0===e.isColor?"color":e instanceof ArrayBuffer?"ArrayBuffer":null}function qs(o,...u){const l=o?o.slice(-4):void 0;return 1===u.length&&("vec2"===l?u=[u[0],u[0]]:"vec3"===l?u=[u[0],u[0],u[0]]:"vec4"===l&&(u=[u[0],u[0],u[0],u[0]])),"color"===o?new e(...u):"vec2"===l?new t(...u):"vec3"===l?new r(...u):"vec4"===l?new s(...u):"mat2"===l?new i(...u):"mat3"===l?new n(...u):"mat4"===l?new a(...u):"bool"===o?u[0]||!1:"float"===o||"int"===o||"uint"===o?u[0]||0:"string"===o?u[0]||"":"ArrayBuffer"===o?Ks(u[0]):null}function js(e){let t=Vs.get(e);return void 0===t&&(t={},Vs.set(e,t)),t}function Xs(e){let t="";const r=new Uint8Array(e);for(let e=0;ee.charCodeAt(0)).buffer}var Ys=Object.freeze({__proto__:null,arrayBufferToBase64:Xs,base64ToArrayBuffer:Ks,getAlignmentFromType:Ws,getDataFromObject:js,getLengthFromType:zs,getMemoryLengthFromType:$s,getTypeFromLength:ks,getTypedArrayFromType:Gs,getValueFromType:qs,getValueType:Hs,hash:Is,hashArray:Us,hashString:Ds});const Qs={VERTEX:"vertex",FRAGMENT:"fragment"},Zs={NONE:"none",FRAME:"frame",RENDER:"render",OBJECT:"object"},Js={BOOLEAN:"bool",INTEGER:"int",FLOAT:"float",VECTOR2:"vec2",VECTOR3:"vec3",VECTOR4:"vec4",MATRIX2:"mat2",MATRIX3:"mat3",MATRIX4:"mat4"},ei={READ_ONLY:"readOnly",WRITE_ONLY:"writeOnly",READ_WRITE:"readWrite"},ti=["fragment","vertex"],ri=["setup","analyze","generate"],si=[...ti,"compute"],ii=["x","y","z","w"],ni={analyze:"setup",generate:"analyze"};let ai=0;class oi extends u{static get type(){return"Node"}constructor(e=null){super(),this.nodeType=e,this.updateType=Zs.NONE,this.updateBeforeType=Zs.NONE,this.updateAfterType=Zs.NONE,this.uuid=l.generateUUID(),this.version=0,this.name="",this.global=!1,this.parents=!1,this.isNode=!0,this._beforeNodes=null,this._cacheKey=null,this._cacheKeyVersion=0,Object.defineProperty(this,"id",{value:ai++})}set needsUpdate(e){!0===e&&this.version++}get type(){return this.constructor.type}onUpdate(e,t){return this.updateType=t,this.update=e.bind(this),this}onFrameUpdate(e){return this.onUpdate(e,Zs.FRAME)}onRenderUpdate(e){return this.onUpdate(e,Zs.RENDER)}onObjectUpdate(e){return this.onUpdate(e,Zs.OBJECT)}onReference(e){return this.updateReference=e.bind(this),this}updateReference(){return this}isGlobal(){return this.global}*getChildren(){for(const{childNode:e}of this._getChildren())yield e}dispose(){this.dispatchEvent({type:"dispose"})}traverse(e){e(this);for(const t of this.getChildren())t.traverse(e)}_getChildren(e=new Set){const t=[];e.add(this);for(const r of Object.getOwnPropertyNames(this)){const s=this[r];if(!0!==r.startsWith("_")&&!e.has(s))if(!0===Array.isArray(s))for(let e=0;e0&&(e.inputNodes=r)}deserialize(e){if(void 0!==e.inputNodes){const t=e.meta.nodes;for(const r in e.inputNodes)if(Array.isArray(e.inputNodes[r])){const s=[];for(const i of e.inputNodes[r])s.push(t[i]);this[r]=s}else if("object"==typeof e.inputNodes[r]){const s={};for(const i in e.inputNodes[r]){const n=e.inputNodes[r][i];s[i]=t[n]}this[r]=s}else{const s=e.inputNodes[r];this[r]=t[s]}}}toJSON(e){const{uuid:t,type:r}=this,s=void 0===e||"string"==typeof e;s&&(e={textures:{},images:{},nodes:{}});let i=e.nodes[t];function n(e){const t=[];for(const r in e){const s=e[r];delete s.metadata,t.push(s)}return t}if(void 0===i&&(i={uuid:t,type:r,meta:e,metadata:{version:4.7,type:"Node",generator:"Node.toJSON"}},!0!==s&&(e.nodes[i.uuid]=i),this.serialize(i),delete i.meta),s){const t=n(e.textures),r=n(e.images),s=n(e.nodes);t.length>0&&(i.textures=t),r.length>0&&(i.images=r),s.length>0&&(i.nodes=s)}return i}}class ui extends oi{static get type(){return"ArrayElementNode"}constructor(e,t){super(),this.node=e,this.indexNode=t,this.isArrayElementNode=!0}getNodeType(e){return this.node.getElementType(e)}getMemberType(e,t){return this.node.getMemberType(e,t)}generate(e){const t=this.indexNode.getNodeType(e);return`${this.node.build(e)}[ ${this.indexNode.build(e,!e.isVector(t)&&e.isInteger(t)?t:"uint")} ]`}}class li extends oi{static get type(){return"ConvertNode"}constructor(e,t){super(),this.node=e,this.convertTo=t}getNodeType(e){const t=this.node.getNodeType(e);let r=null;for(const s of this.convertTo.split("|"))null!==r&&e.getTypeLength(t)!==e.getTypeLength(s)||(r=s);return r}serialize(e){super.serialize(e),e.convertTo=this.convertTo}deserialize(e){super.deserialize(e),this.convertTo=e.convertTo}generate(e,t){const r=this.node,s=this.getNodeType(e),i=r.build(e,s);return e.format(i,s,t)}}class di extends oi{static get type(){return"TempNode"}constructor(e=null){super(e),this.isTempNode=!0}hasDependencies(e){return e.getDataFromNode(this).usageCount>1}build(e,t){if("generate"===e.getBuildStage()){const r=e.getVectorType(this.getNodeType(e,t)),s=e.getDataFromNode(this);if(void 0!==s.propertyName)return e.format(s.propertyName,r,t);if("void"!==r&&"void"!==t&&this.hasDependencies(e)){const i=super.build(e,r),n=e.getVarFromNode(this,null,r),a=e.getPropertyName(n);return e.addLineFlowCode(`${a} = ${i}`,this),s.snippet=i,s.propertyName=a,e.format(s.propertyName,r,t)}}return super.build(e,t)}}class ci extends di{static get type(){return"JoinNode"}constructor(e=[],t=null){super(t),this.nodes=e}getNodeType(e){return null!==this.nodeType?e.getVectorType(this.nodeType):e.getTypeFromLength(this.nodes.reduce((t,r)=>t+e.getTypeLength(r.getNodeType(e)),0))}generate(e,t){const r=this.getNodeType(e),s=e.getTypeLength(r),i=this.nodes,n=e.getComponentType(r),a=[];let u=0;for(const t of i){if(u>=s){o(`TSL: Length of parameters exceeds maximum length of function '${r}()' type.`);break}let i,l=t.getNodeType(e),d=e.getTypeLength(l);u+d>s&&(o(`TSL: Length of '${r}()' data exceeds maximum length of output type.`),d=s-u,l=e.getTypeFromLength(d)),u+=d,i=t.build(e,l);if(e.getComponentType(l)!==n){const t=e.getTypeFromLength(d,n);i=e.format(i,l,t)}a.push(i)}const l=`${e.getType(r)}( ${a.join(", ")} )`;return e.format(l,r,t)}}const hi=ii.join("");class pi extends oi{static get type(){return"SplitNode"}constructor(e,t="x"){super(),this.node=e,this.components=t,this.isSplitNode=!0}getVectorLength(){let e=this.components.length;for(const t of this.components)e=Math.max(ii.indexOf(t)+1,e);return e}getComponentType(e){return e.getComponentType(this.node.getNodeType(e))}getNodeType(e){return e.getTypeFromLength(this.components.length,this.getComponentType(e))}getScope(){return this.node.getScope()}generate(e,t){const r=this.node,s=e.getTypeLength(r.getNodeType(e));let i=null;if(s>1){let n=null;this.getVectorLength()>=s&&(n=e.getTypeFromLength(this.getVectorLength(),this.getComponentType(e)));const a=r.build(e,n);i=this.components.length===s&&this.components===hi.slice(0,this.components.length)?e.format(a,n,t):e.format(`${a}.${this.components}`,this.getNodeType(e),t)}else i=r.build(e,t);return i}serialize(e){super.serialize(e),e.components=this.components}deserialize(e){super.deserialize(e),this.components=e.components}}class gi extends di{static get type(){return"SetNode"}constructor(e,t,r){super(),this.sourceNode=e,this.components=t,this.targetNode=r}getNodeType(e){return this.sourceNode.getNodeType(e)}generate(e){const{sourceNode:t,components:r,targetNode:s}=this,i=this.getNodeType(e),n=e.getComponentType(s.getNodeType(e)),a=e.getTypeFromLength(r.length,n),o=s.build(e,a),u=t.build(e,i),l=e.getTypeLength(i),d=[];for(let e=0;e(e=>e.replace(/r|s/g,"x").replace(/g|t/g,"y").replace(/b|p/g,"z").replace(/a|q/g,"w"))(e).split("").sort().join("");oi.prototype.assign=function(...e){if(!0!==this.isStackNode)return null!==Ti?Ti.assign(this,...e):o("TSL: No stack defined for assign operation. Make sure the assign is inside a Fn()."),this;{const t=_i.get("assign");return this.addToStack(t(...e))}},oi.prototype.toVarIntent=function(){return this},oi.prototype.get=function(e){return new xi(this,e)};const Si={};function Ri(e,t,r){Si[e]=Si[t]=Si[r]={get(){this._cache=this._cache||{};let t=this._cache[e];return void 0===t&&(t=new pi(this,e),this._cache[e]=t),t},set(t){this[e].assign(Qi(t))}};const s=e.toUpperCase(),i=t.toUpperCase(),n=r.toUpperCase();oi.prototype["set"+s]=oi.prototype["set"+i]=oi.prototype["set"+n]=function(t){const r=Ni(e);return new gi(this,r,Qi(t))},oi.prototype["flip"+s]=oi.prototype["flip"+i]=oi.prototype["flip"+n]=function(){const t=Ni(e);return new mi(this,t)}}const Ai=["x","y","z","w"],Ei=["r","g","b","a"],wi=["s","t","p","q"];for(let e=0;e<4;e++){let t=Ai[e],r=Ei[e],s=wi[e];Ri(t,r,s);for(let i=0;i<4;i++){t=Ai[e]+Ai[i],r=Ei[e]+Ei[i],s=wi[e]+wi[i],Ri(t,r,s);for(let n=0;n<4;n++){t=Ai[e]+Ai[i]+Ai[n],r=Ei[e]+Ei[i]+Ei[n],s=wi[e]+wi[i]+wi[n],Ri(t,r,s);for(let a=0;a<4;a++)t=Ai[e]+Ai[i]+Ai[n]+Ai[a],r=Ei[e]+Ei[i]+Ei[n]+Ei[a],s=wi[e]+wi[i]+wi[n]+wi[a],Ri(t,r,s)}}}for(let e=0;e<32;e++)Si[e]={get(){this._cache=this._cache||{};let t=this._cache[e];return void 0===t&&(t=new ui(this,new bi(e,"uint")),this._cache[e]=t),t},set(t){this[e].assign(Qi(t))}};Object.defineProperties(oi.prototype,Si);const Ci=new WeakMap,Mi=function(e,t=null){for(const r in e)e[r]=Qi(e[r],t);return e},Bi=function(e,t=null){const r=e.length;for(let s=0;su?(o(`TSL: "${r}" parameter length exceeds limit.`),t.slice(0,u)):t}return null===t?n=(...t)=>i(new e(...en(d(t)))):null!==r?(r=Qi(r),n=(...s)=>i(new e(t,...en(d(s)),r))):n=(...r)=>i(new e(t,...en(d(r)))),n.setParameterLength=(...e)=>(1===e.length?a=u=e[0]:2===e.length&&([a,u]=e),n),n.setName=e=>(l=e,n),n},Li=function(e,...t){return new e(...en(t))};class Pi extends oi{constructor(e,t){super(),this.shaderNode=e,this.rawInputs=t,this.isShaderCallNodeInternal=!0}getNodeType(e){return this.shaderNode.nodeType||this.getOutputNode(e).getNodeType(e)}getElementType(e){return this.getOutputNode(e).getElementType(e)}getMemberType(e,t){return this.getOutputNode(e).getMemberType(e,t)}call(e){const{shaderNode:t,rawInputs:r}=this,s=e.getNodeProperties(t),i=e.getClosestSubBuild(t.subBuilds)||"",n=i||"default";if(s[n])return s[n];const a=e.subBuildFn,o=e.fnCall;e.subBuildFn=i,e.fnCall=this;let u=null;if(t.layout){let s=Ci.get(e.constructor);void 0===s&&(s=new WeakMap,Ci.set(e.constructor,s));let i=s.get(t);void 0===i&&(i=Qi(e.buildFunctionNode(t)),s.set(t,i)),e.addInclude(i);const n=r?function(e){let t;Ji(e);t=e[0]&&(e[0].isNode||Object.getPrototypeOf(e[0])!==Object.prototype)?[...e]:e[0];return t}(r):null;u=Qi(i.call(n))}else{const s=new Proxy(e,{get:(e,t,r)=>{let s;return s=Symbol.iterator===t?function*(){yield}:Reflect.get(e,t,r),s}}),i=r?function(e){let t=0;return Ji(e),new Proxy(e,{get:(r,s,i)=>{let n;if("length"===s)return n=e.length,n;if(Symbol.iterator===s)n=function*(){for(const t of e)yield Qi(t)};else{if(e.length>0)if(Object.getPrototypeOf(e[0])===Object.prototype){const r=e[0];n=void 0===r[s]?r[t++]:Reflect.get(r,s,i)}else e[0]instanceof oi&&(n=void 0===e[s]?e[t++]:Reflect.get(e,s,i));else n=Reflect.get(r,s,i);n=Qi(n)}return n}})}(r):null,n=Array.isArray(r)?r.length>0:null!==r,a=t.jsFunc,o=n||a.length>1?a(i,s):a(s);u=Qi(o)}return e.subBuildFn=a,e.fnCall=o,t.once&&(s[n]=u),u}setupOutput(e){return e.addStack(),e.stack.outputNode=this.call(e),e.removeStack()}getOutputNode(e){const t=e.getNodeProperties(this),r=e.getSubBuildOutput(this);return t[r]=t[r]||this.setupOutput(e),t[r].subBuild=e.getClosestSubBuild(this),t[r]}build(e,t=null){let r=null;const s=e.getBuildStage(),i=e.getNodeProperties(this),n=e.getSubBuildOutput(this),a=this.getOutputNode(e),o=e.fnCall;if(e.fnCall=this,"setup"===s){const t=e.getSubBuildProperty("initialized",this);if(!0!==i[t]&&(i[t]=!0,i[n]=this.getOutputNode(e),i[n].build(e),this.shaderNode.subBuilds))for(const t of e.chaining){const r=e.getDataFromNode(t,"any");r.subBuilds=r.subBuilds||new Set;for(const e of this.shaderNode.subBuilds)r.subBuilds.add(e)}r=i[n]}else"analyze"===s?a.build(e,t):"generate"===s&&(r=a.build(e,t)||"");return e.fnCall=o,r}}class Di extends oi{constructor(e,t){super(t),this.jsFunc=e,this.layout=null,this.global=!0,this.once=!1}setLayout(e){return this.layout=e,this}getLayout(){return this.layout}call(e=null){return new Pi(this,e)}setup(){return this.call()}}const Ui=[!1,!0],Ii=[0,1,2,3],Oi=[-1,-2],Vi=[.5,1.5,1/3,1e-6,1e6,Math.PI,2*Math.PI,1/Math.PI,2/Math.PI,1/(2*Math.PI),Math.PI/2],ki=new Map;for(const e of Ui)ki.set(e,new bi(e));const Gi=new Map;for(const e of Ii)Gi.set(e,new bi(e,"uint"));const zi=new Map([...Gi].map(e=>new bi(e.value,"int")));for(const e of Oi)zi.set(e,new bi(e,"int"));const $i=new Map([...zi].map(e=>new bi(e.value)));for(const e of Vi)$i.set(e,new bi(e));for(const e of Vi)$i.set(-e,new bi(-e));const Wi={bool:ki,uint:Gi,ints:zi,float:$i},Hi=new Map([...ki,...$i]),qi=(e,t)=>Hi.has(e)?Hi.get(e):!0===e.isNode?e:new bi(e,t),ji=function(e,t=null){return(...r)=>{for(const t of r)if(void 0===t)return o(`TSL: Invalid parameter for the type "${e}".`),new bi(0,e);if((0===r.length||!["bool","float","int","uint"].includes(e)&&r.every(e=>{const t=typeof e;return"object"!==t&&"function"!==t}))&&(r=[qs(e,...r)]),1===r.length&&null!==t&&t.has(r[0]))return Zi(t.get(r[0]));if(1===r.length){const t=qi(r[0],e);return t.nodeType===e?Zi(t):Zi(new li(t,e))}const s=r.map(e=>qi(e));return Zi(new ci(s,e))}},Xi=e=>"object"==typeof e&&null!==e?e.value:e,Ki=e=>null!=e?e.nodeType||e.convertTo||("string"==typeof e?e:null):null;function Yi(e,t){return new Di(e,t)}const Qi=(e,t=null)=>function(e,t=null){const r=Hs(e);return"node"===r?e:null===t&&("float"===r||"boolean"===r)||r&&"shader"!==r&&"string"!==r?Qi(qi(e,t)):"shader"===r?e.isFn?e:on(e):e}(e,t),Zi=(e,t=null)=>Qi(e,t).toVarIntent(),Ji=(e,t=null)=>new Mi(e,t),en=(e,t=null)=>new Bi(e,t),tn=(e,t=null,r=null,s=null)=>new Fi(e,t,r,s),rn=(e,...t)=>new Li(e,...t),sn=(e,t=null,r=null,s={})=>new Fi(e,t,r,{...s,intent:!0});let nn=0;class an extends oi{constructor(e,t=null){super();let r=null;null!==t&&("object"==typeof t?r=t.return:("string"==typeof t?r=t:o("TSL: Invalid layout type."),t=null)),this.shaderNode=new Yi(e,r),null!==t&&this.setLayout(t),this.isFn=!0}setLayout(e){const t=this.shaderNode.nodeType;if("object"!=typeof e.inputs){const r={name:"fn"+nn++,type:t,inputs:[]};for(const t in e)"return"!==t&&r.inputs.push({name:t,type:e[t]});e=r}return this.shaderNode.setLayout(e),this}getNodeType(e){return this.shaderNode.getNodeType(e)||"float"}call(...e){const t=this.shaderNode.call(e);return"void"===this.shaderNode.nodeType&&t.toStack(),t.toVarIntent()}once(e=null){return this.shaderNode.once=!0,this.shaderNode.subBuilds=e,this}generate(e){const t=this.getNodeType(e);return o('TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".'),e.generateConst(t)}}function on(e,t=null){const r=new an(e,t);return new Proxy(()=>{},{apply:(e,t,s)=>r.call(...s),get:(e,t,s)=>Reflect.get(r,t,s),set:(e,t,s,i)=>Reflect.set(r,t,s,i)})}const un=e=>{Ti=e},ln=()=>Ti,dn=(...e)=>Ti.If(...e);function cn(e){return Ti&&Ti.addToStack(e),e}vi("toStack",cn);const hn=new ji("color"),pn=new ji("float",Wi.float),gn=new ji("int",Wi.ints),mn=new ji("uint",Wi.uint),fn=new ji("bool",Wi.bool),yn=new ji("vec2"),bn=new ji("ivec2"),xn=new ji("uvec2"),Tn=new ji("bvec2"),_n=new ji("vec3"),vn=new ji("ivec3"),Nn=new ji("uvec3"),Sn=new ji("bvec3"),Rn=new ji("vec4"),An=new ji("ivec4"),En=new ji("uvec4"),wn=new ji("bvec4"),Cn=new ji("mat2"),Mn=new ji("mat3"),Bn=new ji("mat4");vi("toColor",hn),vi("toFloat",pn),vi("toInt",gn),vi("toUint",mn),vi("toBool",fn),vi("toVec2",yn),vi("toIVec2",bn),vi("toUVec2",xn),vi("toBVec2",Tn),vi("toVec3",_n),vi("toIVec3",vn),vi("toUVec3",Nn),vi("toBVec3",Sn),vi("toVec4",Rn),vi("toIVec4",An),vi("toUVec4",En),vi("toBVec4",wn),vi("toMat2",Cn),vi("toMat3",Mn),vi("toMat4",Bn);const Fn=tn(ui).setParameterLength(2),Ln=(e,t)=>Qi(new li(Qi(e),t));vi("element",Fn),vi("convert",Ln);vi("append",e=>(d("TSL: .append() has been renamed to .toStack()."),cn(e)));class Pn extends oi{static get type(){return"PropertyNode"}constructor(e,t=null,r=!1){super(e),this.name=t,this.varying=r,this.isPropertyNode=!0,this.global=!0}customCacheKey(){return Ds(this.type+":"+(this.name||"")+":"+(this.varying?"1":"0"))}getHash(e){return this.name||super.getHash(e)}generate(e){let t;return!0===this.varying?(t=e.getVaryingFromNode(this,this.name),t.needsInterpolation=!0):t=e.getVarFromNode(this,this.name),e.getPropertyName(t)}}const Dn=(e,t)=>new Pn(e,t),Un=(e,t)=>new Pn(e,t,!0),In=rn(Pn,"vec4","DiffuseColor"),On=rn(Pn,"vec3","DiffuseContribution"),Vn=rn(Pn,"vec3","EmissiveColor"),kn=rn(Pn,"float","Roughness"),Gn=rn(Pn,"float","Metalness"),zn=rn(Pn,"float","Clearcoat"),$n=rn(Pn,"float","ClearcoatRoughness"),Wn=rn(Pn,"vec3","Sheen"),Hn=rn(Pn,"float","SheenRoughness"),qn=rn(Pn,"float","Iridescence"),jn=rn(Pn,"float","IridescenceIOR"),Xn=rn(Pn,"float","IridescenceThickness"),Kn=rn(Pn,"float","AlphaT"),Yn=rn(Pn,"float","Anisotropy"),Qn=rn(Pn,"vec3","AnisotropyT"),Zn=rn(Pn,"vec3","AnisotropyB"),Jn=rn(Pn,"color","SpecularColor"),ea=rn(Pn,"color","SpecularColorBlended"),ta=rn(Pn,"float","SpecularF90"),ra=rn(Pn,"float","Shininess"),sa=rn(Pn,"vec4","Output"),ia=rn(Pn,"float","dashSize"),na=rn(Pn,"float","gapSize"),aa=rn(Pn,"float","pointWidth"),oa=rn(Pn,"float","IOR"),ua=rn(Pn,"float","Transmission"),la=rn(Pn,"float","Thickness"),da=rn(Pn,"float","AttenuationDistance"),ca=rn(Pn,"color","AttenuationColor"),ha=rn(Pn,"float","Dispersion");class pa extends oi{static get type(){return"UniformGroupNode"}constructor(e,t=!1,r=1){super("string"),this.name=e,this.shared=t,this.order=r,this.isUniformGroup=!0}serialize(e){super.serialize(e),e.name=this.name,e.version=this.version,e.shared=this.shared}deserialize(e){super.deserialize(e),this.name=e.name,this.version=e.version,this.shared=e.shared}}const ga=e=>new pa(e),ma=(e,t=0)=>new pa(e,!0,t),fa=ma("frame"),ya=ma("render"),ba=ga("object");class xa extends fi{static get type(){return"UniformNode"}constructor(e,t=null){super(e,t),this.isUniformNode=!0,this.name="",this.groupNode=ba}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setGroup(e){return this.groupNode=e,this}getGroup(){return this.groupNode}getUniformHash(e){return this.getHash(e)}onUpdate(e,t){return e=e.bind(this),super.onUpdate(t=>{const r=e(t,this);void 0!==r&&(this.value=r)},t)}getInputType(e){let t=super.getInputType(e);return"bool"===t&&(t="uint"),t}generate(e,t){const r=this.getNodeType(e),s=this.getUniformHash(e);let i=e.getNodeFromHash(s);void 0===i&&(e.setHashNode(this,s),i=this);const n=i.getInputType(e),a=e.getUniformFromNode(i,n,e.shaderStage,this.name||e.context.nodeName),o=e.getPropertyName(a);void 0!==e.context.nodeName&&delete e.context.nodeName;let u=o;if("bool"===r){const t=e.getDataFromNode(this);let s=t.propertyName;if(void 0===s){const i=e.getVarFromNode(this,null,"bool");s=e.getPropertyName(i),t.propertyName=s,u=e.format(o,n,r),e.addLineFlowCode(`${s} = ${u}`,this)}u=s}return e.format(u,r,t)}}const Ta=(e,t)=>{const r=Ki(t||e);if(r===e&&(e=qs(r)),e&&!0===e.isNode){let t=e.value;e.traverse(e=>{!0===e.isConstNode&&(t=e.value)}),e=t}return new xa(e,r)};class _a extends di{static get type(){return"ArrayNode"}constructor(e,t,r=null){super(e),this.count=t,this.values=r,this.isArrayNode=!0}getArrayCount(){return this.count}getNodeType(e){return null===this.nodeType?this.values[0].getNodeType(e):this.nodeType}getElementType(e){return this.getNodeType(e)}getMemberType(e,t){return null===this.nodeType?this.values[0].getMemberType(e,t):super.getMemberType(e,t)}generate(e){const t=this.getNodeType(e);return e.generateArray(t,this.count,this.values)}}const va=(...e)=>{let t;if(1===e.length){const r=e[0];t=new _a(null,r.length,r)}else{const r=e[0],s=e[1];t=new _a(r,s)}return Qi(t)};vi("toArray",(e,t)=>va(Array(t).fill(e)));class Na extends di{static get type(){return"AssignNode"}constructor(e,t){super(),this.targetNode=e,this.sourceNode=t,this.isAssignNode=!0}hasDependencies(){return!1}getNodeType(e,t){return"void"!==t?this.targetNode.getNodeType(e):"void"}needsSplitAssign(e){const{targetNode:t}=this;if(!1===e.isAvailable("swizzleAssign")&&t.isSplitNode&&t.components.length>1){const r=e.getTypeLength(t.node.getNodeType(e));return ii.join("").slice(0,r)!==t.components}return!1}setup(e){const{targetNode:t,sourceNode:r}=this,s=t.getScope();e.getDataFromNode(s).assign=!0;const i=e.getNodeProperties(this);i.sourceNode=r,i.targetNode=t.context({assign:!0})}generate(e,t){const{targetNode:r,sourceNode:s}=e.getNodeProperties(this),i=this.needsSplitAssign(e),n=r.build(e),a=r.getNodeType(e),o=s.build(e,a),u=s.getNodeType(e),l=e.getDataFromNode(this);let d;if(!0===l.initialized)"void"!==t&&(d=n);else if(i){const s=e.getVarFromNode(this,null,a),i=e.getPropertyName(s);e.addLineFlowCode(`${i} = ${o}`,this);const u=r.node,l=u.node.context({assign:!0}).build(e);for(let t=0;t{const s=r.type;let i;return i="pointer"===s?"&"+t.build(e):t.build(e,s),i};if(Array.isArray(i)){if(i.length>s.length)o("TSL: The number of provided parameters exceeds the expected number of inputs in 'Fn()'."),i.length=s.length;else if(i.length(t=t.length>1||t[0]&&!0===t[0].isNode?en(t):Ji(t[0]),new Ra(Qi(e),t));vi("call",Aa);const Ea={"==":"equal","!=":"notEqual","<":"lessThan",">":"greaterThan","<=":"lessThanEqual",">=":"greaterThanEqual","%":"mod"};class wa extends di{static get type(){return"OperatorNode"}constructor(e,t,r,...s){if(super(),s.length>0){let i=new wa(e,t,r);for(let t=0;t>"===r||"<<"===r)return e.getIntegerType(n);if("!"===r||"&&"===r||"||"===r||"^^"===r)return"bool";if("=="===r||"!="===r||"<"===r||">"===r||"<="===r||">="===r){const t=Math.max(e.getTypeLength(n),e.getTypeLength(a));return t>1?`bvec${t}`:"bool"}if(e.isMatrix(n)){if("float"===a)return n;if(e.isVector(a))return e.getVectorFromMatrix(n);if(e.isMatrix(a))return n}else if(e.isMatrix(a)){if("float"===n)return a;if(e.isVector(n))return e.getVectorFromMatrix(a)}return e.getTypeLength(a)>e.getTypeLength(n)?a:n}generate(e,t){const r=this.op,{aNode:s,bNode:i}=this,n=this.getNodeType(e,t);let a=null,o=null;"void"!==n?(a=s.getNodeType(e),o=i?i.getNodeType(e):null,"<"===r||">"===r||"<="===r||">="===r||"=="===r||"!="===r?e.isVector(a)?o=a:e.isVector(o)?a=o:a!==o&&(a=o="float"):">>"===r||"<<"===r?(a=n,o=e.changeComponentType(o,"uint")):"%"===r?(a=n,o=e.isInteger(a)&&e.isInteger(o)?o:a):e.isMatrix(a)?"float"===o?o="float":e.isVector(o)?o=e.getVectorFromMatrix(a):e.isMatrix(o)||(a=o=n):a=e.isMatrix(o)?"float"===a?"float":e.isVector(a)?e.getVectorFromMatrix(o):o=n:o=n):a=o=n;const u=s.build(e,a),l=i?i.build(e,o):null,d=e.getFunctionOperator(r);if("void"!==t){const s=e.renderer.coordinateSystem===c;if("=="===r||"!="===r||"<"===r||">"===r||"<="===r||">="===r)return s&&e.isVector(a)?e.format(`${this.getOperatorMethod(e,t)}( ${u}, ${l} )`,n,t):e.format(`( ${u} ${r} ${l} )`,n,t);if("%"===r)return e.isInteger(o)?e.format(`( ${u} % ${l} )`,n,t):e.format(`${this.getOperatorMethod(e,n)}( ${u}, ${l} )`,n,t);if("!"===r||"~"===r)return e.format(`(${r}${u})`,a,t);if(d)return e.format(`${d}( ${u}, ${l} )`,n,t);if(e.isMatrix(a)&&"float"===o)return e.format(`( ${l} ${r} ${u} )`,n,t);if("float"===a&&e.isMatrix(o))return e.format(`${u} ${r} ${l}`,n,t);{let i=`( ${u} ${r} ${l} )`;return!s&&"bool"===n&&e.isVector(a)&&e.isVector(o)&&(i=`all${i}`),e.format(i,n,t)}}if("void"!==a)return d?e.format(`${d}( ${u}, ${l} )`,n,t):e.isMatrix(a)&&"float"===o?e.format(`${l} ${r} ${u}`,n,t):e.format(`${u} ${r} ${l}`,n,t)}serialize(e){super.serialize(e),e.op=this.op}deserialize(e){super.deserialize(e),this.op=e.op}}const Ca=sn(wa,"+").setParameterLength(2,1/0).setName("add"),Ma=sn(wa,"-").setParameterLength(2,1/0).setName("sub"),Ba=sn(wa,"*").setParameterLength(2,1/0).setName("mul"),Fa=sn(wa,"/").setParameterLength(2,1/0).setName("div"),La=sn(wa,"%").setParameterLength(2).setName("mod"),Pa=sn(wa,"==").setParameterLength(2).setName("equal"),Da=sn(wa,"!=").setParameterLength(2).setName("notEqual"),Ua=sn(wa,"<").setParameterLength(2).setName("lessThan"),Ia=sn(wa,">").setParameterLength(2).setName("greaterThan"),Oa=sn(wa,"<=").setParameterLength(2).setName("lessThanEqual"),Va=sn(wa,">=").setParameterLength(2).setName("greaterThanEqual"),ka=sn(wa,"&&").setParameterLength(2,1/0).setName("and"),Ga=sn(wa,"||").setParameterLength(2,1/0).setName("or"),za=sn(wa,"!").setParameterLength(1).setName("not"),$a=sn(wa,"^^").setParameterLength(2).setName("xor"),Wa=sn(wa,"&").setParameterLength(2).setName("bitAnd"),Ha=sn(wa,"~").setParameterLength(1).setName("bitNot"),qa=sn(wa,"|").setParameterLength(2).setName("bitOr"),ja=sn(wa,"^").setParameterLength(2).setName("bitXor"),Xa=sn(wa,"<<").setParameterLength(2).setName("shiftLeft"),Ka=sn(wa,">>").setParameterLength(2).setName("shiftRight"),Ya=on(([e])=>(e.addAssign(1),e)),Qa=on(([e])=>(e.subAssign(1),e)),Za=on(([e])=>{const t=gn(e).toConst();return e.addAssign(1),t}),Ja=on(([e])=>{const t=gn(e).toConst();return e.subAssign(1),t});vi("add",Ca),vi("sub",Ma),vi("mul",Ba),vi("div",Fa),vi("mod",La),vi("equal",Pa),vi("notEqual",Da),vi("lessThan",Ua),vi("greaterThan",Ia),vi("lessThanEqual",Oa),vi("greaterThanEqual",Va),vi("and",ka),vi("or",Ga),vi("not",za),vi("xor",$a),vi("bitAnd",Wa),vi("bitNot",Ha),vi("bitOr",qa),vi("bitXor",ja),vi("shiftLeft",Xa),vi("shiftRight",Ka),vi("incrementBefore",Ya),vi("decrementBefore",Qa),vi("increment",Za),vi("decrement",Ja);const eo=(e,t)=>(d('TSL: "modInt()" is deprecated. Use "mod( int( ... ) )" instead.'),La(gn(e),gn(t)));vi("modInt",eo);class to extends di{static get type(){return"MathNode"}constructor(e,t,r=null,s=null){if(super(),(e===to.MAX||e===to.MIN)&&arguments.length>3){let i=new to(e,t,r);for(let t=2;tn&&i>a?t:n>a?r:a>i?s:t}getNodeType(e){const t=this.method;return t===to.LENGTH||t===to.DISTANCE||t===to.DOT?"float":t===to.CROSS?"vec3":t===to.ALL||t===to.ANY?"bool":t===to.EQUALS?e.changeComponentType(this.aNode.getNodeType(e),"bool"):this.getInputType(e)}setup(e){const{aNode:t,bNode:r,method:s}=this;let i=null;if(s===to.ONE_MINUS)i=Ma(1,t);else if(s===to.RECIPROCAL)i=Fa(1,t);else if(s===to.DIFFERENCE)i=Co(Ma(t,r));else if(s===to.TRANSFORM_DIRECTION){let s=t,n=r;e.isMatrix(s.getNodeType(e))?n=Rn(_n(n),0):s=Rn(_n(s),0);const a=Ba(s,n).xyz;i=_o(a)}return null!==i?i:super.setup(e)}generate(e,t){if(e.getNodeProperties(this).outputNode)return super.generate(e,t);let r=this.method;const s=this.getNodeType(e),i=this.getInputType(e),n=this.aNode,a=this.bNode,o=this.cNode,u=e.renderer.coordinateSystem;if(r===to.NEGATE)return e.format("( - "+n.build(e,i)+" )",s,t);{const l=[];return r===to.CROSS?l.push(n.build(e,s),a.build(e,s)):u===c&&r===to.STEP?l.push(n.build(e,1===e.getTypeLength(n.getNodeType(e))?"float":i),a.build(e,i)):u!==c||r!==to.MIN&&r!==to.MAX?r===to.REFRACT?l.push(n.build(e,i),a.build(e,i),o.build(e,"float")):r===to.MIX?l.push(n.build(e,i),a.build(e,i),o.build(e,1===e.getTypeLength(o.getNodeType(e))?"float":i)):(u===h&&r===to.ATAN&&null!==a&&(r="atan2"),"fragment"===e.shaderStage||r!==to.DFDX&&r!==to.DFDY||(d(`TSL: '${r}' is not supported in the ${e.shaderStage} stage.`),r="/*"+r+"*/"),l.push(n.build(e,i)),null!==a&&l.push(a.build(e,i)),null!==o&&l.push(o.build(e,i))):l.push(n.build(e,i),a.build(e,1===e.getTypeLength(a.getNodeType(e))?"float":i)),e.format(`${e.getMethod(r,s)}( ${l.join(", ")} )`,s,t)}}serialize(e){super.serialize(e),e.method=this.method}deserialize(e){super.deserialize(e),this.method=e.method}}to.ALL="all",to.ANY="any",to.RADIANS="radians",to.DEGREES="degrees",to.EXP="exp",to.EXP2="exp2",to.LOG="log",to.LOG2="log2",to.SQRT="sqrt",to.INVERSE_SQRT="inversesqrt",to.FLOOR="floor",to.CEIL="ceil",to.NORMALIZE="normalize",to.FRACT="fract",to.SIN="sin",to.COS="cos",to.TAN="tan",to.ASIN="asin",to.ACOS="acos",to.ATAN="atan",to.ABS="abs",to.SIGN="sign",to.LENGTH="length",to.NEGATE="negate",to.ONE_MINUS="oneMinus",to.DFDX="dFdx",to.DFDY="dFdy",to.ROUND="round",to.RECIPROCAL="reciprocal",to.TRUNC="trunc",to.FWIDTH="fwidth",to.TRANSPOSE="transpose",to.DETERMINANT="determinant",to.INVERSE="inverse",to.EQUALS="equals",to.MIN="min",to.MAX="max",to.STEP="step",to.REFLECT="reflect",to.DISTANCE="distance",to.DIFFERENCE="difference",to.DOT="dot",to.CROSS="cross",to.POW="pow",to.TRANSFORM_DIRECTION="transformDirection",to.MIX="mix",to.CLAMP="clamp",to.REFRACT="refract",to.SMOOTHSTEP="smoothstep",to.FACEFORWARD="faceforward";const ro=pn(1e-6),so=pn(1e6),io=pn(Math.PI),no=pn(2*Math.PI),ao=pn(2*Math.PI),oo=pn(.5*Math.PI),uo=sn(to,to.ALL).setParameterLength(1),lo=sn(to,to.ANY).setParameterLength(1),co=sn(to,to.RADIANS).setParameterLength(1),ho=sn(to,to.DEGREES).setParameterLength(1),po=sn(to,to.EXP).setParameterLength(1),go=sn(to,to.EXP2).setParameterLength(1),mo=sn(to,to.LOG).setParameterLength(1),fo=sn(to,to.LOG2).setParameterLength(1),yo=sn(to,to.SQRT).setParameterLength(1),bo=sn(to,to.INVERSE_SQRT).setParameterLength(1),xo=sn(to,to.FLOOR).setParameterLength(1),To=sn(to,to.CEIL).setParameterLength(1),_o=sn(to,to.NORMALIZE).setParameterLength(1),vo=sn(to,to.FRACT).setParameterLength(1),No=sn(to,to.SIN).setParameterLength(1),So=sn(to,to.COS).setParameterLength(1),Ro=sn(to,to.TAN).setParameterLength(1),Ao=sn(to,to.ASIN).setParameterLength(1),Eo=sn(to,to.ACOS).setParameterLength(1),wo=sn(to,to.ATAN).setParameterLength(1,2),Co=sn(to,to.ABS).setParameterLength(1),Mo=sn(to,to.SIGN).setParameterLength(1),Bo=sn(to,to.LENGTH).setParameterLength(1),Fo=sn(to,to.NEGATE).setParameterLength(1),Lo=sn(to,to.ONE_MINUS).setParameterLength(1),Po=sn(to,to.DFDX).setParameterLength(1),Do=sn(to,to.DFDY).setParameterLength(1),Uo=sn(to,to.ROUND).setParameterLength(1),Io=sn(to,to.RECIPROCAL).setParameterLength(1),Oo=sn(to,to.TRUNC).setParameterLength(1),Vo=sn(to,to.FWIDTH).setParameterLength(1),ko=sn(to,to.TRANSPOSE).setParameterLength(1),Go=sn(to,to.DETERMINANT).setParameterLength(1),zo=sn(to,to.INVERSE).setParameterLength(1),$o=sn(to,to.MIN).setParameterLength(2,1/0),Wo=sn(to,to.MAX).setParameterLength(2,1/0),Ho=sn(to,to.STEP).setParameterLength(2),qo=sn(to,to.REFLECT).setParameterLength(2),jo=sn(to,to.DISTANCE).setParameterLength(2),Xo=sn(to,to.DIFFERENCE).setParameterLength(2),Ko=sn(to,to.DOT).setParameterLength(2),Yo=sn(to,to.CROSS).setParameterLength(2),Qo=sn(to,to.POW).setParameterLength(2),Zo=e=>Ba(e,e),Jo=e=>Ba(e,e,e),eu=e=>Ba(e,e,e,e),tu=sn(to,to.TRANSFORM_DIRECTION).setParameterLength(2),ru=e=>Ba(Mo(e),Qo(Co(e),1/3)),su=e=>Ko(e,e),iu=sn(to,to.MIX).setParameterLength(3),nu=(e,t=0,r=1)=>Qi(new to(to.CLAMP,Qi(e),Qi(t),Qi(r))),au=e=>nu(e),ou=sn(to,to.REFRACT).setParameterLength(3),uu=sn(to,to.SMOOTHSTEP).setParameterLength(3),lu=sn(to,to.FACEFORWARD).setParameterLength(3),du=on(([e])=>{const t=Ko(e.xy,yn(12.9898,78.233)),r=La(t,io);return vo(No(r).mul(43758.5453))}),cu=(e,t,r)=>iu(t,r,e),hu=(e,t,r)=>uu(t,r,e),pu=(e,t)=>Ho(t,e),gu=lu,mu=bo;vi("all",uo),vi("any",lo),vi("radians",co),vi("degrees",ho),vi("exp",po),vi("exp2",go),vi("log",mo),vi("log2",fo),vi("sqrt",yo),vi("inverseSqrt",bo),vi("floor",xo),vi("ceil",To),vi("normalize",_o),vi("fract",vo),vi("sin",No),vi("cos",So),vi("tan",Ro),vi("asin",Ao),vi("acos",Eo),vi("atan",wo),vi("abs",Co),vi("sign",Mo),vi("length",Bo),vi("lengthSq",su),vi("negate",Fo),vi("oneMinus",Lo),vi("dFdx",Po),vi("dFdy",Do),vi("round",Uo),vi("reciprocal",Io),vi("trunc",Oo),vi("fwidth",Vo),vi("min",$o),vi("max",Wo),vi("step",pu),vi("reflect",qo),vi("distance",jo),vi("dot",Ko),vi("cross",Yo),vi("pow",Qo),vi("pow2",Zo),vi("pow3",Jo),vi("pow4",eu),vi("transformDirection",tu),vi("mix",cu),vi("clamp",nu),vi("refract",ou),vi("smoothstep",hu),vi("faceForward",lu),vi("difference",Xo),vi("saturate",au),vi("cbrt",ru),vi("transpose",ko),vi("determinant",Go),vi("inverse",zo),vi("rand",du);class fu extends oi{static get type(){return"ConditionalNode"}constructor(e,t,r=null){super(),this.condNode=e,this.ifNode=t,this.elseNode=r}getNodeType(e){const{ifNode:t,elseNode:r}=e.getNodeProperties(this);if(void 0===t)return e.flowBuildStage(this,"setup"),this.getNodeType(e);const s=t.getNodeType(e);if(null!==r){const t=r.getNodeType(e);if(e.getTypeLength(t)>e.getTypeLength(s))return t}return s}setup(e){const t=this.condNode,r=this.ifNode.isolate(),s=this.elseNode?this.elseNode.isolate():null,i=e.context.nodeBlock;e.getDataFromNode(r).parentNodeBlock=i,null!==s&&(e.getDataFromNode(s).parentNodeBlock=i);const n=e.context.uniformFlow,a=e.getNodeProperties(this);a.condNode=t,a.ifNode=n?r:r.context({nodeBlock:r}),a.elseNode=s?n?s:s.context({nodeBlock:s}):null}generate(e,t){const r=this.getNodeType(e),s=e.getDataFromNode(this);if(void 0!==s.nodeProperty)return s.nodeProperty;const{condNode:i,ifNode:n,elseNode:a}=e.getNodeProperties(this),o=e.currentFunctionNode,u="void"!==t,l=u?Dn(r).build(e):"";s.nodeProperty=l;const c=i.build(e,"bool");if(e.context.uniformFlow&&null!==a){const s=n.build(e,r),i=a.build(e,r),o=e.getTernary(c,s,i);return e.format(o,r,t)}e.addFlowCode(`\n${e.tab}if ( ${c} ) {\n\n`).addFlowTab();let h=n.build(e,r);if(h&&(u?h=l+" = "+h+";":(h="return "+h+";",null===o&&(d("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values."),h="// "+h))),e.removeFlowTab().addFlowCode(e.tab+"\t"+h+"\n\n"+e.tab+"}"),null!==a){e.addFlowCode(" else {\n\n").addFlowTab();let t=a.build(e,r);t&&(u?t=l+" = "+t+";":(t="return "+t+";",null===o&&(d("TSL: Return statement used in an inline 'Fn()'. Define a layout struct to allow return values."),t="// "+t))),e.removeFlowTab().addFlowCode(e.tab+"\t"+t+"\n\n"+e.tab+"}\n\n")}else e.addFlowCode("\n\n");return e.format(l,r,t)}}const yu=tn(fu).setParameterLength(2,3);vi("select",yu);class bu extends oi{static get type(){return"ContextNode"}constructor(e=null,t={}){super(),this.isContextNode=!0,this.node=e,this.value=t}getScope(){return this.node.getScope()}getNodeType(e){return this.node.getNodeType(e)}getFlowContextData(){const e=[];return this.traverse(t=>{!0===t.isContextNode&&e.push(t.value)}),Object.assign({},...e)}getMemberType(e,t){return this.node.getMemberType(e,t)}analyze(e){const t=e.addContext(this.value);this.node.build(e),e.setContext(t)}setup(e){const t=e.addContext(this.value);this.node.build(e),e.setContext(t)}generate(e,t){const r=e.addContext(this.value),s=this.node.build(e,t);return e.setContext(r),s}}const xu=(e=null,t={})=>{let r=e;return null!==r&&!0===r.isNode||(t=r||t,r=null),new bu(r,t)},Tu=e=>xu(e,{uniformFlow:!0}),_u=(e,t)=>xu(e,{nodeName:t});function vu(e,t,r=null){return xu(r,{getShadow:({light:r,shadowColorNode:s})=>t===r?s.mul(e):s})}function Nu(e,t=null){return xu(t,{getAO:(t,{material:r})=>!0===r.transparent?t:null!==t?t.mul(e):e})}function Su(e,t){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),_u(e,t)}vi("context",xu),vi("label",Su),vi("uniformFlow",Tu),vi("setName",_u),vi("builtinShadowContext",(e,t,r)=>vu(t,r,e)),vi("builtinAOContext",(e,t)=>Nu(t,e));class Ru extends oi{static get type(){return"VarNode"}constructor(e,t=null,r=!1){super(),this.node=e,this.name=t,this.global=!0,this.isVarNode=!0,this.readOnly=r,this.parents=!0,this.intent=!1}setIntent(e){return this.intent=e,this}isIntent(e){return!0!==e.getDataFromNode(this).forceDeclaration&&this.intent}getIntent(){return this.intent}getMemberType(e,t){return this.node.getMemberType(e,t)}getElementType(e){return this.node.getElementType(e)}getNodeType(e){return this.node.getNodeType(e)}getArrayCount(e){return this.node.getArrayCount(e)}isAssign(e){return e.getDataFromNode(this).assign}build(...e){const t=e[0];if(!1===this._hasStack(t)&&"setup"===t.buildStage&&(t.context.nodeLoop||t.context.nodeBlock)){let e=!1;if(this.node.isShaderCallNodeInternal&&null===this.node.shaderNode.getLayout()&&t.fnCall&&t.fnCall.shaderNode){if(t.getDataFromNode(this.node.shaderNode).hasLoop){t.getDataFromNode(this).forceDeclaration=!0,e=!0}}const r=t.getBaseStack();e?r.addToStackBefore(this):r.addToStack(this)}return this.isIntent(t)&&!0!==this.isAssign(t)?this.node.build(...e):super.build(...e)}generate(e){const{node:t,name:r,readOnly:s}=this,{renderer:i}=e,n=!0===i.backend.isWebGPUBackend;let a=!1,u=!1;s&&(a=e.isDeterministic(t),u=n?s:a);const l=this.getNodeType(e);if("void"==l){!0!==this.isIntent(e)&&o('TSL: ".toVar()" can not be used with void type.');return t.build(e)}const d=e.getVectorType(l),c=t.build(e,d),h=e.getVarFromNode(this,r,d,void 0,u),p=e.getPropertyName(h);let g=p;if(u)if(n)g=a?`const ${p}`:`let ${p}`;else{const r=t.getArrayCount(e);g=`const ${e.getVar(h.type,p,r)}`}return e.addLineFlowCode(`${g} = ${c}`,this),p}_hasStack(e){return void 0!==e.getDataFromNode(this).stack}}const Au=tn(Ru),Eu=(e,t=null)=>Au(e,t).toStack(),wu=(e,t=null)=>Au(e,t,!0).toStack(),Cu=e=>Au(e).setIntent(!0).toStack();vi("toVar",Eu),vi("toConst",wu),vi("toVarIntent",Cu);class Mu extends oi{static get type(){return"SubBuild"}constructor(e,t,r=null){super(r),this.node=e,this.name=t,this.isSubBuildNode=!0}getNodeType(e){if(null!==this.nodeType)return this.nodeType;e.addSubBuild(this.name);const t=this.node.getNodeType(e);return e.removeSubBuild(),t}build(e,...t){e.addSubBuild(this.name);const r=this.node.build(e,...t);return e.removeSubBuild(),r}}const Bu=(e,t,r=null)=>Qi(new Mu(Qi(e),t,r));class Fu extends oi{static get type(){return"VaryingNode"}constructor(e,t=null){super(),this.node=Bu(e,"VERTEX"),this.name=t,this.isVaryingNode=!0,this.interpolationType=null,this.interpolationSampling=null,this.global=!0}setInterpolation(e,t=null){return this.interpolationType=e,this.interpolationSampling=t,this}getHash(e){return this.name||super.getHash(e)}getNodeType(e){return this.node.getNodeType(e)}setupVarying(e){const t=e.getNodeProperties(this);let r=t.varying;if(void 0===r){const s=this.name,i=this.getNodeType(e),n=this.interpolationType,a=this.interpolationSampling;t.varying=r=e.getVaryingFromNode(this,s,i,n,a),t.node=Bu(this.node,"VERTEX")}return r.needsInterpolation||(r.needsInterpolation="fragment"===e.shaderStage),r}setup(e){this.setupVarying(e),e.flowNodeFromShaderStage(Qs.VERTEX,this.node)}analyze(e){this.setupVarying(e),e.flowNodeFromShaderStage(Qs.VERTEX,this.node)}generate(e){const t=e.getSubBuildProperty("property",e.currentStack),r=e.getNodeProperties(this),s=this.setupVarying(e);if(void 0===r[t]){const i=this.getNodeType(e),n=e.getPropertyName(s,Qs.VERTEX);e.flowNodeFromShaderStage(Qs.VERTEX,r.node,i,n),r[t]=n}return e.getPropertyName(s)}}const Lu=tn(Fu).setParameterLength(1,2),Pu=e=>Lu(e);vi("toVarying",Lu),vi("toVertexStage",Pu);const Du=on(([e])=>{const t=e.mul(.9478672986).add(.0521327014).pow(2.4),r=e.mul(.0773993808),s=e.lessThanEqual(.04045);return iu(t,r,s)}).setLayout({name:"sRGBTransferEOTF",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Uu=on(([e])=>{const t=e.pow(.41666).mul(1.055).sub(.055),r=e.mul(12.92),s=e.lessThanEqual(.0031308);return iu(t,r,s)}).setLayout({name:"sRGBTransferOETF",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Iu="WorkingColorSpace";class Ou extends di{static get type(){return"ColorSpaceNode"}constructor(e,t,r){super("vec4"),this.colorNode=e,this.source=t,this.target=r}resolveColorSpace(e,t){return t===Iu?p.workingColorSpace:"OutputColorSpace"===t?e.context.outputColorSpace||e.renderer.outputColorSpace:t}setup(e){const{colorNode:t}=this,r=this.resolveColorSpace(e,this.source),s=this.resolveColorSpace(e,this.target);let i=t;return!1!==p.enabled&&r!==s&&r&&s?(p.getTransfer(r)===g&&(i=Rn(Du(i.rgb),i.a)),p.getPrimaries(r)!==p.getPrimaries(s)&&(i=Rn(Mn(p._getMatrix(new n,r,s)).mul(i.rgb),i.a)),p.getTransfer(s)===g&&(i=Rn(Uu(i.rgb),i.a)),i):i}}const Vu=(e,t)=>Qi(new Ou(Qi(e),Iu,t)),ku=(e,t)=>Qi(new Ou(Qi(e),t,Iu));vi("workingToColorSpace",Vu),vi("colorSpaceToWorking",ku);let Gu=class extends ui{static get type(){return"ReferenceElementNode"}constructor(e,t){super(e,t),this.referenceNode=e,this.isReferenceElementNode=!0}getNodeType(){return this.referenceNode.uniformType}generate(e){const t=super.generate(e),r=this.referenceNode.getNodeType(),s=this.getNodeType();return e.format(t,r,s)}};class zu extends oi{static get type(){return"ReferenceBaseNode"}constructor(e,t,r=null,s=null){super(),this.property=e,this.uniformType=t,this.object=r,this.count=s,this.properties=e.split("."),this.reference=r,this.node=null,this.group=null,this.updateType=Zs.OBJECT}setGroup(e){return this.group=e,this}element(e){return new Gu(this,Qi(e))}setNodeType(e){const t=Ta(null,e);null!==this.group&&t.setGroup(this.group),this.node=t}getNodeType(e){return null===this.node&&(this.updateReference(e),this.updateValue()),this.node.getNodeType(e)}getValueFromReference(e=this.reference){const{properties:t}=this;let r=e[t[0]];for(let e=1;enew $u(e,t,r);class Hu extends di{static get type(){return"ToneMappingNode"}constructor(e,t=ju,r=null){super("vec3"),this._toneMapping=e,this.exposureNode=t,this.colorNode=r}customCacheKey(){return Is(this._toneMapping)}setToneMapping(e){return this._toneMapping=e,this}getToneMapping(){return this._toneMapping}setup(e){const t=this.colorNode||e.context.color,r=this._toneMapping;if(r===m)return t;let s=null;const i=e.renderer.library.getToneMappingFunction(r);return null!==i?s=Rn(i(t.rgb,this.exposureNode),t.a):(o("ToneMappingNode: Unsupported Tone Mapping configuration.",r),s=t),s}}const qu=(e,t,r)=>Qi(new Hu(e,Qi(t),Qi(r))),ju=Wu("toneMappingExposure","float");vi("toneMapping",(e,t,r)=>qu(t,r,e));const Xu=new WeakMap;function Ku(e,t){let r=Xu.get(e);return void 0===r&&(r=new b(e,t),Xu.set(e,r)),r}class Yu extends fi{static get type(){return"BufferAttributeNode"}constructor(e,t=null,r=0,s=0){super(e,t),this.isBufferNode=!0,this.bufferType=t,this.bufferStride=r,this.bufferOffset=s,this.usage=f,this.instanced=!1,this.attribute=null,this.global=!0,e&&!0===e.isBufferAttribute&&e.itemSize<=4&&(this.attribute=e,this.usage=e.usage,this.instanced=e.isInstancedBufferAttribute)}getHash(e){if(0===this.bufferStride&&0===this.bufferOffset){let t=e.globalCache.getData(this.value);return void 0===t&&(t={node:this},e.globalCache.setData(this.value,t)),t.node.uuid}return this.uuid}getNodeType(e){return null===this.bufferType&&(this.bufferType=e.getTypeFromAttribute(this.attribute)),this.bufferType}setup(e){if(null!==this.attribute)return;const t=this.getNodeType(e),r=e.getTypeLength(t),s=this.value,i=this.bufferStride||r,n=this.bufferOffset;let a;a=!0===s.isInterleavedBuffer?s:!0===s.isBufferAttribute?Ku(s.array,i):Ku(s,i);const o=new y(a,r,n);a.setUsage(this.usage),this.attribute=o,this.attribute.isInstancedBufferAttribute=this.instanced}generate(e){const t=this.getNodeType(e),r=e.getBufferAttributeFromNode(this,t),s=e.getPropertyName(r);let i=null;if("vertex"===e.shaderStage||"compute"===e.shaderStage)this.name=s,i=s;else{i=Lu(this).build(e,t)}return i}getInputType(){return"bufferAttribute"}setUsage(e){return this.usage=e,this.attribute&&!0===this.attribute.isBufferAttribute&&(this.attribute.usage=e),this}setInstanced(e){return this.instanced=e,this}}function Qu(e,t=null,r=0,s=0,i=f,n=!1){return"mat3"===t||null===t&&9===e.itemSize?Mn(new Yu(e,"vec3",9,0).setUsage(i).setInstanced(n),new Yu(e,"vec3",9,3).setUsage(i).setInstanced(n),new Yu(e,"vec3",9,6).setUsage(i).setInstanced(n)):"mat4"===t||null===t&&16===e.itemSize?Bn(new Yu(e,"vec4",16,0).setUsage(i).setInstanced(n),new Yu(e,"vec4",16,4).setUsage(i).setInstanced(n),new Yu(e,"vec4",16,8).setUsage(i).setInstanced(n),new Yu(e,"vec4",16,12).setUsage(i).setInstanced(n)):new Yu(e,t,r,s).setUsage(i)}const Zu=(e,t=null,r=0,s=0)=>Qu(e,t,r,s),Ju=(e,t=null,r=0,s=0)=>Qu(e,t,r,s,f,!0),el=(e,t=null,r=0,s=0)=>Qu(e,t,r,s,x,!0);vi("toAttribute",e=>Zu(e.value));class tl extends oi{static get type(){return"ComputeNode"}constructor(e,t){super("void"),this.isComputeNode=!0,this.computeNode=e,this.workgroupSize=t,this.count=null,this.version=1,this.name="",this.updateBeforeType=Zs.OBJECT,this.onInitFunction=null}setCount(e){return this.count=e,this}getCount(){return this.count}dispose(){this.dispatchEvent({type:"dispose"})}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}onInit(e){return this.onInitFunction=e,this}updateBefore({renderer:e}){e.compute(this)}setup(e){const t=this.computeNode.build(e);if(t){e.getNodeProperties(this).outputComputeNode=t.outputNode,t.outputNode=null}return t}generate(e,t){const{shaderStage:r}=e;if("compute"===r){const t=this.computeNode.build(e,"void");""!==t&&e.addLineFlowCode(t,this)}else{const r=e.getNodeProperties(this).outputComputeNode;if(r)return r.build(e,t)}}}const rl=(e,t=[64])=>{(0===t.length||t.length>3)&&o("TSL: compute() workgroupSize must have 1, 2, or 3 elements");for(let e=0;erl(e,r).setCount(t);vi("compute",sl),vi("computeKernel",rl);class il extends oi{static get type(){return"IsolateNode"}constructor(e,t=!0){super(),this.node=e,this.parent=t,this.isIsolateNode=!0}getNodeType(e){const t=e.getCache(),r=e.getCacheFromNode(this,this.parent);e.setCache(r);const s=this.node.getNodeType(e);return e.setCache(t),s}build(e,...t){const r=e.getCache(),s=e.getCacheFromNode(this,this.parent);e.setCache(s);const i=this.node.build(e,...t);return e.setCache(r),i}setParent(e){return this.parent=e,this}getParent(){return this.parent}}const nl=e=>new il(Qi(e));function al(e,t=!0){return d('TSL: "cache()" has been deprecated. Use "isolate()" instead.'),nl(e).setParent(t)}vi("cache",al),vi("isolate",nl);class ol extends oi{static get type(){return"BypassNode"}constructor(e,t){super(),this.isBypassNode=!0,this.outputNode=e,this.callNode=t}getNodeType(e){return this.outputNode.getNodeType(e)}generate(e){const t=this.callNode.build(e,"void");return""!==t&&e.addLineFlowCode(t,this),this.outputNode.build(e)}}const ul=tn(ol).setParameterLength(2);vi("bypass",ul);class ll extends oi{static get type(){return"RemapNode"}constructor(e,t,r,s=pn(0),i=pn(1)){super(),this.node=e,this.inLowNode=t,this.inHighNode=r,this.outLowNode=s,this.outHighNode=i,this.doClamp=!0}setup(){const{node:e,inLowNode:t,inHighNode:r,outLowNode:s,outHighNode:i,doClamp:n}=this;let a=e.sub(t).div(r.sub(t));return!0===n&&(a=a.clamp()),a.mul(i.sub(s)).add(s)}}const dl=tn(ll,null,null,{doClamp:!1}).setParameterLength(3,5),cl=tn(ll).setParameterLength(3,5);vi("remap",dl),vi("remapClamp",cl);class hl extends oi{static get type(){return"ExpressionNode"}constructor(e="",t="void"){super(t),this.snippet=e}generate(e,t){const r=this.getNodeType(e),s=this.snippet;if("void"!==r)return e.format(s,r,t);e.addLineFlowCode(s,this)}}const pl=tn(hl).setParameterLength(1,2),gl=e=>(e?yu(e,pl("discard")):pl("discard")).toStack();vi("discard",gl);class ml extends di{static get type(){return"RenderOutputNode"}constructor(e,t,r){super("vec4"),this.colorNode=e,this._toneMapping=t,this.outputColorSpace=r,this.isRenderOutputNode=!0}setToneMapping(e){return this._toneMapping=e,this}getToneMapping(){return this._toneMapping}setup({context:e}){let t=this.colorNode||e.color;const r=(null!==this._toneMapping?this._toneMapping:e.toneMapping)||m,s=(null!==this.outputColorSpace?this.outputColorSpace:e.outputColorSpace)||T;return r!==m&&(t=t.toneMapping(r)),s!==T&&s!==p.workingColorSpace&&(t=t.workingToColorSpace(s)),t}}const fl=(e,t=null,r=null)=>Qi(new ml(Qi(e),t,r));vi("renderOutput",fl);class yl extends di{static get type(){return"DebugNode"}constructor(e,t=null){super(),this.node=e,this.callback=t}getNodeType(e){return this.node.getNodeType(e)}setup(e){return this.node.build(e)}analyze(e){return this.node.build(e)}generate(e){const t=this.callback,r=this.node.build(e);if(null!==t)t(e,r);else{const t="--- TSL debug - "+e.shaderStage+" shader ---",s="-".repeat(t.length);let i="";i+="// #"+t+"#\n",i+=e.flow.code.replace(/^\t/gm,"")+"\n",i+="/* ... */ "+r+" /* ... */\n",i+="// #"+s+"#\n",_(i)}return r}}const bl=(e,t=null)=>Qi(new yl(Qi(e),t)).toStack();vi("debug",bl);class xl{constructor(){this._renderer=null,this.currentFrame=null}get nodeFrame(){return this._renderer._nodes.nodeFrame}setRenderer(e){return this._renderer=e,this}getRenderer(){return this._renderer}init(){}begin(){}finish(){}inspect(){}computeAsync(){}beginCompute(){}finishCompute(){}beginRender(){}finishRender(){}copyTextureToTexture(){}copyFramebufferToTexture(){}}class Tl extends oi{static get type(){return"InspectorNode"}constructor(e,t="",r=null){super(),this.node=e,this.name=t,this.callback=r,this.updateType=Zs.FRAME,this.isInspectorNode=!0}getName(){return this.name||this.node.name}update(e){e.renderer.inspector.inspect(this)}getNodeType(e){return this.node.getNodeType(e)}setup(e){let t=this.node;return!0===e.context.inspector&&null!==this.callback&&(t=this.callback(t)),!0!==e.renderer.backend.isWebGPUBackend&&e.renderer.inspector.constructor!==xl&&v('TSL: ".toInspector()" is only available with WebGPU.'),t}}function _l(e,t="",r=null){return(e=Qi(e)).before(new Tl(e,t,r))}vi("toInspector",_l);class vl extends oi{static get type(){return"AttributeNode"}constructor(e,t=null){super(t),this.global=!0,this._attributeName=e}getHash(e){return this.getAttributeName(e)}getNodeType(e){let t=this.nodeType;if(null===t){const r=this.getAttributeName(e);if(e.hasGeometryAttribute(r)){const s=e.geometry.getAttribute(r);t=e.getTypeFromAttribute(s)}else t="float"}return t}setAttributeName(e){return this._attributeName=e,this}getAttributeName(){return this._attributeName}generate(e){const t=this.getAttributeName(e),r=this.getNodeType(e);if(!0===e.hasGeometryAttribute(t)){const s=e.geometry.getAttribute(t),i=e.getTypeFromAttribute(s),n=e.getAttribute(t,i);if("vertex"===e.shaderStage)return e.format(n.name,i,r);return Lu(this).build(e,r)}return d(`AttributeNode: Vertex attribute "${t}" not found on geometry.`),e.generateConst(r)}serialize(e){super.serialize(e),e.global=this.global,e._attributeName=this._attributeName}deserialize(e){super.deserialize(e),this.global=e.global,this._attributeName=e._attributeName}}const Nl=(e,t=null)=>new vl(e,t),Sl=(e=0)=>Nl("uv"+(e>0?e:""),"vec2");class Rl extends oi{static get type(){return"TextureSizeNode"}constructor(e,t=null){super("uvec2"),this.isTextureSizeNode=!0,this.textureNode=e,this.levelNode=t}generate(e,t){const r=this.textureNode.build(e,"property"),s=null===this.levelNode?"0":this.levelNode.build(e,"int");return e.format(`${e.getMethod("textureDimensions")}( ${r}, ${s} )`,this.getNodeType(e),t)}}const Al=tn(Rl).setParameterLength(1,2);class El extends xa{static get type(){return"MaxMipLevelNode"}constructor(e){super(0),this._textureNode=e,this.updateType=Zs.FRAME}get textureNode(){return this._textureNode}get texture(){return this._textureNode.value}update(){const e=this.texture,t=e.images,r=t&&t.length>0?t[0]&&t[0].image||t[0]:e.image;if(r&&void 0!==r.width){const{width:e,height:t}=r;this.value=Math.log2(Math.max(e,t))}}}const wl=tn(El).setParameterLength(1),Cl=new N;class Ml extends xa{static get type(){return"TextureNode"}constructor(e=Cl,t=null,r=null,s=null){super(e),this.isTextureNode=!0,this.uvNode=t,this.levelNode=r,this.biasNode=s,this.compareNode=null,this.depthNode=null,this.gradNode=null,this.offsetNode=null,this.sampler=!0,this.updateMatrix=!1,this.updateType=Zs.NONE,this.referenceNode=null,this._value=e,this._matrixUniform=null,this._flipYUniform=null,this.setUpdateMatrix(null===t)}set value(e){this.referenceNode?this.referenceNode.value=e:this._value=e}get value(){return this.referenceNode?this.referenceNode.value:this._value}getUniformHash(){return this.value.uuid}getNodeType(){return!0===this.value.isDepthTexture?"float":this.value.type===S?"uvec4":this.value.type===R?"ivec4":"vec4"}getInputType(){return"texture"}getDefaultUV(){return Sl(this.value.channel)}updateReference(){return this.value}getTransformedUV(e){return null===this._matrixUniform&&(this._matrixUniform=Ta(this.value.matrix)),this._matrixUniform.mul(_n(e,1)).xy}setUpdateMatrix(e){return this.updateMatrix=e,this}setupUV(e,t){return e.isFlipY()&&(null===this._flipYUniform&&(this._flipYUniform=Ta(!1)),t=t.toVar(),t=this.sampler?this._flipYUniform.select(t.flipY(),t):this._flipYUniform.select(t.setY(gn(Al(this,this.levelNode).y).sub(t.y).sub(1)),t)),t}setup(e){const t=e.getNodeProperties(this);t.referenceNode=this.referenceNode;const r=this.value;if(!r||!0!==r.isTexture)throw new Error("THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().");const s=on(()=>{let t=this.uvNode;return null!==t&&!0!==e.context.forceUVContext||!e.context.getUV||(t=e.context.getUV(this,e)),t||(t=this.getDefaultUV()),!0===this.updateMatrix&&(t=this.getTransformedUV(t)),t=this.setupUV(e,t),this.updateType=null!==this._matrixUniform||null!==this._flipYUniform?Zs.OBJECT:Zs.NONE,t})();let i=this.levelNode;null===i&&e.context.getTextureLevel&&(i=e.context.getTextureLevel(this));let n=null,a=null;null!==this.compareNode&&(e.renderer.hasCompatibility(A.TEXTURE_COMPARE)?n=this.compareNode:(null!==this.value.compareFunction&&this.value.compareFunction!==E&&v('TSL: Only "LessCompare" is supported for depth texture comparison fallback.'),a=this.compareNode)),t.uvNode=s,t.levelNode=i,t.biasNode=this.biasNode,t.compareNode=n,t.compareStepNode=a,t.gradNode=this.gradNode,t.depthNode=this.depthNode,t.offsetNode=this.offsetNode}generateUV(e,t){return t.build(e,!0===this.sampler?"vec2":"ivec2")}generateOffset(e,t){return t.build(e,"ivec2")}generateSnippet(e,t,r,s,i,n,a,o,u){const l=this.value;let d;return d=i?e.generateTextureBias(l,t,r,i,n,u):o?e.generateTextureGrad(l,t,r,o,n,u):a?e.generateTextureCompare(l,t,r,a,n,u):!1===this.sampler?e.generateTextureLoad(l,t,r,s,n,u):s?e.generateTextureLevel(l,t,r,s,n,u):e.generateTexture(l,t,r,n,u),d}generate(e,t){const r=this.value,s=e.getNodeProperties(this),i=super.generate(e,"property");if(/^sampler/.test(t))return i+"_sampler";if(e.isReference(t))return i;{const n=e.getDataFromNode(this),a=this.getNodeType(e);let o=n.propertyName;if(void 0===o){const{uvNode:t,levelNode:r,biasNode:u,compareNode:l,compareStepNode:d,depthNode:c,gradNode:h,offsetNode:p}=s,g=this.generateUV(e,t),m=r?r.build(e,"float"):null,f=u?u.build(e,"float"):null,y=c?c.build(e,"int"):null,b=l?l.build(e,"float"):null,x=d?d.build(e,"float"):null,T=h?[h[0].build(e,"vec2"),h[1].build(e,"vec2")]:null,_=p?this.generateOffset(e,p):null,v=e.getVarFromNode(this);o=e.getPropertyName(v);let N=this.generateSnippet(e,i,g,m,f,y,b,T,_);null!==x&&(N=Ho(pl(x,"float"),pl(N,a)).build(e,a)),e.addLineFlowCode(`${o} = ${N}`,this),n.snippet=N,n.propertyName=o}let u=o;return e.needsToWorkingColorSpace(r)&&(u=ku(pl(u,a),r.colorSpace).setup(e).build(e,a)),e.format(u,a,t)}}setSampler(e){return this.sampler=e,this}getSampler(){return this.sampler}sample(e){const t=this.clone();return t.uvNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}load(e){return this.sample(e).setSampler(!1)}blur(e){const t=this.clone();t.biasNode=Qi(e).mul(wl(t)),t.referenceNode=this.getBase();const r=t.value;return!1===t.generateMipmaps&&(r&&!1===r.generateMipmaps||r.minFilter===w||r.magFilter===w)&&(d("TSL: texture().blur() requires mipmaps and sampling. Use .generateMipmaps=true and .minFilter/.magFilter=THREE.LinearFilter in the Texture."),t.biasNode=null),Qi(t)}level(e){const t=this.clone();return t.levelNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}size(e){return Al(this,e)}bias(e){const t=this.clone();return t.biasNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}getBase(){return this.referenceNode?this.referenceNode.getBase():this}compare(e){const t=this.clone();return t.compareNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}grad(e,t){const r=this.clone();return r.gradNode=[Qi(e),Qi(t)],r.referenceNode=this.getBase(),Qi(r)}depth(e){const t=this.clone();return t.depthNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}offset(e){const t=this.clone();return t.offsetNode=Qi(e),t.referenceNode=this.getBase(),Qi(t)}serialize(e){super.serialize(e),e.value=this.value.toJSON(e.meta).uuid,e.sampler=this.sampler,e.updateMatrix=this.updateMatrix,e.updateType=this.updateType}deserialize(e){super.deserialize(e),this.value=e.meta.textures[e.value],this.sampler=e.sampler,this.updateMatrix=e.updateMatrix,this.updateType=e.updateType}update(){const e=this.value,t=this._matrixUniform;null!==t&&(t.value=e.matrix),!0===e.matrixAutoUpdate&&e.updateMatrix();const r=this._flipYUniform;null!==r&&(r.value=e.image instanceof ImageBitmap&&!0===e.flipY||!0===e.isRenderTargetTexture||!0===e.isFramebufferTexture||!0===e.isDepthTexture)}clone(){const e=new this.constructor(this.value,this.uvNode,this.levelNode,this.biasNode);return e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e}}const Bl=tn(Ml).setParameterLength(1,4).setName("texture"),Fl=(e=Cl,t=null,r=null,s=null)=>{let i;return e&&!0===e.isTextureNode?(i=Qi(e.clone()),i.referenceNode=e.getBase(),null!==t&&(i.uvNode=Qi(t)),null!==r&&(i.levelNode=Qi(r)),null!==s&&(i.biasNode=Qi(s))):i=Bl(e,t,r,s),i},Ll=(...e)=>Fl(...e).setSampler(!1);class Pl extends xa{static get type(){return"BufferNode"}constructor(e,t,r=0){super(e,t),this.isBufferNode=!0,this.bufferType=t,this.bufferCount=r,this.updateRanges=[]}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}getElementType(e){return this.getNodeType(e)}getInputType(){return"buffer"}}const Dl=(e,t,r)=>new Pl(e,t,r);class Ul extends ui{static get type(){return"UniformArrayElementNode"}constructor(e,t){super(e,t),this.isArrayBufferElementNode=!0}generate(e){const t=super.generate(e),r=this.getNodeType(),s=this.node.getPaddedType();return e.format(t,s,r)}}class Il extends Pl{static get type(){return"UniformArrayNode"}constructor(e,t=null){super(null),this.array=e,this.elementType=null===t?Hs(e[0]):t,this.paddedType=this.getPaddedType(),this.updateType=Zs.RENDER,this.isArrayBufferNode=!0}getNodeType(){return this.paddedType}getElementType(){return this.elementType}getPaddedType(){const e=this.elementType;let t="vec4";return"mat2"===e?t="mat2":!0===/mat/.test(e)?t="mat4":"i"===e.charAt(0)?t="ivec4":"u"===e.charAt(0)&&(t="uvec4"),t}update(){const{array:e,value:t}=this,r=this.elementType;if("float"===r||"int"===r||"uint"===r)for(let r=0;rnew Il(e,t);class Vl extends oi{constructor(e){super("float"),this.name=e,this.isBuiltinNode=!0}generate(){return this.name}}const kl=tn(Vl).setParameterLength(1);let Gl,zl;class $l extends oi{static get type(){return"ScreenNode"}constructor(e){super(),this.scope=e,this._output=null,this.isViewportNode=!0}getNodeType(){return this.scope===$l.DPR?"float":this.scope===$l.VIEWPORT?"vec4":"vec2"}getUpdateType(){let e=Zs.NONE;return this.scope!==$l.SIZE&&this.scope!==$l.VIEWPORT&&this.scope!==$l.DPR||(e=Zs.RENDER),this.updateType=e,e}update({renderer:e}){const t=e.getRenderTarget();this.scope===$l.VIEWPORT?null!==t?zl.copy(t.viewport):(e.getViewport(zl),zl.multiplyScalar(e.getPixelRatio())):this.scope===$l.DPR?this._output.value=e.getPixelRatio():null!==t?(Gl.width=t.width,Gl.height=t.height):e.getDrawingBufferSize(Gl)}setup(){const e=this.scope;let r=null;return r=e===$l.SIZE?Ta(Gl||(Gl=new t)):e===$l.VIEWPORT?Ta(zl||(zl=new s)):e===$l.DPR?Ta(1):yn(jl.div(ql)),this._output=r,r}generate(e){if(this.scope===$l.COORDINATE){let t=e.getFragCoord();if(e.isFlipY()){const r=e.getNodeProperties(ql).outputNode.build(e);t=`${e.getType("vec2")}( ${t}.x, ${r}.y - ${t}.y )`}return t}return super.generate(e)}}$l.COORDINATE="coordinate",$l.VIEWPORT="viewport",$l.SIZE="size",$l.UV="uv",$l.DPR="dpr";const Wl=rn($l,$l.DPR),Hl=rn($l,$l.UV),ql=rn($l,$l.SIZE),jl=rn($l,$l.COORDINATE),Xl=rn($l,$l.VIEWPORT),Kl=Xl.zw,Yl=jl.sub(Xl.xy),Ql=Yl.div(Kl),Zl=on(()=>(d('TSL: "viewportResolution" is deprecated. Use "screenSize" instead.'),ql),"vec2").once()(),Jl=Ta(0,"uint").setName("u_cameraIndex").setGroup(ma("cameraIndex")).toVarying("v_cameraIndex"),ed=Ta("float").setName("cameraNear").setGroup(ya).onRenderUpdate(({camera:e})=>e.near),td=Ta("float").setName("cameraFar").setGroup(ya).onRenderUpdate(({camera:e})=>e.far),rd=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.projectionMatrix);t=Ol(r).setGroup(ya).setName("cameraProjectionMatrices").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraProjectionMatrix")}else t=Ta("mat4").setName("cameraProjectionMatrix").setGroup(ya).onRenderUpdate(({camera:e})=>e.projectionMatrix);return t}).once()(),sd=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.projectionMatrixInverse);t=Ol(r).setGroup(ya).setName("cameraProjectionMatricesInverse").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraProjectionMatrixInverse")}else t=Ta("mat4").setName("cameraProjectionMatrixInverse").setGroup(ya).onRenderUpdate(({camera:e})=>e.projectionMatrixInverse);return t}).once()(),id=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.matrixWorldInverse);t=Ol(r).setGroup(ya).setName("cameraViewMatrices").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraViewMatrix")}else t=Ta("mat4").setName("cameraViewMatrix").setGroup(ya).onRenderUpdate(({camera:e})=>e.matrixWorldInverse);return t}).once()(),nd=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.matrixWorld);t=Ol(r).setGroup(ya).setName("cameraWorldMatrices").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraWorldMatrix")}else t=Ta("mat4").setName("cameraWorldMatrix").setGroup(ya).onRenderUpdate(({camera:e})=>e.matrixWorld);return t}).once()(),ad=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.normalMatrix);t=Ol(r).setGroup(ya).setName("cameraNormalMatrices").element(e.isMultiViewCamera?kl("gl_ViewID_OVR"):Jl).toConst("cameraNormalMatrix")}else t=Ta("mat3").setName("cameraNormalMatrix").setGroup(ya).onRenderUpdate(({camera:e})=>e.normalMatrix);return t}).once()(),od=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const s=[];for(let t=0,i=e.cameras.length;t{const r=e.cameras,s=t.array;for(let e=0,t=r.length;et.value.setFromMatrixPosition(e.matrixWorld));return t}).once()(),ud=on(({camera:e})=>{let t;if(e.isArrayCamera&&e.cameras.length>0){const r=[];for(const t of e.cameras)r.push(t.viewport);t=Ol(r,"vec4").setGroup(ya).setName("cameraViewports").element(Jl).toConst("cameraViewport")}else t=Rn(0,0,ql.x,ql.y).toConst("cameraViewport");return t}).once()(),ld=new C;class dd extends oi{static get type(){return"Object3DNode"}constructor(e,t=null){super(),this.scope=e,this.object3d=t,this.updateType=Zs.OBJECT,this.uniformNode=new xa(null)}getNodeType(){const e=this.scope;return e===dd.WORLD_MATRIX?"mat4":e===dd.POSITION||e===dd.VIEW_POSITION||e===dd.DIRECTION||e===dd.SCALE?"vec3":e===dd.RADIUS?"float":void 0}update(e){const t=this.object3d,s=this.uniformNode,i=this.scope;if(i===dd.WORLD_MATRIX)s.value=t.matrixWorld;else if(i===dd.POSITION)s.value=s.value||new r,s.value.setFromMatrixPosition(t.matrixWorld);else if(i===dd.SCALE)s.value=s.value||new r,s.value.setFromMatrixScale(t.matrixWorld);else if(i===dd.DIRECTION)s.value=s.value||new r,t.getWorldDirection(s.value);else if(i===dd.VIEW_POSITION){const i=e.camera;s.value=s.value||new r,s.value.setFromMatrixPosition(t.matrixWorld),s.value.applyMatrix4(i.matrixWorldInverse)}else if(i===dd.RADIUS){const r=e.object.geometry;null===r.boundingSphere&&r.computeBoundingSphere(),ld.copy(r.boundingSphere).applyMatrix4(t.matrixWorld),s.value=ld.radius}}generate(e){const t=this.scope;return t===dd.WORLD_MATRIX?this.uniformNode.nodeType="mat4":t===dd.POSITION||t===dd.VIEW_POSITION||t===dd.DIRECTION||t===dd.SCALE?this.uniformNode.nodeType="vec3":t===dd.RADIUS&&(this.uniformNode.nodeType="float"),this.uniformNode.build(e)}serialize(e){super.serialize(e),e.scope=this.scope}deserialize(e){super.deserialize(e),this.scope=e.scope}}dd.WORLD_MATRIX="worldMatrix",dd.POSITION="position",dd.SCALE="scale",dd.VIEW_POSITION="viewPosition",dd.DIRECTION="direction",dd.RADIUS="radius";const cd=tn(dd,dd.DIRECTION).setParameterLength(1),hd=tn(dd,dd.WORLD_MATRIX).setParameterLength(1),pd=tn(dd,dd.POSITION).setParameterLength(1),gd=tn(dd,dd.SCALE).setParameterLength(1),md=tn(dd,dd.VIEW_POSITION).setParameterLength(1),fd=tn(dd,dd.RADIUS).setParameterLength(1);class yd extends dd{static get type(){return"ModelNode"}constructor(e){super(e)}update(e){this.object3d=e.object,super.update(e)}}const bd=rn(yd,yd.DIRECTION),xd=rn(yd,yd.WORLD_MATRIX),Td=rn(yd,yd.POSITION),_d=rn(yd,yd.SCALE),vd=rn(yd,yd.VIEW_POSITION),Nd=rn(yd,yd.RADIUS),Sd=Ta(new n).onObjectUpdate(({object:e},t)=>t.value.getNormalMatrix(e.matrixWorld)),Rd=Ta(new a).onObjectUpdate(({object:e},t)=>t.value.copy(e.matrixWorld).invert()),Ad=on(e=>e.context.modelViewMatrix||Ed).once()().toVar("modelViewMatrix"),Ed=id.mul(xd),wd=on(e=>(e.context.isHighPrecisionModelViewMatrix=!0,Ta("mat4").onObjectUpdate(({object:e,camera:t})=>e.modelViewMatrix.multiplyMatrices(t.matrixWorldInverse,e.matrixWorld)))).once()().toVar("highpModelViewMatrix"),Cd=on(e=>{const t=e.context.isHighPrecisionModelViewMatrix;return Ta("mat3").onObjectUpdate(({object:e,camera:r})=>(!0!==t&&e.modelViewMatrix.multiplyMatrices(r.matrixWorldInverse,e.matrixWorld),e.normalMatrix.getNormalMatrix(e.modelViewMatrix)))}).once()().toVar("highpModelNormalViewMatrix"),Md=on(e=>"fragment"!==e.shaderStage?(v("TSL: `clipSpace` is only available in fragment stage."),Rn()):e.context.clipSpace.toVarying("v_clipSpace")).once()(),Bd=Nl("position","vec3"),Fd=Bd.toVarying("positionLocal"),Ld=Bd.toVarying("positionPrevious"),Pd=on(e=>xd.mul(Fd).xyz.toVarying(e.getSubBuildProperty("v_positionWorld")),"vec3").once(["POSITION"])(),Dd=on(()=>Fd.transformDirection(xd).toVarying("v_positionWorldDirection").normalize().toVar("positionWorldDirection"),"vec3").once(["POSITION"])(),Ud=on(e=>{if("fragment"===e.shaderStage&&e.material.vertexNode){const e=sd.mul(Md);return e.xyz.div(e.w).toVar("positionView")}return e.context.setupPositionView().toVarying("v_positionView")},"vec3").once(["POSITION","VERTEX"])(),Id=on(e=>{let t;return t=e.camera.isOrthographicCamera?_n(0,0,1):Ud.negate().toVarying("v_positionViewDirection").normalize(),t.toVar("positionViewDirection")},"vec3").once(["POSITION"])();class Od extends oi{static get type(){return"FrontFacingNode"}constructor(){super("bool"),this.isFrontFacingNode=!0}generate(e){if("fragment"!==e.shaderStage)return"true";const{material:t}=e;return t.side===M?"false":e.getFrontFacing()}}const Vd=rn(Od),kd=pn(Vd).mul(2).sub(1),Gd=on(([e],{material:t})=>{const r=t.side;return r===M?e=e.mul(-1):r===B&&(e=e.mul(kd)),e}),zd=Nl("normal","vec3"),$d=on(e=>!1===e.geometry.hasAttribute("normal")?(d('TSL: Vertex attribute "normal" not found on geometry.'),_n(0,1,0)):zd,"vec3").once()().toVar("normalLocal"),Wd=Ud.dFdx().cross(Ud.dFdy()).normalize().toVar("normalFlat"),Hd=on(e=>{let t;return t=e.isFlatShading()?Wd:Qd($d).toVarying("v_normalViewGeometry").normalize(),t},"vec3").once()().toVar("normalViewGeometry"),qd=on(e=>{let t=Hd.transformDirection(id);return!0!==e.isFlatShading()&&(t=t.toVarying("v_normalWorldGeometry")),t.normalize().toVar("normalWorldGeometry")},"vec3").once()(),jd=on(e=>{let t;return"NORMAL"===e.subBuildFn||"VERTEX"===e.subBuildFn?(t=Hd,!0!==e.isFlatShading()&&(t=Gd(t))):t=e.context.setupNormal().context({getUV:null,getTextureLevel:null}),t},"vec3").once(["NORMAL","VERTEX"])().toVar("normalView"),Xd=jd.transformDirection(id).toVar("normalWorld"),Kd=on(({subBuildFn:e,context:t})=>{let r;return r="NORMAL"===e||"VERTEX"===e?jd:t.setupClearcoatNormal().context({getUV:null,getTextureLevel:null}),r},"vec3").once(["NORMAL","VERTEX"])().toVar("clearcoatNormalView"),Yd=on(([e,t=xd])=>{const r=Mn(t),s=e.div(_n(r[0].dot(r[0]),r[1].dot(r[1]),r[2].dot(r[2])));return r.mul(s).xyz}),Qd=on(([e],t)=>{const r=t.context.modelNormalViewMatrix;if(r)return r.transformDirection(e);const s=Sd.mul(e);return id.transformDirection(s)}),Zd=on(()=>(d('TSL: "transformedNormalView" is deprecated. Use "normalView" instead.'),jd)).once(["NORMAL","VERTEX"])(),Jd=on(()=>(d('TSL: "transformedNormalWorld" is deprecated. Use "normalWorld" instead.'),Xd)).once(["NORMAL","VERTEX"])(),ec=on(()=>(d('TSL: "transformedClearcoatNormalView" is deprecated. Use "clearcoatNormalView" instead.'),Kd)).once(["NORMAL","VERTEX"])(),tc=new F,rc=new a,sc=Ta(0).onReference(({material:e})=>e).onObjectUpdate(({material:e})=>e.refractionRatio),ic=Ta(1).onReference(({material:e})=>e).onObjectUpdate(function({material:e,scene:t}){return e.envMap?e.envMapIntensity:t.environmentIntensity}),nc=Ta(new a).onReference(function(e){return e.material}).onObjectUpdate(function({material:e,scene:t}){const r=null!==t.environment&&null===e.envMap?t.environmentRotation:e.envMapRotation;return r?(tc.copy(r),rc.makeRotationFromEuler(tc)):rc.identity(),rc}),ac=Id.negate().reflect(jd),oc=Id.negate().refract(jd,sc),uc=ac.transformDirection(id).toVar("reflectVector"),lc=oc.transformDirection(id).toVar("reflectVector"),dc=new L;class cc extends Ml{static get type(){return"CubeTextureNode"}constructor(e,t=null,r=null,s=null){super(e,t,r,s),this.isCubeTextureNode=!0}getInputType(){return!0===this.value.isDepthTexture?"cubeDepthTexture":"cubeTexture"}getDefaultUV(){const e=this.value;return e.mapping===P?uc:e.mapping===D?lc:(o('CubeTextureNode: Mapping "%s" not supported.',e.mapping),_n(0,0,0))}setUpdateMatrix(){}setupUV(e,t){const r=this.value;return!0===r.isDepthTexture?e.renderer.coordinateSystem===h?_n(t.x,t.y.negate(),t.z):t:(e.renderer.coordinateSystem!==h&&r.isRenderTargetTexture||(t=_n(t.x.negate(),t.yz)),nc.mul(t))}generateUV(e,t){return t.build(e,!0===this.sampler?"vec3":"ivec3")}}const hc=tn(cc).setParameterLength(1,4).setName("cubeTexture"),pc=(e=dc,t=null,r=null,s=null)=>{let i;return e&&!0===e.isCubeTextureNode?(i=Qi(e.clone()),i.referenceNode=e,null!==t&&(i.uvNode=Qi(t)),null!==r&&(i.levelNode=Qi(r)),null!==s&&(i.biasNode=Qi(s))):i=hc(e,t,r,s),i};class gc extends ui{static get type(){return"ReferenceElementNode"}constructor(e,t){super(e,t),this.referenceNode=e,this.isReferenceElementNode=!0}getNodeType(){return this.referenceNode.uniformType}generate(e){const t=super.generate(e),r=this.referenceNode.getNodeType(),s=this.getNodeType();return e.format(t,r,s)}}class mc extends oi{static get type(){return"ReferenceNode"}constructor(e,t,r=null,s=null){super(),this.property=e,this.uniformType=t,this.object=r,this.count=s,this.properties=e.split("."),this.reference=r,this.node=null,this.group=null,this.name=null,this.updateType=Zs.OBJECT}element(e){return new gc(this,Qi(e))}setGroup(e){return this.group=e,this}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setNodeType(e){let t=null;t=null!==this.count?Dl(null,e,this.count):Array.isArray(this.getValueFromReference())?Ol(null,e):"texture"===e?Fl(null):"cubeTexture"===e?pc(null):Ta(null,e),null!==this.group&&t.setGroup(this.group),null!==this.name&&t.setName(this.name),this.node=t}getNodeType(e){return null===this.node&&(this.updateReference(e),this.updateValue()),this.node.getNodeType(e)}getValueFromReference(e=this.reference){const{properties:t}=this;let r=e[t[0]];for(let e=1;enew mc(e,t,r),yc=(e,t,r,s)=>new mc(e,t,s,r);class bc extends mc{static get type(){return"MaterialReferenceNode"}constructor(e,t,r=null){super(e,t,r),this.material=r,this.isMaterialReferenceNode=!0}updateReference(e){return this.reference=null!==this.material?this.material:e.material,this.reference}}const xc=(e,t,r=null)=>new bc(e,t,r),Tc=Sl(),_c=Ud.dFdx(),vc=Ud.dFdy(),Nc=Tc.dFdx(),Sc=Tc.dFdy(),Rc=jd,Ac=vc.cross(Rc),Ec=Rc.cross(_c),wc=Ac.mul(Nc.x).add(Ec.mul(Sc.x)),Cc=Ac.mul(Nc.y).add(Ec.mul(Sc.y)),Mc=wc.dot(wc).max(Cc.dot(Cc)),Bc=Mc.equal(0).select(0,Mc.inverseSqrt()),Fc=wc.mul(Bc).toVar("tangentViewFrame"),Lc=Cc.mul(Bc).toVar("bitangentViewFrame"),Pc=Nl("tangent","vec4"),Dc=Pc.xyz.toVar("tangentLocal"),Uc=on(e=>{let t;return t="VERTEX"===e.subBuildFn||e.geometry.hasAttribute("tangent")?Ad.mul(Rn(Dc,0)).xyz.toVarying("v_tangentView").normalize():Fc,!0!==e.isFlatShading()&&(t=Gd(t)),t},"vec3").once(["NORMAL","VERTEX"])().toVar("tangentView"),Ic=Uc.transformDirection(id).toVarying("v_tangentWorld").normalize().toVar("tangentWorld"),Oc=on(([e,t],r)=>{let s=e.mul(Pc.w).xyz;return"NORMAL"===r.subBuildFn&&!0!==r.isFlatShading()&&(s=s.toVarying(t)),s}).once(["NORMAL"]),Vc=Oc(zd.cross(Pc),"v_bitangentGeometry").normalize().toVar("bitangentGeometry"),kc=Oc($d.cross(Dc),"v_bitangentLocal").normalize().toVar("bitangentLocal"),Gc=on(e=>{let t;return t="VERTEX"===e.subBuildFn||e.geometry.hasAttribute("tangent")?Oc(jd.cross(Uc),"v_bitangentView").normalize():Lc,!0!==e.isFlatShading()&&(t=Gd(t)),t},"vec3").once(["NORMAL","VERTEX"])().toVar("bitangentView"),zc=Oc(Xd.cross(Ic),"v_bitangentWorld").normalize().toVar("bitangentWorld"),$c=Mn(Uc,Gc,jd).toVar("TBNViewMatrix"),Wc=Id.mul($c),Hc=on(()=>{let e=Zn.cross(Id);return e=e.cross(Zn).normalize(),e=iu(e,jd,Yn.mul(kn.oneMinus()).oneMinus().pow2().pow2()).normalize(),e}).once()(),qc=e=>Qi(e).mul(.5).add(.5),jc=e=>_n(e,yo(au(pn(1).sub(Ko(e,e)))));class Xc extends di{static get type(){return"NormalMapNode"}constructor(e,t=null){super("vec3"),this.node=e,this.scaleNode=t,this.normalMapType=U,this.unpackNormalMode=I}setup(e){const{normalMapType:t,scaleNode:r,unpackNormalMode:s}=this;let i=this.node.mul(2).sub(1);if(t===U?s===O?i=jc(i.xy):s===V?i=jc(i.yw):s!==I&&console.error(`THREE.NodeMaterial: Unexpected unpack normal mode: ${s}`):s!==I&&console.error(`THREE.NodeMaterial: Normal map type '${t}' is not compatible with unpack normal mode '${s}'`),null!==r){let t=r;!0===e.isFlatShading()&&(t=Gd(t)),i=_n(i.xy.mul(t),i.z)}let n=null;return t===k?n=Qd(i):t===U?n=$c.mul(i).normalize():(o(`NodeMaterial: Unsupported normal map type: ${t}`),n=jd),n}}const Kc=tn(Xc).setParameterLength(1,2),Yc=on(({textureNode:e,bumpScale:t})=>{const r=t=>e.isolate().context({getUV:e=>t(e.uvNode||Sl()),forceUVContext:!0}),s=pn(r(e=>e));return yn(pn(r(e=>e.add(e.dFdx()))).sub(s),pn(r(e=>e.add(e.dFdy()))).sub(s)).mul(t)}),Qc=on(e=>{const{surf_pos:t,surf_norm:r,dHdxy:s}=e,i=t.dFdx().normalize(),n=r,a=t.dFdy().normalize().cross(n),o=n.cross(i),u=i.dot(a).mul(kd),l=u.sign().mul(s.x.mul(a).add(s.y.mul(o)));return u.abs().mul(r).sub(l).normalize()});class Zc extends di{static get type(){return"BumpMapNode"}constructor(e,t=null){super("vec3"),this.textureNode=e,this.scaleNode=t}setup(){const e=null!==this.scaleNode?this.scaleNode:1,t=Yc({textureNode:this.textureNode,bumpScale:e});return Qc({surf_pos:Ud,surf_norm:jd,dHdxy:t})}}const Jc=tn(Zc).setParameterLength(1,2),eh=new Map;class th extends oi{static get type(){return"MaterialNode"}constructor(e){super(),this.scope=e}getCache(e,t){let r=eh.get(e);return void 0===r&&(r=xc(e,t),eh.set(e,r)),r}getFloat(e){return this.getCache(e,"float")}getColor(e){return this.getCache(e,"color")}getTexture(e){return this.getCache("map"===e?"map":e+"Map","texture")}setup(e){const t=e.context.material,r=this.scope;let s=null;if(r===th.COLOR){const e=void 0!==t.color?this.getColor(r):_n();s=t.map&&!0===t.map.isTexture?e.mul(this.getTexture("map")):e}else if(r===th.OPACITY){const e=this.getFloat(r);s=t.alphaMap&&!0===t.alphaMap.isTexture?e.mul(this.getTexture("alpha")):e}else if(r===th.SPECULAR_STRENGTH)s=t.specularMap&&!0===t.specularMap.isTexture?this.getTexture("specular").r:pn(1);else if(r===th.SPECULAR_INTENSITY){const e=this.getFloat(r);s=t.specularIntensityMap&&!0===t.specularIntensityMap.isTexture?e.mul(this.getTexture(r).a):e}else if(r===th.SPECULAR_COLOR){const e=this.getColor(r);s=t.specularColorMap&&!0===t.specularColorMap.isTexture?e.mul(this.getTexture(r).rgb):e}else if(r===th.ROUGHNESS){const e=this.getFloat(r);s=t.roughnessMap&&!0===t.roughnessMap.isTexture?e.mul(this.getTexture(r).g):e}else if(r===th.METALNESS){const e=this.getFloat(r);s=t.metalnessMap&&!0===t.metalnessMap.isTexture?e.mul(this.getTexture(r).b):e}else if(r===th.EMISSIVE){const e=this.getFloat("emissiveIntensity"),i=this.getColor(r).mul(e);s=t.emissiveMap&&!0===t.emissiveMap.isTexture?i.mul(this.getTexture(r)):i}else if(r===th.NORMAL)t.normalMap?(s=Kc(this.getTexture("normal"),this.getCache("normalScale","vec2")),s.normalMapType=t.normalMapType,t.normalMap.format!=G&&t.normalMap.format!=z&&t.normalMap.format!=$||(s.unpackNormalMode=O)):s=t.bumpMap?Jc(this.getTexture("bump").r,this.getFloat("bumpScale")):jd;else if(r===th.CLEARCOAT){const e=this.getFloat(r);s=t.clearcoatMap&&!0===t.clearcoatMap.isTexture?e.mul(this.getTexture(r).r):e}else if(r===th.CLEARCOAT_ROUGHNESS){const e=this.getFloat(r);s=t.clearcoatRoughnessMap&&!0===t.clearcoatRoughnessMap.isTexture?e.mul(this.getTexture(r).r):e}else if(r===th.CLEARCOAT_NORMAL)s=t.clearcoatNormalMap?Kc(this.getTexture(r),this.getCache(r+"Scale","vec2")):jd;else if(r===th.SHEEN){const e=this.getColor("sheenColor").mul(this.getFloat("sheen"));s=t.sheenColorMap&&!0===t.sheenColorMap.isTexture?e.mul(this.getTexture("sheenColor").rgb):e}else if(r===th.SHEEN_ROUGHNESS){const e=this.getFloat(r);s=t.sheenRoughnessMap&&!0===t.sheenRoughnessMap.isTexture?e.mul(this.getTexture(r).a):e,s=s.clamp(1e-4,1)}else if(r===th.ANISOTROPY)if(t.anisotropyMap&&!0===t.anisotropyMap.isTexture){const e=this.getTexture(r);s=Cn(Vh.x,Vh.y,Vh.y.negate(),Vh.x).mul(e.rg.mul(2).sub(yn(1)).normalize().mul(e.b))}else s=Vh;else if(r===th.IRIDESCENCE_THICKNESS){const e=fc("1","float",t.iridescenceThicknessRange);if(t.iridescenceThicknessMap){const i=fc("0","float",t.iridescenceThicknessRange);s=e.sub(i).mul(this.getTexture(r).g).add(i)}else s=e}else if(r===th.TRANSMISSION){const e=this.getFloat(r);s=t.transmissionMap?e.mul(this.getTexture(r).r):e}else if(r===th.THICKNESS){const e=this.getFloat(r);s=t.thicknessMap?e.mul(this.getTexture(r).g):e}else if(r===th.IOR)s=this.getFloat(r);else if(r===th.LIGHT_MAP)s=this.getTexture(r).rgb.mul(this.getFloat("lightMapIntensity"));else if(r===th.AO)s=this.getTexture(r).r.sub(1).mul(this.getFloat("aoMapIntensity")).add(1);else if(r===th.LINE_DASH_OFFSET)s=t.dashOffset?this.getFloat(r):pn(0);else{const t=this.getNodeType(e);s=this.getCache(r,t)}return s}}th.ALPHA_TEST="alphaTest",th.COLOR="color",th.OPACITY="opacity",th.SHININESS="shininess",th.SPECULAR="specular",th.SPECULAR_STRENGTH="specularStrength",th.SPECULAR_INTENSITY="specularIntensity",th.SPECULAR_COLOR="specularColor",th.REFLECTIVITY="reflectivity",th.ROUGHNESS="roughness",th.METALNESS="metalness",th.NORMAL="normal",th.CLEARCOAT="clearcoat",th.CLEARCOAT_ROUGHNESS="clearcoatRoughness",th.CLEARCOAT_NORMAL="clearcoatNormal",th.EMISSIVE="emissive",th.ROTATION="rotation",th.SHEEN="sheen",th.SHEEN_ROUGHNESS="sheenRoughness",th.ANISOTROPY="anisotropy",th.IRIDESCENCE="iridescence",th.IRIDESCENCE_IOR="iridescenceIOR",th.IRIDESCENCE_THICKNESS="iridescenceThickness",th.IOR="ior",th.TRANSMISSION="transmission",th.THICKNESS="thickness",th.ATTENUATION_DISTANCE="attenuationDistance",th.ATTENUATION_COLOR="attenuationColor",th.LINE_SCALE="scale",th.LINE_DASH_SIZE="dashSize",th.LINE_GAP_SIZE="gapSize",th.LINE_WIDTH="linewidth",th.LINE_DASH_OFFSET="dashOffset",th.POINT_SIZE="size",th.DISPERSION="dispersion",th.LIGHT_MAP="light",th.AO="ao";const rh=rn(th,th.ALPHA_TEST),sh=rn(th,th.COLOR),ih=rn(th,th.SHININESS),nh=rn(th,th.EMISSIVE),ah=rn(th,th.OPACITY),oh=rn(th,th.SPECULAR),uh=rn(th,th.SPECULAR_INTENSITY),lh=rn(th,th.SPECULAR_COLOR),dh=rn(th,th.SPECULAR_STRENGTH),ch=rn(th,th.REFLECTIVITY),hh=rn(th,th.ROUGHNESS),ph=rn(th,th.METALNESS),gh=rn(th,th.NORMAL),mh=rn(th,th.CLEARCOAT),fh=rn(th,th.CLEARCOAT_ROUGHNESS),yh=rn(th,th.CLEARCOAT_NORMAL),bh=rn(th,th.ROTATION),xh=rn(th,th.SHEEN),Th=rn(th,th.SHEEN_ROUGHNESS),_h=rn(th,th.ANISOTROPY),vh=rn(th,th.IRIDESCENCE),Nh=rn(th,th.IRIDESCENCE_IOR),Sh=rn(th,th.IRIDESCENCE_THICKNESS),Rh=rn(th,th.TRANSMISSION),Ah=rn(th,th.THICKNESS),Eh=rn(th,th.IOR),wh=rn(th,th.ATTENUATION_DISTANCE),Ch=rn(th,th.ATTENUATION_COLOR),Mh=rn(th,th.LINE_SCALE),Bh=rn(th,th.LINE_DASH_SIZE),Fh=rn(th,th.LINE_GAP_SIZE),Lh=rn(th,th.LINE_WIDTH),Ph=rn(th,th.LINE_DASH_OFFSET),Dh=rn(th,th.POINT_SIZE),Uh=rn(th,th.DISPERSION),Ih=rn(th,th.LIGHT_MAP),Oh=rn(th,th.AO),Vh=Ta(new t).onReference(function(e){return e.material}).onRenderUpdate(function({material:e}){this.value.set(e.anisotropy*Math.cos(e.anisotropyRotation),e.anisotropy*Math.sin(e.anisotropyRotation))}),kh=on(e=>e.context.setupModelViewProjection(),"vec4").once()().toVarying("v_modelViewProjection");class Gh extends ui{static get type(){return"StorageArrayElementNode"}constructor(e,t){super(e,t),this.isStorageArrayElementNode=!0}set storageBufferNode(e){this.node=e}get storageBufferNode(){return this.node}getMemberType(e,t){const r=this.storageBufferNode.structTypeNode;return r?r.getMemberType(e,t):"void"}setup(e){return!1===e.isAvailable("storageBuffer")&&!0===this.node.isPBO&&e.setupPBO(this.node),super.setup(e)}generate(e,t){let r;const s=e.context.assign;if(r=!1===e.isAvailable("storageBuffer")?!0!==this.node.isPBO||!0===s||!this.node.value.isInstancedBufferAttribute&&"compute"===e.shaderStage?this.node.build(e):e.generatePBO(this):super.generate(e),!0!==s){const s=this.getNodeType(e);r=e.format(r,s,t)}return r}}const zh=tn(Gh).setParameterLength(2);class $h extends Pl{static get type(){return"StorageBufferNode"}constructor(e,t=null,r=0){let s,i=null;t&&t.isStruct?(s="struct",i=t.layout,(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute)&&(r=e.count)):null===t&&(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute)?(s=ks(e.itemSize),r=e.count):s=t,super(e,s,r),this.isStorageBufferNode=!0,this.structTypeNode=i,this.access=ei.READ_WRITE,this.isAtomic=!1,this.isPBO=!1,this._attribute=null,this._varying=null,this.global=!0,!0!==e.isStorageBufferAttribute&&!0!==e.isStorageInstancedBufferAttribute&&(e.isInstancedBufferAttribute?e.isStorageInstancedBufferAttribute=!0:e.isStorageBufferAttribute=!0)}getHash(e){if(0===this.bufferCount){let t=e.globalCache.getData(this.value);return void 0===t&&(t={node:this},e.globalCache.setData(this.value,t)),t.node.uuid}return this.uuid}getInputType(){return this.value.isIndirectStorageBufferAttribute?"indirectStorageBuffer":"storageBuffer"}element(e){return zh(this,e)}setPBO(e){return this.isPBO=e,this}getPBO(){return this.isPBO}setAccess(e){return this.access=e,this}toReadOnly(){return this.setAccess(ei.READ_ONLY)}setAtomic(e){return this.isAtomic=e,this}toAtomic(){return this.setAtomic(!0)}getAttributeData(){return null===this._attribute&&(this._attribute=Zu(this.value),this._varying=Lu(this._attribute)),{attribute:this._attribute,varying:this._varying}}getNodeType(e){if(null!==this.structTypeNode)return this.structTypeNode.getNodeType(e);if(e.isAvailable("storageBuffer")||e.isAvailable("indirectStorageBuffer"))return super.getNodeType(e);const{attribute:t}=this.getAttributeData();return t.getNodeType(e)}getMemberType(e,t){return null!==this.structTypeNode?this.structTypeNode.getMemberType(e,t):"void"}generate(e){if(null!==this.structTypeNode&&this.structTypeNode.build(e),e.isAvailable("storageBuffer")||e.isAvailable("indirectStorageBuffer"))return super.generate(e);const{attribute:t,varying:r}=this.getAttributeData(),s=r.build(e);return e.registerTransform(s,t),s}}const Wh=(e,t=null,r=0)=>new $h(e,t,r);class Hh extends oi{static get type(){return"IndexNode"}constructor(e){super("uint"),this.scope=e,this.isIndexNode=!0}generate(e){const t=this.getNodeType(e),r=this.scope;let s,i;if(r===Hh.VERTEX)s=e.getVertexIndex();else if(r===Hh.INSTANCE)s=e.getInstanceIndex();else if(r===Hh.DRAW)s=e.getDrawIndex();else if(r===Hh.INVOCATION_LOCAL)s=e.getInvocationLocalIndex();else if(r===Hh.INVOCATION_SUBGROUP)s=e.getInvocationSubgroupIndex();else{if(r!==Hh.SUBGROUP)throw new Error("THREE.IndexNode: Unknown scope: "+r);s=e.getSubgroupIndex()}if("vertex"===e.shaderStage||"compute"===e.shaderStage)i=s;else{i=Lu(this).build(e,t)}return i}}Hh.VERTEX="vertex",Hh.INSTANCE="instance",Hh.SUBGROUP="subgroup",Hh.INVOCATION_LOCAL="invocationLocal",Hh.INVOCATION_SUBGROUP="invocationSubgroup",Hh.DRAW="draw";const qh=rn(Hh,Hh.VERTEX),jh=rn(Hh,Hh.INSTANCE),Xh=rn(Hh,Hh.SUBGROUP),Kh=rn(Hh,Hh.INVOCATION_SUBGROUP),Yh=rn(Hh,Hh.INVOCATION_LOCAL),Qh=rn(Hh,Hh.DRAW);class Zh extends oi{static get type(){return"InstanceNode"}constructor(e,t,r=null){super("void"),this.count=e,this.instanceMatrix=t,this.instanceColor=r,this.instanceMatrixNode=null,this.instanceColorNode=null,this.updateType=Zs.FRAME,this.buffer=null,this.bufferColor=null,this.previousInstanceMatrixNode=null}get isStorageMatrix(){const{instanceMatrix:e}=this;return e&&!0===e.isStorageInstancedBufferAttribute}get isStorageColor(){const{instanceColor:e}=this;return e&&!0===e.isStorageInstancedBufferAttribute}setup(e){let{instanceMatrixNode:t,instanceColorNode:r}=this;null===t&&(t=this._createInstanceMatrixNode(!0,e),this.instanceMatrixNode=t);const{instanceColor:s,isStorageColor:i}=this;if(s&&null===r){if(i)r=Wh(s,"vec3",Math.max(s.count,1)).element(jh);else{const e=new W(s.array,3),t=s.usage===x?el:Ju;this.bufferColor=e,r=_n(t(e,"vec3",3,0))}this.instanceColorNode=r}const n=t.mul(Fd).xyz;if(Fd.assign(n),e.needsPreviousData()&&Ld.assign(this.getPreviousInstancedPosition(e)),e.hasGeometryAttribute("normal")){const e=Yd($d,t);$d.assign(e)}null!==this.instanceColorNode&&Un("vec3","vInstanceColor").assign(this.instanceColorNode)}update(e){null!==this.buffer&&!0!==this.isStorageMatrix&&(this.buffer.clearUpdateRanges(),this.buffer.updateRanges.push(...this.instanceMatrix.updateRanges),this.instanceMatrix.version!==this.buffer.version&&(this.buffer.version=this.instanceMatrix.version)),this.instanceColor&&null!==this.bufferColor&&!0!==this.isStorageColor&&(this.bufferColor.clearUpdateRanges(),this.bufferColor.updateRanges.push(...this.instanceColor.updateRanges),this.instanceColor.version!==this.bufferColor.version&&(this.bufferColor.version=this.instanceColor.version)),null!==this.previousInstanceMatrixNode&&e.object.previousInstanceMatrix.array.set(this.instanceMatrix.array)}getPreviousInstancedPosition(e){const t=e.object;return null===this.previousInstanceMatrixNode&&(t.previousInstanceMatrix=this.instanceMatrix.clone(),this.previousInstanceMatrixNode=this._createInstanceMatrixNode(!1,e)),this.previousInstanceMatrixNode.mul(Ld).xyz}_createInstanceMatrixNode(e,t){let r;const{instanceMatrix:s}=this,{count:i}=s;if(this.isStorageMatrix)r=Wh(s,"mat4",Math.max(i,1)).element(jh);else{if(i<=(!0===t.renderer.backend.isWebGPUBackend?1e3:250))r=Dl(s.array,"mat4",Math.max(i,1)).element(jh);else{const t=new H(s.array,16,1);!0===e&&(this.buffer=t);const i=s.usage===x?el:Ju,n=[i(t,"vec4",16,0),i(t,"vec4",16,4),i(t,"vec4",16,8),i(t,"vec4",16,12)];r=Bn(...n)}}return r}}const Jh=tn(Zh).setParameterLength(2,3);class ep extends Zh{static get type(){return"InstancedMeshNode"}constructor(e){const{count:t,instanceMatrix:r,instanceColor:s}=e;super(t,r,s),this.instancedMesh=e}}const tp=tn(ep).setParameterLength(1);class rp extends oi{static get type(){return"BatchNode"}constructor(e){super("void"),this.batchMesh=e,this.batchingIdNode=null}setup(e){null===this.batchingIdNode&&(null===e.getDrawIndex()?this.batchingIdNode=jh:this.batchingIdNode=Qh);const t=on(([e])=>{const t=gn(Al(Ll(this.batchMesh._indirectTexture),0).x).toConst(),r=gn(e).mod(t).toConst(),s=gn(e).div(t).toConst();return Ll(this.batchMesh._indirectTexture,bn(r,s)).x}).setLayout({name:"getIndirectIndex",type:"uint",inputs:[{name:"id",type:"int"}]}),r=t(gn(this.batchingIdNode)),s=this.batchMesh._matricesTexture,i=gn(Al(Ll(s),0).x).toConst(),n=pn(r).mul(4).toInt().toConst(),a=n.mod(i).toConst(),o=n.div(i).toConst(),u=Bn(Ll(s,bn(a,o)),Ll(s,bn(a.add(1),o)),Ll(s,bn(a.add(2),o)),Ll(s,bn(a.add(3),o))),l=this.batchMesh._colorsTexture;if(null!==l){const e=on(([e])=>{const t=gn(Al(Ll(l),0).x).toConst(),r=e,s=r.mod(t).toConst(),i=r.div(t).toConst();return Ll(l,bn(s,i)).rgb}).setLayout({name:"getBatchingColor",type:"vec3",inputs:[{name:"id",type:"int"}]}),t=e(r);Un("vec3","vBatchColor").assign(t)}const d=Mn(u);Fd.assign(u.mul(Fd));const c=$d.div(_n(d[0].dot(d[0]),d[1].dot(d[1]),d[2].dot(d[2]))),h=d.mul(c).xyz;$d.assign(h),e.hasGeometryAttribute("tangent")&&Dc.mulAssign(d)}}const sp=tn(rp).setParameterLength(1),ip=new WeakMap;class np extends oi{static get type(){return"SkinningNode"}constructor(e){super("void"),this.skinnedMesh=e,this.updateType=Zs.OBJECT,this.skinIndexNode=Nl("skinIndex","uvec4"),this.skinWeightNode=Nl("skinWeight","vec4"),this.bindMatrixNode=fc("bindMatrix","mat4"),this.bindMatrixInverseNode=fc("bindMatrixInverse","mat4"),this.boneMatricesNode=yc("skeleton.boneMatrices","mat4",e.skeleton.bones.length),this.positionNode=Fd,this.toPositionNode=Fd,this.previousBoneMatricesNode=null}getSkinnedPosition(e=this.boneMatricesNode,t=this.positionNode){const{skinIndexNode:r,skinWeightNode:s,bindMatrixNode:i,bindMatrixInverseNode:n}=this,a=e.element(r.x),o=e.element(r.y),u=e.element(r.z),l=e.element(r.w),d=i.mul(t),c=Ca(a.mul(s.x).mul(d),o.mul(s.y).mul(d),u.mul(s.z).mul(d),l.mul(s.w).mul(d));return n.mul(c).xyz}getSkinnedNormalAndTangent(e=this.boneMatricesNode,t=$d,r=Dc){const{skinIndexNode:s,skinWeightNode:i,bindMatrixNode:n,bindMatrixInverseNode:a}=this,o=e.element(s.x),u=e.element(s.y),l=e.element(s.z),d=e.element(s.w);let c=Ca(i.x.mul(o),i.y.mul(u),i.z.mul(l),i.w.mul(d));c=a.mul(c).mul(n);return{skinNormal:c.transformDirection(t).xyz,skinTangent:c.transformDirection(r).xyz}}getPreviousSkinnedPosition(e){const t=e.object;return null===this.previousBoneMatricesNode&&(t.skeleton.previousBoneMatrices=new Float32Array(t.skeleton.boneMatrices),this.previousBoneMatricesNode=yc("skeleton.previousBoneMatrices","mat4",t.skeleton.bones.length)),this.getSkinnedPosition(this.previousBoneMatricesNode,Ld)}setup(e){e.needsPreviousData()&&Ld.assign(this.getPreviousSkinnedPosition(e));const t=this.getSkinnedPosition();if(this.toPositionNode&&this.toPositionNode.assign(t),e.hasGeometryAttribute("normal")){const{skinNormal:t,skinTangent:r}=this.getSkinnedNormalAndTangent();$d.assign(t),e.hasGeometryAttribute("tangent")&&Dc.assign(r)}return t}generate(e,t){if("void"!==t)return super.generate(e,t)}update(e){const t=e.object&&e.object.skeleton?e.object.skeleton:this.skinnedMesh.skeleton;ip.get(t)!==e.frameId&&(ip.set(t,e.frameId),null!==this.previousBoneMatricesNode&&(null===t.previousBoneMatrices&&(t.previousBoneMatrices=new Float32Array(t.boneMatrices)),t.previousBoneMatrices.set(t.boneMatrices)),t.update())}}const ap=e=>new np(e);class op extends oi{static get type(){return"LoopNode"}constructor(e=[]){super("void"),this.params=e}getVarName(e){return String.fromCharCode("i".charCodeAt(0)+e)}getProperties(e){const t=e.getNodeProperties(this);if(void 0!==t.stackNode)return t;const r={};for(let e=0,t=this.params.length-1;eNumber(l)?">=":"<")),a)n=`while ( ${l} )`;else{const r={start:u,end:l},s=r.start,i=r.end;let a;const g=()=>h.includes("<")?"+=":"-=";if(null!=p)switch(typeof p){case"function":a=e.flowStagesNode(t.updateNode,"void").code.replace(/\t|;/g,"");break;case"number":a=d+" "+g()+" "+e.generateConst(c,p);break;case"string":a=d+" "+p;break;default:p.isNode?a=d+" "+g()+" "+p.build(e):(o("TSL: 'Loop( { update: ... } )' is not a function, string or number."),a="break /* invalid update */")}else p="int"===c||"uint"===c?h.includes("<")?"++":"--":g()+" 1.",a=d+" "+p;n=`for ( ${e.getVar(c,d)+" = "+s}; ${d+" "+h+" "+i}; ${a} )`}e.addFlowCode((0===s?"\n":"")+e.tab+n+" {\n\n").addFlowTab()}const i=s.build(e,"void");t.returnsNode.build(e,"void"),e.removeFlowTab().addFlowCode("\n"+e.tab+i);for(let t=0,r=this.params.length-1;tnew op(en(e,"int")).toStack(),lp=()=>pl("break").toStack(),dp=new WeakMap,cp=new s,hp=on(({bufferMap:e,influence:t,stride:r,width:s,depth:i,offset:n})=>{const a=gn(qh).mul(r).add(n),o=a.div(s),u=a.sub(o.mul(s));return Ll(e,bn(u,o)).depth(i).xyz.mul(t)});class pp extends oi{static get type(){return"MorphNode"}constructor(e){super("void"),this.mesh=e,this.morphBaseInfluence=Ta(1),this.updateType=Zs.OBJECT}setup(e){const{geometry:r}=e,s=void 0!==r.morphAttributes.position,i=r.hasAttribute("normal")&&void 0!==r.morphAttributes.normal,n=r.morphAttributes.position||r.morphAttributes.normal||r.morphAttributes.color,a=void 0!==n?n.length:0,{texture:o,stride:u,size:l}=function(e){const r=void 0!==e.morphAttributes.position,s=void 0!==e.morphAttributes.normal,i=void 0!==e.morphAttributes.color,n=e.morphAttributes.position||e.morphAttributes.normal||e.morphAttributes.color,a=void 0!==n?n.length:0;let o=dp.get(e);if(void 0===o||o.count!==a){void 0!==o&&o.texture.dispose();const u=e.morphAttributes.position||[],l=e.morphAttributes.normal||[],d=e.morphAttributes.color||[];let c=0;!0===r&&(c=1),!0===s&&(c=2),!0===i&&(c=3);let h=e.attributes.position.count*c,p=1;const g=4096;h>g&&(p=Math.ceil(h/g),h=g);const m=new Float32Array(h*p*4*a),f=new q(m,h,p,a);f.type=j,f.needsUpdate=!0;const y=4*c;for(let x=0;x{const t=pn(0).toVar();this.mesh.count>1&&null!==this.mesh.morphTexture&&void 0!==this.mesh.morphTexture?t.assign(Ll(this.mesh.morphTexture,bn(gn(e).add(1),gn(jh))).r):t.assign(fc("morphTargetInfluences","float").element(e).toVar()),dn(t.notEqual(0),()=>{!0===s&&Fd.addAssign(hp({bufferMap:o,influence:t,stride:u,width:d,depth:e,offset:gn(0)})),!0===i&&$d.addAssign(hp({bufferMap:o,influence:t,stride:u,width:d,depth:e,offset:gn(1)}))})})}update(){const e=this.morphBaseInfluence;this.mesh.geometry.morphTargetsRelative?e.value=1:e.value=1-this.mesh.morphTargetInfluences.reduce((e,t)=>e+t,0)}}const gp=tn(pp).setParameterLength(1);class mp extends oi{static get type(){return"LightingNode"}constructor(){super("vec3"),this.isLightingNode=!0}}class fp extends mp{static get type(){return"AONode"}constructor(e=null){super(),this.aoNode=e}setup(e){e.context.ambientOcclusion.mulAssign(this.aoNode)}}class yp extends bu{static get type(){return"LightingContextNode"}constructor(e,t=null,r=null,s=null){super(e),this.lightingModel=t,this.backdropNode=r,this.backdropAlphaNode=s,this._value=null}getContext(){const{backdropNode:e,backdropAlphaNode:t}=this,r={directDiffuse:_n().toVar("directDiffuse"),directSpecular:_n().toVar("directSpecular"),indirectDiffuse:_n().toVar("indirectDiffuse"),indirectSpecular:_n().toVar("indirectSpecular")};return{radiance:_n().toVar("radiance"),irradiance:_n().toVar("irradiance"),iblIrradiance:_n().toVar("iblIrradiance"),ambientOcclusion:pn(1).toVar("ambientOcclusion"),reflectedLight:r,backdrop:e,backdropAlpha:t}}setup(e){return this.value=this._value||(this._value=this.getContext()),this.value.lightingModel=this.lightingModel||e.context.lightingModel,super.setup(e)}}const bp=tn(yp);class xp extends mp{static get type(){return"IrradianceNode"}constructor(e){super(),this.node=e}setup(e){e.context.irradiance.addAssign(this.node)}}const Tp=new t;class _p extends Ml{static get type(){return"ViewportTextureNode"}constructor(e=Hl,t=null,r=null){let s=null;null===r?(s=new X,s.minFilter=K,r=s):s=r,super(r,e,t),this.generateMipmaps=!1,this.defaultFramebuffer=s,this.isOutputTextureNode=!0,this.updateBeforeType=Zs.RENDER,this._cacheTextures=new WeakMap}getTextureForReference(e=null){let t,r;if(this.referenceNode?(t=this.referenceNode.defaultFramebuffer,r=this.referenceNode._cacheTextures):(t=this.defaultFramebuffer,r=this._cacheTextures),null===e)return t;if(!1===r.has(e)){const s=t.clone();r.set(e,s)}return r.get(e)}updateReference(e){const t=e.renderer.getRenderTarget();return this.value=this.getTextureForReference(t),this.value}updateBefore(e){const t=e.renderer,r=t.getRenderTarget();null===r?t.getDrawingBufferSize(Tp):Tp.set(r.width,r.height);const s=this.getTextureForReference(r);s.image.width===Tp.width&&s.image.height===Tp.height||(s.image.width=Tp.width,s.image.height=Tp.height,s.needsUpdate=!0);const i=s.generateMipmaps;s.generateMipmaps=this.generateMipmaps,t.copyFramebufferToTexture(s),s.generateMipmaps=i}clone(){const e=new this.constructor(this.uvNode,this.levelNode,this.value);return e.generateMipmaps=this.generateMipmaps,e}}const vp=tn(_p).setParameterLength(0,3),Np=tn(_p,null,null,{generateMipmaps:!0}).setParameterLength(0,3),Sp=Np(),Rp=(e=Hl,t=null)=>Sp.sample(e,t);let Ap=null;class Ep extends _p{static get type(){return"ViewportDepthTextureNode"}constructor(e=Hl,t=null){null===Ap&&(Ap=new Y),super(e,t,Ap)}getTextureForReference(){return Ap}}const wp=tn(Ep).setParameterLength(0,2);class Cp extends oi{static get type(){return"ViewportDepthNode"}constructor(e,t=null){super("float"),this.scope=e,this.valueNode=t,this.isViewportDepthNode=!0}generate(e){const{scope:t}=this;return t===Cp.DEPTH_BASE?e.getFragDepth():super.generate(e)}setup({camera:e}){const{scope:t}=this,r=this.valueNode;let s=null;if(t===Cp.DEPTH_BASE)null!==r&&(s=Pp().assign(r));else if(t===Cp.DEPTH)s=e.isPerspectiveCamera?Bp(Ud.z,ed,td):Mp(Ud.z,ed,td);else if(t===Cp.LINEAR_DEPTH)if(null!==r)if(e.isPerspectiveCamera){const e=Fp(r,ed,td);s=Mp(e,ed,td)}else s=r;else s=Mp(Ud.z,ed,td);return s}}Cp.DEPTH_BASE="depthBase",Cp.DEPTH="depth",Cp.LINEAR_DEPTH="linearDepth";const Mp=(e,t,r)=>e.add(t).div(t.sub(r)),Bp=(e,t,r)=>t.add(e).mul(r).div(r.sub(t).mul(e)),Fp=(e,t,r)=>t.mul(r).div(r.sub(t).mul(e).sub(r)),Lp=(e,t,r)=>{t=t.max(1e-6).toVar();const s=fo(e.negate().div(t)),i=fo(r.div(t));return s.div(i)},Pp=tn(Cp,Cp.DEPTH_BASE),Dp=rn(Cp,Cp.DEPTH),Up=tn(Cp,Cp.LINEAR_DEPTH).setParameterLength(0,1),Ip=Up(wp());Dp.assign=e=>Pp(e);class Op extends oi{static get type(){return"ClippingNode"}constructor(e=Op.DEFAULT){super(),this.scope=e}setup(e){super.setup(e);const t=e.clippingContext,{intersectionPlanes:r,unionPlanes:s}=t;return this.hardwareClipping=e.material.hardwareClipping,this.scope===Op.ALPHA_TO_COVERAGE?this.setupAlphaToCoverage(r,s):this.scope===Op.HARDWARE?this.setupHardwareClipping(s,e):this.setupDefault(r,s)}setupAlphaToCoverage(e,t){return on(()=>{const r=pn().toVar("distanceToPlane"),s=pn().toVar("distanceToGradient"),i=pn(1).toVar("clipOpacity"),n=t.length;if(!1===this.hardwareClipping&&n>0){const e=Ol(t).setGroup(ya);up(n,({i:t})=>{const n=e.element(t);r.assign(Ud.dot(n.xyz).negate().add(n.w)),s.assign(r.fwidth().div(2)),i.mulAssign(uu(s.negate(),s,r))})}const a=e.length;if(a>0){const t=Ol(e).setGroup(ya),n=pn(1).toVar("intersectionClipOpacity");up(a,({i:e})=>{const i=t.element(e);r.assign(Ud.dot(i.xyz).negate().add(i.w)),s.assign(r.fwidth().div(2)),n.mulAssign(uu(s.negate(),s,r).oneMinus())}),i.mulAssign(n.oneMinus())}In.a.mulAssign(i),In.a.equal(0).discard()})()}setupDefault(e,t){return on(()=>{const r=t.length;if(!1===this.hardwareClipping&&r>0){const e=Ol(t).setGroup(ya);up(r,({i:t})=>{const r=e.element(t);Ud.dot(r.xyz).greaterThan(r.w).discard()})}const s=e.length;if(s>0){const t=Ol(e).setGroup(ya),r=fn(!0).toVar("clipped");up(s,({i:e})=>{const s=t.element(e);r.assign(Ud.dot(s.xyz).greaterThan(s.w).and(r))}),r.discard()}})()}setupHardwareClipping(e,t){const r=e.length;return t.enableHardwareClipping(r),on(()=>{const s=Ol(e).setGroup(ya),i=kl(t.getClipDistance());up(r,({i:e})=>{const t=s.element(e),r=Ud.dot(t.xyz).sub(t.w).negate();i.element(e).assign(r)})})()}}Op.ALPHA_TO_COVERAGE="alphaToCoverage",Op.DEFAULT="default",Op.HARDWARE="hardware";const Vp=on(([e])=>vo(Ba(1e4,No(Ba(17,e.x).add(Ba(.1,e.y)))).mul(Ca(.1,Co(No(Ba(13,e.y).add(e.x))))))),kp=on(([e])=>Vp(yn(Vp(e.xy),e.z))),Gp=on(([e])=>{const t=Wo(Bo(Po(e.xyz)),Bo(Do(e.xyz))),r=pn(1).div(pn(.05).mul(t)).toVar("pixScale"),s=yn(go(xo(fo(r))),go(To(fo(r)))),i=yn(kp(xo(s.x.mul(e.xyz))),kp(xo(s.y.mul(e.xyz)))),n=vo(fo(r)),a=Ca(Ba(n.oneMinus(),i.x),Ba(n,i.y)),o=$o(n,n.oneMinus()),u=_n(a.mul(a).div(Ba(2,o).mul(Ma(1,o))),a.sub(Ba(.5,o)).div(Ma(1,o)),Ma(1,Ma(1,a).mul(Ma(1,a)).div(Ba(2,o).mul(Ma(1,o))))),l=a.lessThan(o.oneMinus()).select(a.lessThan(o).select(u.x,u.y),u.z);return nu(l,1e-6,1)}).setLayout({name:"getAlphaHashThreshold",type:"float",inputs:[{name:"position",type:"vec3"}]});class zp extends vl{static get type(){return"VertexColorNode"}constructor(e){super(null,"vec4"),this.isVertexColorNode=!0,this.index=e}getAttributeName(){const e=this.index;return"color"+(e>0?e:"")}generate(e){const t=this.getAttributeName(e);let r;return r=!0===e.hasGeometryAttribute(t)?super.generate(e):e.generateConst(this.nodeType,new s(1,1,1,1)),r}serialize(e){super.serialize(e),e.index=this.index}deserialize(e){super.deserialize(e),this.index=e.index}}const $p=(e=0)=>new zp(e),Wp=on(([e,t])=>$o(1,e.oneMinus().div(t)).oneMinus()).setLayout({name:"blendBurn",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),Hp=on(([e,t])=>$o(e.div(t.oneMinus()),1)).setLayout({name:"blendDodge",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),qp=on(([e,t])=>e.oneMinus().mul(t.oneMinus()).oneMinus()).setLayout({name:"blendScreen",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),jp=on(([e,t])=>iu(e.mul(2).mul(t),e.oneMinus().mul(2).mul(t.oneMinus()).oneMinus(),Ho(.5,e))).setLayout({name:"blendOverlay",type:"vec3",inputs:[{name:"base",type:"vec3"},{name:"blend",type:"vec3"}]}),Xp=on(([e,t])=>{const r=t.a.add(e.a.mul(t.a.oneMinus()));return Rn(t.rgb.mul(t.a).add(e.rgb.mul(e.a).mul(t.a.oneMinus())).div(r),r)}).setLayout({name:"blendColor",type:"vec4",inputs:[{name:"base",type:"vec4"},{name:"blend",type:"vec4"}]}),Kp=on(([e])=>Rn(e.rgb.mul(e.a),e.a),{color:"vec4",return:"vec4"}),Yp=on(([e])=>(dn(e.a.equal(0),()=>Rn(0)),Rn(e.rgb.div(e.a),e.a)),{color:"vec4",return:"vec4"});class Qp extends Q{static get type(){return"NodeMaterial"}get type(){return this.constructor.type}set type(e){}constructor(){super(),this.isNodeMaterial=!0,this.fog=!0,this.lights=!1,this.hardwareClipping=!1,this.lightsNode=null,this.envNode=null,this.aoNode=null,this.colorNode=null,this.normalNode=null,this.opacityNode=null,this.backdropNode=null,this.backdropAlphaNode=null,this.alphaTestNode=null,this.maskNode=null,this.maskShadowNode=null,this.positionNode=null,this.geometryNode=null,this.depthNode=null,this.receivedShadowPositionNode=null,this.castShadowPositionNode=null,this.receivedShadowNode=null,this.castShadowNode=null,this.outputNode=null,this.mrtNode=null,this.fragmentNode=null,this.vertexNode=null,this.contextNode=null}_getNodeChildren(){const e=[];for(const t of Object.getOwnPropertyNames(this)){if(!0===t.startsWith("_"))continue;const r=this[t];r&&!0===r.isNode&&e.push({property:t,childNode:r})}return e}customProgramCacheKey(){const e=[];for(const{property:t,childNode:r}of this._getNodeChildren())e.push(Ds(t.slice(0,-4)),r.getCacheKey());return this.type+Us(e)}build(e){this.setup(e)}setupObserver(e){return new Ls(e)}setup(e){e.context.setupNormal=()=>Bu(this.setupNormal(e),"NORMAL","vec3"),e.context.setupPositionView=()=>this.setupPositionView(e),e.context.setupModelViewProjection=()=>this.setupModelViewProjection(e);const t=e.renderer,r=t.getRenderTarget();!0===t.contextNode.isContextNode?e.context={...e.context,...t.contextNode.getFlowContextData()}:o('NodeMaterial: "renderer.contextNode" must be an instance of `context()`.'),null!==this.contextNode&&(!0===this.contextNode.isContextNode?e.context={...e.context,...this.contextNode.getFlowContextData()}:o('NodeMaterial: "material.contextNode" must be an instance of `context()`.')),e.addStack();const s=this.setupVertex(e),i=Bu(this.vertexNode||s,"VERTEX");let n;e.context.clipSpace=i,e.stack.outputNode=i,this.setupHardwareClipping(e),null!==this.geometryNode&&(e.stack.outputNode=e.stack.outputNode.bypass(this.geometryNode)),e.addFlow("vertex",e.removeStack()),e.addStack();const a=this.setupClipping(e);if(!0!==this.depthWrite&&!0!==this.depthTest||(null!==r?!0===r.depthBuffer&&this.setupDepth(e):!0===t.depth&&this.setupDepth(e)),null===this.fragmentNode){this.setupDiffuseColor(e),this.setupVariants(e);const s=this.setupLighting(e);null!==a&&e.stack.addToStack(a);const i=Rn(s,In.a).max(0);n=this.setupOutput(e,i),sa.assign(n);const o=null!==this.outputNode;if(o&&(n=this.outputNode),e.context.getOutput&&(n=e.context.getOutput(n,e)),null!==r){const e=t.getMRT(),r=this.mrtNode;null!==e?(o&&sa.assign(n),n=e,null!==r&&(n=e.merge(r))):null!==r&&(n=r)}}else{let t=this.fragmentNode;!0!==t.isOutputStructNode&&(t=Rn(t)),n=this.setupOutput(e,t)}e.stack.outputNode=n,e.addFlow("fragment",e.removeStack()),e.observer=this.setupObserver(e)}setupClipping(e){if(null===e.clippingContext)return null;const{unionPlanes:t,intersectionPlanes:r}=e.clippingContext;let s=null;if(t.length>0||r.length>0){const t=e.renderer.currentSamples;this.alphaToCoverage&&t>1?s=new Op(Op.ALPHA_TO_COVERAGE):e.stack.addToStack(new Op)}return s}setupHardwareClipping(e){if(this.hardwareClipping=!1,null===e.clippingContext)return;const t=e.clippingContext.unionPlanes.length;t>0&&t<=8&&e.isAvailable("clipDistance")&&(e.stack.addToStack(new Op(Op.HARDWARE)),this.hardwareClipping=!0)}setupDepth(e){const{renderer:t,camera:r}=e;let s=this.depthNode;if(null===s){const e=t.getMRT();e&&e.has("depth")?s=e.get("depth"):!0===t.logarithmicDepthBuffer&&(s=r.isPerspectiveCamera?Lp(Ud.z,ed,td):Mp(Ud.z,ed,td))}null!==s&&Dp.assign(s).toStack()}setupPositionView(){return Ad.mul(Fd).xyz}setupModelViewProjection(){return rd.mul(Ud)}setupVertex(e){return e.addStack(),this.setupPosition(e),e.context.position=e.removeStack(),kh}setupPosition(e){const{object:t,geometry:r}=e;if((r.morphAttributes.position||r.morphAttributes.normal||r.morphAttributes.color)&&gp(t).toStack(),!0===t.isSkinnedMesh&&ap(t).toStack(),this.displacementMap){const e=xc("displacementMap","texture"),t=xc("displacementScale","float"),r=xc("displacementBias","float");Fd.addAssign($d.normalize().mul(e.x.mul(t).add(r)))}return t.isBatchedMesh&&sp(t).toStack(),t.isInstancedMesh&&t.instanceMatrix&&!0===t.instanceMatrix.isInstancedBufferAttribute&&tp(t).toStack(),null!==this.positionNode&&Fd.assign(Bu(this.positionNode,"POSITION","vec3")),Fd}setupDiffuseColor(e){const{object:t,geometry:r}=e;null!==this.maskNode&&fn(this.maskNode).not().discard();let s=this.colorNode?Rn(this.colorNode):sh;if(!0===this.vertexColors&&r.hasAttribute("color")&&(s=s.mul($p())),t.instanceColor){s=Un("vec3","vInstanceColor").mul(s)}if(t.isBatchedMesh&&t._colorsTexture){s=Un("vec3","vBatchColor").mul(s)}In.assign(s);const i=this.opacityNode?pn(this.opacityNode):ah;In.a.assign(In.a.mul(i));let n=null;(null!==this.alphaTestNode||this.alphaTest>0)&&(n=null!==this.alphaTestNode?pn(this.alphaTestNode):rh,!0===this.alphaToCoverage?(In.a=uu(n,n.add(Vo(In.a)),In.a),In.a.lessThanEqual(0).discard()):In.a.lessThanEqual(n).discard()),!0===this.alphaHash&&In.a.lessThan(Gp(Fd)).discard(),e.isOpaque()&&In.a.assign(1)}setupVariants(){}setupOutgoingLight(){return!0===this.lights?_n(0):In.rgb}setupNormal(){return this.normalNode?_n(this.normalNode):gh}setupEnvironment(){let e=null;return this.envNode?e=this.envNode:this.envMap&&(e=this.envMap.isCubeTexture?xc("envMap","cubeTexture"):xc("envMap","texture")),e}setupLightMap(e){let t=null;return e.material.lightMap&&(t=new xp(Ih)),t}setupLights(e){const t=[],r=this.setupEnvironment(e);r&&r.isLightingNode&&t.push(r);const s=this.setupLightMap(e);s&&s.isLightingNode&&t.push(s);let i=this.aoNode;null===i&&e.material.aoMap&&(i=Oh),e.context.getAO&&(i=e.context.getAO(i,e)),i&&t.push(new fp(i));let n=this.lightsNode||e.lightsNode;return t.length>0&&(n=e.renderer.lighting.createNode([...n.getLights(),...t])),n}setupLightingModel(){}setupLighting(e){const{material:t}=e,{backdropNode:r,backdropAlphaNode:s,emissiveNode:i}=this,n=!0===this.lights||null!==this.lightsNode?this.setupLights(e):null;let a=this.setupOutgoingLight(e);if(n&&n.getScope().hasLights){const t=this.setupLightingModel(e)||null;a=bp(n,t,r,s)}else null!==r&&(a=_n(null!==s?iu(a,r,s):r));return(i&&!0===i.isNode||t.emissive&&!0===t.emissive.isColor)&&(Vn.assign(_n(i||nh)),a=a.add(Vn)),a}setupFog(e,t){const r=e.fogNode;return r&&(sa.assign(t),t=Rn(r.toVar())),t}setupPremultipliedAlpha(e,t){return Kp(t)}setupOutput(e,t){return!0===this.fog&&(t=this.setupFog(e,t)),!0===this.premultipliedAlpha&&(t=this.setupPremultipliedAlpha(e,t)),t}setDefaultValues(e){for(const t in e){const r=e[t];void 0===this[t]&&(this[t]=r,r&&r.clone&&(this[t]=r.clone()))}const t=Object.getOwnPropertyDescriptors(e.constructor.prototype);for(const e in t)void 0===Object.getOwnPropertyDescriptor(this.constructor.prototype,e)&&void 0!==t[e].get&&Object.defineProperty(this.constructor.prototype,e,t[e])}toJSON(e){const t=void 0===e||"string"==typeof e;t&&(e={textures:{},images:{},nodes:{}});const r=Q.prototype.toJSON.call(this,e);r.inputNodes={};for(const{property:t,childNode:s}of this._getNodeChildren())r.inputNodes[t]=s.toJSON(e).uuid;function s(e){const t=[];for(const r in e){const s=e[r];delete s.metadata,t.push(s)}return t}if(t){const t=s(e.textures),i=s(e.images),n=s(e.nodes);t.length>0&&(r.textures=t),i.length>0&&(r.images=i),n.length>0&&(r.nodes=n)}return r}copy(e){return this.lightsNode=e.lightsNode,this.envNode=e.envNode,this.aoNode=e.aoNode,this.colorNode=e.colorNode,this.normalNode=e.normalNode,this.opacityNode=e.opacityNode,this.backdropNode=e.backdropNode,this.backdropAlphaNode=e.backdropAlphaNode,this.alphaTestNode=e.alphaTestNode,this.maskNode=e.maskNode,this.maskShadowNode=e.maskShadowNode,this.positionNode=e.positionNode,this.geometryNode=e.geometryNode,this.depthNode=e.depthNode,this.receivedShadowPositionNode=e.receivedShadowPositionNode,this.castShadowPositionNode=e.castShadowPositionNode,this.receivedShadowNode=e.receivedShadowNode,this.castShadowNode=e.castShadowNode,this.outputNode=e.outputNode,this.mrtNode=e.mrtNode,this.fragmentNode=e.fragmentNode,this.vertexNode=e.vertexNode,this.contextNode=e.contextNode,super.copy(e)}}const Zp=new Z;class Jp extends Qp{static get type(){return"LineBasicNodeMaterial"}constructor(e){super(),this.isLineBasicNodeMaterial=!0,this.setDefaultValues(Zp),this.setValues(e)}}const eg=new J;class tg extends Qp{static get type(){return"LineDashedNodeMaterial"}constructor(e){super(),this.isLineDashedNodeMaterial=!0,this.setDefaultValues(eg),this.dashOffset=0,this.offsetNode=null,this.dashScaleNode=null,this.dashSizeNode=null,this.gapSizeNode=null,this.setValues(e)}setupVariants(){const e=this.offsetNode?pn(this.offsetNode):Ph,t=this.dashScaleNode?pn(this.dashScaleNode):Mh,r=this.dashSizeNode?pn(this.dashSizeNode):Bh,s=this.gapSizeNode?pn(this.gapSizeNode):Fh;ia.assign(r),na.assign(s);const i=Lu(Nl("lineDistance").mul(t));(e?i.add(e):i).mod(ia.add(na)).greaterThan(ia).discard()}}const rg=new J;class sg extends Qp{static get type(){return"Line2NodeMaterial"}constructor(e={}){super(),this.isLine2NodeMaterial=!0,this.setDefaultValues(rg),this.vertexColors=e.vertexColors,this.dashOffset=0,this.lineColorNode=null,this.offsetNode=null,this.dashScaleNode=null,this.dashSizeNode=null,this.gapSizeNode=null,this.blending=ee,this._useDash=e.dashed,this._useAlphaToCoverage=!0,this._useWorldUnits=!1,this.setValues(e)}setup(e){const{renderer:t}=e,r=this._useAlphaToCoverage,s=this.vertexColors,i=this._useDash,n=this._useWorldUnits,a=on(({start:e,end:t})=>{const r=rd.element(2).element(2),s=rd.element(3).element(2).mul(-.5).div(r).sub(e.z).div(t.z.sub(e.z));return Rn(iu(e.xyz,t.xyz,s),t.w)}).setLayout({name:"trimSegment",type:"vec4",inputs:[{name:"start",type:"vec4"},{name:"end",type:"vec4"}]});this.vertexNode=on(()=>{const e=Nl("instanceStart"),t=Nl("instanceEnd"),r=Rn(Ad.mul(Rn(e,1))).toVar("start"),s=Rn(Ad.mul(Rn(t,1))).toVar("end");if(i){const e=this.dashScaleNode?pn(this.dashScaleNode):Mh,t=this.offsetNode?pn(this.offsetNode):Ph,r=Nl("instanceDistanceStart"),s=Nl("instanceDistanceEnd");let i=Bd.y.lessThan(.5).select(e.mul(r),e.mul(s));i=i.add(t),Un("float","lineDistance").assign(i)}n&&(Un("vec3","worldStart").assign(r.xyz),Un("vec3","worldEnd").assign(s.xyz));const o=Xl.z.div(Xl.w),u=rd.element(2).element(3).equal(-1);dn(u,()=>{dn(r.z.lessThan(0).and(s.z.greaterThan(0)),()=>{s.assign(a({start:r,end:s}))}).ElseIf(s.z.lessThan(0).and(r.z.greaterThanEqual(0)),()=>{r.assign(a({start:s,end:r}))})});const l=rd.mul(r),d=rd.mul(s),c=l.xyz.div(l.w),h=d.xyz.div(d.w),p=h.xy.sub(c.xy).toVar();p.x.assign(p.x.mul(o)),p.assign(p.normalize());const g=Rn().toVar();if(n){const e=s.xyz.sub(r.xyz).normalize(),t=iu(r.xyz,s.xyz,.5).normalize(),n=e.cross(t).normalize(),a=e.cross(n),o=Un("vec4","worldPos");o.assign(Bd.y.lessThan(.5).select(r,s));const u=Lh.mul(.5);o.addAssign(Rn(Bd.x.lessThan(0).select(n.mul(u),n.mul(u).negate()),0)),i||(o.addAssign(Rn(Bd.y.lessThan(.5).select(e.mul(u).negate(),e.mul(u)),0)),o.addAssign(Rn(a.mul(u),0)),dn(Bd.y.greaterThan(1).or(Bd.y.lessThan(0)),()=>{o.subAssign(Rn(a.mul(2).mul(u),0))})),g.assign(rd.mul(o));const l=_n().toVar();l.assign(Bd.y.lessThan(.5).select(c,h)),g.z.assign(l.z.mul(g.w))}else{const e=yn(p.y,p.x.negate()).toVar("offset");p.x.assign(p.x.div(o)),e.x.assign(e.x.div(o)),e.assign(Bd.x.lessThan(0).select(e.negate(),e)),dn(Bd.y.lessThan(0),()=>{e.assign(e.sub(p))}).ElseIf(Bd.y.greaterThan(1),()=>{e.assign(e.add(p))}),e.assign(e.mul(Lh)),e.assign(e.div(Xl.w.div(Wl))),g.assign(Bd.y.lessThan(.5).select(l,d)),e.assign(e.mul(g.w)),g.assign(g.add(Rn(e,0,0)))}return g})();const o=on(({p1:e,p2:t,p3:r,p4:s})=>{const i=e.sub(r),n=s.sub(r),a=t.sub(e),o=i.dot(n),u=n.dot(a),l=i.dot(a),d=n.dot(n),c=a.dot(a).mul(d).sub(u.mul(u)),h=o.mul(u).sub(l.mul(d)).div(c).clamp(),p=o.add(u.mul(h)).div(d).clamp();return yn(h,p)});if(this.colorNode=on(()=>{const e=Sl();if(i){const t=this.dashSizeNode?pn(this.dashSizeNode):Bh,r=this.gapSizeNode?pn(this.gapSizeNode):Fh;ia.assign(t),na.assign(r);const s=Un("float","lineDistance");e.y.lessThan(-1).or(e.y.greaterThan(1)).discard(),s.mod(ia.add(na)).greaterThan(ia).discard()}const a=pn(1).toVar("alpha");if(n){const e=Un("vec3","worldStart"),s=Un("vec3","worldEnd"),n=Un("vec4","worldPos").xyz.normalize().mul(1e5),u=s.sub(e),l=o({p1:e,p2:s,p3:_n(0,0,0),p4:n}),d=e.add(u.mul(l.x)),c=n.mul(l.y),h=d.sub(c).length().div(Lh);if(!i)if(r&&t.currentSamples>0){const e=h.fwidth();a.assign(uu(e.negate().add(.5),e.add(.5),h).oneMinus())}else h.greaterThan(.5).discard()}else if(r&&t.currentSamples>0){const t=e.x,r=e.y.greaterThan(0).select(e.y.sub(1),e.y.add(1)),s=t.mul(t).add(r.mul(r)),i=pn(s.fwidth()).toVar("dlen");dn(e.y.abs().greaterThan(1),()=>{a.assign(uu(i.oneMinus(),i.add(1),s).oneMinus())})}else dn(e.y.abs().greaterThan(1),()=>{const t=e.x,r=e.y.greaterThan(0).select(e.y.sub(1),e.y.add(1));t.mul(t).add(r.mul(r)).greaterThan(1).discard()});let u;if(this.lineColorNode)u=this.lineColorNode;else if(s){const e=Nl("instanceColorStart"),t=Nl("instanceColorEnd");u=Bd.y.lessThan(.5).select(e,t).mul(sh)}else u=sh;return Rn(u,a)})(),this.transparent){const e=this.opacityNode?pn(this.opacityNode):ah;this.outputNode=Rn(this.colorNode.rgb.mul(e).add(Rp().rgb.mul(e.oneMinus())),this.colorNode.a)}super.setup(e)}get worldUnits(){return this._useWorldUnits}set worldUnits(e){this._useWorldUnits!==e&&(this._useWorldUnits=e,this.needsUpdate=!0)}get dashed(){return this._useDash}set dashed(e){this._useDash!==e&&(this._useDash=e,this.needsUpdate=!0)}get alphaToCoverage(){return this._useAlphaToCoverage}set alphaToCoverage(e){this._useAlphaToCoverage!==e&&(this._useAlphaToCoverage=e,this.needsUpdate=!0)}}const ig=new te;class ng extends Qp{static get type(){return"MeshNormalNodeMaterial"}constructor(e){super(),this.isMeshNormalNodeMaterial=!0,this.setDefaultValues(ig),this.setValues(e)}setupDiffuseColor(){const e=this.opacityNode?pn(this.opacityNode):ah;In.assign(ku(Rn(qc(jd),e),re))}}const ag=on(([e=Dd])=>{const t=e.z.atan(e.x).mul(1/(2*Math.PI)).add(.5),r=e.y.clamp(-1,1).asin().mul(1/Math.PI).add(.5);return yn(t,r)});class og extends se{constructor(e=1,t={}){super(e,e,t),this.isCubeRenderTarget=!0;const r={width:e,height:e,depth:1},s=[r,r,r,r,r,r];this.texture=new L(s),this._setTextureOptions(t),this.texture.isRenderTargetTexture=!0}fromEquirectangularTexture(e,t){const r=t.minFilter,s=t.generateMipmaps;t.generateMipmaps=!0,this.texture.type=t.type,this.texture.colorSpace=t.colorSpace,this.texture.generateMipmaps=t.generateMipmaps,this.texture.minFilter=t.minFilter,this.texture.magFilter=t.magFilter;const i=new ie(5,5,5),n=ag(Dd),a=new Qp;a.colorNode=Fl(t,n,0),a.side=M,a.blending=ee;const o=new ne(i,a),u=new ae;u.add(o),t.minFilter===K&&(t.minFilter=oe);const l=new ue(1,10,this),d=e.getMRT();return e.setMRT(null),l.update(e,u),e.setMRT(d),t.minFilter=r,t.currentGenerateMipmaps=s,o.geometry.dispose(),o.material.dispose(),this}clear(e,t=!0,r=!0,s=!0){const i=e.getRenderTarget();for(let i=0;i<6;i++)e.setRenderTarget(this,i),e.clear(t,r,s);e.setRenderTarget(i)}}const ug=new WeakMap;class lg extends di{static get type(){return"CubeMapNode"}constructor(e){super("vec3"),this.envNode=e,this._cubeTexture=null,this._cubeTextureNode=pc(null);const t=new L;t.isRenderTargetTexture=!0,this._defaultTexture=t,this.updateBeforeType=Zs.RENDER}updateBefore(e){const{renderer:t,material:r}=e,s=this.envNode;if(s.isTextureNode||s.isMaterialReferenceNode){const e=s.isTextureNode?s.value:r[s.property];if(e&&e.isTexture){const r=e.mapping;if(r===le||r===de){if(ug.has(e)){const t=ug.get(e);cg(t,e.mapping),this._cubeTexture=t}else{const r=e.image;if(function(e){return null!=e&&e.height>0}(r)){const s=new og(r.height);s.fromEquirectangularTexture(t,e),cg(s.texture,e.mapping),this._cubeTexture=s.texture,ug.set(e,s.texture),e.addEventListener("dispose",dg)}else this._cubeTexture=this._defaultTexture}this._cubeTextureNode.value=this._cubeTexture}else this._cubeTextureNode=this.envNode}}}setup(e){return this.updateBefore(e),this._cubeTextureNode}}function dg(e){const t=e.target;t.removeEventListener("dispose",dg);const r=ug.get(t);void 0!==r&&(ug.delete(t),r.dispose())}function cg(e,t){t===le?e.mapping=P:t===de&&(e.mapping=D)}const hg=tn(lg).setParameterLength(1);class pg extends mp{static get type(){return"BasicEnvironmentNode"}constructor(e=null){super(),this.envNode=e}setup(e){e.context.environment=hg(this.envNode)}}class gg extends mp{static get type(){return"BasicLightMapNode"}constructor(e=null){super(),this.lightMapNode=e}setup(e){const t=pn(1/Math.PI);e.context.irradianceLightMap=this.lightMapNode.mul(t)}}class mg{start(e){e.lightsNode.setupLights(e,e.lightsNode.getLightNodes(e)),this.indirect(e)}finish(){}direct(){}directRectArea(){}indirect(){}ambientOcclusion(){}}class fg extends mg{constructor(){super()}indirect({context:e}){const t=e.ambientOcclusion,r=e.reflectedLight,s=e.irradianceLightMap;r.indirectDiffuse.assign(Rn(0)),s?r.indirectDiffuse.addAssign(s):r.indirectDiffuse.addAssign(Rn(1,1,1,0)),r.indirectDiffuse.mulAssign(t),r.indirectDiffuse.mulAssign(In.rgb)}finish(e){const{material:t,context:r}=e,s=r.outgoingLight,i=e.context.environment;if(i)switch(t.combine){case pe:s.rgb.assign(iu(s.rgb,s.rgb.mul(i.rgb),dh.mul(ch)));break;case he:s.rgb.assign(iu(s.rgb,i.rgb,dh.mul(ch)));break;case ce:s.rgb.addAssign(i.rgb.mul(dh.mul(ch)));break;default:d("BasicLightingModel: Unsupported .combine value:",t.combine)}}}const yg=new ge;class bg extends Qp{static get type(){return"MeshBasicNodeMaterial"}constructor(e){super(),this.isMeshBasicNodeMaterial=!0,this.lights=!0,this.setDefaultValues(yg),this.setValues(e)}setupNormal(){return Gd(Hd)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new pg(t):null}setupLightMap(e){let t=null;return e.material.lightMap&&(t=new gg(Ih)),t}setupOutgoingLight(){return In.rgb}setupLightingModel(){return new fg}}const xg=on(({f0:e,f90:t,dotVH:r})=>{const s=r.mul(-5.55473).sub(6.98316).mul(r).exp2();return e.mul(s.oneMinus()).add(t.mul(s))}),Tg=on(e=>e.diffuseColor.mul(1/Math.PI)),_g=on(({dotNH:e})=>ra.mul(pn(.5)).add(1).mul(pn(1/Math.PI)).mul(e.pow(ra))),vg=on(({lightDirection:e})=>{const t=e.add(Id).normalize(),r=jd.dot(t).clamp(),s=Id.dot(t).clamp(),i=xg({f0:Jn,f90:1,dotVH:s}),n=pn(.25),a=_g({dotNH:r});return i.mul(n).mul(a)});class Ng extends fg{constructor(e=!0){super(),this.specular=e}direct({lightDirection:e,lightColor:t,reflectedLight:r}){const s=jd.dot(e).clamp().mul(t);r.directDiffuse.addAssign(s.mul(Tg({diffuseColor:In.rgb}))),!0===this.specular&&r.directSpecular.addAssign(s.mul(vg({lightDirection:e})).mul(dh))}indirect(e){const{ambientOcclusion:t,irradiance:r,reflectedLight:s}=e.context;s.indirectDiffuse.addAssign(r.mul(Tg({diffuseColor:In}))),s.indirectDiffuse.mulAssign(t)}}const Sg=new me;class Rg extends Qp{static get type(){return"MeshLambertNodeMaterial"}constructor(e){super(),this.isMeshLambertNodeMaterial=!0,this.lights=!0,this.setDefaultValues(Sg),this.setValues(e)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new pg(t):null}setupLightingModel(){return new Ng(!1)}}const Ag=new fe;class Eg extends Qp{static get type(){return"MeshPhongNodeMaterial"}constructor(e){super(),this.isMeshPhongNodeMaterial=!0,this.lights=!0,this.shininessNode=null,this.specularNode=null,this.setDefaultValues(Ag),this.setValues(e)}setupEnvironment(e){const t=super.setupEnvironment(e);return t?new pg(t):null}setupLightingModel(){return new Ng}setupVariants(){const e=(this.shininessNode?pn(this.shininessNode):ih).max(1e-4);ra.assign(e);const t=this.specularNode||oh;Jn.assign(t)}copy(e){return this.shininessNode=e.shininessNode,this.specularNode=e.specularNode,super.copy(e)}}const wg=on(e=>{if(!1===e.geometry.hasAttribute("normal"))return pn(0);const t=Hd.dFdx().abs().max(Hd.dFdy().abs());return t.x.max(t.y).max(t.z)}),Cg=on(e=>{const{roughness:t}=e,r=wg();let s=t.max(.0525);return s=s.add(r),s=s.min(1),s}),Mg=on(({alpha:e,dotNL:t,dotNV:r})=>{const s=e.pow2(),i=t.mul(s.add(s.oneMinus().mul(r.pow2())).sqrt()),n=r.mul(s.add(s.oneMinus().mul(t.pow2())).sqrt());return Fa(.5,i.add(n).max(ro))}).setLayout({name:"V_GGX_SmithCorrelated",type:"float",inputs:[{name:"alpha",type:"float"},{name:"dotNL",type:"float"},{name:"dotNV",type:"float"}]}),Bg=on(({alphaT:e,alphaB:t,dotTV:r,dotBV:s,dotTL:i,dotBL:n,dotNV:a,dotNL:o})=>{const u=o.mul(_n(e.mul(r),t.mul(s),a).length()),l=a.mul(_n(e.mul(i),t.mul(n),o).length());return Fa(.5,u.add(l))}).setLayout({name:"V_GGX_SmithCorrelated_Anisotropic",type:"float",inputs:[{name:"alphaT",type:"float",qualifier:"in"},{name:"alphaB",type:"float",qualifier:"in"},{name:"dotTV",type:"float",qualifier:"in"},{name:"dotBV",type:"float",qualifier:"in"},{name:"dotTL",type:"float",qualifier:"in"},{name:"dotBL",type:"float",qualifier:"in"},{name:"dotNV",type:"float",qualifier:"in"},{name:"dotNL",type:"float",qualifier:"in"}]}),Fg=on(({alpha:e,dotNH:t})=>{const r=e.pow2(),s=t.pow2().mul(r.oneMinus()).oneMinus();return r.div(s.pow2()).mul(1/Math.PI)}).setLayout({name:"D_GGX",type:"float",inputs:[{name:"alpha",type:"float"},{name:"dotNH",type:"float"}]}),Lg=pn(1/Math.PI),Pg=on(({alphaT:e,alphaB:t,dotNH:r,dotTH:s,dotBH:i})=>{const n=e.mul(t),a=_n(t.mul(s),e.mul(i),n.mul(r)),o=a.dot(a),u=n.div(o);return Lg.mul(n.mul(u.pow2()))}).setLayout({name:"D_GGX_Anisotropic",type:"float",inputs:[{name:"alphaT",type:"float",qualifier:"in"},{name:"alphaB",type:"float",qualifier:"in"},{name:"dotNH",type:"float",qualifier:"in"},{name:"dotTH",type:"float",qualifier:"in"},{name:"dotBH",type:"float",qualifier:"in"}]}),Dg=on(({lightDirection:e,f0:t,f90:r,roughness:s,f:i,normalView:n=jd,USE_IRIDESCENCE:a,USE_ANISOTROPY:o})=>{const u=s.pow2(),l=e.add(Id).normalize(),d=n.dot(e).clamp(),c=n.dot(Id).clamp(),h=n.dot(l).clamp(),p=Id.dot(l).clamp();let g,m,f=xg({f0:t,f90:r,dotVH:p});if(Xi(a)&&(f=qn.mix(f,i)),Xi(o)){const t=Qn.dot(e),r=Qn.dot(Id),s=Qn.dot(l),i=Zn.dot(e),n=Zn.dot(Id),a=Zn.dot(l);g=Bg({alphaT:Kn,alphaB:u,dotTV:r,dotBV:n,dotTL:t,dotBL:i,dotNV:c,dotNL:d}),m=Pg({alphaT:Kn,alphaB:u,dotNH:h,dotTH:s,dotBH:a})}else g=Mg({alpha:u,dotNL:d,dotNV:c}),m=Fg({alpha:u,dotNH:h});return f.mul(g).mul(m)}),Ug=new Uint16Array([12469,15057,12620,14925,13266,14620,13807,14376,14323,13990,14545,13625,14713,13328,14840,12882,14931,12528,14996,12233,15039,11829,15066,11525,15080,11295,15085,10976,15082,10705,15073,10495,13880,14564,13898,14542,13977,14430,14158,14124,14393,13732,14556,13410,14702,12996,14814,12596,14891,12291,14937,11834,14957,11489,14958,11194,14943,10803,14921,10506,14893,10278,14858,9960,14484,14039,14487,14025,14499,13941,14524,13740,14574,13468,14654,13106,14743,12678,14818,12344,14867,11893,14889,11509,14893,11180,14881,10751,14852,10428,14812,10128,14765,9754,14712,9466,14764,13480,14764,13475,14766,13440,14766,13347,14769,13070,14786,12713,14816,12387,14844,11957,14860,11549,14868,11215,14855,10751,14825,10403,14782,10044,14729,9651,14666,9352,14599,9029,14967,12835,14966,12831,14963,12804,14954,12723,14936,12564,14917,12347,14900,11958,14886,11569,14878,11247,14859,10765,14828,10401,14784,10011,14727,9600,14660,9289,14586,8893,14508,8533,15111,12234,15110,12234,15104,12216,15092,12156,15067,12010,15028,11776,14981,11500,14942,11205,14902,10752,14861,10393,14812,9991,14752,9570,14682,9252,14603,8808,14519,8445,14431,8145,15209,11449,15208,11451,15202,11451,15190,11438,15163,11384,15117,11274,15055,10979,14994,10648,14932,10343,14871,9936,14803,9532,14729,9218,14645,8742,14556,8381,14461,8020,14365,7603,15273,10603,15272,10607,15267,10619,15256,10631,15231,10614,15182,10535,15118,10389,15042,10167,14963,9787,14883,9447,14800,9115,14710,8665,14615,8318,14514,7911,14411,7507,14279,7198,15314,9675,15313,9683,15309,9712,15298,9759,15277,9797,15229,9773,15166,9668,15084,9487,14995,9274,14898,8910,14800,8539,14697,8234,14590,7790,14479,7409,14367,7067,14178,6621,15337,8619,15337,8631,15333,8677,15325,8769,15305,8871,15264,8940,15202,8909,15119,8775,15022,8565,14916,8328,14804,8009,14688,7614,14569,7287,14448,6888,14321,6483,14088,6171,15350,7402,15350,7419,15347,7480,15340,7613,15322,7804,15287,7973,15229,8057,15148,8012,15046,7846,14933,7611,14810,7357,14682,7069,14552,6656,14421,6316,14251,5948,14007,5528,15356,5942,15356,5977,15353,6119,15348,6294,15332,6551,15302,6824,15249,7044,15171,7122,15070,7050,14949,6861,14818,6611,14679,6349,14538,6067,14398,5651,14189,5311,13935,4958,15359,4123,15359,4153,15356,4296,15353,4646,15338,5160,15311,5508,15263,5829,15188,6042,15088,6094,14966,6001,14826,5796,14678,5543,14527,5287,14377,4985,14133,4586,13869,4257,15360,1563,15360,1642,15358,2076,15354,2636,15341,3350,15317,4019,15273,4429,15203,4732,15105,4911,14981,4932,14836,4818,14679,4621,14517,4386,14359,4156,14083,3795,13808,3437,15360,122,15360,137,15358,285,15355,636,15344,1274,15322,2177,15281,2765,15215,3223,15120,3451,14995,3569,14846,3567,14681,3466,14511,3305,14344,3121,14037,2800,13753,2467,15360,0,15360,1,15359,21,15355,89,15346,253,15325,479,15287,796,15225,1148,15133,1492,15008,1749,14856,1882,14685,1886,14506,1783,14324,1608,13996,1398,13702,1183]);let Ig=null;const Og=on(({roughness:e,dotNV:t})=>{null===Ig&&(Ig=new ye(Ug,16,16,G,be),Ig.name="DFG_LUT",Ig.minFilter=oe,Ig.magFilter=oe,Ig.wrapS=xe,Ig.wrapT=xe,Ig.generateMipmaps=!1,Ig.needsUpdate=!0);const r=yn(e,t);return Fl(Ig,r).rg}),Vg=on(({lightDirection:e,f0:t,f90:r,roughness:s,f:i,USE_IRIDESCENCE:n,USE_ANISOTROPY:a})=>{const o=Dg({lightDirection:e,f0:t,f90:r,roughness:s,f:i,USE_IRIDESCENCE:n,USE_ANISOTROPY:a}),u=jd.dot(e).clamp(),l=jd.dot(Id).clamp(),d=Og({roughness:s,dotNV:l}),c=Og({roughness:s,dotNV:u}),h=t.mul(d.x).add(r.mul(d.y)),p=t.mul(c.x).add(r.mul(c.y)),g=d.x.add(d.y),m=c.x.add(c.y),f=pn(1).sub(g),y=pn(1).sub(m),b=t.add(t.oneMinus().mul(.047619)),x=h.mul(p).mul(b).div(pn(1).sub(f.mul(y).mul(b).mul(b)).add(ro)),T=f.mul(y),_=x.mul(T);return o.add(_)}),kg=on(e=>{const{dotNV:t,specularColor:r,specularF90:s,roughness:i}=e,n=Og({dotNV:t,roughness:i});return r.mul(n.x).add(s.mul(n.y))}),Gg=on(({f:e,f90:t,dotVH:r})=>{const s=r.oneMinus().saturate(),i=s.mul(s),n=s.mul(i,i).clamp(0,.9999);return e.sub(_n(t).mul(n)).div(n.oneMinus())}).setLayout({name:"Schlick_to_F0",type:"vec3",inputs:[{name:"f",type:"vec3"},{name:"f90",type:"float"},{name:"dotVH",type:"float"}]}),zg=on(({roughness:e,dotNH:t})=>{const r=e.pow2(),s=pn(1).div(r),i=t.pow2().oneMinus().max(.0078125);return pn(2).add(s).mul(i.pow(s.mul(.5))).div(2*Math.PI)}).setLayout({name:"D_Charlie",type:"float",inputs:[{name:"roughness",type:"float"},{name:"dotNH",type:"float"}]}),$g=on(({dotNV:e,dotNL:t})=>pn(1).div(pn(4).mul(t.add(e).sub(t.mul(e))))).setLayout({name:"V_Neubelt",type:"float",inputs:[{name:"dotNV",type:"float"},{name:"dotNL",type:"float"}]}),Wg=on(({lightDirection:e})=>{const t=e.add(Id).normalize(),r=jd.dot(e).clamp(),s=jd.dot(Id).clamp(),i=jd.dot(t).clamp(),n=zg({roughness:Hn,dotNH:i}),a=$g({dotNV:s,dotNL:r});return Wn.mul(n).mul(a)}),Hg=on(({N:e,V:t,roughness:r})=>{const s=e.dot(t).saturate(),i=yn(r,s.oneMinus().sqrt());return i.assign(i.mul(.984375).add(.0078125)),i}).setLayout({name:"LTC_Uv",type:"vec2",inputs:[{name:"N",type:"vec3"},{name:"V",type:"vec3"},{name:"roughness",type:"float"}]}),qg=on(({f:e})=>{const t=e.length();return Wo(t.mul(t).add(e.z).div(t.add(1)),0)}).setLayout({name:"LTC_ClippedSphereFormFactor",type:"float",inputs:[{name:"f",type:"vec3"}]}),jg=on(({v1:e,v2:t})=>{const r=e.dot(t),s=r.abs().toVar(),i=s.mul(.0145206).add(.4965155).mul(s).add(.8543985).toVar(),n=s.add(4.1616724).mul(s).add(3.417594).toVar(),a=i.div(n),o=r.greaterThan(0).select(a,Wo(r.mul(r).oneMinus(),1e-7).inverseSqrt().mul(.5).sub(a));return e.cross(t).mul(o)}).setLayout({name:"LTC_EdgeVectorFormFactor",type:"vec3",inputs:[{name:"v1",type:"vec3"},{name:"v2",type:"vec3"}]}),Xg=on(({N:e,V:t,P:r,mInv:s,p0:i,p1:n,p2:a,p3:o})=>{const u=n.sub(i).toVar(),l=o.sub(i).toVar(),d=u.cross(l),c=_n().toVar();return dn(d.dot(r.sub(i)).greaterThanEqual(0),()=>{const u=t.sub(e.mul(t.dot(e))).normalize(),l=e.cross(u).negate(),d=s.mul(Mn(u,l,e).transpose()).toVar(),h=d.mul(i.sub(r)).normalize().toVar(),p=d.mul(n.sub(r)).normalize().toVar(),g=d.mul(a.sub(r)).normalize().toVar(),m=d.mul(o.sub(r)).normalize().toVar(),f=_n(0).toVar();f.addAssign(jg({v1:h,v2:p})),f.addAssign(jg({v1:p,v2:g})),f.addAssign(jg({v1:g,v2:m})),f.addAssign(jg({v1:m,v2:h})),c.assign(_n(qg({f:f})))}),c}).setLayout({name:"LTC_Evaluate",type:"vec3",inputs:[{name:"N",type:"vec3"},{name:"V",type:"vec3"},{name:"P",type:"vec3"},{name:"mInv",type:"mat3"},{name:"p0",type:"vec3"},{name:"p1",type:"vec3"},{name:"p2",type:"vec3"},{name:"p3",type:"vec3"}]}),Kg=on(({P:e,p0:t,p1:r,p2:s,p3:i})=>{const n=r.sub(t).toVar(),a=i.sub(t).toVar(),o=n.cross(a),u=_n().toVar();return dn(o.dot(e.sub(t)).greaterThanEqual(0),()=>{const n=t.sub(e).normalize().toVar(),a=r.sub(e).normalize().toVar(),o=s.sub(e).normalize().toVar(),l=i.sub(e).normalize().toVar(),d=_n(0).toVar();d.addAssign(jg({v1:n,v2:a})),d.addAssign(jg({v1:a,v2:o})),d.addAssign(jg({v1:o,v2:l})),d.addAssign(jg({v1:l,v2:n})),u.assign(_n(qg({f:d.abs()})))}),u}).setLayout({name:"LTC_Evaluate",type:"vec3",inputs:[{name:"P",type:"vec3"},{name:"p0",type:"vec3"},{name:"p1",type:"vec3"},{name:"p2",type:"vec3"},{name:"p3",type:"vec3"}]}),Yg=1/6,Qg=e=>Ba(Yg,Ba(e,Ba(e,e.negate().add(3)).sub(3)).add(1)),Zg=e=>Ba(Yg,Ba(e,Ba(e,Ba(3,e).sub(6))).add(4)),Jg=e=>Ba(Yg,Ba(e,Ba(e,Ba(-3,e).add(3)).add(3)).add(1)),em=e=>Ba(Yg,Qo(e,3)),tm=e=>Qg(e).add(Zg(e)),rm=e=>Jg(e).add(em(e)),sm=e=>Ca(-1,Zg(e).div(Qg(e).add(Zg(e)))),im=e=>Ca(1,em(e).div(Jg(e).add(em(e)))),nm=(e,t,r)=>{const s=e.uvNode,i=Ba(s,t.zw).add(.5),n=xo(i),a=vo(i),o=tm(a.x),u=rm(a.x),l=sm(a.x),d=im(a.x),c=sm(a.y),h=im(a.y),p=yn(n.x.add(l),n.y.add(c)).sub(.5).mul(t.xy),g=yn(n.x.add(d),n.y.add(c)).sub(.5).mul(t.xy),m=yn(n.x.add(l),n.y.add(h)).sub(.5).mul(t.xy),f=yn(n.x.add(d),n.y.add(h)).sub(.5).mul(t.xy),y=tm(a.y).mul(Ca(o.mul(e.sample(p).level(r)),u.mul(e.sample(g).level(r)))),b=rm(a.y).mul(Ca(o.mul(e.sample(m).level(r)),u.mul(e.sample(f).level(r))));return y.add(b)},am=on(([e,t])=>{const r=yn(e.size(gn(t))),s=yn(e.size(gn(t.add(1)))),i=Fa(1,r),n=Fa(1,s),a=nm(e,Rn(i,r),xo(t)),o=nm(e,Rn(n,s),To(t));return vo(t).mix(a,o)}),om=on(([e,t])=>{const r=t.mul(wl(e));return am(e,r)}),um=on(([e,t,r,s,i])=>{const n=_n(ou(t.negate(),_o(e),Fa(1,s))),a=_n(Bo(i[0].xyz),Bo(i[1].xyz),Bo(i[2].xyz));return _o(n).mul(r.mul(a))}).setLayout({name:"getVolumeTransmissionRay",type:"vec3",inputs:[{name:"n",type:"vec3"},{name:"v",type:"vec3"},{name:"thickness",type:"float"},{name:"ior",type:"float"},{name:"modelMatrix",type:"mat4"}]}),lm=on(([e,t])=>e.mul(nu(t.mul(2).sub(2),0,1))).setLayout({name:"applyIorToRoughness",type:"float",inputs:[{name:"roughness",type:"float"},{name:"ior",type:"float"}]}),dm=Np(),cm=Rp(),hm=on(([e,t,r],{material:s})=>{const i=(s.side===M?dm:cm).sample(e),n=fo(ql.x).mul(lm(t,r));return am(i,n)}),pm=on(([e,t,r])=>(dn(r.notEqual(0),()=>{const s=mo(t).negate().div(r);return po(s.negate().mul(e))}),_n(1))).setLayout({name:"volumeAttenuation",type:"vec3",inputs:[{name:"transmissionDistance",type:"float"},{name:"attenuationColor",type:"vec3"},{name:"attenuationDistance",type:"float"}]}),gm=on(([e,t,r,s,i,n,a,o,u,l,d,c,h,p,g])=>{let m,f;if(g){m=Rn().toVar(),f=_n().toVar();const i=d.sub(1).mul(g.mul(.025)),n=_n(d.sub(i),d,d.add(i));up({start:0,end:3},({i:i})=>{const d=n.element(i),g=um(e,t,c,d,o),y=a.add(g),b=l.mul(u.mul(Rn(y,1))),x=yn(b.xy.div(b.w)).toVar();x.addAssign(1),x.divAssign(2),x.assign(yn(x.x,x.y.oneMinus()));const T=hm(x,r,d);m.element(i).assign(T.element(i)),m.a.addAssign(T.a),f.element(i).assign(s.element(i).mul(pm(Bo(g),h,p).element(i)))}),m.a.divAssign(3)}else{const i=um(e,t,c,d,o),n=a.add(i),g=l.mul(u.mul(Rn(n,1))),y=yn(g.xy.div(g.w)).toVar();y.addAssign(1),y.divAssign(2),y.assign(yn(y.x,y.y.oneMinus())),m=hm(y,r,d),f=s.mul(pm(Bo(i),h,p))}const y=f.rgb.mul(m.rgb),b=e.dot(t).clamp(),x=_n(kg({dotNV:b,specularColor:i,specularF90:n,roughness:r})),T=f.r.add(f.g,f.b).div(3);return Rn(x.oneMinus().mul(y),m.a.oneMinus().mul(T).oneMinus())}),mm=Mn(3.2404542,-.969266,.0556434,-1.5371385,1.8760108,-.2040259,-.4985314,.041556,1.0572252),fm=(e,t)=>e.sub(t).div(e.add(t)).pow2(),ym=on(({outsideIOR:e,eta2:t,cosTheta1:r,thinFilmThickness:s,baseF0:i})=>{const n=iu(e,t,uu(0,.03,s)),a=e.div(n).pow2().mul(r.pow2().oneMinus()).oneMinus();dn(a.lessThan(0),()=>_n(1));const o=a.sqrt(),u=fm(n,e),l=xg({f0:u,f90:1,dotVH:r}),d=l.oneMinus(),c=n.lessThan(e).select(Math.PI,0),h=pn(Math.PI).sub(c),p=(e=>{const t=e.sqrt();return _n(1).add(t).div(_n(1).sub(t))})(i.clamp(0,.9999)),g=fm(p,n.toVec3()),m=xg({f0:g,f90:1,dotVH:o}),f=_n(p.x.lessThan(n).select(Math.PI,0),p.y.lessThan(n).select(Math.PI,0),p.z.lessThan(n).select(Math.PI,0)),y=n.mul(s,o,2),b=_n(h).add(f),x=l.mul(m).clamp(1e-5,.9999),T=x.sqrt(),_=d.pow2().mul(m).div(_n(1).sub(x)),v=l.add(_).toVar(),N=_.sub(d).toVar();return up({start:1,end:2,condition:"<=",name:"m"},({m:e})=>{N.mulAssign(T);const t=((e,t)=>{const r=e.mul(2*Math.PI*1e-9),s=_n(54856e-17,44201e-17,52481e-17),i=_n(1681e3,1795300,2208400),n=_n(43278e5,93046e5,66121e5),a=pn(9747e-17*Math.sqrt(2*Math.PI*45282e5)).mul(r.mul(2239900).add(t.x).cos()).mul(r.pow2().mul(-45282e5).exp());let o=s.mul(n.mul(2*Math.PI).sqrt()).mul(i.mul(r).add(t).cos()).mul(r.pow2().negate().mul(n).exp());return o=_n(o.x.add(a),o.y,o.z).div(1.0685e-7),mm.mul(o)})(pn(e).mul(y),pn(e).mul(b)).mul(2);v.addAssign(N.mul(t))}),v.max(_n(0))}).setLayout({name:"evalIridescence",type:"vec3",inputs:[{name:"outsideIOR",type:"float"},{name:"eta2",type:"float"},{name:"cosTheta1",type:"float"},{name:"thinFilmThickness",type:"float"},{name:"baseF0",type:"vec3"}]}),bm=on(({normal:e,viewDir:t,roughness:r})=>{const s=e.dot(t).saturate(),i=r.mul(r),n=r.add(.1).reciprocal(),a=pn(-1.9362).add(r.mul(1.0678)).add(i.mul(.4573)).sub(n.mul(.8469)),o=pn(-.6014).add(r.mul(.5538)).sub(i.mul(.467)).sub(n.mul(.1255));return a.mul(s).add(o).exp().saturate()}),xm=_n(.04),Tm=pn(1);class _m extends mg{constructor(e=!1,t=!1,r=!1,s=!1,i=!1,n=!1){super(),this.clearcoat=e,this.sheen=t,this.iridescence=r,this.anisotropy=s,this.transmission=i,this.dispersion=n,this.clearcoatRadiance=null,this.clearcoatSpecularDirect=null,this.clearcoatSpecularIndirect=null,this.sheenSpecularDirect=null,this.sheenSpecularIndirect=null,this.iridescenceFresnel=null,this.iridescenceF0=null,this.iridescenceF0Dielectric=null,this.iridescenceF0Metallic=null}start(e){if(!0===this.clearcoat&&(this.clearcoatRadiance=_n().toVar("clearcoatRadiance"),this.clearcoatSpecularDirect=_n().toVar("clearcoatSpecularDirect"),this.clearcoatSpecularIndirect=_n().toVar("clearcoatSpecularIndirect")),!0===this.sheen&&(this.sheenSpecularDirect=_n().toVar("sheenSpecularDirect"),this.sheenSpecularIndirect=_n().toVar("sheenSpecularIndirect")),!0===this.iridescence){const e=jd.dot(Id).clamp(),t=ym({outsideIOR:pn(1),eta2:jn,cosTheta1:e,thinFilmThickness:Xn,baseF0:Jn}),r=ym({outsideIOR:pn(1),eta2:jn,cosTheta1:e,thinFilmThickness:Xn,baseF0:In.rgb});this.iridescenceFresnel=iu(t,r,Gn),this.iridescenceF0Dielectric=Gg({f:t,f90:1,dotVH:e}),this.iridescenceF0Metallic=Gg({f:r,f90:1,dotVH:e}),this.iridescenceF0=iu(this.iridescenceF0Dielectric,this.iridescenceF0Metallic,Gn)}if(!0===this.transmission){const t=Pd,r=od.sub(Pd).normalize(),s=Xd,i=e.context;i.backdrop=gm(s,r,kn,On,ea,ta,t,xd,id,rd,oa,la,ca,da,this.dispersion?ha:null),i.backdropAlpha=ua,In.a.mulAssign(iu(1,i.backdrop.a,ua))}super.start(e)}computeMultiscattering(e,t,r,s,i=null){const n=jd.dot(Id).clamp(),a=Og({roughness:kn,dotNV:n}),o=i?qn.mix(s,i):s,u=o.mul(a.x).add(r.mul(a.y)),l=a.x.add(a.y).oneMinus(),d=o.add(o.oneMinus().mul(.047619)),c=u.mul(d).div(l.mul(d).oneMinus());e.addAssign(u),t.addAssign(c.mul(l))}direct({lightDirection:e,lightColor:t,reflectedLight:r}){const s=jd.dot(e).clamp().mul(t).toVar();if(!0===this.sheen){this.sheenSpecularDirect.addAssign(s.mul(Wg({lightDirection:e})));const t=bm({normal:jd,viewDir:Id,roughness:Hn}),r=bm({normal:jd,viewDir:e,roughness:Hn}),i=Wn.r.max(Wn.g).max(Wn.b).mul(t.max(r)).oneMinus();s.mulAssign(i)}if(!0===this.clearcoat){const r=Kd.dot(e).clamp().mul(t);this.clearcoatSpecularDirect.addAssign(r.mul(Dg({lightDirection:e,f0:xm,f90:Tm,roughness:$n,normalView:Kd})))}r.directDiffuse.addAssign(s.mul(Tg({diffuseColor:On}))),r.directSpecular.addAssign(s.mul(Vg({lightDirection:e,f0:ea,f90:1,roughness:kn,f:this.iridescenceFresnel,USE_IRIDESCENCE:this.iridescence,USE_ANISOTROPY:this.anisotropy})))}directRectArea({lightColor:e,lightPosition:t,halfWidth:r,halfHeight:s,reflectedLight:i,ltc_1:n,ltc_2:a}){const o=t.add(r).sub(s),u=t.sub(r).sub(s),l=t.sub(r).add(s),d=t.add(r).add(s),c=jd,h=Id,p=Ud.toVar(),g=Hg({N:c,V:h,roughness:kn}),m=n.sample(g).toVar(),f=a.sample(g).toVar(),y=Mn(_n(m.x,0,m.y),_n(0,1,0),_n(m.z,0,m.w)).toVar(),b=ea.mul(f.x).add(ta.sub(ea).mul(f.y)).toVar();if(i.directSpecular.addAssign(e.mul(b).mul(Xg({N:c,V:h,P:p,mInv:y,p0:o,p1:u,p2:l,p3:d}))),i.directDiffuse.addAssign(e.mul(On).mul(Xg({N:c,V:h,P:p,mInv:Mn(1,0,0,0,1,0,0,0,1),p0:o,p1:u,p2:l,p3:d}))),!0===this.clearcoat){const t=Kd,r=Hg({N:t,V:h,roughness:$n}),s=n.sample(r),i=a.sample(r),c=Mn(_n(s.x,0,s.y),_n(0,1,0),_n(s.z,0,s.w)),g=xm.mul(i.x).add(Tm.sub(xm).mul(i.y));this.clearcoatSpecularDirect.addAssign(e.mul(g).mul(Xg({N:t,V:h,P:p,mInv:c,p0:o,p1:u,p2:l,p3:d})))}}indirect(e){this.indirectDiffuse(e),this.indirectSpecular(e),this.ambientOcclusion(e)}indirectDiffuse(e){const{irradiance:t,reflectedLight:r}=e.context,s=t.mul(Tg({diffuseColor:On})).toVar();if(!0===this.sheen){const e=bm({normal:jd,viewDir:Id,roughness:Hn}),t=Wn.r.max(Wn.g).max(Wn.b).mul(e).oneMinus();s.mulAssign(t)}r.indirectDiffuse.addAssign(s)}indirectSpecular(e){const{radiance:t,iblIrradiance:r,reflectedLight:s}=e.context;if(!0===this.sheen&&this.sheenSpecularIndirect.addAssign(r.mul(Wn,bm({normal:jd,viewDir:Id,roughness:Hn}))),!0===this.clearcoat){const e=Kd.dot(Id).clamp(),t=kg({dotNV:e,specularColor:xm,specularF90:Tm,roughness:$n});this.clearcoatSpecularIndirect.addAssign(this.clearcoatRadiance.mul(t))}const i=_n().toVar("singleScatteringDielectric"),n=_n().toVar("multiScatteringDielectric"),a=_n().toVar("singleScatteringMetallic"),o=_n().toVar("multiScatteringMetallic");this.computeMultiscattering(i,n,ta,Jn,this.iridescenceF0Dielectric),this.computeMultiscattering(a,o,ta,In.rgb,this.iridescenceF0Metallic);const u=iu(i,a,Gn),l=iu(n,o,Gn),d=i.add(n),c=On.mul(d.oneMinus()),h=r.mul(1/Math.PI),p=t.mul(u).add(l.mul(h)).toVar(),g=c.mul(h).toVar();if(!0===this.sheen){const e=bm({normal:jd,viewDir:Id,roughness:Hn}),t=Wn.r.max(Wn.g).max(Wn.b).mul(e).oneMinus();p.mulAssign(t),g.mulAssign(t)}s.indirectSpecular.addAssign(p),s.indirectDiffuse.addAssign(g)}ambientOcclusion(e){const{ambientOcclusion:t,reflectedLight:r}=e.context,s=jd.dot(Id).clamp().add(t),i=kn.mul(-16).oneMinus().negate().exp2(),n=t.sub(s.pow(i).oneMinus()).clamp();!0===this.clearcoat&&this.clearcoatSpecularIndirect.mulAssign(t),!0===this.sheen&&this.sheenSpecularIndirect.mulAssign(t),r.indirectDiffuse.mulAssign(t),r.indirectSpecular.mulAssign(n)}finish({context:e}){const{outgoingLight:t}=e;if(!0===this.clearcoat){const e=Kd.dot(Id).clamp(),r=xg({dotVH:e,f0:xm,f90:Tm}),s=t.mul(zn.mul(r).oneMinus()).add(this.clearcoatSpecularDirect.add(this.clearcoatSpecularIndirect).mul(zn));t.assign(s)}if(!0===this.sheen){const e=t.add(this.sheenSpecularDirect,this.sheenSpecularIndirect.mul(1/Math.PI));t.assign(e)}}}const vm=pn(1),Nm=pn(-2),Sm=pn(.8),Rm=pn(-1),Am=pn(.4),Em=pn(2),wm=pn(.305),Cm=pn(3),Mm=pn(.21),Bm=pn(4),Fm=pn(4),Lm=pn(16),Pm=on(([e])=>{const t=_n(Co(e)).toVar(),r=pn(-1).toVar();return dn(t.x.greaterThan(t.z),()=>{dn(t.x.greaterThan(t.y),()=>{r.assign(yu(e.x.greaterThan(0),0,3))}).Else(()=>{r.assign(yu(e.y.greaterThan(0),1,4))})}).Else(()=>{dn(t.z.greaterThan(t.y),()=>{r.assign(yu(e.z.greaterThan(0),2,5))}).Else(()=>{r.assign(yu(e.y.greaterThan(0),1,4))})}),r}).setLayout({name:"getFace",type:"float",inputs:[{name:"direction",type:"vec3"}]}),Dm=on(([e,t])=>{const r=yn().toVar();return dn(t.equal(0),()=>{r.assign(yn(e.z,e.y).div(Co(e.x)))}).ElseIf(t.equal(1),()=>{r.assign(yn(e.x.negate(),e.z.negate()).div(Co(e.y)))}).ElseIf(t.equal(2),()=>{r.assign(yn(e.x.negate(),e.y).div(Co(e.z)))}).ElseIf(t.equal(3),()=>{r.assign(yn(e.z.negate(),e.y).div(Co(e.x)))}).ElseIf(t.equal(4),()=>{r.assign(yn(e.x.negate(),e.z).div(Co(e.y)))}).Else(()=>{r.assign(yn(e.x,e.y).div(Co(e.z)))}),Ba(.5,r.add(1))}).setLayout({name:"getUV",type:"vec2",inputs:[{name:"direction",type:"vec3"},{name:"face",type:"float"}]}),Um=on(([e])=>{const t=pn(0).toVar();return dn(e.greaterThanEqual(Sm),()=>{t.assign(vm.sub(e).mul(Rm.sub(Nm)).div(vm.sub(Sm)).add(Nm))}).ElseIf(e.greaterThanEqual(Am),()=>{t.assign(Sm.sub(e).mul(Em.sub(Rm)).div(Sm.sub(Am)).add(Rm))}).ElseIf(e.greaterThanEqual(wm),()=>{t.assign(Am.sub(e).mul(Cm.sub(Em)).div(Am.sub(wm)).add(Em))}).ElseIf(e.greaterThanEqual(Mm),()=>{t.assign(wm.sub(e).mul(Bm.sub(Cm)).div(wm.sub(Mm)).add(Cm))}).Else(()=>{t.assign(pn(-2).mul(fo(Ba(1.16,e))))}),t}).setLayout({name:"roughnessToMip",type:"float",inputs:[{name:"roughness",type:"float"}]}),Im=on(([e,t])=>{const r=e.toVar();r.assign(Ba(2,r).sub(1));const s=_n(r,1).toVar();return dn(t.equal(0),()=>{s.assign(s.zyx)}).ElseIf(t.equal(1),()=>{s.assign(s.xzy),s.xz.mulAssign(-1)}).ElseIf(t.equal(2),()=>{s.x.mulAssign(-1)}).ElseIf(t.equal(3),()=>{s.assign(s.zyx),s.xz.mulAssign(-1)}).ElseIf(t.equal(4),()=>{s.assign(s.xzy),s.xy.mulAssign(-1)}).ElseIf(t.equal(5),()=>{s.z.mulAssign(-1)}),s}).setLayout({name:"getDirection",type:"vec3",inputs:[{name:"uv",type:"vec2"},{name:"face",type:"float"}]}),Om=on(([e,t,r,s,i,n])=>{const a=pn(r),o=_n(t),u=nu(Um(a),Nm,n),l=vo(u),d=xo(u),c=_n(Vm(e,o,d,s,i,n)).toVar();return dn(l.notEqual(0),()=>{const t=_n(Vm(e,o,d.add(1),s,i,n)).toVar();c.assign(iu(c,t,l))}),c}),Vm=on(([e,t,r,s,i,n])=>{const a=pn(r).toVar(),o=_n(t),u=pn(Pm(o)).toVar(),l=pn(Wo(Fm.sub(a),0)).toVar();a.assign(Wo(a,Fm));const d=pn(go(a)).toVar(),c=yn(Dm(o,u).mul(d.sub(2)).add(1)).toVar();return dn(u.greaterThan(2),()=>{c.y.addAssign(d),u.subAssign(3)}),c.x.addAssign(u.mul(d)),c.x.addAssign(l.mul(Ba(3,Lm))),c.y.addAssign(Ba(4,go(n).sub(d))),c.x.mulAssign(s),c.y.mulAssign(i),e.sample(c).grad(yn(),yn())}),km=on(({envMap:e,mipInt:t,outputDirection:r,theta:s,axis:i,CUBEUV_TEXEL_WIDTH:n,CUBEUV_TEXEL_HEIGHT:a,CUBEUV_MAX_MIP:o})=>{const u=So(s),l=r.mul(u).add(i.cross(r).mul(No(s))).add(i.mul(i.dot(r).mul(u.oneMinus())));return Vm(e,l,t,n,a,o)}),Gm=on(({n:e,latitudinal:t,poleAxis:r,outputDirection:s,weights:i,samples:n,dTheta:a,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c})=>{const h=_n(yu(t,r,Yo(r,s))).toVar();dn(h.equal(_n(0)),()=>{h.assign(_n(s.z,0,s.x.negate()))}),h.assign(_o(h));const p=_n().toVar();return p.addAssign(i.element(0).mul(km({theta:0,axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c}))),up({start:gn(1),end:e},({i:e})=>{dn(e.greaterThanEqual(n),()=>{lp()});const t=pn(a.mul(pn(e))).toVar();p.addAssign(i.element(e).mul(km({theta:t.mul(-1),axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c}))),p.addAssign(i.element(e).mul(km({theta:t,axis:h,outputDirection:s,mipInt:o,envMap:u,CUBEUV_TEXEL_WIDTH:l,CUBEUV_TEXEL_HEIGHT:d,CUBEUV_MAX_MIP:c})))}),Rn(p,1)}),zm=on(([e])=>{const t=mn(e).toVar();return t.assign(t.shiftLeft(mn(16)).bitOr(t.shiftRight(mn(16)))),t.assign(t.bitAnd(mn(1431655765)).shiftLeft(mn(1)).bitOr(t.bitAnd(mn(2863311530)).shiftRight(mn(1)))),t.assign(t.bitAnd(mn(858993459)).shiftLeft(mn(2)).bitOr(t.bitAnd(mn(3435973836)).shiftRight(mn(2)))),t.assign(t.bitAnd(mn(252645135)).shiftLeft(mn(4)).bitOr(t.bitAnd(mn(4042322160)).shiftRight(mn(4)))),t.assign(t.bitAnd(mn(16711935)).shiftLeft(mn(8)).bitOr(t.bitAnd(mn(4278255360)).shiftRight(mn(8)))),pn(t).mul(2.3283064365386963e-10)}),$m=on(([e,t])=>yn(pn(e).div(pn(t)),zm(e))),Wm=on(([e,t,r])=>{const s=r.mul(r).toConst(),i=_n(1,0,0).toConst(),n=Yo(t,i).toConst(),a=yo(e.x).toConst(),o=Ba(2,3.14159265359).mul(e.y).toConst(),u=a.mul(So(o)).toConst(),l=a.mul(No(o)).toVar(),d=Ba(.5,t.z.add(1)).toConst();l.assign(d.oneMinus().mul(yo(u.mul(u).oneMinus())).add(d.mul(l)));const c=i.mul(u).add(n.mul(l)).add(t.mul(yo(Wo(0,u.mul(u).add(l.mul(l)).oneMinus()))));return _o(_n(s.mul(c.x),s.mul(c.y),Wo(0,c.z)))}),Hm=on(({roughness:e,mipInt:t,envMap:r,N_immutable:s,GGX_SAMPLES:i,CUBEUV_TEXEL_WIDTH:n,CUBEUV_TEXEL_HEIGHT:a,CUBEUV_MAX_MIP:o})=>{const u=_n(s).toVar(),l=_n(0).toVar(),d=pn(0).toVar();return dn(e.lessThan(.001),()=>{l.assign(Vm(r,u,t,n,a,o))}).Else(()=>{const s=yu(Co(u.z).lessThan(.999),_n(0,0,1),_n(1,0,0)),c=_o(Yo(s,u)).toVar(),h=Yo(u,c).toVar();up({start:mn(0),end:i},({i:s})=>{const p=$m(s,i),g=Wm(p,_n(0,0,1),e),m=_o(c.mul(g.x).add(h.mul(g.y)).add(u.mul(g.z))),f=_o(m.mul(Ko(u,m).mul(2)).sub(u)),y=Wo(Ko(u,f),0);dn(y.greaterThan(0),()=>{const e=Vm(r,f,t,n,a,o);l.addAssign(e.mul(y)),d.addAssign(y)})}),dn(d.greaterThan(0),()=>{l.assign(l.div(d))})}),Rn(l,1)}),qm=[.125,.215,.35,.446,.526,.582],jm=20,Xm=new _e(-1,1,1,-1,0,1),Km=new ve(90,1),Ym=new e;let Qm=null,Zm=0,Jm=0;const ef=new r,tf=new WeakMap,rf=[3,1,5,0,4,2],sf=Im(Sl(),Nl("faceIndex")).normalize(),nf=_n(sf.x,sf.y,sf.z);class af{constructor(e){this._renderer=e,this._pingPongRenderTarget=null,this._lodMax=0,this._cubeSize=0,this._sizeLods=[],this._sigmas=[],this._lodMeshes=[],this._blurMaterial=null,this._ggxMaterial=null,this._cubemapMaterial=null,this._equirectMaterial=null,this._backgroundBox=null}get _hasInitialized(){return this._renderer.hasInitialized()}fromScene(e,t=0,r=.1,s=100,i={}){const{size:n=256,position:a=ef,renderTarget:o=null}=i;if(this._setSize(n),!1===this._hasInitialized){d('PMREMGenerator: ".fromScene()" called before the backend is initialized. Try using "await renderer.init()" instead.');const n=o||this._allocateTarget();return i.renderTarget=n,this.fromSceneAsync(e,t,r,s,i),n}Qm=this._renderer.getRenderTarget(),Zm=this._renderer.getActiveCubeFace(),Jm=this._renderer.getActiveMipmapLevel();const u=o||this._allocateTarget();return u.depthBuffer=!0,this._init(u),this._sceneToCubeUV(e,r,s,u,a),t>0&&this._blur(u,0,0,t),this._applyPMREM(u),this._cleanup(u),u}async fromSceneAsync(e,t=0,r=.1,s=100,i={}){return v('PMREMGenerator: ".fromSceneAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this.fromScene(e,t,r,s,i)}fromEquirectangular(e,t=null){if(!1===this._hasInitialized){d('PMREMGenerator: .fromEquirectangular() called before the backend is initialized. Try using "await renderer.init()" instead.'),this._setSizeFromTexture(e);const r=t||this._allocateTarget();return this.fromEquirectangularAsync(e,r),r}return this._fromTexture(e,t)}async fromEquirectangularAsync(e,t=null){return v('PMREMGenerator: ".fromEquirectangularAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this._fromTexture(e,t)}fromCubemap(e,t=null){if(!1===this._hasInitialized){d("PMREMGenerator: .fromCubemap() called before the backend is initialized. Try using .fromCubemapAsync() instead."),this._setSizeFromTexture(e);const r=t||this._allocateTarget();return this.fromCubemapAsync(e,t),r}return this._fromTexture(e,t)}async fromCubemapAsync(e,t=null){return v('PMREMGenerator: ".fromCubemapAsync()" is deprecated. Use "await renderer.init()" instead.'),await this._renderer.init(),this._fromTexture(e,t)}async compileCubemapShader(){null===this._cubemapMaterial&&(this._cubemapMaterial=df(),await this._compileMaterial(this._cubemapMaterial))}async compileEquirectangularShader(){null===this._equirectMaterial&&(this._equirectMaterial=cf(),await this._compileMaterial(this._equirectMaterial))}dispose(){this._dispose(),null!==this._cubemapMaterial&&this._cubemapMaterial.dispose(),null!==this._equirectMaterial&&this._equirectMaterial.dispose(),null!==this._backgroundBox&&(this._backgroundBox.geometry.dispose(),this._backgroundBox.material.dispose())}_setSizeFromTexture(e){e.mapping===P||e.mapping===D?this._setSize(0===e.image.length?16:e.image[0].width||e.image[0].image.width):this._setSize(e.image.width/4)}_setSize(e){this._lodMax=Math.floor(Math.log2(e)),this._cubeSize=Math.pow(2,this._lodMax)}_dispose(){null!==this._blurMaterial&&this._blurMaterial.dispose(),null!==this._ggxMaterial&&this._ggxMaterial.dispose(),null!==this._pingPongRenderTarget&&this._pingPongRenderTarget.dispose();for(let e=0;ee-4?o=qm[a-e+4-1]:0===a&&(o=0),r.push(o);const u=1/(n-2),l=-u,d=1+u,c=[l,l,d,l,d,d,l,l,d,d,l,d],h=6,p=6,g=3,m=2,f=1,y=new Float32Array(g*p*h),b=new Float32Array(m*p*h),x=new Float32Array(f*p*h);for(let e=0;e2?0:-1,s=[t,r,0,t+2/3,r,0,t+2/3,r+1,0,t,r,0,t+2/3,r+1,0,t,r+1,0],i=rf[e];y.set(s,g*p*i),b.set(c,m*p*i);const n=[i,i,i,i,i,i];x.set(n,f*p*i)}const T=new Te;T.setAttribute("position",new Ae(y,g)),T.setAttribute("uv",new Ae(b,m)),T.setAttribute("faceIndex",new Ae(x,f)),s.push(new ne(T,null)),i>4&&i--}return{lodMeshes:s,sizeLods:t,sigmas:r}}(t)),this._blurMaterial=function(e,t,s){const i=Ol(new Array(jm).fill(0)),n=Ta(new r(0,1,0)),a=Ta(0),o=pn(jm),u=Ta(0),l=Ta(1),d=Fl(),c=Ta(0),h=pn(1/t),p=pn(1/s),g=pn(e),m={n:o,latitudinal:u,weights:i,poleAxis:n,outputDirection:nf,dTheta:a,samples:l,envMap:d,mipInt:c,CUBEUV_TEXEL_WIDTH:h,CUBEUV_TEXEL_HEIGHT:p,CUBEUV_MAX_MIP:g},f=lf("blur");return f.fragmentNode=Gm({...m,latitudinal:u.equal(1)}),tf.set(f,m),f}(t,e.width,e.height),this._ggxMaterial=function(e,t,r){const s=Fl(),i=Ta(0),n=Ta(0),a=pn(1/t),o=pn(1/r),u=pn(e),l={envMap:s,roughness:i,mipInt:n,CUBEUV_TEXEL_WIDTH:a,CUBEUV_TEXEL_HEIGHT:o,CUBEUV_MAX_MIP:u},d=lf("ggx");return d.fragmentNode=Hm({...l,N_immutable:nf,GGX_SAMPLES:mn(512)}),tf.set(d,l),d}(t,e.width,e.height)}}async _compileMaterial(e){const t=new ne(new Te,e);await this._renderer.compile(t,Xm)}_sceneToCubeUV(e,t,r,s,i){const n=Km;n.near=t,n.far=r;const a=[1,1,1,1,-1,1],o=[1,-1,1,-1,1,-1],u=this._renderer,l=u.autoClear;u.getClearColor(Ym),u.autoClear=!1,null===this._backgroundBox&&(this._backgroundBox=new ne(new ie,new ge({name:"PMREM.Background",side:M,depthWrite:!1,depthTest:!1})));const d=this._backgroundBox,c=d.material;let h=!1;const p=e.background;p?p.isColor&&(c.color.copy(p),e.background=null,h=!0):(c.color.copy(Ym),h=!0),u.setRenderTarget(s),u.clear(),h&&u.render(d,n);for(let t=0;t<6;t++){const r=t%3;0===r?(n.up.set(0,a[t],0),n.position.set(i.x,i.y,i.z),n.lookAt(i.x+o[t],i.y,i.z)):1===r?(n.up.set(0,0,a[t]),n.position.set(i.x,i.y,i.z),n.lookAt(i.x,i.y+o[t],i.z)):(n.up.set(0,a[t],0),n.position.set(i.x,i.y,i.z),n.lookAt(i.x,i.y,i.z+o[t]));const l=this._cubeSize;uf(s,r*l,t>2?l:0,l,l),u.render(e,n)}u.autoClear=l,e.background=p}_textureToCubeUV(e,t){const r=this._renderer,s=e.mapping===P||e.mapping===D;s?null===this._cubemapMaterial&&(this._cubemapMaterial=df(e)):null===this._equirectMaterial&&(this._equirectMaterial=cf(e));const i=s?this._cubemapMaterial:this._equirectMaterial;i.fragmentNode.value=e;const n=this._lodMeshes[0];n.material=i;const a=this._cubeSize;uf(t,0,0,3*a,2*a),r.setRenderTarget(t),r.render(n,Xm)}_applyPMREM(e){const t=this._renderer,r=t.autoClear;t.autoClear=!1;const s=this._lodMeshes.length;for(let t=1;tc-4?r-c+4:0),g=4*(this._cubeSize-h);e.texture.frame=(e.texture.frame||0)+1,o.envMap.value=e.texture,o.roughness.value=d,o.mipInt.value=c-t,uf(i,p,g,3*h,2*h),s.setRenderTarget(i),s.render(a,Xm),i.texture.frame=(i.texture.frame||0)+1,o.envMap.value=i.texture,o.roughness.value=0,o.mipInt.value=c-r,uf(e,p,g,3*h,2*h),s.setRenderTarget(e),s.render(a,Xm)}_blur(e,t,r,s,i){const n=this._pingPongRenderTarget;this._halfBlur(e,n,t,r,s,"latitudinal",i),this._halfBlur(n,e,r,r,s,"longitudinal",i)}_halfBlur(e,t,r,s,i,n,a){const u=this._renderer,l=this._blurMaterial;"latitudinal"!==n&&"longitudinal"!==n&&o("blur direction must be either latitudinal or longitudinal!");const c=this._lodMeshes[s];c.material=l;const h=tf.get(l),p=this._sizeLods[r]-1,g=isFinite(i)?Math.PI/(2*p):2*Math.PI/39,m=i/g,f=isFinite(i)?1+Math.floor(3*m):jm;f>jm&&d(`sigmaRadians, ${i}, is too large and will clip, as it requested ${f} samples when the maximum is set to 20`);const y=[];let b=0;for(let e=0;ex-4?s-x+4:0),4*(this._cubeSize-T),3*T,2*T),u.setRenderTarget(t),u.render(c,Xm)}}function of(e,t){const r=new se(e,t,{magFilter:oe,minFilter:oe,generateMipmaps:!1,type:be,format:Se,colorSpace:Ne});return r.texture.mapping=Re,r.texture.name="PMREM.cubeUv",r.texture.isPMREMTexture=!0,r.scissorTest=!0,r}function uf(e,t,r,s,i){e.viewport.set(t,r,s,i),e.scissor.set(t,r,s,i)}function lf(e){const t=new Qp;return t.depthTest=!1,t.depthWrite=!1,t.blending=ee,t.name=`PMREM_${e}`,t}function df(e){const t=lf("cubemap");return t.fragmentNode=pc(e,nf),t}function cf(e){const t=lf("equirect");return t.fragmentNode=Fl(e,ag(nf),0),t}const hf=new WeakMap;function pf(e,t,r){const s=function(e){let t=hf.get(e);void 0===t&&(t=new WeakMap,hf.set(e,t));return t}(t);let i=s.get(e);if((void 0!==i?i.pmremVersion:-1)!==e.pmremVersion){const t=e.image;if(e.isCubeTexture){if(!function(e){if(null==e)return!1;let t=0;const r=6;for(let s=0;s0}(t))return null;i=r.fromEquirectangular(e,i)}i.pmremVersion=e.pmremVersion,s.set(e,i)}return i.texture}class gf extends di{static get type(){return"PMREMNode"}constructor(e,t=null,r=null){super("vec3"),this._value=e,this._pmrem=null,this.uvNode=t,this.levelNode=r,this._generator=null;const s=new N;s.isRenderTargetTexture=!0,this._texture=Fl(s),this._width=Ta(0),this._height=Ta(0),this._maxMip=Ta(0),this.updateBeforeType=Zs.RENDER}set value(e){this._value=e,this._pmrem=null}get value(){return this._value}updateFromTexture(e){const t=function(e){const t=Math.log2(e)-2,r=1/e;return{texelWidth:1/(3*Math.max(Math.pow(2,t),112)),texelHeight:r,maxMip:t}}(e.image.height);this._texture.value=e,this._width.value=t.texelWidth,this._height.value=t.texelHeight,this._maxMip.value=t.maxMip}updateBefore(e){let t=this._pmrem;const r=t?t.pmremVersion:-1,s=this._value;r!==s.pmremVersion&&(t=!0===s.isPMREMTexture?s:pf(s,e.renderer,this._generator),null!==t&&(this._pmrem=t,this.updateFromTexture(t)))}setup(e){null===this._generator&&(this._generator=new af(e.renderer)),this.updateBefore(e);let t=this.uvNode;null===t&&e.context.getUV&&(t=e.context.getUV(this,e)),t=nc.mul(_n(t.x,t.y.negate(),t.z));let r=this.levelNode;return null===r&&e.context.getTextureLevel&&(r=e.context.getTextureLevel(this)),Om(this._texture,t,r,this._width,this._height,this._maxMip)}dispose(){super.dispose(),null!==this._generator&&this._generator.dispose()}}const mf=tn(gf).setParameterLength(1,3),ff=new WeakMap;class yf extends mp{static get type(){return"EnvironmentNode"}constructor(e=null){super(),this.envNode=e}setup(e){const{material:t}=e;let r=this.envNode;if(r.isTextureNode||r.isMaterialReferenceNode){const e=r.isTextureNode?r.value:t[r.property];let s=ff.get(e);void 0===s&&(s=mf(e),ff.set(e,s)),r=s}const s=!0===t.useAnisotropy||t.anisotropy>0?Hc:jd,i=r.context(bf(kn,s)).mul(ic),n=r.context(xf(Xd)).mul(Math.PI).mul(ic),a=nl(i),o=nl(n);e.context.radiance.addAssign(a),e.context.iblIrradiance.addAssign(o);const u=e.context.lightingModel.clearcoatRadiance;if(u){const e=r.context(bf($n,Kd)).mul(ic),t=nl(e);u.addAssign(t)}}}const bf=(e,t)=>{let r=null;return{getUV:()=>(null===r&&(r=Id.negate().reflect(t),r=eu(e).mix(r,t).normalize(),r=r.transformDirection(id)),r),getTextureLevel:()=>e}},xf=e=>({getUV:()=>e,getTextureLevel:()=>pn(1)}),Tf=new Ee;class _f extends Qp{static get type(){return"MeshStandardNodeMaterial"}constructor(e){super(),this.isMeshStandardNodeMaterial=!0,this.lights=!0,this.emissiveNode=null,this.metalnessNode=null,this.roughnessNode=null,this.setDefaultValues(Tf),this.setValues(e)}setupEnvironment(e){let t=super.setupEnvironment(e);return null===t&&e.environmentNode&&(t=e.environmentNode),t?new yf(t):null}setupLightingModel(){return new _m}setupSpecular(){const e=iu(_n(.04),In.rgb,Gn);Jn.assign(_n(.04)),ea.assign(e),ta.assign(1)}setupVariants(){const e=this.metalnessNode?pn(this.metalnessNode):ph;Gn.assign(e);let t=this.roughnessNode?pn(this.roughnessNode):hh;t=Cg({roughness:t}),kn.assign(t),this.setupSpecular(),On.assign(In.rgb.mul(e.oneMinus()))}copy(e){return this.emissiveNode=e.emissiveNode,this.metalnessNode=e.metalnessNode,this.roughnessNode=e.roughnessNode,super.copy(e)}}const vf=new we;class Nf extends _f{static get type(){return"MeshPhysicalNodeMaterial"}constructor(e){super(),this.isMeshPhysicalNodeMaterial=!0,this.clearcoatNode=null,this.clearcoatRoughnessNode=null,this.clearcoatNormalNode=null,this.sheenNode=null,this.sheenRoughnessNode=null,this.iridescenceNode=null,this.iridescenceIORNode=null,this.iridescenceThicknessNode=null,this.specularIntensityNode=null,this.specularColorNode=null,this.iorNode=null,this.transmissionNode=null,this.thicknessNode=null,this.attenuationDistanceNode=null,this.attenuationColorNode=null,this.dispersionNode=null,this.anisotropyNode=null,this.setDefaultValues(vf),this.setValues(e)}get useClearcoat(){return this.clearcoat>0||null!==this.clearcoatNode}get useIridescence(){return this.iridescence>0||null!==this.iridescenceNode}get useSheen(){return this.sheen>0||null!==this.sheenNode}get useAnisotropy(){return this.anisotropy>0||null!==this.anisotropyNode}get useTransmission(){return this.transmission>0||null!==this.transmissionNode}get useDispersion(){return this.dispersion>0||null!==this.dispersionNode}setupSpecular(){const e=this.iorNode?pn(this.iorNode):Eh;oa.assign(e),Jn.assign($o(Zo(oa.sub(1).div(oa.add(1))).mul(lh),_n(1)).mul(uh)),ea.assign(iu(Jn,In.rgb,Gn)),ta.assign(iu(uh,1,Gn))}setupLightingModel(){return new _m(this.useClearcoat,this.useSheen,this.useIridescence,this.useAnisotropy,this.useTransmission,this.useDispersion)}setupVariants(e){if(super.setupVariants(e),this.useClearcoat){const e=this.clearcoatNode?pn(this.clearcoatNode):mh,t=this.clearcoatRoughnessNode?pn(this.clearcoatRoughnessNode):fh;zn.assign(e),$n.assign(Cg({roughness:t}))}if(this.useSheen){const e=this.sheenNode?_n(this.sheenNode):xh,t=this.sheenRoughnessNode?pn(this.sheenRoughnessNode):Th;Wn.assign(e),Hn.assign(t)}if(this.useIridescence){const e=this.iridescenceNode?pn(this.iridescenceNode):vh,t=this.iridescenceIORNode?pn(this.iridescenceIORNode):Nh,r=this.iridescenceThicknessNode?pn(this.iridescenceThicknessNode):Sh;qn.assign(e),jn.assign(t),Xn.assign(r)}if(this.useAnisotropy){const e=(this.anisotropyNode?yn(this.anisotropyNode):_h).toVar();Yn.assign(e.length()),dn(Yn.equal(0),()=>{e.assign(yn(1,0))}).Else(()=>{e.divAssign(yn(Yn)),Yn.assign(Yn.saturate())}),Kn.assign(Yn.pow2().mix(kn.pow2(),1)),Qn.assign($c[0].mul(e.x).add($c[1].mul(e.y))),Zn.assign($c[1].mul(e.x).sub($c[0].mul(e.y)))}if(this.useTransmission){const e=this.transmissionNode?pn(this.transmissionNode):Rh,t=this.thicknessNode?pn(this.thicknessNode):Ah,r=this.attenuationDistanceNode?pn(this.attenuationDistanceNode):wh,s=this.attenuationColorNode?_n(this.attenuationColorNode):Ch;if(ua.assign(e),la.assign(t),da.assign(r),ca.assign(s),this.useDispersion){const e=this.dispersionNode?pn(this.dispersionNode):Uh;ha.assign(e)}}}setupClearcoatNormal(){return this.clearcoatNormalNode?_n(this.clearcoatNormalNode):yh}setup(e){e.context.setupClearcoatNormal=()=>Bu(this.setupClearcoatNormal(e),"NORMAL","vec3"),super.setup(e)}copy(e){return this.clearcoatNode=e.clearcoatNode,this.clearcoatRoughnessNode=e.clearcoatRoughnessNode,this.clearcoatNormalNode=e.clearcoatNormalNode,this.sheenNode=e.sheenNode,this.sheenRoughnessNode=e.sheenRoughnessNode,this.iridescenceNode=e.iridescenceNode,this.iridescenceIORNode=e.iridescenceIORNode,this.iridescenceThicknessNode=e.iridescenceThicknessNode,this.specularIntensityNode=e.specularIntensityNode,this.specularColorNode=e.specularColorNode,this.iorNode=e.iorNode,this.transmissionNode=e.transmissionNode,this.thicknessNode=e.thicknessNode,this.attenuationDistanceNode=e.attenuationDistanceNode,this.attenuationColorNode=e.attenuationColorNode,this.dispersionNode=e.dispersionNode,this.anisotropyNode=e.anisotropyNode,super.copy(e)}}class Sf extends _m{constructor(e=!1,t=!1,r=!1,s=!1,i=!1,n=!1,a=!1){super(e,t,r,s,i,n),this.useSSS=a}direct({lightDirection:e,lightColor:t,reflectedLight:r},s){if(!0===this.useSSS){const i=s.material,{thicknessColorNode:n,thicknessDistortionNode:a,thicknessAmbientNode:o,thicknessAttenuationNode:u,thicknessPowerNode:l,thicknessScaleNode:d}=i,c=e.add(jd.mul(a)).normalize(),h=pn(Id.dot(c.negate()).saturate().pow(l).mul(d)),p=_n(h.add(o).mul(n));r.directDiffuse.addAssign(p.mul(u.mul(t)))}super.direct({lightDirection:e,lightColor:t,reflectedLight:r},s)}}class Rf extends Nf{static get type(){return"MeshSSSNodeMaterial"}constructor(e){super(e),this.thicknessColorNode=null,this.thicknessDistortionNode=pn(.1),this.thicknessAmbientNode=pn(0),this.thicknessAttenuationNode=pn(.1),this.thicknessPowerNode=pn(2),this.thicknessScaleNode=pn(10)}get useSSS(){return null!==this.thicknessColorNode}setupLightingModel(){return new Sf(this.useClearcoat,this.useSheen,this.useIridescence,this.useAnisotropy,this.useTransmission,this.useDispersion,this.useSSS)}copy(e){return this.thicknessColorNode=e.thicknessColorNode,this.thicknessDistortionNode=e.thicknessDistortionNode,this.thicknessAmbientNode=e.thicknessAmbientNode,this.thicknessAttenuationNode=e.thicknessAttenuationNode,this.thicknessPowerNode=e.thicknessPowerNode,this.thicknessScaleNode=e.thicknessScaleNode,super.copy(e)}}const Af=on(({normal:e,lightDirection:t,builder:r})=>{const s=e.dot(t),i=yn(s.mul(.5).add(.5),0);if(r.material.gradientMap){const e=xc("gradientMap","texture").context({getUV:()=>i});return _n(e.r)}{const e=i.fwidth().mul(.5);return iu(_n(.7),_n(1),uu(pn(.7).sub(e.x),pn(.7).add(e.x),i.x))}});class Ef extends mg{direct({lightDirection:e,lightColor:t,reflectedLight:r},s){const i=Af({normal:zd,lightDirection:e,builder:s}).mul(t);r.directDiffuse.addAssign(i.mul(Tg({diffuseColor:In.rgb})))}indirect(e){const{ambientOcclusion:t,irradiance:r,reflectedLight:s}=e.context;s.indirectDiffuse.addAssign(r.mul(Tg({diffuseColor:In}))),s.indirectDiffuse.mulAssign(t)}}const wf=new Ce;class Cf extends Qp{static get type(){return"MeshToonNodeMaterial"}constructor(e){super(),this.isMeshToonNodeMaterial=!0,this.lights=!0,this.setDefaultValues(wf),this.setValues(e)}setupLightingModel(){return new Ef}}const Mf=on(()=>{const e=_n(Id.z,0,Id.x.negate()).normalize(),t=Id.cross(e);return yn(e.dot(jd),t.dot(jd)).mul(.495).add(.5)}).once(["NORMAL","VERTEX"])().toVar("matcapUV"),Bf=new Me;class Ff extends Qp{static get type(){return"MeshMatcapNodeMaterial"}constructor(e){super(),this.isMeshMatcapNodeMaterial=!0,this.setDefaultValues(Bf),this.setValues(e)}setupVariants(e){const t=Mf;let r;r=e.material.matcap?xc("matcap","texture").context({getUV:()=>t}):_n(iu(.2,.8,t.y)),In.rgb.mulAssign(r.rgb)}}class Lf extends di{static get type(){return"RotateNode"}constructor(e,t){super(),this.positionNode=e,this.rotationNode=t}getNodeType(e){return this.positionNode.getNodeType(e)}setup(e){const{rotationNode:t,positionNode:r}=this;if("vec2"===this.getNodeType(e)){const e=t.cos(),s=t.sin();return Cn(e,s,s.negate(),e).mul(r)}{const e=t,s=Bn(Rn(1,0,0,0),Rn(0,So(e.x),No(e.x).negate(),0),Rn(0,No(e.x),So(e.x),0),Rn(0,0,0,1)),i=Bn(Rn(So(e.y),0,No(e.y),0),Rn(0,1,0,0),Rn(No(e.y).negate(),0,So(e.y),0),Rn(0,0,0,1)),n=Bn(Rn(So(e.z),No(e.z).negate(),0,0),Rn(No(e.z),So(e.z),0,0),Rn(0,0,1,0),Rn(0,0,0,1));return s.mul(i).mul(n).mul(Rn(r,1)).xyz}}}const Pf=tn(Lf).setParameterLength(2),Df=new Be;class Uf extends Qp{static get type(){return"SpriteNodeMaterial"}constructor(e){super(),this.isSpriteNodeMaterial=!0,this._useSizeAttenuation=!0,this.positionNode=null,this.rotationNode=null,this.scaleNode=null,this.transparent=!0,this.setDefaultValues(Df),this.setValues(e)}setupPositionView(e){const{object:t,camera:r}=e,{positionNode:s,rotationNode:i,scaleNode:n,sizeAttenuation:a}=this,o=Ad.mul(_n(s||0));let u=yn(xd[0].xyz.length(),xd[1].xyz.length());null!==n&&(u=u.mul(yn(n))),r.isPerspectiveCamera&&!1===a&&(u=u.mul(o.z.negate()));let l=Bd.xy;if(t.center&&!0===t.center.isVector2){const e=((e,t,r)=>new zu(e,t,r))("center","vec2",t);l=l.sub(e.sub(.5))}l=l.mul(u);const d=pn(i||bh),c=Pf(l,d);return Rn(o.xy.add(c),o.zw)}copy(e){return this.positionNode=e.positionNode,this.rotationNode=e.rotationNode,this.scaleNode=e.scaleNode,super.copy(e)}get sizeAttenuation(){return this._useSizeAttenuation}set sizeAttenuation(e){this._useSizeAttenuation!==e&&(this._useSizeAttenuation=e,this.needsUpdate=!0)}}const If=new Fe,Of=new t;class Vf extends Uf{static get type(){return"PointsNodeMaterial"}constructor(e){super(),this.sizeNode=null,this.isPointsNodeMaterial=!0,this.setDefaultValues(If),this.setValues(e)}setupPositionView(){const{positionNode:e}=this;return Ad.mul(_n(e||Fd)).xyz}setupVertexSprite(e){const{material:t,camera:r}=e,{rotationNode:s,scaleNode:i,sizeNode:n,sizeAttenuation:a}=this;let o=super.setupVertex(e);if(!0!==t.isNodeMaterial)return o;let u=null!==n?yn(n):Dh;u=u.mul(Wl),r.isPerspectiveCamera&&!0===a&&(u=u.mul(kf.div(Ud.z.negate()))),i&&i.isNode&&(u=u.mul(yn(i)));let l=Bd.xy;if(s&&s.isNode){const e=pn(s);l=Pf(l,e)}return l=l.mul(u),l=l.div(Kl.div(2)),l=l.mul(o.w),o=o.add(Rn(l,0,0)),o}setupVertex(e){return e.object.isPoints?super.setupVertex(e):this.setupVertexSprite(e)}get alphaToCoverage(){return this._useAlphaToCoverage}set alphaToCoverage(e){this._useAlphaToCoverage!==e&&(this._useAlphaToCoverage=e,this.needsUpdate=!0)}}const kf=Ta(1).onFrameUpdate(function({renderer:e}){const t=e.getSize(Of);this.value=.5*t.y});class Gf extends mg{constructor(){super(),this.shadowNode=pn(1).toVar("shadowMask")}direct({lightNode:e}){null!==e.shadowNode&&this.shadowNode.mulAssign(e.shadowNode)}finish({context:e}){In.a.mulAssign(this.shadowNode.oneMinus()),e.outgoingLight.rgb.assign(In.rgb)}}const zf=new Le;class $f extends Qp{static get type(){return"ShadowNodeMaterial"}constructor(e){super(),this.isShadowNodeMaterial=!0,this.lights=!0,this.transparent=!0,this.setDefaultValues(zf),this.setValues(e)}setupLightingModel(){return new Gf}}const Wf=Dn("vec3"),Hf=Dn("vec3"),qf=Dn("vec3");class jf extends mg{constructor(){super()}start(e){const{material:t}=e,r=Dn("vec3"),s=Dn("vec3");dn(od.sub(Pd).length().greaterThan(Nd.mul(2)),()=>{r.assign(od),s.assign(Pd)}).Else(()=>{r.assign(Pd),s.assign(od)});const i=s.sub(r),n=Ta("int").onRenderUpdate(({material:e})=>e.steps),a=i.length().div(n).toVar(),o=i.normalize().toVar(),u=pn(0).toVar(),l=_n(1).toVar();t.offsetNode&&u.addAssign(t.offsetNode.mul(a)),up(n,()=>{const s=r.add(o.mul(u)),i=id.mul(Rn(s,1)).xyz;let n;null!==t.depthNode&&(Hf.assign(Up(Bp(i.z,ed,td))),e.context.sceneDepthNode=Up(t.depthNode).toVar()),e.context.positionWorld=s,e.context.shadowPositionWorld=s,e.context.positionView=i,Wf.assign(0),t.scatteringNode&&(n=t.scatteringNode({positionRay:s})),super.start(e),n&&Wf.mulAssign(n);const d=Wf.mul(.01).negate().mul(a).exp();l.mulAssign(d),u.addAssign(a)}),qf.addAssign(l.saturate().oneMinus())}scatteringLight(e,t){const r=t.context.sceneDepthNode;r?dn(r.greaterThanEqual(Hf),()=>{Wf.addAssign(e)}):Wf.addAssign(e)}direct({lightNode:e,lightColor:t},r){if(void 0===e.light.distance)return;const s=t.xyz.toVar();s.mulAssign(e.shadowNode),this.scatteringLight(s,r)}directRectArea({lightColor:e,lightPosition:t,halfWidth:r,halfHeight:s},i){const n=t.add(r).sub(s),a=t.sub(r).sub(s),o=t.sub(r).add(s),u=t.add(r).add(s),l=i.context.positionView,d=e.xyz.mul(Kg({P:l,p0:n,p1:a,p2:o,p3:u})).pow(1.5);this.scatteringLight(d,i)}finish(e){e.context.outgoingLight.assign(qf)}}class Xf extends Qp{static get type(){return"VolumeNodeMaterial"}constructor(e){super(),this.isVolumeNodeMaterial=!0,this.steps=25,this.offsetNode=null,this.scatteringNode=null,this.lights=!0,this.transparent=!0,this.side=M,this.depthTest=!1,this.depthWrite=!1,this.setValues(e)}setupLightingModel(){return new jf}}class Kf{constructor(e,t,r){this.renderer=e,this.nodes=t,this.info=r,this._context="undefined"!=typeof self?self:null,this._animationLoop=null,this._requestId=null}start(){const e=(t,r)=>{this._requestId=this._context.requestAnimationFrame(e),!0===this.info.autoReset&&this.info.reset(),this.nodes.nodeFrame.update(),this.info.frame=this.nodes.nodeFrame.frameId,this.renderer._inspector.begin(),null!==this._animationLoop&&this._animationLoop(t,r),this.renderer._inspector.finish()};e()}stop(){this._context.cancelAnimationFrame(this._requestId),this._requestId=null}getAnimationLoop(){return this._animationLoop}setAnimationLoop(e){this._animationLoop=e}getContext(){return this._context}setContext(e){this._context=e}dispose(){this.stop()}}class Yf{constructor(){this.weakMaps={}}_getWeakMap(e){const t=e.length;let r=this.weakMaps[t];return void 0===r&&(r=new WeakMap,this.weakMaps[t]=r),r}get(e){let t=this._getWeakMap(e);for(let r=0;r{this.dispose()},this.onGeometryDispose=()=>{this.attributes=null,this.attributesId=null},this.material.addEventListener("dispose",this.onMaterialDispose),this.geometry.addEventListener("dispose",this.onGeometryDispose)}updateClipping(e){this.clippingContext=e}get clippingNeedsUpdate(){return null!==this.clippingContext&&this.clippingContext.cacheKey!==this.clippingContextCacheKey&&(this.clippingContextCacheKey=this.clippingContext.cacheKey,!0)}get hardwareClippingPlanes(){return!0===this.material.hardwareClipping?this.clippingContext.unionClippingCount:0}getNodeBuilderState(){return this._nodeBuilderState||(this._nodeBuilderState=this._nodes.getForRender(this))}getMonitor(){return this._monitor||(this._monitor=this.getNodeBuilderState().observer)}getBindings(){return this._bindings||(this._bindings=this.getNodeBuilderState().createBindings())}getBindingGroup(e){for(const t of this.getBindings())if(t.name===e)return t}getIndex(){return this._geometries.getIndex(this)}getIndirect(){return this._geometries.getIndirect(this)}getIndirectOffset(){return this._geometries.getIndirectOffset(this)}getChainArray(){return[this.object,this.material,this.context,this.lightsNode]}setGeometry(e){this.geometry=e,this.attributes=null,this.attributesId=null}getAttributes(){if(null!==this.attributes)return this.attributes;const e=this.getNodeBuilderState().nodeAttributes,t=this.geometry,r=[],s=new Set,i={};for(const n of e){let e;if(n.node&&n.node.attribute?e=n.node.attribute:(e=t.getAttribute(n.name),i[n.name]=e.id),void 0===e)continue;r.push(e);const a=e.isInterleavedBufferAttribute?e.data:e;s.add(a)}return this.attributes=r,this.attributesId=i,this.vertexBuffers=Array.from(s.values()),r}getVertexBuffers(){return null===this.vertexBuffers&&this.getAttributes(),this.vertexBuffers}getDrawParameters(){const{object:e,material:t,geometry:r,group:s,drawRange:i}=this,n=this.drawParams||(this.drawParams={vertexCount:0,firstVertex:0,instanceCount:0,firstInstance:0}),a=this.getIndex(),o=null!==a;let u=1;if(!0===r.isInstancedBufferGeometry?u=r.instanceCount:void 0!==e.count&&(u=Math.max(0,e.count)),0===u)return null;if(n.instanceCount=u,!0===e.isBatchedMesh)return n;let l=1;!0!==t.wireframe||e.isPoints||e.isLineSegments||e.isLine||e.isLineLoop||(l=2);let d=i.start*l,c=(i.start+i.count)*l;null!==s&&(d=Math.max(d,s.start*l),c=Math.min(c,(s.start+s.count)*l));const h=r.attributes.position;let p=1/0;o?p=a.count:null!=h&&(p=h.count),d=Math.max(d,0),c=Math.min(c,p);const g=c-d;return g<0||g===1/0?null:(n.vertexCount=g,n.firstVertex=d,n)}getGeometryCacheKey(){const{geometry:e}=this;let t="";for(const r of Object.keys(e.attributes).sort()){const s=e.attributes[r];t+=r+",",s.data&&(t+=s.data.stride+","),s.offset&&(t+=s.offset+","),s.itemSize&&(t+=s.itemSize+","),s.normalized&&(t+="n,")}for(const r of Object.keys(e.morphAttributes).sort()){const s=e.morphAttributes[r];t+="morph-"+r+",";for(let e=0,r=s.length;e1||Array.isArray(e.morphTargetInfluences))&&(s+=e.uuid+","),s+=this.context.id+",",s+=e.receiveShadow+",",Ds(s)}get needsGeometryUpdate(){if(this.geometry.id!==this.object.geometry.id)return!0;if(null!==this.attributes){const e=this.attributesId;for(const t in e){const r=this.geometry.getAttribute(t);if(void 0===r||e[t]!==r.id)return!0}}return!1}get needsUpdate(){return this.initialNodesCacheKey!==this.getDynamicCacheKey()||this.clippingNeedsUpdate}getDynamicCacheKey(){let e=0;return!0!==this.material.isShadowPassMaterial&&(e=this._nodes.getCacheKey(this.scene,this.lightsNode)),this.camera.isArrayCamera&&(e=Is(e,this.camera.cameras.length)),this.object.receiveShadow&&(e=Is(e,1)),e=Is(e,this.renderer.contextNode.id,this.renderer.contextNode.version),e}getCacheKey(){return this.getMaterialCacheKey()+this.getDynamicCacheKey()}dispose(){this.material.removeEventListener("dispose",this.onMaterialDispose),this.geometry.removeEventListener("dispose",this.onGeometryDispose),this.onDispose()}}const Jf=[];class ey{constructor(e,t,r,s,i,n){this.renderer=e,this.nodes=t,this.geometries=r,this.pipelines=s,this.bindings=i,this.info=n,this.chainMaps={}}get(e,t,r,s,i,n,a,o){const u=this.getChainMap(o);Jf[0]=e,Jf[1]=t,Jf[2]=n,Jf[3]=i;let l=u.get(Jf);return void 0===l?(l=this.createRenderObject(this.nodes,this.geometries,this.renderer,e,t,r,s,i,n,a,o),u.set(Jf,l)):(l.camera=s,l.updateClipping(a),l.needsGeometryUpdate&&l.setGeometry(e.geometry),(l.version!==t.version||l.needsUpdate)&&(l.initialCacheKey!==l.getCacheKey()?(l.dispose(),l=this.get(e,t,r,s,i,n,a,o)):l.version=t.version)),Jf[0]=null,Jf[1]=null,Jf[2]=null,Jf[3]=null,l}getChainMap(e="default"){return this.chainMaps[e]||(this.chainMaps[e]=new Yf)}dispose(){this.chainMaps={}}createRenderObject(e,t,r,s,i,n,a,o,u,l,d){const c=this.getChainMap(d),h=new Zf(e,t,r,s,i,n,a,o,u,l);return h.onDispose=()=>{this.pipelines.delete(h),this.bindings.deleteForRender(h),this.nodes.delete(h),c.delete(h.getChainArray())},h}}class ty{constructor(){this.data=new WeakMap}get(e){let t=this.data.get(e);return void 0===t&&(t={},this.data.set(e,t)),t}delete(e){let t=null;return this.data.has(e)&&(t=this.data.get(e),this.data.delete(e)),t}has(e){return this.data.has(e)}dispose(){this.data=new WeakMap}}const ry=1,sy=2,iy=3,ny=4,ay=16;class oy extends ty{constructor(e){super(),this.backend=e}delete(e){const t=super.delete(e);return null!==t&&this.backend.destroyAttribute(e),t}update(e,t){const r=this.get(e);if(void 0===r.version)t===ry?this.backend.createAttribute(e):t===sy?this.backend.createIndexAttribute(e):t===iy?this.backend.createStorageAttribute(e):t===ny&&this.backend.createIndirectStorageAttribute(e),r.version=this._getBufferAttribute(e).version;else{const t=this._getBufferAttribute(e);(r.version{this.info.memory.geometries--;const s=t.index,i=e.getAttributes();null!==s&&this.attributes.delete(s);for(const e of i)this.attributes.delete(e);const n=this.wireframes.get(t);void 0!==n&&this.attributes.delete(n),t.removeEventListener("dispose",r),this._geometryDisposeListeners.delete(t)};t.addEventListener("dispose",r),this._geometryDisposeListeners.set(t,r)}updateAttributes(e){const t=e.getAttributes();for(const e of t)e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute?this.updateAttribute(e,iy):this.updateAttribute(e,ry);const r=this.getIndex(e);null!==r&&this.updateAttribute(r,sy);const s=e.geometry.indirect;null!==s&&this.updateAttribute(s,ny)}updateAttribute(e,t){const r=this.info.render.calls;e.isInterleavedBufferAttribute?void 0===this.attributeCall.get(e)?(this.attributes.update(e,t),this.attributeCall.set(e,r)):this.attributeCall.get(e.data)!==r&&(this.attributes.update(e,t),this.attributeCall.set(e.data,r),this.attributeCall.set(e,r)):this.attributeCall.get(e)!==r&&(this.attributes.update(e,t),this.attributeCall.set(e,r))}getIndirect(e){return e.geometry.indirect}getIndirectOffset(e){return e.geometry.indirectOffset}getIndex(e){const{geometry:t,material:r}=e;let s=t.index;if(!0===r.wireframe){const e=this.wireframes;let r=e.get(t);void 0===r?(r=dy(t),e.set(t,r)):r.version===uy(t)&&r.__id===ly(t)||(this.attributes.delete(r),r=dy(t),e.set(t,r)),s=r}return s}dispose(){for(const[e,t]of this._geometryDisposeListeners.entries())e.removeEventListener("dispose",t);this._geometryDisposeListeners.clear()}}class hy{constructor(){this.autoReset=!0,this.frame=0,this.calls=0,this.render={calls:0,frameCalls:0,drawCalls:0,triangles:0,points:0,lines:0,timestamp:0},this.compute={calls:0,frameCalls:0,timestamp:0},this.memory={geometries:0,textures:0}}update(e,t,r){this.render.drawCalls++,e.isMesh||e.isSprite?this.render.triangles+=r*(t/3):e.isPoints?this.render.points+=r*t:e.isLineSegments?this.render.lines+=r*(t/2):e.isLine?this.render.lines+=r*(t-1):o("WebGPUInfo: Unknown object type.")}reset(){this.render.drawCalls=0,this.render.frameCalls=0,this.compute.frameCalls=0,this.render.triangles=0,this.render.points=0,this.render.lines=0}dispose(){this.reset(),this.calls=0,this.render.calls=0,this.compute.calls=0,this.render.timestamp=0,this.compute.timestamp=0,this.memory.geometries=0,this.memory.textures=0}}class py{constructor(e){this.cacheKey=e,this.usedTimes=0}}class gy extends py{constructor(e,t,r){super(e),this.vertexProgram=t,this.fragmentProgram=r}}class my extends py{constructor(e,t){super(e),this.computeProgram=t,this.isComputePipeline=!0}}let fy=0;class yy{constructor(e,t,r,s=null,i=null){this.id=fy++,this.code=e,this.stage=t,this.name=r,this.transforms=s,this.attributes=i,this.usedTimes=0}}class by extends ty{constructor(e,t){super(),this.backend=e,this.nodes=t,this.bindings=null,this.caches=new Map,this.programs={vertex:new Map,fragment:new Map,compute:new Map}}getForCompute(e,t){const{backend:r}=this,s=this.get(e);if(this._needsComputeUpdate(e)){const i=s.pipeline;i&&(i.usedTimes--,i.computeProgram.usedTimes--);const n=this.nodes.getForCompute(e);let a=this.programs.compute.get(n.computeShader);void 0===a&&(i&&0===i.computeProgram.usedTimes&&this._releaseProgram(i.computeProgram),a=new yy(n.computeShader,"compute",e.name,n.transforms,n.nodeAttributes),this.programs.compute.set(n.computeShader,a),r.createProgram(a));const o=this._getComputeCacheKey(e,a);let u=this.caches.get(o);void 0===u&&(i&&0===i.usedTimes&&this._releasePipeline(i),u=this._getComputePipeline(e,a,o,t)),u.usedTimes++,a.usedTimes++,s.version=e.version,s.pipeline=u}return s.pipeline}getForRender(e,t=null){const{backend:r}=this,s=this.get(e);if(this._needsRenderUpdate(e)){const i=s.pipeline;i&&(i.usedTimes--,i.vertexProgram.usedTimes--,i.fragmentProgram.usedTimes--);const n=e.getNodeBuilderState(),a=e.material?e.material.name:"";let o=this.programs.vertex.get(n.vertexShader);void 0===o&&(i&&0===i.vertexProgram.usedTimes&&this._releaseProgram(i.vertexProgram),o=new yy(n.vertexShader,"vertex",a),this.programs.vertex.set(n.vertexShader,o),r.createProgram(o));let u=this.programs.fragment.get(n.fragmentShader);void 0===u&&(i&&0===i.fragmentProgram.usedTimes&&this._releaseProgram(i.fragmentProgram),u=new yy(n.fragmentShader,"fragment",a),this.programs.fragment.set(n.fragmentShader,u),r.createProgram(u));const l=this._getRenderCacheKey(e,o,u);let d=this.caches.get(l);void 0===d?(i&&0===i.usedTimes&&this._releasePipeline(i),d=this._getRenderPipeline(e,o,u,l,t)):e.pipeline=d,d.usedTimes++,o.usedTimes++,u.usedTimes++,s.pipeline=d}return s.pipeline}delete(e){const t=this.get(e).pipeline;return t&&(t.usedTimes--,0===t.usedTimes&&this._releasePipeline(t),t.isComputePipeline?(t.computeProgram.usedTimes--,0===t.computeProgram.usedTimes&&this._releaseProgram(t.computeProgram)):(t.fragmentProgram.usedTimes--,t.vertexProgram.usedTimes--,0===t.vertexProgram.usedTimes&&this._releaseProgram(t.vertexProgram),0===t.fragmentProgram.usedTimes&&this._releaseProgram(t.fragmentProgram))),super.delete(e)}dispose(){super.dispose(),this.caches=new Map,this.programs={vertex:new Map,fragment:new Map,compute:new Map}}updateForRender(e){this.getForRender(e)}_getComputePipeline(e,t,r,s){r=r||this._getComputeCacheKey(e,t);let i=this.caches.get(r);return void 0===i&&(i=new my(r,t),this.caches.set(r,i),this.backend.createComputePipeline(i,s)),i}_getRenderPipeline(e,t,r,s,i){s=s||this._getRenderCacheKey(e,t,r);let n=this.caches.get(s);return void 0===n&&(n=new gy(s,t,r),this.caches.set(s,n),e.pipeline=n,this.backend.createRenderPipeline(e,i)),n}_getComputeCacheKey(e,t){return e.id+","+t.id}_getRenderCacheKey(e,t,r){return t.id+","+r.id+","+this.backend.getRenderCacheKey(e)}_releasePipeline(e){this.caches.delete(e.cacheKey)}_releaseProgram(e){const t=e.code,r=e.stage;this.programs[r].delete(t)}_needsComputeUpdate(e){const t=this.get(e);return void 0===t.pipeline||t.version!==e.version}_needsRenderUpdate(e){return void 0===this.get(e).pipeline||this.backend.needsRenderUpdate(e)}}class xy extends ty{constructor(e,t,r,s,i,n){super(),this.backend=e,this.textures=r,this.pipelines=i,this.attributes=s,this.nodes=t,this.info=n,this.pipelines.bindings=this}getForRender(e){const t=e.getBindings();for(const e of t){const r=this.get(e);void 0===r.bindGroup&&(this._init(e),this.backend.createBindings(e,t,0),r.bindGroup=e)}return t}getForCompute(e){const t=this.nodes.getForCompute(e).bindings;for(const e of t){const r=this.get(e);void 0===r.bindGroup&&(this._init(e),this.backend.createBindings(e,t,0),r.bindGroup=e)}return t}updateForCompute(e){this._updateBindings(this.getForCompute(e))}updateForRender(e){this._updateBindings(this.getForRender(e))}deleteForCompute(e){const t=this.nodes.getForCompute(e).bindings;for(const e of t)this.backend.deleteBindGroupData(e),this.delete(e)}deleteForRender(e){const t=e.getBindings();for(const e of t)this.backend.deleteBindGroupData(e),this.delete(e)}_updateBindings(e){for(const t of e)this._update(t,e)}_init(e){for(const t of e.bindings)if(t.isSampledTexture)this.textures.updateTexture(t.texture);else if(t.isSampler)this.textures.updateSampler(t.texture);else if(t.isStorageBuffer){const e=t.attribute,r=e.isIndirectStorageBufferAttribute?ny:iy;this.attributes.update(e,r)}}_update(e,t){const{backend:r}=this;let s=!1,i=!0,n=0,a=0;for(const t of e.bindings){if(!1!==this.nodes.updateGroup(t)){if(t.isStorageBuffer){const e=t.attribute,i=e.isIndirectStorageBufferAttribute?ny:iy,n=r.get(t);this.attributes.update(e,i),n.attribute!==e&&(n.attribute=e,s=!0)}if(t.isUniformBuffer){t.update()&&r.updateBinding(t)}else if(t.isSampledTexture){const e=t.update(),o=t.texture,u=this.textures.get(o);e&&(this.textures.updateTexture(o),t.generation!==u.generation&&(t.generation=u.generation,s=!0,i=!1));if(void 0!==r.get(o).externalTexture||u.isDefaultTexture?i=!1:(n=10*n+o.id,a+=o.version),!0===o.isStorageTexture&&!0===o.mipmapsAutoUpdate){const e=this.get(o);!0===t.store?e.needsMipmap=!0:this.textures.needsMipmaps(o)&&!0===e.needsMipmap&&(this.backend.generateMipmaps(o),e.needsMipmap=!1)}}else if(t.isSampler){if(t.update()){const e=this.textures.updateSampler(t.texture);t.samplerKey!==e&&(t.samplerKey=e,s=!0,i=!1)}}t.isBuffer&&t.updateRanges.length>0&&t.clearUpdateRanges()}}!0===s&&this.backend.updateBindings(e,t,i?n:0,a)}}function Ty(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?e.z-t.z:e.id-t.id}function _y(e,t){return e.groupOrder!==t.groupOrder?e.groupOrder-t.groupOrder:e.renderOrder!==t.renderOrder?e.renderOrder-t.renderOrder:e.z!==t.z?t.z-e.z:e.id-t.id}function vy(e){return(e.transmission>0||e.transmissionNode&&e.transmissionNode.isNode)&&e.side===B&&!1===e.forceSinglePass}class Ny{constructor(e,t,r){this.renderItems=[],this.renderItemsIndex=0,this.opaque=[],this.transparentDoublePass=[],this.transparent=[],this.bundles=[],this.lightsNode=e.getNode(t,r),this.lightsArray=[],this.scene=t,this.camera=r,this.occlusionQueryCount=0}begin(){return this.renderItemsIndex=0,this.opaque.length=0,this.transparentDoublePass.length=0,this.transparent.length=0,this.bundles.length=0,this.lightsArray.length=0,this.occlusionQueryCount=0,this}getNextRenderItem(e,t,r,s,i,n,a){let o=this.renderItems[this.renderItemsIndex];return void 0===o?(o={id:e.id,object:e,geometry:t,material:r,groupOrder:s,renderOrder:e.renderOrder,z:i,group:n,clippingContext:a},this.renderItems[this.renderItemsIndex]=o):(o.id=e.id,o.object=e,o.geometry=t,o.material=r,o.groupOrder=s,o.renderOrder=e.renderOrder,o.z=i,o.group=n,o.clippingContext=a),this.renderItemsIndex++,o}push(e,t,r,s,i,n,a){const o=this.getNextRenderItem(e,t,r,s,i,n,a);!0===e.occlusionTest&&this.occlusionQueryCount++,!0===r.transparent||r.transmission>0||r.transmissionNode&&r.transmissionNode.isNode||r.backdropNode&&r.backdropNode.isNode?(vy(r)&&this.transparentDoublePass.push(o),this.transparent.push(o)):this.opaque.push(o)}unshift(e,t,r,s,i,n,a){const o=this.getNextRenderItem(e,t,r,s,i,n,a);!0===r.transparent||r.transmission>0||r.transmissionNode&&r.transmissionNode.isNode||r.backdropNode&&r.backdropNode.isNode?(vy(r)&&this.transparentDoublePass.unshift(o),this.transparent.unshift(o)):this.opaque.unshift(o)}pushBundle(e){this.bundles.push(e)}pushLight(e){this.lightsArray.push(e)}sort(e,t){this.opaque.length>1&&this.opaque.sort(e||Ty),this.transparentDoublePass.length>1&&this.transparentDoublePass.sort(t||_y),this.transparent.length>1&&this.transparent.sort(t||_y)}finish(){this.lightsNode.setLights(this.lightsArray);for(let e=this.renderItemsIndex,t=this.renderItems.length;e>t,u=a.height>>t;let l=e.depthTexture||i[t];const d=!0===e.depthBuffer||!0===e.stencilBuffer;let c=!1;void 0===l&&d&&(l=new Y,l.format=e.stencilBuffer?Ie:Oe,l.type=e.stencilBuffer?Ve:S,l.image.width=o,l.image.height=u,l.image.depth=a.depth,l.renderTarget=e,l.isArrayTexture=!0===e.multiview&&a.depth>1,i[t]=l),r.width===a.width&&a.height===r.height||(c=!0,l&&(l.needsUpdate=!0,l.image.width=o,l.image.height=u,l.image.depth=l.isArrayTexture?l.image.depth:1)),r.width=a.width,r.height=a.height,r.textures=n,r.depthTexture=l||null,r.depth=e.depthBuffer,r.stencil=e.stencilBuffer,r.renderTarget=e,r.sampleCount!==s&&(c=!0,l&&(l.needsUpdate=!0),r.sampleCount=s);const h={sampleCount:s};if(!0!==e.isXRRenderTarget){for(let e=0;e{this._destroyRenderTarget(e)},e.addEventListener("dispose",r.onDispose))}updateTexture(e,t={}){const r=this.get(e);if(!0===r.initialized&&r.version===e.version)return;const s=e.isRenderTargetTexture||e.isDepthTexture||e.isFramebufferTexture,i=this.backend;if(s&&!0===r.initialized&&i.destroyTexture(e),e.isFramebufferTexture){const t=this.renderer.getRenderTarget();e.type=t?t.texture.type:ke}const{width:n,height:a,depth:o}=this.getSize(e);if(t.width=n,t.height=a,t.depth=o,t.needsMipmaps=this.needsMipmaps(e),t.levels=t.needsMipmaps?this.getMipLevels(e,n,a):1,e.isCubeTexture&&e.mipmaps.length>0&&t.levels++,s||!0===e.isStorageTexture||!0===e.isExternalTexture)i.createTexture(e,t),r.generation=e.version;else if(e.version>0){const s=e.image;if(void 0===s)d("Renderer: Texture marked for update but image is undefined.");else if(!1===s.complete)d("Renderer: Texture marked for update but image is incomplete.");else{if(e.images){const r=[];for(const t of e.images)r.push(t);t.images=r}else t.image=s;void 0!==r.isDefaultTexture&&!0!==r.isDefaultTexture||(i.createTexture(e,t),r.isDefaultTexture=!1,r.generation=e.version),!0===e.source.dataReady&&i.updateTexture(e,t);const n=!0===e.isStorageTexture&&!1===e.mipmapsAutoUpdate;t.needsMipmaps&&0===e.mipmaps.length&&!n&&i.generateMipmaps(e),e.onUpdate&&e.onUpdate(e)}}else i.createDefaultTexture(e),r.isDefaultTexture=!0,r.generation=e.version;!0!==r.initialized&&(r.initialized=!0,r.generation=e.version,this.info.memory.textures++,e.isVideoTexture&&!0===p.enabled&&p.getTransfer(e.colorSpace)!==g&&d("WebGPURenderer: Video textures must use a color space with a sRGB transfer function, e.g. SRGBColorSpace."),r.onDispose=()=>{this._destroyTexture(e)},e.addEventListener("dispose",r.onDispose)),r.version=e.version}updateSampler(e){return this.backend.updateSampler(e)}getSize(e,t=My){let r=e.images?e.images[0]:e.image;return r?(void 0!==r.image&&(r=r.image),"undefined"!=typeof HTMLVideoElement&&r instanceof HTMLVideoElement?(t.width=r.videoWidth||1,t.height=r.videoHeight||1,t.depth=1):"undefined"!=typeof VideoFrame&&r instanceof VideoFrame?(t.width=r.displayWidth||1,t.height=r.displayHeight||1,t.depth=1):(t.width=r.width||1,t.height=r.height||1,t.depth=e.isCubeTexture?6:r.depth||1)):t.width=t.height=t.depth=1,t}getMipLevels(e,t,r){let s;return s=e.mipmaps.length>0?e.mipmaps.length:!0===e.isCompressedTexture?1:Math.floor(Math.log2(Math.max(t,r)))+1,s}needsMipmaps(e){return!0===e.generateMipmaps||e.mipmaps.length>0}_destroyRenderTarget(e){if(!0===this.has(e)){const t=this.get(e),r=t.textures,s=t.depthTexture;e.removeEventListener("dispose",t.onDispose);for(let e=0;e=2)for(let r=0;r{if(this._currentNode=t,!t.isVarNode||!t.isIntent(e)||!0===t.isAssign(e))if("setup"===s)t.build(e);else if("analyze"===s)t.build(e,this);else if("generate"===s){const r=e.getDataFromNode(t,"any").stages,s=r&&r[e.shaderStage];if(t.isVarNode&&s&&1===s.length&&s[0]&&s[0].isStackNode)return;t.build(e,"void")}},n=[...this.nodes];for(const e of n)i(e);this._currentNode=null;const a=this.nodes.filter(e=>-1===n.indexOf(e));for(const e of a)i(e);let o;return o=this.hasOutput(e)?this.outputNode.build(e,...t):super.build(e,...t),un(r),e.removeActiveStack(this),o}}const Dy=tn(Py).setParameterLength(0,1);class Uy extends oi{static get type(){return"StructTypeNode"}constructor(e,t=null){var r;super("struct"),this.membersLayout=(r=e,Object.entries(r).map(([e,t])=>"string"==typeof t?{name:e,type:t,atomic:!1}:{name:e,type:t.type,atomic:t.atomic||!1})),this.name=t,this.isStructLayoutNode=!0}getLength(){const e=Float32Array.BYTES_PER_ELEMENT;let t=1,r=0;for(const s of this.membersLayout){const i=s.type,n=$s(i),a=Ws(i)/e;t=Math.max(t,a);const o=r%t%a;0!==o&&(r+=a-o),r+=n}return Math.ceil(r/t)*t}getMemberType(e,t){const r=this.membersLayout.find(e=>e.name===t);return r?r.type:"void"}getNodeType(e){return e.getStructTypeFromNode(this,this.membersLayout,this.name).name}setup(e){e.getStructTypeFromNode(this,this.membersLayout,this.name),e.addInclude(this)}generate(e){return this.getNodeType(e)}}class Iy extends oi{static get type(){return"StructNode"}constructor(e,t){super("vec3"),this.structTypeNode=e,this.values=t,this.isStructNode=!0}getNodeType(e){return this.structTypeNode.getNodeType(e)}getMemberType(e,t){return this.structTypeNode.getMemberType(e,t)}_getChildren(){const e=super._getChildren(),t=e.find(e=>e.childNode===this.structTypeNode);return e.splice(e.indexOf(t),1),e.push(t),e}generate(e){const t=e.getVarFromNode(this),r=t.type,s=e.getPropertyName(t);return e.addLineFlowCode(`${s} = ${e.generateStruct(r,this.structTypeNode.membersLayout,this.values)}`,this),t.name}}class Oy extends oi{static get type(){return"OutputStructNode"}constructor(...e){super(),this.members=e,this.isOutputStructNode=!0}getNodeType(){return"OutputType"}generate(e){const t=e.getDataFromNode(this);if(void 0===t.membersLayout){const r=this.members,s=[];for(let t=0;tnew qy(e,"uint","float"),Ky={};class Yy extends to{static get type(){return"BitcountNode"}constructor(e,t){super(e,t),this.isBitcountNode=!0}_resolveElementType(e,t,r){"int"===r?t.assign(jy(e,"uint")):t.assign(e)}_returnDataNode(e){switch(e){case"uint":return mn;case"int":return gn;case"uvec2":return xn;case"uvec3":return Nn;case"uvec4":return En;case"ivec2":return bn;case"ivec3":return vn;case"ivec4":return An}}_createTrailingZerosBaseLayout(e,t){const r=this._returnDataNode(t);return on(([e])=>{const s=mn(0);this._resolveElementType(e,s,t);const i=pn(s.bitAnd(Fo(s))),n=Xy(i).shiftRight(23).sub(127);return r(n)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createLeadingZerosBaseLayout(e,t){const r=this._returnDataNode(t);return on(([e])=>{dn(e.equal(mn(0)),()=>mn(32));const s=mn(0),i=mn(0);return this._resolveElementType(e,s,t),dn(s.shiftRight(16).equal(0),()=>{i.addAssign(16),s.shiftLeftAssign(16)}),dn(s.shiftRight(24).equal(0),()=>{i.addAssign(8),s.shiftLeftAssign(8)}),dn(s.shiftRight(28).equal(0),()=>{i.addAssign(4),s.shiftLeftAssign(4)}),dn(s.shiftRight(30).equal(0),()=>{i.addAssign(2),s.shiftLeftAssign(2)}),dn(s.shiftRight(31).equal(0),()=>{i.addAssign(1)}),r(i)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createOneBitsBaseLayout(e,t){const r=this._returnDataNode(t);return on(([e])=>{const s=mn(0);this._resolveElementType(e,s,t),s.assign(s.sub(s.shiftRight(mn(1)).bitAnd(mn(1431655765)))),s.assign(s.bitAnd(mn(858993459)).add(s.shiftRight(mn(2)).bitAnd(mn(858993459))));const i=s.add(s.shiftRight(mn(4))).bitAnd(mn(252645135)).mul(mn(16843009)).shiftRight(mn(24));return r(i)}).setLayout({name:e,type:t,inputs:[{name:"value",type:t}]})}_createMainLayout(e,t,r,s){const i=this._returnDataNode(t);return on(([e])=>{if(1===r)return i(s(e));{const t=i(0),n=["x","y","z","w"];for(let i=0;id(r))()}}Yy.COUNT_TRAILING_ZEROS="countTrailingZeros",Yy.COUNT_LEADING_ZEROS="countLeadingZeros",Yy.COUNT_ONE_BITS="countOneBits";const Qy=sn(Yy,Yy.COUNT_TRAILING_ZEROS).setParameterLength(1),Zy=sn(Yy,Yy.COUNT_LEADING_ZEROS).setParameterLength(1),Jy=sn(Yy,Yy.COUNT_ONE_BITS).setParameterLength(1),eb=on(([e])=>{const t=e.toUint().mul(747796405).add(2891336453),r=t.shiftRight(t.shiftRight(28).add(4)).bitXor(t).mul(277803737);return r.shiftRight(22).bitXor(r).toFloat().mul(1/2**32)}),tb=(e,t)=>Qo(Ba(4,e.mul(Ma(1,e))),t);class rb extends di{static get type(){return"PackFloatNode"}constructor(e,t){super(),this.vectorNode=t,this.encoding=e,this.isPackFloatNode=!0}getNodeType(){return"uint"}generate(e){const t=this.vectorNode.getNodeType(e);return`${e.getFloatPackingMethod(this.encoding)}(${this.vectorNode.build(e,t)})`}}const sb=sn(rb,"snorm").setParameterLength(1),ib=sn(rb,"unorm").setParameterLength(1),nb=sn(rb,"float16").setParameterLength(1);class ab extends di{static get type(){return"UnpackFloatNode"}constructor(e,t){super(),this.uintNode=t,this.encoding=e,this.isUnpackFloatNode=!0}getNodeType(){return"vec2"}generate(e){const t=this.uintNode.getNodeType(e);return`${e.getFloatUnpackingMethod(this.encoding)}(${this.uintNode.build(e,t)})`}}const ob=sn(ab,"snorm").setParameterLength(1),ub=sn(ab,"unorm").setParameterLength(1),lb=sn(ab,"float16").setParameterLength(1),db=on(([e])=>e.fract().sub(.5).abs()).setLayout({name:"tri",type:"float",inputs:[{name:"x",type:"float"}]}),cb=on(([e])=>_n(db(e.z.add(db(e.y.mul(1)))),db(e.z.add(db(e.x.mul(1)))),db(e.y.add(db(e.x.mul(1)))))).setLayout({name:"tri3",type:"vec3",inputs:[{name:"p",type:"vec3"}]}),hb=on(([e,t,r])=>{const s=_n(e).toVar(),i=pn(1.4).toVar(),n=pn(0).toVar(),a=_n(s).toVar();return up({start:pn(0),end:pn(3),type:"float",condition:"<="},()=>{const e=_n(cb(a.mul(2))).toVar();s.addAssign(e.add(r.mul(pn(.1).mul(t)))),a.mulAssign(1.8),i.mulAssign(1.5),s.mulAssign(1.2);const o=pn(db(s.z.add(db(s.x.add(db(s.y)))))).toVar();n.addAssign(o.div(i)),a.addAssign(.14)}),n}).setLayout({name:"triNoise3D",type:"float",inputs:[{name:"position",type:"vec3"},{name:"speed",type:"float"},{name:"time",type:"float"}]});class pb extends oi{static get type(){return"FunctionOverloadingNode"}constructor(e=[],...t){super(),this.functionNodes=e,this.parametersNodes=t,this._candidateFn=null,this.global=!0}getNodeType(e){return this.getCandidateFn(e).shaderNode.layout.type}getCandidateFn(e){const t=this.parametersNodes;let r=this._candidateFn;if(null===r){let s=null,i=-1;for(const r of this.functionNodes){const n=r.shaderNode.layout;if(null===n)throw new Error("FunctionOverloadingNode: FunctionNode must be a layout.");const a=n.inputs;if(t.length===a.length){let n=0;for(let r=0;ri&&(s=r,i=n)}}this._candidateFn=r=s}return r}setup(e){return this.getCandidateFn(e)(...this.parametersNodes)}}const gb=tn(pb),mb=e=>(...t)=>gb(e,...t),fb=Ta(0).setGroup(ya).onRenderUpdate(e=>e.time),yb=Ta(0).setGroup(ya).onRenderUpdate(e=>e.deltaTime),bb=Ta(0,"uint").setGroup(ya).onRenderUpdate(e=>e.frameId);const xb=on(([e,t,r=yn(.5)])=>Pf(e.sub(r),t).add(r)),Tb=on(([e,t,r=yn(.5)])=>{const s=e.sub(r),i=s.dot(s),n=i.mul(i).mul(t);return e.add(s.mul(n))}),_b=on(({position:e=null,horizontal:t=!0,vertical:r=!1})=>{let s;null!==e?(s=xd.toVar(),s[3][0]=e.x,s[3][1]=e.y,s[3][2]=e.z):s=xd;const i=id.mul(s);return Xi(t)&&(i[0][0]=xd[0].length(),i[0][1]=0,i[0][2]=0),Xi(r)&&(i[1][0]=0,i[1][1]=xd[1].length(),i[1][2]=0),i[2][0]=0,i[2][1]=0,i[2][2]=1,rd.mul(i).mul(Fd)}),vb=on(([e=null])=>{const t=Up();return Up(wp(e)).sub(t).lessThan(0).select(Hl,e)}),Nb=on(([e,t=Sl(),r=pn(0)])=>{const s=e.x,i=e.y,n=r.mod(s.mul(i)).floor(),a=n.mod(s),o=i.sub(n.add(1).div(s).ceil()),u=e.reciprocal(),l=yn(a,o);return t.add(l).mul(u)}),Sb=on(([e,t=null,r=null,s=pn(1),i=Fd,n=$d])=>{let a=n.abs().normalize();a=a.div(a.dot(_n(1)));const o=i.yz.mul(s),u=i.zx.mul(s),l=i.xy.mul(s),d=e.value,c=null!==t?t.value:d,h=null!==r?r.value:d,p=Fl(d,o).mul(a.x),g=Fl(c,u).mul(a.y),m=Fl(h,l).mul(a.z);return Ca(p,g,m)}),Rb=new qe,Ab=new r,Eb=new r,wb=new r,Cb=new a,Mb=new r(0,0,-1),Bb=new s,Fb=new r,Lb=new r,Pb=new s,Db=new t,Ub=new se,Ib=Hl.flipX();Ub.depthTexture=new Y(1,1);let Ob=!1;class Vb extends Ml{static get type(){return"ReflectorNode"}constructor(e={}){super(e.defaultTexture||Ub.texture,Ib),this._reflectorBaseNode=e.reflector||new kb(this,e),this._depthNode=null,this.setUpdateMatrix(!1)}get reflector(){return this._reflectorBaseNode}get target(){return this._reflectorBaseNode.target}getDepthNode(){if(null===this._depthNode){if(!0!==this._reflectorBaseNode.depth)throw new Error("THREE.ReflectorNode: Depth node can only be requested when the reflector is created with { depth: true }. ");this._depthNode=Qi(new Vb({defaultTexture:Ub.depthTexture,reflector:this._reflectorBaseNode}))}return this._depthNode}setup(e){return e.object.isQuadMesh||this._reflectorBaseNode.build(e),super.setup(e)}clone(){const e=new this.constructor(this.reflectorNode);return e.uvNode=this.uvNode,e.levelNode=this.levelNode,e.biasNode=this.biasNode,e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e._reflectorBaseNode=this._reflectorBaseNode,e}dispose(){super.dispose(),this._reflectorBaseNode.dispose()}}class kb extends oi{static get type(){return"ReflectorBaseNode"}constructor(e,t={}){super();const{target:r=new je,resolutionScale:s=1,generateMipmaps:i=!1,bounces:n=!0,depth:a=!1,samples:o=0}=t;this.textureNode=e,this.target=r,this.resolutionScale=s,void 0!==t.resolution&&(v('ReflectorNode: The "resolution" parameter has been renamed to "resolutionScale".'),this.resolutionScale=t.resolution),this.generateMipmaps=i,this.bounces=n,this.depth=a,this.samples=o,this.updateBeforeType=n?Zs.RENDER:Zs.FRAME,this.virtualCameras=new WeakMap,this.renderTargets=new Map,this.forceUpdate=!1,this.hasOutput=!1}_updateResolution(e,t){const r=this.resolutionScale;t.getDrawingBufferSize(Db),e.setSize(Math.round(Db.width*r),Math.round(Db.height*r))}setup(e){return this._updateResolution(Ub,e.renderer),super.setup(e)}dispose(){super.dispose();for(const e of this.renderTargets.values())e.dispose()}getVirtualCamera(e){let t=this.virtualCameras.get(e);return void 0===t&&(t=e.clone(),this.virtualCameras.set(e,t)),t}getRenderTarget(e){let t=this.renderTargets.get(e);return void 0===t&&(t=new se(0,0,{type:be,samples:this.samples}),!0===this.generateMipmaps&&(t.texture.minFilter=Xe,t.texture.generateMipmaps=!0),!0===this.depth&&(t.depthTexture=new Y),this.renderTargets.set(e,t)),t}updateBefore(e){if(!1===this.bounces&&Ob)return!1;Ob=!0;const{scene:t,camera:r,renderer:s,material:i}=e,{target:n}=this,a=this.getVirtualCamera(r),o=this.getRenderTarget(a);s.getDrawingBufferSize(Db),this._updateResolution(o,s),Eb.setFromMatrixPosition(n.matrixWorld),wb.setFromMatrixPosition(r.matrixWorld),Cb.extractRotation(n.matrixWorld),Ab.set(0,0,1),Ab.applyMatrix4(Cb),Fb.subVectors(Eb,wb);let u=!1;if(!0===Fb.dot(Ab)>0&&!1===this.forceUpdate){if(!1===this.hasOutput)return void(Ob=!1);u=!0}Fb.reflect(Ab).negate(),Fb.add(Eb),Cb.extractRotation(r.matrixWorld),Mb.set(0,0,-1),Mb.applyMatrix4(Cb),Mb.add(wb),Lb.subVectors(Eb,Mb),Lb.reflect(Ab).negate(),Lb.add(Eb),a.coordinateSystem=r.coordinateSystem,a.position.copy(Fb),a.up.set(0,1,0),a.up.applyMatrix4(Cb),a.up.reflect(Ab),a.lookAt(Lb),a.near=r.near,a.far=r.far,a.updateMatrixWorld(),a.projectionMatrix.copy(r.projectionMatrix),Rb.setFromNormalAndCoplanarPoint(Ab,Eb),Rb.applyMatrix4(a.matrixWorldInverse),Bb.set(Rb.normal.x,Rb.normal.y,Rb.normal.z,Rb.constant);const l=a.projectionMatrix;Pb.x=(Math.sign(Bb.x)+l.elements[8])/l.elements[0],Pb.y=(Math.sign(Bb.y)+l.elements[9])/l.elements[5],Pb.z=-1,Pb.w=(1+l.elements[10])/l.elements[14],Bb.multiplyScalar(1/Bb.dot(Pb));l.elements[2]=Bb.x,l.elements[6]=Bb.y,l.elements[10]=s.coordinateSystem===h?Bb.z-0:Bb.z+1-0,l.elements[14]=Bb.w,this.textureNode.value=o.texture,!0===this.depth&&(this.textureNode.getDepthNode().value=o.depthTexture),i.visible=!1;const d=s.getRenderTarget(),c=s.getMRT(),p=s.autoClear;s.setMRT(null),s.setRenderTarget(o),s.autoClear=!0;const g=t.name;t.name=(t.name||"Scene")+" [ Reflector ]",u?(s.clear(),this.hasOutput=!1):(s.render(t,a),this.hasOutput=!0),t.name=g,s.setMRT(c),s.setRenderTarget(d),s.autoClear=p,i.visible=!0,Ob=!1,this.forceUpdate=!1}get resolution(){return v('ReflectorNode: The "resolution" property has been renamed to "resolutionScale".'),this.resolutionScale}set resolution(e){v('ReflectorNode: The "resolution" property has been renamed to "resolutionScale".'),this.resolutionScale=e}}const Gb=new _e(-1,1,1,-1,0,1);class zb extends Te{constructor(e=!1){super();const t=!1===e?[0,-1,0,1,2,1]:[0,2,0,0,2,0];this.setAttribute("position",new Ke([-1,3,0,-1,-1,0,3,-1,0],3)),this.setAttribute("uv",new Ke(t,2))}}const $b=new zb;class Wb extends ne{constructor(e=null){super($b,e),this.camera=Gb,this.isQuadMesh=!0}async renderAsync(e){v('QuadMesh: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await e.init(),e.render(this,Gb)}render(e){e.render(this,Gb)}}const Hb=new t;class qb extends Ml{static get type(){return"RTTNode"}constructor(e,t=null,r=null,s={type:be}){const i=new se(t,r,s);super(i.texture,Sl()),this.isRTTNode=!0,this.node=e,this.width=t,this.height=r,this.pixelRatio=1,this.renderTarget=i,this.textureNeedsUpdate=!0,this.autoUpdate=!0,this._rttNode=null,this._quadMesh=new Wb(new Qp),this.updateBeforeType=Zs.RENDER}get autoResize(){return null===this.width}setup(e){return this._rttNode=this.node.context(e.getSharedContext()),this._quadMesh.material.name="RTT",this._quadMesh.material.needsUpdate=!0,super.setup(e)}setSize(e,t){this.width=e,this.height=t;const r=e*this.pixelRatio,s=t*this.pixelRatio;this.renderTarget.setSize(r,s),this.textureNeedsUpdate=!0}setPixelRatio(e){this.pixelRatio=e,this.setSize(this.width,this.height)}updateBefore({renderer:e}){if(!1===this.textureNeedsUpdate&&!1===this.autoUpdate)return;if(this.textureNeedsUpdate=!1,!0===this.autoResize){const t=e.getPixelRatio(),r=e.getSize(Hb),s=Math.floor(r.width*t),i=Math.floor(r.height*t);s===this.renderTarget.width&&i===this.renderTarget.height||(this.renderTarget.setSize(s,i),this.textureNeedsUpdate=!0)}let t="RTT";this.node.name&&(t=this.node.name+" [ "+t+" ]"),this._quadMesh.material.fragmentNode=this._rttNode,this._quadMesh.name=t;const r=e.getRenderTarget();e.setRenderTarget(this.renderTarget),this._quadMesh.render(e),e.setRenderTarget(r)}clone(){const e=new Ml(this.value,this.uvNode,this.levelNode);return e.sampler=this.sampler,e.referenceNode=this,e}}const jb=(e,...t)=>Qi(new qb(Qi(e),...t)),Xb=on(([e,t,r],s)=>{let i;s.renderer.coordinateSystem===h?(e=yn(e.x,e.y.oneMinus()).mul(2).sub(1),i=Rn(_n(e,t),1)):i=Rn(_n(e.x,e.y.oneMinus(),t).mul(2).sub(1),1);const n=Rn(r.mul(i));return n.xyz.div(n.w)}),Kb=on(([e,t])=>{const r=t.mul(Rn(e,1)),s=r.xy.div(r.w).mul(.5).add(.5).toVar();return yn(s.x,s.y.oneMinus())}),Yb=on(([e,t,r])=>{const s=Al(Ll(t)),i=bn(e.mul(s)).toVar(),n=Ll(t,i).toVar(),a=Ll(t,i.sub(bn(2,0))).toVar(),o=Ll(t,i.sub(bn(1,0))).toVar(),u=Ll(t,i.add(bn(1,0))).toVar(),l=Ll(t,i.add(bn(2,0))).toVar(),d=Ll(t,i.add(bn(0,2))).toVar(),c=Ll(t,i.add(bn(0,1))).toVar(),h=Ll(t,i.sub(bn(0,1))).toVar(),p=Ll(t,i.sub(bn(0,2))).toVar(),g=Co(Ma(pn(2).mul(o).sub(a),n)).toVar(),m=Co(Ma(pn(2).mul(u).sub(l),n)).toVar(),f=Co(Ma(pn(2).mul(c).sub(d),n)).toVar(),y=Co(Ma(pn(2).mul(h).sub(p),n)).toVar(),b=Xb(e,n,r).toVar(),x=g.lessThan(m).select(b.sub(Xb(e.sub(yn(pn(1).div(s.x),0)),o,r)),b.negate().add(Xb(e.add(yn(pn(1).div(s.x),0)),u,r))),T=f.lessThan(y).select(b.sub(Xb(e.add(yn(0,pn(1).div(s.y))),c,r)),b.negate().add(Xb(e.sub(yn(0,pn(1).div(s.y))),h,r)));return _o(Yo(x,T))}),Qb=on(([e])=>vo(pn(52.9829189).mul(vo(Ko(e,yn(.06711056,.00583715)))))).setLayout({name:"interleavedGradientNoise",type:"float",inputs:[{name:"position",type:"vec2"}]}),Zb=on(([e,t,r])=>{const s=pn(2.399963229728653),i=yo(pn(e).add(.5).div(pn(t))),n=pn(e).mul(s).add(r);return yn(So(n),No(n)).mul(i)}).setLayout({name:"vogelDiskSample",type:"vec2",inputs:[{name:"sampleIndex",type:"int"},{name:"samplesCount",type:"int"},{name:"phi",type:"float"}]});class Jb extends oi{static get type(){return"SampleNode"}constructor(e,t=null){super(),this.callback=e,this.uvNode=t,this.isSampleNode=!0}setup(){return this.sample(Sl())}sample(e){return this.callback(e)}}class ex extends oi{static get type(){return"EventNode"}constructor(e,t){super("void"),this.eventType=e,this.callback=t,e===ex.OBJECT?this.updateType=Zs.OBJECT:e===ex.MATERIAL?this.updateType=Zs.RENDER:e===ex.BEFORE_OBJECT?this.updateBeforeType=Zs.OBJECT:e===ex.BEFORE_MATERIAL&&(this.updateBeforeType=Zs.RENDER)}update(e){this.callback(e)}updateBefore(e){this.callback(e)}}ex.OBJECT="object",ex.MATERIAL="material",ex.BEFORE_OBJECT="beforeObject",ex.BEFORE_MATERIAL="beforeMaterial";const tx=(e,t)=>new ex(e,t).toStack();class rx extends W{constructor(e,t,r=Float32Array){super(ArrayBuffer.isView(e)?e:new r(e*t),t),this.isStorageInstancedBufferAttribute=!0}}class sx extends Ae{constructor(e,t,r=Float32Array){super(ArrayBuffer.isView(e)?e:new r(e*t),t),this.isStorageBufferAttribute=!0}}class ix extends oi{static get type(){return"PointUVNode"}constructor(){super("vec2"),this.isPointUVNode=!0}generate(){return"vec2( gl_PointCoord.x, 1.0 - gl_PointCoord.y )"}}const nx=rn(ix),ax=new F,ox=new a,ux=Ta(0).setGroup(ya).onRenderUpdate(({scene:e})=>e.backgroundBlurriness),lx=Ta(1).setGroup(ya).onRenderUpdate(({scene:e})=>e.backgroundIntensity),dx=Ta(new a).setGroup(ya).onRenderUpdate(({scene:e})=>{const t=e.background;return null!==t&&t.isTexture&&t.mapping!==Ye?(ax.copy(e.backgroundRotation),ax.x*=-1,ax.y*=-1,ax.z*=-1,ox.makeRotationFromEuler(ax)):ox.identity(),ox});class cx extends Ml{static get type(){return"StorageTextureNode"}constructor(e,t,r=null){super(e,t),this.storeNode=r,this.mipLevel=0,this.isStorageTextureNode=!0,this.access=ei.WRITE_ONLY}getInputType(){return"storageTexture"}setup(e){super.setup(e);const t=e.getNodeProperties(this);return t.storeNode=this.storeNode,t}setAccess(e){return this.access=e,this}setMipLevel(e){return this.mipLevel=e,this}generate(e,t){let r;return r=null!==this.storeNode?this.generateStore(e):super.generate(e,t),r}toReadWrite(){return this.setAccess(ei.READ_WRITE)}toReadOnly(){return this.setAccess(ei.READ_ONLY)}toWriteOnly(){return this.setAccess(ei.WRITE_ONLY)}generateStore(e){const t=e.getNodeProperties(this),{uvNode:r,storeNode:s,depthNode:i}=t,n=super.generate(e,"property"),a=r.build(e,!0===this.value.is3DTexture?"uvec3":"uvec2"),o=s.build(e,"vec4"),u=i?i.build(e,"int"):null,l=e.generateTextureStore(e,n,a,u,o);e.addLineFlowCode(l,this)}clone(){const e=super.clone();return e.storeNode=this.storeNode,e.mipLevel=this.mipLevel,e.access=this.access,e}}const hx=tn(cx).setParameterLength(1,3),px=on(({texture:e,uv:t})=>{const r=1e-4,s=_n().toVar();return dn(t.x.lessThan(r),()=>{s.assign(_n(1,0,0))}).ElseIf(t.y.lessThan(r),()=>{s.assign(_n(0,1,0))}).ElseIf(t.z.lessThan(r),()=>{s.assign(_n(0,0,1))}).ElseIf(t.x.greaterThan(.9999),()=>{s.assign(_n(-1,0,0))}).ElseIf(t.y.greaterThan(.9999),()=>{s.assign(_n(0,-1,0))}).ElseIf(t.z.greaterThan(.9999),()=>{s.assign(_n(0,0,-1))}).Else(()=>{const r=.01,i=e.sample(t.add(_n(-.01,0,0))).r.sub(e.sample(t.add(_n(r,0,0))).r),n=e.sample(t.add(_n(0,-.01,0))).r.sub(e.sample(t.add(_n(0,r,0))).r),a=e.sample(t.add(_n(0,0,-.01))).r.sub(e.sample(t.add(_n(0,0,r))).r);s.assign(_n(i,n,a))}),s.normalize()});class gx extends Ml{static get type(){return"Texture3DNode"}constructor(e,t=null,r=null){super(e,t,r),this.isTexture3DNode=!0}getInputType(){return"texture3D"}getDefaultUV(){return _n(.5,.5,.5)}setUpdateMatrix(){}generateUV(e,t){return t.build(e,!0===this.sampler?"vec3":"ivec3")}generateOffset(e,t){return t.build(e,"ivec3")}normal(e){return px({texture:this,uv:e})}}const mx=tn(gx).setParameterLength(1,3);class fx extends mc{static get type(){return"UserDataNode"}constructor(e,t,r=null){super(e,t,r),this.userData=r}updateReference(e){return this.reference=null!==this.userData?this.userData:e.object.userData,this.reference}}const yx=new WeakMap;class bx extends di{static get type(){return"VelocityNode"}constructor(){super("vec2"),this.projectionMatrix=null,this.updateType=Zs.OBJECT,this.updateAfterType=Zs.OBJECT,this.previousModelWorldMatrix=Ta(new a),this.previousProjectionMatrix=Ta(new a).setGroup(ya),this.previousCameraViewMatrix=Ta(new a)}setProjectionMatrix(e){this.projectionMatrix=e}update({frameId:e,camera:t,object:r}){const s=Tx(r);this.previousModelWorldMatrix.value.copy(s);const i=xx(t);i.frameId!==e&&(i.frameId=e,void 0===i.previousProjectionMatrix?(i.previousProjectionMatrix=new a,i.previousCameraViewMatrix=new a,i.currentProjectionMatrix=new a,i.currentCameraViewMatrix=new a,i.previousProjectionMatrix.copy(this.projectionMatrix||t.projectionMatrix),i.previousCameraViewMatrix.copy(t.matrixWorldInverse)):(i.previousProjectionMatrix.copy(i.currentProjectionMatrix),i.previousCameraViewMatrix.copy(i.currentCameraViewMatrix)),i.currentProjectionMatrix.copy(this.projectionMatrix||t.projectionMatrix),i.currentCameraViewMatrix.copy(t.matrixWorldInverse),this.previousProjectionMatrix.value.copy(i.previousProjectionMatrix),this.previousCameraViewMatrix.value.copy(i.previousCameraViewMatrix))}updateAfter({object:e}){Tx(e).copy(e.matrixWorld)}setup(){const e=null===this.projectionMatrix?rd:Ta(this.projectionMatrix),t=this.previousCameraViewMatrix.mul(this.previousModelWorldMatrix),r=e.mul(Ad).mul(Fd),s=this.previousProjectionMatrix.mul(t).mul(Ld),i=r.xy.div(r.w),n=s.xy.div(s.w);return Ma(i,n)}}function xx(e){let t=yx.get(e);return void 0===t&&(t={},yx.set(e,t)),t}function Tx(e,t=0){const r=xx(e);let s=r[t];return void 0===s&&(r[t]=s=new a,r[t].copy(e.matrixWorld)),s}const _x=rn(bx),vx=on(([e])=>Ax(e.rgb)),Nx=on(([e,t=pn(1)])=>t.mix(Ax(e.rgb),e.rgb)),Sx=on(([e,t=pn(1)])=>{const r=Ca(e.r,e.g,e.b).div(3),s=e.r.max(e.g.max(e.b)),i=s.sub(r).mul(t).mul(-3);return iu(e.rgb,s,i)}),Rx=on(([e,t=pn(1)])=>{const r=_n(.57735,.57735,.57735),s=t.cos();return _n(e.rgb.mul(s).add(r.cross(e.rgb).mul(t.sin()).add(r.mul(Ko(r,e.rgb).mul(s.oneMinus())))))}),Ax=(e,t=_n(p.getLuminanceCoefficients(new r)))=>Ko(e,t),Ex=on(([e,t=_n(1),s=_n(0),i=_n(1),n=pn(1),a=_n(p.getLuminanceCoefficients(new r,Ne))])=>{const o=e.rgb.dot(_n(a)),u=Wo(e.rgb.mul(t).add(s),0).toVar(),l=u.pow(i).toVar();return dn(u.r.greaterThan(0),()=>{u.r.assign(l.r)}),dn(u.g.greaterThan(0),()=>{u.g.assign(l.g)}),dn(u.b.greaterThan(0),()=>{u.b.assign(l.b)}),u.assign(o.add(u.sub(o).mul(n))),Rn(u.rgb,e.a)});class wx extends di{static get type(){return"PosterizeNode"}constructor(e,t){super(),this.sourceNode=e,this.stepsNode=t}setup(){const{sourceNode:e,stepsNode:t}=this;return e.mul(t).floor().div(t)}}const Cx=tn(wx).setParameterLength(2);let Mx=null;class Bx extends _p{static get type(){return"ViewportSharedTextureNode"}constructor(e=Hl,t=null){null===Mx&&(Mx=new X),super(e,t,Mx)}getTextureForReference(){return Mx}updateReference(){return this}}const Fx=tn(Bx).setParameterLength(0,2),Lx=new t;class Px extends Ml{static get type(){return"PassTextureNode"}constructor(e,t){super(t),this.passNode=e,this.setUpdateMatrix(!1)}setup(e){return this.passNode.build(e),super.setup(e)}clone(){return new this.constructor(this.passNode,this.value)}}class Dx extends Px{static get type(){return"PassMultipleTextureNode"}constructor(e,t,r=!1){super(e,null),this.textureName=t,this.previousTexture=r}updateTexture(){this.value=this.previousTexture?this.passNode.getPreviousTexture(this.textureName):this.passNode.getTexture(this.textureName)}setup(e){return this.updateTexture(),super.setup(e)}clone(){const e=new this.constructor(this.passNode,this.textureName,this.previousTexture);return e.uvNode=this.uvNode,e.levelNode=this.levelNode,e.biasNode=this.biasNode,e.sampler=this.sampler,e.depthNode=this.depthNode,e.compareNode=this.compareNode,e.gradNode=this.gradNode,e.offsetNode=this.offsetNode,e}}class Ux extends di{static get type(){return"PassNode"}constructor(e,t,r,s={}){super("vec4"),this.scope=e,this.scene=t,this.camera=r,this.options=s,this._pixelRatio=1,this._width=1,this._height=1;const i=new Y;i.isRenderTargetTexture=!0,i.name="depth";const n=new se(this._width*this._pixelRatio,this._height*this._pixelRatio,{type:be,...s});n.texture.name="output",n.depthTexture=i,this.renderTarget=n,this.overrideMaterial=null,this.transparent=!0,this.opaque=!0,this.contextNode=null,this._contextNodeCache=null,this._textures={output:n.texture,depth:i},this._textureNodes={},this._linearDepthNodes={},this._viewZNodes={},this._previousTextures={},this._previousTextureNodes={},this._cameraNear=Ta(0),this._cameraFar=Ta(0),this._mrt=null,this._layers=null,this._resolutionScale=1,this._viewport=null,this._scissor=null,this.isPassNode=!0,this.updateBeforeType=Zs.FRAME,this.global=!0}setResolutionScale(e){return this._resolutionScale=e,this}getResolutionScale(){return this._resolutionScale}setResolution(e){return d("PassNode: .setResolution() is deprecated. Use .setResolutionScale() instead."),this.setResolutionScale(e)}getResolution(){return d("PassNode: .getResolution() is deprecated. Use .getResolutionScale() instead."),this.getResolutionScale()}setLayers(e){return this._layers=e,this}getLayers(){return this._layers}setMRT(e){return this._mrt=e,this}getMRT(){return this._mrt}getTexture(e){let t=this._textures[e];if(void 0===t){t=this.renderTarget.texture.clone(),t.name=e,this._textures[e]=t,this.renderTarget.textures.push(t)}return t}getPreviousTexture(e){let t=this._previousTextures[e];return void 0===t&&(t=this.getTexture(e).clone(),this._previousTextures[e]=t),t}toggleTexture(e){const t=this._previousTextures[e];if(void 0!==t){const r=this._textures[e],s=this.renderTarget.textures.indexOf(r);this.renderTarget.textures[s]=t,this._textures[e]=t,this._previousTextures[e]=r,this._textureNodes[e].updateTexture(),this._previousTextureNodes[e].updateTexture()}}getTextureNode(e="output"){let t=this._textureNodes[e];return void 0===t&&(t=new Dx(this,e),t.updateTexture(),this._textureNodes[e]=t),t}getPreviousTextureNode(e="output"){let t=this._previousTextureNodes[e];return void 0===t&&(void 0===this._textureNodes[e]&&this.getTextureNode(e),t=new Dx(this,e,!0),t.updateTexture(),this._previousTextureNodes[e]=t),t}getViewZNode(e="depth"){let t=this._viewZNodes[e];if(void 0===t){const r=this._cameraNear,s=this._cameraFar;this._viewZNodes[e]=t=Fp(this.getTextureNode(e),r,s)}return t}getLinearDepthNode(e="depth"){let t=this._linearDepthNodes[e];if(void 0===t){const r=this._cameraNear,s=this._cameraFar,i=this.getViewZNode(e);this._linearDepthNodes[e]=t=Mp(i,r,s)}return t}async compileAsync(e){const t=e.getRenderTarget(),r=e.getMRT();e.setRenderTarget(this.renderTarget),e.setMRT(this._mrt),await e.compileAsync(this.scene,this.camera),e.setRenderTarget(t),e.setMRT(r)}setup({renderer:e}){return this.renderTarget.samples=void 0===this.options.samples?e.samples:this.options.samples,this.renderTarget.texture.type=e.getOutputBufferType(),this.scope===Ux.COLOR?this.getTextureNode():this.getLinearDepthNode()}updateBefore(e){const{renderer:t}=e,{scene:r}=this;let s,i;const n=t.getOutputRenderTarget();n&&!0===n.isXRRenderTarget?(i=1,s=t.xr.getCamera(),t.xr.updateCamera(s),Lx.set(n.width,n.height)):(s=this.camera,i=t.getPixelRatio(),t.getSize(Lx)),this._pixelRatio=i,this.setSize(Lx.width,Lx.height);const a=t.getRenderTarget(),o=t.getMRT(),u=t.autoClear,l=t.transparent,d=t.opaque,c=s.layers.mask,h=t.contextNode,p=r.overrideMaterial;this._cameraNear.value=s.near,this._cameraFar.value=s.far,null!==this._layers&&(s.layers.mask=this._layers.mask);for(const e in this._previousTextures)this.toggleTexture(e);null!==this.overrideMaterial&&(r.overrideMaterial=this.overrideMaterial),t.setRenderTarget(this.renderTarget),t.setMRT(this._mrt),t.autoClear=!0,t.transparent=this.transparent,t.opaque=this.opaque,null!==this.contextNode&&(null!==this._contextNodeCache&&this._contextNodeCache.version===this.version||(this._contextNodeCache={version:this.version,context:xu({...t.contextNode.getFlowContextData(),...this.contextNode.getFlowContextData()})}),t.contextNode=this._contextNodeCache.context);const g=r.name;r.name=this.name?this.name:r.name,t.render(r,s),r.name=g,r.overrideMaterial=p,t.setRenderTarget(a),t.setMRT(o),t.autoClear=u,t.transparent=l,t.opaque=d,t.contextNode=h,s.layers.mask=c}setSize(e,t){this._width=e,this._height=t;const r=Math.floor(this._width*this._pixelRatio*this._resolutionScale),s=Math.floor(this._height*this._pixelRatio*this._resolutionScale);this.renderTarget.setSize(r,s),null!==this._scissor&&this.renderTarget.scissor.copy(this._scissor),null!==this._viewport&&this.renderTarget.viewport.copy(this._viewport)}setScissor(e,t,r,i){null===e?this._scissor=null:(null===this._scissor&&(this._scissor=new s),e.isVector4?this._scissor.copy(e):this._scissor.set(e,t,r,i),this._scissor.multiplyScalar(this._pixelRatio*this._resolutionScale).floor())}setViewport(e,t,r,i){null===e?this._viewport=null:(null===this._viewport&&(this._viewport=new s),e.isVector4?this._viewport.copy(e):this._viewport.set(e,t,r,i),this._viewport.multiplyScalar(this._pixelRatio*this._resolutionScale).floor())}setPixelRatio(e){this._pixelRatio=e,this.setSize(this._width,this._height)}dispose(){this.renderTarget.dispose()}}Ux.COLOR="color",Ux.DEPTH="depth";class Ix extends Ux{static get type(){return"ToonOutlinePassNode"}constructor(e,t,r,s,i){super(Ux.COLOR,e,t),this.colorNode=r,this.thicknessNode=s,this.alphaNode=i,this._materialCache=new WeakMap,this.name="Outline Pass"}updateBefore(e){const{renderer:t}=e,r=t.getRenderObjectFunction();t.setRenderObjectFunction((e,r,s,i,n,a,o,u)=>{if((n.isMeshToonMaterial||n.isMeshToonNodeMaterial)&&!1===n.wireframe){const l=this._getOutlineMaterial(n);t.renderObject(e,r,s,i,l,a,o,u)}t.renderObject(e,r,s,i,n,a,o,u)}),super.updateBefore(e),t.setRenderObjectFunction(r)}_createMaterial(){const e=new Qp;e.isMeshToonOutlineMaterial=!0,e.name="Toon_Outline",e.side=M;const t=$d.negate(),r=rd.mul(Ad),s=pn(1),i=r.mul(Rn(Fd,1)),n=r.mul(Rn(Fd.add(t),1)),a=_o(i.sub(n));return e.vertexNode=i.add(a.mul(this.thicknessNode).mul(i.w).mul(s)),e.colorNode=Rn(this.colorNode,this.alphaNode),e}_getOutlineMaterial(e){let t=this._materialCache.get(e);return void 0===t&&(t=this._createMaterial(),this._materialCache.set(e,t)),t}}const Ox=on(([e,t])=>e.mul(t).clamp()).setLayout({name:"linearToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),Vx=on(([e,t])=>(e=e.mul(t)).div(e.add(1)).clamp()).setLayout({name:"reinhardToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),kx=on(([e,t])=>{const r=(e=(e=e.mul(t)).sub(.004).max(0)).mul(e.mul(6.2).add(.5)),s=e.mul(e.mul(6.2).add(1.7)).add(.06);return r.div(s).pow(2.2)}).setLayout({name:"cineonToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),Gx=on(([e])=>{const t=e.mul(e.add(.0245786)).sub(90537e-9),r=e.mul(e.add(.432951).mul(.983729)).add(.238081);return t.div(r)}),zx=on(([e,t])=>{const r=Mn(.59719,.35458,.04823,.076,.90834,.01566,.0284,.13383,.83777),s=Mn(1.60475,-.53108,-.07367,-.10208,1.10813,-.00605,-.00327,-.07276,1.07602);return e=e.mul(t).div(.6),e=r.mul(e),e=Gx(e),(e=s.mul(e)).clamp()}).setLayout({name:"acesFilmicToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),$x=Mn(_n(1.6605,-.1246,-.0182),_n(-.5876,1.1329,-.1006),_n(-.0728,-.0083,1.1187)),Wx=Mn(_n(.6274,.0691,.0164),_n(.3293,.9195,.088),_n(.0433,.0113,.8956)),Hx=on(([e])=>{const t=_n(e).toVar(),r=_n(t.mul(t)).toVar(),s=_n(r.mul(r)).toVar();return pn(15.5).mul(s.mul(r)).sub(Ba(40.14,s.mul(t))).add(Ba(31.96,s).sub(Ba(6.868,r.mul(t))).add(Ba(.4298,r).add(Ba(.1191,t).sub(.00232))))}),qx=on(([e,t])=>{const r=_n(e).toVar(),s=Mn(_n(.856627153315983,.137318972929847,.11189821299995),_n(.0951212405381588,.761241990602591,.0767994186031903),_n(.0482516061458583,.101439036467562,.811302368396859)),i=Mn(_n(1.1271005818144368,-.1413297634984383,-.14132976349843826),_n(-.11060664309660323,1.157823702216272,-.11060664309660294),_n(-.016493938717834573,-.016493938717834257,1.2519364065950405)),n=pn(-12.47393),a=pn(4.026069);return r.mulAssign(t),r.assign(Wx.mul(r)),r.assign(s.mul(r)),r.assign(Wo(r,1e-10)),r.assign(fo(r)),r.assign(r.sub(n).div(a.sub(n))),r.assign(nu(r,0,1)),r.assign(Hx(r)),r.assign(i.mul(r)),r.assign(Qo(Wo(_n(0),r),_n(2.2))),r.assign($x.mul(r)),r.assign(nu(r,0,1)),r}).setLayout({name:"agxToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]}),jx=on(([e,t])=>{const r=pn(.76),s=pn(.15);e=e.mul(t);const i=$o(e.r,$o(e.g,e.b)),n=yu(i.lessThan(.08),i.sub(Ba(6.25,i.mul(i))),.04);e.subAssign(n);const a=Wo(e.r,Wo(e.g,e.b));dn(a.lessThan(r),()=>e);const o=Ma(1,r),u=Ma(1,o.mul(o).div(a.add(o.sub(r))));e.mulAssign(u.div(a));const l=Ma(1,Fa(1,s.mul(a.sub(u)).add(1)));return iu(e,_n(u),l)}).setLayout({name:"neutralToneMapping",type:"vec3",inputs:[{name:"color",type:"vec3"},{name:"exposure",type:"float"}]});class Xx extends oi{static get type(){return"CodeNode"}constructor(e="",t=[],r=""){super("code"),this.isCodeNode=!0,this.global=!0,this.code=e,this.includes=t,this.language=r}setIncludes(e){return this.includes=e,this}getIncludes(){return this.includes}generate(e){const t=this.getIncludes(e);for(const r of t)r.build(e);const r=e.getCodeFromNode(this,this.getNodeType(e));return r.code=this.code,r.code}serialize(e){super.serialize(e),e.code=this.code,e.language=this.language}deserialize(e){super.deserialize(e),this.code=e.code,this.language=e.language}}const Kx=tn(Xx).setParameterLength(1,3);class Yx extends Xx{static get type(){return"FunctionNode"}constructor(e="",t=[],r=""){super(e,t,r)}getNodeType(e){return this.getNodeFunction(e).type}getMemberType(e,t){const r=this.getNodeType(e);return e.getStructTypeNode(r).getMemberType(e,t)}getInputs(e){return this.getNodeFunction(e).inputs}getNodeFunction(e){const t=e.getDataFromNode(this);let r=t.nodeFunction;return void 0===r&&(r=e.parser.parseFunction(this.code),t.nodeFunction=r),r}generate(e,t){super.generate(e);const r=this.getNodeFunction(e),s=r.name,i=r.type,n=e.getCodeFromNode(this,i);""!==s&&(n.name=s);const a=e.getPropertyName(n),o=this.getNodeFunction(e).getCode(a);return n.code=o+"\n","property"===t?a:e.format(`${a}()`,i,t)}}const Qx=(e,t=[],r="")=>{for(let e=0;es.call(...e);return i.functionNode=s,i};class Zx extends oi{static get type(){return"ScriptableValueNode"}constructor(e=null){super(),this._value=e,this._cache=null,this.inputType=null,this.outputType=null,this.events=new u,this.isScriptableValueNode=!0}get isScriptableOutputNode(){return null!==this.outputType}set value(e){this._value!==e&&(this._cache&&"URL"===this.inputType&&this.value.value instanceof ArrayBuffer&&(URL.revokeObjectURL(this._cache),this._cache=null),this._value=e,this.events.dispatchEvent({type:"change"}),this.refresh())}get value(){return this._value}refresh(){this.events.dispatchEvent({type:"refresh"})}getValue(){const e=this.value;if(e&&null===this._cache&&"URL"===this.inputType&&e.value instanceof ArrayBuffer)this._cache=URL.createObjectURL(new Blob([e.value]));else if(e&&null!==e.value&&void 0!==e.value&&(("URL"===this.inputType||"String"===this.inputType)&&"string"==typeof e.value||"Number"===this.inputType&&"number"==typeof e.value||"Vector2"===this.inputType&&e.value.isVector2||"Vector3"===this.inputType&&e.value.isVector3||"Vector4"===this.inputType&&e.value.isVector4||"Color"===this.inputType&&e.value.isColor||"Matrix3"===this.inputType&&e.value.isMatrix3||"Matrix4"===this.inputType&&e.value.isMatrix4))return e.value;return this._cache||e}getNodeType(e){return this.value&&this.value.isNode?this.value.getNodeType(e):"float"}setup(){return this.value&&this.value.isNode?this.value:pn()}serialize(e){super.serialize(e),null!==this.value?"ArrayBuffer"===this.inputType?e.value=Xs(this.value):e.value=this.value?this.value.toJSON(e.meta).uuid:null:e.value=null,e.inputType=this.inputType,e.outputType=this.outputType}deserialize(e){super.deserialize(e);let t=null;null!==e.value&&(t="ArrayBuffer"===e.inputType?Ks(e.value):"Texture"===e.inputType?e.meta.textures[e.value]:e.meta.nodes[e.value]||null),this.value=t,this.inputType=e.inputType,this.outputType=e.outputType}}const Jx=tn(Zx).setParameterLength(1);class eT extends Map{get(e,t=null,...r){if(this.has(e))return super.get(e);if(null!==t){const s=t(...r);return this.set(e,s),s}}}class tT{constructor(e){this.scriptableNode=e}get parameters(){return this.scriptableNode.parameters}get layout(){return this.scriptableNode.getLayout()}getInputLayout(e){return this.scriptableNode.getInputLayout(e)}get(e){const t=this.parameters[e];return t?t.getValue():null}}const rT=new eT;class sT extends oi{static get type(){return"ScriptableNode"}constructor(e=null,t={}){super(),this.codeNode=e,this.parameters=t,this._local=new eT,this._output=Jx(null),this._outputs={},this._source=this.source,this._method=null,this._object=null,this._value=null,this._needsOutputUpdate=!0,this.onRefresh=this.onRefresh.bind(this),this.isScriptableNode=!0}get source(){return this.codeNode?this.codeNode.code:""}setLocal(e,t){return this._local.set(e,t)}getLocal(e){return this._local.get(e)}onRefresh(){this._refresh()}getInputLayout(e){for(const t of this.getLayout())if(t.inputType&&(t.id===e||t.name===e))return t}getOutputLayout(e){for(const t of this.getLayout())if(t.outputType&&(t.id===e||t.name===e))return t}setOutput(e,t){const r=this._outputs;return void 0===r[e]?r[e]=Jx(t):r[e].value=t,this}getOutput(e){return this._outputs[e]}getParameter(e){return this.parameters[e]}setParameter(e,t){const r=this.parameters;return t&&t.isScriptableNode?(this.deleteParameter(e),r[e]=t,r[e].getDefaultOutput().events.addEventListener("refresh",this.onRefresh)):t&&t.isScriptableValueNode?(this.deleteParameter(e),r[e]=t,r[e].events.addEventListener("refresh",this.onRefresh)):void 0===r[e]?(r[e]=Jx(t),r[e].events.addEventListener("refresh",this.onRefresh)):r[e].value=t,this}getValue(){return this.getDefaultOutput().getValue()}deleteParameter(e){let t=this.parameters[e];return t&&(t.isScriptableNode&&(t=t.getDefaultOutput()),t.events.removeEventListener("refresh",this.onRefresh)),this}clearParameters(){for(const e of Object.keys(this.parameters))this.deleteParameter(e);return this.needsUpdate=!0,this}call(e,...t){const r=this.getObject()[e];if("function"==typeof r)return r(...t)}async callAsync(e,...t){const r=this.getObject()[e];if("function"==typeof r)return"AsyncFunction"===r.constructor.name?await r(...t):r(...t)}getNodeType(e){return this.getDefaultOutputNode().getNodeType(e)}refresh(e=null){null!==e?this.getOutput(e).refresh():this._refresh()}getObject(){if(this.needsUpdate&&this.dispose(),null!==this._object)return this._object;const e=new tT(this),t=rT.get("THREE"),r=rT.get("TSL"),s=this.getMethod(),i=[e,this._local,rT,()=>this.refresh(),(e,t)=>this.setOutput(e,t),t,r];this._object=s(...i);const n=this._object.layout;if(n&&(!1===n.cache&&this._local.clear(),this._output.outputType=n.outputType||null,Array.isArray(n.elements)))for(const e of n.elements){const t=e.id||e.name;e.inputType&&(void 0===this.getParameter(t)&&this.setParameter(t,null),this.getParameter(t).inputType=e.inputType),e.outputType&&(void 0===this.getOutput(t)&&this.setOutput(t,null),this.getOutput(t).outputType=e.outputType)}return this._object}deserialize(e){super.deserialize(e);for(const e in this.parameters){let t=this.parameters[e];t.isScriptableNode&&(t=t.getDefaultOutput()),t.events.addEventListener("refresh",this.onRefresh)}}getLayout(){return this.getObject().layout}getDefaultOutputNode(){const e=this.getDefaultOutput().value;return e&&e.isNode?e:pn()}getDefaultOutput(){return this._exec()._output}getMethod(){if(this.needsUpdate&&this.dispose(),null!==this._method)return this._method;const e=["layout","init","main","dispose"].join(", "),t="\nreturn { ...output, "+e+" };",r="var "+e+"; var output = {};\n"+this.codeNode.code+t;return this._method=new Function(...["parameters","local","global","refresh","setOutput","THREE","TSL"],r),this._method}dispose(){null!==this._method&&(this._object&&"function"==typeof this._object.dispose&&this._object.dispose(),this._method=null,this._object=null,this._source=null,this._value=null,this._needsOutputUpdate=!0,this._output.value=null,this._outputs={})}setup(){return this.getDefaultOutputNode()}getCacheKey(e){const t=[Ds(this.source),this.getDefaultOutputNode().getCacheKey(e)];for(const r in this.parameters)t.push(this.parameters[r].getCacheKey(e));return Us(t)}set needsUpdate(e){!0===e&&this.dispose()}get needsUpdate(){return this.source!==this._source}_exec(){return null===this.codeNode||(!0===this._needsOutputUpdate&&(this._value=this.call("main"),this._needsOutputUpdate=!1),this._output.value=this._value),this}_refresh(){this.needsUpdate=!0,this._exec(),this._output.refresh()}}const iT=tn(sT).setParameterLength(1,2);function nT(e){let t;const r=e.context.getViewZ;return void 0!==r&&(t=r(this)),(t||Ud.z).negate()}const aT=on(([e,t],r)=>{const s=nT(r);return uu(e,t,s)}),oT=on(([e],t)=>{const r=nT(t);return e.mul(e,r,r).negate().exp().oneMinus()}),uT=on(([e,t],r)=>{const s=nT(r),i=t.sub(Pd.y).max(0).toConst().mul(s).toConst();return e.mul(e,i,i).negate().exp().oneMinus()}),lT=on(([e,t])=>Rn(t.toFloat().mix(sa.rgb,e.toVec3()),sa.a));let dT=null,cT=null;class hT extends oi{static get type(){return"RangeNode"}constructor(e=pn(),t=pn()){super(),this.minNode=e,this.maxNode=t}getVectorLength(e){const t=this.getConstNode(this.minNode),r=this.getConstNode(this.maxNode),s=e.getTypeLength(Hs(t.value)),i=e.getTypeLength(Hs(r.value));return s>i?s:i}getNodeType(e){return e.object.count>1?e.getTypeFromLength(this.getVectorLength(e)):"float"}getConstNode(e){let t=null;if(e.traverse(e=>{!0===e.isConstNode&&(t=e)}),null===t)throw new Error('THREE.TSL: No "ConstNode" found in node graph.');return t}setup(e){const t=e.object;let r=null;if(t.count>1){const i=this.getConstNode(this.minNode),n=this.getConstNode(this.maxNode),a=i.value,o=n.value,u=e.getTypeLength(Hs(a)),d=e.getTypeLength(Hs(o));dT=dT||new s,cT=cT||new s,dT.setScalar(0),cT.setScalar(0),1===u?dT.setScalar(a):a.isColor?dT.set(a.r,a.g,a.b,1):dT.set(a.x,a.y,a.z||0,a.w||0),1===d?cT.setScalar(o):o.isColor?cT.set(o.r,o.g,o.b,1):cT.set(o.x,o.y,o.z||0,o.w||0);const c=4,h=c*t.count,p=new Float32Array(h);for(let e=0;enew gT(e,t),fT=mT("numWorkgroups","uvec3"),yT=mT("workgroupId","uvec3"),bT=mT("globalId","uvec3"),xT=mT("localId","uvec3"),TT=mT("subgroupSize","uint");class _T extends oi{constructor(e){super(),this.scope=e}generate(e){const{scope:t}=this,{renderer:r}=e;!0===r.backend.isWebGLBackend?e.addFlowCode(`\t// ${t}Barrier \n`):e.addLineFlowCode(`${t}Barrier()`,this)}}const vT=tn(_T);class NT extends ui{constructor(e,t){super(e,t),this.isWorkgroupInfoElementNode=!0}generate(e,t){let r;const s=e.context.assign;if(r=super.generate(e),!0!==s){const s=this.getNodeType(e);r=e.format(r,s,t)}return r}}class ST extends oi{constructor(e,t,r=0){super(t),this.bufferType=t,this.bufferCount=r,this.isWorkgroupInfoNode=!0,this.elementType=t,this.scope=e,this.name=""}setName(e){return this.name=e,this}label(e){return d('TSL: "label()" has been deprecated. Use "setName()" instead.'),this.setName(e)}setScope(e){return this.scope=e,this}getElementType(){return this.elementType}getInputType(){return`${this.scope}Array`}element(e){return new NT(this,e)}generate(e){const t=""!==this.name?this.name:`${this.scope}Array_${this.id}`;return e.getScopedArray(t,this.scope.toLowerCase(),this.bufferType,this.bufferCount)}}class RT extends oi{static get type(){return"AtomicFunctionNode"}constructor(e,t,r){super("uint"),this.method=e,this.pointerNode=t,this.valueNode=r,this.parents=!0}getInputType(e){return this.pointerNode.getNodeType(e)}getNodeType(e){return this.getInputType(e)}generate(e){const t=e.getNodeProperties(this),r=t.parents,s=this.method,i=this.getNodeType(e),n=this.getInputType(e),a=this.pointerNode,o=this.valueNode,u=[];u.push(`&${a.build(e,n)}`),null!==o&&u.push(o.build(e,n));const l=`${e.getMethod(s,i)}( ${u.join(", ")} )`;if(!(!!r&&(1===r.length&&!0===r[0].isStackNode)))return void 0===t.constNode&&(t.constNode=pl(l,i).toConst()),t.constNode.build(e);e.addLineFlowCode(l,this)}}RT.ATOMIC_LOAD="atomicLoad",RT.ATOMIC_STORE="atomicStore",RT.ATOMIC_ADD="atomicAdd",RT.ATOMIC_SUB="atomicSub",RT.ATOMIC_MAX="atomicMax",RT.ATOMIC_MIN="atomicMin",RT.ATOMIC_AND="atomicAnd",RT.ATOMIC_OR="atomicOr",RT.ATOMIC_XOR="atomicXor";const AT=tn(RT),ET=(e,t,r)=>AT(e,t,r).toStack();class wT extends di{static get type(){return"SubgroupFunctionNode"}constructor(e,t=null,r=null){super(),this.method=e,this.aNode=t,this.bNode=r}getInputType(e){const t=this.aNode?this.aNode.getNodeType(e):null,r=this.bNode?this.bNode.getNodeType(e):null;return(e.isMatrix(t)?0:e.getTypeLength(t))>(e.isMatrix(r)?0:e.getTypeLength(r))?t:r}getNodeType(e){const t=this.method;return t===wT.SUBGROUP_ELECT?"bool":t===wT.SUBGROUP_BALLOT?"uvec4":this.getInputType(e)}generate(e,t){const r=this.method,s=this.getNodeType(e),i=this.getInputType(e),n=this.aNode,a=this.bNode,o=[];if(r===wT.SUBGROUP_BROADCAST||r===wT.SUBGROUP_SHUFFLE||r===wT.QUAD_BROADCAST){const t=a.getNodeType(e);o.push(n.build(e,s),a.build(e,"float"===t?"int":s))}else r===wT.SUBGROUP_SHUFFLE_XOR||r===wT.SUBGROUP_SHUFFLE_DOWN||r===wT.SUBGROUP_SHUFFLE_UP?o.push(n.build(e,s),a.build(e,"uint")):(null!==n&&o.push(n.build(e,i)),null!==a&&o.push(a.build(e,i)));const u=0===o.length?"()":`( ${o.join(", ")} )`;return e.format(`${e.getMethod(r,s)}${u}`,s,t)}serialize(e){super.serialize(e),e.method=this.method}deserialize(e){super.deserialize(e),this.method=e.method}}wT.SUBGROUP_ELECT="subgroupElect",wT.SUBGROUP_BALLOT="subgroupBallot",wT.SUBGROUP_ADD="subgroupAdd",wT.SUBGROUP_INCLUSIVE_ADD="subgroupInclusiveAdd",wT.SUBGROUP_EXCLUSIVE_AND="subgroupExclusiveAdd",wT.SUBGROUP_MUL="subgroupMul",wT.SUBGROUP_INCLUSIVE_MUL="subgroupInclusiveMul",wT.SUBGROUP_EXCLUSIVE_MUL="subgroupExclusiveMul",wT.SUBGROUP_AND="subgroupAnd",wT.SUBGROUP_OR="subgroupOr",wT.SUBGROUP_XOR="subgroupXor",wT.SUBGROUP_MIN="subgroupMin",wT.SUBGROUP_MAX="subgroupMax",wT.SUBGROUP_ALL="subgroupAll",wT.SUBGROUP_ANY="subgroupAny",wT.SUBGROUP_BROADCAST_FIRST="subgroupBroadcastFirst",wT.QUAD_SWAP_X="quadSwapX",wT.QUAD_SWAP_Y="quadSwapY",wT.QUAD_SWAP_DIAGONAL="quadSwapDiagonal",wT.SUBGROUP_BROADCAST="subgroupBroadcast",wT.SUBGROUP_SHUFFLE="subgroupShuffle",wT.SUBGROUP_SHUFFLE_XOR="subgroupShuffleXor",wT.SUBGROUP_SHUFFLE_UP="subgroupShuffleUp",wT.SUBGROUP_SHUFFLE_DOWN="subgroupShuffleDown",wT.QUAD_BROADCAST="quadBroadcast";const CT=sn(wT,wT.SUBGROUP_ELECT).setParameterLength(0),MT=sn(wT,wT.SUBGROUP_BALLOT).setParameterLength(1),BT=sn(wT,wT.SUBGROUP_ADD).setParameterLength(1),FT=sn(wT,wT.SUBGROUP_INCLUSIVE_ADD).setParameterLength(1),LT=sn(wT,wT.SUBGROUP_EXCLUSIVE_AND).setParameterLength(1),PT=sn(wT,wT.SUBGROUP_MUL).setParameterLength(1),DT=sn(wT,wT.SUBGROUP_INCLUSIVE_MUL).setParameterLength(1),UT=sn(wT,wT.SUBGROUP_EXCLUSIVE_MUL).setParameterLength(1),IT=sn(wT,wT.SUBGROUP_AND).setParameterLength(1),OT=sn(wT,wT.SUBGROUP_OR).setParameterLength(1),VT=sn(wT,wT.SUBGROUP_XOR).setParameterLength(1),kT=sn(wT,wT.SUBGROUP_MIN).setParameterLength(1),GT=sn(wT,wT.SUBGROUP_MAX).setParameterLength(1),zT=sn(wT,wT.SUBGROUP_ALL).setParameterLength(0),$T=sn(wT,wT.SUBGROUP_ANY).setParameterLength(0),WT=sn(wT,wT.SUBGROUP_BROADCAST_FIRST).setParameterLength(2),HT=sn(wT,wT.QUAD_SWAP_X).setParameterLength(1),qT=sn(wT,wT.QUAD_SWAP_Y).setParameterLength(1),jT=sn(wT,wT.QUAD_SWAP_DIAGONAL).setParameterLength(1),XT=sn(wT,wT.SUBGROUP_BROADCAST).setParameterLength(2),KT=sn(wT,wT.SUBGROUP_SHUFFLE).setParameterLength(2),YT=sn(wT,wT.SUBGROUP_SHUFFLE_XOR).setParameterLength(2),QT=sn(wT,wT.SUBGROUP_SHUFFLE_UP).setParameterLength(2),ZT=sn(wT,wT.SUBGROUP_SHUFFLE_DOWN).setParameterLength(2),JT=sn(wT,wT.QUAD_BROADCAST).setParameterLength(1);let e_;function t_(e){e_=e_||new WeakMap;let t=e_.get(e);return void 0===t&&e_.set(e,t={}),t}function r_(e){const t=t_(e);return t.shadowMatrix||(t.shadowMatrix=Ta("mat4").setGroup(ya).onRenderUpdate(t=>(!0===e.castShadow&&!1!==t.renderer.shadowMap.enabled||(e.shadow.camera.coordinateSystem!==t.camera.coordinateSystem&&(e.shadow.camera.coordinateSystem=t.camera.coordinateSystem,e.shadow.camera.updateProjectionMatrix()),e.shadow.updateMatrices(e)),e.shadow.matrix)))}function s_(e,t=Pd){const r=r_(e).mul(t);return r.xyz.div(r.w)}function i_(e){const t=t_(e);return t.position||(t.position=Ta(new r).setGroup(ya).onRenderUpdate((t,r)=>r.value.setFromMatrixPosition(e.matrixWorld)))}function n_(e){const t=t_(e);return t.targetPosition||(t.targetPosition=Ta(new r).setGroup(ya).onRenderUpdate((t,r)=>r.value.setFromMatrixPosition(e.target.matrixWorld)))}function a_(e){const t=t_(e);return t.viewPosition||(t.viewPosition=Ta(new r).setGroup(ya).onRenderUpdate(({camera:t},s)=>{s.value=s.value||new r,s.value.setFromMatrixPosition(e.matrixWorld),s.value.applyMatrix4(t.matrixWorldInverse)}))}const o_=e=>id.transformDirection(i_(e).sub(n_(e))),u_=(e,t)=>{for(const r of t)if(r.isAnalyticLightNode&&r.light.id===e)return r;return null},l_=new WeakMap,d_=[];class c_ extends oi{static get type(){return"LightsNode"}constructor(){super("vec3"),this.totalDiffuseNode=Dn("vec3","totalDiffuse"),this.totalSpecularNode=Dn("vec3","totalSpecular"),this.outgoingLightNode=Dn("vec3","outgoingLight"),this._lights=[],this._lightNodes=null,this._lightNodesHash=null,this.global=!0}customCacheKey(){const e=this._lights;for(let t=0;te.sort((e,t)=>e.id-t.id))(this._lights),i=e.renderer.library;for(const e of s)if(e.isNode)t.push(Qi(e));else{let s=null;if(null!==r&&(s=u_(e.id,r)),null===s){const r=i.getLightNodeClass(e.constructor);if(null===r){d(`LightsNode.setupNodeLights: Light node not found for ${e.constructor.name}`);continue}let s=null;l_.has(e)?s=l_.get(e):(s=new r(e),l_.set(e,s)),t.push(s)}}this._lightNodes=t}setupDirectLight(e,t,r){const{lightingModel:s,reflectedLight:i}=e.context;s.direct({...r,lightNode:t,reflectedLight:i},e)}setupDirectRectAreaLight(e,t,r){const{lightingModel:s,reflectedLight:i}=e.context;s.directRectArea({...r,lightNode:t,reflectedLight:i},e)}setupLights(e,t){for(const r of t)r.build(e)}getLightNodes(e){return null===this._lightNodes&&this.setupLightsNode(e),this._lightNodes}setup(e){const t=e.lightsNode;e.lightsNode=this;let r=this.outgoingLightNode;const s=e.context,i=s.lightingModel,n=e.getNodeProperties(this);if(i){const{totalDiffuseNode:t,totalSpecularNode:a}=this;s.outgoingLight=r;const o=e.addStack();n.nodes=o.nodes,i.start(e);const{backdrop:u,backdropAlpha:l}=s,{directDiffuse:d,directSpecular:c,indirectDiffuse:h,indirectSpecular:p}=s.reflectedLight;let g=d.add(h);null!==u&&(g=_n(null!==l?l.mix(g,u):u)),t.assign(g),a.assign(c.add(p)),r.assign(t.add(a)),i.finish(e),r=r.bypass(e.removeStack())}else n.nodes=[];return e.lightsNode=t,r}setLights(e){return this._lights=e,this._lightNodes=null,this._lightNodesHash=null,this}getLights(){return this._lights}get hasLights(){return this._lights.length>0}}class h_ extends oi{static get type(){return"ShadowBaseNode"}constructor(e){super(),this.light=e,this.updateBeforeType=Zs.RENDER,this.isShadowBaseNode=!0}setupShadowPosition({context:e,material:t}){p_.assign(t.receivedShadowPositionNode||e.shadowPositionWorld||Pd)}}const p_=Dn("vec3","shadowPositionWorld");function g_(t,r={}){return r.toneMapping=t.toneMapping,r.toneMappingExposure=t.toneMappingExposure,r.outputColorSpace=t.outputColorSpace,r.renderTarget=t.getRenderTarget(),r.activeCubeFace=t.getActiveCubeFace(),r.activeMipmapLevel=t.getActiveMipmapLevel(),r.renderObjectFunction=t.getRenderObjectFunction(),r.pixelRatio=t.getPixelRatio(),r.mrt=t.getMRT(),r.clearColor=t.getClearColor(r.clearColor||new e),r.clearAlpha=t.getClearAlpha(),r.autoClear=t.autoClear,r.scissorTest=t.getScissorTest(),r}function m_(e,t){return t=g_(e,t),e.setMRT(null),e.setRenderObjectFunction(null),e.setClearColor(0,1),e.autoClear=!0,t}function f_(e,t){e.toneMapping=t.toneMapping,e.toneMappingExposure=t.toneMappingExposure,e.outputColorSpace=t.outputColorSpace,e.setRenderTarget(t.renderTarget,t.activeCubeFace,t.activeMipmapLevel),e.setRenderObjectFunction(t.renderObjectFunction),e.setPixelRatio(t.pixelRatio),e.setMRT(t.mrt),e.setClearColor(t.clearColor,t.clearAlpha),e.autoClear=t.autoClear,e.setScissorTest(t.scissorTest)}function y_(e,t={}){return t.background=e.background,t.backgroundNode=e.backgroundNode,t.overrideMaterial=e.overrideMaterial,t}function b_(e,t){return t=y_(e,t),e.background=null,e.backgroundNode=null,e.overrideMaterial=null,t}function x_(e,t){e.background=t.background,e.backgroundNode=t.backgroundNode,e.overrideMaterial=t.overrideMaterial}function T_(e,t,r){return r=b_(t,r=m_(e,r))}function __(e,t,r){f_(e,r),x_(t,r)}var v_=Object.freeze({__proto__:null,resetRendererAndSceneState:T_,resetRendererState:m_,resetSceneState:b_,restoreRendererAndSceneState:__,restoreRendererState:f_,restoreSceneState:x_,saveRendererAndSceneState:function(e,t,r={}){return r=y_(t,r=g_(e,r))},saveRendererState:g_,saveSceneState:y_});const N_=new WeakMap,S_=on(({depthTexture:e,shadowCoord:t,depthLayer:r})=>{let s=Fl(e,t.xy).setName("t_basic");return e.isArrayTexture&&(s=s.depth(r)),s.compare(t.z)}),R_=on(({depthTexture:e,shadowCoord:t,shadow:r,depthLayer:s})=>{const i=(t,r)=>{let i=Fl(e,t);return e.isArrayTexture&&(i=i.depth(s)),i.compare(r)},n=fc("mapSize","vec2",r).setGroup(ya),a=fc("radius","float",r).setGroup(ya),o=yn(1).div(n),u=a.mul(o.x),l=Qb(jl.xy).mul(6.28318530718);return Ca(i(t.xy.add(Zb(0,5,l).mul(u)),t.z),i(t.xy.add(Zb(1,5,l).mul(u)),t.z),i(t.xy.add(Zb(2,5,l).mul(u)),t.z),i(t.xy.add(Zb(3,5,l).mul(u)),t.z),i(t.xy.add(Zb(4,5,l).mul(u)),t.z)).mul(.2)}),A_=on(({depthTexture:e,shadowCoord:t,shadow:r,depthLayer:s})=>{const i=(t,r)=>{let i=Fl(e,t);return e.isArrayTexture&&(i=i.depth(s)),i.compare(r)},n=fc("mapSize","vec2",r).setGroup(ya),a=yn(1).div(n),o=a.x,u=a.y,l=t.xy,d=vo(l.mul(n).add(.5));return l.subAssign(d.mul(a)),Ca(i(l,t.z),i(l.add(yn(o,0)),t.z),i(l.add(yn(0,u)),t.z),i(l.add(a),t.z),iu(i(l.add(yn(o.negate(),0)),t.z),i(l.add(yn(o.mul(2),0)),t.z),d.x),iu(i(l.add(yn(o.negate(),u)),t.z),i(l.add(yn(o.mul(2),u)),t.z),d.x),iu(i(l.add(yn(0,u.negate())),t.z),i(l.add(yn(0,u.mul(2))),t.z),d.y),iu(i(l.add(yn(o,u.negate())),t.z),i(l.add(yn(o,u.mul(2))),t.z),d.y),iu(iu(i(l.add(yn(o.negate(),u.negate())),t.z),i(l.add(yn(o.mul(2),u.negate())),t.z),d.x),iu(i(l.add(yn(o.negate(),u.mul(2))),t.z),i(l.add(yn(o.mul(2),u.mul(2))),t.z),d.x),d.y)).mul(1/9)}),E_=on(({depthTexture:e,shadowCoord:t,depthLayer:r})=>{let s=Fl(e).sample(t.xy);e.isArrayTexture&&(s=s.depth(r)),s=s.rg;const i=s.x,n=Wo(1e-7,s.y.mul(s.y)),a=Ho(t.z,i),o=pn(1).toVar();return dn(a.notEqual(1),()=>{const e=t.z.sub(i);let r=n.div(n.add(e.mul(e)));r=nu(Ma(r,.3).div(.65)),o.assign(Wo(a,r))}),o}),w_=e=>{let t=N_.get(e);return void 0===t&&(t=new Qp,t.colorNode=Rn(0,0,0,1),t.isShadowPassMaterial=!0,t.name="ShadowMaterial",t.blending=ee,t.fog=!1,N_.set(e,t)),t},C_=e=>{const t=N_.get(e);void 0!==t&&(t.dispose(),N_.delete(e))},M_=new Yf,B_=[],F_=(e,t,r,s)=>{B_[0]=e,B_[1]=t;let i=M_.get(B_);return void 0!==i&&i.shadowType===r&&i.useVelocity===s||(i=(i,n,a,o,u,l,...d)=>{(!0===i.castShadow||i.receiveShadow&&r===Qe)&&(s&&(js(i).useVelocity=!0),i.onBeforeShadow(e,i,a,t.camera,o,n.overrideMaterial,l),e.renderObject(i,n,a,o,u,l,...d),i.onAfterShadow(e,i,a,t.camera,o,n.overrideMaterial,l))},i.shadowType=r,i.useVelocity=s,M_.set(B_,i)),B_[0]=null,B_[1]=null,i},L_=on(({samples:e,radius:t,size:r,shadowPass:s,depthLayer:i})=>{const n=pn(0).toVar("meanVertical"),a=pn(0).toVar("squareMeanVertical"),o=e.lessThanEqual(pn(1)).select(pn(0),pn(2).div(e.sub(1))),u=e.lessThanEqual(pn(1)).select(pn(0),pn(-1));up({start:gn(0),end:gn(e),type:"int",condition:"<"},({i:e})=>{const l=u.add(pn(e).mul(o));let d=s.sample(Ca(jl.xy,yn(0,l).mul(t)).div(r));s.value.isArrayTexture&&(d=d.depth(i)),d=d.x,n.addAssign(d),a.addAssign(d.mul(d))}),n.divAssign(e),a.divAssign(e);const l=yo(a.sub(n.mul(n)).max(0));return yn(n,l)}),P_=on(({samples:e,radius:t,size:r,shadowPass:s,depthLayer:i})=>{const n=pn(0).toVar("meanHorizontal"),a=pn(0).toVar("squareMeanHorizontal"),o=e.lessThanEqual(pn(1)).select(pn(0),pn(2).div(e.sub(1))),u=e.lessThanEqual(pn(1)).select(pn(0),pn(-1));up({start:gn(0),end:gn(e),type:"int",condition:"<"},({i:e})=>{const l=u.add(pn(e).mul(o));let d=s.sample(Ca(jl.xy,yn(l,0).mul(t)).div(r));s.value.isArrayTexture&&(d=d.depth(i)),n.addAssign(d.x),a.addAssign(Ca(d.y.mul(d.y),d.x.mul(d.x)))}),n.divAssign(e),a.divAssign(e);const l=yo(a.sub(n.mul(n)).max(0));return yn(n,l)}),D_=[S_,R_,A_,E_];let U_;const I_=new Wb;class O_ extends h_{static get type(){return"ShadowNode"}constructor(e,t=null){super(e),this.shadow=t||e.shadow,this.shadowMap=null,this.vsmShadowMapVertical=null,this.vsmShadowMapHorizontal=null,this.vsmMaterialVertical=null,this.vsmMaterialHorizontal=null,this._node=null,this._currentShadowType=null,this._cameraFrameId=new WeakMap,this.isShadowNode=!0,this.depthLayer=0}setupShadowFilter(e,{filterFn:t,depthTexture:r,shadowCoord:s,shadow:i,depthLayer:n}){const a=s.x.greaterThanEqual(0).and(s.x.lessThanEqual(1)).and(s.y.greaterThanEqual(0)).and(s.y.lessThanEqual(1)).and(s.z.lessThanEqual(1)),o=t({depthTexture:r,shadowCoord:s,shadow:i,depthLayer:n});return a.select(o,pn(1))}setupShadowCoord(e,t){const{shadow:r}=this,{renderer:s}=e,i=r.biasNode||fc("bias","float",r).setGroup(ya);let n,a=t;if(r.camera.isOrthographicCamera||!0!==s.logarithmicDepthBuffer)a=a.xyz.div(a.w),n=a.z,s.coordinateSystem===h&&(n=n.mul(2).sub(1));else{const e=a.w;a=a.xy.div(e);const t=fc("near","float",r.camera).setGroup(ya),s=fc("far","float",r.camera).setGroup(ya);n=Lp(e.negate(),t,s)}return a=_n(a.x,a.y.oneMinus(),n.add(i)),a}getShadowFilterFn(e){return D_[e]}setupRenderTarget(e,t){const r=new Y(e.mapSize.width,e.mapSize.height);r.name="ShadowDepthTexture",r.compareFunction=Ze;const s=t.createRenderTarget(e.mapSize.width,e.mapSize.height);return s.texture.name="ShadowMap",s.texture.type=e.mapType,s.depthTexture=r,{shadowMap:s,depthTexture:r}}setupShadow(e){const{renderer:t,camera:r}=e,{light:s,shadow:i}=this,{depthTexture:n,shadowMap:a}=this.setupRenderTarget(i,e),o=t.shadowMap.type;if(o===Je||o===et?(n.minFilter=oe,n.magFilter=oe):(n.minFilter=w,n.magFilter=w),i.camera.coordinateSystem=r.coordinateSystem,i.camera.updateProjectionMatrix(),o===Qe&&!0!==i.isPointLightShadow){n.compareFunction=null,a.depth>1?(a._vsmShadowMapVertical||(a._vsmShadowMapVertical=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depth:a.depth,depthBuffer:!1}),a._vsmShadowMapVertical.texture.name="VSMVertical"),this.vsmShadowMapVertical=a._vsmShadowMapVertical,a._vsmShadowMapHorizontal||(a._vsmShadowMapHorizontal=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depth:a.depth,depthBuffer:!1}),a._vsmShadowMapHorizontal.texture.name="VSMHorizontal"),this.vsmShadowMapHorizontal=a._vsmShadowMapHorizontal):(this.vsmShadowMapVertical=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depthBuffer:!1}),this.vsmShadowMapHorizontal=e.createRenderTarget(i.mapSize.width,i.mapSize.height,{format:G,type:be,depthBuffer:!1}));let t=Fl(n);n.isArrayTexture&&(t=t.depth(this.depthLayer));let r=Fl(this.vsmShadowMapVertical.texture);n.isArrayTexture&&(r=r.depth(this.depthLayer));const s=fc("blurSamples","float",i).setGroup(ya),o=fc("radius","float",i).setGroup(ya),u=fc("mapSize","vec2",i).setGroup(ya);let l=this.vsmMaterialVertical||(this.vsmMaterialVertical=new Qp);l.fragmentNode=L_({samples:s,radius:o,size:u,shadowPass:t,depthLayer:this.depthLayer}).context(e.getSharedContext()),l.name="VSMVertical",l=this.vsmMaterialHorizontal||(this.vsmMaterialHorizontal=new Qp),l.fragmentNode=P_({samples:s,radius:o,size:u,shadowPass:r,depthLayer:this.depthLayer}).context(e.getSharedContext()),l.name="VSMHorizontal"}const u=fc("intensity","float",i).setGroup(ya),l=fc("normalBias","float",i).setGroup(ya),d=r_(s).mul(p_.add(Xd.mul(l))),c=this.setupShadowCoord(e,d),h=i.filterNode||this.getShadowFilterFn(t.shadowMap.type)||null;if(null===h)throw new Error("THREE.WebGPURenderer: Shadow map type not supported yet.");const p=o===Qe&&!0!==i.isPointLightShadow?this.vsmShadowMapHorizontal.texture:n,g=this.setupShadowFilter(e,{filterFn:h,shadowTexture:a.texture,depthTexture:p,shadowCoord:c,shadow:i,depthLayer:this.depthLayer});let m,f;!0===t.shadowMap.transmitted&&(a.texture.isCubeTexture?m=pc(a.texture,c.xyz):(m=Fl(a.texture,c),n.isArrayTexture&&(m=m.depth(this.depthLayer)))),f=m?iu(1,g.rgb.mix(m,1),u.mul(m.a)).toVar():iu(1,g,u).toVar(),this.shadowMap=a,this.shadow.map=a;const y=`${this.light.type} Shadow [ ${this.light.name||"ID: "+this.light.id} ]`;return m&&f.toInspector(`${y} / Color`,()=>this.shadowMap.texture.isCubeTexture?pc(this.shadowMap.texture):Fl(this.shadowMap.texture)),f.toInspector(`${y} / Depth`,()=>this.shadowMap.texture.isCubeTexture?pc(this.shadowMap.texture).r.oneMinus():Ll(this.shadowMap.depthTexture,Sl().mul(Al(Fl(this.shadowMap.depthTexture)))).r.oneMinus())}setup(e){if(!1!==e.renderer.shadowMap.enabled)return on(()=>{const t=e.renderer.shadowMap.type;this._currentShadowType!==t&&(this._reset(),this._node=null);let r=this._node;return this.setupShadowPosition(e),null===r&&(this._node=r=this.setupShadow(e),this._currentShadowType=t),e.material.receivedShadowNode&&(r=e.material.receivedShadowNode(r)),r})()}renderShadow(e){const{shadow:t,shadowMap:r,light:s}=this,{renderer:i,scene:n}=e;t.updateMatrices(s),r.setSize(t.mapSize.width,t.mapSize.height,r.depth);const a=n.name;n.name=`Shadow Map [ ${s.name||"ID: "+s.id} ]`,i.render(n,t.camera),n.name=a}updateShadow(e){const{shadowMap:t,light:r,shadow:s}=this,{renderer:i,scene:n,camera:a}=e,o=i.shadowMap.type,u=t.depthTexture.version;this._depthVersionCached=u;const l=s.camera.layers.mask;4294967294&s.camera.layers.mask||(s.camera.layers.mask=a.layers.mask);const d=i.getRenderObjectFunction(),c=i.getMRT(),h=!!c&&c.has("velocity");U_=T_(i,n,U_),n.overrideMaterial=w_(r),i.setRenderObjectFunction(F_(i,s,o,h)),i.setClearColor(0,0),i.setRenderTarget(t),this.renderShadow(e),i.setRenderObjectFunction(d),o===Qe&&!0!==s.isPointLightShadow&&this.vsmPass(i),s.camera.layers.mask=l,__(i,n,U_)}vsmPass(e){const{shadow:t}=this,r=this.shadowMap.depth;this.vsmShadowMapVertical.setSize(t.mapSize.width,t.mapSize.height,r),this.vsmShadowMapHorizontal.setSize(t.mapSize.width,t.mapSize.height,r),e.setRenderTarget(this.vsmShadowMapVertical),I_.material=this.vsmMaterialVertical,I_.render(e),e.setRenderTarget(this.vsmShadowMapHorizontal),I_.material=this.vsmMaterialHorizontal,I_.render(e)}dispose(){this._reset(),super.dispose()}_reset(){this._currentShadowType=null,C_(this.light),this.shadowMap&&(this.shadowMap.dispose(),this.shadowMap=null),null!==this.vsmShadowMapVertical&&(this.vsmShadowMapVertical.dispose(),this.vsmShadowMapVertical=null,this.vsmMaterialVertical.dispose(),this.vsmMaterialVertical=null),null!==this.vsmShadowMapHorizontal&&(this.vsmShadowMapHorizontal.dispose(),this.vsmShadowMapHorizontal=null,this.vsmMaterialHorizontal.dispose(),this.vsmMaterialHorizontal=null)}updateBefore(e){const{shadow:t}=this;let r=t.needsUpdate||t.autoUpdate;r&&(this._cameraFrameId[e.camera]===e.frameId&&(r=!1),this._cameraFrameId[e.camera]=e.frameId),r&&(this.updateShadow(e),this.shadowMap.depthTexture.version===this._depthVersionCached&&(t.needsUpdate=!1))}}const V_=(e,t)=>new O_(e,t),k_=new e,G_=new a,z_=new r,$_=new r,W_=[new r(1,0,0),new r(-1,0,0),new r(0,-1,0),new r(0,1,0),new r(0,0,1),new r(0,0,-1)],H_=[new r(0,-1,0),new r(0,-1,0),new r(0,0,-1),new r(0,0,1),new r(0,-1,0),new r(0,-1,0)],q_=[new r(1,0,0),new r(-1,0,0),new r(0,1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1)],j_=[new r(0,-1,0),new r(0,-1,0),new r(0,0,1),new r(0,0,-1),new r(0,-1,0),new r(0,-1,0)],X_=on(({depthTexture:e,bd3D:t,dp:r})=>pc(e,t).compare(r)),K_=on(({depthTexture:e,bd3D:t,dp:r,shadow:s})=>{const i=fc("radius","float",s).setGroup(ya),n=fc("mapSize","vec2",s).setGroup(ya),a=i.div(n.x),o=Co(t),u=_o(Yo(t,o.x.greaterThan(o.z).select(_n(0,1,0),_n(1,0,0)))),l=Yo(t,u),d=Qb(jl.xy).mul(6.28318530718),c=Zb(0,5,d),h=Zb(1,5,d),p=Zb(2,5,d),g=Zb(3,5,d),m=Zb(4,5,d);return pc(e,t.add(u.mul(c.x).add(l.mul(c.y)).mul(a))).compare(r).add(pc(e,t.add(u.mul(h.x).add(l.mul(h.y)).mul(a))).compare(r)).add(pc(e,t.add(u.mul(p.x).add(l.mul(p.y)).mul(a))).compare(r)).add(pc(e,t.add(u.mul(g.x).add(l.mul(g.y)).mul(a))).compare(r)).add(pc(e,t.add(u.mul(m.x).add(l.mul(m.y)).mul(a))).compare(r)).mul(.2)}),Y_=on(({filterFn:e,depthTexture:t,shadowCoord:r,shadow:s})=>{const i=r.xyz.toConst(),n=i.abs().toConst(),a=n.x.max(n.y).max(n.z),o=Ta("float").setGroup(ya).onRenderUpdate(()=>s.camera.near),u=Ta("float").setGroup(ya).onRenderUpdate(()=>s.camera.far),l=fc("bias","float",s).setGroup(ya),d=pn(1).toVar();return dn(a.sub(u).lessThanEqual(0).and(a.sub(o).greaterThanEqual(0)),()=>{const r=Bp(a.negate(),o,u);r.addAssign(l);const n=i.normalize();d.assign(e({depthTexture:t,bd3D:n,dp:r,shadow:s}))}),d});class Q_ extends O_{static get type(){return"PointShadowNode"}constructor(e,t=null){super(e,t)}getShadowFilterFn(e){return e===tt?X_:K_}setupShadowCoord(e,t){return t}setupShadowFilter(e,{filterFn:t,depthTexture:r,shadowCoord:s,shadow:i}){return Y_({filterFn:t,depthTexture:r,shadowCoord:s,shadow:i})}setupRenderTarget(e,t){const r=new rt(e.mapSize.width);r.name="PointShadowDepthTexture",r.compareFunction=Ze;const s=t.createCubeRenderTarget(e.mapSize.width);return s.texture.name="PointShadowMap",s.depthTexture=r,{shadowMap:s,depthTexture:r}}renderShadow(e){const{shadow:t,shadowMap:r,light:s}=this,{renderer:i,scene:n}=e,a=t.camera,o=t.matrix,u=i.coordinateSystem===h,l=u?W_:q_,d=u?H_:j_;r.setSize(t.mapSize.width,t.mapSize.width);const c=i.autoClear,p=i.getClearColor(k_),g=i.getClearAlpha();i.autoClear=!1,i.setClearColor(t.clearColor,t.clearAlpha);for(let e=0;e<6;e++){i.setRenderTarget(r,e),i.clear();const u=s.distance||a.far;u!==a.far&&(a.far=u,a.updateProjectionMatrix()),z_.setFromMatrixPosition(s.matrixWorld),a.position.copy(z_),$_.copy(a.position),$_.add(l[e]),a.up.copy(d[e]),a.lookAt($_),a.updateMatrixWorld(),o.makeTranslation(-z_.x,-z_.y,-z_.z),G_.multiplyMatrices(a.projectionMatrix,a.matrixWorldInverse),t._frustum.setFromProjectionMatrix(G_,a.coordinateSystem,a.reversedDepth);const c=n.name;n.name=`Point Light Shadow [ ${s.name||"ID: "+s.id} ] - Face ${e+1}`,i.render(n,a),n.name=c}i.autoClear=c,i.setClearColor(p,g)}}const Z_=(e,t)=>new Q_(e,t);class J_ extends mp{static get type(){return"AnalyticLightNode"}constructor(t=null){super(),this.light=t,this.color=new e,this.colorNode=t&&t.colorNode||Ta(this.color).setGroup(ya),this.baseColorNode=null,this.shadowNode=null,this.shadowColorNode=null,this.isAnalyticLightNode=!0,this.updateType=Zs.FRAME,t&&t.shadow&&(this._shadowDisposeListener=()=>{this.disposeShadow()},t.addEventListener("dispose",this._shadowDisposeListener))}dispose(){this._shadowDisposeListener&&this.light.removeEventListener("dispose",this._shadowDisposeListener),super.dispose()}disposeShadow(){null!==this.shadowNode&&(this.shadowNode.dispose(),this.shadowNode=null),this.shadowColorNode=null,null!==this.baseColorNode&&(this.colorNode=this.baseColorNode,this.baseColorNode=null)}getHash(){return this.light.uuid}getLightVector(e){return a_(this.light).sub(e.context.positionView||Ud)}setupDirect(){}setupDirectRectArea(){}setupShadowNode(){return V_(this.light)}setupShadow(e){const{renderer:t}=e;if(!1===t.shadowMap.enabled)return;let r=this.shadowColorNode;if(null===r){const e=this.light.shadow.shadowNode;let t;t=void 0!==e?Qi(e):this.setupShadowNode(),this.shadowNode=t,this.shadowColorNode=r=this.colorNode.mul(t),this.baseColorNode=this.colorNode}e.context.getShadow&&(r=e.context.getShadow(this,e)),this.colorNode=r}setup(e){this.colorNode=this.baseColorNode||this.colorNode,this.light.castShadow?e.object.receiveShadow&&this.setupShadow(e):null!==this.shadowNode&&(this.shadowNode.dispose(),this.shadowNode=null,this.shadowColorNode=null);const t=this.setupDirect(e),r=this.setupDirectRectArea(e);t&&e.lightsNode.setupDirectLight(e,this,t),r&&e.lightsNode.setupDirectRectAreaLight(e,this,r)}update(){const{light:e}=this;this.color.copy(e.color).multiplyScalar(e.intensity)}}const ev=on(({lightDistance:e,cutoffDistance:t,decayExponent:r})=>{const s=e.pow(r).max(.01).reciprocal();return t.greaterThan(0).select(s.mul(e.div(t).pow4().oneMinus().clamp().pow2()),s)}),tv=({color:e,lightVector:t,cutoffDistance:r,decayExponent:s})=>{const i=t.normalize(),n=t.length(),a=ev({lightDistance:n,cutoffDistance:r,decayExponent:s});return{lightDirection:i,lightColor:e.mul(a)}};class rv extends J_{static get type(){return"PointLightNode"}constructor(e=null){super(e),this.cutoffDistanceNode=Ta(0).setGroup(ya),this.decayExponentNode=Ta(2).setGroup(ya)}update(e){const{light:t}=this;super.update(e),this.cutoffDistanceNode.value=t.distance,this.decayExponentNode.value=t.decay}setupShadowNode(){return Z_(this.light)}setupDirect(e){return tv({color:this.colorNode,lightVector:this.getLightVector(e),cutoffDistance:this.cutoffDistanceNode,decayExponent:this.decayExponentNode})}}const sv=on(([e=Sl()])=>{const t=e.mul(2),r=t.x.floor(),s=t.y.floor();return r.add(s).mod(2).sign()}),iv=on(([e=Sl()],{renderer:t,material:r})=>{const s=su(e.mul(2).sub(1));let i;if(r.alphaToCoverage&&t.currentSamples>0){const e=pn(s.fwidth()).toVar();i=uu(e.oneMinus(),e.add(1),s).oneMinus()}else i=yu(s.greaterThan(1),0,1);return i}),nv=on(([e,t,r])=>{const s=pn(r).toVar(),i=pn(t).toVar(),n=fn(e).toVar();return yu(n,i,s)}).setLayout({name:"mx_select",type:"float",inputs:[{name:"b",type:"bool"},{name:"t",type:"float"},{name:"f",type:"float"}]}),av=on(([e,t])=>{const r=fn(t).toVar(),s=pn(e).toVar();return yu(r,s.negate(),s)}).setLayout({name:"mx_negate_if",type:"float",inputs:[{name:"val",type:"float"},{name:"b",type:"bool"}]}),ov=on(([e])=>{const t=pn(e).toVar();return gn(xo(t))}).setLayout({name:"mx_floor",type:"int",inputs:[{name:"x",type:"float"}]}),uv=on(([e,t])=>{const r=pn(e).toVar();return t.assign(ov(r)),r.sub(pn(t))}),lv=mb([on(([e,t,r,s,i,n])=>{const a=pn(n).toVar(),o=pn(i).toVar(),u=pn(s).toVar(),l=pn(r).toVar(),d=pn(t).toVar(),c=pn(e).toVar(),h=pn(Ma(1,o)).toVar();return Ma(1,a).mul(c.mul(h).add(d.mul(o))).add(a.mul(l.mul(h).add(u.mul(o))))}).setLayout({name:"mx_bilerp_0",type:"float",inputs:[{name:"v0",type:"float"},{name:"v1",type:"float"},{name:"v2",type:"float"},{name:"v3",type:"float"},{name:"s",type:"float"},{name:"t",type:"float"}]}),on(([e,t,r,s,i,n])=>{const a=pn(n).toVar(),o=pn(i).toVar(),u=_n(s).toVar(),l=_n(r).toVar(),d=_n(t).toVar(),c=_n(e).toVar(),h=pn(Ma(1,o)).toVar();return Ma(1,a).mul(c.mul(h).add(d.mul(o))).add(a.mul(l.mul(h).add(u.mul(o))))}).setLayout({name:"mx_bilerp_1",type:"vec3",inputs:[{name:"v0",type:"vec3"},{name:"v1",type:"vec3"},{name:"v2",type:"vec3"},{name:"v3",type:"vec3"},{name:"s",type:"float"},{name:"t",type:"float"}]})]),dv=mb([on(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=pn(d).toVar(),h=pn(l).toVar(),p=pn(u).toVar(),g=pn(o).toVar(),m=pn(a).toVar(),f=pn(n).toVar(),y=pn(i).toVar(),b=pn(s).toVar(),x=pn(r).toVar(),T=pn(t).toVar(),_=pn(e).toVar(),v=pn(Ma(1,p)).toVar(),N=pn(Ma(1,h)).toVar();return pn(Ma(1,c)).toVar().mul(N.mul(_.mul(v).add(T.mul(p))).add(h.mul(x.mul(v).add(b.mul(p))))).add(c.mul(N.mul(y.mul(v).add(f.mul(p))).add(h.mul(m.mul(v).add(g.mul(p))))))}).setLayout({name:"mx_trilerp_0",type:"float",inputs:[{name:"v0",type:"float"},{name:"v1",type:"float"},{name:"v2",type:"float"},{name:"v3",type:"float"},{name:"v4",type:"float"},{name:"v5",type:"float"},{name:"v6",type:"float"},{name:"v7",type:"float"},{name:"s",type:"float"},{name:"t",type:"float"},{name:"r",type:"float"}]}),on(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=pn(d).toVar(),h=pn(l).toVar(),p=pn(u).toVar(),g=_n(o).toVar(),m=_n(a).toVar(),f=_n(n).toVar(),y=_n(i).toVar(),b=_n(s).toVar(),x=_n(r).toVar(),T=_n(t).toVar(),_=_n(e).toVar(),v=pn(Ma(1,p)).toVar(),N=pn(Ma(1,h)).toVar();return pn(Ma(1,c)).toVar().mul(N.mul(_.mul(v).add(T.mul(p))).add(h.mul(x.mul(v).add(b.mul(p))))).add(c.mul(N.mul(y.mul(v).add(f.mul(p))).add(h.mul(m.mul(v).add(g.mul(p))))))}).setLayout({name:"mx_trilerp_1",type:"vec3",inputs:[{name:"v0",type:"vec3"},{name:"v1",type:"vec3"},{name:"v2",type:"vec3"},{name:"v3",type:"vec3"},{name:"v4",type:"vec3"},{name:"v5",type:"vec3"},{name:"v6",type:"vec3"},{name:"v7",type:"vec3"},{name:"s",type:"float"},{name:"t",type:"float"},{name:"r",type:"float"}]})]),cv=on(([e,t,r])=>{const s=pn(r).toVar(),i=pn(t).toVar(),n=mn(e).toVar(),a=mn(n.bitAnd(mn(7))).toVar(),o=pn(nv(a.lessThan(mn(4)),i,s)).toVar(),u=pn(Ba(2,nv(a.lessThan(mn(4)),s,i))).toVar();return av(o,fn(a.bitAnd(mn(1)))).add(av(u,fn(a.bitAnd(mn(2)))))}).setLayout({name:"mx_gradient_float_0",type:"float",inputs:[{name:"hash",type:"uint"},{name:"x",type:"float"},{name:"y",type:"float"}]}),hv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=pn(t).toVar(),o=mn(e).toVar(),u=mn(o.bitAnd(mn(15))).toVar(),l=pn(nv(u.lessThan(mn(8)),a,n)).toVar(),d=pn(nv(u.lessThan(mn(4)),n,nv(u.equal(mn(12)).or(u.equal(mn(14))),a,i))).toVar();return av(l,fn(u.bitAnd(mn(1)))).add(av(d,fn(u.bitAnd(mn(2)))))}).setLayout({name:"mx_gradient_float_1",type:"float",inputs:[{name:"hash",type:"uint"},{name:"x",type:"float"},{name:"y",type:"float"},{name:"z",type:"float"}]}),pv=mb([cv,hv]),gv=on(([e,t,r])=>{const s=pn(r).toVar(),i=pn(t).toVar(),n=Nn(e).toVar();return _n(pv(n.x,i,s),pv(n.y,i,s),pv(n.z,i,s))}).setLayout({name:"mx_gradient_vec3_0",type:"vec3",inputs:[{name:"hash",type:"uvec3"},{name:"x",type:"float"},{name:"y",type:"float"}]}),mv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=pn(t).toVar(),o=Nn(e).toVar();return _n(pv(o.x,a,n,i),pv(o.y,a,n,i),pv(o.z,a,n,i))}).setLayout({name:"mx_gradient_vec3_1",type:"vec3",inputs:[{name:"hash",type:"uvec3"},{name:"x",type:"float"},{name:"y",type:"float"},{name:"z",type:"float"}]}),fv=mb([gv,mv]),yv=on(([e])=>{const t=pn(e).toVar();return Ba(.6616,t)}).setLayout({name:"mx_gradient_scale2d_0",type:"float",inputs:[{name:"v",type:"float"}]}),bv=on(([e])=>{const t=pn(e).toVar();return Ba(.982,t)}).setLayout({name:"mx_gradient_scale3d_0",type:"float",inputs:[{name:"v",type:"float"}]}),xv=mb([yv,on(([e])=>{const t=_n(e).toVar();return Ba(.6616,t)}).setLayout({name:"mx_gradient_scale2d_1",type:"vec3",inputs:[{name:"v",type:"vec3"}]})]),Tv=mb([bv,on(([e])=>{const t=_n(e).toVar();return Ba(.982,t)}).setLayout({name:"mx_gradient_scale3d_1",type:"vec3",inputs:[{name:"v",type:"vec3"}]})]),_v=on(([e,t])=>{const r=gn(t).toVar(),s=mn(e).toVar();return s.shiftLeft(r).bitOr(s.shiftRight(gn(32).sub(r)))}).setLayout({name:"mx_rotl32",type:"uint",inputs:[{name:"x",type:"uint"},{name:"k",type:"int"}]}),vv=on(([e,t,r])=>{e.subAssign(r),e.bitXorAssign(_v(r,gn(4))),r.addAssign(t),t.subAssign(e),t.bitXorAssign(_v(e,gn(6))),e.addAssign(r),r.subAssign(t),r.bitXorAssign(_v(t,gn(8))),t.addAssign(e),e.subAssign(r),e.bitXorAssign(_v(r,gn(16))),r.addAssign(t),t.subAssign(e),t.bitXorAssign(_v(e,gn(19))),e.addAssign(r),r.subAssign(t),r.bitXorAssign(_v(t,gn(4))),t.addAssign(e)}),Nv=on(([e,t,r])=>{const s=mn(r).toVar(),i=mn(t).toVar(),n=mn(e).toVar();return s.bitXorAssign(i),s.subAssign(_v(i,gn(14))),n.bitXorAssign(s),n.subAssign(_v(s,gn(11))),i.bitXorAssign(n),i.subAssign(_v(n,gn(25))),s.bitXorAssign(i),s.subAssign(_v(i,gn(16))),n.bitXorAssign(s),n.subAssign(_v(s,gn(4))),i.bitXorAssign(n),i.subAssign(_v(n,gn(14))),s.bitXorAssign(i),s.subAssign(_v(i,gn(24))),s}).setLayout({name:"mx_bjfinal",type:"uint",inputs:[{name:"a",type:"uint"},{name:"b",type:"uint"},{name:"c",type:"uint"}]}),Sv=on(([e])=>{const t=mn(e).toVar();return pn(t).div(pn(mn(gn(4294967295))))}).setLayout({name:"mx_bits_to_01",type:"float",inputs:[{name:"bits",type:"uint"}]}),Rv=on(([e])=>{const t=pn(e).toVar();return t.mul(t).mul(t).mul(t.mul(t.mul(6).sub(15)).add(10))}).setLayout({name:"mx_fade",type:"float",inputs:[{name:"t",type:"float"}]}),Av=mb([on(([e])=>{const t=gn(e).toVar(),r=mn(mn(1)).toVar(),s=mn(mn(gn(3735928559)).add(r.shiftLeft(mn(2))).add(mn(13))).toVar();return Nv(s.add(mn(t)),s,s)}).setLayout({name:"mx_hash_int_0",type:"uint",inputs:[{name:"x",type:"int"}]}),on(([e,t])=>{const r=gn(t).toVar(),s=gn(e).toVar(),i=mn(mn(2)).toVar(),n=mn().toVar(),a=mn().toVar(),o=mn().toVar();return n.assign(a.assign(o.assign(mn(gn(3735928559)).add(i.shiftLeft(mn(2))).add(mn(13))))),n.addAssign(mn(s)),a.addAssign(mn(r)),Nv(n,a,o)}).setLayout({name:"mx_hash_int_1",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"}]}),on(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=gn(e).toVar(),a=mn(mn(3)).toVar(),o=mn().toVar(),u=mn().toVar(),l=mn().toVar();return o.assign(u.assign(l.assign(mn(gn(3735928559)).add(a.shiftLeft(mn(2))).add(mn(13))))),o.addAssign(mn(n)),u.addAssign(mn(i)),l.addAssign(mn(s)),Nv(o,u,l)}).setLayout({name:"mx_hash_int_2",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"}]}),on(([e,t,r,s])=>{const i=gn(s).toVar(),n=gn(r).toVar(),a=gn(t).toVar(),o=gn(e).toVar(),u=mn(mn(4)).toVar(),l=mn().toVar(),d=mn().toVar(),c=mn().toVar();return l.assign(d.assign(c.assign(mn(gn(3735928559)).add(u.shiftLeft(mn(2))).add(mn(13))))),l.addAssign(mn(o)),d.addAssign(mn(a)),c.addAssign(mn(n)),vv(l,d,c),l.addAssign(mn(i)),Nv(l,d,c)}).setLayout({name:"mx_hash_int_3",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xx",type:"int"}]}),on(([e,t,r,s,i])=>{const n=gn(i).toVar(),a=gn(s).toVar(),o=gn(r).toVar(),u=gn(t).toVar(),l=gn(e).toVar(),d=mn(mn(5)).toVar(),c=mn().toVar(),h=mn().toVar(),p=mn().toVar();return c.assign(h.assign(p.assign(mn(gn(3735928559)).add(d.shiftLeft(mn(2))).add(mn(13))))),c.addAssign(mn(l)),h.addAssign(mn(u)),p.addAssign(mn(o)),vv(c,h,p),c.addAssign(mn(a)),h.addAssign(mn(n)),Nv(c,h,p)}).setLayout({name:"mx_hash_int_4",type:"uint",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xx",type:"int"},{name:"yy",type:"int"}]})]),Ev=mb([on(([e,t])=>{const r=gn(t).toVar(),s=gn(e).toVar(),i=mn(Av(s,r)).toVar(),n=Nn().toVar();return n.x.assign(i.bitAnd(gn(255))),n.y.assign(i.shiftRight(gn(8)).bitAnd(gn(255))),n.z.assign(i.shiftRight(gn(16)).bitAnd(gn(255))),n}).setLayout({name:"mx_hash_vec3_0",type:"uvec3",inputs:[{name:"x",type:"int"},{name:"y",type:"int"}]}),on(([e,t,r])=>{const s=gn(r).toVar(),i=gn(t).toVar(),n=gn(e).toVar(),a=mn(Av(n,i,s)).toVar(),o=Nn().toVar();return o.x.assign(a.bitAnd(gn(255))),o.y.assign(a.shiftRight(gn(8)).bitAnd(gn(255))),o.z.assign(a.shiftRight(gn(16)).bitAnd(gn(255))),o}).setLayout({name:"mx_hash_vec3_1",type:"uvec3",inputs:[{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"}]})]),wv=mb([on(([e])=>{const t=yn(e).toVar(),r=gn().toVar(),s=gn().toVar(),i=pn(uv(t.x,r)).toVar(),n=pn(uv(t.y,s)).toVar(),a=pn(Rv(i)).toVar(),o=pn(Rv(n)).toVar(),u=pn(lv(pv(Av(r,s),i,n),pv(Av(r.add(gn(1)),s),i.sub(1),n),pv(Av(r,s.add(gn(1))),i,n.sub(1)),pv(Av(r.add(gn(1)),s.add(gn(1))),i.sub(1),n.sub(1)),a,o)).toVar();return xv(u)}).setLayout({name:"mx_perlin_noise_float_0",type:"float",inputs:[{name:"p",type:"vec2"}]}),on(([e])=>{const t=_n(e).toVar(),r=gn().toVar(),s=gn().toVar(),i=gn().toVar(),n=pn(uv(t.x,r)).toVar(),a=pn(uv(t.y,s)).toVar(),o=pn(uv(t.z,i)).toVar(),u=pn(Rv(n)).toVar(),l=pn(Rv(a)).toVar(),d=pn(Rv(o)).toVar(),c=pn(dv(pv(Av(r,s,i),n,a,o),pv(Av(r.add(gn(1)),s,i),n.sub(1),a,o),pv(Av(r,s.add(gn(1)),i),n,a.sub(1),o),pv(Av(r.add(gn(1)),s.add(gn(1)),i),n.sub(1),a.sub(1),o),pv(Av(r,s,i.add(gn(1))),n,a,o.sub(1)),pv(Av(r.add(gn(1)),s,i.add(gn(1))),n.sub(1),a,o.sub(1)),pv(Av(r,s.add(gn(1)),i.add(gn(1))),n,a.sub(1),o.sub(1)),pv(Av(r.add(gn(1)),s.add(gn(1)),i.add(gn(1))),n.sub(1),a.sub(1),o.sub(1)),u,l,d)).toVar();return Tv(c)}).setLayout({name:"mx_perlin_noise_float_1",type:"float",inputs:[{name:"p",type:"vec3"}]})]),Cv=mb([on(([e])=>{const t=yn(e).toVar(),r=gn().toVar(),s=gn().toVar(),i=pn(uv(t.x,r)).toVar(),n=pn(uv(t.y,s)).toVar(),a=pn(Rv(i)).toVar(),o=pn(Rv(n)).toVar(),u=_n(lv(fv(Ev(r,s),i,n),fv(Ev(r.add(gn(1)),s),i.sub(1),n),fv(Ev(r,s.add(gn(1))),i,n.sub(1)),fv(Ev(r.add(gn(1)),s.add(gn(1))),i.sub(1),n.sub(1)),a,o)).toVar();return xv(u)}).setLayout({name:"mx_perlin_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"vec2"}]}),on(([e])=>{const t=_n(e).toVar(),r=gn().toVar(),s=gn().toVar(),i=gn().toVar(),n=pn(uv(t.x,r)).toVar(),a=pn(uv(t.y,s)).toVar(),o=pn(uv(t.z,i)).toVar(),u=pn(Rv(n)).toVar(),l=pn(Rv(a)).toVar(),d=pn(Rv(o)).toVar(),c=_n(dv(fv(Ev(r,s,i),n,a,o),fv(Ev(r.add(gn(1)),s,i),n.sub(1),a,o),fv(Ev(r,s.add(gn(1)),i),n,a.sub(1),o),fv(Ev(r.add(gn(1)),s.add(gn(1)),i),n.sub(1),a.sub(1),o),fv(Ev(r,s,i.add(gn(1))),n,a,o.sub(1)),fv(Ev(r.add(gn(1)),s,i.add(gn(1))),n.sub(1),a,o.sub(1)),fv(Ev(r,s.add(gn(1)),i.add(gn(1))),n,a.sub(1),o.sub(1)),fv(Ev(r.add(gn(1)),s.add(gn(1)),i.add(gn(1))),n.sub(1),a.sub(1),o.sub(1)),u,l,d)).toVar();return Tv(c)}).setLayout({name:"mx_perlin_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec3"}]})]),Mv=mb([on(([e])=>{const t=pn(e).toVar(),r=gn(ov(t)).toVar();return Sv(Av(r))}).setLayout({name:"mx_cell_noise_float_0",type:"float",inputs:[{name:"p",type:"float"}]}),on(([e])=>{const t=yn(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar();return Sv(Av(r,s))}).setLayout({name:"mx_cell_noise_float_1",type:"float",inputs:[{name:"p",type:"vec2"}]}),on(([e])=>{const t=_n(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar(),i=gn(ov(t.z)).toVar();return Sv(Av(r,s,i))}).setLayout({name:"mx_cell_noise_float_2",type:"float",inputs:[{name:"p",type:"vec3"}]}),on(([e])=>{const t=Rn(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar(),i=gn(ov(t.z)).toVar(),n=gn(ov(t.w)).toVar();return Sv(Av(r,s,i,n))}).setLayout({name:"mx_cell_noise_float_3",type:"float",inputs:[{name:"p",type:"vec4"}]})]),Bv=mb([on(([e])=>{const t=pn(e).toVar(),r=gn(ov(t)).toVar();return _n(Sv(Av(r,gn(0))),Sv(Av(r,gn(1))),Sv(Av(r,gn(2))))}).setLayout({name:"mx_cell_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"float"}]}),on(([e])=>{const t=yn(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar();return _n(Sv(Av(r,s,gn(0))),Sv(Av(r,s,gn(1))),Sv(Av(r,s,gn(2))))}).setLayout({name:"mx_cell_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec2"}]}),on(([e])=>{const t=_n(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar(),i=gn(ov(t.z)).toVar();return _n(Sv(Av(r,s,i,gn(0))),Sv(Av(r,s,i,gn(1))),Sv(Av(r,s,i,gn(2))))}).setLayout({name:"mx_cell_noise_vec3_2",type:"vec3",inputs:[{name:"p",type:"vec3"}]}),on(([e])=>{const t=Rn(e).toVar(),r=gn(ov(t.x)).toVar(),s=gn(ov(t.y)).toVar(),i=gn(ov(t.z)).toVar(),n=gn(ov(t.w)).toVar();return _n(Sv(Av(r,s,i,n,gn(0))),Sv(Av(r,s,i,n,gn(1))),Sv(Av(r,s,i,n,gn(2))))}).setLayout({name:"mx_cell_noise_vec3_3",type:"vec3",inputs:[{name:"p",type:"vec4"}]})]),Fv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=gn(t).toVar(),o=_n(e).toVar(),u=pn(0).toVar(),l=pn(1).toVar();return up(a,()=>{u.addAssign(l.mul(wv(o))),l.mulAssign(i),o.mulAssign(n)}),u}).setLayout({name:"mx_fractal_noise_float",type:"float",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Lv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=gn(t).toVar(),o=_n(e).toVar(),u=_n(0).toVar(),l=pn(1).toVar();return up(a,()=>{u.addAssign(l.mul(Cv(o))),l.mulAssign(i),o.mulAssign(n)}),u}).setLayout({name:"mx_fractal_noise_vec3",type:"vec3",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Pv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=gn(t).toVar(),o=_n(e).toVar();return yn(Fv(o,a,n,i),Fv(o.add(_n(gn(19),gn(193),gn(17))),a,n,i))}).setLayout({name:"mx_fractal_noise_vec2",type:"vec2",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Dv=on(([e,t,r,s])=>{const i=pn(s).toVar(),n=pn(r).toVar(),a=gn(t).toVar(),o=_n(e).toVar(),u=_n(Lv(o,a,n,i)).toVar(),l=pn(Fv(o.add(_n(gn(19),gn(193),gn(17))),a,n,i)).toVar();return Rn(u,l)}).setLayout({name:"mx_fractal_noise_vec4",type:"vec4",inputs:[{name:"p",type:"vec3"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Uv=mb([on(([e,t,r,s,i,n,a])=>{const o=gn(a).toVar(),u=pn(n).toVar(),l=gn(i).toVar(),d=gn(s).toVar(),c=gn(r).toVar(),h=gn(t).toVar(),p=yn(e).toVar(),g=_n(Bv(yn(h.add(d),c.add(l)))).toVar(),m=yn(g.x,g.y).toVar();m.subAssign(.5),m.mulAssign(u),m.addAssign(.5);const f=yn(yn(pn(h),pn(c)).add(m)).toVar(),y=yn(f.sub(p)).toVar();return dn(o.equal(gn(2)),()=>Co(y.x).add(Co(y.y))),dn(o.equal(gn(3)),()=>Wo(Co(y.x),Co(y.y))),Ko(y,y)}).setLayout({name:"mx_worley_distance_0",type:"float",inputs:[{name:"p",type:"vec2"},{name:"x",type:"int"},{name:"y",type:"int"},{name:"xoff",type:"int"},{name:"yoff",type:"int"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),on(([e,t,r,s,i,n,a,o,u])=>{const l=gn(u).toVar(),d=pn(o).toVar(),c=gn(a).toVar(),h=gn(n).toVar(),p=gn(i).toVar(),g=gn(s).toVar(),m=gn(r).toVar(),f=gn(t).toVar(),y=_n(e).toVar(),b=_n(Bv(_n(f.add(p),m.add(h),g.add(c)))).toVar();b.subAssign(.5),b.mulAssign(d),b.addAssign(.5);const x=_n(_n(pn(f),pn(m),pn(g)).add(b)).toVar(),T=_n(x.sub(y)).toVar();return dn(l.equal(gn(2)),()=>Co(T.x).add(Co(T.y)).add(Co(T.z))),dn(l.equal(gn(3)),()=>Wo(Co(T.x),Co(T.y),Co(T.z))),Ko(T,T)}).setLayout({name:"mx_worley_distance_1",type:"float",inputs:[{name:"p",type:"vec3"},{name:"x",type:"int"},{name:"y",type:"int"},{name:"z",type:"int"},{name:"xoff",type:"int"},{name:"yoff",type:"int"},{name:"zoff",type:"int"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),Iv=on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=yn(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=yn(uv(n.x,a),uv(n.y,o)).toVar(),l=pn(1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{const r=pn(Uv(u,e,t,a,o,i,s)).toVar();l.assign($o(l,r))})}),dn(s.equal(gn(0)),()=>{l.assign(yo(l))}),l}).setLayout({name:"mx_worley_noise_float_0",type:"float",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),Ov=on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=yn(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=yn(uv(n.x,a),uv(n.y,o)).toVar(),l=yn(1e6,1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{const r=pn(Uv(u,e,t,a,o,i,s)).toVar();dn(r.lessThan(l.x),()=>{l.y.assign(l.x),l.x.assign(r)}).ElseIf(r.lessThan(l.y),()=>{l.y.assign(r)})})}),dn(s.equal(gn(0)),()=>{l.assign(yo(l))}),l}).setLayout({name:"mx_worley_noise_vec2_0",type:"vec2",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),Vv=on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=yn(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=yn(uv(n.x,a),uv(n.y,o)).toVar(),l=_n(1e6,1e6,1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{const r=pn(Uv(u,e,t,a,o,i,s)).toVar();dn(r.lessThan(l.x),()=>{l.z.assign(l.y),l.y.assign(l.x),l.x.assign(r)}).ElseIf(r.lessThan(l.y),()=>{l.z.assign(l.y),l.y.assign(r)}).ElseIf(r.lessThan(l.z),()=>{l.z.assign(r)})})}),dn(s.equal(gn(0)),()=>{l.assign(yo(l))}),l}).setLayout({name:"mx_worley_noise_vec3_0",type:"vec3",inputs:[{name:"p",type:"vec2"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]}),kv=mb([Iv,on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=_n(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=gn().toVar(),l=_n(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=pn(1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{up({start:-1,end:gn(1),name:"z",condition:"<="},({z:r})=>{const n=pn(Uv(l,e,t,r,a,o,u,i,s)).toVar();d.assign($o(d,n))})})}),dn(s.equal(gn(0)),()=>{d.assign(yo(d))}),d}).setLayout({name:"mx_worley_noise_float_1",type:"float",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),Gv=mb([Ov,on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=_n(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=gn().toVar(),l=_n(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=yn(1e6,1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{up({start:-1,end:gn(1),name:"z",condition:"<="},({z:r})=>{const n=pn(Uv(l,e,t,r,a,o,u,i,s)).toVar();dn(n.lessThan(d.x),()=>{d.y.assign(d.x),d.x.assign(n)}).ElseIf(n.lessThan(d.y),()=>{d.y.assign(n)})})})}),dn(s.equal(gn(0)),()=>{d.assign(yo(d))}),d}).setLayout({name:"mx_worley_noise_vec2_1",type:"vec2",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),zv=mb([Vv,on(([e,t,r])=>{const s=gn(r).toVar(),i=pn(t).toVar(),n=_n(e).toVar(),a=gn().toVar(),o=gn().toVar(),u=gn().toVar(),l=_n(uv(n.x,a),uv(n.y,o),uv(n.z,u)).toVar(),d=_n(1e6,1e6,1e6).toVar();return up({start:-1,end:gn(1),name:"x",condition:"<="},({x:e})=>{up({start:-1,end:gn(1),name:"y",condition:"<="},({y:t})=>{up({start:-1,end:gn(1),name:"z",condition:"<="},({z:r})=>{const n=pn(Uv(l,e,t,r,a,o,u,i,s)).toVar();dn(n.lessThan(d.x),()=>{d.z.assign(d.y),d.y.assign(d.x),d.x.assign(n)}).ElseIf(n.lessThan(d.y),()=>{d.z.assign(d.y),d.y.assign(n)}).ElseIf(n.lessThan(d.z),()=>{d.z.assign(n)})})})}),dn(s.equal(gn(0)),()=>{d.assign(yo(d))}),d}).setLayout({name:"mx_worley_noise_vec3_1",type:"vec3",inputs:[{name:"p",type:"vec3"},{name:"jitter",type:"float"},{name:"metric",type:"int"}]})]),$v=on(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=gn(e).toVar(),h=yn(t).toVar(),p=yn(r).toVar(),g=yn(s).toVar(),m=pn(i).toVar(),f=pn(n).toVar(),y=pn(a).toVar(),b=fn(o).toVar(),x=gn(u).toVar(),T=pn(l).toVar(),_=pn(d).toVar(),v=h.mul(p).add(g),N=pn(0).toVar();return dn(c.equal(gn(0)),()=>{N.assign(Cv(v))}),dn(c.equal(gn(1)),()=>{N.assign(Bv(v))}),dn(c.equal(gn(2)),()=>{N.assign(zv(v,m,gn(0)))}),dn(c.equal(gn(3)),()=>{N.assign(Lv(_n(v,0),x,T,_))}),N.assign(N.mul(y.sub(f)).add(f)),dn(b,()=>{N.assign(nu(N,f,y))}),N}).setLayout({name:"mx_unifiednoise2d",type:"float",inputs:[{name:"noiseType",type:"int"},{name:"texcoord",type:"vec2"},{name:"freq",type:"vec2"},{name:"offset",type:"vec2"},{name:"jitter",type:"float"},{name:"outmin",type:"float"},{name:"outmax",type:"float"},{name:"clampoutput",type:"bool"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Wv=on(([e,t,r,s,i,n,a,o,u,l,d])=>{const c=gn(e).toVar(),h=_n(t).toVar(),p=_n(r).toVar(),g=_n(s).toVar(),m=pn(i).toVar(),f=pn(n).toVar(),y=pn(a).toVar(),b=fn(o).toVar(),x=gn(u).toVar(),T=pn(l).toVar(),_=pn(d).toVar(),v=h.mul(p).add(g),N=pn(0).toVar();return dn(c.equal(gn(0)),()=>{N.assign(Cv(v))}),dn(c.equal(gn(1)),()=>{N.assign(Bv(v))}),dn(c.equal(gn(2)),()=>{N.assign(zv(v,m,gn(0)))}),dn(c.equal(gn(3)),()=>{N.assign(Lv(v,x,T,_))}),N.assign(N.mul(y.sub(f)).add(f)),dn(b,()=>{N.assign(nu(N,f,y))}),N}).setLayout({name:"mx_unifiednoise3d",type:"float",inputs:[{name:"noiseType",type:"int"},{name:"position",type:"vec3"},{name:"freq",type:"vec3"},{name:"offset",type:"vec3"},{name:"jitter",type:"float"},{name:"outmin",type:"float"},{name:"outmax",type:"float"},{name:"clampoutput",type:"bool"},{name:"octaves",type:"int"},{name:"lacunarity",type:"float"},{name:"diminish",type:"float"}]}),Hv=on(([e])=>{const t=e.y,r=e.z,s=_n().toVar();return dn(t.lessThan(1e-4),()=>{s.assign(_n(r,r,r))}).Else(()=>{let i=e.x;i=i.sub(xo(i)).mul(6).toVar();const n=gn(Oo(i)),a=i.sub(pn(n)),o=r.mul(t.oneMinus()),u=r.mul(t.mul(a).oneMinus()),l=r.mul(t.mul(a.oneMinus()).oneMinus());dn(n.equal(gn(0)),()=>{s.assign(_n(r,l,o))}).ElseIf(n.equal(gn(1)),()=>{s.assign(_n(u,r,o))}).ElseIf(n.equal(gn(2)),()=>{s.assign(_n(o,r,l))}).ElseIf(n.equal(gn(3)),()=>{s.assign(_n(o,u,r))}).ElseIf(n.equal(gn(4)),()=>{s.assign(_n(l,o,r))}).Else(()=>{s.assign(_n(r,o,u))})}),s}).setLayout({name:"mx_hsvtorgb",type:"vec3",inputs:[{name:"hsv",type:"vec3"}]}),qv=on(([e])=>{const t=_n(e).toVar(),r=pn(t.x).toVar(),s=pn(t.y).toVar(),i=pn(t.z).toVar(),n=pn($o(r,$o(s,i))).toVar(),a=pn(Wo(r,Wo(s,i))).toVar(),o=pn(a.sub(n)).toVar(),u=pn().toVar(),l=pn().toVar(),d=pn().toVar();return d.assign(a),dn(a.greaterThan(0),()=>{l.assign(o.div(a))}).Else(()=>{l.assign(0)}),dn(l.lessThanEqual(0),()=>{u.assign(0)}).Else(()=>{dn(r.greaterThanEqual(a),()=>{u.assign(s.sub(i).div(o))}).ElseIf(s.greaterThanEqual(a),()=>{u.assign(Ca(2,i.sub(r).div(o)))}).Else(()=>{u.assign(Ca(4,r.sub(s).div(o)))}),u.mulAssign(1/6),dn(u.lessThan(0),()=>{u.addAssign(1)})}),_n(u,l,d)}).setLayout({name:"mx_rgbtohsv",type:"vec3",inputs:[{name:"c",type:"vec3"}]}),jv=on(([e])=>{const t=_n(e).toVar(),r=Sn(Ia(t,_n(.04045))).toVar(),s=_n(t.div(12.92)).toVar(),i=_n(Qo(Wo(t.add(_n(.055)),_n(0)).div(1.055),_n(2.4))).toVar();return iu(s,i,r)}).setLayout({name:"mx_srgb_texture_to_lin_rec709",type:"vec3",inputs:[{name:"color",type:"vec3"}]}),Xv=(e,t)=>{e=pn(e),t=pn(t);const r=yn(t.dFdx(),t.dFdy()).length().mul(.7071067811865476);return uu(e.sub(r),e.add(r),t)},Kv=(e,t,r,s)=>iu(e,t,r[s].clamp()),Yv=(e,t,r,s,i)=>iu(e,t,Xv(r,s[i])),Qv=on(([e,t,r])=>{const s=_o(e).toVar(),i=Ma(pn(.5).mul(t.sub(r)),Pd).div(s).toVar(),n=Ma(pn(-.5).mul(t.sub(r)),Pd).div(s).toVar(),a=_n().toVar();a.x=s.x.greaterThan(pn(0)).select(i.x,n.x),a.y=s.y.greaterThan(pn(0)).select(i.y,n.y),a.z=s.z.greaterThan(pn(0)).select(i.z,n.z);const o=$o(a.x,a.y,a.z).toVar();return Pd.add(s.mul(o)).toVar().sub(r)}),Zv=on(([e,t])=>{const r=e.x,s=e.y,i=e.z;let n=t.element(0).mul(.886227);return n=n.add(t.element(1).mul(1.023328).mul(s)),n=n.add(t.element(2).mul(1.023328).mul(i)),n=n.add(t.element(3).mul(1.023328).mul(r)),n=n.add(t.element(4).mul(.858086).mul(r).mul(s)),n=n.add(t.element(5).mul(.858086).mul(s).mul(i)),n=n.add(t.element(6).mul(i.mul(i).mul(.743125).sub(.247708))),n=n.add(t.element(7).mul(.858086).mul(r).mul(i)),n=n.add(t.element(8).mul(.429043).mul(Ba(r,r).sub(Ba(s,s)))),n});var Jv=Object.freeze({__proto__:null,BRDF_GGX:Dg,BRDF_Lambert:Tg,BasicPointShadowFilter:X_,BasicShadowFilter:S_,Break:lp,Const:wu,Continue:()=>pl("continue").toStack(),DFGLUT:Og,D_GGX:Fg,Discard:gl,EPSILON:ro,F_Schlick:xg,Fn:on,HALF_PI:oo,INFINITY:so,If:dn,Loop:up,NodeAccess:ei,NodeShaderStage:Qs,NodeType:Js,NodeUpdateType:Zs,OnBeforeMaterialUpdate:e=>tx(ex.BEFORE_MATERIAL,e),OnBeforeObjectUpdate:e=>tx(ex.BEFORE_OBJECT,e),OnMaterialUpdate:e=>tx(ex.MATERIAL,e),OnObjectUpdate:e=>tx(ex.OBJECT,e),PCFShadowFilter:R_,PCFSoftShadowFilter:A_,PI:io,PI2:no,PointShadowFilter:K_,Return:()=>pl("return").toStack(),Schlick_to_F0:Gg,ScriptableNodeResources:rT,ShaderNode:Yi,Stack:cn,Switch:(...e)=>Ti.Switch(...e),TBNViewMatrix:$c,TWO_PI:ao,VSMShadowFilter:E_,V_GGX_SmithCorrelated:Mg,Var:Eu,VarIntent:Cu,abs:Co,acesFilmicToneMapping:zx,acos:Eo,add:Ca,addMethodChaining:vi,addNodeElement:function(e){d("TSL: AddNodeElement has been removed in favor of tree-shaking. Trying add",e)},agxToneMapping:qx,all:uo,alphaT:Kn,and:ka,anisotropy:Yn,anisotropyB:Zn,anisotropyT:Qn,any:lo,append:e=>(d("TSL: append() has been renamed to Stack()."),cn(e)),array:va,arrayBuffer:e=>new bi(e,"ArrayBuffer"),asin:Ao,assign:Sa,atan:wo,atomicAdd:(e,t)=>ET(RT.ATOMIC_ADD,e,t),atomicAnd:(e,t)=>ET(RT.ATOMIC_AND,e,t),atomicFunc:ET,atomicLoad:e=>ET(RT.ATOMIC_LOAD,e,null),atomicMax:(e,t)=>ET(RT.ATOMIC_MAX,e,t),atomicMin:(e,t)=>ET(RT.ATOMIC_MIN,e,t),atomicOr:(e,t)=>ET(RT.ATOMIC_OR,e,t),atomicStore:(e,t)=>ET(RT.ATOMIC_STORE,e,t),atomicSub:(e,t)=>ET(RT.ATOMIC_SUB,e,t),atomicXor:(e,t)=>ET(RT.ATOMIC_XOR,e,t),attenuationColor:ca,attenuationDistance:da,attribute:Nl,attributeArray:(e,t="float")=>{let r,s;!0===t.isStruct?(r=t.layout.getLength(),s=Gs("float")):(r=zs(t),s=Gs(t));const i=new sx(e,r,s);return Wh(i,t,e)},backgroundBlurriness:ux,backgroundIntensity:lx,backgroundRotation:dx,batch:sp,bentNormalView:Hc,billboarding:_b,bitAnd:Wa,bitNot:Ha,bitOr:qa,bitXor:ja,bitangentGeometry:Vc,bitangentLocal:kc,bitangentView:Gc,bitangentWorld:zc,bitcast:jy,blendBurn:Wp,blendColor:Xp,blendDodge:Hp,blendOverlay:jp,blendScreen:qp,blur:Gm,bool:fn,buffer:Dl,bufferAttribute:Zu,builtin:kl,builtinAOContext:Nu,builtinShadowContext:vu,bumpMap:Jc,bvec2:Tn,bvec3:Sn,bvec4:wn,bypass:ul,cache:al,call:Aa,cameraFar:td,cameraIndex:Jl,cameraNear:ed,cameraNormalMatrix:ad,cameraPosition:od,cameraProjectionMatrix:rd,cameraProjectionMatrixInverse:sd,cameraViewMatrix:id,cameraViewport:ud,cameraWorldMatrix:nd,cbrt:ru,cdl:Ex,ceil:To,checker:sv,cineonToneMapping:kx,clamp:nu,clearcoat:zn,clearcoatNormalView:Kd,clearcoatRoughness:$n,clipSpace:Md,code:Kx,color:hn,colorSpaceToWorking:ku,colorToDirection:e=>Qi(e).mul(2).sub(1),compute:sl,computeKernel:rl,computeSkinning:(e,t=null)=>{const r=new np(e);return r.positionNode=Wh(new W(e.geometry.getAttribute("position").array,3),"vec3").setPBO(!0).toReadOnly().element(jh).toVar(),r.skinIndexNode=Wh(new W(new Uint32Array(e.geometry.getAttribute("skinIndex").array),4),"uvec4").setPBO(!0).toReadOnly().element(jh).toVar(),r.skinWeightNode=Wh(new W(e.geometry.getAttribute("skinWeight").array,4),"vec4").setPBO(!0).toReadOnly().element(jh).toVar(),r.bindMatrixNode=Ta(e.bindMatrix,"mat4"),r.bindMatrixInverseNode=Ta(e.bindMatrixInverse,"mat4"),r.boneMatricesNode=Dl(e.skeleton.boneMatrices,"mat4",e.skeleton.bones.length),r.toPositionNode=t,Qi(r)},context:xu,convert:Ln,convertColorSpace:(e,t,r)=>Qi(new Ou(Qi(e),t,r)),convertToTexture:(e,...t)=>e.isSampleNode||e.isTextureNode?e:e.isPassNode?e.getTextureNode():jb(e,...t),cos:So,countLeadingZeros:Zy,countOneBits:Jy,countTrailingZeros:Qy,cross:Yo,cubeTexture:pc,cubeTextureBase:hc,dFdx:Po,dFdy:Do,dashSize:ia,debug:bl,decrement:Ja,decrementBefore:Qa,defaultBuildStages:ri,defaultShaderStages:ti,defined:Xi,degrees:ho,deltaTime:yb,densityFogFactor:oT,depth:Dp,depthPass:(e,t,r)=>new Ux(Ux.DEPTH,e,t,r),determinant:Go,difference:Xo,diffuseColor:In,diffuseContribution:On,directPointLight:tv,directionToColor:qc,directionToFaceDirection:Gd,dispersion:ha,disposeShadowMaterial:C_,distance:jo,div:Fa,dot:Ko,drawIndex:Qh,dynamicBufferAttribute:(e,t=null,r=0,s=0)=>Qu(e,t,r,s,x),element:Fn,emissive:Vn,equal:Pa,equirectUV:ag,exp:po,exp2:go,exponentialHeightFogFactor:uT,expression:pl,faceDirection:kd,faceForward:lu,faceforward:gu,float:pn,floatBitsToInt:e=>new qy(e,"int","float"),floatBitsToUint:Xy,floor:xo,fog:lT,fract:vo,frameGroup:fa,frameId:bb,frontFacing:Vd,fwidth:Vo,gain:(e,t)=>e.lessThan(.5)?tb(e.mul(2),t).div(2):Ma(1,tb(Ba(Ma(1,e),2),t).div(2)),gapSize:na,getConstNodeType:Ki,getCurrentStack:ln,getDirection:Im,getDistanceAttenuation:ev,getGeometryRoughness:wg,getNormalFromDepth:Yb,getParallaxCorrectNormal:Qv,getRoughness:Cg,getScreenPosition:Kb,getShIrradianceAt:Zv,getShadowMaterial:w_,getShadowRenderObjectFunction:F_,getTextureIndex:$y,getViewPosition:Xb,ggxConvolution:Hm,globalId:bT,glsl:(e,t)=>Kx(e,t,"glsl"),glslFn:(e,t)=>Qx(e,t,"glsl"),grayscale:vx,greaterThan:Ia,greaterThanEqual:Va,hash:eb,highpModelNormalViewMatrix:Cd,highpModelViewMatrix:wd,hue:Rx,increment:Za,incrementBefore:Ya,inspector:_l,instance:Jh,instanceIndex:jh,instancedArray:(e,t="float")=>{let r,s;!0===t.isStruct?(r=t.layout.getLength(),s=Gs("float")):(r=zs(t),s=Gs(t));const i=new rx(e,r,s);return Wh(i,t,e)},instancedBufferAttribute:Ju,instancedDynamicBufferAttribute:el,instancedMesh:tp,int:gn,intBitsToFloat:e=>new qy(e,"float","int"),interleavedGradientNoise:Qb,inverse:zo,inverseSqrt:bo,inversesqrt:mu,invocationLocalIndex:Yh,invocationSubgroupIndex:Kh,ior:oa,iridescence:qn,iridescenceIOR:jn,iridescenceThickness:Xn,isolate:nl,ivec2:bn,ivec3:vn,ivec4:An,js:(e,t)=>Kx(e,t,"js"),label:Su,length:Bo,lengthSq:su,lessThan:Ua,lessThanEqual:Oa,lightPosition:i_,lightProjectionUV:s_,lightShadowMatrix:r_,lightTargetDirection:o_,lightTargetPosition:n_,lightViewPosition:a_,lightingContext:bp,lights:(e=[])=>(new c_).setLights(e),linearDepth:Up,linearToneMapping:Ox,localId:xT,log:mo,log2:fo,logarithmicDepthToViewZ:(e,t,r)=>{const s=e.mul(mo(r.div(t)));return pn(Math.E).pow(s).mul(t).negate()},luminance:Ax,mat2:Cn,mat3:Mn,mat4:Bn,matcapUV:Mf,materialAO:Oh,materialAlphaTest:rh,materialAnisotropy:_h,materialAnisotropyVector:Vh,materialAttenuationColor:Ch,materialAttenuationDistance:wh,materialClearcoat:mh,materialClearcoatNormal:yh,materialClearcoatRoughness:fh,materialColor:sh,materialDispersion:Uh,materialEmissive:nh,materialEnvIntensity:ic,materialEnvRotation:nc,materialIOR:Eh,materialIridescence:vh,materialIridescenceIOR:Nh,materialIridescenceThickness:Sh,materialLightMap:Ih,materialLineDashOffset:Ph,materialLineDashSize:Bh,materialLineGapSize:Fh,materialLineScale:Mh,materialLineWidth:Lh,materialMetalness:ph,materialNormal:gh,materialOpacity:ah,materialPointSize:Dh,materialReference:xc,materialReflectivity:ch,materialRefractionRatio:sc,materialRotation:bh,materialRoughness:hh,materialSheen:xh,materialSheenRoughness:Th,materialShininess:ih,materialSpecular:oh,materialSpecularColor:lh,materialSpecularIntensity:uh,materialSpecularStrength:dh,materialThickness:Ah,materialTransmission:Rh,max:Wo,maxMipLevel:wl,mediumpModelViewMatrix:Ed,metalness:Gn,min:$o,mix:iu,mixElement:cu,mod:La,modInt:eo,modelDirection:bd,modelNormalMatrix:Sd,modelPosition:Td,modelRadius:Nd,modelScale:_d,modelViewMatrix:Ad,modelViewPosition:vd,modelViewProjection:kh,modelWorldMatrix:xd,modelWorldMatrixInverse:Rd,morphReference:gp,mrt:Hy,mul:Ba,mx_aastep:Xv,mx_add:(e,t=pn(0))=>Ca(e,t),mx_atan2:(e=pn(0),t=pn(1))=>wo(e,t),mx_cell_noise_float:(e=Sl())=>Mv(e.convert("vec2|vec3")),mx_contrast:(e,t=1,r=.5)=>pn(e).sub(r).mul(t).add(r),mx_divide:(e,t=pn(1))=>Fa(e,t),mx_fractal_noise_float:(e=Sl(),t=3,r=2,s=.5,i=1)=>Fv(e,gn(t),r,s).mul(i),mx_fractal_noise_vec2:(e=Sl(),t=3,r=2,s=.5,i=1)=>Pv(e,gn(t),r,s).mul(i),mx_fractal_noise_vec3:(e=Sl(),t=3,r=2,s=.5,i=1)=>Lv(e,gn(t),r,s).mul(i),mx_fractal_noise_vec4:(e=Sl(),t=3,r=2,s=.5,i=1)=>Dv(e,gn(t),r,s).mul(i),mx_frame:()=>bb,mx_heighttonormal:(e,t)=>(e=_n(e),t=pn(t),Jc(e,t)),mx_hsvtorgb:Hv,mx_ifequal:(e,t,r,s)=>e.equal(t).mix(r,s),mx_ifgreater:(e,t,r,s)=>e.greaterThan(t).mix(r,s),mx_ifgreatereq:(e,t,r,s)=>e.greaterThanEqual(t).mix(r,s),mx_invert:(e,t=pn(1))=>Ma(t,e),mx_modulo:(e,t=pn(1))=>La(e,t),mx_multiply:(e,t=pn(1))=>Ba(e,t),mx_noise_float:(e=Sl(),t=1,r=0)=>wv(e.convert("vec2|vec3")).mul(t).add(r),mx_noise_vec3:(e=Sl(),t=1,r=0)=>Cv(e.convert("vec2|vec3")).mul(t).add(r),mx_noise_vec4:(e=Sl(),t=1,r=0)=>{e=e.convert("vec2|vec3");return Rn(Cv(e),wv(e.add(yn(19,73)))).mul(t).add(r)},mx_place2d:(e,t=yn(.5,.5),r=yn(1,1),s=pn(0),i=yn(0,0))=>{let n=e;if(t&&(n=n.sub(t)),r&&(n=n.mul(r)),s){const e=s.mul(Math.PI/180),t=e.cos(),r=e.sin();n=yn(n.x.mul(t).sub(n.y.mul(r)),n.x.mul(r).add(n.y.mul(t)))}return t&&(n=n.add(t)),i&&(n=n.add(i)),n},mx_power:(e,t=pn(1))=>Qo(e,t),mx_ramp4:(e,t,r,s,i=Sl())=>{const n=i.x.clamp(),a=i.y.clamp(),o=iu(e,t,n),u=iu(r,s,n);return iu(o,u,a)},mx_ramplr:(e,t,r=Sl())=>Kv(e,t,r,"x"),mx_ramptb:(e,t,r=Sl())=>Kv(e,t,r,"y"),mx_rgbtohsv:qv,mx_rotate2d:(e,t)=>{e=yn(e);const r=(t=pn(t)).mul(Math.PI/180);return Pf(e,r)},mx_rotate3d:(e,t,r)=>{e=_n(e),t=pn(t),r=_n(r);const s=t.mul(Math.PI/180),i=r.normalize(),n=s.cos(),a=s.sin(),o=pn(1).sub(n);return e.mul(n).add(i.cross(e).mul(a)).add(i.mul(i.dot(e)).mul(o))},mx_safepower:(e,t=1)=>(e=pn(e)).abs().pow(t).mul(e.sign()),mx_separate:(e,t=null)=>{if("string"==typeof t){const r={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3},s=t.replace(/^out/,"").toLowerCase();if(void 0!==r[s])return e.element(r[s])}if("number"==typeof t)return e.element(t);if("string"==typeof t&&1===t.length){const r={x:0,r:0,y:1,g:1,z:2,b:2,w:3,a:3};if(void 0!==r[t])return e.element(r[t])}return e},mx_splitlr:(e,t,r,s=Sl())=>Yv(e,t,r,s,"x"),mx_splittb:(e,t,r,s=Sl())=>Yv(e,t,r,s,"y"),mx_srgb_texture_to_lin_rec709:jv,mx_subtract:(e,t=pn(0))=>Ma(e,t),mx_timer:()=>fb,mx_transform_uv:(e=1,t=0,r=Sl())=>r.mul(e).add(t),mx_unifiednoise2d:(e,t=Sl(),r=yn(1,1),s=yn(0,0),i=1,n=0,a=1,o=!1,u=1,l=2,d=.5)=>$v(e,t.convert("vec2|vec3"),r,s,i,n,a,o,u,l,d),mx_unifiednoise3d:(e,t=Sl(),r=yn(1,1),s=yn(0,0),i=1,n=0,a=1,o=!1,u=1,l=2,d=.5)=>Wv(e,t.convert("vec2|vec3"),r,s,i,n,a,o,u,l,d),mx_worley_noise_float:(e=Sl(),t=1)=>kv(e.convert("vec2|vec3"),t,gn(1)),mx_worley_noise_vec2:(e=Sl(),t=1)=>Gv(e.convert("vec2|vec3"),t,gn(1)),mx_worley_noise_vec3:(e=Sl(),t=1)=>zv(e.convert("vec2|vec3"),t,gn(1)),negate:Fo,neutralToneMapping:jx,nodeArray:en,nodeImmutable:rn,nodeObject:Qi,nodeObjectIntent:Zi,nodeObjects:Ji,nodeProxy:tn,nodeProxyIntent:sn,normalFlat:Wd,normalGeometry:zd,normalLocal:$d,normalMap:Kc,normalView:jd,normalViewGeometry:Hd,normalWorld:Xd,normalWorldGeometry:qd,normalize:_o,not:za,notEqual:Da,numWorkgroups:fT,objectDirection:cd,objectGroup:ba,objectPosition:pd,objectRadius:fd,objectScale:gd,objectViewPosition:md,objectWorldMatrix:hd,oneMinus:Lo,or:Ga,orthographicDepthToViewZ:(e,t,r)=>t.sub(r).mul(e).sub(t),oscSawtooth:(e=fb)=>e.fract(),oscSine:(e=fb)=>e.add(.75).mul(2*Math.PI).sin().mul(.5).add(.5),oscSquare:(e=fb)=>e.fract().round(),oscTriangle:(e=fb)=>e.add(.5).fract().mul(2).sub(1).abs(),output:sa,outputStruct:Vy,overloadingFn:mb,packHalf2x16:nb,packSnorm2x16:sb,packUnorm2x16:ib,parabola:tb,parallaxDirection:Wc,parallaxUV:(e,t)=>e.sub(Wc.mul(t)),parameter:(e,t)=>new Ly(e,t),pass:(e,t,r)=>new Ux(Ux.COLOR,e,t,r),passTexture:(e,t)=>new Px(e,t),pcurve:(e,t,r)=>Qo(Fa(Qo(e,t),Ca(Qo(e,t),Qo(Ma(1,e),r))),1/t),perspectiveDepthToViewZ:Fp,pmremTexture:mf,pointShadow:Z_,pointUV:nx,pointWidth:aa,positionGeometry:Bd,positionLocal:Fd,positionPrevious:Ld,positionView:Ud,positionViewDirection:Id,positionWorld:Pd,positionWorldDirection:Dd,posterize:Cx,pow:Qo,pow2:Zo,pow3:Jo,pow4:eu,premultiplyAlpha:Kp,property:Dn,quadBroadcast:JT,quadSwapDiagonal:jT,quadSwapX:HT,quadSwapY:qT,radians:co,rand:du,range:pT,rangeFogFactor:aT,reciprocal:Io,reference:fc,referenceBuffer:yc,reflect:qo,reflectVector:uc,reflectView:ac,reflector:e=>new Vb(e),refract:ou,refractVector:lc,refractView:oc,reinhardToneMapping:Vx,remap:dl,remapClamp:cl,renderGroup:ya,renderOutput:fl,rendererReference:Wu,replaceDefaultUV:function(e,t=null){return xu(t,{getUV:e})},rotate:Pf,rotateUV:xb,roughness:kn,round:Uo,rtt:jb,sRGBTransferEOTF:Du,sRGBTransferOETF:Uu,sample:(e,t=null)=>new Jb(e,Qi(t)),sampler:e=>(!0===e.isNode?e:Fl(e)).convert("sampler"),samplerComparison:e=>(!0===e.isNode?e:Fl(e)).convert("samplerComparison"),saturate:au,saturation:Nx,screenCoordinate:jl,screenDPR:Wl,screenSize:ql,screenUV:Hl,scriptable:iT,scriptableValue:Jx,select:yu,setCurrentStack:un,setName:_u,shaderStages:si,shadow:V_,shadowPositionWorld:p_,shapeCircle:iv,sharedUniformGroup:ma,sheen:Wn,sheenRoughness:Hn,shiftLeft:Xa,shiftRight:Ka,shininess:ra,sign:Mo,sin:No,sinc:(e,t)=>No(io.mul(t.mul(e).sub(1))).div(io.mul(t.mul(e).sub(1))),skinning:ap,smoothstep:uu,smoothstepElement:hu,specularColor:Jn,specularColorBlended:ea,specularF90:ta,spherizeUV:Tb,split:(e,t)=>Qi(new pi(Qi(e),t)),spritesheetUV:Nb,sqrt:yo,stack:Dy,step:Ho,stepElement:pu,storage:Wh,storageBarrier:()=>vT("storage").toStack(),storageTexture:hx,string:(e="")=>new bi(e,"string"),struct:(e,t=null)=>{const r=new Uy(e,t),s=(...t)=>{let s=null;if(t.length>0)if(t[0].isNode){s={};const r=Object.keys(e);for(let e=0;emx(e,t).level(r),texture3DLoad:(...e)=>mx(...e).setSampler(!1),textureBarrier:()=>vT("texture").toStack(),textureBicubic:om,textureBicubicLevel:am,textureCubeUV:Om,textureLevel:(e,t,r)=>Fl(e,t).level(r),textureLoad:Ll,textureSize:Al,textureStore:(e,t,r)=>{let s;return!0===e.isStorageTextureNode?(s=e.clone(),s.uvNode=t,s.storeNode=r):s=hx(e,t,r),null!==r&&s.toStack(),s},thickness:la,time:fb,toneMapping:qu,toneMappingExposure:ju,toonOutlinePass:(t,r,s=new e(0,0,0),i=.003,n=1)=>Qi(new Ix(t,r,Qi(s),Qi(i),Qi(n))),transformDirection:tu,transformNormal:Yd,transformNormalToView:Qd,transformedClearcoatNormalView:ec,transformedNormalView:Zd,transformedNormalWorld:Jd,transmission:ua,transpose:ko,triNoise3D:hb,triplanarTexture:(...e)=>Sb(...e),triplanarTextures:Sb,trunc:Oo,uint:mn,uintBitsToFloat:e=>new qy(e,"float","uint"),uniform:Ta,uniformArray:Ol,uniformCubeTexture:(e=dc)=>hc(e),uniformFlow:Tu,uniformGroup:ga,uniformTexture:(e=Cl)=>Fl(e),unpackHalf2x16:lb,unpackNormal:jc,unpackSnorm2x16:ob,unpackUnorm2x16:ub,unpremultiplyAlpha:Yp,userData:(e,t,r)=>new fx(e,t,r),uv:Sl,uvec2:xn,uvec3:Nn,uvec4:En,varying:Lu,varyingProperty:Un,vec2:yn,vec3:_n,vec4:Rn,vectorComponents:ii,velocity:_x,vertexColor:$p,vertexIndex:qh,vertexStage:Pu,vibrance:Sx,viewZToLogarithmicDepth:Lp,viewZToOrthographicDepth:Mp,viewZToPerspectiveDepth:Bp,viewport:Xl,viewportCoordinate:Yl,viewportDepthTexture:wp,viewportLinearDepth:Ip,viewportMipTexture:Np,viewportOpaqueMipTexture:Rp,viewportResolution:Zl,viewportSafeUV:vb,viewportSharedTexture:Fx,viewportSize:Kl,viewportTexture:vp,viewportUV:Ql,vogelDiskSample:Zb,wgsl:(e,t)=>Kx(e,t,"wgsl"),wgslFn:(e,t)=>Qx(e,t,"wgsl"),workgroupArray:(e,t)=>new ST("Workgroup",e,t),workgroupBarrier:()=>vT("workgroup").toStack(),workgroupId:yT,workingToColorSpace:Vu,xor:$a});const eN=new Fy;class tN extends ty{constructor(e,t){super(),this.renderer=e,this.nodes=t}update(e,t,r){const s=this.renderer,i=this.nodes.getBackgroundNode(e)||e.background;let n=!1;if(null===i)s._clearColor.getRGB(eN),eN.a=s._clearColor.a;else if(!0===i.isColor)i.getRGB(eN),eN.a=1,n=!0;else if(!0===i.isNode){const u=this.get(e),l=i;eN.copy(s._clearColor);let d=u.backgroundMesh;if(void 0===d){const h=Rn(l).mul(lx).context({getUV:()=>dx.mul(qd),getTextureLevel:()=>ux}),p=rd.element(3).element(3).equal(1),g=Fa(1,rd.element(1).element(1)).mul(3),m=p.select(Fd.mul(g),Fd),f=Ad.mul(Rn(m,0));let y=rd.mul(Rn(f.xyz,1));y=y.setZ(y.w);const b=new Qp;function x(){i.removeEventListener("dispose",x),d.material.dispose(),d.geometry.dispose()}b.name="Background.material",b.side=M,b.depthTest=!1,b.depthWrite=!1,b.allowOverride=!1,b.fog=!1,b.lights=!1,b.vertexNode=y,b.colorNode=h,u.backgroundMeshNode=h,u.backgroundMesh=d=new ne(new st(1,32,32),b),d.frustumCulled=!1,d.name="Background.mesh",i.addEventListener("dispose",x)}const c=l.getCacheKey();u.backgroundCacheKey!==c&&(u.backgroundMeshNode.node=Rn(l).mul(lx),u.backgroundMeshNode.needsUpdate=!0,d.material.needsUpdate=!0,u.backgroundCacheKey=c),t.unshift(d,d.geometry,d.material,0,0,null,null)}else o("Renderer: Unsupported background configuration.",i);const a=s.xr.getEnvironmentBlendMode();if("additive"===a?eN.set(0,0,0,1):"alpha-blend"===a&&eN.set(0,0,0,0),!0===s.autoClear||!0===n){const T=r.clearColorValue;T.r=eN.r,T.g=eN.g,T.b=eN.b,T.a=eN.a,!0!==s.backend.isWebGLBackend&&!0!==s.alpha||(T.r*=T.a,T.g*=T.a,T.b*=T.a),r.depthClearValue=s._clearDepth,r.stencilClearValue=s._clearStencil,r.clearColor=!0===s.autoClearColor,r.clearDepth=!0===s.autoClearDepth,r.clearStencil=!0===s.autoClearStencil}else r.clearColor=!1,r.clearDepth=!1,r.clearStencil=!1}}let rN=0;class sN{constructor(e="",t=[],r=0){this.name=e,this.bindings=t,this.index=r,this.id=rN++}}class iN{constructor(e,t,r,s,i,n,a,o,u,l=[]){this.vertexShader=e,this.fragmentShader=t,this.computeShader=r,this.transforms=l,this.nodeAttributes=s,this.bindings=i,this.updateNodes=n,this.updateBeforeNodes=a,this.updateAfterNodes=o,this.observer=u,this.usedTimes=0}createBindings(){const e=[];for(const t of this.bindings){if(!0!==t.bindings[0].groupNode.shared){const r=new sN(t.name,[],t.index);e.push(r);for(const e of t.bindings)r.bindings.push(e.clone())}else e.push(t)}return e}}class nN{constructor(e,t,r=null){this.isNodeAttribute=!0,this.name=e,this.type=t,this.node=r}}class aN{constructor(e,t,r){this.isNodeUniform=!0,this.name=e,this.type=t,this.node=r}get value(){return this.node.value}set value(e){this.node.value=e}get id(){return this.node.id}get groupNode(){return this.node.groupNode}}class oN{constructor(e,t,r=!1,s=null){this.isNodeVar=!0,this.name=e,this.type=t,this.readOnly=r,this.count=s}}class uN extends oN{constructor(e,t,r=null,s=null){super(e,t),this.needsInterpolation=!1,this.isNodeVarying=!0,this.interpolationType=r,this.interpolationSampling=s}}class lN{constructor(e,t,r=""){this.name=e,this.type=t,this.code=r,Object.defineProperty(this,"isNodeCode",{value:!0})}}let dN=0;class cN{constructor(e=null){this.id=dN++,this.nodesData=new WeakMap,this.parent=e}getData(e){let t=this.nodesData.get(e);return void 0===t&&null!==this.parent&&(t=this.parent.getData(e)),t}setData(e,t){this.nodesData.set(e,t)}}class hN{constructor(e,t){this.name=e,this.members=t,this.output=!1}}class pN{constructor(e,t){this.name=e,this.value=t,this.boundary=0,this.itemSize=0,this.offset=0,this.index=-1}setValue(e){this.value=e}getValue(){return this.value}}class gN extends pN{constructor(e,t=0){super(e,t),this.isNumberUniform=!0,this.boundary=4,this.itemSize=1}}class mN extends pN{constructor(e,r=new t){super(e,r),this.isVector2Uniform=!0,this.boundary=8,this.itemSize=2}}class fN extends pN{constructor(e,t=new r){super(e,t),this.isVector3Uniform=!0,this.boundary=16,this.itemSize=3}}class yN extends pN{constructor(e,t=new s){super(e,t),this.isVector4Uniform=!0,this.boundary=16,this.itemSize=4}}class bN extends pN{constructor(t,r=new e){super(t,r),this.isColorUniform=!0,this.boundary=16,this.itemSize=3}}class xN extends pN{constructor(e,t=new i){super(e,t),this.isMatrix2Uniform=!0,this.boundary=8,this.itemSize=4}}class TN extends pN{constructor(e,t=new n){super(e,t),this.isMatrix3Uniform=!0,this.boundary=48,this.itemSize=12}}class _N extends pN{constructor(e,t=new a){super(e,t),this.isMatrix4Uniform=!0,this.boundary=64,this.itemSize=16}}class vN extends gN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class NN extends mN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class SN extends fN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class RN extends yN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class AN extends bN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class EN extends xN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class wN extends TN{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}class CN extends _N{constructor(e){super(e.name,e.value),this.nodeUniform=e}getValue(){return this.nodeUniform.value}getType(){return this.nodeUniform.type}}let MN=0;const BN=new WeakMap,FN=new WeakMap,LN=new Map([[Int8Array,"int"],[Int16Array,"int"],[Int32Array,"int"],[Uint8Array,"uint"],[Uint16Array,"uint"],[Uint32Array,"uint"],[Float32Array,"float"]]),PN=e=>/e/g.test(e)?String(e).replace(/\+/g,""):(e=Number(e))+(e%1?"":".0");class DN{constructor(e,t,r){this.object=e,this.material=e&&e.material||null,this.geometry=e&&e.geometry||null,this.renderer=t,this.parser=r,this.scene=null,this.camera=null,this.nodes=[],this.sequentialNodes=[],this.updateNodes=[],this.updateBeforeNodes=[],this.updateAfterNodes=[],this.hashNodes={},this.observer=null,this.lightsNode=null,this.environmentNode=null,this.fogNode=null,this.clippingContext=null,this.vertexShader=null,this.fragmentShader=null,this.computeShader=null,this.flowNodes={vertex:[],fragment:[],compute:[]},this.flowCode={vertex:"",fragment:"",compute:""},this.uniforms={vertex:[],fragment:[],compute:[],index:0},this.structs={vertex:[],fragment:[],compute:[],index:0},this.types={vertex:[],fragment:[],compute:[],index:0},this.bindings={vertex:{},fragment:{},compute:{}},this.bindingsIndexes={},this.bindGroups=null,this.attributes=[],this.bufferAttributes=[],this.varyings=[],this.codes={},this.vars={},this.declarations={},this.flow={code:""},this.chaining=[],this.stack=Dy(),this.stacks=[],this.tab="\t",this.currentFunctionNode=null,this.context={material:this.material},this.cache=new cN,this.globalCache=this.cache,this.flowsData=new WeakMap,this.shaderStage=null,this.buildStage=null,this.subBuildLayers=[],this.activeStacks=[],this.subBuildFn=null,this.fnCall=null,Object.defineProperty(this,"id",{value:MN++})}isFlatShading(){return!0===this.material.flatShading||!1===this.geometry.hasAttribute("normal")}isOpaque(){const e=this.material;return!1===e.transparent&&e.blending===Ge&&!1===e.alphaToCoverage}getBindGroupsCache(){let e=FN.get(this.renderer);return void 0===e&&(e=new Yf,FN.set(this.renderer,e)),e}createRenderTarget(e,t,r){return new se(e,t,r)}createCubeRenderTarget(e,t){return new og(e,t)}includes(e){return this.nodes.includes(e)}getOutputStructName(){}_getBindGroup(e,t){const r=this.getBindGroupsCache(),s=[];let i,n=!0;for(const e of t)s.push(e),n=n&&e.groupNode.shared;return n?(i=r.get(s),void 0===i&&(i=new sN(e,s,this.bindingsIndexes[e].group),r.set(s,i))):i=new sN(e,s,this.bindingsIndexes[e].group),i}getBindGroupArray(e,t){const r=this.bindings[t];let s=r[e];return void 0===s&&(void 0===this.bindingsIndexes[e]&&(this.bindingsIndexes[e]={binding:0,group:Object.keys(this.bindingsIndexes).length}),r[e]=s=[]),s}getBindings(){let e=this.bindGroups;if(null===e){const t={},r=this.bindings;for(const e of si)for(const s in r[e]){const i=r[e][s],n=t[s]||(t[s]=[]);for(const e of i)!1===n.includes(e)&&n.push(e)}e=[];for(const r in t){const s=t[r],i=this._getBindGroup(r,s);e.push(i)}this.bindGroups=e}return e}sortBindingGroups(){const e=this.getBindings();e.sort((e,t)=>e.bindings[0].groupNode.order-t.bindings[0].groupNode.order);for(let t=0;t=0?`${Math.round(n)}u`:"0u";if("bool"===i)return n?"true":"false";if("color"===i)return`${this.getType("vec3")}( ${PN(n.r)}, ${PN(n.g)}, ${PN(n.b)} )`;const a=this.getTypeLength(i),o=this.getComponentType(i),u=e=>this.generateConst(o,e);if(2===a)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)} )`;if(3===a)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)}, ${u(n.z)} )`;if(4===a&&"mat2"!==i)return`${this.getType(i)}( ${u(n.x)}, ${u(n.y)}, ${u(n.z)}, ${u(n.w)} )`;if(a>=4&&n&&(n.isMatrix2||n.isMatrix3||n.isMatrix4))return`${this.getType(i)}( ${n.elements.map(u).join(", ")} )`;if(a>4)return`${this.getType(i)}()`;throw new Error(`NodeBuilder: Type '${i}' not found in generate constant attempt.`)}getType(e){return"color"===e?"vec3":e}hasGeometryAttribute(e){return this.geometry&&void 0!==this.geometry.getAttribute(e)}getAttribute(e,t){const r=this.attributes;for(const t of r)if(t.name===e)return t;const s=new nN(e,t);return this.registerDeclaration(s),r.push(s),s}getPropertyName(e){return e.name}isVector(e){return/vec\d/.test(e)}isMatrix(e){return/mat\d/.test(e)}isReference(e){return"void"===e||"property"===e||"sampler"===e||"samplerComparison"===e||"texture"===e||"cubeTexture"===e||"storageTexture"===e||"depthTexture"===e||"texture3D"===e}needsToWorkingColorSpace(){return!1}getComponentTypeFromTexture(e){const t=e.type;if(e.isDataTexture){if(t===R)return"int";if(t===S)return"uint"}return"float"}getElementType(e){return"mat2"===e?"vec2":"mat3"===e?"vec3":"mat4"===e?"vec4":this.getComponentType(e)}getComponentType(e){if("float"===(e=this.getVectorType(e))||"bool"===e||"int"===e||"uint"===e)return e;const t=/(b|i|u|)(vec|mat)([2-4])/.exec(e);return null===t?null:"b"===t[1]?"bool":"i"===t[1]?"int":"u"===t[1]?"uint":"float"}getVectorType(e){return"color"===e?"vec3":"texture"===e||"cubeTexture"===e||"storageTexture"===e||"texture3D"===e?"vec4":e}getTypeFromLength(e,t="float"){if(1===e)return t;let r=ks(e);const s="float"===t?"":t[0];return!0===/mat2/.test(t)&&(r=r.replace("vec","mat")),s+r}getTypeFromArray(e){return LN.get(e.constructor)}isInteger(e){return/int|uint|(i|u)vec/.test(e)}getTypeFromAttribute(e){let t=e;e.isInterleavedBufferAttribute&&(t=e.data);const r=t.array,s=e.itemSize,i=e.normalized;let n;return e instanceof at||!0===i||(n=this.getTypeFromArray(r)),this.getTypeFromLength(s,n)}getTypeLength(e){const t=this.getVectorType(e),r=/vec([2-4])/.exec(t);return null!==r?Number(r[1]):"float"===t||"bool"===t||"int"===t||"uint"===t?1:!0===/mat2/.test(e)?4:!0===/mat3/.test(e)?9:!0===/mat4/.test(e)?16:0}getVectorFromMatrix(e){return e.replace("mat","vec")}changeComponentType(e,t){return this.getTypeFromLength(this.getTypeLength(e),t)}getIntegerType(e){const t=this.getComponentType(e);return"int"===t||"uint"===t?e:this.changeComponentType(e,"int")}setActiveStack(e){this.activeStacks.push(e)}removeActiveStack(e){if(this.activeStacks[this.activeStacks.length-1]!==e)throw new Error("NodeBuilder: Invalid active stack removal.");this.activeStacks.pop()}getActiveStack(){return this.activeStacks[this.activeStacks.length-1]}getBaseStack(){return this.activeStacks[0]}addStack(){this.stack=Dy(this.stack);const e=ln();return this.stacks.push(e),un(this.stack),this.stack}removeStack(){const e=this.stack;for(const t of e.nodes){this.getDataFromNode(t).stack=e}return this.stack=e.parent,un(this.stacks.pop()),e}getDataFromNode(e,t=this.shaderStage,r=null){let s=(r=null===r?e.isGlobal(this)?this.globalCache:this.cache:r).getData(e);void 0===s&&(s={},r.setData(e,s)),void 0===s[t]&&(s[t]={});let i=s[t];const n=s.any?s.any.subBuilds:null,a=this.getClosestSubBuild(n);return a&&(void 0===i.subBuildsCache&&(i.subBuildsCache={}),i=i.subBuildsCache[a]||(i.subBuildsCache[a]={}),i.subBuilds=n),i}getNodeProperties(e,t="any"){const r=this.getDataFromNode(e,t);return r.properties||(r.properties={outputNode:null})}getBufferAttributeFromNode(e,t){const r=this.getDataFromNode(e,"vertex");let s=r.bufferAttribute;if(void 0===s){const i=this.uniforms.index++;s=new nN("nodeAttribute"+i,t,e),this.bufferAttributes.push(s),r.bufferAttribute=s}return s}getStructTypeNode(e,t=this.shaderStage){return this.types[t][e]||null}getStructTypeFromNode(e,t,r=null,s=this.shaderStage){const i=this.getDataFromNode(e,s,this.globalCache);let n=i.structType;if(void 0===n){const a=this.structs.index++;null===r&&(r="StructType"+a),n=new hN(r,t),this.structs[s].push(n),this.types[s][r]=e,i.structType=n}return n}getOutputStructTypeFromNode(e,t){const r=this.getStructTypeFromNode(e,t,"OutputType","fragment");return r.output=!0,r}getUniformFromNode(e,t,r=this.shaderStage,s=null){const i=this.getDataFromNode(e,r,this.globalCache);let n=i.uniform;if(void 0===n){const a=this.uniforms.index++;n=new aN(s||"nodeUniform"+a,t,e),this.uniforms[r].push(n),this.registerDeclaration(n),i.uniform=n}return n}getVarFromNode(e,t=null,r=e.getNodeType(this),s=this.shaderStage,i=!1){const n=this.getDataFromNode(e,s),a=this.getSubBuildProperty("variable",n.subBuilds);let o=n[a];if(void 0===o){const u=i?"_const":"_var",l=this.vars[s]||(this.vars[s]=[]),d=this.vars[u]||(this.vars[u]=0);null===t&&(t=(i?"nodeConst":"nodeVar")+d,this.vars[u]++),"variable"!==a&&(t=this.getSubBuildProperty(t,n.subBuilds));const c=e.getArrayCount(this);o=new oN(t,r,i,c),i||l.push(o),this.registerDeclaration(o),n[a]=o}return o}isDeterministic(e){if(e.isMathNode)return this.isDeterministic(e.aNode)&&(!e.bNode||this.isDeterministic(e.bNode))&&(!e.cNode||this.isDeterministic(e.cNode));if(e.isOperatorNode)return this.isDeterministic(e.aNode)&&(!e.bNode||this.isDeterministic(e.bNode));if(e.isArrayNode){if(null!==e.values)for(const t of e.values)if(!this.isDeterministic(t))return!1;return!0}return!!e.isConstNode}getVaryingFromNode(e,t=null,r=e.getNodeType(this),s=null,i=null){const n=this.getDataFromNode(e,"any"),a=this.getSubBuildProperty("varying",n.subBuilds);let o=n[a];if(void 0===o){const e=this.varyings,u=e.length;null===t&&(t="nodeVarying"+u),"varying"!==a&&(t=this.getSubBuildProperty(t,n.subBuilds)),o=new uN(t,r,s,i),e.push(o),this.registerDeclaration(o),n[a]=o}return o}registerDeclaration(e){const t=this.shaderStage,r=this.declarations[t]||(this.declarations[t]={}),s=this.getPropertyName(e);let i=1,n=s;for(;void 0!==r[n];)n=s+"_"+i++;i>1&&(e.name=n,d(`TSL: Declaration name '${s}' of '${e.type}' already in use. Renamed to '${n}'.`)),r[n]=e}getCodeFromNode(e,t,r=this.shaderStage){const s=this.getDataFromNode(e);let i=s.code;if(void 0===i){const e=this.codes[r]||(this.codes[r]=[]),n=e.length;i=new lN("nodeCode"+n,t),e.push(i),s.code=i}return i}addFlowCodeHierarchy(e,t){const{flowCodes:r,flowCodeBlock:s}=this.getDataFromNode(e);let i=!0,n=t;for(;n;){if(!0===s.get(n)){i=!1;break}n=this.getDataFromNode(n).parentNodeBlock}if(i)for(const e of r)this.addLineFlowCode(e)}addLineFlowCodeBlock(e,t,r){const s=this.getDataFromNode(e),i=s.flowCodes||(s.flowCodes=[]),n=s.flowCodeBlock||(s.flowCodeBlock=new WeakMap);i.push(t),n.set(r,!0)}addLineFlowCode(e,t=null){return""===e||(null!==t&&this.context.nodeBlock&&this.addLineFlowCodeBlock(t,e,this.context.nodeBlock),e=this.tab+e,/;\s*$/.test(e)||(e+=";\n"),this.flow.code+=e),this}addFlowCode(e){return this.flow.code+=e,this}addFlowTab(){return this.tab+="\t",this}removeFlowTab(){return this.tab=this.tab.slice(0,-1),this}getFlowData(e){return this.flowsData.get(e)}flowNode(e){const t=e.getNodeType(this),r=this.flowChildNode(e,t);return this.flowsData.set(e,r),r}addInclude(e){null!==this.currentFunctionNode&&this.currentFunctionNode.includes.push(e)}buildFunctionNode(e){const t=new Yx,r=this.currentFunctionNode;return this.currentFunctionNode=t,t.code=this.buildFunctionCode(e),this.currentFunctionNode=r,t}flowShaderNode(e){const t=e.layout,r={[Symbol.iterator](){let e=0;const t=Object.values(this);return{next:()=>({value:t[e],done:e++>=t.length})}}};for(const e of t.inputs)r[e.name]=new Ly(e.type,e.name);e.layout=null;const s=e.call(r),i=this.flowStagesNode(s,t.type);return e.layout=t,i}flowBuildStage(e,t,r=null){const s=this.getBuildStage();this.setBuildStage(t);const i=e.build(this,r);return this.setBuildStage(s),i}flowStagesNode(e,t=null){const r=this.flow,s=this.vars,i=this.declarations,n=this.cache,a=this.buildStage,o=this.stack,u={code:""};this.flow=u,this.vars={},this.declarations={},this.cache=new cN,this.stack=Dy();for(const r of ri)this.setBuildStage(r),u.result=e.build(this,t);return u.vars=this.getVars(this.shaderStage),this.flow=r,this.vars=s,this.declarations=i,this.cache=n,this.stack=o,this.setBuildStage(a),u}getFunctionOperator(){return null}buildFunctionCode(){d("Abstract function.")}flowChildNode(e,t=null){const r=this.flow,s={code:""};return this.flow=s,s.result=e.build(this,t),this.flow=r,s}flowNodeFromShaderStage(e,t,r=null,s=null){const i=this.tab,n=this.cache,a=this.shaderStage,o=this.context;this.setShaderStage(e);const u={...this.context};delete u.nodeBlock,this.cache=this.globalCache,this.tab="\t",this.context=u;let l=null;if("generate"===this.buildStage){const i=this.flowChildNode(t,r);null!==s&&(i.code+=`${this.tab+s} = ${i.result};\n`),this.flowCode[e]=this.flowCode[e]+i.code,l=i}else l=t.build(this);return this.setShaderStage(a),this.cache=n,this.tab=i,this.context=o,l}getAttributesArray(){return this.attributes.concat(this.bufferAttributes)}getAttributes(){d("Abstract function.")}getVaryings(){d("Abstract function.")}getVar(e,t,r=null){return`${null!==r?this.generateArrayDeclaration(e,r):this.getType(e)} ${t}`}getVars(e){let t="";const r=this.vars[e];if(void 0!==r)for(const e of r)t+=`${this.getVar(e.type,e.name)}; `;return t}getUniforms(){d("Abstract function.")}getCodes(e){const t=this.codes[e];let r="";if(void 0!==t)for(const e of t)r+=e.code+"\n";return r}getHash(){return this.vertexShader+this.fragmentShader+this.computeShader}setShaderStage(e){this.shaderStage=e}getShaderStage(){return this.shaderStage}setBuildStage(e){this.buildStage=e}getBuildStage(){return this.buildStage}buildCode(){d("Abstract function.")}get subBuild(){return this.subBuildLayers[this.subBuildLayers.length-1]||null}addSubBuild(e){this.subBuildLayers.push(e)}removeSubBuild(){return this.subBuildLayers.pop()}getClosestSubBuild(e){let t;if(t=e&&e.isNode?e.isShaderCallNodeInternal?e.shaderNode.subBuilds:e.isStackNode?[e.subBuild]:this.getDataFromNode(e,"any").subBuilds:e instanceof Set?[...e]:e,!t)return null;const r=this.subBuildLayers;for(let e=t.length-1;e>=0;e--){const s=t[e];if(r.includes(s))return s}return null}getSubBuildOutput(e){return this.getSubBuildProperty("outputNode",e)}getSubBuildProperty(e="",t=null){let r,s;return r=null!==t?this.getClosestSubBuild(t):this.subBuildFn,s=r?e?r+"_"+e:r:e,s}build(){const{object:e,material:t,renderer:r}=this;if(null!==t){let e=r.library.fromMaterial(t);null===e&&(o(`NodeMaterial: Material "${t.type}" is not compatible.`),e=new Qp),e.build(this)}else this.addFlow("compute",e);for(const e of ri){this.setBuildStage(e),this.context.position&&this.context.position.isNode&&this.flowNodeFromShaderStage("vertex",this.context.position);for(const t of si){this.setShaderStage(t);const r=this.flowNodes[t];for(const t of r)"generate"===e?this.flowNode(t):t.build(this)}}return this.setBuildStage(null),this.setShaderStage(null),this.buildCode(),this.buildUpdateNodes(),this}getSharedDataFromNode(e){let t=BN.get(e);return void 0===t&&(t={}),t}getNodeUniform(e,t){const r=this.getSharedDataFromNode(e);let s=r.cache;if(void 0===s){if("float"===t||"int"===t||"uint"===t)s=new vN(e);else if("vec2"===t||"ivec2"===t||"uvec2"===t)s=new NN(e);else if("vec3"===t||"ivec3"===t||"uvec3"===t)s=new SN(e);else if("vec4"===t||"ivec4"===t||"uvec4"===t)s=new RN(e);else if("color"===t)s=new AN(e);else if("mat2"===t)s=new EN(e);else if("mat3"===t)s=new wN(e);else{if("mat4"!==t)throw new Error(`Uniform "${t}" not implemented.`);s=new CN(e)}r.cache=s}return s}format(e,t,r){if((t=this.getVectorType(t))===(r=this.getVectorType(r))||null===r||this.isReference(r))return e;const s=this.getTypeLength(t),i=this.getTypeLength(r);return 16===s&&9===i?`${this.getType(r)}( ${e}[ 0 ].xyz, ${e}[ 1 ].xyz, ${e}[ 2 ].xyz )`:9===s&&4===i?`${this.getType(r)}( ${e}[ 0 ].xy, ${e}[ 1 ].xy )`:s>4||i>4||0===i?e:s===i?`${this.getType(r)}( ${e} )`:s>i?(e="bool"===r?`all( ${e} )`:`${e}.${"xyz".slice(0,i)}`,this.format(e,this.getTypeFromLength(i,this.getComponentType(t)),r)):4===i&&s>1?`${this.getType(r)}( ${this.format(e,t,"vec3")}, 1.0 )`:2===s?`${this.getType(r)}( ${this.format(e,t,"vec2")}, 0.0 )`:(1===s&&i>1&&t!==this.getComponentType(r)&&(e=`${this.getType(this.getComponentType(r))}( ${e} )`),`${this.getType(r)}( ${e} )`)}getSignature(){return`// Three.js r${ot} - Node System\n`}needsPreviousData(){const e=this.renderer.getMRT();return e&&e.has("velocity")||!0===js(this.object).useVelocity}}class UN{constructor(){this.time=0,this.deltaTime=0,this.frameId=0,this.renderId=0,this.updateMap=new WeakMap,this.updateBeforeMap=new WeakMap,this.updateAfterMap=new WeakMap,this.renderer=null,this.material=null,this.camera=null,this.object=null,this.scene=null}_getMaps(e,t){let r=e.get(t);return void 0===r&&(r={renderId:0,frameId:0},e.set(t,r)),r}updateBeforeNode(e){const t=e.getUpdateBeforeType(),r=e.updateReference(this);if(t===Zs.FRAME){const t=this._getMaps(this.updateBeforeMap,r);if(t.frameId!==this.frameId){const r=t.frameId;t.frameId=this.frameId,!1===e.updateBefore(this)&&(t.frameId=r)}}else if(t===Zs.RENDER){const t=this._getMaps(this.updateBeforeMap,r);if(t.renderId!==this.renderId){const r=t.renderId;t.renderId=this.renderId,!1===e.updateBefore(this)&&(t.renderId=r)}}else t===Zs.OBJECT&&e.updateBefore(this)}updateAfterNode(e){const t=e.getUpdateAfterType(),r=e.updateReference(this);if(t===Zs.FRAME){const t=this._getMaps(this.updateAfterMap,r);t.frameId!==this.frameId&&!1!==e.updateAfter(this)&&(t.frameId=this.frameId)}else if(t===Zs.RENDER){const t=this._getMaps(this.updateAfterMap,r);t.renderId!==this.renderId&&!1!==e.updateAfter(this)&&(t.renderId=this.renderId)}else t===Zs.OBJECT&&e.updateAfter(this)}updateNode(e){const t=e.getUpdateType(),r=e.updateReference(this);if(t===Zs.FRAME){const t=this._getMaps(this.updateMap,r);t.frameId!==this.frameId&&!1!==e.update(this)&&(t.frameId=this.frameId)}else if(t===Zs.RENDER){const t=this._getMaps(this.updateMap,r);t.renderId!==this.renderId&&!1!==e.update(this)&&(t.renderId=this.renderId)}else t===Zs.OBJECT&&e.update(this)}update(){this.frameId++,void 0===this.lastTime&&(this.lastTime=performance.now()),this.deltaTime=(performance.now()-this.lastTime)/1e3,this.lastTime=performance.now(),this.time+=this.deltaTime}}class IN{constructor(e,t,r=null,s="",i=!1){this.type=e,this.name=t,this.count=r,this.qualifier=s,this.isConst=i}}IN.isNodeFunctionInput=!0;class ON extends J_{static get type(){return"AmbientLightNode"}constructor(e=null){super(e)}setup({context:e}){e.irradiance.addAssign(this.colorNode)}}class VN extends J_{static get type(){return"DirectionalLightNode"}constructor(e=null){super(e)}setupDirect(){const e=this.colorNode;return{lightDirection:o_(this.light),lightColor:e}}}class kN extends J_{static get type(){return"HemisphereLightNode"}constructor(t=null){super(t),this.lightPositionNode=i_(t),this.lightDirectionNode=this.lightPositionNode.normalize(),this.groundColorNode=Ta(new e).setGroup(ya)}update(e){const{light:t}=this;super.update(e),this.lightPositionNode.object3d=t,this.groundColorNode.value.copy(t.groundColor).multiplyScalar(t.intensity)}setup(e){const{colorNode:t,groundColorNode:r,lightDirectionNode:s}=this,i=Xd.dot(s).mul(.5).add(.5),n=iu(r,t,i);e.context.irradiance.addAssign(n)}}class GN extends J_{static get type(){return"SpotLightNode"}constructor(e=null){super(e),this.coneCosNode=Ta(0).setGroup(ya),this.penumbraCosNode=Ta(0).setGroup(ya),this.cutoffDistanceNode=Ta(0).setGroup(ya),this.decayExponentNode=Ta(0).setGroup(ya),this.colorNode=Ta(this.color).setGroup(ya)}update(e){super.update(e);const{light:t}=this;this.coneCosNode.value=Math.cos(t.angle),this.penumbraCosNode.value=Math.cos(t.angle*(1-t.penumbra)),this.cutoffDistanceNode.value=t.distance,this.decayExponentNode.value=t.decay}getSpotAttenuation(e,t){const{coneCosNode:r,penumbraCosNode:s}=this;return uu(r,s,t)}getLightCoord(e){const t=e.getNodeProperties(this);let r=t.projectionUV;return void 0===r&&(r=s_(this.light,e.context.positionWorld),t.projectionUV=r),r}setupDirect(e){const{colorNode:t,cutoffDistanceNode:r,decayExponentNode:s,light:i}=this,n=this.getLightVector(e),a=n.normalize(),o=a.dot(o_(i)),u=this.getSpotAttenuation(e,o),l=n.length(),d=ev({lightDistance:l,cutoffDistance:r,decayExponent:s});let c,h,p=t.mul(u).mul(d);if(i.colorNode?(h=this.getLightCoord(e),c=i.colorNode(h)):i.map&&(h=this.getLightCoord(e),c=Fl(i.map,h.xy).onRenderUpdate(()=>i.map)),c){p=h.mul(2).sub(1).abs().lessThan(1).all().select(p.mul(c),p)}return{lightColor:p,lightDirection:a}}}class zN extends GN{static get type(){return"IESSpotLightNode"}getSpotAttenuation(e,t){const r=this.light.iesMap;let s=null;if(r&&!0===r.isTexture){const e=t.acos().mul(1/Math.PI);s=Fl(r,yn(e,0),0).r}else s=super.getSpotAttenuation(t);return s}}class $N extends J_{static get type(){return"LightProbeNode"}constructor(e=null){super(e);const t=[];for(let e=0;e<9;e++)t.push(new r);this.lightProbe=Ol(t)}update(e){const{light:t}=this;super.update(e);for(let e=0;e<9;e++)this.lightProbe.array[e].copy(t.sh.coefficients[e]).multiplyScalar(t.intensity)}setup(e){const t=Zv(Xd,this.lightProbe);e.context.irradiance.addAssign(t)}}const WN=on(([e,t])=>{const r=e.abs().sub(t);return Bo(Wo(r,0)).add($o(Wo(r.x,r.y),0))});class HN extends GN{static get type(){return"ProjectorLightNode"}update(e){super.update(e);const t=this.light;if(this.penumbraCosNode.value=Math.min(Math.cos(t.angle*(1-t.penumbra)),.99999),null===t.aspect){let e=1;null!==t.map&&(e=t.map.width/t.map.height),t.shadow.aspect=e}else t.shadow.aspect=t.aspect}getSpotAttenuation(e){const t=pn(0),r=this.penumbraCosNode,s=r_(this.light).mul(e.context.positionWorld||Pd);return dn(s.w.greaterThan(0),()=>{const e=s.xyz.div(s.w),i=WN(e.xy.sub(yn(.5)),yn(.5)),n=Fa(-1,Ma(1,Eo(r)).sub(1));t.assign(au(i.mul(-2).mul(n)))}),t}}const qN=new a,jN=new a;let XN=null;class KN extends J_{static get type(){return"RectAreaLightNode"}constructor(e=null){super(e),this.halfHeight=Ta(new r).setGroup(ya),this.halfWidth=Ta(new r).setGroup(ya),this.updateType=Zs.RENDER}update(e){super.update(e);const{light:t}=this,r=e.camera.matrixWorldInverse;jN.identity(),qN.copy(t.matrixWorld),qN.premultiply(r),jN.extractRotation(qN),this.halfWidth.value.set(.5*t.width,0,0),this.halfHeight.value.set(0,.5*t.height,0),this.halfWidth.value.applyMatrix4(jN),this.halfHeight.value.applyMatrix4(jN)}setupDirectRectArea(e){let t,r;e.isAvailable("float32Filterable")?(t=Fl(XN.LTC_FLOAT_1),r=Fl(XN.LTC_FLOAT_2)):(t=Fl(XN.LTC_HALF_1),r=Fl(XN.LTC_HALF_2));const{colorNode:s,light:i}=this;return{lightColor:s,lightPosition:a_(i),halfWidth:this.halfWidth,halfHeight:this.halfHeight,ltc_1:t,ltc_2:r}}static setLTC(e){XN=e}}class YN{parseFunction(){d("Abstract function.")}}class QN{constructor(e,t,r="",s=""){this.type=e,this.inputs=t,this.name=r,this.precision=s}getCode(){d("Abstract function.")}}QN.isNodeFunction=!0;const ZN=/^\s*(highp|mediump|lowp)?\s*([a-z_0-9]+)\s*([a-z_0-9]+)?\s*\(([\s\S]*?)\)/i,JN=/[a-z_0-9]+/gi,eS="#pragma main";class tS extends QN{constructor(e){const{type:t,inputs:r,name:s,precision:i,inputsCode:n,blockCode:a,headerCode:o}=(e=>{const t=(e=e.trim()).indexOf(eS),r=-1!==t?e.slice(t+12):e,s=r.match(ZN);if(null!==s&&5===s.length){const i=s[4],n=[];let a=null;for(;null!==(a=JN.exec(i));)n.push(a);const o=[];let u=0;for(;u{const r=this.backend.createNodeBuilder(e.object,this.renderer);return r.scene=e.scene,r.material=t,r.camera=e.camera,r.context.material=t,r.lightsNode=e.lightsNode,r.environmentNode=this.getEnvironmentNode(e.scene),r.fogNode=this.getFogNode(e.scene),r.clippingContext=e.clippingContext,this.renderer.getOutputRenderTarget()&&this.renderer.getOutputRenderTarget().multiview&&r.enableMultiview(),r};let n=t(e.material);try{n.build()}catch(e){n=t(new Qp),n.build(),o("TSL: "+e)}r=this._createNodeBuilderState(n),s.set(i,r)}r.usedTimes++,t.nodeBuilderState=r}return r}delete(e){if(e.isRenderObject){const t=this.get(e).nodeBuilderState;t.usedTimes--,0===t.usedTimes&&this.nodeBuilderCache.delete(this.getForRenderCacheKey(e))}return super.delete(e)}getForCompute(e){const t=this.get(e);let r=t.nodeBuilderState;if(void 0===r){const s=this.backend.createNodeBuilder(e,this.renderer);s.build(),r=this._createNodeBuilderState(s),t.nodeBuilderState=r}return r}_createNodeBuilderState(e){return new iN(e.vertexShader,e.fragmentShader,e.computeShader,e.getAttributesArray(),e.getBindings(),e.updateNodes,e.updateBeforeNodes,e.updateAfterNodes,e.observer,e.transforms)}getEnvironmentNode(e){this.updateEnvironment(e);let t=null;if(e.environmentNode&&e.environmentNode.isNode)t=e.environmentNode;else{const r=this.get(e);r.environmentNode&&(t=r.environmentNode)}return t}getBackgroundNode(e){this.updateBackground(e);let t=null;if(e.backgroundNode&&e.backgroundNode.isNode)t=e.backgroundNode;else{const r=this.get(e);r.backgroundNode&&(t=r.backgroundNode)}return t}getFogNode(e){return this.updateFog(e),e.fogNode||this.get(e).fogNode||null}getCacheKey(e,t){iS[0]=e,iS[1]=t;const r=this.renderer.info.calls,s=this.callHashCache.get(iS)||{};if(s.callId!==r){const i=this.getEnvironmentNode(e),n=this.getFogNode(e);t&&nS.push(t.getCacheKey(!0)),i&&nS.push(i.getCacheKey()),n&&nS.push(n.getCacheKey()),nS.push(this.renderer.getOutputRenderTarget()&&this.renderer.getOutputRenderTarget().multiview?1:0),nS.push(this.renderer.shadowMap.enabled?1:0),nS.push(this.renderer.shadowMap.type),s.callId=r,s.cacheKey=Us(nS),this.callHashCache.set(iS,s),nS.length=0}return iS[0]=null,iS[1]=null,s.cacheKey}get isToneMappingState(){return!this.renderer.getRenderTarget()}updateBackground(e){const t=this.get(e),r=e.background;if(r){const s=0===e.backgroundBlurriness&&t.backgroundBlurriness>0||e.backgroundBlurriness>0&&0===t.backgroundBlurriness;if(t.background!==r||s){const i=this.getCacheNode("background",r,()=>{if(!0===r.isCubeTexture||r.mapping===le||r.mapping===de||r.mapping===Re){if(e.backgroundBlurriness>0||r.mapping===Re)return mf(r);{let e;return e=!0===r.isCubeTexture?pc(r):Fl(r),hg(e)}}if(!0===r.isTexture)return Fl(r,Hl.flipY()).setUpdateMatrix(!0);!0!==r.isColor&&o("WebGPUNodes: Unsupported background configuration.",r)},s);t.backgroundNode=i,t.background=r,t.backgroundBlurriness=e.backgroundBlurriness}}else t.backgroundNode&&(delete t.backgroundNode,delete t.background)}getCacheNode(e,t,r,s=!1){const i=this.cacheLib[e]||(this.cacheLib[e]=new WeakMap);let n=i.get(t);return(void 0===n||s)&&(n=r(),i.set(t,n)),n}updateFog(e){const t=this.get(e),r=e.fog;if(r){if(t.fog!==r){const e=this.getCacheNode("fog",r,()=>{if(r.isFogExp2){const e=fc("color","color",r).setGroup(ya),t=fc("density","float",r).setGroup(ya);return lT(e,oT(t))}if(r.isFog){const e=fc("color","color",r).setGroup(ya),t=fc("near","float",r).setGroup(ya),s=fc("far","float",r).setGroup(ya);return lT(e,aT(t,s))}o("Renderer: Unsupported fog configuration.",r)});t.fogNode=e,t.fog=r}}else delete t.fogNode,delete t.fog}updateEnvironment(e){const t=this.get(e),r=e.environment;if(r){if(t.environment!==r){const e=this.getCacheNode("environment",r,()=>!0===r.isCubeTexture?pc(r):!0===r.isTexture?Fl(r):void o("Nodes: Unsupported environment configuration.",r));t.environmentNode=e,t.environment=r}}else t.environmentNode&&(delete t.environmentNode,delete t.environment)}getNodeFrame(e=this.renderer,t=null,r=null,s=null,i=null){const n=this.nodeFrame;return n.renderer=e,n.scene=t,n.object=r,n.camera=s,n.material=i,n}getNodeFrameForRender(e){return this.getNodeFrame(e.renderer,e.scene,e.object,e.camera,e.material)}getOutputCacheKey(){const e=this.renderer;return e.toneMapping+","+e.currentColorSpace+","+e.xr.isPresenting}hasOutputChange(e){return sS.get(e)!==this.getOutputCacheKey()}getOutputNode(e){const t=this.renderer,r=this.getOutputCacheKey(),s=e.isArrayTexture?mx(e,_n(Hl,kl("gl_ViewID_OVR"))).renderOutput(t.toneMapping,t.currentColorSpace):Fl(e,Hl).renderOutput(t.toneMapping,t.currentColorSpace);return sS.set(e,r),s}updateBefore(e){const t=e.getNodeBuilderState();for(const r of t.updateBeforeNodes)this.getNodeFrameForRender(e).updateBeforeNode(r)}updateAfter(e){const t=e.getNodeBuilderState();for(const r of t.updateAfterNodes)this.getNodeFrameForRender(e).updateAfterNode(r)}updateForCompute(e){const t=this.getNodeFrame(),r=this.getForCompute(e);for(const e of r.updateNodes)t.updateNode(e)}updateForRender(e){const t=this.getNodeFrameForRender(e),r=e.getNodeBuilderState();for(const e of r.updateNodes)t.updateNode(e)}needsRefresh(e){const t=this.getNodeFrameForRender(e);return e.getMonitor().needsRefresh(e,t)}dispose(){super.dispose(),this.nodeFrame=new UN,this.nodeBuilderCache=new Map,this.cacheLib={}}}const oS=new qe;class uS{constructor(e=null){this.version=0,this.clipIntersection=null,this.cacheKey="",this.shadowPass=!1,this.viewNormalMatrix=new n,this.clippingGroupContexts=new WeakMap,this.intersectionPlanes=[],this.unionPlanes=[],this.parentVersion=null,null!==e&&(this.viewNormalMatrix=e.viewNormalMatrix,this.clippingGroupContexts=e.clippingGroupContexts,this.shadowPass=e.shadowPass,this.viewMatrix=e.viewMatrix)}projectPlanes(e,t,r){const s=e.length;for(let i=0;i0,alpha:!0,depth:t.depth,stencil:t.stencil,framebufferScaleFactor:this.getFramebufferScaleFactor()},i=new XRWebGLLayer(e,s,r);this._glBaseLayer=i,e.updateRenderState({baseLayer:i}),t.setPixelRatio(1),t._setXRLayerSize(i.framebufferWidth,i.framebufferHeight),this._xrRenderTarget=new fS(i.framebufferWidth,i.framebufferHeight,{format:Se,type:ke,colorSpace:t.outputColorSpace,stencilBuffer:t.stencil,resolveDepthBuffer:!1===i.ignoreDepthValues,resolveStencilBuffer:!1===i.ignoreDepthValues}),this._xrRenderTarget._isOpaqueFramebuffer=!0,this._referenceSpace=await e.requestReferenceSpace(this.getReferenceSpaceType())}this.setFoveation(this.getFoveation()),t._animation.setAnimationLoop(this._onAnimationFrame),t._animation.setContext(e),t._animation.start(),this.isPresenting=!0,this.dispatchEvent({type:"sessionstart"})}}updateCamera(e){const t=this._session;if(null===t)return;const r=e.near,s=e.far,i=this._cameraXR,n=this._cameraL,a=this._cameraR;i.near=a.near=n.near=r,i.far=a.far=n.far=s,i.isMultiViewCamera=this._useMultiview,this._currentDepthNear===i.near&&this._currentDepthFar===i.far||(t.updateRenderState({depthNear:i.near,depthFar:i.far}),this._currentDepthNear=i.near,this._currentDepthFar=i.far),i.layers.mask=6|e.layers.mask,n.layers.mask=-5&i.layers.mask,a.layers.mask=-3&i.layers.mask;const o=e.parent,u=i.cameras;TS(i,o);for(let e=0;e=0&&(r[n]=null,t[n].disconnect(i))}for(let s=0;s=r.length){r.push(i),n=e;break}if(null===r[e]){r[e]=i,n=e;break}}if(-1===n)break}const a=t[n];a&&a.connect(i)}}function SS(e){return"quad"===e.type?this._glBinding.createQuadLayer({transform:new XRRigidTransform(e.translation,e.quaternion),width:e.width/2,height:e.height/2,space:this._referenceSpace,viewPixelWidth:e.pixelwidth,viewPixelHeight:e.pixelheight,clearOnAccess:!1}):this._glBinding.createCylinderLayer({transform:new XRRigidTransform(e.translation,e.quaternion),radius:e.radius,centralAngle:e.centralAngle,aspectRatio:e.aspectRatio,space:this._referenceSpace,viewPixelWidth:e.pixelwidth,viewPixelHeight:e.pixelheight,clearOnAccess:!1})}function RS(e,t){if(void 0===t)return;const r=this._cameraXR,i=this._renderer,n=i.backend,a=this._glBaseLayer,o=this.getReferenceSpace(),u=t.getViewerPose(o);if(this._xrFrame=t,null!==u){const e=u.views;null!==this._glBaseLayer&&n.setXRTarget(a.framebuffer);let t=!1;e.length!==r.cameras.length&&(r.cameras.length=0,t=!0);for(let i=0;i{await this.compileAsync(e,t);const s=this._renderLists.get(e,t),i=this._renderContexts.get(this._renderTarget,this._mrt),n=e.overrideMaterial||r.material,a=this._objects.get(r,n,e,t,s.lightsNode,i,i.clippingContext),{fragmentShader:o,vertexShader:u}=a.getNodeBuilderState();return{fragmentShader:o,vertexShader:u}}}}async init(){return null!==this._initPromise||(this._initPromise=new Promise(async(e,t)=>{let r=this.backend;try{await r.init(this)}catch(e){if(null===this._getFallback)return void t(e);try{this.backend=r=this._getFallback(e),await r.init(this)}catch(e){return void t(e)}}this._nodes=new aS(this,r),this._animation=new Kf(this,this._nodes,this.info),this._attributes=new oy(r),this._background=new tN(this,this._nodes),this._geometries=new cy(this._attributes,this.info),this._textures=new By(this,r,this.info),this._pipelines=new by(r,this._nodes),this._bindings=new xy(r,this._nodes,this._textures,this._attributes,this._pipelines,this.info),this._objects=new ey(this,this._nodes,this._geometries,this._pipelines,this._bindings,this.info),this._renderLists=new Ry(this.lighting),this._bundles=new cS,this._renderContexts=new Cy,this._animation.start(),this._initialized=!0,this._inspector.init(),e(this)})),this._initPromise}get domElement(){return this._canvasTarget.domElement}get coordinateSystem(){return this.backend.coordinateSystem}async compileAsync(e,t,r=null){if(!0===this._isDeviceLost)return;!1===this._initialized&&await this.init();const s=this._nodes.nodeFrame,i=s.renderId,n=this._currentRenderContext,a=this._currentRenderObjectFunction,o=this._handleObjectFunction,u=this._compilationPromises,l=!0===e.isScene?e:ES;null===r&&(r=e);const d=this._renderTarget,c=this._renderContexts.get(d,this._mrt),h=this._activeMipmapLevel,p=[];this._currentRenderContext=c,this._currentRenderObjectFunction=this.renderObject,this._handleObjectFunction=this._createObjectPipeline,this._compilationPromises=p,s.renderId++,s.update(),c.depth=this.depth,c.stencil=this.stencil,c.clippingContext||(c.clippingContext=new uS),c.clippingContext.updateGlobal(l,t),l.onBeforeRender(this,e,t,d);const g=this._renderLists.get(e,t);if(g.begin(),this._projectObject(e,t,0,g,c.clippingContext),r!==e&&r.traverseVisible(function(e){e.isLight&&e.layers.test(t.layers)&&g.pushLight(e)}),g.finish(),null!==d){this._textures.updateRenderTarget(d,h);const e=this._textures.get(d);c.textures=e.textures,c.depthTexture=e.depthTexture}else c.textures=null,c.depthTexture=null;r!==e?this._background.update(r,g,c):this._background.update(l,g,c);const m=g.opaque,f=g.transparent,y=g.transparentDoublePass,b=g.lightsNode;!0===this.opaque&&m.length>0&&this._renderObjects(m,t,l,b),!0===this.transparent&&f.length>0&&this._renderTransparents(f,y,t,l,b),s.renderId=i,this._currentRenderContext=n,this._currentRenderObjectFunction=a,this._handleObjectFunction=o,this._compilationPromises=u,await Promise.all(p)}async renderAsync(e,t){v('Renderer: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.render(e,t)}async waitForGPU(){o("Renderer: waitForGPU() has been removed. Read https://github.com/mrdoob/three.js/issues/32012 for more information.")}set inspector(e){null!==this._inspector&&this._inspector.setRenderer(null),this._inspector=e,this._inspector.setRenderer(this)}get inspector(){return this._inspector}set highPrecision(e){const t=this.contextNode.value;!0===e?(t.modelViewMatrix=wd,t.modelNormalViewMatrix=Cd):this.highPrecision&&(delete t.modelViewMatrix,delete t.modelNormalViewMatrix)}get highPrecision(){const e=this.contextNode.value;return e.modelViewMatrix===wd&&e.modelNormalViewMatrix===Cd}setMRT(e){return this._mrt=e,this}getMRT(){return this._mrt}getOutputBufferType(){return this._outputBufferType}getColorBufferType(){return v('Renderer: ".getColorBufferType()" has been renamed to ".getOutputBufferType()".'),this.getOutputBufferType()}_onDeviceLost(e){let t=`THREE.WebGPURenderer: ${e.api} Device Lost:\n\nMessage: ${e.message}`;e.reason&&(t+=`\nReason: ${e.reason}`),o(t),this._isDeviceLost=!0}_renderBundle(e,t,r){const{bundleGroup:s,camera:i,renderList:n}=e,a=this._currentRenderContext,o=this._bundles.get(s,i),u=this.backend.get(o);void 0===u.renderContexts&&(u.renderContexts=new Set);const l=s.version!==u.version,d=!1===u.renderContexts.has(a)||l;if(u.renderContexts.add(a),d){this.backend.beginBundle(a),(void 0===u.renderObjects||l)&&(u.renderObjects=[]),this._currentRenderBundle=o;const{transparentDoublePass:e,transparent:d,opaque:c}=n;!0===this.opaque&&c.length>0&&this._renderObjects(c,i,t,r),!0===this.transparent&&d.length>0&&this._renderTransparents(d,e,i,t,r),this._currentRenderBundle=null,this.backend.finishBundle(a,o),u.version=s.version}else{const{renderObjects:e}=u;for(let t=0,r=e.length;t>=h,g.viewportValue.height>>=h,g.viewportValue.minDepth=_,g.viewportValue.maxDepth=v,g.viewport=!1===g.viewportValue.equals(CS),g.scissorValue.copy(x).multiplyScalar(T).floor(),g.scissor=y._scissorTest&&!1===g.scissorValue.equals(CS),g.scissorValue.width>>=h,g.scissorValue.height>>=h,g.clippingContext||(g.clippingContext=new uS),g.clippingContext.updateGlobal(l,t),l.onBeforeRender(this,e,t,p);const N=t.isArrayCamera?BS:MS;t.isArrayCamera||(FS.multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse),N.setFromProjectionMatrix(FS,t.coordinateSystem,t.reversedDepth));const S=this._renderLists.get(e,t);if(S.begin(),this._projectObject(e,t,0,S,g.clippingContext),S.finish(),!0===this.sortObjects&&S.sort(this._opaqueSort,this._transparentSort),null!==p){this._textures.updateRenderTarget(p,h);const e=this._textures.get(p);g.textures=e.textures,g.depthTexture=e.depthTexture,g.width=e.width,g.height=e.height,g.renderTarget=p,g.depth=p.depthBuffer,g.stencil=p.stencilBuffer}else g.textures=null,g.depthTexture=null,g.width=wS.width,g.height=wS.height,g.depth=this.depth,g.stencil=this.stencil;g.width>>=h,g.height>>=h,g.activeCubeFace=c,g.activeMipmapLevel=h,g.occlusionQueryCount=S.occlusionQueryCount,g.scissorValue.max(LS.set(0,0,0,0)),g.scissorValue.x+g.scissorValue.width>g.width&&(g.scissorValue.width=Math.max(g.width-g.scissorValue.x,0)),g.scissorValue.y+g.scissorValue.height>g.height&&(g.scissorValue.height=Math.max(g.height-g.scissorValue.y,0)),this._background.update(l,S,g),g.camera=t,this.backend.beginRender(g);const{bundles:R,lightsNode:A,transparentDoublePass:E,transparent:w,opaque:C}=S;return R.length>0&&this._renderBundles(R,l,A),!0===this.opaque&&C.length>0&&this._renderObjects(C,t,l,A),!0===this.transparent&&w.length>0&&this._renderTransparents(w,E,t,l,A),this.backend.finishRender(g),i.renderId=n,this._currentRenderContext=a,this._currentRenderObjectFunction=o,this._handleObjectFunction=u,this._callDepth--,null!==s&&(this.setRenderTarget(d,c,h),this._renderOutput(p)),l.onAfterRender(this,e,t,p),this.inspector.finishRender(this.backend.getTimestampUID(g)),g}_setXRLayerSize(e,t){this._canvasTarget._width=e,this._canvasTarget._height=t,this.setViewport(0,0,e,t)}_renderOutput(e){const t=this._quad;this._nodes.hasOutputChange(e.texture)&&(t.material.fragmentNode=this._nodes.getOutputNode(e.texture),t.material.needsUpdate=!0);const r=this.autoClear,s=this.xr.enabled;this.autoClear=!1,this.xr.enabled=!1,this._renderScene(t,t.camera,!1),this.autoClear=r,this.xr.enabled=s}getMaxAnisotropy(){return this.backend.getMaxAnisotropy()}getActiveCubeFace(){return this._activeCubeFace}getActiveMipmapLevel(){return this._activeMipmapLevel}async setAnimationLoop(e){!1===this._initialized&&await this.init(),this._animation.setAnimationLoop(e)}getAnimationLoop(){return this._animation.getAnimationLoop()}async getArrayBufferAsync(e){return await this.backend.getArrayBufferAsync(e)}getContext(){return this.backend.getContext()}getPixelRatio(){return this._canvasTarget.getPixelRatio()}getDrawingBufferSize(e){return this._canvasTarget.getDrawingBufferSize(e)}getSize(e){return this._canvasTarget.getSize(e)}setPixelRatio(e=1){this._canvasTarget.setPixelRatio(e)}setDrawingBufferSize(e,t,r){this.xr&&this.xr.isPresenting||this._canvasTarget.setDrawingBufferSize(e,t,r)}setSize(e,t,r=!0){this.xr&&this.xr.isPresenting||this._canvasTarget.setSize(e,t,r)}setOpaqueSort(e){this._opaqueSort=e}setTransparentSort(e){this._transparentSort=e}getScissor(e){return this._canvasTarget.getScissor(e)}setScissor(e,t,r,s){this._canvasTarget.setScissor(e,t,r,s)}getScissorTest(){return this._canvasTarget.getScissorTest()}setScissorTest(e){this._canvasTarget.setScissorTest(e),this.backend.setScissorTest(e)}getViewport(e){return this._canvasTarget.getViewport(e)}setViewport(e,t,r,s,i=0,n=1){this._canvasTarget.setViewport(e,t,r,s,i,n)}getClearColor(e){return e.copy(this._clearColor)}setClearColor(e,t=1){this._clearColor.set(e),this._clearColor.a=t}getClearAlpha(){return this._clearColor.a}setClearAlpha(e){this._clearColor.a=e}getClearDepth(){return this._clearDepth}setClearDepth(e){this._clearDepth=e}getClearStencil(){return this._clearStencil}setClearStencil(e){this._clearStencil=e}isOccluded(e){const t=this._currentRenderContext;return t&&this.backend.isOccluded(t,e)}clear(e=!0,t=!0,r=!0){if(!1===this._initialized)throw new Error('Renderer: .clear() called before the backend is initialized. Use "await renderer.init();" before before using this method.');const s=this._renderTarget||this._getFrameBufferTarget();let i=null;if(null!==s){this._textures.updateRenderTarget(s);const e=this._textures.get(s);i=this._renderContexts.get(s),i.textures=e.textures,i.depthTexture=e.depthTexture,i.width=e.width,i.height=e.height,i.renderTarget=s,i.depth=s.depthBuffer,i.stencil=s.stencilBuffer;const t=this.backend.getClearColor();i.clearColorValue.r=t.r,i.clearColorValue.g=t.g,i.clearColorValue.b=t.b,i.clearColorValue.a=t.a,i.activeCubeFace=this.getActiveCubeFace(),i.activeMipmapLevel=this.getActiveMipmapLevel()}this.backend.clear(e,t,r,i),null!==s&&null===this._renderTarget&&this._renderOutput(s)}clearColor(){this.clear(!0,!1,!1)}clearDepth(){this.clear(!1,!0,!1)}clearStencil(){this.clear(!1,!1,!0)}async clearAsync(e=!0,t=!0,r=!0){v('Renderer: "clearAsync()" has been deprecated. Use "clear()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.clear(e,t,r)}async clearColorAsync(){v('Renderer: "clearColorAsync()" has been deprecated. Use "clearColor()" and "await renderer.init();" when creating the renderer.'),this.clear(!0,!1,!1)}async clearDepthAsync(){v('Renderer: "clearDepthAsync()" has been deprecated. Use "clearDepth()" and "await renderer.init();" when creating the renderer.'),this.clear(!1,!0,!1)}async clearStencilAsync(){v('Renderer: "clearStencilAsync()" has been deprecated. Use "clearStencil()" and "await renderer.init();" when creating the renderer.'),this.clear(!1,!1,!0)}get needsFrameBufferTarget(){const e=this.currentToneMapping!==m,t=this.currentColorSpace!==p.workingColorSpace;return e||t}get samples(){return this._samples}get currentSamples(){let e=this._samples;return null!==this._renderTarget?e=this._renderTarget.samples:this.needsFrameBufferTarget&&(e=0),e}get currentToneMapping(){return this.isOutputTarget?this.toneMapping:m}get currentColorSpace(){return this.isOutputTarget?this.outputColorSpace:p.workingColorSpace}get isOutputTarget(){return this._renderTarget===this._outputRenderTarget||null===this._renderTarget}dispose(){!0===this._initialized&&(this.info.dispose(),this.backend.dispose(),this._animation.dispose(),this._objects.dispose(),this._geometries.dispose(),this._pipelines.dispose(),this._nodes.dispose(),this._bindings.dispose(),this._renderLists.dispose(),this._renderContexts.dispose(),this._textures.dispose(),null!==this._frameBufferTarget&&this._frameBufferTarget.dispose(),Object.values(this.backend.timestampQueryPool).forEach(e=>{null!==e&&e.dispose()})),this.setRenderTarget(null),this.setAnimationLoop(null)}setRenderTarget(e,t=0,r=0){this._renderTarget=e,this._activeCubeFace=t,this._activeMipmapLevel=r}getRenderTarget(){return this._renderTarget}setOutputRenderTarget(e){this._outputRenderTarget=e}getOutputRenderTarget(){return this._outputRenderTarget}setCanvasTarget(e){this._canvasTarget.removeEventListener("resize",this._onCanvasTargetResize),this._canvasTarget=e,this._canvasTarget.addEventListener("resize",this._onCanvasTargetResize)}getCanvasTarget(){return this._canvasTarget}_resetXRState(){this.backend.setXRTarget(null),this.setOutputRenderTarget(null),this.setRenderTarget(null),this._frameBufferTarget.dispose(),this._frameBufferTarget=null}setRenderObjectFunction(e){this._renderObjectFunction=e}getRenderObjectFunction(){return this._renderObjectFunction}compute(e,t=null){if(!0===this._isDeviceLost)return;if(!1===this._initialized)return d("Renderer: .compute() called before the backend is initialized. Try using .computeAsync() instead."),this.computeAsync(e,t);const r=this._nodes.nodeFrame,s=r.renderId;this.info.calls++,this.info.compute.calls++,this.info.compute.frameCalls++,r.renderId=this.info.calls,this.backend.updateTimeStampUID(e),this.inspector.beginCompute(this.backend.getTimestampUID(e),e);const i=this.backend,n=this._pipelines,a=this._bindings,o=this._nodes,u=Array.isArray(e)?e:[e];if(void 0===u[0]||!0!==u[0].isComputeNode)throw new Error("THREE.Renderer: .compute() expects a ComputeNode.");i.beginCompute(e);for(const r of u){if(!1===n.has(r)){const e=()=>{r.removeEventListener("dispose",e),n.delete(r),a.deleteForCompute(r),o.delete(r)};r.addEventListener("dispose",e);const t=r.onInitFunction;null!==t&&t.call(r,{renderer:this})}o.updateForCompute(r),a.updateForCompute(r);const s=a.getForCompute(r),u=n.getForCompute(r,s);i.compute(e,r,s,u,t)}i.finishCompute(e),r.renderId=s,this.inspector.finishCompute(this.backend.getTimestampUID(e))}async computeAsync(e,t=null){!1===this._initialized&&await this.init(),this.compute(e,t)}async hasFeatureAsync(e){return v('Renderer: "hasFeatureAsync()" has been deprecated. Use "hasFeature()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.hasFeature(e)}async resolveTimestampsAsync(e="render"){return!1===this._initialized&&await this.init(),this.backend.resolveTimestampsAsync(e)}hasFeature(e){if(!1===this._initialized)throw new Error('Renderer: .hasFeature() called before the backend is initialized. Use "await renderer.init();" before before using this method.');return this.backend.hasFeature(e)}hasInitialized(){return this._initialized}async initTextureAsync(e){v('Renderer: "initTextureAsync()" has been deprecated. Use "initTexture()" and "await renderer.init();" when creating the renderer.'),await this.init(),this.initTexture(e)}initTexture(e){if(!1===this._initialized)throw new Error('Renderer: .initTexture() called before the backend is initialized. Use "await renderer.init();" before before using this method.');this._textures.updateTexture(e)}initRenderTarget(e){if(!1===this._initialized)throw new Error('Renderer: .initRenderTarget() called before the backend is initialized. Use "await renderer.init();" before before using this method.');this._textures.updateRenderTarget(e);const t=this._textures.get(e),r=this._renderContexts.get(e);r.textures=t.textures,r.depthTexture=t.depthTexture,r.width=t.width,r.height=t.height,r.renderTarget=e,r.depth=e.depthBuffer,r.stencil=e.stencilBuffer,this.backend.initRenderTarget(r)}copyFramebufferToTexture(e,t=null){if(null!==t)if(t.isVector2)t=LS.set(t.x,t.y,e.image.width,e.image.height).floor();else{if(!t.isVector4)return void o("Renderer.copyFramebufferToTexture: Invalid rectangle.");t=LS.copy(t).floor()}else t=LS.set(0,0,e.image.width,e.image.height);let r,s=this._currentRenderContext;null!==s?r=s.renderTarget:(r=this._renderTarget||this._getFrameBufferTarget(),null!==r&&(this._textures.updateRenderTarget(r),s=this._textures.get(r))),this._textures.updateTexture(e,{renderTarget:r}),this.backend.copyFramebufferToTexture(e,s,t),this._inspector.copyFramebufferToTexture(e)}copyTextureToTexture(e,t,r=null,s=null,i=0,n=0){this._textures.updateTexture(e),this._textures.updateTexture(t),this.backend.copyTextureToTexture(e,t,r,s,i,n),this._inspector.copyTextureToTexture(e,t)}async readRenderTargetPixelsAsync(e,t,r,s,i,n=0,a=0){return this.backend.copyTextureToBuffer(e.textures[n],t,r,s,i,a)}_projectObject(e,t,r,s,i){if(!1===e.visible)return;if(e.layers.test(t.layers))if(e.isGroup)r=e.renderOrder,e.isClippingGroup&&e.enabled&&(i=i.getGroupContext(e));else if(e.isLOD)!0===e.autoUpdate&&e.update(t);else if(e.isLight)s.pushLight(e);else if(e.isSprite){const n=t.isArrayCamera?BS:MS;if(!e.frustumCulled||n.intersectsSprite(e,t)){!0===this.sortObjects&&LS.setFromMatrixPosition(e.matrixWorld).applyMatrix4(FS);const{geometry:t,material:n}=e;n.visible&&s.push(e,t,n,r,LS.z,null,i)}}else if(e.isLineLoop)o("Renderer: Objects of type THREE.LineLoop are not supported. Please use THREE.Line or THREE.LineSegments.");else if(e.isMesh||e.isLine||e.isPoints){const n=t.isArrayCamera?BS:MS;if(!e.frustumCulled||n.intersectsObject(e,t)){const{geometry:t,material:n}=e;if(!0===this.sortObjects&&(null===t.boundingSphere&&t.computeBoundingSphere(),LS.copy(t.boundingSphere.center).applyMatrix4(e.matrixWorld).applyMatrix4(FS)),Array.isArray(n)){const a=t.groups;for(let o=0,u=a.length;o0){for(const{material:e}of t)e.side=M;this._renderObjects(t,r,s,i,"backSide");for(const{material:e}of t)e.side=dt;this._renderObjects(e,r,s,i);for(const{material:e}of t)e.side=B}else this._renderObjects(e,r,s,i)}_renderObjects(e,t,r,s,i=null){for(let n=0,a=e.length;n(t.not().discard(),e))(u)}}e.depthNode&&e.depthNode.isNode&&(l=e.depthNode),e.castShadowPositionNode&&e.castShadowPositionNode.isNode?o=e.castShadowPositionNode:e.positionNode&&e.positionNode.isNode&&(o=e.positionNode),r={version:t,colorNode:u,depthNode:l,positionNode:o},this._cacheShadowNodes.set(e,r)}return r}renderObject(e,t,r,s,i,n,a,o=null,u=null){let l,d,c,h,p=!1;if(e.onBeforeRender(this,t,r,s,i,n),!0===i.allowOverride&&null!==t.overrideMaterial){const e=t.overrideMaterial;if(p=!0,l=e.isNodeMaterial?e.colorNode:null,d=e.isNodeMaterial?e.depthNode:null,c=e.isNodeMaterial?e.positionNode:null,h=t.overrideMaterial.side,i.positionNode&&i.positionNode.isNode&&(e.positionNode=i.positionNode),e.alphaTest=i.alphaTest,e.alphaMap=i.alphaMap,e.transparent=i.transparent||i.transmission>0||i.transmissionNode&&i.transmissionNode.isNode||i.backdropNode&&i.backdropNode.isNode,e.isShadowPassMaterial){const{colorNode:t,depthNode:r,positionNode:s}=this._getShadowNodes(i);this.shadowMap.type===Qe?e.side=null!==i.shadowSide?i.shadowSide:i.side:e.side=null!==i.shadowSide?i.shadowSide:PS[i.side],null!==t&&(e.colorNode=t),null!==r&&(e.depthNode=r),null!==s&&(e.positionNode=s)}i=e}!0===i.transparent&&i.side===B&&!1===i.forceSinglePass?(i.side=M,this._handleObjectFunction(e,i,t,r,a,n,o,"backSide"),i.side=dt,this._handleObjectFunction(e,i,t,r,a,n,o,u),i.side=B):this._handleObjectFunction(e,i,t,r,a,n,o,u),p&&(t.overrideMaterial.colorNode=l,t.overrideMaterial.depthNode=d,t.overrideMaterial.positionNode=c,t.overrideMaterial.side=h),e.onAfterRender(this,t,r,s,i,n)}hasCompatibility(e){return this.backend.hasCompatibility(e)}_renderObjectDirect(e,t,r,s,i,n,a,o){const u=this._objects.get(e,t,r,s,i,this._currentRenderContext,a,o);if(u.drawRange=e.geometry.drawRange,u.group=n,null!==this._currentRenderBundle){this.backend.get(this._currentRenderBundle).renderObjects.push(u),u.bundle=this._currentRenderBundle.bundleGroup}const l=this._nodes.needsRefresh(u);l&&(this._nodes.updateBefore(u),this._geometries.updateForRender(u),this._nodes.updateForRender(u),this._bindings.updateForRender(u)),this._pipelines.updateForRender(u),this.backend.draw(u,this.info),l&&this._nodes.updateAfter(u)}_createObjectPipeline(e,t,r,s,i,n,a,o){const u=this._objects.get(e,t,r,s,i,this._currentRenderContext,a,o);u.drawRange=e.geometry.drawRange,u.group=n,this._nodes.updateBefore(u),this._geometries.updateForRender(u),this._nodes.updateForRender(u),this._bindings.updateForRender(u),this._pipelines.getForRender(u,this._compilationPromises),this._nodes.updateAfter(u)}_onCanvasTargetResize(){this._initialized&&this.backend.updateSize()}get compile(){return this.compileAsync}}class US{constructor(e=""){this.name=e,this.visibility=0}setVisibility(e){this.visibility|=e}getVisibility(){return this.visibility}clone(){return Object.assign(new this.constructor,this)}}class IS extends US{constructor(e,t=null){super(e),this.isBuffer=!0,this.bytesPerElement=Float32Array.BYTES_PER_ELEMENT,this._buffer=t,this._updateRanges=[]}get updateRanges(){return this._updateRanges}addUpdateRange(e,t){this.updateRanges.push({start:e,count:t})}clearUpdateRanges(){this.updateRanges.length=0}get byteLength(){return(e=this._buffer.byteLength)+(ay-e%ay)%ay;var e}get buffer(){return this._buffer}update(){return!0}}class OS extends IS{constructor(e,t=null){super(e,t),this.isUniformBuffer=!0}}let VS=0;class kS extends OS{constructor(e,t){super("UniformBuffer_"+VS++,e?e.value:null),this.nodeUniform=e,this.groupNode=t,this.isNodeUniformBuffer=!0}set updateRanges(e){this.nodeUniform.updateRanges=e}get updateRanges(){return this.nodeUniform.updateRanges}addUpdateRange(e,t){this.nodeUniform.addUpdateRange(e,t)}clearUpdateRanges(){this.nodeUniform.clearUpdateRanges()}get buffer(){return this.nodeUniform.value}}class GS extends OS{constructor(e){super(e),this.isUniformsGroup=!0,this._values=null,this.uniforms=[],this._updateRangeCache=new Map}addUniformUpdateRange(e){const t=e.index;if(!0!==this._updateRangeCache.has(t)){const r=this.updateRanges,s={start:e.offset,count:e.itemSize};r.push(s),this._updateRangeCache.set(t,s)}}clearUpdateRanges(){this._updateRangeCache.clear(),super.clearUpdateRanges()}addUniform(e){return this.uniforms.push(e),this}removeUniform(e){const t=this.uniforms.indexOf(e);return-1!==t&&this.uniforms.splice(t,1),this}get values(){return null===this._values&&(this._values=Array.from(this.buffer)),this._values}get buffer(){let e=this._buffer;if(null===e){const t=this.byteLength;e=new Float32Array(new ArrayBuffer(t)),this._buffer=e}return e}get byteLength(){const e=this.bytesPerElement;let t=0;for(let r=0,s=this.uniforms.length;r{this.generation=null,this.version=0},this.texture=t,this.version=t?t.version:0,this.generation=null,this.samplerKey="",this.isSampler=!0}set texture(e){this._texture!==e&&(this._texture&&this._texture.removeEventListener("dispose",this._onTextureDispose),this._texture=e,this.generation=null,this.version=0,this._texture&&this._texture.addEventListener("dispose",this._onTextureDispose))}get texture(){return this._texture}update(){const{texture:e,version:t}=this;return t!==e.version&&(this.version=e.version,!0)}clone(){const e=super.clone();return e._texture=null,e._onTextureDispose=()=>{e.generation=null,e.version=0},e.texture=this.texture,e}}let HS=0;class qS extends WS{constructor(e,t){super(e,t),this.id=HS++,this.store=!1,this.mipLevel=0,this.isSampledTexture=!0}}class jS extends qS{constructor(e,t,r,s=null){super(e,t?t.value:null),this.textureNode=t,this.groupNode=r,this.access=s}update(){const{textureNode:e}=this;return this.texture!==e.value?(this.texture=e.value,!0):super.update()}}class XS extends jS{constructor(e,t,r,s=null){super(e,t,r,s),this.isSampledCubeTexture=!0}}class KS extends jS{constructor(e,t,r,s=null){super(e,t,r,s),this.isSampledTexture3D=!0}}const YS={bitcast_int_uint:new Xx("uint tsl_bitcast_int_to_uint ( int x ) { return floatBitsToUint( intBitsToFloat ( x ) ); }"),bitcast_uint_int:new Xx("uint tsl_bitcast_uint_to_int ( uint x ) { return floatBitsToInt( uintBitsToFloat ( x ) ); }")},QS={textureDimensions:"textureSize",equals:"equal",bitcast_float_int:"floatBitsToInt",bitcast_int_float:"intBitsToFloat",bitcast_uint_float:"uintBitsToFloat",bitcast_float_uint:"floatBitsToUint",bitcast_uint_int:"tsl_bitcast_uint_to_int",bitcast_int_uint:"tsl_bitcast_int_to_uint",floatpack_snorm_2x16:"packSnorm2x16",floatpack_unorm_2x16:"packUnorm2x16",floatpack_float16_2x16:"packHalf2x16",floatunpack_snorm_2x16:"unpackSnorm2x16",floatunpack_unorm_2x16:"unpackUnorm2x16",floatunpack_float16_2x16:"unpackHalf2x16"},ZS={low:"lowp",medium:"mediump",high:"highp"},JS={swizzleAssign:!0,storageBuffer:!1},eR={perspective:"smooth",linear:"noperspective"},tR={centroid:"centroid"},rR="\nprecision highp float;\nprecision highp int;\nprecision highp sampler2D;\nprecision highp sampler3D;\nprecision highp samplerCube;\nprecision highp sampler2DArray;\n\nprecision highp usampler2D;\nprecision highp usampler3D;\nprecision highp usamplerCube;\nprecision highp usampler2DArray;\n\nprecision highp isampler2D;\nprecision highp isampler3D;\nprecision highp isamplerCube;\nprecision highp isampler2DArray;\n\nprecision highp sampler2DShadow;\nprecision highp sampler2DArrayShadow;\nprecision highp samplerCubeShadow;\n";class sR extends DN{constructor(e,t){super(e,t,new rS),this.uniformGroups={},this.transforms=[],this.extensions={},this.builtins={vertex:[],fragment:[],compute:[]}}needsToWorkingColorSpace(e){return!0===e.isVideoTexture&&e.colorSpace!==T}_include(e){const t=YS[e];return t.build(this),this.addInclude(t),t}getMethod(e){return void 0!==YS[e]&&this._include(e),QS[e]||e}getBitcastMethod(e,t){return this.getMethod(`bitcast_${t}_${e}`)}getFloatPackingMethod(e){return this.getMethod(`floatpack_${e}_2x16`)}getFloatUnpackingMethod(e){return this.getMethod(`floatunpack_${e}_2x16`)}getTernary(e,t,r){return`${e} ? ${t} : ${r}`}getOutputStructName(){return""}buildFunctionCode(e){const t=e.layout,r=this.flowShaderNode(e),s=[];for(const e of t.inputs)s.push(this.getType(e.type)+" "+e.name);return`${this.getType(t.type)} ${t.name}( ${s.join(", ")} ) {\n\n\t${r.vars}\n\n${r.code}\n\treturn ${r.result};\n\n}`}setupPBO(e){const t=e.value;if(void 0===t.pbo){const e=t.array,r=t.count*t.itemSize,{itemSize:s}=t,i=t.array.constructor.name.toLowerCase().includes("int");let n=i?xt:Tt;2===s?n=i?St:G:3===s?n=i?Rt:At:4===s&&(n=i?Et:Se);const a={Float32Array:j,Uint8Array:ke,Uint16Array:Nt,Uint32Array:S,Int8Array:vt,Int16Array:_t,Int32Array:R,Uint8ClampedArray:ke},o=Math.pow(2,Math.ceil(Math.log2(Math.sqrt(r/s))));let u=Math.ceil(r/s/o);o*u*s0?i:"";t=`${r.name} {\n\t${s} ${e.name}[${n}];\n};\n`}else{const t=e.groupNode.name;if(void 0===s[t]){const e=this.uniformGroups[t];if(void 0!==e){const r=[];for(const t of e.uniforms){const e=t.getType(),s=this.getVectorType(e),i=t.nodeUniform.node.precision;let n=`${s} ${t.name};`;null!==i&&(n=ZS[i]+" "+n),r.push("\t"+n)}s[t]=r}}i=!0}if(!i){const s=e.node.precision;null!==s&&(t=ZS[s]+" "+t),t="uniform "+t,r.push(t)}}let i="";for(const e in s){const t=s[e];i+=this._getGLSLUniformStruct(e,t.join("\n"))+"\n"}return i+=r.join("\n"),i}getTypeFromAttribute(e){let t=super.getTypeFromAttribute(e);if(/^[iu]/.test(t)&&e.gpuType!==R){let r=e;e.isInterleavedBufferAttribute&&(r=e.data);const s=r.array;!1==(s instanceof Uint32Array||s instanceof Int32Array)&&(t=t.slice(1))}return t}getAttributes(e){let t="";if("vertex"===e||"compute"===e){const e=this.getAttributesArray();let r=0;for(const s of e)t+=`layout( location = ${r++} ) in ${s.type} ${s.name};\n`}return t}getStructMembers(e){const t=[];for(const r of e.members)t.push(`\t${r.type} ${r.name};`);return t.join("\n")}getStructs(e){const t=[],r=this.structs[e],s=[];for(const e of r)if(e.output)for(const t of e.members)s.push(`layout( location = ${t.index} ) out ${t.type} ${t.name};`);else{let r="struct "+e.name+" {\n";r+=this.getStructMembers(e),r+="\n};\n",t.push(r)}return 0===s.length&&s.push("layout( location = 0 ) out vec4 fragColor;"),"\n"+s.join("\n")+"\n\n"+t.join("\n")}getVaryings(e){let t="";const r=this.varyings;if("vertex"===e||"compute"===e)for(const s of r){"compute"===e&&(s.needsInterpolation=!0);const r=this.getType(s.type);if(s.needsInterpolation)if(s.interpolationType){t+=`${eR[s.interpolationType]||s.interpolationType} ${tR[s.interpolationSampling]||""} out ${r} ${s.name};\n`}else{t+=`${r.includes("int")||r.includes("uv")||r.includes("iv")?"flat ":""}out ${r} ${s.name};\n`}else t+=`${r} ${s.name};\n`}else if("fragment"===e)for(const e of r)if(e.needsInterpolation){const r=this.getType(e.type);if(e.interpolationType){t+=`${eR[e.interpolationType]||e.interpolationType} ${tR[e.interpolationSampling]||""} in ${r} ${e.name};\n`}else{t+=`${r.includes("int")||r.includes("uv")||r.includes("iv")?"flat ":""}in ${r} ${e.name};\n`}}for(const r of this.builtins[e])t+=`${r};\n`;return t}getVertexIndex(){return"uint( gl_VertexID )"}getInstanceIndex(){return"uint( gl_InstanceID )"}getInvocationLocalIndex(){return`uint( gl_InstanceID ) % ${this.object.workgroupSize.reduce((e,t)=>e*t,1)}u`}getSubgroupSize(){o("GLSLNodeBuilder: WebGLBackend does not support the subgroupSize node")}getInvocationSubgroupIndex(){o("GLSLNodeBuilder: WebGLBackend does not support the invocationSubgroupIndex node")}getSubgroupIndex(){o("GLSLNodeBuilder: WebGLBackend does not support the subgroupIndex node")}getDrawIndex(){return this.renderer.backend.extensions.has("WEBGL_multi_draw")?"uint( gl_DrawID )":null}getFrontFacing(){return"gl_FrontFacing"}getFragCoord(){return"gl_FragCoord.xy"}getFragDepth(){return"gl_FragDepth"}enableExtension(e,t,r=this.shaderStage){const s=this.extensions[r]||(this.extensions[r]=new Map);!1===s.has(e)&&s.set(e,{name:e,behavior:t})}getExtensions(e){const t=[];if("vertex"===e){const t=this.renderer.backend.extensions;this.object.isBatchedMesh&&t.has("WEBGL_multi_draw")&&this.enableExtension("GL_ANGLE_multi_draw","require",e)}const r=this.extensions[e];if(void 0!==r)for(const{name:e,behavior:s}of r.values())t.push(`#extension ${e} : ${s}`);return t.join("\n")}getClipDistance(){return"gl_ClipDistance"}isAvailable(e){let t=JS[e];if(void 0===t){let r;switch(t=!1,e){case"float32Filterable":r="OES_texture_float_linear";break;case"clipDistance":r="WEBGL_clip_cull_distance"}if(void 0!==r){const e=this.renderer.backend.extensions;e.has(r)&&(e.get(r),t=!0)}JS[e]=t}return t}isFlipY(){return!0}enableHardwareClipping(e){this.enableExtension("GL_ANGLE_clip_cull_distance","require"),this.builtins.vertex.push(`out float gl_ClipDistance[ ${e} ]`)}enableMultiview(){this.enableExtension("GL_OVR_multiview2","require","fragment"),this.enableExtension("GL_OVR_multiview2","require","vertex"),this.builtins.vertex.push("layout(num_views = 2) in")}registerTransform(e,t){this.transforms.push({varyingName:e,attributeNode:t})}getTransforms(){const e=this.transforms;let t="";for(let r=0;r0&&(r+="\n"),r+=`\t// flow -> ${n}\n\t`),r+=`${s.code}\n\t`,e===i&&"compute"!==t&&(r+="// result\n\t","vertex"===t?(r+="gl_Position = ",r+=`${s.result};`):"fragment"===t&&(e.outputNode.isOutputStructNode||(r+="fragColor = ",r+=`${s.result};`)))}const n=e[t];n.extensions=this.getExtensions(t),n.uniforms=this.getUniforms(t),n.attributes=this.getAttributes(t),n.varyings=this.getVaryings(t),n.vars=this.getVars(t),n.structs=this.getStructs(t),n.codes=this.getCodes(t),n.transforms=this.getTransforms(t),n.flow=r}null!==this.material?(this.vertexShader=this._getGLSLVertexCode(e.vertex),this.fragmentShader=this._getGLSLFragmentCode(e.fragment)):this.computeShader=this._getGLSLVertexCode(e.compute)}getUniformFromNode(e,t,r,s=null){const i=super.getUniformFromNode(e,t,r,s),n=this.getDataFromNode(e,r,this.globalCache);let a=n.uniformGPU;if(void 0===a){const s=e.groupNode,o=s.name,u=this.getBindGroupArray(o,r);if("texture"===t)a=new jS(i.name,i.node,s),u.push(a);else if("cubeTexture"===t||"cubeDepthTexture"===t)a=new XS(i.name,i.node,s),u.push(a);else if("texture3D"===t)a=new KS(i.name,i.node,s),u.push(a);else if("buffer"===t){i.name=`buffer${e.id}`;const t=this.getSharedDataFromNode(e);let r=t.buffer;void 0===r&&(e.name=`NodeBuffer_${e.id}`,r=new kS(e,s),r.name=e.name,t.buffer=r),u.push(r),a=r}else{let e=this.uniformGroups[o];void 0===e?(e=new $S(o,s),this.uniformGroups[o]=e,u.push(e)):-1===u.indexOf(e)&&u.push(e),a=this.getNodeUniform(i,t);const r=a.name;e.uniforms.some(e=>e.name===r)||e.addUniform(a)}n.uniformGPU=a}return i}}let iR=null,nR=null;class aR{constructor(e={}){this.parameters=Object.assign({},e),this.data=new WeakMap,this.renderer=null,this.domElement=null,this.timestampQueryPool={[wt.RENDER]:null,[wt.COMPUTE]:null},this.trackTimestamp=!0===e.trackTimestamp}async init(e){this.renderer=e}get coordinateSystem(){}beginRender(){}finishRender(){}beginCompute(){}finishCompute(){}draw(){}compute(){}createProgram(){}destroyProgram(){}createBindings(){}updateBindings(){}updateBinding(){}createRenderPipeline(){}createComputePipeline(){}needsRenderUpdate(){}getRenderCacheKey(){}createNodeBuilder(){}updateSampler(){}createDefaultTexture(){}createTexture(){}updateTexture(){}generateMipmaps(){}destroyTexture(){}async copyTextureToBuffer(){}copyTextureToTexture(){}copyFramebufferToTexture(){}createAttribute(){}createIndexAttribute(){}createStorageAttribute(){}updateAttribute(){}destroyAttribute(){}getContext(){}updateSize(){}updateViewport(){}updateTimeStampUID(e){const t=this.get(e),r=this.renderer.info.frame;let s;s=!0===e.isComputeNode?"c:"+this.renderer.info.compute.frameCalls:"r:"+this.renderer.info.render.frameCalls,t.timestampUID=s+":"+e.id+":f"+r}getTimestampUID(e){return this.get(e).timestampUID}getTimestampFrames(e){const t=this.timestampQueryPool[e];return t?t.getTimestampFrames():[]}_getQueryPool(e){const t=e.startsWith("c:")?wt.COMPUTE:wt.RENDER;return this.timestampQueryPool[t]}getTimestamp(e){return this._getQueryPool(e).getTimestamp(e)}hasTimestamp(e){return this._getQueryPool(e).hasTimestamp(e)}isOccluded(){}async resolveTimestampsAsync(e="render"){if(!this.trackTimestamp)return void v("WebGPURenderer: Timestamp tracking is disabled.");const t=this.timestampQueryPool[e];if(!t)return;const r=await t.resolveQueriesAsync();return this.renderer.info[e].timestamp=r,r}async getArrayBufferAsync(){}async hasFeatureAsync(){}hasFeature(){}getMaxAnisotropy(){}getDrawingBufferSize(){return iR=iR||new t,this.renderer.getDrawingBufferSize(iR)}setScissorTest(){}getClearColor(){const e=this.renderer;return nR=nR||new Fy,e.getClearColor(nR),nR.getRGB(nR),nR}getDomElement(){let e=this.domElement;return null===e&&(e=void 0!==this.parameters.canvas?this.parameters.canvas:Ct(),"setAttribute"in e&&e.setAttribute("data-engine",`three.js r${ot} webgpu`),this.domElement=e),e}hasCompatibility(){return!1}initRenderTarget(){}set(e,t){this.data.set(e,t)}get(e){let t=this.data.get(e);return void 0===t&&(t={},this.data.set(e,t)),t}has(e){return this.data.has(e)}delete(e){this.data.delete(e)}deleteBindGroupData(){}dispose(){}}let oR,uR,lR=0;class dR{constructor(e,t){this.buffers=[e.bufferGPU,t],this.type=e.type,this.bufferType=e.bufferType,this.pbo=e.pbo,this.byteLength=e.byteLength,this.bytesPerElement=e.BYTES_PER_ELEMENT,this.version=e.version,this.isInteger=e.isInteger,this.activeBufferIndex=0,this.baseId=e.id}get id(){return`${this.baseId}|${this.activeBufferIndex}`}get bufferGPU(){return this.buffers[this.activeBufferIndex]}get transformBuffer(){return this.buffers[1^this.activeBufferIndex]}switchBuffers(){this.activeBufferIndex^=1}}class cR{constructor(e){this.backend=e}createAttribute(e,t){const r=this.backend,{gl:s}=r,i=e.array,n=e.usage||s.STATIC_DRAW,a=e.isInterleavedBufferAttribute?e.data:e,o=r.get(a);let u,l=o.bufferGPU;if(void 0===l&&(l=this._createBuffer(s,t,i,n),o.bufferGPU=l,o.bufferType=t,o.version=a.version),i instanceof Float32Array)u=s.FLOAT;else if("undefined"!=typeof Float16Array&&i instanceof Float16Array)u=s.HALF_FLOAT;else if(i instanceof Uint16Array)u=e.isFloat16BufferAttribute?s.HALF_FLOAT:s.UNSIGNED_SHORT;else if(i instanceof Int16Array)u=s.SHORT;else if(i instanceof Uint32Array)u=s.UNSIGNED_INT;else if(i instanceof Int32Array)u=s.INT;else if(i instanceof Int8Array)u=s.BYTE;else if(i instanceof Uint8Array)u=s.UNSIGNED_BYTE;else{if(!(i instanceof Uint8ClampedArray))throw new Error("THREE.WebGLBackend: Unsupported buffer data format: "+i);u=s.UNSIGNED_BYTE}let d={bufferGPU:l,bufferType:t,type:u,byteLength:i.byteLength,bytesPerElement:i.BYTES_PER_ELEMENT,version:e.version,pbo:e.pbo,isInteger:u===s.INT||u===s.UNSIGNED_INT||e.gpuType===R,id:lR++};if(e.isStorageBufferAttribute||e.isStorageInstancedBufferAttribute){const e=this._createBuffer(s,t,i,n);d=new dR(d,e)}r.set(e,d)}updateAttribute(e){const t=this.backend,{gl:r}=t,s=e.array,i=e.isInterleavedBufferAttribute?e.data:e,n=t.get(i),a=n.bufferType,o=e.isInterleavedBufferAttribute?e.data.updateRanges:e.updateRanges;if(r.bindBuffer(a,n.bufferGPU),0===o.length)r.bufferSubData(a,0,s);else{for(let e=0,t=o.length;e0?this.enable(s.SAMPLE_ALPHA_TO_COVERAGE):this.disable(s.SAMPLE_ALPHA_TO_COVERAGE),r>0&&this.currentClippingPlanes!==r){const e=12288;for(let t=0;t<8;t++)t{!function i(){const n=e.clientWaitSync(t,e.SYNC_FLUSH_COMMANDS_BIT,0);if(n===e.WAIT_FAILED)return e.deleteSync(t),void s();n!==e.TIMEOUT_EXPIRED?(e.deleteSync(t),r()):requestAnimationFrame(i)}()})}}let gR,mR,fR,yR=!1;class bR{constructor(e){this.backend=e,this.gl=e.gl,this.extensions=e.extensions,this.defaultTextures={},this._srcFramebuffer=null,this._dstFramebuffer=null,!1===yR&&(this._init(),yR=!0)}_init(){const e=this.gl;gR={[Or]:e.REPEAT,[xe]:e.CLAMP_TO_EDGE,[Ir]:e.MIRRORED_REPEAT},mR={[w]:e.NEAREST,[Vr]:e.NEAREST_MIPMAP_NEAREST,[nt]:e.NEAREST_MIPMAP_LINEAR,[oe]:e.LINEAR,[it]:e.LINEAR_MIPMAP_NEAREST,[K]:e.LINEAR_MIPMAP_LINEAR},fR={[Hr]:e.NEVER,[Wr]:e.ALWAYS,[E]:e.LESS,[Ze]:e.LEQUAL,[$r]:e.EQUAL,[zr]:e.GEQUAL,[Gr]:e.GREATER,[kr]:e.NOTEQUAL}}getGLTextureType(e){const{gl:t}=this;let r;return r=!0===e.isCubeTexture?t.TEXTURE_CUBE_MAP:!0===e.isArrayTexture||!0===e.isDataArrayTexture||!0===e.isCompressedArrayTexture?t.TEXTURE_2D_ARRAY:!0===e.isData3DTexture?t.TEXTURE_3D:t.TEXTURE_2D,r}getInternalFormat(e,t,r,s,i=!1){const{gl:n,extensions:a}=this;if(null!==e){if(void 0!==n[e])return n[e];d("WebGLBackend: Attempt to use non-existing WebGL internal format '"+e+"'")}let o=t;if(t===n.RED&&(r===n.FLOAT&&(o=n.R32F),r===n.HALF_FLOAT&&(o=n.R16F),r===n.UNSIGNED_BYTE&&(o=n.R8),r===n.UNSIGNED_SHORT&&(o=n.R16),r===n.UNSIGNED_INT&&(o=n.R32UI),r===n.BYTE&&(o=n.R8I),r===n.SHORT&&(o=n.R16I),r===n.INT&&(o=n.R32I)),t===n.RED_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.R8UI),r===n.UNSIGNED_SHORT&&(o=n.R16UI),r===n.UNSIGNED_INT&&(o=n.R32UI),r===n.BYTE&&(o=n.R8I),r===n.SHORT&&(o=n.R16I),r===n.INT&&(o=n.R32I)),t===n.RG&&(r===n.FLOAT&&(o=n.RG32F),r===n.HALF_FLOAT&&(o=n.RG16F),r===n.UNSIGNED_BYTE&&(o=n.RG8),r===n.UNSIGNED_SHORT&&(o=n.RG16),r===n.UNSIGNED_INT&&(o=n.RG32UI),r===n.BYTE&&(o=n.RG8I),r===n.SHORT&&(o=n.RG16I),r===n.INT&&(o=n.RG32I)),t===n.RG_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RG8UI),r===n.UNSIGNED_SHORT&&(o=n.RG16UI),r===n.UNSIGNED_INT&&(o=n.RG32UI),r===n.BYTE&&(o=n.RG8I),r===n.SHORT&&(o=n.RG16I),r===n.INT&&(o=n.RG32I)),t===n.RGB){const e=i?qr:p.getTransfer(s);r===n.FLOAT&&(o=n.RGB32F),r===n.HALF_FLOAT&&(o=n.RGB16F),r===n.UNSIGNED_BYTE&&(o=n.RGB8),r===n.UNSIGNED_SHORT&&(o=n.RGB16),r===n.UNSIGNED_INT&&(o=n.RGB32UI),r===n.BYTE&&(o=n.RGB8I),r===n.SHORT&&(o=n.RGB16I),r===n.INT&&(o=n.RGB32I),r===n.UNSIGNED_BYTE&&(o=e===g?n.SRGB8:n.RGB8),r===n.UNSIGNED_SHORT_5_6_5&&(o=n.RGB565),r===n.UNSIGNED_SHORT_5_5_5_1&&(o=n.RGB5_A1),r===n.UNSIGNED_SHORT_4_4_4_4&&(o=n.RGB4),r===n.UNSIGNED_INT_5_9_9_9_REV&&(o=n.RGB9_E5),r===n.UNSIGNED_INT_10F_11F_11F_REV&&(o=n.R11F_G11F_B10F)}if(t===n.RGB_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RGB8UI),r===n.UNSIGNED_SHORT&&(o=n.RGB16UI),r===n.UNSIGNED_INT&&(o=n.RGB32UI),r===n.BYTE&&(o=n.RGB8I),r===n.SHORT&&(o=n.RGB16I),r===n.INT&&(o=n.RGB32I)),t===n.RGBA){const e=i?qr:p.getTransfer(s);r===n.FLOAT&&(o=n.RGBA32F),r===n.HALF_FLOAT&&(o=n.RGBA16F),r===n.UNSIGNED_BYTE&&(o=n.RGBA8),r===n.UNSIGNED_SHORT&&(o=n.RGBA16),r===n.UNSIGNED_INT&&(o=n.RGBA32UI),r===n.BYTE&&(o=n.RGBA8I),r===n.SHORT&&(o=n.RGBA16I),r===n.INT&&(o=n.RGBA32I),r===n.UNSIGNED_BYTE&&(o=e===g?n.SRGB8_ALPHA8:n.RGBA8),r===n.UNSIGNED_SHORT_4_4_4_4&&(o=n.RGBA4),r===n.UNSIGNED_SHORT_5_5_5_1&&(o=n.RGB5_A1)}return t===n.RGBA_INTEGER&&(r===n.UNSIGNED_BYTE&&(o=n.RGBA8UI),r===n.UNSIGNED_SHORT&&(o=n.RGBA16UI),r===n.UNSIGNED_INT&&(o=n.RGBA32UI),r===n.BYTE&&(o=n.RGBA8I),r===n.SHORT&&(o=n.RGBA16I),r===n.INT&&(o=n.RGBA32I)),t===n.DEPTH_COMPONENT&&(r===n.UNSIGNED_SHORT&&(o=n.DEPTH_COMPONENT16),r===n.UNSIGNED_INT&&(o=n.DEPTH_COMPONENT24),r===n.FLOAT&&(o=n.DEPTH_COMPONENT32F)),t===n.DEPTH_STENCIL&&r===n.UNSIGNED_INT_24_8&&(o=n.DEPTH24_STENCIL8),o!==n.R16F&&o!==n.R32F&&o!==n.RG16F&&o!==n.RG32F&&o!==n.RGBA16F&&o!==n.RGBA32F||a.get("EXT_color_buffer_float"),o}setTextureParameters(e,t){const{gl:r,extensions:s,backend:i}=this,n=p.getPrimaries(p.workingColorSpace),a=t.colorSpace===T?null:p.getPrimaries(t.colorSpace),o=t.colorSpace===T||n===a?r.NONE:r.BROWSER_DEFAULT_WEBGL;r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,t.flipY),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,t.premultiplyAlpha),r.pixelStorei(r.UNPACK_ALIGNMENT,t.unpackAlignment),r.pixelStorei(r.UNPACK_COLORSPACE_CONVERSION_WEBGL,o),r.texParameteri(e,r.TEXTURE_WRAP_S,gR[t.wrapS]),r.texParameteri(e,r.TEXTURE_WRAP_T,gR[t.wrapT]),e!==r.TEXTURE_3D&&e!==r.TEXTURE_2D_ARRAY||t.isArrayTexture||r.texParameteri(e,r.TEXTURE_WRAP_R,gR[t.wrapR]),r.texParameteri(e,r.TEXTURE_MAG_FILTER,mR[t.magFilter]);const u=void 0!==t.mipmaps&&t.mipmaps.length>0,l=t.minFilter===oe&&u?K:t.minFilter;if(r.texParameteri(e,r.TEXTURE_MIN_FILTER,mR[l]),t.compareFunction&&(r.texParameteri(e,r.TEXTURE_COMPARE_MODE,r.COMPARE_REF_TO_TEXTURE),r.texParameteri(e,r.TEXTURE_COMPARE_FUNC,fR[t.compareFunction])),!0===s.has("EXT_texture_filter_anisotropic")){if(t.magFilter===w)return;if(t.minFilter!==nt&&t.minFilter!==K)return;if(t.type===j&&!1===s.has("OES_texture_float_linear"))return;if(t.anisotropy>1){const n=s.get("EXT_texture_filter_anisotropic");r.texParameterf(e,n.TEXTURE_MAX_ANISOTROPY_EXT,Math.min(t.anisotropy,i.getMaxAnisotropy()))}}}createDefaultTexture(e){const{gl:t,backend:r,defaultTextures:s}=this,i=this.getGLTextureType(e);let n=s[i];void 0===n&&(n=t.createTexture(),r.state.bindTexture(i,n),t.texParameteri(i,t.TEXTURE_MIN_FILTER,t.NEAREST),t.texParameteri(i,t.TEXTURE_MAG_FILTER,t.NEAREST),s[i]=n),r.set(e,{textureGPU:n,glTextureType:i})}createTexture(e,t){const{gl:r,backend:s}=this,{levels:i,width:n,height:a,depth:o}=t,u=s.utils.convert(e.format,e.colorSpace),l=s.utils.convert(e.type),d=this.getInternalFormat(e.internalFormat,u,l,e.colorSpace,e.isVideoTexture),c=r.createTexture(),h=this.getGLTextureType(e);s.state.bindTexture(h,c),this.setTextureParameters(h,e),e.isArrayTexture||e.isDataArrayTexture||e.isCompressedArrayTexture?r.texStorage3D(r.TEXTURE_2D_ARRAY,i,d,n,a,o):e.isData3DTexture?r.texStorage3D(r.TEXTURE_3D,i,d,n,a,o):e.isVideoTexture||r.texStorage2D(h,i,d,n,a),s.set(e,{textureGPU:c,glTextureType:h,glFormat:u,glType:l,glInternalFormat:d})}copyBufferToTexture(e,t){const{gl:r,backend:s}=this,{textureGPU:i,glTextureType:n,glFormat:a,glType:o}=s.get(t),{width:u,height:l}=t.source.data;r.bindBuffer(r.PIXEL_UNPACK_BUFFER,e),s.state.bindTexture(n,i),r.pixelStorei(r.UNPACK_FLIP_Y_WEBGL,!1),r.pixelStorei(r.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),r.texSubImage2D(n,0,0,0,u,l,a,o,0),r.bindBuffer(r.PIXEL_UNPACK_BUFFER,null),s.state.unbindTexture()}updateTexture(e,t){const{gl:r}=this,{width:s,height:i}=t,{textureGPU:n,glTextureType:a,glFormat:o,glType:u,glInternalFormat:l}=this.backend.get(e);if(!e.isRenderTargetTexture&&void 0!==n)if(this.backend.state.bindTexture(a,n),this.setTextureParameters(a,e),e.isCompressedTexture){const s=e.mipmaps,i=t.image;for(let t=0;t0){const t=jr(s.width,s.height,e.format,e.type);for(const i of e.layerUpdates){const e=s.data.subarray(i*t/s.data.BYTES_PER_ELEMENT,(i+1)*t/s.data.BYTES_PER_ELEMENT);r.texSubImage3D(r.TEXTURE_2D_ARRAY,0,0,0,i,s.width,s.height,1,o,u,e)}e.clearLayerUpdates()}else r.texSubImage3D(r.TEXTURE_2D_ARRAY,0,0,0,0,s.width,s.height,s.depth,o,u,s.data)}else if(e.isData3DTexture){const e=t.image;r.texSubImage3D(r.TEXTURE_3D,0,0,0,0,e.width,e.height,e.depth,o,u,e.data)}else if(e.isVideoTexture)e.update(),r.texImage2D(a,0,l,o,u,t.image);else{const n=e.mipmaps;if(n.length>0)for(let e=0,t=n.length;e0,c=t.renderTarget?t.renderTarget.height:this.backend.getDrawingBufferSize().y;if(d){const r=0!==a||0!==o;let d,h;if(!0===e.isDepthTexture?(d=s.DEPTH_BUFFER_BIT,h=s.DEPTH_ATTACHMENT,t.stencil&&(d|=s.STENCIL_BUFFER_BIT)):(d=s.COLOR_BUFFER_BIT,h=s.COLOR_ATTACHMENT0),r){const e=this.backend.get(t.renderTarget),r=e.framebuffers[t.getCacheKey()],h=e.msaaFrameBuffer;i.bindFramebuffer(s.DRAW_FRAMEBUFFER,r),i.bindFramebuffer(s.READ_FRAMEBUFFER,h);const p=c-o-l;s.blitFramebuffer(a,p,a+u,p+l,a,p,a+u,p+l,d,s.NEAREST),i.bindFramebuffer(s.READ_FRAMEBUFFER,r),i.bindTexture(s.TEXTURE_2D,n),s.copyTexSubImage2D(s.TEXTURE_2D,0,0,0,a,p,u,l),i.unbindTexture()}else{const e=s.createFramebuffer();i.bindFramebuffer(s.DRAW_FRAMEBUFFER,e),s.framebufferTexture2D(s.DRAW_FRAMEBUFFER,h,s.TEXTURE_2D,n,0),s.blitFramebuffer(0,0,u,l,0,0,u,l,d,s.NEAREST),s.deleteFramebuffer(e)}}else i.bindTexture(s.TEXTURE_2D,n),s.copyTexSubImage2D(s.TEXTURE_2D,0,0,0,a,c-l-o,u,l),i.unbindTexture();e.generateMipmaps&&this.generateMipmaps(e),this.backend._setFramebuffer(t)}setupRenderBufferStorage(e,t,r,s=!1){const{gl:i}=this,n=t.renderTarget,{depthTexture:a,depthBuffer:o,stencilBuffer:u,width:l,height:d}=n;if(i.bindRenderbuffer(i.RENDERBUFFER,e),o&&!u){let t=i.DEPTH_COMPONENT24;if(!0===s){this.extensions.get("WEBGL_multisampled_render_to_texture").renderbufferStorageMultisampleEXT(i.RENDERBUFFER,n.samples,t,l,d)}else r>0?(a&&a.isDepthTexture&&a.type===i.FLOAT&&(t=i.DEPTH_COMPONENT32F),i.renderbufferStorageMultisample(i.RENDERBUFFER,r,t,l,d)):i.renderbufferStorage(i.RENDERBUFFER,t,l,d);i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_ATTACHMENT,i.RENDERBUFFER,e)}else o&&u&&(r>0?i.renderbufferStorageMultisample(i.RENDERBUFFER,r,i.DEPTH24_STENCIL8,l,d):i.renderbufferStorage(i.RENDERBUFFER,i.DEPTH_STENCIL,l,d),i.framebufferRenderbuffer(i.FRAMEBUFFER,i.DEPTH_STENCIL_ATTACHMENT,i.RENDERBUFFER,e));i.bindRenderbuffer(i.RENDERBUFFER,null)}async copyTextureToBuffer(e,t,r,s,i,n){const{backend:a,gl:o}=this,{textureGPU:u,glFormat:l,glType:d}=this.backend.get(e),c=o.createFramebuffer();a.state.bindFramebuffer(o.READ_FRAMEBUFFER,c);const h=e.isCubeTexture?o.TEXTURE_CUBE_MAP_POSITIVE_X+n:o.TEXTURE_2D;o.framebufferTexture2D(o.READ_FRAMEBUFFER,o.COLOR_ATTACHMENT0,h,u,0);const p=this._getTypedArrayType(d),g=s*i*this._getBytesPerTexel(d,l),m=o.createBuffer();o.bindBuffer(o.PIXEL_PACK_BUFFER,m),o.bufferData(o.PIXEL_PACK_BUFFER,g,o.STREAM_READ),o.readPixels(t,r,s,i,l,d,0),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),await a.utils._clientWaitAsync();const f=new p(g/p.BYTES_PER_ELEMENT);return o.bindBuffer(o.PIXEL_PACK_BUFFER,m),o.getBufferSubData(o.PIXEL_PACK_BUFFER,0,f),o.bindBuffer(o.PIXEL_PACK_BUFFER,null),a.state.bindFramebuffer(o.READ_FRAMEBUFFER,null),o.deleteFramebuffer(c),f}_getTypedArrayType(e){const{gl:t}=this;if(e===t.UNSIGNED_BYTE)return Uint8Array;if(e===t.UNSIGNED_SHORT_4_4_4_4)return Uint16Array;if(e===t.UNSIGNED_SHORT_5_5_5_1)return Uint16Array;if(e===t.UNSIGNED_SHORT_5_6_5)return Uint16Array;if(e===t.UNSIGNED_SHORT)return Uint16Array;if(e===t.UNSIGNED_INT)return Uint32Array;if(e===t.HALF_FLOAT)return Uint16Array;if(e===t.FLOAT)return Float32Array;throw new Error(`Unsupported WebGL type: ${e}`)}_getBytesPerTexel(e,t){const{gl:r}=this;let s=0;return e===r.UNSIGNED_BYTE&&(s=1),e!==r.UNSIGNED_SHORT_4_4_4_4&&e!==r.UNSIGNED_SHORT_5_5_5_1&&e!==r.UNSIGNED_SHORT_5_6_5&&e!==r.UNSIGNED_SHORT&&e!==r.HALF_FLOAT||(s=2),e!==r.UNSIGNED_INT&&e!==r.FLOAT||(s=4),t===r.RGBA?4*s:t===r.RGB?3*s:t===r.ALPHA?s:void 0}dispose(){const{gl:e}=this;null!==this._srcFramebuffer&&e.deleteFramebuffer(this._srcFramebuffer),null!==this._dstFramebuffer&&e.deleteFramebuffer(this._dstFramebuffer)}}function xR(e){return e.isDataTexture?e.image.data:"undefined"!=typeof HTMLImageElement&&e instanceof HTMLImageElement||"undefined"!=typeof HTMLCanvasElement&&e instanceof HTMLCanvasElement||"undefined"!=typeof ImageBitmap&&e instanceof ImageBitmap||"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas?e:e.data}class TR{constructor(e){this.backend=e,this.gl=this.backend.gl,this.availableExtensions=this.gl.getSupportedExtensions(),this.extensions={}}get(e){let t=this.extensions[e];return void 0===t&&(t=this.gl.getExtension(e),this.extensions[e]=t),t}has(e){return this.availableExtensions.includes(e)}}class _R{constructor(e){this.backend=e,this.maxAnisotropy=null}getMaxAnisotropy(){if(null!==this.maxAnisotropy)return this.maxAnisotropy;const e=this.backend.gl,t=this.backend.extensions;if(!0===t.has("EXT_texture_filter_anisotropic")){const r=t.get("EXT_texture_filter_anisotropic");this.maxAnisotropy=e.getParameter(r.MAX_TEXTURE_MAX_ANISOTROPY_EXT)}else this.maxAnisotropy=0;return this.maxAnisotropy}}const vR={WEBGL_multi_draw:"WEBGL_multi_draw",WEBGL_compressed_texture_astc:"texture-compression-astc",WEBGL_compressed_texture_etc:"texture-compression-etc2",WEBGL_compressed_texture_etc1:"texture-compression-etc1",WEBGL_compressed_texture_pvrtc:"texture-compression-pvrtc",WEBGL_compressed_texture_s3tc:"texture-compression-s3tc",EXT_texture_compression_bptc:"texture-compression-bc",EXT_disjoint_timer_query_webgl2:"timestamp-query",OVR_multiview2:"OVR_multiview2"};class NR{constructor(e){this.gl=e.gl,this.extensions=e.extensions,this.info=e.renderer.info,this.mode=null,this.index=0,this.type=null,this.object=null}render(e,t){const{gl:r,mode:s,object:i,type:n,info:a,index:o}=this;0!==o?r.drawElements(s,t,n,e):r.drawArrays(s,e,t),a.update(i,t,1)}renderInstances(e,t,r){const{gl:s,mode:i,type:n,index:a,object:o,info:u}=this;0!==r&&(0!==a?s.drawElementsInstanced(i,t,n,e,r):s.drawArraysInstanced(i,e,t,r),u.update(o,t,r))}renderMultiDraw(e,t,r){const{extensions:s,mode:i,object:n,info:a}=this;if(0===r)return;const o=s.get("WEBGL_multi_draw");if(null===o)for(let s=0;sthis.maxQueries)return v(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`),null;const t=this.currentQueryIndex;return this.currentQueryIndex+=2,this.queryStates.set(t,"inactive"),this.queryOffsets.set(e,t),t}beginQuery(e){if(!this.trackTimestamp||this.isDisposed)return;const t=this.queryOffsets.get(e);if(null==t)return;if(null!==this.activeQuery)return;const r=this.queries[t];if(r)try{"inactive"===this.queryStates.get(t)&&(this.gl.beginQuery(this.ext.TIME_ELAPSED_EXT,r),this.activeQuery=t,this.queryStates.set(t,"started"))}catch(e){o("Error in beginQuery:",e),this.activeQuery=null,this.queryStates.set(t,"inactive")}}endQuery(e){if(!this.trackTimestamp||this.isDisposed)return;const t=this.queryOffsets.get(e);if(null!=t&&this.activeQuery===t)try{this.gl.endQuery(this.ext.TIME_ELAPSED_EXT),this.queryStates.set(t,"ended"),this.activeQuery=null}catch(e){o("Error in endQuery:",e),this.queryStates.set(t,"inactive"),this.activeQuery=null}}async resolveQueriesAsync(){if(!this.trackTimestamp||this.pendingResolve)return this.lastValue;this.pendingResolve=!0;try{const e=new Map;for(const[t,r]of this.queryOffsets){if("ended"===this.queryStates.get(r)){const s=this.queries[r];e.set(t,this.resolveQuery(s))}}if(0===e.size)return this.lastValue;const t={},r=[];for(const[s,i]of e){const e=s.match(/^(.*):f(\d+)$/),n=parseInt(e[2]);!1===r.includes(n)&&r.push(n),void 0===t[n]&&(t[n]=0);const a=await i;this.timestamps.set(s,a),t[n]+=a}const s=t[r[r.length-1]];return this.lastValue=s,this.frames=r,this.currentQueryIndex=0,this.queryOffsets.clear(),this.queryStates.clear(),this.activeQuery=null,s}catch(e){return o("Error resolving queries:",e),this.lastValue}finally{this.pendingResolve=!1}}async resolveQuery(e){return new Promise(t=>{if(this.isDisposed)return void t(this.lastValue);let r,s=!1;const i=e=>{s||(s=!0,r&&(clearTimeout(r),r=null),t(e))},n=()=>{if(this.isDisposed)i(this.lastValue);else try{if(this.gl.getParameter(this.ext.GPU_DISJOINT_EXT))return void i(this.lastValue);if(!this.gl.getQueryParameter(e,this.gl.QUERY_RESULT_AVAILABLE))return void(r=setTimeout(n,1));const s=this.gl.getQueryParameter(e,this.gl.QUERY_RESULT);t(Number(s)/1e6)}catch(e){o("Error checking query:",e),t(this.lastValue)}};n()})}dispose(){if(!this.isDisposed&&(this.isDisposed=!0,this.trackTimestamp)){for(const e of this.queries)this.gl.deleteQuery(e);this.queries=[],this.queryStates.clear(),this.queryOffsets.clear(),this.lastValue=0,this.activeQuery=null}}}class AR extends aR{constructor(e={}){super(e),this.isWebGLBackend=!0,this.attributeUtils=null,this.extensions=null,this.capabilities=null,this.textureUtils=null,this.bufferRenderer=null,this.gl=null,this.state=null,this.utils=null,this.vaoCache={},this.transformFeedbackCache={},this.discard=!1,this.disjoint=null,this.parallel=null,this._currentContext=null,this._knownBindings=new WeakSet,this._supportsInvalidateFramebuffer="undefined"!=typeof navigator&&/OculusBrowser/g.test(navigator.userAgent),this._xrFramebuffer=null}init(e){super.init(e);const t=this.parameters,r={antialias:e.currentSamples>0,alpha:!0,depth:e.depth,stencil:e.stencil},s=void 0!==t.context?t.context:e.domElement.getContext("webgl2",r);function i(t){t.preventDefault();const r={api:"WebGL",message:t.statusMessage||"Unknown reason",reason:null,originalEvent:t};e.onDeviceLost(r)}this._onContextLost=i,e.domElement.addEventListener("webglcontextlost",i,!1),this.gl=s,this.extensions=new TR(this),this.capabilities=new _R(this),this.attributeUtils=new cR(this),this.textureUtils=new bR(this),this.bufferRenderer=new NR(this),this.state=new hR(this),this.utils=new pR(this),this.extensions.get("EXT_color_buffer_float"),this.extensions.get("WEBGL_clip_cull_distance"),this.extensions.get("OES_texture_float_linear"),this.extensions.get("EXT_color_buffer_half_float"),this.extensions.get("WEBGL_multisampled_render_to_texture"),this.extensions.get("WEBGL_render_shared_exponent"),this.extensions.get("WEBGL_multi_draw"),this.extensions.get("OVR_multiview2"),this.disjoint=this.extensions.get("EXT_disjoint_timer_query_webgl2"),this.parallel=this.extensions.get("KHR_parallel_shader_compile"),this.drawBuffersIndexedExt=this.extensions.get("OES_draw_buffers_indexed")}get coordinateSystem(){return c}async getArrayBufferAsync(e){return await this.attributeUtils.getArrayBufferAsync(e)}async makeXRCompatible(){!0!==this.gl.getContextAttributes().xrCompatible&&await this.gl.makeXRCompatible()}setXRTarget(e){this._xrFramebuffer=e}setXRRenderTargetTextures(e,t,r=null){const s=this.gl;if(this.set(e.texture,{textureGPU:t,glInternalFormat:s.RGBA8}),null!==r){const t=e.stencilBuffer?s.DEPTH24_STENCIL8:s.DEPTH_COMPONENT24;this.set(e.depthTexture,{textureGPU:r,glInternalFormat:t}),!0===this.extensions.has("WEBGL_multisampled_render_to_texture")&&!0===e._autoAllocateDepthBuffer&&!1===e.multiview&&d("WebGLBackend: Render-to-texture extension was disabled because an external texture was provided"),e._autoAllocateDepthBuffer=!1}}initTimestampQuery(e,t){if(!this.disjoint||!this.trackTimestamp)return;this.timestampQueryPool[e]||(this.timestampQueryPool[e]=new RR(this.gl,e,2048));const r=this.timestampQueryPool[e];null!==r.allocateQueriesForContext(t)&&r.beginQuery(t)}prepareTimestampBuffer(e,t){if(!this.disjoint||!this.trackTimestamp)return;this.timestampQueryPool[e].endQuery(t)}getContext(){return this.gl}beginRender(e){const{state:t}=this,r=this.get(e);if(e.viewport)this.updateViewport(e);else{const{width:e,height:r}=this.getDrawingBufferSize();t.viewport(0,0,e,r)}if(e.scissor)this.updateScissor(e);else{const{width:e,height:r}=this.getDrawingBufferSize();t.scissor(0,0,e,r)}this.initTimestampQuery(wt.RENDER,this.getTimestampUID(e)),r.previousContext=this._currentContext,this._currentContext=e,this._setFramebuffer(e),this.clear(e.clearColor,e.clearDepth,e.clearStencil,e,!1);const s=e.occlusionQueryCount;s>0&&(r.currentOcclusionQueries=r.occlusionQueries,r.currentOcclusionQueryObjects=r.occlusionQueryObjects,r.lastOcclusionObject=null,r.occlusionQueries=new Array(s),r.occlusionQueryObjects=new Array(s),r.occlusionQueryIndex=0)}finishRender(e){const{gl:t,state:r}=this,s=this.get(e),i=s.previousContext;r.resetVertexState();const n=e.occlusionQueryCount;n>0&&(n>s.occlusionQueryIndex&&t.endQuery(t.ANY_SAMPLES_PASSED),this.resolveOccludedAsync(e));const a=e.textures;if(null!==a)for(let e=0;e{let a=0;for(let t=0;t{t.isBatchedMesh?null!==t._multiDrawInstances?(v("WebGLBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection."),b.renderMultiDrawInstances(t._multiDrawStarts,t._multiDrawCounts,t._multiDrawCount,t._multiDrawInstances)):this.hasFeature("WEBGL_multi_draw")?b.renderMultiDraw(t._multiDrawStarts,t._multiDrawCounts,t._multiDrawCount):v("WebGLBackend: WEBGL_multi_draw not supported."):T>1?b.renderInstances(_,x,T):b.render(_,x)};if(!0===e.camera.isArrayCamera&&e.camera.cameras.length>0&&!1===e.camera.isMultiViewCamera){const r=this.get(e.camera),s=e.camera.cameras,i=e.getBindingGroup("cameraIndex").bindings[0];if(void 0===r.indexesGPU||r.indexesGPU.length!==s.length){const e=new Uint32Array([0,0,0,0]),t=[];for(let r=0,i=s.length;r{const i=this.parallel,n=()=>{r.getProgramParameter(a,i.COMPLETION_STATUS_KHR)?(this._completeCompile(e,s),t()):requestAnimationFrame(n)};n()});return void t.push(i)}this._completeCompile(e,s)}_handleSource(e,t){const r=e.split("\n"),s=[],i=Math.max(t-6,0),n=Math.min(t+6,r.length);for(let e=i;e":" "} ${i}: ${r[e]}`)}return s.join("\n")}_getShaderErrors(e,t,r){const s=e.getShaderParameter(t,e.COMPILE_STATUS),i=(e.getShaderInfoLog(t)||"").trim();if(s&&""===i)return"";const n=/ERROR: 0:(\d+)/.exec(i);if(n){const s=parseInt(n[1]);return r.toUpperCase()+"\n\n"+i+"\n\n"+this._handleSource(e.getShaderSource(t),s)}return i}_logProgramError(e,t,r){if(this.renderer.debug.checkShaderErrors){const s=this.gl,i=(s.getProgramInfoLog(e)||"").trim();if(!1===s.getProgramParameter(e,s.LINK_STATUS))if("function"==typeof this.renderer.debug.onShaderError)this.renderer.debug.onShaderError(s,e,r,t);else{const n=this._getShaderErrors(s,r,"vertex"),a=this._getShaderErrors(s,t,"fragment");o("THREE.WebGLProgram: Shader Error "+s.getError()+" - VALIDATE_STATUS "+s.getProgramParameter(e,s.VALIDATE_STATUS)+"\n\nProgram Info Log: "+i+"\n"+n+"\n"+a)}else""!==i&&d("WebGLProgram: Program Info Log:",i)}}_completeCompile(e,t){const{state:r,gl:s}=this,i=this.get(t),{programGPU:n,fragmentShader:a,vertexShader:o}=i;!1===s.getProgramParameter(n,s.LINK_STATUS)&&this._logProgramError(n,a,o),r.useProgram(n);const u=e.getBindings();this._setupBindings(u,n),this.set(t,{programGPU:n})}createComputePipeline(e,t){const{state:r,gl:s}=this,i={stage:"fragment",code:"#version 300 es\nprecision highp float;\nvoid main() {}"};this.createProgram(i);const{computeProgram:n}=e,a=s.createProgram(),o=this.get(i).shaderGPU,u=this.get(n).shaderGPU,l=n.transforms,d=[],c=[];for(let e=0;evR[t]===e),r=this.extensions;for(let e=0;e1,h=!0===i.isXRRenderTarget,p=!0===h&&!0===i._hasExternalTextures;let g=n.msaaFrameBuffer,m=n.depthRenderbuffer;const f=this.extensions.get("WEBGL_multisampled_render_to_texture"),y=this.extensions.get("OVR_multiview2"),b=this._useMultisampledExtension(i),x=wy(e);let T;if(l?(n.cubeFramebuffers||(n.cubeFramebuffers={}),T=n.cubeFramebuffers[x]):h&&!1===p?T=this._xrFramebuffer:(n.framebuffers||(n.framebuffers={}),T=n.framebuffers[x]),void 0===T){T=t.createFramebuffer(),r.bindFramebuffer(t.FRAMEBUFFER,T);const s=e.textures,o=[];if(l){n.cubeFramebuffers[x]=T;const{textureGPU:e}=this.get(s[0]),r=this.renderer._activeCubeFace,i=this.renderer._activeMipmapLevel;t.framebufferTexture2D(t.FRAMEBUFFER,t.COLOR_ATTACHMENT0,t.TEXTURE_CUBE_MAP_POSITIVE_X+r,e,i)}else{n.framebuffers[x]=T;for(let r=0;r0&&!1===b&&!i.multiview){if(void 0===g){const s=[];g=t.createFramebuffer(),r.bindFramebuffer(t.FRAMEBUFFER,g);const i=[],l=e.textures;for(let r=0;r0&&!1===this._useMultisampledExtension(s)){const n=i.framebuffers[e.getCacheKey()];let a=t.COLOR_BUFFER_BIT;s.resolveDepthBuffer&&(s.depthBuffer&&(a|=t.DEPTH_BUFFER_BIT),s.stencilBuffer&&s.resolveStencilBuffer&&(a|=t.STENCIL_BUFFER_BIT));const o=i.msaaFrameBuffer,u=i.msaaRenderbuffers,l=e.textures,d=l.length>1;if(r.bindFramebuffer(t.READ_FRAMEBUFFER,o),r.bindFramebuffer(t.DRAW_FRAMEBUFFER,n),d)for(let e=0;e0&&!0===this.extensions.has("WEBGL_multisampled_render_to_texture")&&!1!==e._autoAllocateDepthBuffer}dispose(){null!==this.textureUtils&&this.textureUtils.dispose();const e=this.extensions.get("WEBGL_lose_context");e&&e.loseContext(),this.renderer.domElement.removeEventListener("webglcontextlost",this._onContextLost)}}const ER="point-list",wR="line-list",CR="line-strip",MR="triangle-list",BR="undefined"!=typeof self&&self.GPUShaderStage?self.GPUShaderStage:{VERTEX:1,FRAGMENT:2,COMPUTE:4},FR="never",LR="less",PR="equal",DR="less-equal",UR="greater",IR="not-equal",OR="greater-equal",VR="always",kR="store",GR="load",zR="clear",$R="ccw",WR="cw",HR="none",qR="back",jR="uint16",XR="uint32",KR="r8unorm",YR="r8snorm",QR="r8uint",ZR="r8sint",JR="r16uint",eA="r16sint",tA="r16float",rA="rg8unorm",sA="rg8snorm",iA="rg8uint",nA="rg8sint",aA="r32uint",oA="r32sint",uA="r32float",lA="rg16uint",dA="rg16sint",cA="rg16float",hA="rgba8unorm",pA="rgba8unorm-srgb",gA="rgba8snorm",mA="rgba8uint",fA="rgba8sint",yA="bgra8unorm",bA="bgra8unorm-srgb",xA="rgb9e5ufloat",TA="rgb10a2unorm",_A="rg11b10ufloat",vA="rg32uint",NA="rg32sint",SA="rg32float",RA="rgba16uint",AA="rgba16sint",EA="rgba16float",wA="rgba32uint",CA="rgba32sint",MA="rgba32float",BA="depth16unorm",FA="depth24plus",LA="depth24plus-stencil8",PA="depth32float",DA="depth32float-stencil8",UA="bc1-rgba-unorm",IA="bc1-rgba-unorm-srgb",OA="bc2-rgba-unorm",VA="bc2-rgba-unorm-srgb",kA="bc3-rgba-unorm",GA="bc3-rgba-unorm-srgb",zA="bc4-r-unorm",$A="bc4-r-snorm",WA="bc5-rg-unorm",HA="bc5-rg-snorm",qA="bc6h-rgb-ufloat",jA="bc6h-rgb-float",XA="bc7-rgba-unorm",KA="bc7-rgba-unorm-srgb",YA="etc2-rgb8unorm",QA="etc2-rgb8unorm-srgb",ZA="etc2-rgb8a1unorm",JA="etc2-rgb8a1unorm-srgb",eE="etc2-rgba8unorm",tE="etc2-rgba8unorm-srgb",rE="eac-r11unorm",sE="eac-r11snorm",iE="eac-rg11unorm",nE="eac-rg11snorm",aE="astc-4x4-unorm",oE="astc-4x4-unorm-srgb",uE="astc-5x4-unorm",lE="astc-5x4-unorm-srgb",dE="astc-5x5-unorm",cE="astc-5x5-unorm-srgb",hE="astc-6x5-unorm",pE="astc-6x5-unorm-srgb",gE="astc-6x6-unorm",mE="astc-6x6-unorm-srgb",fE="astc-8x5-unorm",yE="astc-8x5-unorm-srgb",bE="astc-8x6-unorm",xE="astc-8x6-unorm-srgb",TE="astc-8x8-unorm",_E="astc-8x8-unorm-srgb",vE="astc-10x5-unorm",NE="astc-10x5-unorm-srgb",SE="astc-10x6-unorm",RE="astc-10x6-unorm-srgb",AE="astc-10x8-unorm",EE="astc-10x8-unorm-srgb",wE="astc-10x10-unorm",CE="astc-10x10-unorm-srgb",ME="astc-12x10-unorm",BE="astc-12x10-unorm-srgb",FE="astc-12x12-unorm",LE="astc-12x12-unorm-srgb",PE="clamp-to-edge",DE="repeat",UE="mirror-repeat",IE="linear",OE="nearest",VE="zero",kE="one",GE="src",zE="one-minus-src",$E="src-alpha",WE="one-minus-src-alpha",HE="dst",qE="one-minus-dst",jE="dst-alpha",XE="one-minus-dst-alpha",KE="src-alpha-saturated",YE="constant",QE="one-minus-constant",ZE="add",JE="subtract",ew="reverse-subtract",tw="min",rw="max",sw=0,iw=15,nw="keep",aw="zero",ow="replace",uw="invert",lw="increment-clamp",dw="decrement-clamp",cw="increment-wrap",hw="decrement-wrap",pw="storage",gw="read-only-storage",mw="write-only",fw="read-only",yw="read-write",bw="non-filtering",xw="comparison",Tw="float",_w="unfilterable-float",vw="depth",Nw="sint",Sw="uint",Rw="2d",Aw="3d",Ew="2d",ww="2d-array",Cw="cube",Mw="3d",Bw="all",Fw="vertex",Lw="instance",Pw={CoreFeaturesAndLimits:"core-features-and-limits",DepthClipControl:"depth-clip-control",Depth32FloatStencil8:"depth32float-stencil8",TextureCompressionBC:"texture-compression-bc",TextureCompressionBCSliced3D:"texture-compression-bc-sliced-3d",TextureCompressionETC2:"texture-compression-etc2",TextureCompressionASTC:"texture-compression-astc",TextureCompressionASTCSliced3D:"texture-compression-astc-sliced-3d",TimestampQuery:"timestamp-query",IndirectFirstInstance:"indirect-first-instance",ShaderF16:"shader-f16",RG11B10UFloat:"rg11b10ufloat-renderable",BGRA8UNormStorage:"bgra8unorm-storage",Float32Filterable:"float32-filterable",Float32Blendable:"float32-blendable",ClipDistances:"clip-distances",DualSourceBlending:"dual-source-blending",Subgroups:"subgroups",TextureFormatsTier1:"texture-formats-tier1",TextureFormatsTier2:"texture-formats-tier2"},Dw={"texture-compression-s3tc":"texture-compression-bc","texture-compression-etc1":"texture-compression-etc2"};class Uw extends WS{constructor(e,t,r){super(e,t?t.value:null),this.textureNode=t,this.groupNode=r}update(){const{textureNode:e}=this;return this.texture!==e.value?(this.texture=e.value,!0):super.update()}}class Iw extends IS{constructor(e,t){super(e,t?t.array:null),this._attribute=t,this.isStorageBuffer=!0}get attribute(){return this._attribute}}let Ow=0;class Vw extends Iw{constructor(e,t){super("StorageBuffer_"+Ow++,e?e.value:null),this.nodeUniform=e,this.access=e?e.access:ei.READ_WRITE,this.groupNode=t}get attribute(){return this.nodeUniform.value}get buffer(){return this.nodeUniform.value.array}}class kw extends ty{constructor(e){super(),this.device=e;this.mipmapSampler=e.createSampler({minFilter:IE}),this.flipYSampler=e.createSampler({minFilter:OE}),this.flipUniformBuffer=e.createBuffer({size:4,usage:GPUBufferUsage.UNIFORM|GPUBufferUsage.COPY_DST}),e.queue.writeBuffer(this.flipUniformBuffer,0,new Uint32Array([1])),this.noFlipUniformBuffer=e.createBuffer({size:4,usage:GPUBufferUsage.UNIFORM}),this.transferPipelines={},this.mipmapShaderModule=e.createShaderModule({label:"mipmap",code:"\nstruct VarysStruct {\n\t@builtin( position ) Position: vec4f,\n\t@location( 0 ) vTex : vec2f,\n\t@location( 1 ) @interpolate(flat, either) vBaseArrayLayer: u32,\n};\n\n@group( 0 ) @binding ( 2 )\nvar flipY: u32;\n\n@vertex\nfn mainVS(\n\t\t@builtin( vertex_index ) vertexIndex : u32,\n\t\t@builtin( instance_index ) instanceIndex : u32 ) -> VarysStruct {\n\n\tvar Varys : VarysStruct;\n\n\tvar pos = array(\n\t\tvec2f( -1, -1 ),\n\t\tvec2f( -1, 3 ),\n\t\tvec2f( 3, -1 ),\n\t);\n\n\tlet p = pos[ vertexIndex ];\n\tlet mult = select( vec2f( 0.5, -0.5 ), vec2f( 0.5, 0.5 ), flipY != 0 );\n\tVarys.vTex = p * vec2f( 0.5, -0.5 ) + vec2f( 0.5 );\n\tVarys.Position = vec4f( p, 0, 1 );\n\tVarys.vBaseArrayLayer = instanceIndex;\n\n\treturn Varys;\n\n}\n\n@group( 0 ) @binding( 0 )\nvar imgSampler : sampler;\n\n@group( 0 ) @binding( 1 )\nvar img2d : texture_2d;\n\n@fragment\nfn main_2d( Varys: VarysStruct ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( img2d, imgSampler, Varys.vTex );\n\n}\n\n@group( 0 ) @binding( 1 )\nvar img2dArray : texture_2d_array;\n\n@fragment\nfn main_2d_array( Varys: VarysStruct ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( img2dArray, imgSampler, Varys.vTex, Varys.vBaseArrayLayer );\n\n}\n\nconst faceMat = array(\n mat3x3f( 0, 0, -2, 0, -2, 0, 1, 1, 1 ), // pos-x\n mat3x3f( 0, 0, 2, 0, -2, 0, -1, 1, -1 ), // neg-x\n mat3x3f( 2, 0, 0, 0, 0, 2, -1, 1, -1 ), // pos-y\n mat3x3f( 2, 0, 0, 0, 0, -2, -1, -1, 1 ), // neg-y\n mat3x3f( 2, 0, 0, 0, -2, 0, -1, 1, 1 ), // pos-z\n mat3x3f( -2, 0, 0, 0, -2, 0, 1, 1, -1 ), // neg-z\n);\n\n@group( 0 ) @binding( 1 )\nvar imgCube : texture_cube;\n\n@fragment\nfn main_cube( Varys: VarysStruct ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( imgCube, imgSampler, faceMat[ Varys.vBaseArrayLayer ] * vec3f( fract( Varys.vTex ), 1 ) );\n\n}\n\n@group( 0 ) @binding( 1 )\nvar imgCubeArray : texture_cube_array;\n\n@fragment\nfn main_cube_array( Varys: VarysStruct ) -> @location( 0 ) vec4 {\n\n\treturn textureSample( imgCubeArray, imgSampler, faceMat[ Varys.vBaseArrayLayer % 6 ] * vec3f( fract( Varys.vTex ), 1 ), Varys.vBaseArrayLayer );\n\n}\n"})}getTransferPipeline(e,t){const r=`${e}-${t=t||"2d-array"}`;let s=this.transferPipelines[r];return void 0===s&&(s=this.device.createRenderPipeline({label:`mipmap-${e}-${t}`,vertex:{module:this.mipmapShaderModule},fragment:{module:this.mipmapShaderModule,entryPoint:`main_${t.replace("-","_")}`,targets:[{format:e}]},layout:"auto"}),this.transferPipelines[e]=s),s}flipY(e,t,r=0){const s=t.format,{width:i,height:n}=t.size,a=this.device.createTexture({size:{width:i,height:n},format:s,usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.TEXTURE_BINDING}),o=this.getTransferPipeline(s,e.textureBindingViewDimension),u=this.getTransferPipeline(s,a.textureBindingViewDimension),l=this.device.createCommandEncoder({}),d=(e,t,r,s,i,n)=>{const a=e.getBindGroupLayout(0),o=this.device.createBindGroup({layout:a,entries:[{binding:0,resource:this.flipYSampler},{binding:1,resource:t.createView({dimension:t.textureBindingViewDimension||"2d-array",baseMipLevel:0,mipLevelCount:1})},{binding:2,resource:{buffer:n?this.flipUniformBuffer:this.noFlipUniformBuffer}}]}),u=l.beginRenderPass({colorAttachments:[{view:s.createView({dimension:"2d",baseMipLevel:0,mipLevelCount:1,baseArrayLayer:i,arrayLayerCount:1}),loadOp:zR,storeOp:kR}]});u.setPipeline(e),u.setBindGroup(0,o),u.draw(3,1,0,r),u.end()};d(o,e,r,a,0,!1),d(u,a,0,e,r,!0),this.device.queue.submit([l.finish()]),a.destroy()}generateMipmaps(e,t=null){const r=this.get(e),s=r.layers||this._mipmapCreateBundles(e),i=t||this.device.createCommandEncoder({label:"mipmapEncoder"});this._mipmapRunBundles(i,s),null===t&&this.device.queue.submit([i.finish()]),r.layers=s}_mipmapCreateBundles(e){const t=e.textureBindingViewDimension||"2d-array",r=this.getTransferPipeline(e.format,t),s=r.getBindGroupLayout(0),i=[];for(let n=1;n0)for(let t=0,n=s.length;t0)for(let t=0,n=s.length;t0?e.width:r.size.width,l=a>0?e.height:r.size.height;try{o.queue.copyExternalImageToTexture({source:e,flipY:i},{texture:t,mipLevel:a,origin:{x:0,y:0,z:s},premultipliedAlpha:n},{width:u,height:l,depthOrArrayLayers:1})}catch(e){}}_getPassUtils(){let e=this._passUtils;return null===e&&(this._passUtils=e=new kw(this.backend.device)),e}_generateMipmaps(e,t,r=0,s=null){this._getPassUtils().generateMipmaps(e,t,r,s)}_flipY(e,t,r=0){this._getPassUtils().flipY(e,t,r)}_copyBufferToTexture(e,t,r,s,i,n=0,a=0){const o=this.backend.device,u=e.data,l=this._getBytesPerTexel(r.format),d=e.width*l;o.queue.writeTexture({texture:t,mipLevel:a,origin:{x:0,y:0,z:s}},u,{offset:e.width*e.height*l*n,bytesPerRow:d},{width:e.width,height:e.height,depthOrArrayLayers:1}),!0===i&&this._flipY(t,r,s)}_copyCompressedBufferToTexture(e,t,r){const s=this.backend.device,i=this._getBlockData(r.format),n=r.size.depthOrArrayLayers>1;for(let a=0;a]*\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/i,qw=/([a-z_0-9]+)\s*:\s*([a-z_0-9]+(?:<[\s\S]+?>)?)/gi,jw={f32:"float",i32:"int",u32:"uint",bool:"bool","vec2":"vec2","vec2":"ivec2","vec2":"uvec2","vec2":"bvec2",vec2f:"vec2",vec2i:"ivec2",vec2u:"uvec2",vec2b:"bvec2","vec3":"vec3","vec3":"ivec3","vec3":"uvec3","vec3":"bvec3",vec3f:"vec3",vec3i:"ivec3",vec3u:"uvec3",vec3b:"bvec3","vec4":"vec4","vec4":"ivec4","vec4":"uvec4","vec4":"bvec4",vec4f:"vec4",vec4i:"ivec4",vec4u:"uvec4",vec4b:"bvec4","mat2x2":"mat2",mat2x2f:"mat2","mat3x3":"mat3",mat3x3f:"mat3","mat4x4":"mat4",mat4x4f:"mat4",sampler:"sampler",texture_1d:"texture",texture_2d:"texture",texture_2d_array:"texture",texture_multisampled_2d:"cubeTexture",texture_depth_2d:"depthTexture",texture_depth_2d_array:"depthTexture",texture_depth_multisampled_2d:"depthTexture",texture_depth_cube:"depthTexture",texture_depth_cube_array:"depthTexture",texture_3d:"texture3D",texture_cube:"cubeTexture",texture_cube_array:"cubeTexture",texture_storage_1d:"storageTexture",texture_storage_2d:"storageTexture",texture_storage_2d_array:"storageTexture",texture_storage_3d:"storageTexture"};class Xw extends QN{constructor(e){const{type:t,inputs:r,name:s,inputsCode:i,blockCode:n,outputType:a}=(e=>{const t=(e=e.trim()).match(Hw);if(null!==t&&4===t.length){const r=t[2],s=[];let i=null;for(;null!==(i=qw.exec(r));)s.push({name:i[1],type:i[2]});const n=[];for(let e=0;e "+this.outputType:"";return`fn ${e} ( ${this.inputsCode.trim()} ) ${t}`+this.blockCode}}class Kw extends YN{parseFunction(e){return new Xw(e)}}const Yw={[ei.READ_ONLY]:"read",[ei.WRITE_ONLY]:"write",[ei.READ_WRITE]:"read_write"},Qw={[Or]:"repeat",[xe]:"clamp",[Ir]:"mirror"},Zw={vertex:BR.VERTEX,fragment:BR.FRAGMENT,compute:BR.COMPUTE},Jw={instance:!0,swizzleAssign:!1,storageBuffer:!0},eC={"^^":"tsl_xor"},tC={float:"f32",int:"i32",uint:"u32",bool:"bool",color:"vec3",vec2:"vec2",ivec2:"vec2",uvec2:"vec2",bvec2:"vec2",vec3:"vec3",ivec3:"vec3",uvec3:"vec3",bvec3:"vec3",vec4:"vec4",ivec4:"vec4",uvec4:"vec4",bvec4:"vec4",mat2:"mat2x2",mat3:"mat3x3",mat4:"mat4x4"},rC={},sC={tsl_xor:new Xx("fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }"),mod_float:new Xx("fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }"),mod_vec2:new Xx("fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }"),mod_vec3:new Xx("fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }"),mod_vec4:new Xx("fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }"),equals_bool:new Xx("fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }"),equals_bvec2:new Xx("fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }"),equals_bvec3:new Xx("fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }"),equals_bvec4:new Xx("fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }"),repeatWrapping_float:new Xx("fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }"),mirrorWrapping_float:new Xx("fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }"),clampWrapping_float:new Xx("fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }"),biquadraticTexture:new Xx("\nfn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, iRes : vec2u, level : u32 ) -> vec4f {\n\n\tlet res = vec2f( iRes );\n\n\tlet uvScaled = coord * res;\n\tlet uvWrapping = ( ( uvScaled % res ) + res ) % res;\n\n\t// https://www.shadertoy.com/view/WtyXRy\n\n\tlet uv = uvWrapping - 0.5;\n\tlet iuv = floor( uv );\n\tlet f = fract( uv );\n\n\tlet rg1 = textureLoad( map, vec2u( iuv + vec2( 0.5, 0.5 ) ) % iRes, level );\n\tlet rg2 = textureLoad( map, vec2u( iuv + vec2( 1.5, 0.5 ) ) % iRes, level );\n\tlet rg3 = textureLoad( map, vec2u( iuv + vec2( 0.5, 1.5 ) ) % iRes, level );\n\tlet rg4 = textureLoad( map, vec2u( iuv + vec2( 1.5, 1.5 ) ) % iRes, level );\n\n\treturn mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y );\n\n}\n")},iC={dFdx:"dpdx",dFdy:"- dpdy",mod_float:"tsl_mod_float",mod_vec2:"tsl_mod_vec2",mod_vec3:"tsl_mod_vec3",mod_vec4:"tsl_mod_vec4",equals_bool:"tsl_equals_bool",equals_bvec2:"tsl_equals_bvec2",equals_bvec3:"tsl_equals_bvec3",equals_bvec4:"tsl_equals_bvec4",inversesqrt:"inverseSqrt",bitcast:"bitcast",floatpack_snorm_2x16:"pack2x16snorm",floatpack_unorm_2x16:"pack2x16unorm",floatpack_float16_2x16:"pack2x16float",floatunpack_snorm_2x16:"unpack2x16snorm",floatunpack_unorm_2x16:"unpack2x16unorm",floatunpack_float16_2x16:"unpack2x16float"};let nC="";!0!==("undefined"!=typeof navigator&&/Firefox|Deno/g.test(navigator.userAgent))&&(nC+="diagnostic( off, derivative_uniformity );\n");class aC extends DN{constructor(e,t){super(e,t,new Kw),this.uniformGroups={},this.uniformGroupsBindings={},this.builtins={},this.directives={},this.scopedArrays=new Map}_generateTextureSample(e,t,r,s,i,n=this.shaderStage){return"fragment"===n?s?i?`textureSample( ${t}, ${t}_sampler, ${r}, ${s}, ${i} )`:`textureSample( ${t}, ${t}_sampler, ${r}, ${s} )`:i?`textureSample( ${t}, ${t}_sampler, ${r}, ${i} )`:`textureSample( ${t}, ${t}_sampler, ${r} )`:this.generateTextureSampleLevel(e,t,r,"0",s)}generateTextureSampleLevel(e,t,r,s,i,n){return!1===this.isUnfilterable(e)?n?`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s} )`:this.isFilteredTexture(e)?this.generateFilteredTexture(e,t,r,n,s):this.generateTextureLod(e,t,r,i,n,s)}generateWrapFunction(e){const t=`tsl_coord_${Qw[e.wrapS]}S_${Qw[e.wrapT]}_${e.is3DTexture||e.isData3DTexture?"3d":"2d"}T`;let r=rC[t];if(void 0===r){const s=[],i=e.is3DTexture||e.isData3DTexture?"vec3f":"vec2f";let n=`fn ${t}( coord : ${i} ) -> ${i} {\n\n\treturn ${i}(\n`;const a=(e,t)=>{e===Or?(s.push(sC.repeatWrapping_float),n+=`\t\ttsl_repeatWrapping_float( coord.${t} )`):e===xe?(s.push(sC.clampWrapping_float),n+=`\t\ttsl_clampWrapping_float( coord.${t} )`):e===Ir?(s.push(sC.mirrorWrapping_float),n+=`\t\ttsl_mirrorWrapping_float( coord.${t} )`):(n+=`\t\tcoord.${t}`,d(`WebGPURenderer: Unsupported texture wrap type "${e}" for vertex shader.`))};a(e.wrapS,"x"),n+=",\n",a(e.wrapT,"y"),(e.is3DTexture||e.isData3DTexture)&&(n+=",\n",a(e.wrapR,"z")),n+="\n\t);\n\n}\n",rC[t]=r=new Xx(n,s)}return r.build(this),t}generateArrayDeclaration(e,t){return`array< ${this.getType(e)}, ${t} >`}generateTextureDimension(e,t,r){const s=this.getDataFromNode(e,this.shaderStage,this.globalCache);void 0===s.dimensionsSnippet&&(s.dimensionsSnippet={});let i=s.dimensionsSnippet[r];if(void 0===s.dimensionsSnippet[r]){let n,a;const{primarySamples:o}=this.renderer.backend.utils.getTextureSampleData(e),u=o>1;a=e.is3DTexture||e.isData3DTexture?"vec3":"vec2",n=u||e.isStorageTexture?t:`${t}${r?`, u32( ${r} )`:""}`,i=new Ru(new hl(`textureDimensions( ${n} )`,a)),s.dimensionsSnippet[r]=i,(e.isArrayTexture||e.isDataArrayTexture||e.is3DTexture||e.isData3DTexture)&&(s.arrayLayerCount=new Ru(new hl(`textureNumLayers(${t})`,"u32"))),e.isTextureCube&&(s.cubeFaceCount=new Ru(new hl("6u","u32")))}return i.build(this)}generateFilteredTexture(e,t,r,s,i="0u"){this._include("biquadraticTexture");const n=this.generateWrapFunction(e),a=this.generateTextureDimension(e,t,i);return s&&(r=`${r} + vec2(${s}) / ${a}`),`tsl_biquadraticTexture( ${t}, ${n}( ${r} ), ${a}, u32( ${i} ) )`}generateTextureLod(e,t,r,s,i,n="0u"){if(!0===e.isCubeTexture){i&&(r=`${r} + vec3(${i})`);return`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${e.isDepthTexture?"u32":"f32"}( ${n} ) )`}const a=this.generateWrapFunction(e),o=this.generateTextureDimension(e,t,n),u=e.is3DTexture||e.isData3DTexture?"vec3":"vec2";i&&(r=`${r} + ${u}(${i}) / ${u}( ${o} )`);return r=`${u}( clamp( floor( ${a}( ${r} ) * ${u}( ${o} ) ), ${`${u}( 0 )`}, ${`${u}( ${o} - ${"vec3"===u?"vec3( 1, 1, 1 )":"vec2( 1, 1 )"} )`} ) )`,this.generateTextureLoad(e,t,r,n,s,null)}generateTextureLoad(e,t,r,s,i,n){const a=!0===e.isStorageTexture;let o;return null!==s||a||(s="0u"),n&&(r=`${r} + ${n}`),i?o=a?`textureLoad( ${t}, ${r}, ${i} )`:`textureLoad( ${t}, ${r}, ${i}, u32( ${s} ) )`:a?o=`textureLoad( ${t}, ${r} )`:(o=`textureLoad( ${t}, ${r}, u32( ${s} ) )`,this.renderer.backend.compatibilityMode&&e.isDepthTexture&&(o+=".x")),o}generateTextureStore(e,t,r,s,i){let n;return n=s?`textureStore( ${t}, ${r}, ${s}, ${i} )`:`textureStore( ${t}, ${r}, ${i} )`,n}isSampleCompare(e){return!0===e.isDepthTexture&&null!==e.compareFunction&&this.renderer.hasCompatibility(A.TEXTURE_COMPARE)}isUnfilterable(e){return"float"!==this.getComponentTypeFromTexture(e)||!this.isAvailable("float32Filterable")&&!0===e.isDataTexture&&e.type===j||!1===this.isSampleCompare(e)&&e.minFilter===w&&e.magFilter===w||this.renderer.backend.utils.getTextureSampleData(e).primarySamples>1}generateTexture(e,t,r,s,i,n=this.shaderStage){let a=null;return a=this.isUnfilterable(e)?this.generateTextureLod(e,t,r,s,i,"0",n):this._generateTextureSample(e,t,r,s,i,n),a}generateTextureGrad(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return n?`textureSampleGrad( ${t}, ${t}_sampler, ${r}, ${s[0]}, ${s[1]}, ${n} )`:`textureSampleGrad( ${t}, ${t}_sampler, ${r}, ${s[0]}, ${s[1]} )`;o(`WebGPURenderer: THREE.TextureNode.gradient() does not support ${a} shader.`)}generateTextureCompare(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return!0===e.isDepthTexture&&!0===e.isArrayTexture?n?`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${i}, ${s}, ${n} )`:`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${i}, ${s} )`:n?`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleCompare( ${t}, ${t}_sampler, ${r}, ${s} )`;o(`WebGPURenderer: THREE.DepthTexture.compareFunction() does not support ${a} shader.`)}generateTextureLevel(e,t,r,s,i,n){return!1===this.isUnfilterable(e)?n?`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleLevel( ${t}, ${t}_sampler, ${r}, ${s} )`:this.isFilteredTexture(e)?this.generateFilteredTexture(e,t,r,n,s):this.generateTextureLod(e,t,r,i,n,s)}generateTextureBias(e,t,r,s,i,n,a=this.shaderStage){if("fragment"===a)return n?`textureSampleBias( ${t}, ${t}_sampler, ${r}, ${s}, ${n} )`:`textureSampleBias( ${t}, ${t}_sampler, ${r}, ${s} )`;o(`WebGPURenderer: THREE.TextureNode.biasNode does not support ${a} shader.`)}getPropertyName(e,t=this.shaderStage){if(!0===e.isNodeVarying&&!0===e.needsInterpolation){if("vertex"===t)return`varyings.${e.name}`}else if(!0===e.isNodeUniform){const t=e.name,r=e.type;return"texture"===r||"cubeTexture"===r||"cubeDepthTexture"===r||"storageTexture"===r||"texture3D"===r?t:"buffer"===r||"storageBuffer"===r||"indirectStorageBuffer"===r?this.isCustomStruct(e)?t:t+".value":e.groupNode.name+"."+t}return super.getPropertyName(e)}getOutputStructName(){return"output"}getFunctionOperator(e){const t=eC[e];return void 0!==t?(this._include(t),t):null}getNodeAccess(e,t){return"compute"!==t?!0===e.isAtomic?(d("WebGPURenderer: Atomic operations are only supported in compute shaders."),ei.READ_WRITE):ei.READ_ONLY:e.access}getStorageAccess(e,t){return Yw[this.getNodeAccess(e,t)]}getUniformFromNode(e,t,r,s=null){const i=super.getUniformFromNode(e,t,r,s),n=this.getDataFromNode(e,r,this.globalCache);if(void 0===n.uniformGPU){let a;const o=e.groupNode,u=o.name,l=this.getBindGroupArray(u,r);if("texture"===t||"cubeTexture"===t||"cubeDepthTexture"===t||"storageTexture"===t||"texture3D"===t){let s=null;const n=this.getNodeAccess(e,r);"texture"===t||"storageTexture"===t?s=!0===e.value.is3DTexture?new KS(i.name,i.node,o,n):new jS(i.name,i.node,o,n):"cubeTexture"===t||"cubeDepthTexture"===t?s=new XS(i.name,i.node,o,n):"texture3D"===t&&(s=new KS(i.name,i.node,o,n)),s.store=!0===e.isStorageTextureNode,s.mipLevel=s.store?e.mipLevel:0,s.setVisibility(Zw[r]);if(!0===e.value.isCubeTexture||!1===this.isUnfilterable(e.value)&&!1===s.store){const e=new Uw(`${i.name}_sampler`,i.node,o);e.setVisibility(Zw[r]),l.push(e,s),a=[e,s]}else l.push(s),a=[s]}else if("buffer"===t||"storageBuffer"===t||"indirectStorageBuffer"===t){const n=this.getSharedDataFromNode(e);let u=n.buffer;if(void 0===u){u=new("buffer"===t?kS:Vw)(e,o),n.buffer=u}u.setVisibility(u.getVisibility()|Zw[r]),l.push(u),a=u,i.name=s||"NodeBuffer_"+i.id}else{let e=this.uniformGroups[u];void 0===e?(e=new $S(u,o),e.setVisibility(Zw[r]),this.uniformGroups[u]=e,l.push(e)):(e.setVisibility(e.getVisibility()|Zw[r]),-1===l.indexOf(e)&&l.push(e)),a=this.getNodeUniform(i,t);const s=a.name;e.uniforms.some(e=>e.name===s)||e.addUniform(a)}n.uniformGPU=a}return i}getBuiltin(e,t,r,s=this.shaderStage){const i=this.builtins[s]||(this.builtins[s]=new Map);return!1===i.has(e)&&i.set(e,{name:e,property:t,type:r}),t}hasBuiltin(e,t=this.shaderStage){return void 0!==this.builtins[t]&&this.builtins[t].has(e)}getVertexIndex(){return"vertex"===this.shaderStage?this.getBuiltin("vertex_index","vertexIndex","u32","attribute"):"vertexIndex"}buildFunctionCode(e){const t=e.layout,r=this.flowShaderNode(e),s=[];for(const e of t.inputs)s.push(e.name+" : "+this.getType(e.type));let i=`fn ${t.name}( ${s.join(", ")} ) -> ${this.getType(t.type)} {\n${r.vars}\n${r.code}\n`;return r.result&&(i+=`\treturn ${r.result};\n`),i+="\n}\n",i}getInstanceIndex(){return"vertex"===this.shaderStage?this.getBuiltin("instance_index","instanceIndex","u32","attribute"):"instanceIndex"}getInvocationLocalIndex(){return this.getBuiltin("local_invocation_index","invocationLocalIndex","u32","attribute")}getSubgroupSize(){return this.enableSubGroups(),this.getBuiltin("subgroup_size","subgroupSize","u32","attribute")}getInvocationSubgroupIndex(){return this.enableSubGroups(),this.getBuiltin("subgroup_invocation_id","invocationSubgroupIndex","u32","attribute")}getSubgroupIndex(){return this.enableSubGroups(),this.getBuiltin("subgroup_id","subgroupIndex","u32","attribute")}getDrawIndex(){return null}getFrontFacing(){return this.getBuiltin("front_facing","isFront","bool")}getFragCoord(){return this.getBuiltin("position","fragCoord","vec4")+".xy"}getFragDepth(){return"output."+this.getBuiltin("frag_depth","depth","f32","output")}getClipDistance(){return"varyings.hw_clip_distances"}isFlipY(){return!1}enableDirective(e,t=this.shaderStage){(this.directives[t]||(this.directives[t]=new Set)).add(e)}getDirectives(e){const t=[],r=this.directives[e];if(void 0!==r)for(const e of r)t.push(`enable ${e};`);return t.join("\n")}enableSubGroups(){this.enableDirective("subgroups")}enableSubgroupsF16(){this.enableDirective("subgroups-f16")}enableClipDistances(){this.enableDirective("clip_distances")}enableShaderF16(){this.enableDirective("f16")}enableDualSourceBlending(){this.enableDirective("dual_source_blending")}enableHardwareClipping(e){this.enableClipDistances(),this.getBuiltin("clip_distances","hw_clip_distances",`array`,"vertex")}getBuiltins(e){const t=[],r=this.builtins[e];if(void 0!==r)for(const{name:e,property:s,type:i}of r.values())t.push(`@builtin( ${e} ) ${s} : ${i}`);return t.join(",\n\t")}getScopedArray(e,t,r,s){return!1===this.scopedArrays.has(e)&&this.scopedArrays.set(e,{name:e,scope:t,bufferType:r,bufferCount:s}),e}getScopedArrays(e){if("compute"!==e)return;const t=[];for(const{name:e,scope:r,bufferType:s,bufferCount:i}of this.scopedArrays.values()){const n=this.getType(s);t.push(`var<${r}> ${e}: array< ${n}, ${i} >;`)}return t.join("\n")}getAttributes(e){const t=[];if("compute"===e&&(this.getBuiltin("global_invocation_id","globalId","vec3","attribute"),this.getBuiltin("workgroup_id","workgroupId","vec3","attribute"),this.getBuiltin("local_invocation_id","localId","vec3","attribute"),this.getBuiltin("num_workgroups","numWorkgroups","vec3","attribute"),this.renderer.hasFeature("subgroups")&&(this.enableDirective("subgroups",e),this.getBuiltin("subgroup_size","subgroupSize","u32","attribute"))),"vertex"===e||"compute"===e){const e=this.getBuiltins("attribute");e&&t.push(e);const r=this.getAttributesArray();for(let e=0,s=r.length;e"),t.push(`\t${s+r.name} : ${i}`)}return e.output&&t.push(`\t${this.getBuiltins("output")}`),t.join(",\n")}getStructs(e){let t="";const r=this.structs[e];if(r.length>0){const e=[];for(const t of r){let r=`struct ${t.name} {\n`;r+=this.getStructMembers(t),r+="\n};",e.push(r)}t="\n"+e.join("\n\n")+"\n"}return t}getVar(e,t,r=null){let s=`var ${t} : `;return s+=null!==r?this.generateArrayDeclaration(e,r):this.getType(e),s}getVars(e){const t=[],r=this.vars[e];if(void 0!==r)for(const e of r)t.push(`\t${this.getVar(e.type,e.name,e.count)};`);return`\n${t.join("\n")}\n`}getVaryings(e){const t=[];if("vertex"===e&&this.getBuiltin("position","builtinClipSpace","vec4","vertex"),"vertex"===e||"fragment"===e){const r=this.varyings,s=this.vars[e];for(let i=0;ir.value.itemSize;return s&&!i}getUniforms(e){const t=this.uniforms[e],r=[],s=[],i=[],n={};for(const i of t){const t=i.groupNode.name,a=this.bindingsIndexes[t];if("texture"===i.type||"cubeTexture"===i.type||"cubeDepthTexture"===i.type||"storageTexture"===i.type||"texture3D"===i.type){const t=i.node.value;let s;(!0===t.isCubeTexture||!1===this.isUnfilterable(t)&&!0!==i.node.isStorageTextureNode)&&(this.isSampleCompare(t)?r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name}_sampler : sampler_comparison;`):r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name}_sampler : sampler;`));let n="";const{primarySamples:o}=this.renderer.backend.utils.getTextureSampleData(t);if(o>1&&(n="_multisampled"),!0===t.isCubeTexture&&!0===t.isDepthTexture)s="texture_depth_cube";else if(!0===t.isCubeTexture)s="texture_cube";else if(!0===t.isDepthTexture)s=this.renderer.backend.compatibilityMode&&null===t.compareFunction?`texture${n}_2d`:`texture_depth${n}_2d${!0===t.isArrayTexture?"_array":""}`;else if(!0===i.node.isStorageTextureNode){const r=Ww(t),n=this.getStorageAccess(i.node,e),a=i.node.value.is3DTexture,o=i.node.value.isArrayTexture;s=`texture_storage_${a?"3d":"2d"+(o?"_array":"")}<${r}, ${n}>`}else if(!0===t.isArrayTexture||!0===t.isDataArrayTexture||!0===t.isCompressedArrayTexture)s="texture_2d_array";else if(!0===t.is3DTexture||!0===t.isData3DTexture)s="texture_3d";else{s=`texture${n}_2d<${this.getComponentTypeFromTexture(t).charAt(0)}32>`}r.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var ${i.name} : ${s};`)}else if("buffer"===i.type||"storageBuffer"===i.type||"indirectStorageBuffer"===i.type){const t=i.node,r=this.getType(t.getNodeType(this)),n=t.bufferCount,o=n>0&&"buffer"===i.type?", "+n:"",u=t.isStorageBufferNode?`storage, ${this.getStorageAccess(t,e)}`:"uniform";if(this.isCustomStruct(i))s.push(`@binding( ${a.binding++} ) @group( ${a.group} ) var<${u}> ${i.name} : ${r};`);else{const e=`\tvalue : array< ${t.isAtomic?`atomic<${r}>`:`${r}`}${o} >`;s.push(this._getWGSLStructBinding(i.name,e,u,a.binding++,a.group))}}else{const e=i.groupNode.name;if(void 0===n[e]){const t=this.uniformGroups[e];if(void 0!==t){const r=[];for(const e of t.uniforms){const t=e.getType(),s=this.getType(this.getVectorType(t));r.push(`\t${e.name} : ${s}`)}let s=this.uniformGroupsBindings[e];void 0===s&&(s={index:a.binding++,id:a.group},this.uniformGroupsBindings[e]=s),n[e]={index:s.index,id:s.id,snippets:r}}}}}for(const e in n){const t=n[e];i.push(this._getWGSLStructBinding(e,t.snippets.join(",\n"),"uniform",t.index,t.id))}return[...r,...s,...i].join("\n")}buildCode(){const e=null!==this.material?{fragment:{},vertex:{}}:{compute:{}};this.sortBindingGroups();for(const t in e){this.shaderStage=t;const r=e[t];r.uniforms=this.getUniforms(t),r.attributes=this.getAttributes(t),r.varyings=this.getVaryings(t),r.structs=this.getStructs(t),r.vars=this.getVars(t),r.codes=this.getCodes(t),r.directives=this.getDirectives(t),r.scopedArrays=this.getScopedArrays(t);let s="// code\n\n";s+=this.flowCode[t];const i=this.flowNodes[t],n=i[i.length-1],a=n.outputNode,o=void 0!==a&&!0===a.isOutputStructNode;for(const e of i){const i=this.getFlowData(e),u=e.name;if(u&&(s.length>0&&(s+="\n"),s+=`\t// flow -> ${u}\n`),s+=`${i.code}\n\t`,e===n&&"compute"!==t)if(s+="// result\n\n\t","vertex"===t)s+=`varyings.builtinClipSpace = ${i.result};`;else if("fragment"===t)if(o)r.returnType=a.getNodeType(this),r.structs+="var output : "+r.returnType+";",s+=`return ${i.result};`;else{let e="\t@location(0) color: vec4";const t=this.getBuiltins("output");t&&(e+=",\n\t"+t),r.returnType="OutputStruct",r.structs+=this._getWGSLStruct("OutputStruct",e),r.structs+="\nvar output : OutputStruct;",s+=`output.color = ${i.result};\n\n\treturn output;`}}r.flow=s}if(this.shaderStage=null,null!==this.material)this.vertexShader=this._getWGSLVertexCode(e.vertex),this.fragmentShader=this._getWGSLFragmentCode(e.fragment);else{const t=this.object.workgroupSize;this.computeShader=this._getWGSLComputeCode(e.compute,t)}}getMethod(e,t=null){let r;return null!==t&&(r=this._getWGSLMethod(e+"_"+t)),void 0===r&&(r=this._getWGSLMethod(e)),r||e}getBitcastMethod(e){return`bitcast<${this.getType(e)}>`}getFloatPackingMethod(e){return this.getMethod(`floatpack_${e}_2x16`)}getFloatUnpackingMethod(e){return this.getMethod(`floatunpack_${e}_2x16`)}getTernary(e,t,r){return`select( ${r}, ${t}, ${e} )`}getType(e){return tC[e]||e}isAvailable(e){let t=Jw[e];return void 0===t&&("float32Filterable"===e?t=this.renderer.hasFeature("float32-filterable"):"clipDistance"===e&&(t=this.renderer.hasFeature("clip-distances")),Jw[e]=t),t}_getWGSLMethod(e){return void 0!==sC[e]&&this._include(e),iC[e]}_include(e){const t=sC[e];return t.build(this),this.addInclude(t),t}_getWGSLVertexCode(e){return`${this.getSignature()}\n// directives\n${e.directives}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// varyings\n${e.varyings}\nvar varyings : VaryingsStruct;\n\n// codes\n${e.codes}\n\n@vertex\nfn main( ${e.attributes} ) -> VaryingsStruct {\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n\treturn varyings;\n\n}\n`}_getWGSLFragmentCode(e){return`${this.getSignature()}\n// global\n${nC}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// codes\n${e.codes}\n\n@fragment\nfn main( ${e.varyings} ) -> ${e.returnType} {\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n}\n`}_getWGSLComputeCode(e,t){const[r,s,i]=t;return`${this.getSignature()}\n// directives\n${e.directives}\n\n// system\nvar instanceIndex : u32;\n\n// locals\n${e.scopedArrays}\n\n// structs\n${e.structs}\n\n// uniforms\n${e.uniforms}\n\n// codes\n${e.codes}\n\n@compute @workgroup_size( ${r}, ${s}, ${i} )\nfn main( ${e.attributes} ) {\n\n\t// system\n\tinstanceIndex = globalId.x\n\t\t+ globalId.y * ( ${r} * numWorkgroups.x )\n\t\t+ globalId.z * ( ${r} * numWorkgroups.x ) * ( ${s} * numWorkgroups.y );\n\n\t// vars\n\t${e.vars}\n\n\t// flow\n\t${e.flow}\n\n}\n`}_getWGSLStruct(e,t){return`\nstruct ${e} {\n${t}\n};`}_getWGSLStructBinding(e,t,r,s=0,i=0){const n=e+"Struct";return`${this._getWGSLStruct(n,t)}\n@binding( ${s} ) @group( ${i} )\nvar<${r}> ${e} : ${n};`}}class oC{constructor(e){this.backend=e}getCurrentDepthStencilFormat(e){let t;return e.depth&&(t=null!==e.depthTexture?this.getTextureFormatGPU(e.depthTexture):e.stencil?LA:FA),t}getTextureFormatGPU(e){return this.backend.get(e).format}getTextureSampleData(e){let t;if(e.isFramebufferTexture)t=1;else if(e.isDepthTexture&&!e.renderTarget){const e=this.backend.renderer,r=e.getRenderTarget();t=r?r.samples:e.currentSamples}else e.renderTarget&&(t=e.renderTarget.samples);t=t||1;const r=t>1&&null!==e.renderTarget&&!0!==e.isDepthTexture&&!0!==e.isFramebufferTexture;return{samples:t,primarySamples:r?1:t,isMSAA:r}}getCurrentColorFormat(e){let t;return t=null!==e.textures?this.getTextureFormatGPU(e.textures[0]):this.getPreferredCanvasFormat(),t}getCurrentColorFormats(e){return null!==e.textures?e.textures.map(e=>this.getTextureFormatGPU(e)):[this.getPreferredCanvasFormat()]}getCurrentColorSpace(e){return null!==e.textures?e.textures[0].colorSpace:this.backend.renderer.outputColorSpace}getPrimitiveTopology(e,t){return e.isPoints?ER:e.isLineSegments||e.isMesh&&!0===t.wireframe?wR:e.isLine?CR:e.isMesh?MR:void 0}getSampleCount(e){return e>=4?4:1}getSampleCountRenderContext(e){return null!==e.textures?this.getSampleCount(e.sampleCount):this.getSampleCount(this.backend.renderer.currentSamples)}getPreferredCanvasFormat(){const e=this.backend.parameters.outputType;if(void 0===e)return navigator.gpu.getPreferredCanvasFormat();if(e===ke)return yA;if(e===be)return EA;throw new Error("Unsupported output buffer type.")}}const uC=new Map([[Int8Array,["sint8","snorm8"]],[Uint8Array,["uint8","unorm8"]],[Int16Array,["sint16","snorm16"]],[Uint16Array,["uint16","unorm16"]],[Int32Array,["sint32","snorm32"]],[Uint32Array,["uint32","unorm32"]],[Float32Array,["float32"]]]);"undefined"!=typeof Float16Array&&uC.set(Float16Array,["float16"]);const lC=new Map([[at,["float16"]]]),dC=new Map([[Int32Array,"sint32"],[Int16Array,"sint32"],[Uint32Array,"uint32"],[Uint16Array,"uint32"],[Float32Array,"float32"]]);class cC{constructor(e){this.backend=e}createAttribute(e,t){const r=this._getBufferAttribute(e),s=this.backend,i=s.get(r);let n=i.buffer;if(void 0===n){const a=s.device;let o=r.array;if(!1===e.normalized)if(o.constructor===Int16Array||o.constructor===Int8Array)o=new Int32Array(o);else if((o.constructor===Uint16Array||o.constructor===Uint8Array)&&(o=new Uint32Array(o),t&GPUBufferUsage.INDEX))for(let e=0;e0&&(void 0===n.groups&&(n.groups=[],n.versions=[]),n.versions[r]===s&&(o=n.groups[r])),void 0===o&&(o=this.createBindGroup(e,a),r>0&&(n.groups[r]=o,n.versions[r]=s)),n.group=o}updateBinding(e){const t=this.backend,r=t.device,s=e.buffer,i=t.get(e).buffer,n=e.updateRanges;if(0===n.length)r.queue.writeBuffer(i,0,s,0);else{const e=Xr(s),t=e?1:s.BYTES_PER_ELEMENT;for(let a=0,o=n.length;a1&&(i+=`-${e.texture.depthOrArrayLayers}`),i+=`-${r}-${s}`,a=e[i],void 0===a){const n=Bw;let o;o=t.isSampledCubeTexture?Cw:t.isSampledTexture3D?Mw:t.texture.isArrayTexture||t.texture.isDataArrayTexture||t.texture.isCompressedArrayTexture?ww:Ew,a=e[i]=e.texture.createView({aspect:n,dimension:o,mipLevelCount:r,baseMipLevel:s})}}n.push({binding:i,resource:a})}else if(t.isSampler){const e=r.get(t.texture);n.push({binding:i,resource:e.sampler})}i++}return s.createBindGroup({label:"bindGroup_"+e.name,layout:t,entries:n})}_createLayoutEntries(e){const t=[];let r=0;for(const s of e.bindings){const e=this.backend,i={binding:r,visibility:s.visibility};if(s.isUniformBuffer||s.isStorageBuffer){const e={};s.isStorageBuffer&&(s.visibility&BR.COMPUTE&&(s.access===ei.READ_WRITE||s.access===ei.WRITE_ONLY)?e.type=pw:e.type=gw),i.buffer=e}else if(s.isSampledTexture&&s.store){const e={};e.format=this.backend.get(s.texture).texture.format;const t=s.access;e.access=t===ei.READ_WRITE?yw:t===ei.WRITE_ONLY?mw:fw,s.texture.isArrayTexture?e.viewDimension=ww:s.texture.is3DTexture&&(e.viewDimension=Mw),i.storageTexture=e}else if(s.isSampledTexture){const t={},{primarySamples:r}=e.utils.getTextureSampleData(s.texture);if(r>1&&(t.multisampled=!0,s.texture.isDepthTexture||(t.sampleType=_w)),s.texture.isDepthTexture)e.compatibilityMode&&null===s.texture.compareFunction?t.sampleType=_w:t.sampleType=vw;else if(s.texture.isDataTexture||s.texture.isDataArrayTexture||s.texture.isData3DTexture){const e=s.texture.type;e===R?t.sampleType=Nw:e===S?t.sampleType=Sw:e===j&&(this.backend.hasFeature("float32-filterable")?t.sampleType=Tw:t.sampleType=_w)}s.isSampledCubeTexture?t.viewDimension=Cw:s.texture.isArrayTexture||s.texture.isDataArrayTexture||s.texture.isCompressedArrayTexture?t.viewDimension=ww:s.isSampledTexture3D&&(t.viewDimension=Mw),i.texture=t}else if(s.isSampler){const t={};s.texture.isDepthTexture&&(null!==s.texture.compareFunction&&e.hasCompatibility(A.TEXTURE_COMPARE)?t.type=xw:t.type=bw),i.sampler=t}else o(`WebGPUBindingUtils: Unsupported binding "${s}".`);t.push(i),r++}return t}deleteBindGroupData(e){const{backend:t}=this,r=t.get(e);r.layout&&(r.layout.usedTimes--,0===r.layout.usedTimes&&this._bindGroupLayoutCache.delete(r.layoutKey),r.layout=void 0,r.layoutKey=void 0)}dispose(){this._bindGroupLayoutCache.clear()}}class gC{constructor(e){this.backend=e,this._activePipelines=new WeakMap}setPipeline(e,t){this._activePipelines.get(e)!==t&&(e.setPipeline(t),this._activePipelines.set(e,t))}_getSampleCount(e){return this.backend.utils.getSampleCountRenderContext(e)}createRenderPipeline(e,t){const{object:r,material:s,geometry:i,pipeline:n}=e,{vertexProgram:a,fragmentProgram:u}=n,l=this.backend,d=l.device,c=l.utils,h=l.get(n),p=[];for(const t of e.getBindings()){const e=l.get(t),{layoutGPU:r}=e.layout;p.push(r)}const g=l.attributeUtils.createShaderVertexBuffers(e);let m;s.blending===ee||s.blending===Ge&&!1===s.transparent||(m=this._getBlending(s));let f={};!0===s.stencilWrite&&(f={compare:this._getStencilCompare(s),failOp:this._getStencilOperation(s.stencilFail),depthFailOp:this._getStencilOperation(s.stencilZFail),passOp:this._getStencilOperation(s.stencilZPass)});const y=this._getColorWriteMask(s),b=[];if(null!==e.context.textures){const t=e.context.textures,r=e.context.mrt;for(let e=0;e1},layout:d.createPipelineLayout({bindGroupLayouts:p})},A={},E=e.context.depth,w=e.context.stencil;if(!0!==E&&!0!==w||(!0===E&&(A.format=N,A.depthWriteEnabled=s.depthWrite,A.depthCompare=v),!0===w&&(A.stencilFront=f,A.stencilBack={},A.stencilReadMask=s.stencilFuncMask,A.stencilWriteMask=s.stencilWriteMask),!0===s.polygonOffset&&(A.depthBias=s.polygonOffsetUnits,A.depthBiasSlopeScale=s.polygonOffsetFactor,A.depthBiasClamp=0),R.depthStencil=A),d.pushErrorScope("validation"),null===t)h.pipeline=d.createRenderPipeline(R),d.popErrorScope().then(e=>{null!==e&&(h.error=!0,o(e.message))});else{const e=new Promise(async e=>{try{h.pipeline=await d.createRenderPipelineAsync(R)}catch(e){}const t=await d.popErrorScope();null!==t&&(h.error=!0,o(t.message)),e()});t.push(e)}}createBundleEncoder(e,t="renderBundleEncoder"){const r=this.backend,{utils:s,device:i}=r,n=s.getCurrentDepthStencilFormat(e),a={label:t,colorFormats:s.getCurrentColorFormats(e),depthStencilFormat:n,sampleCount:this._getSampleCount(e)};return i.createRenderBundleEncoder(a)}createComputePipeline(e,t){const r=this.backend,s=r.device,i=r.get(e.computeProgram).module,n=r.get(e),a=[];for(const e of t){const t=r.get(e),{layoutGPU:s}=t.layout;a.push(s)}n.pipeline=s.createComputePipeline({compute:i,layout:s.createPipelineLayout({bindGroupLayouts:a})})}_getBlending(e){let t,r;const s=e.blending,i=e.blendSrc,n=e.blendDst,a=e.blendEquation;if(s===ct){const s=null!==e.blendSrcAlpha?e.blendSrcAlpha:i,o=null!==e.blendDstAlpha?e.blendDstAlpha:n,u=null!==e.blendEquationAlpha?e.blendEquationAlpha:a;t={srcFactor:this._getBlendFactor(i),dstFactor:this._getBlendFactor(n),operation:this._getBlendOperation(a)},r={srcFactor:this._getBlendFactor(s),dstFactor:this._getBlendFactor(o),operation:this._getBlendOperation(u)}}else{const i=(e,s,i,n)=>{t={srcFactor:e,dstFactor:s,operation:ZE},r={srcFactor:i,dstFactor:n,operation:ZE}};if(e.premultipliedAlpha)switch(s){case Ge:i(kE,WE,kE,WE);break;case Ht:i(kE,kE,kE,kE);break;case Wt:i(VE,zE,VE,kE);break;case $t:i(HE,WE,VE,kE)}else switch(s){case Ge:i($E,WE,kE,WE);break;case Ht:i($E,kE,kE,kE);break;case Wt:o(`WebGPURenderer: "SubtractiveBlending" requires "${e.isMaterial?"material":"blendMode"}.premultipliedAlpha = true".`);break;case $t:o(`WebGPURenderer: "MultiplyBlending" requires "${e.isMaterial?"material":"blendMode"}.premultipliedAlpha = true".`)}}if(void 0!==t&&void 0!==r)return{color:t,alpha:r};o("WebGPURenderer: Invalid blending: ",s)}_getBlendFactor(e){let t;switch(e){case ht:t=VE;break;case Vt:t=kE;break;case Ot:t=GE;break;case Pt:t=zE;break;case ze:t=$E;break;case $e:t=WE;break;case Ut:t=HE;break;case Lt:t=qE;break;case Dt:t=jE;break;case Ft:t=XE;break;case It:t=KE;break;case 211:t=YE;break;case 212:t=QE;break;default:o("WebGPURenderer: Blend factor not supported.",e)}return t}_getStencilCompare(e){let t;const r=e.stencilFunc;switch(r){case rs:t=FR;break;case ts:t=VR;break;case es:t=LR;break;case Jr:t=DR;break;case Zr:t=PR;break;case Qr:t=OR;break;case Yr:t=UR;break;case Kr:t=IR;break;default:o("WebGPURenderer: Invalid stencil function.",r)}return t}_getStencilOperation(e){let t;switch(e){case ds:t=nw;break;case ls:t=aw;break;case us:t=ow;break;case os:t=uw;break;case as:t=lw;break;case ns:t=dw;break;case is:t=cw;break;case ss:t=hw;break;default:o("WebGPURenderer: Invalid stencil operation.",t)}return t}_getBlendOperation(e){let t;switch(e){case We:t=ZE;break;case Bt:t=JE;break;case Mt:t=ew;break;case hs:t=tw;break;case cs:t=rw;break;default:o("WebGPUPipelineUtils: Blend equation not supported.",e)}return t}_getPrimitiveState(e,t,r){const s={},i=this.backend.utils;s.topology=i.getPrimitiveTopology(e,r),null!==t.index&&!0===e.isLine&&!0!==e.isLineSegments&&(s.stripIndexFormat=t.index.array instanceof Uint16Array?jR:XR);let n=r.side===M;return e.isMesh&&e.matrixWorld.determinant()<0&&(n=!n),s.frontFace=!0===n?WR:$R,s.cullMode=r.side===B?HR:qR,s}_getColorWriteMask(e){return!0===e.colorWrite?iw:sw}_getDepthCompare(e){let t;if(!1===e.depthTest)t=VR;else{const r=e.depthFunc;switch(r){case Jt:t=FR;break;case Zt:t=VR;break;case Qt:t=LR;break;case Yt:t=DR;break;case Kt:t=PR;break;case Xt:t=OR;break;case jt:t=UR;break;case qt:t=IR;break;default:o("WebGPUPipelineUtils: Invalid depth function.",r)}}return t}}class mC extends SR{constructor(e,t,r=2048){super(r),this.device=e,this.type=t,this.querySet=this.device.createQuerySet({type:"timestamp",count:this.maxQueries,label:`queryset_global_timestamp_${t}`});const s=8*this.maxQueries;this.resolveBuffer=this.device.createBuffer({label:`buffer_timestamp_resolve_${t}`,size:s,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),this.resultBuffer=this.device.createBuffer({label:`buffer_timestamp_result_${t}`,size:s,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ})}allocateQueriesForContext(e){if(!this.trackTimestamp||this.isDisposed)return null;if(this.currentQueryIndex+2>this.maxQueries)return v(`WebGPUTimestampQueryPool [${this.type}]: Maximum number of queries exceeded, when using trackTimestamp it is necessary to resolves the queries via renderer.resolveTimestampsAsync( THREE.TimestampQuery.${this.type.toUpperCase()} ).`),null;const t=this.currentQueryIndex;return this.currentQueryIndex+=2,this.queryOffsets.set(e,t),t}async resolveQueriesAsync(){if(!this.trackTimestamp||0===this.currentQueryIndex||this.isDisposed)return this.lastValue;if(this.pendingResolve)return this.pendingResolve;this.pendingResolve=this._resolveQueries();try{return await this.pendingResolve}finally{this.pendingResolve=null}}async _resolveQueries(){if(this.isDisposed)return this.lastValue;try{if("unmapped"!==this.resultBuffer.mapState)return this.lastValue;const e=new Map(this.queryOffsets),t=this.currentQueryIndex,r=8*t;this.currentQueryIndex=0,this.queryOffsets.clear();const s=this.device.createCommandEncoder();s.resolveQuerySet(this.querySet,0,t,this.resolveBuffer,0),s.copyBufferToBuffer(this.resolveBuffer,0,this.resultBuffer,0,r);const i=s.finish();if(this.device.queue.submit([i]),"unmapped"!==this.resultBuffer.mapState)return this.lastValue;if(await this.resultBuffer.mapAsync(GPUMapMode.READ,0,r),this.isDisposed)return"mapped"===this.resultBuffer.mapState&&this.resultBuffer.unmap(),this.lastValue;const n=new BigUint64Array(this.resultBuffer.getMappedRange(0,r)),a={},o=[];for(const[t,r]of e){const e=t.match(/^(.*):f(\d+)$/),s=parseInt(e[2]);!1===o.includes(s)&&o.push(s),void 0===a[s]&&(a[s]=0);const i=n[r],u=n[r+1],l=Number(u-i)/1e6;this.timestamps.set(t,l),a[s]+=l}const u=a[o[o.length-1]];return this.resultBuffer.unmap(),this.lastValue=u,this.frames=o,u}catch(e){return o("Error resolving queries:",e),"mapped"===this.resultBuffer.mapState&&this.resultBuffer.unmap(),this.lastValue}}async dispose(){if(!this.isDisposed){if(this.isDisposed=!0,this.pendingResolve)try{await this.pendingResolve}catch(e){o("Error waiting for pending resolve:",e)}if(this.resultBuffer&&"mapped"===this.resultBuffer.mapState)try{this.resultBuffer.unmap()}catch(e){o("Error unmapping buffer:",e)}this.querySet&&(this.querySet.destroy(),this.querySet=null),this.resolveBuffer&&(this.resolveBuffer.destroy(),this.resolveBuffer=null),this.resultBuffer&&(this.resultBuffer.destroy(),this.resultBuffer=null),this.queryOffsets.clear(),this.pendingResolve=null}}}class fC extends aR{constructor(e={}){super(e),this.isWebGPUBackend=!0,this.parameters.alpha=void 0===e.alpha||e.alpha,this.parameters.requiredLimits=void 0===e.requiredLimits?{}:e.requiredLimits,this.compatibilityMode=null,this.device=null,this.defaultRenderPassdescriptor=null,this.utils=new oC(this),this.attributeUtils=new cC(this),this.bindingUtils=new pC(this),this.pipelineUtils=new gC(this),this.textureUtils=new $w(this),this.occludedResolveCache=new Map;const t="undefined"==typeof navigator||!1===/Android/.test(navigator.userAgent);this._compatibility={[A.TEXTURE_COMPARE]:t}}async init(e){await super.init(e);const t=this.parameters;let r;if(void 0===t.device){const e={powerPreference:t.powerPreference,featureLevel:"compatibility"},s="undefined"!=typeof navigator?await navigator.gpu.requestAdapter(e):null;if(null===s)throw new Error("WebGPUBackend: Unable to create WebGPU adapter.");const i=Object.values(Pw),n=[];for(const e of i)s.features.has(e)&&n.push(e);const a={requiredFeatures:n,requiredLimits:t.requiredLimits};r=await s.requestDevice(a)}else r=t.device;this.compatibilityMode=!r.features.has("core-features-and-limits"),this.compatibilityMode&&(e._samples=0),r.lost.then(t=>{if("destroyed"===t.reason)return;const r={api:"WebGPU",message:t.message||"Unknown reason",reason:t.reason||null,originalEvent:t};e.onDeviceLost(r)}),this.device=r,this.trackTimestamp=this.trackTimestamp&&this.hasFeature(Pw.TimestampQuery),this.updateSize()}get context(){const e=this.renderer.getCanvasTarget(),t=this.get(e);let r=t.context;if(void 0===r){const s=this.parameters;r=!0===e.isDefaultCanvasTarget&&void 0!==s.context?s.context:e.domElement.getContext("webgpu"),"setAttribute"in e.domElement&&e.domElement.setAttribute("data-engine",`three.js r${ot} webgpu`);const i=s.alpha?"premultiplied":"opaque",n=s.outputType===be?"extended":"standard";r.configure({device:this.device,format:this.utils.getPreferredCanvasFormat(),usage:GPUTextureUsage.RENDER_ATTACHMENT|GPUTextureUsage.COPY_SRC,alphaMode:i,toneMapping:{mode:n}}),t.context=r}return r}get coordinateSystem(){return h}async getArrayBufferAsync(e){return await this.attributeUtils.getArrayBufferAsync(e)}getContext(){return this.context}_getDefaultRenderPassDescriptor(){const e=this.renderer,t=e.getCanvasTarget(),r=this.get(t),s=e.currentSamples;let i=r.descriptor;if(void 0===i||r.samples!==s){i={colorAttachments:[{view:null}]},!0!==e.depth&&!0!==e.stencil||(i.depthStencilAttachment={view:this.textureUtils.getDepthBuffer(e.depth,e.stencil).createView()});const t=i.colorAttachments[0];s>0?t.view=this.textureUtils.getColorBuffer().createView():t.resolveTarget=void 0,r.descriptor=i,r.samples=s}const n=i.colorAttachments[0];return s>0?n.resolveTarget=this.context.getCurrentTexture().createView():n.view=this.context.getCurrentTexture().createView(),i}_isRenderCameraDepthArray(e){return e.depthTexture&&e.depthTexture.image.depth>1&&e.camera.isArrayCamera}_getRenderPassDescriptor(e,t={}){const r=e.renderTarget,s=this.get(r);let i=s.descriptors;void 0!==i&&s.width===r.width&&s.height===r.height&&s.samples===r.samples||(i={},s.descriptors=i);const n=e.getCacheKey();let a=i[n];if(void 0===a){const t=e.textures,o=[];let u;const l=this._isRenderCameraDepthArray(e);for(let s=0;s1)if(!0===l){const t=e.camera.cameras;for(let e=0;e0&&(t.currentOcclusionQuerySet&&t.currentOcclusionQuerySet.destroy(),t.currentOcclusionQueryBuffer&&t.currentOcclusionQueryBuffer.destroy(),t.currentOcclusionQuerySet=t.occlusionQuerySet,t.currentOcclusionQueryBuffer=t.occlusionQueryBuffer,t.currentOcclusionQueryObjects=t.occlusionQueryObjects,i=r.createQuerySet({type:"occlusion",count:s,label:`occlusionQuerySet_${e.id}`}),t.occlusionQuerySet=i,t.occlusionQueryIndex=0,t.occlusionQueryObjects=new Array(s),t.lastOcclusionObject=null),n=null===e.textures?this._getDefaultRenderPassDescriptor():this._getRenderPassDescriptor(e,{loadOp:GR}),this.initTimestampQuery(wt.RENDER,this.getTimestampUID(e),n),n.occlusionQuerySet=i;const a=n.depthStencilAttachment;if(null!==e.textures){const t=n.colorAttachments;for(let r=0;r0&&t.currentPass.executeBundles(t.renderBundles),r>t.occlusionQueryIndex&&t.currentPass.endOcclusionQuery();const s=t.encoder;if(!0===this._isRenderCameraDepthArray(e)){const r=[];for(let e=0;e0){const s=8*r;let i=this.occludedResolveCache.get(s);void 0===i&&(i=this.device.createBuffer({size:s,usage:GPUBufferUsage.QUERY_RESOLVE|GPUBufferUsage.COPY_SRC}),this.occludedResolveCache.set(s,i));const n=this.device.createBuffer({size:s,usage:GPUBufferUsage.COPY_DST|GPUBufferUsage.MAP_READ});t.encoder.resolveQuerySet(t.occlusionQuerySet,0,r,i,0),t.encoder.copyBufferToBuffer(i,0,n,0,s),t.occlusionQueryBuffer=n,this.resolveOccludedAsync(e)}if(this.device.queue.submit([t.encoder.finish()]),null!==e.textures){const t=e.textures;for(let e=0;eo&&(i[0]=Math.min(a,o),i[1]=Math.ceil(a/o)),n.dispatchSize=i}i=n.dispatchSize}a.dispatchWorkgroups(i[0],i[1]||1,i[2]||1)}finishCompute(e){const t=this.get(e);t.passEncoderGPU.end(),this.device.queue.submit([t.cmdEncoderGPU.finish()])}draw(e,t){const{object:r,material:s,context:i,pipeline:n}=e,a=e.getBindings(),o=this.get(i),u=this.get(n),l=u.pipeline;if(!0===u.error)return;const d=e.getIndex(),c=null!==d,h=e.getDrawParameters();if(null===h)return;const p=(t,r)=>{this.pipelineUtils.setPipeline(t,l),r.pipeline=l;const n=r.bindingGroups;for(let e=0,r=a.length;e{if(p(s,i),!0===r.isBatchedMesh){const e=r._multiDrawStarts,i=r._multiDrawCounts,n=r._multiDrawCount,a=r._multiDrawInstances;null!==a&&v("WebGPUBackend: renderMultiDrawInstances has been deprecated and will be removed in r184. Append to renderMultiDraw arguments and use indirection.");for(let o=0;o1?0:o;!0===c?s.drawIndexed(i[o],n,e[o]/d.array.BYTES_PER_ELEMENT,0,u):s.draw(i[o],n,e[o],u),t.update(r,i[o],n)}}else if(!0===c){const{vertexCount:i,instanceCount:n,firstVertex:a}=h,o=e.getIndirect();if(null!==o){const t=this.get(o).buffer,r=e.getIndirectOffset(),i=Array.isArray(r)?r:[r];for(let e=0;e0){const t=this.get(e.camera),s=e.camera.cameras,n=e.getBindingGroup("cameraIndex");if(void 0===t.indexesGPU||t.indexesGPU.length!==s.length){const e=this.get(n),r=[],i=new Uint32Array([0,0,0,0]);for(let t=0,n=s.length;t(d("WebGPURenderer: WebGPU is not available, running under WebGL2 backend."),new AR(e)));super(new t(e),e),this.library=new xC,this.isWebGPURenderer=!0}}class _C extends As{constructor(){super(),this.isBundleGroup=!0,this.type="BundleGroup",this.static=!0,this.version=0}set needsUpdate(e){!0===e&&this.version++}}class vC{constructor(e,t=Rn(0,0,1,1)){this.renderer=e,this.outputNode=t,this.outputColorTransform=!0,this.needsUpdate=!0;const r=new Qp;r.name="RenderPipeline",this._quadMesh=new Wb(r),this._quadMesh.name="Render Pipeline",this._context=null}render(){const e=this.renderer;this._update(),null!==this._context.onBeforeRenderPipeline&&this._context.onBeforeRenderPipeline();const t=e.toneMapping,r=e.outputColorSpace;e.toneMapping=m,e.outputColorSpace=p.workingColorSpace;const s=e.xr.enabled;e.xr.enabled=!1,this._quadMesh.render(e),e.xr.enabled=s,e.toneMapping=t,e.outputColorSpace=r,null!==this._context.onAfterRenderPipeline&&this._context.onAfterRenderPipeline()}get context(){return this._context}dispose(){this._quadMesh.material.dispose()}_update(){if(!0===this.needsUpdate){const e=this.renderer,t=e.toneMapping,r=e.outputColorSpace,s={renderPipeline:this,onBeforeRenderPipeline:null,onAfterRenderPipeline:null};let i=this.outputNode;!0===this.outputColorTransform?(i=i.context(s),i=fl(i,t,r)):(s.toneMapping=t,s.outputColorSpace=r,i=i.context(s)),this._context=s,this._quadMesh.material.fragmentNode=i,this._quadMesh.material.needsUpdate=!0,this.needsUpdate=!1}}async renderAsync(){v('RenderPipeline: "renderAsync()" has been deprecated. Use "render()" and "await renderer.init();" when creating the renderer.'),await this.renderer.init(),this.render()}}class NC extends vC{constructor(e,t){v('PostProcessing: "PostProcessing" has been renamed to "RenderPipeline". Please update your code to use "THREE.RenderPipeline" instead.'),super(e,t)}}class SC extends N{constructor(e=1,t=1){super(),this.image={width:e,height:t},this.magFilter=oe,this.minFilter=oe,this.isStorageTexture=!0,this.mipmapsAutoUpdate=!0}setSize(e,t){this.image.width===e&&this.image.height===t||(this.image.width=e,this.image.height=t,this.dispose())}}class RC extends sx{constructor(e,t){super(e,t,Uint32Array),this.isIndirectStorageBufferAttribute=!0}}class AC extends Es{constructor(e){super(e),this.textures={},this.nodes={}}load(e,t,r,s){const i=new ws(this.manager);i.setPath(this.path),i.setRequestHeader(this.requestHeader),i.setWithCredentials(this.withCredentials),i.load(e,r=>{try{t(this.parse(JSON.parse(r)))}catch(t){s?s(t):o(t),this.manager.itemError(e)}},r,s)}parseNodes(e){const t={};if(void 0!==e){for(const r of e){const{uuid:e,type:s}=r;t[e]=this.createNodeFromType(s),t[e].uuid=e}const r={nodes:t,textures:this.textures};for(const s of e){s.meta=r;t[s.uuid].deserialize(s),delete s.meta}}return t}parse(e){const t=this.createNodeFromType(e.type);t.uuid=e.uuid;const r={nodes:this.parseNodes(e.nodes),textures:this.textures};return e.meta=r,t.deserialize(e),delete e.meta,t}setTextures(e){return this.textures=e,this}setNodes(e){return this.nodes=e,this}createNodeFromType(e){return void 0===this.nodes[e]?(o("NodeLoader: Node type not found:",e),pn()):new this.nodes[e]}}class EC extends Cs{constructor(e){super(e),this.nodes={},this.nodeMaterials={}}parse(e){const t=super.parse(e),r=this.nodes,s=e.inputNodes;for(const e in s){const i=s[e];t[e]=r[i]}return t}setNodes(e){return this.nodes=e,this}setNodeMaterials(e){return this.nodeMaterials=e,this}createMaterialFromType(e){const t=this.nodeMaterials[e];return void 0!==t?new t:super.createMaterialFromType(e)}}class wC extends Ms{constructor(e){super(e),this.nodes={},this.nodeMaterials={},this._nodesJSON=null}setNodes(e){return this.nodes=e,this}setNodeMaterials(e){return this.nodeMaterials=e,this}parse(e,t){this._nodesJSON=e.nodes;const r=super.parse(e,t);return this._nodesJSON=null,r}parseNodes(e,t){if(void 0!==e){const r=new AC;return r.setNodes(this.nodes),r.setTextures(t),r.parseNodes(e)}return{}}parseMaterials(e,t){const r={};if(void 0!==e){const s=this.parseNodes(this._nodesJSON,t),i=new EC;i.setTextures(t),i.setNodes(s),i.setNodeMaterials(this.nodeMaterials);for(let t=0,s=e.length;t