/
githubmirror
/
pixijs
Обзор
Документация
Войти
/
githubmirror
/
pixijs
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
src/rendering/renderers/gl/GlBackBufferSystem.ts
216 строк
7 KB
Mat Groves
feat(rendering): object-form bind/push and capturable bind state (#12104)
08 июл 2026, 14:48
Не верифицирован
08 июл 2026, 14:48
3b9495d
Код
Авторство
О чём код?
import { ExtensionType } from '../../../extensions/Extensions'; import { warn } from '../../../utils/logging/warn'; import { Geometry } from '../shared/geometry/Geometry'; import { Shader } from '../shared/shader/Shader'; import { State } from '../shared/state/State'; import { TextureSource } from '../shared/texture/sources/TextureSource'; import { Texture } from '../shared/texture/Texture'; import { GlProgram } from './shader/GlProgram'; import type { RenderOptions } from '../shared/system/AbstractRenderer'; import type { System } from '../shared/system/System'; import type { WebGLRenderer } from './WebGLRenderer'; const bigTriangleGeometry = new Geometry({ attributes: { aPosition: [ -1.0, -1.0, // Bottom left corner 3.0, -1.0, // Bottom right corner, extending beyond right edge -1.0, 3.0 // Top left corner, extending beyond top edge ], }, }); /** * The options for the back buffer system. * @category rendering * @property {boolean} [useBackBuffer=false] - if true will use the back buffer where required * @property {boolean} [antialias=false] - if true will ensure the texture is antialiased * @advanced */ export interface GlBackBufferOptions { /** * if true will use the back buffer where required * @default false */ useBackBuffer?: boolean; /** if true will ensure the texture is antialiased */ antialias?: boolean; } /** * For blend modes you need to know what pixels you are actually drawing to. For this to be possible in WebGL * we need to render to a texture and then present that texture to the screen. This system manages that process. * * As the main scene is rendered to a texture, it means we can sample it and copy its pixels, * something not possible on the main canvas. * * If antialiasing is set to to true and useBackBuffer is set to true, then the back buffer will be antialiased. * and the main gl context will not. * * You only need to activate this back buffer if you are using a blend mode that requires it. * * to activate is simple, you pass `useBackBuffer:true` to your render options * @category rendering * @advanced */ export class GlBackBufferSystem implements System<GlBackBufferOptions> { /** @ignore */ public static extension = { type: [ ExtensionType.WebGLSystem, ], name: 'backBuffer', priority: 1 } as const; /** default options for the back buffer system */ public static defaultOptions: GlBackBufferOptions = { /** if true will use the back buffer where required */ useBackBuffer: false, }; /** if true, the back buffer is used */ public useBackBuffer = false; private _backBufferTexture: Texture; private readonly _renderer: WebGLRenderer; private _targetTexture: TextureSource; private _useBackBufferThisRender = false; private _antialias: boolean; private _state: State; private _bigTriangleShader: Shader; constructor(renderer: WebGLRenderer) { this._renderer = renderer; } public init(options: GlBackBufferOptions = {}) { const { useBackBuffer, antialias } = { ...GlBackBufferSystem.defaultOptions, ...options }; this.useBackBuffer = useBackBuffer; this._antialias = antialias; if (!this._renderer.context.supports.msaa) { warn('antialiasing, is not supported on when using the back buffer'); this._antialias = false; } this._state = State.for2d(); const bigTriangleProgram = new GlProgram({ vertex: ` attribute vec2 aPosition; out vec2 vUv; void main() { gl_Position = vec4(aPosition, 0.0, 1.0); vUv = (aPosition + 1.0) / 2.0; // flip dem UVs vUv.y = 1.0 - vUv.y; }`, fragment: ` in vec2 vUv; out vec4 finalColor; uniform sampler2D uTexture; void main() { finalColor = texture(uTexture, vUv); }`, name: 'big-triangle', }); this._bigTriangleShader = new Shader({ glProgram: bigTriangleProgram, resources: { uTexture: Texture.WHITE.source, }, }); } /** * This is called before the RenderTargetSystem is started. This is where * we replace the target with the back buffer if required. * @param options - The options for this render. */ protected renderStart(options: RenderOptions) { const renderTarget = this._renderer.renderTarget.getRenderTarget(options.target); this._useBackBufferThisRender = this.useBackBuffer && !!renderTarget.isRoot; if (this._useBackBufferThisRender) { const renderTarget = this._renderer.renderTarget.getRenderTarget(options.target); this._targetTexture = renderTarget.colorTexture; options.target = this._getBackBufferTexture(renderTarget.colorTexture); } } protected renderEnd() { this._presentBackBuffer(); } private _presentBackBuffer() { const renderer = this._renderer; renderer.renderTarget.finishRenderPass(); if (!this._useBackBufferThisRender) return; renderer.renderTarget.bind({ target: this._targetTexture, clear: false }); this._bigTriangleShader.resources.uTexture = this._backBufferTexture.source; renderer.encoder.draw({ geometry: bigTriangleGeometry, shader: this._bigTriangleShader, state: this._state, }); } private _getBackBufferTexture(targetSourceTexture: TextureSource) { this._backBufferTexture = this._backBufferTexture || new Texture({ source: new TextureSource({ width: targetSourceTexture.width, height: targetSourceTexture.height, resolution: targetSourceTexture._resolution, antialias: this._antialias, }), }); // this will not resize if its the same size already! No extra check required this._backBufferTexture.source.resize( targetSourceTexture.width, targetSourceTexture.height, targetSourceTexture._resolution, ); return this._backBufferTexture; } /** destroys the back buffer */ public destroy() { if (this._backBufferTexture) { this._backBufferTexture.destroy(); this._backBufferTexture = null; } } }