ombres du pochoir - moteur doom 3 - erreurs de précision - fissures d'ombre - pourquoi?

8

Je teste les limites du moteur Doom 3 - en ce qui concerne la taille maximale de la carte.

J'ai remarqué des erreurs de précision de l'ombre du pochoir qui deviennent plus prononcées lorsque les objets s'éloignent de plus en plus de l'origine de la carte.

en position: -10901 -18214 -11204 Exemple 1

à la position: -10802 -26483 -19383 exemple2

en position: -10802 -34683 -27540 exemple3

Je crois que ces erreurs ont été appelées "fissures d'ombre", mais je ne suis pas certain de ce que ces artefacts ont été appelés auparavant.

Presque tous les artefacts apparaissent le long des limites des lumières / ombres - ce qui peut être vu ici: entrez la description de l'image ici

Quelqu'un a-t-il déjà vu ce type d'artefact graphique avec des ombres au pochoir? Comment s'appellent-ils? Quelle est la cause?

Plus d'exemples: misc1 misc2

Il s'agit du moteur Doom 3 vanilla que l'on trouve ici: https://github.com/TTimo/doom3.gpl

J'ai remarqué en testant la cvar r_useOptimizedShadows (qui gère les volumes d'ombre de la géométrie Worldspawn) que l'artefact a disparu. Ensuite, j'ai travaillé sur cette fonction:

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

que j'ai changé en ceci:

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

Cela supprime les artefacts - mais maintenant, il suppose que nous ne sommes jamais à l'intérieur des volumes d'ombre de la géométrie mondiale. Donc, chaque fois que nous entrons dans un volume fantôme, ce volume fantôme n'est pas rendu correctement.

Stepan1010
la source
1
Vous n'êtes pas sûr de cette implémentation spécifique, mais la virgule flottante perd en précision à mesure que vous vous éloignez de zéro.
concept3d
2
D'accord. 7 chiffres est à peu près le maximum de précision que vous pouvez attendre des nombres à virgule flottante 32 bits (alias C / C ++ float). Vous en avez facilement utilisé 5. en.wikipedia.org/wiki/…
snake5
@ concept3d - Je suppose que la conversion des flottants pertinents en doubles aiderait? Si quelqu'un avait le savoir-faire technique pour le faire. Même si cela entraînerait des temps de rendu plus longs.
Stepan1010
1
@glampert J'ai mis à jour la question. C'est le moteur vanille Doom 3.
Stepan1010
1
Que se passe-t-il lorsque vous modifiez les calculs du volume fantôme? (Par exemple, redimensionnez tous les volumes d'ombre par une petite valeur) Les artefacts apparaissent-ils / changent-ils / disparaissent-ils toujours?
Roy T.

Réponses:

3

J'ai finalement trouvé une solution - en fait quelques solutions différentes. Je n'ai pas trouvé la cause réelle de l'artefact du point de vue de la programmation graphique - mais j'ai trouvé des solutions.

Comme je l'ai dit précédemment dans ma question, il est apparu que l'artefact ne se produisait que sur les volumes d'ombre pré-calculés de la géométrie statique Worldspawn (qui est fondamentalement une géométrie que le moteur sait ne va jamais bouger, donc il pré-calcule à l'avance) -temps les volumes fantômes et d'autres choses avec une commande entrée dans la console appelée "dmap"). Je n'ai pas compris pourquoi c'était uniquement sur les ombres de la géométrie statique mondiale et pas sur aucun des modèles ASE ou LWO.

Maintenant, ce que j'ai remarqué, c'est qu'il y a en fait une pléthore de paramètres qui peuvent être utilisés avec la commande dmap - l'un de ces paramètres est appelé "shadowOpt" - qui doit représenter le niveau d'optimisation des ombres. Ce paramètre définit une énumération - il semble y avoir différents niveaux d'optimisation des ombres:

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;

