**Implementation Details, Advice, and Examples for Assignment 4** Perspective Projection =============================================================================== `Renderer.projectVertices = function(verts, viewMat)` Project the input traingle vertices using viewMat, which is composed of the perspective projection matrix and the inverse of camera pose. The perspective projection and inverse camera matrices have been computed for you and then multiplied together beforehand in the render function for efficiency. Thus, viewMat serves to map world space coordiantes to normalized device coordinates (NDC). Return the screen space coordinates of each projected vertex, as well as its z in normalized device coordinates (NDC) for later use of z buffering. Note that we need to skip the input traingle (return undefined) if any of its camera space z is not between the near plane and the far plane of the camera, because it shouldn’t be seen. We have provided implementation of orthogonal projection in `projectVerticesNaive`, and you may refer to it as a starting point. Also check this slides (OpenGL projection matrix-Perspective projection part) for how the perspective projection transformation maps a view volume (pyramidal frustrum) to a canonical view volume (cube with range [-1, 1] in each of x, y, z dimensions) in whcih normalized device coordinates is defined. Hint: In renderer.js, there is a global object called "Renderer" which stores properties of the renderer we are using and has functions that define the entire rendering pipeline. You will need to utilize its properties in your implementation of perspective projection and also other assignment features. The following images are generated using the attached urls, where you can click through to examine your results. The back face of the cube looks smaller than the front face due to perspective projection. ![ Generated using this url](./example-images/perspective0.png border="1" width="480") ![ Generated using this url](./example-images/perspective1.png border="1" width="480") Phong Reflection Model ======================================================================== `Reflection.phongReflectionModel = function(vertex, view, normal, lightPos, phongMaterial)` You should apply this equation: $I = I_E + K_A I_{AL} + K_D (N \cdot L) I_L + K_S(V \cdot R)^n I_L$ We ignore the emission term ($I_E = [0, 0, 0]$) and assume the light color is white ($I_{AL} = I_L = [1, 1, 1]$). This is similar to what you have implemented in A3. In the code, we have already computed diffuse color, and you need to add in ambient color and specular color. The following images are generated using the Phong shader. ![](./example-images/phong_reflection0.png border="1") ![](./example-images/phong_reflection1.png border="1") ![](./example-images/phong_reflection2.png border="1") Helpers ======================================================================== You will not be able to directly observe the effects of the helper functions on GUI, but they will be helpful when you implement shaders. Bounding Box ------------------------------------------------------------------------ `Renderer.computeBoundingBox = function(projectedVerts)` This computes the screen-space bounding box for the triangle defined in projectedVerts. The bounding box should always be within the screen coordinates since any locations outside the screen won't be rendered. This function is useful when we do rasterization for each projected triangle, where we need to loop over pixels that cover the projected traingle. One simple way to do it is to compute the bounding box around the projected triangle, and just loop over pixels inside it. There are more effficient algorithms of rasterizing triangles which are up to your choice for optimization. Barycentric coordinates ------------------------------------------------------------------------ `Renderer.computeBarycentric = function(projectedVerts, x, y)` Compute the barycentric coordinates for a point (x, y) inside the triangle defined in projectedVerts. Return undefined if (x,y) is outside the triangle. See this article and pages 30-33 of this slides for an efficient 2D algorithm (the only difference from A3 is that the points are all 2D and that efficiency is even more important). Shaders with Phong Reflection Model ======================================================================== The pipeline of rendering a triangle is similar for all the three shaders to be implemented: Loop over pixels in the tiangle