mcpField
U
unity-lighting-vfx

unity-lighting-vfx

github.com/nice-wolf-studioクリエイティブ・メディア4092 回インストール6 週間前に更新
リポジトリ

unity-lighting-vfx について

Unity 開発者向けに、ライティングとビジュアルエフェクトを解説するリファレンススキルです。照明、グローバルイルミネーション、プローブ、パーティクルに加え、VFX Graph、C# 制御例、注意点を扱います。

主な機能

  1. 01リアルタイム・ベイク・ミックス照明
  2. 02グローバルイルミネーションと環境反射
  3. 03Light Probe と APV
  4. 04Particle System モジュールのリファレンス
  5. 05VFX Graph の基礎とパターン
  6. 06C# によるエフェクト制御例

活用シーン

  1. 01静的・動的シーンの照明方式を選ぶ
  2. 02移動オブジェクトの間接照明を設定する
  3. 03Particle System と VFX Graph を比較する
  4. 04照明やエフェクトの性能問題を調べる

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/nice-wolf-studio/unity-claude-skills --skill unity-lighting-vfx

インストール後、Claude Code で/unity-lighting-vfxを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

references/
lighting-guide.md
particle-system.md
vfx-graph.md

詳細

Unity のライティングとビジュアルエフェクト

ライティングモード

Unity には、照明の計算方法を制御する 3 つのライトモードがあります。

リアルタイムライト
  • 実行時に毎フレームライティングを計算します
  • 強度、色、位置を動的に変更できます
  • Shadow Distance までの距離に影を落とします
  • デフォルトでは直接光のみが寄与します(バウンス光はありません)
  • 実行時の負荷が高く、特に複雑なシーンやローエンドのハードウェアで顕著です
  • 最適な用途:動的なオブジェクト、ちらつきエフェクト、移動する光源
ベイク済みライト
  • 計算はUnity Editor 内で行われ、ライティングデータとしてディスクに保存されます
  • 実行時には、動的に計算する代わりに事前計算済みデータを読み込みます
  • 直接光と間接光の両方をライトマップにベイクします
  • 移動するオブジェクト用の情報を Light Probes に保存します
  • 実行時にライトのプロパティを変更できず、動的な GameObject を照らしません
  • スペキュラーへの寄与はありません
  • 最適な用途:静的な背景、複雑な間接光、パフォーマンスが重要なシナリオ
ミックスドライト
  • ベイク済みの間接光とリアルタイムの直接光を組み合わせます
  • 動作は Lighting ウィンドウの Lighting Mode 設定によって異なります
  • リアルタイムの影を落とします(ベイク済みのソフトシャドウではありません)
  • 実行時にプロパティを変更できます(リアルタイム部分のみに影響します)
  • 完全にベイク済みのライティングより、常に処理負荷が高くなります
  • 最適な用途:背景のライティングをベイクしつつ、動的な影を使う場合

重要: ベイク済み/ミックスドのすべてのモードで、Baked Global Illuminationを有効にする必要があります。有効にしない場合、ミックスドライトとベイク済みライトはリアルタイムライトとして動作します。

ライトの種類

ディレクショナルライト
  • 無限遠に配置され、一方向に光を放射します
  • 光線は平行で、距離に応じた強度の減衰はありません
  • 太陽や月をシミュレートします。新しいシーンにはデフォルトで 1 つ含まれます
  • プロシージャルスカイシステムと連携し、回転させて時間帯の変化を表現できます
ポイントライト
  • 1 点に配置され、全方向に均等に光を放射します
  • 強度は逆二乗の法則に従います(距離の二乗に応じて減衰します)
  • ランプ、爆発、局所的な照明に使用します
スポットライト
  • 1 点に配置され、円錐形に光を放射します
  • 円錐角度を調整できます。光は端で減衰します(半影)
  • 角度を広げると、より大きなフェード領域ができます
  • 懐中電灯、ヘッドライト、サーチライトに使用します
エリアライト
  • 長方形または円盤として定義され、表面全体から均一に光を放射します
  • 逆二乗の法則に従い、柔らかく控えめな陰影を生み出します
  • ベイク専用で、実行時には使用できません
  • 街灯、リアルな室内照明に使用します

