Lab 5留学生辅导、讲解C/C++、辅导SimplePolygon、讲解C/C++程序
- 首页 >> 其他 Project One
Description: Your ray tracing work will conclude with this project. The project will require you to implement shadow feelers to create shadows, trace reflection vectors to create mirror-like inter-object reflections, and add additional types of shapes to a scene. Your starting point for this lab is your completed lab four.
Your grade on this project will depend not only on successful implementation of additional aspects of ray tracing, but also on quality of the scene that is rendered by your project.
Your project must include the capability to enable and disable individual light sources using the ‘a,’ ‘d,’ ‘p,’ and ‘s’ keys as described in Lab 5.
Simple Polygon Surfaces
Simple polygons are described by three or more vertices in same plane, are convex, and have no sides which cross one another. The front face of the polygon is normally defined as the face on which the vertices appear in counter clockwise order. The surface normal for the polygon should point out of the front face.
Implement a subclass of the Plane class that represents a simple polygon. Name the class something like SimplePolygon or ConvexPolygon. DO NOT NAME THE CLASS POLYGON, THIS WILL CAUSE A NAME COLLISION WITH SOMETHING IN ONE OF THE LIBRARIES WE ARE USING. The constructor among other things should have an input parameter that is a vector of dvec3 objects which specify the vertex locations for the polygon in counter-clockwise order.
The sub-class should use the findClosestIntersetion method of Plane class to determine if the plane in which the polygon lies is intersected by the ray. It can then use the method described in the notes to determine if the intersection is inside the polygon described by the vertices passed to the constructor. You should be able to account for intersections with both the front and back side of the polygon. Both sides of the polygon should be rendered with correct lighting. Thus, you must make sure that the surface normal placed in the hit record is pointing in the correct direction.
Quadric Surfaces
Download the QuadricSurface declaration and definition and add the class to your project.
Implement two specialized sub-classes of the QuadricSurface class. One should be the Ellipsoid. The other should be a limited version of an infinite shape. For instance, if you create a Cylinder or Hyperboloid class, the rendered object should have a specified radius or radii and a limited length. Cones, Elliptical Paraboloids, and Hyperboloids should go in only on direction and have a limited height.
Your specialization should enable the rendering of a quadric surface such as a cylinder, cone, ellipsoid, paraboloid, hyperbolic paraboloid, etc. Shapes such as the cone or cylinder should not be infinite. It must be possible to render them in any position within the scene.
In your sub-class findClosestIntersetion method, use the findClosestIntersetion of the QuadricSurface class to do the heavy lifting of intersection testing. In the sub-class findClosestIntersetion method, check the point of intersection to see if it is in the more limited shape you are creating. If it is not in the limited shape, cast a second ray going from the “non-intersection point to see if that ray hit the other side of the limited shape. If it does return this point of intersection for rendering. Otherwise, return a hit record that indicate that the ray did not intersect the object.
Both sides of the surface should be rendered with correct lighting. The normal for an intersection should always point away from the direction of the ray being traced.
Function to Look for Ray Intersections
Ray tracing is all about finding intersections between rays and surfaces in a scene. You have already written code that carries out this task. You will need the functionality that carries out this task to create shadows and reflections.
Write either a function or a method findIntersection. Add the declaration to Ray.h. Create a new file called Ray.cpp . dPlace the declaration of the function or method in the new file. Depending on where you create a function or a method, the prototype should look like one of the following:
HitRecord findIntersection( const Ray & ray, const SurfaceVector & surfaces )
HitRecord Ray::findIntersection( const SurfaceVector & surfaces )
The code in the function/method should similar to what you previously implemented in the traceIndividualRay of RayTracer. Modify your RayTracer class so that it calls this function when individual rays are traced. Make sure everything still works.
Shadows
Implement shadows by checking shadow feelers for intersections with the surfaces in the scene. Cast a shadow feeler whenever a traced ray intersects an object. For directional light sources, an intersection with a surface anywhere along a shadow feeler that points in the direction of the light vector for the source should result in there being no contribution from that light source. For positional light sources, an intersection with a surface in between the origin of the shadow feeler and the position of the light source should result in there being no contribution from that light source.
With the ray tracing infrastructure we have been developing in the labs, the illuminate methods of the LightSource structs and sub-structs already accept a third parameter containing all the surfaces in the scene that was unused until this point. Shadow feelers can be appropriately generated and tested for intersections within the illuminate method by calling the findIntersection function/method you implemented.
virtual color illuminate( const dvec3 & eyeVector,
HitRecord & closestHit,
const SurfaceVector & surfaces)…
Inter-Object Reflections
Add mirror-like inter object reflections by tracing a reflection ray to the closest surface intersection for each view ray. Once generated, the reflection ray can be traced in exactly the same way as the viewing rays. The best way to accomplish this is by calling the traceIndividualRay method recursively and adding what it returns to the total color for the pixel. To do this, it is necessary to keep the recursion from being infinite. This can be accomplished by using the recursionLevel parameter that is passed to the traceIndividualRay method. This parameter can be decremented prior to each recursive call. The recursion would stop when the value is less than or equal to zero.
color RayTracer::traceIndividualRay( const Ray & viewRay,
int recursionLevel)
Taking it Further
Implement at least two of the following extensions for your ray tracing program. You are of course encouraged to implement more if you like.
Do at least one of the following:
Reflect the “Sky”
Reflection rays often do not intersect any surfaces in the scene. The illumination for these non-intersecting rays can simply be “no color” or if can be a scaled down default color. The later will cause shiny objects to appear to reflect the default color as though it is the sky. Modify your program to create this effect.
Day and Night
Modify the program so that pressing the ‘m’ and ‘n’ causes the scene to be rendered in day and night modes respectively. You can simply “dim” the lights or change the lighting entirely to create the two different effects.
Multiple Views
Modify the program so that pressing the ‘f,’ ‘g,’ and ‘h’ keys causes the scene to be rendered from three significantly different opposite viewpoints.
Perspective Versus Orthographic Projection
Modify the program so that pressing the ‘o’ key causes the scene to be toggled back and forth between perspective and orthographic renderings of the scene.
Do at least one of the following:
Attenuation
Use constant, linear, and quadratic attenuation constants to attenuate the contributions of positional light sources based on their distance from the point of intersection.
Use attenuation to reduce the contribution of reflection vectors based on the distance to the intersection between the reflection ray and the object it hits.
To test this, you may want to position either a light source at a distance and render the scene with and without attenuation.
Antialiasing
Modify the program so that pressing the ‘z’ key toggles on and off antialiasing.
Because of the discrete nature of raster image representation, rendered images will include aliasing artifacts. These artifacts create a jagged or stair stepped in objects that should appear smooth. In ray tracing applications, anti-aliasing can be performed by simply tracing multiple rays per pixel. The simplest approach is to subdivide each pixel into the grid, cast one rays per grid square, and then set the rendered pixel intensity to the average of color associated with the rays.
If you implement this functionality, don’t go crazy with the number of rays. Remember, we have no hardware acceleration. Nine rays per-pixel as depicted above should do have an impact. Also realize that there are much more complex stochastic methods for generating the rays.
Texture Mapping
Basic texture mapping uses a function to determine the diffuse color at the point of intersection with a surface. I will provide a lab on texture mapping that will be used in future sections of this course. If you are interested in adding texture mapping to your project, use the lab as a guide. Incorporating texture mapping would count as two extensions.
Create a Scene
Create a scene composed of the spheres, planes, polygons, and the quadric surfaces you created. Create a full-screen capture of the best result you achieve when rendering your scene.
Turn it in
Submission instructions for this project are similar to the lab instructions with the exception of the screen capture.
1.When submitting your project include the screen capture of the scene that is created by your project.
2.Copy the folder containing your solution to the desktop.
3.Change the name of the folder to CSE287ProjectOne followed by your unique identifier. For instance “CSE287ProjectOneBachmaer.”
4.Open the solution. Make sure it still runs.
5.Clean the solution by clicking on clean.bat. (The will delete all the intermediate temporary files that are part of your project and reduce the size of your submission.)
6.Zip up the solution folder using the standard windows compression tool. (No 7zips, rars, etc.)
Submit your zip archive of the solution through canvas.
Description: Your ray tracing work will conclude with this project. The project will require you to implement shadow feelers to create shadows, trace reflection vectors to create mirror-like inter-object reflections, and add additional types of shapes to a scene. Your starting point for this lab is your completed lab four.
Your grade on this project will depend not only on successful implementation of additional aspects of ray tracing, but also on quality of the scene that is rendered by your project.
Your project must include the capability to enable and disable individual light sources using the ‘a,’ ‘d,’ ‘p,’ and ‘s’ keys as described in Lab 5.
Simple Polygon Surfaces
Simple polygons are described by three or more vertices in same plane, are convex, and have no sides which cross one another. The front face of the polygon is normally defined as the face on which the vertices appear in counter clockwise order. The surface normal for the polygon should point out of the front face.
Implement a subclass of the Plane class that represents a simple polygon. Name the class something like SimplePolygon or ConvexPolygon. DO NOT NAME THE CLASS POLYGON, THIS WILL CAUSE A NAME COLLISION WITH SOMETHING IN ONE OF THE LIBRARIES WE ARE USING. The constructor among other things should have an input parameter that is a vector of dvec3 objects which specify the vertex locations for the polygon in counter-clockwise order.
The sub-class should use the findClosestIntersetion method of Plane class to determine if the plane in which the polygon lies is intersected by the ray. It can then use the method described in the notes to determine if the intersection is inside the polygon described by the vertices passed to the constructor. You should be able to account for intersections with both the front and back side of the polygon. Both sides of the polygon should be rendered with correct lighting. Thus, you must make sure that the surface normal placed in the hit record is pointing in the correct direction.
Quadric Surfaces
Download the QuadricSurface declaration and definition and add the class to your project.
Implement two specialized sub-classes of the QuadricSurface class. One should be the Ellipsoid. The other should be a limited version of an infinite shape. For instance, if you create a Cylinder or Hyperboloid class, the rendered object should have a specified radius or radii and a limited length. Cones, Elliptical Paraboloids, and Hyperboloids should go in only on direction and have a limited height.
Your specialization should enable the rendering of a quadric surface such as a cylinder, cone, ellipsoid, paraboloid, hyperbolic paraboloid, etc. Shapes such as the cone or cylinder should not be infinite. It must be possible to render them in any position within the scene.
In your sub-class findClosestIntersetion method, use the findClosestIntersetion of the QuadricSurface class to do the heavy lifting of intersection testing. In the sub-class findClosestIntersetion method, check the point of intersection to see if it is in the more limited shape you are creating. If it is not in the limited shape, cast a second ray going from the “non-intersection point to see if that ray hit the other side of the limited shape. If it does return this point of intersection for rendering. Otherwise, return a hit record that indicate that the ray did not intersect the object.
Both sides of the surface should be rendered with correct lighting. The normal for an intersection should always point away from the direction of the ray being traced.
Function to Look for Ray Intersections
Ray tracing is all about finding intersections between rays and surfaces in a scene. You have already written code that carries out this task. You will need the functionality that carries out this task to create shadows and reflections.
Write either a function or a method findIntersection. Add the declaration to Ray.h. Create a new file called Ray.cpp . dPlace the declaration of the function or method in the new file. Depending on where you create a function or a method, the prototype should look like one of the following:
HitRecord findIntersection( const Ray & ray, const SurfaceVector & surfaces )
HitRecord Ray::findIntersection( const SurfaceVector & surfaces )
The code in the function/method should similar to what you previously implemented in the traceIndividualRay of RayTracer. Modify your RayTracer class so that it calls this function when individual rays are traced. Make sure everything still works.
Shadows
Implement shadows by checking shadow feelers for intersections with the surfaces in the scene. Cast a shadow feeler whenever a traced ray intersects an object. For directional light sources, an intersection with a surface anywhere along a shadow feeler that points in the direction of the light vector for the source should result in there being no contribution from that light source. For positional light sources, an intersection with a surface in between the origin of the shadow feeler and the position of the light source should result in there being no contribution from that light source.
With the ray tracing infrastructure we have been developing in the labs, the illuminate methods of the LightSource structs and sub-structs already accept a third parameter containing all the surfaces in the scene that was unused until this point. Shadow feelers can be appropriately generated and tested for intersections within the illuminate method by calling the findIntersection function/method you implemented.
virtual color illuminate( const dvec3 & eyeVector,
HitRecord & closestHit,
const SurfaceVector & surfaces)…
Inter-Object Reflections
Add mirror-like inter object reflections by tracing a reflection ray to the closest surface intersection for each view ray. Once generated, the reflection ray can be traced in exactly the same way as the viewing rays. The best way to accomplish this is by calling the traceIndividualRay method recursively and adding what it returns to the total color for the pixel. To do this, it is necessary to keep the recursion from being infinite. This can be accomplished by using the recursionLevel parameter that is passed to the traceIndividualRay method. This parameter can be decremented prior to each recursive call. The recursion would stop when the value is less than or equal to zero.
color RayTracer::traceIndividualRay( const Ray & viewRay,
int recursionLevel)
Taking it Further
Implement at least two of the following extensions for your ray tracing program. You are of course encouraged to implement more if you like.
Do at least one of the following:
Reflect the “Sky”
Reflection rays often do not intersect any surfaces in the scene. The illumination for these non-intersecting rays can simply be “no color” or if can be a scaled down default color. The later will cause shiny objects to appear to reflect the default color as though it is the sky. Modify your program to create this effect.
Day and Night
Modify the program so that pressing the ‘m’ and ‘n’ causes the scene to be rendered in day and night modes respectively. You can simply “dim” the lights or change the lighting entirely to create the two different effects.
Multiple Views
Modify the program so that pressing the ‘f,’ ‘g,’ and ‘h’ keys causes the scene to be rendered from three significantly different opposite viewpoints.
Perspective Versus Orthographic Projection
Modify the program so that pressing the ‘o’ key causes the scene to be toggled back and forth between perspective and orthographic renderings of the scene.
Do at least one of the following:
Attenuation
Use constant, linear, and quadratic attenuation constants to attenuate the contributions of positional light sources based on their distance from the point of intersection.
Use attenuation to reduce the contribution of reflection vectors based on the distance to the intersection between the reflection ray and the object it hits.
To test this, you may want to position either a light source at a distance and render the scene with and without attenuation.
Antialiasing
Modify the program so that pressing the ‘z’ key toggles on and off antialiasing.
Because of the discrete nature of raster image representation, rendered images will include aliasing artifacts. These artifacts create a jagged or stair stepped in objects that should appear smooth. In ray tracing applications, anti-aliasing can be performed by simply tracing multiple rays per pixel. The simplest approach is to subdivide each pixel into the grid, cast one rays per grid square, and then set the rendered pixel intensity to the average of color associated with the rays.
If you implement this functionality, don’t go crazy with the number of rays. Remember, we have no hardware acceleration. Nine rays per-pixel as depicted above should do have an impact. Also realize that there are much more complex stochastic methods for generating the rays.
Texture Mapping
Basic texture mapping uses a function to determine the diffuse color at the point of intersection with a surface. I will provide a lab on texture mapping that will be used in future sections of this course. If you are interested in adding texture mapping to your project, use the lab as a guide. Incorporating texture mapping would count as two extensions.
Create a Scene
Create a scene composed of the spheres, planes, polygons, and the quadric surfaces you created. Create a full-screen capture of the best result you achieve when rendering your scene.
Turn it in
Submission instructions for this project are similar to the lab instructions with the exception of the screen capture.
1.When submitting your project include the screen capture of the scene that is created by your project.
2.Copy the folder containing your solution to the desktop.
3.Change the name of the folder to CSE287ProjectOne followed by your unique identifier. For instance “CSE287ProjectOneBachmaer.”
4.Open the solution. Make sure it still runs.
5.Clean the solution by clicking on clean.bat. (The will delete all the intermediate temporary files that are part of your project and reduce the size of your submission.)
6.Zip up the solution folder using the standard windows compression tool. (No 7zips, rars, etc.)
Submit your zip archive of the solution through canvas.