I have written a really basic ray tracer. It generates primary rays and sets the colour of the pixel to the colour of the object that I have set myself. The code for which can be seen below.

from PIL import Image, ImageDraw
from Sphere import Sphere
import numpy as np

imgx = 300
imgy = 300

img = Image.new('RGB', (imgx, imgy), color = 'black')
pixelMap = img.load()

#Place a Sphere in centre, distance 10 away.
#Sphere has a constructor (centre, colour, radius)
sphere1 = Sphere(np.array([0,0,-1]), (255, 255, 255), 100)
#sphere2 = Sphere(np.array([300,0,-1]), (255, 0, 0), 100)

objects = [sphere1]

for i in range(img.size[0]):
    for j in range(img.size[1]):

        u = -imgx/2 + (imgx)*(i+0.5)/imgx
        v = -imgy/2 + (imgy)*(j+0.5)/imgy

        rayDirection = -1*np.array([0,0,1]) + u*np.array([1,0,0]) + v*np.array([0,1,0])
        rayOrigin = np.array([0,0,0])
        #p(t) = rayorigin + t*raydirect

        #Sphere intersection
        for obj in objects:     
            a = np.dot(rayDirection, rayDirection)
            b = np.dot(2*rayDirection, (rayOrigin - obj.centre))
            c = np.dot((rayOrigin - obj.centre), (rayOrigin - obj.centre)) - obj.radius**2

            eminc = rayOrigin - obj.centre

            discrim = (np.dot(rayDirection, eminc))**2 - ((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc))-obj.radius**2)
            if(discrim >= 0):
                pixelMap[i,j] = obj.colour
                pixelMap[i,j] = (0, 0,0)


enter image description here

It works in the sense that when I run the code, I get an image of a white circle. My issue arises when I change the centre of the sphere. Instead of shifting to the left, right, up or down. I get a skewed image. Seen below when I set the Sphere to have centre np.array([3,0,-1]).

enter image description here

I believe the problem may be to do with the translation between world co-ordinates and camera co-ordinates? However, I am not sure what transformation matrix to use or how to use it. For what it's worth, my code takes ideas from Fundamentals of Computer Graphics by Pete Shirley and Steve Marschner.

  • $\begingroup$ discrim = (np.dot(rayDirection, eminc))**2 - ((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc))-obj.radius**2), use discrim = b * b-4*a*c $\endgroup$ – lightxbulb Jul 15 '19 at 13:34
  • $\begingroup$ @lightxbulb discrim is equivalent to b^2-4ac with the values for a,b and c substituted in. $\endgroup$ – Tim Jul 15 '19 at 16:26
  • $\begingroup$ It is not. It would be if you actually wrote (np.dot(rayDirection, eminc))**2 - 4*((np.dot(rayDirection, rayDirection))*(np.dot(eminc, eminc)-obj.radius**2)). So just put in b * b - 4 * a * c, and check whether it works. $\endgroup$ – lightxbulb Jul 15 '19 at 18:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.