Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Propiedades De Sistemas De Partículas

Iniciado por CoLSoN2, 19 de Septiembre de 2005, 10:31:02 AM

« anterior - próximo »

CoLSoN2

 Quiero implementar un buen motor de sistemas de partículas (2D) en mi engine, con su editor y tal, y me gustaría hacer una lista extensa de todas las propiedades o features que podría ponerle. Cosas que hayáis visto por ahí o hayáis hecho vosotros mismos alguna vez, cualquier cosa vale.

De momento tengo las cosas básicas:

Propiedades de partícula:
- Imagen/Textura
- Tamaño*
- Color de blending + Alpha*
- Rotación*
- Velocidad inicial (min, max)
- Aceleración

Propiedades del emisor:
- Posición
- Tipo (circulo, donut, cuadrado, línea, punto)
- Ratio de emisión (partículas por segundo)
- Tiempo de vida

*(el inicial, el final y el método de interpolación (linear, bezier, senoidal..))

En cuanto a propiedades del emisor, en el thread sobre el editor de partículas del Haddd creo recordar que se habló de otra propiedad cuyo nombre no recuerdo que determinaba si las partículas se iban emitiendo constantemente o "a golpes". Si alguien sabe explicarlo mejor y ya de paso explicar como funciona, lo agradecería.

Además de eso y de lo que ya tengo listado, a alguien se le ocurren más propiedades? Lo de que colisionen o no lo tengo descartado porque supondría un overhead bastante grande.

Un saludo
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

Haddd

 El sistema está desarrollado enteramente por BerserKer, además ahora lo está modificando para incorporarlo al visor. Seguro que te explica lo que necesites  ;)  

Ithaqua

 -Tipo de blending (alpha blending o aditivo). Un humo sería con el primero, un fuego con el segundo.
-Duracion de la emision (p.ej que emita solamente durante los primeros n segundos y luego deje de emitir).
-Propiedades de modo burbuja (las particulas además de ir en dirección de salida, se mueven oscilando como burbujas en el eje): amplitud, periodo y fase.
-Ángulos de apertura de emisión (0-360º). Yo lo modelo con 2. Si por ejemplo pongo solo uno a 180º sería un abanico. Los 2 a 30º una fuente. Los 2 a 360 una explosión de fuegos artificiales etc.
-Puntero al nodo al que están linkados. Si no hay nodo emiten desde su posicion, sino desde la del nodo.

Un consejo es que permitas especificar un parámetro adicional que indique el nivel de caos de cada variable. Cuando asigno un parámetro del sistema, aparte puedo especificar otro que indica eso. Si vale 0.0 es que hay uniformidad, si vale 1.0 es que tiene caos máximo.

Por ejemplo si tienes un sistema de partículas con un parámetro de vida de 2 segundos y 0.0 de caos, todas valdrían 2 al salir.
Si especificas de caos un 0.2 tendrían un valor aleatorio en el rango  [2 - 2(*0.2), 2 + 2*(0.2)] osea [1.6, 2.4]. Con caos máximo sería [0, 4].
Eso viene bien porque los sistemas de partículas en general quedan demasiado uniformes cuando todas las partículas tienen el mismo valor. Simplemente añadiendo un poco de caos en la velocidad y vida hace que el sistema quede mucho más bonito visualmente, y a veces es necesario hacerlo para que el resultado quede como tú quieres.

SetSpeed(speed, caos)
SetLife(life, caos)  etc, todos las variables que tenga cada partícula individualmente.
thaqua^Stravaganza
http://ithaqua.stravaganza.org

CoLSoN2

 
Citar-Tipo de blending (alpha blending o aditivo). Un humo sería con el primero, un fuego con el segundo.
Cierto, un clásico que se me escapó.

Citar-Duracion de la emision (p.ej que emita solamente durante los primeros n segundos y luego deje de emitir).
Esto lo tengo por vida del emisor. Es decir, cuando termina su vida las particulas que están aún vivas no se mueren al instante, simplemente se deja de emitir.

