3 #include <color/spectrum.hpp>
5 #include <hittable/pdf.hpp>
6 #include <texture/texture.hpp>
8 using namespace ptracey;
15 shared_ptr<pdf> pdf_ptr;
19 virtual color emitted(
const ray &r_in,
21 Real v,
const point3 &p)
const {
24 virtual bool scatter(
const ray &r_in,
29 virtual Real scattering_pdf(
const ray &r_in,
31 const ray &scattered)
const {
38 : albedo(make_shared<solid_color>(a)) {}
39 lambertian(shared_ptr<texture> a) : albedo(a) {}
42 srec.is_specular =
false;
43 srec.attenuation = albedo->value(rec.u, rec.v, rec.p,
45 srec.pdf_ptr = make_shared<cosine_pdf>(rec.normal);
48 Real scattering_pdf(
const ray &r_in,
50 const ray &scattered)
const override {
52 dot(rec.normal, unit_vector(scattered.direction()));
53 return cosine < 0 ? 0 : cosine / M_PI;
57 shared_ptr<texture> albedo;
62 : albedo(make_shared<solid_color>(a)),
63 fuzz(f < 1 ? f : 1) {}
68 reflect(unit_vector(r_in.direction()), rec.normal);
69 srec.specular_ray =
ray(
70 rec.p, reflected + fuzz * random_in_unit_sphere(),
71 r_in.time(), r_in.wavelength());
73 albedo->value(rec.u, rec.v, rec.p,
74 srec.specular_ray.wavelength());
75 srec.is_specular =
true;
76 srec.pdf_ptr =
nullptr;
81 shared_ptr<texture> albedo;
87 : ir(index_of_refraction) {}
91 srec.is_specular =
true;
92 srec.pdf_ptr =
nullptr;
94 srec.attenuation = white;
95 Real refraction_ratio =
96 rec.front_face ? (1.0 / ir) : ir;
98 vec3 unit_direction = unit_vector(r_in.direction());
100 fmin(dot(-unit_direction, rec.normal), 1.0);
101 Real sin_theta = sqrt(1.0 - cos_theta * cos_theta);
103 bool cannot_refract =
104 refraction_ratio * sin_theta > 1.0;
107 if (cannot_refract ||
108 reflectance(cos_theta, refraction_ratio) >
110 direction = reflect(unit_direction, rec.normal);
112 direction = refract(unit_direction, rec.normal,
115 srec.specular_ray =
ray(rec.p, direction, r_in.time(),
124 static Real reflectance(Real cosine, Real ref_idx) {
126 auto r0 = (1 - ref_idx) / (1 + ref_idx);
128 return r0 + (1 - r0) * pow((1 - cosine), 5);
135 : emit(make_shared<solid_color>(c)) {}
139 const point3 &p)
const override {
142 return emit->value(u, v, p, r_in.wavelength());
146 shared_ptr<texture> emit;
151 : albedo(make_shared<solid_color>(c)) {}
152 isotropic(shared_ptr<texture> a) : albedo(a) {}
156 srec.specular_ray =
ray(rec.p, random_in_unit_sphere(),
157 r_in.time(), r_in.wavelength());
159 albedo->value(rec.u, rec.v, rec.p,
160 srec.specular_ray.wavelength());
161 srec.is_specular =
true;
162 srec.pdf_ptr =
nullptr;
167 shared_ptr<texture> albedo;