Skip to content

Shader

pz.shader runs a function you write in WGSL, fn shade(uv, px, size, time) -> vec4<f32>, for every pixel of the widget, every frame, on the GPU: animated backgrounds, plasma, fire or a radar sweep cost Python nothing. Each entry of uniforms becomes a WGSL function of the same name, and mouse() gives the pointer. Without a GPU the widget shows fallback. See the Shaders guide and the showcase.

pz.shader · Category: Content · Full reference →

ShaderShader
  • For animated backgrounds behind glass panels, menus and HUDs.
  • For game visuals and effects that would be too slow to draw from Python every frame.
import pyzed as pz
pz.shader("""
fn shade(uv: vec2<f32>, px: vec2<f32>, size: vec2<f32>, time: f32) -> vec4<f32> {
let wave = 0.5 + 0.5 * sin(uv.x * 12.0 + uv.y * 4.0 + time * speed());
return vec4<f32>(mix(vec3<f32>(0.08, 0.09, 0.2), tint().rgb, wave), 1.0);
}
""", uniforms={"speed": 2.0, "tint": "#c678dd"}, width=640, height=240, time=0.5,
fallback=pz.Gradient(["#14172f", "#c678dd"], angle=0))

Each capture is one frame at time=0.5; run the example to see it move. Without a GPU the widget draws its fallback.

Shader: tint="#c678dd"Shader: tint="#c678dd"
tint="#c678dd"
Code
pz.shader("""
fn shade(uv: vec2<f32>, px: vec2<f32>, size: vec2<f32>, time: f32) -> vec4<f32> {
let wave = 0.5 + 0.5 * sin(uv.x * 12.0 + uv.y * 4.0 + time * 2.0);
return vec4<f32>(mix(vec3<f32>(0.08, 0.09, 0.2), tint().rgb, wave), 1.0);
}
""", uniforms={"tint": "#c678dd"}, width=260, height=110, time=0.5,
fallback=pz.Gradient(["#14172f", "#c678dd"], angle=0))
Shader: tint="#56b6c2"Shader: tint="#56b6c2"
tint="#56b6c2"
Code
pz.shader("""
fn shade(uv: vec2<f32>, px: vec2<f32>, size: vec2<f32>, time: f32) -> vec4<f32> {
let wave = 0.5 + 0.5 * sin(uv.x * 12.0 + uv.y * 4.0 + time * 2.0);
return vec4<f32>(mix(vec3<f32>(0.08, 0.09, 0.2), tint().rgb, wave), 1.0);
}
""", uniforms={"tint": "#56b6c2"}, width=260, height=110, time=0.5,
fallback=pz.Gradient(["#14172f", "#56b6c2"], angle=0))
Shader: tint="#e5c07b"Shader: tint="#e5c07b"
tint="#e5c07b"
Code
pz.shader("""
fn shade(uv: vec2<f32>, px: vec2<f32>, size: vec2<f32>, time: f32) -> vec4<f32> {
let wave = 0.5 + 0.5 * sin(uv.x * 12.0 + uv.y * 4.0 + time * 2.0);
return vec4<f32>(mix(vec3<f32>(0.08, 0.09, 0.2), tint().rgb, wave), 1.0);
}
""", uniforms={"tint": "#e5c07b"}, width=260, height=110, time=0.5,
fallback=pz.Gradient(["#14172f", "#e5c07b"], angle=0))

Shader has no events of its own: it shows what you give it. Like every widget it also has the 18 common events (click, double_click, right_click, mouse_enter, drag, key_down, resize…), attached with .on(...): see Events and Events of every component.

shader(
code,
*,
uniforms=None,
textures=None,
width=None,
height=None,
animate=True,
time=None,
fallback=None,
)

A widget painted on the GPU by your WGSL fn shade(uv, px, size, time) -> vec4<f32>, which returns each pixel’s color, or by a shader graph made of nodes (a .pzshad path or a pyzed.shading Graph or Shader). Each entry of uniforms becomes a function of the same name ({"speed": 2} -> speed()); mouse() gives the pointer. Without a GPU the widget shows fallback. Raises ValueError with the compiler’s message for invalid code. See the shaders guide.

Property Default Description
code required WGSL source that defines shade (and any helper functions), or a .pzshad path, Graph or Shader.
uniforms None Up to 32 named values: a number, 2 to 4 numbers or a color. With a .pzshad, the shader’s mutable variables by name.
textures None Up to 8 images, {name: path}: each becomes name(uv), the image’s color at uv.
width None Width ("fill" by default).
height None Height ("fill" by default).
animate True Redraw every frame so time moves (True).
time None A fixed time in seconds, for a still frame.
fallback None Color or gradient shown without a GPU.

Full reference →