tanaka's Programming Memo

プログラミングについてのメモ。

Definitive Stylized Waterで海る

f:id:am1tanaka:20190731111605p:plain
Definitive Stylized Waterで海る

夏といえば海!ということで、少し古いモバイル端末でも動作する水面を描いてくれるアセットDefinitive Stylized Waterの記事です。

Definitive Stylized Water - Asset Store

この記事は、Unity アセット真夏のアドベントカレンダー 2019 Summer!の4日目の記事です。

目次

アセットの概要

Definitive Stylized Waterはトゥーン調の水面を描画することができるアセットです。VoxelorerBirdのマップ画面の水面を描画したくて購入しました。水深に応じて色を変化させたり、水面の波紋を描いたりしてくれます。

f:id:am1tanaka:20190731111513g:plain
水面が動きます

UnityAssetStoreJapanさんの紹介ツイート。

この手のものだとStylized Water Shaderの方が実績があるような印象がありましたが、OpenGL ES2に対応しているのでこちらの方を選びました。うちにあったかなり古いAndroid4.2.2のSH-08Eでも動きましたし、速度も綺麗さもいい感じでお気に入りのアセットです^^

設定の仕方や問題の解決策、設定の概要などをご紹介します。

動作条件

  • AssetStoreの記載ではUnity5.4.5以降対応。Unity 2017 & 2018も動作確認済みとなっています
    • Unity2019.1.12でも動作しました
  • モバイル版は、OpenGL ES2以降に対応です
  • カメラのProjection設定がOrthographicだと動作しません

標準版とモバイル版

フル機能の標準版に加えて、機能制限をして機能が弱いモバイル端末でも動作するモバイル版が同梱されています。設定項目の違いは以下のような感じです。

f:id:am1tanaka:20190731121424p:plain
モバイル版と標準版の設定項目

御覧の通り、右の標準版の方が設定は豊富です。主な違いは以下の通りです。

  • 水面下のオブジェクトが揺らいで見えるかの有無(Opacity)
  • 水面の波による変形の有無(WAVES)
  • 鏡面反射(REFLECTIONS)の有無

標準版がDeferredレンダリングで、モバイル版がForwardレンダリングです。Deferredレンダリングに対応しているモバイル端末であれば標準版も動作します。両方組み込んでおいて、実行時に機能を確認してどちらを使うかを選択するのもありかなと考えています。

iPhoneSEでもアセット付属の標準版サンプルが60fpsで動きましたので、iOS向けなら標準版で問題なさそうです。モバイル版はちょっと弱いAndroid用という感じです。

水面を作る

自分のプロジェクトにDefinitive Stylized Waterをインポートして、水面を表示します。このブログの操作はUnity2019.1.12で行っています。別のバージョンの場合は操作位置が異なる場合があります。

  • 対応するバージョンのUnityで、水面を表示したいプロジェクトを新規に作成するか読み込みます
  • Asset StoreでDefinitive Stylized Waterを購入、ダウンロードしてインポートします

Definitive Stylized Water - Asset Store

  • カメラのProjection設定はPerspectiveにしてください。Orthographic(平行投影モード。遠近感がなくなる主に2D用の設定)には非対応です
    • Orthographicを利用していた場合は、Perspectiveに変更して視野角を小さくして対応するとよいでしょう

f:id:am1tanaka:20190731230549p:plain
ProjectionはPerspectiveに

  • 必要に応じて地形を配置します。以下の例では、Definitive Stylized Waterに付属の灯台のモデル(Lighthouseプレハブ)を座標0, 0, 0の位置に配置しました

f:id:am1tanaka:20190719153423p:plain
海底を配置

  • 水面プレハブをシーンに配置します。標準版はStylizedWaterShaderフォルダーの直下にあるWaterPlaneです。モバイル版はStylizedWaterShader > MobileVersionフォルダー内のMobileWaterPlaneです。どちらか利用したい方をHierarchyウィンドウかSceneウィンドウにドラッグ&ドロップします

f:id:am1tanaka:20190731230912p:plain
水面プレハブの場所

f:id:am1tanaka:20190719153924p:plain
Mobile版の水面を設定

水面が真っ白になった時の対処

この段階で、水面が真っ白になる可能性があります。

f:id:am1tanaka:20190801191259p:plain
水面が真っ白

考えられる原因はすでに述べていますが、以下の二つです。

  • CameraRendering Pathが、水面シェーダーと合っていない
  • CameraProjectionが、Orthographicになっている

Sceneウィンドウでは、Isoモードでも白くなります。

標準版での水面が真っ白になった時の対処

標準版は、Rendering PathDeferredである必要があります。手っ取り早いのはカメラで設定することです。

  • Main Cameraを選択して、Inspectorウィンドウで以下を確認して、必要なら設定します
    • ProjectionPerspective
    • Rendering PathDeferred

f:id:am1tanaka:20190801194800p:plain
標準版のCameraの設定

