我正在写一个光线追踪器。到目前为止,我有漫反射,布林照明和反射。我的折射出现了问题,我也不知道该怎么办。我希望有人能帮助我。

我有一个大的红色漫反射+布林球,还有一个折射率n = 1.5的小折射球。

小家伙真的搞砸了。

相关代码:

ReflectiveSurface::ReflectiveSurface(const Color& _n, const Color& _k) :
F0(Color(((_n - 1)*(_n - 1) + _k * _k) / ((_n + 1)*(_n + 1) + _k * _k))) {}

Color ReflectiveSurface::F(const Point& N, const Point& V) const {
    float cosa = fabs(N * V);
    return F0 + (F0 * (-1) + 1) * pow(1 - cosa, 5);
}

Color ReflectiveSurface::getColor(const Incidence& incidence, const Scene& scene, int traceDepth) const {
    Point reflectedDir = reflect(incidence.normal, incidence.direction);
    Ray ray = Ray(incidence.point + reflectedDir * epsilon, reflectedDir);
    return F(incidence.normal, incidence.direction) * scene.rayTrace(ray, traceDepth + 1);
}

Point ReflectiveSurface::reflect(const Point& N, const Point& V) const {
    return V - N * (2 * (N * V));
}

bool RefractiveSurface::refractionDir(Point& T, Point& N, const Point& V) const {
    float cosa = -(N * V), cn = n;
    if (cosa < 0) { cosa = -cosa; N = N * (-1); cn = 1 / n; }
    float disc = 1 - (1 - cosa * cosa) / cn / cn;
    if (disc < 0) return false;
    T = V / cn + N * (cosa / cn - sqrt(disc));
    return true;
}

RefractiveSurface::RefractiveSurface(float _n, const Color& _k) : ReflectiveSurface(Color(1, 1, 1) * _n, _k) {}

Surface* RefractiveSurface::copy() { return new RefractiveSurface(*this); }

Color RefractiveSurface::getColor(const Incidence& incidence, const Scene& scene, int traceDepth) const {
    Incidence I = Incidence(incidence);
    Color reflectedColor, refractedColor;
    Point direction = reflect(I.normal, I.direction);
    Ray reflectedRay = Ray(I.point + direction * epsilon, direction);
    if (refractionDir(direction, I.normal, I.direction)) {
        Ray refractedRay = Ray(I.point + direction * epsilon, direction);
        Color colorF = F(I.normal, I.direction);
        reflectedColor = colorF * scene.rayTrace(reflectedRay, traceDepth + 1);
        refractedColor = (Color(1, 1, 1) - colorF) * scene.rayTrace(refractedRay, traceDepth + 1);
    }
    else {
        reflectedColor = scene.rayTrace(reflectedRay, traceDepth + 1);
    }
    return reflectedColor + refractedColor;
}

代码无处不在,因为这是一项家庭作业,不允许我包含其他 header ,并且我必须将其发送到一个cpp文件中,因此我不得不将每个类分为以下几个部分:正向声明,声明和实现那一个文件。它使我呕吐,但我试图保持其尽可能干净。有大量的代码,所以我只包括了我认为最相关的内容。 ReflectiveSurface是RefractiveSurface的父类。 N是表面法线,V是此法线的射线方向 vector ,n是折射率。入射结构包含一个点,一个法线和一个方向 vector 。

菲涅耳近似和折射 vector 的公式分别为:

您可以在代码中看到,我使用epsilon *射线方向值来避免由 float 不精确引起的阴影痤疮。不过,小领域似乎正在发生类似的情况。
另一个屏幕截图:


如您所见,该球体看起来不是透明的,但它确实继承了扩散球体的颜色。它通常也有一些白色像素。

无折射:

最佳答案

RefractiveSurface::refractionDir通过(非const)引用获取普通的N,并且可以将其反转。这似乎很危险。尚不清楚调用者是否希望翻转I.normal,因为它被用于颜色计算的下层。

另外,refracted_color并不总是初始化的(除非Color构造函数将其设为黑色)。

尝试(暂时)简化,然后看看折射的光线是否击中了您期望的位置。删除菲涅耳计算和反射组件,只需将refracted_color设置为折射光线的跟踪结果即可。这将有助于确定该错误是在菲涅耳计算中还是在弯曲射线的几何形状中。

调试提示:用黑色以外的颜色给不会碰到任何东西的像素上色。这样可以很容易地将阴影和阴影(表面痤疮)区别开来。

关于c++ - 光线追踪-折射错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/26740643/

10-09 05:58