1 Overview

In this part of the course, we will focus on rendering images using ray tracing. One of the most important operations in ray tracing is to find the intersection of light and object. Once the intersection of the light and the object is found, you can perform shading and return the pixel color. In this assignment, we need to realize two parts: the generation of light and the intersection of light and triangle. The workflow of this code framework is:

- Start with the main function. We define the parameters of the scene, add objects (spheres or triangles) to the scene, set their materials, and then add light sources to the scene.
- Call the Render(scene) function. In the cycle of traversing all pixels, the corresponding light is generated and the returned color is saved in the frame buffer. At the end of the rendering process, the information in the frame buffer is saved as an image.
- After generating the light corresponding to the pixel, we call the CastRay function, which calls trace to query the intersection of the light and the nearest object in the scene.
- Then, we perform shading at this intersection. We have set up three different shading situations and have provided you with the code.

The functions you need to modify are:

• Renderer. Render() in CPP: Here you need to generate a corresponding ray for each pixel, then call the function castRay() to get the color, and finally store the color in the corresponding pixel in the frame buffer.

• Triangle. Raytriangleintersect() in HPP: V0, V1 and V2 are the three vertices of the triangle, orig is the starting point of the light, and dir is the direction vector of the light unit. tnear, u, v are the parameters you need to update using the Moller trumbore algorithm derived in our class.

rayTriangleIntersect() is finished by typing once according to the class. Render() involves the conversion between camera position, world coordinate system and area pixels (I, J). Refer to the following:

reference resources: Ray-Tracing: Generating Camera Rays

code:

bool rayTriangleIntersect(const Vector3f& v0, const Vector3f& v1, const Vector3f& v2, const Vector3f& orig, const Vector3f& dir, float& tnear, float& u, float& v) { // TODO: Implement this function that tests whether the triangle // that's specified bt v0, v1 and v2 intersects with the ray (whose // origin is *orig* and direction is *dir*) // Also don't forget to update tnear, u and v. Vector3f e1 = v1 - v0; Vector3f e2 = v2 - v0; Vector3f s = orig - v0; Vector3f s1 = crossProduct(dir, e2); Vector3f s2 = crossProduct(s, e1); float s1e1 = dotProduct(s1, e1); tnear = dotProduct(s2, e2) / s1e1; u = dotProduct(s1, s) / s1e1; v = dotProduct(s2, dir) / s1e1; if (tnear > 0 && u >= 0 && u <= 1 && v >= 0 && v <= 1 && 1 - u - v >= 0 && 1 - u - v <= 1)return true; return false; }

// generate primary ray direction float x = (2 * ((i + 0.5) / scene.width) - 1) * scale * imageAspectRatio; float y = (1 - 2 * ((j + 0.5) / scene.height)) * scale; // TODO: Find the x and y positions of the current pixel to get the direction // vector that passes through it. // Also, don't forget to multiply both of them with the variable *scale*, and // x (horizontal) variable with the *imageAspectRatio* Vector3f dir = normalize(Vector3f(x, y, -1)); // Don't forget to normalize this direction! framebuffer[m++] = castRay(eye_pos, dir, scene, 0);

The last one is a ppm file. It's easy for me to find. You can open it with ps