Browse Source

Updated builds.

Mr.doob 8 tháng trước cách đây
mục cha
commit
7a1f975aca

+ 1 - 1
build/three.cjs

@@ -67148,7 +67148,7 @@ function WebGLShadowMap( renderer, objects, capabilities ) {
 		// Set GL state for depth map.
 		_state.setBlending( NoBlending );
 
-		if ( _state.buffers.depth.getReversed() ) {
+		if ( _state.buffers.depth.getReversed() === true ) {
 
 			_state.buffers.color.setClear( 0, 0, 0, 0 );
 

+ 1 - 1
build/three.module.js

@@ -8474,7 +8474,7 @@ function WebGLShadowMap( renderer, objects, capabilities ) {
 		// Set GL state for depth map.
 		_state.setBlending( NoBlending );
 
-		if ( _state.buffers.depth.getReversed() ) {
+		if ( _state.buffers.depth.getReversed() === true ) {
 
 			_state.buffers.color.setClear( 0, 0, 0, 0 );
 

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
build/three.module.min.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1 - 0
build/three.tsl.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
build/three.tsl.min.js


+ 176 - 23
build/three.webgpu.js

@@ -1939,6 +1939,16 @@ class Node extends EventDispatcher {
 
 			}
 
+			if ( result === '' && output !== null && output !== 'void' && output !== 'OutputType' ) {
+
+				// if no snippet is generated, return a default value
+
+				console.error( `THREE.TSL: Invalid generated code, expected a "${ output }".` );
+
+				result = builder.generateConst( output );
+
+			}
+
 		}
 
 		builder.removeChain( this );
@@ -3528,25 +3538,57 @@ class ShaderCallNodeInternal extends Node {
 				let index = 0;
 
 				inputs = new Proxy( inputs, {
+
 					get: ( target, property, receiver ) => {
 
+						let value;
+
 						if ( target[ property ] === undefined ) {
 
-							return target[ index ++ ];
+							value = target[ index ++ ];
 
 						} else {
 
-							return Reflect.get( target, property, receiver );
+							value = Reflect.get( target, property, receiver );
 
 						}
 
+						return value;
+
 					}
+
 				} );
 
 			}
 
+			const secureNodeBuilder = new Proxy( builder, {
+
+				get: ( target, property, receiver ) => {
+
+					let value;
+
+					if ( Symbol.iterator === property ) {
+
+						value = function* () {
+
+							yield undefined;
+
+						};
+
+					} else {
+
+						value = Reflect.get( target, property, receiver );
+
+					}
+
+					return value;
+
+				}
+
+			} );
+
 			const jsFunc = shaderNode.jsFunc;
-			const outputNode = inputs !== null || jsFunc.length > 1 ? jsFunc( inputs || [], builder ) : jsFunc( builder );
+			const outputNode = inputs !== null || jsFunc.length > 1 ? jsFunc( inputs || [], secureNodeBuilder ) : jsFunc( secureNodeBuilder );
 
 			result = nodeObject( outputNode );
 
@@ -3732,6 +3774,18 @@ const ConvertType = function ( type, cacheMap = null ) {
 
 	return ( ...params ) => {
 
+		for ( const param of params ) {
+
+			if ( param === undefined ) {
+
+				console.error( `THREE.TSL: Invalid parameter for the type "${ type }".` );
+
+				return nodeObject( new ConstNode( 0, type ) );
+
+			}
+
+		}
+
 		if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => {
 
 			const paramType = typeof param;
@@ -3913,7 +3967,7 @@ class FnNode extends Node {
 
 		const type = this.getNodeType( builder );
 
-		console.warn( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' );
+		console.error( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' );
 
 		return builder.generateConst( type );
 
@@ -4780,16 +4834,24 @@ class UniformNode extends InputNode {
  *
  * @tsl
  * @function
- * @param {any} arg1 - The value of this node. Usually a JS primitive or three.js object (vector, matrix, color, texture).
- * @param {string} [arg2] - The node type. If no explicit type is defined, the node tries to derive the type from its value.
+ * @param {any|string} value - The value of this uniform or your type. Usually a JS primitive or three.js object (vector, matrix, color, texture).
+ * @param {string} [type] - The node type. If no explicit type is defined, the node tries to derive the type from its value.
  * @returns {UniformNode}
  */
-const uniform = ( arg1, arg2 ) => {
+const uniform = ( value, type ) => {
+
+	const nodeType = getConstNodeType( type || value );
+
+	if ( nodeType === value ) {
+
+		// if the value is a type but no having a value
 
-	const nodeType = getConstNodeType( arg2 || arg1 );
+		value = getValueFromType( nodeType );
+
+	}
 
 	// @TODO: get ConstNode from .traverse() in the future
-	const value = ( arg1 && arg1.isNode === true ) ? ( arg1.node && arg1.node.value ) || arg1.value : arg1;
+	value = ( value && value.isNode === true ) ? ( value.node && value.node.value ) || value.value : value;
 
 	return nodeObject( new UniformNode( value, nodeType ) );
 
@@ -5055,11 +5117,10 @@ class AssignNode extends TempNode {
 
 		const needsSplitAssign = this.needsSplitAssign( builder );
 
+		const target = targetNode.build( builder );
 		const targetType = targetNode.getNodeType( builder );
 
-		const target = targetNode.build( builder );
 		const source = sourceNode.build( builder, targetType );
-
 		const sourceType = sourceNode.getNodeType( builder );
 
 		const nodeData = builder.getDataFromNode( this );
@@ -7309,10 +7370,12 @@ class ConditionalNode extends Node {
 
 		//
 
+		const isUniformFlow = builder.context.uniformFlow;
+
 		const properties = builder.getNodeProperties( this );
 		properties.condNode = condNode;
-		properties.ifNode = ifNode.context( { nodeBlock: ifNode } );
-		properties.elseNode = elseNode ? elseNode.context( { nodeBlock: elseNode } ) : null;
+		properties.ifNode = isUniformFlow ? ifNode : ifNode.context( { nodeBlock: ifNode } );
+		properties.elseNode = elseNode ? ( isUniformFlow ? elseNode : elseNode.context( { nodeBlock: elseNode } ) ) : null;
 
 	}
 
@@ -7337,6 +7400,20 @@ class ConditionalNode extends Node {
 		nodeData.nodeProperty = nodeProperty;
 
 		const nodeSnippet = condNode.build( builder, 'bool' );
+		const isUniformFlow = builder.context.uniformFlow;
+
+		if ( isUniformFlow && elseNode !== null ) {
+
+			const ifSnippet = ifNode.build( builder, type );
+			const elseSnippet = elseNode.build( builder, type );
+
+			const mathSnippet = builder.getTernary( nodeSnippet, ifSnippet, elseSnippet );
+
+			// TODO: If node property already exists return something else
+
+			return builder.format( mathSnippet, type, output );
+
+		}
 
 		builder.addFlowCode( `\n${ builder.tab }if ( ${ nodeSnippet } ) {\n\n` ).addFlowTab();
 
@@ -7550,6 +7627,16 @@ class ContextNode extends Node {
  */
 const context = /*@__PURE__*/ nodeProxy( ContextNode ).setParameterLength( 1, 2 );
 
+/**
+ * TSL function for defining a uniformFlow context value for a given node.
+ *
+ * @tsl
+ * @function
+ * @param {Node} node - The node whose dependencies should all execute within a uniform control-flow path.
+ * @returns {ContextNode}
+ */
+const uniformFlow = ( node ) => context( node, { uniformFlow: true } );
+
 /**
  * TSL function for defining a name for the context value for a given node.
  *
@@ -7581,6 +7668,7 @@ function label( node, name ) {
 
 addMethodChaining( 'context', context );
 addMethodChaining( 'label', label );
+addMethodChaining( 'uniformFlow', uniformFlow );
 addMethodChaining( 'setName', setName );
 
 /**
@@ -30936,13 +31024,13 @@ class StackNode extends Node {
 
 	getNodeType( builder ) {
 
-		return this.outputNode ? this.outputNode.getNodeType( builder ) : 'void';
+		return this.hasOutput ? this.outputNode.getNodeType( builder ) : 'void';
 
 	}
 
 	getMemberType( builder, name ) {
 
-		return this.outputNode ? this.outputNode.getMemberType( builder, name ) : 'void';
+		return this.hasOutput ? this.outputNode.getMemberType( builder, name ) : 'void';
 
 	}
 
@@ -30954,6 +31042,13 @@ class StackNode extends Node {
 	 */
 	add( node ) {
 
+		if ( node.isNode !== true ) {
+
+			console.error( 'THREE.TSL: Invalid node added to stack.' );
+			return this;
+
+		}
+
 		this.nodes.push( node );
 
 		return this;
@@ -31047,7 +31142,7 @@ class StackNode extends Node {
 
 		} else {
 
-			throw new Error( 'TSL: Invalid parameter length. Case() requires at least two parameters.' );
+			console.error( 'THREE.TSL: Invalid parameter length. Case() requires at least two parameters.' );
 
 		}
 
@@ -31131,6 +31226,12 @@ class StackNode extends Node {
 
 	}
 
+	get hasOutput() {
+
+		return this.outputNode && this.outputNode.isNode;
+
+	}
+
 	build( builder, ...params ) {
 
 		const previousBuildStack = builder.currentStack;
@@ -31181,7 +31282,19 @@ class StackNode extends Node {
 
 		}
 
-		const result = this.outputNode ? this.outputNode.build( builder, ...params ) : super.build( builder, ...params );
+		//
+
+		let result;
+
+		if ( this.hasOutput ) {
+
+			result = this.outputNode.build( builder, ...params );
+
+		} else {
+
+			result = super.build( builder, ...params );
+
+		}
 
 		setCurrentStack( previousStack );
 
@@ -43380,6 +43493,7 @@ var TSL = /*#__PURE__*/Object.freeze({
 	uniform: uniform,
 	uniformArray: uniformArray,
 	uniformCubeTexture: uniformCubeTexture,
+	uniformFlow: uniformFlow,
 	uniformGroup: uniformGroup,
 	uniformTexture: uniformTexture,
 	unpremultiplyAlpha: unpremultiplyAlpha,
@@ -45781,6 +45895,22 @@ class NodeBuilder {
 
 	}
 
+	/**
+	 * Returns the native snippet for a ternary operation. E.g. GLSL would output
+	 * a ternary op as `cond ? x : y` whereas WGSL would output it as `select(y, x, cond)`
+	 *
+	 * @abstract
+	 * @param {string} condSnippet - The condition determining which expression gets resolved.
+	 * @param {string} ifSnippet - The expression to resolve to if the condition is true.
+	 * @param {string} elseSnippet - The expression to resolve to if the condition is false.
+	 * @return {string} The resolved method name.
+	 */
+	getTernary( /* condSnippet, ifSnippet, elseSnippet*/ ) {
+
+		return null;
+
+	}
+
 	/**
 	 * Returns a node for the given hash, see {@link NodeBuilder#setHashNode}.
 	 *
@@ -46097,7 +46227,6 @@ class NodeBuilder {
 
 	}
 
-
 	/**
 	 * Generates the shader string for the given type and value.
 	 *
@@ -47876,11 +48005,6 @@ class NodeBuilder {
 
 	}
 
-	/**
-	 * Prevents the node builder from being used as an iterable in TSL.Fn(), avoiding potential runtime errors.
-	 */
-	*[ Symbol.iterator ]() { }
-
 }
 
 /**
@@ -56502,6 +56626,20 @@ class GLSLNodeBuilder extends NodeBuilder {
 
 	}
 
+	/**
+	 * Returns the native snippet for a ternary operation.
+	 *
+	 * @param {string} condSnippet - The condition determining which expression gets resolved.
+	 * @param {string} ifSnippet - The expression to resolve to if the condition is true.
+	 * @param {string} elseSnippet - The expression to resolve to if the condition is false.
+	 * @return {string} The resolved method name.
+	 */
+	getTernary( condSnippet, ifSnippet, elseSnippet ) {
+
+		return `${condSnippet} ? ${ifSnippet} : ${elseSnippet}`;
+
+	}
+
 	/**
 	 * Returns the output struct name. Not relevant for GLSL.
 	 *
@@ -69029,6 +69167,21 @@ ${ flowData.code }
 
 	}
 
+	/**
+	 * Returns the native snippet for a ternary operation.
+	 *
+	 * @param {string} condSnippet - The condition determining which expression gets resolved.
+	 * @param {string} ifSnippet - The expression to resolve to if the condition is true.
+	 * @param {string} elseSnippet - The expression to resolve to if the condition is false.
+	 * @return {string} The resolved method name.
+	 */
+	getTernary( condSnippet, ifSnippet, elseSnippet ) {
+
+		return `select( ${elseSnippet}, ${ifSnippet}, ${condSnippet} )`;
+
+	}
+
+
 	/**
 	 * Returns the WGSL type of the given node data type.
 	 *

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
build/three.webgpu.min.js


+ 176 - 23
build/three.webgpu.nodes.js

@@ -1939,6 +1939,16 @@ class Node extends EventDispatcher {
 
 			}
 
+			if ( result === '' && output !== null && output !== 'void' && output !== 'OutputType' ) {
+
+				// if no snippet is generated, return a default value
+
+				console.error( `THREE.TSL: Invalid generated code, expected a "${ output }".` );
+
+				result = builder.generateConst( output );
+
+			}
+
 		}
 
 		builder.removeChain( this );
@@ -3528,25 +3538,57 @@ class ShaderCallNodeInternal extends Node {
 				let index = 0;
 
 				inputs = new Proxy( inputs, {
+
 					get: ( target, property, receiver ) => {
 
+						let value;
+
 						if ( target[ property ] === undefined ) {
 
-							return target[ index ++ ];
+							value = target[ index ++ ];
 
 						} else {
 
-							return Reflect.get( target, property, receiver );
+							value = Reflect.get( target, property, receiver );
 
 						}
 
+						return value;
+
 					}
+
 				} );
 
 			}
 
+			const secureNodeBuilder = new Proxy( builder, {
+
+				get: ( target, property, receiver ) => {
+
+					let value;
+
+					if ( Symbol.iterator === property ) {
+
+						value = function* () {
+
+							yield undefined;
+
+						};
+
+					} else {
+
+						value = Reflect.get( target, property, receiver );
+
+					}
+
+					return value;
+
+				}
+
+			} );
+
 			const jsFunc = shaderNode.jsFunc;
-			const outputNode = inputs !== null || jsFunc.length > 1 ? jsFunc( inputs || [], builder ) : jsFunc( builder );
+			const outputNode = inputs !== null || jsFunc.length > 1 ? jsFunc( inputs || [], secureNodeBuilder ) : jsFunc( secureNodeBuilder );
 
 			result = nodeObject( outputNode );
 
@@ -3732,6 +3774,18 @@ const ConvertType = function ( type, cacheMap = null ) {
 
 	return ( ...params ) => {
 
+		for ( const param of params ) {
+
+			if ( param === undefined ) {
+
+				console.error( `THREE.TSL: Invalid parameter for the type "${ type }".` );
+
+				return nodeObject( new ConstNode( 0, type ) );
+
+			}
+
+		}
+
 		if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => {
 
 			const paramType = typeof param;
@@ -3913,7 +3967,7 @@ class FnNode extends Node {
 
 		const type = this.getNodeType( builder );
 
-		console.warn( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' );
+		console.error( 'THREE.TSL: "Fn()" was declared but not invoked. Try calling it like "Fn()( ...params )".' );
 
 		return builder.generateConst( type );
 
@@ -4780,16 +4834,24 @@ class UniformNode extends InputNode {
  *
  * @tsl
  * @function
- * @param {any} arg1 - The value of this node. Usually a JS primitive or three.js object (vector, matrix, color, texture).
- * @param {string} [arg2] - The node type. If no explicit type is defined, the node tries to derive the type from its value.
+ * @param {any|string} value - The value of this uniform or your type. Usually a JS primitive or three.js object (vector, matrix, color, texture).
+ * @param {string} [type] - The node type. If no explicit type is defined, the node tries to derive the type from its value.
  * @returns {UniformNode}
  */
-const uniform = ( arg1, arg2 ) => {
+const uniform = ( value, type ) => {
+
+	const nodeType = getConstNodeType( type || value );
+
+	if ( nodeType === value ) {
+
+		// if the value is a type but no having a value
 
-	const nodeType = getConstNodeType( arg2 || arg1 );
+		value = getValueFromType( nodeType );
+
+	}
 
 	// @TODO: get ConstNode from .traverse() in the future
-	const value = ( arg1 && arg1.isNode === true ) ? ( arg1.node && arg1.node.value ) || arg1.value : arg1;
+	value = ( value && value.isNode === true ) ? ( value.node && value.node.value ) || value.value : value;
 
 	return nodeObject( new UniformNode( value, nodeType ) );
 
@@ -5055,11 +5117,10 @@ class AssignNode extends TempNode {
 
 		const needsSplitAssign = this.needsSplitAssign( builder );
 
+		const target = targetNode.build( builder );
 		const targetType = targetNode.getNodeType( builder );
 
-		const target = targetNode.build( builder );
 		const source = sourceNode.build( builder, targetType );
-
 		const sourceType = sourceNode.getNodeType( builder );
 
 		const nodeData = builder.getDataFromNode( this );
@@ -7309,10 +7370,12 @@ class ConditionalNode extends Node {
 
 		//
 
+		const isUniformFlow = builder.context.uniformFlow;
+
 		const properties = builder.getNodeProperties( this );
 		properties.condNode = condNode;
-		properties.ifNode = ifNode.context( { nodeBlock: ifNode } );
-		properties.elseNode = elseNode ? elseNode.context( { nodeBlock: elseNode } ) : null;
+		properties.ifNode = isUniformFlow ? ifNode : ifNode.context( { nodeBlock: ifNode } );
+		properties.elseNode = elseNode ? ( isUniformFlow ? elseNode : elseNode.context( { nodeBlock: elseNode } ) ) : null;
 
 	}
 
@@ -7337,6 +7400,20 @@ class ConditionalNode extends Node {
 		nodeData.nodeProperty = nodeProperty;
 
 		const nodeSnippet = condNode.build( builder, 'bool' );
+		const isUniformFlow = builder.context.uniformFlow;
+
+		if ( isUniformFlow && elseNode !== null ) {
+
+			const ifSnippet = ifNode.build( builder, type );
+			const elseSnippet = elseNode.build( builder, type );
+
+			const mathSnippet = builder.getTernary( nodeSnippet, ifSnippet, elseSnippet );
+
+			// TODO: If node property already exists return something else
+
+			return builder.format( mathSnippet, type, output );
+
+		}
 
 		builder.addFlowCode( `\n${ builder.tab }if ( ${ nodeSnippet } ) {\n\n` ).addFlowTab();
 
@@ -7550,6 +7627,16 @@ class ContextNode extends Node {
  */
 const context = /*@__PURE__*/ nodeProxy( ContextNode ).setParameterLength( 1, 2 );
 
+/**
+ * TSL function for defining a uniformFlow context value for a given node.
+ *
+ * @tsl
+ * @function
+ * @param {Node} node - The node whose dependencies should all execute within a uniform control-flow path.
+ * @returns {ContextNode}
+ */
+const uniformFlow = ( node ) => context( node, { uniformFlow: true } );
+
 /**
  * TSL function for defining a name for the context value for a given node.
  *
@@ -7581,6 +7668,7 @@ function label( node, name ) {
 
 addMethodChaining( 'context', context );
 addMethodChaining( 'label', label );
+addMethodChaining( 'uniformFlow', uniformFlow );
 addMethodChaining( 'setName', setName );
 
 /**
@@ -30936,13 +31024,13 @@ class StackNode extends Node {
 
 	getNodeType( builder ) {
 
-		return this.outputNode ? this.outputNode.getNodeType( builder ) : 'void';
+		return this.hasOutput ? this.outputNode.getNodeType( builder ) : 'void';
 
 	}
 
 	getMemberType( builder, name ) {
 
-		return this.outputNode ? this.outputNode.getMemberType( builder, name ) : 'void';
+		return this.hasOutput ? this.outputNode.getMemberType( builder, name ) : 'void';
 
 	}
 
@@ -30954,6 +31042,13 @@ class StackNode extends Node {
 	 */
 	add( node ) {
 
+		if ( node.isNode !== true ) {
+
+			console.error( 'THREE.TSL: Invalid node added to stack.' );
+			return this;
+
+		}
+
 		this.nodes.push( node );
 
 		return this;
@@ -31047,7 +31142,7 @@ class StackNode extends Node {
 
 		} else {
 
-			throw new Error( 'TSL: Invalid parameter length. Case() requires at least two parameters.' );
+			console.error( 'THREE.TSL: Invalid parameter length. Case() requires at least two parameters.' );
 
 		}
 
@@ -31131,6 +31226,12 @@ class StackNode extends Node {
 
 	}
 
+	get hasOutput() {
+
+		return this.outputNode && this.outputNode.isNode;
+
+	}
+
 	build( builder, ...params ) {
 
 		const previousBuildStack = builder.currentStack;
@@ -31181,7 +31282,19 @@ class StackNode extends Node {
 
 		}
 
-		const result = this.outputNode ? this.outputNode.build( builder, ...params ) : super.build( builder, ...params );
+		//
+
+		let result;
+
+		if ( this.hasOutput ) {
+
+			result = this.outputNode.build( builder, ...params );
+
+		} else {
+
+			result = super.build( builder, ...params );
+
+		}
 
 		setCurrentStack( previousStack );
 
@@ -43380,6 +43493,7 @@ var TSL = /*#__PURE__*/Object.freeze({
 	uniform: uniform,
 	uniformArray: uniformArray,
 	uniformCubeTexture: uniformCubeTexture,
+	uniformFlow: uniformFlow,
 	uniformGroup: uniformGroup,
 	uniformTexture: uniformTexture,
 	unpremultiplyAlpha: unpremultiplyAlpha,
@@ -45781,6 +45895,22 @@ class NodeBuilder {
 
 	}
 
+	/**
+	 * Returns the native snippet for a ternary operation. E.g. GLSL would output
+	 * a ternary op as `cond ? x : y` whereas WGSL would output it as `select(y, x, cond)`
+	 *
+	 * @abstract
+	 * @param {string} condSnippet - The condition determining which expression gets resolved.
+	 * @param {string} ifSnippet - The expression to resolve to if the condition is true.
+	 * @param {string} elseSnippet - The expression to resolve to if the condition is false.
+	 * @return {string} The resolved method name.
+	 */
+	getTernary( /* condSnippet, ifSnippet, elseSnippet*/ ) {
+
+		return null;
+
+	}
+
 	/**
 	 * Returns a node for the given hash, see {@link NodeBuilder#setHashNode}.
 	 *
@@ -46097,7 +46227,6 @@ class NodeBuilder {
 
 	}
 
-
 	/**
 	 * Generates the shader string for the given type and value.
 	 *
@@ -47876,11 +48005,6 @@ class NodeBuilder {
 
 	}
 
-	/**
-	 * Prevents the node builder from being used as an iterable in TSL.Fn(), avoiding potential runtime errors.
-	 */
-	*[ Symbol.iterator ]() { }
-
 }
 
 /**
@@ -56502,6 +56626,20 @@ class GLSLNodeBuilder extends NodeBuilder {
 
 	}
 
+	/**
+	 * Returns the native snippet for a ternary operation.
+	 *
+	 * @param {string} condSnippet - The condition determining which expression gets resolved.
+	 * @param {string} ifSnippet - The expression to resolve to if the condition is true.
+	 * @param {string} elseSnippet - The expression to resolve to if the condition is false.
+	 * @return {string} The resolved method name.
+	 */
+	getTernary( condSnippet, ifSnippet, elseSnippet ) {
+
+		return `${condSnippet} ? ${ifSnippet} : ${elseSnippet}`;
+
+	}
+
 	/**
 	 * Returns the output struct name. Not relevant for GLSL.
 	 *
@@ -69029,6 +69167,21 @@ ${ flowData.code }
 
 	}
 
+	/**
+	 * Returns the native snippet for a ternary operation.
+	 *
+	 * @param {string} condSnippet - The condition determining which expression gets resolved.
+	 * @param {string} ifSnippet - The expression to resolve to if the condition is true.
+	 * @param {string} elseSnippet - The expression to resolve to if the condition is false.
+	 * @return {string} The resolved method name.
+	 */
+	getTernary( condSnippet, ifSnippet, elseSnippet ) {
+
+		return `select( ${elseSnippet}, ${ifSnippet}, ${condSnippet} )`;
+
+	}
+
+
 	/**
 	 * Returns the WGSL type of the given node data type.
 	 *

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 0 - 0
build/three.webgpu.nodes.min.js


Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác

粤ICP备19079148号