まずは15作目の完成動画です。
今回は渦巻きの描画方法を学んだので学習記録も兼ねて紹介します。ここからは僕なりの考えですので参考までにどうぞ。
渦巻きを描画するための肝は、
『原点からの距離に角度を足していく』
ということです。
ではコードと画像を見ていきましょう。
void mainImage(out vec4 fragColor, in vec2 fragCoord){<br> vec2 uv = (2.0*fragCoord-iResolution.xy)/iResolution.y;<br><br> vec3 col = vec3(0.5); //基準色をグレーに<br><br> float r = length(uv); //原点からの距離<br><br> col *= r; //距離による色の変化<br><br> fragColor = vec4(col, 1.0);<br>}
ここでは基礎コードと「(原点からの)距離による色の変化」を描画してます。背景色は分かりやすくグレーにしてます。(「vec3 col = vec3(0.5);」のところ)
これを描画したのが右画像です。
距離が遠いほど値が大きくなる、つまり色のRGB値が(0,0,0)→(1,1,1)に近づいていく。なので原点に近いほど黒く、遠いほど白くなっていきます。
ここまでで一旦距離の要素は加わりましたが、この距離に周期性を持たせることで縞模様を生み出します。これで一気に渦巻きに近づきます。
void mainImage(out vec4 fragColor, in vec2 fragCoord){<br> vec2 uv = (2.0*fragCoord-iResolution.xy)/iResolution.y;<br> vec2 m = (2.0*iMouse.xy-iResolution.xy)/iResolution.y;<br><br> vec3 col = vec3(0.5);<br><br> float r = length(uv); //原点からの距離<br><br> col *= sin(r); //距離による色の変化を周期的に<br><br> fragColor = vec4(col, 1.0);<br>}
最初のコードのcol(色のvec3値)に距離をそのまま乗算していたのをsin関数(cosでも可)を与えることで-1〜+1の周期性を距離ごとに獲得します。
これだと右画像のようになりますが、まだ周期性が分かりづらいです。これは-1-1への変化が遅いからです。なので変化を早めるためにrに大きな数値を掛けてみましょう。
10を掛けると。。。
col *= sin(r*10.); //距離による色の変化を周期的に<br>
100を掛けると。。。
col *= sin(r*100.); //距離による色の変化を周期的に<br>
一気に渦巻きに近づきましたね。ここまでは『距離』の情報を色情報に掛け合わせることだけで表現してます。
では渦巻きにするためには後一歩です。ここにさらに『角度』の情報を加えましょう。
角度はアークタンジェント(atan)で取得します。これはラジアンで取得することになることに注意しましょう。2π=360° でしたね。コード例を示します。
float a = atan(uv.y, uv.x); //原点中心とした角度(ラジアン) -πからπ
アークタンジェントとは、三角関数のタンジェント(tan)の逆関数で、要はいつも角度を入れて値を取得していたことの逆をするのです。
図を見ると分かりやすいと思います。
例えば、
π/4 = atan(1,1)
π/6 = atan(1,√3)
ですね。
https://blog-imgs-38.fc2.com/2/0/1/20100718seko/atan_01.jpg
では角度情報を単純に乗算してみましょう。
void mainImage(out vec4 fragColor, in vec2 fragCoord){
vec2 uv = (2.0*fragCoord-iResolution.xy)/iResolution.y;
vec3 col = vec3(0.5);
float r = length(uv); //原点からの距離
float a = atan(uv.y, uv.x); //原点中心とした角度(ラジアン) -πからπ
col *= sin(r * 100.); //距離による色の変化を周期的に
col *= a;
fragColor = vec4(col, 1.0);
}
これは例えば左上はπ/2~π(約1.55~3.14)あたりの角度が掛けられたので、col値は大きくなり、白に近づきます。
一方右側は角度が小さいので、黒に近づきます。
ではこの角度情報を距離に足し合わせるとどうでしょう。まずは画像を見るのが分かりやすいと思います。
void mainImage(out vec4 fragColor, in vec2 fragCoord){
vec2 uv = (2.0*fragCoord-iResolution.xy)/iResolution.y;
vec2 m = (2.0*iMouse.xy-iResolution.xy)/iResolution.y;
vec3 col = vec3(0.5);
float r = length(uv); //原点からの距離
float a = atan(uv.y, uv.x); //原点中心とした角度(ラジアン) -πからπ
// col *= r; //距離による色の変化
col *= sin(r * 100. + a); //距離による色の変化を周期的に + 角度情報を加えて渦巻きに
fragColor = vec4(col, 1.0);
}
どうでしょうか。
紛うことなき渦巻きです。
長さに角度が足されるということは、回転するほど長さが徐々に大きくなるということなので渦巻きになります。
ここまでで一旦本記事の目標とする『GLSLで渦巻を描く』ということは達成しました。
ここからは僕がGLSLにハマっている理由の一端を紹介します。
僕の考えるGLSL(というかコンピューターライティング)の魅力は、
『パラメーターを少しいじるだけで見栄えが想像の100倍変化する!!』
ということです。
今回の渦巻きのコードをいじった実例をお見せします。流し見でいいので少しコードの値をいじるだけでここまで見た目が変わるのかと思ってくれれば嬉しいです。
これをみたら少し僕の気持ちが理解してくれるかと。。。
col *= sin(r * 100. + a); //距離による色の変化を周期的に + 角度情報を加えて渦巻きに
ではこの部分の r と a (距離と角度)の重みを色々いじってみます。
① r:1、a:1
col *= sin(r * 1. + a * 1.); //距離による色の変化を周期的に
② r:100、a:1 (本編の例ですね。)
col *= sin(r * 100. + a * 1.); //距離による色の変化を周期的に
③ r:1000、a:1 (rをめちゃくちゃ大きくすると)
col *= sin(r * 1000. + a * 1.); //距離による色の変化を周期的に
③ r:1、a:10 (次は a の重みを大きくしていきます)
col *= sin(r * 1. + a * 10.); //距離による色の変化を周期的に
③ r:1、a:100
col *= sin(r * 1. + a * 100.); //距離による色の変化を周期的に
③ r:1、a:1000 (aをめちゃくちゃ大きくすると)
col *= sin(r * 1. + a * 1000.); //距離による色の変化を周期的に
こんな感じでどんどん見た目が変わっていきます。
これに色の変化や時間経過に伴う変化を少し加えるだけで、見た目の変化具合は恐ろしく変化していきます。参考例が最初のデモシーン動画です。
では今日はこの辺で。今後も制作を続けていきます。
#デジタルアート #デモシーン #3DCG #シェーダーコーディング #レイマーチング #SF #demoscene
コメント