Skip to content

⬅️ Back to Table of Contents

📄 TextureNode.js

📊 Analysis Summary

Metric Count
🔧 Functions 33
🧱 Classes 1
📦 Imports 16
📊 Variables & Constants 20

📚 Table of Contents

🛠️ File Location:

📂 src/nodes/accessors/TextureNode.js

📦 Imports

Name Source
uniform ../core/UniformNode.js
UniformNode ../core/UniformNode.js
uv ./UV.js
textureSize ./TextureSizeNode.js
colorSpaceToWorking ../display/ColorSpaceNode.js
expression ../code/ExpressionNode.js
maxMipLevel ../utils/MaxMipLevelNode.js
nodeProxy ../tsl/TSLBase.js
vec3 ../tsl/TSLBase.js
nodeObject ../tsl/TSLBase.js
int ../tsl/TSLBase.js
NodeUpdateType ../core/constants.js
IntType ../../constants.js
NearestFilter ../../constants.js
UnsignedIntType ../../constants.js
Texture ../../textures/Texture.js

Variables & Constants

Name Type Kind Value Exported
EmptyTexture Texture let/var new Texture()
texture Texture let/var this.value
texture Texture let/var this.value
uvNode any let/var this.uvNode
levelNode any let/var this.levelNode
texture Texture let/var this.value
snippet any let/var *not shown*
texture Texture let/var this.value
propertyName any let/var nodeData.propertyName
levelSnippet any let/var levelNode ? levelNode.build( builder, 'float' ) : null
biasSnippet any let/var biasNode ? biasNode.build( builder, 'float' ) : null
depthSnippet any let/var depthNode ? depthNode.build( builder, 'int' ) : null
compareSnippet any let/var compareNode ? compareNode.build( builder, 'float' ) : null
gradSnippet any[] let/var gradNode ? [ gradNode[ 0 ].build( builder, 'vec2' ), gradNode[ 1 ].build( bui...
snippet any let/var propertyName
map Texture let/var textureNode.value
texture Texture let/var this.value
matrixUniform any let/var this._matrixUniform
newNode any let/var new this.constructor( this.value, this.uvNode, this.levelNode, this.biasNode )
textureNode any let/var *not shown*

Functions

TextureNode.getUniformHash(): string

JSDoc:

/**
     * Overwritten since the uniform hash is defined by the texture's UUID.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @return {string} The uniform hash.
     */

Returns: string

Code
getUniformHash( /*builder*/ ) {

        return this.value.uuid;

    }

TextureNode.getNodeType(): string

JSDoc:

/**
     * Overwritten since the node type is inferred from the texture type.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @return {string} The node type.
     */

Returns: string

Code
getNodeType( /*builder*/ ) {

        if ( this.value.isDepthTexture === true ) return 'float';

        if ( this.value.type === UnsignedIntType ) {

            return 'uvec4';

        } else if ( this.value.type === IntType ) {

            return 'ivec4';

        }

        return 'vec4';

    }

TextureNode.getInputType(): string

JSDoc:

/**
     * Overwrites the default implementation to return a fixed value `'texture'`.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @return {string} The input type.
     */

Returns: string

Code
getInputType( /*builder*/ ) {

        return 'texture';

    }

TextureNode.getDefaultUV(): AttributeNode<vec2>

JSDoc:

/**
     * Returns a default uvs based on the current texture's channel.
     *
     * @return {AttributeNode<vec2>} The default uvs.
     */

Returns: AttributeNode<vec2>

Calls:

  • uv (from ./UV.js)
Code
getDefaultUV() {

        return uv( this.value.channel );

    }

TextureNode.updateReference(): Texture

JSDoc:

/**
     * Overwritten to always return the texture reference of the node.
     *
     * @param {any} state - This method can be invocated in different contexts so `state` can refer to any object type.
     * @return {Texture} The texture reference.
     */

Returns: Texture

Code
updateReference( /*state*/ ) {

        return this.value;

    }

TextureNode.getTransformedUV(uvNode: Node): Node

JSDoc:

/**
     * Transforms the given uv node with the texture transformation matrix.
     *
     * @param {Node} uvNode - The uv node to transform.
     * @return {Node} The transformed uv node.
     */

Parameters:

  • uvNode Node

Returns: Node

Calls:

  • uniform (from ../core/UniformNode.js)
  • this._matrixUniform.mul
  • vec3 (from ../tsl/TSLBase.js)
Code
getTransformedUV( uvNode ) {

        if ( this._matrixUniform === null ) this._matrixUniform = uniform( this.value.matrix );

        return this._matrixUniform.mul( vec3( uvNode, 1 ) ).xy;

    }

TextureNode.setUpdateMatrix(value: boolean): TextureNode

JSDoc:

/**
     * Defines whether the uv transformation matrix should automatically be updated or not.
     *
     * @param {boolean} value - The update toggle.
     * @return {TextureNode} A reference to this node.
     */

Parameters:

  • value boolean

Returns: TextureNode

Code
setUpdateMatrix( value ) {

        this.updateMatrix = value;
        this.updateType = value ? NodeUpdateType.OBJECT : NodeUpdateType.NONE;

        return this;

    }

TextureNode.setupUV(builder: NodeBuilder, uvNode: Node): Node

JSDoc:

/**
     * Setups the uv node. Depending on the backend as well as texture's image and type, it might be necessary
     * to modify the uv node for correct sampling.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @param {Node} uvNode - The uv node to setup.
     * @return {Node} The updated uv node.
     */

Parameters:

  • builder NodeBuilder
  • uvNode Node

Returns: Node

Calls:

  • builder.isFlipY
  • uvNode.flipY
  • uvNode.setY
  • int( textureSize( this, this.levelNode ).y ).sub( uvNode.y ).sub
Code
setupUV( builder, uvNode ) {

        const texture = this.value;

        if ( builder.isFlipY() && ( ( texture.image instanceof ImageBitmap && texture.flipY === true ) || texture.isRenderTargetTexture === true || texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) {

            if ( this.sampler ) {

                uvNode = uvNode.flipY();

            } else {

                uvNode = uvNode.setY( int( textureSize( this, this.levelNode ).y ).sub( uvNode.y ).sub( 1 ) );

            }

        }

        return uvNode;

    }

TextureNode.setup(builder: NodeBuilder): void

JSDoc:

/**
     * Setups texture node by preparing the internal nodes for code generation.
     *
     * @param {NodeBuilder} builder - The current node builder.
     */

Parameters:

  • builder NodeBuilder

Returns: void

Calls:

  • builder.getNodeProperties
  • builder.context.getUV
  • this.getDefaultUV
  • this.getTransformedUV
  • this.setupUV
  • builder.context.getTextureLevel

Internal Comments:

// (x10)

Code
setup( builder ) {

        const properties = builder.getNodeProperties( this );
        properties.referenceNode = this.referenceNode;

        //

        const texture = this.value;

        if ( ! texture || texture.isTexture !== true ) {

            throw new Error( 'THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().' );

        }

        //

        let uvNode = this.uvNode;

        if ( ( uvNode === null || builder.context.forceUVContext === true ) && builder.context.getUV ) {

            uvNode = builder.context.getUV( this, builder );

        }

        if ( ! uvNode ) uvNode = this.getDefaultUV();

        if ( this.updateMatrix === true ) {

            uvNode = this.getTransformedUV( uvNode );

        }

        uvNode = this.setupUV( builder, uvNode );

        //

        let levelNode = this.levelNode;

        if ( levelNode === null && builder.context.getTextureLevel ) {

            levelNode = builder.context.getTextureLevel( this );

        }

        //

        properties.uvNode = uvNode;
        properties.levelNode = levelNode;
        properties.biasNode = this.biasNode;
        properties.compareNode = this.compareNode;
        properties.gradNode = this.gradNode;
        properties.depthNode = this.depthNode;

    }

TextureNode.generateUV(builder: NodeBuilder, uvNode: Node): string

JSDoc:

/**
     * Generates the uv code snippet.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @param {Node} uvNode - The uv node to generate code for.
     * @return {string} The generated code snippet.
     */

Parameters:

  • builder NodeBuilder
  • uvNode Node

Returns: string

Calls:

  • uvNode.build
Code
generateUV( builder, uvNode ) {

        return uvNode.build( builder, this.sampler === true ? 'vec2' : 'ivec2' );

    }

TextureNode.generateSnippet(builder: NodeBuilder, textureProperty: string, uvSnippet: string, levelSnippet: string, biasSnippet: string, depthSnippet: string, compareSnippet: string, gradSnippet: string[]): string

JSDoc:

/**
     * Generates the snippet for the texture sampling.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @param {string} textureProperty - The texture property.
     * @param {string} uvSnippet - The uv snippet.
     * @param {?string} levelSnippet - The level snippet.
     * @param {?string} biasSnippet - The bias snippet.
     * @param {?string} depthSnippet - The depth snippet.
     * @param {?string} compareSnippet - The compare snippet.
     * @param {?Array<string>} gradSnippet - The grad snippet.
     * @return {string} The generated code snippet.
     */

Parameters:

  • builder NodeBuilder
  • textureProperty string
  • uvSnippet string
  • levelSnippet string
  • biasSnippet string
  • depthSnippet string
  • compareSnippet string
  • gradSnippet string[]

Returns: string

Calls:

  • builder.generateTextureLevel
  • builder.generateTextureBias
  • builder.generateTextureGrad
  • builder.generateTextureCompare
  • builder.generateTextureLoad
  • builder.generateTexture
Code
generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet ) {

        const texture = this.value;

        let snippet;

        if ( levelSnippet ) {

            snippet = builder.generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet );

        } else if ( biasSnippet ) {

            snippet = builder.generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet );

        } else if ( gradSnippet ) {

            snippet = builder.generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet );

        } else if ( compareSnippet ) {

            snippet = builder.generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet );

        } else if ( this.sampler === false ) {

            snippet = builder.generateTextureLoad( texture, textureProperty, uvSnippet, depthSnippet );

        } else {

            snippet = builder.generateTexture( texture, textureProperty, uvSnippet, depthSnippet );

        }

        return snippet;

    }

