F
Phong schrieb:
Entweder du verteilst die reflektierenden Strahlen gleich über alle Raumwinkel und skalierst nur deren Energie, oder aber du machst Strahlen gleicher Stärke, welche allerdings nach oben angegebener Formel verteilt sind.
Ich habe inzwischen beide Methoden einmal implementiert, dabei bin ich nach dem Schema mit der Energie vorgegangen. Ich habe die Strahlen zufällig verteilt nach einer perfekten diffusen Reflexion und dann das Skalarprodukt berechnet und kurz in die entsprechende Formel eingesetzt. Zwar war das einfach zu implementieren, hatte jedoch den Nachteil, dass es nur sehr langsam konvergiert.
Dann wollte ich die andere Methode umsetzen. Jedoch braucht man, soviel ich weiss, für eine Zufallsverteilung das Integral der Funktion. Jedoch habe ich weder für abs(exp(-tan(x)^2))^ γ noch für cos(x)^ γ die Stammfunktion herausgefunden. Gäbe es ohne diese auch eine Möglichkeit, Zahlen demnach zu verteilen?
Für das Phong-Modell habe ich eine Alternative zusammengebastelt, die zwar wesentlich schneller konvergiert als die Energie-Methode, aber immer noch nur halb so schnell wie eine Lambertsche Oberfläche (für die ich gemütlich ohne Umwege mit einer Linearkombination generieren kann).
So sieht die "Notlösung" für die Phong-Verteilung aus:
Vector3 Specular = Incidence - (2 * Normal.dot(Incidence)) * Normal;
static std::uniform_real_distribution<RealT> DotDistribution(0, 1);
static std::uniform_real_distribution<RealT> CircleDistribution(0, TwoPi);
RealT RandomDot = Root(DotDistribution(Generator), Gamma);
AngleT CircleAngle(ArcCos(RandomDot));
Vector3 Axis = Normal.cross(Specular).normalized();
Vector3 OnCircle = MakeRotation(CircleAngle, Axis) * Specular; // MakeRotation gibt eine 3x3 Matrix zurück => teuer!
do
{
Result.Direction = MakeRotation(AngleT(CircleDistribution(Generator)), Specular) * OnCircle;
}
while(InteriorAngle(Normal, Result.Direction) > AngleT::RightAngle());
Result.Origin = IntersectionPoint + Result.Direction * RealTEps;
Und das Resultat für ein Gamma von 250:
http://i.cubeupload.com/9rclzv.png
Meine Frage:
Ich habe ein orthogonales Koordinatensystem, den Einfallswinkel, den idealen Ausfallswinkel und γ gegeben, wie kann ich Strahlen (die diese Verteilung befolgen, natürlich) generieren ohne Rotationsmatrizen zu verwenden?
Danke euch beiden schonmal und Gruss