【Unity】Post Processingやシェーダーを使用して水中を表現する

この記事ではPost Processingやシェーダー、パーティクルシステムを利用して、水の中を表現する方法を紹介します。
Post Processingなどを活用すると手軽にシーンの雰囲気を変えられるので、シーン制作の参考になれば嬉しいです。

サンプル

今回は海の底のシーンを作成しました。

Post Processingで海を表現する

Post Processingで色を変更する

Post Processingで色を変更する

まずは水中を表現するため、Post Processingを利用してシーンビュー自体の色を青くして海っぽくします。Post Processingを利用することでカメラにエフェクトをかけられるので、シーンビュー全体の見た目を変更することができます。

Post Processingを設定する

Post Processingを使用するには、UnityにPackage Managerからインポートする必要があります。以下の記事で説明しているので、参照してください。

Post Processing Stack v2をインポートできたら、以下の設定を進めてください。

Color Gradingを編集して海の中を表現する

Color Gradingを編集する

Color Gradingを編集する(画像1)


Color GradingのTrackballsを編集する

Color GradingのTrackballsを編集する(画像2)

Color Gradingは画面上の色について、輝度や明度などを修正するエフェクトです。全体の色味を整える役割があるので、今回はこれを利用して水中らしさを演出します。編集する箇所はスクリーンショット(画像1)(画像2)の赤枠内です。以下、その詳細について説明します。

  • Mode…Color Gradingのエフェクトの種類を選択できます。VRでは通常HDR レンダリングには対応していないので、Low Definition Rangeを選択します。
  • Color Filter…画面にかける色フィルターの設定です。カラーピッカーをクリックすることでウィンドウが開くので、お好みの色を設定します。また、このウィンドウ上でIntensity(光の強度)を編集できるので、バーを動かして明るさを調整できます。今回は少しIntensityを低くすることで水中らしくします。
  • Trackballs…ここまで編集した色味に対して微調整できます。左から「暗い色域」「中間の色域」「明るい色域」の色味を調整できます。ここを編集することで「暗い部分はより青っぽくして際立たせる」といった調整ができます(画像2の部分です)。

セルラーノイズをシェーダーで作成する

作成するシェーダー

作成するシェーダー

海っぽさを演出するためにプールの表面などで見られる光の網(コースティクス)を、海底に模したPlaneに表示させます。
今回は、シェーダーでセルラーノイズを作ることで表現しています。

シェーダーの新規作成

Planeを新規作成する

Planeを新規作成する

まずは、後でマテリアルを適用するためのPlaneを作成しておきます。

シェーダーを新規作成する

シェーダーを新規作成する

コードでシェーダーを作成します。プロジェクトウィンドウ上で右クリック> Create > Shader > UnlitShaderでシェーダーを新規作成してください。

Shader "SeaCellular"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        LOD 100

        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #pragma multi_compile_fog

            #include "UnityCG.cginc"

            struct appdata
            {
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct v2f
            {
                float2 uv : TEXCOORD0;
                UNITY_FOG_COORDS(1)
                float4 vertex : SV_POSITION;
            };

            sampler2D _MainTex;
            float4 _MainTex_ST;

            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.uv = TRANSFORM_TEX(v.uv, _MainTex);
                UNITY_TRANSFER_FOG(o,o.vertex);
                return o;
            }

            float2 random2(float2 st)
            {
                st = float2(dot(st, float2(127.1, 311.7)),
                            dot(st, float2(269.5, 183.3)));
                return -1.0 + 2.0 * frac(sin(st) * 43758.5453123);
            }


            float cellularnoise(float2 st, float n) {
                st *= n;

                float2 ist = floor(st);
                float2 fst = frac(st);

                float distance = 5;

                for (int y = -1; y <= 1; y++)
                for (int x = -1; x <= 1; x++)
                    {
                        float2 neighbor = float2(x, y);
                        float2 p = 0.5 + 0.5 * sin(_Time.y + 6.2831 * random2(ist + neighbor));
                        float2 diff = neighbor + p - fst;
                        distance = min(distance, length(diff));
                    }

                float color = distance * 0.2;

                return color;
            }


            fixed4 frag(v2f i) :  SV_Target{

                return cellularnoise(i.uv, 16) * float4(1, 2, -2, 1) + float4(0.1,0.5,1.5,1);
            }
            ENDCG
        }
    }
}

今回は、以下のサイトを参考にしてシェーダーを作成しました。
【UnityShader】Unityで水面の模様を描画するシェーダ・セルラーノイズ
シェーダでノイズ3(セルノイズ) 空の缶詰 – Unity

 

マテリアルの新規作成

作成したシェーダーをマテリアルに適用する

作成したシェーダーをマテリアルに適用する

シェーダーを使用するには、シェーダーを適用したマテリアルをオブジェクトにアタッチする必要があるので、まずマテリアルを新規作成します。マテリアルのShaderをクリックすると、先ほどのシェーダーを選択できるようになっています。

マテリアルを適用する

