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

Haolan Zheng Assignment-1 #16

Open
wants to merge 3 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
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
**Deadline**: 30.09.20201

Please put your name here:
**Name**: .......
**Name**: HaolanZheng
## Foreword
### Implementation of a Minimal Ray Tracing System

Expand Down
Binary file added renders/perspective1.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 renders/perspective1withDisc.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 renders/perspective2.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 renders/perspective3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
49 changes: 49 additions & 0 deletions src/CameraEnvironmental.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,52 @@

// --- IMPLENET class CCameraEnvironmental ---
// --- PUT YOUR CODE HERE ---

class CCameraEnvironmental : public ICamera
{
public:
CCameraEnvironmental(Size resolution, const Vec3f& pos, const Vec3f& dir,
const Vec3f& up, float angle)
: ICamera(resolution)
, m_pos(pos)
, m_up(up)
{
//m_focus = pow(pos[0],2) - pow(pos[])
////define orientation
//m_zAxis = m_dir;
//m_xAxis = normalize(m_zAxis.cross(up));
//m_yAxis = normalize(m_zAxis.cross(m_xAxis));
}
virtual void InitRay(Ray& ray, int x, int y) override
{
/*
PBR book
<<Compute environment camera ray direction>>=
Float theta = Pi * sample.pFilm.y / film->fullResolution.y;
Float phi = 2 * Pi * sample.pFilm.x / film->fullResolution.x;
Vector3f dir(std::sin(theta) * std::cos(phi), std::cos(theta),
std::sin(theta) * std::sin(phi));
*/
auto Resolution = getResolution();
float theta = Pi * static_cast<float>(y) / Resolution.height;
float phi = 2 * Pi * static_cast<float>(x) / Resolution.width;
ray.dir = Vec3f(sinf(theta) * cosf(phi),
cosf(theta),
sinf(theta) * sinf(phi)
);
ray.org = m_pos;
ray.t = float(INFINITY);
}

private:
// input values
Vec3f m_pos; ///< Camera origin (center of projection)
Vec3f m_dir; ///< Camera viewing direction
Vec3f m_up; ///< Camera up-vector
float m_focus; ///< The focal length

// preprocessed values
Vec3f m_xAxis; ///< Camera x-axis in WCS
Vec3f m_yAxis; ///< Camera y-axis in WCS
Vec3f m_zAxis; ///< Camera z-axis in WCS
};
66 changes: 66 additions & 0 deletions src/CameraPerspective-J.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
// Perspective Camera class
// Written by Sergey Kosov in 2005 for Rendering Competition
#pragma once

#include "ICamera.h"
#include "ray.h"

// ================================ Perspective Camera Class ================================
/**
* @brief Perspective Camera class
* @ingroup moduleCamera
* @author Sergey G. Kosov, [email protected]
*/
class CCameraPerspective : public ICamera
{
public:
/**
* @brief Constructor
* @param resolution The image resolution in pixels
* @param pos Camera origin (center of projection)
* @param dir Normalized camera viewing direction
* @param up Normalized camera up-vector
* @param angle (Vertical) full opening angle of the viewing frustum in degrees
*/
CCameraPerspective(Size resolution, const Vec3f& pos, const Vec3f& dir,
const Vec3f& up, float angle)
: ICamera(resolution)
, m_pos(pos)
, m_dir(dir)
, m_up(up)
, m_focus(1.0f / tanf(angle * Pif / 360))
{
//define orientation
m_zAxis = m_dir;
m_xAxis = normalize(m_zAxis.cross(up));
m_yAxis = normalize(m_zAxis.cross(m_xAxis));
}
virtual ~CCameraPerspective(void) = default;

virtual void InitRay(Ray& ray, int x, int y) override
{
//convert raster to ssc
Size res = getResolution();
float sscx = 2 * (static_cast<float>(x) / res.width)-1;
float sscy = 2 * (static_cast<float>(y) / res.height)-1;

//define ray
ray.dir = normalize(m_zAxis*m_focus + m_xAxis*sscx*getAspectRatio() + m_yAxis*sscy);
ray.org = m_pos;
ray.t = std::numeric_limits<float>::infinity();
}


private:
// input values
Vec3f m_pos; ///< Camera origin (center of projection)
Vec3f m_dir; ///< Camera viewing direction
Vec3f m_up; ///< Camera up-vector
float m_focus; ///< The focal length

// preprocessed values
Vec3f m_xAxis; ///< Camera x-axis in WCS
Vec3f m_yAxis; ///< Camera y-axis in WCS
Vec3f m_zAxis; ///< Camera z-axis in WCS
};

