Преглед на файлове

TSL: Fix `bitcast` type resolver (#31746)

* fix bitcast on WebGPU

* remove comments

* simpler method

* remove extraneous conditional

* allow for possibility of future MathNode operations whose b and ctypes are not necessarily of type node

* fix spacing

* add bitcast node

* add bitcastNode

* use NodeProxyIntent

* remove functions

* add getBitcastMethod simplify bitcastNode generate

* fix spacing

* add to nodes export
Christian Helgeson преди 4 месеца
родител
ревизия
b261c86ba5

+ 3 - 0
src/nodes/Nodes.js

@@ -57,6 +57,9 @@ export { default as MemberNode } from './utils/MemberNode.js';
 export { default as DebugNode } from './utils/DebugNode.js';
 export { default as EventNode } from './utils/EventNode.js';
 
+// math
+export { default as BitcastNode } from './math/BitcastNode.js';
+
 // accessors
 export { default as UniformArrayNode } from './accessors/UniformArrayNode.js';
 export { default as BufferAttributeNode } from './accessors/BufferAttributeNode.js';

+ 1 - 0
src/nodes/TSL.js

@@ -19,6 +19,7 @@ export * from './core/OutputStructNode.js';
 export * from './core/MRTNode.js';
 
 // math
+export * from './math/BitcastNode.js';
 export * from './math/Hash.js';
 export * from './math/MathUtils.js';
 export * from './math/TriNoise3D.js';

+ 88 - 0
src/nodes/math/BitcastNode.js

@@ -0,0 +1,88 @@
+import TempNode from '../core/TempNode.js';
+import { nodeProxyIntent } from '../tsl/TSLCore.js';
+/**
+ * This node represents an operation that reinterprets the bit representation of a value
+ * in one type as a value in another type.
+ *
+ * @augments TempNode
+ */
+class BitcastNode extends TempNode {
+
+	static get type() {
+
+		return 'BitcastNode';
+
+	}
+
+	/**
+	 * Constructs a new bitcast node.
+	 *
+	 * @param {Node} valueNode - The value to convert.
+	 * @param {string} conversionType - The type to convert to.
+	 */
+	constructor( valueNode, conversionType ) {
+
+		super();
+
+		/**
+		 * The data to bitcast to a new type.
+		 *
+		 * @type {Node}
+		 */
+		this.valueNode = valueNode;
+
+		/**
+		 * The type the value will be converted to.
+		 *
+		 * @type {string}
+		 * @default null
+		 */
+		this.conversionType = conversionType;
+
+		/**
+		 * This flag can be used for type testing.
+		 *
+		 * @type {boolean}
+		 * @readonly
+		 * @default true
+		 */
+		this.isBitcastNode = true;
+
+	}
+
+	/**
+	 * The node's type is defined by the conversion type.
+	 *
+	 * @return {string} The node type.
+	 */
+	getNodeType() {
+
+		return this.conversionType;
+
+	}
+
+
+	generate( builder ) {
+
+		const type = this.getNodeType( builder );
+		const inputType = this.valueNode.getNodeType( builder );
+
+		return `${builder.getBitcastMethod( type, inputType )}( ${ this.valueNode.build( builder, inputType ) } )`;
+
+
+	}
+
+}
+
+export default BitcastNode;
+
+/**
+ * Reinterpret the bit representation of a value in one type as a value in another type.
+ *
+ * @tsl
+ * @function
+ * @param {Node | number} x - The parameter.
+ * @param {string} y - The new type.
+ * @returns {Node}
+ */
+export const bitcast = /*@__PURE__*/ nodeProxyIntent( BitcastNode ).setParameterLength( 2 );

+ 0 - 12
src/nodes/math/MathNode.js

@@ -366,7 +366,6 @@ MathNode.INVERSE = 'inverse';
 
 // 2 inputs
 
-MathNode.BITCAST = 'bitcast';
 MathNode.EQUALS = 'equals';
 MathNode.MIN = 'min';
 MathNode.MAX = 'max';
@@ -767,17 +766,6 @@ export const inverse = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.INVERSE
 
 // 2 inputs
 
-/**
- * Reinterpret the bit representation of a value in one type as a value in another type.
- *
- * @tsl
- * @function
- * @param {Node | number} x - The parameter.
- * @param {string} y - The new type.
- * @returns {Node}
- */
-export const bitcast = /*@__PURE__*/ nodeProxyIntent( MathNode, MathNode.BITCAST ).setParameterLength( 2 );
-
 /**
  * Returns `true` if `x` equals `y`.
  *

+ 18 - 1
src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js

@@ -10,7 +10,11 @@ import { DataTexture } from '../../../textures/DataTexture.js';
 
 const glslMethods = {
 	textureDimensions: 'textureSize',
-	equals: 'equal'
+	equals: 'equal',
+	bitcast_float_int: 'floatBitsToInt',
+	bitcast_int_float: 'intBitsToFloat',
+	bitcast_uint_float: 'uintBitsToFloat',
+	bitcast_float_uint: 'floatBitsToUint',
 };
 
 const precisionLib = {
@@ -134,6 +138,19 @@ class GLSLNodeBuilder extends NodeBuilder {
 
 	}
 
+	/**
+	 * Returns the bitcast method name for a given input and outputType.
+	 *
+	 * @param {string} type - The output type to bitcast to.
+	 * @param {string} inputType - The input type of the.
+	 * @return {string} The resolved WGSL bitcast invocation.
+	 */
+	getBitcastMethod( type, inputType ) {
+
+		return glslMethods[ `bitcast_${ inputType }_${ type }` ];
+
+	}
+
 	/**
 	 * Returns the native snippet for a ternary operation.
 	 *

+ 14 - 0
src/renderers/webgpu/nodes/WGSLNodeBuilder.js

@@ -1960,6 +1960,20 @@ ${ flowData.code }
 
 	}
 
+	/**
+	 * Returns the bitcast method name for a given input and outputType.
+	 *
+	 * @param {string} type - The output type to bitcast to.
+	 * @return {string} The resolved WGSL bitcast invocation.
+	 */
+	getBitcastMethod( type ) {
+
+		const dataType = this.getType( type );
+
+		return `bitcast<${ dataType }>`;
+
+	}
+
 	/**
 	 * Returns the native snippet for a ternary operation.
 	 *

粤ICP备19079148号