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.