マテリアルをPlaneにアタッチする

マテリアルをPlaneにアタッチする

完成したマテリアルを、最初に作っておいたPlaneに適用します。マテリアルをヒエラルキーのPlaneに直接ドラッグすることでアタッチできます。

泡のパーティクルを作成する

ここからはパーティクルを使用して「泡」を作成します。

パーティクルで泡を発生させる

パーティクルで泡を発生させる

このような、ぶくぶくと沸き立つような泡を作成します。

泡のマテリアルを作成する

泡のテクスチャ

泡のテクスチャ(見えにくいです)

まず、マテリアルに適用するための泡のテクスチャを用意します。PhotoShopなどでお好みの泡の画像ファイルを用意してください。アウトラインと光沢の線をちょっと描いたくらい単純なものでも充分に泡っぽくなります。
画像ファイルはUnityのプロジェクトウィンドウに入れておいてください。

マテリアルを新規作成する

マテリアルを新規作成する

プロジェクトウィンドウ上で右クリック > Create > Materialを選択して、マテリアルを新規作成してください。わかりやすいように名前を「bubble」に変更します。

テクスチャをアタッチする

テクスチャをアタッチする

Albedoの枠内をCtrlを押しながらクリックして画像を選択、もしくは画像を直接Albedoの枠にドラッグすることでもアタッチできます。

Shaderを変更する

Shaderを変更する

Shaderを変更します。デフォルトではStanderdに設定されており、このままだと泡の画像は透明(Alpha)を含むので正しく描画されません。枠のどこかをクリックし、Mobile > Particles > Alpha Blendedと選択して設定します。これで描画されるようになります。

パーティクルを新規作成する

パーティクルを新規作成する

パーティクルを新規作成する

ヒエラルキーウィンドウ上で右クリック > Effects > Particle Systemパーティクルを選択し、パーティクルを新規作成します。

Rendererモジュールを編集する

Rendererモジュールを編集する

Rendererモジュールを編集する

Rendererモジュールは下の方にあるので順番的には最後に編集する事が多いですが、最初に見た目が変わった方がわかりやすいため、今回は初めに編集します。

Rendererモジュールの編集内容は、Materialに先ほど作成したマテリアルをアタッチするだけです。これで、パーティクルに泡が描画されるようになりました。

Mainモジュールを編集する

Mainモジュールを編集する

Mainモジュールを編集する

Mainモジュールでライフタイムやローテーションをランダムに設定することで、泡がある程度バラバラに発生するようにしています。
パラメータを変更する場所は下記を参照ください。

ParametersValue
Duration3.00
Start Lifetime1/5
Start Speed0.5/5
Start Size0.5/0.05
Max Particles100
  • Duration…パーティクルが継続する時間です。
  • Start Lifetime…パーティクルが発生してから消滅するまでの寿命です。右の三角マークからRandom Between Two Constantを選択することで、任意の数値の間でランダムな数値が設定されます。
  • Start Speed…パーティクルが移動する速さです。数値が大きいほど速くなります。右の三角マークからRandom Between Two Constantを選択することで、任意の数値の間でランダムな数値が設定されます。
  • Start Size…パーティクルのサイズです。数値が大きいほど大きくなります。右の三角マークからRandom Between Two Constantを選択することで、任意の数値の間でランダムな数値が設定されます。
  • Max Particles…表示されるパーティクルの最大数です。数値が大きいほど多くのパーティクルを表示できます。

Emissionモジュールの編集

Emissionモジュールはデフォルトのままで問題ないので、チェックボックスがオンになっているのを確認して次の項目を編集してください。

Shapeモジュールの編集

Shapeモジュールを編集する

Shapeモジュールを編集する

Shapeモジュールはパーティクルの形状を設定できるモジュールです。今回は泡が下から上に立ち上るようにしたいのでBoxを選んでください。形状を変更するだけで他のパラメータを編集する必要はありません。

Size over Lifetimeモジュールの編集

Size over Lifetimeモジュールを編集する

Size over Lifetimeモジュールを編集する

Size over Lifetimeモジュールはパーティクルの大きさをライフタイムによって変更するように設定できるモジュールです。Separate Axisのチェックボックスをオンにすることで、X(幅)、Y(高さ)、 Z(深度)それぞれの軸をグラフで個別に設定できます。今回は自然に発生している泡を模したいので、少しだけグラフに強弱をつけている程度です。シーンビューで確認しながらお好みで設定してください。

シーンをととのえる

今回は記事で紹介した内容のほか、海底に射す太陽光と、海の生き物などを配置しました。

参考にした記事はこちら

使用したアセットはこちら

STYLYへアップロード

実際にSTYLYへアップロードして使用しましょう。

今回はUnityのシーンをそのままSTYLYにアップロードするので、こちらをご参照ください。

STYLYアカウントを作成する

アカウント作成方法

STYLYに関する質問、バグ報告、改善してほしい要望はSTYLY FORUMまで
https://jp.forum.styly.cc/support/discussions