Adding dielectric material.
This commit is contained in:
parent
129854222d
commit
3683a309c5
2
Makefile
2
Makefile
@ -9,7 +9,7 @@ TARGET = wtracer
|
|||||||
|
|
||||||
all: $(TARGET) run
|
all: $(TARGET) run
|
||||||
|
|
||||||
run:
|
run: $(TARGET)
|
||||||
time -f '%E elapsed' ./wtracer > image.ppm
|
time -f '%E elapsed' ./wtracer > image.ppm
|
||||||
eog image.ppm
|
eog image.ppm
|
||||||
|
|
||||||
|
27
material.cpp
27
material.cpp
@ -1,5 +1,7 @@
|
|||||||
#include "material.h"
|
#include "material.h"
|
||||||
|
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
bool Lambertian::scatter(const Ray& r_in, const hit_record& rec, Color& attenuation, Ray& scattered) const {
|
bool Lambertian::scatter(const Ray& r_in, const hit_record& rec, Color& attenuation, Ray& scattered) const {
|
||||||
//Vec3 scatter_direction = rec.normal + random_in_unit_sphere();
|
//Vec3 scatter_direction = rec.normal + random_in_unit_sphere();
|
||||||
Vec3 scatter_direction = rec.normal + random_unit_vector();
|
Vec3 scatter_direction = rec.normal + random_unit_vector();
|
||||||
@ -15,3 +17,28 @@ bool Metal::scatter(const Ray& r_in, const hit_record& rec, Color& attenuation,
|
|||||||
attenuation = albedo;
|
attenuation = albedo;
|
||||||
return (dot(scattered.direction(), rec.normal) > 0);
|
return (dot(scattered.direction(), rec.normal) > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double schlick(double cosine, double ref_idx) {
|
||||||
|
auto r0 = (1 - ref_idx) / (1 + ref_idx);
|
||||||
|
r0 = r0 * r0;
|
||||||
|
return r0 + (1 - r0) * std::pow((1 - cosine), 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Dielectric::scatter(const Ray& r_in, const hit_record& rec, Color& attenuation, Ray& scattered) const {
|
||||||
|
attenuation = Color(1.0, 1.0, 1.0);
|
||||||
|
double etai_over_etat = rec.front_face ? 1.0 / ref_idx : ref_idx;
|
||||||
|
|
||||||
|
Vec3 unit_direction = unit_vector(r_in.direction());
|
||||||
|
double cos_theta = std::fmin(dot(-unit_direction, rec.normal), 1.0);
|
||||||
|
double sin_theta = std::sqrt(1.0 - cos_theta*cos_theta);
|
||||||
|
double reflect_prob = schlick(cos_theta, etai_over_etat);
|
||||||
|
if (etai_over_etat * sin_theta > 1.0 || random_double() < reflect_prob) {
|
||||||
|
Vec3 reflected = reflect(unit_direction, rec.normal);
|
||||||
|
scattered = Ray(rec.p, reflected);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Vec3 refracted = refract(unit_direction, rec.normal, etai_over_etat);
|
||||||
|
scattered = Ray(rec.p, refracted);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
10
material.h
10
material.h
@ -31,4 +31,14 @@ private:
|
|||||||
double fuzz;
|
double fuzz;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
double schlick(double cosine, double ref_idx);
|
||||||
|
|
||||||
|
class Dielectric : public Material {
|
||||||
|
public:
|
||||||
|
Dielectric(double ri) : ref_idx(ri) {}
|
||||||
|
virtual bool scatter(const Ray& r_in, const hit_record& rec, Color& attenuation, Ray& scattered) const;
|
||||||
|
private:
|
||||||
|
double ref_idx;
|
||||||
|
};
|
||||||
|
|
||||||
#endif // MATERIAL_H
|
#endif // MATERIAL_H
|
||||||
|
7
vec3.cpp
7
vec3.cpp
@ -22,3 +22,10 @@ Vec3 random_in_hemisphere(const Vec3& normal) {
|
|||||||
else
|
else
|
||||||
return -in_unit_sphere;
|
return -in_unit_sphere;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Vec3 refract(const Vec3& uv, const Vec3& n, double etai_over_etat) {
|
||||||
|
auto cos_theta = dot(-uv, n);
|
||||||
|
Vec3 r_out_parallel = etai_over_etat * (uv + cos_theta*n);
|
||||||
|
Vec3 r_out_perp = - std::sqrt(1.0 - r_out_parallel.length_squared()) * n;
|
||||||
|
return r_out_parallel + r_out_perp;
|
||||||
|
}
|
||||||
|
2
vec3.h
2
vec3.h
@ -122,4 +122,6 @@ Vec3 random_unit_vector();
|
|||||||
|
|
||||||
Vec3 random_in_hemisphere(const Vec3& normal);
|
Vec3 random_in_hemisphere(const Vec3& normal);
|
||||||
|
|
||||||
|
Vec3 refract(const Vec3& uv, const Vec3& n, double etai_over_etat);
|
||||||
|
|
||||||
#endif // VEC3_H
|
#endif // VEC3_H
|
||||||
|
10
wtracer.cpp
10
wtracer.cpp
@ -41,14 +41,14 @@ int main() {
|
|||||||
std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";
|
std::cout << "P3\n" << image_width << " " << image_height << "\n255\n";
|
||||||
|
|
||||||
Hittable_list world;
|
Hittable_list world;
|
||||||
/*world.add(std::make_shared<Sphere>(Point3(0, 0, -1), 0.5));
|
|
||||||
world.add(std::make_shared<Sphere>(Point3(0, -100.5, -1), 100));*/
|
|
||||||
|
|
||||||
world.add(std::make_shared<Sphere>(Point3(0, 0, -1), 0.5, std::make_shared<Lambertian>(Color(0.7, 0.3, 0.3))));
|
world.add(std::make_shared<Sphere>(Point3(0, 0, -1), 0.5, std::make_shared<Lambertian>(Color(0.1, 0.2, 0.5))));
|
||||||
world.add(std::make_shared<Sphere>(Point3(0, -100.5, -1), 100, std::make_shared<Lambertian>(Color(0.8, 0.8, 0.0))));
|
world.add(std::make_shared<Sphere>(Point3(0, -100.5, -1), 100, std::make_shared<Lambertian>(Color(0.8, 0.8, 0.0))));
|
||||||
|
|
||||||
world.add(std::make_shared<Sphere>(Point3(1, 0, -1), 0.5, std::make_shared<Metal>(Color(0.8, 0.6, 0.2), 0.3)));
|
world.add(std::make_shared<Sphere>(Point3(1, 0, -1), 0.5, std::make_shared<Metal>(Color(0.8, 0.6, 0.2), 0.0)));
|
||||||
world.add(std::make_shared<Sphere>(Point3(-1, 0, -1), 0.5, std::make_shared<Metal>(Color(0.8, 0.8, 0.8), 1.0)));
|
|
||||||
|
|
||||||
|
world.add(std::make_shared<Sphere>(Point3(-1, 0, -1), 0.5, std::make_shared<Dielectric>(1.45)));
|
||||||
|
|
||||||
Camera cam;
|
Camera cam;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user