グローバルイルミネーション

グローバルイルミネーション(GI)は、光が表面間で反射する様子をシミュレートし、リアルな間接光を生成します。

ベイク済み GI
  • Progressive Lightmapper(CPU または GPU)を使用して、間接光をライトマップに事前計算します
  • 結果はライトマップテクスチャと Light Probes に保存されます
  • Lighting ウィンドウの Bake 設定で構成します
  • GPU Progressive Lightmapper では、タイルサイズを設定してベイク時間を短縮できます
環境ライティング

Lighting ウィンドウの Environment タブで設定する 3 種類のアンビエント光源:

  • Skybox:スカイボックスのマテリアルの色を使い、異なる角度からのアンビエント光を表現します
  • Gradient:空、地平線、地面に別々の色を設定し、滑らかにブレンドします
  • Color:シーン全体に均一なアンビエント光を設定します

Intensity Multiplier(0~8、デフォルトは 1)でアンビエント光の明るさを制御します。

環境反射
  • ソース:スカイボックス、またはカスタムの Cubemap/RenderTexture
  • 解像度、圧縮、強度の乗数を設定できます
  • Bounces 設定で、オブジェクト間の反射を評価する反復回数を制御します

Light Probes と Adaptive Probe Volumes

Light Probes
  • シーン全体の空間でライティング情報を取得します
  • 実行時には、最も近いプローブを使って動的な GameObject の間接光を近似します
  • 移動するオブジェクトに間接的なバウンス光を与え、LOD システムにも対応します
  • Light Probe Groups を使って手動で配置する必要があります
  • ベイク済みのライティング情報を保存し、直接光と間接光の両方で機能します
適応型プローブボリューム(APV)

APV は、URP における手動のライトプローブ配置に代わる最新の方法です。

  • プローブ配置の自動化 -- ライトプローブグループの手動配置が不要になります
  • ピクセル単位のライティング -- オブジェクト単位の手法より優れた品質を実現します
  • シーンのベイク -- ベイクセットを使用して複数のシーンをまとめてベイクできます
  • ランタイム調整 -- ライティングシナリオとスカイオクルージョンにより動的な変更に対応します
  • 大規模ワールドのサポート -- 広大なオープンワールド環境向けにデータをストリーミングします
  • データの柔軟性 -- AssetBundles または Addressables から読み込めます
  • 可視化ツールを使って、プローブ密度とボリュームサイズを設定できます

リフレクションプローブ

周囲の球状ビューをキューブマップとしてキャプチャし、反射マテリアルに使用します。

種類
種類説明
ベイク済み静的な GameObject のみをキャプチャします。パフォーマンスを重視する場合に最適です
カスタムカスタムテクスチャを使って動的オブジェクトをキャプチャできます
リアルタイムゲームプレイ中に更新します。リフレッシュモードを設定できます
主なプロパティ
  • 重要度:複数のプローブが重なる場合の描画優先度
  • 強度:シェーダー計算におけるテクスチャの明るさ
  • ボックスプロジェクション:室内向けのプロジェクションマッピングを有効にします(URP の設定が必要です)
  • ボックスサイズ/オフセット:反射の寄与範囲を定めるワールド空間のバウンディングボックス
  • ブレンド距離:遅延プローブのブレンド距離
リアルタイムのオプション
  • リフレッシュモード:Awake 時、毎フレーム、またはスクリプト経由
  • 時間分割:全フェイスを一度に、個別のフェイス、時間分割なし

パーティクルシステムと VFX Graph の比較

機能パーティクルシステムVFX Graph
シミュレーションCPU ベースGPU ベース
パーティクル数数千数百万
レンダーパイプラインすべてのパイプラインURP/HDRP のみ
制作方法インスペクターモジュールノードベースのグラフエディター
物理演算組み込みの衝突判定カスタム衝突ブロック
スクリプト完全な C# APIイベントベースの C# API
サブエミッターネイティブサポートGPU イベントコンテキスト
最適な用途小規模/中規模のエフェクト、モバイル大規模エフェクト、ハイエンド

