¿Cómo puedo hacer que las partículas brillen y arrojen luz sobre sus alrededores?

22

Actualmente estoy intentando hacer un efecto de luciérnaga en un bosque oscuro. El nivel tiene muy poca luz y el jugador es una de las pocas fuentes de luz. Para permitir que el jugador vea mejor el nivel, estoy tratando de hacer que las luciérnagas brillantes aparezcan al azar en el mapa. Una forma es usar un sistema de partículas. Pero no puedo hacer que las partículas arrojen luz sobre los alrededores. ¿Hay alguna forma de hacer esto?

DarkDestry
fuente
3
El verdadero problema aquí es que "la luz es cara". Puede que sea mejor colocar algunas luces de punto fijo que iluminen el área lo suficiente, hornear las luces en un mapa de luz, luego usar las partículas para explicar de dónde proviene la fuente de luz, en lugar de usar docenas de luces dinámicas horriblemente caras.
Draco18s
@ Draco18s No habrá docenas de luciérnagas. Solo aparecerán dentro de la vista del jugador. Es de arriba hacia abajo y, como tal, fácil de controlar. Y en un momento dado solo debería haber menos de 10 luciérnagas. ¿Supongo que 10 puntos dinámicos de luz son caros?
DarkDestry
De manera predeterminada, Unity solo permite que dos luces dinámicas activas iluminen la geometría a la vez (aunque puede ser diferente para una configuración 2D). Puede aumentar esto, por supuesto, pero tenga en cuenta que +1 luz es x2 impacto en las llamadas de sorteo.
Draco18s
2
@ Draco18s esto puede ser cierto para la ruta de renderizado hacia adelante, pero como se indica en los documentos "Cuando se usa sombreado diferido, no hay límite en la cantidad de luces que pueden afectar un objeto" - Muchas luces pequeñas que afectan solo una pequeña porción de la pantalla es exactamente el tipo de uso diferido de las rutas de representación diferidas en el manejo eficiente. (Con un costo típico de una llamada de sorteo por luz única, en lugar de un multiplicador como con el renderizado hacia adelante)
DMGregory
Ese es un buen punto. Me olvido de las diferentes rutas de renderizado la mayor parte del tiempo.
Draco18s

Respuestas:

7

Las partículas que emiten luz ahora son una característica incorporada de Unity en 5.5.

Simplemente habilite Luces en el inspector de partículas, agregue una referencia a un prefabricado de luz (funcionan tanto las luces puntuales como puntuales) y cambie la Relación a 1.

ingrese la descripción de la imagen aquí

Y voilà, partículas que emiten luces: ! [ingrese la descripción de la imagen aquí

Resulta que esta es una configuración bastante optimizada, que funciona a 1500 + fps en mi plataforma incluso con la máxima cantidad de luces en cientos.

Editar: después de algunas observaciones, me parece que las luces de partículas alternan entre la iluminación por fragmento y la iluminación de vértices (¿presumiblemente para la optimización?). Esto podría producir pequeñas cantidades de artefactos visuales si las luces máximas se configuran demasiado altas.

Edit2: como señaló DMGregory, los artefactos son un subproducto de las optimizaciones de renderizado directo. La iluminación diferida resuelve el problema. Añadido mejor gif

eclmist
fuente
1
¡Esas son buenas noticias! :) Esta respuesta sería aún mejor si incluyera algunas instrucciones paso a paso sobre cómo configurar esto con las nuevas características del sistema de partículas.
DMGregory
1
El comportamiento de iluminación de vértices que estás viendo suena un poco como algunas de las optimizaciones que Unity aplica en el renderizado hacia adelante. ¿Ves el mismo comportamiento cuando usas la ruta diferida?
DMGregory
¡Tienes razón! Los artefactos ya no están presentes cuando se utiliza la ruta de representación diferida.
eclmist
31

Aviso:

Esta respuesta está desactualizada. Unity ahora admite partículas de luz puntuales de forma nativa Por favor, vea esta respuesta para más detalles.

Dejaré esto aquí para cualquier persona curiosa, o que use versiones antiguas de Unity, o que necesite más control manual que el que ofrece el método nativo; solo tenga en cuenta que es probable que el soporte nativo sea mucho más eficiente y escalable que el enfoque presentado a continuación.


No estoy seguro de por qué tantas respuestas afirman que esto es difícil o imposible. Manejar unas pocas docenas de luces de puntos dinámicos es bastante convencional para una tubería de renderizado diferido moderna que se ejecuta en PC.

Aquí hay un ejemplo rápido que preparé: Ejemplo de luciérnagas con luces

Utilizo este script para generar dinámicamente suficientes luces para mis partículas máximas (asegúrese de ajustar la configuración del sistema de partículas para que el máximo sea razonable: el valor predeterminado de 1000 no hará que su tarjeta gráfica sea muy feliz), y luego las actualiza para seguir el activo partículas:

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

Editar: puede crear un prefabricado creando primero un objeto de juego (en este caso, Crear -> Luz -> Luz de punto), configurándolo con el nombre / parámetros / scripts / niños que desee, luego arrastrándolo desde su Jerarquía a su explorador de proyectos. Esto guarda el objeto como un activo que puede reutilizar en múltiples escenas y guiones, con un cierto grado de herencia. Puede eliminar la copia en su escena y el activo permanecerá en su carpeta de Activos para que se haga referencia cuando sea necesario.

