Schablonenschatten - Doom 3 Engine - Präzisionsfehler - Schattenrisse - warum?

8

Ich teste die Grenzen der Doom 3-Engine - in Bezug auf die maximale Kartengröße.

Ich bemerkte einige Schablonenschatten-Präzisionsfehler, die stärker werden, wenn Objekte immer weiter vom Kartenursprung entfernt werden.

an Position: -10901 -18214 -11204 Beispiel 1

an Position: -10802 -26483 -19383 Beispiel2

an Position: -10802 -34683 -27540 Beispiel3

Ich glaube, diese Fehler wurden als "Schattenrisse" bezeichnet, aber ich bin mir nicht sicher, wie diese Artefakte zuvor genannt wurden.

Fast alle Artefakte erscheinen entlang der Grenzen der Lichter / Schatten - was hier zu sehen ist: Geben Sie hier die Bildbeschreibung ein

Hat jemand diese Art von grafischem Artefakt schon einmal mit Schablonenschatten gesehen? Wie werden sie genannt? Was ist die Ursache?

Mehr Beispiele: Sonstiges1 misc2

Dies ist die Vanilla Doom 3 Engine, wie sie hier zu finden ist: https://github.com/TTimo/doom3.gpl

Beim Testen der cvar r_useOptimizedShadows (die die Schattenvolumina der Worldspawn-Geometrie verarbeitet) ist mir aufgefallen, dass das Artefakt verschwunden ist. Dann habe ich mich zu dieser Funktion durchgearbeitet:

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

was ich geändert habe:

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

Dadurch werden die Artefakte beseitigt - aber jetzt wird davon ausgegangen, dass wir uns niemals in Schattenvolumina der Worldspawn-Geometrie befinden. Wenn wir also in ein Schattenvolumen gehen, wird dieses Schattenvolumen nicht richtig gerendert.

Stepan1010
quelle
1
Ich bin mir bei dieser speziellen Implementierung nicht sicher, aber Gleitkomma verliert an Genauigkeit, je weiter Sie von Null entfernt sind.
concept3d
2
Einverstanden. 7 Stellen sind ungefähr die maximale Genauigkeit, die Sie von 32-Bit-Gleitkommazahlen (auch bekannt als C / C ++ float) erwarten können . Sie haben leicht 5 davon verbraucht. en.wikipedia.org/wiki/…
snake5
@ concept3d - Ich nehme an, die Konvertierung der relevanten Floats in Doubles würde helfen? Wenn jemand das technische Know-how dazu hätte. Auch wenn dies zu längeren Renderzeiten führen würde.
Stepan1010
1
@glampert Ich habe die Frage aktualisiert. Es ist der Vanilla Doom 3 Motor.
Stepan1010
1
Was passiert, wenn Sie die Schattenvolumenberechnungen ändern? (Skalieren Sie zum Beispiel einfach alle Schattenvolumina um einen kleinen Wert.) Erscheinen / ändern / verschwinden die Artefakte immer noch?
Roy T.

Antworten:

3

Ich habe endlich eine Lösung gefunden - eigentlich ein paar verschiedene Lösungen. Ich habe nicht herauszufinden , die eigentliche Ursache des Artefakts aus einer Grafik Perspektive Programmierung - aber ich habe einige Lösungen zu finden.

Wie ich bereits in meiner Frage festgestellt habe, schien das Artefakt nur auf den vorberechneten Schattenvolumina der statischen Geometrie der Weltbrut aufzutreten (bei der es sich im Grunde um eine Geometrie handelt, von der die Engine weiß, dass sie sich niemals bewegen wird, sodass sie vorab berechnet wird -Zeit die Schattenvolumes und andere Dinge mit einem in der Konsole eingegebenen Befehl namens "dmap"). Ich habe nicht herausgefunden, warum es nur auf den Schatten der statischen Worldspawn-Geometrie und nicht auf einem der ASE- oder LWO-Modelle lag.

Nun ist mir aufgefallen, dass es tatsächlich eine Vielzahl von Parametern gibt, die mit dem Befehl dmap verwendet werden können - einer dieser Parameter heißt "shadowOpt" - und der für die Schattenoptimierungsstufe stehen muss. Dieser Parameter legt eine Aufzählung fest - es scheint einige verschiedene Schattenoptimierungsstufen zu geben:

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;

Ich hatte Erfolg mit Option 2 - "SO_CULL_OCCLUDED". Es behebt alle Artefakte - die Ausführung dauert etwas länger - aber ich glaube, ein Großteil dieser Zeit wird für das Drucken großer Informationsmengen auf die Konsole aufgewendet - diese Ausdrucke könnten wahrscheinlich reduziert oder beseitigt werden.

