UNPKG

wave-roll

Version:

JavaScript Library for Comparative MIDI Piano-Roll Visualization

1,565 lines (1,523 loc) 86.2 kB
import { q as Le, G as ae, t as ne, u as He, k as ie, M as v, v as oe, E as u, e as O, x as S, y as ze, z as F, F as b, R as L, H as le, I as We, s as m, S as f, h as B, w as H, J, K as Ve, b as X, B as k, i as U, L as M, j as T, N as w, O as Ne, a as je, Q as ue, V as de, W as ce, X as he, C as P, Y as $e, Z as A, D as z, _ as qe, P as Ke, c as Ye, T as Q, $ as Z, a0 as Je, a1 as Xe, a2 as Qe } from "./index-B5Sv2rNJ.js"; import { S as fe, B as pe, c as Ze } from "./colorToUniform-zJcCVLeu.js"; const me = class I extends Le { /** * @param options - The optional parameters of this filter. */ constructor(e) { e = { ...I.defaultOptions, ...e }, super(e), this.enabled = !0, this._state = fe.for2d(), this.blendMode = e.blendMode, 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.clipToViewport = e.clipToViewport, 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, s) { e.applyFilter(this, t, r, s); } /** * 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, ...s } = e; let n, i; return t && (n = ae.from(t)), r && (i = ne.from(r)), new I({ gpuProgram: n, glProgram: i, ...s }); } }; me.defaultOptions = { blendMode: "normal", resolution: 1, padding: 0, antialias: "off", blendRequired: !1, clipToViewport: !0 }; let et = me; var tt = `in vec2 vMaskCoord; in vec2 vTextureCoord; uniform sampler2D uTexture; uniform sampler2D uMaskTexture; uniform float uAlpha; uniform vec4 uMaskClamp; uniform float uInverse; 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); float a = alphaMul * masky.r * npmAlpha * clip; if (uInverse == 1.0) { a = 1.0 - a; } finalColor = original * a; } `, rt = `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); } `, ee = `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, uInverse: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 uAlpha = filterUniforms.uAlpha; 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 alphaMul = 1.0 - uAlpha * (1.0 - mask.a); var a: f32 = alphaMul * mask.r * uAlpha * clip; if (filterUniforms.uInverse == 1.0) { a = 1.0 - a; } return source * a; } `; class st extends et { constructor(e) { const { sprite: t, ...r } = e, s = new He(t.texture), n = new ie({ uFilterMatrix: { value: new v(), type: "mat3x3<f32>" }, uMaskClamp: { value: s.uClampFrame, type: "vec4<f32>" }, uAlpha: { value: 1, type: "f32" }, uInverse: { value: e.inverse ? 1 : 0, type: "f32" } }), i = ae.from({ vertex: { source: ee, entryPoint: "mainVertex" }, fragment: { source: ee, entryPoint: "mainFragment" } }), o = ne.from({ vertex: rt, fragment: tt, name: "mask-filter" }); super({ ...r, gpuProgram: i, glProgram: o, clipToViewport: !1, resources: { filterUniforms: n, uMaskTexture: t.texture.source } }), this.sprite = t, this._textureMatrix = s; } set inverse(e) { this.resources.filterUniforms.uniforms.uInverse = e ? 1 : 0; } get inverse() { return this.resources.filterUniforms.uniforms.uInverse === 1; } apply(e, t, r, s) { 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, s); } } const W = class ve { constructor(e, t) { this.state = fe.for2d(), this._batchersByInstructionSet = /* @__PURE__ */ Object.create(null), this._activeBatches = /* @__PURE__ */ Object.create(null), this.renderer = e, this._adaptor = t, this._adaptor.init?.(this); } static getBatcher(e) { return new this._availableBatchers[e](); } buildStart(e) { let t = this._batchersByInstructionSet[e.uid]; t || (t = this._batchersByInstructionSet[e.uid] = /* @__PURE__ */ Object.create(null), t.default || (t.default = new oe({ maxTextures: this.renderer.limits.maxBatchableTextures }))), this._activeBatches = t, this._activeBatch = this._activeBatches.default; for (const r in this._activeBatches) this._activeBatches[r].begin(); } addToBatch(e, t) { if (this._activeBatch.name !== e.batcherName) { this._activeBatch.break(t); let r = this._activeBatches[e.batcherName]; r || (r = this._activeBatches[e.batcherName] = ve.getBatcher(e.batcherName), r.begin()), this._activeBatch = r; } this._activeBatch.add(e); } break(e) { this._activeBatch.break(e); } buildEnd(e) { this._activeBatch.break(e); const t = this._activeBatches; for (const r in t) { const s = t[r], n = s.geometry; n.indexBuffer.setDataWithSize(s.indexBuffer, s.indexSize, !0), n.buffers[0].setDataWithSize(s.attributeBuffer.float32View, s.attributeSize, !1); } } upload(e) { const t = this._batchersByInstructionSet[e.uid]; for (const r in t) { const s = t[r], n = s.geometry; s.dirty && (s.dirty = !1, n.buffers[0].update(s.attributeSize * 4)); } } execute(e) { if (e.action === "startBatch") { const t = e.batcher, r = t.geometry, s = t.shader; this._adaptor.start(this, r, s); } this._adaptor.execute(this, e); } destroy() { this.state = null, this.renderer = null, this._adaptor = null; for (const e in this._activeBatches) this._activeBatches[e].destroy(); this._activeBatches = null; } }; W.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "batch" }; W._availableBatchers = /* @__PURE__ */ Object.create(null); let ge = W; O.handleByMap(u.Batcher, ge._availableBatchers); O.add(oe); const Ut = { 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); ` ) } }, At = { 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); ` ) } }, at = new F(); class nt extends le { constructor() { super(), this.filters = [new st({ sprite: new We(m.EMPTY), inverse: !1, resolution: "inherit", antialias: "inherit" })]; } get sprite() { return this.filters[0].sprite; } set sprite(e) { this.filters[0].sprite = e; } get inverse() { return this.filters[0].inverse; } set inverse(e) { this.filters[0].inverse = e; } } class xe { constructor(e) { this._activeMaskStage = [], this._renderer = e; } push(e, t, r) { const s = this._renderer; if (s.renderPipes.batch.break(r), r.add({ renderPipeId: "alphaMask", action: "pushMaskBegin", mask: e, inverse: t._maskOptions.inverse, canBundle: !1, maskedContainer: t }), e.inverse = t._maskOptions.inverse, e.renderMaskToTexture) { const n = e.mask; n.includeInBuild = !0, n.collectRenderables( r, s, null ), n.includeInBuild = !1; } s.renderPipes.batch.break(r), r.add({ renderPipeId: "alphaMask", action: "pushMaskEnd", mask: e, maskedContainer: t, inverse: t._maskOptions.inverse, canBundle: !1 }); } pop(e, t, r) { this._renderer.renderPipes.batch.break(r), r.add({ renderPipeId: "alphaMask", action: "popMaskEnd", mask: e, inverse: t._maskOptions.inverse, canBundle: !1 }); } execute(e) { const t = this._renderer, r = e.mask.renderMaskToTexture; if (e.action === "pushMaskBegin") { const s = S.get(nt); if (s.inverse = e.inverse, r) { e.mask.mask.measurable = !0; const n = ze(e.mask.mask, !0, at); e.mask.mask.measurable = !1, n.ceil(); const i = t.renderTarget.renderTarget.colorTexture.source, o = b.getOptimalTexture( n.width, n.height, i._resolution, i.antialias ); t.renderTarget.push(o, !0), t.globalUniforms.push({ offset: n, worldColor: 4294967295 }); const l = s.sprite; l.texture = o, l.worldTransform.tx = n.minX, l.worldTransform.ty = n.minY, this._activeMaskStage.push({ filterEffect: s, maskedContainer: e.maskedContainer, filterTexture: o }); } else s.sprite = e.mask.mask, this._activeMaskStage.push({ filterEffect: s, maskedContainer: e.maskedContainer }); } else if (e.action === "pushMaskEnd") { const s = this._activeMaskStage[this._activeMaskStage.length - 1]; r && (t.type === L.WEBGL && t.renderTarget.finishRenderPass(), t.renderTarget.pop(), t.globalUniforms.pop()), t.filter.push({ renderPipeId: "filter", action: "pushFilter", container: s.maskedContainer, filterEffect: s.filterEffect, canBundle: !1 }); } else if (e.action === "popMaskEnd") { t.filter.pop(); const s = this._activeMaskStage.pop(); r && b.returnTexture(s.filterTexture), S.return(s.filterEffect); } } destroy() { this._renderer = null, this._activeMaskStage = null; } } xe.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "alphaMask" }; class _e { 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; } } _e.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "colorMask" }; class be { constructor(e) { this._maskStackHash = {}, this._maskHash = /* @__PURE__ */ new WeakMap(), this._renderer = e; } push(e, t, r) { var s; 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, inverse: t._maskOptions.inverse, canBundle: !1 }); const o = n.mask; o.includeInBuild = !0, this._maskHash.has(n) || this._maskHash.set(n, { instructionsStart: 0, instructionsLength: 0 }); const l = this._maskHash.get(n); l.instructionsStart = r.instructionSize, o.collectRenderables( r, i, null ), o.includeInBuild = !1, i.renderPipes.batch.break(r), r.add({ renderPipeId: "stencilMask", action: "pushMaskEnd", mask: e, inverse: t._maskOptions.inverse, canBundle: !1 }); const d = r.instructionSize - l.instructionsStart - 1; l.instructionsLength = d; const c = i.renderTarget.renderTarget.uid; (s = this._maskStackHash)[c] ?? (s[c] = 0); } pop(e, t, r) { const s = e, n = this._renderer; n.renderPipes.batch.break(r), n.renderPipes.blendMode.setBlendMode(s.mask, "none", r), r.add({ renderPipeId: "stencilMask", action: "popMaskBegin", inverse: t._maskOptions.inverse, canBundle: !1 }); const i = this._maskHash.get(e); for (let o = 0; o < i.instructionsLength; o++) r.instructions[r.instructionSize++] = r.instructions[i.instructionsStart++]; r.add({ renderPipeId: "stencilMask", action: "popMaskEnd", canBundle: !1 }); } execute(e) { var t; const r = this._renderer, s = r.renderTarget.renderTarget.uid; let n = (t = this._maskStackHash)[s] ?? (t[s] = 0); e.action === "pushMaskBegin" ? (r.renderTarget.ensureDepthStencil(), r.stencil.setStencilMode(f.RENDERING_MASK_ADD, n), n++, r.colorMask.setMask(0)) : e.action === "pushMaskEnd" ? (e.inverse ? r.stencil.setStencilMode(f.INVERSE_MASK_ACTIVE, n) : r.stencil.setStencilMode(f.MASK_ACTIVE, n), r.colorMask.setMask(15)) : e.action === "popMaskBegin" ? (r.colorMask.setMask(0), n !== 0 ? r.stencil.setStencilMode(f.RENDERING_MASK_REMOVE, n) : (r.renderTarget.clear(null, B.STENCIL), r.stencil.setStencilMode(f.DISABLED, n)), n--) : e.action === "popMaskEnd" && (e.inverse ? r.stencil.setStencilMode(f.INVERSE_MASK_ACTIVE, n) : r.stencil.setStencilMode(f.MASK_ACTIVE, n), r.colorMask.setMask(15)), this._maskStackHash[s] = n; } destroy() { this._renderer = null, this._maskStackHash = null, this._maskHash = null; } } be.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "stencilMask" }; function It(a, e) { for (const t in a.attributes) { const r = a.attributes[t], s = e[t]; s ? (r.format ?? (r.format = s.format), r.offset ?? (r.offset = s.offset), r.instance ?? (r.instance = s.instance)) : H(`Attribute ${t} is not present in the shader, but is present in the geometry. Unable to infer attribute details.`); } it(a); } function it(a) { const { buffers: e, attributes: t } = a, r = {}, s = {}; for (const n in e) { const i = e[n]; r[i.uid] = 0, s[i.uid] = 0; } for (const n in t) { const i = t[n]; r[i.buffer.uid] += J(i.format).stride; } for (const n in t) { const i = t[n]; i.stride ?? (i.stride = r[i.buffer.uid]), i.start ?? (i.start = s[i.buffer.uid]), s[i.buffer.uid] += J(i.format).stride; } } const x = []; x[f.NONE] = void 0; x[f.DISABLED] = { stencilWriteMask: 0, stencilReadMask: 0 }; x[f.RENDERING_MASK_ADD] = { stencilFront: { compare: "equal", passOp: "increment-clamp" }, stencilBack: { compare: "equal", passOp: "increment-clamp" } }; x[f.RENDERING_MASK_REMOVE] = { stencilFront: { compare: "equal", passOp: "decrement-clamp" }, stencilBack: { compare: "equal", passOp: "decrement-clamp" } }; x[f.MASK_ACTIVE] = { stencilWriteMask: 0, stencilFront: { compare: "equal", passOp: "keep" }, stencilBack: { compare: "equal", passOp: "keep" } }; x[f.INVERSE_MASK_ACTIVE] = { stencilWriteMask: 0, stencilFront: { compare: "not-equal", passOp: "keep" }, stencilBack: { compare: "not-equal", passOp: "keep" } }; class Gt { constructor(e) { this._syncFunctionHash = /* @__PURE__ */ Object.create(null), this._adaptor = e, this._systemCheck(); } /** * Overridable function by `pixi.js/unsafe-eval` to silence * throwing an error if platform doesn't support unsafe-evals. * @private */ _systemCheck() { if (!Ve()) 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 X({ 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 s = Object.keys(e.uniformStructures).map((o) => e.uniformStructures[o]), n = this._adaptor.createUboElements(s), 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 s = this.getUniformGroupData(e); e.buffer || (e.buffer = new X({ data: new Float32Array(s.layout.size / 4), usage: k.UNIFORM | k.COPY_DST })); let n = null; return t || (t = e.buffer.data, n = e.buffer.dataInt32), r || (r = 0), s.syncFunction(e.uniforms, t, n, 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 C = [ // uploading pixi matrix object to mat3 { type: "mat3x3<f32>", test: (a) => a.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: (a) => a.type === "vec4<f32>" && a.size === 1 && a.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: (a) => a.type === "vec2<f32>" && a.size === 1 && a.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: (a) => a.type === "vec4<f32>" && a.size === 1 && a.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: (a) => a.type === "vec3<f32>" && a.size === 1 && a.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 Dt(a, e, t, r) { const s = [` var v = null; var v2 = null; var t = 0; var index = 0; var name = null; var arrayOffset = null; `]; let n = 0; for (let o = 0; o < a.length; o++) { const l = a[o], d = l.data.name; let c = !1, h = 0; for (let p = 0; p < C.length; p++) if (C[p].test(l.data)) { h = l.offset / 4, s.push( `name = "${d}";`, `offset += ${h - n};`, C[p][e] || C[p].ubo ), c = !0; break; } if (!c) if (l.data.size > 1) h = l.offset / 4, s.push(t(l, h - n)); else { const p = r[l.data.type]; h = l.offset / 4, s.push( /* wgsl */ ` v = uv.${d}; offset += ${h - n}; ${p}; ` ); } n = h; } const i = s.join(` `); return new Function( "uv", "data", "dataInt32", "offset", i ); } function g(a, e) { return ` for (let i = 0; i < ${a * e}; i++) { data[offset + (((i / ${a})|0) * 4) + (i % ${a})] = v[i]; } `; } const ot = { f32: ` data[offset] = v;`, i32: ` dataInt32[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];`, "vec2<i32>": ` dataInt32[offset] = v[0]; dataInt32[offset + 1] = v[1];`, "vec3<i32>": ` dataInt32[offset] = v[0]; dataInt32[offset + 1] = v[1]; dataInt32[offset + 2] = v[2];`, "vec4<i32>": ` dataInt32[offset] = v[0]; dataInt32[offset + 1] = v[1]; dataInt32[offset + 2] = v[2]; dataInt32[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>": g(3, 2), "mat4x2<f32>": g(4, 2), "mat2x3<f32>": g(2, 3), "mat4x3<f32>": g(4, 3), "mat2x4<f32>": g(2, 4), "mat3x4<f32>": g(3, 4) }, Et = { ...ot, "mat2x2<f32>": ` data[offset] = v[0]; data[offset + 1] = v[1]; data[offset + 2] = v[2]; data[offset + 3] = v[3]; ` }; function lt(a, e, t, r, s, n) { const i = n ? 1 : -1; return a.identity(), a.a = 1 / r * 2, a.d = i * (1 / s * 2), a.tx = -1 - e * a.a, a.ty = -i - t * a.d, a; } const _ = /* @__PURE__ */ new Map(); function Te(a, e) { if (!_.has(a)) { const t = new m({ source: new U({ resource: a, ...e }) }), r = () => { _.get(a) === t && _.delete(a); }; t.once("destroy", r), t.source.once("destroy", r), _.set(a, t); } return _.get(a); } function ut(a) { const e = a.colorTexture.source.resource; return globalThis.HTMLCanvasElement && e instanceof HTMLCanvasElement && document.body.contains(e); } const ye = class ke { /** * @param [descriptor] - Options for creating a render target. */ constructor(e = {}) { if (this.uid = M("renderTarget"), this.colorTextures = [], this.dirtyId = 0, this.isRoot = !1, this._size = new Float32Array(2), this._managedColorTextures = !1, e = { ...ke.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 T({ 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 T ? 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 */ ensureDepthStencilTexture() { this.depthStencilTexture || (this.depthStencilTexture = new T({ 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, s = !1) { this.dirtyId++, this.colorTextures.forEach((n, i) => { s && 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); } }; ye.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 G = ye; class Ot { constructor(e) { this.rootViewPort = new w(), this.viewport = new w(), this.onRenderTargetChange = new Ne("onRenderTargetChange"), this.projectionMatrix = new v(), this.defaultClearColor = [0, 0, 0, 0], this._renderSurfaceToRenderTargetHash = /* @__PURE__ */ new Map(), this._gpuRenderTargetHash = /* @__PURE__ */ Object.create(null), this._renderTargetStack = [], this._renderer = e, e.renderableGC.addManagedHash(this, "_gpuRenderTargetHash"); } /** 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: s }) { this._renderTargetStack.length = 0, this.push( e, t, r, s ), this.rootViewPort.copyFrom(this.viewport), this.rootRenderTarget = this.renderTarget, this.renderingToScreen = ut(this.rootRenderTarget), this.adaptor.prerender?.(this.rootRenderTarget); } postrender() { this.adaptor.postrender?.(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, s) { const n = this.getRenderTarget(e), i = this.renderTarget !== n; this.renderTarget = n, this.renderSurface = e; const o = this.getGpuRenderTarget(n); (n.pixelWidth !== o.width || n.pixelHeight !== o.height) && (this.adaptor.resizeGpuRenderTarget(n), o.width = n.pixelWidth, o.height = n.pixelHeight); const l = n.colorTexture, d = this.viewport, c = l.pixelWidth, h = l.pixelHeight; if (!s && e instanceof m && (s = e.frame), s) { const p = l._resolution; d.x = s.x * p + 0.5 | 0, d.y = s.y * p + 0.5 | 0, d.width = s.width * p + 0.5 | 0, d.height = s.height * p + 0.5 | 0; } else d.x = 0, d.y = 0, d.width = c, d.height = h; return lt( this.projectionMatrix, 0, 0, d.width / l.resolution, d.height / l.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, s) { const n = this.bind(e, t, r, s); return this._renderTargetStack.push({ renderTarget: n, frame: s }), 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. * * NOTE: * for sourceRenderSurfaceTexture, The render target must be something that is written too by the renderer * * The following is not valid: * @example * const canvas = document.createElement('canvas') * canvas.width = 200; * canvas.height = 200; * * const ctx = canvas2.getContext('2d')! * ctx.fillStyle = 'red' * ctx.fillRect(0, 0, 200, 200); * * const texture = RenderTexture.create({ * width: 200, * height: 200, * }) * const renderTarget = renderer.renderTarget.getRenderTarget(canvas2); * * renderer.renderTarget.copyToTexture(renderTarget,texture, {x:0,y:0},{width:200,height:200},{x:0,y:0}); * * The best way to copy a canvas is to create a texture from it. Then render with that. * * Parsing in a RenderTarget canvas context (with a 2d context) * @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, s, n) { r.x < 0 && (s.width += r.x, n.x -= r.x, r.x = 0), r.y < 0 && (s.height += r.y, n.y -= r.y, r.y = 0); const { pixelWidth: i, pixelHeight: o } = e; return s.width = Math.min(s.width, i - r.x), s.height = Math.min(s.height, o - r.y), this.adaptor.copyToTexture( e, t, r, s, 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 = Te(e).source), e instanceof G ? t = e : e instanceof T && (t = new G({ colorTextures: [e] }), e.source instanceof U && (t.isRoot = !0), e.once("destroy", () => { t.destroy(), this._renderSurfaceToRenderTargetHash.delete(e); 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)); } resetState() { this.renderTarget = null, this.renderSurface = null; } } class Ft extends je { /** * 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 = M("buffer"), this._resourceType = "bufferResource", this._touched = 0, this._resourceId = M("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 = M("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 Ce { constructor(e) { this._renderer = e; } updateRenderable() { } destroyRenderable() { } validateRenderable() { return !1; } addRenderable(e, t) { this._renderer.renderPipes.batch.break(t), t.add(e); } execute(e) { e.isRenderable && e.render(this._renderer); } destroy() { this._renderer = null; } } Ce.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "customRender" }; function D(a, e) { const t = a.instructionSet, r = t.instructions; for (let s = 0; s < t.instructionSize; s++) { const n = r[s]; e[n.renderPipeId].execute(n); } } const dt = new v(); class Me { constructor(e) { this._renderer = e; } addRenderGroup(e, t) { e.isCachedAsTexture ? this._addRenderableCacheAsTexture(e, t) : this._addRenderableDirect(e, t); } execute(e) { e.isRenderable && (e.isCachedAsTexture ? this._executeCacheAsTexture(e) : this._executeDirect(e)); } destroy() { this._renderer = null; } _addRenderableDirect(e, t) { this._renderer.renderPipes.batch.break(t), e._batchableRenderGroup && (S.return(e._batchableRenderGroup), e._batchableRenderGroup = null), t.add(e); } _addRenderableCacheAsTexture(e, t) { const r = e._batchableRenderGroup ?? (e._batchableRenderGroup = S.get(pe)); r.renderable = e.root, r.transform = e.root.relativeGroupTransform, r.texture = e.texture, r.bounds = e._textureBounds, t.add(e), this._renderer.renderPipes.batch.addToBatch(r, t); } _executeCacheAsTexture(e) { if (e.textureNeedsUpdate) { e.textureNeedsUpdate = !1; const t = dt.identity().translate( -e._textureBounds.x, -e._textureBounds.y ); this._renderer.renderTarget.push(e.texture, !0, null, e.texture.frame), this._renderer.globalUniforms.push({ worldTransformMatrix: t, worldColor: 4294967295 }), D(e, this._renderer.renderPipes), this._renderer.renderTarget.finishRenderPass(), this._renderer.renderTarget.pop(), this._renderer.globalUniforms.pop(); } e._batchableRenderGroup._batcher.updateElement(e._batchableRenderGroup), e._batchableRenderGroup._batcher.geometry.buffers[0].update(); } _executeDirect(e) { this._renderer.globalUniforms.push({ worldTransformMatrix: e.inverseParentTextureTransform, worldColor: e.worldColorAlpha }), D(e, this._renderer.renderPipes), this._renderer.globalUniforms.pop(); } } Me.extension = { type: [ u.WebGLPipes, u.WebGPUPipes, u.CanvasPipes ], name: "renderGroup" }; function E(a, e) { e || (e = 0); for (let t = e; t < a.length && a[t]; t++) a[t] = null; } const ct = new P(), te = de | ce | he; function Se(a, e = !1) { ht(a); const t = a.childrenToUpdate, r = a.updateTick++; for (const s in t) { const n = Number(s), i = t[s], o = i.list, l = i.index; for (let d = 0; d < l; d++) { const c = o[d]; c.parentRenderGroup === a && c.relativeRenderGroupDepth === n && we(c, r, 0); } E(o, l), i.index = 0; } if (e) for (let s = 0; s < a.renderGroupChildren.length; s++) Se(a.renderGroupChildren[s], e); } function ht(a) { const e = a.root; let t; if (a.renderGroupParent) { const r = a.renderGroupParent; a.worldTransform.appendFrom( e.relativeGroupTransform, r.worldTransform ), a.worldColor = ue( e.groupColor, r.worldColor ), t = e.groupAlpha * r.worldAlpha; } else a.worldTransform.copyFrom(e.localTransform), a.worldColor = e.localColor, t = e.localAlpha; t = t < 0 ? 0 : t > 1 ? 1 : t, a.worldAlpha = t, a.worldColorAlpha = a.worldColor + ((t * 255 | 0) << 24); } function we(a, e, t) { if (e === a.updateTick) return; a.updateTick = e, a.didChange = !1; const r = a.localTransform; a.updateLocalTransform(); const s = a.parent; if (s && !s.renderGroup ? (t |= a._updateFlags, a.relativeGroupTransform.appendFrom( r, s.relativeGroupTransform ), t & te && re(a, s, t)) : (t = a._updateFlags, a.relativeGroupTransform.copyFrom(r), t & te && re(a, ct, t)), !a.renderGroup) { const n = a.children, i = n.length; for (let d = 0; d < i; d++) we(n[d], e, t); const o = a.parentRenderGroup, l = a; l.renderPipeId && !o.structureDidChange && o.updateRenderable(l); } } function re(a, e, t) { if (t & ce) { a.groupColor = ue( a.localColor, e.groupColor ); let r = a.localAlpha * e.groupAlpha; r = r < 0 ? 0 : r > 1 ? 1 : r, a.groupAlpha = r, a.groupColorAlpha = a.groupColor + ((r * 255 | 0) << 24); } t & he && (a.groupBlendMode = a.localBlendMode === "inherit" ? e.groupBlendMode : a.localBlendMode), t & de && (a.globalDisplayStatus = a.localDisplayStatus & e.globalDisplayStatus), a._updateFlags = 0; } function ft(a, e) { const { list: t, index: r } = a.childrenRenderablesToUpdate; let s = !1; for (let n = 0; n < r; n++) { const i = t[n]; if (s = e[i.renderPipeId].validateRenderable(i), s) break; } return a.structureDidChange = s, s; } const pt = new v(); class Pe { constructor(e) { this._renderer = e; } render({ container: e, transform: t }) { const r = e.parent, s = e.renderGroup.renderGroupParent; e.parent = null, e.renderGroup.renderGroupParent = null; const n = this._renderer; let i = pt; t && (i = i.copyFrom(e.renderGroup.localTransform), e.renderGroup.localTransform.copyFrom(t)); const o = n.renderPipes; this._updateCachedRenderGroups(e.renderGroup, null), this._updateRenderGroups(e.renderGroup), n.globalUniforms.start({ worldTransformMatrix: t ? e.renderGroup.localTransform : e.renderGroup.worldTransform, worldColor: e.renderGroup.worldColorAlpha }), D(e.renderGroup, o), o.uniformBatch && o.uniformBatch.renderEnd(), t && e.renderGroup.localTransform.copyFrom(i), e.parent = r, e.renderGroup.renderGroupParent = s; } destroy() { this._renderer = null; } _updateCachedRenderGroups(e, t) { if (e.isCachedAsTexture) { if (!e.updateCacheTexture) return; t = e; } e._parentCacheAsTextureRenderGroup = t; for (let r = e.renderGroupChildren.length - 1; r >= 0; r--) this._updateCachedRenderGroups(e.renderGroupChildren[r], t); if (e.invalidateMatrices(), e.isCachedAsTexture) { if (e.textureNeedsUpdate) { const r = e.root.getLocalBounds(); r.ceil(); const s = e.texture; e.texture && b.returnTexture(e.texture, !0); const n = this._renderer, i = e.textureOptions.resolution || n.view.resolution, o = e.textureOptions.antialias ?? n.view.antialias, l = e.textureOptions.scaleMode ?? "linear", d = b.getOptimalTexture( r.width, r.height, i, o ); d._source.style = new $e({ scaleMode: l }), e.texture = d, e._textureBounds || (e._textureBounds = new F()), e._textureBounds.copyFrom(r), s !== e.texture && e.renderGroupParent && (e.renderGroupParent.structureDidChange = !0); } } else e.texture && (b.returnTexture(e.texture, !0), e.texture = null); } _updateRenderGroups(e) { const t = this._renderer, r = t.renderPipes; if (e.runOnRender(t), e.instructionSet.renderPipes = r, e.structureDidChange ? E(e.childrenRenderablesToUpdate.list, 0) : ft(e, r), Se(e), e.structureDidChange ? (e.structureDidChange = !1, this._buildInstructions(e, t)) : this._updateRenderables(e), e.childrenRenderablesToUpdate.index = 0, t.renderPipes.batch.upload(e.instructionSet), !(e.isCachedAsTexture && !e.textureNeedsUpdate)) for (let s = 0; s < e.renderGroupChildren.length; s++) this._updateRenderGroups(e.renderGroupChildren[s]); } _updateRenderables(e) { const { list: t, index: r } = e.childrenRenderablesToUpdate; for (let s = 0; s < r; s++) { const n = t[s]; n.didViewUpdate && e.updateRenderable(n); } E(t, r); } _buildInstructions(e, t) { const r = e.root, s = e.instructionSet; s.reset(); const n = t.renderPipes ? t : t.batch.renderer, i = n.renderPipes; i.batch.buildStart(s), i.blendMode.buildStart(), i.colorMask.buildStart(), r.sortableChildren && r.sortChildren(), r.collectRenderablesWithEffects(s, n, null), i.batch.buildEnd(s), i.blendMode.buildEnd(s); } } Pe.extension = { type: [ u.WebGLSystem, u.WebGPUSystem, u.CanvasSystem ], name: "renderGroup" }; class Re { constructor(e) { this._renderer = e; } addRenderable(e, t) { const r = this._getGpuSprite(e); e.didViewUpdate && this._updateBatchableSprite(e, r), th