diff --git a/Graphics/Aman/camera.h b/Graphics/Aman/camera.h new file mode 100644 index 0000000..5b38314 --- /dev/null +++ b/Graphics/Aman/camera.h @@ -0,0 +1,22 @@ +#ifndef CAMERAH +#define CAMERAH + +#include "ray.h" + +class camera { + public: + camera() { + lower_left_corner = vec3(-2.0,-1.0,-1.0); + horizontal = vec3(4.0,0.0,0.0); + vertical = 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, lower_left_corner+u*horizontal+v*vertical - origin);} + + vec3 lower_left_corner; + vec3 origin; + vec3 vertical; + vec3 horizontal; +}; + +#endif \ No newline at end of file diff --git a/Graphics/Aman/chap1.cpp b/Graphics/Aman/chap1.cpp new file mode 100644 index 0000000..2086337 --- /dev/null +++ b/Graphics/Aman/chap1.cpp @@ -0,0 +1,24 @@ +#include +#include + +int main(){ + int nx=200; + int ny=100; + std::ofstream fout("chap1.ppm"); + if(fout.fail()) return -1; + + fout <<"P3\n" << nx << " " << ny << "\n255\n"; + for(int j= ny-1;j>=0;j--){ + for(int i=0;i +#include +#include "vec3.h" + +int main(){ + std::ofstream fout("chap2.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include "ray.h" + +vec3 color(const ray& r) { + vec3 unit_direction = unit_vector(r.direction()); + float t= 0.5*(unit_direction.y() + 1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); +} + +int main(){ + std::ofstream fout("chap3.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include "ray.h" + +bool hit_sphere(const vec3& center, float radius, const ray& r){ + vec3 oc= r.origin()-center; + float a = dot(r.direction(), r.direction()); + float b= 2.0*dot(oc,r.direction()); + float c= dot(oc,oc) - radius*radius; + float discriminant = b*b - 4*a*c; + return (discriminant>0); +} + + +vec3 color(const ray& r) { + if(hit_sphere(vec3(0,0,-1),0.5,r)) + return vec3(1,0,0); + vec3 unit_direction = unit_vector(r.direction()); + float t= 0.5*(unit_direction.y() + 1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); +} + +int main(){ + std::ofstream fout("chap4.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include "ray.h" + +float hit_sphere(const vec3& center, float radius, const ray& r){ + vec3 oc= r.origin()-center; + float a = dot(r.direction(), r.direction()); + float b= 2.0*dot(oc,r.direction()); + float c= dot(oc,oc) - radius*radius; + float discriminant = b*b - 4*a*c; + if(discriminant <0) + return -1.0; + + return (-b-sqrt(discriminant))/(2.0*a); +} + + +vec3 color(const ray& r) { + float t=hit_sphere(vec3(0,0,-1),0.5,r); + if(t>0.0){ + vec3 N = unit_vector(r.point_at_parameter(t) -vec3(0,0,-1)); + return 0.5*vec3(N.x()+1,N.y()+1,N.z()+1); + } + vec3 unit_direction = unit_vector(r.direction()); + t= 0.5*(unit_direction.y() + 1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); +} + +int main(){ + std::ofstream fout("chap5_1.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include "sphere.h" +#include "hitable_list.h" +#include "float.h" + +vec3 color(const ray& r, hitable *world){ + hit_record rec; + if(world -> hit(r,0.0, FLT_MAX, rec)) { + return 0.5*vec3(rec.normal.x() +1, rec.normal.y()+1,rec.normal.z()+1); + } + else { + vec3 unit_direction = unit_vector(r.direction()); + float t= 0.5*(unit_direction.y() +1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); + } +} + +int main(){ + std::ofstream fout("chap5_2.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include +#include +#include "sphere.h" +#include "hitable_list.h" +#include "float.h" +#include "camera.h" +#define drand48() ((double) rand()/RAND_MAX) + +vec3 color(const ray& r, hitable *world){ + hit_record rec; + if(world -> hit(r,0.0, FLT_MAX, rec)) { + return 0.5*vec3(rec.normal.x() +1, rec.normal.y()+1,rec.normal.z()+1); + } + else { + vec3 unit_direction = unit_vector(r.direction()); + float t= 0.5*(unit_direction.y() +1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); + } +} + +int main(){ + std::ofstream fout("chap6.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + int ns=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include +#include +#include "sphere.h" +#include "hitable_list.h" +#include "float.h" +#include "camera.h" +#define drand48() ((double) rand()/RAND_MAX) + +vec3 random_in_unit_sphere() { + vec3 p; + do { + p=2.0*vec3(drand48(), drand48(), drand48()) - vec3(1,1,1); + } while (p.squared_length() >= 1.0); + return p; +} + +vec3 color(const ray& r, hitable *world){ + hit_record rec; + if(world -> hit(r,0.0, FLT_MAX, rec)) { + vec3 target = rec.p + rec.normal + random_in_unit_sphere(); + return 0.5*color(ray(rec.p,target-rec.p), world); + } + else { + vec3 unit_direction = unit_vector(r.direction()); + float t= 0.5*(unit_direction.y() +1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); + } +} + +int main(){ + std::ofstream fout("chap7.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + int ns=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include +#include +#include "sphere.h" +#include "hitable_list.h" +#include "float.h" +#include "camera.h" +#define drand48() ((double) rand()/RAND_MAX) + +vec3 random_in_unit_sphere() { + vec3 p; + do { + p=2.0*vec3(drand48(), drand48(), drand48()) - vec3(1,1,1); + } while (p.squared_length() >= 1.0); + return p; +} + +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.mat_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 t= 0.5*(unit_direction.y() +1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); + } +} + +class lambertain: public material { + public: + lambertain (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; +}; + +vec3 reflect(const vec3& v, const vec3& n) { + return v-2*dot(v,n)*n; +} + +class metal : public material { + public: + metal(const vec3& a) : albedo(a) {} + 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); + attenuation = albedo; + return (dot(scattered.direction(), rec.normal)>0); + } + vec3 albedo; + float fuzz; +}; + +int main(){ + std::ofstream fout("chap8.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + int ns=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include +#include +#include "sphere.h" +#include "hitable_list.h" +#include "float.h" +#include "camera.h" +#define drand48() ((double) rand()/RAND_MAX) + +vec3 random_in_unit_sphere() { + vec3 p; + do { + p=2.0*vec3(drand48(), drand48(), drand48()) - vec3(1,1,1); + } while (p.squared_length() >= 1.0); + return p; +} + +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.mat_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 t= 0.5*(unit_direction.y() +1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); + } +} + +class lambertain: public material { + public: + lambertain (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; +}; + +vec3 reflect(const vec3& v, const vec3& n) { + return v-2*dot(v,n)*n; +} + +class metal : public material { + public: + metal(const vec3& a) : albedo(a) {} + 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); + attenuation = albedo; + return (dot(scattered.direction(), rec.normal)>0); + } + vec3 albedo; + float fuzz; +}; + +bool refract(const vec3& v, const vec3& n, float ni_over_nt,vec3& refracated){ + vec3 uv= unit_vector(v); + float dt = dot(uv,n); + float discriminant = 1.0 -(ni_over_nt*ni_over_nt)*(1-dt*dt); + if(discriminant >0){ + refracated = ni_over_nt*(uv - n*dt) - n*sqrt(discriminant); + return true; + } + else + return false; +} + +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; + if(dot(r_in.direction(), rec.normal)>0){ + outward_normal = -rec.normal; + ni_over_nt = ref_idx; + } + else{ + outward_normal = rec.normal; + ni_over_nt = 1.0/ref_idx; + } + if(refract(r_in.direction(), outward_normal, ni_over_nt, refracted)) { + scattered = ray(rec.p, refracted); + } + else{ + scattered = ray(rec.p, reflected); + return false; + } + return true; + } + float ref_idx; +}; + + +int main(){ + std::ofstream fout("chap9_1.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + int ns=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;i +#include +#include +#include +#include "sphere.h" +#include "hitable_list.h" +#include "float.h" +#include "camera.h" +#define drand48() ((double) rand()/RAND_MAX) + +vec3 random_in_unit_sphere() { + vec3 p; + do { + p=2.0*vec3(drand48(), drand48(), drand48()) - vec3(1,1,1); + } while (p.squared_length() >= 1.0); + return p; +} + +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.mat_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 t= 0.5*(unit_direction.y() +1.0); + return (1.0 -t)*vec3(1.0,1.0,1.0) + t*vec3(0.5,0.7,1.0); + } +} + +class lambertain: public material { + public: + lambertain (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; +}; + +vec3 reflect(const vec3& v, const vec3& n) { + return v-2*dot(v,n)*n; +} + +class metal : public material { + public: + metal(const vec3& a) : albedo(a) {} + 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); + attenuation = albedo; + return (dot(scattered.direction(), rec.normal)>0); + } + vec3 albedo; + float fuzz; +}; + +bool refract(const vec3& v, const vec3& n, float ni_over_nt,vec3& refracated){ + vec3 uv= unit_vector(v); + float dt = dot(uv,n); + float discriminant = 1.0 -(ni_over_nt*ni_over_nt)*(1-dt*dt); + if(discriminant >0){ + refracated = ni_over_nt*(uv - n*dt) - n*sqrt(discriminant); + return true; + } + else + return false; +} + +float schlick (float cosine, float ref_idx){ + float r0 = (1-ref_idx) / (1 + ref_idx); + r0*=r0; + return r0 + (1- r0)*pow((1-cosine),5); +} + +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 = -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 = -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( drand48() < reflect_prob){ + scattered = ray(rec.p, reflected); + } + else{ + scattered = ray(rec.p, refracted); + } + return true; + } + float ref_idx; +}; + + +int main(){ + std::ofstream fout("chap9_2.ppm"); + if(fout.fail()) return -1; + + int nx=200; + int ny=100; + int ns=100; + fout<<"P3\n"<=0;j--){ + for(int i=0;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 \ No newline at end of file diff --git a/Graphics/Aman/ray.h b/Graphics/Aman/ray.h new file mode 100644 index 0000000..e1883df --- /dev/null +++ b/Graphics/Aman/ray.h @@ -0,0 +1,17 @@ +#ifndef RAYH +#define RAYH +#include "vec3.h" + +class ray{ + public: + ray() {} + ray(const vec3& a, const vec3& b) { A=a; B=b;} + vec3 origin() const { return A;} + vec3 direction() const { return B;} + vec3 point_at_parameter(float t) const { return A + t*B; } + + vec3 A; + vec3 B; +}; + +#endif \ No newline at end of file diff --git a/Graphics/Aman/sphere.h b/Graphics/Aman/sphere.h new file mode 100644 index 0000000..ebcbebc --- /dev/null +++ b/Graphics/Aman/sphere.h @@ -0,0 +1,44 @@ +#ifndef SPHEREH +#define SPHEREH + +#include "hitable.h" + +class sphere: public hitable { + public: + sphere() {} + sphere(vec3 cen,float r, material *mat) : center(cen), radius(r), mat_(mat) {}; + virtual bool hit(const ray& r, float tmin, float tmax, hit_record& res) const; + vec3 center; + float radius; + material *mat_; +}; + +bool sphere::hit(const ray& r, float t_min, float t_max, hit_record& rec) const { + vec3 oc = r.origin()- 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_min){ + rec.t = temp; + rec.p = r.point_at_parameter(rec.t); + rec.normal = (rec.p - center)/radius; + rec.mat_ptr = mat_; + return true; + } + temp = (-b + sqrt(b*b - a*c))/a; + if(tempt_min){ + rec.t = temp; + rec.p = r.point_at_parameter(rec.t); + rec.normal = (rec.p - center)/radius; + rec.mat_ptr =mat_; + return true; + } + } + return false; +} + + +#endif \ No newline at end of file diff --git a/Graphics/Aman/vec3.h b/Graphics/Aman/vec3.h new file mode 100644 index 0000000..43cb879 --- /dev/null +++ b/Graphics/Aman/vec3.h @@ -0,0 +1,142 @@ +#include +#include +#include + +class vec3 { + public: + vec3() {} + vec3(float e0, float e1, float e2) { e[0]= e0; e[1]= e1; e[2]=e2;} + inline float x() const { return e[0];} + inline float y() const { return e[1];} + inline float z() const { return e[2];} + inline float r() const { return e[0];} + inline float g() const { return e[1];} + inline float b() const { return e[2];} + + inline const vec3& operator+() const { return *this; } + inline vec3 operator-() const { return vec3(-e[0], -e[1], -e[2]);} + inline float operator[](int i) const { return e[i];} + inline float& operator[](int i) { return e[i]; }; + + inline vec3& operator+= (const vec3 &v2); + inline vec3& operator-= (const vec3 &v2); + inline vec3& operator*= (const vec3 &v2); + inline vec3& operator/= (const vec3 &v2); + inline vec3& operator*= (const float t); + inline vec3& operator/= (const float t); + + inline float length() const { + return sqrt( e[0]*e[0] + e[1]*e[1] + e[2]*e[2]); + } + inline float squared_length() const { + return (e[0]*e[0]+e[1]*e[1]+e[2]*e[2]); + } + inline void make_unit_vector(); + + float e[3]; +}; + +inline std::istream& operator>>(std::istream &is, vec3 &t){ + is>>t.e[0]>>t.e[1]>>t.e[2]; + return is; +} + +inline std::ostream& operator<<(std::ostream &os, const vec3 &t){ + os<