【Unity 6 / URP 17】Shader Graph で作る原神風の水面

深度+反射+白波+波アニメまで完全解説(Unity 6000.2.7f2 対応)

Unity 6(Unity 6000.2.7f2)および URP 17.0.x の環境で、Shader Graph を使って原神のような水面表現を再現するチュートリアルです。

  • 浅瀬ほど明るくなる「深度グラデーション」
  • 2 本の波で揺らす Gerstner 風の頂点アニメ
  • 深度+ノイズによる「白波(Foam)」
  • Skybox(Reflection Probe)の反射
  • Fresnel による縁の強調

最新の Unity 6 環境に合わせて、すべての手順をスクショ横にそのまま使える文章+ノード図でフル解説します。


1. 使用バージョン・前提条件

この記事は以下の環境で動作確認しています。

  • Unity 6000.2.7f2
  • Universal Render Pipeline(URP 17.0.x)
  • Shader Graph 17.x

Unity 6(6000.x)では内部レンダラが整理されていますが、Shader Graph を使った深度取得・反射・White Foam の構築は、従来の URP とほぼ同じ方法で実現できます。


2. プロジェクト設定(URP / Depth Texture)

Depth Texture を ON にする(必須)

水面で Scene Depth を利用するため、URP の Depth Texture を有効化します。

パス:

Project Settings > Graphics > URP Global Settings

Rendering > Depth Texture にチェックを入れる

スクショ横説明文:

URP の深度テクスチャを有効化しないと Scene Depth ノードが正しく動作しません。

Unity 6000.2.7f2 ではこの設定が必須です。


3. Reflection Probe の設置(反射に必須)

水面に Skybox(空)を反射させるため、Reflection Probe を配置します。

  1. GameObject > Light > Reflection Probe
  2. サイズを水面全体を覆うように調整
  3. Refresh Mode:On Demand(推奨)
  4. 必要に応じて「Bake」ボタンでベイク

スクショ横説明文:

Unity 6/URP 17 では Reflection Probe の Cubemap が Shader Graph の Sample Cubemap から直接利用できます。

水面全体が Probe の範囲に入っていることを確認してください。


4. Shader Graph の作成(URP Lit Shader Graph)

  1. Create > Shader Graph > URP > Lit Shader Graph
  2. 名前:Water_Genshin_SG
  3. Graph Inspector の設定
    • Surface:Opaque
    • Blend:None(不透明)
    • Allow Material Override:ON
    • Two Sided:必要なら ON

5. Blackboard の Property 一覧(コピペ可)

この記事の Shader Graph で使うパラメータです。

■ 色

  • ShallowColor(Color)浅瀬
  • DeepColor(Color)深部
  • FoamColor(Color)白波

■ 深度制御

  • DepthScale(Float, 1.5)
  • DepthOffset(Float, 0.0)

■ 波(2 本)

  • WaveAmp1(Float)
  • WaveFreq1(Float)
  • WaveSpeed1(Float)
  • WaveDir1(Vector2)
  • WaveAmp2
  • WaveFreq2
  • WaveSpeed2
  • WaveDir2

■ 白波

  • FoamIntensity
  • FoamDepthThreshold
  • FoamDepthSoftness
  • FoamNoiseTiling
  • FoamNoiseSpeed

■ Fresnel / 反射

  • FresnelPower
  • FresnelIntensity
  • ReflectionStrength

6. 頂点ステージで「波アニメーション」を作る

(Gerstner 風)

Unity 6 Shader Graph でも、頂点の変位は Vertex Stage で行います。

Vertex 出力を有効化

右上の歯車 → Graph Settings → Vertex を ON。

ノード構成(ASCII 図)

[Position(World)]──┬──────→ Split → X,Z → PosXZ(float2)
                    │
                    └──→ Y は後で加算

波1:
PosXZ → Dot(WaveDir1) → *WaveFreq1
      → + (Time * WaveSpeed1)
      → Sine → *WaveAmp1 → Disp1

波2:
PosXZ → Dot(WaveDir2) → *WaveFreq2
      → + (Time * WaveSpeed2)
      → Sine → *WaveAmp2 → Disp2

