implement Material as tagged union
This commit is contained in:
parent
bc3fb54991
commit
c842fcf713
2 changed files with 53 additions and 44 deletions
|
@ -7,13 +7,41 @@ const Ray = @import("ray.zig").Ray;
|
|||
const HitRecord = @import("hittable.zig").HitRecord;
|
||||
|
||||
pub const MaterialType = enum {
|
||||
Lambertian,
|
||||
Metal,
|
||||
lambertian,
|
||||
metal,
|
||||
};
|
||||
|
||||
pub const Material = struct {
|
||||
materialType: MaterialType,
|
||||
pub const Lambertian = struct {
|
||||
color: Color,
|
||||
|
||||
pub fn scatter(self: Lambertian, ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay {
|
||||
var scatterDirection = hit.normal.add(vec3.random_unit_vector(rng));
|
||||
// Catch degenerate scatter direction
|
||||
if (scatterDirection.nearZero()) {
|
||||
scatterDirection = hit.normal;
|
||||
}
|
||||
return ScatteredRay{
|
||||
.ray = Ray{ .origin = hit.p, .direction = scatterDirection},
|
||||
.color = self.color,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const Metal = struct {
|
||||
color: Color,
|
||||
// fuzzy: f32,
|
||||
|
||||
pub fn scatter(self: Metal, ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay {
|
||||
const reflected = ray.direction.unit().reflect(hit.normal);
|
||||
const scattered = Ray{ .origin = hit.p, .direction = reflected };
|
||||
if (scattered.direction.dot(hit.normal) <= 0) {
|
||||
return null;
|
||||
}
|
||||
return ScatteredRay{
|
||||
.ray = scattered,
|
||||
.color = self.color,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
pub const ScatteredRay = struct {
|
||||
|
@ -21,35 +49,14 @@ pub const ScatteredRay = struct {
|
|||
color: Color,
|
||||
};
|
||||
|
||||
pub const Material = union(MaterialType) {
|
||||
lambertian: Lambertian,
|
||||
metal: Metal,
|
||||
};
|
||||
|
||||
pub fn scatter(ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay {
|
||||
const scatteredDirection = switch (hit.material.materialType) {
|
||||
|
||||
.Lambertian => blk: {
|
||||
var scatterDirection = hit.normal.add(vec3.random_unit_vector(rng));
|
||||
// Catch degenerate scatter direction
|
||||
if (scatterDirection.nearZero()) {
|
||||
scatterDirection = hit.normal;
|
||||
}
|
||||
break :blk scatterDirection;
|
||||
},
|
||||
|
||||
.Metal => blk: {
|
||||
const reflected = ray.direction.unit().reflect(hit.normal);
|
||||
const scattered = Ray{ .origin = hit.p, .direction = reflected };
|
||||
if (scattered.direction.dot(hit.normal) <= 0) {
|
||||
break :blk null;
|
||||
}
|
||||
break :blk scattered.direction;
|
||||
},
|
||||
|
||||
return switch (hit.material) {
|
||||
.lambertian => |m| m.scatter(ray, hit, rng),
|
||||
.metal => |m| m.scatter(ray, hit, rng),
|
||||
};
|
||||
|
||||
if (scatteredDirection) |dir| {
|
||||
return ScatteredRay{
|
||||
.ray = Ray{ .origin = hit.p, .direction = dir},
|
||||
.color = hit.material.color,
|
||||
};
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue