UNPKG

evotars

Version:

Show animated characters on stream

1,620 lines (1,575 loc) 66 kB
import { l as Re, M as g, o as Be, p as Ue, E as u, q as b, s as Ae, t as q, F as K, v as Ie, j as m, S as p, d as B, w as Y, x as Fe, b as H, B as k, h as U, u as C, i as _, R as w, y as Ee, a as De, C as S, z as Oe, G as ze, H as He, I as J, e as X, J as Le, P as We, c as Ve, D as Q, K as je, L as $e } from "./index-BYnkzXxX.js"; import { b as Ne, S as Z, G as ee, f as te, U as re, T as L, h as W, B as qe, i as Ke, R as se } from "./colorToUniform-CPC7AZcR.js"; const ae = class A extends Ne { /** * @param options - The optional parameters of this filter. */ constructor(e) { e = { ...A.defaultOptions, ...e }, super(e), this.enabled = !0, this._state = Z.for2d(), this.padding = e.padding, typeof e.antialias == "boolean" ? this.antialias = e.antialias ? "on" : "off" : this.antialias = e.antialias, this.resolution = e.resolution, this.blendRequired = e.blendRequired, this.addResource("uTexture", 0, 1); } /** * Applies the filter * @param filterManager - The renderer to retrieve the filter from * @param input - The input render target. * @param output - The target to output to. * @param clearMode - Should the output be cleared before rendering to it */ apply(e, t, r, a) { e.applyFilter(this, t, r, a); } /** * Get the blend mode of the filter. * @default "normal" */ get blendMode() { return this._state.blendMode; } /** Sets the blend mode of the filter. */ set blendMode(e) { this._state.blendMode = e; } /** * A short hand function to create a filter based of a vertex and fragment shader src. * @param options * @returns A shiny new PixiJS filter! */ static from(e) { const { gpu: t, gl: r, ...a } = e; let n, i; return t && (n = ee.from(t)), r && (i = te.from(r)), new A({ gpuProgram: n, glProgram: i, ...a }); } }; ae.defaultOptions = { blendMode: "normal", resolution: 1, padding: 0, antialias: "off", blendRequired: !1 }; let Ye = ae; var Je = `in vec2 vMaskCoord; in vec2 vTextureCoord; uniform sampler2D uTexture; uniform sampler2D uMaskTexture; uniform float uAlpha; uniform vec4 uMaskClamp; out vec4 finalColor; void main(void) { float clip = step(3.5, step(uMaskClamp.x, vMaskCoord.x) + step(uMaskClamp.y, vMaskCoord.y) + step(vMaskCoord.x, uMaskClamp.z) + step(vMaskCoord.y, uMaskClamp.w)); // TODO look into why this is needed float npmAlpha = uAlpha; vec4 original = texture(uTexture, vTextureCoord); vec4 masky = texture(uMaskTexture, vMaskCoord); float alphaMul = 1.0 - npmAlpha * (1.0 - masky.a); original *= (alphaMul * masky.r * uAlpha * clip); finalColor = original; } `, Xe = `in vec2 aPosition; out vec2 vTextureCoord; out vec2 vMaskCoord; uniform vec4 uInputSize; uniform vec4 uOutputFrame; uniform vec4 uOutputTexture; uniform mat3 uFilterMatrix; vec4 filterVertexPosition( vec2 aPosition ) { vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; return vec4(position, 0.0, 1.0); } vec2 filterTextureCoord( vec2 aPosition ) { return aPosition * (uOutputFrame.zw * uInputSize.zw); } vec2 getFilterCoord( vec2 aPosition ) { return ( uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy; } void main(void) { gl_Position = filterVertexPosition(aPosition); vTextureCoord = filterTextureCoord(aPosition); vMaskCoord = getFilterCoord(aPosition); } `, V = `struct GlobalFilterUniforms { uInputSize:vec4<f32>, uInputPixel:vec4<f32>, uInputClamp:vec4<f32>, uOutputFrame:vec4<f32>, uGlobalFrame:vec4<f32>, uOutputTexture:vec4<f32>, }; struct MaskUniforms { uFilterMatrix:mat3x3<f32>, uMaskClamp:vec4<f32>, uAlpha:f32, }; @group(0) @binding(0) var<uniform> gfu: GlobalFilterUniforms; @group(0) @binding(1) var uTexture: texture_2d<f32>; @group(0) @binding(2) var uSampler : sampler; @group(1) @binding(0) var<uniform> filterUniforms : MaskUniforms; @group(1) @binding(1) var uMaskTexture: texture_2d<f32>; struct VSOutput { @builtin(position) position: vec4<f32>, @location(0) uv : vec2<f32>, @location(1) filterUv : vec2<f32>, }; fn filterVertexPosition(aPosition:vec2<f32>) -> vec4<f32> { var position = aPosition * gfu.uOutputFrame.zw + gfu.uOutputFrame.xy; position.x = position.x * (2.0 / gfu.uOutputTexture.x) - 1.0; position.y = position.y * (2.0*gfu.uOutputTexture.z / gfu.uOutputTexture.y) - gfu.uOutputTexture.z; return vec4(position, 0.0, 1.0); } fn filterTextureCoord( aPosition:vec2<f32> ) -> vec2<f32> { return aPosition * (gfu.uOutputFrame.zw * gfu.uInputSize.zw); } fn globalTextureCoord( aPosition:vec2<f32> ) -> vec2<f32> { return (aPosition.xy / gfu.uGlobalFrame.zw) + (gfu.uGlobalFrame.xy / gfu.uGlobalFrame.zw); } fn getFilterCoord(aPosition:vec2<f32> ) -> vec2<f32> { return ( filterUniforms.uFilterMatrix * vec3( filterTextureCoord(aPosition), 1.0) ).xy; } fn getSize() -> vec2<f32> { return gfu.uGlobalFrame.zw; } @vertex fn mainVertex( @location(0) aPosition : vec2<f32>, ) -> VSOutput { return VSOutput( filterVertexPosition(aPosition), filterTextureCoord(aPosition), getFilterCoord(aPosition) ); } @fragment fn mainFragment( @location(0) uv: vec2<f32>, @location(1) filterUv: vec2<f32>, @builtin(position) position: vec4<f32> ) -> @location(0) vec4<f32> { var maskClamp = filterUniforms.uMaskClamp; var clip = step(3.5, step(maskClamp.x, filterUv.x) + step(maskClamp.y, filterUv.y) + step(filterUv.x, maskClamp.z) + step(filterUv.y, maskClamp.w)); var mask = textureSample(uMaskTexture, uSampler, filterUv); var source = textureSample(uTexture, uSampler, uv); var npmAlpha = 0.0; var alphaMul = 1.0 - npmAlpha * (1.0 - mask.a); var a = (alphaMul * mask.r) * clip; return vec4(source.rgb, source.a) * a; }`; class Qe extends Ye { constructor(e) { const { sprite: t, ...r } = e, a = new Re(t.texture), n = new re({ uFilterMatrix: { value: new g(), type: "mat3x3<f32>" }, uMaskClamp: { value: a.uClampFrame, type: "vec4<f32>" }, uAlpha: { value: 1, type: "f32" } }), i = ee.from({ vertex: { source: V, entryPoint: "mainVertex" }, fragment: { source: V, entryPoint: "mainFragment" } }), l = te.from({ vertex: Xe, fragment: Je, name: "mask-filter" }); super({ ...r, gpuProgram: i, glProgram: l, resources: { filterUniforms: n, uMaskTexture: t.texture.source } }), this.sprite = t, this._textureMatrix = a; } apply(e, t, r, a) { this._textureMatrix.texture = this.sprite.texture, e.calculateSpriteMatrix( this.resources.filterUniforms.uniforms.uFilterMatrix, this.sprite ).prepend(this._textureMatrix.mapCoord), this.resources.uMaskTexture = this.sprite.texture.source, e.applyFilter(this, t, r, a); } } class ne { constructor(e, t) { this.state = Z.for2d(), this._batches = /* @__PURE__ */ Object.create(null), this._geometries = /* @__PURE__ */ Object.create(null), this.renderer = e, this._adaptor = t, this._adaptor.init(this); } buildStart(e) { if (!this._batches[e.uid]) { const t = new Be(); this._batches[e.uid] = t, this._geometries[t.uid] = new Ue(); } this._activeBatch = this._batches[e.uid], this._activeGeometry = this._geometries[this._activeBatch.uid], this._activeBatch.begin(); } addToBatch(e) { this._activeBatch.add(e); } break(e) { this._activeBatch.break(e); } buildEnd(e) { const t = this._activeBatch, r = this._activeGeometry; t.finish(e), r.indexBuffer.setDataWithSize(t.indexBuffer, t.indexSize, !0), r.buffers[0].setDataWithSize(t.attributeBuffer.float32View, t.attributeSize, !1); } upload(e) { const t = this._batches[e.uid], r = this._geometries[t.uid]; t.dirty && (t.dirty = !1, r.buffers[0].update(t.attributeSize * 4)); } execute(e) { if (e.action === "startBatch") { const t = e.batcher, r = this._geometries[t.uid]; this._adaptor.start(this, r); } this._adaptor.execute(this, e); } destroy() { this.state = null, this.renderer = null, this._adaptor.destroy(), this._adaptor = null; for (const e in this._batches) this._batches[e].destroy(); this._batches = null; for (const e in this._geometries) this._geometries[e].destroy(); this._geometries = null; } } ne.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "batch" }; const Mt = { name: "texture-bit", vertex: { header: ( /* wgsl */ ` struct TextureUniforms { uTextureMatrix:mat3x3<f32>, } @group(2) @binding(2) var<uniform> textureUniforms : TextureUniforms; ` ), main: ( /* wgsl */ ` uv = (textureUniforms.uTextureMatrix * vec3(uv, 1.0)).xy; ` ) }, fragment: { header: ( /* wgsl */ ` @group(2) @binding(0) var uTexture: texture_2d<f32>; @group(2) @binding(1) var uSampler: sampler; ` ), main: ( /* wgsl */ ` outColor = textureSample(uTexture, uSampler, vUV); ` ) } }, Ct = { name: "texture-bit", vertex: { header: ( /* glsl */ ` uniform mat3 uTextureMatrix; ` ), main: ( /* glsl */ ` uv = (uTextureMatrix * vec3(uv, 1.0)).xy; ` ) }, fragment: { header: ( /* glsl */ ` uniform sampler2D uTexture; ` ), main: ( /* glsl */ ` outColor = texture(uTexture, vUV); ` ) } }; function Ze(s, e) { const t = s.root, r = s.instructionSet; r.reset(), e.batch.buildStart(r), e.blendMode.buildStart(), e.colorMask.buildStart(), t.sortableChildren && t.sortChildren(), ie(t, r, e, !0), e.batch.buildEnd(r), e.blendMode.buildEnd(r); } function P(s, e, t) { s.globalDisplayStatus < 7 || !s.includeInBuild || (s.sortableChildren && s.sortChildren(), s.isSimple ? et(s, e, t) : ie(s, e, t, !1)); } function et(s, e, t) { if (s.renderPipeId && (t.blendMode.setBlendMode(s, s.groupBlendMode, e), s.didViewUpdate = !1, t[s.renderPipeId].addRenderable(s, e)), !s.renderGroup) { const r = s.children, a = r.length; for (let n = 0; n < a; n++) P(r[n], e, t); } } function ie(s, e, t, r) { if (!r && s.renderGroup) t.renderGroup.addRenderGroup(s.renderGroup, e); else { for (let i = 0; i < s.effects.length; i++) { const l = s.effects[i]; t[l.pipe].push(l, s, e); } const a = s.renderPipeId; a && (t.blendMode.setBlendMode(s, s.groupBlendMode, e), s.didViewUpdate = !1, t[a].addRenderable(s, e)); const n = s.children; if (n.length) for (let i = 0; i < n.length; i++) P(n[i], e, t); for (let i = s.effects.length - 1; i >= 0; i--) { const l = s.effects[i]; t[l.pipe].pop(l, s, e); } } } const tt = new q(); class rt extends K { constructor() { super(), this.filters = [new Qe({ sprite: new Ie(m.EMPTY) })]; } get sprite() { return this.filters[0].sprite; } set sprite(e) { this.filters[0].sprite = e; } } class oe { constructor(e) { this._activeMaskStage = [], this._renderer = e; } push(e, t, r) { const a = this._renderer; if (a.renderPipes.batch.break(r), r.add({ renderPipeId: "alphaMask", action: "pushMaskBegin", mask: e, canBundle: !1, maskedContainer: t }), e.renderMaskToTexture) { const n = e.mask; n.includeInBuild = !0, P( n, r, a.renderPipes ), n.includeInBuild = !1; } a.renderPipes.batch.break(r), r.add({ renderPipeId: "alphaMask", action: "pushMaskEnd", mask: e, maskedContainer: t, canBundle: !1 }); } pop(e, t, r) { this._renderer.renderPipes.batch.break(r), r.add({ renderPipeId: "alphaMask", action: "popMaskEnd", mask: e, canBundle: !1 }); } execute(e) { const t = this._renderer, r = e.mask.renderMaskToTexture; if (e.action === "pushMaskBegin") { const a = b.get(rt); if (r) { e.mask.mask.measurable = !0; const n = Ae(e.mask.mask, !0, tt); e.mask.mask.measurable = !1, n.ceil(); const i = L.getOptimalTexture( n.width, n.height, 1, !1 ); t.renderTarget.push(i, !0), t.globalUniforms.push({ offset: n, worldColor: 4294967295 }); const l = a.sprite; l.texture = i, l.worldTransform.tx = n.minX, l.worldTransform.ty = n.minY, this._activeMaskStage.push({ filterEffect: a, maskedContainer: e.maskedContainer, filterTexture: i }); } else a.sprite = e.mask.mask, this._activeMaskStage.push({ filterEffect: a, maskedContainer: e.maskedContainer }); } else if (e.action === "pushMaskEnd") { const a = this._activeMaskStage[this._activeMaskStage.length - 1]; r && (t.renderTarget.pop(), t.globalUniforms.pop()), t.filter.push({ renderPipeId: "filter", action: "pushFilter", container: a.maskedContainer, filterEffect: a.filterEffect, canBundle: !1 }); } else if (e.action === "popMaskEnd") { t.filter.pop(); const a = this._activeMaskStage.pop(); r && L.returnTexture(a.filterTexture), b.return(a.filterEffect); } } destroy() { this._renderer = null, this._activeMaskStage = null; } } oe.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "alphaMask" }; class le { constructor(e) { this._colorStack = [], this._colorStackIndex = 0, this._currentColor = 0, this._renderer = e; } buildStart() { this._colorStack[0] = 15, this._colorStackIndex = 1, this._currentColor = 15; } push(e, t, r) { this._renderer.renderPipes.batch.break(r); const n = this._colorStack; n[this._colorStackIndex] = n[this._colorStackIndex - 1] & e.mask; const i = this._colorStack[this._colorStackIndex]; i !== this._currentColor && (this._currentColor = i, r.add({ renderPipeId: "colorMask", colorMask: i, canBundle: !1 })), this._colorStackIndex++; } pop(e, t, r) { this._renderer.renderPipes.batch.break(r); const n = this._colorStack; this._colorStackIndex--; const i = n[this._colorStackIndex - 1]; i !== this._currentColor && (this._currentColor = i, r.add({ renderPipeId: "colorMask", colorMask: i, canBundle: !1 })); } execute(e) { this._renderer.colorMask.setMask(e.colorMask); } destroy() { this._colorStack = null; } } le.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "colorMask" }; class ue { constructor(e) { this._maskStackHash = {}, this._maskHash = /* @__PURE__ */ new WeakMap(), this._renderer = e; } push(e, t, r) { var a; const n = e, i = this._renderer; i.renderPipes.batch.break(r), i.renderPipes.blendMode.setBlendMode(n.mask, "none", r), r.add({ renderPipeId: "stencilMask", action: "pushMaskBegin", mask: e, canBundle: !1 }); const l = n.mask; l.includeInBuild = !0, this._maskHash.has(n) || this._maskHash.set(n, { instructionsStart: 0, instructionsLength: 0 }); const o = this._maskHash.get(n); o.instructionsStart = r.instructionSize, P( l, r, i.renderPipes ), l.includeInBuild = !1, i.renderPipes.batch.break(r), r.add({ renderPipeId: "stencilMask", action: "pushMaskEnd", mask: e, canBundle: !1 }); const d = r.instructionSize - o.instructionsStart - 1; o.instructionsLength = d; const c = i.renderTarget.renderTarget.uid; (a = this._maskStackHash)[c] ?? (a[c] = 0); } pop(e, t, r) { const a = e, n = this._renderer; n.renderPipes.batch.break(r), n.renderPipes.blendMode.setBlendMode(a.mask, "none", r), r.add({ renderPipeId: "stencilMask", action: "popMaskBegin", canBundle: !1 }); const i = this._maskHash.get(e); for (let l = 0; l < i.instructionsLength; l++) r.instructions[r.instructionSize++] = r.instructions[i.instructionsStart++]; r.add({ renderPipeId: "stencilMask", action: "popMaskEnd", canBundle: !1 }); } execute(e) { var t; const r = this._renderer, a = r.renderTarget.renderTarget.uid; let n = (t = this._maskStackHash)[a] ?? (t[a] = 0); e.action === "pushMaskBegin" ? (r.renderTarget.ensureDepthStencil(), r.stencil.setStencilMode(p.RENDERING_MASK_ADD, n), n++, r.colorMask.setMask(0)) : e.action === "pushMaskEnd" ? (r.stencil.setStencilMode(p.MASK_ACTIVE, n), r.colorMask.setMask(15)) : e.action === "popMaskBegin" ? (r.colorMask.setMask(0), n !== 0 ? r.stencil.setStencilMode(p.RENDERING_MASK_REMOVE, n) : (r.renderTarget.clear(null, B.STENCIL), r.stencil.setStencilMode(p.DISABLED, n)), n--) : e.action === "popMaskEnd" && (r.stencil.setStencilMode(p.MASK_ACTIVE, n), r.colorMask.setMask(15)), this._maskStackHash[a] = n; } destroy() { this._renderer = null, this._maskStackHash = null, this._maskHash = null; } } ue.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "stencilMask" }; function wt(s, e) { for (const t in s.attributes) { const r = s.attributes[t], a = e[t]; a ? (r.location ?? (r.location = a.location), r.format ?? (r.format = a.format), r.offset ?? (r.offset = a.offset), r.instance ?? (r.instance = a.instance)) : Y(`Attribute ${t} is not present in the shader, but is present in the geometry. Unable to infer attribute details.`); } st(s); } function st(s) { const { buffers: e, attributes: t } = s, r = {}, a = {}; for (const n in e) { const i = e[n]; r[i.uid] = 0, a[i.uid] = 0; } for (const n in t) { const i = t[n]; r[i.buffer.uid] += W(i.format).stride; } for (const n in t) { const i = t[n]; i.stride ?? (i.stride = r[i.buffer.uid]), i.start ?? (i.start = a[i.buffer.uid]), a[i.buffer.uid] += W(i.format).stride; } } const T = []; T[p.NONE] = void 0; T[p.DISABLED] = { stencilWriteMask: 0, stencilReadMask: 0 }; T[p.RENDERING_MASK_ADD] = { stencilFront: { compare: "equal", passOp: "increment-clamp" }, stencilBack: { compare: "equal", passOp: "increment-clamp" } }; T[p.RENDERING_MASK_REMOVE] = { stencilFront: { compare: "equal", passOp: "decrement-clamp" }, stencilBack: { compare: "equal", passOp: "decrement-clamp" } }; T[p.MASK_ACTIVE] = { stencilWriteMask: 0, stencilFront: { compare: "equal", passOp: "keep" }, stencilBack: { compare: "equal", passOp: "keep" } }; class St { constructor(e) { this._syncFunctionHash = /* @__PURE__ */ Object.create(null), this._adaptor = e, this._systemCheck(); } /** * Overrideable function by `pixi.js/unsafe-eval` to silence * throwing an error if platform doesn't support unsafe-evals. * @private */ _systemCheck() { if (!Fe()) throw new Error("Current environment does not allow unsafe-eval, please use pixi.js/unsafe-eval module to enable support."); } ensureUniformGroup(e) { const t = this.getUniformGroupData(e); e.buffer || (e.buffer = new H({ data: new Float32Array(t.layout.size / 4), usage: k.UNIFORM | k.COPY_DST })); } getUniformGroupData(e) { return this._syncFunctionHash[e._signature] || this._initUniformGroup(e); } _initUniformGroup(e) { const t = e._signature; let r = this._syncFunctionHash[t]; if (!r) { const a = Object.keys(e.uniformStructures).map((l) => e.uniformStructures[l]), n = this._adaptor.createUboElements(a), i = this._generateUboSync(n.uboElements); r = this._syncFunctionHash[t] = { layout: n, syncFunction: i }; } return this._syncFunctionHash[t]; } _generateUboSync(e) { return this._adaptor.generateUboSync(e); } syncUniformGroup(e, t, r) { const a = this.getUniformGroupData(e); return e.buffer || (e.buffer = new H({ data: new Float32Array(a.layout.size / 4), usage: k.UNIFORM | k.COPY_DST })), t || (t = e.buffer.data), r || (r = 0), a.syncFunction(e.uniforms, t, r), !0; } updateUniformGroup(e) { if (e.isStatic && !e._dirtyId) return !1; e._dirtyId = 0; const t = this.syncUniformGroup(e); return e.buffer.update(), t; } destroy() { this._syncFunctionHash = null; } } const M = [ // uploading pixi matrix object to mat3 { type: "mat3x3<f32>", test: (s) => s.value.a !== void 0, ubo: ` var matrix = uv[name].toArray(true); data[offset] = matrix[0]; data[offset + 1] = matrix[1]; data[offset + 2] = matrix[2]; data[offset + 4] = matrix[3]; data[offset + 5] = matrix[4]; data[offset + 6] = matrix[5]; data[offset + 8] = matrix[6]; data[offset + 9] = matrix[7]; data[offset + 10] = matrix[8]; `, uniform: ` gl.uniformMatrix3fv(ud[name].location, false, uv[name].toArray(true)); ` }, // uploading a pixi rectangle as a vec4 { type: "vec4<f32>", test: (s) => s.type === "vec4<f32>" && s.size === 1 && s.value.width !== void 0, ubo: ` v = uv[name]; data[offset] = v.x; data[offset + 1] = v.y; data[offset + 2] = v.width; data[offset + 3] = v.height; `, uniform: ` cv = ud[name].value; v = uv[name]; if (cv[0] !== v.x || cv[1] !== v.y || cv[2] !== v.width || cv[3] !== v.height) { cv[0] = v.x; cv[1] = v.y; cv[2] = v.width; cv[3] = v.height; gl.uniform4f(ud[name].location, v.x, v.y, v.width, v.height); } ` }, // uploading a pixi point as a vec2 { type: "vec2<f32>", test: (s) => s.type === "vec2<f32>" && s.size === 1 && s.value.x !== void 0, ubo: ` v = uv[name]; data[offset] = v.x; data[offset + 1] = v.y; `, uniform: ` cv = ud[name].value; v = uv[name]; if (cv[0] !== v.x || cv[1] !== v.y) { cv[0] = v.x; cv[1] = v.y; gl.uniform2f(ud[name].location, v.x, v.y); } ` }, // uploading a pixi color as a vec4 { type: "vec4<f32>", test: (s) => s.type === "vec4<f32>" && s.size === 1 && s.value.red !== void 0, ubo: ` v = uv[name]; data[offset] = v.red; data[offset + 1] = v.green; data[offset + 2] = v.blue; data[offset + 3] = v.alpha; `, uniform: ` cv = ud[name].value; v = uv[name]; if (cv[0] !== v.red || cv[1] !== v.green || cv[2] !== v.blue || cv[3] !== v.alpha) { cv[0] = v.red; cv[1] = v.green; cv[2] = v.blue; cv[3] = v.alpha; gl.uniform4f(ud[name].location, v.red, v.green, v.blue, v.alpha); } ` }, // uploading a pixi color as a vec3 { type: "vec3<f32>", test: (s) => s.type === "vec3<f32>" && s.size === 1 && s.value.red !== void 0, ubo: ` v = uv[name]; data[offset] = v.red; data[offset + 1] = v.green; data[offset + 2] = v.blue; `, uniform: ` cv = ud[name].value; v = uv[name]; if (cv[0] !== v.red || cv[1] !== v.green || cv[2] !== v.blue) { cv[0] = v.red; cv[1] = v.green; cv[2] = v.blue; gl.uniform3f(ud[name].location, v.red, v.green, v.blue); } ` } ]; function Pt(s, e, t, r) { const a = [` var v = null; var v2 = null; var t = 0; var index = 0; var name = null; var arrayOffset = null; `]; let n = 0; for (let l = 0; l < s.length; l++) { const o = s[l], d = o.data.name; let c = !1, h = 0; for (let f = 0; f < M.length; f++) if (M[f].test(o.data)) { h = o.offset / 4, a.push( `name = "${d}";`, `offset += ${h - n};`, M[f][e] || M[f].ubo ), c = !0; break; } if (!c) if (o.data.size > 1) h = o.offset / 4, a.push(t(o, h - n)); else { const f = r[o.data.type]; h = o.offset / 4, a.push( /* wgsl */ ` v = uv.${d}; offset += ${h - n}; ${f}; ` ); } n = h; } const i = a.join(` `); return new Function( "uv", "data", "offset", i ); } function x(s, e) { return ` for (let i = 0; i < ${s * e}; i++) { data[offset + (((i / ${s})|0) * 4) + (i % ${s})] = v[i]; } `; } const at = { f32: ` data[offset] = v;`, i32: ` data[offset] = v;`, "vec2<f32>": ` data[offset] = v[0]; data[offset + 1] = v[1];`, "vec3<f32>": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 2] = v[2];`, "vec4<f32>": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 2] = v[2]; data[offset + 3] = v[3];`, "mat2x2<f32>": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 4] = v[2]; data[offset + 5] = v[3];`, "mat3x3<f32>": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 2] = v[2]; data[offset + 4] = v[3]; data[offset + 5] = v[4]; data[offset + 6] = v[5]; data[offset + 8] = v[6]; data[offset + 9] = v[7]; data[offset + 10] = v[8];`, "mat4x4<f32>": ` for (let i = 0; i < 16; i++) { data[offset + i] = v[i]; }`, "mat3x2<f32>": x(3, 2), "mat4x2<f32>": x(4, 2), "mat2x3<f32>": x(2, 3), "mat4x3<f32>": x(4, 3), "mat2x4<f32>": x(2, 4), "mat3x4<f32>": x(3, 4) }, Gt = { ...at, "mat2x2<f32>": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 2] = v[2]; data[offset + 3] = v[3]; ` }; function nt(s, e, t, r, a, n) { const i = n ? 1 : -1; return s.identity(), s.a = 1 / r * 2, s.d = i * (1 / a * 2), s.tx = -1 - e * s.a, s.ty = -i - t * s.d, s; } const v = /* @__PURE__ */ new Map(); function de(s, e) { if (!v.has(s)) { const t = new m({ source: new U({ resource: s, ...e }) }), r = () => { v.get(s) === t && v.delete(s); }; t.once("destroy", r), t.source.once("destroy", r), v.set(s, t); } return v.get(s); } function it(s) { const e = s.colorTexture.source.resource; return globalThis.HTMLCanvasElement && e instanceof HTMLCanvasElement && document.body.contains(e); } const ce = class he { /** * @param [descriptor] - Options for creating a render target. */ constructor(e = {}) { if (this.uid = C("renderTarget"), this.colorTextures = [], this.dirtyId = 0, this.isRoot = !1, this._size = new Float32Array(2), this._managedColorTextures = !1, e = { ...he.defaultOptions, ...e }, this.stencil = e.stencil, this.depth = e.depth, this.isRoot = e.isRoot, typeof e.colorTextures == "number") { this._managedColorTextures = !0; for (let t = 0; t < e.colorTextures; t++) this.colorTextures.push( new _({ width: e.width, height: e.height, resolution: e.resolution, antialias: e.antialias }) ); } else { this.colorTextures = [...e.colorTextures.map((r) => r.source)]; const t = this.colorTexture.source; this.resize(t.width, t.height, t._resolution); } this.colorTexture.source.on("resize", this.onSourceResize, this), (e.depthStencilTexture || this.stencil) && (e.depthStencilTexture instanceof m || e.depthStencilTexture instanceof _ ? this.depthStencilTexture = e.depthStencilTexture.source : this.ensureDepthStencilTexture()); } get size() { const e = this._size; return e[0] = this.pixelWidth, e[1] = this.pixelHeight, e; } get width() { return this.colorTexture.source.width; } get height() { return this.colorTexture.source.height; } get pixelWidth() { return this.colorTexture.source.pixelWidth; } get pixelHeight() { return this.colorTexture.source.pixelHeight; } get resolution() { return this.colorTexture.source._resolution; } get colorTexture() { return this.colorTextures[0]; } onSourceResize(e) { this.resize(e.width, e.height, e._resolution, !0); } /** * This will ensure a depthStencil texture is created for this render target. * Most likely called by the mask system to make sure we have stencil buffer added. * @internal * @ignore */ ensureDepthStencilTexture() { this.depthStencilTexture || (this.depthStencilTexture = new _({ width: this.width, height: this.height, resolution: this.resolution, format: "depth24plus-stencil8", autoGenerateMipmaps: !1, antialias: !1, mipLevelCount: 1 // sampleCount: handled by the render target system.. })); } resize(e, t, r = this.resolution, a = !1) { this.dirtyId++, this.colorTextures.forEach((n, i) => { a && i === 0 || n.source.resize(e, t, r); }), this.depthStencilTexture && this.depthStencilTexture.source.resize(e, t, r); } destroy() { this.colorTexture.source.off("resize", this.onSourceResize, this), this._managedColorTextures && this.colorTextures.forEach((e) => { e.destroy(); }), this.depthStencilTexture && (this.depthStencilTexture.destroy(), delete this.depthStencilTexture); } }; ce.defaultOptions = { /** the width of the RenderTarget */ width: 0, /** the height of the RenderTarget */ height: 0, /** the resolution of the RenderTarget */ resolution: 1, /** an array of textures, or a number indicating how many color textures there should be */ colorTextures: 1, /** should this render target have a stencil buffer? */ stencil: !1, /** should this render target have a depth buffer? */ depth: !1, /** should this render target be antialiased? */ antialias: !1, // save on perf by default! /** is this a root element, true if this is gl context owners render target */ isRoot: !1 }; let I = ce; class Rt { constructor(e) { this.rootViewPort = new w(), this.viewport = new w(), this.onRenderTargetChange = new Ee("onRenderTargetChange"), this.projectionMatrix = new g(), this.defaultClearColor = [0, 0, 0, 0], this._renderSurfaceToRenderTargetHash = /* @__PURE__ */ new Map(), this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null), this._renderTargetStack = [], this._renderer = e; } /** called when dev wants to finish a render pass */ finishRenderPass() { this.adaptor.finishRenderPass(this.renderTarget); } /** * called when the renderer starts to render a scene. * @param options * @param options.target - the render target to render to * @param options.clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111 * @param options.clearColor - the color to clear to * @param options.frame - the frame to render to */ renderStart({ target: e, clear: t, clearColor: r, frame: a }) { this._renderTargetStack.length = 0, this.push( e, t, r, a ), this.rootViewPort.copyFrom(this.viewport), this.rootRenderTarget = this.renderTarget, this.renderingToScreen = it(this.rootRenderTarget); } /** * Binding a render surface! This is the main function of the render target system. * It will take the RenderSurface (which can be a texture, canvas, or render target) and bind it to the renderer. * Once bound all draw calls will be rendered to the render surface. * * If a frame is not provide and the render surface is a texture, the frame of the texture will be used. * @param renderSurface - the render surface to bind * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111 * @param clearColor - the color to clear to * @param frame - the frame to render to * @returns the render target that was bound */ bind(e, t = !0, r, a) { const n = this.getRenderTarget(e), i = this.renderTarget !== n; this.renderTarget = n, this.renderSurface = e; const l = this.getGpuRenderTarget(n); (n.pixelWidth !== l.width || n.pixelHeight !== l.height) && (this.adaptor.resizeGpuRenderTarget(n), l.width = n.pixelWidth, l.height = n.pixelHeight); const o = n.colorTexture, d = this.viewport, c = o.pixelWidth, h = o.pixelHeight; if (!a && e instanceof m && (a = e.frame), a) { const f = o._resolution; d.x = a.x * f + 0.5 | 0, d.y = a.y * f + 0.5 | 0, d.width = a.width * f + 0.5 | 0, d.height = a.height * f + 0.5 | 0; } else d.x = 0, d.y = 0, d.width = c, d.height = h; return nt( this.projectionMatrix, 0, 0, d.width / o.resolution, d.height / o.resolution, !n.isRoot ), this.adaptor.startRenderPass(n, t, r, d), i && this.onRenderTargetChange.emit(n), n; } clear(e, t = B.ALL, r) { t && (e && (e = this.getRenderTarget(e)), this.adaptor.clear( e || this.renderTarget, t, r, this.viewport )); } contextChange() { this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null); } /** * Push a render surface to the renderer. This will bind the render surface to the renderer, * @param renderSurface - the render surface to push * @param clear - the clear mode to use. Can be true or a CLEAR number 'COLOR | DEPTH | STENCIL' 0b111 * @param clearColor - the color to clear to * @param frame - the frame to use when rendering to the render surface */ push(e, t = B.ALL, r, a) { const n = this.bind(e, t, r, a); return this._renderTargetStack.push({ renderTarget: n, frame: a }), n; } /** Pops the current render target from the renderer and restores the previous render target. */ pop() { this._renderTargetStack.pop(); const e = this._renderTargetStack[this._renderTargetStack.length - 1]; this.bind(e.renderTarget, !1, null, e.frame); } /** * Gets the render target from the provide render surface. Eg if its a texture, * it will return the render target for the texture. * If its a render target, it will return the same render target. * @param renderSurface - the render surface to get the render target for * @returns the render target for the render surface */ getRenderTarget(e) { return e.isTexture && (e = e.source), this._renderSurfaceToRenderTargetHash.get(e) ?? this._initRenderTarget(e); } /** * Copies a render surface to another texture * @param sourceRenderSurfaceTexture - the render surface to copy from * @param destinationTexture - the texture to copy to * @param originSrc - the origin of the copy * @param originSrc.x - the x origin of the copy * @param originSrc.y - the y origin of the copy * @param size - the size of the copy * @param size.width - the width of the copy * @param size.height - the height of the copy * @param originDest - the destination origin (top left to paste from!) * @param originDest.x - the x origin of the paste * @param originDest.y - the y origin of the paste */ copyToTexture(e, t, r, a, n) { r.x < 0 && (a.width += r.x, n.x -= r.x, r.x = 0), r.y < 0 && (a.height += r.y, n.y -= r.y, r.y = 0); const { pixelWidth: i, pixelHeight: l } = e; return a.width = Math.min(a.width, i - r.x), a.height = Math.min(a.height, l - r.y), this.adaptor.copyToTexture( e, t, r, a, n ); } /** * ensures that we have a depth stencil buffer available to render to * This is used by the mask system to make sure we have a stencil buffer. */ ensureDepthStencil() { this.renderTarget.stencil || (this.renderTarget.stencil = !0, this.adaptor.startRenderPass(this.renderTarget, !1, null, this.viewport)); } /** nukes the render target system */ destroy() { this._renderer = null, this._renderSurfaceToRenderTargetHash.forEach((e, t) => { e !== t && e.destroy(); }), this._renderSurfaceToRenderTargetHash.clear(), this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null); } _initRenderTarget(e) { let t = null; return U.test(e) && (e = de(e).source), e instanceof I ? t = e : e instanceof _ && (t = new I({ colorTextures: [e] }), U.test(e.source.resource) && (t.isRoot = !0), e.once("destroy", () => { t.destroy(); const r = this._gpuRenderTargetHash[t.uid]; r && (this._gpuRenderTargetHash[t.uid] = null, this.adaptor.destroyGpuRenderTarget(r)); })), this._renderSurfaceToRenderTargetHash.set(e, t), t; } getGpuRenderTarget(e) { return this._gpuRenderTargetHash[e.uid] || (this._gpuRenderTargetHash[e.uid] = this.adaptor.initGpuRenderTarget(e)); } } class Bt extends De { /** * Create a new Buffer Resource. * @param options - The options for the buffer resource * @param options.buffer - The underlying buffer that this resource is using * @param options.offset - The offset of the buffer this resource is using. * If not provided, then it will use the offset of the buffer. * @param options.size - The size of the buffer this resource is using. * If not provided, then it will use the size of the buffer. */ constructor({ buffer: e, offset: t, size: r }) { super(), this.uid = C("buffer"), this._resourceType = "bufferResource", this._touched = 0, this._resourceId = C("resource"), this._bufferResource = !0, this.destroyed = !1, this.buffer = e, this.offset = t | 0, this.size = r, this.buffer.on("change", this.onBufferChange, this); } onBufferChange() { this._resourceId = C("resource"), this.emit("change", this); } /** * Destroys this resource. Make sure the underlying buffer is not used anywhere else * if you want to destroy it as well, or code will explode * @param destroyBuffer - Should the underlying buffer be destroyed as well? */ destroy(e = !1) { this.destroyed = !0, e && this.buffer.destroy(), this.emit("change", this), this.buffer = null; } } class fe { constructor(e) { this._renderer = e; } addRenderable(e, t) { this._renderer.renderPipes.batch.break(t), t.add(e); } execute(e) { e.isRenderable && e.render(this._renderer); } destroy() { this._renderer = null; } } fe.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "customRender" }; function pe(s, e) { const t = s.instructionSet, r = t.instructions; for (let a = 0; a < t.instructionSize; a++) { const n = r[a]; e[n.renderPipeId].execute(n); } } class me { constructor(e) { this._renderer = e; } addRenderGroup(e, t) { this._renderer.renderPipes.batch.break(t), t.add(e); } execute(e) { e.isRenderable && (this._renderer.globalUniforms.push({ worldTransformMatrix: e.worldTransform, worldColor: e.worldColorAlpha }), pe(e, this._renderer.renderPipes), this._renderer.globalUniforms.pop()); } destroy() { this._renderer = null; } } me.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "renderGroup" }; function ge(s, e = []) { e.push(s); for (let t = 0; t < s.renderGroupChildren.length; t++) ge(s.renderGroupChildren[t], e); return e; } function ot(s, e, t) { const r = s >> 16 & 255, a = s >> 8 & 255, n = s & 255, i = e >> 16 & 255, l = e >> 8 & 255, o = e & 255, d = r + (i - r) * t, c = a + (l - a) * t, h = n + (o - n) * t; return (d << 16) + (c << 8) + h; } const G = 16777215; function xe(s, e) { return s === G || e === G ? s + e - G : ot(s, e, 0.5); } const lt = new S(); function ve(s, e = !1) { ut(s); const t = s.childrenToUpdate, r = s.updateTick++; for (const a in t) { const n = t[a], i = n.list, l = n.index; for (let o = 0; o < l; o++) { const d = i[o]; d.parentRenderGroup === s && be(d, r, 0); } n.index = 0; } if (e) for (let a = 0; a < s.renderGroupChildren.length; a++) ve(s.renderGroupChildren[a], e); } function ut(s) { const e = s.root; let t; if (s.renderGroupParent) { const r = s.renderGroupParent; s.worldTransform.appendFrom( e.relativeGroupTransform, r.worldTransform ), s.worldColor = xe( e.groupColor, r.worldColor ), t = e.groupAlpha * r.worldAlpha; } else s.worldTransform.copyFrom(e.localTransform), s.worldColor = e.localColor, t = e.localAlpha; t = t < 0 ? 0 : t > 1 ? 1 : t, s.worldAlpha = t, s.worldColorAlpha = s.worldColor + ((t * 255 | 0) << 24); } function be(s, e, t) { if (e === s.updateTick) return; s.updateTick = e, s.didChange = !1; const r = s.localTransform; s.updateLocalTransform(); const a = s.parent; if (a && !a.renderGroup ? (t = t | s._updateFlags, s.relativeGroupTransform.appendFrom( r, a.relativeGroupTransform ), t && j(s, a, t)) : (t = s._updateFlags, s.relativeGroupTransform.copyFrom(r), t && j(s, lt, t)), !s.renderGroup) { const n = s.children, i = n.length; for (let o = 0; o < i; o++) be(n[o], e, t); const l = s.parentRenderGroup; s.renderPipeId && !l.structureDidChange && l.updateRenderable(s); } } function j(s, e, t) { if (t & Oe) { s.groupColor = xe( s.localColor, e.groupColor ); let r = s.localAlpha * e.groupAlpha; r = r < 0 ? 0 : r > 1 ? 1 : r, s.groupAlpha = r, s.groupColorAlpha = s.groupColor + ((r * 255 | 0) << 24); } t & ze && (s.groupBlendMode = s.localBlendMode === "inherit" ? e.groupBlendMode : s.localBlendMode), t & He && (s.globalDisplayStatus = s.localDisplayStatus & e.globalDisplayStatus), s._updateFlags = 0; } function dt(s, e) { const { list: t, index: r } = s.childrenRenderablesToUpdate; let a = !1; for (let n = 0; n < r; n++) { const i = t[n]; if (a = e[i.renderPipeId].validateRenderable(i), a) break; } return s.structureDidChange = a, a; } const ct = new g(); class _e { constructor(e) { this._renderer = e; } render({ container: e, transform: t }) { e.isRenderGroup = !0; const r = e.parent, a = e.renderGroup.renderGroupParent; e.parent = null, e.renderGroup.renderGroupParent = null; const n = this._renderer, i = ge(e.renderGroup, []); let l = ct; t && (l = l.copyFrom(e.renderGroup.localTransform), e.renderGroup.localTransform.copyFrom(t)); const o = n.renderPipes; for (let d = 0; d < i.length; d++) { const c = i[d]; c.runOnRender(), c.instructionSet.renderPipes = o, c.structureDidChange || dt(c, o), ve(c), c.structureDidChange ? (c.structureDidChange = !1, Ze(c, o)) : ht(c), c.childrenRenderablesToUpdate.index = 0, n.renderPipes.batch.upload(c.instructionSet); } n.globalUniforms.start({ worldTransformMatrix: t ? e.renderGroup.localTransform : e.renderGroup.worldTransform, worldColor: e.renderGroup.worldColorAlpha }), pe(e.renderGroup, o), o.uniformBatch && o.uniformBatch.renderEnd(), t && e.renderGroup.localTransform.copyFrom(l), e.parent = r, e.renderGroup.renderGroupParent = a; } destroy() { this._renderer = null; } } _e.extension = { type: [ u.WebGLSystem, u.WebGPUSystem, u.CanvasSystem ], name: "renderGroup" }; function ht(s) { const { list: e, index: t } = s.childrenRenderablesToUpdate; for (let r = 0; r < t; r++) { const a = e[r]; a.didViewUpdate && s.updateRenderable(a); } } class ye { constructor(e) { this._gpuSpriteHash = /* @__PURE__ */ Object.create(null), this._renderer = e; } addRenderable(e, t) { const r = this._getGpuSprite(e); e._didSpriteUpdate && this._updateBatchableSprite(e, r), this._renderer.renderPipes.batch.addToBatch(r); } updateRenderable(e) { const t = this._gpuSpriteHash[e.uid]; e._didSpriteUpdate && this._updateBatchableSprite(e, t), t.batcher.updateElement(t); } validateRenderable(e) { const t = e._texture, r = this._getGpuSprite(e); return r.texture._source !== t._source ? !r.batcher.checkAndUpdateTexture(r, t) : !1; } destroyRenderable(e) { const t = this._gpuSpriteHash[e.uid]; b.return(t), this._gpuSpriteHash[e.uid] = null; } _updateBatchableSprite(e, t) { e._didSpriteUpdate = !1, t.bounds = e.bounds, t.texture = e._texture; } _getGpuSprite(e) { return this._gpuSpriteHash[e.uid] || this._initGPUSprite(e); } _initGPUSprite(e) { const t = b.get(qe); return t.renderable = e, t.texture = e._texture, t.bounds = e.bounds, t.roundPixels = this._renderer._roundPixels | e._roundPixels, this._gpuSpriteHash[e.uid] = t, e._didSpriteUpdate = !1, e.on("destroyed", () => { this.destroyRenderable(e); }), t; } destroy() { for (const e in this._gpuSpriteHash) b.return(this._gpuSpriteHash[e]); this._gpuSpriteHash = null, this._renderer = null; } } ye.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "sprite" }; const F = class Te { constructor() { this.clearBeforeRender = !0, this._backgroundColor = new J(0), this.color = this._backgroundColor, this.alpha = 1; } /** * initiates the background system * @param options - the options for the background colors */ init(e) { e = { ...Te.defaultOptions, ...e }, this.clearBeforeRender = e.clearBeforeRender, this.color = e.background || e.backgroundColor || this._backgroundColor, this.alpha = e.backgroundAlpha, this._backgroundColor.setAlpha(e.backgroundAlpha); } /** The background color to fill if not transparent */ get color() { return this._backgroundColor; } set color(e) { this._backgroundColor.setValue(e); } /** The background color alpha. Setting this to 0 will make the canvas transparent. */ get alpha() { return this._backgroundColor.alpha; } set alpha(e) { this._backgroundColor.setAlpha(e); } /** The background color as an [R, G, B, A] array. */ get colorRgba() { return this._backgroundColor.toArray(); } /** * destroys the background system * @internal * @ignore */ destroy() { } }; F.extension = { type: [ u.WebGLSystem, u.WebGPUSystem, u.CanvasSystem ], name: "background", priority: 0 }; F.defaultOptions = { /** * {@link WebGLOptions.backgroundAlpha} * @default 1 */ backgroundAlpha: 1, /** * {@link WebGLOptions.backgroundColor} * @default 0x000000 */ backgroundColor: 0, /** * {@link WebGLOptions.clearBeforeRender} * @default true */ clearBeforeRender: !0 }; let ft = F; const y = {}; X.handle(u.BlendMode, (s) => { if (!s.name) throw new Error("BlendMode extension must have a name property"); y[s.name] = s.ref; }, (s) => { delete y[s.name]; }); class ke { constructor(e) { this._isAdvanced = !1, this._filterHash = /* @__PURE__ */ Object.create(null), this._renderer = e; } /** * This ensures that a blendMode switch is added to the instruction set if the blend mode has changed. * @param renderable - The renderable we are adding to the instruction set * @param blendMode - The blend mode of the renderable * @param instructionSet - The instruction set we are adding to */ setBlendMode(e, t, r) { if (this._activeBlendMode === t) { this._isAdvanced && this._renderableList.push(e); return; } this._activeBlendMode = t, this._isAdvanced && this._endAdvancedBlendMode(r), this._isAdvanced = !!y[t], this._isAdvanced && (this._beginAdvancedBlendMode(r), this._renderableList.push(e)); } _beginAdvancedBlendMode(e) { this._renderer.renderPipes.batch.break(e); const t = this._activeBlendMode; if (!y[t]) { Y(`Unable to assign BlendMode: '${t}'. You may want to include: import 'pixi.js/advanced-blend-modes'`); return; } let r = this._filterHash[t]; r || (r = this._filterHash[t] = new K(), r.filters = [new y[t]()]); const a = { renderPipeId: "filter", action: "pushFilter", renderables: [], filterEffect: r, canBundle: !1 }; this._renderableList = a.renderables, e.add(a); } _endAdvancedBlendMode(e) { this._renderableList = null, this._renderer.renderPipes.batch.break(e), e.add({ renderPipeId: "filter", action: "popFilter", canBundle: !1 }); } /** * called when the instruction build process is starting this will reset internally to the default blend mode * @internal * @ignore */ buildStart() { this._isAdvanced = !1; } /** * called when the instruction build process is finished, ensuring that if there is an advanced blend mode * active, we add the final render instructions added to the instruction set * @param instructionSet - The instruction set we are adding to * @internal * @ignore */ buildEnd(e) { this._isAdvanced && this._endAdvancedBlendMode(e); } /** * @internal * @ignore */ destroy() { this._renderer = null, this._renderableList = null; for (const e in this._filterHash) this._filterHash[e].dest