sombras de la plantilla - motor de doom 3 - errores de precisión - grietas de sombra - ¿por qué?

8

Estoy probando los límites del motor Doom 3, en lo que respecta al tamaño máximo del mapa.

Noté algunos errores de precisión de sombra de plantilla que se vuelven más pronunciados cuando los objetos se alejan más y más del origen del mapa.

en la posición: -10901-18214-11204 Ejemplo 1

en la posición: -10802-26483-19383 ejemplo2

en la posición: -10802 -34683 -27540 ejemplo3

Creo que estos errores se han denominado "grietas en la sombra", pero no estoy seguro de cómo se han denominado anteriormente estos artefactos.

Casi todos los artefactos aparecen a lo largo de los límites de las luces / sombras, que se pueden ver aquí: ingrese la descripción de la imagen aquí

¿Alguien ha visto este tipo de artefacto gráfico antes con sombras de plantilla? ¿Cómo se llaman? ¿Cual es la causa?

Más ejemplos: misc1 misc2

Este es el motor Vanilla Doom 3 que se encuentra aquí: https://github.com/TTimo/doom3.gpl

Al probar el cvar r_useOptimizedShadows (que maneja los volúmenes de sombra de la geometría de engendro del mundo), noté que el artefacto desapareció. Luego me abrí camino a esta función:

R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, true /* FIXME? */ );

que cambié a esto:

R_LinkLightSurf( &vLight->globalShadows, tri, NULL, light, NULL, vLight->scissorRect, false /* FIXME? */ );

Eso elimina los artefactos, pero ahora supone que nunca estamos dentro de los volúmenes de sombra de la geometría del engendro del mundo. Entonces, cada vez que vamos dentro de un volumen sombra, ese volumen sombra no se representa correctamente.

Stepan1010
fuente
1
No estoy seguro acerca de esta implementación específica, pero el punto flotante pierde precisión cuanto más se aleja de cero.
concept3d
2
Convenido. 7 dígitos es casi la cantidad máxima de precisión que puede esperar de los números de coma flotante de 32 bits (también conocido como C / C ++ float). Has usado fácilmente 5 de esos. en.wikipedia.org/wiki/…
snake5
@ concept3d - Supongo que convertir los flotadores relevantes en dobles ayudaría. Si alguien tuviera los conocimientos técnicos para hacer eso. Incluso si resultaría en tiempos de render más largos.
Stepan1010
1
@glampert Actualicé la pregunta. Es el motor Vanilla Doom 3.
Stepan1010
1
¿Qué sucede cuando cambias los cálculos de volumen sombra? (Por ejemplo, simplemente escale todos los volúmenes de sombra en un valor pequeño) ¿Los artefactos todavía aparecen / cambian / desaparecen?
Roy T.

Respuestas:

3

Finalmente encontré una solución, en realidad algunas soluciones diferentes. Yo no averiguar la causa real del artefacto de un gráfico de programación perspectiva - pero he encontrado algunas soluciones.

Como dije anteriormente en mi pregunta, parecía que el artefacto solo estaba ocurriendo en los volúmenes de sombra calculados previamente de la geometría estática engendrada por el mundo (que es básicamente geometría que el motor sabe que nunca se moverá, por lo que calcula de antemano -time los volúmenes de sombra y otras cosas con un comando ingresado en la consola llamado "dmap"). No entendí por qué solo estaba en las sombras de la geometría estática del engendro del mundo y no en ninguno de los modelos ASE o LWO.

Ahora, lo que noté fue que en realidad hay una gran cantidad de parámetros que se pueden usar con el comando dmap, uno de estos parámetros se llama "shadowOpt", que debe representar el nivel de optimización de la sombra. Este parámetro establece una enumeración; parece haber algunos niveles diferentes de optimización de sombra:

typedef enum {
    SO_NONE,            // 0 // NOTE: I haven't tried this one yet - should test this one.
    SO_MERGE_SURFACES,  // 1 // NOTE: this was the original default one - it causes some artifacts - the ones I have been trying to fix.
    SO_CULL_OCCLUDED,   // 2 // NOTE: this one works the best - takes a bit longer - but it has alot of unnecessary print statements that could probably be removed.
    SO_CLIP_OCCLUDERS,  // 3 // NOTE: I haven't tried this one yet - but it is not used anywhere.
    SO_CLIP_SILS,       // 4 // NOTE: I haven't tried this one yet - should test this one.
    SO_SIL_OPTIMIZE     // 5 // NOTE: this one doesn't seem to work well at all - and it takes an extrememly long amount of time - was probably an expirimental version.
} shadowOptLevel_t;