Citar-Propiedades de modo burbuja (las particulas además de ir en dirección de salida, se mueven oscilando como burbujas en el eje): amplitud, periodo y fase.
Entonces los parámetros para este "modo burbuja" serían:
- [bool] activado
- [vec2] eje
- [float] amplitud
- [float] periodo
- [float] fase
Cierto? Y sería tan simple como un movimiento harmónico sobre ese eje, supongo.

Citar-Ángulos de apertura de emisión (0-360º). Yo lo modelo con 2. Si por ejemplo pongo solo uno a 180º sería un abanico. Los 2 a 30º una fuente. Los 2 a 360 una explosión de fuegos artificiales etc.
Esto es independiente de la forma del emisor (punto, circulo, rectangulo..), sino más bien respecto a la velocidad inicial, ¿no?

Citar-Puntero al nodo al que están linkados. Si no hay nodo emiten desde su posicion, sino desde la del nodo.
No tengo la escena organizada en un grafo, si es a lo que te refieres.

CitarUn consejo es que permitas especificar un parámetro adicional que indique el nivel de caos de cada variable. Cuando asigno un parámetro del sistema, aparte puedo especificar otro que indica eso. Si vale 0.0 es que hay uniformidad, si vale 1.0 es que tiene caos máximo.
Más que eso, había pensado en usar lo típico de (min, max) para cada valor de este tipo (vida, tamaño, etc.), aunque ambas formas sirven.

Por cierto, una pregunta que tengo sobre el tema de la aceleración, gravedad o los "affectors", cómo queráis llamarlos. Si en vez de una gravedad típica, que acelere las partículas hacia abajo, quiero algo como, por ejemplo, que vayan reduciendo su velocidad relativa al centro del emisor, como unos fuegos artificiales (que empiezan avanzando muy rápido pero van disminuyendo), cómo sería mejor simular esto?

- Separar la velocidad en dos parámetros, inicial y final, e interpolar?
- Crear algún sistema de clases Affector que influyan al emisor o las partículas y puedan ser añadidas como componentes?
- Otra idea
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

Lord Trancos 2

 Usa un vector velocidad actual, no uses uno de velocidad inicial + tiempo, y aplicales fisica de verdad :P

Echale un vistazo al ejemplo de Nehe:
http://nehe.gamedev.net/data/lessons/lesso...n.asp?lesson=39

Otra cosa que podria "molar", es que una particula pueda ser emisora a su vez de otras particulas.
on los años y mucho esfuerzo he llegado a atesorar una ignorancia total sobre casi todas las cosas.
Gate to Avalon (mi Blog)

CoLSoN2

Cita de: "Lord Trancos 2"Usa un vector velocidad actual, no uses uno de velocidad inicial + tiempo, y aplicales fisica de verdad :P
No entiendo a qué te refieres. ¿Podrías explicarlo mejor?

Citar
Echale un vistazo al ejemplo de Nehe:
http://nehe.gamedev.net/data/lessons/lesso...n.asp?lesson=39
No lo he leído entero, más bien le he echado un vistazo, pero parece más bien algo de físicas de partículas a nivel de cuerpos sólidos que no aplicado a sistemas de partículas en plan efecto gráfico, que es lo que yo quiero.

Citar
Otra cosa que podria "molar", es que una particula pueda ser emisora a su vez de otras particulas.
Estaría bien, pero creo que complicaría demasiado el diseño del sistema, teniendo en cuenta que no es una feature especialmente necesaria, aunque si que estaría bien que por ejemplo la clase Emitter derivara de Particle, y poder así Emitters que emitieran Emitters, y rizar el rizo. Alguna idea de cómo implementar esto elegantemente? Porque estoy seguro que desde el editor sería bastante complicado hacer estas "composiciones" extrañas, y me gustaría no tener que hardcodear nada.
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

BeRSeRKeR

 La propiedad que hace que las partículas salgan de forma intermitente, en Doom3 se denomina bunching pero no es más que definir un "birth rate constante" (birthRate = count / lifeTime) o especificado por el usuario. Así, si por ejemplo tenemos un sistema de partículas con 200 partículas y una vida de 2 segundos, si ponemos un birth rate constante, nos saldrán a emitir 100 partículas por segundo, mientras que si ponemos un birth rate variable de 200, en esos dos segundos, en el primer segundo se emitirán 200 partículas (el total del sistema) y en el siguiente segundo nada. Eso es lo que crea el "bunching".

