Compare commits
No commits in common. "6b4be0ed1e4e4101396cdb48a2456c468befa2db" and "a2012e674220310b4fd255ed79c1ab00df7f1db1" have entirely different histories.
6b4be0ed1e
...
a2012e6742
@ -1,2 +0,0 @@
|
|||||||
fd zig | entr -c bash -c "zig build test && zig build -Drelease-safe=true &&
|
|
||||||
./zig-out/bin/zigrtiow | convert ppm:- /tmp/output.png"
|
|
||||||
@ -1,8 +1,6 @@
|
|||||||
const vec = @import("./vec.zig");
|
const vec = @import("./vec.zig");
|
||||||
const ray = @import("./ray.zig");
|
const ray = @import("./ray.zig");
|
||||||
|
|
||||||
const Material = @import("./material.zig").Material;
|
|
||||||
|
|
||||||
const Sphere = @import("./sphere.zig").Sphere;
|
const Sphere = @import("./sphere.zig").Sphere;
|
||||||
const HittableList = @import("./hittable_list.zig").HittableList;
|
const HittableList = @import("./hittable_list.zig").HittableList;
|
||||||
|
|
||||||
@ -27,7 +25,6 @@ pub const HitRecord = struct {
|
|||||||
normal: Vec3,
|
normal: Vec3,
|
||||||
t: f32,
|
t: f32,
|
||||||
front_face: bool,
|
front_face: bool,
|
||||||
material: Material,
|
|
||||||
|
|
||||||
pub fn set_face_normal(hr: *HitRecord, r: Ray, outward_normal: Vec3) void {
|
pub fn set_face_normal(hr: *HitRecord, r: Ray, outward_normal: Vec3) void {
|
||||||
hr.front_face = r.direction().dot(outward_normal) < 0;
|
hr.front_face = r.direction().dot(outward_normal) < 0;
|
||||||
|
|||||||
@ -6,32 +6,27 @@ const vec = @import("./vec.zig");
|
|||||||
const sphere = @import("./sphere.zig");
|
const sphere = @import("./sphere.zig");
|
||||||
const hittable = @import("./hittable.zig");
|
const hittable = @import("./hittable.zig");
|
||||||
const hittable_list = @import("./hittable_list.zig");
|
const hittable_list = @import("./hittable_list.zig");
|
||||||
const material = @import("./material.zig");
|
|
||||||
|
|
||||||
const Camera = camera.Camera;
|
const Camera = camera.Camera;
|
||||||
const Color = vec.Color;
|
const Color = vec.Color;
|
||||||
const Hittable = hittable.Hittable;
|
const Hittable = hittable.Hittable;
|
||||||
const HittableList = hittable_list.HittableList;
|
const HittableList = hittable_list.HittableList;
|
||||||
const Labertian = material.Labertian;
|
|
||||||
const Metal = material.Metal;
|
|
||||||
const Material = material.Material;
|
|
||||||
const Point3 = vec.Point3;
|
const Point3 = vec.Point3;
|
||||||
const Ray = ray.Ray;
|
const Ray = ray.Ray;
|
||||||
const Sphere = sphere.Sphere;
|
const Sphere = sphere.Sphere;
|
||||||
const Vec3 = vec.Vec3;
|
const Vec3 = vec.Vec3;
|
||||||
const info = std.log.info;
|
|
||||||
const random_in_hemisphere = vec.random_in_hemisphere;
|
const random_in_hemisphere = vec.random_in_hemisphere;
|
||||||
|
const info = std.log.info;
|
||||||
const write_color = color.write_color;
|
const write_color = color.write_color;
|
||||||
|
|
||||||
fn ray_color(r: Ray, world: Hittable, depth: isize) Color {
|
fn ray_color(r: Ray, world: Hittable, depth: isize) Color {
|
||||||
// If we've exceeded the ray bounce limit, no more light is gathered.
|
// If we've exceeded the ray bounce limit, no more light is gathered.
|
||||||
if (depth <= 0) return Color.init(0, 0, 0);
|
if (depth <= 0) return Color.init(0, 0, 0);
|
||||||
|
|
||||||
if (world.hit(r, 0.0001, std.math.inf(f32))) |hit_rec| {
|
var hit = world.hit(r, 0.0001, std.math.inf(f32));
|
||||||
if (hit_rec.material.scatter(r, hit_rec)) |scatter_rec| {
|
if (hit) |rec| {
|
||||||
return scatter_rec.attenuation.mul(ray_color(scatter_rec.scattered, world, depth - 1));
|
const target = rec.p.add(rec.normal.add(random_in_hemisphere(rec.normal)));
|
||||||
}
|
return ray_color(Ray.init(rec.p, target.sub(rec.p)), world, depth - 1).scale(0.5);
|
||||||
return Color.init(0, 0, 0);
|
|
||||||
}
|
}
|
||||||
var unit_direction = r.direction().unit();
|
var unit_direction = r.direction().unit();
|
||||||
const t = 0.5 * (unit_direction.y() + 1);
|
const t = 0.5 * (unit_direction.y() + 1);
|
||||||
@ -48,16 +43,8 @@ pub fn main() anyerror!void {
|
|||||||
|
|
||||||
// World
|
// World
|
||||||
var tmp_world = HittableList.init();
|
var tmp_world = HittableList.init();
|
||||||
|
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 0, -1), 0.5) });
|
||||||
const material_ground = Material{ .labertian = Labertian{ .albedo = Color.init(0.8, 0.8, 0.0) } };
|
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -100.5, -1), 100) });
|
||||||
const material_center = Material{ .labertian = Labertian{ .albedo = Color.init(0.7, 0.3, 0.3) } };
|
|
||||||
const material_left = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.8, 0.8) } };
|
|
||||||
const material_right = Material{ .metal = Metal{ .albedo = Color.init(0.8, 0.6, 0.2) } };
|
|
||||||
|
|
||||||
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -100.5, -1), 100, material_ground) });
|
|
||||||
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 0, -1), 0.5, material_center) });
|
|
||||||
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(-1, 0, -1), 0.5, material_left) });
|
|
||||||
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(1, 0, -1), 0.5, material_right) });
|
|
||||||
const world = Hittable{ .hittable_list = tmp_world };
|
const world = Hittable{ .hittable_list = tmp_world };
|
||||||
|
|
||||||
// Camera
|
// Camera
|
||||||
|
|||||||
@ -1,56 +0,0 @@
|
|||||||
const vec = @import("./vec.zig");
|
|
||||||
const Ray = @import("./ray.zig").Ray;
|
|
||||||
const HitRecord = @import("./hittable.zig").HitRecord;
|
|
||||||
|
|
||||||
const Vec3 = vec.Vec3;
|
|
||||||
const Color = vec.Color;
|
|
||||||
const random_unit_vector = vec.random_unit_vector;
|
|
||||||
|
|
||||||
pub const Material = union(enum) {
|
|
||||||
labertian: Labertian,
|
|
||||||
metal: Metal,
|
|
||||||
|
|
||||||
pub fn scatter(material: Material, r_in: Ray, rec: HitRecord) ?ScatterRec {
|
|
||||||
return switch (material) {
|
|
||||||
.labertian => |labertian| labertian.scatter(r_in, rec),
|
|
||||||
.metal => |metal| metal.scatter(r_in, rec),
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const ScatterRec = struct { attenuation: Color, scattered: Ray };
|
|
||||||
|
|
||||||
pub const Labertian = struct {
|
|
||||||
albedo: Vec3,
|
|
||||||
pub fn scatter(labertian: Labertian, r_in: Ray, rec: HitRecord) ?ScatterRec {
|
|
||||||
_ = r_in;
|
|
||||||
var scatter_direction = rec.normal.add(random_unit_vector());
|
|
||||||
if (scatter_direction.near_zero()) {
|
|
||||||
scatter_direction = rec.normal;
|
|
||||||
}
|
|
||||||
return ScatterRec{
|
|
||||||
.scattered = Ray.init(rec.p, scatter_direction),
|
|
||||||
.attenuation = labertian.albedo,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const Metal = struct {
|
|
||||||
albedo: Vec3,
|
|
||||||
pub fn scatter(metal: Metal, r_in: Ray, rec: HitRecord) ?ScatterRec {
|
|
||||||
const reflected = reflect(r_in.direction().unit(), rec.normal);
|
|
||||||
const scattered = Ray.init(rec.p, reflected);
|
|
||||||
const attenuation = metal.albedo;
|
|
||||||
if (scattered.direction().dot(rec.normal) > 0) {
|
|
||||||
return ScatterRec{
|
|
||||||
.scattered = scattered,
|
|
||||||
.attenuation = attenuation,
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn reflect(v: Vec3, n: Vec3) Vec3 {
|
|
||||||
return v.sub(n.scale(v.dot(n) * 2));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@ -2,8 +2,6 @@ const vec = @import("./vec.zig");
|
|||||||
const ray = @import("./ray.zig");
|
const ray = @import("./ray.zig");
|
||||||
const hittable = @import("./hittable.zig");
|
const hittable = @import("./hittable.zig");
|
||||||
|
|
||||||
const Material = @import("./material.zig").Material;
|
|
||||||
|
|
||||||
const Vec3 = vec.Vec3;
|
const Vec3 = vec.Vec3;
|
||||||
const Point3 = vec.Point3;
|
const Point3 = vec.Point3;
|
||||||
const Ray = ray.Ray;
|
const Ray = ray.Ray;
|
||||||
@ -12,13 +10,11 @@ const HitRecord = hittable.HitRecord;
|
|||||||
pub const Sphere = struct {
|
pub const Sphere = struct {
|
||||||
center: Point3,
|
center: Point3,
|
||||||
radius: f32,
|
radius: f32,
|
||||||
material: Material,
|
|
||||||
|
|
||||||
pub fn init(center: Point3, radius: f32, material: Material) Sphere {
|
pub fn init(center: Point3, radius: f32) Sphere {
|
||||||
return Sphere{
|
return Sphere{
|
||||||
.center = center,
|
.center = center,
|
||||||
.radius = radius,
|
.radius = radius,
|
||||||
.material = material,
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
pub fn hit(sphere: Sphere, r: Ray, t_min: f32, t_max: f32) ?HitRecord {
|
pub fn hit(sphere: Sphere, r: Ray, t_min: f32, t_max: f32) ?HitRecord {
|
||||||
@ -48,7 +44,6 @@ pub const Sphere = struct {
|
|||||||
.p = p,
|
.p = p,
|
||||||
.normal = Vec3.init(0, 0, 0),
|
.normal = Vec3.init(0, 0, 0),
|
||||||
.front_face = false,
|
.front_face = false,
|
||||||
.material = sphere.material,
|
|
||||||
};
|
};
|
||||||
hr.set_face_normal(r, outward_normal);
|
hr.set_face_normal(r, outward_normal);
|
||||||
return hr;
|
return hr;
|
||||||
|
|||||||
@ -34,9 +34,6 @@ pub const Vec3 = struct {
|
|||||||
pub fn sub(lhs: Vec3, rhs: Vec3) Vec3 {
|
pub fn sub(lhs: Vec3, rhs: Vec3) Vec3 {
|
||||||
return Vec3{ .v = lhs.v - rhs.v };
|
return Vec3{ .v = lhs.v - rhs.v };
|
||||||
}
|
}
|
||||||
pub fn mul(lhs: Vec3, rhs: Vec3) Vec3 {
|
|
||||||
return Vec3{ .v = lhs.v * rhs.v };
|
|
||||||
}
|
|
||||||
pub fn scale(vec: Vec3, t: f32) Vec3 {
|
pub fn scale(vec: Vec3, t: f32) Vec3 {
|
||||||
return Vec3{ .v = vec.v * @splat(3, t) };
|
return Vec3{ .v = vec.v * @splat(3, t) };
|
||||||
}
|
}
|
||||||
@ -55,12 +52,6 @@ pub const Vec3 = struct {
|
|||||||
rand.float(f32) * 2 - 1,
|
rand.float(f32) * 2 - 1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
pub fn near_zero(vec: Vec3) bool {
|
|
||||||
// Return true if the vector is close to zero in all dimensions.
|
|
||||||
const s = 1e-8;
|
|
||||||
const e = vec.v;
|
|
||||||
return (@fabs(e[0]) < s) and (@fabs(e[1]) < s) and (@fabs(e[2]) < s);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn random_in_unit_sphere() Vec3 {
|
pub fn random_in_unit_sphere() Vec3 {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user