Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homework 2 #1

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@ doc/html
./vscode

.DS_Store

# CLion IDE
.idea
cmake-build-debug
13 changes: 12 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,18 @@
**Dealine**: 15.10.2020

Please put your name here:
**Name**: .......
**Name**: Otmane Sabir.

## Changes

* I made a small change to the main file so that it would output the images to my render directory differently and
so that it is also outputs the image before displaying the window.

* I had to change the `.gitignore` file as well to avoid committing some garbage files from CLion.

* I additionally changed the `main.cpp` file in order to automate the testing a little more. This might have resulted in more
boiler plate code but automated the change of the shader by changing a single variable.

## Problem 1
### Encapsulate camera and primitives from main application logic (Points 5)
1. Fork the current repository
Expand Down
Binary file added render/a_cool_bug.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added render/eyelight.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added render/flat.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added render/mirror.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added render/phong.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion src/IShader.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class IShader
/**
* @brief Calculates the color of the hit by the ray \ray object
* @param ray The ray
* @return The color of the hit objesct
* @return The color of the hit object
*/
virtual Vec3f shade(const Ray& ray) const = 0;
};
Expand Down
7 changes: 4 additions & 3 deletions src/LightOmni.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,12 @@ class CLightOmni : public ILight

virtual std::optional<Vec3f> illuminate(Ray& ray) override
{
// --- PUT YOUR CODE HERE ---
return std::nullopt;
Vec3f pointRay = m_org - ray.org;
ray.t = norm(pointRay);
ray.dir = normalize(pointRay);
return m_intensity / pow(ray.t, 2);
}


private:
Vec3f m_intensity; ///< The emission (red, green, blue)
Vec3f m_org; ///< The light source origin
Expand Down
5 changes: 3 additions & 2 deletions src/PrimPlane.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,14 @@ class CPrimPlane : public IPrim
if (dist < Epsilon || isinf(dist) || dist > ray.t) return false;

ray.t = dist;
ray.hit = shared_from_this();
return true;
}

virtual Vec3f getNormal(const Ray& ray) const override
{
// --- PUT YOUR CODE HERE ---
return Vec3f();
/*Here we already know this planes normal.*/
return m_normal;
}

private:
Expand Down
8 changes: 6 additions & 2 deletions src/PrimSphere.h
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,17 @@ class CPrimSphere : public IPrim
}

ray.t = dist;
ray.hit = shared_from_this();
return true;
}

virtual Vec3f getNormal(const Ray& ray) const override
{
// --- PUT YOUR CODE HERE ---
return Vec3f();
/* To find the normal of a point on a sphere
* we simply need to find the vector that's orthogonal
* to the tangent (vector with dir similar to vec from
* center to intersection pt). */
return normalize((ray.dir*ray.t + ray.org) - m_origin);
}

private:
Expand Down
11 changes: 8 additions & 3 deletions src/PrimTriangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,19 @@ class CPrimTriangle : public IPrim
if (ray.t <= f || f < Epsilon ) return false;

ray.t = f;
ray.hit = shared_from_this();
return true;
}

virtual Vec3f getNormal(const Ray& ray) const override
{
// --- PUT YOUR CODE HERE ---
return Vec3f();
/* Here I'll be using logic found here:
* https://www.khronos.org/opengl/wiki/Calculating_a_Surface_Normal#:~:text=A%20surface%20normal%20for%20a,of%20the%20face%20w.r.t.%20winding).
* */
auto result = Vec3f(m_edge1.val[1]*m_edge2.val[2] - m_edge1.val[2]*m_edge2.val[1],
m_edge1.val[2]*m_edge2.val[0] - m_edge1.val[0]*m_edge2.val[2],
m_edge1.val[0]*m_edge2.val[1] - m_edge1.val[1]*m_edge2.val[0]);
return normalize(result);
}

private:
Expand Down
23 changes: 14 additions & 9 deletions src/Scene.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,23 +29,24 @@ class CScene
*/
void add(const ptr_prim_t pPrim)
{
// --- PUT YOUR CODE HERE ---
m_vpPrims.push_back(pPrim);
}
/**
* @brief Adds a new light to the scene
* @param pLight Pointer to the light
*/
void add(const ptr_light_t pLight)
{
// --- PUT YOUR CODE HERE ---
m_vpLights.push_back(pLight);
}
/**
* @brief Adds a new camera to the scene and makes it to ba active
* @param pCamera Pointer to the camera
*/
void add(const ptr_camera_t pCamera)
{
// --- PUT YOUR CODE HERE ---
m_vpCameras.push_back(pCamera);
m_activeCamera = m_vpCameras.size() - 1;
}
/**
* @brief Returns the container with all scene light source objects
Expand All @@ -67,16 +68,21 @@ class CScene
*/
bool intersect(Ray& ray) const
{
// --- PUT YOUR CODE HERE ---
return false;
bool doesIntersect = false;
for (const auto& prim : m_vpPrims)
doesIntersect |= prim->intersect(ray);
return doesIntersect;
}

