diff --git a/src/materials/nodes/LineBasicNodeMaterial.js b/src/materials/nodes/LineBasicNodeMaterial.js index c167ab0ecb988f..1e0fbdb4dfa118 100644 --- a/src/materials/nodes/LineBasicNodeMaterial.js +++ b/src/materials/nodes/LineBasicNodeMaterial.js @@ -4,6 +4,11 @@ import { LineBasicMaterial } from '../LineBasicMaterial.js'; const _defaultValues = /*@__PURE__*/ new LineBasicMaterial(); +/** + * Node material version of `LineBasicMaterial`. + * + * @augments NodeMaterial + */ class LineBasicNodeMaterial extends NodeMaterial { static get type() { @@ -12,14 +17,24 @@ class LineBasicNodeMaterial extends NodeMaterial { } + /** + * Constructs a new line basic node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isLineBasicNodeMaterial = true; - this.lights = false; - this.setDefaultValues( _defaultValues ); this.setValues( parameters ); diff --git a/src/materials/nodes/LineDashedNodeMaterial.js b/src/materials/nodes/LineDashedNodeMaterial.js index e1c0421d83aaf5..ed06e7080fe0c4 100644 --- a/src/materials/nodes/LineDashedNodeMaterial.js +++ b/src/materials/nodes/LineDashedNodeMaterial.js @@ -8,6 +8,11 @@ import { LineDashedMaterial } from '../LineDashedMaterial.js'; const _defaultValues = /*@__PURE__*/ new LineDashedMaterial(); +/** + * Node material version of `LineDashedMaterial`. + * + * @augments NodeMaterial + */ class LineDashedNodeMaterial extends NodeMaterial { static get type() { @@ -16,33 +21,101 @@ class LineDashedNodeMaterial extends NodeMaterial { } + /** + * Constructs a new line dashed node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isLineDashedNodeMaterial = true; - this.lights = false; - this.setDefaultValues( _defaultValues ); + /** + * The dash offset. + * + * @type {Number} + * @default 0 + */ this.dashOffset = 0; + /** + * The offset of dash materials is by default inferred from the `dashOffset` + * property. This node property allows to overwrite the default + * and define the offset with a node instead. + * + * If you don't want to overwrite the offset but modify the existing + * value instead, use {@link module:MaterialNode.materialLineDashOffset}. + * + * @type {Node?} + * @default null + */ this.offsetNode = null; + + /** + * The scale of dash materials is by default inferred from the `scale` + * property. This node property allows to overwrite the default + * and define the scale with a node instead. + * + * If you don't want to overwrite the scale but modify the existing + * value instead, use {@link module:MaterialNode.materialLineScale}. + * + * @type {Node?} + * @default null + */ this.dashScaleNode = null; + + /** + * The dash size of dash materials is by default inferred from the `dashSize` + * property. This node property allows to overwrite the default + * and define the dash size with a node instead. + * + * If you don't want to overwrite the dash size but modify the existing + * value instead, use {@link module:MaterialNode.materialLineDashSize}. + * + * @type {Node?} + * @default null + */ this.dashSizeNode = null; + + /** + * The gap size of dash materials is by default inferred from the `gapSize` + * property. This node property allows to overwrite the default + * and define the gap size with a node instead. + * + * If you don't want to overwrite the gap size but modify the existing + * value instead, use {@link module:MaterialNode.materialLineGapSize}. + * + * @type {Node?} + * @default null + */ this.gapSizeNode = null; this.setValues( parameters ); } - setupVariants() { + /** + * Setups the dash specific node variables. + * + * @param {NodeBuilder} builder - The current node builder. + */ + setupVariants( /* builder */ ) { const offsetNode = this.offsetNode ? float( this.offsetNodeNode ) : materialLineDashOffset; const dashScaleNode = this.dashScaleNode ? float( this.dashScaleNode ) : materialLineScale; const dashSizeNode = this.dashSizeNode ? float( this.dashSizeNode ) : materialLineDashSize; - const gapSizeNode = this.dashSizeNode ? float( this.dashGapNode ) : materialLineGapSize; + const gapSizeNode = this.gapSizeNode ? float( this.gapSizeNode ) : materialLineGapSize; dashSize.assign( dashSizeNode ); gapSize.assign( gapSizeNode ); diff --git a/src/materials/nodes/MeshBasicNodeMaterial.js b/src/materials/nodes/MeshBasicNodeMaterial.js index 5be8a986df11e2..13dbe1d99062e5 100644 --- a/src/materials/nodes/MeshBasicNodeMaterial.js +++ b/src/materials/nodes/MeshBasicNodeMaterial.js @@ -10,6 +10,11 @@ import { MeshBasicMaterial } from '../MeshBasicMaterial.js'; const _defaultValues = /*@__PURE__*/ new MeshBasicMaterial(); +/** + * Node material version of `MeshBasicMaterial`. + * + * @augments NodeMaterial + */ class MeshBasicNodeMaterial extends NodeMaterial { static get type() { @@ -18,12 +23,32 @@ class MeshBasicNodeMaterial extends NodeMaterial { } + /** + * Constructs a new mesh basic node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isMeshBasicNodeMaterial = true; + /** + * Although the basic material is by definition unlit, we set + * this property to `true` since we use a lighting model to compute + * the outgoing light of the fragment shader. + * + * @type {Boolean} + * @default true + */ this.lights = true; this.setDefaultValues( _defaultValues ); @@ -32,12 +57,25 @@ class MeshBasicNodeMaterial extends NodeMaterial { } + /** + * Basic materials are not affected by normal and bump maps so we + * return by default {@link module:Normal.normalView}. + * + * @return {Node} The normal node. + */ setupNormal() { return normalView; // see #28839 } + /** + * Overwritten since this type of material uses {@link BasicEnvironmentNode} + * to implement the default environment mapping. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {BasicEnvironmentNode?} The environment node. + */ setupEnvironment( builder ) { const envNode = super.setupEnvironment( builder ); @@ -46,6 +84,13 @@ class MeshBasicNodeMaterial extends NodeMaterial { } + /** + * This method must be overwriten since light maps are evaluated + * with a special scaling factor for basic materials. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {BasicLightMapNode?} The light map node. + */ setupLightMap( builder ) { let node = null; @@ -60,12 +105,23 @@ class MeshBasicNodeMaterial extends NodeMaterial { } + /** + * The material overwrites this method because `lights` is set to `true` but + * we still want to return the diffuse color as the outgoing light. + * + * @return {Node} The outgoing light node. + */ setupOutgoingLight() { return diffuseColor.rgb; } + /** + * Setups the lighting model. + * + * @return {BasicLightingModel} The lighting model. + */ setupLightingModel() { return new BasicLightingModel(); diff --git a/src/materials/nodes/MeshLambertNodeMaterial.js b/src/materials/nodes/MeshLambertNodeMaterial.js index 033ff96c92f9cf..da4e4c28cc1dbd 100644 --- a/src/materials/nodes/MeshLambertNodeMaterial.js +++ b/src/materials/nodes/MeshLambertNodeMaterial.js @@ -6,6 +6,11 @@ import { MeshLambertMaterial } from '../MeshLambertMaterial.js'; const _defaultValues = /*@__PURE__*/ new MeshLambertMaterial(); +/** + * Node material version of `MeshLambertMaterial`. + * + * @augments NodeMaterial + */ class MeshLambertNodeMaterial extends NodeMaterial { static get type() { @@ -14,12 +19,30 @@ class MeshLambertNodeMaterial extends NodeMaterial { } + /** + * Constructs a new mesh lambert node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isMeshLambertNodeMaterial = true; + /** + * Set to `true` because lambert materials react on lights. + * + * @type {Boolean} + * @default true + */ this.lights = true; this.setDefaultValues( _defaultValues ); @@ -28,6 +51,13 @@ class MeshLambertNodeMaterial extends NodeMaterial { } + /** + * Overwritten since this type of material uses {@link BasicEnvironmentNode} + * to implement the default environment mapping. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {BasicEnvironmentNode?} The environment node. + */ setupEnvironment( builder ) { const envNode = super.setupEnvironment( builder ); @@ -36,6 +66,11 @@ class MeshLambertNodeMaterial extends NodeMaterial { } + /** + * Setups the lighting model. + * + * @return {PhongLightingModel} The lighting model. + */ setupLightingModel( /*builder*/ ) { return new PhongLightingModel( false ); // ( specular ) -> force lambert diff --git a/src/materials/nodes/MeshMatcapNodeMaterial.js b/src/materials/nodes/MeshMatcapNodeMaterial.js index 19f274cc78366a..df3a1ac95b3f31 100644 --- a/src/materials/nodes/MeshMatcapNodeMaterial.js +++ b/src/materials/nodes/MeshMatcapNodeMaterial.js @@ -9,6 +9,11 @@ import { MeshMatcapMaterial } from '../MeshMatcapMaterial.js'; const _defaultValues = /*@__PURE__*/ new MeshMatcapMaterial(); +/** + * Node material version of `MeshMatcapMaterial`. + * + * @augments NodeMaterial + */ class MeshMatcapNodeMaterial extends NodeMaterial { static get type() { @@ -17,12 +22,22 @@ class MeshMatcapNodeMaterial extends NodeMaterial { } + /** + * Constructs a new mesh normal node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); - this.lights = false; - + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isMeshMatcapNodeMaterial = true; this.setDefaultValues( _defaultValues ); @@ -31,6 +46,11 @@ class MeshMatcapNodeMaterial extends NodeMaterial { } + /** + * Setups the matcap specific node variables. + * + * @param {NodeBuilder} builder - The current node builder. + */ setupVariants( builder ) { const uv = matcapUV; diff --git a/src/materials/nodes/MeshNormalNodeMaterial.js b/src/materials/nodes/MeshNormalNodeMaterial.js index 3917cc3594cb62..e88fce34737e0c 100644 --- a/src/materials/nodes/MeshNormalNodeMaterial.js +++ b/src/materials/nodes/MeshNormalNodeMaterial.js @@ -9,6 +9,11 @@ import { MeshNormalMaterial } from '../MeshNormalMaterial.js'; const _defaultValues = /*@__PURE__*/ new MeshNormalMaterial(); +/** + * Node material version of `MeshNormalMaterial`. + * + * @augments NodeMaterial + */ class MeshNormalNodeMaterial extends NodeMaterial { static get type() { @@ -17,12 +22,22 @@ class MeshNormalNodeMaterial extends NodeMaterial { } + /** + * Constructs a new mesh normal node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); - this.lights = false; - + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isMeshNormalNodeMaterial = true; this.setDefaultValues( _defaultValues ); @@ -31,6 +46,10 @@ class MeshNormalNodeMaterial extends NodeMaterial { } + /** + * Overwrites the default implementation by computing the diffuse color + * based on the normal data. + */ setupDiffuseColor() { const opacityNode = this.opacityNode ? float( this.opacityNode ) : materialOpacity; diff --git a/src/materials/nodes/MeshPhongNodeMaterial.js b/src/materials/nodes/MeshPhongNodeMaterial.js index c152283c913690..3d47a140a9a44d 100644 --- a/src/materials/nodes/MeshPhongNodeMaterial.js +++ b/src/materials/nodes/MeshPhongNodeMaterial.js @@ -9,6 +9,11 @@ import { MeshPhongMaterial } from '../MeshPhongMaterial.js'; const _defaultValues = /*@__PURE__*/ new MeshPhongMaterial(); +/** + * Node material version of `MeshPhongMaterial`. + * + * @augments NodeMaterial + */ class MeshPhongNodeMaterial extends NodeMaterial { static get type() { @@ -17,15 +22,56 @@ class MeshPhongNodeMaterial extends NodeMaterial { } + /** + * Constructs a new mesh lambert node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isMeshPhongNodeMaterial = true; + /** + * Set to `true` because phong materials react on lights. + * + * @type {Boolean} + * @default true + */ this.lights = true; + /** + * The shininess of phong materials is by default inferred from the `shininess` + * property. This node property allows to overwrite the default + * and define the shininess with a node instead. + * + * If you don't want to overwrite the shininess but modify the existing + * value instead, use {@link module:MaterialNode.materialShininess}. + * + * @type {Node?} + * @default null + */ this.shininessNode = null; + + /** + * The specular color of phong materials is by default inferred from the + * `specular` property. This node property allows to overwrite the default + * and define the specular color with a node instead. + * + * If you don't want to overwrite the specular color but modify the existing + * value instead, use {@link module:MaterialNode.materialSpecular}. + * + * @type {Node?} + * @default null + */ this.specularNode = null; this.setDefaultValues( _defaultValues ); @@ -34,6 +80,13 @@ class MeshPhongNodeMaterial extends NodeMaterial { } + /** + * Overwritten since this type of material uses {@link BasicEnvironmentNode} + * to implement the default environment mapping. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {BasicEnvironmentNode?} The environment node. + */ setupEnvironment( builder ) { const envNode = super.setupEnvironment( builder ); @@ -42,13 +95,23 @@ class MeshPhongNodeMaterial extends NodeMaterial { } + /** + * Setups the lighting model. + * + * @return {PhongLightingModel} The lighting model. + */ setupLightingModel( /*builder*/ ) { return new PhongLightingModel(); } - setupVariants() { + /** + * Setups the phong specific node variables. + * + * @param {NodeBuilder} builder - The current node builder. + */ + setupVariants( /*builder*/ ) { // SHININESS diff --git a/src/materials/nodes/MeshStandardNodeMaterial.js b/src/materials/nodes/MeshStandardNodeMaterial.js index e7b5bce191981a..ef84543c133354 100644 --- a/src/materials/nodes/MeshStandardNodeMaterial.js +++ b/src/materials/nodes/MeshStandardNodeMaterial.js @@ -11,6 +11,11 @@ import { MeshStandardMaterial } from '../MeshStandardMaterial.js'; const _defaultValues = /*@__PURE__*/ new MeshStandardMaterial(); +/** + * Node material version of `MeshStandardMaterial`. + * + * @augments NodeMaterial + */ class MeshStandardNodeMaterial extends NodeMaterial { static get type() { @@ -19,17 +24,69 @@ class MeshStandardNodeMaterial extends NodeMaterial { } + /** + * Constructs a new mesh standard node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isMeshStandardNodeMaterial = true; + /** + * Set to `true` because standard materials react on lights. + * + * @type {Boolean} + * @default true + */ this.lights = true; + /** + * The emissive color of standard materials is by default inferred from the `emissive`, + * `emissiveIntensity` and `emissiveMap` properties. This node property allows to + * overwrite the default and define the emissive color with a node instead. + * + * If you don't want to overwrite the emissive color but modify the existing + * value instead, use {@link module:MaterialNode.materialEmissive}. + * + * @type {Node?} + * @default null + */ this.emissiveNode = null; + /** + * The metalness of standard materials is by default inferred from the `metalness`, + * and `metalnessMap` properties. This node property allows to + * overwrite the default and define the metalness with a node instead. + * + * If you don't want to overwrite the metalness but modify the existing + * value instead, use {@link module:MaterialNode.materialMetalness}. + * + * @type {Node?} + * @default null + */ this.metalnessNode = null; + + /** + * The roughness of standard materials is by default inferred from the `roughness`, + * and `roughnessMap` properties. This node property allows to + * overwrite the default and define the roughness with a node instead. + * + * If you don't want to overwrite the roughness but modify the existing + * value instead, use {@link module:MaterialNode.materialRoughness}. + * + * @type {Node?} + * @default null + */ this.roughnessNode = null; this.setDefaultValues( _defaultValues ); @@ -38,6 +95,14 @@ class MeshStandardNodeMaterial extends NodeMaterial { } + /** + * Overwritten since this type of material uses {@link EnvironmentNode} + * to implement the PBR (PMREM based) environment mapping. Besides, the + * method honors `Scene.environment`. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {EnvironmentNode?} The environment node. + */ setupEnvironment( builder ) { let envNode = super.setupEnvironment( builder ); @@ -52,12 +117,20 @@ class MeshStandardNodeMaterial extends NodeMaterial { } + /** + * Setups the lighting model. + * + * @return {PhysicalLightingModel} The lighting model. + */ setupLightingModel( /*builder*/ ) { return new PhysicalLightingModel(); } + /** + * Setups the specular related node variables. + */ setupSpecular() { const specularColorNode = mix( vec3( 0.04 ), diffuseColor.rgb, metalness ); @@ -67,6 +140,11 @@ class MeshStandardNodeMaterial extends NodeMaterial { } + /** + * Setups the standard specific node variables. + * + * @param {NodeBuilder} builder - The current node builder. + */ setupVariants() { // METALNESS diff --git a/src/materials/nodes/MeshToonNodeMaterial.js b/src/materials/nodes/MeshToonNodeMaterial.js index 4137dcd5db5f1e..adaee0cfb0960b 100644 --- a/src/materials/nodes/MeshToonNodeMaterial.js +++ b/src/materials/nodes/MeshToonNodeMaterial.js @@ -5,6 +5,11 @@ import { MeshToonMaterial } from '../MeshToonMaterial.js'; const _defaultValues = /*@__PURE__*/ new MeshToonMaterial(); +/** + * Node material version of `MeshToonMaterial`. + * + * @augments NodeMaterial + */ class MeshToonNodeMaterial extends NodeMaterial { static get type() { @@ -13,12 +18,30 @@ class MeshToonNodeMaterial extends NodeMaterial { } + /** + * Constructs a new mesh toon node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isMeshToonNodeMaterial = true; + /** + * Set to `true` because toon materials react on lights. + * + * @type {Boolean} + * @default true + */ this.lights = true; this.setDefaultValues( _defaultValues ); @@ -27,6 +50,11 @@ class MeshToonNodeMaterial extends NodeMaterial { } + /** + * Setups the lighting model. + * + * @return {ToonLightingModel} The lighting model. + */ setupLightingModel( /*builder*/ ) { return new ToonLightingModel(); diff --git a/src/materials/nodes/NodeMaterial.js b/src/materials/nodes/NodeMaterial.js index e9654c6fc1756f..cd8ccbd8224bc1 100644 --- a/src/materials/nodes/NodeMaterial.js +++ b/src/materials/nodes/NodeMaterial.js @@ -255,7 +255,7 @@ class NodeMaterial extends Material { * The idea is to assign a `Fn` definition that holds the geometry modification logic. A typical example * would be a GPU based particle system that provides a node material for usage on app level. The particle * simulation would be implemented as compute shaders and managed inside a `Fn` function. This function is - * eventually assigned to `ParticleNodeMaterial.geometryNode`. + * eventually assigned to `geometryNode`. * * @type {Function} * @default null @@ -635,12 +635,13 @@ class NodeMaterial extends Material { } /** - * Setups the position in view space of. This method exists + * Setups the position node in view space. This method exists * so derived node materials can modifiy the implementation e.g. sprite materials. * + * @param {NodeBuilder} builder - The current node builder. * @return {Node} The position in view space. */ - setupPositionView() { + setupPositionView( /*builder*/ ) { return modelViewMatrix.mul( positionLocal ).xyz; @@ -649,9 +650,10 @@ class NodeMaterial extends Material { /** * Setups the position in clip space. * + * @param {NodeBuilder} builder - The current node builder. * @return {Node} The position in view space. */ - setupModelViewProjection() { + setupModelViewProjection( /*builder*/ ) { return cameraProjectionMatrix.mul( positionView ); @@ -934,6 +936,7 @@ class NodeMaterial extends Material { * * @abstract * @param {NodeBuilder} builder - The current node builder. + * @return {LightingModel} The lighting model. */ setupLightingModel( /*builder*/ ) { @@ -1018,9 +1021,9 @@ class NodeMaterial extends Material { /** * Most classic material types have a node pendant e.g. for `MeshBasicMaterial` * there is `MeshBasicNodeMaterial`. This utility method is intended for - * define all material property of the classic type in the node type. + * defining all material properties of the classic type in the node type. * - * @param {Material} material - The material to copy properties with their values over to this node material. + * @param {Material} material - The material to copy properties with their values to this node material. */ setDefaultValues( material ) { diff --git a/src/materials/nodes/PointsNodeMaterial.js b/src/materials/nodes/PointsNodeMaterial.js index 028402d95f625f..193df0ded1cef6 100644 --- a/src/materials/nodes/PointsNodeMaterial.js +++ b/src/materials/nodes/PointsNodeMaterial.js @@ -4,6 +4,16 @@ import { PointsMaterial } from '../PointsMaterial.js'; const _defaultValues = /*@__PURE__*/ new PointsMaterial(); +/** + * Node material version of `PointsMaterial`. + * + * Since WebGPU can render point primitives only with a size of one pixel, + * this material type does not evaluate the `size` and `sizeAttenuation` + * property of `PointsMaterial`. Use {@link InstancedPointsNodeMaterial} + * instead if you need points with a size larger than one pixel. + * + * @augments NodeMaterial + */ class PointsNodeMaterial extends NodeMaterial { static get type() { @@ -12,31 +22,30 @@ class PointsNodeMaterial extends NodeMaterial { } + /** + * Constructs a new points node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isPointsNodeMaterial = true; - this.lights = false; - this.transparent = true; - - this.sizeNode = null; - this.setDefaultValues( _defaultValues ); this.setValues( parameters ); } - copy( source ) { - - this.sizeNode = source.sizeNode; - - return super.copy( source ); - - } - } export default PointsNodeMaterial; diff --git a/src/materials/nodes/ShadowNodeMaterial.js b/src/materials/nodes/ShadowNodeMaterial.js index 756c22599ee1c4..7470783cfd9dfa 100644 --- a/src/materials/nodes/ShadowNodeMaterial.js +++ b/src/materials/nodes/ShadowNodeMaterial.js @@ -5,6 +5,11 @@ import { ShadowMaterial } from '../ShadowMaterial.js'; const _defaultValues = /*@__PURE__*/ new ShadowMaterial(); +/** + * Node material version of `ShadowMaterial`. + * + * @augments NodeMaterial + */ class ShadowNodeMaterial extends NodeMaterial { static get type() { @@ -13,12 +18,31 @@ class ShadowNodeMaterial extends NodeMaterial { } + /** + * Constructs a new shadow node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isShadowNodeMaterial = true; + /** + * Set to `true` because so it's possible to implement + * the shadow mask effect. + * + * @type {Boolean} + * @default true + */ this.lights = true; this.setDefaultValues( _defaultValues ); @@ -27,6 +51,11 @@ class ShadowNodeMaterial extends NodeMaterial { } + /** + * Setups the lighting model. + * + * @return {ShadowMaskModel} The lighting model. + */ setupLightingModel( /*builder*/ ) { return new ShadowMaskModel(); diff --git a/src/materials/nodes/SpriteNodeMaterial.js b/src/materials/nodes/SpriteNodeMaterial.js index b0ce982208f6c4..f0880c47e5347f 100644 --- a/src/materials/nodes/SpriteNodeMaterial.js +++ b/src/materials/nodes/SpriteNodeMaterial.js @@ -11,6 +11,11 @@ import { reference } from '../../nodes/accessors/ReferenceBaseNode.js'; const _defaultValues = /*@__PURE__*/ new SpriteMaterial(); +/** + * Node material version of `SpriteMaterial`. + * + * @augments NodeMaterial + */ class SpriteNodeMaterial extends NodeMaterial { static get type() { @@ -19,17 +24,66 @@ class SpriteNodeMaterial extends NodeMaterial { } + /** + * Constructs a new sprite node material. + * + * @param {Object?} parameters - The configuration parameter. + */ constructor( parameters ) { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isSpriteNodeMaterial = true; - this.lights = false; this._useSizeAttenuation = true; + /** + * This property makes it possible to define the position of the sprite with a + * node. That can be useful when the material is used with instanced rendering + * and node data are defined with an instanced attribute node: + * ```js + * const positionAttribute = new InstancedBufferAttribute( new Float32Array( positions ), 3 ); + * material.positionNode = instancedBufferAttribute( positionAttribute ); + * ``` + * Another possibility is to compute the instanced data with a compute shader: + * ```js + * const positionBuffer = instancedArray( particleCount, 'vec3' ); + * particleMaterial.positionNode = positionBuffer.toAttribute(); + * ``` + * + * @type {Node?} + * @default null + */ this.positionNode = null; + + /** + * The rotation of sprite materials is by default inferred from the `rotation`, + * property. This node property allows to overwrite the default and define + * the rotation with a node instead. + * + * If you don't want to overwrite the rotation but modify the existing + * value instead, use {@link module:MaterialNode.materialRotation}. + * + * @type {Node?} + * @default null + */ this.rotationNode = null; + + /** + * This node property provides an additional way to scale sprites next to + * `Object3D.scale`. The scale transformation based in `Object3D.scale` + * is multiplied with the scale value of this node in the vertex shader. + * + * @type {Node?} + * @default null + */ this.scaleNode = null; this.setDefaultValues( _defaultValues ); @@ -38,14 +92,19 @@ class SpriteNodeMaterial extends NodeMaterial { } + /** + * Setups the position node in view space. This method implements + * the sprite specific vertex shader. + * + * @param {NodeBuilder} builder - The current node builder. + * @return {Node} The position in view space. + */ setupPositionView( builder ) { const { object, camera } = builder; const sizeAttenuation = this.sizeAttenuation; - // < VERTEX STAGE > - const { positionNode, rotationNode, scaleNode } = this; const mvPosition = modelViewMatrix.mul( vec3( positionNode || 0 ) ); @@ -58,7 +117,7 @@ class SpriteNodeMaterial extends NodeMaterial { } - if ( ! sizeAttenuation ) { + if ( sizeAttenuation === false ) { if ( camera.isPerspectiveCamera ) { @@ -77,7 +136,7 @@ class SpriteNodeMaterial extends NodeMaterial { if ( object.center && object.center.isVector2 === true ) { - const center = reference( 'center', 'vec2' ); + const center = reference( 'center', 'vec2', object ); alignedPosition = alignedPosition.sub( center.sub( 0.5 ) ); @@ -103,6 +162,12 @@ class SpriteNodeMaterial extends NodeMaterial { } + /** + * Whether to use size attenuation or not. + * + * @type {Boolean} + * @default true + */ get sizeAttenuation() { return this._useSizeAttenuation; diff --git a/src/nodes/core/PropertyNode.js b/src/nodes/core/PropertyNode.js index 681173b1d3346e..df58c8f8bf959b 100644 --- a/src/nodes/core/PropertyNode.js +++ b/src/nodes/core/PropertyNode.js @@ -1,8 +1,10 @@ import Node from './Node.js'; import { nodeImmutable, nodeObject } from '../tsl/TSLCore.js'; +/** @module PropertyNode **/ + /** - * This class represents a shader property. It can be used on + * This class represents a shader property. It can be used * to explicitly define a property and assign a value to it. * * ```js @@ -101,34 +103,218 @@ class PropertyNode extends Node { export default PropertyNode; +/** + * TSL function for creating a property node. + * + * @function + * @param {String} type - The type of the node. + * @param {String?} [name=null] - The name of the property in the shader. + * @returns {PropertyNode} + */ export const property = ( type, name ) => nodeObject( new PropertyNode( type, name ) ); + +/** + * TSL function for creating a varying property node. + * + * @function + * @param {String} type - The type of the node. + * @param {String?} [name=null] - The name of the varying in the shader. + * @returns {PropertyNode} + */ export const varyingProperty = ( type, name ) => nodeObject( new PropertyNode( type, name, true ) ); +/** + * TSL object that represents the shader variable `DiffuseColor`. + * + * @type {PropertyNode} + */ export const diffuseColor = /*@__PURE__*/ nodeImmutable( PropertyNode, 'vec4', 'DiffuseColor' ); + +/** + * TSL object that represents the shader variable `EmissiveColor`. + * + * @type {PropertyNode} + */ export const emissive = /*@__PURE__*/ nodeImmutable( PropertyNode, 'vec3', 'EmissiveColor' ); + +/** + * TSL object that represents the shader variable `Roughness`. + * + * @type {PropertyNode} + */ export const roughness = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Roughness' ); + +/** + * TSL object that represents the shader variable `Metalness`. + * + * @type {PropertyNode} + */ export const metalness = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Metalness' ); + +/** + * TSL object that represents the shader variable `Clearcoat`. + * + * @type {PropertyNode} + */ export const clearcoat = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Clearcoat' ); + +/** + * TSL object that represents the shader variable `ClearcoatRoughness`. + * + * @type {PropertyNode} + */ export const clearcoatRoughness = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'ClearcoatRoughness' ); + +/** + * TSL object that represents the shader variable `Sheen`. + * + * @type {PropertyNode} + */ export const sheen = /*@__PURE__*/ nodeImmutable( PropertyNode, 'vec3', 'Sheen' ); + +/** + * TSL object that represents the shader variable `SheenRoughness`. + * + * @type {PropertyNode} + */ export const sheenRoughness = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'SheenRoughness' ); + +/** + * TSL object that represents the shader variable `Iridescence`. + * + * @type {PropertyNode} + */ export const iridescence = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Iridescence' ); + +/** + * TSL object that represents the shader variable `IridescenceIOR`. + * + * @type {PropertyNode} + */ export const iridescenceIOR = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'IridescenceIOR' ); + +/** + * TSL object that represents the shader variable `IridescenceThickness`. + * + * @type {PropertyNode} + */ export const iridescenceThickness = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'IridescenceThickness' ); + +/** + * TSL object that represents the shader variable `AlphaT`. + * + * @type {PropertyNode} + */ export const alphaT = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'AlphaT' ); + +/** + * TSL object that represents the shader variable `Anisotropy`. + * + * @type {PropertyNode} + */ export const anisotropy = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Anisotropy' ); + +/** + * TSL object that represents the shader variable `AnisotropyT`. + * + * @type {PropertyNode} + */ export const anisotropyT = /*@__PURE__*/ nodeImmutable( PropertyNode, 'vec3', 'AnisotropyT' ); + +/** + * TSL object that represents the shader variable `AnisotropyB`. + * + * @type {PropertyNode} + */ export const anisotropyB = /*@__PURE__*/ nodeImmutable( PropertyNode, 'vec3', 'AnisotropyB' ); + +/** + * TSL object that represents the shader variable `SpecularColor`. + * + * @type {PropertyNode} + */ export const specularColor = /*@__PURE__*/ nodeImmutable( PropertyNode, 'color', 'SpecularColor' ); + +/** + * TSL object that represents the shader variable `SpecularF90`. + * + * @type {PropertyNode} + */ export const specularF90 = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'SpecularF90' ); + +/** + * TSL object that represents the shader variable `Shininess`. + * + * @type {PropertyNode} + */ export const shininess = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Shininess' ); + +/** + * TSL object that represents the shader variable `Output`. + * + * @type {PropertyNode} + */ export const output = /*@__PURE__*/ nodeImmutable( PropertyNode, 'vec4', 'Output' ); + +/** + * TSL object that represents the shader variable `dashSize`. + * + * @type {PropertyNode} + */ export const dashSize = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'dashSize' ); + +/** + * TSL object that represents the shader variable `gapSize`. + * + * @type {PropertyNode} + */ export const gapSize = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'gapSize' ); + +/** + * TSL object that represents the shader variable `pointWidth`. + * + * @type {PropertyNode} + */ export const pointWidth = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'pointWidth' ); + +/** + * TSL object that represents the shader variable `IOR`. + * + * @type {PropertyNode} + */ export const ior = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'IOR' ); + +/** + * TSL object that represents the shader variable `Transmission`. + * + * @type {PropertyNode} + */ export const transmission = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Transmission' ); + +/** + * TSL object that represents the shader variable `Thickness`. + * + * @type {PropertyNode} + */ export const thickness = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Thickness' ); + +/** + * TSL object that represents the shader variable `AttenuationDistance`. + * + * @type {PropertyNode} + */ export const attenuationDistance = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'AttenuationDistance' ); + +/** + * TSL object that represents the shader variable `AttenuationColor`. + * + * @type {PropertyNode} + */ export const attenuationColor = /*@__PURE__*/ nodeImmutable( PropertyNode, 'color', 'AttenuationColor' ); + +/** + * TSL object that represents the shader variable `Dispersion`. + * + * @type {PropertyNode} + */ export const dispersion = /*@__PURE__*/ nodeImmutable( PropertyNode, 'float', 'Dispersion' );