首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >针孔相机渲染系统的优化

针孔相机渲染系统的优化
EN

Stack Overflow用户
提问于 2009-12-07 19:24:37
回答 3查看 1K关注 0票数 2

我正在为学校制作一个软件栅格,我使用的是一种不寻常的渲染方法,而不是传统的矩阵计算。它是基于针孔照相机的。我在3D空间中有几个点,通过获取它与摄像机之间的距离并将其规范化,将它们转换为2D屏幕坐标。

代码语言:javascript
复制
Vec3 ray_to_camera = (a_Point - plane_pos).Normalize();

这给了我一个指向相机的方向矢量。然后,我把光线的原点放在摄像机上,然后将光线的方向转换成光线,并在摄像机后面做一个光线平面与平面的交点。

代码语言:javascript
复制
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]);
   }
}

这很好,但我想知道:算法能变得更快吗?现在,对于场景中的每一个三角形,我必须计算出三个法线。

代码语言:javascript
复制
float length = 1 / sqrtf(GetSquaredLength());
x *= length;
y *= length;
z *= length;

即使使用快速倒数平方根近似(1 / sqrt(x)),这也是非常苛刻的。

因此,我的问题是:

有什么方法可以近似这三个法线吗?

这种渲染技术叫什么?

这三个顶点能用质心的法线近似吗?((v0 + v1 + v2) / 3)

提前谢谢。

附注:“在这一领域的专家的帮助下,您将在接下来的七周内构建一个功能齐全的软件栅格。开始吧。”我热爱我的教育。:)

编辑:

代码语言:javascript
复制
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;

这将返回正确的结果,但是模型现在与摄像机的位置无关。:(

它是一个更短和更快的!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2009-12-08 12:52:09

很难确切地理解您的代码在做什么,因为它似乎正在执行许多冗余操作!然而,如果我理解你说的你想做的事,你就是:

  • 从针孔到点求矢量
  • 正规化
  • 沿着归一化向量向后投影到“图像平面”(针孔后面,自然!)
  • 从图像平面上的一个中心点求到这一点的向量
  • 用“轴”向量对结果进行点积,以求x和y屏幕坐标。

如果上面的描述代表了您的意图,那么规范化应该是多余的--您根本不必这么做!如果取消规范化会给您带来不好的结果,那么您可能正在做一些与您声明的计划略有不同的事情。换句话说,您可能和我一起混淆了自己,规范化步骤是“修复”它,使它在您的测试用例中看起来足够好,尽管它可能仍然没有达到您想要的效果。

总体的问题,我认为,是您的代码是大规模过度设计:您正在编写您的所有高级向量代数作为代码要在内循环中执行。优化的方法是在纸上计算出所有的向量代数,为你的内环找到最简单的表达式,并在摄像机设置时预先计算所有必要的常量。针孔相机规格将只作为相机设置程序的输入。

不幸的是,除非我猜错了,否则这会使你的针孔相机减少到传统的、无聊的旧矩阵计算。(光线追踪确实可以让你轻松地做一些很酷的非标准相机--但你所描述的应该是完美的标准.)

票数 3
EN

Stack Overflow用户

发布于 2009-12-07 19:45:19

这被称为射线追踪器--这是第一堂计算机图形学课程的典型作业*--你可以在经典的Foley/Van教科书(计算机图形学原理与实践)上找到很多有趣的实现细节。我强烈建议你买/借这本书,仔细阅读。

*等你开始反射和折射.现在乐趣开始了!

票数 4
EN

Stack Overflow用户

发布于 2009-12-08 00:44:53

嗯,在程序启动时,你可以计算每个三角形的法线。当你真正在跑步的时候,你只需要访问法线。这种节省成本的启动计算以后往往会在图形中发生。这就是为什么我们在很多电子游戏中都有大的加载屏幕的原因!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1862287

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档