add Dielectric material

master
Fabien Freling 2021-05-27 21:48:57 +02:00
parent a596058a0d
commit dde1f91f01
3 changed files with 29 additions and 5 deletions

View File

@ -97,14 +97,13 @@ pub fn main() anyerror!void {
} }
}; };
const materialCenter = Material{ const materialCenter = Material{
.lambertian = material.Lambertian{ .dielectric = material.Dielectric{
.color = Color{ .x = 0.7, .y = 0.3, .z = 0.3 }, .refraction_index = 1.5,
} }
}; };
const materialLeft = Material{ const materialLeft = Material{
.metal = material.Metal{ .dielectric = material.Dielectric{
.color = Color{ .x = 0.8, .y = 0.8, .z = 0.8 }, .refraction_index = 1.5,
.fuzz = 0.3,
} }
}; };
const materialRight = Material{ const materialRight = Material{

View File

@ -9,6 +9,7 @@ const HitRecord = @import("hittable.zig").HitRecord;
pub const MaterialType = enum { pub const MaterialType = enum {
lambertian, lambertian,
metal, metal,
dielectric,
}; };
pub const Lambertian = struct { pub const Lambertian = struct {
@ -44,6 +45,21 @@ pub const Metal = struct {
} }
}; };
pub const Dielectric = struct {
refraction_index: f32,
pub fn scatter(self: Dielectric, ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay {
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 unit_direction = ray.direction.unit();
const refracted = vec3.refract(unit_direction, hit.normal, refraction_ratio);
return ScatteredRay{
.ray = Ray{ .origin = hit.p, .direction = refracted},
.color = attenuation,
};
}
};
pub const ScatteredRay = struct { pub const ScatteredRay = struct {
ray: Ray, ray: Ray,
color: Color, color: Color,
@ -52,11 +68,13 @@ pub const ScatteredRay = struct {
pub const Material = union(MaterialType) { pub const Material = union(MaterialType) {
lambertian: Lambertian, lambertian: Lambertian,
metal: Metal, metal: Metal,
dielectric: Dielectric,
}; };
pub fn scatter(ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay { pub fn scatter(ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay {
return switch (hit.material) { return switch (hit.material) {
.lambertian => |m| m.scatter(ray, hit, rng), .lambertian => |m| m.scatter(ray, hit, rng),
.metal => |m| m.scatter(ray, hit, rng), .metal => |m| m.scatter(ray, hit, rng),
.dielectric => |m| m.scatter(ray, hit, rng),
}; };
} }

View File

@ -116,6 +116,13 @@ 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;