diff --git a/src/nodes/accessors/Bitangent.js b/src/nodes/accessors/Bitangent.js index ff76e5fffd105e..87af35b760ea73 100644 --- a/src/nodes/accessors/Bitangent.js +++ b/src/nodes/accessors/Bitangent.js @@ -3,11 +3,48 @@ import { cameraViewMatrix } from './Camera.js'; import { normalGeometry, normalLocal, normalView, normalWorld, transformedNormalView } from './Normal.js'; import { tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView } from './Tangent.js'; +/** @module Bitangent **/ + const getBitangent = ( crossNormalTangent ) => crossNormalTangent.mul( tangentGeometry.w ).xyz; +/** + * TSL object that represents the bitangent attribute of the current rendered object. + * + * @type {Node} + */ export const bitangentGeometry = /*@__PURE__*/ varying( getBitangent( normalGeometry.cross( tangentGeometry ) ), 'v_bitangentGeometry' ).normalize().toVar( 'bitangentGeometry' ); + +/** + * TSL object that represents the vertex bitangent in local space of the current rendered object. + * + * @type {Node} + */ export const bitangentLocal = /*@__PURE__*/ varying( getBitangent( normalLocal.cross( tangentLocal ) ), 'v_bitangentLocal' ).normalize().toVar( 'bitangentLocal' ); + +/** + * TSL object that represents the vertex bitangent in view space of the current rendered object. + * + * @type {Node} + */ export const bitangentView = /*@__PURE__*/ varying( getBitangent( normalView.cross( tangentView ) ), 'v_bitangentView' ).normalize().toVar( 'bitangentView' ); + +/** + * TSL object that represents the vertex bitangent in world space of the current rendered object. + * + * @type {Node} + */ export const bitangentWorld = /*@__PURE__*/ varying( getBitangent( normalWorld.cross( tangentWorld ) ), 'v_bitangentWorld' ).normalize().toVar( 'bitangentWorld' ); + +/** + * TSL object that represents the transformed vertex bitangent in view space of the current rendered object. + * + * @type {Node} + */ export const transformedBitangentView = /*@__PURE__*/ getBitangent( transformedNormalView.cross( transformedTangentView ) ).normalize().toVar( 'transformedBitangentView' ); + +/** + * TSL object that represents the transformed vertex bitangent in world space of the current rendered object. + * + * @type {Node} + */ export const transformedBitangentWorld = /*@__PURE__*/ transformedBitangentView.transformDirection( cameraViewMatrix ).normalize().toVar( 'transformedBitangentWorld' ); diff --git a/src/nodes/accessors/CubeTextureNode.js b/src/nodes/accessors/CubeTextureNode.js index a376268976cda0..18cedc7c0233d6 100644 --- a/src/nodes/accessors/CubeTextureNode.js +++ b/src/nodes/accessors/CubeTextureNode.js @@ -4,6 +4,13 @@ import { nodeProxy, vec3 } from '../tsl/TSLBase.js'; import { CubeReflectionMapping, CubeRefractionMapping, WebGPUCoordinateSystem } from '../../constants.js'; +/** @module CubeTextureNode **/ + +/** + * This type of uniform node represents a cube texture. + * + * @augments module:TextureNode~TextureNode + */ class CubeTextureNode extends TextureNode { static get type() { @@ -12,20 +19,46 @@ class CubeTextureNode extends TextureNode { } + /** + * Constructs a new cube texture node. + * + * @param {CubeTexture} value - The cube texture. + * @param {Node?} [uvNode=null] - The uv node. + * @param {Node?} [levelNode=null] - The level node. + * @param {Node?} [biasNode=null] - The bias node. + */ constructor( value, uvNode = null, levelNode = null, biasNode = null ) { super( value, uvNode, levelNode, biasNode ); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isCubeTextureNode = true; } + /** + * Overwrites the default implementation to return a fixed value `'cubeTexture'`. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The input type. + */ getInputType( /*builder*/ ) { return 'cubeTexture'; } + /** + * Returns a default uvs based on the mapping type of the cube texture. + * + * @return {Node} The default uv attribute. + */ getDefaultUV() { const texture = this.value; @@ -48,8 +81,22 @@ class CubeTextureNode extends TextureNode { } + /** + * Overwritten with an empty implementation since the `updateMatrix` flag is ignored + * for cube textures. The uv transformation matrix is not applied to cube textures. + * + * @param {Boolean} value - The update toggle. + */ setUpdateMatrix( /*updateMatrix*/ ) { } // Ignore .updateMatrix for CubeTextureNode + /** + * Setups the uv node. Depending on the backend as well as the texture type, it might be necessary + * to modify the uv node for correct sampling. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {Node} uvNode - The uv node to setup. + * @return {Node} The updated uv node. + */ setupUV( builder, uvNode ) { const texture = this.value; @@ -66,6 +113,13 @@ class CubeTextureNode extends TextureNode { } + /** + * Generates the uv code snippet. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {Node} cubeUV - The uv node to generate code for. + * @return {String} The generated code snippet. + */ generateUV( builder, cubeUV ) { return cubeUV.build( builder, 'vec3' ); @@ -76,4 +130,14 @@ class CubeTextureNode extends TextureNode { export default CubeTextureNode; +/** + * TSL function for creating a cube texture node. + * + * @function + * @param {CubeTexture} value - The cube texture. + * @param {Node?} [uvNode=null] - The uv node. + * @param {Node?} [levelNode=null] - The level node. + * @param {Node?} [biasNode=null] - The bias node. + * @returns {CubeTextureNode} + */ export const cubeTexture = /*@__PURE__*/ nodeProxy( CubeTextureNode ); diff --git a/src/nodes/accessors/MaterialProperties.js b/src/nodes/accessors/MaterialProperties.js index 117214b7422dff..15951acaf4deb9 100644 --- a/src/nodes/accessors/MaterialProperties.js +++ b/src/nodes/accessors/MaterialProperties.js @@ -1,3 +1,10 @@ import { uniform } from '../core/UniformNode.js'; +/** @module MaterialProperties **/ + +/** + * TSL object that represents the refraction ratio of the material used for rendering the current object. + * + * @type {UniformNode} + */ export const materialRefractionRatio = /*@__PURE__*/ uniform( 0 ).onReference( ( { material } ) => material ).onRenderUpdate( ( { material } ) => material.refractionRatio ); diff --git a/src/nodes/accessors/MaterialReferenceNode.js b/src/nodes/accessors/MaterialReferenceNode.js index c2c0585c692b9e..11fc4218a67700 100644 --- a/src/nodes/accessors/MaterialReferenceNode.js +++ b/src/nodes/accessors/MaterialReferenceNode.js @@ -1,8 +1,19 @@ import ReferenceNode from './ReferenceNode.js'; -//import { renderGroup } from '../core/UniformGroupNode.js'; -//import { NodeUpdateType } from '../core/constants.js'; import { nodeObject } from '../tsl/TSLBase.js'; +/** @module MaterialReferenceNode **/ + +/** + * This node is a special type of reference node which is intended + * for linking material properties with node values. + * ```js + * const opacityNode = materialReference( 'opacity', 'float', material ); + * ``` + * When changing `material.opacity`, the node value of `opacityNode` will + * automatically be updated. + * + * @augments module:ReferenceNode~ReferenceNode + */ class MaterialReferenceNode extends ReferenceNode { static get type() { @@ -11,26 +22,45 @@ class MaterialReferenceNode extends ReferenceNode { } + /** + * Constructs a new material reference node. + * + * @param {String} property - The name of the property the node refers to. + * @param {String} inputType - The uniform type that should be used to represent the property value. + * @param {Material?} [material=null] - The material the property belongs to. When no material is set, + * the node refers to the material of the current rendered object. + */ constructor( property, inputType, material = null ) { super( property, inputType, material ); + /** + * The material the property belongs to. When no material is set, + * the node refers to the material of the current rendered object. + * + * @type {Material?} + * @default null + */ this.material = material; - //this.updateType = NodeUpdateType.RENDER; - + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isMaterialReferenceNode = true; } - /*setNodeType( node ) { - - super.setNodeType( node ); - - this.node.groupNode = renderGroup; - - }*/ - + /** + * Updates the reference based on the given state. The state is only evaluated + * {@link module:MaterialReferenceNode~MaterialReferenceNode#material} is not set. + * + * @param {(NodeFrame|NodeBuilder)} state - The current state. + * @return {Object} The updated reference. + */ updateReference( state ) { this.reference = this.material !== null ? this.material : state.material; @@ -43,4 +73,14 @@ class MaterialReferenceNode extends ReferenceNode { export default MaterialReferenceNode; -export const materialReference = ( name, type, material ) => nodeObject( new MaterialReferenceNode( name, type, material ) ); +/** + * TSL function for creating a material reference node. + * + * @function + * @param {String} name - The name of the property the node refers to. + * @param {String} type - The uniform type that should be used to represent the property value. + * @param {Material?} [material=null] - The material the property belongs to. + * When no material is set, the node refers to the material of the current rendered object. + * @returns {MaterialReferenceNode} + */ +export const materialReference = ( name, type, material = null ) => nodeObject( new MaterialReferenceNode( name, type, material ) ); diff --git a/src/nodes/accessors/Object3DNode.js b/src/nodes/accessors/Object3DNode.js index 97e9f28cdb9fb5..47b1b7fafca679 100644 --- a/src/nodes/accessors/Object3DNode.js +++ b/src/nodes/accessors/Object3DNode.js @@ -2,9 +2,23 @@ import Node from '../core/Node.js'; import { NodeUpdateType } from '../core/constants.js'; import UniformNode from '../core/UniformNode.js'; import { nodeProxy } from '../tsl/TSLBase.js'; - import { Vector3 } from '../../math/Vector3.js'; +/** @module Object3DNode **/ + +/** + * This node can be used to access transformation related metrics of 3D objects. + * Depending on the selected scope, a different metric is represented as a uniform + * in the shader. The following scopes are supported: + * + * - `POSITION`: The object's position in world space. + * - `VIEW_POSITION`: The object's position in view/camera space. + * - `DIRECTION`: The object's direction in world space. + * - `SCALE`: The object's scale in world space. + * - `WORLD_MATRIX`: The object's matrix in world space. + * + * @augments Node + */ class Object3DNode extends Node { static get type() { @@ -13,19 +27,55 @@ class Object3DNode extends Node { } + /** + * Constructs a new object 3D node. + * + * @param {('position'|'viewPosition'|'direction'|'scale'|'worldMatrix')} scope - The node represents a different type of transformation depending on the scope. + * @param {Object3D?} [object3d=null] - The 3D object. + */ constructor( scope, object3d = null ) { super(); + /** + * The node reports a different type of transformation depending on the scope. + * + * @type {('position'|'viewPosition'|'direction'|'scale'|'worldMatrix')} + */ this.scope = scope; + + /** + * The 3D object. + * + * @type {Object3D?} + * @default null + */ this.object3d = object3d; + /** + * Overwritten since this type of node is updated per object. + * + * @type {String} + * @default 'object' + */ this.updateType = NodeUpdateType.OBJECT; + /** + * Holds the value of the node as a uniform. + * + * @private + * @type {UniformNode} + */ this._uniformNode = new UniformNode( null ); } + /** + * Overwritten since the node type is inferred from the scope. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The node type. + */ getNodeType() { const scope = this.scope; @@ -42,6 +92,11 @@ class Object3DNode extends Node { } + /** + * Updates the uniform value depending on the scope. + * + * @param {NodeFrame} frame - The current node frame. + */ update( frame ) { const object = this.object3d; @@ -83,6 +138,13 @@ class Object3DNode extends Node { } + /** + * Generates the code snippet of the uniform node. The node type of the uniform + * node also depends on the selected scope. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The generated code snippet. + */ generate( builder ) { const scope = this.scope; @@ -127,8 +189,47 @@ Object3DNode.DIRECTION = 'direction'; export default Object3DNode; +/** + * TSL function for creating an object 3D node that represents the object's direction in world space. + * + * @function + * @param {Object3D?} [object3d=null] - The 3D object. + * @returns {Object3DNode} + */ export const objectDirection = /*@__PURE__*/ nodeProxy( Object3DNode, Object3DNode.DIRECTION ); + +/** + * TSL function for creating an object 3D node that represents the object's world matrix. + * + * @function + * @param {Object3D?} [object3d=null] - The 3D object. + * @returns {Object3DNode} + */ export const objectWorldMatrix = /*@__PURE__*/ nodeProxy( Object3DNode, Object3DNode.WORLD_MATRIX ); + +/** + * TSL function for creating an object 3D node that represents the object's position in world space. + * + * @function + * @param {Object3D?} [object3d=null] - The 3D object. + * @returns {Object3DNode} + */ export const objectPosition = /*@__PURE__*/ nodeProxy( Object3DNode, Object3DNode.POSITION ); + +/** + * TSL function for creating an object 3D node that represents the object's scale in world space. + * + * @function + * @param {Object3D?} [object3d=null] - The 3D object. + * @returns {Object3DNode} + */ export const objectScale = /*@__PURE__*/ nodeProxy( Object3DNode, Object3DNode.SCALE ); + +/** + * TSL function for creating an object 3D node that represents the object's position in view/camera space. + * + * @function + * @param {Object3D?} [object3d=null] - The 3D object. + * @returns {Object3DNode} + */ export const objectViewPosition = /*@__PURE__*/ nodeProxy( Object3DNode, Object3DNode.VIEW_POSITION ); diff --git a/src/nodes/accessors/ReferenceNode.js b/src/nodes/accessors/ReferenceNode.js index f4c8f105a70922..213c21c8567747 100644 --- a/src/nodes/accessors/ReferenceNode.js +++ b/src/nodes/accessors/ReferenceNode.js @@ -394,7 +394,8 @@ export default ReferenceNode; export const reference = ( name, type, object ) => nodeObject( new ReferenceNode( name, type, object ) ); /** - * TSL function for creating a reference node. + * TSL function for creating a reference node. Use this function if you want need a reference + * to an array-like property that should be represented as a uniform buffer. * * @function * @param {String} name - The name of the property the node refers to. diff --git a/src/nodes/accessors/RendererReferenceNode.js b/src/nodes/accessors/RendererReferenceNode.js index 4ca517efc4b415..c62bfd86dbcd67 100644 --- a/src/nodes/accessors/RendererReferenceNode.js +++ b/src/nodes/accessors/RendererReferenceNode.js @@ -2,6 +2,19 @@ import ReferenceBaseNode from './ReferenceBaseNode.js'; import { nodeObject } from '../tsl/TSLCore.js'; import { renderGroup } from '../core/UniformGroupNode.js'; +/** @module RendererReferenceNode **/ + +/** + * This node is a special type of reference node which is intended + * for linking renderer properties with node values. + * ```js + * const exposureNode = rendererReference( 'toneMappingExposure', 'float', renderer ); + * ``` + * When changing `renderer.toneMappingExposure`, the node value of `exposureNode` will + * automatically be updated. + * + * @augments ReferenceBaseNode + */ class RendererReferenceNode extends ReferenceBaseNode { static get type() { @@ -10,16 +23,38 @@ class RendererReferenceNode extends ReferenceBaseNode { } + /** + * Constructs a new renderer reference node. + * + * @param {String} property - The name of the property the node refers to. + * @param {String} inputType - The uniform type that should be used to represent the property value. + * @param {Renderer?} [renderer=null] - The renderer the property belongs to. When no renderer is set, + * the node refers to the renderer of the current state. + */ constructor( property, inputType, renderer = null ) { super( property, inputType, renderer ); + /** + * The renderer the property belongs to. When no renderer is set, + * the node refers to the renderer of the current state. + * + * @type {Renderer?} + * @default null + */ this.renderer = renderer; this.setGroup( renderGroup ); } + /** + * Updates the reference based on the given state. The state is only evaluated + * {@link module:RendererReferenceNode~RendererReferenceNode#renderer} is not set. + * + * @param {(NodeFrame|NodeBuilder)} state - The current state. + * @return {Object} The updated reference. + */ updateReference( state ) { this.reference = this.renderer !== null ? this.renderer : state.renderer; @@ -32,4 +67,14 @@ class RendererReferenceNode extends ReferenceBaseNode { export default RendererReferenceNode; -export const rendererReference = ( name, type, renderer ) => nodeObject( new RendererReferenceNode( name, type, renderer ) ); +/** + * TSL function for creating a renderer reference node. + * + * @function + * @param {String} name - The name of the property the node refers to. + * @param {String} type - The uniform type that should be used to represent the property value. + * @param {Renderer?} [renderer=null] - The renderer the property belongs to. When no renderer is set, + * the node refers to the renderer of the current state. + * @returns {RendererReferenceNode} + */ +export const rendererReference = ( name, type, renderer = null ) => nodeObject( new RendererReferenceNode( name, type, renderer ) ); diff --git a/src/nodes/accessors/SkinningNode.js b/src/nodes/accessors/SkinningNode.js index 25b33a00953bdf..3ff56902d98987 100644 --- a/src/nodes/accessors/SkinningNode.js +++ b/src/nodes/accessors/SkinningNode.js @@ -10,8 +10,16 @@ import { tangentLocal } from './Tangent.js'; import { uniform } from '../core/UniformNode.js'; import { buffer } from './BufferNode.js'; +/** @module SkinningNode **/ + const _frameId = new WeakMap(); +/** + * This node implements the vertex transformation shader logic which is required + * for skinning/skeletal animation. + * + * @augments Node + */ class SkinningNode extends Node { static get type() { @@ -20,18 +28,52 @@ class SkinningNode extends Node { } + /** + * Constructs a new skinning node. + * + * @param {SkinnedMesh} skinnedMesh - The skinned mesh. + * @param {Boolean} [useReference=false] - Whether to use reference nodes for internal skinned mesh related data or not. + */ constructor( skinnedMesh, useReference = false ) { super( 'void' ); + /** + * The skinned mesh. + * + * @type {SkinnedMesh} + */ this.skinnedMesh = skinnedMesh; + + /** + * Whether to use reference nodes for internal skinned mesh related data or not. + * TODO: Explain the purpose of the property. + * + * @type {Boolean} + */ this.useReference = useReference; + /** + * The update type overwritten sind skinning nodes are updated per object. + * + * @type {String} + */ this.updateType = NodeUpdateType.OBJECT; // + /** + * The skin index attribute. + * + * @type {AttributeNode} + */ this.skinIndexNode = attribute( 'skinIndex', 'uvec4' ); + + /** + * The skin weight attribute. + * + * @type {AttributeNode} + */ this.skinWeightNode = attribute( 'skinWeight', 'vec4' ); let bindMatrixNode, bindMatrixInverseNode, boneMatricesNode; @@ -50,13 +92,45 @@ class SkinningNode extends Node { } + /** + * The bind matrix node. + * + * @type {Node} + */ this.bindMatrixNode = bindMatrixNode; + + /** + * The bind matrix inverse node. + * + * @type {Node} + */ this.bindMatrixInverseNode = bindMatrixInverseNode; + + /** + * The bind martices as a uniform buffer node. + * + * @type {Node} + */ this.boneMatricesNode = boneMatricesNode; + + /** + * The previous bind martices as a uniform buffer node. + * Required for computing motion vectors. + * + * @type {Node?} + * @default null + */ this.previousBoneMatricesNode = null; } + /** + * Transfroms the given vertex position via skinning. + * + * @param {Node} [boneMatrices=this.boneMatricesNode] - The bone matrices + * @param {Node} [position=positionLocal] - The vertex position in local space. + * @return {Node} The transformed vertex position. + */ getSkinnedPosition( boneMatrices = this.boneMatricesNode, position = positionLocal ) { const { skinIndexNode, skinWeightNode, bindMatrixNode, bindMatrixInverseNode } = this; @@ -81,6 +155,13 @@ class SkinningNode extends Node { } + /** + * Transfroms the given vertex normal via skinning. + * + * @param {Node} [boneMatrices=this.boneMatricesNode] - The bone matrices + * @param {Node} [normal=normalLocal] - The vertex normal in local space. + * @return {Node} The transformed vertex normal. + */ getSkinnedNormal( boneMatrices = this.boneMatricesNode, normal = normalLocal ) { const { skinIndexNode, skinWeightNode, bindMatrixNode, bindMatrixInverseNode } = this; @@ -105,6 +186,12 @@ class SkinningNode extends Node { } + /** + * Transfroms the given vertex normal via skinning. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {Node} The skinned position from the previous frame. + */ getPreviousSkinnedPosition( builder ) { const skinnedMesh = builder.object; @@ -121,6 +208,12 @@ class SkinningNode extends Node { } + /** + * Returns `true` if bone matrices from the previous frame are required. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {Boolean} Whether bone matrices from the previous frame are required or not. + */ needsPreviousBoneMatrices( builder ) { const mrt = builder.renderer.getMRT(); @@ -129,6 +222,11 @@ class SkinningNode extends Node { } + /** + * Setups texture node by assigning the transformed vertex data to predefined node variables. + * + * @param {NodeBuilder} builder - The current node builder. + */ setup( builder ) { if ( this.needsPreviousBoneMatrices( builder ) ) { @@ -158,6 +256,13 @@ class SkinningNode extends Node { } + /** + * Generates the code snippet of the skinning node. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {String} output - The current output. + * @return {String} The generated code snippet. + */ generate( builder, output ) { if ( output !== 'void' ) { @@ -168,6 +273,11 @@ class SkinningNode extends Node { } + /** + * Updates the state of the skinned mesh by updating the skeleton once per frame. + * + * @param {NodeFrame} frame - The current node frame. + */ update( frame ) { const object = this.useReference ? frame.object : this.skinnedMesh; @@ -187,5 +297,20 @@ class SkinningNode extends Node { export default SkinningNode; +/** + * TSL function for creating a skinning node. + * + * @function + * @param {SkinnedMesh} skinnedMesh - The skinned mesh. + * @returns {SkinningNode} + */ export const skinning = ( skinnedMesh ) => nodeObject( new SkinningNode( skinnedMesh ) ); + +/** + * TSL function for creating a skinning node with reference usage. + * + * @function + * @param {SkinnedMesh} skinnedMesh - The skinned mesh. + * @returns {SkinningNode} + */ export const skinningReference = ( skinnedMesh ) => nodeObject( new SkinningNode( skinnedMesh, true ) ); diff --git a/src/nodes/accessors/StorageTextureNode.js b/src/nodes/accessors/StorageTextureNode.js index db7063b1618a67..c87c5d28344a6b 100644 --- a/src/nodes/accessors/StorageTextureNode.js +++ b/src/nodes/accessors/StorageTextureNode.js @@ -2,6 +2,39 @@ import TextureNode from './TextureNode.js'; import { nodeProxy } from '../tsl/TSLBase.js'; import { NodeAccess } from '../core/constants.js'; +/** @module StorageTextureNode **/ + +/** + * This special version of a texture node can be used to + * write data into a storage texture with a compute shader. + * + * ```js + * const storageTexture = new THREE.StorageTexture( width, height ); + * + * const computeTexture = Fn( ( { storageTexture } ) => { + * + * const posX = instanceIndex.modInt( width ); + * const posY = instanceIndex.div( width ); + * const indexUV = uvec2( posX, posY ); + * + * // generate RGB values + * + * const r = 1; + * const g = 1; + * const b = 1; + * + * textureStore( storageTexture, indexUV, vec4( r, g, b, 1 ) ).toWriteOnly(); + * + * } ); + * + * const computeNode = computeTexture( { storageTexture } ).compute( width * height ); + * renderer.computeAsync( computeNode ); + * ``` + * + * This node can only be used with a WebGPU backend. + * + * @augments module:TextureNode~TextureNode + */ class StorageTextureNode extends TextureNode { static get type() { @@ -10,18 +43,50 @@ class StorageTextureNode extends TextureNode { } + /** + * Constructs a new storage texture node. + * + * @param {StorageTexture} value - The storage texture. + * @param {Node} uvNode - The uv node. + * @param {Node?} [storeNode=null] - The value node that should be stored in the texture. + */ constructor( value, uvNode, storeNode = null ) { super( value, uvNode ); + /** + * The value node that should be stored in the texture. + * + * @type {Node?} + * @default null + */ this.storeNode = storeNode; + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isStorageTextureNode = true; + /** + * The acces type of the texture node. + * + * @type {String} + * @default 'writeOnly' + */ this.access = NodeAccess.WRITE_ONLY; } + /** + * Overwrites the default implementation to return a fixed value `'storageTexture'`. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The input type. + */ getInputType( /*builder*/ ) { return 'storageTexture'; @@ -37,6 +102,12 @@ class StorageTextureNode extends TextureNode { } + /** + * Defines the node access. + * + * @param {String} value - The node access. + * @return {StorageTextureNode} A reference to this node. + */ setAccess( value ) { this.access = value; @@ -44,6 +115,14 @@ class StorageTextureNode extends TextureNode { } + /** + * Generates the code snippet of the stroge node. If no `storeNode` + * is defined, the texture node is generated as normal texture. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {String} output - The current output. + * @return {String} The generated code snippet. + */ generate( builder, output ) { let snippet; @@ -62,24 +141,44 @@ class StorageTextureNode extends TextureNode { } + /** + * Convenience method for configuring a read/write node access. + * + * @return {StorageTextureNode} A reference to this node. + */ toReadWrite() { return this.setAccess( NodeAccess.READ_WRITE ); } + /** + * Convenience method for configuring a read-only node access. + * + * @return {StorageTextureNode} A reference to this node. + */ toReadOnly() { return this.setAccess( NodeAccess.READ_ONLY ); } + /** + * Convenience method for configuring a write-only node access. + * + * @return {StorageTextureNode} A reference to this node. + */ toWriteOnly() { return this.setAccess( NodeAccess.WRITE_ONLY ); } + /** + * Generates the code snippet of the storage texture node. + * + * @param {NodeBuilder} builder - The current node builder. + */ generateStore( builder ) { const properties = builder.getNodeProperties( this ); @@ -100,8 +199,27 @@ class StorageTextureNode extends TextureNode { export default StorageTextureNode; +/** + * TSL function for creating a storage texture node. + * + * @function + * @param {StorageTexture} value - The storage texture. + * @param {Node} uvNode - The uv node. + * @param {Node?} [storeNode=null] - The value node that should be stored in the texture. + * @returns {StorageTextureNode} + */ export const storageTexture = /*@__PURE__*/ nodeProxy( StorageTextureNode ); + +/** + * TODO: Explain differnece to `storageTexture()`. + * + * @function + * @param {StorageTexture} value - The storage texture. + * @param {Node} uvNode - The uv node. + * @param {Node?} [storeNode=null] - The value node that should be stored in the texture. + * @returns {StorageTextureNode} + */ export const textureStore = ( value, uvNode, storeNode ) => { const node = storageTexture( value, uvNode, storeNode ); diff --git a/src/nodes/accessors/Texture3DNode.js b/src/nodes/accessors/Texture3DNode.js index af92c679e2547c..e1f11a326e97d5 100644 --- a/src/nodes/accessors/Texture3DNode.js +++ b/src/nodes/accessors/Texture3DNode.js @@ -1,6 +1,8 @@ import TextureNode from './TextureNode.js'; import { nodeProxy, vec3, Fn, If } from '../tsl/TSLBase.js'; +/** @module Texture3DNode **/ + const normal = Fn( ( { texture, uv } ) => { const epsilon = 0.0001; @@ -47,7 +49,11 @@ const normal = Fn( ( { texture, uv } ) => { } ); - +/** + * This type of uniform node represents a 3D texture. + * + * @augments module:TextureNode~TextureNode + */ class Texture3DNode extends TextureNode { static get type() { @@ -56,40 +62,92 @@ class Texture3DNode extends TextureNode { } + /** + * Constructs a new 3D texture node. + * + * @param {Data3DTexture} value - The 3D texture. + * @param {Node?} [uvNode=null] - The uv node. + * @param {Node?} [levelNode=null] - The level node. + */ constructor( value, uvNode = null, levelNode = null ) { super( value, uvNode, levelNode ); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isTexture3DNode = true; } + /** + * Overwrites the default implementation to return a fixed value `'texture3D'`. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The input type. + */ getInputType( /*builder*/ ) { return 'texture3D'; } + /** + * Returns a default uv node which is in context of 3D textures a three-dimensional + * uv node. + * + * @return {Node} The default uv node. + */ getDefaultUV() { return vec3( 0.5, 0.5, 0.5 ); } + /** + * Overwritten with an empty implementation since the `updateMatrix` flag is ignored + * for 3D textures. The uv transformation matrix is not applied to 3D textures. + * + * @param {Boolean} value - The update toggle. + */ setUpdateMatrix( /*updateMatrix*/ ) { } // Ignore .updateMatrix for 3d TextureNode + /** + * Overwrites the default implementation to return the unmodified uv node. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {Node} uvNode - The uv node to setup. + * @return {Node} The unmodified uv node. + */ setupUV( builder, uvNode ) { return uvNode; } + /** + * Generates the uv code snippet. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {Node} uvNode - The uv node to generate code for. + * @return {String} The generated code snippet. + */ generateUV( builder, uvNode ) { return uvNode.build( builder, 'vec3' ); } + /** + * TODO. + * + * @param {Node} uvNode - The uv node . + * @return {Node} TODO. + */ normal( uvNode ) { return normal( { texture: this, uv: uvNode } ); @@ -100,4 +158,13 @@ class Texture3DNode extends TextureNode { export default Texture3DNode; +/** + * TSL function for creating a 3D texture node. + * + * @function + * @param {Data3DTexture} value - The 3D texture. + * @param {Node?} [uvNode=null] - The uv node. + * @param {Node?} [levelNode=null] - The level node. + * @returns {Texture3DNode} + */ export const texture3D = /*@__PURE__*/ nodeProxy( Texture3DNode ); diff --git a/src/nodes/accessors/TextureBicubic.js b/src/nodes/accessors/TextureBicubic.js index 8f8f0523de183b..09b56fa1e76ade 100644 --- a/src/nodes/accessors/TextureBicubic.js +++ b/src/nodes/accessors/TextureBicubic.js @@ -2,6 +2,8 @@ import { add, mul, div } from '../math/OperatorNode.js'; import { floor, ceil, fract, pow } from '../math/MathNode.js'; import { Fn, float, vec2, vec4, int } from '../tsl/TSLBase.js'; +/** @module TextureBicubic **/ + // Mipped Bicubic Texture Filtering by N8 // https://www.shadertoy.com/view/Dl2SDW @@ -51,6 +53,14 @@ const bicubic = ( textureNode, texelSize, lod ) => { }; +/** + * Applies mipped bicubic texture filtering to the given texture node. + * + * @method + * @param {TextureNode} textureNode - The texture node that should be filtered. + * @param {Node} [lodNode=float(3)] - Defines the LOD to sample from. + * @return {Node} The filtered texture sample. + */ export const textureBicubic = /*@__PURE__*/ Fn( ( [ textureNode, lodNode = float( 3 ) ] ) => { const fLodSize = vec2( textureNode.size( int( lodNode ) ) ); diff --git a/src/nodes/accessors/TextureNode.js b/src/nodes/accessors/TextureNode.js index a4f118282314b8..190726980db0be 100644 --- a/src/nodes/accessors/TextureNode.js +++ b/src/nodes/accessors/TextureNode.js @@ -9,6 +9,13 @@ import { NodeUpdateType } from '../core/constants.js'; import { IntType, UnsignedIntType } from '../../constants.js'; +/** @module TextureNode **/ + +/** + * This type of uniform node represents a 2D texture. + * + * @augments module:UniformNode~UniformNode + */ class TextureNode extends UniformNode { static get type() { @@ -17,26 +24,125 @@ class TextureNode extends UniformNode { } + /** + * Constructs a new texture node. + * + * @param {Texture} value - The texture. + * @param {Node?} [uvNode=null] - The uv node. + * @param {Node?} [levelNode=null] - The level node. + * @param {Node?} [biasNode=null] - The bias node. + */ constructor( value, uvNode = null, levelNode = null, biasNode = null ) { super( value ); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isTextureNode = true; + /** + * Represents the texture coordinates. + * + * @type {Node?} + * @default null + */ this.uvNode = uvNode; + + /** + * Represents the mip level that should be selected. + * + * @type {Node?} + * @default null + */ this.levelNode = levelNode; + + /** + * Represents the bias to be applied during level-of-detail computation. + * + * @type {Node?} + * @default null + */ this.biasNode = biasNode; + + /** + * Represents a reference value a texture sample is compared to. + * + * @type {Node?} + * @default null + */ this.compareNode = null; + + /** + * When using texture arrays, the depth node defines the layer to select. + * + * @type {Node?} + * @default null + */ this.depthNode = null; + + /** + * When defined, a texture is sampled using explicit gradients. + * + * @type {Array>?} + * @default null + */ this.gradNode = null; + /** + * Whether texture values should be sampled or fetched. + * + * @type {Boolean} + * @default true + */ this.sampler = true; + + /** + * Whether the uv transformation matrix should be + * automatically updated or not. Use `setUpdateMatrix()` + * if you want to change the value of the property. + * + * @type {Boolean} + * @default false + */ this.updateMatrix = false; + + /** + * By default the `update()` method is not executed. `setUpdateMatrix()` + * sets the value to `frame` when the uv transformation matrix should + * automatically be updated. + * + * @type {String} + * @default 'none' + */ this.updateType = NodeUpdateType.NONE; + /** + * The reference node. + * + * @type {Node?} + * @default null + */ this.referenceNode = null; + /** + * The texture value is stored in a private property. + * + * @private + * @type {Texture} + */ this._value = value; + + /** + * The uniform node that represents the uv transformation matrix. + * + * @private + * @type {UniformNode?} + */ this._matrixUniform = null; this.setUpdateMatrix( uvNode === null ); @@ -57,18 +163,35 @@ class TextureNode extends UniformNode { } + /** + * The texture value. + * + * @type {Texture} + */ get value() { return this.referenceNode ? this.referenceNode.value : this._value; } + /** + * Overwritten since the uniform hash is defined by the texture's UUID. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The uniform hash. + */ getUniformHash( /*builder*/ ) { return this.value.uuid; } + /** + * Overwritten since the node type is inferred from the texture type. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The node type. + */ getNodeType( /*builder*/ ) { if ( this.value.isDepthTexture === true ) return 'float'; @@ -87,24 +210,47 @@ class TextureNode extends UniformNode { } + /** + * Overwrites the default implementation to return a fixed value `'texture'`. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The input type. + */ getInputType( /*builder*/ ) { return 'texture'; } + /** + * Returns a default uvs based on the current texture's channel. + * + * @return {AttributeNode} The default uvs. + */ getDefaultUV() { return uv( this.value.channel ); } + /** + * Overwritten to always return the texture reference of the node. + * + * @param {Any} state - This method can be invocated in different contexts so `state` can refer to any object type. + * @return {Texture} The texture reference. + */ updateReference( /*state*/ ) { return this.value; } + /** + * Transforms the given uv node with the texture transformation matrix. + * + * @param {Node} uvNode - The uv node to transfrom. + * @return {Node} The transformed uv node. + */ getTransformedUV( uvNode ) { if ( this._matrixUniform === null ) this._matrixUniform = uniform( this.value.matrix ); @@ -113,6 +259,12 @@ class TextureNode extends UniformNode { } + /** + * Defines whether the uv transformation matrix should automatically be updated or not. + * + * @param {Boolean} value - The update toggle. + * @return {TextureNode} A reference to this node. + */ setUpdateMatrix( value ) { this.updateMatrix = value; @@ -122,6 +274,14 @@ class TextureNode extends UniformNode { } + /** + * Setups the uv node. Depending on the backend as well as texture's image and type, it might be necessary + * to modify the uv node for correct sampling. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {Node} uvNode - The uv node to setup. + * @return {Node} The updated uv node. + */ setupUV( builder, uvNode ) { const texture = this.value; @@ -144,6 +304,11 @@ class TextureNode extends UniformNode { } + /** + * Setups texture node by preparing the internal nodes for code generation. + * + * @param {NodeBuilder} builder - The current node builder. + */ setup( builder ) { const properties = builder.getNodeProperties( this ); @@ -190,12 +355,32 @@ class TextureNode extends UniformNode { } + /** + * Generates the uv code snippet. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {Node} uvNode - The uv node to generate code for. + * @return {String} The generated code snippet. + */ generateUV( builder, uvNode ) { return uvNode.build( builder, this.sampler === true ? 'vec2' : 'ivec2' ); } + /** + * Generates the snippet for the texture sampling. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {String} textureProperty - The texture property. + * @param {String} uvSnippet - The uv snippet. + * @param {String} levelSnippet - The level snippet. + * @param {String} biasSnippet - The bias snippet. + * @param {String} depthSnippet - The depth snippet. + * @param {String} compareSnippet - The compare snippet. + * @param {String} gradSnippet - The grad snippet. + * @return {String} The generated code snippet. + */ generateSnippet( builder, textureProperty, uvSnippet, levelSnippet, biasSnippet, depthSnippet, compareSnippet, gradSnippet ) { const texture = this.value; @@ -232,6 +417,13 @@ class TextureNode extends UniformNode { } + /** + * Generates the code snippet of the texture node. + * + * @param {NodeBuilder} builder - The current node builder. + * @param {String} output - The current output. + * @return {String} The generated code snippet. + */ generate( builder, output ) { const properties = builder.getNodeProperties( this ); @@ -299,6 +491,12 @@ class TextureNode extends UniformNode { } + /** + * Sets the sampler value. + * + * @param {Boolean} value - The sampler value to set. + * @return {TextureNode} A reference to this texture node. + */ setSampler( value ) { this.sampler = value; @@ -307,6 +505,11 @@ class TextureNode extends UniformNode { } + /** + * Returns the sampler value. + * + * @return {Boolean} The sampler value. + */ getSampler() { return this.sampler; @@ -323,6 +526,12 @@ class TextureNode extends UniformNode { } + /** + * Samples the texture with the given uv node. + * + * @param {Node} uvNode - The uv node. + * @return {TextureNode} A texture node representing the texture sample. + */ sample( uvNode ) { const textureNode = this.clone(); @@ -333,6 +542,12 @@ class TextureNode extends UniformNode { } + /** + * Samples a blurred version of the texture by defining an internal bias. + * + * @param {Node} amountNode - How blurred the texture should be. + * @return {TextureNode} A texture node representing the texture sample. + */ blur( amountNode ) { const textureNode = this.clone(); @@ -343,6 +558,12 @@ class TextureNode extends UniformNode { } + /** + * Samples a specific mip of the texture. + * + * @param {Node} levelNode - The mip level to sample. + * @return {TextureNode} A texture node representing the texture sample. + */ level( levelNode ) { const textureNode = this.clone(); @@ -353,12 +574,24 @@ class TextureNode extends UniformNode { } + /** + * Returns the texture size of the requested level. + * + * @param {Node} levelNode - The level to compute the size for. + * @return {TextureSizeNode} The texture size. + */ size( levelNode ) { return textureSize( this, levelNode ); } + /** + * Samples the texture with the given bias. + * + * @param {Node} biasNode - The bias node. + * @return {TextureNode} A texture node representing the texture sample. + */ bias( biasNode ) { const textureNode = this.clone(); @@ -369,6 +602,12 @@ class TextureNode extends UniformNode { } + /** + * Samples the texture by executing a compare operation. + * + * @param {Node} compareNode - The node that defines the compare value. + * @return {TextureNode} A texture node representing the texture sample. + */ compare( compareNode ) { const textureNode = this.clone(); @@ -379,6 +618,13 @@ class TextureNode extends UniformNode { } + /** + * Samples the texture using an explicit gradient. + * + * @param {Node} gradNodeX - The gradX node. + * @param {Node} gradNodeY - The gradY node. + * @return {TextureNode} A texture node representing the texture sample. + */ grad( gradNodeX, gradNodeY ) { const textureNode = this.clone(); @@ -389,6 +635,12 @@ class TextureNode extends UniformNode { } + /** + * Samples the texture by defining a depth node. + * + * @param {Node} depthNode - The depth node. + * @return {TextureNode} A texture node representing the texture sample. + */ depth( depthNode ) { const textureNode = this.clone(); @@ -423,6 +675,9 @@ class TextureNode extends UniformNode { } + /** + * The update is used to implement the update of the uv transformation matrix. + */ update() { const texture = this.value; @@ -438,6 +693,11 @@ class TextureNode extends UniformNode { } + /** + * Clones the texture node. + * + * @return {TextureNode} The cloned texture node. + */ clone() { const newNode = new this.constructor( this.value, this.uvNode, this.levelNode, this.biasNode ); @@ -451,9 +711,37 @@ class TextureNode extends UniformNode { export default TextureNode; +/** + * TSL function for creating a texture node. + * + * @function + * @param {Texture} value - The texture. + * @param {Node?} [uvNode=null] - The uv node. + * @param {Node?} [levelNode=null] - The level node. + * @param {Node?} [biasNode=null] - The bias node. + * @returns {TextureNode} + */ export const texture = /*@__PURE__*/ nodeProxy( TextureNode ); + +/** + * TSL function for creating a texture node that fetches/loads texels without interpolation. + * + * @function + * @param {Texture} value - The texture. + * @param {Node?} [uvNode=null] - The uv node. + * @param {Node?} [levelNode=null] - The level node. + * @param {Node?} [biasNode=null] - The bias node. + * @returns {TextureNode} + */ export const textureLoad = ( ...params ) => texture( ...params ).setSampler( false ); //export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level ); +/** + * Converts a texture or texture node to a sampler. + * + * @function + * @param {TextureNode|Texture} aTexture - The texture or texture node to convert. + * @returns {Node} + */ export const sampler = ( aTexture ) => ( aTexture.isNode === true ? aTexture : texture( aTexture ) ).convert( 'sampler' ); diff --git a/src/nodes/math/MathNode.js b/src/nodes/math/MathNode.js index 7ba3c6a4718fa8..8ea32a1a97e31b 100644 --- a/src/nodes/math/MathNode.js +++ b/src/nodes/math/MathNode.js @@ -2,6 +2,8 @@ import TempNode from '../core/TempNode.js'; import { sub, mul, div } from './OperatorNode.js'; import { addMethodChaining, nodeObject, nodeProxy, float, vec2, vec3, vec4, Fn } from '../tsl/TSLCore.js'; +/** @module MathNode **/ + /** * This node represents a variety of mathematical methods available in shaders. * They are divided into three categories: @@ -264,7 +266,6 @@ class MathNode extends TempNode { MathNode.ALL = 'all'; MathNode.ANY = 'any'; -MathNode.EQUALS = 'equals'; MathNode.RADIANS = 'radians'; MathNode.DEGREES = 'degrees'; @@ -295,11 +296,12 @@ MathNode.ROUND = 'round'; MathNode.RECIPROCAL = 'reciprocal'; MathNode.TRUNC = 'trunc'; MathNode.FWIDTH = 'fwidth'; -MathNode.BITCAST = 'bitcast'; MathNode.TRANSPOSE = 'transpose'; // 2 inputs +MathNode.BITCAST = 'bitcast'; +MathNode.EQUALS = 'equals'; MathNode.ATAN2 = 'atan2'; MathNode.MIN = 'min'; MathNode.MAX = 'max'; @@ -323,72 +325,582 @@ MathNode.FACEFORWARD = 'faceforward'; export default MathNode; +// 1 inputs + +/** + * A small value used to handle floating-point precision errors. + * + * @type {Node} + */ export const EPSILON = /*@__PURE__*/ float( 1e-6 ); + +/** + * Represents infinity. + * + * @type {Node} + */ export const INFINITY = /*@__PURE__*/ float( 1e6 ); + +/** + * Represents PI. + * + * @type {Node} + */ export const PI = /*@__PURE__*/ float( Math.PI ); + +/** + * Represents PI * 2. + * + * @type {Node} + */ export const PI2 = /*@__PURE__*/ float( Math.PI * 2 ); +/** + * Returns `true` if all components of `x` are `true`. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const all = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ALL ); + +/** + * Returns `true` if any components of `x` are `true`. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const any = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ANY ); -export const equals = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EQUALS ); +/** + * Converts a quantity in degrees to radians. + * + * @function + * @param {Node | Number} x - The input in degrees. + * @returns {Node} + */ export const radians = /*@__PURE__*/ nodeProxy( MathNode, MathNode.RADIANS ); + +/** + * Convert a quantity in radians to degrees. + * + * @function + * @param {Node | Number} x - The input in radians. + * @returns {Node} + */ export const degrees = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DEGREES ); + +/** + * Returns the natural exponentiation of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const exp = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EXP ); + +/** + * Returns 2 raised to the power of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const exp2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EXP2 ); + +/** + * Returns the natural logarithm of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const log = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LOG ); + +/** + * Returns the base 2 logarithm of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const log2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LOG2 ); + +/** + * Returns the square root of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const sqrt = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SQRT ); + +/** + * Returns the inverse of the square root of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const inverseSqrt = /*@__PURE__*/ nodeProxy( MathNode, MathNode.INVERSE_SQRT ); + +/** + * Finds the nearest integer less than or equal to the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const floor = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FLOOR ); + +/** + * Finds the nearest integer that is greater than or equal to the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const ceil = /*@__PURE__*/ nodeProxy( MathNode, MathNode.CEIL ); + +/** + * Calculates the unit vector in the same direction as the original vector. + * + * @function + * @param {Node} x - The input vector. + * @returns {Node} + */ export const normalize = /*@__PURE__*/ nodeProxy( MathNode, MathNode.NORMALIZE ); + +/** + * Computes the fractional part of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const fract = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FRACT ); + +/** + * Returns the sine of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const sin = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SIN ); + +/** + * Returns the cosine of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const cos = /*@__PURE__*/ nodeProxy( MathNode, MathNode.COS ); + +/** + * Returns the tangent of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const tan = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TAN ); + +/** + * Returns the arcsine of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const asin = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ASIN ); + +/** + * Returns the arccosine of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const acos = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ACOS ); + +/** + * Returns the arc-tangent of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const atan = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ATAN ); + +/** + * Returns the absolute value of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const abs = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ABS ); + +/** + * Extracts the sign of the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const sign = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SIGN ); + +/** + * Calculates the length of a vector. + * + * @function + * @param {Node} x - The parameter. + * @returns {Node} + */ export const length = /*@__PURE__*/ nodeProxy( MathNode, MathNode.LENGTH ); + +/** + * Negates the value of the parameter (-x). + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const negate = /*@__PURE__*/ nodeProxy( MathNode, MathNode.NEGATE ); + +/** + * Return `1` minus the parameter. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const oneMinus = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ONE_MINUS ); + +/** + * Returns the partial derivative of the parameter with respect to x. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const dFdx = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DFDX ); + +/** + * Returns the partial derivative of the parameter with respect to y. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const dFdy = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DFDY ); + +/** + * Rounds the parameter to the nearest integer. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const round = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ROUND ); + +/** + * Returns the reciprocal of the parameter `(1/x)`. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const reciprocal = /*@__PURE__*/ nodeProxy( MathNode, MathNode.RECIPROCAL ); + +/** + * Truncates the parameter, removing the fractional part. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const trunc = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRUNC ); + +/** + * Returns the sum of the absolute derivatives in x and y. + * + * @function + * @param {Node | Number} x - The parameter. + * @returns {Node} + */ export const fwidth = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FWIDTH ); -export const bitcast = /*@__PURE__*/ nodeProxy( MathNode, MathNode.BITCAST ); + +/** + * Returns the transpose of a matrix. + * + * @function + * @param {Node} x - The parameter. + * @returns {Node} + */ export const transpose = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRANSPOSE ); +// 2 inputs + +/** + * Reinterpret the bit representation of a value in one type as a value in another type. + * + * @function + * @param {Node | Number} x - The parameter. + * @param {String} y - The new type. + * @returns {Node} + */ +export const bitcast = /*@__PURE__*/ nodeProxy( MathNode, MathNode.BITCAST ); + +/** + * Returns `true` if `x` equals `y`. + * + * @function + * @param {Node | Number} x - The first parameter. + * @param {Node | Number} y - The second parameter. + * @returns {Node} + */ +export const equals = /*@__PURE__*/ nodeProxy( MathNode, MathNode.EQUALS ); + +/** + * Returns the arc-tangent of the quotient of its parameters. + * + * @function + * @param {Node | Number} x - The y parameter. + * @param {Node | Number} y - The x parameter. + * @returns {Node} + */ export const atan2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.ATAN2 ); + +/** + * Returns the lesser of two values. + * + * @function + * @param {Node | Number} x - The y parameter. + * @param {Node | Number} y - The x parameter. + * @returns {Node} + */ export const min = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MIN ); + +/** + * Returns the greater of two values. + * + * @function + * @param {Node | Number} x - The y parameter. + * @param {Node | Number} y - The x parameter. + * @returns {Node} + */ export const max = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MAX ); + +/** + * Computes the remainder of dividing the first node by the second one. + * + * @function + * @param {Node | Number} x - The y parameter. + * @param {Node | Number} y - The x parameter. + * @returns {Node} + */ export const mod = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MOD ); + +/** + * Generate a step function by comparing two values. + * + * @function + * @param {Node | Number} x - The y parameter. + * @param {Node | Number} y - The x parameter. + * @returns {Node} + */ export const step = /*@__PURE__*/ nodeProxy( MathNode, MathNode.STEP ); + +/** + * Calculates the reflection direction for an incident vector. + * + * @function + * @param {Node} I - The incident vector. + * @param {Node} N - The normal vector. + * @returns {Node} + */ export const reflect = /*@__PURE__*/ nodeProxy( MathNode, MathNode.REFLECT ); + +/** + * Calculates the distance between two points. + * + * @function + * @param {Node} x - The first point. + * @param {Node} y - The second point. + * @returns {Node} + */ export const distance = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DISTANCE ); + +/** + * Calculates the absolute difference between two values. + * + * @function + * @param {Node | Number} x - The first parameter. + * @param {Node | Number} y - The second parameter. + * @returns {Node} + */ export const difference = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DIFFERENCE ); + +/** + * Calculates the dot product of two vectors. + * + * @function + * @param {Node} x - The first vector. + * @param {Node} y - The second vector. + * @returns {Node} + */ export const dot = /*@__PURE__*/ nodeProxy( MathNode, MathNode.DOT ); + +/** + * Calculates the cross product of two vectors. + * + * @function + * @param {Node} x - The first vector. + * @param {Node} y - The second vector. + * @returns {Node} + */ export const cross = /*@__PURE__*/ nodeProxy( MathNode, MathNode.CROSS ); + +/** + * Return the value of the first parameter raised to the power of the second one. + * + * @function + * @param {Node | Number} x - The first parameter. + * @param {Node | Number} y - The second parameter. + * @returns {Node} + */ export const pow = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW ); + +/** + * Returns the square of the parameter. + * + * @function + * @param {Node | Number} x - The first parameter. + * @returns {Node} + */ export const pow2 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 2 ); + +/** + * Returns the cube of the parameter. + * + * @function + * @param {Node | Number} x - The first parameter. + * @returns {Node} + */ export const pow3 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 3 ); + +/** + * Returns the fourth power of the parameter. + * + * @function + * @param {Node | Number} x - The first parameter. + * @returns {Node} + */ export const pow4 = /*@__PURE__*/ nodeProxy( MathNode, MathNode.POW, 4 ); + +/** + * Transforms the direction of a vector by a matrix and then normalizes the result. + * + * @function + * @param {Node} direction - The direction vector. + * @param {Node} matrix - The transformation matrix. + * @returns {Node} + */ export const transformDirection = /*@__PURE__*/ nodeProxy( MathNode, MathNode.TRANSFORM_DIRECTION ); +/** + * Returns the cube root of a number. + * + * @function + * @param {Node | Number} a - The first parameter. + * @returns {Node} + */ export const cbrt = ( a ) => mul( sign( a ), pow( abs( a ), 1.0 / 3.0 ) ); + +/** + * Calculate the squared length of a vector. + * + * @function + * @param {Node} a - The vector. + * @returns {Node} + */ export const lengthSq = ( a ) => dot( a, a ); + +/** + * Linearly interpolates between two values. + * + * @function + * @param {Node | Number} a - The first parameter. + * @param {Node | Number} b - The second parameter. + * @param {Node | Number} t - The interpolation value. + * @returns {Node} + */ export const mix = /*@__PURE__*/ nodeProxy( MathNode, MathNode.MIX ); + +/** + * Constrains a value to lie between two further values. + * + * @function + * @param {Node | Number} value - The value to constrain. + * @param {Node | Number} [low=0] - The lower bound. + * @param {Node | Number} [high=1] - The upper bound. + * @returns {Node} + */ export const clamp = ( value, low = 0, high = 1 ) => nodeObject( new MathNode( MathNode.CLAMP, nodeObject( value ), nodeObject( low ), nodeObject( high ) ) ); + +/** + * Constrains a value between `0` and `1`. + * + * @function + * @param {Node | Number} value - The value to constrain. + * @returns {Node} + */ export const saturate = ( value ) => clamp( value ); + +/** + * Calculates the refraction direction for an incident vector. + * + * @function + * @param {Node} I - The incident vector. + * @param {Node} N - The normal vector. + * @param {Node} eta - The the ratio of indices of refraction. + * @returns {Node} + */ export const refract = /*@__PURE__*/ nodeProxy( MathNode, MathNode.REFRACT ); + +/** + * Performs a Hermite interpolation between two values. + * + * @function + * @param {Node | Number} low - The value of the lower edge of the Hermite function. + * @param {Node | Number} high - The value of the upper edge of the Hermite function. + * @param {Node | Number} x - The source value for interpolation. + * @returns {Node} + */ export const smoothstep = /*@__PURE__*/ nodeProxy( MathNode, MathNode.SMOOTHSTEP ); + +/** + * Returns a vector pointing in the same direction as another. + * + * @function + * @param {Node} N - The vector to orient. + * @param {Node} I - The incident vector. + * @param {Node} Nref - The reference vector. + * @returns {Node} + */ export const faceForward = /*@__PURE__*/ nodeProxy( MathNode, MathNode.FACEFORWARD ); +/** + * Returns a random value for the given uv. + * + * @function + * @param {Node} uv - The uv node. + * @returns {Node} + */ export const rand = /*@__PURE__*/ Fn( ( [ uv ] ) => { const a = 12.9898, b = 78.233, c = 43758.5453; @@ -398,7 +910,26 @@ export const rand = /*@__PURE__*/ Fn( ( [ uv ] ) => { } ); +/** + * Alias for `mix()` with a different parameter order. + * + * @function + * @param {Node | Number} t - The interpolation value. + * @param {Node | Number} e1 - The first parameter. + * @param {Node | Number} e2 - The second parameter. + * @returns {Node} + */ export const mixElement = ( t, e1, e2 ) => mix( e1, e2, t ); + +/** + * Alias for `smoothstep()` with a different parameter order. + * + * @function + * @param {Node | Number} x - The source value for interpolation. + * @param {Node | Number} low - The value of the lower edge of the Hermite function. + * @param {Node | Number} high - The value of the upper edge of the Hermite function. + * @returns {Node} + */ export const smoothstepElement = ( x, low, high ) => smoothstep( low, high, x ); addMethodChaining( 'all', all );