为什么光线追踪器将球渲染成椭圆形?

10

最近几天我一直在编写光线追踪器。然而,有一些怪癖让我困扰,我不知道该如何解决。其中一个问题从一开始就存在,那就是场景中球体的形状——渲染时它们实际上看起来像是椭圆形。当然,场景中存在透视,但最终的形状仍然看起来很奇怪。我附上了一个示例渲染图像,我所遇到的问题在图像左下角的反射球上尤为明显。

示例图像

我真的不知道是什么原因导致这种情况。可能是射线-球体相交代码引起的,其代码如下:

bool Sphere::intersect(Ray ray, glm::vec3& hitPoint) {
//Compute A, B and C coefficients
float a = glm::dot(ray.dir, ray.dir);
float b = 2.0 * glm::dot(ray.dir, ray.org-pos);
float c = glm::dot(ray.org-pos, ray.org-pos) - (rad * rad);

// Find discriminant
float disc = b * b - 4 * a * c;

// if discriminant is negative there are no real roots, so return
// false as ray misses sphere
if (disc < 0)
    return false;

// compute q
float distSqrt = sqrt(disc);
float q;
if (b < 0)
    q = (-b - distSqrt)/2.0;
else
    q = (-b + distSqrt)/2.0;

// compute t0 and t1
float t0 = q / a;
float t1 = c / q;

// make sure t0 is smaller than t1
if (t0 > t1) {
    // if t0 is bigger than t1 swap them around
    float temp = t0;
    t0 = t1;
    t1 = temp;
}

// if t1 is less than zero, the object is in the ray's negative direction
// and consequently the ray misses the sphere
if (t1 < 0)
    return false;

// if t0 is less than zero, the intersection point is at t1
if (t0 < 0) {
    hitPoint = ray.org + t1 * ray.dir;
    return true;
} else { // else the intersection point is at t0
    hitPoint = ray.org + t0 * ray.dir;
    return true;
    }
}

或者可能是另一件事。有人有想法吗?非常感谢!


此外,我还有一种感觉,我的折射率不正确(请看右侧的球体,折射率为1.8)。你们同意吗? - user1845810
当您只在屏幕中心渲染一个球时会发生什么? - OopsUser
1个回答

7

看起来你正在使用非常宽的视野(FoV)。这会产生鱼眼镜头的效果,扭曲图片,特别是向边缘方向。通常类似于90度(即每个方向45度)可以得到合理的图片。

折射实际上看起来相当不错;它被倒置是因为折射率很高。漂亮的图片在这个问题里。


太好了,这就是解决方案!自从项目开始以来,视野范围基本上是我从未更改过的唯一参数,我本可以自己想到的。非常感谢 :) - user1845810

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接