19 changes: 16 additions & 3 deletions src/CameraPerspective.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,32 @@ class CCameraPerspective : public ICamera
* @param up Normalized camera up-vector
* @param angle (Vertical) full opening angle of the viewing frustum in degrees
*/
CCameraPerspective(Size resolution, const Vec3f& pos, const Vec3f& dir, const Vec3f& up, float angle)
CCameraPerspective(Size resolution, const Vec3f& pos, const Vec3f& dir,
const Vec3f& up, float angle)
: ICamera(resolution)
, m_pos(pos)
, m_dir(dir)
, m_up(up)
, m_focus(1.0f / tanf(angle * Pif / 360))
{
// --- PUT YOUR CODE HERE ---
//define orientation
m_zAxis = m_dir;
m_xAxis = normalize(m_zAxis.cross(up));
m_yAxis = normalize(m_zAxis.cross(m_xAxis));
}
virtual ~CCameraPerspective(void) = default;

virtual void InitRay(Ray& ray, int x, int y) override
{
// --- PUT YOUR CODE HERE ---
//convert raster to ssc
Size res = getResolution();
float sscx = 2 * (static_cast<float>(x) / res.width) - 1;
float sscy = 2 * (static_cast<float>(y) / res.height) - 1;

//define ray
ray.dir = normalize(m_zAxis * m_focus + m_xAxis * sscx * getAspectRatio() + m_yAxis * sscy);
ray.org = m_pos;
ray.t = std::numeric_limits<float>::infinity();
}


Expand Down
35 changes: 33 additions & 2 deletions src/PrimDisc.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,37 @@

#include "IPrim.h"
#include "ray.h"

#include "PrimPlane.h"
// --- IMPLENET class CPrimDisc ---
// --- PUT YOUR CODE HERE ---
// --- PUT YOUR CODE HERE ---


class CPrimDisc : public IPrim
{
public:

CPrimDisc(const Vec3f& origin, const Vec3f& normal, const float radius)
: IPrim()
, m_origin(origin)
, m_radius(radius)
, m_normal(normal)
{}
virtual ~CPrimDisc(void) = default;

virtual bool intersect(Ray& ray) const override
{
auto Distance = ((m_origin - ray.org).dot(m_normal)) / ray.dir.dot(m_normal);
if (Distance > ray.t || isinf(Distance) || Distance < Epsilon) { return false; }
const Vec3f Point = ray.org + ray.t * ray.dir;
auto DistanceToOrigin = sqrt((Point - m_origin).dot(Point - m_origin));
if (DistanceToOrigin > m_radius) return false;
ray.t = Distance;
return true;
}


private:
Vec3f m_normal; ///< Point on the plane
Vec3f m_origin; ///< Normal to the plane
float m_radius; ///< Radius of the disc
};
5 changes: 4 additions & 1 deletion src/PrimPlane.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,10 @@ class CPrimPlane : public IPrim
virtual bool intersect(Ray& ray) const override
{
// --- PUT YOUR CODE HERE ---
return false;
auto Distance = ((m_origin - ray.org).dot(m_normal))/ray.dir.dot(m_normal);
if (Distance > ray.t || isinf(Distance) || Distance < Epsilon) { return false; }
ray.t = Distance;
return true;
}


Expand Down
22 changes: 21 additions & 1 deletion src/PrimSphere.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,27 @@ class CPrimSphere : public IPrim
virtual bool intersect(Ray &ray) const override
{
// --- PUT YOUR CODE HERE ---
return false;
double SquareRadius = static_cast<double>(m_radius) * static_cast<double>(m_radius);
auto BigL = m_origin - ray.org;
double Tb = BigL.dot(ray.dir);
auto h2 = pow(BigL.dot(BigL), 2) - pow(Tb, 2);
//solve for t1 and t2
const double a = 1;
const double b = (-2 * static_cast<double>(ray.dir.dot(BigL)));
const double c = static_cast<double>(BigL.dot(BigL)) - SquareRadius;
double inroot = b * b - 4 * a * c;
if (inroot < 0) return false;

auto t1 = (-b + sqrt(inroot)) / (2 * a);
auto t2 = (-b - sqrt(inroot)) / (2 * a);

if (t1 < Epsilon && t2 < Epsilon) return false;
//check if outof range
if (t1 > ray.t && t2 > ray.t) return false;
ray.t = t1 < t2 ? t1 : t2;

return true;

}


