Use ray casting to draw "blue sky" image.

This commit is contained in:
Bill Thiede 2022-07-31 16:34:26 -07:00
parent f0da916a22
commit 8bc5e347cc
3 changed files with 87 additions and 9 deletions

View File

@ -1,13 +1,36 @@
const std = @import("std");
const info = std.log.info;
const color = @import("./color.zig");
const ray = @import("./ray.zig");
const vec = @import("./vec.zig");
const Vec3 = vec.Vec3;
const Color = vec.Color;
const write_color = @import("./color.zig").write_color;
const Vec3 = vec.Vec3;
const Point3 = vec.Point3;
const info = std.log.info;
const write_color = color.write_color;
const Ray = ray.Ray;
fn ray_color(r: Ray) Color {
var unit_direction = r.direction().unit();
var t = 0.5 * (unit_direction.y() + 1);
return Color.init(1, 1, 1).scale(1 - t).add(Color.init(0.5, 0.7, 1.0).scale(t));
}
pub fn main() anyerror!void {
const image_width: isize = 256;
const image_height: isize = 256;
// Image
const aspect_ratio: f32 = 16.0 / 9.0;
const image_width = 400;
const image_height = @floatToInt(isize, @intToFloat(f32, image_width) / aspect_ratio);
// Camera
const viewport_height = 2;
const viewport_width = aspect_ratio * viewport_height;
const focal_length = 1;
const origin = Point3.init(0, 0, 0);
const horizontal = Vec3.init(viewport_width, 0, 0);
const vertical = Vec3.init(0, viewport_height, 0);
const lower_left_corner = origin.sub(horizontal.scale(0.5)).sub(vertical.scale(0.5)).sub(Vec3.init(0, 0, focal_length));
const stdout = std.io.getStdOut();
@ -16,16 +39,20 @@ pub fn main() anyerror!void {
var j: isize = image_height - 1;
while (j >= 0) : (j -= 1) {
info("Scanlines remaining: {d}", .{j});
//info("Scanlines remaining: {d}", .{j});
var i: isize = 0;
while (i < image_width) : (i += 1) {
const pixel_color = Color.init(@intToFloat(f32, i) / @intToFloat(f32, image_width - 1), @intToFloat(f32, j) / @intToFloat(f32, image_height - 1), 0.25);
const u = @intToFloat(f32, i) / @intToFloat(f32, image_width - 1);
const v = @intToFloat(f32, j) / @intToFloat(f32, image_height - 1);
const r = Ray.init(origin, lower_left_corner.add(horizontal.scale(u)).add(vertical.scale(v)).sub(origin));
const pixel_color = ray_color(r);
try write_color(pixel_color);
}
}
}
test "basic test" {
try std.testing.expectEqual(10, 3 + 7);
test {
// Run tests in imported source.
std.testing.refAllDecls(@This());
}

33
zigrtiow/src/ray.zig Normal file
View File

@ -0,0 +1,33 @@
const std = @import("std");
const vec = @import("./vec.zig");
const Vec3 = vec.Vec3;
const Point3 = vec.Point3;
pub const Ray = struct {
orig: Vec3,
dir: Vec3,
pub fn init(orig: Point3, dir: Vec3) Ray {
return Ray{
.orig = orig,
.dir = dir,
};
}
pub fn origin(ray: Ray) Point3 {
return ray.orig;
}
pub fn direction(ray: Ray) Vec3 {
return ray.dir;
}
pub fn at(ray: Ray, t: f32) Point3 {
return ray.orig.add(ray.dir.scale(t));
}
};
test "ray_at" {
const want = Point3.init(0, 0, 1.5);
const r = Ray.init(Point3.init(0, 0, 0), Vec3.init(0, 0, 1));
const got = r.at(1.5);
try std.testing.expectEqual(want, got);
}

View File

@ -14,6 +14,24 @@ pub const Vec3 = struct {
pub fn z(vec: Vec3) f32 {
return vec.v[2];
}
pub fn length(vec: Vec3) f32 {
return @sqrt(vec.length_squared());
}
fn length_squared(vec: Vec3) f32 {
return vec.v[0] * vec.v[0] + vec.v[1] * vec.v[1] + vec.v[2] * vec.v[2];
}
pub fn add(lhs: Vec3, rhs: Vec3) Vec3 {
return Vec3{ .v = lhs.v + rhs.v };
}
pub fn sub(lhs: Vec3, rhs: Vec3) Vec3 {
return Vec3{ .v = lhs.v - rhs.v };
}
pub fn scale(vec: Vec3, t: f32) Vec3 {
return Vec3{ .v = vec.v * @splat(3, t) };
}
pub fn unit(vec: Vec3) Vec3 {
return vec.scale(1 / vec.length());
}
};
pub const Color = Vec3;
pub const Point3 = Vec3;