Skip to content
Open
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
6 changes: 6 additions & 0 deletions src/Three.TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,9 @@ export const output = TSL.output;
export const outputStruct = TSL.outputStruct;
export const overlay = TSL.overlay;
export const overloadingFn = TSL.overloadingFn;
export const packHalf2x16 = TSL.packHalf2x16;
export const packSnorm2x16 = TSL.packSnorm2x16;
export const packUnorm2x16 = TSL.packUnorm2x16;
export const parabola = TSL.parabola;
export const parallaxDirection = TSL.parallaxDirection;
export const parallaxUV = TSL.parallaxUV;
Expand Down Expand Up @@ -583,6 +586,9 @@ export const uniformCubeTexture = TSL.uniformCubeTexture;
export const uniformGroup = TSL.uniformGroup;
export const uniformFlow = TSL.uniformFlow;
export const uniformTexture = TSL.uniformTexture;
export const unpackHalf2x16 = TSL.unpackHalf2x16;
export const unpackSnorm2x16 = TSL.unpackSnorm2x16;
export const unpackUnorm2x16 = TSL.unpackUnorm2x16;
export const unpremultiplyAlpha = TSL.unpremultiplyAlpha;
export const userData = TSL.userData;
export const uv = TSL.uv;
Expand Down
2 changes: 2 additions & 0 deletions src/nodes/TSL.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ export * from './math/BitcastNode.js';
export * from './math/BitcountNode.js';
export * from './math/Hash.js';
export * from './math/MathUtils.js';
export * from './math/PackFloatNode.js';
export * from './math/UnpackFloatNode.js';
export * from './math/TriNoise3D.js';

// utils
Expand Down
98 changes: 98 additions & 0 deletions src/nodes/math/PackFloatNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import TempNode from '../core/TempNode.js';
import { nodeProxyIntent } from '../tsl/TSLCore.js';

/**
* This node represents an operation that packs floating-point values of a vector into an unsigned 32-bit integer
*
* @augments TempNode
*/
class PackFloatNode extends TempNode {

static get type() {

return 'PackFloatNode';

}

/**
*
* @param {'snorm' | 'unorm' | 'float16'} encoding - The numeric encoding that describes how the float values are mapped to the integer range.
* @param {Node} vectorNode - The vector node to be packed
*/
constructor( encoding, vectorNode ) {

super();

/**
* The vector to be packed.
*
* @type {Node}
*/
this.vectorNode = vectorNode;

/**
* The numeric encoding.
*
* @type {string}
*/
this.encoding = encoding;

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

}

getNodeType() {

return 'uint';

}

generate( builder ) {

const inputType = this.vectorNode.getNodeType( builder );
return `${ builder.getFloatPackingMethod( this.encoding ) }(${ this.vectorNode.build( builder, inputType )})`;

}

}

export default PackFloatNode;

/**
* Converts each component of the normalized float to 16-bit integer values. The results are packed into a single unsigned integer.
* round(clamp(c, -1, +1) * 32767.0)
*
* @tsl
* @function
* @param {Node<vec2>} value - The 2-component vector to be packed
* @returns {Node}
*/
export const packSnorm2x16 = /*@__PURE__*/ nodeProxyIntent( PackFloatNode, 'snorm' ).setParameterLength( 1 );

/**
* Converts each component of the normalized float to 16-bit integer values. The results are packed into a single unsigned integer.
* round(clamp(c, 0, +1) * 65535.0)
*
* @tsl
* @function
* @param {Node<vec2>} value - The 2-component vector to be packed
* @returns {Node}
*/
export const packUnorm2x16 = /*@__PURE__*/ nodeProxyIntent( PackFloatNode, 'unorm' ).setParameterLength( 1 );

/**
* Converts each component of the vec2 to 16-bit floating-point values. The results are packed into a single unsigned integer.
*
* @tsl
* @function
* @param {Node<vec2>} value - The 2-component vector to be packed
* @returns {Node}
*/
export const packHalf2x16 = /*@__PURE__*/ nodeProxyIntent( PackFloatNode, 'float16' ).setParameterLength( 1 );
96 changes: 96 additions & 0 deletions src/nodes/math/UnpackFloatNode.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import TempNode from '../core/TempNode.js';
import { nodeProxyIntent } from '../tsl/TSLCore.js';

/**
* This node represents an operation that unpacks values from a 32-bit unsigned integer, reinterpreting the results as a floating-point vector
*
* @augments TempNode
*/
class UnpackFloatNode extends TempNode {

static get type() {

return 'UnpackFloatNode';

}

/**
*
* @param {'snorm' | 'unorm' | 'float16'} encoding - The numeric encoding that describes how the integer values are mapped to the float range
* @param {Node} uintNode - The uint node to be unpacked
*/
constructor( encoding, uintNode ) {

super();

/**
* The unsigned integer to be unpacked.
*
* @type {Node}
*/
this.uintNode = uintNode;

/**
* The numeric encoding.
*
* @type {string}
*/
this.encoding = encoding;

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

}

getNodeType() {

return 'vec2';

}

generate( builder ) {

const inputType = this.uintNode.getNodeType( builder );
return `${ builder.getFloatUnpackingMethod( this.encoding ) }(${ this.uintNode.build( builder, inputType )})`;

}

}

