私は現在、暗い森でホタル効果を作ろうとしています。レベルには非常に低い光があり、プレーヤーは数少ない光源の1つです。プレイヤーにレベルを見やすくさせるために、輝くホタルがマップ上にランダムに表示されるようにしています。1つの方法は、パーティクルシステムを使用することです。しかし、私は粒子が周囲に光を投げかけることはできません。これを行う方法はありますか?
私は現在、暗い森でホタル効果を作ろうとしています。レベルには非常に低い光があり、プレーヤーは数少ない光源の1つです。プレイヤーにレベルを見やすくさせるために、輝くホタルがマップ上にランダムに表示されるようにしています。1つの方法は、パーティクルシステムを使用することです。しかし、私は粒子が周囲に光を投げかけることはできません。これを行う方法はありますか?
回答:
発光粒子は、5.5のUnity機能に組み込まれました。
パーティクルインスペクタでライトを有効にし、ライトプレハブへの参照を挿入し(ポイントライトとスポットライトの両方が機能します)、比率を1に変更します。
結局のところ、これはかなり最適化されたセットアップであり、数百の最大ライトでも、リグで1500 + fpsで実行されます。
編集:いくつかの観察の後、パーティクルライトはフラグメントごとのライティングと頂点ライティングの間でトグルするようです(おそらく最適化のため?)。最大ライトの設定が高すぎる場合、これにより視覚的なアーティファクトが少量発生する可能性があります。
Edit2:DMGregoryが指摘したように、アーティファクトは前方レンダリングの最適化の副産物です。遅延照明は問題を解決します。より良いgifを追加
この答えは時代遅れです。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を作成すると、ホタルの飛行をよりよく制御できることがわかります知っている。;)
数年前、ダイナミックライトが手頃な価格になる前に、単純に2Dビルボードのパーティクルエフェクトを加算ブレンドで使用していました。シーンを白に向かって明るくします。ホタルの正しい深さで描画することにより、ほぼ正しい並べ替えが得られます。アルファブレンディングと比較して、自身をオーバードローする場合、加算アルファはソートを必要としません。すべてのシーンを照らすわけではありませんが、ホタルの周囲を照らします。必要に応じて、ダイナミックライトを使用して、数秒ごとにホタルの1つを選択して実際にシーンを照らすことができます。
グロー効果についての質問と回答が既にあります2DゲームのUnityでこのような照明を実現する方法は?
残念ながら、現在の形式ではUnityの経験があまりないので(何年も前に操作してみました)、エンジンでどの機能セットを使用する必要があるのか正確にはわかりません。
いずれにせよ、使用するエンジンに関係なく、ダイナミックライトは可能な限り避けるべきものです。それらは非常に計算コストが高く、非常に指数関数的な方法でシーンの複雑さを追加する傾向があります。ただし、ほとんどの3Dレンダリングの順序と同様に、不正行為によって同様の効果を達成できる方法は多数あります。
同様の効果を実現する可能な方法は、事前に作成されたグローテクスチャをホタルの下の地形にマッピングすることです(Y =上下座標系を想定)、X位置とZ位置が地形のグローの位置とYオフセットを制御しますテクスチャのアルファを制御する地形から(より明るい=地形により近い)
もちろん、この方法にはいくつかの欠点があります。ライトが使用されていないので影を落とさず、世界の他のジオメトリ(小道具、葉など)に影響を与えません。
火の元Light
で使用し、スクリプトでそのサイズで再生して、燃焼の効果を与えます。そして、あなたのパーティクルシステムを使用してください:)