Buckets:
| import TempNode from '../core/TempNode.js'; | |
| import { default as TextureNode/*, texture*/ } from '../accessors/TextureNode.js'; | |
| import { NodeUpdateType } from '../core/constants.js'; | |
| import { nodeObject } from '../tsl/TSLBase.js'; | |
| import { uniform } from '../core/UniformNode.js'; | |
| import { viewZToOrthographicDepth, perspectiveDepthToViewZ } from './ViewportDepthNode.js'; | |
| import { HalfFloatType/*, FloatType*/ } from '../../constants.js'; | |
| import { Vector2 } from '../../math/Vector2.js'; | |
| import { DepthTexture } from '../../textures/DepthTexture.js'; | |
| import { RenderTarget } from '../../core/RenderTarget.js'; | |
| const _size = /*@__PURE__*/ new Vector2(); | |
| /** | |
| * Represents the texture of a pass node. | |
| * | |
| * @augments TextureNode | |
| */ | |
| class PassTextureNode extends TextureNode { | |
| static get type() { | |
| return 'PassTextureNode'; | |
| } | |
| /** | |
| * Constructs a new pass texture node. | |
| * | |
| * @param {PassNode} passNode - The pass node. | |
| * @param {Texture} texture - The output texture. | |
| */ | |
| constructor( passNode, texture ) { | |
| super( texture ); | |
| /** | |
| * A reference to the pass node. | |
| * | |
| * @type {PassNode} | |
| */ | |
| this.passNode = passNode; | |
| this.setUpdateMatrix( false ); | |
| } | |
| setup( builder ) { | |
| if ( builder.object.isQuadMesh ) this.passNode.build( builder ); | |
| return super.setup( builder ); | |
| } | |
| clone() { | |
| return new this.constructor( this.passNode, this.value ); | |
| } | |
| } | |
| /** | |
| * An extension of `PassTextureNode` which allows to manage more than one | |
| * internal texture. Relevant for the `getPreviousTexture()` related API. | |
| * | |
| * @augments PassTextureNode | |
| */ | |
| class PassMultipleTextureNode extends PassTextureNode { | |
| static get type() { | |
| return 'PassMultipleTextureNode'; | |
| } | |
| /** | |
| * Constructs a new pass texture node. | |
| * | |
| * @param {PassNode} passNode - The pass node. | |
| * @param {string} textureName - The output texture name. | |
| * @param {boolean} [previousTexture=false] - Whether previous frame data should be used or not. | |
| */ | |
| constructor( passNode, textureName, previousTexture = false ) { | |
| // null is passed to the super call since this class does not | |
| // use an external texture for rendering pass data into. Instead | |
| // the texture is managed by the pass node itself | |
| super( passNode, null ); | |
| /** | |
| * The output texture name. | |
| * | |
| * @type {string} | |
| */ | |
| this.textureName = textureName; | |
| /** | |
| * Whether previous frame data should be used or not. | |
| * | |
| * @type {boolean} | |
| */ | |
| this.previousTexture = previousTexture; | |
| } | |
| /** | |
| * Updates the texture reference of this node. | |
| */ | |
| updateTexture() { | |
| this.value = this.previousTexture ? this.passNode.getPreviousTexture( this.textureName ) : this.passNode.getTexture( this.textureName ); | |
| } | |
| setup( builder ) { | |
| this.updateTexture(); | |
| return super.setup( builder ); | |
| } | |
| clone() { | |
| return new this.constructor( this.passNode, this.textureName, this.previousTexture ); | |
| } | |
| } | |
| /** | |
| * Represents a render pass (sometimes called beauty pass) in context of post processing. | |
| * This pass produces a render for the given scene and camera and can provide multiple outputs | |
| * via MRT for further processing. | |
| * | |
| * ```js | |
| * const postProcessing = new PostProcessing( renderer ); | |
| * | |
| * const scenePass = pass( scene, camera ); | |
| * | |
| * postProcessing.outputNode = scenePass; | |
| * ``` | |
| * | |
| * @augments TempNode | |
| */ | |
| class PassNode extends TempNode { | |
| static get type() { | |
| return 'PassNode'; | |
| } | |
| /** | |
| * Constructs a new pass node. | |
| * | |
| * @param {('color'|'depth')} scope - The scope of the pass. The scope determines whether the node outputs color or depth. | |
| * @param {Scene} scene - A reference to the scene. | |
| * @param {Camera} camera - A reference to the camera. | |
| * @param {Object} options - Options for the internal render target. | |
| */ | |
| constructor( scope, scene, camera, options = {} ) { | |
| super( 'vec4' ); | |
| /** | |
| * The scope of the pass. The scope determines whether the node outputs color or depth. | |
| * | |
| * @type {('color'|'depth')} | |
| */ | |
| this.scope = scope; | |
| /** | |
| * A reference to the scene. | |
| * | |
| * @type {Scene} | |
| */ | |
| this.scene = scene; | |
| /** | |
| * A reference to the camera. | |
| * | |
| * @type {Camera} | |
| */ | |
| this.camera = camera; | |
| /** | |
| * Options for the internal render target. | |
| * | |
| * @type {Object} | |
| */ | |
| this.options = options; | |
| /** | |
| * The pass's pixel ratio. Will be kept automatically kept in sync with the renderer's pixel ratio. | |
| * | |
| * @private | |
| * @type {number} | |
| * @default 1 | |
| */ | |
| this._pixelRatio = 1; | |
| /** | |
| * The pass's pixel width. Will be kept automatically kept in sync with the renderer's width. | |
| * @private | |
| * @type {number} | |
| * @default 1 | |
| */ | |
| this._width = 1; | |
| /** | |
| * The pass's pixel height. Will be kept automatically kept in sync with the renderer's height. | |
| * @private | |
| * @type {number} | |
| * @default 1 | |
| */ | |
| this._height = 1; | |
| const depthTexture = new DepthTexture(); | |
| depthTexture.isRenderTargetTexture = true; | |
| //depthTexture.type = FloatType; | |
| depthTexture.name = 'depth'; | |
| const renderTarget = new RenderTarget( this._width * this._pixelRatio, this._height * this._pixelRatio, { type: HalfFloatType, ...options, } ); | |
| renderTarget.texture.name = 'output'; | |
| renderTarget.depthTexture = depthTexture; | |
| /** | |
| * The pass's render target. | |
| * | |
| * @type {RenderTarget} | |
| */ | |
| this.renderTarget = renderTarget; | |
| /** | |
| * A dictionary holding the internal result textures. | |
| * | |
| * @private | |
| * @type {Object<string, Texture>} | |
| */ | |
| this._textures = { | |
| output: renderTarget.texture, | |
| depth: depthTexture | |
| }; | |
| /** | |
| * A dictionary holding the internal texture nodes. | |
| * | |
| * @private | |
| * @type {Object<string, TextureNode>} | |
| */ | |
| this._textureNodes = {}; | |
| /** | |
| * A dictionary holding the internal depth nodes. | |
| * | |
| * @private | |
| * @type {Object} | |
| */ | |
| this._linearDepthNodes = {}; | |
| /** | |
| * A dictionary holding the internal viewZ nodes. | |
| * | |
| * @private | |
| * @type {Object} | |
| */ | |
| this._viewZNodes = {}; | |
| /** | |
| * A dictionary holding the texture data of the previous frame. | |
| * Used for computing velocity/motion vectors. | |
| * | |
| * @private | |
| * @type {Object<string, Texture>} | |
| */ | |
| this._previousTextures = {}; | |
| /** | |
| * A dictionary holding the texture nodes of the previous frame. | |
| * Used for computing velocity/motion vectors. | |
| * | |
| * @private | |
| * @type {Object<string, TextureNode>} | |
| */ | |
| this._previousTextureNodes = {}; | |
| /** | |
| * The `near` property of the camera as a uniform. | |
| * | |
| * @private | |
| * @type {UniformNode} | |
| */ | |
| this._cameraNear = uniform( 0 ); | |
| /** | |
| * The `far` property of the camera as a uniform. | |
| * | |
| * @private | |
| * @type {UniformNode} | |
| */ | |
| this._cameraFar = uniform( 0 ); | |
| /** | |
| * A MRT node configuring the MRT settings. | |
| * | |
| * @private | |
| * @type {?MRTNode} | |
| * @default null | |
| */ | |
| this._mrt = null; | |
| this._layers = null; | |
| this._resolution = 1; | |
| /** | |
| * This flag can be used for type testing. | |
| * | |
| * @type {boolean} | |
| * @readonly | |
| * @default true | |
| */ | |
| this.isPassNode = true; | |
| /** | |
| * The `updateBeforeType` is set to `NodeUpdateType.FRAME` since the node renders the | |
| * scene once per frame in its {@link PassNode#updateBefore} method. | |
| * | |
| * @type {string} | |
| * @default 'frame' | |
| */ | |
| this.updateBeforeType = NodeUpdateType.FRAME; | |
| } | |
| /** | |
| * Sets the resolution for the pass. | |
| * The resolution is a factor that is multiplied with the renderer's width and height. | |
| * | |
| * @param {number} resolution - The resolution to set. A value of `1` means full resolution. | |
| * @return {PassNode} A reference to this pass. | |
| */ | |
| setResolution( resolution ) { | |
| this._resolution = resolution; | |
| return this; | |
| } | |
| /** | |
| * Gets the current resolution of the pass. | |
| * | |
| * @return {number} The current resolution. A value of `1` means full resolution. | |
| * @default 1 | |
| */ | |
| getResolution() { | |
| return this._resolution; | |
| } | |
| setLayers( layers ) { | |
| this._layers = layers; | |
| return this; | |
| } | |
| getLayers() { | |
| return this._layers; | |
| } | |
| /** | |
| * Sets the given MRT node to setup MRT for this pass. | |
| * | |
| * @param {MRTNode} mrt - The MRT object. | |
| * @return {PassNode} A reference to this pass. | |
| */ | |
| setMRT( mrt ) { | |
| this._mrt = mrt; | |
| return this; | |
| } | |
| /** | |
| * Returns the current MRT node. | |
| * | |
| * @return {MRTNode} The current MRT node. | |
| */ | |
| getMRT() { | |
| return this._mrt; | |
| } | |
| /** | |
| * The method is overwritten so it always returns `true`. | |
| * | |
| * @return {boolean} Whether this node is global or not. | |
| */ | |
| isGlobal() { | |
| return true; | |
| } | |
| /** | |
| * Returns the texture for the given output name. | |
| * | |
| * @param {string} name - The output name to get the texture for. | |
| * @return {Texture} The texture. | |
| */ | |
| getTexture( name ) { | |
| let texture = this._textures[ name ]; | |
| if ( texture === undefined ) { | |
| const refTexture = this.renderTarget.texture; | |
| texture = refTexture.clone(); | |
| texture.name = name; | |
| this._textures[ name ] = texture; | |
| this.renderTarget.textures.push( texture ); | |
| } | |
| return texture; | |
| } | |
| /** | |
| * Returns the texture holding the data of the previous frame for the given output name. | |
| * | |
| * @param {string} name - The output name to get the texture for. | |
| * @return {Texture} The texture holding the data of the previous frame. | |
| */ | |
| getPreviousTexture( name ) { | |
| let texture = this._previousTextures[ name ]; | |
| if ( texture === undefined ) { | |
| texture = this.getTexture( name ).clone(); | |
| this._previousTextures[ name ] = texture; | |
| } | |
| return texture; | |
| } | |
| /** | |
| * Switches current and previous textures for the given output name. | |
| * | |
| * @param {string} name - The output name. | |
| */ | |
| toggleTexture( name ) { | |
| const prevTexture = this._previousTextures[ name ]; | |
| if ( prevTexture !== undefined ) { | |
| const texture = this._textures[ name ]; | |
| const index = this.renderTarget.textures.indexOf( texture ); | |
| this.renderTarget.textures[ index ] = prevTexture; | |
| this._textures[ name ] = prevTexture; | |
| this._previousTextures[ name ] = texture; | |
| this._textureNodes[ name ].updateTexture(); | |
| this._previousTextureNodes[ name ].updateTexture(); | |
| } | |
| } | |
| /** | |
| * Returns the texture node for the given output name. | |
| * | |
| * @param {string} [name='output'] - The output name to get the texture node for. | |
| * @return {TextureNode} The texture node. | |
| */ | |
| getTextureNode( name = 'output' ) { | |
| let textureNode = this._textureNodes[ name ]; | |
| if ( textureNode === undefined ) { | |
| textureNode = nodeObject( new PassMultipleTextureNode( this, name ) ); | |
| textureNode.updateTexture(); | |
| this._textureNodes[ name ] = textureNode; | |
| } | |
| return textureNode; | |
| } | |
| /** | |
| * Returns the previous texture node for the given output name. | |
| * | |
| * @param {string} [name='output'] - The output name to get the previous texture node for. | |
| * @return {TextureNode} The previous texture node. | |
| */ | |
| getPreviousTextureNode( name = 'output' ) { | |
| let textureNode = this._previousTextureNodes[ name ]; | |
| if ( textureNode === undefined ) { | |
| if ( this._textureNodes[ name ] === undefined ) this.getTextureNode( name ); | |
| textureNode = nodeObject( new PassMultipleTextureNode( this, name, true ) ); | |
| textureNode.updateTexture(); | |
| this._previousTextureNodes[ name ] = textureNode; | |
| } | |
| return textureNode; | |
| } | |
| /** | |
| * Returns a viewZ node of this pass. | |
| * | |
| * @param {string} [name='depth'] - The output name to get the viewZ node for. In most cases the default `'depth'` can be used however the parameter exists for custom depth outputs. | |
| * @return {Node} The viewZ node. | |
| */ | |
| getViewZNode( name = 'depth' ) { | |
| let viewZNode = this._viewZNodes[ name ]; | |
| if ( viewZNode === undefined ) { | |
| const cameraNear = this._cameraNear; | |
| const cameraFar = this._cameraFar; | |
| this._viewZNodes[ name ] = viewZNode = perspectiveDepthToViewZ( this.getTextureNode( name ), cameraNear, cameraFar ); | |
| } | |
| return viewZNode; | |
| } | |
| /** | |
| * Returns a linear depth node of this pass. | |
| * | |
| * @param {string} [name='depth'] - The output name to get the linear depth node for. In most cases the default `'depth'` can be used however the parameter exists for custom depth outputs. | |
| * @return {Node} The linear depth node. | |
| */ | |
| getLinearDepthNode( name = 'depth' ) { | |
| let linearDepthNode = this._linearDepthNodes[ name ]; | |
| if ( linearDepthNode === undefined ) { | |
| const cameraNear = this._cameraNear; | |
| const cameraFar = this._cameraFar; | |
| const viewZNode = this.getViewZNode( name ); | |
| // TODO: just if ( builder.camera.isPerspectiveCamera ) | |
| this._linearDepthNodes[ name ] = linearDepthNode = viewZToOrthographicDepth( viewZNode, cameraNear, cameraFar ); | |
| } | |
| return linearDepthNode; | |
| } | |
| setup( { renderer } ) { | |
| this.renderTarget.samples = this.options.samples === undefined ? renderer.samples : this.options.samples; | |
| // TODO: Disable MSAA for WebGL backend for now | |
| if ( renderer.backend.isWebGLBackend === true ) { | |
| this.renderTarget.samples = 0; | |
| } | |
| this.renderTarget.texture.type = renderer.getColorBufferType(); | |
| return this.scope === PassNode.COLOR ? this.getTextureNode() : this.getLinearDepthNode(); | |
| } | |
| updateBefore( frame ) { | |
| const { renderer } = frame; | |
| const { scene } = this; | |
| let camera; | |
| let pixelRatio; | |
| const outputRenderTarget = renderer.getOutputRenderTarget(); | |
| if ( outputRenderTarget && outputRenderTarget.isXRRenderTarget === true ) { | |
| pixelRatio = 1; | |
| camera = renderer.xr.getCamera(); | |
| renderer.xr.updateCamera( camera ); | |
| _size.set( outputRenderTarget.width, outputRenderTarget.height ); | |
| } else { | |
| camera = this.camera; | |
| pixelRatio = renderer.getPixelRatio(); | |
| renderer.getSize( _size ); | |
| } | |
| this._pixelRatio = pixelRatio; | |
| this.setSize( _size.width, _size.height ); | |
| const currentRenderTarget = renderer.getRenderTarget(); | |
| const currentMRT = renderer.getMRT(); | |
| const currentMask = camera.layers.mask; | |
| this._cameraNear.value = camera.near; | |
| this._cameraFar.value = camera.far; | |
| if ( this._layers !== null ) { | |
| camera.layers.mask = this._layers.mask; | |
| } | |
| for ( const name in this._previousTextures ) { | |
| this.toggleTexture( name ); | |
| } | |
| renderer.setRenderTarget( this.renderTarget ); | |
| renderer.setMRT( this._mrt ); | |
| renderer.render( scene, camera ); | |
| renderer.setRenderTarget( currentRenderTarget ); | |
| renderer.setMRT( currentMRT ); | |
| camera.layers.mask = currentMask; | |
| } | |
| /** | |
| * Sets the size of the pass's render target. Honors the pixel ratio. | |
| * | |
| * @param {number} width - The width to set. | |
| * @param {number} height - The height to set. | |
| */ | |
| setSize( width, height ) { | |
| this._width = width; | |
| this._height = height; | |
| const effectiveWidth = this._width * this._pixelRatio * this._resolution; | |
| const effectiveHeight = this._height * this._pixelRatio * this._resolution; | |
| this.renderTarget.setSize( effectiveWidth, effectiveHeight ); | |
| } | |
| /** | |
| * Sets the pixel ratio the pass's render target and updates the size. | |
| * | |
| * @param {number} pixelRatio - The pixel ratio to set. | |
| */ | |
| setPixelRatio( pixelRatio ) { | |
| this._pixelRatio = pixelRatio; | |
| this.setSize( this._width, this._height ); | |
| } | |
| /** | |
| * Frees internal resources. Should be called when the node is no longer in use. | |
| */ | |
| dispose() { | |
| this.renderTarget.dispose(); | |
| } | |
| } | |
| /** | |
| * @static | |
| * @type {'color'} | |
| * @default 'color' | |
| */ | |
| PassNode.COLOR = 'color'; | |
| /** | |
| * @static | |
| * @type {'depth'} | |
| * @default 'depth' | |
| */ | |
| PassNode.DEPTH = 'depth'; | |
| export default PassNode; | |
| /** | |
| * TSL function for creating a pass node. | |
| * | |
| * @tsl | |
| * @function | |
| * @param {Scene} scene - A reference to the scene. | |
| * @param {Camera} camera - A reference to the camera. | |
| * @param {Object} options - Options for the internal render target. | |
| * @returns {PassNode} | |
| */ | |
| export const pass = ( scene, camera, options ) => nodeObject( new PassNode( PassNode.COLOR, scene, camera, options ) ); | |
| /** | |
| * TSL function for creating a pass texture node. | |
| * | |
| * @tsl | |
| * @function | |
| * @param {PassNode} pass - The pass node. | |
| * @param {Texture} texture - The output texture. | |
| * @returns {PassTextureNode} | |
| */ | |
| export const passTexture = ( pass, texture ) => nodeObject( new PassTextureNode( pass, texture ) ); | |
| /** | |
| * TSL function for creating a depth pass node. | |
| * | |
| * @tsl | |
| * @function | |
| * @param {Scene} scene - A reference to the scene. | |
| * @param {Camera} camera - A reference to the camera. | |
| * @param {Object} options - Options for the internal render target. | |
| * @returns {PassNode} | |
| */ | |
| export const depthPass = ( scene, camera, options ) => nodeObject( new PassNode( PassNode.DEPTH, scene, camera, options ) ); | |
Xet Storage Details
- Size:
- 16.5 kB
- Xet hash:
- e553a51703d5462cee9422c82836bae39813f81939774a857c21896406219b25
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.