Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

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 09:49]
gweltaz [Ressources]
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 =====
 +
 +=== Couleur ===
 +
 +== Luminance ==
 +<code glsl>
 +float luma(vec4 color) {
 +  return dot(color.rgb,​ vec3(0.299, 0.587, 0.114));
 +}
 +</​code>​
 +
 +== Brightness ==
 +<code glsl>
 +float brightness(vec4 color) {
 +  return dot( color.rgb , vec3( 0.2126 , 0.7152 , 0.0722 ));
 +}
 +</​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 ===
 +<code glsl>
 +float random2d(vec2 coord)
 +{
 +    return fract(sin(dot(coord.xy,​ vec2(12.9898,​ 78.233))) * 43758.5453123);​
 +}
 +</​code>​
 +
 +=== Noise ===
 +== Gradient noise ==
 +<code glsl>
 +// 2D Noise based on Morgan McGuire @morgan3d
 +// https://​www.shadertoy.com/​view/​4dS3Wd
 +float noise (in vec2 coord) {
 +    vec2 i = floor(coord);​
 +    vec2 f = fract(coord);​
 +
 +    // Four corners in 2D of a tile
 +    float a = random(i);
 +    float b = random(i + vec2(1.0, 0.0));
 +    float c = random(i + vec2(0.0, 1.0));
 +    float d = random(i + vec2(1.0, 1.0));
 +
 +    // Smooth Interpolation
 +
 +    // Cubic Hermite Curve. ​ Same as SmoothStep()
 +    vec2 u = f*f*(3.0-2.0*f);​
 +    // u = smoothstep(0.,​1.,​f);​
 +
 +    // Mix 4 coorners percentages
 +    return mix(a, b, u.x) +
 +            (c - a)* u.y * (1.0 - u.x) +
 +            (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>​
 +
 +== Simplex noise ==
 +<code glsl>
 +//
 +// Description : GLSL 2D simplex noise function
 +//      Author : Ian McEwan, Ashima Arts
 +//  Maintainer : ijm
 +//     ​Lastmod : 20110822 (ijm)
 +//     ​License :
 +//  Copyright (C) 2011 Ashima Arts. All rights reserved.
 +//  Distributed under the MIT License. See LICENSE file.
 +//  https://​github.com/​ashima/​webgl-noise
 +//
 +
 +// Some useful functions
 +vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
 +vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
 +vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x);​ }
 +
 +float snoise(vec2 v) {
 +
 +    // Precompute values for skewed triangular grid
 +    const vec4 C = vec4(0.211324865405187,​
 +                        // (3.0-sqrt(3.0))/​6.0
 +                        0.366025403784439,​
 +                        // 0.5*(sqrt(3.0)-1.0)
 +                        -0.577350269189626,​
 +                        // -1.0 + 2.0 * C.x
 +                        0.024390243902439);​
 +                        // 1.0 / 41.0
 +
 +    // First corner (x0)
 +    vec2 i  = floor(v + dot(v, C.yy));
 +    vec2 x0 = v - i + dot(i, C.xx);
 +
 +    // Other two corners (x1, x2)
 +    vec2 i1 = vec2(0.0);
 +    i1 = (x0.x > x0.y)? vec2(1.0, 0.0):​vec2(0.0,​ 1.0);
 +    vec2 x1 = x0.xy + C.xx - i1;
 +    vec2 x2 = x0.xy + C.zz;
 +
 +    // Do some permutations to avoid
 +    // truncation effects in permutation
 +    i = mod289(i);
 +    vec3 p = permute(
 +            permute( i.y + vec3(0.0, i1.y, 1.0))
 +                + i.x + vec3(0.0, i1.x, 1.0 ));
 +
 +    vec3 m = max(0.5 - vec3(
 +                        dot(x0,x0),
 +                        dot(x1,x1),
 +                        dot(x2,x2)
 +                        ), 0.0);
 +
 +    m = m*m ;
 +    m = m*m ;
 +
 +    // Gradients:
 +    //  41 pts uniformly over a line, mapped onto a diamond
 +    //  The ring size 17*17 = 289 is close to a multiple
 +    //      of 41 (41*7 = 287)
 +
 +    vec3 x = 2.0 * fract(p * C.www) - 1.0;
 +    vec3 h = abs(x) - 0.5;
 +    vec3 ox = floor(x + 0.5);
 +    vec3 a0 = x - ox;
 +
 +    // Normalise gradients implicitly by scaling m
 +    // Approximation of: m *= inversesqrt(a0*a0 + h*h);
 +    m *= 1.79284291400159 - 0.85373472095314 * (a0*a0+h*h);​
 +
 +    // Compute final noise value at P
 +    vec3 g = vec3(0.0);
 +    g.x  = a0.x  * x0.x  + h.x  * x0.y;
 +    g.yz = a0.yz * vec2(x1.x,​x2.x) + h.yz * vec2(x1.y,​x2.y);​
 +    return 130.0 * dot(m, g);
 +}
 +</​code>​
 +
 +=== Rotations ===
 +== 2D ==
 +<code glsl>
 +mat2 rotation2d(float a) {
 +    float c=cos(a);
 +    float s=sin(a);
 +    return mat2(c,​-s,​s,​c);​
 +}
 +
 +vec2 rotate(vec2 v, float angle) {
 + return rotation2d(angle) * v;
 +}
 +</​code>​
 +
 +== 3D ==
 +<code glsl>
 +mat4 rotation3d(vec3 axis, float angle) {
 +  axis = normalize(axis);​
 +  float s = sin(angle);
 +  float c = cos(angle);
 +  float oc = 1.0 - c;
 +
 +  return mat4(
 +    oc * axis.x * axis.x + c,           oc * axis.x * axis.y - axis.z * s,  oc * axis.z * axis.x + axis.y * s,  0.0,
 +    oc * axis.x * axis.y + axis.z * s,  oc * axis.y * axis.y + c,           oc * axis.y * axis.z - axis.x * s,  0.0,
 +    oc * axis.z * axis.x - axis.y * s,  oc * axis.y * axis.z + axis.x * s,  oc * axis.z * axis.z + c,           0.0,
 +    0.0,                                0.0,                                0.0,                                1.0
 +  );
 +}
 +
 +vec3 rotate(vec3 v, vec3 axis, float angle) {
 + return (rotation3d(axis,​ angle) * vec4(v, 1.0)).xyz;
 +}
 +</​code>​
  
 === Flou Gaussien === === Flou Gaussien ===
