Files
agent-recur/docs/recur-shader-reference.ca.md
Xose 6128e251c1 Regenerado: el eje Y del aparato, y correccion de lo de las capturas
En este aparato gl_FragCoord.y = 0 cae ARRIBA en un 0-input. Y la captura de
glslViewer coincide con el aparato: NO hay que voltearla, que es lo contrario
de lo que decia la version anterior de esta guia.

Ademas, check_port.py ya no cuenta las llamadas que aparecen dentro de los
comentarios.

Generado con generar-agente-portable.py. No editar aqui.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 17:58:49 +02:00

13 KiB
Raw Permalink Blame History

doc, rev, canonical_language, canonical_source, translations
doc rev canonical_language canonical_source translations
RECUR-SHADER-REF 03 en docs/recur-shader-reference.en.md
ca
docs/recur-shader-reference.ca.md (rev 03, al dia)

Com funcionen de debò els shaders a r_e_c_u_r

Tot el que hi ha aquí està comprovat llegint el codi font dels tres repositoris implicats, no llegint fòrums. Cada afirmació porta fitxer:línia. Allò que no es pot tancar llegint codi va marcat com a [PER VERIFICAR A LA MÀQUINA].

Verificat el 2026-08-28 contra el commit 16e1fae de r_e_c_u_r.

La cadena: qui dibuixa què

No és un sol programa. Són tres peces, i confondre-les fa perdre el temps:

r_e_c_u_r (Python, la interfície)
    │  navega Shaders/, llegeix el fitxer, decideix què enviar
    │  OSC → port local
    ▼
