Ir al contenido

Tu primer shader

En esta página creas un círculo brillante que late, en unos diez minutos, conectando cajas con el ratón. No necesitas saber matemáticas ni WGSL. Al final tendrás un archivo .pzshad que puedes usar en cualquier app de Pyzed y conocerás las pocas ideas sobre las que se construye todo shader.

Adónde llega esta página: una forma brillante que respira, hecha solo con nodos.
  1. Un shader es una receta que se ejecuta para cada píxel. La tarjeta gráfica pregunta “¿de qué color es este píxel?” para cada píxel del widget, sesenta veces por segundo, todos a la vez. Tu grafo es la respuesta.
  2. Cada píxel sabe dónde está. El nodo UV lo dice: x va de 0 (izquierda) a 1 (derecha) e y de 0 (arriba) a 1 (abajo). Formas, degradados y patrones son solo cálculos sobre esa posición.
  3. Los colores son números de 0 a 1. El rojo es (1, 0, 0), el blanco (1, 1, 1), un gris medio (0.5, 0.5, 0.5). Multiplicar un color por un número de 0 a 1 lo oscurece; así funcionan las máscaras.
  1. Abre Pyzed Design. Inicia la app que descargaste o ábrela desde Python:

    Ventana de terminal
    uv run pyzed design # dentro de un proyecto uv con pyzed-ui
    uvx --from "pyzed-ui[designer]" pyzed design # sin proyecto
  2. Crea un shader. Pulsa Ctrl+N para abrir el diálogo Nuevo, elige la tarjeta Shader, llámalo pulse y elige la plantilla En blanco. Crear shader guarda pulse.pzshad y lo abre.

    El diálogo Nuevo en la tarjeta Shader, con sus plantillas
    El diálogo Nuevo: Shader, un nombre, una carpeta y una plantilla.
  3. Echa un vistazo. La plantilla en blanco son tres nodos: UV → Degradado → Salida. Cada nodo muestra una pequeña vista previa de lo que produce, y la vista previa de Salida en la esquina es el shader terminado. El panel izquierdo muestra ahora la barra Shading (todos los nodos, por categoría) y la Estructura (variables y nodos).

    La vista Shader con la barra Shading, un grafo de nodos y la vista previa de Salida
    La vista Shader: barra lateral a la izquierda, el grafo en el centro y Propiedades a la derecha.
  4. Dibuja un círculo. Haz doble clic en un hueco del lienzo (o pulsa Shift+A) y escribe círculo; pulsa Enter para añadir el nodo Círculo. Haz lo mismo con Relleno. Arrastra desde la salida distance del Círculo hasta la entrada distance del Relleno: su vista previa muestra un disco blanco sobre negro.

    El nodo Círculo con sus entradas de centro y radio, su salida de distancia y su vista previa
    El nodo Círculo. Su vista previa muestra la distancia: el disco en el centro y anillos que crecen hacia fuera.
  5. Dale color. Añade un nodo RGBA. Conecta la salida mask del Relleno a la entrada rgb de RGBA (un número rellena rojo, verde y azul: blanco) y la salida color de RGBA a la entrada color de la Salida. El Degradado ya no se usa: selecciónalo y pulsa Supr.

  6. Hazlo latir. Añade un nodo Tiempo y un nodo Multiplicar y sumar. Conecta la salida sin del Tiempo (un valor que oscila entre −1 y 1) a la entrada a, y escribe 0.05 en b y 0.3 en c: el resultado oscila entre 0.25 y 0.35. Conéctalo al radius del Círculo. Todas las vistas previas empiezan a respirar.

  7. Añade un resplandor. Añade un nodo Resplandor, conéctale la distance del Círculo, y un nodo Sumar que sume la mask del Relleno y el value del Resplandor. Conecta la suma a rgb de RGBA en lugar de la máscara.

  8. Dale un color que se pueda cambiar. En la Estructura, pulsa la flecha de Añadir y elige variable color; llámala tint y elige un rosa. Arrastra tint de la Estructura al grafo: se convierte en un nodo Parámetro. Añade un nodo Multiplicar: el rgb de tint por la suma, hacia rgb de RGBA.

  9. Pruébalo. Abre la pestaña Vista previa: el shader en grande, con un deslizador o una muestra de color para cada variable. La pestaña WGSL muestra el código en que se compila el grafo. Pulsa F5 para abrirlo en una ventana propia que sigue tus cambios. Guarda con Ctrl+S.

    La pestaña Vista previa con un deslizador por variable
    La pestaña Vista previa: cada variable mutable tiene un control.

Un archivo .pzshad se usa como una imagen: pasa su ruta a pz.shader. uniforms fija sus variables mutables por nombre, así tu código puede cambiar el color mientras la app corre, sin coste.

app.py
from pathlib import Path
import pyzed as pz
HERE = Path(__file__).parent
class Pulse(pz.App):
title = "Mi primer shader"
size = (420, 320)
def view(self):
return pz.shader(HERE / "pulse.pzshad", uniforms={"tint": "#22d3ee"}, width="fill", height="fill",
fallback="#1e1b4b")
if __name__ == "__main__":
pz.run(Pulse)

Ejecuta la app, o mira el shader solo (pulsa V en esa ventana para un deslizador por variable):

Ventana de terminal
uv run app.py
uv run pyzed run pulse.pzshad

Todo lo que hace la vista Shader también es una API de Python. Esto crea el mismo grafo y lo guarda; abre el archivo en Pyzed Design para seguir editándolo con el ratón.

make_pulse.py
from pyzed import shading
g = shading.Graph("pulse")
tint = g.uniform("tint", "color", "#f472b6") # una variable y un nodo Parámetro
radius = g.time()["sin"] * 0.05 + 0.3 # nodos de matemáticas, añadidos por ti
circle = g.circle(radius=radius)
light = g.fill(circle) + g.glow(circle, radius=0.1)
g.output(g.rgba(tint["rgb"] * light, 1.0))
g.arrange() # columnas ordenadas, como Ordenar en la barra
g.save("pulse.pzshad")