Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Sprites 2d En Un Mundo 3d

Iniciado por zupervaca, 27 de Abril de 2006, 04:42:23 PM

« anterior - próximo »

zupervaca

 Estoy probando a hacer un render para sprites 2D en un espacio 3D, la duda la tengo a la hora de realizar el render de los sprites ya que existen varias formas, usar dos triangulos o indicarle al render que es un punto y su tamaño, el primero se que es el mas dinamico de todos, pero el ultimo es algo mas rapido, ¿que se suele utilizar?

PD: La duda me ha venido por que el sistema de renderizado por puntos no soporta rotacion alguna, ademas en ancho y alto del sprite son iguales, con dos triangulos esta claro que soportaria todo, pero implicaria tener 4 vertices y 6 indices.

Pogacha

 Creo que te estas dando la respuesta tu mismo ... depende de lo que vallas a utilizar o si dudas mucho implementa ambos ya que no creo que sea tan dificil.

BeRSeRKeR

 Los point sprites tienen varias limitaciones, como las que has comentado de la rotación y el tema del tamaño. Si utilizas triángulos, puedes definir los sprites como triangle fans o triangle strips con lo cual estarías consumiendo 4 vértices y sin necesidad de utilizar índices.

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

zupervaca

 Renderizar con triangle strips lo habia pensado, pero mi idea basica es tener todos los sprites en un mismo vertexbuffer y asi renderizarlos todos a la vez y con este sistema el siguiente sprite se enlazaria con el ultimo renderizado, aunque claro no se si realmente se gana velocidad renderizando todos al mismo tiempo, ¿en vuestro sistema de particulas que usais? es que lo he mirado y soporta rotaciones y diferente ancho y alto

_Grey

 
Citary con este sistema el siguiente sprite se enlazaria con el ultimo renderizado

Te refieres a que se verían vértices saliendo desde la posición del primer sprite al siguiente!??! Si es asi, tranquilo puedes tener un triangle strip y, por ejemplo, 2 mallas que se vean perfectamente separadas, esto se conseguía haciendo ciertos chanchullos con los indices... Ni recuerdo como, pero lo que ganarías con un strip para ahorrar datos de vértices, casi, casi, lo perderías poniendo basura en el buffer de indices para que no se vean los 2 sprites "unidos".

Puede que haga mucho que no toque 3D, pero recuerdo perfectamente como en tutos y demás se ceñían a usar una lista de puntos o cuadrados usando 2 triángulos. Usando 2 triángulos tendrás todo el control.

Yo usaría una lista de triángulos sin indexbuffer, de hecho, quizá ni vertexbuffer y tirar de DrawPrimitiveUP(), por que si vas a tener que actualizar a "mano" las posiciones de esos sprites, no te vendrá mal tenerlos mas a mano tu que la gráfica, pero eso dependerá ya, del sistema y necesidades que tengas.

Saludos.

senior wapo

 No se hacen chanchullos con los index buffers, es que unes los diferentes bloques con triángulos degenerados de altitud (o bien la anchura) 0 poniendo dos vértices de un triángulo con la misma componente vertical (u horizontal según el caso). Esto se hace con strips, no fans (ya se que pusiste strips, solo aclaro).

Hay unos papers en la web de NVIDIA creo.

En cuanto a usar vertex buffers para sprites (no para tiles de fondos), a menos que uses vertex shaders, ¿ no será más rentable usar directamente un array y volcarlo todo de golpe ? Se supone que los sprites sufren cambios en cada frame, asi que de todas formas los subes en cada frame aunque uses VB, ¿ no ?

zupervaca

 He probado varias cosas:
- El chanchullo no me convence ya que nadie me asegura que eso siempre sea asi, aunque esta bien saberlo :lol:
- Es mucho mas rapido tener un vertexbuffer para todos los sprites, en 1000 sprites ganas hasta el doble de velocidad.
- Al tener en vertexbuffer en memoria ram indicando con managed no noto diferencia al llamar a la funcion DrawPrimitiveUP, me huele que esta funcion tiene un vertexbuffer que actualiza con el bufer de vertices que le pasas, es decir, no te libras del memcpy.
- Renderizar los vertices como puntos es muy pero que muy rapido, pero solo vale para sprites del mismo ancho y alto y ademas exisge un shader especial para el render.

