Shader 入門ランチャー

マルチメディア表現II / INS300A
スケッチ制作:Adam Ferriss
リンク集:大谷安宏
1スケッチを開く
2画面を触ってみる
3コードの1行を書き換える
4何が変わったか確認する
Step 01 / 基礎
UV と色
シェーダーの最初の一歩。画面上の「位置」が「色」になる。
座標(UV)を理解すれば、残りはすべてその応用になる。
// UV = 画面上の位置を 0〜1 に正規化した座標 vec2 uv = vTexCoord; // 【キーライン】位置をそのまま色にする gl_FragColor = vec4(uv.x, uv.y, 1.0, 1.0); // x座標 → 赤 y座標 → 緑 固定値1.0 → 青

今日やること

「UV を色にする」を開いて、frag シェーダーの最後の行を1か所だけ変える
変わった結果をスクリーンショットで保存する
「なぜそう変わったか」を制作ノートに1行書く
Step 02 / 基礎
マウス入力
マウスの座標をシェーダーに送る(uniform変数)。
「外からデータを渡す」という考え方がシェーダーの核心のひとつ。
// p5.js 側でマウス座標を送る myShader.setUniform('u_mouse', [mouseX/width, mouseY/height]); // シェーダー側で受け取る uniform vec2 u_mouse; // 使う float r = u_mouse.x; // マウスX → 赤チャンネル

今日やること

マウスで色が変わるスケッチを開き、u_mouse.x と u_mouse.y を入れ替える
smoothstep の第2引数を 0.01 → 0.5 → 0.99 と変えて3種類保存
「smoothstep は何を制御しているか」を1文で書く
Step 03 / 基礎
時間・アニメーション
時間(millis)をシェーダーに送ると、静止画が動き出す。
sin(time) と組み合わせることで周期的な変化が生まれる。
// p5.js 側 myShader.setUniform('u_time', millis() / 1000.0); // シェーダー側 uniform float u_time; // sin で -1〜1 を繰り返す → 0〜1 に変換 float wave = sin(u_time) * 0.5 + 0.5;

今日やること

ウィグル歪みを開いて、sin の引数に u_time * 2.0 など倍数を掛ける
速さ・振れ幅を変えて、気に入った状態を録画(V キー)で保存
「速さと印象の関係」を制作ノートに記録する
Step 04 / 変形
歪み・ウィグル・ディスプレイスメント
UV座標を数式で動かすと、画像が伸び縮みしたり溶けたりする。
「座標を変える」=「見え方を変える」というシェーダーの核心。
// 座標をそのままサンプリング(普通) vec4 col = texture2D(tex, uv); // 【キーライン】座標を歪ませてからサンプリング vec2 warped = uv + vec2(sin(uv.y * 10.0 + time) * 0.05, 0.0); vec4 col = texture2D(tex, warped);

今日やること

ウィグルの sin の周波数(10.0)と振幅(0.05)を自由に変えて5パターン作る
「前回のLoop断片のPNG」を画像として読み込み、歪みをかけてみる
最も気に入ったパターンをPNG保存して制作ノートに理由を書く
Step 05 / 変形
しきい値・ポスタライズ
連続した色を「段階」に分けると絵画的・版画的な表現になる。
step() と smoothstep() の違いを体感する。
// step: 0か1かの二値化(境界がくっきり) float mask = step(0.5, brightness); // smoothstep: 境界をなめらかにする float mask = smoothstep(0.4, 0.6, brightness); // ↑低 ↑高 ← この幅が「ぼかし量」

今日やること

ポスタライズの段階数を 2 / 4 / 8 / 16 に変えて印象の違いを確認
「前回のLoop断片のPNG」にしきい値処理をかけてPNG保存
コラージュ素材として使えそうかどうかを制作ノートに書く
Step 06 / 変形
色分離・クロマティック収差・グリッチ
RGB の各チャンネルを別々の座標からサンプリングする。
ズレの量を変えるだけで、繊細なものから激しいグリッチまで作れる。
// 【キーライン】RGBを別々の位置からサンプリング float r = texture2D(tex, uv + vec2(offset, 0.0)).r; float g = texture2D(tex, uv ).g; float b = texture2D(tex, uv - vec2(offset, 0.0)).b; // offset を大きくするほど色ズレが強くなる

今日やること

クロマティック収差を「さりげない量(0.003)」と「グリッチ量(0.04)」で2種類保存
前回のLoop断片のPNGに適用して、コラージュ素材を3点以上作る
「どの量が自分の表現テーマに合うか」を制作ノートに記録
Step 07 / 発展
ノイズ・パターン生成
乱数とノイズ関数で「自然に見えるランダム」を作る。
パターン生成の基礎。画像なしで素材を生成できる。
// 擬似乱数:同じ入力 → 常に同じ出力 float hash(vec2 p){ return fract(sin(dot(p, vec2(127.1, 311.7))) * 43758.5); } // fract = 小数部分だけ取り出す(必ず 0〜1) // sin と大きな数の掛け算でランダムに見える値を作る

今日やること

Shadertoy変換例のコードを読んで、p5の変数名とShadertoyの変数名の対応をノートにまとめる
shader_gallery.html のステージ3(ノイズ)を録画して素材として保存
生成した素材とLoop断片を並べて、コラージュの構成を1案考える
Step 08 / 発展
フィードバック
前のフレームを今のフレームに混ぜることで「残像」「増殖」「崩壊」が生まれる。
VJやエクスペリメンタル映像の定番手法。
// 前のフレームを少し暗くしながら混ぜる vec4 prev = texture2D(u_prev_frame, uv); vec4 curr = texture2D(u_curr_frame, uv); gl_FragColor = mix(curr, prev * 0.95, 0.5); // ↑ 0.95 = 残像の残り方(1.0で消えない)

今日やること

フィードバックの係数を 0.8 / 0.95 / 0.999 で試して録画保存
「係数の違いが映像の印象にどう影響するか」を問いの形で書く
最も自分のテーマに近い係数を1つ選んで理由をノートに記録