three
Version:
JavaScript 3D library
342 lines (257 loc) • 7.96 kB
JavaScript
import { EventDispatcher } from '../../core/EventDispatcher.js';
import { Vector4 } from '../../math/Vector4.js';
import { FramebufferTexture } from '../../textures/FramebufferTexture.js';
import { DepthTexture } from '../../textures/DepthTexture.js';
/**
* CanvasTarget is a class that represents the final output destination of the renderer.
*
* @augments EventDispatcher
*/
class CanvasTarget extends EventDispatcher {
/**
* Constructs a new CanvasTarget.
*
* @param {HTMLCanvasElement|OffscreenCanvas} domElement - The canvas element to render to.
*/
constructor( domElement ) {
super();
/**
* A reference to the canvas element the renderer is drawing to.
* This value of this property will automatically be created by
* the renderer.
*
* @type {HTMLCanvasElement|OffscreenCanvas}
*/
this.domElement = domElement;
/**
* The renderer's pixel ratio.
*
* @private
* @type {number}
* @default 1
*/
this._pixelRatio = 1;
/**
* The width of the renderer's default framebuffer in logical pixel unit.
*
* @private
* @type {number}
*/
this._width = this.domElement.width;
/**
* The height of the renderer's default framebuffer in logical pixel unit.
*
* @private
* @type {number}
*/
this._height = this.domElement.height;
/**
* The viewport of the renderer in logical pixel unit.
*
* @private
* @type {Vector4}
*/
this._viewport = new Vector4( 0, 0, this._width, this._height );
/**
* The scissor rectangle of the renderer in logical pixel unit.
*
* @private
* @type {Vector4}
*/
this._scissor = new Vector4( 0, 0, this._width, this._height );
/**
* Whether the scissor test should be enabled or not.
*
* @private
* @type {boolean}
*/
this._scissorTest = false;
/**
* The color texture of the default framebuffer.
*
* @type {FramebufferTexture}
*/
this.colorTexture = new FramebufferTexture();
/**
* The depth texture of the default framebuffer.
*
* @type {DepthTexture}
*/
this.depthTexture = new DepthTexture();
}
/**
* Returns the pixel ratio.
*
* @return {number} The pixel ratio.
*/
getPixelRatio() {
return this._pixelRatio;
}
/**
* Returns the drawing buffer size in physical pixels. This method honors the pixel ratio.
*
* @param {Vector2} target - The method writes the result in this target object.
* @return {Vector2} The drawing buffer size.
*/
getDrawingBufferSize( target ) {
return target.set( this._width * this._pixelRatio, this._height * this._pixelRatio ).floor();
}
/**
* Returns the renderer's size in logical pixels. This method does not honor the pixel ratio.
*
* @param {Vector2} target - The method writes the result in this target object.
* @return {Vector2} The renderer's size in logical pixels.
*/
getSize( target ) {
return target.set( this._width, this._height );
}
/**
* Sets the given pixel ratio and resizes the canvas if necessary.
*
* @param {number} [value=1] - The pixel ratio.
*/
setPixelRatio( value = 1 ) {
if ( this._pixelRatio === value ) return;
this._pixelRatio = value;
this.setSize( this._width, this._height, false );
}
/**
* This method allows to define the drawing buffer size by specifying
* width, height and pixel ratio all at once. The size of the drawing
* buffer is computed with this formula:
* ```js
* size.x = width * pixelRatio;
* size.y = height * pixelRatio;
* ```
*
* @param {number} width - The width in logical pixels.
* @param {number} height - The height in logical pixels.
* @param {number} pixelRatio - The pixel ratio.
*/
setDrawingBufferSize( width, height, pixelRatio ) {
// Renderer can't be resized while presenting in XR.
if ( this.xr && this.xr.isPresenting ) return;
this._width = width;
this._height = height;
this._pixelRatio = pixelRatio;
this.domElement.width = Math.floor( width * pixelRatio );
this.domElement.height = Math.floor( height * pixelRatio );
this.setViewport( 0, 0, width, height );
this._dispatchResize();
}
/**
* Sets the size of the renderer.
*
* @param {number} width - The width in logical pixels.
* @param {number} height - The height in logical pixels.
* @param {boolean} [updateStyle=true] - Whether to update the `style` attribute of the canvas or not.
*/
setSize( width, height, updateStyle = true ) {
// Renderer can't be resized while presenting in XR.
if ( this.xr && this.xr.isPresenting ) return;
this._width = width;
this._height = height;
this.domElement.width = Math.floor( width * this._pixelRatio );
this.domElement.height = Math.floor( height * this._pixelRatio );
if ( updateStyle === true ) {
this.domElement.style.width = width + 'px';
this.domElement.style.height = height + 'px';
}
this.setViewport( 0, 0, width, height );
this._dispatchResize();
}
/**
* Returns the scissor rectangle.
*
* @param {Vector4} target - The method writes the result in this target object.
* @return {Vector4} The scissor rectangle.
*/
getScissor( target ) {
const scissor = this._scissor;
target.x = scissor.x;
target.y = scissor.y;
target.width = scissor.width;
target.height = scissor.height;
return target;
}
/**
* Defines the scissor rectangle.
*
* @param {number | Vector4} x - The horizontal coordinate for the lower left corner of the box in logical pixel unit.
* Instead of passing four arguments, the method also works with a single four-dimensional vector.
* @param {number} y - The vertical coordinate for the lower left corner of the box in logical pixel unit.
* @param {number} width - The width of the scissor box in logical pixel unit.
* @param {number} height - The height of the scissor box in logical pixel unit.
*/
setScissor( x, y, width, height ) {
const scissor = this._scissor;
if ( x.isVector4 ) {
scissor.copy( x );
} else {
scissor.set( x, y, width, height );
}
}
/**
* Returns the scissor test value.
*
* @return {boolean} Whether the scissor test should be enabled or not.
*/
getScissorTest() {
return this._scissorTest;
}
/**
* Defines the scissor test.
*
* @param {boolean} boolean - Whether the scissor test should be enabled or not.
*/
setScissorTest( boolean ) {
this._scissorTest = boolean;
}
/**
* Returns the viewport definition.
*
* @param {Vector4} target - The method writes the result in this target object.
* @return {Vector4} The viewport definition.
*/
getViewport( target ) {
return target.copy( this._viewport );
}
/**
* Defines the viewport.
*
* @param {number | Vector4} x - The horizontal coordinate for the lower left corner of the viewport origin in logical pixel unit.
* @param {number} y - The vertical coordinate for the lower left corner of the viewport origin in logical pixel unit.
* @param {number} width - The width of the viewport in logical pixel unit.
* @param {number} height - The height of the viewport in logical pixel unit.
* @param {number} minDepth - The minimum depth value of the viewport. WebGPU only.
* @param {number} maxDepth - The maximum depth value of the viewport. WebGPU only.
*/
setViewport( x, y, width, height, minDepth = 0, maxDepth = 1 ) {
const viewport = this._viewport;
if ( x.isVector4 ) {
viewport.copy( x );
} else {
viewport.set( x, y, width, height );
}
viewport.minDepth = minDepth;
viewport.maxDepth = maxDepth;
}
/**
* Dispatches the resize event.
*
* @private
*/
_dispatchResize() {
this.dispatchEvent( { type: 'resize' } );
}
/**
* Frees the GPU-related resources allocated by this instance. Call this
* method whenever this instance is no longer used in your app.
*
* @fires RenderTarget#dispose
*/
dispose() {
this.dispatchEvent( { type: 'dispose' } );
}
}
export default CanvasTarget;