Différences
Ci-dessous, les différences entre deux révisions de la page.
| Les deux révisions précédentes Révision précédente Prochaine révision | Révision précédente | ||
|
ressource:code:processing:shaders [2022/09/07 10:18] gweltaz |
ressource:code:processing:shaders [2023/04/25 18:13] (Version actuelle) zemog [Variables uniform communes à tous les shaders dans Processing] |
||
|---|---|---|---|
| Ligne 1: | Ligne 1: | ||
| + | {{tag>processing shaders}} | ||
| ====== Initiation aux Shaders avec Processing ====== | ====== Initiation aux Shaders avec Processing ====== | ||
| ===== Le hello World des shaders ===== | ===== Le hello World des shaders ===== | ||
| + | |||
| + | Les fichiers ''vert.glsl'' et ''frag.glsl'' sont à placer dans le dossier ''data'' du sketch. | ||
| <accordion><panel title="shader_01"> | <accordion><panel title="shader_01"> | ||
| Ligne 19: | Ligne 22: | ||
| </code> | </code> | ||
| - | <code glsl freg.glsl> | + | <code glsl frag.glsl> |
| #ifdef GL_ES | #ifdef GL_ES | ||
| precision mediump float; | precision mediump float; | ||
| Ligne 54: | Ligne 57: | ||
| ===== Communication entre l'application et les shaders ===== | ===== Communication entre l'application et les shaders ===== | ||
| + | {{ :ressource:code:processing:shader_comm.png?direct |}} | ||
| + | |||
| L'application (programme Processing) peut envoyer des données vers les shaders par des variable déclarées avec le mot-clé ''uniform''. | L'application (programme Processing) peut envoyer des données vers les shaders par des variable déclarées avec le mot-clé ''uniform''. | ||
| + | |||
| + | ==== Fonctions GLSL ==== | ||
| + | * step(seuil, val) | ||
| + | Renvoi 0. si val < seuil, renvoi 1. si val > seuil | ||
| + | * smoothstep(seuil1, seuil2, val) | ||
| + | * clamp() | ||
| + | * pow() | ||
| + | * fract() | ||
| + | Returns the fractional part of a number | ||
| + | * mod(a, b) | ||
| + | a modulo b | ||
| + | * length() | ||
| + | * atan(y,x) | ||
| + | * mix(v1, v2, pct) | ||
| + | Interpolation linéaire entre v1 et v2 en fonction de 'pct' | ||
| + | * sign(float val) | ||
| + | Renvoi -1 si val est négatif, 1 si val est positif | ||
| ==== Fonctions Processing pour transmettre des données ==== | ==== Fonctions Processing pour transmettre des données ==== | ||
| Ligne 74: | Ligne 96: | ||
| > Attention ! Lorsqu'on transmet des nombres entiers, comme par exemple : ''set("u_resolution", 512, 512)'', soyez sûr d'avoir déclaré les variables ''uniform'' pour des types entiers, comme : ''ivec2'', ''ivec3''... \\ | > Attention ! Lorsqu'on transmet des nombres entiers, comme par exemple : ''set("u_resolution", 512, 512)'', soyez sûr d'avoir déclaré les variables ''uniform'' pour des types entiers, comme : ''ivec2'', ''ivec3''... \\ | ||
| > Une autre solution est de les convertir en nombres flottants avant de les transmettre : ''set("u_resolution", float(512), float(512))'' | > Une autre solution est de les convertir en nombres flottants avant de les transmettre : ''set("u_resolution", float(512), float(512))'' | ||
| + | |||
| + | ==== Variables uniform communes à tous les shaders dans Processing ==== | ||
| + | Certaines variables ''uniform'' sont définies dans Processing et sont disponibles dans tous les shaders.\\ | ||
| + | Elles sont déclarées dans le fichier ''PShader.java'' de Processing. | ||
| + | <code glsl> | ||
| + | uniform mat4 transformMatrix; // la matrice de model view projection pour transformer les coordonnées du vertex du model space au clip space | ||
| + | uniform mat4 projectionMatrix; // la matrice de projection permet de passer du camera space au clip space | ||
| + | uniform mat4 modelviewMatrix; // la matrice modelview permet de passer du model space au world space puis au camera space | ||
| + | uniform vec2 resolution; // contient la résolution de notre fenêtre | ||
| + | uniform vec4 viewport; // contient la position de notre fenêtre ainsi que sa résolution | ||
| + | </code> | ||
| ===== Textures ===== | ===== Textures ===== | ||
| + | Pour sampler un texel en GLSL (extraire la couleur d'une texture à un point donné), on utilise la fonction: | ||
| + | ''texture2D(sampler2D image, vec2 uv)'' \\ | ||
| + | Les coordonnes UV doivent être comprises entre 0.0 et 1.0 \\ | ||
| + | Elles pour origine le coin bas-gauche (0, 0) contrairement aux coordonnées d'écran, qui ont pour origine le coin haut-gauche. | ||
| + | |||
| + | ===== Utilisation d'un buffer hors-écran ===== | ||
| + | Pratique pour créer des effets avec retour d'information (feedback), comme par exemple un effet de réaction-diffusion. | ||
| + | |||
| + | <code java> | ||
| + | PGraphics buffer = createGraphics(x, y, P2D); | ||
| + | |||
| + | buffer.beginDraw(); | ||
| + | buffer.shader(myShader); | ||
| + | buffer.rect(0, 0, buffer.width, buffer.height); | ||
| + | buffer.endDraw(); | ||
| + | |||
| + | image(buffer, 0, 0); | ||
| + | </code> | ||
| + | |||
| ===== Fonctions utiles ===== | ===== Fonctions utiles ===== | ||
| Ligne 95: | Ligne 147: | ||
| </code> | </code> | ||
| + | == HSB -> RGB == | ||
| + | <code glsl> | ||
| + | vec3 hsb2rgb( in vec3 c ){ | ||
| + | vec3 rgb = clamp(abs(mod(c.x*6.0+vec3(0.0,4.0,2.0), | ||
| + | 6.0)-3.0)-1.0, | ||
| + | 0.0, | ||
| + | 1.0 ); | ||
| + | rgb = rgb*rgb*(3.0-2.0*rgb); | ||
| + | return c.z * mix(vec3(1.0), rgb, c.y); | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | == RGB -> HSB == | ||
| + | <code glsl> | ||
| + | vec3 rgb2hsb( in vec3 c ){ | ||
| + | vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); | ||
| + | vec4 p = mix(vec4(c.bg, K.wz), | ||
| + | vec4(c.gb, K.xy), | ||
| + | step(c.b, c.g)); | ||
| + | vec4 q = mix(vec4(p.xyw, c.r), | ||
| + | vec4(c.r, p.yzx), | ||
| + | step(p.x, c.r)); | ||
| + | float d = q.x - min(q.w, q.y); | ||
| + | float e = 1.0e-10; | ||
| + | return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), | ||
| + | d / (q.x + e), | ||
| + | q.x); | ||
| + | } | ||
| + | </code> | ||
| === Random === | === Random === | ||
| <code glsl> | <code glsl> | ||
| Ligne 128: | Ligne 209: | ||
| (c - a)* u.y * (1.0 - u.x) + | (c - a)* u.y * (1.0 - u.x) + | ||
| (d - b) * u.x * u.y; | (d - b) * u.x * u.y; | ||
| + | } | ||
| + | </code> | ||
| + | |||
| + | == Fractional Brownian Motion == | ||
| + | <code glsl> | ||
| + | float hash(vec2 coord) | ||
| + | { | ||
| + | return fract(sin(dot(coord.xy, vec2(12.9898, 78.233))) * 43758.5453123); | ||
| + | } | ||
| + | |||
| + | float noise(vec2 U) | ||
| + | { | ||
| + | vec2 id = floor(U); | ||
| + | U = fract(U); | ||
| + | U *= U * ( 3. - 2. * U ); | ||
| + | |||
| + | vec2 A = vec2( hash(id), hash(id + vec2(0,1)) ), | ||
| + | B = vec2( hash(id + vec2(1,0)), hash(id + vec2(1,1)) ), | ||
| + | C = mix( A, B, U.x); | ||
| + | |||
| + | return mix( C.x, C.y, U.y ); | ||
| + | } | ||
| + | |||
| + | /** | ||
| + | fBM stands for Fractional Brownian Motion | ||
| + | https://iquilezles.org/articles/fbm/ | ||
| + | Set octave to 8 for a detailed noise | ||
| + | A value of 1.0 for H is good | ||
| + | */ | ||
| + | float fbm(vec2 x, float H, int octave) | ||
| + | { | ||
| + | float G = exp2(-H); | ||
| + | float f = 1.0; | ||
| + | float a = 1.0; | ||
| + | float t = 0.0; | ||
| + | for( int i=0; i<octave; i++ ) | ||
| + | { | ||
| + | t += a*noise(f*x); | ||
| + | f *= 2.0; | ||
| + | a *= G; | ||
| + | } | ||
| + | return t; | ||
| } | } | ||
| </code> | </code> | ||