Skip to content
Development
Skill

/makepad-2.0-shaders

CRITICAL: Use for Makepad 2.0 shader system. Triggers on: makepad shader, Sdf2d, pixel shader, draw_bg, draw_text, draw_quad, makepad gpu, shader function, pixel fn, vertex fn, instance, uniform, shader variable, sdf, premultiply, Pal.premul, GaussShadow, makepad graphics,

From plugin
makepad-skills
75214 skills

Claude Code

$ npx -y skills add ZhangHanDong/makepad-skills --skill makepad-2.0-shaders --agent claude-code

SKILL.md

makepad-2.0-shaders.SKILL.md
name: makepad-2.0-shaders
description: |
  CRITICAL: Use for Makepad 2.0 shader system. Triggers on:
  makepad shader, Sdf2d, pixel shader, draw_bg, draw_text, draw_quad,
  makepad gpu, shader function, pixel fn, vertex fn, instance, uniform,
  shader variable, sdf, premultiply, Pal.premul, GaussShadow,
  makepad graphics, custom draw, DrawQuad, DrawVector,
  着色器, 像素, 渲染, 自定义绘制, 距离场

Makepad 2.0 Shader Skill

> **Version:** makepad-widgets (dev branch) | **Last Updated:** 2026-03-03

Overview

Makepad uses a custom GPU shader system integrated into the widget property tree. Shaders are defined inline using `pixel: fn() { ... }` and `vertex: fn() { ... }` blocks within `draw_bg`, `draw_text`, or custom draw objects.

Documentation

Refer to the local files for detailed documentation:

  • `./references/shader-reference.md` - Shader syntax, variables, built-ins, custom functions
  • `./references/sdf2d-reference.md` - SDF2D primitives, combinators, drawing operations

---

Shader Basics

Pixel Shader Structure

draw_bg +: {
    // Declare variables
    instance hover: 0.0          // Animatable per-instance
    uniform accent: #4488ff      // Shared across all instances

    pixel: fn() {
        let sdf = Sdf2d.viewport(self.pos * self.rect_size)
        // ... SDF operations ...
        return sdf.result
    }
}

Variable Types

| Type | Declaration | Animatable | Scope | |------|-------------|-----------|-------| | `instance` | `instance hover: 0.0` | Yes (via Animator) | Per-widget instance | | `uniform` | `uniform color: #fff` | No | Shared across instances | | `texture_2d` | `texture_2d tex: none` | No | Texture sampler | | `varying` | `varying uv: vec2` | No | Vertex → fragment |

Built-in Variables

| Variable | Type | Description | |----------|------|-------------| | `self.pos` | `vec2` | Normalized position (0.0 to 1.0) | | `self.rect_size` | `vec2` | Widget size in pixels | | `self.dpi_factor` | `float` | Screen DPI factor | | `self.draw_pass.time` | `float` | Time in seconds |

---

CRITICAL: Premultiply Alpha

**Every pixel shader MUST return premultiplied alpha color!**

// WRONG - non-premultiplied
pixel: fn() {
    return vec4(1.0, 0.0, 0.0, 0.5)
}

// CORRECT - use Pal.premul()
pixel: fn() {
    return Pal.premul(vec4(1.0, 0.0, 0.0, 0.5))
}

