[Unity] #12 : SimpleWaterで最小の水面を作る(Plane+URPシェーダー+テクスチャ)

はじめに

Unity 7日目、後半。

ツール開発したり、アセットストアに申請したりなど、寄り道が多すぎて中々実装できなかった「SimpleWater」を実装しました。

実装内容としては、前回の記事でEditorツールを作成し「Terrain」を一括で底上げしたことによってくぼみを作れるようになったので、 地形を凹ませて、その上にPlaneジオメトリーを配置し、シェーダー処理で地形を上下させて波を演出というもの。

更にその上に水のテクスチャーを貼るというシンプルな内容です。

以下、動画を撮ってみましたが、今回の処理のメインは、初となる、Uintyでのシェーダー処理で、波を上下やテクスチャの移動処理をする事でややリアルな演出を作成してる事だと思います。

よいよ、Unityでもシェーダーを扱うようになってきました。

ゲーム画面

前回の記事:

1. 概要

Unity には高機能な水システム(Water System、Stylized Water 等)があるが、 今回は 最小限のシェーダーだけで水面を作る方法 をまとめる。

これは

  • Three.js 時代の “Plane + GLSL”
  • Unity の “Shader + Plane”

が、ほぼ同じ感覚で作れることを理解するのに最適な題材。

今回は湖を例に、最短で水面を作る流れをまとめた。

2. Plane を置く

  1. Hierarchy → 3D Object → Plane を作成
  2. Scale を拡大して、湖のサイズにフィットさせる
  3. Position を調整して、Terrain の凹みに“ぴったり水位が合う高さ”に置く

ポイント: Plane は「ただの1枚ポリゴン」だけど、水面は基本的に平面で十分。 Terrain の形に合わせて盛り下がりしなくても、水面を一枚だけ“水平に”置けばリアルに見える。

シェーダー側で 揺らぎ(波)を頂点に加えるだけで立体感が出るから、この段階では本当に Plane を置くだけでOK。

3. SimpleWater シェーダーを作る

最小構成の HLSL で水面を揺らす。 波は 頂点を上下に動かしているだけ で、構造は非常にシンプル。

保存場所は

assets - Prefabs - Shaders

Shader "Custom/SimpleWater"
{
    Properties
    {
        _Color ("Water Color", Color) = (0.1, 0.4, 0.8, 0.6)
        _WaveSpeed ("Wave Speed", Float) = 1.0
        _WaveStrength ("Wave Strength", Float) = 0.1
        _MainTex ("Water Texture", 2D) = "white" {}
    }

    SubShader
    {
        Tags { "RenderType"="Transparent" "Queue"="Transparent" }
        Pass
        {
            Blend SrcAlpha OneMinusSrcAlpha
            ZWrite Off
            Cull Off

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings {
                float4 positionHCS : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            float4 _Color;
            float _WaveSpeed;
            float _WaveStrength;
            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);

            Varyings vert (Attributes v)
            {
                Varyings o;

                float wave = sin(_Time.y * _WaveSpeed + v.positionOS.x * 0.3 + v.positionOS.y * 0.3)
                            * _WaveStrength;

                float3 pos = v.positionOS.xyz;
                pos.y += wave;

                o.positionHCS = TransformObjectToHClip(pos);
                o.uv = v.uv;
                return o;
            }

            half4 frag (Varyings i) : SV_Target
            {
                half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, i.uv);
                return col * _Color;
            }
            ENDHLSL
        }
    }
}

4. マテリアルを作成し Plane に適用

  1. Project → Create → Material 名前は SimpleWater_Mat
  2. Inspector の Shader を Custom → SimpleWater に変更
  3. このマテリアルを Plane にドラッグして適用

水の調整ポイント

SimpleWater_Mat では以下を自由に調整できる:

  • Water Color 水の基本色。やや青寄りにすると自然。
  • Wave Speed 波の揺れの速さ。速すぎると不自然なので 0.3〜1.0 の間が扱いやすい。
  • Wave Strength 波の高さ(振幅)。0.01〜0.05 くらいの控えめがリアル。
  • Water Texture 貼りたい水のテクスチャをドラッグするだけで、 “ベタ塗り → リアル水面” に一気に変化する。

テクスチャを載せるだけでも見た目が劇的に変わるので、 最初の水シェーダーとしては十分実用レベルになる。

5. テクスチャを追加して質感をアップ

フラットな水色だけだと どうしても安っぽく見える。 そこで、_MainTex に 水面の模様テクスチャ を設定すると、一気に “水っぽさ” が出る。

今回は無料の Stylize Water Texture を使用。

マテリアル側の調整ポイントは以下の通り:

調整ポイント

  • Tiling:2〜4倍 1 のままだと模様が大きすぎる。 湖サイズに合わせて密度を上げると自然になる。

  • Color(アルファ値)0.4〜0.6 _Color.a(透明度)を少し下げると 透明感が出て水っぽさが大幅に向上する。

  • 色味はテクスチャ × _Color の掛け算 _Color を青寄りにすると “深い水色” に、 緑寄りにすると “池・沼・川っぽい” 色になる。

Before / After の変化

  • テクスチャなし:のっぺりしたベタ塗り
  • テクスチャあり:模様が流れているように見えて一気にリアル化

とにかく テクスチャを載せるだけで水面の説得力が段違い。

6. ゲームビューで確認

実際にキャラクターを立たせて見ると、 地形の凹みと波の組み合わせでリアルな湖になる。

最初の水としてはこれで十分。

  • 揺れがある
  • テクスチャの質感がある
  • 色味の調整ができる
  • 透明半透明の見た目が自然

7. おわりに

今回の SimpleWater は “最小構成の水面” だが、 Plane+自作シェーダー+テクスチャ の組み合わせだけで 箱庭の景観が一段階アップするのを実感できた。

特に、Terrain の凹みに水を流し込むと、 それだけで世界に “奥行き” や “生活感” が生まれる。 水はゲーム世界の印象を大きく変える要素だと改めて感じた。

次のステップとしては、より本格的な表現にも進める:

  • 深度差による色の変化(Depth Fade)  → 浅瀬は明るく、深い所は青く沈む自然な水面に。

  • UV アニメーションによる流れの表現  → 川・海の動きを付ける最初の一歩。

  • 反射・屈折の導入(軽量〜高度)  → 湖面が空や周囲を映し込み、一気に“本物感”が増す。

  • Unity Water System(URP/HDRP)への移行  → よりリアルで高機能な水を使いたい時の選択肢。

まずは“最低限の水”を自分で組み立てられたことで、 今後の水表現の理解がとてもスムーズになる。