まだ白いかも知れませんが、構わずPlayしてみてください。

f:id:am1tanaka:20190801194922p:plain
標準版の水面

以上で設定完了です。

モバイル版での水面が真っ白になった時の対処

モバイル版は、Rendering PathForwardである必要があります。カメラにアタッチするためのスクリプトがあるのでひと手間増えます。

  • Main Cameraを選択して、Inspectorウィンドウで以下を確認して、必要なら設定します
    • ProjectionPerspective
    • Rendering PathForward

f:id:am1tanaka:20190801195123p:plain
モバイル版のカメラの設定

  • StylizedWaterShaderフォルダーの中のCodeフォルダーに入っているEnableCameraDepthInForwardスクリプトを、カメラにドラッグ&ドロップしてアタッチします

f:id:am1tanaka:20190801195406p:plain
カメラにスクリプトをアタッチ

まだ白いかも知れませんが、構わずPlayしてみてください。

f:id:am1tanaka:20190801195450p:plain
モバイル版の水面

以上で設定完了です。

Sceneウィンドウの水面が白い

Sceneウィンドウの水面が白いままだった場合、Isoモードになっているものと思われます。右上のGizmoIsoになっていると思いますので、クリックしてPerspに変更してください。

f:id:am1tanaka:20190801194420p:plain
SceneウィンドウのカメラがIsoモードになっていても白くなる

以上で設定完了ですが、水面は白いままの場合があります。設定したらとりあえずPlayしてみてください。設定ができていればPlayすれば正しく描画されます。

水面の位置はPosition、水面の大きさはScaleで調整すればOKです。

モバイル版の設定

モバイル版の設定概要です。標準版の設定概要はこちら

水面の設定はマテリアルで調整できます。MobileWaterPlaneオブジェクトのMesh Rendererに設定されているマテリアルがそうです。

f:id:am1tanaka:20190801200442p:plain
水面用マテリアル

モバイル版と標準版の水面シェーダーが設定されているマテリアルは以下の位置にあります。必要に応じて複製して、水面にアタッチして利用するとよいでしょう。

f:id:am1tanaka:20190801200343p:plain
水面の設定をするためのマテリアル

Color0, 1, 2

Color0, 1, 2は、水深ごとの色味です。以下はColor0の変更例で、水深0の部分の色です。

f:id:am1tanaka:20190801201751g:plain
Color0, 1, 2

Color1Gradient1の水深の色、Color2Gradient2より深いところの色です。

Gradient1, 2

Color0, 1, 2と組み合わせて使う設定です。変更に応じて色が適用される深さが変わっています。マイナスになると無効になります。

f:id:am1tanaka:20190801202446g:plain
Gradient

FresnelColor

Fresnelと書いてフレネルです。理科で習ったのではないかと思いますが(カリキュラム的に習わないコースもあるかもですが)、定義はwikiより以下の通りです。

屈折率が異なる物質間の界面に入射すると、一部は反射し、一部は透過(屈折)する。このふるまいを記述するのがフレネルの式である。 フレネルの式 - Wikipedia

といいつつ、このアセットではカメラから遠い水面の色を変化させる設定になっています。フォグの水面版といった感じです。

f:id:am1tanaka:20190801203800g:plain
Fresnel

Color2だと深い部分全体の色が設定されますが、Fresnelの方は遠方の水面の色が変わっているのが観察できると思います。

FresnelExp

フレネルの距離です。値を小さくすればより近くからフレネルの色が適用され始めます。負の値が設定できますが、色味が明らかにおかしくなります^^;

f:id:am1tanaka:20190801204211g:plain
FresnelExp

Foam

フォーム=泡の設定です。水面や浅いところの白い筋の模様の設定です。MainとSecondaryの2種類を設定することで、立体感のある揺らぎが演出されます。以下、MainFoamの設定です。

f:id:am1tanaka:20190801212349g:plain
MainFoam

SecondaryFoamも基本的に同様です。

Textureは水面を表現するための画像データと思われます。ここをいじる必要はありません。

モバイル版の設定は以上です。

標準版の設定

標準版についてはオフィシャルの動画が分かりやすいです。

youtu.be

設定の概要は以下の通りです。

COLOR GRADIENT

