Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Pintando Geometría

Iniciado por ProD, 08 de Octubre de 2003, 10:03:27 AM

« anterior - próximo »

ProD

 Buenas, tengo mi propio formato de exportación en el cual por cada objeto del MAX consigo sus vértices y caras además del ID del material de cada cara... y quería saber cual es la forma más eficiente de pintar esto con Direct3D. Ya que tener un VB e IB estático por cada objeto me parece excesivo...

Un saludo
as ideas son capitales que sólo ganan intereses entre las manos del talento

AgeR

 Supongo que cada uno que te conteste te va a decir una cosa distinta, así que empiezo yo XD diciendo una de las más básicas :

Ordenas las caras por material guardandote en un vector o similar las caras en las que cambia de un material a otro.
Estas caras ordenadas las metes en tu VB.
Luego renderizas por pasos el VB, cambiando de material cuando corresponda. (Creo que ya había un thread parecido sobre esto).

De este modo puedes tener toda la geometría en un mismo VB estático (siempre que no vaya a cambiar, claro) y solamente has de preocuparte por los cambios de material.

Saludos!

MChiz

 Esto es algo que siempre me ronda por la cabeza, y no tengo muy claro.
La gente de DirectX jura y perjura que es mejor hacer el minimo de cambios de vertex buffer. Vale, estoy de acuerdo pero... realmente va a penalizar TANTO?
Por otro lado, la gente de GL dice que su extension GL_ARB_vertex_buffer_object ( que es LO MISMO que los vertex buffer ) puede hacer cambios de vertex buffer sin apenas penalizacion alguna...
Alguien sabe algo respecto al tema??

Por lo demas, estoy completamente de acuerdo con AgeR. Y si puedes estripificar la malla, mejor! : )

AgeR

 MChiz yo tengo la misma duda que tú.
La verdad es que me quedé sorprendido cuando empezamos la prueba esta del "Test de motores". En mi test utilizaba un VB estático para CADA objeto (y cada objeto con una única textura) y creo que no iba nada mal, teniendo en cuenta que no había descarte de geometría etc etc...
Incluso la versión anterior, en la que usaba DrawPrimitiveUP, iba más rápido de lo que yo me esperaba por los comentarios de la mayoría de la gente.

De todos modos, aún en el caso en que no afectara mucho el cambio de VB, siempre será más compacto.

La verdad es que me parece un tema muy interesante  (uoh) .

Saludos!

MChiz

 mmm... que interesante : )

Pero que mas da que sea mas compacto? Es mucho mas intuitivo tener un vertex buffer por objeto. Veo bien el tener un vertex buffer para todos los nodos del mundo ( por ejemplo ).

Nadie dice nada al respecto??  (uoh)  

Doom Carmak

wenass!! (vuelvo a los foros después de un año y medio de ausencia XDD )

PROD, la mejor forma de entender cual es el "ajuste" adecuado de geometria y renderización en D3D es mirarse las ID3DXMesh. Puede parecer una broma, pero no, hablo en serio. Mirate un tutorial al respecto de 13 páginas en la MSDN de la web de M$. Tienes k ordenar por caras->vertices según un indexbuffer k a su vez va asociado a una lista de ATRIBUTOS. Normalmente el atributo X está intimamente relacionado con el material de un trig X. Me extenderia mucho si lo explicara todo aki, así k please, mirate el tuto ese en
"http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dndrive/html/directx01212003.asp"

El caso es k hay k intentar siempre dibujar en strip (más de un trig por DrawPrimitive), intentar indexar siempre k se pueda y dibujar en grupos de materiales y por lo tanto en grupos de texturas (a poder ser).
Cumpliendo todos estos rekisítos alcanzas la mayor velocidad en D3D...
Weno, espero aver ayudado, ahora me toca hacer a mi una sobre mapas Q3  :-D
oding is fun!

Haddd

 La penalización no es por tener muchos VB, sino por hacer cambios en el VB. Si el VB está en memoria de vídeo, no cuesta nada cambiar de VB.

Miki

 Uno de las dudas más frecuentes en D3D sería esa ¿CUANTOS VB ES ACONSEJABLE USAR, y sobretodo, CUANTOS REFERIDOS AL MISMO OBJETO/ESCENARIO?