選択ガイド:

  • モバイル向け、シンプルなエフェクト、CPU 側のスクリプト制御を完全に行う必要がある場合、またはビルトインレンダーパイプラインを対象とする場合は、パーティクルシステムを使用します
  • 膨大なパーティクル数、GPU 主導のシミュレーション、複雑なノードベースの制作、または URP/HDRP を使用するハイエンドプラットフォームを対象とする場合は、VFX Graphを使用します

パーティクルシステムのモジュール

モジュール目的
Main初期状態:ライフタイム、速度、サイズ、重力、シミュレーション空間
Emissionパーティクルの放出率とタイミング
Shape放出のためのボリューム/サーフェスと開始時の速度方向
Velocity over Lifetimeパーティクルの経過時間に応じて移動を変更します
Noise有機的で不規則な動きを生み出す乱流
Limit Velocity over Lifetime自然な減速
Force over Lifetimeシミュレートされた物理的な力
Inherit Velocityサブエミッターパーティクルが親の速度を引き継ぎます
Lifetime by Emitter Speedエミッターの速度に基づいて寿命を調整します
Color over Lifetime / by Speed経過時間または速度に基づく色の変化
Size over Lifetime / by Speed時間または速度に基づく寸法の変化
Rotation over Lifetime / by Speed向きの変化
Collisionシーンのジオメトリとのパーティクル衝突
Triggersパーティクルを衝突トリガーとして指定します
Sub Emitters他のパーティクルを放出するパーティクル
Texture Sheet Animationテクスチャグリッドのアニメーションフレーム
Trailsモーショントレイルの描画
Lightsパーティクルに対するリアルタイムライト
External Forcesウィンドゾーンとフォースフィールド
Renderer画像/メッシュの変換、シェーディング、オーバードロー
Custom Dataカスタムデータをパーティクルに付加します

VFX Graph の基本

システム
  1. Spawn System:放出を管理する単一の Spawn Context
  2. Particle System:Initialize -> Update -> Output の連続処理
  3. Mesh Output System:単一の Mesh Output Context
コンテキスト
  • Spawn:各フレームを実行してスポーン数を計算します。状態:Running、Idle、Waiting。ループ時間、カウント、遅延を設定できます
  • Initialize:パーティクルの生成時に実行され、初期状態を設定します。新しくスポーンしたパーティクルに対してブロックを処理します。範囲と容量を設定できます
  • Update:生存中のすべてのパーティクルに対して毎フレーム実行されます。位置の積分、回転の積分、経過時間の更新、不要なパーティクルの除去を自動で行います
  • Output:パーティクルを描画します(Quad、Mesh など)。出力ポートはありません。描画ブロックをカスタマイズできます
グラフ要素
  • ブロック:コンテキスト内に積み重ねられるノードです。それぞれが1つの操作を処理し、上から下へ実行されます
  • オペレーター:ブロック/コンテキストのポートに接続する、低レベルのプロパティワークフローノードです
  • プロパティ:プロパティワークフローを介して接続できます
  • 設定:コンテキストごとに編集できる、接続不可の値です
GPU イベント

GPU がイベントを計算する実験的な機能です(通常のイベントでは CPU が計算します)。ブロックでカスタマイズすることはできません。

