読者です 読者をやめる 読者になる 読者になる

VR 研究記

3D技術の経験を活かして、VRに挑戦するおっさんの奮闘記

【Shaderプログラミング】雪を降らせる手法について Part.5

まだまだ、「雪を降らせよう」をテーマに続きますよ。
今回は、『条件』の定義です。

『条件』とは、皆様の頭でも無意識に判断している【基準】のこと。
では、雪が積もる基準をベクトルを使って創造しましょう。

Let's try it.

おさらい

前回は、余弦定理を使ってベクトルの内積を説明しました。
結局、公式は出せたけど、式の意味までは掴めませんでしたねw

【Shaderプログラミング】雪を降らせる手法について Part.4 - VR 研究記


今日は、これまでの基礎を踏まえて、プログラミングの話です。
結局、プログラミングとは、言語は『道具』、ロジックは『数学・物理』って組み合わせなんです。

最初の考察に戻りましょう。

物理学および数学を利用した雪の考察

改めて、メッシュ表面の法線ベクトル、重力ベクトル、風力ベクトルを加味した画像を確認しながら考察してみましょう。
「風を考慮しない(無風)の場合」と「風を考慮する(有風な場合)」に分けて考察します。

無風な場合:

まずは、簡単な風を考慮しない場合の物理的イメージから思い出しましょうか。
紫が重力ベクトル (9.8m/s^2 ・・・ 実際はコレ嘘なんですよ、場所によります。)と覚えましたねw
※実は、重力は赤道付近に行けば軽くなります。(体感的に軽いなって思えるほどではないですよ。)
緑が、法線ベクトルです。

f:id:subrutm:20170212021550p:plain

雪が積もりやすいのは、重力ベクトルと面の法線ベクトルの向きが同じまたは真逆になる時ですね。
 \theta = 0 or 180の時、もっとも安定していると言えます。

では、ベクトルを使って \thetaを算出する道具は何だったでしょうか?

内積ですね。

②が一番積もりやすいので、この内積考えて見ましょう。
法線(Normal)ベクトル N(n_1, n_2), 重力(Gravity)ベクトル G(g_1, g_2)とする。

f:id:subrutm:20170422123807p:plain
Figure1. Normalize vector and Gravity vector, no wind vector

 n_1g_1 + n_2g_2 = |N||G| \cos \thetaから
 \cos \theta = {\frac{n_1g_1 + n_2g_2}{|N||G|}}となる。

 |N| = \sqrt{n_1^2 + n_2^2}
 |G| = \sqrt{g_1^2 + g_2^2} なので、

 \cos \theta = {\frac{n_1g_1 + n_2g_2}{\sqrt{n_1^2 + n_2^2}\sqrt{g_1^2 + g_2^2}}}となる。

図のイメージから、 \thetaが小さいほど積もりやすいので、

微分を使います。 (突然、微分出しちゃってごめんなさい。)
 \displaystyle \lim_{ \theta \to 0 } \cos \theta = 1.0より

条件は、 \cos \theta = {\frac{n_1g_1 + n_2g_2}{\sqrt{n_1^2 + n_2^2}\sqrt{g_1^2 + g_2^2}}} ≒ 1.0
この、『1.0』を【閾値】と言います。 (生物学的にもコンピュータアーキテクチャ的にも関係あり)
この閾値が、《条件》になるわけです。

補足: 正規化について
 \cos \thetaの範囲は、 0≦\cos \theta≦1.0なのですが、物理的な力は『1.0』に納まることはマレであるから、1.0を最大値とした値に変換する処理を良く行われます。
この処理のことを通常【正規化】と言っています。

有風な場合:

次に、風を考慮した場合の物理的イメージを書いてみましょう。
紫が重力ベクトル、緑が法線ベクトル、そしてオレンジが今回追加された風ベクトルです。

f:id:subrutm:20170318165939p:plain

AIにも『強いAI』と『弱いAI』があるように、風にも『強い風』と『弱い風』があります。
強い時と弱い時で図にして、どのようなベクトルになるか確認しましょう。
まずは、無風の場合と同じように②の面を使って、『弱い風』の《弱い風の場合》から見ていきます。

法線(Normal)ベクトル N(n_1, n_2), 重力(Gravity)ベクトル G(g_1, g_2), 風力(Wind)ベクトルを W(w_1, w_2)とする。

■弱い風の場合
弱い風の場合では、Figure2のようになります。

f:id:subrutm:20170422145300p:plain
Figure2. Case of weak wind


■強い風の場合
強い風の場合では、Figure3のようになります。

f:id:subrutm:20170422150149p:plain
Figure3. Case of strong wind


雪自体には、質量の重さが比較的軽いため、シミュレーションとして表現する訳ではないため、考慮しないものとすると、条件は下記の通りとなります。
条件:  \cos \theta = {\frac{n_1w_1 + n_2w_2}{\sqrt{n_1^2 + n_2^2}\sqrt{w_1^2 + w_2^2}}} ≒ 1.0

やはり、こちらの場合でも \thetaが小さい程、積もりやすい傾向があると考えられる。
また、風が無い場合は、風ベクトルが0であるが、重力ベクトルと同じ力が働いているとみなせば、アルゴリズムを汎化出来るのではないかと結論出来そうですね。

まとめ

結論としては、条件は『風ベクトル』と『法線ベクトル』の内積の値に閾値を設定することで、ある程度それっぽく見せられそうだという結論に達しました。
『風ベクトル』がゼロの場合は、『重力ベクトル』を利用する。
※実際は、レイベクトルを風ベクトルの逆向きに飛ばして、面との衝突判定をするべきです。
そうすることで、実際には影になって雪がのらないケースの判定に利用出来からです。 (今回はやらない)

現実に近づける程に物理的な考慮が必要になるので、膨大な計算になることが理解出来れば十分です。

では、今回の考察で得た結果から、プログラミンを組んでいきましょう。
いよいよ、シェーダプログラミングの集大成になります。
乞うご期待ください。

シリーズ一覧:
【Shaderプログラミング】雪を降らせる手法について Part.1 - VR 研究記
【Shaderプログラミング】雪を降らせる手法について Part.2 - VR 研究記
【Shaderプログラミング】雪を降らせる手法について Part.3 - VR 研究記
【Shaderプログラミング】雪を降らせる手法について Part.4 - VR 研究記