ギンの備忘録

デジタルアートやプログラミングやテクノロジー関連のこと。

p5.jsでのシェーダー(GLSL)入門(3)シェーダーの描画を動かす

前回までは静止した描画を行ってきました。

gin-graphic.hatenablog.com

今回はp5.jsから変数を渡すことで、動的にGLSLでの描画を変化させ、動画を作りたいと思います。

シェーダー描画を動かす

シェーダーの描画を動かすために、p5.js から変数を渡すします。 p5.js でのframeCountに相当するフレームが進むにつれて変化する変数をGLSLに渡せば、時間変化する描画をすることごできます。

GLSLでy方向に上下に動く描画を試してみます。

let vs = `
   precision highp float;

   attribute vec3 aPosition;
   attribute vec2 aTexCoord;
   varying vec2 vTexCoord;

   uniform mat4 uProjectionMatrix;
   uniform mat4 uModelViewMatrix;

   void main() {
      vec4 positionVec4 = vec4(aPosition, 1.0);

      vTexCoord = aTexCoord;

      gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
   }
`;

let fs = `
   precision highp float;

   varying vec2 vTexCoord;

   uniform float u_time;
   const float pi = 3.1415926535;

   void main() {
      vec2 b = vTexCoord * 2.0 - 1.0;
      b.y += sin(pi/10.0 * u_time );
      vec3 col = vec3(pow(1.0 - abs(b.y), 8.0) * 2.0);
      col *= vec3(0.2, 0.5, 0.9) ;

      gl_FragColor = vec4(col, 1.0);
    }
`;

let theShader;

function setup() {
   createCanvas(500, 500, WEBGL);

   theShader = createShader(vs, fs);

   rectMode(CENTER);
   noStroke();
}

function draw(){
   const wh = 75 ;
   let t = frameCount / 10;

   background("#B0D0B0");

   shader(theShader);

   theShader.setUniform('u_time', t);
   push();
   translate(100, -150);
   rotate(radians(30));
   rect(0, 0, wh, wh);
   pop();

   theShader.setUniform('u_time', t/2);
   push();
   translate(100, -50);
   rotate(radians(60));
   ellipse(0, 0, wh, wh);
   pop();

   theShader.setUniform('u_time', t/3);
   push();
   translate(100, 50);
   rotate(radians(270));
   triangle(0, -wh/2, wh/2, wh/2, -wh/2, wh/2);
   pop();

   theShader.setUniform('u_time', t/4);
   push();
   translate(100, 150);
   rotate(radians(-30));
   plane(wh, wh);
   pop();

   resetShader();

   push();
   translate(-100, -150);
   rotate(radians(30));
   rect(0, 0, wh, wh);
   pop();

   push();
   translate(-100, -50);
   rotate(radians(60));
   ellipse(0, 0, wh, wh);
   pop();

   push();
   translate(-100, 50);
   rotate(radians(270));
   triangle(0, -wh/2, wh/2, wh/2, -wh/2, wh/2);
   pop();

   push();
   translate(-100, 150);
   rotate(radians(-30));
   plane(wh, wh);
   pop();
}

f:id:gin_graphic:20201208210945p:plain:w250

www.youtube.com

p5.js からGLSLへ変数を渡すにはtheShader.setUniform();という関数を使います。 GLSLでuniform型で宣言した変数は、p5.js でtheShader.setUniform();を使って値を代入できます。

コードではtheShader.setUniform('u_time', t);として、frameCountから作ったtを代入しています。

また、theShader.setUniform();で変数の値を何度か変えることもできます。 図形毎に渡す値をtt/2t/3t/4と変えて、4つの図形の描画速度を異なるものにしています。

まとめ

p5.js からGLSLへ変数を渡すことで、シェーダー描画を動かすことごできました。 これにより、シェーダーを使った動画の作成ができるようになりました。 p5.jsとGLSLでの作品づくりの表現が一つ増えました。

参考文献

wgld.org

webglfundamentals.org

thebookofshaders.com

p5.jsでのシェーダー(GLSL)入門

p5.jsでのシェーダー(GLSL)入門(1)描画してみる - ギンGraphic

p5.jsでのシェーダー(GLSL)入門(2)図形にシェーダーを適用 - ギンGraphic

p5.jsでのシェーダー(GLSL)入門(3)シェーダーの描画を動かす - ギンGraphic

p5.jsでのシェーダー(GLSL)入門(4)図形を変形する - ギンGraphic