Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Dudas sobre sistemas de particulas en D3D

Iniciado por CoLSoN2, 24 de Noviembre de 2002, 01:50:42 PM

« anterior - próximo »

CoLSoN2

                                1) ke seria mejor, acer ke las particulas sean solo 1 punto (x,y,z), por lo k deberia generar 1 array para estas y otra para los quads de cada particula, o simplemente decir en la structura sPARTICLE los 4 vertices ?

2) como tengo ke manipular la posicion de cada particula , osea cada quad, seria recomendable usar vertex buffers y por lo tanto tener ke lockear/unlockear a cada frame para manipular los verticeS; o usar DrawPrimitiveUP y renderizar el array directamente?

3) si yo pongo la posicion de cada particula relativa al sistema de particulas, (digamos ke el sistema está en V(3,4,5)) tonces debería usar una matriz de mundo al renderizar , no ? para que se trasformen los vertices, aunque de esta manera si muevo el sistema las posiciones se conservarian. En cambio, si kiero p ej que una nave medio en llamas vaia caiendo y vaya dejando una estela de humo, tendria ke acer las posiciones absolutas, no ? osea no relativas al sistema de particulas, tonces si ke si io suelto una particula parriba vertical y muevo el sistema esa particula seguiria vertical prariba, no ? tonces no usaría matriz de mundo y seria simplemente sumarle a la posicion relativa al objeto de la particula, la del sistema, no ? osea PosPartic = PosParticRelativaSist + PosAbsolSist; es asi ? (sorry si me raiao XD)                                
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

                                Yo soy de lo que piensan que no hay que pensar en optimizar si por eso se pierde en claridad. No creo que ganes mucho tiempo utilizando un array de vértices que si lo construyes al vuelo. Por tanto respecto al punto a) yo elijo un punto.

B) Usar vertexbuffers siempre es mejor. No tienes que lockear, puesto que tu partícula sigue siendo un Quad. Lo único que tienes que hacer es modificar la matriz WORLD para que coloque la partícula en el lugar que le corresponda.

c) No hagas las partículas relativas a nada, no ocurre así en la vida real. Cuando generas una partícula, le das unas propiedades y en ese momento esa partícula sabe "vivir" sola. Por eso al generar una partícula cuando una nave cae, no tienes que hacer nada, puesto que consigues un efecto real con la nave que cae y la partícula que sube.

Por cierto, ¿Podrías escribir un poco mejor? Me cuesta bastante leer tus post. Ya supongo que sí sabes escribir, pero me refiero a que no uses "palabras reducidas" porque (pq) yo no estoy muy acostumbrado a leer así y me resulta difícil.                                

Lord Trancos

                                El primer consejo q yo te daria es que el sistema de particulas lo hagas de forma independiente del API grafico, en este caso Direct3D. Create una clase que se encargue de todo el tema de gestion de memoria de las particulas (lo ideal es usar una lista), de ordenarlas si es necesario, etc...

Y despues dependiendo de las necesidades de tu juego pues te creas el vertex buffer conforme lo consideres necesario.... ademas, un sistema de particulas no tiene que servir solo para dibujar billboards... tambien tienes que poder usar objetos solidos; como por ejemplo un grupo de aves.

Asi q:

1; create una estructura para la particulas lo suficientemente flexible; posicion, velocidad lineal, velocidad angular, color... etc aunque luego no uses todos esos valores...

2; no siempre es necesario bloquear el vertex buffer. Si estas dibujando billboards basta con modificar la matriz world antes de dibujar cada particula (tal y como te comenta Haddd); esto te permitira moverlas, y cambiarles el tamaño sin tocar el VB. Si ademas quieres cambiar el canal alpha, puedes crearte un VB con 255 quads,... uno con cada nivel de transparencia, y de nuevo te ahorras bloquear el VB. De todos modos, tal y como te he comentado mas arriba, lo mejor es NO limitar el sistema de particulas imponiendole un VB, ni siquiera un API.

3; puedes crear uno o varios emisores de particulas, pero lo ideal es que las particulas no dependan de ellos, sino que sean independientes. La unica funcion que deberia de tener un emisor de particulas es automatizar la generacion de estas; le dices cuantas particulas debe de emitir por unidad de tiempo, y el tiempo de vida del emisor. En el caso de la nave que cae soltando humo,... creas un emisor que se va moviendo conforme la posicion de la nave,... pero cada particula emitida tiene su propia "vida" (como dice haddd), por lo que una vez emitida su comportamiento debe de ser (por lo general) autonomo e independiente de donde se encuentre o lo que este haciendo el emisor.                                
i>SaludoteZ de Lord Trancos!
http://www.dxlab.tk - http://dxlab.host.sk - programación de DirectX con Delphi.

