c++ - 光线追踪:为什么我的球体呈现为椭圆形?

标签 c++ raytracing

我要写一个光线追踪器,但我似乎已经遇到了我的第一个大问题。无论出于何种原因,我的球体(因为我只是开始 - 当光线照射时我只是将其着色为白色)被渲染为椭圆形。

此外,似乎失真越来越严重,我将球体中心移离 x = 0 和 y = 0

越远

这是交集和主循环代码:

double const Sphere::getIntersection(Ray const& ray) const
{
  double t;
  double A = 1;
  double B = 2*( ray.dir[0]*(ray.origin[0] - center_[0]) + ray.dir[1] * (ray.origin[1] - center_[1]) + ray.dir[2] * (ray.origin[2] - center_[2]));
  double C = pow(ray.origin[0]-center_[0], 2) + pow(ray.origin[1]-center_[1], 2) + pow(ray.origin[2] - center_[2], 2) - radius_pow2_;
  double discr = B*B - 4*C;

  if(discr > 0)
  {
    t = (-B - sqrt(discr))/2;
    if(t <= 0)
    {
      t = (-B + sqrt(discr))/2;
    }
  }
  else t = 0;

  return t;
}

Sphere blub = Sphere(math3d::point(300., 300., -500.), 200.);
Ray mu = Ray();
// for all pixels of window
for (std::size_t y = 0; y < window.height(); ++y) {
  for (std::size_t x = 0; x < window.width(); ++x) {
    Pixel p(x, y);
    mu = Ray(math3d::point(0., 0., 0.), math3d::vector(float(x), float(y), -300.));

    if (blub.getIntersection(mu) == 0. ) {
      p.color = Color(0.0, 0.0, 0.0);
    } else {
      p.color = Color(1., 1., 1.);
    }
  }
}

Sphere with center at 300,300,-500 Sphere with center at 0,0,-500

我也不明白为什么我的“椭圆”不在图片的中心。我有一个 600 x 600 像素的窗口,所以将球体的中心设置为 300 x 300 应该 afaik 也将球体放在窗口的中心。


我的具体解决方案

(感谢 Thomas 将我推向正确的方向!)

正如 Thomas 所说,我的问题是两个截然不同的问题。考虑到在中心投影球体,我按照他的建议做了,改变了光线的原点和投影。

为了获得正确的视角,我没有意识到我已经必须计算 focal length从维度。

focal_length = sqrt(width^2 + height^2)/( 2*tan( 45/2 ) )

结果:

Sphere with center at 200,300,-focal_length

最佳答案

这对于线性透视投影来说是正常的,并且会因摄像机角度过大而加剧;见http://en.wikipedia.org/wiki/Perspective_projection_distortion .大多数游戏在水平方向使用 90 度,两边 45 度。但是,通过在 x 方向上转换光线超过 600 个像素,但在 z 方向上转换光线超过 300 个像素,你的光线明显更宽,准确地说是 126 度。


你的球体没有居中的原因是你从屏幕的左下角转换光线:

mu = Ray(math3d::point(0.,0.,0.),math3d::vector(float(x),float(y),-300.));

应该是这样的:

mu = Ray(math3d::point(width/2,height/2,0.),math3d::vector(float(x-width/2),float(y-height/2),-300.));

关于c++ - 光线追踪:为什么我的球体呈现为椭圆形?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18174076/

相关文章:

objective-c - C 或 ObjC 用于 iOS 上的实时光线追踪器?

c# - 如何与 C# 统一进行实时光线追踪

render - 为什么我的蒙特卡洛光线追踪如此嘈杂?

c++ - 使用 UnhookWindowsHookEx() 解除 Hook 时,多个程序崩溃

c++ - 在 Bison 中有一种方法可以返回 token 的名称而不是其类型

c++ - 使用 C++ 从排序的 std::list<float> 构建最小高度 BST

multithreading - 如何在Rust中的线程之间共享不可变数据?

c++ - 为什么我的输入文件的最后一行运行了两次?

c++ - C++中链表的队列实现

cuda - 有效载荷中的 Optix 动态大小数组