【发布时间】:2009-12-07 19:24:37
【问题描述】:
我正在为学校制作软件光栅化器,并且我正在使用一种不寻常的渲染方法而不是传统的矩阵计算。它基于pinhole camera。我在 3D 空间中有几个点,我通过获取它与相机之间的距离并对其进行归一化将它们转换为 2D 屏幕坐标
Vec3 ray_to_camera = (a_Point - plane_pos).Normalize();
这给了我一个朝向相机的方向向量。然后,我通过将光线的原点放在相机上并与略在相机后面的平面执行光线平面相交,将这个方向转换为光线。
Vec3 plane_pos = m_Position + (m_Direction * m_ScreenDistance);
float dot = ray_to_camera.GetDotProduct(m_Direction);
if (dot < 0)
{
float time = (-m_ScreenDistance - plane_pos.GetDotProduct(m_Direction)) / dot;
// if time is smaller than 0 the ray is either parallel to the plane or misses it
if (time >= 0)
{
// retrieving the actual intersection point
a_Point -= (m_Direction * ((a_Point - plane_pos).GetDotProduct(m_Direction)));
// subtracting the plane origin from the intersection point
// puts the point at world origin (0, 0, 0)
Vec3 sub = a_Point - plane_pos;
// the axes are calculated by saying the directional vector of the camera
// is the new z axis
projected.x = sub.GetDotProduct(m_Axis[0]);
projected.y = sub.GetDotProduct(m_Axis[1]);
}
}
这很好用,但我想知道:算法可以更快吗?现在,对于场景中的每个三角形,我必须计算三个法线。
float length = 1 / sqrtf(GetSquaredLength());
x *= length;
y *= length;
z *= length;
即使使用快速倒数平方根近似 (1 / sqrt(x)) 也将非常苛刻。
我的问题是:
有没有近似三个法线的好方法?
这种渲染技术叫什么?
可以使用质心的法线来近似三个顶点吗? (((v0 + v1 + v2) / 3)
提前致谢。
附: “在接下来的七周内,您将在该领域专家的帮助下构建一个功能齐全的软件光栅化器。开始吧。”我喜欢我的教育。 :)
编辑:
Vec2 projected;
// the plane is behind the camera
Vec3 plane_pos = m_Position + (m_Direction * m_ScreenDistance);
float scale = m_ScreenDistance / (m_Position - plane_pos).GetSquaredLength();
// times -100 because of the squared length instead of the length
// (which would involve a squared root)
projected.x = a_Point.GetDotProduct(m_Axis[0]).x * scale * -100;
projected.y = a_Point.GetDotProduct(m_Axis[1]).y * scale * -100;
return projected;
这会返回正确的结果,但是模型现在独立于相机位置。 :(
虽然它更短更快!
【问题讨论】:
-
很高兴在这里见到 IGAD 的同学们 :-)
-
针孔相机模型通常使用齐次坐标的矩阵计算来实现。那你为什么不使用它呢?
标签: c++ optimization math rendering