CoLSoN2

                                1)
Citar¿Podrías escribir un poco mejor?
Claro que sí =)

2)
CitarUsar vertexbuffers siempre es mejor.
Leyendo vuestros replys me he dado cuenta de que con 1 sólo quad me apañaría para todas las partículas. Es decir, tengo un vertex buffer de 4 vertices que forman un triangle strip de 2 triangulos, y los pasos a seguir serían:
- Poner Matriz Mundo para Particula 1
- Renderizar Quad
- ...
-  - Poner Matriz Mundo para Particula N
- Renderizar Quad (el mismo!)

ya que la forma que tenga el polígono será siempre el mismo, para todas las partículas, no?

3)
CitarNo hagas las partículas relativas a nada, no ocurre así en la vida real
Entonces al crearlas, les paso la posicion del emisor en ese momento y se lo sumo a su posicion mas o menos aleatoria que le doy, no? Y a partir de ahi sólo voy sumandole o restandole, pero será su posicion absoluta en la escena, no?

4)
CitarSi ademas quieres cambiar el canal alpha, puedes crearte un VB con 255 quads
¿? La verdad es que no he trabajado prácticamente con el tema transparencias. ¿El alpha se indica en la estructura del vertice?

5)
Esto es una pergunta extra :)
Si creo una lista enlazada para las partículas, sería mejor en vez de borrar y añadir a cada frame del sistema de partículas (ya que algunas mueren y otras se crean); marcar las muertas como DIED y al intentar crear alguna, si hay alguna DIED (que no se renderizaría), pues re-inicializamos los valores de esta?

Una última cosa. El color de los vertices debe de cambiar (normalmente), cada X frames, así que eso si que tengo que modificarlo en el quad, no ? Porque esa informacion si que debe ser propiedad de los vertices, o se puede hacer algo estilo glColor3f (creo que era así)? osea que los vertices que se rendericen a continuacion usen ese color.

gracias a los dos                                
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

                                Bueno, cuando usas vertices q incluyen informacion de color (DIFFUSE) uno de los componentes de dicho color es el canal alpha. Si tienes la necesidad de cambiar el color de tus particulas, tienes varias opciones;

- Usar "paletas"; exactamente lo mismo que te comentaba para el canal alpha; creas un VB de X quads y dependiendo del color dibujas uno u otro. Por ejemplo; imagina 255 quads el primero de color rojo y con 0 de transparencia y el ultimo de color amarillo y 100% de transparencia, y el resto una gradiante; de este modo evitas lockear el VB.

- Lockear el VB. Como vas a hacerlo cada frame deberas de tener en cuenta varias cosas; usa correctamente los FLags al crear el VB y al lockearlo.

 - Cambiar el material; cambiar el material cada vez que dibujes una particula.... a mi me parece q debe de ser algo poco aconsejable, pero la verdad es q no lo se. O tal vez sea mejor cambiar por ejemplo el color ambiental en lugar de el material... no se.... tal vez DX8 tenga algun registro donde se le pueda decir el color con el que tiene q dibujar los triangulos sin que tenga q hacer lighting.... pero si existe no se cual es. (¿alquien lo sabe?)                                
i>SaludoteZ de Lord Trancos!
http://www.dxlab.tk - http://dxlab.host.sk - programación de DirectX con Delphi.

Ithaqua

                                Tener un solo quad y cambiar la matriz world por cada partícula me parece bastante mala solución en términos de velocidad.                                
thaqua^Stravaganza
http://ithaqua.stravaganza.org

Haddd

                                ¿y qué propones tu ithaqua?                                

Ithaqua

                                Que cada partícula tenga sus coordenadas, como siempre, ya sean absolutas o usando algún sistema de coordenadas local al sistema
Cambiar la matriz por cada partícula es un poco locura...
Además en D3D si no me equivoco podéis hacer uso de los point sprites no? y sino pues con quads de toda la vida, pero el caso es que cambiar la matriz mundo por cada partícula no es muy buena idea.                                
thaqua^Stravaganza
http://ithaqua.stravaganza.org

_Grey

                                No es que tenga especial experiencia en el tema de las particulas, pero me gustaria comentaros como lo hago y me digais que hos parece:

   Yo no cambia la matriz de mundo al renderizar, esta tiene la matriz de IDENTIDAD, es decir que calculo "a mano" la posicion de la particula.