Ligne 83: Ligne 371:
 A exécuter en deux passes : horizontale et verticale \\ A exécuter en deux passes : horizontale et verticale \\
  
-<code glsl> +<code glsl> ​
-uniform float offset[3] = float[](0.0,​ 1.3846153846,​ 3.2307692308);​ +
-uniform float weight[3] = float[](0.2270270270,​ 0.3162162162,​ 0.0702702703);​ +
- +
 vec4 blur(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) { vec4 blur(sampler2D image, vec2 uv, vec2 resolution, vec2 direction) {
-    vec4 color = texture2D(image,​ uv / resolution) * weight[0];+    ​const float offset[3] = float[](0.0,​ 1.3846153846,​ 3.2307692308);​ 
 +    const float weight[3] = float[](0.2270270270,​ 0.3162162162,​ 0.0702702703);​ 
 + 
 +    ​vec4 colorOut ​= texture2D(image,​ uv / resolution) * weight[0];
     for (int i=1; i<3; i++) {     for (int i=1; i<3; i++) {
-        color += texture2D(image,​ (uv + direction * offset[i]) / resolution) ​* weight[i]+        ​vec3 color = texture2D(image,​ (uv + direction * offset[i]) / resolution);​ 
-        color += texture2D(image,​ (uv - direction * offset[i]) / resolution) * weight[i];+        color += texture2D(image,​ (uv - direction * offset[i]) / resolution)
 +        colorOut += color * weight[i];
     }     }
-    return ​color;+    return ​colorOut;
 } }
 </​code>​ </​code>​
Ligne 99: Ligne 388:
 ===== Librairies Processing ===== ===== Librairies Processing =====
 Quelques librairies externes pour l'​utilisation de shaders dans Processing : Quelques librairies externes pour l'​utilisation de shaders dans Processing :
- * PixelFlow+  ​https://​github.com/​diwi/​PixelFlow
  
 ===== Ressources ===== ===== Ressources =====
 Liste de liens incontournables pour approfondir et aller plus loin... Liste de liens incontournables pour approfondir et aller plus loin...
   * https://​thebookofshaders.com/​   * https://​thebookofshaders.com/​
-  * https://​shadertoy.com+  * https://www.shadertoy.com
   * https://​iquilezles.org/​articles/​functions/​   * https://​iquilezles.org/​articles/​functions/​
  • ressource/code/processing/shaders.1662536984.txt.gz
  • Dernière modification: 2022/09/07 09:49
  • par gweltaz