DispTotal = Disp1 + Disp2

最終:
Combine(X, Y + DispTotal, Z)
       → Vertex Position

スクショ横説明文:

Position(World) の Y 成分に波の変位を足すことで、Plane が水面のように揺れます。


7. Scene Depth を使った「浅瀬グラデーション」

深度取得ノード構成

[Screen Position] (Default)
        │
        ↓
[Scene Depth] (Space:Eye)
        │
        ↓
[Position(View)] → Split → Z = SurfaceDepth
        │
        ↓
DepthDiff = SceneDepth - SurfaceDepth
DepthFactor = saturate(DepthDiff * DepthScale + DepthOffset)

BaseDepthColor = Lerp(DeepColor, ShallowColor, DepthFactor)

スクショ横説明文:

Scene Depth(Eye)の深度と、Position(View) の深度を比較することで、

カメラから見て浅い部分と深い部分を判定します。


8. 白波(Foam)

深度 × ノイズの組み合わせ

ノード構成(ASCII)

深度マスク:
DepthDiff → *FoamDepthThreshold → OneMinus
→ Smoothstep(0, FoamDepthSoftness)
→ FoamDepthMask

ノイズ:
WorldPos.XZ → *FoamNoiseTiling
→ + (Time.y * FoamNoiseSpeed)
→ Simple Noise → NoiseRaw

FoamMask = saturate(FoamDepthMask * NoiseRaw * FoamIntensity)

FoamTerm = FoamColor * FoamMask

スクショ横説明文:

浅瀬の縁にだけ白波が発生するよう、深度差とノイズを掛け合わせています。


9. Fresnel(縁の強調)+ Reflection Probe(Skybox 反射)

ノード構成

Normal = Normalize(Normal Vector(World))
ViewDir = Normalize(View Direction(World))

NdotV = dot(Normal, -ViewDir)
Fres = pow(1 - NdotV, FresnelPower) * FresnelIntensity

ReflDir = Reflect(-ViewDir, Normal)

ReflectionColor =
  Sample Cubemap( Reflection Probe, ReflDir )

ReflectionTerm = ReflectionColor * Fres * ReflectionStrength

スクショ横説明文:

Fresnel で縁を強調し、Reflection Probe の Cubemap を

Reflect 方向でサンプルすることで、空の反射を作ります。


10. 最終合成

FinalColor =
  BaseDepthColor
+ FoamTerm
+ ReflectionTerm

Shader Graph の Base Color に FinalColor を接続すれば完成です。


11. マテリアル設定(推奨)

  • ShallowColor: (0.6, 0.9, 0.9)
  • DeepColor: (0.0, 0.15, 0.4)
  • FoamColor: (1,1,1)
  • DepthScale: 1.2〜2.0
  • FoamNoiseTiling: 0.5〜1.5
  • ReflectionStrength: 0.3〜0.6
  • FresnelIntensity: 0.2〜0.5

12. シーン構成例(Unity 6)

  • Plane(水面)にマテリアルを適用
  • Plane(砂浜・地面)を水面の下に設置
  • Reflection Probe を水面を覆うように配置
  • メインカメラを斜め角度から向けると反射が見やすい

13. まとめ

Unity 6(6000.2.7f2)/URP 17.x 対応で、

Shader Graph だけを使って原神風の水面を実装しました。

本記事で扱った要素:

  • 深度差で浅瀬の色を変える
  • 波(Gerstner 風)
  • 白波(Foam)
  • Fresnel
  • Skybox 反射(Reflection Probe)
  • 頂点+フラグメントの組み合わせ設計

Unity 6 の URP は内部的には変化していますが、Shader Graph の基本原理は変わっていないため、

この記事の構成は Unity 6000 系 urp プロジェクトでそのまま動作します。


必要であれば:

  • GitHub README 版(英語)
  • 記事の締め画像用の “完成レンダー風キャプション”
  • サンプル Unity プロジェクト構造(フォルダツリー + 空 Scene)

も作成できます。

訪問数 6 回, 今日の訪問数 6回

C#

Posted by hidepon