粒子を発光させ、周囲に光を当てるにはどうすればよいですか?


22

私は現在、暗い森でホタル効果を作ろうとしています。レベルには非常に低い光があり、プレーヤーは数少ない光源の1つです。プレイヤーにレベルを見やすくさせるために、輝くホタルがマップ上にランダムに表示されるようにしています。1つの方法は、パーティクルシステムを使用することです。しかし、私は粒子が周囲に光を投​​げかけることはできません。これを行う方法はありますか?


3
ここでの本当の問題は、「光は高価です」ということです。恐ろしく高価な数十の動的ライトを使用するよりも、エリアを十分に照らすライトをいくつかの固定点ライトに配置し、ライトをライトマップに焼き付けてから、パーティクルを使用して光源がどこから来たかを説明する方が良いかもしれません。
Draco18s

@ Draco18s数十匹のホタルはいません。プレーヤーのビュー内にのみ表示されます。それはトップダウンであり、制御が簡単です。また、常に10匹未満のホタルがいるはずです。10個のダイナミックポイントライトが高価だとは思いませんか?
DarkDestry

デフォルトでは、Unityは一度に2つのアクティブなダイナミックライトのみをジオメトリに照らします(2Dセットアップでは異なる場合があります)。もちろんこれを増やすことができますが、+ 1の光はドローコールに2倍の影響があることに注意してください。
Draco18s

2
@ Draco18sこれはフォワードレンダリングパスに当てはまる場合がありますが、ドキュメント「遅延シェーディングを使用する場合、オブジェクトに影響を与えることができるライトの数に制限はありません」に述べられているように画面はまさに、ユースケースの種類であり、遅延レンダリングパスは効率的な処理に優れています。(1回の引き分けのユニークな光あたりの呼び出しではなく、前方レンダリングと同様に乗算器の典型的なコストで)
DMGregory

それは良い点です。ほとんどの場合、さまざまなレンダリングパスを忘れてしまいます。
Draco18s

回答:


7

発光粒子は、5.5のUnity機能に組み込まれました。

パーティクルインスペクタでライトを有効にし、ライトプレハブへの参照を挿入し(ポイントライトとスポットライトの両方が機能します)、比率を1に変更します。

ここに画像の説明を入力してください

そして、ボイラ、光を発する粒子: ![ここに画像の説明を入力してください

結局のところ、これはかなり最適化されたセットアップであり、数百の最大ライトでも、リグで1500 + fpsで実行されます。

編集:いくつかの観察の後、パーティクルライトはフラグメントごとのライティングと頂点ライティングの間でトグルするようです(おそらく最適化のため?)。最大ライトの設定が高すぎる場合、これにより視覚的なアーティファクトが少量発生する可能性があります。

Edit2:DMGregoryが指摘したように、アーティファクトは前方レンダリングの最適化の副産物です。遅延照明は問題を解決します。より良いgifを追加


1
それは朗報です!:)この回答には、新しいパーティクルシステム機能を使用してこれを設定する方法についての段階的な手順が含まれていれば、さらに良いでしょう。
DMGregory

1
表示されている頂点ライティングの動作は、Unityがフォワードレンダリングで適用する最適化の一部に少し似ています。遅延パスを使用すると、同じ動作が見られますか?
DMGregory

あなたが正しい!遅延レンダリングパスを使用する場合、アーティファクトはもう存在しません。
eclmist

31

注意喚起:

この答えは時代遅れです。Unityは、ポイントライトパーティクルをネイティブにサポートするようになりました。詳細については、この回答をご覧ください。

好奇心が強い人、古いバージョンのUnityを使用している人、またはネイティブメソッドが提供するよりも多くの手動制御が必要な人のために、ここに投稿します-ネイティブサポートは、以下に示すアプローチよりもはるかに効率的でスケーラブルであることに注意してください。


多くの回答がこれが困難または不可能であると主張する理由はわかりません。数十個のダイナミックポイントライトの処理は、PC上で実行される最新の遅延レンダリングパイプラインではかなり慣習です。

これが私が作成した簡単な例です: ライト付きホタルの例

このスクリプトを使用して、最大パーティクルに十分なライトを動的に生成し(パーティクルシステムの設定を調整して、最大値が妥当であるようにします-デフォルトの1000はグラフィックカードを非常に満足させません)、その後、アクティブに追従するように更新します粒子:

[RequireComponent(typeof(ParticleSystem))]
public class ParticleLights : MonoBehaviour {

    public Light lightPrefab;

    ParticleSystem _system;
    ParticleSystem.Particle[] _particles;
    Light[] _lights;


    void Start () {
        _system = GetComponent<ParticleSystem>();
        _particles = new ParticleSystem.Particle[_system.maxParticles];

        _lights = new Light[_system.maxParticles];
        for(int i = 0; i < _lights.Length; i++)
        {
            _lights[i] = (Light)Instantiate(lightPrefab);
            _lights[i].transform.parent = transform;
        }
    }

    void Update () {

        int count = _system.GetParticles(_particles);
        for(int i = 0; i < count; i++)
        {
            _lights[i].gameObject.SetActive(true);
            _lights[i].transform.localPosition = _particles[i].position;

            // Looks like the GetCurrentColor function was added in 5.3.
            // You can use other methods in earlier Unity versions.
            _lights[i].color = _particles[i].GetCurrentColor(_system);
        }

        for (int i = count; i < _particles.Length; i++)
        {
            _lights[i].gameObject.SetActive(false);
        }
    }
}