/**
* find occluder
*/
bool occluded(Ray& ray)
{
// --- PUT YOUR CODE HERE ---
// pretty much the exact same logic as intersect?
for (const auto& prim : m_vpPrims)
if(prim->occluded(ray))
return true;
return false;
}

Expand All @@ -85,9 +91,8 @@ class CScene
return the color of the shaded ray
*/
Vec3f RayTrace(Ray& ray) const
{
// --- PUT YOUR CODE HERE ---
return Vec3f();
{
return intersect(ray) ? ray.hit->getShader()->shade(ray) : m_bgColor;
}


Expand Down
3 changes: 1 addition & 2 deletions src/ShaderEyelight.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,7 @@ class CShaderEyelight : public CShaderFlat

virtual Vec3f shade(const Ray& ray) const override
{
// --- PUT YOUR CODE HERE ---
return RGB(0, 0, 0);
return abs(ray.dir.dot(ray.hit->getNormal(ray))) * CShaderFlat::shade(ray);
}
};

3 changes: 1 addition & 2 deletions src/ShaderFlat.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,7 @@ class CShaderFlat : public IShader

virtual Vec3f shade(const Ray& ray = Ray()) const override
{
// --- PUT YOUR CODE HERE ---
return RGB(0, 0, 0);
return m_color;
}

private:
Expand Down
12 changes: 10 additions & 2 deletions src/ShaderMirror.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,16 @@ class CShaderMirror : public IShader

virtual Vec3f shade(const Ray& ray) const override
{
// --- PUT YOUR CODE HERE ---
return Vec3f(0,0,0);
Vec3f normal = ray.hit->getNormal(ray);
if (ray.dir.dot(normal) > 0)
normal *= -1;
Vec3f reflected_dir = ray.dir - 2*(ray.dir.dot(normal))*normal;

Ray reflected;
reflected.dir = normalize(reflected_dir);
reflected.t = std::numeric_limits<double>::infinity();
reflected.org = ray.t * ray.dir + ray.org;
return m_scene.RayTrace(reflected);
}


Expand Down
46 changes: 43 additions & 3 deletions src/ShaderPhong.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class CShaderPhong : public CShaderFlat
* @param color The color of the object
* @param ka The ambient coefficient
* @param kd The diffuse reflection coefficients
* @param ks The specular refelection coefficients
* @param ks The specular reflection coefficients
* @param ke The shininess exponent
*/
CShaderPhong(CScene& scene, Vec3f color, float ka, float kd, float ks, float ke)
Expand All @@ -24,10 +24,50 @@ class CShaderPhong : public CShaderFlat
{}
virtual ~CShaderPhong(void) = default;

/*
* Lr = ka*ca*La + kd*cd Σl=0n-1 Ll(Il·N)+ ks*cs Σl=0n-1 Ll(Il·R)ke
* */
virtual Vec3f shade(const Ray& ray) const override
{
// --- PUT YOUR CODE HERE ---
return RGB(0, 0, 0);
Vec3f normal = ray.hit->getNormal(ray);
if (ray.dir.dot(normal) > 0)
normal *= -1;
// r = d−2(d⋅n)n
Vec3f reflected = normalize(ray.dir - 2*(ray.dir.dot(normal))*normal);
Vec3f color = CShaderFlat::shade(ray);
Vec3f ambient = m_ka * color;
auto ambientIntensity = RGB(1, 1, 1);
// mul is what we need for element wise multiplication.
Vec3f final = ambient.mul(ambientIntensity);
Ray temp;
temp.org = ray.org + ray.t * ray.dir;
for (const auto& light : m_scene.getLights()){
auto intensity = light->illuminate(temp);
if (!intensity.has_value())
continue;
double cosLN = temp.dir.dot(normal);
double cosLR = temp.dir.dot(reflected);
if (cosLN > 0){
/*
* "For the purpose of shadow mapping in particular we should note that objects that
* are directly lit by the light source reflect all 3 of the light components, while
* objects in the shadow only reflect the ambient component."
* https://blogs.igalia.com/itoral/2017/07/06/working_lights_shadows_parti_phong_reflection_model/
* */
if (m_scene.occluded(temp))
continue;
Vec3f diffuse = m_kd * color;
final += (diffuse * cosLN).mul(intensity.value());
}
// make sure we're in the front side.
if (cosLR > 0){
Vec3f specular = m_ks * RGB(1, 1, 1);
final += (specular * pow(cosLR, m_ke)).mul(intensity.value());
}
}
for (auto &x : final.val)
x = MIN(x, 1);
return final;
}


Expand Down
Loading