ombre stencil - motore doom 3 - errori di precisione - ombre crepe - perché?


8

Sto testando i limiti del motore Doom 3 - per quanto riguarda le dimensioni massime della mappa.

Ho notato alcuni errori di precisione dell'ombra dello stencil che diventano più pronunciati quando gli oggetti si allontanano sempre più dall'origine della mappa.

in posizione: -10901-18214-11204 Esempio 1

in posizione: -10802 -26483 -19383 example2

in posizione: -10802-34683 -27540 Example3

Credo che questi errori siano stati definiti "crepe dell'ombra", ma non sono sicuro di come questi artefatti siano stati precedentemente chiamati.

Quasi tutti i manufatti compaiono lungo i confini delle luci / ombre - che possono essere visti qui: inserisci qui la descrizione dell'immagine

Qualcuno ha mai visto questo tipo di artefatto grafico con ombre stencil? Come si chiamano? Qual è la causa?

Altri esempi: misc1 MISC2

Questo è il motore Doom 3 alla vaniglia come si trova qui: https://github.com/TTimo/doom3.gpl

Durante il test di r_useOptimizedShadows cvar (che gestisce i volumi d'ombra della geometria del mondo) ho notato che l'artefatto è scomparso. Quindi ho lavorato per questa funzione:

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

che ho cambiato in questo:

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

Ciò elimina i manufatti, ma ora assume che non siamo mai all'interno dei volumi ombra della geometria del mondo. Quindi ogni volta che andiamo all'interno di un volume shadow, quel volume shadow non viene visualizzato correttamente.


1
Non sei sicuro di questa specifica implementazione, ma in virgola mobile perde precisione quanto più vai da zero.
concept3d

2
Concordato. 7 cifre rappresentano quasi la massima precisione che ci si può aspettare da numeri in virgola mobile a 32 bit (ovvero C / C ++ float). Ne hai facilmente utilizzate 5. en.wikipedia.org/wiki/…
snake5

@ concept3d - Suppongo che la conversione dei float rilevanti in double sarebbe di aiuto? Se qualcuno avesse il know-how tecnico per farlo. Anche se ciò comporterebbe tempi di rendering più lunghi.
Stepan1010,

1
@glampert Ho aggiornato la domanda. È il motore Doom 3 alla vaniglia.
Stepan1010,

1
Cosa succede quando si modificano i calcoli del volume ombra? (Ad esempio, ridimensionare tutti i volumi delle ombre di un valore ridotto) Gli artefatti appaiono ancora / cambiano / scompaiono?
Roy T.

Risposte:


3

Alla fine ho trovato una soluzione, in realtà alcune soluzioni diverse. Ho fatto non capire la vera causa del manufatto da una grafica di programmazione punto di vista - ma ho trovato alcune soluzioni.

Come ho affermato in precedenza nella mia domanda, sembrava che il manufatto si stesse verificando solo sui volumi d'ombra precalcolati della geometria statica generata dal mondo (che è fondamentalmente geometria che il motore sa che non si muoverà mai, quindi pre-calcola in anticipo -time i volumi shadow e altre cose con un comando inserito nella console chiamato "dmap"). Non ho capito perché fosse solo sulle ombre della geometria statica generata dal mondo e non su nessuno dei modelli ASE o LWO.

Ora, la cosa che ho notato è che in realtà esiste una pletora di parametri che possono essere utilizzati con il comando dmap - uno di questi parametri è chiamato "shadowOpt" - che deve rappresentare il livello di ottimizzazione dell'ombra. Questo parametro imposta un enum: sembrano esserci diversi livelli di ottimizzazione dell'ombra:

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;

Ho avuto successo con l'opzione 2 - "SO_CULL_OCCLUDED". Corregge tutti gli artefatti - richiede un po 'più di tempo per essere eseguito - ma credo che molto di questo tempo sia passato a stampare grandi quantità di informazioni sulla console - queste stampe potrebbero probabilmente essere ridotte o eliminate.

Uno dei luoghi che mi ha dato alcuni indizi è stato il commento qui 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 ) {

Ora, il problema con questa ottimizzazione dell'ombra "extra" solo durante "dmap" è che se una di queste luci viene mai spostata (il che è sempre possibile a seconda del tipo di progetto che stai facendo) - tornerà automaticamente al processo di creazione del volume dell'ombra in tempo reale "non ottimizzato" (per la luce spostata) e gli artefatti riappariranno per quella luce. Quindi l'unico modo per garantire che questi artefatti non appaiano è quello di eseguire sempre il costoso processo di ottimizzazione per queste ombre statiche dipinte dal mondo. È infatti molto costoso, quindi questa sarebbe l'ultima risorsa assoluta se non riuscissi a trovare una soluzione grafica adeguata. (se lo fai, assicurati di pubblicare la tua soluzione qui.)

Consiglierei a chiunque crei mappe di grandi dimensioni per il motore Doom 3 vaniglia - e usando la geometria di worldspawn - di creare una cvar che possano cambiare in base alle loro esigenze per la creazione in tempo reale dei volumi di ombra ottimizzati. Ho chiamato il mio cvar r_useExpensiveShadowOptimizations - che sembra essere un ossimoro. Per esempio:

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

Raccomando anche che, a seconda della dimensione delle mappe (e supponendo che le luci non si muovano), aumenti il ​​livello di ottimizzazione del volume dell'ombra statica con il parametro "shadowOpt" per dmap.

Quindi praticamente tutte le cose che ti servono per avere una grande mappa e non avere artefatti ombra sono lì per te, devi solo decidere quali ti serviranno. Farlo in tempo reale è estremamente costoso e dovrebbe essere fatto come ultima risorsa se non riesci a trovare una soluzione grafica adeguata. Farlo in DMAP ha perfettamente senso in quanto risolve il problema e richiede solo qualche secondo in più per la compilazione della mappa.


2

Potrebbe benissimo essere un errore di precisione del puntatore mobile, poiché Doom ha usato floats per il rendering (principalmente una limitazione OpenGL). Tuttavia, armeggiando tr_stencilshadow.cpp, ho notato questo commento che potrebbe essere correlato al problema ( PointsOrdered()funzione 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

Quindi eccolo. Potrebbe anche essere una limitazione nota del modo in cui è stato implementato il rendering dell'ombra. Francamente, il codice è molto disordinato e difficile da leggere, quindi non posso dirtelo con certezza. Potresti provare a spedire gli sviluppatori per ottenere maggiori informazioni.


1
Ho visto anche quel commento. Tuttavia, quando ho commentato il codice di quella funzione e l'ho appena restituito vero (o falso - non importa) - non sembra fare alcuna differenza visiva a nulla. Pensi che qualcuno degli sviluppatori risponderebbe se li inviassi via email? Sento che probabilmente non avrebbero risposto. Immagino di poterlo provare se tutto il resto fallisce.
Stepan1010,

@ Stepan1010 Beh, non lo so, Carmack è un ragazzo simpatico, una volta gli ho inviato una mail su qualcosa che non era legato alla programmazione e lui ha risposto. Immagino che non danneggerà provare ... Ma forse dovresti spedire il responsabile del repository, poiché Carmack non è più un membro di idSoftware. Se mostri un problema legittimo e il lavoro svolto, potrebbero essere interessati.
glampert
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.