pixi.js
Version:
<p align="center"> <a href="https://pixijs.com" target="_blank" rel="noopener noreferrer"> <img height="150" src="https://files.pixijs.download/branding/pixijs-logo-transparent-dark.svg?v=1" alt="PixiJS logo"> </a> </p> <br/> <p align="center">
1 lines • 12.4 kB
Source Map (JSON)
{"version":3,"file":"BlendModePipe.mjs","sources":["../../../../../src/rendering/renderers/shared/blendModes/BlendModePipe.ts"],"sourcesContent":["import { extensions, ExtensionType } from '../../../../extensions/Extensions';\nimport { FilterEffect } from '../../../../filters/FilterEffect';\nimport { RenderGroup } from '../../../../scene/container/RenderGroup';\nimport { warn } from '../../../../utils/logging/warn';\n\nimport type { BlendModeFilter } from '../../../../filters/blend-modes/BlendModeFilter';\nimport type { FilterInstruction } from '../../../../filters/FilterSystem';\nimport type { Renderer } from '../../types';\nimport type { Instruction } from '../instructions/Instruction';\nimport type { InstructionSet } from '../instructions/InstructionSet';\nimport type { InstructionPipe } from '../instructions/RenderPipe';\nimport type { Renderable } from '../Renderable';\nimport type { BLEND_MODES } from '../state/const';\n\ninterface AdvancedBlendInstruction extends Instruction\n{\n renderPipeId: 'blendMode',\n blendMode: BLEND_MODES,\n activeBlend: Renderable[],\n}\n\n// class map\nconst BLEND_MODE_FILTERS: Partial<Record<BLEND_MODES, new () => BlendModeFilter>> = {} as const;\n\nextensions.handle(ExtensionType.BlendMode, (value) =>\n{\n if (!value.name)\n {\n throw new Error('BlendMode extension must have a name property');\n }\n BLEND_MODE_FILTERS[value.name as BLEND_MODES] = value.ref;\n}, (value) =>\n{\n delete BLEND_MODE_FILTERS[value.name as BLEND_MODES];\n});\n\n/**\n * This Pipe handles the blend mode switching of the renderer.\n * It will insert instructions into the {@link InstructionSet} to switch the blend mode according to the\n * blend modes of the scene graph.\n *\n * This pipe is were wwe handle Advanced blend modes. Advanced blend modes essentially wrap the renderables\n * in a filter that applies the blend mode.\n *\n * You only need to use this class if you are building your own render instruction set rather than letting PixiJS build\n * the instruction set for you by traversing the scene graph\n * @category rendering\n * @internal\n */\nexport class BlendModePipe implements InstructionPipe<AdvancedBlendInstruction>\n{\n /** @ignore */\n public static extension = {\n type: [\n ExtensionType.WebGLPipes,\n ExtensionType.WebGPUPipes,\n ExtensionType.CanvasPipes,\n ],\n name: 'blendMode',\n } as const;\n\n private _renderer: Renderer;\n\n private _renderableList?: Renderable[];\n private _activeBlendMode: BLEND_MODES;\n private readonly _blendModeStack: BLEND_MODES[] = [];\n\n private _isAdvanced = false;\n\n private _filterHash: Partial<Record<BLEND_MODES, FilterEffect>> = Object.create(null);\n\n constructor(renderer: Renderer)\n {\n this._renderer = renderer;\n this._renderer.runners.prerender.add(this);\n }\n\n public prerender()\n {\n // make sure we reset the blend modes to normal\n // this way the next render will register any changes\n this._activeBlendMode = 'normal';\n this._isAdvanced = false;\n }\n\n /**\n * Push a blend mode onto the internal stack and apply it to the instruction set if needed.\n * @param renderable - The renderable or {@link RenderGroup} associated with the change.\n * @param blendMode - The blend mode to activate.\n * @param instructionSet - The instruction set being built.\n */\n public pushBlendMode(renderable: Renderable | RenderGroup, blendMode: BLEND_MODES, instructionSet: InstructionSet): void\n {\n this._blendModeStack.push(blendMode);\n\n this.setBlendMode(renderable, blendMode, instructionSet);\n }\n\n /**\n * Pop the last blend mode from the stack and apply the new top-of-stack mode.\n * @param instructionSet - The instruction set being built.\n */\n public popBlendMode(instructionSet: InstructionSet): void\n {\n this._blendModeStack.pop();\n const blendMode = this._blendModeStack[this._activeBlendMode.length - 1] ?? 'normal';\n\n this.setBlendMode(null, blendMode, instructionSet);\n }\n\n /**\n * Ensure a blend mode switch is added to the instruction set when the mode changes.\n * If an advanced blend mode is active, subsequent renderables will be collected so they can be\n * rendered within a single filter pass.\n * @param renderable - The renderable or {@link RenderGroup} to associate with the change, or null when unwinding.\n * @param blendMode - The target blend mode.\n * @param instructionSet - The instruction set being built.\n */\n public setBlendMode(\n renderable: Renderable | RenderGroup | null,\n blendMode: BLEND_MODES,\n instructionSet: InstructionSet\n )\n {\n const isRenderGroup = renderable instanceof RenderGroup;\n\n if (this._activeBlendMode === blendMode)\n {\n if (this._isAdvanced && renderable && !isRenderGroup)\n {\n this._renderableList?.push(renderable);\n }\n\n return;\n }\n\n if (this._isAdvanced) this._endAdvancedBlendMode(instructionSet);\n\n this._activeBlendMode = blendMode;\n\n if (!renderable) return;\n\n this._isAdvanced = !!BLEND_MODE_FILTERS[blendMode];\n\n if (this._isAdvanced) this._beginAdvancedBlendMode(renderable, instructionSet);\n }\n\n private _beginAdvancedBlendMode(renderable: Renderable | RenderGroup, instructionSet: InstructionSet)\n {\n this._renderer.renderPipes.batch.break(instructionSet);\n\n const blendMode = this._activeBlendMode;\n\n if (!BLEND_MODE_FILTERS[blendMode])\n {\n // #if _DEBUG\n warn(`Unable to assign BlendMode: '${blendMode}'. `\n + `You may want to include: import 'pixi.js/advanced-blend-modes'`);\n // #endif\n\n return;\n }\n\n const filterEffect = this._ensureFilterEffect(blendMode);\n const isRenderGroup = renderable instanceof RenderGroup;\n const instruction: FilterInstruction = {\n renderPipeId: 'filter',\n action: 'pushFilter',\n filterEffect,\n renderables: isRenderGroup ? null : [renderable],\n container: isRenderGroup ? renderable.root : null,\n canBundle: false\n };\n\n this._renderableList = instruction.renderables;\n\n instructionSet.add(instruction);\n }\n\n private _ensureFilterEffect(blendMode: BLEND_MODES): FilterEffect\n {\n let filterEffect: FilterEffect = this._filterHash[blendMode];\n\n if (!filterEffect)\n {\n filterEffect = this._filterHash[blendMode] = new FilterEffect();\n filterEffect.filters = [new BLEND_MODE_FILTERS[blendMode as keyof typeof BLEND_MODE_FILTERS]()];\n }\n\n return filterEffect;\n }\n\n private _endAdvancedBlendMode(instructionSet: InstructionSet)\n {\n this._isAdvanced = false;\n this._renderableList = null;\n this._renderer.renderPipes.batch.break(instructionSet);\n\n instructionSet.add({\n renderPipeId: 'filter',\n action: 'popFilter',\n canBundle: false,\n });\n }\n\n /**\n * called when the instruction build process is starting this will reset internally to the default blend mode\n * @internal\n */\n public buildStart()\n {\n this._isAdvanced = false;\n }\n\n /**\n * called when the instruction build process is finished, ensuring that if there is an advanced blend mode\n * active, we add the final render instructions added to the instruction set\n * @param instructionSet - The instruction set we are adding to\n * @internal\n */\n public buildEnd(instructionSet: InstructionSet)\n {\n if (!this._isAdvanced) return;\n\n this._endAdvancedBlendMode(instructionSet);\n }\n\n /** @internal */\n public destroy()\n {\n this._renderer = null;\n this._renderableList = null;\n\n for (const i in this._filterHash)\n {\n this._filterHash[i as BLEND_MODES].destroy();\n }\n\n this._filterHash = null;\n }\n}\n"],"names":[],"mappings":"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"}