Otra propiedad que no me ha parecido ver es el aspect ratio de la partícula, que no es ni más ni menos que para conseguir partículas no cuadradas. Este parámetro, al igual que la velocidad, el tamaño, etc, también tiene un valor inicial y otro final que se interpolará con el método especificado.

Por otro lado también tengo dos tipos de partículas, las que encaran a la cámara en los ejes XY (las típicas) y la partículas de tipo "aimed" (como se las llama en Doom3) que encaran a la cámara en un sólo eje. Estas últimas son ideales para simular chispas. Hay que tener en cuenta que con una partícula de un sólo quad, no podemos curvarla. Entonces con este nuevo tipo de partícula, entran en juego otras propiedades como el número de segmentos que conforman la partícula (cuantos más, mejor curvada quedará la partícula) y el tiempo de diferencia entre el segmento inicial y el final, que afectará a la longitud de la partícula. El efecto que se produce es como el de un muelle, cuando coge la mayor velocidad (por ejemplo cuando asciende o cae) se estira al máximo y cuando llega a la cúspide de la parábola (mínima velocidad), se estrecha al máximo.

Luego hay otros temas para mejorar las partículas que es un sistema basado en eventos como por ejemplo tiene el Particle Flow de MAX. Si tienes la oportunidad, échale un vistazo a la ayuda de MAX para más información. Pero bueno, como podrás imaginar, es como los eventos que se utilizan en la programación. Si se produce tal cosa, la partícula reacciona de tal forma. Por ejemplo, podemos poner un evento en las partículas que sea que si la partícula cumple cierta edad, se generen nuevas partículas a partir de ella (como ha comentado Lord Trancos), o que cambie de color...o cualquier cosa que se te ocurra.

Finalmente, otra cosa que quiero implementar son lo que en MAX se denomina space warps. Por ejemplo, en las primeras pruebas que llevo hechas, he añadido la fuerza de la gravedad, tanto esférica (fuerza gravitatoria) como direccional (fuerza de la gravedad terrestre) y tanto atractiva como repulsiva. Pero bueno, la cantidad de fuerzas que se pueden añadir son muy variadas. Por ejemplo en MAX tenemos viento, bomba de aire, tornado, deflectores, etc.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

[EX3]

 Yo tambien ando interesado en estos temas ultimamente, me habia parecido interesante añadir un sistema de particulas a la nueva version de la dx_lib32 pero ando algo pez en este tema y los dos ejemplos que tengo uno es muy sencillo (aunque algo es algo) y el otro es un paripe de codigo que me pierdo en el con tanta historia (el del SDK de DirectX). No sabeis de algun tutorial que exponga bien este tema y oriente lo suficiente para comprender e implementar este sistema?

Salu2...
José Miguel Sánchez Fernández
.NET Developer | Game Programmer | Unity Developer

Blog | Game Portfolio | LinkedIn | Twitter | Itch.io | Gamejolt

CoLSoN2

 BeRSeRKeR e Itaqua, que tenéis experiencia en impementar sistemas de partículas, creéis que vale la pena crear clases para emisores y partículas "muy básicas", por ejemplo, con un solo valor para tamaño/rotacion/color/etc en vez de un rango; o sin ningún parámetro "fuerza", e implementar esa funcionalidad mediante clases affector que modifiquen las partículas o los emisores al principio o durante su vida, y que se puedan añadir, quitar y crear nuevos fácilmente, sin tener que cambiar continuamente estas clases básicas? Es como lo hace Ogre y no me parece mal sistema.
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

TheAzazel

 A mi este tema tambien me interesa bastante.... estoy intento crear uno a ratos y lo que habeis puesto por aqui...mas lo que se pondra me servira porque estoy un poco ducho en este tema....

CoLSoN2

 He hecho un borrador de cómo podría ser la interfaz del sistema utilizando affectors. Como en el curro no puedo acceder al FTP lo pego aquí directamente. La jerarquía que quiero tener es la siguiente:

