我正在尝试计算机图形学,并希望实现Z Buffer算法以在软件中进行渲染。
所以我试图使用以下平面方程:
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缓冲区已正确初始化。
我仅为您的问题代码略过而道歉,但是如果您要进行透视投影,请确保您对每个像素进行线性插值的“深度”为不是世界/相机深度但是某些东西与[[(什么?这里没有mathjax?)与1 / Z_world(或1 / W)成比例也就是说,您有一个投影三角形,其中每个顶点Vi都有{Vi_screenX,Vi_screenY,Vi_projectedDepth}和Vi_projectedDSepth = linear_function_of(1 / Vi_Z_camera)。
非常简单的例子包括:
Vi_projectedDepth = 1 / Vi_Z_camera或
Vi_projectedDepth = 1.0-1 / Vi_Z_camera您必须在整个三角形上线性内插Vi_projectedDepth值(但您不必取这些内插值的倒数,至少不需要Z缓冲区排序)。>>如果不这样做,则每当几何具有隐式相交时,您都会得到非常奇怪的结果。