UV・マテリアル表現

フローマップ

Flow Map

方向を書いた画像に沿って川や溶岩の模様を流す。

4 / 10

インタラクティブデモ

デモを準備しています…

フローマップ

ドラッグで視点を回転、Ctrl(⌘)+ スクロールでズーム。タッチ操作は 2 本指です。

ひとことで

各地点の流れの向きと強さを色(RG チャンネル)で書き込んだ画像(フローマップ)を用意し、それに沿って UV をずらすことで、模様を場所ごとに違う向きへ流す手法です。UV スクロールが「どこでも同じ向き」なのに対し、岩を回り込む川、渦を巻く溶岩、排水口へ吸い込まれる水など、曲がりくねった流れを表現できます。Valve が『Portal 2』や『Left 4 Dead 2』の水で使った手法として知られています。

ゲームでの使いどころ

  • 川・滝つぼ:岩や岸に沿って曲がる水面の模様。
  • 溶岩・毒の沼:地形に沿ってゆっくり流れる、あるいは渦を巻く表面。
  • 雲・星雲・ガス惑星:一方向ではない複雑な流れ。
  • 魔法のエフェクト:中心へ吸い込まれる、または放射状に噴き出すエネルギー。

しくみ

素朴に考えると、UV をフローマップの向き f\mathbf{f} に時間 tt だけずらせばよさそうです。

uv′=uv−f(uv) t\mathbf{uv}' = \mathbf{uv} - \mathbf{f}(\mathbf{uv})\,t

しかし場所ごとにずらす量が違うので、時間が経つほど模様はどんどん引き伸ばされ、ぐちゃぐちゃになります。そこで2 つの位相を半周期ずらして交互に使うのが定番の解決法です。

ϕ0=fract(t),ϕ1=fract(t+0.5)c0=T(uv−f ϕ0 s),c1=T(uv−f ϕ1 s)c=mix(c0,  c1,  ∣2ϕ0−1∣)\begin{aligned} \phi_0 &= \text{fract}(t), & \phi_1 &= \text{fract}(t + 0.5)\\ c_0 &= T(\mathbf{uv} - \mathbf{f}\,\phi_0\,s), & c_1 &= T(\mathbf{uv} - \mathbf{f}\,\phi_1\,s)\\ c &= \text{mix}(c_0,\; c_1,\; |2\phi_0 - 1|) \end{aligned}

各層は 1 周期ぶんだけずらされたところでリセットされますが、リセットの瞬間にはその層の重みが 0 になっているので、切り替わりは見えません。2 つ目の層の UV に少しオフセットを加えておくと、同じ模様が周期的に現れる「脈打ち」を目立たなくできます。

実装のポイント

  • フローマップの作り方:Houdini などで流体シミュレーションの速度を焼き込む、専用のペイントツールで描く、あるいはデモのように数式(岩を回り込むポテンシャル流)から計算する方法があります。
  • テクスチャの形式:向きは線形の値なので、sRGB ではなく線形のテクスチャとして読み込みます。圧縮の誤差で向きがぶれやすいので、BC5 などの 2 チャンネル形式が向いています。
  • 強さで泡を出す:流れの速さ(ベクトルの長さ)を泡や白波の量に使うと、岩の脇の速い流れが自然に白くなります。

つまずきやすい点

  • 周期的な脈打ち:2 層の切り替え周期が一定なので、じっと見ると模様が周期的に「脈打つ」ように見えます。層ごとのオフセットや、位相をノイズで場所ごとにずらす方法で和らげます。
  • 流れの強さとずらし幅:ずらし幅が大きすぎると、1 周期の間に模様が伸びきって見えます。流れが強い場所ほど周期を短くする工夫もあります。
  • 本当の流体ではない:模様を運ぶだけなので、物を浮かべて流す、流れがぶつかって盛り上がるといった表現には、流れ場を CPU でも参照するか(デモの落ち葉)、浅水波などのシミュレーションが必要です。

デモで試すこと

  1. 「一方向の UV スクロール」に切り替えると、水面の模様も落ち葉も岩を突き抜けてまっすぐ流れます。フローマップでは岩を回り込みます。
  2. 「フローマップを表示」をオンにすると、流れの向きを色で書いた画像と、各地点の向きの矢印が見えます。岩の前後で流れが左右に分かれていることを確認してください。
  3. 「流れの速さ」を上げたとき、模様が伸びきらずに流れ続けるのは、2 つの位相を交互に入れ替えているからです。

参考資料

Unreal Engine Material Coordinates ↗

分野全体の資料で、この項目を直接扱っているとは限りません。