Aun me queda por probar que ira mas rapido, si renderizar 4 vertices con 6 indices o renderizar 8 vertices sin indices, lo que tengo casi seguro es que me quedare con la opcion de renderizar los sprites mediante dos triangulos mas que nada por su flexibilidad.

No obstante voy a hecharle un vistazo al paper que mencionas de nvidia por si se escapa algun sistema mucho mejor.

Editado: Creo que me pondre a investigar esto

Son muchos fps de diferencia (genial)

Editado 2: Antes de que se me olvide, esto solo vale para gforce6 o superior, ¿sabe alguien si es soportado por ati y a partir de que tarjetas?

_Grey

 Bueno, pensandolo friamente, el indexbuffer solo lo tienes que rellenar una vez, no tienes por que actualizarlo en los siguientes frames, con lo que podria no estar demas, y usaras menos vertices... respecto al vertexbuffer, ya no lo tengo tan claro, igual si lo creas D3DPOOL_MANAGED, y lo abres solo para escritura te tira bien de velocidad, pero para una escritura/lectura constante de vertices no se si llegara a ser tan bueno como como usar DrawPrimitiveUP()  <_< ...

CitarAntes de que se me olvide, esto solo vale para gforce6 o superior, ¿sabe alguien si es soportado por ati y a partir de que tarjetas?

a que te refieres.... ?

zupervaca

 
Citarrespecto al vertexbuffer, ya no lo tengo tan claro, igual si lo creas D3DPOOL_MANAGED, y lo abres solo para escritura te tira bien de velocidad, pero para una escritura/lectura constante de vertices no se si llegara a ser tan bueno como como usar DrawPrimitiveUP()
Esta es la prueba exacta que he hecho y va igual, el motivo de por que lectura/escritura en managed vaya bien es simple, direct3d almacena el bufer en memoria ram y cuando lo bloqueas te pasa ese bufer de la memoria ram, despues al desbloquearlo se indica mediante un flag que el bufer ha sido modificado, si se requiere renderizar ese bufer y tiene el flag activado entonces se sube el vertexbuffer para usarse, con la funcion DrawPrimitiveUP pasa exactamente igual, trabajas con tu bufer en memoria ram, se lo pasas a la funcion y esta lo sube, ¿cual es la ventaja del vertexbuffer? si no lo has modificado no se vuelve a subir en cambio con la funcion DrawPrimitiveUP lo estas subiendo siempre, ¿por que va igual? por que ahora mismo en las pruebas que hago siempre modifico el vertexbuffer, en cambio si en alguna ocasion no lo hiciera lo mas seguro que gane velocidad usandolo.

Hablo del sistema de instanciar, este sistema de render lo que hace es renderizar el vertexbuffer e indexbuffer tantas veces como elementos tenga otra vertexbuffer que le hayas indicado, este ultimo vertexbuffer tiene memorizado la transformacion de cada modelo en el espacio, el efecto que se consigue es un incremento espectacular en los fps, los sistemas de particulas podrian notar una mejoria mas que sorprendente.
Se que la serie geforce6 o superior funciona, pero no se si ati actualmente soporta este sistema de renderizado.

Haddd

 Instanciar es lo mejor desde luego. Pero no es compatible 2.0. Si miras el ejemplo de Instancing de DX, se puede simular con constantes, y vas mandando grupos.

Por cierto..¿utilizas los vertices transformados? ¿los transformas tu en el VS?

zupervaca

 Por ahora estan transformandose en el vertexshader, pero cuando decida como optimizar el render probare los dos sistemas para ver que ventajas tiene uno y otro, muchos pensareis que soy un loco de los fps, pero se puede ganar o perder mucha velocidad renderizando de una u otra forma.






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.