Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Algoritmo de LOD para terrenos en juegos RTS

Iniciado por eduwushu, 25 de Septiembre de 2009, 10:27:09 AM

« anterior - próximo »

eduwushu

Primero, saludos a todos:
Ando embarcado en el desarrollo de un juego de estrategia bastante sencillito y estoy divagando acerca de qué técnica de LOD sería la mejor para aplicar al terreno. Hasta ahora hago una carga simple de terreno a partir de un heightmap. En esa carga especifico la dimensión que quiero que tenga el terreno y la resolución vertical y horizontal del mismo en vértices/metro. Esto me deja al final con una malla 3D regular donde los vértices se distribuyen de manera uniforme.
Teniendo en cuenta que en un RTS normalmente la vista del terreno es una vista superior donde estaremos viendo gran parte del mismo en todo momento he considerado utilizar alguna técnica de LOD, para que en esos momentos en que tenemos una visión más amplia del terreno se simplifique la malla reduciendo el númer de polys. Si no utilizara esto me vería en el compromiso de elegir entre una malla de baja resolución (un número de polys aceptable para todo el terreno) que me permitiera manejar el escenario con comodidad cuando tengo una visión amplia pero que mostraría un nivel de detalle pobre si el usuario quiere acercarse a al acción; o bien una malla de alta resolución que me da detalle para distancias cortas pero que se hace inmanejable cuando el usuario se aleja para dar órdenes a las tropas.
He visto varios ejemplos del uso de ROAM, pero todos tienen un efecto bastante desagradable de 'popping' que hace que el suelo parezca panceta en una sartén. También he visto un ejemplo de Chunked LOD, pero que a su vez tiene otro efecto bastante desagradable en las juntas entre parches que hace que se vean esas costuras (en las juntas se arregla el 'cracking' del terreno con un corte vertical).

Como supongo que nos ocurre a todos, me gsutaría dar con una solución óptima, que me permitiera hacer un LOD sencillo (si es combinado con culling mejor que mejor) y que evitara esos efectos que al final hacen que el juego parezca 'cutre'.

Agradeceré cualqueir sugerencia.

¡Un saludo a todos!!

tamat

yo creo que de momento lo mejor es que no dejes que la camara se abra demasiado y trabajes en picado, te ahorrará problemas. Rompes el terreno en muchos patches (dividir el heighmap en trozos más pequeños) y así puedes controlar mejor qué se pinta.

Si más adelante quieres permitir que la cámara se abra entonces basta con que hagas algo a lo geomipmapping teniendo varias versiones de cada mesh (aunque coserlas es jodido).

Pero centraté por ahora en tener un terreno cómodo, no en poder mover la camara libremente.
Por un stratos menos tenso

eduwushu

Bueno, al final me decanté por hacer una adaptación del algoritmo de 3D game engine architecture a XNA. Dicho algoritmo usa una división del terreno en patches de tamaño 2^n+1. Por tanto un terreno podrá tener dimensiones vertical y horizontal diferentes que sean múltiplo del tamaño de patch elegido. cad patch se gestiona como un quadtree donde cada nodo del quadtree puede tener hasta 9 vértices activos (Lo mínimo es tener 4 vértices y dos triángulos activos). Cada rama del quadtree se va refinando en un modo dependiente de la vista hasta un nivel de detalle diferente. Luego se ven las dependencias entre vértices y se determina si alguna rama requiere de un refinamiento extra para evitar roturas en el terreno.
En el algoritmo propuesto en el libro cada patch tenía su propia lista de vértices e índices que se gestionaba de forma independiente y que cambiaba en cada simplificación del terreno.
El algoritmo me pareció ineficiente por dos motivos:
1.- Utiliza una lista dinámica de vértices e índices que cambia con cada simplificación. Esto supone que o bien tengo vertex e indexbuffer dinámicos o bien utilizo llamadas a drawUserIndexedPrimitive, lo que significa tener que mandar en cada simplificación las nuevas listas por cada patch a GPU, lo que bajaba el framerate una burrada.
2.- Para dibujar el terreno tengo que hacer tantas llamadas a DrawUserIndexedPrimitive como patches visibles tenga el terreno en cada momento.
Para solucionar estos problemas hice ua modificación al algoritmo: guardo todos los vértices del terreno (de máxima resolución) en un VB estático (con lo que sus posiciones, normales y color quedan fijos). Luego lo único que hago dinámico es un indexbuffer global dodne los diferentes patches van añadiendo los índices que necesitan para dibujarse. Este indexbuffer es lo que se modifica en cada simplificación del terreno y es lo único que tengo que mandar a la gráfica cada vez que cambia la simplificación.
De esta forma además sólo necesito hacer una única llamada a DrawIndexedPrimitive para dibujar todo el terreno. Además no necesito reenviar la información de vértices cada vez que el terreno cambia.
Hasta ahora me va fenomenal con un fps constante de 62. Sin embargo ahora me encuentro un problema cuando quiero texturizar el terreno. Mi idea era usar algun tipo de texture splatting, sin embargo ahora mi problema reside en qué valor poner a las coordenadas de textura de mis vértices.
Para seguir funcionando con mi esquema necesito que las coordenadas de textura para los vértices sean fijas (he intentado utilizar coordenadas variables que meto en un vertexstream diferente dinámico y la actualización se hace totalmente ineficiente). Sin embargo no se me ocurre ninguna forma de salir de este inconveniente, porque los vértices que coponen el terreno en cada simplificación son diferentes y cubren zonas distintas.

¿Teneis alguna idea?

Gracias

tamat

utilizar la x y la z de los vertices como u y v? :-m
Por un stratos menos tenso

JL10

has echado un vistazo al algoritmo Clipmap?.  :o
Gracias






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.