6 Stimmen

Python Berechnung von Lichtstrahlen

Ich baue einen einfachen Python-Raytracer mit reinem Python (nur so zum Spaß), bin aber auf eine Blockade gestoßen.

Das Setup meiner Szene sieht derzeit so aus:

  1. Kamera befindet sich bei 0, -10, 0 und zeigt entlang der y-Achse.
  2. Kugel mit Radius 1 bei 0, 0, 0.
  3. Die Bildfläche ist 1 Entfernt von der Kamera und hat eine Breite und Höhe von 0,5.

Ich schieße Photonen in einer gleichmäßig zufälligen Verteilung durch die Bildfläche, und wenn ein Photon zufällig ein Objekt trifft, zeichne ich einen roten Punkt auf der Bilderleinwand, der dem Punkt auf der Bildfläche entspricht, durch den der Strahl verläuft.

Mein Schnittcode (Ich habe nur Kugeln):

def schnitt(self, strahl):
  cp = self.pos - strahl.origin
  v = cp.dot(strahl.richtung)
  diskriminante = self.radius**2  - cp.dot(cp) + v * v

  if diskriminante < 0:
    return False
  else:
    return strahl.position(v - sqrt(diskriminante)) # Position des Strahls zur Zeit t

Und mein Render-Code (es rendert eine bestimmte Anzahl von Photonen, nicht Pixel für Pixel):

def backen(self, strahlen):
  self.image = Image.new('RGB', [int(self.kamera.fokalebene.breite * 800), int(self.kamera.fokalebene.höhe * 800)])
  leinwand = ImageDraw.Draw(self.image)

  for i in xrange(strahlen):
    x = random.uniform(-kamera.fokalebene.breite / 2.0, kamera.fokalebene.breite / 2.0)
    z = random.uniform(-kamera.fokalebene.höhe / 2.0, kamera.fokalebene.höhe / 2.0)

    strahl = Strahl(kamera.pos, Vektor(x, 1, z))

    for name in szene.objekte.keys():
      ergebnis = szene.objekte[name].schnitt(strahl)

      if ergebnis:
        n = Vektor(0, 1, 0)
        d = ((strahl.origin - Punkt(self.kamera.pos.x, self.kamera.pos.y + self.kamera.fokalebene.versatz, self.kamera.pos.z)).dot(n)) / (strahl.richtung.dot(n))
        pos = strahl.position(d)

        x = pos.x
        y = pos.y

        leinwand.point([int(self.kamera.fokalebene.breite * 800) * (self.kamera.fokalebene.breite / 2 + x) / self.kamera.fokalebene.breite,
                      int(self.kamera.fokalebene.höhe * 800) * (self.kamera.fokalebene.höhe / 2 + z) / self.kamera.fokalebene.höhe],
                      fill = 128)

Es sollte richtig funktionieren, aber wenn ich ein Testbild rendern lasse, sehe ich nichts, was wie die Umrisse einer Kugel aussieht:

Bildbeschreibung eingeben

Ich hatte etwas wie das erwartet:

Bildbeschreibung eingeben

Weiß jemand, warum mein Code nicht richtig funktioniert? Ich habe diesen Teil schon viel zu lange optimiert und neu geschrieben...

8voto

Alnitak Punkte 324207

Normalisieren Sie den Richtungsvektor des Strahls?

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X