Skip to content

CompGraph Assignment #12

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

Open
wants to merge 1 commit into
base: main
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
20,003 changes: 20,003 additions & 0 deletions CompGraph/Ninth.ppm

Large diffs are not rendered by default.

25 changes: 25 additions & 0 deletions CompGraph/camera.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef CAMERAH
#define CAMERAH

#include "ray.h"

class camera {
public:
camera(){
bottom_left_corner = vec3(-2.0 , -1.0 , -1.0);
x_motion = vec3(4.0 , 0.0 , 0.0);
y_motion = vec3(0.0 , 2.0 , 0.0);
origin = vec3(0.0 , 0.0 , 0.0);
}

ray get_ray(float u , float v) {
return ray(origin , bottom_left_corner + u*x_motion + v*y_motion - origin);
}

vec3 origin;
vec3 bottom_left_corner;
vec3 x_motion;
vec3 y_motion;
};

#endif
21 changes: 21 additions & 0 deletions CompGraph/hitable.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
#ifndef HITABLEH
#define HITABLEH

#include "ray.h"
class material;
struct hit_record {
float t;
vec3 p;
vec3 normal;
material *material_ptr;
};

class hitable {
public:
virtual bool hit(const ray& r , float t_min , float t_max , hit_record& rec) const = 0;
};
class material {
public:
virtual bool scatter(const ray& r_in, const hit_record& rec , vec3& attenuation , ray& scattered) const = 0;
};
#endif
30 changes: 30 additions & 0 deletions CompGraph/hitable_list.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef HITABLELISTH
#define HITABLELISTH

#include "hitable.h"

class hitable_list: public hitable {
public:
hitable_list() {}
hitable_list(hitable **l , int n) {list = l ; list_size = n;}
virtual bool hit(const ray&r , float t_min , float t_max , hit_record& rec) const;
hitable **list;
int list_size;
};

bool hitable_list::hit(const ray&r , float t_min , float t_max , hit_record& rec) const {
hit_record temp_rec;
bool hit_anything = false;
double closest_so_far = t_max;
for (int i = 0; i < list_size ; i++){
if ( list[i] -> hit(r, t_min , closest_so_far , temp_rec)) {
hit_anything = true;
closest_so_far = temp_rec.t;
rec = temp_rec;
}
}

return hit_anything;
}

#endif
77 changes: 77 additions & 0 deletions CompGraph/materials.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#ifndef MATERIALH
#define MATERIALH

#include "ray.h"
#include "hitable.h"


class lambertian : public material {
public:
lambertian(const vec3& a) : albedo(a) {}
virtual bool scatter(const ray& r_in , const hit_record& rec , vec3& attenuation , ray& scattered) const {
vec3 target = rec.p + rec.normal + random_in_unit_sphere();
scattered = ray(rec.p , target - rec.p);
attenuation = albedo;
return true;
}

vec3 albedo;
};

class metal : public material {
public:
metal(const vec3& a , float f) : albedo(a) {if(f<1) fuzz = f; else fuzz =1; }
virtual bool scatter (const ray& r_in , const hit_record& rec , vec3& attenuation , ray& scattered) const {
vec3 reflected = reflect(unit_vector(r_in.direction()) , rec.normal);
scattered = ray(rec.p , reflected + fuzz*random_in_unit_sphere());
attenuation = albedo;
return (dot(scattered.direction() , rec.normal) > 0);
}
vec3 albedo;
float fuzz;
};
class dielectric : public material {
public:
dielectric(float ri): ref_idx(ri) {}
virtual bool scatter(const ray& r_in , const hit_record& rec , vec3& attenuation , ray& scattered) const {
vec3 outward_normal;
vec3 reflected = reflect(r_in.direction() , rec.normal);
float ni_over_nt;
attenuation = vec3(1.0 , 1.0 ,1.0);
vec3 refracted;
float reflect_prob;
float cosine;
if(dot(r_in.direction() , rec.normal) > 0) {
outward_normal = (-1.0)*rec.normal;
ni_over_nt = ref_idx;
cosine = ref_idx * dot(r_in.direction() , rec.normal) / r_in.direction().length();
}
else{
outward_normal = rec.normal;
ni_over_nt = 1.0/ref_idx;
cosine = (-1.0)*dot(r_in.direction() , rec.normal) / r_in.direction().length();
}

if(refract(r_in.direction() , outward_normal , ni_over_nt , refracted)) {
reflect_prob = schlick(cosine , ref_idx);
}
else{
scattered = ray(rec.p , reflected);
reflect_prob = 1.0;
}

if ( (float(rand() % 1000) / float(1000)) < reflect_prob) {
scattered = ray(rec.p , reflected);
}
else{
scattered = ray(rec.p , refracted);
}

return true;
}

float ref_idx;
};


#endif
39 changes: 39 additions & 0 deletions CompGraph/ray.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef RAYH
#define RAYH
#include "vec3.h"