よく使うパターン(C#)

ライトの作成と設定
using UnityEngine;

public class LightSetup : MonoBehaviour
{
    void Start()
    {
        GameObject lightObj = new GameObject("Dynamic Light");
        Light light = lightObj.AddComponent<Light>();
        light.type = LightType.Point;
        light.color = Color.yellow;
        light.intensity = 2.0f;
        light.range = 15f;
        light.shadows = LightShadows.Soft;
        light.shadowResolution = UnityEngine.Rendering.LightShadowResolution.Medium;
    }
}
リアルタイム反射プローブの作成
using UnityEngine;
using UnityEngine.Rendering;

public class ProbeSetup : MonoBehaviour
{
    void Start()
    {
        GameObject probeObj = new GameObject("Realtime Reflection Probe");
        ReflectionProbe probe = probeObj.AddComponent<ReflectionProbe>();
        probe.size = new Vector3(10, 10, 10);
        probe.mode = ReflectionProbeMode.Realtime;
        probe.refreshMode = ReflectionProbeRefreshMode.EveryFrame;
        probe.resolution = 256;
        probe.hdr = true;
    }
}
実行時のパーティクルシステム制御
using UnityEngine;

public class ParticleController : MonoBehaviour
{
    ParticleSystem ps;

    void Start()
    {
        ps = GetComponent<ParticleSystem>();

        // Modify emission rate -- cache module in local variable first
        var emission = ps.emission;
        emission.rateOverTimeMultiplier = 50f;

        // Modify main module
        var main = ps.main;
        main.startLifetime = 3f;
        main.startSpeed = 5f;
        main.simulationSpace = ParticleSystemSimulationSpace.World;
    }

    void OnTriggerEnter(Collider other)
    {
        // Burst emit particles
        ps.Emit(100);
    }

    void OnDisable()
    {
        ps.Stop(true, ParticleSystemStopBehavior.StopEmittingAndClear);
    }
}
VFX Graph の実行時制御
using UnityEngine;
using UnityEngine.VFX;

public class VFXController : MonoBehaviour
{
    VisualEffect vfx;
    VFXEventAttribute eventAttr;

    void Start()
    {
        vfx = GetComponent<VisualEffect>();
        eventAttr = vfx.CreateVFXEventAttribute();

        // Set exposed properties
        vfx.SetFloat("SpawnRate", 100f);
        vfx.SetVector3("Direction", Vector3.up);
        vfx.playRate = 1.5f;
    }

    void OnTriggerEnter(Collider other)
    {
        // Send custom event with attributes
        eventAttr.SetVector3("position", other.transform.position);
        vfx.SendEvent("OnHit", eventAttr);
    }

    public void StopEffect()
    {
        vfx.Stop();
    }
}
必要に応じた反射プローブの更新
using UnityEngine;

public class ProbeRefresher : MonoBehaviour
{
    ReflectionProbe probe;

    void Start()
    {
        probe = GetComponent<ReflectionProbe>();
        probe.refreshMode = UnityEngine.Rendering.ReflectionProbeRefreshMode.ViaScripting;
    }

    public void RefreshReflections()
    {
        probe.RenderProbe();
    }

    public bool IsReady()
    {
        return probe.IsFinishedRendering(probe.RenderProbe());
    }
}

避けるべきパターン

ライティングで避けるべきパターン
  1. リアルタイムライトが多すぎる:リアルタイムライトはそれぞれ、毎フレームの処理負荷を増加させます。静的なライトには、Baked または Mixed を使用してください
  2. ベイクしたグローバルイルミネーションの有効化を忘れる:これを有効にしないと、Mixed/Baked ライトは警告なく Realtime にフォールバックします
  3. Importance 値を設定せずに反射プローブを重ねる:ちらつきの原因になります。優先順位を決めるため、必ず Importance を設定してください
  4. 実行時の動作を期待して Area Light を使用する:Area Light はベイク専用であり、実行時には光を発しません
  5. Indirect Multiplier を無視する:デフォルトのままでは、反射光が明るすぎたり暗すぎたりすることがあります。ライトごとに調整してください
  6. Shadow Bias を適切に設定しない:低すぎるとセルフシャドウのアーティファクト(シャドウアクネ)が発生し、高すぎると影がオブジェクトから離れます(ピーターパニング)
  7. 大きなシーンで Light Probe を手動配置する:自動化されたピクセル単位の品質を得るには、URP では代わりに Adaptive Probe Volumes(APV)を使用してください
パーティクルシステムで避けるべきパターン
  1. モジュール参照をキャッシュしない:モジュール構造体のプロパティにアクセスするたびに、ネイティブコードへ即座に書き込みが行われます。モジュール変数をキャッシュしてください
  2. アタッチされたエフェクトに World シミュレーション空間を使用する:パーティクルが移動する親オブジェクトから離れていきます。アタッチされた FX には Local 空間を使用してください
  3. CPU でパーティクル数を増やしすぎる:Particle System は CPU がボトルネックになります。パーティクルが 10K を超える場合は、VFX Graph を検討してください
  4. Stop/Clear を忘れる:破棄されずに残ったパーティクルシステムは、見えない状態でも CPU を消費します
VFX Graph で避けるべきパターン
  1. モバイルのシンプルなエフェクトに VFX Graph を使用する:GPU の処理負荷があり、URP/HDRP が必要となるため、モバイルのシンプルなエフェクトには過剰です
  2. Initialize で Capacity を設定しない:デフォルトの容量では、GPU メモリを割り当てすぎたり、足りなくなったりすることがあります
  3. Bounds を無視する:Bounds が正しくないと、エフェクトが表示される範囲内にあってもカリングされます。必ず Initialize コンテキストで Bounds を設定してください
  4. スロットリングせずに毎フレームイベントを送信する:SendEvent には CPU と GPU の同期コストがかかります。イベントの送信をまとめるか、頻度を抑えてください

主要 API クイックリファレンス

Light (UnityEngine.Light)
MemberTypeDescription
typeプロパティLightType(Directional、Point、Spot、Area)
colorプロパティ発光色
intensityプロパティ明るさの倍率
rangeプロパティ最大距離(Point/Spot)
spotAngle / innerSpotAngleプロパティ外側/内側の円錐角
shadowsプロパティLightShadows(None、Hard、Soft)
shadowResolutionプロパティシャドウマップの品質
shadowBias / shadowNormalBiasプロパティシャドウのアーティファクトを軽減
bounceIntensityプロパティGI のバウンス強度
cookieプロパティ投影テクスチャマスク
cullingMaskプロパティレイヤーベースのフィルタリング
colorTemperatureプロパティケルビン単位の CCT
lightmapBakeTypeプロパティベイク設定
bakingOutputプロパティ直近のベイクへの寄与の詳細
AddCommandBuffer()メソッド指定したタイミングで GPU コマンドを実行
ParticleSystem (UnityEngine.ParticleSystem)
MemberTypeDescription
main / emission / shapeプロパティモジュールアクセス用の構造体
particleCountプロパティ現在アクティブなパーティクル数
isPlaying / isPaused / isStoppedプロパティ再生状態
Play() / Pause() / Stop()メソッド再生制御
Emit(count)メソッドパーティクルを即時に生成
Simulate(time)メソッドシミュレーションを早送り
GetParticles() / SetParticles()メソッドパーティクルデータに直接アクセス
Clear()メソッドすべてのパーティクルを削除
TriggerSubEmitter()メソッドサブエミッターを有効化
VisualEffect (UnityEngine.VFX.VisualEffect)
MemberTypeDescription
visualEffectAssetプロパティエフェクトグラフを割り当て/変更
playRateプロパティシミュレーション速度
aliveParticleCountプロパティアクティブなパーティクル数
Play() / Stop() / Reinit()メソッド再生制御
SendEvent(name, attr)メソッドグラフイベントをトリガー
CreateVFXEventAttribute()メソッドイベントペイロードを作成
SetFloat() / SetVector3() / etc.メソッド公開プロパティを設定
GetFloat() / GetVector3() / etc.メソッド公開プロパティを読み取り
HasFloat() / HasVector3() / etc.メソッドプロパティの有無を確認
ResetOverride(property)メソッド元の値に戻す
ReflectionProbe (UnityEngine.ReflectionProbe)
MemberTypeDescription
modeプロパティベイク済み/カスタム/リアルタイム
size / centerプロパティバウンディングボックスの設定
intensity / importanceプロパティ明るさと優先度
boxProjectionプロパティボックスプロジェクションを有効化
refreshMode / timeSlicingModeプロパティリアルタイム更新の設定
RenderProbe()メソッドキューブマップの更新を強制
IsFinishedRendering()メソッド時分割処理の完了を確認
BlendCubemap()メソッド2つのキューブマップをブレンド

関連スキル

  • unity-graphics -- レンダーパイプライン(URP/HDRP/Built-in)、シェーダー、マテリアル、カメラ
  • unity-2d -- 2D ライティング(URP 2D Renderer)、スプライトのレンダリング
  • unity-platforms -- プラットフォーム別のライティング品質設定、モバイル最適化

Additional Resources

コメント