Introduction to Rendering

Introduction to rendering using RayTracer.jl

In this example we will render the famous UTAH Teapot model. We will go through the entire rendering API. We will load an obj file for the scene. This needs to be downloaded manually.

Run this code in your terminal to get the file: wget https://raw.githubusercontent.com/McNopper/OpenGL/master/Binaries/teapot.obj

If you are using REPL mode you need the ImageView.jl package

using RayTracer, Images #, ImageView

General Attributes of the Scene

Specify the dimensions of the image we want to generate. screen_size is never passed into the RayTracer directly so it need not be a named tuple.

screen_size = (w = 256, h = 256)

Load the teapot object from an obj file. We can also specify the scene using primitive objects directly but that becomes a bit involved when there are complicated objects in the scene.

scene = load_obj("teapot.obj")

We shall define a convenience function for rendering and saving the images. For understanding the parameters passed to the individual functions look into the documentations of get_primary_rays, raytrace and get_image

function generate_render_and_save(cam, light, filename)
    #src # Get the primary rays for the camera
    origin, direction = get_primary_rays(cam)

    #src # Render the scene
    color = raytrace(origin, direction, scene, light, origin, 2)

    #src # This will reshape `color` into the proper dimensions and return
    #src # an RGB image
    img = get_image(color, screen_size...)

    #src # Display the image
    #src # For REPL mode change this to `imshow(img)`
    display(img)

    #src # Save the generated image
    save(filename, img)
end

Understanding the Light and Camera API

DistantLight

In this example we will be using the DistantLight. This king of lighting is useful when we want to render a scene in which all parts of the scene receive the same intensity of light.

For the DistantLight we need to provide three attributes:

Camera

We use a perspective view Camera Model in RayTracer. Let us look into the arguments we need to pass into the Camera constructor.

Rendering Different Views of the Teapot

Now that we know what each argument means let us render the teapot

TOP VIEW Render

light = DistantLight(
    Vec3(1.0f0),
    100.0f0,
    Vec3(0.0f0, 1.0f0, 0.0f0)
)

cam = Camera(
    Vec3(1.0f0, 10.0f0, -1.0f0),
    Vec3(0.0f0),
    Vec3(0.0f0, 1.0f0, 0.0f0),
    45.0f0,
    1.0f0,
    screen_size...
)

generate_render_and_save(cam, light, "teapot_top.jpg")

SIDE VIEW Render

light = DistantLight(
    Vec3(1.0f0),
    100.0f0,
    Vec3(1.0f0, 1.0f0, -1.0f0)
)

cam = Camera(
    Vec3(1.0f0, 2.0f0, -10.0f0),
    Vec3(0.0f0, 1.0f0, 0.0f0),
    Vec3(0.0f0, 1.0f0, 0.0f0),
    45.0f0,
    1.0f0,
    screen_size...
)

generate_render_and_save(cam, light, "teapot_side.jpg")

FRONT VIEW Render

light = DistantLight(
    Vec3(1.0f0),
    100.0f0,
    Vec3(1.0f0, 1.0f0, 0.0f0)
)

cam = Camera(
    Vec3(10.0f0, 2.0f0, 0.0f0),
    Vec3(0.0f0, 1.0f0, 0.0f0),
    Vec3(0.0f0, 1.0f0, 0.0f0),
    45.0f0,
    1.0f0,
    screen_size...
)

generate_render_and_save(cam, light, "teapot_front.jpg")

Next Steps

This page was generated using Literate.jl.