1717struct hit_record ;
1818
1919
20- double schlick (double cosine, double ref_idx) {
21- auto r0 = (1 -ref_idx) / (1 +ref_idx);
22- r0 = r0*r0;
23- return r0 + (1 -r0)*pow ((1 - cosine),5 );
24- }
25-
26-
2720class material {
2821 public:
2922 virtual bool scatter (
@@ -70,6 +63,14 @@ class metal : public material {
7063
7164
7265class dielectric : public material {
66+ private:
67+ static double reflectance (double cosine, double ref_idx) {
68+ // Use Schlick's approximation for reflectance.
69+ auto r0 = (1 -ref_idx) / (1 +ref_idx);
70+ r0 = r0*r0;
71+ return r0 + (1 -r0)*pow ((1 - cosine),5 );
72+ }
73+
7374 public:
7475 dielectric (double index_of_refraction) : ir(index_of_refraction) {}
7576
@@ -85,16 +86,11 @@ class dielectric : public material {
8586
8687 bool cannot_refract = refraction_ratio * sin_theta > 1.0 ;
8788
88- // If the ray cannot refract, or if it probabilistically reflects because of its
89- // grazing angle, then return the reflected path.
90- if (cannot_refract || random_double () < schlick (cos_theta, refraction_ratio)) {
91- vec3 reflected = reflect (unit_direction, rec.normal );
92- scattered = ray (rec.p , reflected);
93- return true ;
94- }
89+ if (cannot_refract || reflectance (cos_theta, refraction_ratio) > random_double ())
90+ scattered = ray (rec.p , reflect (unit_direction, rec.normal ));
91+ else
92+ scattered = ray (rec.p , refract (unit_direction, rec.normal , refraction_ratio));
9593
96- vec3 refracted = refract (unit_direction, rec.normal , refraction_ratio);
97- scattered = ray (rec.p , refracted);
9894 return true ;
9995 }
10096
0 commit comments