add Metal material

This commit is contained in:
Fabien Freling 2021-05-11 22:52:51 +02:00
parent b3c47a914f
commit bc3fb54991
3 changed files with 45 additions and 11 deletions

View file

@ -94,17 +94,27 @@ pub fn main() anyerror!void {
// World // World
const materialGround = Material{ const materialGround = Material{
.materialType = MaterialType.Lambertian, .materialType = .Lambertian,
.color = Color{ .x = 0.8, .y = 0.8, .z = 0.0 }, .color = Color{ .x = 0.8, .y = 0.8, .z = 0.0 },
}; };
const materialCenter = Material{ const materialCenter = Material{
.materialType = MaterialType.Lambertian, .materialType = .Lambertian,
.color = Color{ .x = 0.7, .y = 0.3, .z = 0.3 }, .color = Color{ .x = 0.7, .y = 0.3, .z = 0.3 },
}; };
const materialLeft = Material{
.materialType = .Metal,
.color = Color{ .x = 0.8, .y = 0.8, .z = 0.8 },
};
const materialRight = Material{
.materialType = .Metal,
.color = Color{ .x = 0.8, .y = 0.6, .z = 0.2 },
};
const spheres = [_]Sphere{ const spheres = [_]Sphere{
Sphere{ .center = Point3{ .x = 0, .y = 0, .z = -1 }, .radius = 0.5, .material = materialCenter },
Sphere{ .center = Point3{ .x = 0, .y = -100.5, .z = -1 }, .radius = 100, .material = materialGround }, Sphere{ .center = Point3{ .x = 0, .y = -100.5, .z = -1 }, .radius = 100, .material = materialGround },
Sphere{ .center = Point3{ .x = 0, .y = 0, .z = -1 }, .radius = 0.5, .material = materialCenter },
Sphere{ .center = Point3{ .x = -1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialLeft },
Sphere{ .center = Point3{ .x = 1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialRight },
}; };
const world = World{ .spheres = spheres[0..spheres.len] }; const world = World{ .spheres = spheres[0..spheres.len] };

View file

@ -8,6 +8,7 @@ const HitRecord = @import("hittable.zig").HitRecord;
pub const MaterialType = enum { pub const MaterialType = enum {
Lambertian, Lambertian,
Metal,
}; };
pub const Material = struct { pub const Material = struct {
@ -21,15 +22,34 @@ pub const ScatteredRay = struct {
}; };
pub fn scatter(ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay { pub fn scatter(ray: Ray, hit: HitRecord, rng: *Random) ?ScatteredRay {
var scatterDirection = hit.normal.add(vec3.random_unit_vector(rng)); const scatteredDirection = switch (hit.material.materialType) {
// Catch degenerate scatter direction .Lambertian => blk: {
if (scatterDirection.nearZero()) { var scatterDirection = hit.normal.add(vec3.random_unit_vector(rng));
scatterDirection = hit.normal; // 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;
},
};
if (scatteredDirection) |dir| {
return ScatteredRay{
.ray = Ray{ .origin = hit.p, .direction = dir},
.color = hit.material.color,
};
} }
return ScatteredRay{ return null;
.ray = Ray{ .origin = hit.p, .direction = scatterDirection},
.color = hit.material.color,
};
} }

View file

@ -78,6 +78,10 @@ pub const Vec3 = packed struct {
and math.absFloat(self.y) < t and math.absFloat(self.y) < t
and math.absFloat(self.z) < t; and math.absFloat(self.z) < t;
} }
pub fn reflect(self: Vec3, n: Vec3) Vec3 {
return self.sub(n.mul_s(self.dot(n) * 2));
}
}; };
pub fn random(rng: *Random, min: f32, max: f32) Vec3 { pub fn random(rng: *Random, min: f32, max: f32) Vec3 {