Python Raytracing - PullRequest
       12

Python Raytracing

5 голосов
/ 23 марта 2011

Я создаю простой Python raytracer с чистым Python (просто так), но я наткнулся на контрольно-пропускной пункт.

Настройка моей сцены в настоящее время такова:

  1. Камера, расположенная в 0, -10, 0, направленная вдоль оси y .
  2. Сфера с радиусом 1, расположенная в 0, 0, 0.
  3. Плоскость формирования изображениявсе находится на расстоянии 1 от камеры и имеет ширину и высоту 0.5.

Я снимаю фотоны равномерно случайным образом через плоскость формирования изображения, и еслислучается, что фотон пересекает объект, я рисую красную точку на холсте изображения, соответствующую точке на плоскости изображения, через которую прошел луч.

Мой код пересечения (у меня есть только сферы):

def intersection(self, ray):
  cp = self.pos - ray.origin
  v = cp.dot(ray.direction)
  discriminant = self.radius**2  - cp.dot(cp) + v * v

  if discriminant < 0:
    return False
  else:
    return ray.position(v - sqrt(discriminant)) # Position of ray at time t

И мой код рендеринга (он отображает определенное количество фотонов, а не попиксельно):

def bake(self, rays):
  self.image = Image.new('RGB', [int(self.camera.focalplane.width * 800), int(self.camera.focalplane.height * 800)])
  canvas = ImageDraw.Draw(self.image)

  for i in xrange(rays):
    x = random.uniform(-camera.focalplane.width / 2.0, camera.focalplane.width / 2.0)
    z = random.uniform(-camera.focalplane.height / 2.0, camera.focalplane.height / 2.0)

    ray = Ray(camera.pos, Vector(x, 1, z))

    for name in scene.objects.keys():
      result = scene.objects[name].intersection(ray)

      if result:
        n = Vector(0, 1, 0)
        d = ((ray.origin - Point(self.camera.pos.x, self.camera.pos.y + self.camera.focalplane.offset, self.camera.pos.z)).dot(n)) / (ray.direction.dot(n))
        pos = ray.position(d)

        x = pos.x
        y = pos.y

        canvas.point([int(self.camera.focalplane.width * 800) * (self.camera.focalplane.width / 2 + x) / self.camera.focalplane.width,
                      int(self.camera.focalplane.height * 800) * (self.camera.focalplane.height / 2 + z) / self.camera.focalplane.height],
                      fill = 128)

Он должен работать правильно, но когда я рендеринг тестового изображения, яне получите ничего похожего на контур сферы:

enter image description here

Я ожидал что-то вроде этого:

enter image description here

Кто-нибудь знает, почему мой код не работает должным образом?Я слишком долго дорабатывал и переписывал эту часть ...

1 Ответ

8 голосов
/ 23 марта 2011

Вы нормализуете вектор направления луча?

...