はじめに(URPとBuilt-inの違い)

スポンサーリンク

組み込み系エンジニアのeightです。最近、趣味でUnityをさわり始めて「せっかくなら見た目もこだわりたい!」と思い、シェーダー制作に挑戦してみました😊

まず最初に悩んだのが、「URP(Universal Render Pipeline)」と「Built-in Render Pipeline」の違いです。Unityにはレンダリングパイプラインが複数あり、それぞれシェーダーの書き方も変わってきます。簡単にまとめると以下のとおりです。

項目Built-inURP
対応バージョンUnity全バージョンUnity 2019.3以降
Shader Graph非対応対応
パフォーマンス標準的モバイル向けに最適化
シェーダー記述ShaderLab / HLSLShaderLab / HLSL / Shader Graph

Built-inはコードでゴリゴリ書く必要がありますが、URPではノードをつないでビジュアルにシェーダーを組めるShader Graphが使えます。非グラフィックス系エンジニアとしては、これは非常にありがたいです。

URPのレンダリングパイプラインは、以下のような流れで描画処理が行われます。

CPU カリング/更新 Shadow 影の計算 Depth 深度プリパス Geometry 描画コール Lighting 照明計算 Post FX 後処理効果 画面出力 Final Image
図1: URPのレンダリングパイプライン(処理の流れ)

URPとShader Graphのセットアップ

まずはプロジェクトの準備からです。Unity Hubで新規プロジェクトを作成する際に「Universal 3D」テンプレートを選択すると、最初からURPが有効な状態で始められます。これが一番ラクでした。

既存プロジェクトにURPを追加する場合は、PackageManagerから導入します。

  1. メニューバーから Window → Package Manager を開く
  2. 左上の「+」ボタンから「Add package by name」を選択
  3. com.unity.render-pipelines.universal と入力してインストール
  4. 同様に com.unity.shadergraph もインストール

インストール後、URPのRendering Assetを作成してProjectSettingsに割り当てる必要があります。

  1. Projectウィンドウで右クリック → Create → Rendering → URP Asset (with Universal Renderer)
  2. Edit → Project Settings → Graphics を開き、作成したアセットを「Scriptable Render Pipeline Settings」にドラッグ

これでURPとShader Graphが使えるようになります。初回はマテリアルがピンクになることがありますが、それはシェーダーがURP未対応のためです。マテリアルを選択して「Fix」ボタンを押すかURPシェーダーに差し替えれば解決しました😊

Shader Graphの基本的な使い方

セットアップが終わったら、いよいよShader Graphを触ってみます。

Shader Graphアセットの作成

ProjectウィンドウでAssetsフォルダを右クリックし、Create → Shader Graph → URP → Unlit Shader Graphを選択します。今回は発光っぽい表現を作りたかったので「Unlit」にしました。

ノードの基本操作と接続

Shader Graphをダブルクリックすると専用エディタが開きます。ノードは以下のような構成で接続します。

Shader Graphのノード接続例(UV→Sin→Multiply→Fragment)
  • Vertex:頂点の座標や法線を操作する
  • Fragment:ピクセルの色や透明度を操作する

ノードの追加はグラフ上でスペースキーを押すか右クリックから「Create Node」で行います。ノード同士はポートをドラッグしてつなぎます。左下のプレビューウィンドウでリアルタイムに結果が確認できるのが便利でした。

実践:波紋エフェクトシェーダーを作る

基本操作がわかったところで、本題の波紋エフェクトを作っていきます。SinノードとTimeノードを組み合わせてアニメーションさせるのがポイントです😊

ノード構成

  1. UV座標を中心からの距離に変換(Distanceノード)
  2. 距離にTimeを加算して動きを出す(Addノード)
  3. Sin関数で波形を作る(Sineノード)
  4. 波の色をBaseColorとして出力

Custom FunctionでHLSLを書く

Shader GraphのCustom Functionノードを使うと、HLSLでロジックを記述できます。

// RippleEffect.hlsl
void RippleEffect_float(
    float2 UV,
    float Time,
    float Speed,
    float Frequency,
    out float Wave
)
{
    float2 center = float2(0.5, 0.5);
    float dist = distance(UV, center);
    Wave = sin(dist * Frequency - Time * Speed);
}

このファイルをAssetsフォルダに保存し、Shader Graphの「Custom Function」ノードで「File」タイプを選択して参照します。SpeedとFrequencyはPropertyとして公開しておくと、マテリアルのInspectorからリアルタイムに調整できてとても便利でした。

// Propertyの推奨初期値
Speed     : 2.0   // 波が広がる速さ
Frequency : 20.0  // 波の細かさ
WaveColor : (0.0, 0.6, 1.0, 1.0)  // 水色系

この設定で平面のPlaneオブジェクトにマテリアルを当てると、中心から外側に向かって波紋が広がるエフェクトが実現できました。アニメーションしているのをゲームビューで初めて確認した瞬間はかなり感動しましたよ😊

さいごに

今回はURPのセットアップからShader Graphを使った波紋エフェクトの制作まで、一通り試してみました。Shader Graphのノードベースのアプローチのおかげで、グラフィックス未経験でも取っつきやすかったです。

応用例としては、以下のようなエフェクトも同じアプローチで作れます。

  • 水面の揺らぎ(UVスクロール + Normal Map)
  • 炎・オーラのディゾルブエフェクト(Noiseノード活用)
  • ホログラム風スキャンライン(Fractとフロアで縞模様)
  • キャラクターのダメージフラッシュ(Lerpでカラーブレンド)

次回はNoise系ノードを使ったディゾルブエフェクトにも挑戦してみようと思います。同じようにシェーダーに興味を持ち始めた方の参考になれば嬉しいです!

それでは、今回はここまで。ありがとうございました😊