export default UnpackFloatNode;

/**
* Unpacks a 32-bit unsigned integer into two 16-bit values, interpreted as normalized signed integers. Returns a vec2 with both values.
*
* @tsl
* @function
* @param {Node<uint>} value - The unsigned integer to be unpacked
* @returns {Node}
*/
export const unpackSnorm2x16 = /*@__PURE__*/ nodeProxyIntent( UnpackFloatNode, 'snorm' ).setParameterLength( 1 );

/**
* Unpacks a 32-bit unsigned integer into two 16-bit values, interpreted as normalized unsigned integers. Returns a vec2 with both values.
*
* @tsl
* @function
* @param {Node<uint>} value - The unsigned integer to be unpacked
* @returns {Node}
*/
export const unpackUnorm2x16 = /*@__PURE__*/ nodeProxyIntent( UnpackFloatNode, 'unorm' ).setParameterLength( 1 );

/**
* Unpacks a 32-bit unsigned integer into two 16-bit values, interpreted as 16-bit floating-point numbers. Returns a vec2 with both values.
*
* @tsl
* @function
* @param {Node<uint>} value - The unsigned integer to be unpacked
* @returns {Node}
*/
export const unpackHalf2x16 = /*@__PURE__*/ nodeProxyIntent( UnpackFloatNode, 'float16' ).setParameterLength( 1 );
32 changes: 31 additions & 1 deletion src/renderers/webgl-fallback/nodes/GLSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,13 @@ const glslMethods = {
bitcast_uint_float: 'uintBitsToFloat',
bitcast_float_uint: 'floatBitsToUint',
bitcast_uint_int: 'tsl_bitcast_uint_to_int',
bitcast_int_uint: 'tsl_bitcast_int_to_uint'
bitcast_int_uint: 'tsl_bitcast_int_to_uint',
floatpack_snorm_2x16: 'packSnorm2x16',
floatpack_unorm_2x16: 'packUnorm2x16',
floatpack_float16_2x16: 'packHalf2x16',
floatunpack_snorm_2x16: 'unpackSnorm2x16',
floatunpack_unorm_2x16: 'unpackUnorm2x16',
floatunpack_float16_2x16: 'unpackHalf2x16'
};

const precisionLib = {
Expand Down Expand Up @@ -184,6 +190,30 @@ class GLSLNodeBuilder extends NodeBuilder {

}

/**
* Returns the float packing method name for a given numeric encoding.
*
* @param {string} encoding - The numeric encoding that describes how the float values are mapped to the integer range.
* @returns {string} The resolved GLSL float packing method name.
*/
getFloatPackingMethod( encoding ) {

return this.getMethod( `floatpack_${ encoding }_2x16` );

}

/**
* Returns the float unpacking method name for a given numeric encoding.
*
* @param {string} encoding - The numeric encoding that describes how the integer values are mapped to the float range.
* @returns {string} The resolved GLSL float unpacking method name.
*/
getFloatUnpackingMethod( encoding ) {

return this.getMethod( `floatunpack_${ encoding }_2x16` );

}

/**
* Returns the native snippet for a ternary operation.
*
Expand Down
32 changes: 31 additions & 1 deletion src/renderers/webgpu/nodes/WGSLNodeBuilder.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,13 @@ const wgslMethods = {
equals_bvec3: 'tsl_equals_bvec3',
equals_bvec4: 'tsl_equals_bvec4',
inversesqrt: 'inverseSqrt',
bitcast: 'bitcast<f32>'
bitcast: 'bitcast<f32>',
floatpack_snorm_2x16: 'pack2x16snorm',
floatpack_unorm_2x16: 'pack2x16unorm',
floatpack_float16_2x16: 'pack2x16float',
floatunpack_snorm_2x16: 'unpack2x16snorm',
floatunpack_unorm_2x16: 'unpack2x16unorm',
floatunpack_float16_2x16: 'unpack2x16float'
};

//
Expand Down Expand Up @@ -1990,6 +1996,30 @@ ${ flowData.code }

}

/**
* Returns the float packing method name for a given numeric encoding.
*
* @param {string} encoding - The numeric encoding that describes how the float values are mapped to the integer range.
* @returns {string} The resolve WGSL float packing method name.
*/
getFloatPackingMethod( encoding ) {

return this.getMethod( `floatpack_${ encoding }_2x16` );

}

/**
* Returns the float unpacking method name for a given numeric encoding.
*
* @param {string} encoding - The numeric encoding that describes how the integer values are mapped to the float range.
* @returns {string} The resolve WGSL float unpacking method name.
*/
getFloatUnpackingMethod( encoding ) {

return this.getMethod( `floatunpack_${ encoding }_2x16` );

}

/**
* Returns the native snippet for a ternary operation.
*
Expand Down