| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- import Node from '../core/Node.js';
- import { NodeUpdateType } from '../core/constants.js';
- import { uniform } from '../core/UniformNode.js';
- import { Fn, nodeImmutable, vec2 } from '../tsl/TSLBase.js';
- import { Vector2 } from '../../math/Vector2.js';
- import { Vector4 } from '../../math/Vector4.js';
- let _screenSizeVec, _viewportVec;
- /**
- * This node provides a collection of screen related metrics.
- * Depending on {@link ScreenNode#scope}, the nodes can represent
- * resolution or viewport data as well as fragment or uv coordinates.
- *
- * @augments Node
- */
- class ScreenNode extends Node {
- static get type() {
- return 'ScreenNode';
- }
- /**
- * Constructs a new screen node.
- *
- * @param {('coordinate'|'viewport'|'size'|'uv'|'dpr')} scope - The node's scope.
- */
- constructor( scope ) {
- super();
- /**
- * The node represents different metric depending on which scope is selected.
- *
- * - `ScreenNode.COORDINATE`: Window-relative coordinates of the current fragment according to WebGPU standards.
- * - `ScreenNode.VIEWPORT`: The current viewport defined as a four-dimensional vector.
- * - `ScreenNode.SIZE`: The dimensions of the current bound framebuffer.
- * - `ScreenNode.UV`: Normalized coordinates.
- * - `ScreenNode.DPR`: Device pixel ratio.
- *
- * @type {('coordinate'|'viewport'|'size'|'uv'|'dpr')}
- */
- this.scope = scope;
- /**
- * This output node.
- *
- * @type {?Node}
- * @default null
- */
- this._output = null;
- /**
- * This flag can be used for type testing.
- *
- * @type {boolean}
- * @readonly
- * @default true
- */
- this.isViewportNode = true;
- }
- /**
- * This method is overwritten since the node type depends on the selected scope.
- *
- * @return {('float'|'vec2'|'vec4')} The node type.
- */
- getNodeType() {
- if ( this.scope === ScreenNode.DPR ) return 'float';
- if ( this.scope === ScreenNode.VIEWPORT ) return 'vec4';
- else return 'vec2';
- }
- /**
- * This method is overwritten since the node's update type depends on the selected scope.
- *
- * @return {NodeUpdateType} The update type.
- */
- getUpdateType() {
- let updateType = NodeUpdateType.NONE;
- if ( this.scope === ScreenNode.SIZE || this.scope === ScreenNode.VIEWPORT || this.scope === ScreenNode.DPR ) {
- updateType = NodeUpdateType.RENDER;
- }
- this.updateType = updateType;
- return updateType;
- }
- /**
- * `ScreenNode` implements {@link Node#update} to retrieve viewport and size information
- * from the current renderer.
- *
- * @param {NodeFrame} frame - A reference to the current node frame.
- */
- update( { renderer } ) {
- const renderTarget = renderer.getRenderTarget();
- if ( this.scope === ScreenNode.VIEWPORT ) {
- if ( renderTarget !== null ) {
- _viewportVec.copy( renderTarget.viewport );
- } else {
- renderer.getViewport( _viewportVec );
- _viewportVec.multiplyScalar( renderer.getPixelRatio() );
- }
- } else if ( this.scope === ScreenNode.DPR ) {
- this._output.value = renderer.getPixelRatio();
- } else {
- if ( renderTarget !== null ) {
- _screenSizeVec.width = renderTarget.width;
- _screenSizeVec.height = renderTarget.height;
- } else {
- renderer.getDrawingBufferSize( _screenSizeVec );
- }
- }
- }
- setup( /*builder*/ ) {
- const scope = this.scope;
- let output = null;
- if ( scope === ScreenNode.SIZE ) {
- output = uniform( _screenSizeVec || ( _screenSizeVec = new Vector2() ) );
- } else if ( scope === ScreenNode.VIEWPORT ) {
- output = uniform( _viewportVec || ( _viewportVec = new Vector4() ) );
- } else if ( scope === ScreenNode.DPR ) {
- output = uniform( 1 );
- } else {
- output = vec2( screenCoordinate.div( screenSize ) );
- }
- this._output = output;
- return output;
- }
- generate( builder ) {
- if ( this.scope === ScreenNode.COORDINATE ) {
- let coord = builder.getFragCoord();
- if ( builder.isFlipY() ) {
- // follow webgpu standards
- const size = builder.getNodeProperties( screenSize ).outputNode.build( builder );
- coord = `${ builder.getType( 'vec2' ) }( ${ coord }.x, ${ size }.y - ${ coord }.y )`;
- }
- return coord;
- }
- return super.generate( builder );
- }
- }
- ScreenNode.COORDINATE = 'coordinate';
- ScreenNode.VIEWPORT = 'viewport';
- ScreenNode.SIZE = 'size';
- ScreenNode.UV = 'uv';
- ScreenNode.DPR = 'dpr';
- export default ScreenNode;
- // Screen
- /**
- * TSL object that represents the current DPR.
- *
- * @tsl
- * @type {ScreenNode<float>}
- */
- export const screenDPR = /*@__PURE__*/ nodeImmutable( ScreenNode, ScreenNode.DPR );
- /**
- * TSL object that represents normalized screen coordinates, unitless in `[0, 1]`.
- *
- * @tsl
- * @type {ScreenNode<vec2>}
- */
- export const screenUV = /*@__PURE__*/ nodeImmutable( ScreenNode, ScreenNode.UV );
- /**
- * TSL object that represents the screen resolution in physical pixel units.
- *
- * @tsl
- * @type {ScreenNode<vec2>}
- */
- export const screenSize = /*@__PURE__*/ nodeImmutable( ScreenNode, ScreenNode.SIZE );
- /**
- * TSL object that represents the current `x`/`y` pixel position on the screen in physical pixel units.
- *
- * @tsl
- * @type {ScreenNode<vec2>}
- */
- export const screenCoordinate = /*@__PURE__*/ nodeImmutable( ScreenNode, ScreenNode.COORDINATE );
- // Viewport
- /**
- * TSL object that represents the viewport rectangle as `x`, `y`, `width` and `height` in physical pixel units.
- *
- * @tsl
- * @type {ScreenNode<vec4>}
- */
- export const viewport = /*@__PURE__*/ nodeImmutable( ScreenNode, ScreenNode.VIEWPORT );
- /**
- * TSL object that represents the viewport resolution in physical pixel units.
- *
- * @tsl
- * @type {ScreenNode<vec2>}
- */
- export const viewportSize = viewport.zw;
- /**
- * TSL object that represents the current `x`/`y` pixel position on the viewport in physical pixel units.
- *
- * @tsl
- * @type {ScreenNode<vec2>}
- */
- export const viewportCoordinate = /*@__PURE__*/ screenCoordinate.sub( viewport.xy );
- /**
- * TSL object that represents normalized viewport coordinates, unitless in `[0, 1]`.
- *
- * @tsl
- * @type {ScreenNode<vec2>}
- */
- export const viewportUV = /*@__PURE__*/ viewportCoordinate.div( viewportSize );
- // Deprecated
- /**
- * @deprecated since r169. Use {@link screenSize} instead.
- */
- export const viewportResolution = /*@__PURE__*/ ( Fn( () => { // @deprecated, r169
- console.warn( 'THREE.TSL: "viewportResolution" is deprecated. Use "screenSize" instead.' );
- return screenSize;
- }, 'vec2' ).once() )();
|