J'ai réussi avec l'option 2 - "SO_CULL_OCCLUDED". Il corrige tous les artefacts - son exécution prend un peu plus de temps - mais je crois qu'une grande partie de ce temps est consacrée à l'impression de grandes quantités d'informations sur la console - ces impressions pourraient probablement être réduites ou supprimées.

L'un des endroits qui m'a donné des indices était le commentaire ici dans 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 ) {

Maintenant, le problème avec seulement cette optimisation d'ombre "supplémentaire" pendant "dmap" est que si l'une de ces lumières est déplacée (ce qui est toujours possible selon le type de projet que vous faites) - elle reviendra par défaut à la processus de création de volume d'ombre en temps réel "non optimisé" (pour la lumière déplacée) et les artefacts réapparaîtront pour cette lumière. Ainsi, la seule façon de garantir que ces artefacts n'apparaîtront pas est de toujours exécuter le processus d'optimisation très coûteux pour ces ombres statiques. C'est en fait très cher, ce serait donc un dernier recours absolu si vous ne pouvez pas trouver une solution graphique appropriée. (si vous le faites, assurez-vous de poster votre solution ici.)

Je recommanderais à quiconque crée de grandes cartes pour le moteur vanilla Doom 3 - et utilise la géométrie worldspawn - de créer une cvar qu'ils peuvent changer en fonction de leurs besoins pour la création en temps réel des volumes d'ombre optimisés. J'ai appelé mon cvar r_useExpensiveShadowOptimizations - qui semble être un oxymore. Par exemple:

// 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() ) {

Je recommande également qu'en fonction de la taille de vos cartes (et en supposant que les lumières ne bougent pas), vous augmentez le niveau d'optimisation du volume d'ombre statique avec le paramètre "shadowOpt" pour dmap.

Donc, fondamentalement, toutes les choses dont vous avez besoin pour avoir une grande carte et ne pas avoir d'artefacts d'ombre sont là pour vous, il vous suffit de décider celles que vous devrez utiliser. Le faire en temps réel est extrêmement coûteux et ne doit être fait qu'en dernier recours si vous ne trouvez pas de solution graphique appropriée. Le faire dans DMAP est parfaitement logique car il résout le problème et ne prend que quelques secondes de plus pour que la carte soit compilée.

Stepan1010
la source
2

Cela pourrait très bien être une erreur de précision du pointeur flottant, car Doom a utilisé floats pour le rendu (principalement une limitation OpenGL). Cependant, en tripotant tr_stencilshadow.cpp, j'ai remarqué ce commentaire qui pourrait être lié au problème ( PointsOrdered()fonction interne ):

// 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

Tiens voilà. Il peut également s'agir d'une limitation connue de la façon dont le rendu des ombres a été implémenté. Franchement, le code est très compliqué et difficile à lire, donc je ne peux pas vous le dire avec certitude. Vous pouvez essayer d'envoyer un mail aux développeurs pour obtenir plus d'informations.

glampert
la source
1
J'ai également vu ce commentaire. Cependant, lorsque j'ai commenté le code de cette fonction et que je l'ai simplement renvoyé vrai (ou faux - cela n'a pas d'importance) - cela ne semble faire aucune différence visuelle. Pensez-vous que l'un des développeurs répondrait si je lui envoyais un e-mail? J'ai l'impression qu'ils ne répondraient probablement pas. Je suppose que je pourrais essayer si tout le reste échoue.
Stepan1010
@ Stepan1010 Eh bien, je ne sais pas, Carmack est un gars cool, je lui ai envoyé une fois quelque chose sans rapport avec la programmation et il a répondu. Je suppose que cela ne fera pas de mal d'essayer ... Mais peut-être que vous devriez envoyer un mail au mainteneur du repo, car Carmack n'est plus membre d'idSoftware. Si vous montrez un problème légitime et le travail que vous avez fait, ils pourraient être intéressés.
glampert