Ich schreibe einen Ray Tracer. Bisher habe ich diffuse, Blinn-Beleuchtung und Reflexionen. Irgendetwas ist mit meinen Brechungen falsch gelaufen und ich habe keine Ahnung was. Ich hoffe, dass mir jemand helfen kann. Ray Tracing - Refraktion Bug
Ich habe eine große rote diffuse + Blinn Kugel und eine kleine refraktive mit einem Brechungsindex n = 1,5.
Der Kleine ist einfach nur vermasselt.
Relevante Code:
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;
}
Der Code ist ganz über den Platz, da dies eine Hausaufgabe und ich bin nicht zusätzliche Header enthalten darf, und ich habe es in einer CPP-Datei senden in, so Ich musste jede Klasse in Vorwärtsdeklaration, Deklaration und Implementierung in dieser einen Datei trennen. Es bringt mich zum Erbrechen, aber ich habe versucht, es so sauber wie möglich zu halten. Es gibt Tonnen von Code, also habe ich nur das aufgenommen, was ich für am meisten verwandt hielt. ReflectiveSurface ist die Elternklasse von RefractiveSurface. N ist die Flächennormale, V ist der Strahlrichtungsvektor diese Normale, n ist der Brechungsindex. Die Inzidenzstruktur enthält einen Punkt-, einen Normal- und einen Richtungsvektor.
Formeln für die Fersnel Annäherung und der Brechungsvektor jeweils:
Sie können im Code sehen, dass ich ein Epsilon * Strahlrichtung Wert verwenden Schatten Akne durch Schwimmer Unschärfen zu vermeiden. Ähnliches scheint jedoch der kleinen Sphäre zu passieren. Ein weiterer Screenshot:
Wie Sie sehen können, wird die Kugel nicht transparent erscheinen, aber es die diffusen Kugel der Farbe nicht erben. Es hat normalerweise auch einige weiße Pixel.
ohne Brechung:
Um welche Art von Zahlen handelt es sich? Es ist möglich, dass Ihre Werte zu klein werden, um durch "float" genau dargestellt zu werden und auf Null gehen. Können/haben Sie versucht, stattdessen 'double' zu verwenden? –
Scheint für die zwei Farbwerte in den ersten paar Iterationen im Bereich von 20-100 zu sein, wenn es am Ende der getColor-Funktion im Debug-Modus ankommt, und das dann durch die Entfernung^2 von der Kamera und geteilt wird gesättigt. – PEC
Wir denken es alle. TODESSTERN –