Come devo gestire i vertici di ritaglio più vicini all'occhio rispetto al piano di clip vicino?


13

Sto rotolando il mio motore 3D, in JavaScript, e usando solo il disegno su tela, senza WebGL. Questo è un altro clone di Minecraft; Adoro le scatole, non giudicarmi.

Finora, tutto funziona meravigliosamente, tranne una cosa: in 3D, quando alcuni vertici passano dietro il piano di ritaglio vicino, la loro proiezione sullo schermo risulta strana (supponendo che altri vertici usati per tracciare un piano siano davanti).

Ho provato a ritagliare questi punti ma poi riesco a vedere attraverso le superfici che usano questi vertici. In WebGL / OpenGL la scheda grafica si occupa di questi punti e il piano è reso correttamente, ma non ho accesso all'hardware, quindi devo codificarlo da solo.

Non sono sicuro di cosa farne, attualmente l'ultima cosa che mi è venuta in mente è di invertire la proiezione dei punti dietro il piano di ritaglio vicino del giocatore, il che sembra logico poiché devo proiettare un punto su uno schermo che si trova di fronte del vertice.

Ecco i miei pensieri:

inserisci qui la descrizione dell'immagine

Ecco alcune immagini per illustrare cosa succede:

inserisci qui la descrizione dell'immagine

Da lontano il riquadro blu viene visualizzato perfettamente.

inserisci qui la descrizione dell'immagine

Quando alcuni dei vertici passano dietro il piano di ritaglio vicino del giocatore, faccio una proiezione inversa, ma non sembra giusto:

focalLength *= -1;
2d.x = x*focalLength/z;
2d.y = y*focalLength/z;

Nota che la casella grigia dietro è stata completamente rimossa poiché tutti i vertici usati per disegnare le sue facce sono dietro il giocatore.

inserisci qui la descrizione dell'immagine

Questo è ciò che accade quando si guarda in alto o in basso.

Non so cosa pensare della matematica dietro questo, spero che qualcuno abbia già riscontrato lo stesso problema e possa aiutarmi.


1
Se i punti sono più vicini all'occhio rispetto al piano di clip vicino, dovrebbero essere tagliati - e questo potrebbe effettivamente farti vedere "attraverso" un oggetto. Questo è il comportamento tipico; la collisione normalmente impedisce quel particolare artefatto visivo. Era l'unica cosa sbagliata con la tua soluzione di ritaglio?

@JoshPetrie: Capisco che i punti devono essere tagliati, ma se lo faccio tutto il quadrato scompare quando mancano uno o due dei vertici entro i quali deve passare la routine di disegno (in 2d) e il giocatore sarebbe in grado di vedere attraverso quella piazza. Vorrei che fossero "fuori" dalla tela (sulla proiezione) in modo che il quadrato potesse ancora essere disegnato. Non sono sicuro di essere abbastanza chiaro.
Solenoide,

Stai dicendo che è un comportamento normale e vuoi impedire che ciò accada impedendo al giocatore di avvicinarsi così tanto a uno dei cubi. Se vuoi davvero farlo, dovresti tagliare ma ricostruire i triangoli (possibilmente). Questo sembrerà ancora insolito, specialmente se hai trame. Se ciò che sto dicendo non ha senso, puoi unirti a noi nella chat in modo da non creare un thread di commenti davvero chiacchierone.

Quello che stai dicendo ha senso, la ricostruzione richiede troppo tempo, quindi non è la soluzione. Speravo che ci fosse un modo per disegnare quel vertice sul piano 2d che era dietro il giocatore, quindi la lineTo(x,y)funzione poteva ancora essere chiamata, solo che non so come si comporta ... è una dimensione bizzarra, sono d'accordo.
Solenoide,

Risposte:


1

Lo scopo del piano di ritaglio vicino è che si tratta di un piano di ritaglio . I triangoli che si trovano all'esterno di un piano di ritaglio vengono ritagliati : tagliati in pezzi in modo tale che ogni pezzo rimasto sia all'interno dell'area di ritaglio.

Puoi provare a ignorare la clip vicina se lo desideri. In effetti OpenGL e D3D hanno dei modi per disattivare del tutto il clipping vicino al piano (sebbene il buffer di profondità abbia ancora un valore quasi prossimo). Il problema non è la clip vicina.

Il problema è con i vertici dietro la telecamera.

Non è possibile eseguire il rendering di triangoli dietro la telecamera. Non con una proiezione prospettica. Tali triangoli non hanno senso sotto la matematica dietro le proiezioni prospettiche. Inoltre, sono anche al di fuori del frustum.

La disattivazione vicino al ritaglio trasforma un frustum in una piramide. Il motivo per cui la piramide si ferma nel punto è perché i punti sopra la piramide sono dietro tutti e quattro i lati della piramide. Quindi qualsiasi punto dietro la telecamera (la punta della piramide) è sopra, sotto, a sinistra ea destra della regione visibile dello schermo. Tutto allo stesso tempo.

Come ho detto: i vertici sotto una proiezione prospettica dietro la telecamera non hanno senso.

È necessario implementare il ritaglio. È necessario rilevare quando un vertice di un triangolo, nello spazio di clip ( prima della divisione della prospettiva) è dietro la telecamera. In tal caso, è necessario tagliare quel triangolo, generando solo triangoli che si trovano davanti alla telecamera.

Questo non è un processo semplice. Implica la matematica che ha senso solo se hai una piena comprensione dei sistemi di coordinate omogenei. In alternativa, puoi semplicemente raddrizzare qualsiasi triangolo se un vertice è dietro la telecamera.


Fino ad ora ho tagliato l'intero triangolo, ma poi ho visto attraverso l'aereo (vedi foto sopra). Avevo davvero bisogno di un'immagine per capire perché non avesse senso geometricamente. L'unica soluzione è calcolare l'intersezione della linea piana quando uno dei vertici è dietro il piano di ritaglio e utilizzare quell'intersezione per tracciare la linea dal vertice che si trova davanti, purtroppo è costoso.
Solenoide,

0

Se parte del triangolo dietro il piano vicino è possibile eseguire un controllo per pixel per vedere se la posizione del pixel è dietro il piano di ritaglio?

È possibile trattare il piano vicino come qualsiasi altro piano di ritaglio. Ad esempio i piani di ritaglio sono usati per cose come i piani d'acqua (per riflessioni e rifrazioni). Penserei che questo piano di ritaglio funzionerebbe esattamente come il piano di ritaglio vicino e si taglierebbe per pixel.

So come gestire i piani di ritaglio in HLSL con DirectX, ma la loro implementazione potrebbe essere proprietaria. Se riuscissi a ottenere le informazioni per questo potrebbe essere utile.

Inoltre, ecco un link che potrebbe aiutarti: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter42.html


Il test per pixel è estremamente costoso in un linguaggio interpretato come Javascript, ora sto diventando fps a malapena accettabile così com'è.
Solenoide,
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.