Nella computer grafica tridimensionale, lo z-buffering è una tecnica di gestione della coordinata corrispondente alla profondità di un oggetto. Solitamente viene realizzata dall'hardware, ovvero dalla scheda grafica, che deve essere dotata di un'apposita area di memoria detta z-buffer; tuttavia, può avere all'occorrenza anche un'implementazione totalmente software.

Z-buffer data

Lo z-buffering è una delle strategie possibili per risolvere il problema della visibilità nel rendering tridimensionale, ovvero per stabilire quali parti degli oggetti sulla scena siano visibili e quali siano invece nascoste da altri elementi in primo piano. Stabilire per tempo quali oggetti siano da visualizzare consente di ottenere una maggiore efficienza evitando operazioni di rendering inutili. Alcune tecniche (come il tile based rendering) cercano di anticipare lo z-buffering nella pipeline 3D in modo da ottenere una efficienza ancora maggiore.

Un'altra tecnica molto usata, per quanto meno efficiente, è l'algoritmo del pittore.

Descrizione

Quando un oggetto viene visualizzato da una scheda grafica 3D, la profondità dei pixel che lo rappresentano (la "coordinata z") viene memorizzata nello z-buffer. Questo buffer è solitamente strutturato come una matrice bidimensionale, con un elemento per ogni pixel dello schermo. Se un altro oggetto deve essere visualizzato nello stesso punto, la scheda grafica confronta le profondità dei due oggetti sovrapposti; se il nuovo oggetto è più vicino all'osservatore, i valori corrispondenti per il pixel sostituiscono quelli precedenti, e la cella corrispondente dello z-buffer viene anch'essa aggiornata con la nuova profondità.

La granularità dello z-buffer influisce fortemente sulla qualità dell'immagine; uno z-buffer a 8 o 16 bit può creare sgradevoli artefatti (detti informalmente "lotta per lo z-buffer") nel caso di due oggetti molto vicini. Questi artefatti diminuiscono se si portano i bit dello z-buffer a 24 o but.

Inoltre, la precisione nella memorizzazione delle distanze in uno z-buffer non è costante rispetto al valore assoluto di tali distanze. In altre parole, lo z-buffer distingue molto meglio oggetti vicini che oggetti lontani. Sebbene questa sia una scelta voluta nella progettazione delle schede grafiche (essendo in generale preferibile), in alcuni contesti può portare alla comparsa di artefatti visibili nel rendering di oggetti molto lontani (come in certi programmi di simulazione di volo). Una variante dello z-buffering che mantiene una precisione più costante rispetto alla distanza viene chiamata w-buffering.


At the start of a new scene, the z-buffer must be cleared to a defined value, usually 1.0, because this value is the upper limit (on a scale of 0 to 1) of depth, meaning that no object is present at this point through the viewing frustum.

The invention of the z-buffer concept is most often attributed to Edwin Catmull, although Wolfgang Straßer also described this idea in his 1974 Ph.D. thesis1.

On recent PC graphics cards (1999-2005), z-buffer management uses a significant chunk of the available memory bandwidth. Various methods have been employed to reduce the impact of z-buffer, such as lossless compression (computer resources to compress/decompress are cheaper than bandwidth) and ultra fast hardware z-clear that makes obsolete the "one frame positive, one frame negative" trick (skipping inter-frame clear altogether using signed numbers to cleverly check depths).

Mathematics

The range of depth values in camera space (See 3D projection) to be rendered is often defined between a   and   value of  . After a perspective transformation, the new value of  , or  , is defined by:

 

Where   is the old value of   in camera space, and is sometimes called   or  .

The resulting values of   are normalized between the values of -1 and 1, where the   plane is at -1 and the   plane is at 1. Values outside of this range correspond to points which are not in the viewing frustum, and shoudn't be rendered.

To implement a z-buffer, the values of   are linearly interpolated across screen space between the vertices of the current polygon, and these intermediate values are generally stored in the z-buffer in fixed point format. The values of   are grouped much more densely near the   plane, and much more sparsely farther away, resulting in better precision closer to the camera. The closer the   plane is set to the camera, the less precision there is far away -- having the   plane set too closely is a common cause of undesirable rendering artifacts in more distant objects.

To implement a w-buffer, the old values of   in camera space, or  , are stored in the buffer, generally in floating point format. However, these values cannot be linearly interpolated across screen space from the vertices -- they usually have to be inverted, interpolated, and then inverted again. The resulting values of  , as opposed to  , are spaced evenly between   and  .

Whether a z-buffer or w-buffer results in a better image depends on the application.

When using the <canvas> tag with JavaScript, you can use the following as a Z-Buffer formula.

//F=far, N=near, Z=final return
f=0;
n=0;
z=0;
z=((f+n)/(f-n))+((1/z)*((-2*f*n)/(f-n)));
// Optimized: z=(f+n-2*f*n/z)/(f-n)

Voci correlate

Collegamenti esterni

Notes

Note 1: see W.K. Giloi, J.L. Encarnação, W. Straßer. "The Giloi’s School of Computer Graphics". Computer Graphics 35 4:12–16.