diff --git a/src/renderers/common/Animation.js b/src/renderers/common/Animation.js index ae626f97e21382..9e8ea24ba878c1 100644 --- a/src/renderers/common/Animation.js +++ b/src/renderers/common/Animation.js @@ -1,16 +1,63 @@ + +/** + * This module manages the internal animation loop of the renderer. + * + * @private + */ class Animation { + /** + * Constructs a new animation loop management component. + * + * @param {Nodes} nodes - Renderer component for managing nodes relatd logic. + * @param {Info} info - Renderer component for managing metrics and monitoring data. + */ constructor( nodes, info ) { + /** + * Renderer component for managing nodes relatd logic. + * + * @type {Nodes} + */ this.nodes = nodes; + + /** + * Renderer component for managing metrics and monitoring data. + * + * @type {Info} + */ this.info = info; + /** + * A reference to the context from `requestAnimationFrame()` can + * be called (usually `window`). + * + * @type {Window|XRSession} + */ this._context = self; + + /** + * The user-defined animation loop. + * + * @type {Function?} + * @default null + */ this._animationLoop = null; + + /** + * The requestId whic is returned from the `requestAnimationFrame()` call. + * Can be used to cancel the stop the animation loop. + * + * @type {Number?} + * @default null + */ this._requestId = null; } + /** + * Starts the internal animation loop. + */ start() { const update = ( time, frame ) => { @@ -31,6 +78,9 @@ class Animation { } + /** + * Stops the internal animation loop. + */ stop() { this._context.cancelAnimationFrame( this._requestId ); @@ -39,18 +89,31 @@ class Animation { } + /** + * Defines the user-level animation loop. + * + * @param {Function} callback - The animation loop. + */ setAnimationLoop( callback ) { this._animationLoop = callback; } + /** + * Defines the context in which `requestAnimationFrame()` is executed. + * + * @param {Window|XRSession} context - The context to set. + */ setContext( context ) { this._context = context; } + /** + * Frees all internal resources and stops the animation loop. + */ dispose() { this.stop(); diff --git a/src/renderers/common/Attributes.js b/src/renderers/common/Attributes.js index 0f80a46fe72619..d0cd8fcb21ab0c 100644 --- a/src/renderers/common/Attributes.js +++ b/src/renderers/common/Attributes.js @@ -3,16 +3,38 @@ import { AttributeType } from './Constants.js'; import { DynamicDrawUsage } from '../../constants.js'; +/** + * This renderer module manages geometry attributes. + * + * @private + * @augments DataMap + */ class Attributes extends DataMap { + /** + * Constructs a new attribute management component. + * + * @param {Backend} backend - The renderer's backend. + */ constructor( backend ) { super(); + /** + * The renderer's backend. + * + * @type {Backend} + */ this.backend = backend; } + /** + * Deletes the data for the given attribute. + * + * @param {BufferAttribute} attribute - The attribute. + * @return {Object} The deleted attribute data. + */ delete( attribute ) { const attributeData = super.delete( attribute ); @@ -27,6 +49,13 @@ class Attributes extends DataMap { } + /** + * Updates the given attribute. This method creates attribute buffers + * for new attributes and updates data for existing ones. + * + * @param {BufferAttribute} attribute - The attribute to update. + * @param {Number} type - The attribute type. + */ update( attribute, type ) { const data = this.get( attribute ); @@ -69,6 +98,13 @@ class Attributes extends DataMap { } + /** + * Utility method for handling interleaved buffer attributes correctly. + * To process them, their `InterleavedBuffer` is returned. + * + * @param {BufferAttribute} attribute - The attribute. + * @return {BufferAttribute|InterleavedBuffer} + */ _getBufferAttribute( attribute ) { if ( attribute.isInterleavedBufferAttribute ) attribute = attribute.data; diff --git a/src/renderers/common/Background.js b/src/renderers/common/Background.js index 5d396412ed76bc..18699602c121e3 100644 --- a/src/renderers/common/Background.js +++ b/src/renderers/common/Background.js @@ -9,17 +9,50 @@ import { BackSide, LinearSRGBColorSpace } from '../../constants.js'; const _clearColor = /*@__PURE__*/ new Color4(); +/** + * This renderer module manages the background. + * + * @private + * @augments DataMap + */ class Background extends DataMap { + /** + * Constructs a new background management component. + * + * @param {Renderer} renderer - The renderer. + * @param {Nodes} nodes - Renderer component for managing nodes relatd logic. + */ constructor( renderer, nodes ) { super(); + /** + * The renderer. + * + * @type {Renderer} + */ this.renderer = renderer; + + /** + * Renderer component for managing nodes relatd logic. + * + * @type {Nodes} + */ this.nodes = nodes; } + /** + * Updates the background for the given scene. Depending on how `Scene.background` + * or `Scene.backgroundNode` are configured, this method might configure a simple clear + * or add a mesh to the render list for rendering the background as a textured plane + * or skybox. + * + * @param {Scene} scene - The scene. + * @param {RenderList} renderList - The current render list. + * @param {RenderContext} renderContext - The current render context. + */ update( scene, renderList, renderContext ) { const renderer = this.renderer; diff --git a/src/renderers/common/BundleGroup.js b/src/renderers/common/BundleGroup.js index 9b2dff9f2888ad..448849596dc6cc 100644 --- a/src/renderers/common/BundleGroup.js +++ b/src/renderers/common/BundleGroup.js @@ -1,20 +1,77 @@ import { Group } from '../../objects/Group.js'; +/** + * A specialized group which eanbles applications access to the + * Render Bundle API of WebGPU. The group with all its descendant nodes + * are considered as one render bundle and processed as such by + * the renderer. + * + * This module is only fully supported by `WebGPURenderer` with a WebGPU backend. + * With a WebGL backend, the group can technically be rendered but without + * any performance improvements. + * + * @augments Group + */ class BundleGroup extends Group { + /** + * Constructs a new bundle group. + */ constructor() { super(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isBundleGroup = true; + /** + * This property is only relevant for detecting types + * during serialization/deserialization. It should always + * match the class name. + * + * @type {String} + * @readonly + * @default 'BundleGroup' + */ this.type = 'BundleGroup'; + /** + * Whether the bundle is static or not. When set to `true`, the structure + * is assumed to be static and does not change. E.g. no new objects are + * added to the group + * + * If a change is required, an update can still be forced by setting the + * `needsUpdate` flag to `true`. + * + * @type {Boolean} + * @default true + */ this.static = true; + + /** + * The bundle group's version. + * + * @type {Number} + * @readonly + * @default 0 + */ this.version = 0; } + /** + * Set this property to `true` when the bundle group has changed. + * + * @type {Boolean} + * @default false + * @param {Boolean} value + */ set needsUpdate( value ) { if ( value === true ) this.version ++; diff --git a/src/renderers/common/ChainMap.js b/src/renderers/common/ChainMap.js index 5a3bbface0e481..92292261625096 100644 --- a/src/renderers/common/ChainMap.js +++ b/src/renderers/common/ChainMap.js @@ -1,11 +1,33 @@ +/** + * Data structure for the renderer. It allows defining values + * with chained, hierarchical keys. Keys are meant to be + * objects since the module internally works with Weak Maps + * for perforamnce reasons. + * + * @private + */ export default class ChainMap { + /** + * Constructs a new chained map. + */ constructor() { + /** + * The root Weak Map. + * + * @type {WeakMap} + */ this.weakMap = new WeakMap(); } + /** + * Returns the value for the given array of keys. + * + * @param {Array} keys - List of keys. + * @return {Any} The value. Returns `undefined` if no value was found. + */ get( keys ) { let map = this.weakMap; @@ -22,6 +44,13 @@ export default class ChainMap { } + /** + * Sets the value for the given keys. + * + * @param {Array} keys - List of keys. + * @param {Any} value - The value to set. + * @return {ChainMap} A reference to this chain map. + */ set( keys, value ) { let map = this.weakMap; @@ -36,10 +65,18 @@ export default class ChainMap { } - return map.set( keys[ keys.length - 1 ], value ); + map.set( keys[ keys.length - 1 ], value ); + + return this; } + /** + * Deletes a value for the given keys. + * + * @param {Array} keys - The keys. + * @return {Boolean} Returns `true` if the value has been removed successfully and `false` if the value has not be found. + */ delete( keys ) { let map = this.weakMap; diff --git a/src/renderers/common/Color4.js b/src/renderers/common/Color4.js index 86c58b1d216f69..cc80f77fa64955 100644 --- a/src/renderers/common/Color4.js +++ b/src/renderers/common/Color4.js @@ -1,7 +1,23 @@ import { Color } from '../../math/Color.js'; +/** + * A four-component version of {@link Color} which is internally + * used by the renderer to represents clear color with alpha as + * one object. + * + * @private + * @augments Color + */ class Color4 extends Color { + /** + * Constructs a new four-component color. + * + * @param {Number|String} r - The red value. + * @param {Number} g - The green value. + * @param {Number} b - The blue value. + * @param {Number} [a=1] - The alpha value. + */ constructor( r, g, b, a = 1 ) { super( r, g, b ); @@ -10,6 +26,15 @@ class Color4 extends Color { } + /** + * Overwrites the default to honor alpha. + * + * @param {Number|String} r - The red value. + * @param {Number} g - The green value. + * @param {Number} b - The blue value. + * @param {Number} [a=1] - The alpha value. + * @return {Color4} A reference to this object. + */ set( r, g, b, a = 1 ) { this.a = a; @@ -18,6 +43,12 @@ class Color4 extends Color { } + /** + * Overwrites the default to honor alpha. + * + * @param {Color4} color - The color to copy. + * @return {Color4} A reference to this object. + */ copy( color ) { if ( color.a !== undefined ) this.a = color.a; @@ -26,6 +57,11 @@ class Color4 extends Color { } + /** + * Overwrites the default to honor alpha. + * + * @return {Color4} The cloned color. + */ clone() { return new this.constructor( this.r, this.g, this.b, this.a ); diff --git a/src/renderers/common/DataMap.js b/src/renderers/common/DataMap.js index 28e05d1c46edcd..1316c0f1c2d2a3 100644 --- a/src/renderers/common/DataMap.js +++ b/src/renderers/common/DataMap.js @@ -1,11 +1,32 @@ +/** + * Data structure for the renderer. It is intended to manage + * data of objects in dictionaries. + * + * @private + */ class DataMap { + /** + * Constructs a new data map. + */ constructor() { + /** + * `DataMap` internally uses a weak map + * to manage its data. + * + * @type {WeakMap} + */ this.data = new WeakMap(); } + /** + * Returns the dictionary for the given object. + * + * @param {Object} object - The object. + * @return {Object} The dictionary. + */ get( object ) { let map = this.data.get( object ); @@ -21,9 +42,15 @@ class DataMap { } + /** + * Deletes the dictionary for the given object. + * + * @param {Object} object - The object. + * @return {Object?} The deleted dictionary. + */ delete( object ) { - let map; + let map = null; if ( this.data.has( object ) ) { @@ -37,12 +64,21 @@ class DataMap { } + /** + * Returns `true` if the given object has a dictionary defined. + * + * @param {Object} object - The object to test. + * @return {Boolean} Whether a dictionary is defined or not. + */ has( object ) { return this.data.has( object ); } + /** + * Frees internal resources. + */ dispose() { this.data = new WeakMap(); diff --git a/src/renderers/common/RenderBundle.js b/src/renderers/common/RenderBundle.js index e84c0ad0de8d5c..84598acb067dd2 100644 --- a/src/renderers/common/RenderBundle.js +++ b/src/renderers/common/RenderBundle.js @@ -1,18 +1,24 @@ +/** + * This module is used to represent render bundles inside the renderer + * for further processing. + * + * @private + */ class RenderBundle { - constructor( scene, camera ) { + /** + * Constructs a new bundle group. + * + * @param {BundleGroup} bundleGroup - The bundle group. + * @param {Camera} camera - The camera the bundle group is rendered with. + */ + constructor( bundleGroup, camera ) { - this.scene = scene; + this.bundleGroup = bundleGroup; this.camera = camera; } - clone() { - - return Object.assign( new this.constructor(), this ); - - } - } export default RenderBundle; diff --git a/src/renderers/common/RenderBundles.js b/src/renderers/common/RenderBundles.js index 66045184139de4..a53a7250de2913 100644 --- a/src/renderers/common/RenderBundles.js +++ b/src/renderers/common/RenderBundles.js @@ -1,35 +1,58 @@ import ChainMap from './ChainMap.js'; import RenderBundle from './RenderBundle.js'; +/** + * This renderer module manages render bundles. + * + * @private + */ class RenderBundles { + /** + * Constructs a new render bundle management component. + */ constructor() { - this.lists = new ChainMap(); + /** + * A chain map for maintaining the render bundles. + * + * @type {ChainMap} + */ + this.bundles = new ChainMap(); } - get( scene, camera ) { + /** + * Returns a render bundle for the given bundle group and camera. + * + * @param {BundleGroup} bundleGroup - The bundle group. + * @param {Camera} camera - The camera the bundle group is rendered with. + * @return {RenderBundle} The render bundle. + */ + get( bundleGroup, camera ) { - const lists = this.lists; - const keys = [ scene, camera ]; + const bundles = this.bundles; + const keys = [ bundleGroup, camera ]; - let list = lists.get( keys ); + let bundle = bundles.get( keys ); - if ( list === undefined ) { + if ( bundle === undefined ) { - list = new RenderBundle( scene, camera ); - lists.set( keys, list ); + bundle = new RenderBundle( bundleGroup, camera ); + bundles.set( keys, bundle ); } - return list; + return bundle; } + /** + * Frees all internal resources. + */ dispose() { - this.lists = new ChainMap(); + this.bundles = new ChainMap(); } diff --git a/src/renderers/common/Renderer.js b/src/renderers/common/Renderer.js index 96b6f3ccbdee3a..f75916c66a03e4 100644 --- a/src/renderers/common/Renderer.js +++ b/src/renderers/common/Renderer.js @@ -1003,7 +1003,7 @@ class Renderer { * Renders the given render bundle. * * @private - * @param {RenderBundle} bundle - The render bundle. + * @param {Object} bundle - Render bundle data. * @param {Scene} sceneRef - The scene the render bundle belongs to. * @param {LightsNode} lightsNode - The current lights node. */ @@ -2508,7 +2508,7 @@ class Renderer { * Renders the given render bundles. * * @private - * @param {Array} bundles - The render bundles. + * @param {Array} bundles - Array with render bundle data. * @param {Scene} sceneRef - The scene the render bundles belong to. * @param {LightsNode} lightsNode - The current lights node. */ diff --git a/src/renderers/webgpu/WebGPURenderer.Nodes.js b/src/renderers/webgpu/WebGPURenderer.Nodes.js index 2f2dae57f561af..d5c7c18a69e499 100644 --- a/src/renderers/webgpu/WebGPURenderer.Nodes.js +++ b/src/renderers/webgpu/WebGPURenderer.Nodes.js @@ -3,8 +3,28 @@ import WebGLBackend from '../webgl-fallback/WebGLBackend.js'; import WebGPUBackend from './WebGPUBackend.js'; import BasicNodeLibrary from './nodes/BasicNodeLibrary.js'; +/** + * This alternative version of {@link WebGPURenderer} only supports node materials. + * So classes like `MeshBasicMaterial` are not compatible. + * + * @augments module:Renderer~Renderer + */ class WebGPURenderer extends Renderer { + /** + * Constructs a new WebGPU renderer. + * + * @param {Object} parameters - The configuration parameter. + * @param {Boolean} [parameters.logarithmicDepthBuffer=false] - Whether logarithmic depth buffer is enabled or not. + * @param {Boolean} [parameters.alpha=true] - Whether the default framebuffer (which represents the final contents of the canvas) should be transparent or opaque. + * @param {Boolean} [parameters.depth=true] - Whether the default framebuffer should have a depth buffer or not. + * @param {Boolean} [parameters.stencil=false] - Whether the default framebuffer should have a stencil buffer or not. + * @param {Boolean} [parameters.antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not. + * @param {Number} [parameters.samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 + * to overwrite the default. + * @param {Boolean} [parameters.forceWebGL=false] - If set to `true`, the renderer uses it + * WebGL 2 backend no matter if WebGPU is supported or not. + */ constructor( parameters = {} ) { let BackendClass; @@ -31,8 +51,22 @@ class WebGPURenderer extends Renderer { super( backend, parameters ); + /** + * The generic default value is overwritten with the + * standard node library for type mapping. Material + * mapping is not supported with this version. + * + * @type {BasicNodeLibrary} + */ this.library = new BasicNodeLibrary(); + /** + * This flag can be used for type testing. + * + * @type {Boolean} + * @readonly + * @default true + */ this.isWebGPURenderer = true; }