2012-08-14 5 views
10

Sto imparando OpenGL e l'unico argomento che continua a sconcertarmi è il lontano piano di clipping. Mentre riesco a capire il ragionamento che sta dietro al piano di clipping vicino, e ai piani di ritaglio laterali (che non hanno mai alcun effetto reale perché gli oggetti al di fuori di essi non sarebbero mai resi comunque), il piano di ritaglio lontano sembra essere solo un fastidio.Perché OpenGL ha un piano di ritaglio lontano e quali sono gli idiomi usati per gestire questo?

Dato che quelli dietro OpenGL hanno ovviamente pensato questo, so che ci deve essere qualcosa che mi manca. Perché OpenGL ha un piano di ritaglio lontano? Ancora più importante, perché non è possibile disattivarlo, quali sono gli idiomi e le pratiche consigliate da utilizzare quando si disegnano oggetti a distanze enormi (per oggetti come migliaia di unità di distanza in un gioco spaziale, uno skybox, ecc.)? Vi aspettate solo per rendere l'aereo di ritaglio molto lontano, o c'è una soluzione più elegante? Come viene fatto nel software di produzione?

risposta

19

L'unica ragione è la precisione della profondità. Dal momento che hai solo un numero limitato di bit nel depth buffer, puoi anche solo rappresentare una quantità limitata di profondità con esso.

Tuttavia, è possibile impostare il piano lontano su infinitamente lontano: vedere this. Non funzionerà molto bene con il buffer di profondità: vedrai molti artefatti se hai un'occlusione lontana.

Quindi, dato che questo ruota attorno al buffer di profondità, non avrai problemi a occuparti di cose lontane, purché non lo usi. Ad esempio, una tecnica comune è il rendering della scena in "lastre" che utilizzano ciascuna solo il buffer di profondità internamente (per tutto il materiale in una lastra) ma una qualche forma dell'algoritmo del pittore esternamente (per le lastre, quindi si disegna la più lontana prima)

+0

Vale la pena notare che l'impostazione del piano di ritaglio vicino per chiudere a zero causerà lo stesso effetto di avere il piano di ritaglio lontano impostato troppo lontano. Secondo http://www.opengl.org/archives/resources/faq/technical/depthbuffer.htm circa il numero di bit persi è log2 (lontano/vicino). –

9

Perché OpenGL ha un piano di ritaglio lontano?

Perché i computer sono finito.

Ci sono generalmente due modi per tentare di affrontare questo. Un modo è costruire la proiezione prendendo il limite mentre z-far si avvicina all'infinito. Questo convergerà su valori finiti, ma può creare scompiglio con la precisione della profondità per oggetti distanti.

Un'alternativa (se si desidera che gli oggetti oltre una certa distanza non superino correttamente il test di profondità) è quella di attivare il bloccaggio di profondità con glEnable(GL_DEPTH_CLAMP). Ciò impedirà il clipping contro i piani vicini e lontani; è solo che qualsiasi frammento che avrebbe normalizzato le coordinate z al di fuori dell'intervallo [-1, 1] verrà bloccato a quell'intervallo. Come indicato in precedenza, elimina i test di profondità tra i frammenti che vengono bloccati, ma solitamente questi oggetti sono lontani.

0

È solo "il fatto" che il test di profondità OpenGL è stato eseguito in Coordinate spazio finestra (coordinate del dispositivo normalizzate in [-1,1]^3. Con ridimensionamento extra glViewport e glDepthRange).

Quindi dal mio punto di vista è uno dei punti di vista del progetto della libreria OpenGL.


Uno dei approccio per eliminare questa funzionalità di base estensione/OpenGL OpenGL https://www.opengl.org/registry/specs/ARB/depth_clamp.txt se è disponibile nella versione OpenGL.


Voglio descrivere che nella proiezione prospettica non c'è nulla riguardo al "piano di ritaglio lontano".

3.1 Per la proiezione prospettica è necessario impostare il punto \ vec {c} come centro di proiezione e piano su cui verrà eseguita la proiezione. Chiamiamolo piano di immagine T: (\ vec {r} - \ vec {r_0}, \ vec {n})

3.2 Supponiamo che il piano proiettato T divida punto arbitario \ vec {r} e \ vec { c} centrale della proiezione. In altri casi \ vec {r} e \ vec {c} sono in uno hafe-space e point \ vec {r} dovrebbe essere scartato.

3.4 L'idea di proiezione è di trovare intersezione \ vec {i} con piano T \ vec {i} = (1-t) \ vec {c} + t \ vec {r}

3.5 come è (\ vec {i} - \ vec {r_0}, \ vec {n}) = 0

=>

((1-t) \ vec {c} + t \ vec {r} - \ vec {} r_0, \ vec {} n) = 0

=>

(\ vec {c } + t (\ vec {r} - \ vec {c}) - \ vec {r_0}, \ vec {n}) = 0

3.6. Da "3.5" derivato può essere sottotitolato in "3.4" e si riceverà la proiezione nel piano T.

3.7. Dopo la proiezione, il punto si troverà nell'aereo. Ma se supponiamo che il piano dell'immagine sia parallelo al piano OXY, allora posso suggerire di usare la "profondità" originale per il punto dopo la proiezione.

Quindi dal punto di vista della geometria è possibile non utilizzare affatto il piano lontano. Come anche non usare il modello [-1,1]^3 esplicitamente.

p.s. Non so come digitare le formule al lattice in modo corretto, per es. saranno resi.

Problemi correlati