Shaders give you direct control over how every pixel in your game looks. Want a damage flash, a heat haze effect, or a glitch distortion? That is shader territory, and in Phaser 4, it has never been easier to work with them.
The Phaser 4 Shader API has been reworked from the ground up, with a cleaner config system, explicit uniform handling, and simpler GLSL loading.
A Cleaner Way to Create Shaders in Phaser 4
The Phaser 4 Shader constructor takes a config object as its first argument, followed by position, size, and textures as separate parameters:
this.add.shader(config, x, y, width, height, textures);
The config object, typed as ShaderQuadConfig, is where you define everything about your shader. The only required property is name. Everything else is optional:
const config = {
name: 'myShader',
fragmentKey: 'Marble'
};
const shader = this.add.shader(config, 400, 300, 800, 600);
If you prefer inline GLSL code over a loaded file, use fragmentSource instead of fragmentKey:
const config = {
name: 'myShader',
fragmentSource: '// your GLSL code here'
};
The default vertex shader provides one input to your fragment shader: varying vec2 outTexCoord. This gives you coordinates from 0 to 1 in X and Y, telling the fragment shader which part of the quad it is drawing.
This separation makes your Phaser 4 shader code easier to organize, reuse, and generate programmatically.
Passing Data into Your Shader with setupUniforms
In Phaser 4, uniforms are set through a setupUniforms function defined inside the config object. This function runs every time the shader is rendered, making it the right place to animate values over time:
const config = {
name: 'myShader',
fragmentKey: 'Marble',
setupUniforms: (setUniform, drawingContext) => {
setUniform('time', this.game.loop.getDuration());
}
};
The setUniform(name, value) method is passed in automatically by the render node. Unlike Phaser 3, Shadertoy-style uniforms are no longer injected automatically. You pass only what your shader actually needs, explicitly. This gives you full control and eliminates a source of subtle bugs when migrating shaders from Phaser 3 to Phaser 4.
Using Textures in Your Phaser 4 Shader
If your shader needs a texture, supply it as part of the textures array in the constructor, and bind it as a uniform inside setupUniforms. Textures are assigned to units in list order, starting at 0:
const shader = this.add.shader({
name: 'texturedShader',
fragmentSource: frag,
setupUniforms: (setUniform, drawingContext) => {
setUniform('iChannel0', 0);
}
}, 400, 300, 800, 600, [ 'myTexture' ]);
How Phaser 4 Loads GLSL Shader Files
Loading GLSL files in Phaser 4 is simpler than in v3. In Phaser 3, shaders were classified as either fragment or vertex when loaded, and could be bundled together with metadata. In Phaser 4, that is all gone. A GLSL file is just a single text file:
this.load.glsl('Marble', 'assets/shaders/marble.frag');
Once loaded, you reference it in your config using fragmentKey or vertexKey. There are no more shader bundles. If you need to load large amounts of shader code, use JSON or other supported formats instead.
The Phaser 4 Shader Template System
Phaser 4 introduces a GLSL shader template system using standard preprocessor directives. Use #pragma phaserTemplate(key) to define insertion points in your shader code. These points can be filled at runtime with shader additions, letting you configure and combine shaders without rewriting them.
Because these are valid GLSL preprocessor commands, your editor and linter will understand them correctly. Phaser strips them before sending code to the GPU, so there is no runtime cost.
One performance note: Shader objects are Stand Alone Renders. Each one interrupts the current batch and makes its own draw call. Draw calls are expensive, so use Shader objects sparingly and only where you actually need custom visual effects.
Get Started with Phaser 4 Shaders Today
For the full list of Phaser 4 Shader API changes, see the official changelog. For a deeper dive into the rendering system, the Phaser 4 Shader Guide covers every concept step by step, including filters, render nodes, and advanced shader additions.




