Comment puis-je faire briller les particules et éclairer son environnement?

22

Im essayant actuellement de faire un effet luciole sur une forêt sombre. Le niveau a une lumière très faible et le lecteur est l'une des rares sources de lumière. Pour permettre au joueur de mieux voir le niveau, j'essaie de faire apparaître des lucioles brillantes au hasard sur la carte. Une façon consiste à utiliser un système de particules. Mais je ne peux pas faire jaillir les particules dans l'environnement. Y a-t-il un moyen de faire cela?

DarkDestry
la source
3
Le vrai problème ici est que «la lumière coûte cher». Il serait préférable de placer des lumières à point fixe qui éclairent suffisamment la zone, de faire cuire les lumières dans une carte lumineuse, puis d'utiliser les particules pour expliquer d'où vient la source de lumière, plutôt que d'utiliser des dizaines de lumières dynamiques horriblement chères.
Draco18s
@ Draco18s Il ne va pas y avoir des dizaines de lucioles. Ils n'apparaîtront qu'à la vue du joueur. Il est descendant et facile à contrôler. Et à tout moment, il ne devrait y avoir que moins de 10 lucioles. Je ne pense pas que 10 points dynamiques soient chers?
DarkDestry
Par défaut, Unity ne laisse que deux lumières dynamiques actives éclairer la géométrie à la fois (bien que cela puisse être différent pour une configuration 2D). Vous pouvez bien sûr augmenter cela, mais gardez à l'esprit que +1 lumière est un impact x2 sur les appels de tirage.
Draco18s
2
@ Draco18s, cela peut être vrai pour le chemin de rendu vers l'avant, mais comme indiqué dans les documents "Lors de l'utilisation de l'ombrage différé, il n'y a pas de limite sur le nombre de lumières qui peuvent affecter un objet" - Beaucoup de petites lumières qui n'affectent qu'une petite partie de l'écran est exactement le type de cas d'utilisation que les chemins de rendu différé excellent à gérer efficacement. (Au coût typique d'un appel de tirage par lumière unique, plutôt que d'un multiplicateur comme avec le rendu direct)
DMGregory
C'est un bon point. J'oublie les différents chemins de rendu la plupart du temps.
Draco18s

Réponses:

7

Les particules électroluminescentes sont désormais intégrées à la fonctionnalité Unity de la 5.5.

Activez simplement les lumières dans l'inspecteur de particules, ajoutez une référence à un préfabriqué de lumière (les lumières ponctuelles et spot fonctionnent) et modifiez le rapport à 1.

entrez la description de l'image ici

Et voilà, les particules qui émettent des lumières: ! [entrez la description de l'image ici

Il s'avère que c'est une configuration plutôt optimisée, fonctionnant à 1500 + fps sur ma plate-forme même avec un maximum de lumières par centaines.

Edit: Après quelques observations, il me semble que les lumières des particules basculent entre l'éclairage par fragment et l'éclairage par sommet (probablement pour l'optimisation?). Cela peut produire de petites quantités d'artefacts visuels si le maximum de lumières est réglé trop haut.

Edit2: Comme l'a souligné DMGregory, les artefacts sont un sous-produit des optimisations de rendu direct. Un éclairage différé résout le problème. Gif plus agréable ajouté

eclmist
la source
1
C'est une bonne nouvelle! :) Cette réponse serait encore meilleure si elle incluait des instructions étape par étape sur la façon de configurer cela avec les nouvelles fonctionnalités du système de particules.
DMGregory
1
Le comportement d'éclairage des sommets que vous voyez ressemble un peu à certaines des optimisations qu'Unity applique dans le rendu direct. Voyez-vous le même comportement lorsque vous utilisez le chemin différé?
DMGregory
Tu as raison! Les artefacts ne sont plus présents lors de l'utilisation du chemin de rendu différé.
eclmist
31

La tête haute:

Cette réponse est dépassée. Unity prend désormais en charge les particules de lumière ponctuelle de manière native. Veuillez consulter cette réponse pour plus de détails.

Je laisserai cela ici pour toute personne curieuse, ou utilisant d'anciennes versions de Unity, ou ayant besoin de plus de contrôle manuel que la méthode native n'offre - notez simplement que le support natif est probablement beaucoup plus efficace et évolutif que l'approche présentée ci-dessous.


Je ne sais pas pourquoi tant de réponses affirment que c'est difficile ou impossible. La gestion de quelques dizaines de lumières ponctuelles dynamiques est assez classique pour un pipeline de rendu différé moderne fonctionnant sur PC.

Voici un exemple rapide que j'ai concocté: Exemple de lucioles avec des lumières

J'utilise ce script pour générer dynamiquement suffisamment de lumières pour mes particules maximales (assurez-vous d'ajuster les paramètres de votre système de particules afin que le maximum soit raisonnable - la valeur par défaut de 1000 ne rendra pas votre carte graphique très heureuse), puis les met à jour pour suivre l'actif particules:

[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);
        }
    }
}

Modifier: vous pouvez créer un préfabriqué en créant d'abord un objet de jeu (dans ce cas, Créer -> Lumière -> Lumière ponctuelle), en le configurant avec le nom / paramètres / scripts / enfants que vous voulez, puis en le faisant glisser de votre hiérarchie vers votre explorateur de projets. Cela enregistre l'objet en tant qu'actif que vous pouvez réutiliser sur plusieurs scènes et scripts, avec un certain degré d'héritage. Vous pouvez supprimer la copie dans votre scène et l'actif restera dans votre dossier Assets pour être référencé en cas de besoin.

