UNPKG

pixi.js

Version:

<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">

1 lines 35.5 kB
{"version":3,"file":"RenderTargetSystem.mjs","sources":["../../../../../src/rendering/renderers/shared/renderTarget/RenderTargetSystem.ts"],"sourcesContent":["import { Matrix } from '../../../../maths/matrix/Matrix';\nimport { Rectangle } from '../../../../maths/shapes/Rectangle';\nimport { CLEAR } from '../../gl/const';\nimport { calculateProjection } from '../../gpu/renderTarget/calculateProjection';\nimport { SystemRunner } from '../system/SystemRunner';\nimport { CanvasSource } from '../texture/sources/CanvasSource';\nimport { TextureSource } from '../texture/sources/TextureSource';\nimport { Texture } from '../texture/Texture';\nimport { getCanvasTexture } from '../texture/utils/getCanvasTexture';\nimport { isRenderingToScreen } from './isRenderingToScreen';\nimport { RenderTarget } from './RenderTarget';\n\nimport type { RgbaArray } from '../../../../color/Color';\nimport type { ICanvas } from '../../../../environment/canvas/ICanvas';\nimport type { CanvasRenderTarget } from '../../canvas/renderTarget/CanvasRenderTargetAdaptor';\nimport type { CLEAR_OR_BOOL } from '../../gl/const';\nimport type { GlRenderTarget } from '../../gl/GlRenderTarget';\nimport type { GpuRenderTarget } from '../../gpu/renderTarget/GpuRenderTarget';\nimport type { Renderer } from '../../types';\nimport type { System } from '../system/System';\nimport type { BindableTexture } from '../texture/Texture';\n\n/**\n * A render surface is a texture, canvas, or render target\n * @category rendering\n * @see environment.ICanvas\n * @see Texture\n * @see RenderTarget\n * @advanced\n */\nexport type RenderSurface = ICanvas | BindableTexture | RenderTarget;\n\n/**\n * stores a render target and its frame\n * @ignore\n */\ninterface RenderTargetAndFrame\n{\n /** the render target */\n renderTarget: RenderTarget;\n /** the frame to use when using the render target */\n frame: Rectangle;\n /** mip level to render to (subresource) */\n mipLevel: number;\n /** array layer to render to (subresource) */\n layer: number;\n}\n\n/**\n * An adaptor interface for RenderTargetSystem to support WebGL and WebGPU.\n * This is used internally by the renderer, and is not intended to be used directly.\n * @ignore\n */\ntype RendererRenderTarget = GlRenderTarget | GpuRenderTarget | CanvasRenderTarget;\n\n/**\n * An adaptor interface for RenderTargetSystem to support WebGL and WebGPU.\n * This is used internally by the renderer, and is not intended to be used directly.\n * @category rendering\n * @ignore\n */\nexport interface RenderTargetAdaptor<RENDER_TARGET extends RendererRenderTarget>\n{\n /**\n * Initializes the adaptor.\n * @param {Renderer} renderer - the renderer\n * @param {RenderTargetSystem} renderTargetSystem - the render target system\n */\n init(\n renderer: Renderer,\n renderTargetSystem: RenderTargetSystem<RENDER_TARGET>\n ): void\n\n /**\n * A function copies the contents of a render surface to a texture\n * @param {RenderTarget} sourceRenderSurfaceTexture - the render surface to copy from\n * @param {Texture} destinationTexture - the texture to copy to\n * @param {object} originSrc - the origin of the copy\n * @param {number} originSrc.x - the x origin of the copy\n * @param {number} originSrc.y - the y origin of the copy\n * @param {object} size - the size of the copy\n * @param {number} size.width - the width of the copy\n * @param {number} size.height - the height of the copy\n * @param {object} originDest - the destination origin (top left to paste from!)\n * @param {number} originDest.x - the x destination origin of the copy\n * @param {number} originDest.y - the y destination origin of the copy\n */\n copyToTexture(\n sourceRenderSurfaceTexture: RenderTarget,\n destinationTexture: Texture,\n originSrc: { x: number; y: number },\n size: { width: number; height: number },\n originDest?: { x: number; y: number },\n ): Texture\n\n /**\n * starts a render pass on the render target\n * @param {RenderTarget} renderTarget - the render target to start the render pass on\n * @param {CLEAR_OR_BOOL} clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111*\n * @param {RgbaArray} [clearColor] - the color to clear to\n * @param {Rectangle} [viewport] - the viewport to use\n */\n startRenderPass(\n renderTarget: RenderTarget,\n clear: CLEAR_OR_BOOL,\n clearColor?: RgbaArray,\n /** the viewport to use */\n viewport?: Rectangle,\n /** mip level to render to (subresource) */\n mipLevel?: number,\n /** array layer to render to (subresource) */\n layer?: number\n ): void\n\n /**\n * clears the current render target to the specified color\n * @param {RenderTarget} renderTarget - the render target to clear\n * @param {CLEAR_OR_BOOL} clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111*\n * @param {RgbaArray} [clearColor] - the color to clear to\n * @param {Rectangle} [viewport] - the viewport to use\n */\n clear(\n renderTarget: RenderTarget,\n clear: CLEAR_OR_BOOL,\n clearColor?: RgbaArray,\n /** the viewport to use */\n viewport?: Rectangle,\n /** mip level to clear (subresource) */\n mipLevel?: number,\n /** array layer to clear (subresource) */\n layer?: number\n ): void\n\n /**\n * finishes the current render pass\n * @param {RenderTarget} renderTarget - the render target to finish the render pass for\n */\n finishRenderPass(renderTarget: RenderTarget): void\n\n /**\n * called after the render pass is finished\n * @param {RenderTarget} renderTarget - the render target that was rendered to\n */\n postrender?(renderTarget: RenderTarget): void;\n\n /**\n * called before the render main pass is started\n * @param {RenderTarget} renderTarget - the render target that will be rendered to\n */\n prerender?(renderTarget: RenderTarget): void;\n\n /**\n * initializes a gpu render target\n * @param {RenderTarget} renderTarget - the render target to initialize\n */\n initGpuRenderTarget(\n renderTarget: RenderTarget\n ): RENDER_TARGET\n\n /**\n * resizes the gpu render target\n * @param {RenderTarget} renderTarget - the render target to resize\n */\n resizeGpuRenderTarget(\n renderTarget: RenderTarget\n ): void\n\n /**\n * destroys the gpu render target\n * @param {RendererRenderTarget} gpuRenderTarget - the gpu render target to destroy\n */\n destroyGpuRenderTarget(gpuRenderTarget: RENDER_TARGET): void\n}\n\n/**\n * A system that manages render targets. A render target is essentially a place where the shaders can color in the pixels.\n * The render target system is responsible for binding the render target to the renderer, and managing the viewport.\n * Render targets can be pushed and popped.\n *\n * To make it easier, you can also bind textures and canvases too. This will automatically create a render target for you.\n * The render target itself is a lot more powerful than just a texture or canvas,\n * as it can have multiple textures attached to it.\n * It will also give ou fine grain control over the stencil buffer / depth texture.\n * @example\n *\n * ```js\n *\n * // create a render target\n * const renderTarget = new RenderTarget({\n * colorTextures: [new TextureSource({ width: 100, height: 100 })],\n * });\n *\n * // bind the render target\n * renderer.renderTarget.bind(renderTarget);\n *\n * // draw something!\n * ```\n * @category rendering\n * @advanced\n */\nexport class RenderTargetSystem<RENDER_TARGET extends RendererRenderTarget> implements System\n{\n /** When rendering of a scene begins, this is where the root render surface is stored */\n public rootRenderTarget: RenderTarget;\n /** This is the root viewport for the render pass */\n public rootViewPort = new Rectangle();\n /** A boolean that lets the dev know if the current render pass is rendering to the screen. Used by some plugins */\n public renderingToScreen: boolean;\n /** the current active render target */\n public renderTarget: RenderTarget;\n /** the current active render surface that the render target is created from */\n public renderSurface: RenderSurface;\n /** the current viewport that the gpu is using */\n public readonly viewport = new Rectangle();\n /** the current mip level being rendered to (for texture subresources) */\n public mipLevel = 0;\n /** the current array layer being rendered to (for array-backed targets) */\n public layer = 0;\n /**\n * a runner that lets systems know if the active render target has changed.\n * Eg the Stencil System needs to know so it can manage the stencil buffer\n */\n public readonly onRenderTargetChange = new SystemRunner('onRenderTargetChange');\n /** the projection matrix that is used by the shaders based on the active render target and the viewport */\n public readonly projectionMatrix = new Matrix();\n /** the default clear color for render targets */\n public readonly defaultClearColor: RgbaArray = [0, 0, 0, 0];\n /** a reference to the adaptor that interfaces with WebGL / WebGP */\n public readonly adaptor: RenderTargetAdaptor<RENDER_TARGET>;\n /**\n * a hash that stores the render target for a given render surface. When you pass in a texture source,\n * a render target is created for it. This map stores and makes it easy to retrieve the render target\n */\n private readonly _renderSurfaceToRenderTargetHash: Map<RenderSurface, RenderTarget>\n = new Map();\n /** A hash that stores a gpu render target for a given render target. */\n private _gpuRenderTargetHash: Record<number, RENDER_TARGET> = Object.create(null);\n /**\n * A stack that stores the render target and frame that is currently being rendered to.\n * When push is called, the current render target is stored in this stack.\n * When pop is called, the previous render target is restored.\n */\n private readonly _renderTargetStack: RenderTargetAndFrame[] = [];\n /** A reference to the renderer */\n private readonly _renderer: Renderer;\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n renderer.gc.addCollection(this, '_gpuRenderTargetHash', 'hash');\n }\n\n /** called when dev wants to finish a render pass */\n public finishRenderPass()\n {\n this.adaptor.finishRenderPass(this.renderTarget);\n }\n\n /**\n * called when the renderer starts to render a scene.\n * @param options\n * @param options.target - the render target to render to\n * @param options.clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111\n * @param options.clearColor - the color to clear to\n * @param options.frame - the frame to render to\n * @param options.mipLevel - the mip level to render to\n * @param options.layer - The layer of the render target to render to. Used for array or 3D textures, or when rendering\n * to a specific layer of a layered render target. Optional.\n */\n public renderStart({\n target,\n clear,\n clearColor,\n frame,\n mipLevel,\n layer\n }: {\n target: RenderSurface;\n clear: CLEAR_OR_BOOL;\n clearColor: RgbaArray;\n frame?: Rectangle;\n mipLevel?: number;\n layer?: number;\n }): void\n {\n // TODO no need to reset this - use optimised index instead\n this._renderTargetStack.length = 0;\n\n this.push(\n target,\n clear,\n clearColor,\n frame,\n mipLevel ?? 0,\n layer ?? 0\n );\n\n this.rootViewPort.copyFrom(this.viewport);\n this.rootRenderTarget = this.renderTarget;\n this.renderingToScreen = isRenderingToScreen(this.rootRenderTarget);\n\n this.adaptor.prerender?.(this.rootRenderTarget);\n }\n\n public postrender()\n {\n this.adaptor.postrender?.(this.rootRenderTarget);\n }\n\n /**\n * Binding a render surface! This is the main function of the render target system.\n * It will take the RenderSurface (which can be a texture, canvas, or render target) and bind it to the renderer.\n * Once bound all draw calls will be rendered to the render surface.\n *\n * If a frame is not provided and the render surface is a {@link Texture}, the frame of the texture will be used.\n *\n * IMPORTANT:\n * - `frame` is treated as **base mip (mip 0) pixel space**.\n * - When `mipLevel > 0`, the viewport derived from `frame` is scaled by \\(2^{mipLevel}\\) and clamped to the\n * mip dimensions. This keeps \"render the same region\" semantics consistent across mip levels.\n * - When `renderSurface` is a {@link Texture}, `renderer.render({ container, target: texture, mipLevel })` will\n * render into\n * the underlying {@link TextureSource} (Pixi will create/use a {@link RenderTarget} for the source) using the\n * texture's frame to define the region (in mip 0 space).\n * @param renderSurface - the render surface to bind\n * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111\n * @param clearColor - the color to clear to\n * @param frame - the frame to render to\n * @param mipLevel - the mip level to render to\n * @param layer - the layer (or slice) of the render surface to render to. For array textures,\n * 3D textures, or cubemaps, this specifies the target layer or face. Defaults to 0 (the first layer/face).\n * Ignored for surfaces that do not support layers.\n * @returns the render target that was bound\n */\n public bind(\n renderSurface: RenderSurface,\n clear: CLEAR_OR_BOOL = true,\n clearColor?: RgbaArray,\n frame?: Rectangle,\n mipLevel = 0,\n layer = 0\n ): RenderTarget\n {\n const renderTarget = this.getRenderTarget(renderSurface);\n\n const didChange = this.renderTarget !== renderTarget;\n\n this.renderTarget = renderTarget;\n this.renderSurface = renderSurface;\n\n const gpuRenderTarget = this.getGpuRenderTarget(renderTarget);\n\n if (renderTarget.pixelWidth !== gpuRenderTarget.width\n || renderTarget.pixelHeight !== gpuRenderTarget.height)\n {\n this.adaptor.resizeGpuRenderTarget(renderTarget);\n\n gpuRenderTarget.width = renderTarget.pixelWidth;\n gpuRenderTarget.height = renderTarget.pixelHeight;\n }\n\n const source = renderTarget.colorTexture;\n const viewport = this.viewport;\n const arrayLayerCount = source.arrayLayerCount || 1;\n\n if ((layer | 0) !== layer)\n {\n layer |= 0;\n }\n\n if (layer < 0 || layer >= arrayLayerCount)\n {\n throw new Error(`[RenderTargetSystem] layer ${layer} is out of bounds (arrayLayerCount=${arrayLayerCount}).`);\n }\n\n this.mipLevel = mipLevel | 0;\n this.layer = layer | 0;\n\n const pixelWidth = Math.max(source.pixelWidth >> mipLevel, 1);\n const pixelHeight = Math.max(source.pixelHeight >> mipLevel, 1);\n\n // If no explicit frame was provided, Texture targets default to their frame.\n // IMPORTANT: frame is treated as base-level (mip 0) coordinates; when rendering to mip N,\n // the viewport is scaled down by 2^N.\n if (!frame && renderSurface instanceof Texture)\n {\n frame = renderSurface.frame;\n }\n\n if (frame)\n {\n const resolution = source._resolution;\n const scale = 1 << Math.max(mipLevel | 0, 0);\n\n // Convert frame to pixel units (mip 0), then scale to the requested mip level.\n const baseX = ((frame.x * resolution) + 0.5) | 0;\n const baseY = ((frame.y * resolution) + 0.5) | 0;\n const baseW = ((frame.width * resolution) + 0.5) | 0;\n const baseH = ((frame.height * resolution) + 0.5) | 0;\n\n // Use floor for origin and ceil for size to avoid collapsing to zero due to rounding.\n // (When mipLevel === 0, scale === 1 so this behaves like the base-level case.)\n let x = Math.floor(baseX / scale);\n let y = Math.floor(baseY / scale);\n let w = Math.ceil(baseW / scale);\n let h = Math.ceil(baseH / scale);\n\n // Clamp to mip dimensions.\n x = Math.min(Math.max(x, 0), pixelWidth - 1);\n y = Math.min(Math.max(y, 0), pixelHeight - 1);\n w = Math.min(Math.max(w, 1), pixelWidth - x);\n h = Math.min(Math.max(h, 1), pixelHeight - y);\n\n viewport.x = x;\n viewport.y = y;\n viewport.width = w;\n viewport.height = h;\n }\n else\n {\n viewport.x = 0;\n viewport.y = 0;\n viewport.width = pixelWidth;\n viewport.height = pixelHeight;\n }\n\n calculateProjection(\n this.projectionMatrix,\n 0, 0,\n viewport.width / source.resolution,\n viewport.height / source.resolution,\n !renderTarget.isRoot\n );\n\n this.adaptor.startRenderPass(renderTarget, clear, clearColor, viewport, mipLevel, layer);\n\n if (didChange)\n {\n this.onRenderTargetChange.emit(renderTarget);\n }\n\n return renderTarget;\n }\n\n public clear(\n target?: RenderSurface,\n clear: CLEAR_OR_BOOL = CLEAR.ALL,\n clearColor?: RgbaArray,\n mipLevel = this.mipLevel,\n layer = this.layer,\n )\n {\n if (!clear) return;\n\n if (target)\n {\n target = this.getRenderTarget(target);\n }\n\n this.adaptor.clear(\n (target as RenderTarget) || this.renderTarget,\n clear,\n clearColor,\n this.viewport,\n mipLevel,\n layer\n );\n }\n\n protected contextChange(): void\n {\n this._gpuRenderTargetHash = Object.create(null);\n }\n\n /**\n * Push a render surface to the renderer. This will bind the render surface to the renderer,\n * @param renderSurface - the render surface to push\n * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111\n * @param clearColor - the color to clear to\n * @param frame - the frame to use when rendering to the render surface\n * @param mipLevel - the mip level to render to\n * @param layer - The layer of the render surface to render to. For array textures or cube maps, this specifies\n * which layer or face to target. Defaults to 0 (the first layer).\n */\n public push(\n renderSurface: RenderSurface,\n clear: CLEAR | boolean = CLEAR.ALL,\n clearColor?: RgbaArray,\n frame?: Rectangle,\n mipLevel = 0,\n layer = 0\n )\n {\n const renderTarget = this.bind(renderSurface, clear, clearColor, frame, mipLevel, layer);\n\n this._renderTargetStack.push({\n renderTarget,\n frame,\n mipLevel,\n layer,\n });\n\n return renderTarget;\n }\n\n /** Pops the current render target from the renderer and restores the previous render target. */\n public pop()\n {\n this._renderTargetStack.pop();\n\n const currentRenderTargetData = this._renderTargetStack[this._renderTargetStack.length - 1];\n\n this.bind(\n currentRenderTargetData.renderTarget,\n false,\n null,\n currentRenderTargetData.frame,\n currentRenderTargetData.mipLevel,\n currentRenderTargetData.layer\n );\n }\n\n /**\n * Gets the render target from the provide render surface. Eg if its a texture,\n * it will return the render target for the texture.\n * If its a render target, it will return the same render target.\n * @param renderSurface - the render surface to get the render target for\n * @returns the render target for the render surface\n */\n public getRenderTarget(renderSurface: RenderSurface): RenderTarget\n {\n if (((renderSurface as Texture).isTexture))\n {\n renderSurface = (renderSurface as Texture).source;\n }\n\n return this._renderSurfaceToRenderTargetHash.get(renderSurface)\n ?? this._initRenderTarget(renderSurface);\n }\n\n /**\n * Copies a render surface to another texture.\n *\n * NOTE:\n * for sourceRenderSurfaceTexture, The render target must be something that is written too by the renderer\n *\n * The following is not valid:\n * @example\n * const canvas = document.createElement('canvas')\n * canvas.width = 200;\n * canvas.height = 200;\n *\n * const ctx = canvas2.getContext('2d')!\n * ctx.fillStyle = 'red'\n * ctx.fillRect(0, 0, 200, 200);\n *\n * const texture = RenderTexture.create({\n * width: 200,\n * height: 200,\n * })\n * const renderTarget = renderer.renderTarget.getRenderTarget(canvas2);\n *\n * renderer.renderTarget.copyToTexture(renderTarget,texture, {x:0,y:0},{width:200,height:200},{x:0,y:0});\n *\n * The best way to copy a canvas is to create a texture from it. Then render with that.\n *\n * Parsing in a RenderTarget canvas context (with a 2d context)\n * @param sourceRenderSurfaceTexture - the render surface to copy from\n * @param {Texture} destinationTexture - the texture to copy to\n * @param {object} originSrc - the origin of the copy\n * @param {number} originSrc.x - the x origin of the copy\n * @param {number} originSrc.y - the y origin of the copy\n * @param {object} size - the size of the copy\n * @param {number} size.width - the width of the copy\n * @param {number} size.height - the height of the copy\n * @param {object} originDest - the destination origin (top left to paste from!)\n * @param {number} originDest.x - the x origin of the paste\n * @param {number} originDest.y - the y origin of the paste\n */\n public copyToTexture(\n sourceRenderSurfaceTexture: RenderTarget,\n destinationTexture: Texture,\n originSrc: { x: number; y: number },\n size: { width: number; height: number },\n originDest: { x: number; y: number; },\n )\n {\n // fit the size to the source we don't want to go out of bounds\n\n if (originSrc.x < 0)\n {\n size.width += originSrc.x;\n originDest.x -= originSrc.x;\n originSrc.x = 0;\n }\n\n if (originSrc.y < 0)\n {\n size.height += originSrc.y;\n originDest.y -= originSrc.y;\n originSrc.y = 0;\n }\n\n const { pixelWidth, pixelHeight } = sourceRenderSurfaceTexture;\n\n size.width = Math.min(size.width, pixelWidth - originSrc.x);\n size.height = Math.min(size.height, pixelHeight - originSrc.y);\n\n return this.adaptor.copyToTexture(\n sourceRenderSurfaceTexture,\n destinationTexture,\n originSrc,\n size,\n originDest\n );\n }\n\n /**\n * ensures that we have a depth stencil buffer available to render to\n * This is used by the mask system to make sure we have a stencil buffer.\n */\n public ensureDepthStencil()\n {\n if (!this.renderTarget.stencil)\n {\n this.renderTarget.stencil = true;\n\n this.adaptor.startRenderPass(this.renderTarget, false, null, this.viewport, 0, this.layer);\n }\n }\n\n /** nukes the render target system */\n public destroy()\n {\n (this._renderer as null) = null;\n\n this._renderSurfaceToRenderTargetHash.forEach((renderTarget, key) =>\n {\n if (renderTarget !== key)\n {\n renderTarget.destroy();\n }\n });\n\n this._renderSurfaceToRenderTargetHash.clear();\n\n this._gpuRenderTargetHash = Object.create(null);\n }\n\n private _initRenderTarget(renderSurface: RenderSurface): RenderTarget\n {\n let renderTarget: RenderTarget = null;\n\n if (CanvasSource.test(renderSurface))\n {\n renderSurface = getCanvasTexture(renderSurface as ICanvas).source;\n }\n\n if (renderSurface instanceof RenderTarget)\n {\n renderTarget = renderSurface;\n }\n else if (renderSurface instanceof TextureSource)\n {\n renderTarget = new RenderTarget({\n colorTextures: [renderSurface],\n });\n\n if (renderSurface.source instanceof CanvasSource)\n {\n renderTarget.isRoot = true;\n }\n\n // TODO add a test for this\n renderSurface.once('destroy', () =>\n {\n renderTarget.destroy();\n\n this._renderSurfaceToRenderTargetHash.delete(renderSurface);\n\n const gpuRenderTarget = this._gpuRenderTargetHash[renderTarget.uid];\n\n if (gpuRenderTarget)\n {\n this._gpuRenderTargetHash[renderTarget.uid] = null;\n this.adaptor.destroyGpuRenderTarget(gpuRenderTarget);\n }\n });\n }\n\n this._renderSurfaceToRenderTargetHash.set(renderSurface, renderTarget);\n\n return renderTarget;\n }\n\n public getGpuRenderTarget(renderTarget: RenderTarget)\n {\n return this._gpuRenderTargetHash[renderTarget.uid]\n || (this._gpuRenderTargetHash[renderTarget.uid] = this.adaptor.initGpuRenderTarget(renderTarget));\n }\n\n public resetState(): void\n {\n this.renderTarget = null;\n this.renderSurface = null;\n }\n}\n"],"names":[],"mappings":"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"}