水深に応じた色や、水面の設定を行う項目です。後ろに(*)が書いてある項目は、モバイル版にはない機能です。

  • COLOR GRADIENT 色の勾配
    • 左の3つの色がモバイル版のColor0, 1, 2、右の2つのスライドバーがGradientに該当します
  • Fresnel フレネル
    • 左の色がFresnelColor、右のスライドバーがFresnelExpに該当します
  • Light Color Intensity(*) ライトの色の強度
    • 水の色が、シーンのライトの色の影響を受ける度合いです。0にするとDirectional Lightの色や角度による光の具合の影響を受けなくなります
  • Specular Intensity(*) 反射光の強度
    • 太陽などの光の反射の強さです。0にすると光の反射がなくなり、1にすると強く反射します(Directional Lightが水面に反射して、カメラにうつる位置にないと影響が分からない可能性があります)
  • Roughness(*) 粗さ
    • 光の反射の拡散度合いです。Roughness0だとDirectional Lightの位置による太陽がはっきりと描画されます。1にするとぼんやりと拡散します
  • Water Opacity(*) 水の不透明度
    • この下のOpacity Depthとセットで利用して、水中のものが屈折して見える度合いと深さを設定します
    • 1にすると、Opacity Depthの値に関わらず、水中の屈折が見えなくなります
    • 0にすると、Opacity Depthで設定されている深さまで、水中の屈折が見えるようになります
  • Opacity Depth(*) 透明度の深さ
    • この値の深さまで、水中のものが歪んで描画されます

FOAM 泡

モバイルの設定とほぼ同じです。SpeedIntensityなど、微調整用のパラメーターが増えています。

Always Visibleにチェックを入れると、Intensityの設定に関わらず、水面に縞模様を描画します。トゥーン感を出す場合に有効そうです。

f:id:am1tanaka:20190531201520p:plain
Secondary FoamのAlways Visible

WAVES(*) 波

モバイル版にない設定です。水面に波を発生させます。

  • Amplitude 振幅
    • 波の幅です
  • Speed
    • 波が進む速度です
  • Intensity
    • 波の高さです
  • Direction
    • 波の方向です
  • Vertex Offset
    • チェックを入れると、実際に水面の高さが変化して波打つようになります
    • チェックを外すと、水面の高さは変わらず、光や屈折の描画の変化のみで波を表します

REFLECTIONS(*) 反射

モバイル版にはない設定です。空や水上のオブジェクトを水面に映すかを設定できます。

  • Real time reflections
    • チェックを外すと、水面に水上のオブジェクトが映らなくなります
  • Intensity
    • 映り込みの度合いです
    • 0だと無効になります
  • Wave Distortion 波によるねじれ
    • Waveの動きでどれぐらい映り込みの像をゆがめるかの設定
    • WaveIntensityと関連するようです。1にすると自然に動く感じがします
  • Turbulence Distortion 乱流によるねじれ
    • 波より細かい水面の凹凸を描画する強さを設定します。大きい値にすると映り込みが強くなります
  • Turbulence Scale 乱流のスケール
    • 水面の凹凸のスケールです。値を大きくすると、凹凸が細かくなります

TEXTURES

水面の動きや泡のテクスチャーです。泡のテクスチャーを自前で用意して差し替えると、水面の模様が変えられます。

水面のエフェクト

VFXフォルダーにいくつかエフェクトが入っています。これも何気に便利です。

FoamParticles

泡立っている感じのエフェクトです。

f:id:am1tanaka:20190801224546g:plain
FoamParticles

FoamUp

水しぶきのエフェクトです。

f:id:am1tanaka:20190801224821g:plain
FoamUp

RadialSplash

放射状に広がる波紋です。

f:id:am1tanaka:20190801225130g:plain
RadialSplash

SmallSplash

小さいものが落ちた時のようなしぶきと波紋です。

f:id:am1tanaka:20190801225340g:plain
SmallSplash

WaterSplash

しぶきと波紋が一緒に出現するエフェクトです。

f:id:am1tanaka:20190801225605g:plain
WaterSplash

川などを作る

付属の水面プレハブは平面ですが、ProBuilderなどで川となるメッシュを作成して水面マテリアルなどをアタッチすれば、傾斜のある水面を作ることができます。

f:id:am1tanaka:20190801230534p:plain
川用のメッシュ

背景に乗せるとこんな感じになります。

f:id:am1tanaka:20190801230755p:plain

モバイル版の場合はStylizedWaterMobileマテリアルを設定するだけでOKです。標準版を使う場合は、StylizedWaterマテリアルをアタッチした上で、Codeフォルダー内のWaterReflectionスクリプトをアタッチして鏡面反射に対応させます。

f:id:am1tanaka:20190801230923p:plain
WaterReflection

※水が流れ落ちているエフェクトは、Unity公式のUnity Particle Pack - Asset Storeのものを利用しています。

まとめ

Definitive Stylized Waterの設置方法や設定、付属のエフェクト、平面以外のメッシュを水面にする方法をご紹介しました。トゥーン系のポップな水面を作るのに適していて、少々古いAndroid端末でも動作するのが嬉しいです。標準版であれば、リアルな水面を作ることも可能です。波も生成できるので楽しいです。

暑い夏に、ナイスな海を作ってみてはいかがでしょうか。

関連リンク

Definitive Stylized Waterのアセットストア

Definitive Stylized Water - Asset Store

Definitive Stylized Waterの紹介動画

youtu.be

Definitive Stylized Waterの紹介ツイート

滝の部分に使ったパーティクルアセット

assetstore.unity.com