Assurez-vous que le lightPrefab a une plage relativement petite et n'est pas un shadowcasting, pour vous donner la marge la plus performante pour tout ce qui se passe dans votre scène. Vous n'avez pas besoin de rendre le lightPrefab lui-même vert (ou la couleur de vos lucioles) - il le ramassera de la couleur des particules.

Vous constaterez peut-être que vous avez un meilleur contrôle sur le vol des lucioles si vous créez chacun son propre GameObject, avec un quadruple panneau d'affichage et une lumière attachée avec un script de mouvement / clignotement personnalisé, car obtenir une déambulation convaincante prend plus de talent pour le système de particules que Je sais. ;)

DMGregory
la source
En fait ... même si j'ai dit de ne pas utiliser le shadowcasting pour les lucioles, j'ai juste essayé de l'activer dans ma scène d'exemple et cela n'a posé aucun problème. La façon dont les ombres se balancent lorsque les lucioles passent devant des objets est vraiment cool et pourrait ajouter une atmosphère effrayante. Votre kilométrage peut varier en fonction de la complexité de votre scène et de votre matériel cible, donc profil pour être sûr, mais cela pourrait être un cas d'optimisation prématurée de ma part. :)
DMGregory
Comment créez-vous un préfabriqué léger?
DarkDestry
De plus, pour une raison quelconque, ParticleSystem.Particle fait référence à la particule héritée. Il n'y a pas de méthode GetCurrentColor ou GetCurrentSize pour cela.
DarkDestry
@DarkDestry J'ai ajouté une note à la réponse sur la création de préfabriqués. En ce qui concerne les fonctions manquantes, cela pourrait être un problème de version - je travaille dans 5.3, dans les versions antérieures de Unity, vous pourriez le faire d'une manière différente. Discutons des détails de mise en œuvre dans le chat , en utilisant la salle que Hamza Hasan a gentiment créée.
DMGregory
Un préfabriqué léger est donc le même qu'un préfabriqué normal. A été confondu quand il est mentionné comme un préfabriqué léger.
DarkDestry
3

Il y a des années, avant que les lumières dynamiques ne soient abordables, nous utilisions simplement un effet de particules à panneau d'affichage 2D avec un mélange additif. Cela éclaircirait la scène vers le blanc. En le dessinant avec la bonne profondeur de la luciole, vous obtenez un tri presque correct. L'alpha additif n'a pas besoin d'être trié lors du sur-retrait par rapport au mélange alpha. Il n'éclairera pas TOUTE la scène, mais il éclairera la zone entourant la luciole. Vous pouvez ensuite prendre une lumière dynamique et choisir l'une des lucioles toutes les quelques secondes pour éclairer réellement la scène, si vous en avez besoin.

Il y a déjà une question et une réponse sur les effets de lueur Comment obtenir un éclairage comme celui-ci dans Unity pour les jeux 2D?

Steven
la source
0

Malheureusement, je n'ai pas beaucoup d'expérience avec Unity dans sa forme actuelle (je l'ai joué il y a de nombreuses années), donc je ne sais pas exactement avec quels jeux de fonctionnalités vous devez travailler dans le moteur.

Dans tous les cas, quel que soit le moteur avec lequel vous travaillez, les lumières dynamiques sont à éviter chaque fois que vous le pouvez. Ils sont très coûteux en termes de calcul et ont tendance à ajouter une complexité de scène de manière très exponentielle. Cependant, comme c'est le cas pour la plupart des rendus 3D, il existe de nombreuses façons d'obtenir des effets similaires en trichant;

Un moyen possible d'obtenir un effet similaire consiste à mapper une texture de lueur prédéfinie sur le terrain sous vos lucioles (en supposant un système de coordonnées Y = haut / bas) avec des positions X et Z contrôlant l'emplacement de la lueur sur le terrain et le décalage Y du terrain contrôlant l'alpha de la texture (plus lumineux = plus proche du terrain)

Il existe bien sûr plusieurs inconvénients à cette méthode. Vous ne projetterez pas d'ombres car aucune lumière n'est utilisée, et vous n'affecterez aucune autre géométrie dans le monde (accessoires, feuillage, etc.)

JonBee
la source
-2

Utilisez-le Lightà l'origine du feu et jouez avec sa taille dans le script pour qu'il donne un effet de gravure. Et utilisez votre système de particules :)

Hamza Hasan
la source
Il n'y a pas de feu dans la scène. J'ai des particules rares qui apparaissent dans et hors de l'existence. Il n'y a pas du tout de position fixe pour les particules. Veuillez lire la question.
DarkDestry
Alors, quel est l'affaire? vous pouvez attacher de la lumière à votre préfabriqué de particules plutôt qu'à des positions prédéfinies
Hamza Hasan
La question est de savoir comment procéder. J'utilise le système de particules de l'unité. Et je ne vois pas de préfabriqué là-bas. À moins que vous ne me demandiez de créer un préfabriqué qui a une lumière et de générer une base sur script
DarkDestry
Vous avez donc gameObject de particules dans la scène. Attachez une lumière au même objet de jeu et faites-en un préfabriqué en faisant glisser ce gameObject vers Unity File Explorer.
Hamza Hasan
J'ai un système de particules gameObject dans la scène. Pas une particule.
DarkDestry