c_o_n_j_u_r (aplicació d'openFrameworks, C++)
    │  rep /shader/N/load, /param, /speed
    ▼
la classe conjur (addon ofxVideoArtTools)
    │  fa shader.begin(), enllaça els uniforms, dibuixa
    ▼
OpenGL ES 2.0 / GLSL ES 1.00  ← aquí corre el teu .frag
  • r_e_c_u_r no renderitza res. Només envia missatges OSC.
  • Els uniforms s'enllacen a ofxVideoArtTools/src/conjur.cpp. Aquell fitxer és la font de veritat sobre quines variables existeixen.
  • Repositoris: r_e_c_u_r, c_o_n_j_u_r, ofxVideoArtTools. Tots tres GPL-3.0.

On van els fitxers

data_centre/data.py:34 — r_e_c_u_r busca shaders en aquest ordre:

  1. L'USB o dispositiu extern muntat (PATH_TO_EXTERNAL_DEVICES)
  2. /home/pi/r_e_c_u_r/Shaders
  3. /home/pi/Shaders

Extensions que mostra el navegador: .frag, .shader, .glsl, .glslf, .fsh.

El vertex shader està fixat al codi. ofApp.cpp:317 carrega sempre /home/pi/r_e_c_u_r/Shaders/default.vert, passi el que passi. No pots donar el teu propi vertex shader sense tocar C++. Només escrivim fragment shaders.

Els uniforms que existeixen de debò

De ofxVideoArtTools/src/conjur.cpp:50-73. Aquesta és la llista completa; no n'hi ha més.

Els que fem servir (format Book of Shaders)

Uniform Tipus Què és Font
u_time float Segons des que va arrencar el shader, escalat per la velocitat conjur.cpp:51
u_resolution vec2 Mida de la finestra en píxels conjur.cpp:52
u_x0u_x3 float Els quatre paràmetres de la interfície. Sempre 0.01.0 conjur.cpp:54
u_tex0 sampler2D Textura d'entrada (vídeo, o sortida del shader anterior) conjur.cpp:57
u_tex1 sampler2D Segona entrada, si existeix a la cadena conjur.cpp:57

I del default.vert, disponibles com a varyings:

Varying Tipus Què és
v_texcoord vec2 Coordenada UV normalitzada, 0.01.0. És el que es fa servir sempre
tcoord vec2 Àlies exacte de v_texcoord (suport de dos formats)
v_position, v_color, v_normal Existeixen, però els shaders del repositori no els fan servir

Els legacy (existeixen, però no els facis servir en codi nou)

conjur.cpp:61-73 enllaça a més un joc de noms més antic:

Uniform Tipus Què és
ftime float Només la part decimal de u_time — va de 0 a 1 i salta. No és un rellotge continu
itime int ceil(u_time), comptador de segons enters
tres vec2 Igual que u_resolution
fparams vec4 Els quatre params junts: fparams[0] == u_x0
iparams ivec4 Sempre (0,0,0,0). Està mortconjur.cpp:66 el fixa a zero
tex, tex2 sampler2D Àlies d'u_tex0 i u_tex1

Compte amb ftime: Shaders/0-input/colour_sine.frag el fa servir i és fàcil copiar-lo creient que és el rellotge. Serra cada segon.

D'on surt aquest joc de noms antic

No és un invent de r_e_c_u_r: és la convenció nativa del Structure, el mòdul Eurorack de vídeo d'Erogenous Tones. El default.vert declara tcoord i v_texcoord alhora, amb el comentari literal // twice because supporting two shader formats, precisament per servir les dues comunitats.

Es veu clar a l'únic tutorial de conversió que hi ha a la wiki oficial, tutorial_converting_simple_1input_shader_from_shadertoy: està escrit sencer en la convenció antiga, parla dels «noms que structure/recur esperen» i envia al sandbox d'Erogenous Tones.

Els dos formats funcionen de debò. conjur.cpp:50-73 enllaça els dos jocs sense condicions, i com que fparams s'alimenta del mateix array shaderParams que u_x0..u_x3, un shader escrit a l'estil antic també respon als comandaments. Tot i així, en codi nou convé el joc modern per tres raons concretes: iparams està mort, ftime no és un rellotge continu, i el modern és el que fan servir els shaders d'exemple del repositori.

Si segueixes el tutorial de la wiki: reconstrueix el temps amb float time = float(itime) + ftime;. Com que itime és ceil() i no floor(), això va gairebé un segon avançat respecte a u_time. Tant se val per a un efecte visual, però no és el mateix rellotge.

El que NO existeix

  • No hi ha u_mouse. Les notes de l'autor l'esmenten, però només com a manera de desenvolupar amb glslViewer a l'escriptori; conjur.cpp no l'enllaça mai. Amb l'historial complet al davant es pot afirmar fort: git log -S "u_mouse" sobre src/ no retorna cap commit dels 47 del repositori. No es va treure: no hi va ser mai.
  • No hi ha equivalent d'iTimeDelta, iFrame, iDate, iChannelResolution, ni entrada d'àudio.
  • No hi ha multipassada (els Buffer A/B/C/D de Shadertoy).

La marca //N-input: què fa realment

Tots els shaders del repositori comencen amb //0-input, //1-input o //2-input. video_centre/shaders.py:48-57 busca aquella cadena en qualsevol part del fitxer i la tradueix a 0in/1in/2in; si no en troba cap, el tipus és -.

Però la marca és purament informativa. Seguint la dada fins al final:

  • shaders.py:76 l'envia per OSC com a segon argument de /shader/N/load.
  • ofApp.cpp:317 només llegeix l'argument 0 (la ruta). Ignora el tipus i el nombre de paràmetres.
  • L'únic altre ús és display.py:174, que pinta la primera lletra a la pantalla.

O sia que la marca canvia l'etiqueta del menú i res més. u_tex0 està enllaçat sempre que hi hagi almenys una textura a la cadena, fins i tot en un //0-input. Escriu-la igualment: és el que et diu d'un cop d'ull què fa un shader quan en tens trenta a la llista.

La documentació del mateix autor (c_o_n_j_u_r/notes_on_shader_formats.md) parla de //gen-shader i //pro-shader, i diu que un gen-shader pausa el vídeo. Aquell document està desactualitzat: el codi actual busca //N-input i no fa res amb el resultat. Si segueixes les notes de l'autor al peu de la lletra, el teu shader apareix com a tipus -.

El mateix amb el nombre de paràmetres: les notes diuen que es detecta comptant uniform float u_xN, però shaders.py:61 té un if True: que retorna 4 sempre. Els quatre params estan disponibles declaris els que declaris.

La interfície no informa d'errors del shader

video_centre/shaders.py:18 documenta '!' com a estat d'error, però no hi ha cap camí del codi que l'assigni. Un shader que no compila mostra el mateix estat de «en marxa» que un que funciona. El registre de GLSL només existeix a la sortida estàndard de c_o_n_j_u_r.

Com encadena les tres capes

ofApp.cpp:115-129 — hi ha 3 capes de shader, s'apliquen en ordre, i cadascuna fica la seva sortida al principi de la llista de textures:

if(effectShader0active){
    fbo = effectShader0.apply(effectInput);
    effectInput.insert(effectInput.begin(), fbo.getTexture());
}
// ...igual per a 1 i 2

Conseqüència pràctica: a la capa 1, u_tex0 és la sortida de la capa 0, i u_tex1 és el que la capa 0 tenia d'entrada. Aquí hi ha el truc per barrejar una imatge amb la seva pròpia versió processada.

Temps i velocitat

conjur.cpp:74-77:

void conjur::setSpeed(float value){
    speed = -2.0 + 4.0*value;
}

El valor de la interfície (01) es mapa a un multiplicador de 2 a +2:

Valor UI Velocitat Efecte
0.0 2.0 El temps corre enrere, al doble
0.5 0.0 Congelat
0.75 1.0 Normal
1.0 2.0 El doble de ràpid

El botó de velocitat de r_e_c_u_r (shaders.py:136-140) només alterna entre 0.5 i 0.75, o sia congelat / normal. Per al rang complet cal activar l'ajust X3_AS_SPEED, que segresta u_x3: amb ell activat, u_x3 deixa d'arribar al shader i passa a ser el control de velocitat (shaders.py:157-160). Si el teu shader fa servir els quatre params, compta que el quart pot faltar.

I u_time és acumulat, no absolut (conjur.cpp:88-94): en canviar la velocitat no salta, segueix des d'on anava. Pot ser negatiu si el poses marxa enrere — si el teu shader fa sqrt(u_time) o semblant, es trenca.

Estabilitat d'aquesta llista

Els noms dels uniforms no canvien des del 2019-08-03, commit 4c7312c («added alt shader mode»), que va introduir els dos jocs alhora. Cap commit posterior toca ni un sol nom. El que sí que va canviar després va ser d'on surt el temps:

Commit Data Què va fer
4c7312c 2019-08-03 Fixa els noms dels uniforms, els dos jocs
0483d54 2019-08-30 u_time, ftime i itime deixen de llegir ofGetElapsedTimef() directament i passen pel rellotge virtual getTime(). Aquí neix speed = -2.0 + 4.0*value, i amb ella poder congelar el temps o córrer-lo enrere
b8f4bd4 2019-09-27 Retocs sense efecte sobre els uniforms
4fd0559 2025-04-04 «changing a few things for recurboy update»: només dues línies d'ofLog

Dit d'una altra manera: des del setembre del 2019 no s'ha mogut res que afecti com s'escriu un shader.

Compte amb les branques

master està congelada al commit 16e1fae, del 2020-07-23, i és el que descriu aquest document. Però el repositori va seguir viu en altres branques:

Branca Últim commit Què afegeix
master 2020-07-23 La base. És el documentat aquí
dev 2022-01-11 Sistema de modulació dels 4 params, ajust USE_SHADER_MOD i shaders nous (chroma_key, luma_key_black/white, displace2in, spotlight)
feature_plugins 2020-03-15 Sistema de connectors
pre-plugin-dev 2020-03-14

La bona notícia: el format de shader no canvia. video_centre/shaders.py a dev segueix buscant //0-input///1-input///2-input, i determine_shader_parameter_number conserva el mateix if True: return 4. Tot el d'aquest document val igual a dev.

El que sí que canvia és el que es pot fer amb els params: a dev es poden modular, sumant un valor de 1 a +1 al valor base i retallant el resultat a 01. La wiki documenta a sobre d'això connectors d'LFO i de reacció a àudio.

[PER VERIFICAR A LA MÀQUINA] quina branca corre el teu aparell: git -C ~/r_e_c_u_r branch --show-current.

Ajustos de r_e_c_u_r que afecten els shaders

De json_objects/settings_default.json:

  • X3_AS_SPEED — el dit més amunt: u_x3 passa a ser el control de velocitat.
  • FIX_PARAM_OFFSET_LAYER — canvia a quina capa es dirigeixen els comandaments.
  • SHADER_POSITION (input/output) — si la cadena de shaders s'aplica abans o després del bucle de realimentació detour.

Limitacions de la màquina

  • OpenGL ES 2.0 / GLSL ES 1.00. Ho diu l'autor a notes_on_shader_formats.md («currently the conjur openframeworks application is running gles 2»). És el que més mana en portar des de Shadertoy; vegeu la guia de conversió.
  • No es declara #version a dalt. Es fa servir el bloc #ifdef GL_ES / precision mediump float; / #endif que porten tots els shaders del repositori.
  • El maquinari objectiu és la Raspberry Pi 3.
  • [PER VERIFICAR A LA MÀQUINA] la resolució real de treball: u_resolution surt d'ofGetWidth()/ofGetHeight(), que depèn de com estigui configurada la sortida de vídeo de la Pi.
  • Mesurat el 2026-09-05: per a un shader 0-input, gl_FragCoord.y = 0 cau A DALT de la pantalla en aquest aparell, al reves que en un escriptori. Aixo va de gl_FragCoord, no de v_texcoord; el punt seguent segueix obert.
  • [PER VERIFICAR A LA MÀQUINA] si v_texcoord té l'eix Y invertit respecte a Shadertoy. Els shaders del repositori el fan servir directament sense capgirar, cosa que suggereix que no, però amb textures de vídeo en un FBO convé comprovar-ho amb test-orientation.frag abans de barallar-se amb un port.

Errates al repositori original

Trobades en llegir-lo, per si te'n copies (comprovades sobre el commit 16e1fae):

  • Shaders/0-input/colour_sine.frag:9uniform vec4 fparams sense punt i coma. Aquell fitxer no compila. No el facis servir de plantilla.
  • Shaders/1-input/invert_effect.frag — no porta bloc de precisió.
  • Shaders/2-input/mix_lumaKey.frag — ni marca //N-input ni bloc de precisió, i està escrit sencer amb els noms legacy (tcoord, tex, tex2, tres, fparams). És l'exemple viu del format antic, útil per reconèixer-lo.