Hola. Estoy usando IrrLicht con el renderer de Direct3D9, y me da problemas muy feos de Z-Buffer:
(http://www.galeon.com/jedive/pics/irrlicht_zbuffer.jpg)
En otros engines esto no ocurre, así que supongo que habrá algún parámetro en Direct3D que permita solucionar esto... ¿alguien me puede echar una mano?
El rango del ZBuffer viene dado por los parámetros near y far plane de la cámara. Si hay mucha diferencias entre ellos, puedes tener estos problemas. Compruebalo ;)
O lo que es lo mismo, problemas de precision. Si tu near plane es 1, y tu fear plane es 1.000.000 y tienes un Zbuffer de 24bits, con esos 24bits tiene que controlar la distancia de cada pixel, pero si pones un fear plane de 1.000, esos 24bits del Zbuffer pueden ser mucho mas precisos.
Reduce tu fear plane, supongo que los renders de grandes distancias son ya otro tema ;)
Saludos.
Gracias por vuestra respuesta. ¿Cómo se define el tamaño del z-buffer? ¿Cual es el valor recomendado?
Teniendo en cuenta que sus el Irrlicht seguramente el engine define las funciones internas para cambiar el depth buffer entre 16 y 24 bits, y también para cambiar el znear y el zfar (supongo esto porque debe tener una interfaz común para todo los rasterizers que soporta). Con respecto al valor, mira que la diferencia entre el znear y el zfar sea lo menor posible teniendo en cuenta tus necesidades, lo único que tenes que tener en cuenta es que el znear no sea 0. También mira
http://msdn.microsoft.com/archive/default....onTransform.asp.
Cuidado con los planos y con la resolución. Esta web explica muy bien qué pasa cuando pasa lo que pasa ->
http://www.sjbaker.org/steve/omniv/love_yo...r_z_buffer.html
De irrlicht ni papa, pero buscando he encontrado esta web:
http://irrlicht.sourceforge.net/docu/class...scene_node.htmldonde pone que tienes que usar los metodos .setNearValue y setFarValue
En la web que te ha puesto ethernet, viene muy bien explicado lo del z-buffer.
Lo ideal es usar un z-buffer de 24bits (lo normal hoy en dia), 16 es poco. Pero lo realmente importante es indicar unos valores correctos para el Near y el Far.
Sobre como indicarle a Irrlitcht el tamaño del z-buffer... ni papa.
Investigando un poquito mas... este es en mi opinion el sitio mas adecuado donde se le deberia de poder indicar al Irrlicht el tamaño del z-buffer;
http://irrlicht.sourceforge.net/docu/struc...parameters.htmlpero no esta...
Tal vez no se pueda y sea el motor el que eliga por ti... :(
Gracias a todos por vuestras respuestas. Me referia a cambiar el tamaño del z-buffer en Direct3D directamente, no en IrrLicht.
Si usas una libreria sobre Direct3D quiza no puedas cambiarlo, pero de todas formas... el atributo AutoDepthStencilFormat de la estructura D3DPRESENT_PARAMETERS que le pasas a CreateDevice() es el responsable de esto.
Pero no seria bueno que tocaras esto, no es raro dejar al usuario que elija lo que prefiera; lo mejor es que reduzcas la distancia del farplane.
Ok, pues según veo, IrrLicht fija el tamaño del buffer a D3DFMT_D16, cambiandolo a D3DFMT_D24S8 mejora la calidad de renderer. ¿Recomendáis algún otro valor, o con este se obtiene buen resultado?
D24X8 si D24S8 te falla ya que hay tarjetas que no soportan stencil.
Mirate éste link para que veas que formatos estan implementados REALMENTE en el hardware instalado por ahí y pasa de los listados que salen en la documentación de los APIs Direct3D y OpenGL (mucha teoría). Lo mismo va por los formatos de texturas normales y como rendertargets.
Capacidades de las tarjetas de video más comunesSuerte.
En la matriz de proyeccion define 1.0f como el plano z mas cercano, lo mas seguro que te lo arregle esto. Ahora supongo que tendras puesto 0.1f.
Prueba también con una escala de escenario más pequeña. Es decir, si tienes una medida en 3DS Max (por ejemplo unas dimensiones de 100.000 x 100.000 x 100.000 unidades) escala a 10.000 o a 1.000. Imagina que cada unidad en MAX sea como 1 metro en la vida real. Con esto consigues buenos resultados sin tener que cambiar el far y el near plane y usando incluso z-buffer de 16 bits.
Estoy con zupervaca en que lo mejor es modificar ese valor de la matriz de proyección, y voy más allá creando una función que lo haga mediante el valor pasado.
Antes de cada dibujo y cuando sea necesario se llama a esa función pasando un valor alto para dibujar por ejemplo unos edificios a lo lejos, y un valor pequeño para el interior de un coche.
No sé si es muy exagerado hacer esto, pero yo no veo otra solución para poder dibujar escenas correctamente en las que se combinan objetos grandes muy lejanos, y objetos muy cercanos.
Cita de: "marcode"Estoy con zupervaca en que lo mejor es modificar ese valor de la matriz de proyección, y voy más allá creando una función que lo haga mediante el valor pasado.
Antes de cada dibujo y cuando sea necesario se llama a esa función pasando un valor alto para dibujar por ejemplo unos edificios a lo lejos, y un valor pequeño para el interior de un coche.
No sé si es muy exagerado hacer esto, pero yo no veo otra solución para poder dibujar escenas correctamente en las que se combinan objetos grandes muy lejanos, y objetos muy cercanos.
Pero supongo que eso no se puede hacer a cada objeto, ya que entonces cambias la base sobre la que se calcula el zbuffer, dando resultados erroneos, es una suposicion, no lo he probado.
No se si Jedive sigue con el problema, pero no hay que complicarse tanto la vida para solucionar un fallo de estos, yo lo tuve en el dibMotor que hice hace unos añucos con direct3d, el problema era el que mencionaba, ponia que el plano mas cercano era 0.1f, pero al cabo de investigar un tiempo nada mas que puse 1.0f me funciono a la perfeccion, pero es un 1.0f para todo, es decir creamos la matriz de proyeccion con el plano mas cercano en 1.0f siempre.
Cita de: "zupervaca"No se si Jedive sigue con el problema, pero no hay que complicarse tanto la vida para solucionar un fallo de estos, yo lo tuve en el dibMotor que hice hace unos añucos con direct3d, el problema era el que mencionaba, ponia que el plano mas cercano era 0.1f, pero al cabo de investigar un tiempo nada mas que puse 1.0f me funciono a la perfeccion, pero es un 1.0f para todo, es decir creamos la matriz de proyeccion con el plano mas cercano en 1.0f siempre.
Yo el problema que tenía es que si alejaba el plano como dices, los objetos muy cercanos a la cámara desaparecían, por lo que tuve que adoptar la solución de modificarla dinámicamente (no individualmente para cada render), pero sí de manera específica para algunos.
Pruébalo en más circustancias, quizás con ese valor, te acercas demasiado a un muro con una cámara en 1ª persona y ves lo que hay detrás, otras veces puedes querer ver muy de cerca un objeto, como si fueras una hormiga.
Cita de: "TurBo_biT"
Pero supongo que eso no se puede hacer a cada objeto, ya que entonces cambias la base sobre la que se calcula el zbuffer, dando resultados erroneos, es una suposicion, no lo he probado.
Pues esa suposición también la tuve yo, pero el caso es que funciona, aunque no sé si en todas las circunstancias.
Pongamos un ejemplo, tienes unas montañas a 10 km, y un mapa a 20 cm de la cara (que es la cámara), ves el mapa, pero las montañas hacen el efecto chungo de solapamiento (que ahora no me acuerdo como se llama), alejas el plano y ya se ven bien las montañas, pero el mapa desaparece porque el corte queda a 30 cm. A menos que yo esté confundido algo así es lo que ocurre.
No veo otra solución que modificar la proyección específicamente antes de renderizar cada uno de ellos, es un proceso sencillo puesto que solo hay que obtener la matriz de proyección, modificar la z, y reestablecerla, Aunque tal vez no convenga abusar de ello hasta el punto de modificarla para cada render.
Lo que hice fué adoptar para todos un valor intermedio, que creo que era 0.8, y después para los dibujos críticos por su distancia extremamente cercana o lejana modificar individualmente la matriz justo antes de dibujar.
Cita de: "marcode"Pongamos un ejemplo, tienes unas montañas a 10 km, y un mapa a 20 cm de la cara (que es la cámara)
[...]
No veo otra solución que modificar la proyección específicamente antes de renderizar cada uno de ellos
Creo que el Quake 1 modificaba la matriz para pintar el arma; esto es bastante habitual en los FPS, pero muy concreto y fácil de separar. Los problemas pueden venir si tienes objetos a 10 km, 1 km, 100m, 1m, 10cm, etc. El suelo que ves (y que forma las montañas al fondo) está esparcido por todas esas distancias, de forma contínua. ¿Dónde pones el corte?
Los primeros juegos que mostraban grandes extensiones de mundo con aceleración 3D hacían diabluras de este estilo con la matriz de proyección (el Project IGI en particular, pedazo de motor que se curraron), pero hay que tener siempre presente que no es una solución genérica que "simplemente funciona", hay que poner los cortes y separar los elementos de la escena con mucho cuidadito.