UE4で学ぶ水中表現
Epic Games Japan / Technical Artist
小林 浩之
#UE4 | @UNREALENGINE
自己紹介
小林 浩之
普段はUDNでの解答など、
UE4のサポート業務を中心にやってます
前職はAAAタイトルのTA
Twitter / はのば@hannover_bloss
#UE4 | @UNREALENGINE
勉強会用に
作ってきました
#UE4 | @UNREALENGINE
セノーテ
鍾乳洞の天井が崩落して
できた穴に溜まった泉
ユカタン半島に点在
#UE4 | @UNREALENGINE
目指した絵作り
● 水上、水中両方からみても破綻しない
● リアルな水中表現
#UE4 | @UNREALENGINE
目指した絵作り
● 水上、水中両方からみても破綻しない
● リアルな水中表現
#UE4 | @UNREALENGINE
水上、水中両方からみても破綻しない
カメラが半分水没した状態を再現
#UE4 | @UNREALENGINE
水面のメッシュ構成
カメラと向かい合う面を作って疑似的に水没状態を再現
#UE4 | @UNREALENGINE
水面のメッシュ構成
メッシュA
断面用
#UE4 | @UNREALENGINE
水面のメッシュ構成
メッシュB
水面(表)用
#UE4 | @UNREALENGINE
水面のメッシュ構成
メッシュC
水面(裏)用
#UE4 | @UNREALENGINE
水面のメッシュ構成
メッシュD
境界用
#UE4 | @UNREALENGINE
水面のメッシュ構成
半透明ソート順(描画する順番)をきっちり決めたかったため
4つのメッシュ構成に
#UE4 | @UNREALENGINE
水マテリアル解説
#UE4 | @UNREALENGINE
水面マテリアル(表)
#UE4 | @UNREALENGINE
水面マテリアル(表)
#UE4 | @UNREALENGINE
水面マテリアル(表)
Screen UV歪ませる
Scene Colorと深度、フレネル
#UE4 | @UNREALENGINE
水面マテリアル(表)
#UE4 | @UNREALENGINE
水面マテリアル(表)
OpacityやRefractionは使わず、
Scene ColorをEmissiveに刺すことで半透明を表現
水面の動き(波)はHoudiniで連番テクスチャ作成
ノーマルやWorld Displacementに
#UE4 | @UNREALENGINE
水面の動き
HoudiniのOceanからオフセットとノーマルを連番書き出し
#UE4 | @UNREALENGINE
水面の動き
HoudiniのOceanからオフセットとノーマルを連番書き出し
UVはワールド座標
#UE4 | @UNREALENGINE
水面マテリアル(表)
Screen UV歪ませる
Scene Colorと深度、フレネル
#UE4 | @UNREALENGINE
水面マテリアル(表)
Screen UV歪ませる
#UE4 | @UNREALENGINE
水面マテリアル(表)
Screen UVにPixel Normalを足しているだけ
物理的に正しいものではないので注意
#UE4 | @UNREALENGINE
水面マテリアル(表)
Scene Colorと深度、フレネル
#UE4 | @UNREALENGINE
水面マテリアル(表)
歪めたScreen UVをScene Colorへ
深度によって色を付ける
#UE4 | @UNREALENGINE
水面マテリアル(裏)
#UE4 | @UNREALENGINE
水面マテリアル(裏)
#UE4 | @UNREALENGINE
水面マテリアル(裏)
Screen UV歪ませる
Scene Color
全反射表現(後ほど解説)
#UE4 | @UNREALENGINE
水面マテリアル(裏)
Screen UV歪ませる
Scene Color
#UE4 | @UNREALENGINE
水面マテリアル(裏)
全反射表現(後ほど解説)
#UE4 | @UNREALENGINE
断面マテリアル
#UE4 | @UNREALENGINE
断面マテリアル
マテリアルはシンプルに透過させているだけ
Custom Depthに描画して水面以下判定に使う
#UE4 | @UNREALENGINE
境界マテリアル
#UE4 | @UNREALENGINE
境界マテリアル
#UE4 | @UNREALENGINE
境界マテリアル
境界のグラデーション
Scene Color
#UE4 | @UNREALENGINE
境界マテリアル
境界のグラデーション
#UE4 | @UNREALENGINE
境界マテリアル
矩形に開いたUVからグラデーションを作る
テクスチャでもよさそう
#UE4 | @UNREALENGINE
境界マテリアル
矩形に開いたUVから計算
テクスチャでもよさそう
#UE4 | @UNREALENGINE
境界マテリアル
Scene Color
#UE4 | @UNREALENGINE
境界マテリアル
境界部分のグラデーションを使って、
Scene Colorを適当に歪める
#UE4 | @UNREALENGINE
目指した絵作り
● 水上、水中両方からみても破綻しない
● リアルな水中表現
#UE4 | @UNREALENGINE
目指した絵作り
● 水上、水中両方からみても破綻しない
● リアルな水中表現
#UE4 | @UNREALENGINE
どんな水中表現を使ったか
#UE4 | @UNREALENGINE
何もない状態から要素を足していきます
#UE4 | @UNREALENGINE
水面の反射と屈折
#UE4 | @UNREALENGINE
コースティクス
#UE4 | @UNREALENGINE
色の減衰
#UE4 | @UNREALENGINE
ゴッドレイ
#UE4 | @UNREALENGINE
Before After
#UE4 | @UNREALENGINE
水中の構成要素
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
#UE4 | @UNREALENGINE
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
水中の構成要素
#UE4 | @UNREALENGINE
水面の反射と屈折
#UE4 | @UNREALENGINE
水面の反射と屈折
水中だと水面が鏡のようになるのはなぜ?
#UE4 | @UNREALENGINE
中学物理の授業思い出してみましょう
#UE4 | @UNREALENGINE
入射角、反射角、屈折角について
#UE4 | @UNREALENGINE
簡単に図で説明します
#UE4 | @UNREALENGINE
空気
水
#UE4 | @UNREALENGINE
光
光が差し込んできたとき…
#UE4 | @UNREALENGINE
光が当たった地点から
面に対して垂直な線を引く
光
#UE4 | @UNREALENGINE
入射角
垂直線との間の角
#UE4 | @UNREALENGINE
反射角
一部の光が反射して
入射角の反対側に飛ぶ
角度は入射角と等しい
#UE4 | @UNREALENGINE
屈折角
反射しなかった光は
屈折して水の中へ
空気から水の場合
屈折角は入射角よりも
小さくなる
#UE4 | @UNREALENGINE
空気から水に向かって
光が向かった場合の図
空気
水
#UE4 | @UNREALENGINE
水中から空気へ向かった場合
#UE4 | @UNREALENGINE
#UE4 | @UNREALENGINE
入射角
垂直線との間の角
#UE4 | @UNREALENGINE
反射角
一部の光が反射して
入射角の反対側に飛ぶ
角度は入射角と等しい
#UE4 | @UNREALENGINE
屈折角
水から空気の場合
屈折角は入射角より大きくなる
#UE4 | @UNREALENGINE
臨界角
90°
ある入射角で屈折角が90度になる
さらに入射角を大きくすると…
#UE4 | @UNREALENGINE
全反射
入射角が臨界角を超えると
すべての光を反射する
#UE4 | @UNREALENGINE
UE4で全反射を再現
#UE4 | @UNREALENGINE
Planar Reflection
なるべく綺麗な反射が欲しかったのでPlanarを使用
反射が下向きなのでPlanarも180度ひっくり返す
#UE4 | @UNREALENGINE
Planar Reflection
反射は綺麗だけど、臨界角の境目を作っていないので向こう側が見えない
#UE4 | @UNREALENGINE
マテリアルで臨界角を求める
#UE4 | @UNREALENGINE
約48.6度
水→空気の臨界角
48.6°
#UE4 | @UNREALENGINE
入射角を調べる
48.6°
#UE4 | @UNREALENGINE
水面からの垂直線
Pixel Normalに置き換え
Pixel
Normal
#UE4 | @UNREALENGINE
光のベクトル
Camera Vectorに置き換え
Camera
Vector
#UE4 | @UNREALENGINE
2ベクトルのなす角が48.6度
以上かどうかを求める
#UE4 | @UNREALENGINE
水面マテリアル(裏)
#UE4 | @UNREALENGINE
臨界角マスク
水面マテリアル(裏)
#UE4 | @UNREALENGINE
水面マテリアル(裏)
内積(Dot Product)で
2ベクトルのなす角を求める
#UE4 | @UNREALENGINE
臨界角マスク
水面マテリアル(裏)
臨界角48.6度のマスクができる
#UE4 | @UNREALENGINE
水面マテリアル(裏)
Scene Colorに乗算
透けないように
臨界角マスク
#UE4 | @UNREALENGINE
水面マテリアル(裏)
鏡面に切り替え
臨界角マスク
#UE4 | @UNREALENGINE
#UE4 | @UNREALENGINE
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
水中の構成要素
#UE4 | @UNREALENGINE
水中の構成要素
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
#UE4 | @UNREALENGINE
コースティクス
反射や屈折の影響で光が収束してできる模様
川や海などの底でよく観察できる
#UE4 | @UNREALENGINE
どうやってこの模様ができているんでしょうか?
#UE4 | @UNREALENGINE
先ほどの図に戻ります
#UE4 | @UNREALENGINE
#UE4 | @UNREALENGINE
水面が波打っているとどうなるか
#UE4 | @UNREALENGINE
空気
水
底
#UE4 | @UNREALENGINE
光が水面を通って・・・
#UE4 | @UNREALENGINE
屈折して・・・
#UE4 | @UNREALENGINE
底に当たる
#UE4 | @UNREALENGINE
光が集中した場所は
当然明るくなる
#UE4 | @UNREALENGINE
明るい
#UE4 | @UNREALENGINE
明るい
暗い
#UE4 | @UNREALENGINE
明るい
#UE4 | @UNREALENGINE
明るい
暗い
#UE4 | @UNREALENGINE
どうやって表現するか
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
先ほどの図を3次元で
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
Ocean Simurationで適当に波を作る
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
平面グリッドを用意
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
平面にノーマル転送
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
屈折ベクトルを計算
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
屈折ベクトルへ頂点を移動
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
重なり具合を頂点カラーに転送
#UE4 | @UNREALENGINE
Houdiniで屈折の計算&連番テクスチャ作成
連番テクスチャとしてレンダリング
#UE4 | @UNREALENGINE
UE4でセットアップ
#UE4 | @UNREALENGINE
Light Function
マテリアルで連番テクスチャ再生
Directional Lightに適用
#UE4 | @UNREALENGINE
Light Function
Houdiniで作った連番テクスチャをFlip Bookノードでアニメーション
#UE4 | @UNREALENGINE
Light Function
Houdiniで作った連番テクスチャをFlip Bookノードでアニメーション
#UE4 | @UNREALENGINE
Light Function Off
#UE4 | @UNREALENGINE
Light Function On
#UE4 | @UNREALENGINE
水中の構成要素
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
#UE4 | @UNREALENGINE
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
水中の構成要素
#UE4 | @UNREALENGINE
水は赤い光を吸収する
光が水の中を進むほど赤い光が吸収され、結果的に青が残る
コップの水や浅瀬では吸収量が少ないため無色透明に見える
#UE4 | @UNREALENGINE
ポストプロセスマテリアルで再現
#UE4 | @UNREALENGINE
ポストプロセスマテリアル
#UE4 | @UNREALENGINE
ポストプロセスマテリアル
深度
Custom Depthで
水面以下かどうか判定
深度を元に
Scene Colorへ色を乗算
#UE4 | @UNREALENGINE
ポストプロセスマテリアル
深度
#UE4 | @UNREALENGINE
カメラからの距離
#UE4 | @UNREALENGINE
水面からの距離
#UE4 | @UNREALENGINE
ポストプロセスマテリアル
深度を元に
Scene Colorへ色を乗算
#UE4 | @UNREALENGINE
Scene Colorへ色を乗算
#UE4 | @UNREALENGINE
ポストプロセスマテリアル
Custom Depthで
水面以下かどうか判定
#UE4 | @UNREALENGINE
Custom Depthで水面以下判定
断面メッシュをCustom Depthに描画して・・・
#UE4 | @UNREALENGINE
Custom Depthで水面以下判定
水面以下のマスクを作る
#UE4 | @UNREALENGINE
Custom Depthで水面以下判定
水面以下にだけ色を付ける
#UE4 | @UNREALENGINE
ポストプロセスマテリアル Off
#UE4 | @UNREALENGINE
ポストプロセスマテリアル On
#UE4 | @UNREALENGINE
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
水中の構成要素
#UE4 | @UNREALENGINE
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
水中の構成要素
#UE4 | @UNREALENGINE
水中でのゴッドレイ
水中の浮遊物や泡、微生物などに光が当たって筋に見える
#UE4 | @UNREALENGINE
Volumetric Fog
#UE4 | @UNREALENGINE
Volumetric Fog
普通に置いただけだと全体的にフォグがかかる
#UE4 | @UNREALENGINE
Volumetric Fog
水上と水中でフォグの濃度を変えたい
濃い
薄い
#UE4 | @UNREALENGINE
Volume Material
Particleに対して適用可能
Volumetric Fogの濃度や色をMaterialから制御できる
#UE4 | @UNREALENGINE
Volume Material
#UE4 | @UNREALENGINE
Volume Material
Volume範囲と濃度
#UE4 | @UNREALENGINE
Volume Material
水面以下かどうか
#UE4 | @UNREALENGINE
Volume Material
色
#UE4 | @UNREALENGINE
Niagara Particle
#UE4 | @UNREALENGINE
Niagara Particle
Particle SpawnにParticles.SpriteSizeを追加
フォグを調整したい範囲の大きさを数値入力
#UE4 | @UNREALENGINE
Niagara Particle
RenderからVolume Materialアサイン
#UE4 | @UNREALENGINE
Volumetric Fog Off
#UE4 | @UNREALENGINE
Volumetric Fog On
#UE4 | @UNREALENGINE
まとめ
● 水中表現に必要な要素
#UE4 | @UNREALENGINE
まとめ
● 水中表現に必要な要素
● 水面の反射と屈折
#UE4 | @UNREALENGINE
まとめ
● 水中表現に必要な要素
● 水面の反射と屈折
● コースティクス
#UE4 | @UNREALENGINE
まとめ
● 水中表現に必要な要素
● 水面の反射と屈折
● コースティクス
● 色の減衰
#UE4 | @UNREALENGINE
まとめ
● 水中表現に必要な要素
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
#UE4 | @UNREALENGINE
まとめ
● 水中表現に必要な要素
● 水面の反射と屈折
● コースティクス
● 色の減衰
● ゴッドレイ
これらを理解して表現できれば、リアルな水中が作れる!!
#UE4 | @UNREALENGINE
その他
● 背景アセット
● ライティング
#UE4 | @UNREALENGINE
背景アセット
Megascansライブラリ
#UE4 | @UNREALENGINE
背景アセット
Megascansライブラリ
#UE4 | @UNREALENGINE
濡れマテリアル
#UE4 | @UNREALENGINE
濡れマテリアル
Roughness
水面以下はそのまま
水面以上は0~徐々に元のRoughnessへ
#UE4 | @UNREALENGINE
濡れマテリアル
#UE4 | @UNREALENGINE
濡れマテリアル
水面位置を取得
#UE4 | @UNREALENGINE
濡れマテリアル
水面位置からのグラデーション
#UE4 | @UNREALENGINE
濡れマテリアル
Roughnessテクスチャに乗算
#UE4 | @UNREALENGINE
濡れマテリアル Off
#UE4 | @UNREALENGINE
濡れマテリアル On
#UE4 | @UNREALENGINE
Megascansを使ってよかったこと
モチーフにしたセノーテがそもそもパーツが少ない(岩や枝ばかり)ので
Megascansライブラリが非常に役立った
背景アセットの製作コストを抑えて、メインの水中表現に注力ことができた
#UE4 | @UNREALENGINE
ライティング
ライトは Directional と Sky のみ
#UE4 | @UNREALENGINE
ライティング
Directional Lightの影
Cascade Shadow Area Shadow
#UE4 | @UNREALENGINE
ライティング
Directional Lightの影
Cascade Shadow Area Shadow
#UE4 | @UNREALENGINE
ライティング
Sun Position Calculator
#UE4 | @UNREALENGINE
ライティング
緯度経度、タイムゾーン
日にちと時間を入れると
その場所と時間の太陽の位置を計算する
Sun Position Calculator
#UE4 | @UNREALENGINE
ライティング
Sun Position Calculator レベルに置く
#UE4 | @UNREALENGINE
ライティング
Google Mapから緯度経度を取得
緯度 経度
Sun Position Calculator
#UE4 | @UNREALENGINE
ライティング
Sun Position Calculator
#UE4 | @UNREALENGINE
ライティング
有名なセノーテの緯度経度を取得
緯度 経度
Sun Position Calculator
#UE4 | @UNREALENGINE
ライティング
Sun Position Calculator
#UE4 | @UNREALENGINE
ライティング
Light Map解像度の調整
Light Map密度調整で
トライ&エラーが続き大変だった
#UE4 | @UNREALENGINE
ライティング
Light Map解像度の調整
アクタ選択して・・・
#UE4 | @UNREALENGINE
ライティング
Light Map解像度の調整
アクタ選択して・・・
アセット開いて・・・
#UE4 | @UNREALENGINE
ライティング
Light Map解像度の調整
アクタ選択して・・・
アセット開いて・・・
解像度変えて・・・
#UE4 | @UNREALENGINE
ライティング
Light Map解像度の調整
アクタ選択して・・・
アセット開いて・・・
解像度変えて・・・
これをアセット数分繰り返す
#UE4 | @UNREALENGINE
ライティング
Light Map解像度の調整
アクタ選択して・・・
アセット開いて・・・
解像度変えて・・・
これをアセット数分繰り返す
めんどくさい・・・
#UE4 | @UNREALENGINE
ライティング
Light Map解像度の調整
Pythonで半自動化
#UE4 | @UNREALENGINE
ライティング
Light Map解像度の調整
#UE4 | @UNREALENGINE
ご清聴ありがとうございました

UE4で学ぶ水中表現(UE4 Environment Art Dive)