Skip to content

Commit

Permalink
Nodes: Document more modules. (#30087)
Browse files Browse the repository at this point in the history
  • Loading branch information
Mugen87 authored Dec 10, 2024
1 parent 8ac75e9 commit 0eae292
Show file tree
Hide file tree
Showing 6 changed files with 369 additions and 8 deletions.
4 changes: 3 additions & 1 deletion src/nodes/fog/Fog.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import { positionView } from '../accessors/Position.js';
import { smoothstep } from '../math/MathNode.js';
import { Fn, vec4 } from '../tsl/TSLBase.js';

/** @module Fog **/

/**
* Returns a node that represents the `z` coordinate in view space
* for the current fragment. It's a different representation of the
Expand Down Expand Up @@ -75,7 +77,7 @@ export const fog = Fn( ( [ color, factor ] ) => {

export function rangeFog( color, near, far ) { // @deprecated, r171

console.warn( 'THREE.TSL: "rangeFog( color, near, far )" is deprecated. Use "fog( color, rangeFog( near, far ) )" instead.' );
console.warn( 'THREE.TSL: "rangeFog( color, near, far )" is deprecated. Use "fog( color, rangeFogFactor( near, far ) )" instead.' );
return fog( color, rangeFogFactor( near, far ) );

}
Expand Down
3 changes: 2 additions & 1 deletion src/nodes/lighting/AnalyticLightNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,8 @@ class AnalyticLightNode extends LightingNode {

/**
* Setups the shadow for this light. This method is only executed if the light
* cast shadows and the current build object receives shadows.
* cast shadows and the current build object receives shadows. It incorporates
* shadows into the lighting computation.
*
* @param {NodeBuilder} builder - The current node builder.
*/
Expand Down
113 changes: 111 additions & 2 deletions src/nodes/lighting/LightsNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ import Node from '../core/Node.js';
import { nodeObject, vec3 } from '../tsl/TSLBase.js';
import { hashArray } from '../core/NodeUtils.js';

/** @module LightsNode **/

const sortLights = ( lights ) => {

return lights.sort( ( a, b ) => a.id - b.id );
Expand All @@ -26,6 +28,13 @@ const getLightNodeById = ( id, lightNodes ) => {

const _lightsNodeRef = /*@__PURE__*/ new WeakMap();

/**
* This node represents the scene's lighting and manages the lighting model's life cycle
* for the current build 3D object. It is responsible for computing the total outgoing
* light in a given lighting context.
*
* @augments Node
*/
class LightsNode extends Node {

static get type() {
Expand All @@ -34,29 +43,76 @@ class LightsNode extends Node {

}

/**
* Constructs a new lights node.
*/
constructor() {

super( 'vec3' );

/**
* A node representing the total diffuse light.
*
* @type {Node<vec3>}
*/
this.totalDiffuseNode = vec3().toVar( 'totalDiffuse' );

/**
* A node representing the total specular light.
*
* @type {Node<vec3>}
*/
this.totalSpecularNode = vec3().toVar( 'totalSpecular' );

/**
* A node representing the outgoing light.
*
* @type {Node<vec3>}
*/
this.outgoingLightNode = vec3().toVar( 'outgoingLight' );

/**
* An array representing the lights in the scene.
*
* @private
* @type {Array<Light>}
*/
this._lights = [];

/**
* For each light in the scene, this node will create a
* corresponding light node.
*
* @private
* @type {Array<LightingNode>?}
* @default null
*/
this._lightNodes = null;

/**
* A hash for identifying the current light nodes setup.
*
* @private
* @type {String?}
* @default null
*/
this._lightNodesHash = null;

/**
* `LightsNode` sets this property to `true` by default.
*
* @type {Boolean}
* @default true
*/
this.global = true;

}

/**
* Overwrites the default `customCacheKey()` implementation by including the
* Overwrites the default {@link Node#customCacheKey} implementation by including the
* light IDs into the cache key.
*
* @return {Number} The hash.
* @return {Number} The custom cache key.
*/
customCacheKey() {

Expand All @@ -72,6 +128,12 @@ class LightsNode extends Node {

}

/**
* Computes a hash value for identifying the current light nodes setup.
*
* @param {NodeBuilder} builder - A reference to the current node builder.
* @return {String} The computed hash.
*/
getHash( builder ) {

if ( this._lightNodesHash === null ) {
Expand Down Expand Up @@ -106,6 +168,12 @@ class LightsNode extends Node {

}

/**
* Creates lighting nodes for each scene light. This makes it possible to further
* process lights in the node system.
*
* @param {NodeBuilder} builder - A reference to the current node builder.
*/
setupLightsNode( builder ) {

const lightNodes = [];
Expand Down Expand Up @@ -133,6 +201,8 @@ class LightsNode extends Node {

if ( lightNode === null ) {

// find the corresponding node type for a given light

const lightNodeClass = nodeLibrary.getLightNodeClass( light.constructor );

if ( lightNodeClass === null ) {
Expand Down Expand Up @@ -167,6 +237,13 @@ class LightsNode extends Node {

}

/**
* Setups the internal lights by building all respective
* light nodes.
*
* @param {NodeBuilder} builder - A reference to the current node builder.
* @param {Array<LightingNode>} lightNodes - An array of lighting nodes.
*/
setupLights( builder, lightNodes ) {

for ( const lightNode of lightNodes ) {
Expand All @@ -177,6 +254,14 @@ class LightsNode extends Node {

}

/**
* The implementation makes sure that for each light in the scene
* there is a corresponding light node. By building the light nodes
* and evaluating the lighting model the outgoing light is computed.
*
* @param {NodeBuilder} builder - A reference to the current node builder.
* @return {Node<vec3>} A node representing the outgoing light.
*/
setup( builder ) {

if ( this._lightNodes === null ) this.setupLightsNode( builder );
Expand Down Expand Up @@ -253,6 +338,12 @@ class LightsNode extends Node {

}

/**
* Configures this node with an array of lights.
*
* @param {Array<Light>} lights - An array of lights.
* @return {LightsNode} A reference to this node.
*/
setLights( lights ) {

this._lights = lights;
Expand All @@ -264,12 +355,22 @@ class LightsNode extends Node {

}

/**
* Returns an array of the scene's lights.
*
* @return {Array<Light>} The scene's lights.
*/
getLights() {

return this._lights;

}

/**
* Whether the scene has lights or not.
*
* @type {Boolean}
*/
get hasLights() {

return this._lights.length > 0;
Expand All @@ -280,4 +381,12 @@ class LightsNode extends Node {

export default LightsNode;

/**
* Factory method for creating an instance of `LightsNode` and configuring
* it with the given array of lights.
*
* @method
* @param {Array<Light>} lights - An array of lights.
* @return {LightsNode} The created lights node.
*/
export const lights = ( lights = [] ) => nodeObject( new LightsNode() ).setLights( lights );
50 changes: 50 additions & 0 deletions src/nodes/lighting/ShadowBaseNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,17 @@ import { NodeUpdateType } from '../core/constants.js';
import { vec3 } from '../tsl/TSLBase.js';
import { positionWorld } from '../accessors/Position.js';

/** @module ShadowBaseNode **/

/**
* Base class for all shadow nodes.
*
* Shadow nodes encapsulate shadow related logic and are always coupled to lighting nodes.
* Lighting nodes might share the same shadow node type or use specific ones depending on
* their requirements.
*
* @augments Node
*/
class ShadowBaseNode extends Node {

static get type() {
Expand All @@ -11,17 +22,46 @@ class ShadowBaseNode extends Node {

}

/**
* Constructs a new shadow base node.
*
* @param {Light} light - The shadow casting light.
*/
constructor( light ) {

super();

/**
* The shadow casting light.
*
* @type {Light}
*/
this.light = light;

/**
* Overwritten since shadows are updated by default per render.
*
* @type {String}
* @default 'render'
*/
this.updateBeforeType = NodeUpdateType.RENDER;

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

}

/**
* Setups the shadow position node which is by default the predefined TSL node object `shadowWorldPosition`.
*
* @param {(NodeBuilder|{material})} object - A configuration object that must at least hold a material reference.
*/
setupShadowPosition( { material } ) {

// Use assign inside an Fn()
Expand All @@ -30,6 +70,11 @@ class ShadowBaseNode extends Node {

}

/**
* Can be called when the shadow isn't required anymore. That can happen when
* a lighting node stops casting shadows by setting {@link Object3D#castShadow}
* to `false`.
*/
dispose() {

this.updateBeforeType = NodeUpdateType.NONE;
Expand All @@ -38,6 +83,11 @@ class ShadowBaseNode extends Node {

}

/**
* Represents the vertex position in world space during the shadow pass.
*
* @type {Node<vec3>}
*/
export const shadowWorldPosition = /*@__PURE__*/ vec3().toVar( 'shadowWorldPosition' );

export default ShadowBaseNode;
Loading

0 comments on commit 0eae292

Please sign in to comment.