Dealine: 04.11.2021
Please put your name here:
Name: .......
In this assignment we will continue working with compound objects: solids.
- Fork the current repository.
- Modify the README.md file in your fork and put your name above.
- Have a look at the new classes
CSolidQuad
andCSolidCone
. Study how a quadrilateral and a cone may be constructed from triangles. - Implement the
CSolidSphere
class in the same way asCSolidCone
class is implemented. Please provide your code with comments.
Hint 1: Make use of spherical coordinates.
Hint 2: Sphere will consist of two "caps": top and bottom, consisting out of triangles, and the "sides", consisting out of quadrilaterals. Additional insights may be found in rt::CSolidCylinder
constructor. You might need to use height segments for the sphere as well. Please use the number of height segments equal to the half of the number of sphere's sides.
If your implementation works as expected you should see an image of 3 geometrical objects:
Rather then storing a single geometry normal for a triangle, it is often useful to store at each vertex a corresponding vertex normal. The advantage is that if we have a hit point on a triangle, the shading normal can be smoothly interpolated between the vertex normals. If neighboring triangles share the same vertex normals, a smooth appearance can be generated over non-smooth tesselated geometry.
Proceed as follows:
- Your ray class is extended with two additional
float
values calledRay::u
andRay::v
. - In
bool CPrimTriangle::intersect(Ray& ray) const
, store the computed barycentric coordinates intoRay::u
andRay::v
.Note: as long as your other classes (e.g.
CPrimSphere
) don’t need local surface coordinates, there is no need to compute them yet. - Class
CPrimTriangle
now stores the vertex normals (m_na
,m_nb
andm_nc
) additionaly to the original vertex positions.Note: that all the vertex normals are optionals. Please pay extra attantion to how they initialized in the constructor.
- In
Vec3f CPrimTriangle::getNormal(const Ray& ray) const
check whether the vertex normals are initialized and if yes, use the u/v coordinates of the hitpoint to interpolate between the vertex normals and return interpolated normal.Note: interpolating normalized vectors will not return a normalized vector! Make sure to normalize your interpolated normal!
- Extend the code in
CSolidCone
constructor in such a way that the triangles will be created with the additional normals. Calculate these normals and pass them within the triangles' constructors. What normal will be chosen for the top vertex? Please explain in comments.Note: if you stuck here, you may refere to OpenRT library:
rt::CSolidCone
- Extend your code in
CSolidSphere
constructor in such a way that the triangles will be created with the additional normals. Calculate these normals (e.g. using the spherical coordinate system) and pass them within the triangles' and quads' constructors. - Test your implementation on the scene from Problem 1. Compare the difference between the Solid and Primitive spheres. Explain below why smoothed cone looks strange. How would you fix it?
Explanation and Suggestion: ...
If everything is correct your images should look like this:
Until now we have only used one color per object. Nevertheless, in reality, e.g. in games, objects are very often colorful because of the usage of textures. This is also a way of making a surface look more geometrically complex. Usually, textures are used by storing texture coordinates at the vertices of each triangles, and interpolating those to find the correct texel that has to be used for a surface point.
- Study new class
CTexture
added to the framework. - Classes
CShaderFlat
andCShaderEyelight
now have additional constructors, which take a texture instead of a color as a parameter. - Class
IPrim
now has additional virtual methodvirtual Vec2f getTextureCoords(const Ray& ray) const = 0;
which should be implemented in all derived classes. - Implement method
Vec2f CPrimSphere::getTextureCoords(const Ray& ray) const
using spherical coordinates and lecture notes. The method should return the x and y coordinates of the interpolated vertex texture coordinates.Note: if you stuck here, you may refere to OpenRT library:
rt::CPrimSphere
, however it may contain a bug. Double check with lecture notes and comment the code! - Implement method
Vec3f CShaderFlat::shade(const Ray& ray) const
to use the texture coordinates returned bygetTextureCoords()
if texture exists. - Test your implementation with the texture of the earth by replacing color with texture
pTexture
in main.cpp for eyelight shader.
If everything is correct your images should look like this:
Now we continue with texturing the Solids, which consist out of triangles.
- Class
CPrimTriangle
now contains additional variablesm_ta
,m_tb
andm_tc
, which correspond to the texture coordinates at verticesa
,b
, andc
, respectively. Here we useVec2f
’s to store the texture coordinates (notVec3f
), because they require only 2 coordinates (barycentric coordinates). - Implement method
Vec2f CPrimTriangle::getTextureCoords(const Ray& ray) const
. The method should return the x and y coordinates of the interpolated vertex texture coordinates. - Extend your code in
CSolidSphere
constructor in such a way that the triangles will be created with the additional texture coordinates. Calculate these coordiantes (e.g. using the spherical coordinate system) and pass them within the triangles' and quads' constructors. - Extend the code in
CSolidCone
constructor in such a way that the triangles will be created with the additional texture coordinates. Calculate these coordinates (e.g. using the cylindrical coordinate system) and pass them within the triangles' constructors. Which texture coordinate will you assign to the top of cylinder? - Test your implementation. Make sure that the spheres look the same.
If everything is correct your images should look like this:
Now it is time to apply a texture to a more complex solid - a toy character Barney. In the data folder you will find files barney.obj and barney.bmp. Using the expieriense gained so far, add to the scene Barney and apply his texture. For this you are free to add corresponding code to main.cpp file: comment out the existing geometry, add a second camera to the scene. Render the image.
Test your implementation on barney.obj with barney.bmp. If everything is correct your image should look like this:
Please submit the assignment by making a pull request. Important : Please make sure that
- No extra files are submitted (except those, which were mentioned in the assignment)
- The changes were made only in those files where you were asked to write your code
- The Continiouse Integration system (appVeyor) can build the submitted code
- The rendered images are also submitted in the folder "renders"