Subject ZBuffer
Email poisone@usa.net
Irc irc.ada.net.tr #scene.tr #manowar #atheist
ICQ 6795916
Last Update 24/01/01
Note off.. 3d.. 3d... zor olay..

zbuffer..

3 boyutlu çizimlerdeki en büyük problem, üst üste gelen poligonların çizimi.. diyelimki basit bi obje'yi ekrana çiziyorsunuz.. poligon'ları öyle bir çizmeniz lazımki z eksenine göre arkada kalan poligonların gözükmemesi lazım, şöyle düşünün, bir kalemin arkasındaki kağıt diyelim.. ekrana çizerken eğer kağıdı kalemden sonra çizecek olursanız, kalem gözükmeyecektir (halbuki kalem üstte!..) umarım anlatabildim.

bu tür problemlerin giderilmesi için bir kaç yöntem var bunlardan en basiti zbuffer, zbuffer'a biraz eklentiler yaparak sbuffer (segment anlamında s), biraz daha kasacak olursanız vertex'leri z eksenlerine göre sıraya dizerek bsp (quake'in kullandığı) yapmış olursunuz. :)..

mantık..

yapılacak iş çok basit, öncelikle ekran ile aynı piksel(!) boyutunda bir buffer kullanmanız gerekiyor. bu buffer'ın tipi genelde float(bu ancak 3d hızlandırıcısı olan kartlarda geçerli) veya fixed sayı kullanılır. biz herbişeyi kendimiz yapacağımıza göre fixed kullanmamız gerekli. "fixed neki ?" diyosanız Fixed Math yazısını okuyun.

action..

ekrana çizim yapılırken, ilk yapılması gereken zbuffer'ın her ekran çizimi öncesinde sıfırlanması.. sıfırlama derken 0'a eşitleme değil, sizin z eksenindeki en küçük sayınız ne ise ona eşitleyin, mesela 7fffffffh gibi bi sayıya.. dediğim gibi bu sizin tamamen zbuffer'ı nasıl kullandığınıza bağlı. daha sonra poligon'u çizerken yapmanız gereken, piksel'i basmadan önce aynı x,y koordinatı ile zbuffer'daki değer ile basacağınız piksel'in z değerini karşılaştırmak, basacağınız piksel'in z değeri daha yüksek ise piksel daha öndedir. (veya hiç piksel basmamışsınızdır).. biraz karıştı ise şöyle bi örnek vereyim..

for(;address!=lastaddress;address++)
	 {
	 if (zbuffer[address] < sz)
		 {
		 vidpage[address] = SolidColor;
		 zbuffer[address] = sz;
		 }
	 sz += zinc;
	 }

yukarıdaki kod poligon'un yatay olarak piksellerini basan rutin, address değeri = y * SCREEN_WIDTH + x. aynı değeri zbuffer içinde kullanıp, eğer zbuffer daha küçük ise pikseli basıp zbuffer'ı update ediorum. olay bu kadar..

biraz hayal edebilmeniz için aşağıya nasıl bir şekil olacağını çizdim..

zbuffer tarafını en düşük değer olarak siyah kabul edin, z değeri arttıkça gri ton olarak beyazlaştığını yani en yüksek değerin beyaz olduğunu varsayın. (bunu zbuffer'ı ekrana çizmiş gibi de düşünebilirsiniz.)

zbuffer tahmin edeceğiniz gibi çok yavaş çalışan bişey.. hızlandırmak için bi kaç teknik var, en çok bilineni sbuffer dediğim gibi. segment buffer'da kontrolü piksel olarak değil bölgelere ayırarak yapıyorsunuz. bu konuyu anladıysanız (yada ben anlatabildiysem) biraz üzerinde düşünerek kendiniz bunun mantığını çıkarabilirsiniz..