編集:プレハブを作成するには、最初にゲームオブジェクトを作成し(この場合は、作成->ライト->ポイントライト)、必要な名前/パラメーター/スクリプト/子供を設定してから、階層からそれをドラッグします。プロジェクトエクスプローラー。これにより、オブジェクトが複数のシーンとスクリプトで再利用できる資産として保存され、ある程度の継承が可能になります。シーン内のコピーを削除すると、アセットはAssetsフォルダーに残り、必要なときに参照できます。

lightPrefabの範囲が比較的狭く、シャドウキャスティングではないことを確認してください。これにより、シーンで行われているすべてのことに対して最高のパフォーマンスの余裕が得られます。lightPrefab自体を緑(またはホタルの色)にする必要はありません-パーティクルの色から選択します。

説得力のあるふらつきを得るにはパーティクルシステムの芸術性よりも多くの時間がかかるため、ビルボードのクワッドとカスタムの移動/点滅スクリプトを添付したライトでそれぞれのGameObjectを作成すると、ホタルの飛行をよりよく制御できることがわかります知っている。;)


実際...ホタルにはシャドウキャスティングを使用しないように言ったが、サンプルシーンでシャドウキャスティングをオンにしただけで、問題は発生しなかった。ホタルがオブジェクトを通過するときの影の揺れ方は本当にクールで、不気味な雰囲気を増す可能性があります。走行距離はシーンの複雑さとターゲットハードウェアによって異なる場合があるため、プロファイルを確認してください。ただし、これは私の側での最適化が早すぎる場合です。:)
DMGregory

軽いプレハブをどのように作成しますか?
DarkDestry

また、何らかの理由で、ParticleSystem.Particleはレガシーパーティクルを参照します。GetCurrentColorまたはGetCurrentSizeメソッドはありません。
DarkDestry

@DarkDestryプレハブの作成に関する回答にメモを追加しました。欠落している機能に関しては、これはバージョンの問題である可能性があります-5.3で作業していますが、Unityの以前のバージョンでは、これを別の方法で行うことができます。Hamza Hasanが親切に作成した部屋を使用して、実装の詳細をchat議論しましょう
DMGregory

そのため、軽いプレハブは通常のプレハブと同じです。軽いプレハブとして言及されたときに混乱しました。
DarkDestry

3

数年前、ダイナミックライトが手頃な価格になる前に、単純に2Dビルボードのパーティクルエフェクトを加算ブレンドで使用していました。シーンを白に向かって明るくします。ホタルの正しい深さで描画することにより、ほぼ正しい並べ替えが得られます。アルファブレンディングと比較して、自身をオーバードローする場合、加算アルファはソートを必要としません。すべてのシーンを照らすわけではありませんが、ホタルの周囲を照らします。必要に応じて、ダイナミックライトを使用して、数秒ごとにホタルの1つを選択して実際にシーンを照らすことができます。

グロー効果についての質問と回答が既にあります2DゲームのUnityでこのような照明を実現する方法は?


0

残念ながら、現在の形式ではUnityの経験があまりないので(何年も前に操作してみました)、エンジンでどの機能セットを使用する必要があるのか​​正確にはわかりません。

いずれにせよ、使用するエンジンに関係なく、ダイナミックライトは可能な限り避けるべきものです。それらは非常に計算コストが高く、非常に指数関数的な方法でシーンの複雑さを追加する傾向があります。ただし、ほとんどの3Dレンダリングの順序と同様に、不正行為によって同様の効果を達成できる方法は多数あります。

同様の効果を実現する可能な方法は、事前に作成されたグローテクスチャをホタルの下の地形にマッピングすることです(Y =上下座標系を想定)、X位置とZ位置が地形のグローの位置とYオフセットを制御しますテクスチャのアルファを制御する地形から(より明るい=地形により近い)

もちろん、この方法にはいくつかの欠点があります。ライトが使用されていないので影を落とさず、世界の他のジオメトリ(小道具、葉など)に影響を与えません。


-2

火の元Lightで使用し、スクリプトでそのサイズで再生して、燃焼の効果を与えます。そして、あなたのパーティクルシステムを使用してください:)


シーンには火災はありません。希少な粒子を持っているイムは、存在の内外に現れます。粒子の固定位置はまったくありません。質問を読んでください。
DarkDestry

だから、契約は何ですか?あなたは、事前定義された位置にプレハブではなく、あなたの粒子に光を添付することができます
ハムザ・ハサン

問題は、これを行う方法です。私はUnityのパーティクルシステムを使用しています。そして、私はそこにプレハブを見ません。あなただけの光を持っており、スクリプトに塩基を発生プレハブ作成するために私を求めている場合を除き
DarkDestry

したがって、シーンにパーティクルgameObjectがあります。同じゲームオブジェクトにライトをアタッチし、そのgameObjectをUnity File Explorerにドラッグしてプレハブを作成します。
ハムザ・ハサン

シーンにパーティクルシステムのgameObjectがあります。粒子ではありません。
DarkDestry
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.