// ALSO CORRECT - sdf.result is already premultiplied
pixel: fn() {
    let sdf = Sdf2d.viewport(self.pos * self.rect_size)
    sdf.circle(cx, cy, r)
    sdf.fill(#f00)
    return sdf.result
}

---

SDF2D Quick Reference

Setup

let sdf = Sdf2d.viewport(self.pos * self.rect_size)

Primitives

sdf.circle(cx, cy, radius)
sdf.rect(x, y, w, h)
sdf.box(x, y, w, h, border_radius)
sdf.hexagon(cx, cy, radius)
sdf.arc(cx, cy, radius, start_angle, end_angle, thickness)
sdf.move_to(x, y)
sdf.line_to(x, y)
sdf.close_path()

Drawing

sdf.fill(color)         // Filled shape
sdf.stroke(color, width) // Outlined shape
sdf.glow(color, amount)  // Glow effect
sdf.clear(color)         // Clear with color

Combinators

sdf.union()       // Add shapes together
sdf.intersect()   // Keep overlap only
sdf.subtract()    // Remove second from first
sdf.gloop(radius) // Smooth union
sdf.blend(amount) // Linear blend

Transforms

sdf.translate(x, y)
sdf.rotate(angle, cx, cy)
sdf.scale(factor, cx, cy)

---

Color Operations

// Mix two colors
mix(#f00, #00f, 0.5)           // 50% blend

// Premultiply alpha
Pal.premul(vec4(r, g, b, a))

// HSV conversions
Pal.hsv2rgb(vec4(h, s, v, 1.0))
Pal.rgb2hsv(color)

// Random
Math.random_2d(vec2(x, y))

---

Common Shader Patterns

Gradient Background

draw_bg +: {
    pixel: fn() {
        let grad = mix(#1a1a2e, #16213e, self.pos.y)
        return Pal.premul(vec4(grad.xyz, 1.0))
    }
}

Hover Color Change

draw_bg +: {
    instance hover: 0.0
    color: #333
    pixel: fn() {
        return Pal.premul(mix(self.color, self.color * 1.3, self.hover))
    }
}

Box Shadow

draw_bg +: {
    pixel: fn() {
        let sdf = Sdf2d.viewport(self.pos * self.rect_size)
        // Shadow
        sdf.box(2.0, 2.0, self.rect_size.x - 4.0, self.rect_size.y - 4.0, 8.0)
        sdf.fill(GaussShadow.box_shadow(sdf, 4.0, #0005))
        // Card
        sdf.box(0.0, 0.0, self.rect_size.x - 2.0, self.rect_size.y - 2.0, 8.0)
        sdf.fill(#2a2a3d)
        return sdf.result
    }
}

Rounded Button with States

draw_bg +: {
    instance hover: 0.0
    instance down: 0.0
    uniform color_bg: #4488ff
    uniform color_hover: #5599ff
    uniform color_down: #3377ee

    pixel: fn() {
        let sdf = Sdf2d.viewport(self.pos * self.rect_size)
        sdf.box(0.0, 0.0, self.rect_size.x, self.rect_size.y, 6.0)
        let color = mix(self.color_bg, self.color_hover, self.hover)
        let color = mix(color, self.color_down, self.down)
        sdf.fill(color)
        return sdf.result
    }
}

---

Custom Shader Functions

draw_bg +: {
    fn wave(pos: vec2, time: float) -> float {
        return sin(pos.x * 10.0 + time * 3.0) * 0.1
    }

    pixel: fn() {
        let w = self.wave(self.pos, self.draw_pass.time)
        let color = mix(#1a1a2e, #4488ff, self.pos.y + w)
        return Pal.premul(vec4(color.xyz, 1.0))
    }
}

---

Splash Shader Capability Boundary

**Splash CAN:**

  • Override `pixel: fn()`, `vertex: fn()`, `get_color: fn()` on existing draw types via `+:`
  • Define helper shader functions within `+:` blocks
  • Set instance/uniform variables on existing draw types
  • Use all SDF2D, color, math built-ins in shader functions

**Splash CANNOT:**

  • Create new DrawQuad/DrawText/DrawSvg types (must define in Rust)
  • Add new instance fields to existing shaders (GPU layout is compile-time)

**Rule:** Rust defines the draw type struct + registers it; Splash overrides how it draws.

See `./references/shader-reference.md` "Splash Shader Capabilities & Boundaries" for the fu

Read more
@zhanghandong
Ships withmakepad-skills

Skills for building cross-platform UI applications with Makepad 2.0.

Stars on GitHub

Momentum

stars in total
752
Star history of ZhangHanDong/makepad-skills on GitHub, a chart by star-history.com

Other skills on makepad-skills.

More skills from other plugins.

brainstorming
Auto-invoked

brainstorming

You MUST use this before any creative work - creating features, building components, adding functionality, modifying behavior, or…

@obra@obraInstall Skill
ask-matt

ask-matt

Ask which skill or flow fits your situation. A router over the skills in this repo.

skills10d309k
@mattpocock@mattpocockInstall Skill
accessibility
Auto-invoked

accessibility

Design, implement, and audit accessible UI to WCAG 2.2 Level AA across Web, iOS, and Android — semantic ARIA roles and labels,…

ecc12d293k
@affaan-m@affaan-mInstall Skill
compiler-commit

compiler-commit

Use when you want to verify compiler changes and commit with the correct convention. Runs tests, lint, and format, then commits…

react1d252k
@facebook@facebookInstall Skill

Questions about makepad-2.0-shaders.

Which coding agents can use makepad-2.0-shaders?
makepad-2.0-shaders installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.