#ifndef MATERIAL_H #define MATERIAL_H #include "rtweekend.hpp" struct material { virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const = 0; }; struct lambertian : material { /* Attributes */ color albedo; // Constructor lambertian(const color& c) { albedo = c; } #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const override { vec3 scatter_direction = rec.normal + random_unit_vector(); /* NOTE: it is possible that the random vector we generate is exactly opposite to the normal vector, in which case it will sum to a near-zero scatter vector and generate degenerate results. We check for near-zero vectors here. */ if (scatter_direction.near_zero()) scatter_direction = rec.normal; scattered = ray(rec.p, scatter_direction); attenuation = albedo; return true; } #pragma GCC diagnostic pop }; struct metal : material { /* Attributes */ color albedo; // Constructor metal(const color& c) { albedo = c; }; virtual bool scatter(const ray& r_in, const hit_record& rec, color& attenuation, ray& scattered) const override { vec3 reflected = reflect(normalize(r_in.direction), rec.normal); scattered = ray(rec.p, reflected); attenuation = albedo; return (dot(scattered.direction, rec.normal) > 0); } }; #endif