TextureNode.generate(builder: NodeBuilder, output: string): string

JSDoc:

/**
     * Generates the code snippet of the texture node.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @param {string} output - The current output.
     * @return {string} The generated code snippet.
     */

Parameters:

  • builder NodeBuilder
  • output string

Returns: string

Calls:

  • builder.getNodeProperties
  • super.generate
  • /^sampler/.test
  • builder.isReference
  • builder.getDataFromNode
  • this.generateUV
  • levelNode.build
  • biasNode.build
  • depthNode.build
  • compareNode.build
  • gradNode[ 0 ].build
  • gradNode[ 1 ].build
  • builder.getVarFromNode
  • builder.getPropertyName
  • this.generateSnippet
  • builder.addLineFlowCode
  • this.getNodeType
  • builder.needsToWorkingColorSpace
  • colorSpaceToWorking( expression( snippet, nodeType ), texture.colorSpace ).setup( builder ).build
  • builder.format
Code
generate( builder, output ) {

        const texture = this.value;

        const properties = builder.getNodeProperties( this );
        const textureProperty = super.generate( builder, 'property' );

        if ( /^sampler/.test( output ) ) {

            return textureProperty + '_sampler';

        } else if ( builder.isReference( output ) ) {

            return textureProperty;

        } else {

            const nodeData = builder.getDataFromNode( this );

            let propertyName = nodeData.propertyName;

            if ( propertyName === undefined ) {

                const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties;

                const uvSnippet = this.generateUV( builder, uvNode );
                const levelSnippet = levelNode ? levelNode.build( builder, 'float' ) : null;
                const biasSnippet = biasNode ? biasNode.build( builder, 'float' ) : null;
                const depthSnippet = depthNode ? depthNode.build( builder, 'int' ) : null;
                const compareSnippet = compareNode ? compareNode.build( builder, 'float' ) : null;
                const gradSnippet = gradNode ? [ gradNode[ 0 ].build( builder, 'vec2' ), gradNode[ 1 ].build( builder, 'vec2' ) ] : null;

                const nodeVar = builder.getVarFromNode( this );

                propertyName = builder.getPropertyName( nodeVar );

                const snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet );

                builder.addLineFlowCode( `${propertyName} = ${snippet}`, this );

                nodeData.snippet = snippet;
                nodeData.propertyName = propertyName;

            }

            let snippet = propertyName;
            const nodeType = this.getNodeType( builder );

            if ( builder.needsToWorkingColorSpace( texture ) ) {

                snippet = colorSpaceToWorking( expression( snippet, nodeType ), texture.colorSpace ).setup( builder ).build( builder, nodeType );

            }

            return builder.format( snippet, nodeType, output );

        }

    }