Algunos artículos de nVidia hablan sobre esto. Si bien es verdad apenas se puede comparar el funcionamiento de un HDD con como trabaja la memoria en la t.gráfica, tmb es verdad k hay una lógica k SIEMPRE impera, y es la de DIVIDE Y VENCERAS. Y dicho esto ¿CUANDO MERECE LA PENA USAR VARIOS VB PARA UNA MISMA PANTALLA? Sobre esto hice varias pruebas con mapas del Q3. Resulta k al hacer uso del BSP (de las LEAFS más bien) te das cuenta de que raramente dibujas de forma secuencial o lineal, sino k realmente vas pegando saltos por el VB en busca de los vertices deseados. Cuando esto es así y la pantalla tiene MUCHOS vertices (unos 30.000 por ejemplo), lo mejor es separar los LEAFS en grupos (y con ellos separamos tmb en grupos de polys), de forma k si tenemos 10.000 leafs, haciendo grupos de 500 se nos kedan en 20 grupos de 500, osea, VB's de tantos vertices como polys * numVertsInPoly haya en cada LEAF. De esta forma veremos como el rendimiento se extrema más, kiero decir, cuando iba lento ahora irá más lento XD, pero cuando iba rápido irá más rápido, o lo k es lo mismo, si salimos de la pantalla y miramos a TODO, veremos k el frame rate es más lento k usando solo un VB, pero cuando nos metemos y respetamos la estructura del PVS vemos que normalmente va más rápido, con aceleraciones/decelaraciones causadas por el salto de VB a VB (normal).
Si vamos a dibujar de forma más secuencial, con listas de triangulos o strips, lo mejor seria usar solo un VB, pero claro, tmb depende un poco del tamaño del nivel. Si usamos portal rendering con exteriores gigantescos tipo Unreal, creo k lo mejor seria usar un VB x cada GRAN celda. Aveces hay k pensar en la VideoMem como si se tratara de la FAT del disco. Realmente no tiene mucho k ver, pero si "separamos" en la medida de lo posible lo k creemos k es conveniente separar, veremos un aumento de rendimiento con un 50% de posibilidad.  Sobre vertex buffer dinámicos. Realmente no es conveniente usarlos (lo dice propiamente M$ en la FAQ), pero en juegos como BLADE, en la que la teselación se efectua en tiempo real, es preciso hacer uso de este tipo de VB. Lo que está claro es k a la larga, todo lo precompilado es más rápido...
Espero haberme expresado bien. Taleg!

Haddd

 La tarjeta funciona en paralelo. Si mandas 100.000 triángulos a la tarjeta de golpe y después dibujas 100, esos 100 tendrán que esperar a que terminen los otros 100.000. Pero si entre las dos llamadas utilizas la CPU para hacer tus propios cálculos, estarás reaprovechando los ciclos de CPU que de la otra forma estarían esperando a que terminaran los 100.000 triángulos. Si utilizas un VB enorme tienes mucha menos probabilidad de que la CPU se utilice para ir preparando la información para mandar la siguiente lista de triángulos.

Lo que nunca hay que hacer es bloquear el VB porque pierdes ese paralelismo, a no ser que bloquees antes de mandar nada a la tarjeta. Pero ya con los vertex shaders eso no es necesario. Yo tenía antes dos versiones de mi motor, una que mandaba directamente los vértices yas transformados y otra que no lo hacía. La versión que ya transformaba era mucho más rápida porque utilizaba ese paralelismo y el tiempo que la tarjeta hacía el renderizado, la CPU estaba preparando los vértices para dárselos ya comidos.

Miki

mmm....Haddd, no entiendo muy bien lo k refieres, más me sale una duda...
Aver...yo entre el beginScene y el endScene voy pitando objetos (al fin y al cabo listas de vertices, cada una probablemente en un VB). Para cada uno de ellos, antes de hacer un ->Render() hago su respectivo ->DoTransform() (por k puede k el objeto se hubiese movido, rotado o escalado). mmm..y la pregunta sería...¿lo estoy haciendo bien? XDD  Si primero transformara todo y luego pintara todo, lo k sucederia es k la geometria final kedaria como decidiera la última llamada a ->DoTransform() del último objeto pintado ¿no?   weno...ahí keda la duda. Es k no entendí bien a QUE tipo de calculos te referias...si puedes aclar esto mejor k mejor please... :-)

Haddd

 La CPU y la tarjeta de vídeo van en paralelo. Si tu mandas 1000 poligonos y la tarjeta tarda 0.5s en dibujarlos, esos 0.5s los puede usar la CPU. Pero normalmente la CPU estará esperando a que terminen estos 1000 polígonos para mandarle otros 1000, es decir, estará perdiendo el tiempo. Pero si ese tiempo lo aprovechas para hacer algo, en realidad estás utilizando al máximo la CPU y la tarjeta de vídeo. Pero no tengo ni idea de como hacer esto realmente bien en Windows. Yo querría tener 2 tareas y que cuando ocurriera el DrawPrimitive se me devolviera el control enseguida, pero el DrawPrimitive espera a que la tarjeta esté disponible y ese bucle de espera tonto es el que me fastidia porque n otengo ningún control sobre él.






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.