在软件光栅化器中实现z缓冲区

时间:2009-12-17 23:48:54

标签: c++ math rendering

作为家庭作业,我们正在编写一个软件光栅化器。我注意到我的z缓冲不能正常工作,所以我试图通过输出到屏幕来调试它。 (黑色很近,白色很远)。

但是,我得到每个顶点z的奇特值。这就是我用来转换点数的方法:

float Camera::GetZToPoint(Vec3 a_Point)
{
    Vec3 camera_new = (m_MatRotation * a_Point) - m_Position;

    return (HALFSCREEN / tanf(_RadToDeg(60.f * 0.5f)) / camera_new.z);
}

m_MatRotation是一个3x3矩阵。将它乘以矢量会返回一个变换后的矢量。

我得到0到x之间的最大值和最小值,其中x是一个看似随机的数字。

我正在进行这种转变吗?如果是这样,我怎样才能将我的Z值标准化,使其位于两个设定点之间?

提前致谢。

2 个答案:

答案 0 :(得分:4)

要标准化Z值,您必须定义近剪裁平面和远剪裁平面。然后对Z进行归一化,使其在近平面处为0,在远处平面处为1。

但是,投影后通常会这样做。看起来你的最后一行是投影发生的地方。

其他一些事情:

  • 你计算完整的矩阵向量乘法,但只保留Z,这是浪费。你应该考虑转换点并保持它们的所有X,Y,Z坐标;
  • 你在每个顶点重新计算tanf(),但是它的常量;
  • 我建议你使用投影矩阵而不是tanf计算;
  • 从简单的正交投影开始,它将更容易调试。

答案 1 :(得分:1)

假设你想知道一个椎骨的z,那将是a_Point:

首先,您希望在旋转之前执行平移,以便围绕相机执行旋转,而不是空间的原点,可能在其他位置。其次,camera_new没有很好地选择名称,因为它代表了摄像机位置新参考集中a_Point的坐标。相反,请执行以下操作:

Vec3 point_new = (m_MatRotation * (a_Point-m_Position));

如果这不起作用,你必须通过创建一个真实的投影矩阵来完成它,该矩阵在一次乘法中执行平移,旋转和投影。这里有一些教程帮助我理解了如何做到这一点。

http://www.songho.ca/opengl/gl_projectionmatrix.html

codeguru.com/cpp/misc/misc/math/article.php/c10123 /

一旦你设法以透视正确的方式在屏幕上投影顶点,你将不得不找到一种方法来填充它们之间的空间,并找到每个填充的像素,z是什么。这是一个全新的故事,关于纹理映射的维基百科文章帮助我做到了。

en.wikipedia.org/wiki/Texture_mapping#Perspective_correctness

抱歉,我无法给你更多链接,Stackoverflow不会让我因为我是新用户......