Phaser AE

WebGL2 backend

Free packv3.0.0-82D and 3DRenderers

The WebGL2 half of the renderer. Your game rarely names it: the automatic renderer falls back to it on devices without WebGPU, and the game draws the same, from the same code, minus a short and documented list of features.

This is a Free pack. Every phaser.io account can use it in their games.

Released October 14, 2026 · updated October 20, 2026

WebGL2 backend: a screenshot of its demo
A note about these graphics

Expansion packs don't come with graphics. This screenshot is one way of drawing what the pack does, made for its demo: none of the sprites, tiles or backgrounds in it are in the pack.

That's by design. A pack is a game's logic, mechanics and effects, and it works with whatever art you give it. Some packs draw effects, backdrops or 3D scenes of their own, but none carries a game's sprites.

So the look is yours. Make the art on phaser.io, bring your own, or let your agent draw it in code: the same pack can look like anything.

The pack

webgl2

function webgl2(): Pack<{ gl: WebGl2Api; preloader: PreloaderApi }>

The WebGL2 backend pack. Draws the worlds' sorted sprite tables from the kernel atlas, and each big picture from its texture of its own — world-space in sprites (with world-screen's underlay among them), screen-space in screen — with the same instance layout, the same run splitting and the same blend table as render-webgpu. Compose it INSTEAD of render-webgpu, never beside it. Headless it attaches and draws nothing.

Functions

blendTable

function blendTable(gl: WebGL2RenderingContext): GlBlend[]

Build the table from a live context's enum values, so nothing here hard-codes a GL constant.

fragmentGLSL

function fragmentGLSL(customs:ReadonlyArray<{id:number;def:DeformDef}>,blocky:boolean):string

Custom fragment snippets share the same straight-alpha working colour as WebGPU.

installWebGl2

function installWebGl2(k: Kernel, deferRegistration = false): { gl: WebGl2Api; initialise(): void; register(): void }

Install one backend's passes and commands; the caller controls device initialisation.

Constants

FRAG

const FRAG: "#version 300 es\nprecision highp float;\nconst bool BLOCKY = false;\nuniform sampler2D uTex;\nin vec2 vUvn;\nin vec4 vTint;\nin vec4 vUv;\nin vec4 vTile;\nin float vShade;\nin vec3 vMeta;\nflat in float vCutoff;\nout vec4 outColor;\nvoid main() {\n // tiling: wrap inside the frame's atlas rect, so a 4×1 repeat d... …

The fragment stage: the frame's rect (in the atlas, or in a picture's own texture), tiled, tinted, premultiplied out.

VERT

const VERT = (gridX: number, gridY = gridX, customs: ReadonlyArray<{id:number;def:DeformDef}> = [])=> …

The vertex stage: one instanced quad, or a rectangular grid when a deformer is on.

Types

GlBlend

interface GlBlend

The blend table, in the same order as the backend's: normal, add, multiply, screen, subtract.

Premultiplied source throughout — the atlas and the tint both carry their alpha — so every mode is a pair of factors and an equation, exactly as it is on the WebGPU side.

  • srcRGB: number — GL blend factor (an enum value such as gl.ONE) applied to the source colour channels.
  • dstRGB: number — GL blend factor applied to the destination colour channels.
  • srcA: number — GL blend factor applied to the source alpha.
  • dstA: number — GL blend factor applied to the destination alpha.
  • eq: number — GL blend equation enum (gl.FUNC_ADD or gl.FUNC_REVERSE_SUBTRACT) that combines the two terms.

WebGl2Api

interface WebGl2Api

game.gl.

  • readonly ready: boolean — True once the context and the program are live.
  • readonly drawCalls: number — Draw calls in the last frame.
  • readonly instances: number — Instances in the last frame.
  • readonly missing: ReadonlyArray<string> — The registered DRAWERS this backend cannot run — a pack asked for its own pipeline and got nothing. A game that wants to warn the player, or hide a feature, reads this rather than guessing.