1818
1919
2020double schlick (double cosine, double ref_idx) {
21- double r0 = (1 -ref_idx) / (1 +ref_idx);
21+ auto r0 = (1 -ref_idx) / (1 +ref_idx);
2222 r0 = r0*r0;
2323 return r0 + (1 -r0)*pow ((1 - cosine),5 );
2424}
@@ -36,6 +36,44 @@ class material {
3636};
3737
3838
39+ class lambertian : public material {
40+ public:
41+ lambertian (const color& a) : albedo(make_shared<solid_color>(a)) {}
42+ lambertian (shared_ptr<texture> a) : albedo(a) {}
43+
44+ virtual bool scatter (
45+ const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
46+ ) const {
47+ vec3 scatter_direction = rec.normal + random_unit_vector ();
48+ scattered = ray (rec.p , scatter_direction, r_in.time ());
49+ attenuation = albedo->value (rec.u , rec.v , rec.p );
50+ return true ;
51+ }
52+
53+ public:
54+ shared_ptr<texture> albedo;
55+ };
56+
57+
58+ class metal : public material {
59+ public:
60+ metal (const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1 ) {}
61+
62+ virtual bool scatter (
63+ const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
64+ ) const {
65+ vec3 reflected = reflect (unit_vector (r_in.direction ()), rec.normal );
66+ scattered = ray (rec.p , reflected + fuzz*random_in_unit_sphere (), r_in.time ());
67+ attenuation = albedo;
68+ return (dot (scattered.direction (), rec.normal ) > 0 );
69+ }
70+
71+ public:
72+ color albedo;
73+ double fuzz;
74+ };
75+
76+
3977class dielectric : public material {
4078 public:
4179 dielectric (double ri) : ref_idx(ri) {}
@@ -44,20 +82,15 @@ class dielectric : public material {
4482 const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
4583 ) const {
4684 attenuation = color (1.0 , 1.0 , 1.0 );
47- double etai_over_etat = (rec.front_face ) ? (1.0 / ref_idx) : ( ref_idx) ;
85+ double etai_over_etat = (rec.front_face ) ? (1.0 / ref_idx) : ref_idx;
4886
4987 vec3 unit_direction = unit_vector (r_in.direction ());
5088 double cos_theta = fmin (dot (-unit_direction, rec.normal ), 1.0 );
5189 double sin_theta = sqrt (1.0 - cos_theta*cos_theta);
52- if (etai_over_etat * sin_theta > 1.0 ) {
53- vec3 reflected = reflect (unit_direction, rec.normal );
54- scattered = ray (rec.p , reflected, r_in.time ());
55- return true ;
56- }
5790
58- double reflect_prob = schlick (cos_theta, etai_over_etat);
59- if (random_double () < reflect_prob )
60- {
91+ if ( ( etai_over_etat * sin_theta > 1.0 )
92+ || (random_double () < schlick (cos_theta, etai_over_etat) )
93+ ) {
6194 vec3 reflected = reflect (unit_direction, rec.normal );
6295 scattered = ray (rec.p , reflected, r_in.time ());
6396 return true ;
@@ -110,42 +143,4 @@ class isotropic : public material {
110143};
111144
112145
113- class lambertian : public material {
114- public:
115- lambertian (const color& a) : albedo(make_shared<solid_color>(a)) {}
116- lambertian (shared_ptr<texture> a) : albedo(a) {}
117-
118- virtual bool scatter (
119- const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
120- ) const {
121- vec3 scatter_direction = rec.normal + random_unit_vector ();
122- scattered = ray (rec.p , scatter_direction, r_in.time ());
123- attenuation = albedo->value (rec.u , rec.v , rec.p );
124- return true ;
125- }
126-
127- public:
128- shared_ptr<texture> albedo;
129- };
130-
131-
132- class metal : public material {
133- public:
134- metal (const color& a, double f) : albedo(a), fuzz(f < 1 ? f : 1 ) {}
135-
136- virtual bool scatter (
137- const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered
138- ) const {
139- vec3 reflected = reflect (unit_vector (r_in.direction ()), rec.normal );
140- scattered = ray (rec.p , reflected + fuzz*random_in_unit_sphere (), r_in.time ());
141- attenuation = albedo;
142- return (dot (scattered.direction (), rec.normal ) > 0 );
143- }
144-
145- public:
146- color albedo;
147- double fuzz;
148- };
149-
150-
151146#endif
0 commit comments