class ray
{
public:
ray() {}
ray(const vec3& a , const vec3& b) {A = a ; B = b;}
vec3 origion() const {return A;}
vec3 direction() const {return B;}
vec3 point_at_parameter(float t) const {return A + t*B;}

vec3 A;
vec3 B;
};
inline vec3 reflect(const vec3& v , const vec3& n ) {
return v -2*dot(v,n)*n;
}

inline bool refract(const vec3& v , const vec3& n , float ni_over_nt , vec3& refracted) {
vec3 uv = unit_vector(v);
float dt = dot(uv , n);
float discriminant = 1.0 - ni_over_nt*ni_over_nt*(1.0 - dt*dt);
if(discriminant > 0) {
refracted = ni_over_nt*(uv - dt*n) - sqrt(discriminant)*n;
return true;
}
else
return false;
}

float schlick(float cosine , float ref_idx) {
float r0 = (1.0 - ref_idx) / (1.0 + ref_idx);
r0 = r0*r0;
return r0 + (1-r0)*pow((1-cosine) , 5);
}

#endif
65 changes: 65 additions & 0 deletions CompGraph/rayt.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#include<fstream>
#include<stdlib.h>

#include "materials.h"
#include "sphere.h"
#include "hitable_list.h"
#include "float.h"
#include "camera.h"


vec3 color(const ray& r , hitable *world , int depth){
hit_record rec;
if( world->hit(r , 0.001 , FLT_MAX , rec)) {
ray scattered;
vec3 attenuation;
if(depth < 50 && rec.material_ptr->scatter(r, rec , attenuation , scattered)) {
return attenuation*color(scattered , world , depth+1);
}
else{
return vec3(0,0,0);
}
}
else{
vec3 unit_direction = unit_vector(r.direction());
float yd = 0.5*(unit_direction.y() + 1.0);
return (1.0 - yd)*vec3(1.0 , 1.0 , 1.0) + yd*vec3(0.5 , 0.7 , 1.0);
}
}

int main() {
int npx = 200;
int npy = 100;
int ns = 100;
ofstream ofs("Ninth.ppm" , ios::out | ios::app);
ofs << "P3\n" << npx << " " << npy << "\n255" <<endl;

hitable *list[5];
list[0] = new sphere(vec3(0 , 0 , -1) , 0.5 , new lambertian(vec3(0.1 , 0.2 , 0.5)));
list[1] = new sphere(vec3(0 , -100.5 , -1) , 100 , new lambertian(vec3(0.8 , 0.8 , 0.0)));
list[2] = new sphere(vec3(1,0,-1) , 0.5 , new metal(vec3(0.8,0.6,0.2) , 0.3));
list[3] = new sphere(vec3(-1,0,-1) , 0.5 , new dielectric(1.5));
list[4] = new sphere(vec3(-1,0,-1) , -0.45 , new dielectric(1.5));
hitable *world = new hitable_list(list , 5);
camera cam;

for(int j = npy-1 ; j >= 0 ; j--)
{
for(int i = 0 ; i < npx ; i++)
{
vec3 col(0 , 0 , 0);
for(int s = 0; s < ns; s++){
float x_s = float(rand() % 1000) / float(1000);
float y_s = float(rand() % 1000) / float(1000);
float u = float(i + x_s)/ float(npx);
float v = float(j + y_s)/ float(npy);
ray r = cam.get_ray(u,v);
col += color(r , world , 0);
}
col /= float(ns);
col = vec3( sqrt(col[0]) , sqrt(col[1]) , sqrt(col[2]));
col = col.toColor();
ofs << col.e[0] << " " << col.e[1] << " " << col.e[2] << endl;
}
}
}
Binary file added CompGraph/rayt.exe
Binary file not shown.
44 changes: 44 additions & 0 deletions CompGraph/sphere.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
#ifndef SPHEREH
#define SPHEREH

#include "hitable.h"

class sphere: public hitable {
public:
sphere() {}
sphere(vec3 cen , float r , material *mat_ptr ) : center(cen) , radius(r) , material_ptr(mat_ptr) {};
virtual bool hit(const ray& r , float t_min , float t_max , hit_record& rec) const;
vec3 center;
float radius;
material *material_ptr;
};

bool sphere::hit(const ray& r , float t_min , float t_max , hit_record& rec) const {
vec3 oc = r.origion() - center;
float a = dot(r.direction() , r.direction());
float b = dot(oc , r.direction());
float c = dot(oc , oc) - radius*radius;
float discriminant = b*b - a*c;
if(discriminant > 0) {
float temp = (-b - sqrt(b*b - a*c))/a ;
if(temp < t_max && temp > t_min) {
rec.t = temp;
rec.p = r.point_at_parameter(rec.t);
rec.normal = (rec.p - center)/radius;
rec.material_ptr = material_ptr;
return true;
}
temp = (-b + sqrt(b*b - a*c))/a;
if(temp < t_max && temp > t_min) {
rec.t = temp;
rec.p = r.point_at_parameter(rec.t);
rec.normal = (rec.p - center)/radius;
rec.material_ptr = material_ptr;
return true;
}
}

return false;
}

#endif
Loading