Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/146.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 我的Z缓冲区计算有什么问题?_C++_Depth Buffer_Zbuffer - Fatal编程技术网

C++ 我的Z缓冲区计算有什么问题?

C++ 我的Z缓冲区计算有什么问题?,c++,depth-buffer,zbuffer,C++,Depth Buffer,Zbuffer,我正在实现一个Z缓冲区,以确定在一个充满三角形的简单场景中应该绘制哪些像素。我有一个三角形,一个顶点,一个向量(当然是数学上的(x,y,z))的结构表示,还有一个函数,可以将单个像素绘制到屏幕上。以下是我拥有的结构: struct vertex{ float x, y, z; ... //other members for lighting, etc. that will be used later and are not relevant here }; struct myVe

我正在实现一个Z缓冲区,以确定在一个充满三角形的简单场景中应该绘制哪些像素。我有一个三角形,一个顶点,一个向量(当然是数学上的(x,y,z))的结构表示,还有一个函数,可以将单个像素绘制到屏幕上。以下是我拥有的结构:

struct vertex{
  float x, y, z; 
  ... //other members for lighting, etc. that will be used later and are not relevant here 
}; 

struct myVector{
  float x, y, z; 
}; 

struct triangle{
  ... //other stuff 
  vertex v[3]; 
}; 
不幸的是,当我扫描转换我的三角形到屏幕上时,它依赖于计算深度来确定什么是可见的和要绘制的,我得到了不正确/不切实际的Z值(例如,三角形中某一点的深度超出其所有3个顶点的深度边界)!我一直在一遍又一遍地查看我的代码,不知道我的数学是错的还是我在某个地方犯了一个粗心的错误,所以我会尝试准确地展示我正在尝试做的事情,希望其他人能看到我没有看到的东西。(我仔细检查了确保浮点值仍然是浮点值,我正确地传递了参数,等等,所以这确实令人困惑!)

总的来说,我的扫描转换算法在扫描线上填充像素,如下所示(伪代码):

为了得到平面方程/my z计算的D值,我使用平面方程A(x-x1)+B(y-y1)+C(z-z1)=0,其中(x1,y1,z1)只是平面中的一个参考点。我刚刚选择三角形顶点v[0]作为参考点,并重新排列:

Ax+By+Cz=Ax1+By1+Cz1 因此,D=Ax1+By1+Cz1

最后,为了得到z计算的A、B、C和D,我对每个三角形都这样做,其中
trianglelist[nt]
是场景整体三角形数组中当前索引nt处的三角形:

float pA = planeNormal.x;
float pB = planeNormal.y;
float pC = planeNormal.z;
float pD = (pA*trianglelist[nt].v[0].x)+(pB*trianglelist[nt].v[0].y)+(pC*trianglelist[nt].v[0].z);
从这里开始,在我描述的扫描转换算法中,我计算了zs:

zInit = -1*((pA*cx)+(pB*scanLine)+(pD))/(pC);  //cx is current x value; scanLine is current y value
...
...
float zNext = zPrev - (pA/pC);

唉,经过这么仔细的工作,有些事情发生了!在某些三角形中,深度值是真实的(符号除外)。对于顶点(200,10,75),(75,200,75)和(15,60,75)给出的三角形,所有深度都为-75。对于所有顶点深度相同的其他三角形也是如此。但对于顶点(390300105),(17036080),(19024025),所有的z值都超过300!第一个是310.5,其余的只是变大了,最大值在365左右。当最深顶点位于z=105时,不应发生这种情况!!!那么,经过这么多的漫无边际的讨论,有人能看出这可能是什么原因吗?如果这是一个与符号相关的东西,我不会感到惊讶,但在哪里(毕竟,绝对值在恒定深度的情况下是正确的)

正确的方程式为:

n = cross (v[2] - v[0], v[1] - v[0]);
D = - dot (n, v[0]);

请注意减号。

您应该查看www.scratchapixel.com,尤其是本课:


它包含一个自包含的程序,向您展示如何投影顶点。

您应该将代码分解为小函数,每个函数都应该单独检查错误。因此,如果你编写一个函数来计算一个平面方程,那么就编写(单元)测试来检查原始三角形点是否在该平面上。然后你会发现问题所在。像这样的3d数学很难通过查看调试器中的值来检查。我一直在输出中间值、结果、参数等,到处都是,但还没有任何运气……哈利路亚!非常感谢。但是为什么我的D=Ax1+By1+Cz1的D计算不正确呢?我想我可以从平面方程中解出D。有趣的是,它在恒定深度的情况下起作用。对,但当你把它导出为A(x-x1)+B(y-y1)+C(z-z1)=0-->Ax+By+Cz=Ax1+By1+Cz1(其中x1,y1,z1只是你插入的一个点…我想既然Ax+By+Cz=D,我就应该有D=Ax1+By1+Cz1了。哦……啊哈。谢谢你的澄清。
zInit = -1*((pA*cx)+(pB*scanLine)+(pD))/(pC);  //cx is current x value; scanLine is current y value
...
...
float zNext = zPrev - (pA/pC);
n = cross (v[2] - v[0], v[1] - v[0]);
D = - dot (n, v[0]);