add total internal reflection
This commit is contained in:
parent
dde1f91f01
commit
4a478b08a0
|
@ -97,8 +97,8 @@ pub fn main() anyerror!void {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const materialCenter = Material{
|
const materialCenter = Material{
|
||||||
.dielectric = material.Dielectric{
|
.lambertian = material.Lambertian{
|
||||||
.refraction_index = 1.5,
|
.color = Color{ .x = 0.1, .y = 0.2, .z = 0.5 },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
const materialLeft = Material{
|
const materialLeft = Material{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const Random = std.rand.Random;
|
const Random = std.rand.Random;
|
||||||
|
const math = std.math;
|
||||||
|
|
||||||
const vec3 = @import("vec3.zig");
|
const vec3 = @import("vec3.zig");
|
||||||
const Color = @import("color.zig").Color;
|
const Color = @import("color.zig").Color;
|
||||||
|
@ -52,9 +53,15 @@ pub const Dielectric = struct {
|
||||||
const attenuation = Color{ .x = 1.0, .y = 1.0, .z = 1.0 };
|
const attenuation = Color{ .x = 1.0, .y = 1.0, .z = 1.0 };
|
||||||
const refraction_ratio = if (hit.front_face) 1.0 / self.refraction_index else self.refraction_index;
|
const refraction_ratio = if (hit.front_face) 1.0 / self.refraction_index else self.refraction_index;
|
||||||
const unit_direction = ray.direction.unit();
|
const unit_direction = ray.direction.unit();
|
||||||
const refracted = vec3.refract(unit_direction, hit.normal, refraction_ratio);
|
|
||||||
|
const cos_theta = math.min(unit_direction.mul_s(-1).dot(hit.normal), 1.0);
|
||||||
|
const sin_theta = math.sqrt(1.0 - cos_theta * cos_theta);
|
||||||
|
|
||||||
|
const cant_refract = refraction_ratio * sin_theta > 1.0;
|
||||||
|
const direction = if (cant_refract) unit_direction.reflect(hit.normal)
|
||||||
|
else unit_direction.refract(hit.normal, refraction_ratio);
|
||||||
return ScatteredRay{
|
return ScatteredRay{
|
||||||
.ray = Ray{ .origin = hit.p, .direction = refracted},
|
.ray = Ray{ .origin = hit.p, .direction = direction},
|
||||||
.color = attenuation,
|
.color = attenuation,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -82,6 +82,13 @@ pub const Vec3 = packed struct {
|
||||||
pub fn reflect(self: Vec3, n: Vec3) Vec3 {
|
pub fn reflect(self: Vec3, n: Vec3) Vec3 {
|
||||||
return self.sub(n.mul_s(self.dot(n) * 2));
|
return self.sub(n.mul_s(self.dot(n) * 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn refract(self: Vec3, n: Vec3, etai_over_etat: f32) Vec3 {
|
||||||
|
const cos_theta = math.min(self.mul_s(-1).dot(n), 1.0);
|
||||||
|
const r_out_perp = self.add(n.mul_s(cos_theta)).mul_s(etai_over_etat);
|
||||||
|
const r_out_parallel = n.mul_s(-math.sqrt(math.absFloat(1.0 - r_out_perp.length_squared())));
|
||||||
|
return r_out_perp.add(r_out_parallel);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn random(rng: *Random, min: f32, max: f32) Vec3 {
|
pub fn random(rng: *Random, min: f32, max: f32) Vec3 {
|
||||||
|
@ -116,13 +123,6 @@ pub fn random_in_hemisphere(rng: *Random, normal: Vec3) Vec3 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn refract(uv: Vec3, n: Vec3, etai_over_etat: f32) Vec3 {
|
|
||||||
const cos_theta = math.min(uv.mul_s(-1).dot(n), 1.0);
|
|
||||||
const r_out_perp = uv.add(n.mul_s(cos_theta)).mul_s(etai_over_etat);
|
|
||||||
const r_out_parallel = n.mul_s(-math.sqrt(math.absFloat(1.0 - r_out_perp.length_squared())));
|
|
||||||
return r_out_perp.add(r_out_parallel);
|
|
||||||
}
|
|
||||||
|
|
||||||
pub const Point3 = Vec3;
|
pub const Point3 = Vec3;
|
||||||
|
|
||||||
const assert = @import("std").debug.assert;
|
const assert = @import("std").debug.assert;
|
||||||
|
|
Loading…
Reference in a new issue