Luego cuando quiero renderizar tengo dos funciones, la menos recomendable usa DrawPrimitiveUP() por cada particula, como e dicho la de mundo esta con la matriz de IDENTIDAD.
La siguiente funcion, mete los datos de estos poligonos, en un VertexBuffer y los pinta todos de una pasada, quizas esta ultima funcion a alguno le estrañe, vereis, la gracia de esta ultima funcion es que en lugar de tener una textura por particula, tengamos una textura para TODAS las particulas, donde esten las "imagenes" de cada particula, para poderlas hacer de una pasada, por eso calculo sus posiciones "a mano" y pongo la matriz de mundo en IDENTIDAD, con este segundo metodo se gana bastante de velocidad, puesto que con un solo DrawPrimitive() o DrawIndexPrimitive() las pones todas(o la mayoria.... segun tus necesidades claro).

Saludos.                                

CoLSoN2

                                aparte de ke muchas cosas ke aces no entiendo porqué las haces (¿porque no usas matriz de mundo  ?..) hacer eso seria volver a lo del principio: hay que lockear/unlockear a cada frame el vertex buffer para cambiar el color.
Cuando lo pruebe cambiando la matriz de mundo para cada particula y vea el rendimiento buscaré alguna solucion, si no es buena técnica                                
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

                                Es decir que calculas a mano la orientación de la partícula para que apunte a la cámara y las metes todas en el mismo vertex buffer, siempre que compartan la misma textura. Es una buena técnica, la tendré en cuenta.

Pero si usais vertex shaders, vereis que eso de usar la identidad ya no tiene mucho sentido, porque lo que calculas a mano, lo resuelves con la multiplicación de matrices, y al final, tienes que proyectar igual. Os resumo:

Un shader SIEMPRE proyecta, o más bien multiplica un vector por una matriz.
----------------------------------------------------------------------------
Si nosotros usamos la matriz identidad, nuestro código haría esto:

Vertices * Matriz WORD=Vertices Finales
Cargar Identidad

Ahora entraría en el shader

Vertices * ViewProy=Vertices a renderizar

----------------------------------------------------------------------------
Si no usamos identidad

Matriz=MatrizWORLD*MatrizViewProj

Cargamos la Matriz en el Shader

Vertices * Matriz=Vertices a renderizar


Yo creo que tarda mucho menos el 2º caso. Por ello si usais Shaders, pensaos esto de pasarlo a mano.                                

mac^threepixels

                                En d3d

Point sprites no me convencen mucho, pq tienen limitaciones de tamanyo (64 pixels en la GF3)


Tener una lista enlazada decente (con amortizacion de alocaciones). Hacer la fisica y escribir linealmente a un VB dinamico quads ya orientados a camara. La orientacion puedes probarla a hacer por vshader, aunque no creo que ahorres mucho, 3 o 4 sumas de vectores 3d por particula. Si la particula no esta animada con una pagina de texturas, tb puedes pintar cada particula con un triangulo, aunque chupa algo mas de fillrate:

|
|*
|--

donde * es la textura.

El IB puede ser estatico y ser prealocado.                                
----------------------------------
mac^threepixels
http://www.threepixels.org

Loover

                                ¿Qué es la amortización de alocaciones en la lista ligada?
¿Tienes alguna dire donde lo expliquen? O aún mejor, donde se vea una implementación de lista ligada de ese tipo.                                
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

CordayUK

                                creo que se refiere a que cuando metes y quitas particulas de la lista, no reservas memoria nueva sino que utilizas la memoria que ha dejado otra particula que ya se ha "muerto" :)
esto lo consigues facilmente con un array de booleanos que te digan que particula esta viva o muerta, y cuando crees alguna nueva coges la memoria que utilzaba otra, asi no tienes que hacer new y delete.

no se si no me explicado bien o no era eso a lo que se referia :)

sobre lo de las particulas, yo me quedo con point sprites y lockear el vb cada frame para cambiar las coordenadas de la particula. porque? porque a) te ahorras vertices (en vez de quads tienes puntos)
y B) el vertex buffer creado especialmente para pointsprites ya esta optimizado para eso :) para casos que quieras particulas mayores de que el limite que el pointsprite te lo puedes cambiar por quads orientados a camara, pero son casos muy raros creo yo (tipico fuego, chispas, humo etc sobra con 64 pixels) :-?                                






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.