ParticleSystem es un SceneObject, un objeto de la escena, como un sprite u otra entidad visible del juego. Éste está compuesto de Emitters, que crean partículas, y Affectors, que las modifican. Lo que no tengo claro es si los affectors deberían ser a nivel de ParticleSystem (afectando a todos los Emitters) o a nivel de Emitter. ¿Qué opináis?

Espero que el formateo quede medianamente bien..

/// ----------------------------------------------------------------------------
/// Particle class
/// ----------------------------------------------------------------------------
class Particle
{
int  life
vector position
vector velocity
vector size
float mass
float rotation
Color color
bool additiveBlend
Emitter parent
}

class ImageParticle : Particle
{
Image* image
}

class AnimatedParticle : Particle
{
Animation* animation
}

class Spark : Particle
{
int  length
int  width
vector lastPos
}

/// ----------------------------------------------------------------------------
/// Emitter class
/// ----------------------------------------------------------------------------
class Emitter : Particle
{
enum Type
{
 POINT,
 LINE,
 CIRCLE,
 ARC,
 RECT
}

Type type
int  emitRate
int  bunching
float emitAngle
bool loop

void Start ()
void Update ()
void UpdateF (float theFrac)
void End  ()
Type GetType () const

vector GetPos () = 0
}

class PointEmitter : Emitter
{
vector GetPos()
{
 return position
}
}

class CircleEmitter : Emitter
{
float radius

vector GetPos()
{
 return PolarToCartesian(Rand(0, radius), Rand(0, emitAngle))
}
}

class ArcEmitter : Emitter
{
float radius

vector GetPos()
{
 ang = Rand(0, emitAngle)

 return radius * vector(cos(ang), sin(ang))
}
}

class LineEmitter : Emitter
{
vector a
vector b
vector dir
float  length

void Start()
{
 Emitter::Start()

 length = (b - a).length()
 dir = (b - a).normalise()
}
vector GetPos()
{
 return dir * Rand(0, length) + a
}
}

class RectEmitter : Emitter
{
vector extents // it's (width/2, height/2)

vector GetPos()
{
 return vector2(Rand(-extents.x, extents.x), Rand(-extents.y, extents.y))
}
}

/// ----------------------------------------------------------------------------
/// Affector class
/// ----------------------------------------------------------------------------
class Affector
{
void OnEmitParticle  (Particle* theParticle)
void OnUpdateParticle (Particle* theParticle)
void OnUpdateFParticle (Particle* theParticle, float theFrac)
}

class LinearForce  : Affector;
class ColorFader : Affector;
class SizeFader  : Affector;
class RotationFader : Affector;
class VelocityFader : Affector;
class PathFollower : Affector;
class BubbleMovement: Affector;

/// ----------------------------------------------------------------------------
/// ParticleSystem class
/// ----------------------------------------------------------------------------
class ParticleSystem : SceneObject
{
string   name
list<Emitter> emitters
list<Affector> affectors

void Load (ifstream& theInput);
void Save (ofstream& theOutput);

void Start ();
void Update ();
void UpdateF (float theFrac);
}
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor

BeRSeRKeR

 En mi caso un Particle System sólo podía tener un emisor y luego tenía los Particle Effects que podían tener uno o más particle systems. Así, tenía un particle effect para conseguir el efecto de antorcha que estaba compuesto por dos particle systems, uno que simulaba fuego y el otro que simulaba humo. En cualquier caso son dos formas diferentes de llamar a un mismo concepto.

En cuanto a los affectors, en mi caso en el que un sistema de partículas es sólo un emisor (supongo que es lo que tú llamas emitter), lo pondría a nivel de sistema de partículas  y no a nivel de particle effect ya que un modificador de color no sería lo mismo para el sistema que simula fuego que el que simula humo.

Claro que pensándolo mejor y siguiendo con el ejemplo del efecto de la antorcha compuesta por fuego y humo, en realidad aquí un sistema de eventos podría venir bien ya que en principio, siempre se emite fuego, pero llega un momento (a una edad determinada de la partícula) que debido a la combustión, se produce el humo. Con el uso de eventos, nos bastaría con un sólo sistema de partículas.

