クリエイティブコーディングと数学

今週は、異動先で本格的に活動することが有り、シェーダーの方に時間をさけなかった。

引き続きシェーダーと仲良くなるのを続けており、今週はこれ↓シェイピング関数で絵を描くが終わった。

出力される絵は白黒で地味だが、実は脳内では大幅なレベルアップが行われている。

着目ポイントは「境目」だ。

数学の知識とグラフを使って、
1つ目: 0,1の境目をはっきり分ける
2つ目: 0~1を緩やかに分ける

という違いがある。
2つめは徐々に徐々に白から黒への境目が曖昧になり緩やかに変化しているのがわかる。

教科書の中で一行一行読み解いていって、なぜこの関数を使うのか、つかったらどんな出力が得られるのかを想像して実際に描いてみると面白い。

`
     #include <common>

     //iResolution: 解像度
     uniform vec3 iResolution;
     uniform float iTime;
     uniform float lineWidth;
     uniform float numberOfExponent;
     // マウスの位置
     uniform vec2 u_mouse;
     
     ///////////////////////////////////////////////////////////
     // plot関数 (0.0~1.0の間の値を使って、Y軸に線を引く)
     ////////////////////////////////////////////////////////////
     float plot(vec2 st, float pct) {    
         // smoothstep(min, max, between) この関数はその範囲の間で0.0から1.0まで滑らかに変化する数値を返す
         // 入力値がminより小さい場合、smoothstep()は0を返します。
         // 入力値がmaxと等しいか、maxより大きい場合、smoothstep()は1を返します。
         // 入力がminとmaxの間にある場合、smoothstep()は0と1.0の間の値を(比例して)返します。
         // 最初の2つのパラメータは値の変化の起こる範囲の始まりと終わり
         // 3つめのパラメータはチェックの対象になる値
         // 0.02 よりもabs(position.y - position.x)が小さければ0を返す
         // abs(position.y - position.x) が 0か、0よりも大きい場合 1を返す
         // abs(position.y - position.x) が 0.02 ~ 0 の間にある場合、 0と1.0の間の値を(比例して)返す
         return  smoothstep( pct - lineWidth, pct, st.y) - smoothstep( pct, pct + lineWidth, st.y);
     }
     
     ////////////////////////////////////////////////////////////
     // mainImage関数 (基本はここで操作)
     ////////////////////////////////////////////////////////////
     
     // out 出力用 in 入力用
     void mainImage( out vec4 fragColor, in vec2 fragCoord ){
         
         //正規化(原点を中心におく)
         vec2 position = (fragCoord.xy * 2.0 - iResolution.xy) / min(iResolution.x, iResolution.y);
         
         // Stepは、値が0.5(numberOfExponent)以上でない限り0.0を返します。
         // その場合は1.0を返します。
         float y = step(numberOfExponent, position.x);
         
         vec3 color = vec3(y);
         
         // ラインの描画 (x=y の直線時は1になる)
         float pct = plot(position, y);
         // x=y の直線に近づければ近づくほど、pctは1に近づくから 黒と緑の2色を制御できている
          
         color = (1.0 - pct) * color + pct * vec3(0.0,1.0,0.0);

         // 画面への出力
         fragColor = vec4(color, 1.0);
     }

     ////////////////////////////////////////////////////////////
     // main 関数
     /////////////////////////////////////////////////////////////
     void main() {
       mainImage(gl_FragColor, gl_FragCoord.xy);
     }

 

こんなかんじで、いろいろなグラフを自分のコードに移植して数の変化を楽しんでいた。

ただ、このグラフがどう役に立つのかは、まだ整理しきれていなかった。教科書のこの一文は、次の項に進んだときに、役に立つやん!!!を実感することになる。

このコードがミヤギさんの壁です。よく観察して理解しておくことが大切です。この 0.0 から 1.0 の空間には何度も立ち帰ることになるでしょう。そしてあなたはいずれ、色と形を操る技をマスターするのです。
この関数たちは私たちにとってのミヤギさんの壁なのです。今は1次元、上下の動きをマスターしつつあります。すぐに2次元、3次元、そして4次元についても学んでいきます。

色について

今週の中頃からこちらに入ることにした。

色の変化を、いままで学んだグラフの変化を使って制御するのだ。
早速、前回学んだ数式が役に立つ。

こちらのチートシートには、様々なグラフの制御が一覧でわかるようになっている。こちらを自分のGLSLに移植して色の変化を制御できるようにした。

実は上記3つの作品は、色の変化は同じだか、変化の仕方が異なる。

1つ目: サインカーブ
2つ目:easeInSine
3つ目:easeOutSine

色の変化に加速度の変化をつけることができた。こういう積み上げが、徐々に自分の知識の広がりをもたらすのだろうなと思った。数学と同じだな。

数学と触れていると、学生時代きちんと取り組んでいなかった数学をやり直したくなる。

これを読み始めてみると最初のイントロダクションの複素数平面の時点で躓いてしまった。まずはのんびり複素数平面のそもそもを知ろうかなと思い数学ガールを朝活で読んでみた。

数学1のときに学んだ、実数や数直線、絶対値はこんなに大事だったのかと驚いた。あのときは、見ればわかるものをなぜ勉強しているのだろうと思っていたが、複素数平面の概念を理解するための土台だったとは・・・・

数学はもう少し、習い始める前に何に使うのか、どう大事なのか言ってほしい・・・・。20年に及ぶ数学の伏線回収は、あまりにも長期連載すぎる。

エンジニアとして働いている成長記録やおもしろいと思ったこと色々書いていこうとおもいます 頂いたご支援は、資料や勉強のための本、次のネタのための資金にし、さらに面白いことを発信するために使います 応援おねがいします