プログラミングでかっこいい映像をつくるには、『GLSL(ジーエルエスエル)』なるものを使えればいいと知りまして。
参考記事
こんな映像も『GLSL』でつくれるようです。
昨日の勉強会の懇親会中に20分間のライブコーディングでシェーダーを作りました!
初めて人前でコーディングをしたんですが、めちゃくちゃ楽しかったです!!(当日動かなかったpmod修正済です…)
差分
– q.x = abs(p.x ) – 10.;
+ q.x = abs(q.x ) – 10.;https://t.co/LH3TT4YzSU#klab_meetup pic.twitter.com/k61c3O2ZA1— かねた (@kanetaaaaa) 2019年6月19日
とググっているうちに、
なにやら『レイマーチング(Ray Marching)』なる技がある事を知りましたので、
ざっくりまとめてみたいと思います。
プログラミングでかっこいい映像なら『レイマーチング』がいいらしい
言葉の意味を調べてみると、
- レイ (Ray) は英語で光線
- マーチング (Marching) は英語で行進
になります。
『レイマーチング(Ray Marching)』をざっくりまとめると、
3D空間の中で、
ちょっとずつレイ(光線)を進めて、
『距離関数』で物体との距離を計算する
というような手法だそうです。
動画もありました。
February 4
「How Raymarcher Works」
(by @FMS_Cat ) https://t.co/oZDKV66mDP#EveOneMotion pic.twitter.com/FsLvcolAUz— Everyday One Motion (@motions_work) 2016年2月3日
本日の資料のために眺めるだけでレイマーチングを完全に理解できるかもしれないシェーダーを作りました🤔https://t.co/Hia4I0Dgii#klab_meetup pic.twitter.com/kIuU4USxRJ
— かねた (@kanetaaaaa) 2019年6月19日
画面全体を1スクリーンとして描画するため、
例えばパソコンで表示している画面が 横1024×縦768 だとしたら、
横1024×縦768 = 約78万回 も計算するそうです。
昔はとても実現できなかったそうですが、
最近はパソコンやGPU(グラフィック専門の演算装置)の性能が上がっていることで実現できるようになったようです。
しっかり動かすためにはそこそこハイスペックなパソコンが必要だそうです。
とはいえ、ここまでの説明だと
っとなってしまうので、
参考スライドを貼っておきます。
画像を一部抜粋。
『距離関数』のわかりやすい説明はこちら。
『距離関数』コードのサンプルはこちら。
プログラミングでかっこいい映像をつくるための『レイマーチング』を触ってみる
『レイマーチング(Ray Marching)』の解説を読むだけだとなかなか頭に入ってこないので、
『レイマーチング qiita』などで検索してみて、
良さげな記事をやってみることにしました。
コードはこちら。
#ifdef GL_ES precision mediump float; #endif #extension GL_OES_standard_derivatives : enable uniform float time; //時間 uniform vec2 mouse; uniform vec2 resolution; //解像度 vec3 lightDir = normalize(vec3(1.0, 1.0, 1.0)); //ライトの正規化 float dist_func(vec3 pos, float size) //距離関数 (球) { return length(pos) - size; } //距離関数を微分すると法線ベクトルになる->正規化して法線を得ることができる vec3 getNormal(vec3 pos, float size) //法線(向き)を得る関数 { float ep = 0.0001; return normalize(vec3( //正規化 //計6回 距離関数が実行されている // ep = 0.0001 なので、ちょっとだけ引く・・微分している dist_func(pos, size) - dist_func(vec3(pos.x - ep, pos.y, pos.z), size), dist_func(pos, size) - dist_func(vec3(pos.x, pos.y - ep, pos.z), size), dist_func(pos, size) - dist_func(vec3(pos.x, pos.y, pos.z - ep), size) )); } void main( void ) { // 解像度からテクスチャとして利用できる`-1~1`の間に正規化する vec2 pos = (gl_FragCoord.xy * 2.0 - resolution.xy) / min(resolution.x, resolution.y); vec3 col = vec3(0.0); // 色の初期化 //レイの定義 vec3 cameraPos = vec3(0.0, 0.0, 10.0); //カメラ位置を定義 vec3 ray = normalize(vec3(pos, 0.0) - cameraPos); //レイの方向を定義 vec3 cur = cameraPos; //カメラの位置をレイの初期値にする vec2 mouseNorm = mouse * 2.0 - 1.0; //マウス位置 float size = 1.0 - length(mouseNorm); //マウス位置でサイズを変える //レイを進める for (int i = 0; i < 16; i++) //16回繰り返す { float d = dist_func(cur, size); // d = 球の距離関数 if (d < 0.0001) //レイがオブジェクトに限りなく近づいたら { vec3 normal = getNormal(cur, size); // normal = 法線 float diff = dot(normal, lightDir); // 内積で光の当たり方(強度)を計算 col = vec3(diff) + vec3(0.1); //光の当たり方+ちょっと色つけ break; } cur += ray * d; // レイの位置をレイの方向に、一番近いオブジェクト(物体)分進める } gl_FragColor = vec4(col, 1.0); //フラグメントシェーダに色つけ }
- 『距離関数』を微分すると法線ベクトルになる
- 『内積』で光の当たり方を計算
の2箇所がスッキリしてないんですが、とりあえず前に進みながら調べて見ようと思います。
他のコードの詳細は、
オリジナル記事がとてもわかりやすいので、興味があればぜひ見てみてください。
このコードの中でも当たり前のように『ベクトル』が使われています。
参考記事
プログラミングでかっこいい映像といえば『レイマーチング』まとめ
まさか『プログラミング』でこんなにも、
かっこいい映像表現ができるようになるとは思ってなかったので、
ワクワクしながらググり、試していくことができました。
なかなか難しい内容なので、ちょっとずつコードを読み解きつつ、
『レイマーチング(Ray Marching)』の理解を深めていけたらと思います。
『GLSL(シェーディング)』関係ではこんな記事も読まれています。
1. 【GLSL】プログラムでかっこいい映像をつくりたい! 〜『TouchDesigner』を見据えて2. 【WebGL】入門 わかりやすく【図解】してみた
3. 【OpenGL】と【DirectX】のバージョンをまとめてみた【シェーダーメイン】【初心者向け】
4. 【GLSL(シェーディング)】でよく使う関数とユーザー関数のまとめ※随時更新
5. 【GLSL】プログラムでかっこいい映像をつくるには『レイマーチング』なるものを覚えればいいらしい
6. 【GLSL】『レイマーチング』入門その1 距離関数とレイとカメラの設定
7. 【GLSL】『レイマーチング』入門(2) 立体的に見せる方法〜光の反射は『内積』で〜
8. 【GLSL】『レイマーチング』入門(3) 距離関数を使ってみる・回転・合成・量産
9. 【TouchDesigner】で『GLSL』を使う方法まとめ【画像あり】
10. 【TouchDesigner】『GLSL MAT』の使い方 3次元でぐりぐり動かしてみる
11. 【GLSL】波のつくり方簡易まとめ。波もプログラムでつくれます【コピペスタイル】
アオキのツイッターアカウント。
この記事へのコメントはありません。