He tenido éxito con la opción 2: "SO_CULL_OCCLUDED". Soluciona todos los artefactos, tarda un poco más en ejecutarse, pero creo que gran parte de este tiempo se gasta imprimiendo grandes cantidades de información en la consola; estas impresiones probablemente podrían reducirse o eliminarse.

Uno de los lugares que me dio algunas pistas fue el comentario aquí en tr_stencilshadow.cpp:

// if we are running from dmap, perform the (very) expensive shadow optimizations
// to remove internal sil edges and optimize the caps
if ( callOptimizer ) {

Ahora, el problema con solo hacer esta optimización de sombra "extra" durante "dmap" es que si alguna de estas luces se mueve alguna vez (lo cual siempre es posible dependiendo del tipo de proyecto que esté haciendo), entonces volverá por defecto a proceso de creación de volumen de sombra en tiempo real "no optimizado" (para la luz movida) y los artefactos reaparecerán para esa luz. Entonces, la única forma de garantizar que estos artefactos no aparezcan es ejecutar siempre el costoso proceso de optimización para estas sombras estáticas de engendros mundiales. De hecho, es muy costoso, por lo que este sería un último recurso absoluto si no puede encontrar una solución gráfica adecuada. (si lo hace, asegúrese de publicar su solución aquí).

Recomendaría a cualquiera que cree mapas grandes para el motor Vanilla Doom 3, y que use geometría engendrada por el mundo, que creen un cvar que puedan cambiar dependiendo de sus necesidades para la creación en tiempo real de los volúmenes de sombra optimizados. Llamé a mi cvar r_useExpensiveShadowOptimizations, que parece ser un oxímoron. Por ejemplo:

// if we are running from dmap, perform the (very) expensive shadow optimizations
// to remove internal sil edges and optimize the caps
if ( callOptimizer || r_useExpensiveShadowOptimizations.GetBool() ) {

También recomiendo que, dependiendo del tamaño de sus mapas (y suponiendo que las luces no se muevan), aumente el nivel de optimización del volumen de sombra estática con el parámetro "shadowOpt" para dmap.

Entonces, básicamente, todas las cosas que necesita para tener un mapa grande y no tener artefactos de sombra están ahí para usted, solo tiene que decidir cuáles necesitará usar. Hacerlo en tiempo real es extremadamente costoso y solo debe hacerse como último recurso si no puede encontrar una solución gráfica adecuada. Hacerlo en DMAP tiene mucho sentido ya que resuelve el problema y solo toma unos segundos más para que el mapa se compile.

Stepan1010
fuente
2

Podría muy bien ser un error de precisión de puntero flotante, ya que Doom usaba floats para el renderizado (principalmente una limitación de OpenGL). Sin embargo, jugando tr_stencilshadow.cpp, he notado este comentario que podría estar relacionado con el problema ( PointsOrdered()función interna ):

// vectors that wind up getting an equal hash value will
// potentially cause a misorder, which can show as a couple
// crack pixels in a shadow

....

// in the very rare case that these might be equal, all that would
// happen is an oportunity for a tiny rasterization shadow crack

Entonces ahí está. También podría ser una limitación conocida de la forma en que se implementó el renderizado de sombras. Francamente, el código es muy desordenado y difícil de leer, por lo que no puedo decirte con seguridad. Puede intentar enviar correos a los desarrolladores para obtener más información.

glampert
fuente
1
También vi ese comentario. Sin embargo, cuando comenté el código de esa función y solo hice que devolviera verdadero (o falso, no importa), no parece haber ninguna diferencia visual en nada. ¿Crees que alguno de los desarrolladores respondería si les enviara un correo electrónico? Siento que probablemente no responderían. Supongo que podría intentarlo si todo lo demás falla.
Stepan1010
@ Stepan1010 Bueno, no sé, Carmack es un tipo genial, una vez le envié un correo electrónico sobre algo no relacionado con la programación y él respondió. Supongo que no hará daño intentarlo ... Pero tal vez debería enviar un correo electrónico al responsable del repositorio, ya que Carmack ya no es miembro de idSoftware. Si muestra un problema legítimo y el trabajo que hizo, podrían estar interesados.
glampert