add glass
This commit is contained in:
parent
93330c85c2
commit
ac6cc84bf5
12
src/main.cpp
12
src/main.cpp
|
@ -39,7 +39,7 @@ colour ray_colour(const ray& r, const hittable& world, int depth)
|
||||||
auto t = 0.5 * (unit_direction.y() + 1.0);
|
auto t = 0.5 * (unit_direction.y() + 1.0);
|
||||||
|
|
||||||
auto a = colour(0.5, 0.6, 0.7);
|
auto a = colour(0.5, 0.6, 0.7);
|
||||||
auto b = colour(1.0, 1.0, 1.0);
|
auto b = colour(0.5, 0.5, 0.5);
|
||||||
|
|
||||||
return lerp(a, b, t);
|
return lerp(a, b, t);
|
||||||
}
|
}
|
||||||
|
@ -53,7 +53,7 @@ int main()
|
||||||
world.add(make_shared<sphere>(
|
world.add(make_shared<sphere>(
|
||||||
point3(0,0,-1),
|
point3(0,0,-1),
|
||||||
0.5,
|
0.5,
|
||||||
make_shared<lambertian>(colour(0.7,0.3,0.3))));
|
make_shared<lambertian>(colour(0.1,0.2,0.5))));
|
||||||
world.add(make_shared<sphere>(
|
world.add(make_shared<sphere>(
|
||||||
point3(0,-100.5,-1),
|
point3(0,-100.5,-1),
|
||||||
100,
|
100,
|
||||||
|
@ -62,11 +62,15 @@ int main()
|
||||||
world.add(make_shared<sphere>(
|
world.add(make_shared<sphere>(
|
||||||
point3(1,0,-1),
|
point3(1,0,-1),
|
||||||
0.5,
|
0.5,
|
||||||
make_shared<metal>(colour(0.8,0.6,0.2))));
|
make_shared<metal>(colour(0.8,0.6,0.2), 0.0)));
|
||||||
world.add(make_shared<sphere>(
|
world.add(make_shared<sphere>(
|
||||||
point3(-1,0,-1),
|
point3(-1,0,-1),
|
||||||
0.5,
|
0.5,
|
||||||
make_shared<metal>(colour(0.8,0.8,0.8))));
|
make_shared<dielectric>(1.5)));
|
||||||
|
world.add(make_shared<sphere>(
|
||||||
|
point3(-1,0,-1),
|
||||||
|
-0.45,
|
||||||
|
make_shared<dielectric>(1.5)));
|
||||||
|
|
||||||
camera cam;
|
camera cam;
|
||||||
|
|
||||||
|
|
|
@ -13,6 +13,13 @@ class material
|
||||||
ray& scattered) const = 0;
|
ray& scattered) const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
double schlick(double cosine, double refraction_index)
|
||||||
|
{
|
||||||
|
auto r0 = (1-refraction_index) / (1+refraction_index);
|
||||||
|
r0 = r0*r0;
|
||||||
|
return r0 + (1-r0)*pow(1-cosine, 5);
|
||||||
|
}
|
||||||
|
|
||||||
class lambertian : public material
|
class lambertian : public material
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
@ -37,7 +44,9 @@ class lambertian : public material
|
||||||
class metal : public material
|
class metal : public material
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
metal(const colour& a) : albedo_(a) {}
|
metal(const colour& a, double f) :
|
||||||
|
albedo_(a),
|
||||||
|
fuzz_(f < 1 ? f : 1) {}
|
||||||
|
|
||||||
virtual bool scatter(
|
virtual bool scatter(
|
||||||
const ray& r_in,
|
const ray& r_in,
|
||||||
|
@ -46,11 +55,55 @@ class metal : public material
|
||||||
ray& scattered) const
|
ray& scattered) const
|
||||||
{
|
{
|
||||||
vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal);
|
vec3 reflected = reflect(unit_vector(r_in.direction()), rec.normal);
|
||||||
scattered = ray(rec.p, reflected);
|
scattered = ray(rec.p, reflected + fuzz_*random_in_unit_sphere());
|
||||||
attenuation = albedo_;
|
attenuation = albedo_;
|
||||||
return dot(scattered.direction(), rec.normal) > 0;
|
return dot(scattered.direction(), rec.normal) > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
colour albedo_;
|
colour albedo_;
|
||||||
|
double fuzz_;
|
||||||
|
};
|
||||||
|
|
||||||
|
class dielectric : public material
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
dielectric(double ri) : refraction_index_(ri) {}
|
||||||
|
|
||||||
|
virtual bool scatter(
|
||||||
|
const ray& r_in,
|
||||||
|
const hit_record& rec,
|
||||||
|
colour& attenuation,
|
||||||
|
ray& scattered) const
|
||||||
|
{
|
||||||
|
attenuation = colour(1.0,1.0,1.0);
|
||||||
|
double etai_over_etat = rec.front_face ? (1.0 / refraction_index_) : refraction_index_;
|
||||||
|
|
||||||
|
vec3 unit_direction = unit_vector(r_in.direction());
|
||||||
|
|
||||||
|
double cos_theta = fmin(dot(-unit_direction, rec.normal), 1.0);
|
||||||
|
double sin_theta = sqrt(1.0 - cos_theta*cos_theta);
|
||||||
|
if (etai_over_etat * sin_theta > 1.0)
|
||||||
|
{
|
||||||
|
vec3 reflected = reflect(unit_direction, rec.normal);
|
||||||
|
scattered = ray(rec.p, reflected);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
double reflect_prob = schlick(cos_theta, etai_over_etat);
|
||||||
|
if (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;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
double refraction_index_;
|
||||||
};
|
};
|
||||||
|
|
|
@ -164,3 +164,12 @@ vec3 reflect(const vec3& v, const vec3& n)
|
||||||
{
|
{
|
||||||
return v - 2*dot(v,n)*n;
|
return v - 2*dot(v,n)*n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 = -sqrt(1.0 - r_out_parallel.length_squared()) * n;
|
||||||
|
|
||||||
|
return r_out_parallel + r_out_perp;
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue