#8 空を描く(後編)

もふもふ

index

2020/4/26 作成
2020/4/27 更新


ノイズの種類

「ノイズが〜」と言われたときにあなたは何を思い浮かべますか?
テレビの砂嵐とか周りの環境音とかでしょうか
多くの方が邪魔なものという印象を持っているでしょう
現実世界の中にはノイズが満ち溢れています
先ほど挙げた例も当てはまりますね
ノイズは自然な表現には欠かせません

テンプレじみた話はここまでにして
シェダーでいうノイズはランダム関数に近いものです
完全にランダムだと使いにくいので同じ値を渡すと同じ値が返ってくるノイズ
=ハッシュ関数ですね
マイクラの地形なんかもハッシュですね(同じシード値→同じ地形)

まず砂嵐のノイズを出してみましょう
今回もこちらのコードを借りることにします https://www.shadertoy.com/view/4djSRW
ここでは入力がvec3出力がfloatのものを使っています(z=TIME)
return hash13(vec3(p,TIME));
				
WebGL

このままでは使いづらいのでピクセル化します
p = floor(p*.1)*10.;//floorは切り捨ての関数
return hash13(vec3(p,TIME));
				
WebGL

まだまだ粗いので座標の周囲4点の値を補完して滑らかにします
vec2 fl = floor(p);//切り捨て
vec2 ce = ceil(p);//切り上げ
vec2 fr = smoothstep(0.,1.,fract(p));//小数部分を取る関数+smoothstep
return mix(
	mix(hash13(vec3(fl,TIME)), hash13(vec3(fl.x,ce.y,TIME)),fr.y),
	mix(hash13(vec3(ce.x,fl.y,TIME)), hash13(vec3(ce,TIME)),fr.y),
	fr.x);
				
WebGL

まだブロックっぽいというか雑にぼかした感拭えないので
四点に設定したランダムなベクトルと座標から四点に対するベクトルの内積を使って補完することでさらに滑らかにします
ランダムなベクトルを作るので出力がvec2のハッシュ関数を使います
パーリンノイズという名がついています
長いのでコードは↓から
WebGL

まだ四角いですね
補完する点は4点である必要が無いので3点にします
これにより高速化が図れます
同じくパーリン氏が作ったようです 先人の知恵は偉大ですね…
シンプレックスノイズと呼ばれています
こちらのコードを使っています

WebGL(開いても絶望するだけです)

だいぶ滑らかになりましたねー
ここでは入力がvec3なので全体的に長めですが
今回の雲の描写で使うのは入力がvec2のものなのでもう少し短いです

fbmで雲

ふらくたるぶらうにあんもーしょんの略です
日本語では非整数ブラウン運動らしいです
ざっくり説明すると上で述べたノイズをサイズ変えて重ねたものです

WebGL

このデモでは4枚重ねています
(fbmでvec3入力のノイズ重ねるあほそうそういないと思うんですよ……)
もう既に雲っぽいですね
閾値の調整(smoothstepとmix→#4参照)などして雲にしていきます
雲にvec3入力のノイズを使っても大した効果はないのでvec2入力を使います
雲が流れる様子は p.x+TIMEなどで代用できますし
変形する様子はfbm/time set noon重ね合わせの段階でどうにでもなりますね
こんな感じになりました(飛躍*丸投げ)
WebGL


ノイズ埋め込みまくってたらページが鬼みたいに重くなってしまいました…
申し訳ないです
7つも同時に動かせるってやっぱりgpuすごいですねー(ごめんなさいごめんなさい)
マイクラに移植した今回のサンプルはこちらです
この雲自体にさらに影をつけるなんて演出も可能です
是非考えてみてください
次はちょっと休憩に太陽とか月とか描いていきましょうか…