From 19c76f8c749d417d66ba6629d76d8bfa52877e82 Mon Sep 17 00:00:00 2001 From: sunag Date: Fri, 9 Jan 2026 07:57:12 -0300 Subject: [PATCH 1/2] TSL: Fix `positionView` sub-build (#32691) --- src/materials/nodes/NodeMaterial.js | 4 ++-- src/nodes/accessors/Position.js | 4 ++-- src/nodes/core/VaryingNode.js | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/materials/nodes/NodeMaterial.js b/src/materials/nodes/NodeMaterial.js index 3dab50b4e7e820..c2af24320265e8 100644 --- a/src/materials/nodes/NodeMaterial.js +++ b/src/materials/nodes/NodeMaterial.js @@ -535,9 +535,9 @@ class NodeMaterial extends Material { builder.addStack(); - const mvp = subBuild( this.setupVertex( builder ), 'VERTEX' ); + const mvp = this.setupVertex( builder ); - const vertexNode = this.vertexNode || mvp; + const vertexNode = subBuild( this.vertexNode || mvp, 'VERTEX' ); builder.context.clipSpace = vertexNode; diff --git a/src/nodes/accessors/Position.js b/src/nodes/accessors/Position.js index d15176e91321eb..d791ab9ad305c1 100644 --- a/src/nodes/accessors/Position.js +++ b/src/nodes/accessors/Position.js @@ -67,7 +67,7 @@ export const positionWorld = /*@__PURE__*/ ( Fn( ( builder ) => { return modelWorldMatrix.mul( positionLocal ).xyz.toVarying( builder.getSubBuildProperty( 'v_positionWorld' ) ); -}, 'vec3' ).once( [ 'POSITION' ] ) )(); +}, 'vec3' ).once( [ 'POSITION', 'VERTEX' ] ) )(); /** * TSL object that represents the position world direction of the current rendered object. @@ -103,7 +103,7 @@ export const positionView = /*@__PURE__*/ ( Fn( ( builder ) => { return builder.context.setupPositionView().toVarying( 'v_positionView' ); -}, 'vec3' ).once( [ 'POSITION' ] ) )(); +}, 'vec3' ).once( [ 'POSITION', 'VERTEX' ] ) )(); /** * TSL object that represents the position view direction of the current rendered object. diff --git a/src/nodes/core/VaryingNode.js b/src/nodes/core/VaryingNode.js index c1728a543dbe55..662644fd597b6d 100644 --- a/src/nodes/core/VaryingNode.js +++ b/src/nodes/core/VaryingNode.js @@ -36,7 +36,7 @@ class VaryingNode extends Node { * * @type {Node} */ - this.node = node; + this.node = subBuild( node, 'VERTEX' ); /** * The name of the varying in the shader. If no name is defined, From 8485acc4154581a3773aab9b4d8956ece8f3c473 Mon Sep 17 00:00:00 2001 From: Match <132382032+gayanMatch@users.noreply.github.com> Date: Fri, 9 Jan 2026 02:58:51 -0800 Subject: [PATCH 2/2] SpriteSheetUVNode: Transform to TSL function and fix `countNode` access. (#32693) --- src/nodes/Nodes.js | 1 - src/nodes/TSL.js | 2 +- src/nodes/utils/SpriteSheetUV.js | 35 +++++++++++ src/nodes/utils/SpriteSheetUVNode.js | 90 ---------------------------- 4 files changed, 36 insertions(+), 92 deletions(-) create mode 100644 src/nodes/utils/SpriteSheetUV.js delete mode 100644 src/nodes/utils/SpriteSheetUVNode.js diff --git a/src/nodes/Nodes.js b/src/nodes/Nodes.js index f014c97882eb72..0ec2cdbcb6d317 100644 --- a/src/nodes/Nodes.js +++ b/src/nodes/Nodes.js @@ -49,7 +49,6 @@ export { default as RemapNode } from './utils/RemapNode.js'; export { default as RotateNode } from './utils/RotateNode.js'; export { default as SetNode } from './utils/SetNode.js'; export { default as SplitNode } from './utils/SplitNode.js'; -export { default as SpriteSheetUVNode } from './utils/SpriteSheetUVNode.js'; export { default as StorageArrayElementNode } from './utils/StorageArrayElementNode.js'; export { default as ReflectorNode } from './utils/ReflectorNode.js'; export { default as RTTNode } from './utils/RTTNode.js'; diff --git a/src/nodes/TSL.js b/src/nodes/TSL.js index c4214052e022c9..ddb896c938295e 100644 --- a/src/nodes/TSL.js +++ b/src/nodes/TSL.js @@ -40,7 +40,7 @@ export * from './utils/UVUtils.js'; export * from './utils/SpriteUtils.js'; export * from './utils/ViewportUtils.js'; export * from './utils/RotateNode.js'; -export * from './utils/SpriteSheetUVNode.js'; +export * from './utils/SpriteSheetUV.js'; export * from './utils/Timer.js'; export * from './utils/TriplanarTextures.js'; export * from './utils/ReflectorNode.js'; diff --git a/src/nodes/utils/SpriteSheetUV.js b/src/nodes/utils/SpriteSheetUV.js new file mode 100644 index 00000000000000..82a978e0f56a9f --- /dev/null +++ b/src/nodes/utils/SpriteSheetUV.js @@ -0,0 +1,35 @@ +import { uv } from '../accessors/UV.js'; +import { Fn, float, vec2 } from '../tsl/TSLBase.js'; + +/** + * TSL function for computing texture coordinates for animated sprite sheets. + * + * ```js + * const uvNode = spritesheetUV( vec2( 6, 6 ), uv(), time.mul( animationSpeed ) ); + * + * material.colorNode = texture( spriteSheet, uvNode ); + * ``` + * + * @tsl + * @function + * @param {Node} countNode - The node that defines the number of sprites in the x and y direction (e.g 6x6). + * @param {?Node} [uvNode=uv()] - The uv node. + * @param {?Node} [frameNode=float(0)] - The node that defines the current frame/sprite. + * @returns {Node} + */ +export const spritesheetUV = /*@__PURE__*/ Fn( ( [ countNode, uvNode = uv(), frameNode = float( 0 ) ] ) => { + + const width = countNode.x; + const height = countNode.y; + + const frameNum = frameNode.mod( width.mul( height ) ).floor(); + + const column = frameNum.mod( width ); + const row = height.sub( frameNum.add( 1 ).div( width ).ceil() ); + + const scale = countNode.reciprocal(); + const uvFrameOffset = vec2( column, row ); + + return uvNode.add( uvFrameOffset ).mul( scale ); + +} ); diff --git a/src/nodes/utils/SpriteSheetUVNode.js b/src/nodes/utils/SpriteSheetUVNode.js deleted file mode 100644 index 592fa420811030..00000000000000 --- a/src/nodes/utils/SpriteSheetUVNode.js +++ /dev/null @@ -1,90 +0,0 @@ -import Node from '../core/Node.js'; -import { uv } from '../accessors/UV.js'; -import { nodeProxy, float, vec2 } from '../tsl/TSLBase.js'; - -/** - * Can be used to compute texture coordinates for animated sprite sheets. - * - * ```js - * const uvNode = spritesheetUV( vec2( 6, 6 ), uv(), time.mul( animationSpeed ) ); - * - * material.colorNode = texture( spriteSheet, uvNode ); - * ``` - * - * @augments Node - */ -class SpriteSheetUVNode extends Node { - - static get type() { - - return 'SpriteSheetUVNode'; - - } - - /** - * Constructs a new sprite sheet uv node. - * - * @param {Node} countNode - The node that defines the number of sprites in the x and y direction (e.g 6x6). - * @param {Node} [uvNode=uv()] - The uv node. - * @param {Node} [frameNode=float()] - The node that defines the current frame/sprite. - */ - constructor( countNode, uvNode = uv(), frameNode = float( 0 ) ) { - - super( 'vec2' ); - - /** - * The node that defines the number of sprites in the x and y direction (e.g 6x6). - * - * @type {Node} - */ - this.countNode = countNode; - - /** - * The uv node. - * - * @type {Node} - */ - this.uvNode = uvNode; - - /** - * The node that defines the current frame/sprite. - * - * @type {Node} - */ - this.frameNode = frameNode; - - } - - setup() { - - const { frameNode, uvNode, countNode } = this; - - const { width, height } = countNode; - - const frameNum = frameNode.mod( width.mul( height ) ).floor(); - - const column = frameNum.mod( width ); - const row = height.sub( frameNum.add( 1 ).div( width ).ceil() ); - - const scale = countNode.reciprocal(); - const uvFrameOffset = vec2( column, row ); - - return uvNode.add( uvFrameOffset ).mul( scale ); - - } - -} - -export default SpriteSheetUVNode; - -/** - * TSL function for creating a sprite sheet uv node. - * - * @tsl - * @function - * @param {Node} countNode - The node that defines the number of sprites in the x and y direction (e.g 6x6). - * @param {?Node} [uvNode=uv()] - The uv node. - * @param {?Node} [frameNode=float()] - The node that defines the current frame/sprite. - * @returns {SpriteSheetUVNode} - */ -export const spritesheetUV = /*@__PURE__*/ nodeProxy( SpriteSheetUVNode ).setParameterLength( 3 );