Ir al contenido

publicidad
publicidad

Foto

Dibujando objetos lejanos, muy lejanos...


Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
2 respuestas en este tema

  • mopois

  • GRANDIS SUPERNUS

  • vida restante: 100%
  • Registrado: 24 sep 2003
  • Mensajes: 33.954
#1

Escrito 20 mayo 2011 - 10:14

Buenas,

Sigo en mi ofuscado intento de crear un vidriojuego y sigo con problemas de precisión.

El tema es el siguiente, estoy dibujando objetos muy distantes, se supone que va a ser algo así como un simulador de viajes espaciales y tengo problemas de precisión del zbuffer al dibujar objetos muy distantes, por lo que voy cambiando la distancia mínima y máxima de dibujado para que la resolución del zbuffer no se resienta y no haga cosas raras con los triángulos de los polígonos (se dibujan detrás o delante)

Lo que estoy haciendo actualmente es:

- Dibujar primero el fondo, estrellas proyectadas como sprites, aquí no hay ningún problema.
- Dibujar los planetas del mismo sistema en el que estoy (de 20000kms a 10*UA (unidades astronómicas, distancia de la tierra al sol)
- Dibujar de (1m a 20000 kms).

Puede meter muchos más dibujados para ir "fragmentando" los renders y tener siempre una buena resolución del zbuffer para cada distancia mínima y máxima de dibujado. El problema es que, aunque estoy dibujando cada cuerpo en el orden que debería, tengo problemas ya que en ocasiones, dependiendo de donde esté situado el jugador éste se dibuja por ejemplo por delante de un planeta.

Supongo que la relación de la posición del cuerpo con relación a la distancia máxima y mínima de dibujado es lo que establece el valor comparado para el test interno del zbuffer que hace xna y por eso a veces se me dibuja por detrás...

El tema es... ¿Podría solucionarlo guardando el backbuffer y cargándolo de nuevo como fondo en los pasos de renderizado intermedios? ¿Algún ejemplo de código para echarle un ojo al uso del backbuffer? ¿Alguna otra idea?

Un saludo.

firma_zpsumxtfb8b.jpg

           Prueba mi juegaso para Android


#2

Escrito 20 mayo 2011 - 17:14

Buenas mopois.

Según observo tu principal problema se debe a la precisión de renderizado de polígonos según la matriz de cada objeto a renderizar, ya que como comentas cuentas que aveces hay polígonos que se renderizan por delante de otros polígonos de diferentes objetos. Efectivamente esto se debe a varios motivos.

La solución que te puedo dar no está destinada a C# + XNA que es lo que tu usas, yo hago uso de C++ y Directx 9 con lo que tendrás que hacer ciertas modificaciones para adaptarlo a tu código, pero no creo que te suponga mucho impedimento dado que son muy pocas cosas, varias lineas vamos.

En primer lugar debes establecer un parámetro de precisión mayor a la que usas normalmente en el DepthStencil de tu Device, además de permitir el AutoDepthStencil, con lo que te recomiendo aplicar estos valores.

g_d3dpp.EnableAutoDepthStencil = TRUE;
g_d3dpp.AutoDepthStencilFormat = D3DFMT_D24S8;


En caso que tu GPU no sea compatible con este último formato de profundidad establécelo a D3DFMT_D24X8, eso si, nunca uses el formato D3DFMT_D16 ya que puede provocar problemas de profundidad.

Bien, otro apartado que debes implementar en tu device es el siguiente, recuerda que esto debes establecerlo antes del renderizado de objetos, de acuerdo.

g_pD3DDevice->SetRenderState(D3DRS_ZENABLE, TRUE);
g_pD3DDevice->SetRenderState(D3DRS_ZWRITEENABLE, TRUE);


Esto te permite evitar el problema principal que has comentado, es decir, el renderizado incorrecto de los polígonos por motivos del ZBuffer.

Por último y no menos importante, debes crear un PerspectiveFovLH con los parametros adecuados a la resolución de pantalla, aspecto y distancia de dibujado para tu matriz de proyección.

D3DXMatrixPerspectiveFovLH(&MatrizProjection,D3DXToRadian(45.0f),AspectoRender,0.1f,32000.0f);
g_pD3DDevice->SetTransform(D3DTS_PROJECTION,&MatrizProjection);


Nota: AspectoRender es una variable flotante que contiene el Aspect Ratio, esto se calcula dividiendo el ancho de la ventana de render por su alto, de acuerdo.

Ejemplo:

Si tu resolución es 1024x768, AspectoRender = (1024/768).

El valor 32000.0f permite establecer la "distancia de renderizado", cuanto mayor sea el número mayor será la distancia que será renderizada.

Recuerda, esto debes aplicarlo por cada frame justo al comienzo de la escena.

En caso, de que esto no te sirva puede que no pueda ayudarte mucho mas.

Un Saludo.

  • mopois

  • GRANDIS SUPERNUS

  • vida restante: 100%
  • Registrado: 24 sep 2003
  • Mensajes: 33.954
#3

Escrito 21 mayo 2011 - 16:07

Muchas gracias Renegade.

Me he repasado lo del depthstencil y nada, lo tenía ya incluido en el código, solo que con los cambias de 3.1 a 4.0 ahora es casi solo llamar a dos funciones y listo, lo que si que no tenía puesto era el formato afinado del todo, debugeando he visto que cambia de Depth24 que tenía antes a Depth24Stencil8...

Acabo de semisolucionar el error, la cosa es que si dibujas objetos con diferentes distancias máxima y mínima de visión en la matriz de proyección hay que andarse con cuidado porque te pinta delante el que esté más cerca de la máxima distancia de visionado, por lo que tienes que dibujar el modelo más carcano casi al final de la distacia máxima para que te lo pinte siempre delante. Lo que he hecho finalmente es dibujar con 3 matrices con diferentes distancias máximas y mínimas: Una para la nave, otra para los objetos de 20000 a 800000000 (satélites) y otra para los planetas y estrellas (de 800000000 a un kiloparsec :S ).

firma_zpsumxtfb8b.jpg

           Prueba mi juegaso para Android



Este tema ha sido archivado. Esto significa que no puedes responder en este tema.
publicidad
publicidad