[英]Implementing Z Buffer Algorithm
我正在嘗試使用計算機圖形學,並希望實現 Z 緩沖區算法以在軟件中進行渲染。
所以我試圖使用以下平面方程:
z = -(ax + by + d)/c
要使用平面形式方程計算像素的 Z 坐標,我應該計算三角形的面法線嗎? 還是頂點的法線就足夠了?
這是我計算它的方法:
double zValueOfPoint(float vx, float vy, float vz, float x, float y, float nx, float ny, float nz)
{
float A = nx;
float B = ny;
float C = nz;
float D = -(nx*vx, +ny * vy + nz * vz);
float z = -(A*x + B * y + D) / C;
return z;
}
vx,vy,vz 頂點,x,y 像素坐標,nx,ny,nz 頂點法線
現在對於每個頂部或底部三角形,我檢查 Z 像素到 ZBuffer 像素
// Top of the triangle
for (int y = y0; y<y2; y++)
{
for (int x = xl_edge; x<xr_edge; x++)
{
float zOfPixel = zValueOfPoint(vx, vy, vz, x, y, nx, ny, nz);
if (zOfPixel < zbuffer[int(x + y * m_Width)]) {
zbuffer[int(x + y*m_Width)] = zOfPixel;
SetPixel((unsigned int)x, (unsigned int)y, color);
}
}//end for loop x
底部三角形相同
現在我得到了完全損壞的模型。 Z 緩沖區已正確初始化。
在實現 Z 緩沖時,您不需要對面法線做任何事情。 您只需要投影三角形的每個頂點“深度” 。
此外,我很抱歉只瀏覽了您的問題代碼,但是如果您想進行透視投影,那么請確保您對每個像素進行線性插值的“深度”不是世界/相機深度,而是成比例的東西(什么? SO 上沒有 mathjax?)到 1/Z_world 或 1/W。
也就是說,您有一個投影三角形,其中每個頂點Vi都有
{Vi_screenX, Vi_screenY, Vi_projectedDepth}和
Vi_projectedDepth = linear_function_of(1 / Vi_Z_camera) 。
非常簡單的例子包括:
Vi_projectedDepth = 1/Vi_Z_camera或
Vi_projectedDepth = 1.0 - 1/Vi_Z_camera
然后,您必須線性內插整個三角形Vi_projectedDepth值,但你不需要把這些插值的倒數(至少對於Z緩沖區排序。如果你想要做透視校正紋理,OTOH,你_may_需要最終計算倒數)。
如果你不這樣做,當幾何體有隱式交集時,你會得到非常奇怪的結果 - 我只記得我在SE Graphics 中對此發表了評論。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.