Skip to content

TSL: Introduce uniformTexture() and uniformCubeTexture() #31190

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 28, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/Three.TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -506,8 +506,10 @@ export const trunc = TSL.trunc;
export const tslFn = TSL.tslFn;
export const uint = TSL.uint;
export const uniform = TSL.uniform;
export const uniformCubeTexture = TSL.uniformCubeTexture;
export const uniformArray = TSL.uniformArray;
export const uniformGroup = TSL.uniformGroup;
export const uniformTexture = TSL.uniformTexture;
export const uniforms = TSL.uniforms;
export const unpremult = TSL.unpremult;
export const userData = TSL.userData;
Expand Down
52 changes: 50 additions & 2 deletions src/nodes/accessors/CubeTextureNode.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import TextureNode from './TextureNode.js';
import { reflectVector, refractVector } from './ReflectVector.js';
import { nodeProxy, vec3 } from '../tsl/TSLBase.js';
import { nodeObject, nodeProxy, vec3 } from '../tsl/TSLBase.js';

import { CubeReflectionMapping, CubeRefractionMapping, WebGPUCoordinateSystem } from '../../constants.js';
import { materialEnvRotation } from './MaterialProperties.js';

import { CubeTexture } from '../../textures/CubeTexture.js';

const EmptyTexture = /*@__PURE__*/ new CubeTexture();

/**
* This type of uniform node represents a cube texture.
*
Expand Down Expand Up @@ -138,4 +142,48 @@ export default CubeTextureNode;
* @param {?Node<float>} [biasNode=null] - The bias node.
* @returns {CubeTextureNode}
*/
export const cubeTexture = /*@__PURE__*/ nodeProxy( CubeTextureNode ).setParameterLength( 1, 4 ).setName( 'cubeTexture' );
export const cubeTextureBase = /*@__PURE__*/ nodeProxy( CubeTextureNode ).setParameterLength( 1, 4 ).setName( 'cubeTexture' );

/**
* TSL function for creating a cube texture uniform node.
*
* @tsl
* @function
* @param {?CubeTexture|CubeTextureNode} [value=EmptyTexture] - The cube texture.
* @param {?Node<vec3>} [uvNode=null] - The uv node.
* @param {?Node<int>} [levelNode=null] - The level node.
* @param {?Node<float>} [biasNode=null] - The bias node.
* @returns {CubeTextureNode}
*/
export const cubeTexture = ( value = EmptyTexture, uvNode = null, levelNode = null, biasNode = null ) => {

let textureNode;

if ( value && value.isCubeTextureNode === 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 = cubeTextureBase( value, uvNode, levelNode, biasNode );

}

return textureNode;

};

/**
* TSL function for creating a uniform cube texture node.
*
* @tsl
* @function
* @param {?CubeTexture} [value=EmptyTexture] - The cube texture.
* @returns {CubeTextureNode}
*/
export const uniformCubeTexture = ( value = EmptyTexture ) => cubeTextureBase( value );
58 changes: 53 additions & 5 deletions src/nodes/accessors/TextureNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ import { NodeUpdateType } from '../core/constants.js';

import { IntType, NearestFilter, UnsignedIntType } from '../../constants.js';

import { Texture } from '../../textures/Texture.js';

const EmptyTexture = /*@__PURE__*/ new Texture();

/**
* This type of uniform node represents a 2D texture.
*
Expand All @@ -25,12 +29,12 @@ class TextureNode extends UniformNode {
/**
* Constructs a new texture node.
*
* @param {Texture} value - The texture.
* @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, uvNode = null, levelNode = null, biasNode = null ) {
constructor( value = EmptyTexture, uvNode = null, levelNode = null, biasNode = null ) {

super( value );

Expand Down Expand Up @@ -737,20 +741,64 @@ export default TextureNode;
*
* @tsl
* @function
* @param {Texture} value - The texture.
* @param {?Texture} value - 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.
* @returns {TextureNode}
*/
export const texture = /*@__PURE__*/ nodeProxy( TextureNode ).setParameterLength( 1, 4 );
const textureBase = /*@__PURE__*/ nodeProxy( TextureNode ).setParameterLength( 1, 4 ).setName( 'texture' );

/**
* TSL function for creating a texture node or sample a texture node already existing.
*
* @tsl
* @function
* @param {?Texture|TextureNode} [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.
* @returns {TextureNode}
*/
export const texture = ( 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;

};

/**
* TSL function for creating a uniform texture node.
*
* @tsl
* @function
* @param {?Texture} value - The texture.
* @returns {TextureNode}
*/
export const uniformTexture = ( value = EmptyTexture ) => texture( value );

/**
* TSL function for creating a texture node that fetches/loads texels without interpolation.
*
* @tsl
* @function
* @param {Texture} value - The texture.
* @param {?Texture|TextureNode} [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.
Expand Down