Expand Down
43 changes: 43 additions & 0 deletions src/PrimTriangle.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,51 @@ class CPrimTriangle : public IPrim

virtual bool intersect(Ray& ray) const override
{
/* The semantics of intersect should be as follows:
- Return true if and only if a valid intersection has been found in the interval (Epsilon, ray::t). Epsilon is defined in types.h.
- If a valid intersection has been found with the primitive, set ray::t to the distance to this intersection point (if current t < ray.t).
Find the closest intersection of the ray with the scene by just testing all in main.cpp defined primitives (s1, s2, s3, and p1) sequentially.
*/
// --- PUT YOUR CODE HERE ---

auto e1 = m_b - m_a;
auto e2 = m_c - m_a;

auto BigT = ray.org - m_a;

auto Q = BigT.cross(e1);
auto P = ray.dir.cross(e2);

//determinant
//const Vec3f P = ray.dir.cross(e2);
const float Det = e1.dot(P);
auto InverseDet = 1 / Det;



//Moller-Trumbore
float u = BigT.dot(P);
u *= InverseDet;
float v = ray.dir.dot(Q);
v *= InverseDet;

if (u < 0.f || u > 1.f || v < 0.f || v + u > 1.f) {
return false;
}

//if not false
//calculate distance
auto SmallT = (e2.dot(Q)) * InverseDet;
if (ray.t <= SmallT || SmallT < Epsilon) {
return false;
}
else {
ray.t = SmallT;
return true;
}

return false;

}


Expand Down
35 changes: 27 additions & 8 deletions src/main.cpp
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
#include "CameraPerspective.h"
#include "CameraEnvironmental.h"

#include "PrimDisc.h"
#include "PrimSphere.h"
#include "PrimPlane.h"
#include "PrimTriangle.h"

Mat RenderFrame(ICamera& camera)
{
// scene objects

//CPrimDisc s1(Vec3f(-2, 1.7f, 0), Vec3f(0, 1, 0), 2);
CPrimSphere s1(Vec3f(-2, 1.7f, 0), 2);
CPrimSphere s2(Vec3f(1, -1, 1), 2.2f);
CPrimSphere s3(Vec3f(3, 0.8f, -2), 2);
Expand All @@ -20,20 +20,38 @@ Mat RenderFrame(ICamera& camera)

Mat img(camera.getResolution(), CV_32FC3); // image array
Ray ray; // primary ray

for(int y = 0; y< img.rows; y++)
for (int x = 0; x < img.cols; x++) {

// Initialize your ray here

// --- PUT YOUR CODE HERE ---

camera.InitRay(ray, x, y);
Vec3f col = RGB(0, 0, 0); // background color

/*
* Find closest intersection with scene
* objetcs and calculate color
*/
if (s1.intersect(ray)) {
col = RGB(1, 0, 0);
}
if (s2.intersect(ray)) {
col = RGB(0, 1, 0);
}
if (s3.intersect(ray)) {
col = RGB(0, 0, 1);
}
if (p1.intersect(ray)) {
col = RGB(1, 1, 0);
}
if (t1.intersect(ray)) {
col = RGB(0, 1, 1);
}
if (t2.intersect(ray)) {
col = RGB(1, 1, 1);
}

// --- PUT YOUR CODE HERE ---

Expand All @@ -51,7 +69,7 @@ int main(int argc, char* argv[])

CCameraPerspective cam1(resolution, Vec3f(0, 0, 10), Vec3f(0, 0, -1), Vec3f(0, 1, 0), 60);
Mat img1 = RenderFrame(cam1);
imwrite("perspective1.jpg", img1);
imwrite("perspective1withDisc.jpg", img1);

CCameraPerspective cam2(resolution, Vec3f(-8, 3, 8), Vec3f(1, -0.1f, -1), Vec3f(0, 1, 0), 45);
Mat img2 = RenderFrame(cam2);
Expand All @@ -61,9 +79,10 @@ int main(int argc, char* argv[])
Mat img3 = RenderFrame(cam3);
imwrite("perspective3.jpg", img3);

// AddeEnvironmental camera here as cam4
// Mat img4 = RenderFrame(cam4);
// imwrite("orthographic4.jpg", img4);
//AddeEnvironmental camera here as cam4
CCameraEnvironmental cam4(resolution, Vec3f(-8, 3, 8), Vec3f(1, -0.1f, -1), Vec3f(1, 1, 0), 45);
Mat img4 = RenderFrame(cam4);
imwrite("orthographic4.jpg", img4);

return 0;
}