我正在写一个光线追踪器。到目前为止,我有漫反射,Blinn照明和反射。我的折射出了点问题,我不知道是什么。我希望有人可以帮助我。
我有一个大的红色漫反射+ 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近似和折射向量的公式:
你可以在代码中看到我使用epsilon * ray方向值来避免浮动不精确引起的阴影痤疮。但是,类似的东西似乎正在发生在小球体上。 另一个截图:
正如您所看到的,球体看起来并不透明,但它确实继承了漫反射球体的颜色。它通常也有一些白色像素。
没有折射:
答案 0 :(得分:1)
RefractiveSurface::refractionDir
采用正常N
by(非常量)引用,它可能会将其反转。这似乎很危险。目前还不清楚调用者是否希望将I.normal翻转,因为它会用于进一步降低颜色计算。
此外,refracted_color
并不总是初始化(除非Color构造函数使其变黑)。
尝试(暂时)简化并观察折射光线是否达到预期的位置。删除菲涅耳计算和反射分量,然后将refracted_color
设置为折射光线轨迹的结果。这将有助于确定错误是在菲涅耳计算中还是弯曲射线的几何形状。
调试提示:为不使用黑色以外的任何东西打击的像素着色。这样可以很容易地将未命中与阴影(表面痤疮)区分开来。
答案 1 :(得分:1)
答案结果非常简单,但是我花了3天的时间盯着代码来捕捉错误。我有一个Surface类,我从它派生出两个类:RoughSurface(diffuse + blinn)和RelfectiveSurface。然后,RefractiveSurace派生自RefleciveSurface。 ReflectiveSurface的构造函数将折射率(n)和消光值(k)作为参数,但不存储它们。 (F0)在施工期间从它们计算,然后它们丢失。另一方面,RefractiveSurface在折射角计算中使用(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)值。
从相机两侧照亮的大玻璃球后面的小红球:
它在运动中看起来很棒!D
谢谢你的时间,伙计们。要完成这个作业,然后我会重写整个事情并优化它的地狱。