2014-11-04 92 views
6

我在写射线追踪器。到目前为止,我有漫反射,布林照明和反射。我的折射出现问题,我不知道是什么。我希望有人能帮助我。 enter image description here射线追踪 - 折射错误

我有一个很大的红色diffuse + Blinn球体和一个折射率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; 
} 

的代码是所有的地方,因为这是一门功课,我不会允许包括额外的头,我必须在发送一个CPP文件,所以我不得不将每一个课程分成前向申报,申报和实施。它让我呕吐,但我尽量保持清洁。有很多代码,所以我只包括我认为最相关的东西。 ReflectiveSurface是RefractiveSurface的父类。 N是表面法线,V是该法线的光线方向矢量,n是折射率。发生结构包含一个点,一个法线和一个方向向量。

公式为Fersnel近似和分别折射向量: enter image description here

可以在我使用的ε*射线方向上的值,以避免由浮子不精确阴影粉刺代码中看到。不过,类似的事情似乎也发生在小球体上。 另一张截图: ​​

enter image description here

正如你所看到的,球没有出现透明的,但它确实继承漫球体的颜色。它通常也有一些白色像素。

无折射:

enter image description here

+0

涉及什么样的数字?有可能你的数值变得太小,无法用“float”来准确表示,并且将变为零。你可以/你尝试过使用'double'吗? – 2014-11-04 16:56:37

+0

在开始的几次迭代中,当它在getColor函数的末尾以调试模式到达时,似乎处于20-100范围内,然后将与摄像机的距离^ 2相除,饱和。 – PEC 2014-11-04 17:05:52

+0

我们都在想。死星 – 2014-11-05 17:58:02

回答

1

答案结果非常简单,但我花了3天的时间盯着代码来捕捉错误。我有一个Surface类,我从它派生了两个类:RoughSurface(diffuse + blinn)和RelfectiveSurface。然后,RefractiveSurace来自RefleciveSurface。 ReflectiveSurface的构造函数以折射率(n)和消光值(k)为参数,但不存储它们。(F0)在施工期间由它们计算,然后它们丢失。另一方面,折射表面在折射角计算中使用(n)。

旧的构造函数:

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

新的构造:

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

正如你所看到的,我忘了保存在构造函数RefractiveSurface的(n)的值。从背后摄像头的两边点燃大玻璃球

红色的小球:

enter image description here

它看起来运动d

谢谢您的时间,你们真棒!要完成这个作业,然后我会重写整个事情并优化它。

1

RefractiveSurface::refractionDir取正常N通过(非const)参考,并且它可以倒转。这看起来很危险。目前尚不清楚调用者是否需要翻转正常值,因为它用于进一步降低颜色计算。

此外,refracted_color并不总是初始化(除非Color构造函数使其变为黑色)。

尝试(暂时)简化,看看折射光线是否达到您的预期。除去菲涅耳计算和反射分量,只需设置refracted_color即可得到折射光线的结果。这将有助于确定错误是在菲涅耳计算中还是在弯曲射线的几何中。

一个调试提示:使用除黑色以外的其他东西不使用任何东西的像素着色。这可以很容易地区分阴影(表面痤疮)的缺失。