pyshaderpython in, pixels out

starting Python…
idle

shade(x, y) → (r, g, b)  ·  x, y are 0..1 from the top-left  ·  r, g, b are 0..1

how this works

Define shade(x, y) returning (r, g, b). (pixel, shader and main also work, as does a single function under any name.)

Your function is called once per pixel, so write ordinary Python: if, else, for, break, math. There is no special style to learn and no faster way to write it. That also means a big canvas is a lot of calls — 300×300 is 90,000 of them — so start small and turn the size up when you like what you see: either pick a preset from the size menu, or drag the hatched corner of the image to any size you like. Dragging stretches the pixels you already have as a preview and re-renders once, when you let go. stop or esc interrupts a slow render.

The divider between the editor and the image can be dragged to give either side more room — double-click it to fit the image exactly, or focus it and use the arrow keys. If the image is wider than the space it has, that side scrolls.

x, y0..1, starting at the top-left corner
r, g, b0..1 each; anything outside is clamped
from shaderlib import *the bundled helper library, plus sin, cos, sqrt, …
mathalready imported, no need for the import line
anything in the stdlibimport it as usual

shaderlib lives in pylib/shaderlib/ as plain files — edit them, hit reload pylib, and your changes are live. Add your own modules to pylib/ and list them in pylib/manifest.json.

Your editor contents are kept in localStorage, so they survive a reload. Once you change a shader an edited marker appears next to the dropdown, and picking a different example asks before replacing your work — picking the one you are already on is how you get the original back.

⌘↵/^↵ run · esc stop · ⌘/ comment.