Asegúrese de que lightPrefab tenga un rango relativamente pequeño y no esté proyectando sombras, para darle el mayor margen de rendimiento para todo lo que sucede en su escena. No necesita hacer que el lightPrefab sea verde (o el color de sus luciérnagas): lo recogerá del color de las partículas.

Sin embargo, es posible que tenga un mejor control sobre el vuelo de las luciérnagas si hace que cada uno tenga su propio GameObject, con un quad vallado y una luz adjunta con un script de movimiento / parpadeo personalizado, ya que obtener un recorrido convincente requiere más arte del sistema de partículas que Lo sé. ;)

DMGregory
fuente
En realidad ... aunque dije que no usara el shadowcasting para las luciérnagas, intenté encenderlo en mi escena de ejemplo y no causó ningún problema. La forma en que las sombras se balancean cuando las luciérnagas pasan objetos es realmente genial, y podría agregarse a una atmósfera espeluznante. Su kilometraje puede variar en función de la complejidad de su escena y su hardware de destino, por lo que el perfil es seguro, pero esto podría ser un caso de optimización prematura de mi parte. :)
DMGregory
¿Cómo se crea un prefabricado ligero?
DarkDestry
Además, por alguna razón, ParticleSystem.Particle se refiere a la partícula heredada. No hay un método GetCurrentColor o GetCurrentSize para ello.
DarkDestry
@DarkDestry He agregado una nota a la respuesta sobre la creación de prefabricados. En cuanto a las funciones que faltan, esto podría ser un problema de versión: estoy trabajando en 5.3, en versiones anteriores de Unity podría hacerlo de una manera diferente. Analicemos los detalles de implementación en el chat , utilizando la sala que Hamza Hasan creó amablemente.
DMGregory
Entonces, un prefabricado ligero es lo mismo que un prefabricado normal. Estaba confundido cuando se menciona como un prefabricado ligero.
DarkDestry
3

Hace años, antes de que las luces dinámicas fueran asequibles, simplemente usábamos un efecto de partículas 2D-billboarded con mezcla aditiva. Iluminaría la escena hacia el blanco. Al dibujarlo con la profundidad correcta de la luciérnaga, obtienes una clasificación casi correcta. El alfa aditivo no necesita ser ordenado cuando se sobre dibuja en comparación con la mezcla alfa. No iluminará TODA la escena, pero iluminará el área que rodea a la luciérnaga. A continuación, puede tomar una luz dinámica y elegir una de las luciérnagas cada pocos segundos para iluminar la escena, si la necesita.

Ya hay una pregunta y respuesta sobre los efectos de brillo ¿Cómo lograr una iluminación como esta en Unity para juegos 2D?

Steven
fuente
0

Desafortunadamente, no he tenido mucha experiencia con Unity en su forma actual (jugué con él hace muchos años), por lo que no sé exactamente con qué conjuntos de características tiene que trabajar en el motor.

En cualquier caso, no importa con qué motor trabaje, las luces dinámicas son algo que debe evitar siempre que pueda. Son muy costosos computacionalmente y tienden a agregar complejidad de escena de una manera muy exponencial. Sin embargo, como es el orden del día para la mayoría de los renderizados en 3D, hay muchas maneras en que puede lograr efectos similares haciendo trampa;

Una posible forma de lograr un efecto similar es mapear una textura de brillo prefabricada en el terreno debajo de sus luciérnagas, (suponiendo un sistema de coordenadas Y = arriba / abajo) con las posiciones X y Z que controlan la ubicación del brillo en el terreno y el desplazamiento Y desde el terreno que controla el alfa de la textura (más brillante = más cerca del terreno)

Por supuesto, hay varios inconvenientes para este método. No proyectará sombras ya que no se utiliza luz, y no afectará ninguna otra geometría en el mundo (accesorios, follaje, etc.)

JonBee
fuente
-2

Úselo Lighten el origen del fuego y juegue con su tamaño en el guión para que tenga el efecto de quemar. Y usa tu sistema de partículas :)

Hamza Hasan
fuente
No hay fuego en la escena. Tengo escasas partículas que aparecen dentro y fuera de la existencia. No hay una posición fija para las partículas en absoluto. Por favor lea la pregunta.
DarkDestry
Entonces, ¿cuál es el trato? puedes colocar luz en tu prefabricado de partículas en lugar de hacerlo en posiciones predefinidas
Hamza Hasan
La pregunta es cómo hacer esto. Estoy usando el sistema de partículas de la unidad. Y no veo un prefabricado allí. A menos que me pidas que solo cree un prefabricado que tenga una luz y genere una base en el script
DarkDestry
Entonces tienes un juego de partículas en la escena. Adjunte una luz al mismo objeto del juego y haga que sea prefabricada arrastrando ese GameObject al Unity File Explorer.
Hamza Hasan
Tengo un GameObject de Particle System en la escena. No es una partícula
DarkDestry