From 9ec0b185f9aff6f4dd2669a881a47900d3c3770f Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 13 Dec 2024 15:04:03 +0100 Subject: [PATCH 1/4] Node: Document more modules. --- src/nodes/accessors/BuiltinNode.js | 38 +++ src/nodes/accessors/Lights.js | 45 +++ src/nodes/accessors/MaterialNode.js | 296 +++++++++++++++++- src/nodes/accessors/ModelNode.js | 84 +++++ .../accessors/ModelViewProjectionNode.js | 7 + src/nodes/accessors/MorphNode.js | 49 ++- src/nodes/accessors/ReflectVector.js | 24 ++ 7 files changed, 540 insertions(+), 3 deletions(-) diff --git a/src/nodes/accessors/BuiltinNode.js b/src/nodes/accessors/BuiltinNode.js index 50c88643b09ea0..e694f0a83b6451 100644 --- a/src/nodes/accessors/BuiltinNode.js +++ b/src/nodes/accessors/BuiltinNode.js @@ -1,18 +1,49 @@ import Node from '../core/Node.js'; import { nodeProxy } from '../tsl/TSLBase.js'; +/** @module BuiltinNode **/ + +/** + * The node allows to set values for built-in shader variables. That is + * required for features like hardware-accelerated vertex clipping. + * + * @augments Node + */ class BuiltinNode extends Node { + /** + * Constructs a new builtin node. + * + * @param {String} name - The name of the built-in shader variable. + */ constructor( name ) { super( 'float' ); + /** + * The name of the built-in shader variable. + * + * @type {String} + */ this.name = name; + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isBuiltinNode = true; } + /** + * Generates the code snippet of the builtin node. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {String} The generated code snippet. + */ generate( /* builder */ ) { return this.name; @@ -23,4 +54,11 @@ class BuiltinNode extends Node { export default BuiltinNode; +/** + * TSL function for creating a builtin node. + * + * @function + * @param {String} name - The name of the built-in shader variable. + * @returns {BuiltinNode} + */ export const builtin = nodeProxy( BuiltinNode ); diff --git a/src/nodes/accessors/Lights.js b/src/nodes/accessors/Lights.js index 0cf512d1d4ac2f..f0d0a0e10c8340 100644 --- a/src/nodes/accessors/Lights.js +++ b/src/nodes/accessors/Lights.js @@ -4,6 +4,8 @@ import { Vector3 } from '../../math/Vector3.js'; import { cameraViewMatrix } from './Camera.js'; import { positionWorld } from './Position.js'; +/** @module Lights **/ + let uniformsLib; function getLightData( light ) { @@ -18,6 +20,13 @@ function getLightData( light ) { } +/** + * TSL function for getting a shadow matrix uniform node for the given light. + * + * @function + * @param {Light} light -The light source. + * @returns {UniformNode} The shadow matrix uniform node. + */ export function lightShadowMatrix( light ) { const data = getLightData( light ); @@ -36,6 +45,14 @@ export function lightShadowMatrix( light ) { } +/** + * TSL function for getting projected uv coordinates for the given light. + * Relevant when using maps with spot lights. + * + * @function + * @param {Light} light -The light source. + * @returns {Node} The projected uvs. + */ export function lightProjectionUV( light ) { const data = getLightData( light ); @@ -53,6 +70,13 @@ export function lightProjectionUV( light ) { } +/** + * TSL function for getting the position in world space for the given light. + * + * @function + * @param {Light} light -The light source. + * @returns {UniformNode} The light's position in world space. + */ export function lightPosition( light ) { const data = getLightData( light ); @@ -61,6 +85,13 @@ export function lightPosition( light ) { } +/** + * TSL function for getting the light target position in world space for the given light. + * + * @function + * @param {Light} light -The light source. + * @returns {UniformNode} The light target position in world space. + */ export function lightTargetPosition( light ) { const data = getLightData( light ); @@ -69,6 +100,13 @@ export function lightTargetPosition( light ) { } +/** + * TSL function for getting the position in view space for the given light. + * + * @function + * @param {Light} light -The light source. + * @returns {UniformNode} The light's position in view space. + */ export function lightViewPosition( light ) { const data = getLightData( light ); @@ -84,4 +122,11 @@ export function lightViewPosition( light ) { } +/** + * TSL function for getting the light target direction for the given light. + * + * @function + * @param {Light} light -The light source. + * @returns {Node} The light's target direction. + */ export const lightTargetDirection = ( light ) => cameraViewMatrix.transformDirection( lightPosition( light ).sub( lightTargetPosition( light ) ) ); diff --git a/src/nodes/accessors/MaterialNode.js b/src/nodes/accessors/MaterialNode.js index aa92847247d75b..9390922301e936 100644 --- a/src/nodes/accessors/MaterialNode.js +++ b/src/nodes/accessors/MaterialNode.js @@ -6,11 +6,20 @@ import { nodeImmutable, float, vec2, vec3, mat2 } from '../tsl/TSLBase.js'; import { uniform } from '../core/UniformNode.js'; import { normalMap } from '../display/NormalMapNode.js'; import { bumpMap } from '../display/BumpMapNode.js'; - import { Vector2 } from '../../math/Vector2.js'; +/** @module MaterialNode **/ + const _propertyCache = new Map(); +/** + * This class should simplify the node access to material properties. + * It internal uses reference nodes to make sure changes to material + * properties are automatically reflected to prefdefined TSL objects + * like e.g. `materialColor`. + * + * @augments Node + */ class MaterialNode extends Node { static get type() { @@ -19,14 +28,31 @@ class MaterialNode extends Node { } + /** + * Constructs a new material node. + * + * @param {String} scope - The scope defines what kind of material property is referred by the node. + */ constructor( scope ) { super(); + /** + * The scope defines what material property is referred by the node. + * + * @type {String} + */ this.scope = scope; } + /** + * Returns a cached reference node for the given property and type. + * + * @param {String} property - The name of the material property. + * @param {String} type - The uniform type of the property. + * @return {MaterialReferenceNode} A material reference node representing the property access. + */ getCache( property, type ) { let node = _propertyCache.get( property ); @@ -43,24 +69,49 @@ class MaterialNode extends Node { } + /** + * Returns a float-typed material reference node for the given property name. + * + * @param {String} property - The name of the material property. + * @return {MaterialReferenceNode} A material reference node representing the property access. + */ getFloat( property ) { return this.getCache( property, 'float' ); } + /** + * Returns a color-typed material reference node for the given property name. + * + * @param {String} property - The name of the material property. + * @return {MaterialReferenceNode} A material reference node representing the property access. + */ getColor( property ) { return this.getCache( property, 'color' ); } + /** + * Returns a texture-typed material reference node for the given property name. + * + * @param {String} property - The name of the material property. + * @return {MaterialReferenceNode} A material reference node representing the property access. + */ getTexture( property ) { return this.getCache( property === 'map' ? 'map' : property + 'Map', 'texture' ); } + /** + * The node setup is done depending on the selected scope. Multiple material properties + * might be grouped into a single node composition if they logically belong together. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {Node} The node representing the selected scope. + */ setup( builder ) { const material = builder.context.material; @@ -391,45 +442,288 @@ MaterialNode.AO_MAP = 'ao'; export default MaterialNode; +/** + * TSL object that represents alpha test of the current material. + * + * @type {Node} + */ export const materialAlphaTest = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.ALPHA_TEST ); + +/** + * TSL object that represents the diffuse color of the current material. + * The value is composed via `color` * `map`. + * + * @type {Node} + */ export const materialColor = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.COLOR ); + +/** + * TSL object that represents the shininess of the current material. + * + * @type {Node} + */ export const materialShininess = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.SHININESS ); + +/** + * TSL object that represents the emissive color of the current material. + * The value is composed via `emissive` * `emissiveIntensity` * `emissiveMap`. + * + * @type {Node} + */ export const materialEmissive = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.EMISSIVE ); + +/** + * TSL object that represents the opacity of the current material. + * The value is composed via `opacity` * `alphaMap`. + * + * @type {Node} + */ export const materialOpacity = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.OPACITY ); + +/** + * TSL object that represents the specular of the current material. + * + * @type {Node} + */ export const materialSpecular = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.SPECULAR ); +/** + * TSL object that represents the specular intensity of the current material. + * The value is composed via `specularIntensity` * `specularMap.a`. + * + * @type {Node} + */ export const materialSpecularIntensity = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.SPECULAR_INTENSITY ); + +/** + * TSL object that represents the specular color of the current material. + * The value is composed via `specularColor` * `specularMap.rgb`. + * + * @type {Node} + */ export const materialSpecularColor = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.SPECULAR_COLOR ); +/** + * TSL object that represents the specular strength of the current material. + * The value is composed via `specularMap.r`. + * + * @type {Node} + */ export const materialSpecularStrength = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.SPECULAR_STRENGTH ); + +/** + * TSL object that represents the reflectivity of the current material. + * + * @type {Node} + */ export const materialReflectivity = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.REFLECTIVITY ); + +/** + * TSL object that represents the roughness of the current material. + * The value is composed via `roughness` * `roughnessMap.g` + * + * @type {Node} + */ export const materialRoughness = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.ROUGHNESS ); + +/** + * TSL object that represents the metalness of the current material. + * The value is composed via `metalness` * `metalnessMap.b` + * + * @type {Node} + */ export const materialMetalness = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.METALNESS ); + +/** + * TSL object that represents the normal of the current material. + * The value will be either `normalMap`, `bumpMap` or `normalView`. + * + * @type {Node} + */ export const materialNormal = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.NORMAL ).context( { getUV: null } ); + +/** + * TSL object that represents the clearcoat of the current material. + * The value is composed via `clearcoat` * `clearcoat.r` + * + * @type {Node} + */ export const materialClearcoat = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT ); + +/** + * TSL object that represents the clearcoat roughness of the current material. + * The value is composed via `clearcoatRoughness` * `clearcoatRoughnessMap.r` + * + * @type {Node} + */ export const materialClearcoatRoughness = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT_ROUGHNESS ); + +/** + * TSL object that represents the clearcoat normal of the current material. + * The value will be either `clearcoatNormalMap` or `normalView`. + * + * @type {Node} + */ export const materialClearcoatNormal = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.CLEARCOAT_NORMAL ).context( { getUV: null } ); + +/** + * TSL object that represents the rotation of the current sprite material. + * + * @type {Node} + */ export const materialRotation = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.ROTATION ); + +/** + * TSL object that represents the sheen color of the current material. + * The value is composed via `sheen` * `sheenColor` * `sheenColorMap`. + * + * @type {Node} + */ export const materialSheen = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.SHEEN ); + +/** + * TSL object that represents the sheen roughness of the current material. + * The value is composed via `sheenRoughness` * `sheenRoughnessMap.a` . + * + * @type {Node} + */ export const materialSheenRoughness = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.SHEEN_ROUGHNESS ); + +/** + * TSL object that represents the anisotriopy of the current material. + * + * @type {Node} + */ export const materialAnisotropy = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.ANISOTROPY ); + +/** + * TSL object that represents the iridescence of the current material. + * + * @type {Node} + */ export const materialIridescence = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE ); + +/** + * TSL object that represents the iridescence IOR of the current material. + * + * @type {Node} + */ export const materialIridescenceIOR = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE_IOR ); + +/** + * TSL object that represents the iridescence thickness of the current material. + * + * @type {Node} + */ export const materialIridescenceThickness = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.IRIDESCENCE_THICKNESS ); + +/** + * TSL object that represents the transmission of the current material. + * The value is composed via `transmission` * `transmissionMap.r`. + * + * @type {Node} + */ export const materialTransmission = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.TRANSMISSION ); + +/** + * TSL object that represents the thickness of the current material. + * The value is composed via `thickness` * `thicknessMap.g`. + * + * @type {Node} + */ export const materialThickness = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.THICKNESS ); + +/** + * TSL object that represents the IOR of the current material. + * + * @type {Node} + */ export const materialIOR = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.IOR ); + +/** + * TSL object that represents the attenuation distance of the current material. + * + * @type {Node} + */ export const materialAttenuationDistance = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.ATTENUATION_DISTANCE ); + +/** + * TSL object that represents the attenuation color of the current material. + * + * @type {Node} + */ export const materialAttenuationColor = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.ATTENUATION_COLOR ); + +/** + * TSL object that represents the scale of the current dashed line material. + * + * @type {Node} + */ export const materialLineScale = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.LINE_SCALE ); + +/** + * TSL object that represents the dash size of the current dashed line material. + * + * @type {Node} + */ export const materialLineDashSize = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.LINE_DASH_SIZE ); + +/** + * TSL object that represents the gap size of the current dashed line material. + * + * @type {Node} + */ export const materialLineGapSize = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.LINE_GAP_SIZE ); + +/** + * TSL object that represents the line width of the current line material. + * + * @type {Node} + */ export const materialLineWidth = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.LINE_WIDTH ); + +/** + * TSL object that represents the dash offset of the current line material. + * + * @type {Node} + */ export const materialLineDashOffset = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.LINE_DASH_OFFSET ); + +/** + * TSL object that represents the point width of the current points material. + * + * @type {Node} + */ export const materialPointWidth = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.POINT_WIDTH ); + +/** + * TSL object that represents the dispersion of the current material. + * + * @type {Node} + */ export const materialDispersion = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.DISPERSION ); + +/** + * TSL object that represents the light map of the current material. + * The value is composed via `lightMapIntensity` * `lightMap.rgb`. + * + * @type {Node} + */ export const materialLightMap = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.LIGHT_MAP ); + +/** + * TSL object that represents the ambient occlusion map of the current material. + * The value is composed via `aoMap.r` - 1 * `aoMapIntensity` + 1. + * + * @type {Node} + */ export const materialAOMap = /*@__PURE__*/ nodeImmutable( MaterialNode, MaterialNode.AO_MAP ); + +/** + * TSL object that represents the anisotriopy vector of the current material. + * + * @type {Node} + */ export const materialAnisotropyVector = /*@__PURE__*/ uniform( new Vector2() ).onReference( function ( frame ) { return frame.material; diff --git a/src/nodes/accessors/ModelNode.js b/src/nodes/accessors/ModelNode.js index 1d11feac7abe86..49f1a10d073bf5 100644 --- a/src/nodes/accessors/ModelNode.js +++ b/src/nodes/accessors/ModelNode.js @@ -6,6 +6,16 @@ import { Matrix4 } from '../../math/Matrix4.js'; import { cameraViewMatrix } from './Camera.js'; import { Matrix3 } from '../../math/Matrix3.js'; +/** @module ModelNode **/ + +/** + * This type of node is a specialized version of `Object3DNode` + * with larger set of model related metrics. Unlike `Object3DNode`, + * `ModelNode` extracts the reference to the 3D object from the + * current node frame state. + * + * @augments module:Object3DNode~Object3DNode + */ class ModelNode extends Object3DNode { static get type() { @@ -14,12 +24,23 @@ class ModelNode extends Object3DNode { } + /** + * Constructs a new object model node. + * + * @param {('position'|'viewPosition'|'direction'|'scale'|'worldMatrix')} scope - The node represents a different type of transformation depending on the scope. + */ constructor( scope ) { super( scope ); } + /** + * Extracts the model reference from the frame state and then + * updates the uniform value depending on the scope. + * + * @param {NodeFrame} frame - The current node frame. + */ update( frame ) { this.object3d = frame.object; @@ -32,14 +53,60 @@ class ModelNode extends Object3DNode { export default ModelNode; +/** + * TSL object that represents the object's direction in world space. + * + * @type {ModelNode} + */ export const modelDirection = /*@__PURE__*/ nodeImmutable( ModelNode, ModelNode.DIRECTION ); + +/** + * TSL object that represents the object's world matrix. + * + * @type {ModelNode} + */ export const modelWorldMatrix = /*@__PURE__*/ nodeImmutable( ModelNode, ModelNode.WORLD_MATRIX ); + +/** + * TSL object that represents the object's position in world space. + * + * @type {ModelNode} + */ export const modelPosition = /*@__PURE__*/ nodeImmutable( ModelNode, ModelNode.POSITION ); + +/** + * TSL object that represents the object's scale in world space. + * + * @type {ModelNode} + */ export const modelScale = /*@__PURE__*/ nodeImmutable( ModelNode, ModelNode.SCALE ); + +/** + * TSL object that represents the object's position in view/camera space. + * + * @type {ModelNode} + */ export const modelViewPosition = /*@__PURE__*/ nodeImmutable( ModelNode, ModelNode.VIEW_POSITION ); + +/** + * TSL object that represents the object's normal matrix. + * + * @type {UniformNode} + */ export const modelNormalMatrix = /*@__PURE__*/ uniform( new Matrix3() ).onObjectUpdate( ( { object }, self ) => self.value.getNormalMatrix( object.matrixWorld ) ); + +/** + * TSL object that represents the object's inverse world matrix. + * + * @type {UniformNode} + */ export const modelWorldMatrixInverse = /*@__PURE__*/ uniform( new Matrix4() ).onObjectUpdate( ( { object }, self ) => self.value.copy( object.matrixWorld ).invert() ); +/** + * TSL object that represents the object's model view matrix. + * + * @type {Node} + */ export const modelViewMatrix = /*@__PURE__*/ ( Fn( ( builder ) => { return builder.renderer.nodes.modelViewMatrix || mediumpModelViewMatrix; @@ -48,10 +115,21 @@ export const modelViewMatrix = /*@__PURE__*/ ( Fn( ( builder ) => { // GPU Precision +/** + * TSL object that represents the object's model view in `mediump` precision. + * + * @type {Node} + */ export const mediumpModelViewMatrix = /*@__PURE__*/ cameraViewMatrix.mul( modelWorldMatrix ); // CPU Precision +/** + * TSL object that represents the object's model view in `highp` precision + * which is achieved by computing the matrix in JS and not in the shader. + * + * @type {Node} + */ export const highpModelViewMatrix = /*@__PURE__*/ ( Fn( ( builder ) => { builder.context.isHighPrecisionModelViewMatrix = true; @@ -64,6 +142,12 @@ export const highpModelViewMatrix = /*@__PURE__*/ ( Fn( ( builder ) => { } ).once() )().toVar( 'highpModelViewMatrix' ); +/** + * TSL object that represents the object's model normal view in `highp` precision + * which is achieved by computing the matrix in JS and not in the shader. + * + * @type {Node} + */ export const highpModelNormalViewMatrix = /*@__PURE__*/ ( Fn( ( builder ) => { const isHighPrecisionModelViewMatrix = builder.context.isHighPrecisionModelViewMatrix; diff --git a/src/nodes/accessors/ModelViewProjectionNode.js b/src/nodes/accessors/ModelViewProjectionNode.js index 11a28be3f78914..7e50ff63f296e3 100644 --- a/src/nodes/accessors/ModelViewProjectionNode.js +++ b/src/nodes/accessors/ModelViewProjectionNode.js @@ -1,4 +1,11 @@ import { cameraProjectionMatrix } from './Camera.js'; import { positionView } from './Position.js'; +/** @module ModelViewProjectionNode **/ + +/** + * TSL object that represents the position in clip space after the model-view-projection transform of the current rendered object. + * + * @type {VaryingNode} + */ export const modelViewProjection = /*@__PURE__*/ cameraProjectionMatrix.mul( positionView ).varying( 'v_modelViewProjection' ); diff --git a/src/nodes/accessors/MorphNode.js b/src/nodes/accessors/MorphNode.js index 5df34188d46b22..45a2c13cb1d9de 100644 --- a/src/nodes/accessors/MorphNode.js +++ b/src/nodes/accessors/MorphNode.js @@ -14,6 +14,8 @@ import { Vector2 } from '../../math/Vector2.js'; import { Vector4 } from '../../math/Vector4.js'; import { FloatType } from '../../constants.js'; +/** @module MorphNode **/ + const _morphTextures = /*@__PURE__*/ new WeakMap(); const _morphVec4 = /*@__PURE__*/ new Vector4(); @@ -156,7 +158,12 @@ function getEntry( geometry ) { } - +/** + * This node implements the vertex transformation shader logic which is required + * for morph target animation. + * + * @augments Node + */ class MorphNode extends Node { static get type() { @@ -165,17 +172,43 @@ class MorphNode extends Node { } + /** + * Constructs a new morph node. + * + * @param {Mesh} mesh - The mesh holding the morph targets. + */ constructor( mesh ) { super( 'void' ); + /** + * The mesh holding the morph targets. + * + * @type {Mesh} + */ this.mesh = mesh; + + /** + * A uniform node which represents the morph base influence value. + * + * @type {UniformNode} + */ this.morphBaseInfluence = uniform( 1 ); + /** + * The update type overwritten since morph nodes are updated per object. + * + * @type {String} + */ this.updateType = NodeUpdateType.OBJECT; } + /** + * Setups the morph node by assigning the transformed vertex data to predefined node variables. + * + * @param {NodeBuilder} builder - The current node builder. + */ setup( builder ) { const { geometry } = builder; @@ -239,7 +272,12 @@ class MorphNode extends Node { } - update() { + /** + * Updates the state of the morphed mesh by updating the base influence. + * + * @param {NodeFrame} frame - The current node frame. + */ + update( /*frame*/ ) { const morphBaseInfluence = this.morphBaseInfluence; @@ -259,4 +297,11 @@ class MorphNode extends Node { export default MorphNode; +/** + * TSL function for creating a morph node. + * + * @function + * @param {Mesh} mesh - The mesh holding the morph targets. + * @returns {MorphNode} + */ export const morphReference = /*@__PURE__*/ nodeProxy( MorphNode ); diff --git a/src/nodes/accessors/ReflectVector.js b/src/nodes/accessors/ReflectVector.js index eafd166528c771..252a0fe73225a4 100644 --- a/src/nodes/accessors/ReflectVector.js +++ b/src/nodes/accessors/ReflectVector.js @@ -3,8 +3,32 @@ import { transformedNormalView } from './Normal.js'; import { positionViewDirection } from './Position.js'; import { materialRefractionRatio } from './MaterialProperties.js'; +/** @module ReflectVector **/ + +/** + * The reflect vector in view space. + * + * @type {Node} + */ export const reflectView = /*@__PURE__*/ positionViewDirection.negate().reflect( transformedNormalView ); + +/** + * The refract vector in view space. + * + * @type {Node} + */ export const refractView = /*@__PURE__*/ positionViewDirection.negate().refract( transformedNormalView, materialRefractionRatio ); +/** + * Used for sampling cube maps when using cube reflection mapping. + * + * @type {Node} + */ export const reflectVector = /*@__PURE__*/ reflectView.transformDirection( cameraViewMatrix ).toVar( 'reflectVector' ); + +/** + * Used for sampling cube maps when using cube refraction mapping. + * + * @type {Node} + */ export const refractVector = /*@__PURE__*/ refractView.transformDirection( cameraViewMatrix ).toVar( 'reflectVector' ); From e30e6900bdfa3dd25ba4bdd6338c8f9872050a61 Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 13 Dec 2024 16:14:05 +0100 Subject: [PATCH 2/4] Node: Document more modules. --- src/nodes/accessors/AccessorsUtils.js | 27 ++++++ src/nodes/accessors/BatchNode.js | 42 +++++++++- src/nodes/accessors/InstanceNode.js | 83 +++++++++++++++++++ src/nodes/accessors/InstancedMeshNode.js | 31 ++++++- .../accessors/InstancedPointsMaterialNode.js | 13 +++ src/nodes/accessors/Tangent.js | 10 +-- 6 files changed, 195 insertions(+), 11 deletions(-) diff --git a/src/nodes/accessors/AccessorsUtils.js b/src/nodes/accessors/AccessorsUtils.js index bcd2d72863e432..5f3ac61e9b91ff 100644 --- a/src/nodes/accessors/AccessorsUtils.js +++ b/src/nodes/accessors/AccessorsUtils.js @@ -6,11 +6,38 @@ import { mix } from '../math/MathNode.js'; import { anisotropy, anisotropyB, roughness } from '../core/PropertyNode.js'; import { positionViewDirection } from './Position.js'; +/** @module AccessorsUtils **/ + +/** + * TSL object that represents the TBN matrix in view space. + * + * @type {Node} + */ export const TBNViewMatrix = /*@__PURE__*/ mat3( tangentView, bitangentView, normalView ); +/** + * TSL object that represents the parallax direction. + * + * @type {Node} + */ export const parallaxDirection = /*@__PURE__*/ positionViewDirection.mul( TBNViewMatrix )/*.normalize()*/; + +/** + * TSL function for computing parallax uv coordinates. + * + * @function + * @param {Node} uv - A uv node. + * @param {Node} scale - A scale node. + * @returns {Node} Parallax uv coordinates. + */ export const parallaxUV = ( uv, scale ) => uv.sub( parallaxDirection.mul( scale ) ); +/** + * TSL function for computing bent normals + * + * @function + * @returns {Node} Bent normals. + */ export const transformedBentNormalView = /*@__PURE__*/ ( () => { // https://google.github.io/filament/Filament.md.html#lighting/imagebasedlights/anisotropy diff --git a/src/nodes/accessors/BatchNode.js b/src/nodes/accessors/BatchNode.js index 74661a0a71fe05..c3356c2ac56735 100644 --- a/src/nodes/accessors/BatchNode.js +++ b/src/nodes/accessors/BatchNode.js @@ -8,6 +8,15 @@ import { tangentLocal } from './Tangent.js'; import { instanceIndex, drawIndex } from '../core/IndexNode.js'; import { varyingProperty } from '../core/PropertyNode.js'; +/** @module BatchNode **/ + +/** + * This node implements the vertex shader logic which is required + * when rendering 3D objects via batching. It requires the usage + * of {@link BatchedMesh}. + * + * @augments Node + */ class BatchNode extends Node { static get type() { @@ -16,21 +25,41 @@ class BatchNode extends Node { } + /** + * Constructs a new batch node. + * + * @param {BatchedMesh} batchMesh - A reference to batched mesh. + */ constructor( batchMesh ) { super( 'void' ); + /** + * A reference to batched mesh. + * + * @type {BatchedMesh} + */ this.batchMesh = batchMesh; - + /** + * The batching index node. + * + * @type {IndexNode?} + * @default null + */ this.batchingIdNode = null; } + /** + * Setups the internal buffers and nodes and assigns the transformed vertex data + * to predefined node variables for accumulation. That follows the same patterns + * like with morph and skinning nodes. + * + * @param {NodeBuilder} builder - The current node builder. + */ setup( builder ) { - // POSITION - if ( this.batchingIdNode === null ) { if ( builder.getDrawIndex() === null ) { @@ -125,4 +154,11 @@ class BatchNode extends Node { export default BatchNode; +/** + * TSL function for creating a batch node. + * + * @function + * @param {BatchedMesh} batchMesh - A reference to batched mesh. + * @returns {BatchNode} + */ export const batch = /*@__PURE__*/ nodeProxy( BatchNode ); diff --git a/src/nodes/accessors/InstanceNode.js b/src/nodes/accessors/InstanceNode.js index 5a552441947fa9..596478f86d4540 100644 --- a/src/nodes/accessors/InstanceNode.js +++ b/src/nodes/accessors/InstanceNode.js @@ -12,6 +12,16 @@ import { InstancedInterleavedBuffer } from '../../core/InstancedInterleavedBuffe import { InstancedBufferAttribute } from '../../core/InstancedBufferAttribute.js'; import { DynamicDrawUsage } from '../../constants.js'; +/** @module InstanceNode **/ + +/** + * This node implements the vertex shader logic which is required + * when rendering 3D objects via instanced rendering. The code + * makes sure vertex position, normal and color data can influenced + * via instanced data. + * + * @augments Node + */ class InstanceNode extends Node { static get type() { @@ -20,25 +30,84 @@ class InstanceNode extends Node { } + /** + * Constructs a new instance node. + * + * @param {Number} count - The number of instances. + * @param {InstancedBufferAttribute} instanceMatrix - Instanced buffer attribute representing the instance transformations. + * @param {InstancedBufferAttribute} instanceColor - Instanced buffer attribute representing the instance colors. + */ constructor( count, instanceMatrix, instanceColor ) { super( 'void' ); + /** + * The number of instances. + * + * @type {Number} + */ this.count = count; + + /** + * Instanced buffer attribute representing the transformation of instances. + * + * @type {InstancedBufferAttribute} + */ this.instanceMatrix = instanceMatrix; + + /** + * Instanced buffer attribute representing the color of instances. + * + * @type {InstancedBufferAttribute} + */ this.instanceColor = instanceColor; + /** + * The node that represents the instance matrix data. + * + * @type {Node} + */ this.instanceMatrixNode = null; + /** + * The node that represents the instance color data. + * + * @type {Node} + */ this.instanceColorNode = null; + /** + * The update type is set to `frame` since an update + * of instanced buffer data must be checked per frame. + * + * @type {String} + * @default 'frame' + */ this.updateType = NodeUpdateType.FRAME; + /** + * A reference to a buffer that is used by `instanceMatrixNode`. + * + * @type {InstancedInterleavedBuffer} + */ this.buffer = null; + + /** + * A reference to a buffer that is used by `instanceColorNode`. + * + * @type {InstancedInterleavedBuffer} + */ this.bufferColor = null; } + /** + * Setups the internal buffers and nodes and assigns the transformed vertex data + * to predefined node variables for accumulation. That follows the same patterns + * like with morph and skinning nodes. + * + * @param {NodeBuilder} builder - The current node builder. + */ setup( builder ) { const { count, instanceMatrix, instanceColor } = this; @@ -118,6 +187,11 @@ class InstanceNode extends Node { } + /** + * Checks if the internal buffers required an update. + * + * @param {NodeFrame} frame - The current node frame. + */ update( /*frame*/ ) { if ( this.instanceMatrix.usage !== DynamicDrawUsage && this.buffer !== null && this.instanceMatrix.version !== this.buffer.version ) { @@ -138,4 +212,13 @@ class InstanceNode extends Node { export default InstanceNode; +/** + * TSL function for creating an instance node. + * + * @function + * @param {Number} count - The number of instances. + * @param {InstancedBufferAttribute} instanceMatrix - Instanced buffer attribute representing the instance transformations. + * @param {InstancedBufferAttribute} instanceColor - Instanced buffer attribute representing the instance colors. + * @returns {InstanceNode} + */ export const instance = /*@__PURE__*/ nodeProxy( InstanceNode ); diff --git a/src/nodes/accessors/InstancedMeshNode.js b/src/nodes/accessors/InstancedMeshNode.js index 162893d7c8002b..f9a76cd1749096 100644 --- a/src/nodes/accessors/InstancedMeshNode.js +++ b/src/nodes/accessors/InstancedMeshNode.js @@ -1,6 +1,14 @@ import InstanceNode from './InstanceNode.js'; import { nodeProxy } from '../tsl/TSLBase.js'; +/** @module InstancedMeshNode **/ + +/** + * This is a special version of `InstanceNode` which requires the usage of {@link InstancedMesh}. + * It allows an easier setup of the instance node. + * + * @augments module:InstanceNode~InstanceNode + */ class InstancedMeshNode extends InstanceNode { static get type() { @@ -9,13 +17,23 @@ class InstancedMeshNode extends InstanceNode { } - constructor( instanceMesh ) { + /** + * Constructs a new instanced mesh node. + * + * @param {InstancedMesh} instancedMesh - The instanced mesh. + */ + constructor( instancedMesh ) { - const { count, instanceMatrix, instanceColor } = instanceMesh; + const { count, instanceMatrix, instanceColor } = instancedMesh; super( count, instanceMatrix, instanceColor ); - this.instanceMesh = instanceMesh; + /** + * A reference to the instanced mesh. + * + * @type {InstancedMesh} + */ + this.instancedMesh = instancedMesh; } @@ -23,4 +41,11 @@ class InstancedMeshNode extends InstanceNode { export default InstancedMeshNode; +/** + * TSL function for creating an instanced mesh node. + * + * @function + * @param {InstancedMesh} instancedMesh - The instancedMesh. + * @returns {InstancedMeshNode} + */ export const instancedMesh = /*@__PURE__*/ nodeProxy( InstancedMeshNode ); diff --git a/src/nodes/accessors/InstancedPointsMaterialNode.js b/src/nodes/accessors/InstancedPointsMaterialNode.js index 4a34ac6380ed72..56e935ae7d568a 100644 --- a/src/nodes/accessors/InstancedPointsMaterialNode.js +++ b/src/nodes/accessors/InstancedPointsMaterialNode.js @@ -1,6 +1,14 @@ import MaterialNode from './MaterialNode.js'; import { nodeImmutable } from '../tsl/TSLBase.js'; +/** @module InstancedPointsMaterialNode **/ + +/** + * An extension of material node to provide pre-defined + * TSL objects in context of `InstancedPointsNodeMaterial`. + * + * @augments module:MaterialNode~MaterialNode + */ class InstancedPointsMaterialNode extends MaterialNode { static get type() { @@ -21,4 +29,9 @@ InstancedPointsMaterialNode.POINT_WIDTH = 'pointWidth'; export default InstancedPointsMaterialNode; +/** + * TSL object that represents the point width of the current points material. + * + * @type {InstancedPointsMaterialNode} + */ export const materialPointWidth = /*@__PURE__*/ nodeImmutable( InstancedPointsMaterialNode, InstancedPointsMaterialNode.POINT_WIDTH ); diff --git a/src/nodes/accessors/Tangent.js b/src/nodes/accessors/Tangent.js index e2593b882fb8da..f8a3c9c563c015 100644 --- a/src/nodes/accessors/Tangent.js +++ b/src/nodes/accessors/Tangent.js @@ -25,34 +25,34 @@ export const tangentGeometry = /*@__PURE__*/ Fn( ( builder ) => { /** * TSL object that represents the vertex tangent in local space of the current rendered object. * - * @type {Node} + * @type {Node} */ export const tangentLocal = /*@__PURE__*/ tangentGeometry.xyz.toVar( 'tangentLocal' ); /** * TSL object that represents the vertex tangent in view space of the current rendered object. * - * @type {Node} + * @type {Node} */ export const tangentView = /*@__PURE__*/ modelViewMatrix.mul( vec4( tangentLocal, 0 ) ).xyz.varying( 'v_tangentView' ).normalize().toVar( 'tangentView' ); /** * TSL object that represents the vertex tangent in world space of the current rendered object. * - * @type {Node} + * @type {Node} */ export const tangentWorld = /*@__PURE__*/ tangentView.transformDirection( cameraViewMatrix ).varying( 'v_tangentWorld' ).normalize().toVar( 'tangentWorld' ); /** * TSL object that represents the transformed vertex tangent in view space of the current rendered object. * - * @type {Node} + * @type {Node} */ export const transformedTangentView = /*@__PURE__*/ tangentView.toVar( 'transformedTangentView' ); /** * TSL object that represents the transformed vertex tangent in world space of the current rendered object. * - * @type {Node} + * @type {Node} */ export const transformedTangentWorld = /*@__PURE__*/ transformedTangentView.transformDirection( cameraViewMatrix ).normalize().toVar( 'transformedTangentWorld' ); From 4304d668796393630d6c2296829241ac3f86452f Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 13 Dec 2024 16:22:32 +0100 Subject: [PATCH 3/4] Docs: Clean up. --- src/nodes/accessors/BatchNode.js | 4 ++-- src/nodes/accessors/InstanceNode.js | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/nodes/accessors/BatchNode.js b/src/nodes/accessors/BatchNode.js index c3356c2ac56735..16dad25b412077 100644 --- a/src/nodes/accessors/BatchNode.js +++ b/src/nodes/accessors/BatchNode.js @@ -12,8 +12,8 @@ import { varyingProperty } from '../core/PropertyNode.js'; /** * This node implements the vertex shader logic which is required - * when rendering 3D objects via batching. It requires the usage - * of {@link BatchedMesh}. + * when rendering 3D objects via batching. `BatchNode` must be used + * with instances of {@link BatchedMesh}. * * @augments Node */ diff --git a/src/nodes/accessors/InstanceNode.js b/src/nodes/accessors/InstanceNode.js index 596478f86d4540..d16131f7d09880 100644 --- a/src/nodes/accessors/InstanceNode.js +++ b/src/nodes/accessors/InstanceNode.js @@ -16,9 +16,8 @@ import { DynamicDrawUsage } from '../../constants.js'; /** * This node implements the vertex shader logic which is required - * when rendering 3D objects via instanced rendering. The code - * makes sure vertex position, normal and color data can influenced - * via instanced data. + * when rendering 3D objects via instancing. The code makes sure + * vertex position, normal and color data can influenced via instanced data. * * @augments Node */ From 085048b03e72b1c24c241e1892c9395327257eec Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 13 Dec 2024 16:23:17 +0100 Subject: [PATCH 4/4] Update AccessorsUtils.js --- src/nodes/accessors/AccessorsUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nodes/accessors/AccessorsUtils.js b/src/nodes/accessors/AccessorsUtils.js index 5f3ac61e9b91ff..28c5dd851f634d 100644 --- a/src/nodes/accessors/AccessorsUtils.js +++ b/src/nodes/accessors/AccessorsUtils.js @@ -33,7 +33,7 @@ export const parallaxDirection = /*@__PURE__*/ positionViewDirection.mul( TBNVie export const parallaxUV = ( uv, scale ) => uv.sub( parallaxDirection.mul( scale ) ); /** - * TSL function for computing bent normals + * TSL function for computing bent normals. * * @function * @returns {Node} Bent normals.