Adding glass
This commit is contained in:
		| @ -29,14 +29,55 @@ class lambertian : public material{ | ||||
|  | ||||
| class metal : public material{ | ||||
|     public: | ||||
|         metal(const color& a) : albedo(a){} | ||||
|         metal(const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1){} | ||||
|  | ||||
|         virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered)const override { | ||||
|             vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal); | ||||
|             scattered = ray(rec.p, reflected); | ||||
|             scattered = ray(rec.p, reflected + fuzz * random_in_unit_sphere()); | ||||
|             attenuation =albedo; | ||||
|             return (dot(scattered.direction(), rec.normal) > 0); | ||||
|         } | ||||
|     public: | ||||
|         color albedo; | ||||
|         double fuzz; | ||||
| }; | ||||
|  | ||||
| class dielectric : public material{ | ||||
|     public: | ||||
|         dielectric(double index_of_refraction) : ir(index_of_refraction){} | ||||
|  | ||||
|         virtual bool scatter (const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const override{ | ||||
|             attenuation = color(1.0,1.0,1.0); | ||||
|             double refraction_ratio = rec.front_face ? (1.0/ir) : ir; | ||||
|  | ||||
|             vec3 unit_direction = unit_vector(r_in.direction()); | ||||
|  | ||||
|             double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0); | ||||
|             double sin_theta = sqrt(1.0 - cos_theta * cos_theta); | ||||
|             bool cannot_refract = refraction_ratio * sin_theta > 1.0; | ||||
|             vec3 direction; | ||||
|  | ||||
|             if(cannot_refract || reflectance(cos_theta, refraction_ratio) > random_double()){ | ||||
|                 // Must reflect | ||||
|                 direction = reflect(unit_direction, rec.normal); | ||||
|             } else { | ||||
|                 // can refract  | ||||
|                 direction = refract(unit_direction, rec.normal, refraction_ratio); | ||||
|             } | ||||
|  | ||||
|             scattered = ray(rec.p, direction); | ||||
|  | ||||
|             return true; | ||||
|         } | ||||
|  | ||||
|     public: | ||||
|         double ir; | ||||
|  | ||||
|     private: | ||||
|         static double reflectance(double cosine, double ref_idx){ | ||||
|             // use Schlik's approximation | ||||
|             auto r0 = (1-ref_idx) / (1+ref_idx); | ||||
|             r0 = r0*r0; | ||||
|             return r0 + (1-r0)*pow((1-cosine), 5);    | ||||
|         } | ||||
| }; | ||||
| @ -41,14 +41,15 @@ int main () | ||||
|     hittable_list world; | ||||
|  | ||||
|     auto material_ground = make_shared<lambertian>(color(0.8,0.8, 0.0)); | ||||
|     auto material_center = make_shared<lambertian>(color(0.7,0.3,0.3)); | ||||
|     auto material_left = make_shared<metal> (color(0.8,0.8,0.8)); | ||||
|     auto material_right = make_shared<metal>(color(0.8,0.6,0.2)); | ||||
|     auto material_center = make_shared<lambertian>(color(0.1, 0.2, 0.5)); | ||||
|     auto material_left = make_shared<dielectric> (1.5); | ||||
|     auto material_right = make_shared<metal>(color(0.8,0.6,0.2), 0.0); | ||||
|      | ||||
|  | ||||
|     world.add(make_shared<sphere>(point3(0,-100.5,-1), 100.0, material_ground)); | ||||
|     world.add(make_shared<sphere>(point3(0,0,-1), 0.5,  material_center)); | ||||
|     world.add(make_shared<sphere>(point3(-1.0, 0.0, -1), 0.5, material_left)); | ||||
|     world.add(make_shared<sphere>(point3(-1.0, 0.0, -1), -0.4, material_left)); | ||||
|     world.add(make_shared<sphere>(point3(1.0, 0.0, -1), 0.5, material_right)); | ||||
|  | ||||
|  | ||||
|  | ||||
| @ -130,4 +130,11 @@ vec3 random_in_hemisphere (const vec3& normal){ | ||||
|  | ||||
| vec3 reflect (const vec3& v, const vec3& n){ | ||||
|     return v -2 *dot(v,n) *n; | ||||
| } | ||||
|  | ||||
| vec3 refract(const vec3& uv, const vec3& n, double etai_over_etat){ | ||||
|     auto cos_theta = fmin(dot(-uv,n), 1.0); | ||||
|     vec3 r_out_perp = etai_over_etat * (uv + cos_theta*n); | ||||
|     vec3 r_out_parallel = -sqrt(fabs(1.0 - r_out_perp.length_squared())) * n; | ||||
|     return r_out_perp + r_out_parallel;  | ||||
| } | ||||
		Reference in New Issue
	
	Block a user