Assignment Task
Overview
In this homework, you will extend the implementation of your previous ray tracer.
Starter Code
- Camera.js defines the camera. It contains only one camera class: PinholeCamera as that’s the most common type in computer graphics.
- light.js defines a couple of light source classes, such as PointLight and SpotLight. It also contains a utility function createAreaLight() which can approximate a large area light as a set of individual point lights
- Material.js defines the Material class and utility functions for creating various materials.
- Shape.js defines various geometric shapes such as plane, sphere, triangle, and a utility function shapeLoadOBJ() that loads an obj model and inserts all its triangles to the shapes array.
- Raytracer.js contains the main ray tracing code and is where most of your implementation resides. It also defines the Ray class, and utility functions such as reflect() and refract() .
- The scenes/ subfolder contains a number of provided ray tracing scenes, each in a separate .html file. Each scene file must define the necessary ray tracing parameters (such as image width, image height, etc.), a camera object, lights, shapes, and call the render() function to start ray tracing. Camera, lights, and shapes are created similarly to how a three.js scene is created, but here using our own classes. Some of the scenes require obj models, which are in the models/ subfolder. Similar to before, these are OBJ models converted to Javascript strings.
Code Specifics
- ImageWidth image height: defines image resolution. Reducing these numbers can significantly speed up the computation time, allowing you to see approximate results quickly. Increase them to generate final images at higher resolution and quality.
- Exposure: a scaling factor applied on every pixel to globally brighten or darken the image.
- Background color: defines background color for rays that do not intersect anything in the scene.
- AmbientLight: defines the intensity of ambient light.
- Camera: the camera object. All examples use a pinhole camera defined by eye position, target point, up vector, fov, and aspect ratio.
- Shapes: an array that contains one or more geometric shapes. Each shape must also have an associated material.
- lights: an array that contains one or more light sources.
The Ray Class
The Ray class is defined at the beginning of raytracer.js – it contains a constructor that creates instance variables ( this.o for origin and this.d for direction) by cloning parameters passed to it. Both parameters are of type THREE.Vector3 . In Javascript, all instance variables of a class are accessed by the this pointer, whether in the constructor or other functions of the class. By default, all instance variables are public, so can be accessed directly by any outside class. The Ray class also contains a pointer () function, which computes a point on the ray given ray parameter.
Getting Started
1. Start with the raytracing() function – call the rayIntersectScene() function: if no intersection is found, return backgroundColor , otherwise, compute and return ambient color. Then run _hw5_ambient_test.html scene. The result should match the reference image on the last page.
2. Next, assuming your previous shape implementation was working, you can copy and paste the contents of your shape.js file from HW5 into this homework’s shape.js file.
3. After that, run _hw5_blue_sphere.html and see if the sphere shows up (even though the shading is not correct yet). Then complete the shading() function by implementing the shading equation and shadow calculation, which now includes both diffuse and specular components. For the most part, your diffuse calculation (assuming it worked before) should be able to just be pasted into this version of the shading() funtion. Then _hw5_blue_sphere.html should look correct compared to the reference (and HW5).
4. A useful tip for debugging: you can modify the shading() function to return the position or normal of the shading point as shading color – this allows you to visually check the shading parameters and see if there is anything wrong with the position or normal of the shading points.
5. Another tip: some scenes may run very slowly. You can reduce the image resolution (like from 640 × 480 to 160 × 120) to quickly get an approximate image which will help you debug the code.
6. Now complete the raytracing() function by adding code to handle mirror and glass materials using recursive raytracing. You can tell if a material is mirror or glass by checking whether the material’s kr / kt parameters are null. You can test out the mirror material on ball_mirror.html and the glass material using ball_glass.html.
7. Complete the SpotLight class; you can test this out using ball_spotlight.html.
8. If those work, you can also test your code on the additionally-provided scenes (plus the HW5 scenes):
- Ball_softshadow.html and ball_arealight.html use an area light – note that the AreaLight class is provided for you.
- Ball_array.html uses multiple spheres with glossy (specular) material.
- Glossy_teapot.html is similar to _hw5_purple_teapot.html but with a different viewing angle, two-point lights, and a glossy material.
- Mirrors_opposing.html has multiple mirrors (planes with mirror material) to see interactions of multiple reflections.
9. For your convenience, saved images of the expected outputs are provided in the starter code in the reference_images/ folder. If you open one of those images in your browser and then open a generated image from your code in a different tab, you can alternate between the tabs to look for any differences between your results and the expected results.
10. If part of the code from your HW5 submission is relevant to this homework but did not work (e.g., shape intersection or diffuse reflection) please let me know as soon as possible. If needed, I can provide a solution version of specific parts of HW5 to make sure that you can focus on this homework material.