TextureNode.setSampler(value: boolean): TextureNode

JSDoc:

/**
     * Sets the sampler value.
     *
     * @param {boolean} value - The sampler value to set.
     * @return {TextureNode} A reference to this texture node.
     */

Parameters:

  • value boolean

Returns: TextureNode

Code
setSampler( value ) {

        this.sampler = value;

        return this;

    }

TextureNode.getSampler(): boolean

JSDoc:

/**
     * Returns the sampler value.
     *
     * @return {boolean} The sampler value.
     */

Returns: boolean

Code
getSampler() {

        return this.sampler;

    }

TextureNode.uv(uvNode: Node): TextureNode

JSDoc:

/**
     * @function
     * @deprecated since r172. Use {@link TextureNode#sample} instead.
     *
     * @param {Node} uvNode - The uv node.
     * @return {TextureNode} A texture node representing the texture sample.
     */

Parameters:

  • uvNode Node

Returns: TextureNode

Calls:

  • console.warn
  • this.sample
Code
uv( uvNode ) { // @deprecated, r172

        console.warn( 'THREE.TextureNode: .uv() has been renamed. Use .sample() instead.' );

        return this.sample( uvNode );

    }

TextureNode.sample(uvNode: Node): TextureNode

JSDoc:

/**
     * Samples the texture with the given uv node.
     *
     * @param {Node} uvNode - The uv node.
     * @return {TextureNode} A texture node representing the texture sample.
     */

Parameters:

  • uvNode Node

Returns: TextureNode

Calls:

  • this.clone
  • nodeObject (from ../tsl/TSLBase.js)
  • this.getSelf
