Makepad 2.0 ShadersSAFE
Build App with Makepad and AI skills
Overview
Build App with Makepad and AI skills
7cbc563d4f32OBSERVED · 2026-10-12Host compatibility
What the documentation claims. We have not run a compatibility test.
| Host | Status | Notes |
|---|---|---|
| cursor | mentioned |
What it tells the agent
The instruction file, verbatim from the audited commit — this is the text the model reads, and the surface the audit's instruction layer examines. Quoted here so you can judge it without cloning anything.
---
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 fuTrust audit
SAFEgrade B · trust 89/100 Nothing in the source contradicts what it says it does. Grade A is reserved for packages that have also passed the behavioural sandbox.
| Layer | What it checks | Result |
|---|---|---|
| L0 | Provenance & inventory | PASS |
| L1 | Static analysis of the code | NA |
| L2 | Instruction surface (what it tells the agent) | PASS |
| L3 | Class-specific surface | PASS |
| L4 | Behavioural (sandbox) | SKIPPED |
What the source does
- Filesystem
- none-observed
- Network
- none-observed
- Shell
- none-observed
- Dependencies
- pinned
- Secrets in source
- none-found
Findings (1)
Gates applied: no_behavioural_pass, no_license.
7cbc563d4f32full audit observations/trust-audit/skill/zhanghandong__makepad-2.0-shaders.json · Report an issue / request a re-scanAudit history
Every audit this skill has had.
| Date | Source | Verdict | Grade | Score | Change |
|---|---|---|---|---|---|
| 2026-10-12 | 7cbc563d4f32 | SAFE | B | 89 | first audit |
Questions
What does the Makepad 2.0 Shaders skill do?
Build App with Makepad and AI skills
Is Makepad 2.0 Shaders safe to install?
The audit found nothing in the source that contradicts what it says it does, and graded it B (89/100). Grade A is held back for packages that have also passed a sandboxed behavioural run, which is why a clean skill reads B.
What can Makepad 2.0 Shaders access on my machine?
The audit observed no filesystem, network or shell use at all in its source.
Which assistants does Makepad 2.0 Shaders work with?
Its documentation mentions cursor. That is what the text claims, not a compatibility test we ran.
How current is this page?
The grade is for one exact copy of the source (7cbc563d4f32), read on 2026-10-12. The repository is watched, and a new audit runs when it changes — this is the first audit.