Einer der Orte, die mir einige Hinweise gaben, war der Kommentar hier in 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 ) {

Das Problem, nur diese "zusätzliche" Schattenoptimierung während "dmap" durchzuführen, besteht darin, dass, wenn eines dieser Lichter jemals bewegt wird (was je nach Art des von Ihnen ausgeführten Projekts immer möglich ist), standardmäßig die Option "Zurück" verwendet wird "nicht optimierter" Echtzeit-Prozess zur Erstellung des Schattenvolumens (für das bewegte Licht) und die Artefakte werden für dieses Licht wieder angezeigt. Die einzige Möglichkeit, um sicherzustellen, dass diese Artefakte nicht angezeigt werden, besteht darin, immer den sehr teuren Optimierungsprozess für diese statischen Worldspawn-Schatten auszuführen. Es ist in der Tat sehr teuer, daher wäre dies ein absoluter letzter Ausweg, wenn Sie keine richtige Grafiklösung finden könnten. (Wenn Sie dies tun, stellen Sie sicher, dass Sie Ihre Lösung hier veröffentlichen.)

Ich würde jedem empfehlen, der große Karten für die Vanilla Doom 3-Engine erstellt - und dabei Worldspawn-Geometrie verwendet -, eine Cvar zu erstellen, die er je nach seinen Anforderungen für die Echtzeiterstellung der optimierten Schattenvolumina ändern kann. Ich habe meine cvar r_useExpensiveShadowOptimizations aufgerufen - was ein Oxymoron zu sein scheint. Zum Beispiel:

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

Ich empfehle außerdem, dass Sie abhängig von der Größe Ihrer Karten (und der Annahme, dass sich die Lichter nicht bewegen) die Optimierungsstufe für das statische Schattenvolumen mit dem Parameter "shadowOpt" für dmap erhöhen.

Grundsätzlich sind alle Dinge, die Sie benötigen, um eine große Karte und keine Schattenartefakte zu haben, für Sie da. Sie müssen nur entscheiden, welche Sie verwenden müssen. Dies in Echtzeit zu tun ist extrem teuer und sollte nur als letztes Mittel durchgeführt werden, wenn Sie keine geeignete Grafiklösung finden. Dies in DMAP zu tun, ist absolut sinnvoll, da es das Problem löst und das Kompilieren der Karte nur noch wenige Sekunden dauert.

Stepan1010
quelle
2

Es könnte sehr gut ein Präzisionsfehler mit schwebendem Zeiger sein, da Doom floats für das Rendern verwendet hat (hauptsächlich eine OpenGL-Einschränkung). Beim Herumspielen tr_stencilshadow.cpphabe ich jedoch diesen Kommentar bemerkt, der möglicherweise mit dem Problem zusammenhängt (Innenfunktion PointsOrdered()):

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

Da ist es also. Es könnte auch eine bekannte Einschränkung der Art und Weise sein, wie das Schatten-Rendering implementiert wurde. Ehrlich gesagt ist der Code sehr chaotisch und schwer zu lesen, daher kann ich es Ihnen nicht sicher sagen. Sie können versuchen, den Entwicklern eine E-Mail zu senden, um weitere Informationen zu erhalten.

glampert
quelle
1
Ich habe diesen Kommentar auch gesehen. Wenn ich jedoch den Code dieser Funktion auskommentierte und ihn nur als wahr (oder falsch - es spielt keine Rolle) zurückgeben ließ, schien er überhaupt keinen visuellen Unterschied zu machen. Glaubst du, einer der Entwickler würde antworten, wenn ich ihnen eine E-Mail schicken würde? Ich habe das Gefühl, dass sie wahrscheinlich nicht antworten würden. Ich denke, ich könnte das versuchen, wenn alles andere fehlschlägt.
Stepan1010
@ Stepan1010 Nun, ich weiß nicht, Carmack ist ein cooler Typ. Ich habe ihm einmal eine E-Mail über etwas geschickt, das nichts mit Programmierung zu tun hat, und er hat geantwortet. Ich denke, es schadet nicht, es zu versuchen ... Aber vielleicht sollten Sie dem Repo-Betreuer eine E-Mail senden, da Carmack kein Mitglied von idSoftware mehr ist. Wenn Sie ein legitimes Problem und die von Ihnen geleistete Arbeit zeigen, könnten sie interessiert sein.
Glampert