Code
sample( uvNode ) {

        const textureNode = this.clone();
        textureNode.uvNode = nodeObject( uvNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

TextureNode.load(uvNode: any): TextureNode

JSDoc:

/**
     * TSL function for creating a texture node that fetches/loads texels without interpolation.
     *
     * @param {Node<uvec2>} uvNode - The uv node.
     * @returns {TextureNode} A texture node representing the texture load.
     */

Parameters:

  • uvNode any

Returns: TextureNode

Calls:

  • this.sample( uvNode ).setSampler
Code
load( uvNode ) {

        return this.sample( uvNode ).setSampler( false );

    }

TextureNode.blur(amountNode: any): TextureNode

JSDoc:

/**
     * Samples a blurred version of the texture by defining an internal bias.
     *
     * @param {Node<float>} amountNode - How blurred the texture should be.
     * @return {TextureNode} A texture node representing the texture sample.
     */

Parameters:

  • amountNode any

Returns: TextureNode

Calls:

  • this.clone
  • nodeObject( amountNode ).mul
  • maxMipLevel (from ../utils/MaxMipLevelNode.js)
  • this.getSelf
  • console.warn
  • nodeObject (from ../tsl/TSLBase.js)
Code
blur( amountNode ) {

        const textureNode = this.clone();
        textureNode.biasNode = nodeObject( amountNode ).mul( maxMipLevel( textureNode ) );
        textureNode.referenceNode = this.getSelf();

        const map = textureNode.value;

        if ( textureNode.generateMipmaps === false && ( map && map.generateMipmaps === false || map.minFilter === NearestFilter || map.magFilter === NearestFilter ) ) {

            console.warn( 'THREE.TSL: texture().blur() requires mipmaps and sampling. Use .generateMipmaps=true and .minFilter/.magFilter=THREE.LinearFilter in the Texture.' );

            textureNode.biasNode = null;

        }

        return nodeObject( textureNode );

    }

TextureNode.level(levelNode: any): TextureNode

JSDoc:

/**
     * Samples a specific mip of the texture.
     *
     * @param {Node<int>} levelNode - The mip level to sample.
     * @return {TextureNode} A texture node representing the texture sample.
     */

Parameters:

  • levelNode any

Returns: TextureNode

Calls:

  • this.clone
  • nodeObject (from ../tsl/TSLBase.js)
  • this.getSelf
Code
level( levelNode ) {

        const textureNode = this.clone();
        textureNode.levelNode = nodeObject( levelNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

TextureNode.size(levelNode: any): TextureSizeNode

JSDoc:

/**
     * Returns the texture size of the requested level.
     *
     * @param {Node<int>} levelNode - The level to compute the size for.
     * @return {TextureSizeNode} The texture size.
     */

Parameters:

  • levelNode any

Returns: TextureSizeNode

Calls:

  • textureSize (from ./TextureSizeNode.js)
Code
size( levelNode ) {

        return textureSize( this, levelNode );

    }

TextureNode.bias(biasNode: any): TextureNode

JSDoc:

/**
     * Samples the texture with the given bias.
     *
     * @param {Node<float>} biasNode - The bias node.
     * @return {TextureNode} A texture node representing the texture sample.
     */

Parameters:

  • biasNode any

Returns: TextureNode

Calls:

  • this.clone
  • nodeObject (from ../tsl/TSLBase.js)
  • this.getSelf
Code
bias( biasNode ) {

        const textureNode = this.clone();
        textureNode.biasNode = nodeObject( biasNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

TextureNode.compare(compareNode: any): TextureNode

JSDoc:

/**
     * Samples the texture by executing a compare operation.
     *
     * @param {Node<float>} compareNode - The node that defines the compare value.
     * @return {TextureNode} A texture node representing the texture sample.
     */

Parameters:

  • compareNode any

Returns: TextureNode

Calls:

  • this.clone
  • nodeObject (from ../tsl/TSLBase.js)
  • this.getSelf
Code
compare( compareNode ) {

        const textureNode = this.clone();
        textureNode.compareNode = nodeObject( compareNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

TextureNode.grad(gradNodeX: any, gradNodeY: any): TextureNode

JSDoc:

/**
     * Samples the texture using an explicit gradient.
     *
     * @param {Node<vec2>} gradNodeX - The gradX node.
     * @param {Node<vec2>} gradNodeY - The gradY node.
     * @return {TextureNode} A texture node representing the texture sample.
     */

Parameters:

  • gradNodeX any
  • gradNodeY any

Returns: TextureNode

Calls:

  • this.clone
  • nodeObject (from ../tsl/TSLBase.js)
  • this.getSelf
Code
grad( gradNodeX, gradNodeY ) {

        const textureNode = this.clone();
        textureNode.gradNode = [ nodeObject( gradNodeX ), nodeObject( gradNodeY ) ];
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

TextureNode.depth(depthNode: any): TextureNode

JSDoc:

/**
     * Samples the texture by defining a depth node.
     *
     * @param {Node<int>} depthNode - The depth node.
     * @return {TextureNode} A texture node representing the texture sample.
     */

Parameters:

  • depthNode any

Returns: TextureNode

Calls:

  • this.clone
  • nodeObject (from ../tsl/TSLBase.js)
  • this.getSelf
Code
depth( depthNode ) {

        const textureNode = this.clone();
        textureNode.depthNode = nodeObject( depthNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

TextureNode.serialize(data: any): void

Parameters:

  • data any

Returns: void

Calls:

  • super.serialize
  • this.value.toJSON
Code
serialize( data ) {

        super.serialize( data );

        data.value = this.value.toJSON( data.meta ).uuid;
        data.sampler = this.sampler;
        data.updateMatrix = this.updateMatrix;
        data.updateType = this.updateType;

    }

TextureNode.deserialize(data: any): void

Parameters:

  • data any

Returns: void

Calls:

  • super.deserialize
Code
deserialize( data ) {

        super.deserialize( data );

        this.value = data.meta.textures[ data.value ];
        this.sampler = data.sampler;
        this.updateMatrix = data.updateMatrix;
        this.updateType = data.updateType;

    }

TextureNode.update(): void

JSDoc:

/**
     * The update is used to implement the update of the uv transformation matrix.
     */

Returns: void

Calls:

  • texture.updateMatrix
Code
update() {

        const texture = this.value;
        const matrixUniform = this._matrixUniform;

        if ( matrixUniform !== null ) matrixUniform.value = texture.matrix;

        if ( texture.matrixAutoUpdate === true ) {

            texture.updateMatrix();

        }

    }

TextureNode.clone(): TextureNode

JSDoc:

/**
     * Clones the texture node.
     *
     * @return {TextureNode} The cloned texture node.
     */

Returns: TextureNode

Code
clone() {

        const newNode = new this.constructor( this.value, this.uvNode, this.levelNode, this.biasNode );
        newNode.sampler = this.sampler;
        newNode.depthNode = this.depthNode;
        newNode.compareNode = this.compareNode;
        newNode.gradNode = this.gradNode;

        return newNode;

    }

texture(value: Texture | TextureNode, uvNode: any, levelNode: any, biasNode: any): TextureNode

Parameters:

  • value Texture | TextureNode
  • uvNode any
  • levelNode any
  • biasNode any

Returns: TextureNode

Calls:

  • nodeObject (from ../tsl/TSLBase.js)
  • value.clone
  • value.getSelf
  • textureBase
Code
( value = EmptyTexture, uvNode = null, levelNode = null, biasNode = null ) => {

    let textureNode;

    if ( value && value.isTextureNode === true ) {

        textureNode = nodeObject( value.clone() );
        textureNode.referenceNode = value.getSelf(); // Ensure the reference is set to the original node

        if ( uvNode !== null ) textureNode.uvNode = nodeObject( uvNode );
        if ( levelNode !== null ) textureNode.levelNode = nodeObject( levelNode );
        if ( biasNode !== null ) textureNode.biasNode = nodeObject( biasNode );

    } else {

        textureNode = textureBase( value, uvNode, levelNode, biasNode );

    }

    return textureNode;

}

uniformTexture(value: Texture): TextureNode

Parameters:

  • value Texture

Returns: TextureNode

Calls:

  • texture
Code
( value = EmptyTexture ) => texture( value )

textureLoad(params: any[]): TextureNode

Parameters:

  • params any[]

Returns: TextureNode

Calls:

  • texture( ...params ).setSampler
Code
( ...params ) => texture( ...params ).setSampler( false )

sampler(value: Texture | TextureNode): Node

Parameters:

  • value Texture | TextureNode

Returns: Node

Calls:

  • ( value.isNode === true ? value : texture( value ) ).convert
Code
( value ) => ( value.isNode === true ? value : texture( value ) ).convert( 'sampler' )

samplerComparison(value: Texture | TextureNode): Node

Parameters:

  • value Texture | TextureNode

Returns: Node

Calls:

  • ( value.isNode === true ? value : texture( value ) ).convert
Code
( value ) => ( value.isNode === true ? value : texture( value ) ).convert( 'samplerComparison' )

Classes

TextureNode

Class Code
class TextureNode extends UniformNode {

    static get type() {

        return 'TextureNode';

    }

    /**
     * Constructs a new texture node.
     *
     * @param {Texture} [value=EmptyTexture] - The texture.
     * @param {?Node<vec2|vec3>} [uvNode=null] - The uv node.
     * @param {?Node<int>} [levelNode=null] - The level node.
     * @param {?Node<float>} [biasNode=null] - The bias node.
     */
    constructor( value = EmptyTexture, uvNode = null, levelNode = null, biasNode = null ) {

        super( value );

        /**
         * This flag can be used for type testing.
         *
         * @type {boolean}
         * @readonly
         * @default true
         */
        this.isTextureNode = true;

        /**
         * Represents the texture coordinates.
         *
         * @type {?Node<vec2|vec3>}
         * @default null
         */
        this.uvNode = uvNode;

        /**
         * Represents the mip level that should be selected.
         *
         * @type {?Node<int>}
         * @default null
         */
        this.levelNode = levelNode;

        /**
         * Represents the bias to be applied during level-of-detail computation.
         *
         * @type {?Node<float>}
         * @default null
         */
        this.biasNode = biasNode;

        /**
         * Represents a reference value a texture sample is compared to.
         *
         * @type {?Node<float>}
         * @default null
         */
        this.compareNode = null;

        /**
         * When using texture arrays, the depth node defines the layer to select.
         *
         * @type {?Node<int>}
         * @default null
         */
        this.depthNode = null;

        /**
         * When defined, a texture is sampled using explicit gradients.
         *
         * @type {?Array<Node<vec2>>}
         * @default null
         */
        this.gradNode = null;

        /**
         * Whether texture values should be sampled or fetched.
         *
         * @type {boolean}
         * @default true
         */
        this.sampler = true;

        /**
         * Whether the uv transformation matrix should be
         * automatically updated or not. Use `setUpdateMatrix()`
         * if you want to change the value of the property.
         *
         * @type {boolean}
         * @default false
         */
        this.updateMatrix = false;

        /**
         * By default the `update()` method is not executed. `setUpdateMatrix()`
         * sets the value to `frame` when the uv transformation matrix should
         * automatically be updated.
         *
         * @type {string}
         * @default 'none'
         */
        this.updateType = NodeUpdateType.NONE;

        /**
         * The reference node.
         *
         * @type {?Node}
         * @default null
         */
        this.referenceNode = null;

        /**
         * The texture value is stored in a private property.
         *
         * @private
         * @type {Texture}
         */
        this._value = value;

        /**
         * The uniform node that represents the uv transformation matrix.
         *
         * @private
         * @type {?UniformNode<mat3>}
         */
        this._matrixUniform = null;

        this.setUpdateMatrix( uvNode === null );

    }

    set value( value ) {

        if ( this.referenceNode ) {

            this.referenceNode.value = value;

        } else {

            this._value = value;

        }

    }

    /**
     * The texture value.
     *
     * @type {Texture}
     */
    get value() {

        return this.referenceNode ? this.referenceNode.value : this._value;

    }

    /**
     * Overwritten since the uniform hash is defined by the texture's UUID.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @return {string} The uniform hash.
     */
    getUniformHash( /*builder*/ ) {

        return this.value.uuid;

    }

    /**
     * Overwritten since the node type is inferred from the texture type.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @return {string} The node type.
     */
    getNodeType( /*builder*/ ) {

        if ( this.value.isDepthTexture === true ) return 'float';

        if ( this.value.type === UnsignedIntType ) {

            return 'uvec4';

        } else if ( this.value.type === IntType ) {

            return 'ivec4';

        }

        return 'vec4';

    }

    /**
     * Overwrites the default implementation to return a fixed value `'texture'`.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @return {string} The input type.
     */
    getInputType( /*builder*/ ) {

        return 'texture';

    }

    /**
     * Returns a default uvs based on the current texture's channel.
     *
     * @return {AttributeNode<vec2>} The default uvs.
     */
    getDefaultUV() {

        return uv( this.value.channel );

    }

    /**
     * Overwritten to always return the texture reference of the node.
     *
     * @param {any} state - This method can be invocated in different contexts so `state` can refer to any object type.
     * @return {Texture} The texture reference.
     */
    updateReference( /*state*/ ) {

        return this.value;

    }

    /**
     * Transforms the given uv node with the texture transformation matrix.
     *
     * @param {Node} uvNode - The uv node to transform.
     * @return {Node} The transformed uv node.
     */
    getTransformedUV( uvNode ) {

        if ( this._matrixUniform === null ) this._matrixUniform = uniform( this.value.matrix );

        return this._matrixUniform.mul( vec3( uvNode, 1 ) ).xy;

    }

    /**
     * Defines whether the uv transformation matrix should automatically be updated or not.
     *
     * @param {boolean} value - The update toggle.
     * @return {TextureNode} A reference to this node.
     */
    setUpdateMatrix( value ) {

        this.updateMatrix = value;
        this.updateType = value ? NodeUpdateType.OBJECT : NodeUpdateType.NONE;

        return this;

    }

    /**
     * Setups the uv node. Depending on the backend as well as texture's image and type, it might be necessary
     * to modify the uv node for correct sampling.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @param {Node} uvNode - The uv node to setup.
     * @return {Node} The updated uv node.
     */
    setupUV( builder, uvNode ) {

        const texture = this.value;

        if ( builder.isFlipY() && ( ( texture.image instanceof ImageBitmap && texture.flipY === true ) || texture.isRenderTargetTexture === true || texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) {

            if ( this.sampler ) {

                uvNode = uvNode.flipY();

            } else {

                uvNode = uvNode.setY( int( textureSize( this, this.levelNode ).y ).sub( uvNode.y ).sub( 1 ) );

            }

        }

        return uvNode;

    }

    /**
     * Setups texture node by preparing the internal nodes for code generation.
     *
     * @param {NodeBuilder} builder - The current node builder.
     */
    setup( builder ) {

        const properties = builder.getNodeProperties( this );
        properties.referenceNode = this.referenceNode;

        //

        const texture = this.value;

        if ( ! texture || texture.isTexture !== true ) {

            throw new Error( 'THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().' );

        }

        //

        let uvNode = this.uvNode;

        if ( ( uvNode === null || builder.context.forceUVContext === true ) && builder.context.getUV ) {

            uvNode = builder.context.getUV( this, builder );

        }

        if ( ! uvNode ) uvNode = this.getDefaultUV();

        if ( this.updateMatrix === true ) {

            uvNode = this.getTransformedUV( uvNode );

        }

        uvNode = this.setupUV( builder, uvNode );

        //

        let levelNode = this.levelNode;

        if ( levelNode === null && builder.context.getTextureLevel ) {

            levelNode = builder.context.getTextureLevel( this );

        }

        //

        properties.uvNode = uvNode;
        properties.levelNode = levelNode;
        properties.biasNode = this.biasNode;
        properties.compareNode = this.compareNode;
        properties.gradNode = this.gradNode;
        properties.depthNode = this.depthNode;

    }

    /**
     * Generates the uv code snippet.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @param {Node} uvNode - The uv node to generate code for.
     * @return {string} The generated code snippet.
     */
    generateUV( builder, uvNode ) {

        return uvNode.build( builder, this.sampler === true ? 'vec2' : 'ivec2' );

    }

    /**
     * Generates the snippet for the texture sampling.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @param {string} textureProperty - The texture property.
     * @param {string} uvSnippet - The uv snippet.
     * @param {?string} levelSnippet - The level snippet.
     * @param {?string} biasSnippet - The bias snippet.
     * @param {?string} depthSnippet - The depth snippet.
     * @param {?string} compareSnippet - The compare snippet.
     * @param {?Array<string>} gradSnippet - The grad snippet.
     * @return {string} The generated code snippet.
     */
    generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet ) {

        const texture = this.value;

        let snippet;

        if ( levelSnippet ) {

            snippet = builder.generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet );

        } else if ( biasSnippet ) {

            snippet = builder.generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet );

        } else if ( gradSnippet ) {

            snippet = builder.generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet );

        } else if ( compareSnippet ) {

            snippet = builder.generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet );

        } else if ( this.sampler === false ) {

            snippet = builder.generateTextureLoad( texture, textureProperty, uvSnippet, depthSnippet );

        } else {

            snippet = builder.generateTexture( texture, textureProperty, uvSnippet, depthSnippet );

        }

        return snippet;

    }

    /**
     * Generates the code snippet of the texture node.
     *
     * @param {NodeBuilder} builder - The current node builder.
     * @param {string} output - The current output.
     * @return {string} The generated code snippet.
     */
    generate( builder, output ) {

        const texture = this.value;

        const properties = builder.getNodeProperties( this );
        const textureProperty = super.generate( builder, 'property' );

        if ( /^sampler/.test( output ) ) {

            return textureProperty + '_sampler';

        } else if ( builder.isReference( output ) ) {

            return textureProperty;

        } else {

            const nodeData = builder.getDataFromNode( this );

            let propertyName = nodeData.propertyName;

            if ( propertyName === undefined ) {

                const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties;

                const uvSnippet = this.generateUV( builder, uvNode );
                const levelSnippet = levelNode ? levelNode.build( builder, 'float' ) : null;
                const biasSnippet = biasNode ? biasNode.build( builder, 'float' ) : null;
                const depthSnippet = depthNode ? depthNode.build( builder, 'int' ) : null;
                const compareSnippet = compareNode ? compareNode.build( builder, 'float' ) : null;
                const gradSnippet = gradNode ? [ gradNode[ 0 ].build( builder, 'vec2' ), gradNode[ 1 ].build( builder, 'vec2' ) ] : null;

                const nodeVar = builder.getVarFromNode( this );

                propertyName = builder.getPropertyName( nodeVar );

                const snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet );

                builder.addLineFlowCode( `${propertyName} = ${snippet}`, this );

                nodeData.snippet = snippet;
                nodeData.propertyName = propertyName;

            }

            let snippet = propertyName;
            const nodeType = this.getNodeType( builder );

            if ( builder.needsToWorkingColorSpace( texture ) ) {

                snippet = colorSpaceToWorking( expression( snippet, nodeType ), texture.colorSpace ).setup( builder ).build( builder, nodeType );

            }

            return builder.format( snippet, nodeType, output );

        }

    }

    /**
     * Sets the sampler value.
     *
     * @param {boolean} value - The sampler value to set.
     * @return {TextureNode} A reference to this texture node.
     */
    setSampler( value ) {

        this.sampler = value;

        return this;

    }

    /**
     * Returns the sampler value.
     *
     * @return {boolean} The sampler value.
     */
    getSampler() {

        return this.sampler;

    }

    // @TODO: Move to TSL

    /**
     * @function
     * @deprecated since r172. Use {@link TextureNode#sample} instead.
     *
     * @param {Node} uvNode - The uv node.
     * @return {TextureNode} A texture node representing the texture sample.
     */
    uv( uvNode ) { // @deprecated, r172

        console.warn( 'THREE.TextureNode: .uv() has been renamed. Use .sample() instead.' );

        return this.sample( uvNode );

    }

    /**
     * Samples the texture with the given uv node.
     *
     * @param {Node} uvNode - The uv node.
     * @return {TextureNode} A texture node representing the texture sample.
     */
    sample( uvNode ) {

        const textureNode = this.clone();
        textureNode.uvNode = nodeObject( uvNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

    /**
     * TSL function for creating a texture node that fetches/loads texels without interpolation.
     *
     * @param {Node<uvec2>} uvNode - The uv node.
     * @returns {TextureNode} A texture node representing the texture load.
     */
    load( uvNode ) {

        return this.sample( uvNode ).setSampler( false );

    }

    /**
     * Samples a blurred version of the texture by defining an internal bias.
     *
     * @param {Node<float>} amountNode - How blurred the texture should be.
     * @return {TextureNode} A texture node representing the texture sample.
     */
    blur( amountNode ) {

        const textureNode = this.clone();
        textureNode.biasNode = nodeObject( amountNode ).mul( maxMipLevel( textureNode ) );
        textureNode.referenceNode = this.getSelf();

        const map = textureNode.value;

        if ( textureNode.generateMipmaps === false && ( map && map.generateMipmaps === false || map.minFilter === NearestFilter || map.magFilter === NearestFilter ) ) {

            console.warn( 'THREE.TSL: texture().blur() requires mipmaps and sampling. Use .generateMipmaps=true and .minFilter/.magFilter=THREE.LinearFilter in the Texture.' );

            textureNode.biasNode = null;

        }

        return nodeObject( textureNode );

    }

    /**
     * Samples a specific mip of the texture.
     *
     * @param {Node<int>} levelNode - The mip level to sample.
     * @return {TextureNode} A texture node representing the texture sample.
     */
    level( levelNode ) {

        const textureNode = this.clone();
        textureNode.levelNode = nodeObject( levelNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

    /**
     * Returns the texture size of the requested level.
     *
     * @param {Node<int>} levelNode - The level to compute the size for.
     * @return {TextureSizeNode} The texture size.
     */
    size( levelNode ) {

        return textureSize( this, levelNode );

    }

    /**
     * Samples the texture with the given bias.
     *
     * @param {Node<float>} biasNode - The bias node.
     * @return {TextureNode} A texture node representing the texture sample.
     */
    bias( biasNode ) {

        const textureNode = this.clone();
        textureNode.biasNode = nodeObject( biasNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

    /**
     * Samples the texture by executing a compare operation.
     *
     * @param {Node<float>} compareNode - The node that defines the compare value.
     * @return {TextureNode} A texture node representing the texture sample.
     */
    compare( compareNode ) {

        const textureNode = this.clone();
        textureNode.compareNode = nodeObject( compareNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

    /**
     * Samples the texture using an explicit gradient.
     *
     * @param {Node<vec2>} gradNodeX - The gradX node.
     * @param {Node<vec2>} gradNodeY - The gradY node.
     * @return {TextureNode} A texture node representing the texture sample.
     */
    grad( gradNodeX, gradNodeY ) {

        const textureNode = this.clone();
        textureNode.gradNode = [ nodeObject( gradNodeX ), nodeObject( gradNodeY ) ];
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

    /**
     * Samples the texture by defining a depth node.
     *
     * @param {Node<int>} depthNode - The depth node.
     * @return {TextureNode} A texture node representing the texture sample.
     */
    depth( depthNode ) {

        const textureNode = this.clone();
        textureNode.depthNode = nodeObject( depthNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }

    // --

    serialize( data ) {

        super.serialize( data );

        data.value = this.value.toJSON( data.meta ).uuid;
        data.sampler = this.sampler;
        data.updateMatrix = this.updateMatrix;
        data.updateType = this.updateType;

    }

    deserialize( data ) {

        super.deserialize( data );

        this.value = data.meta.textures[ data.value ];
        this.sampler = data.sampler;
        this.updateMatrix = data.updateMatrix;
        this.updateType = data.updateType;

    }

    /**
     * The update is used to implement the update of the uv transformation matrix.
     */
    update() {

        const texture = this.value;
        const matrixUniform = this._matrixUniform;

        if ( matrixUniform !== null ) matrixUniform.value = texture.matrix;

        if ( texture.matrixAutoUpdate === true ) {

            texture.updateMatrix();

        }

    }

    /**
     * Clones the texture node.
     *
     * @return {TextureNode} The cloned texture node.
     */
    clone() {

        const newNode = new this.constructor( this.value, this.uvNode, this.levelNode, this.biasNode );
        newNode.sampler = this.sampler;
        newNode.depthNode = this.depthNode;
        newNode.compareNode = this.compareNode;
        newNode.gradNode = this.gradNode;

        return newNode;

    }

}

Methods

getUniformHash(): string
Code
getUniformHash( /*builder*/ ) {

        return this.value.uuid;

    }
getNodeType(): string
Code
getNodeType( /*builder*/ ) {

        if ( this.value.isDepthTexture === true ) return 'float';

        if ( this.value.type === UnsignedIntType ) {

            return 'uvec4';

        } else if ( this.value.type === IntType ) {

            return 'ivec4';

        }

        return 'vec4';

    }
getInputType(): string
Code
getInputType( /*builder*/ ) {

        return 'texture';

    }
getDefaultUV(): AttributeNode<vec2>
Code
getDefaultUV() {

        return uv( this.value.channel );

    }
updateReference(): Texture
Code
updateReference( /*state*/ ) {

        return this.value;

    }
getTransformedUV(uvNode: Node): Node
Code
getTransformedUV( uvNode ) {

        if ( this._matrixUniform === null ) this._matrixUniform = uniform( this.value.matrix );

        return this._matrixUniform.mul( vec3( uvNode, 1 ) ).xy;

    }
setUpdateMatrix(value: boolean): TextureNode
Code
setUpdateMatrix( value ) {

        this.updateMatrix = value;
        this.updateType = value ? NodeUpdateType.OBJECT : NodeUpdateType.NONE;

        return this;

    }
setupUV(builder: NodeBuilder, uvNode: Node): Node
Code
setupUV( builder, uvNode ) {

        const texture = this.value;

        if ( builder.isFlipY() && ( ( texture.image instanceof ImageBitmap && texture.flipY === true ) || texture.isRenderTargetTexture === true || texture.isFramebufferTexture === true || texture.isDepthTexture === true ) ) {

            if ( this.sampler ) {

                uvNode = uvNode.flipY();

            } else {

                uvNode = uvNode.setY( int( textureSize( this, this.levelNode ).y ).sub( uvNode.y ).sub( 1 ) );

            }

        }

        return uvNode;

    }
setup(builder: NodeBuilder): void
Code
setup( builder ) {

        const properties = builder.getNodeProperties( this );
        properties.referenceNode = this.referenceNode;

        //

        const texture = this.value;

        if ( ! texture || texture.isTexture !== true ) {

            throw new Error( 'THREE.TSL: `texture( value )` function expects a valid instance of THREE.Texture().' );

        }

        //

        let uvNode = this.uvNode;

        if ( ( uvNode === null || builder.context.forceUVContext === true ) && builder.context.getUV ) {

            uvNode = builder.context.getUV( this, builder );

        }

        if ( ! uvNode ) uvNode = this.getDefaultUV();

        if ( this.updateMatrix === true ) {

            uvNode = this.getTransformedUV( uvNode );

        }

        uvNode = this.setupUV( builder, uvNode );

        //

        let levelNode = this.levelNode;

        if ( levelNode === null && builder.context.getTextureLevel ) {

            levelNode = builder.context.getTextureLevel( this );

        }

        //

        properties.uvNode = uvNode;
        properties.levelNode = levelNode;
        properties.biasNode = this.biasNode;
        properties.compareNode = this.compareNode;
        properties.gradNode = this.gradNode;
        properties.depthNode = this.depthNode;

    }
generateUV(builder: NodeBuilder, uvNode: Node): string
Code
generateUV( builder, uvNode ) {

        return uvNode.build( builder, this.sampler === true ? 'vec2' : 'ivec2' );

    }
generateSnippet(builder: NodeBuilder, textureProperty: string, uvSnippet: string, levelSnippet: string, biasSnippet: string, depthSnippet: string, compareSnippet: string, gradSnippet: string[]): string
Code
generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet ) {

        const texture = this.value;

        let snippet;

        if ( levelSnippet ) {

            snippet = builder.generateTextureLevel( texture, textureProperty, uvSnippet, levelSnippet, depthSnippet );

        } else if ( biasSnippet ) {

            snippet = builder.generateTextureBias( texture, textureProperty, uvSnippet, biasSnippet, depthSnippet );

        } else if ( gradSnippet ) {

            snippet = builder.generateTextureGrad( texture, textureProperty, uvSnippet, gradSnippet, depthSnippet );

        } else if ( compareSnippet ) {

            snippet = builder.generateTextureCompare( texture, textureProperty, uvSnippet, compareSnippet, depthSnippet );

        } else if ( this.sampler === false ) {

            snippet = builder.generateTextureLoad( texture, textureProperty, uvSnippet, depthSnippet );

        } else {

            snippet = builder.generateTexture( texture, textureProperty, uvSnippet, depthSnippet );

        }

        return snippet;

    }
generate(builder: NodeBuilder, output: string): string
Code
generate( builder, output ) {

        const texture = this.value;

        const properties = builder.getNodeProperties( this );
        const textureProperty = super.generate( builder, 'property' );

        if ( /^sampler/.test( output ) ) {

            return textureProperty + '_sampler';

        } else if ( builder.isReference( output ) ) {

            return textureProperty;

        } else {

            const nodeData = builder.getDataFromNode( this );

            let propertyName = nodeData.propertyName;

            if ( propertyName === undefined ) {

                const { uvNode, levelNode, biasNode, compareNode, depthNode, gradNode } = properties;

                const uvSnippet = this.generateUV( builder, uvNode );
                const levelSnippet = levelNode ? levelNode.build( builder, 'float' ) : null;
                const biasSnippet = biasNode ? biasNode.build( builder, 'float' ) : null;
                const depthSnippet = depthNode ? depthNode.build( builder, 'int' ) : null;
                const compareSnippet = compareNode ? compareNode.build( builder, 'float' ) : null;
                const gradSnippet = gradNode ? [ gradNode[ 0 ].build( builder, 'vec2' ), gradNode[ 1 ].build( builder, 'vec2' ) ] : null;

                const nodeVar = builder.getVarFromNode( this );

                propertyName = builder.getPropertyName( nodeVar );

                const snippet = this.generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet );

                builder.addLineFlowCode( `${propertyName} = ${snippet}`, this );

                nodeData.snippet = snippet;
                nodeData.propertyName = propertyName;

            }

            let snippet = propertyName;
            const nodeType = this.getNodeType( builder );

            if ( builder.needsToWorkingColorSpace( texture ) ) {

                snippet = colorSpaceToWorking( expression( snippet, nodeType ), texture.colorSpace ).setup( builder ).build( builder, nodeType );

            }

            return builder.format( snippet, nodeType, output );

        }

    }
setSampler(value: boolean): TextureNode
Code
setSampler( value ) {

        this.sampler = value;

        return this;

    }
getSampler(): boolean
Code
getSampler() {

        return this.sampler;

    }
uv(uvNode: Node): TextureNode
Code
uv( uvNode ) { // @deprecated, r172

        console.warn( 'THREE.TextureNode: .uv() has been renamed. Use .sample() instead.' );

        return this.sample( uvNode );

    }
sample(uvNode: Node): TextureNode
Code
sample( uvNode ) {

        const textureNode = this.clone();
        textureNode.uvNode = nodeObject( uvNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }
load(uvNode: any): TextureNode
Code
load( uvNode ) {

        return this.sample( uvNode ).setSampler( false );

    }
blur(amountNode: any): TextureNode
Code
blur( amountNode ) {

        const textureNode = this.clone();
        textureNode.biasNode = nodeObject( amountNode ).mul( maxMipLevel( textureNode ) );
        textureNode.referenceNode = this.getSelf();

        const map = textureNode.value;

        if ( textureNode.generateMipmaps === false && ( map && map.generateMipmaps === false || map.minFilter === NearestFilter || map.magFilter === NearestFilter ) ) {

            console.warn( 'THREE.TSL: texture().blur() requires mipmaps and sampling. Use .generateMipmaps=true and .minFilter/.magFilter=THREE.LinearFilter in the Texture.' );

            textureNode.biasNode = null;

        }

        return nodeObject( textureNode );

    }
level(levelNode: any): TextureNode
Code
level( levelNode ) {

        const textureNode = this.clone();
        textureNode.levelNode = nodeObject( levelNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }
size(levelNode: any): TextureSizeNode
Code
size( levelNode ) {

        return textureSize( this, levelNode );

    }
bias(biasNode: any): TextureNode
Code
bias( biasNode ) {

        const textureNode = this.clone();
        textureNode.biasNode = nodeObject( biasNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }
compare(compareNode: any): TextureNode
Code
compare( compareNode ) {

        const textureNode = this.clone();
        textureNode.compareNode = nodeObject( compareNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }
grad(gradNodeX: any, gradNodeY: any): TextureNode
Code
grad( gradNodeX, gradNodeY ) {

        const textureNode = this.clone();
        textureNode.gradNode = [ nodeObject( gradNodeX ), nodeObject( gradNodeY ) ];
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }
depth(depthNode: any): TextureNode
Code
depth( depthNode ) {

        const textureNode = this.clone();
        textureNode.depthNode = nodeObject( depthNode );
        textureNode.referenceNode = this.getSelf();

        return nodeObject( textureNode );

    }
serialize(data: any): void
Code
serialize( data ) {

        super.serialize( data );

        data.value = this.value.toJSON( data.meta ).uuid;
        data.sampler = this.sampler;
        data.updateMatrix = this.updateMatrix;
        data.updateType = this.updateType;

    }
deserialize(data: any): void
Code
deserialize( data ) {

        super.deserialize( data );

        this.value = data.meta.textures[ data.value ];
        this.sampler = data.sampler;
        this.updateMatrix = data.updateMatrix;
        this.updateType = data.updateType;

    }
update(): void
Code
update() {

        const texture = this.value;
        const matrixUniform = this._matrixUniform;

        if ( matrixUniform !== null ) matrixUniform.value = texture.matrix;

        if ( texture.matrixAutoUpdate === true ) {

            texture.updateMatrix();

        }

    }
clone(): TextureNode
Code
clone() {

        const newNode = new this.constructor( this.value, this.uvNode, this.levelNode, this.biasNode );
        newNode.sampler = this.sampler;
        newNode.depthNode = this.depthNode;
        newNode.compareNode = this.compareNode;
        newNode.gradNode = this.gradNode;

        return newNode;

    }