Rilevamento della superficie visibile
Quando guardiamo un'immagine contenente oggetti e superfici non trasparenti, non possiamo vedere quegli oggetti che si trovano dietro agli oggetti più vicini all'occhio. Dobbiamo rimuovere queste superfici nascoste per ottenere un'immagine realistica sullo schermo. Viene chiamata l'identificazione e la rimozione di queste superficiHidden-surface problem.
Esistono due approcci per rimuovere i problemi di superficie nascosta: Object-Space method e Image-space method. Il metodo Object-space è implementato nel sistema di coordinate fisico e il metodo image-space è implementato nel sistema di coordinate dello schermo.
Quando vogliamo visualizzare un oggetto 3D su uno schermo 2D, dobbiamo identificare quelle parti di uno schermo che sono visibili da una posizione di visualizzazione scelta.
Metodo Depth Buffer (Z-Buffer)
Questo metodo è sviluppato da Cutmull. È un approccio spazio-immagine. L'idea di base è testare la profondità Z di ciascuna superficie per determinare la superficie (visibile) più vicina.
In questo metodo ogni superficie viene elaborata separatamente, una posizione pixel alla volta sulla superficie. I valori di profondità di un pixel vengono confrontati e la superficie più vicina (z più piccola) determina il colore da visualizzare nel frame buffer.
Si applica in modo molto efficiente sulle superfici del poligono. Le superfici possono essere lavorate in qualsiasi ordine. Per sovrascrivere i poligoni più vicini da quelli lontani, due buffer denominatiframe buffer e depth buffer, sono usati.
Depth buffer viene utilizzato per memorizzare i valori di profondità per la posizione (x, y), mentre le superfici vengono elaborate (0 ≤ profondità ≤ 1).
Il frame buffer viene utilizzato per memorizzare il valore di intensità del valore del colore in ciascuna posizione (x, y).
Le coordinate z sono normalmente normalizzate nell'intervallo [0, 1]. Il valore 0 per la coordinata z indica il riquadro di ritaglio posteriore e il valore 1 per le coordinate z indica il riquadro di ritaglio anteriore.
Algoritmo
Step-1 - Impostare i valori del tampone -
Buffer di profondità (x, y) = 0
Framebuffer (x, y) = colore di sfondo
Step-2 - Elabora ogni poligono (uno alla volta)
Per ogni posizione di pixel proiettata (x, y) di un poligono, calcolare la profondità z.
Se Z> buffer di profondità (x, y)
Calcola il colore della superficie,
imposta il buffer di profondità (x, y) = z,
framebuffer (x, y) = surfacecolor (x, y)
Vantaggi
- È facile da implementare.
- Riduce il problema di velocità se implementato nell'hardware.
- Elabora un oggetto alla volta.
Svantaggi
- Richiede una grande memoria.
- È un processo che richiede tempo.
Metodo linea di scansione
È un metodo dello spazio dell'immagine per identificare la superficie visibile. Questo metodo ha informazioni di profondità solo per una singola linea di scansione. Per richiedere una linea di scansione di valori di profondità, dobbiamo raggruppare ed elaborare tutti i poligoni che intersecano una data linea di scansione contemporaneamente prima di elaborare la successiva linea di scansione. Due tabelle importanti,edge table e polygon table, vengono mantenuti per questo.
The Edge Table - Contiene i punti finali delle coordinate di ciascuna linea nella scena, la pendenza inversa di ciascuna linea e i puntatori nella tabella dei poligoni per collegare i bordi alle superfici.
The Polygon Table - Contiene i coefficienti del piano, le proprietà del materiale della superficie, altri dati sulla superficie e può essere un puntatore alla tabella dei bordi.
Per facilitare la ricerca di superfici che attraversano una data linea di scansione, viene formato un elenco attivo di bordi. L'elenco attivo memorizza solo quei bordi che attraversano la linea di scansione in ordine crescente di x. Inoltre, una bandiera è impostata per ciascuna superficie per indicare se una posizione lungo una linea di scansione è all'interno o all'esterno della superficie.
Le posizioni dei pixel su ciascuna linea di scansione vengono elaborate da sinistra a destra. All'incrocio a sinistra con una superficie, la bandiera di superficie è attivata ea destra, la bandiera è disattivata. È necessario eseguire calcoli di profondità solo quando più superfici hanno i flag attivati in una determinata posizione della linea di scansione.
Metodo di suddivisione dell'area
Il metodo di suddivisione dell'area sfrutta l'individuazione di quelle aree di visualizzazione che rappresentano parte di una singola superficie. Dividere l'area di visualizzazione totale in rettangoli sempre più piccoli fino a quando ogni piccola area è la proiezione di una parte di una singola superficie visibile o nessuna superficie.
Continuare questo processo fino a quando le suddivisioni non vengono facilmente analizzate come appartenenti a una singola superficie o fino a quando non vengono ridotte alle dimensioni di un singolo pixel. Un modo semplice per farlo è dividere successivamente l'area in quattro parti uguali ad ogni passaggio. Esistono quattro possibili relazioni che una superficie può avere con un contorno di area specificato.
Surrounding surface - Uno che racchiuda completamente l'area.
Overlapping surface - Uno che è in parte all'interno e in parte all'esterno dell'area.
Inside surface - Uno che sia completamente all'interno dell'area.
Outside surface - Uno che è completamente al di fuori dell'area.
I test per determinare la visibilità della superficie all'interno di un'area possono essere definiti in base a queste quattro classificazioni. Non sono necessarie ulteriori suddivisioni di un'area specifica se si verifica una delle seguenti condizioni:
- Tutte le superfici sono superfici esterne rispetto all'area.
- Solo una superficie interna, sovrapposta o circostante si trova nell'area.
- Una superficie circostante oscura tutte le altre superfici all'interno dei confini dell'area.
Rilevamento faccia posteriore
Un metodo veloce e semplice dello spazio oggetto per identificare le facce posteriori di un poliedro si basa sui test "interno-esterno". Un punto (x, y, z) è "all'interno" di una superficie poligonale con parametri di piano A, B, C e D se Quando un punto interno si trova lungo la linea di vista verso la superficie, il poligono deve essere una faccia posteriore ( siamo dentro quella faccia e non possiamo vederne la parte anteriore dalla nostra posizione di visione).
Possiamo semplificare questo test considerando il vettore normale N a una superficie poligonale, che ha componenti cartesiane (A, B, C).
In generale, se V è un vettore nella direzione di visione dalla posizione dell'occhio (o della "telecamera"), questo poligono è una faccia posteriore se
V.N > 0
Inoltre, se le descrizioni degli oggetti vengono convertite in coordinate di proiezione e la direzione di visualizzazione è parallela all'asse z di visualizzazione, allora:
V = (0, 0, V z ) e V.N = V Z C
Quindi dobbiamo solo considerare il segno di C la componente del vettore normale N.
In un sistema di visualizzazione destrorso con direzione di visualizzazione lungo l'asse $ Z_ {V} $ negativo, il poligono è una faccia posteriore se C <0. Inoltre, non possiamo vedere alcuna faccia la cui normale ha componente z C = 0, poiché la direzione di visualizzazione è verso quel poligono. Quindi, in generale, possiamo etichettare qualsiasi poligono come faccia posteriore se il suo vettore normale ha il valore del componente az -
C <= 0
Metodi simili possono essere utilizzati in pacchetti che utilizzano un sistema di visualizzazione per mancini. In questi pacchetti, i parametri del piano A, B, C e D possono essere calcolati dalle coordinate del vertice del poligono specificate in senso orario (a differenza della direzione antioraria usata in un sistema destrorso).
Inoltre, le facce posteriori hanno vettori normali che puntano lontano dalla posizione di visualizzazione e sono identificate da C> = 0 quando la direzione di visualizzazione è lungo l'asse $ Z_ {v} $ positivo. Esaminando il parametro C per i diversi piani che definiscono un oggetto, possiamo immediatamente identificare tutte le facce posteriori.
Metodo A-Buffer
Il metodo A-buffer è un'estensione del metodo depth-buffer. Il metodo A-buffer è un metodo di rilevamento della visibilità sviluppato presso i Lucas Film Studios per il sistema di rendering Renders Everything You Ever Saw (REYES).
Il buffer A espande il metodo del buffer di profondità per consentire le trasparenze. La struttura dei dati chiave nell'A-buffer è il buffer di accumulo.
Ogni posizione nell'A-buffer ha due campi:
Depth field - Memorizza un numero reale positivo o negativo
Intensity field - Memorizza le informazioni sull'intensità della superficie o un valore del puntatore
Se profondità> = 0, il numero memorizzato in quella posizione è la profondità di una singola superficie che si sovrappone all'area pixel corrispondente. Il campo di intensità memorizza quindi i componenti RGB del colore della superficie in quel punto e la percentuale di copertura dei pixel.
Se la profondità è <0, indica i contributi su più superfici all'intensità dei pixel. Il campo di intensità memorizza quindi un puntatore a un elenco collegato di dati di superficie. Il buffer di superficie nell'A-buffer include:
- Componenti dell'intensità RGB
- Parametro di opacità
- Depth
- Percentuale di copertura dell'area
- Identificatore di superficie
L'algoritmo procede proprio come l'algoritmo del buffer di profondità. I valori di profondità e opacità vengono utilizzati per determinare il colore finale di un pixel.
Metodo di ordinamento della profondità
Il metodo di ordinamento in profondità utilizza sia lo spazio immagine che le operazioni spazio oggetti. Il metodo di ordinamento in profondità esegue due funzioni di base:
Innanzitutto, le superfici vengono ordinate in ordine di profondità decrescente.
In secondo luogo, le superfici vengono convertite in scansione in ordine, a partire dalla superficie di maggiore profondità.
La conversione della scansione delle superfici poligonali viene eseguita nello spazio dell'immagine. Questo metodo per risolvere il problema della superficie nascosta è spesso indicato comepainter's algorithm. La figura seguente mostra l'effetto dell'ordinamento di profondità:
L'algoritmo inizia con l'ordinamento in base alla profondità. Ad esempio, la stima iniziale della "profondità" di un poligono può essere considerata il valore z più vicino a qualsiasi vertice del poligono.
Prendiamo il poligono P alla fine della lista. Considera tutti i poligoni Q le cui estensioni z si sovrappongono a quelle di P. Prima di disegnare P, eseguiamo i seguenti test. Se uno qualsiasi dei seguenti test è positivo, possiamo supporre che P possa essere disegnato prima di Q.
- Le estensioni x non si sovrappongono?
- Le estensioni y non si sovrappongono?
- P è interamente sul lato opposto del piano di Q dal punto di vista?
- Q è interamente sullo stesso lato del piano di P del punto di vista?
- Le proiezioni dei poligoni non si sovrappongono?
Se tutti i test falliscono, dividiamo P o Q usando il piano dell'altro. I nuovi poligoni tagliati vengono inseriti nell'ordine di profondità e il processo continua. Teoricamente, questo partizionamento potrebbe generare O (n 2 ) poligoni individuali, ma in pratica il numero di poligoni è molto inferiore.
Alberi della partizione spaziale binaria (BSP)
Il partizionamento binario dello spazio viene utilizzato per calcolare la visibilità. Per costruire gli alberi BSP, si dovrebbe iniziare con i poligoni ed etichettare tutti i bordi. Avendo a che fare con un solo bordo alla volta, estendi ciascun bordo in modo che divida il piano in due. Posiziona il primo bordo dell'albero come radice. Aggiungi i bordi successivi in base al fatto che siano interni o esterni. I bordi che coprono l'estensione di un bordo che è già nell'albero vengono divisi in due ed entrambi vengono aggiunti all'albero.
Dalla figura sopra, prima prendere A come radice.
Fai un elenco di tutti i nodi nella figura (a).
Metti tutti i nodi che si trovano davanti a root A sul lato sinistro del nodo A e metti tutti quei nodi che stanno dietro la radice A a destra come mostrato nella figura (b).
Elaborare prima tutti i nodi anteriori e poi i nodi posteriori.
Come mostrato nella figura (c), elaboreremo prima il nodo B. Poiché non c'è niente davanti al nodoB, abbiamo messo NIL. Tuttavia, abbiamo nodeC sul retro del nodo B, quindi nodo C andrà sul lato destro del nodo B.
Ripeti la stessa procedura per il nodo D.