La verdad es que los sistemas de partículas ofrecen muchas posibilidades y seguramente es complicado conseguir un sistema lo suficientemente generalizado para poder llegar a conseguir cualquier efecto que se nos pase por la cabeza.

Saludos.
¡Si te buscan en nombre de la ley, huye en nombre de la libertad!!

Ray

 No se si era correcto o no el sistema que use yo para un juego que hice, pero me parecio efectivo para acelerar considerablemente el tema y así lo dejé. Básicamente fue crear varias funciones estáticas para poder trabajar con grupos de partículas a la vez para crear, procesar y dibujar todas usando bucles, algo así.


void Gota::ProcesarGrupo(Gota *ListaGotas, int numGotas)
{
Gota *pGota=ListaGotas;

for (int i=0;i<numGotas;i++) {
       pGota->VelocidadY + = -1.0; // Gravedad
       pGota->VelocidadY - = pGota->VelocidadY * 0.1; // friccion
       pGota->PosicionY += pGota->VelocidadY; // desplazamiento
       if (pGota->PosicionY<0)  // colision
              pGota->VelocidadY=1000;
       pGota++;
       }
}


No es que fuera exactamente así, esto es solo un pequeño ejemplo para que se entienda más o menos lo que hacía. Si había una cantidad exagerada de partículas y quería comprobar colisiones con otros objetos u otras operaciones complejas, para no sobrecargarlo comprobaba solo una fracción del grupo cada vez, usando un contador.

nostromo

 Sobre cosas a añadir al sistema de particulas:

-  subsampling: para que la animación del movimiento de particulas sea suave. Es decir, tomar "posiciones x,y decimales". Aunque quizas con una resolución grande no haya diferencia.  Respecto a esto puedes ver Wu Pixels

- Te faltaria poner la aceleración como propiedad de una particula. Y calcular en cada paso  v= v+a; p = p + v; Con esto los "affector" pueden modificar la dirección de la particula simplemente variando su aceleración y podras añadirle los efectos gravedad , colisión etc... solo modificando eso.
Esta acelaración puedes cambiarla en funcion del tiempo , distancia , colision etc.... Quizas se puede prescindir de la aceleración  pero no tendrás
tanta flexibilidad.

-  turbulencia:  Seria la función que modela el caos que se ha mencionado antes. Aplicar el caos sobre la aceleración y siempre aplicando el mismo cada x particulas genera unas trayectorias muy vistosas. Esta turbulencia puedes verla por ahi como "noise", se aplica mucho en las texturas procedurales.

- Sobre el codigo que has puesto debes decidir quien mantiene la lista de particulas. La lista de affectors los puedes agregar a los emitters, aunque lo mismo puedes hacer instanciando varios ParticleSystems sobre la misma posición.

Mi pequeña aportación, aunque tengo la sensación de que estamos hablando de las mismas cosas con diferentes nombres. :)

Un saludo
Nostromo

CoLSoN2

 @nostromo:

Bueno, lo de usar coordenadas decimales, por supuesto, sino quedaría muy feo. Aunque en modo software lo hago todo en coordenadas enteras, por cuestiones de rendimiento, pero eso sólo se activa en máquinas muy malas (o a voluntad).

Lo de la aceleración es que no estoy seguro de que en algún momento me vaya a hacer falta una aceleración por-partícula. Lo que dices de que sólo modificando la aceleración puedes modificar todo, es cierto, pero es mucho menos intuitivo que modificar directamente otros atributos, ya que tengo que pensar en el efecto que tendrá la aceleración sobre la velocidad, y ésta sobre la posición.

CitarSobre el codigo que has puesto debes decidir quien mantiene la lista de particulas.
Sí, se me había olvidado añadirlo a Emitter.

CitarLa lista de affectors los puedes agregar a los emitters
Es finalmente lo que he hecho.
Manuel F. Lara
Descargar juegos indie  - blog sobre juegos indie y casual
El Desarrollo Personal.com  - blog sobre productividad, motivación y espíritu emprendedor






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.