zigrtiow: create scene from book cover.

This commit is contained in:
Bill Thiede 2022-08-14 12:18:55 -07:00
parent 62317d57ae
commit b432e9a6dd
2 changed files with 63 additions and 26 deletions

View File

@ -83,36 +83,73 @@ fn render_row(q: *Queue(Task)) void {
} }
} }
} }
fn random_scene() anyerror!Hittable {
var prng = std.rand.DefaultPrng.init(0);
const rand = prng.random();
var world = HittableList.init();
const ground_material = create_labertian(Color.init(0.5, 0.5, 0.5));
try world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, -1000, 0), 1000, ground_material) });
var a: isize = -11;
while (a < 11) : (a += 1) {
var b: isize = -11;
while (b < 11) : (b += 1) {
const choose_mat = rand.float(f32);
const center = Point3.init(@intToFloat(f32, a) + 0.9 * rand.float(f32), 0.2, @intToFloat(f32, b) + 0.9 * rand.float(f32));
if (center.sub(Point3.init(4, 0.2, 0)).length() > 0.9) {
if (choose_mat < 0.8) {
const albedo = Color.random_min_max(0, 1).mul(Color.random_min_max(0, 1));
const sphere_material = create_labertian(albedo);
try world.add(Hittable{ .sphere = Sphere.init(center, 0.2, sphere_material) });
} else if (choose_mat < 0.95) {
const albedo = Color.init(
0.5 + rand.float(f32) / 2.0,
0.5 + rand.float(f32) / 2.0,
0.5 + rand.float(f32) / 2.0,
);
const fuzz = rand.float(f32) / 2.0;
const sphere_material = create_metal(albedo, fuzz);
try world.add(Hittable{ .sphere = Sphere.init(center, 0.2, sphere_material) });
} else {
const sphere_material = create_dielectric(1.5);
try world.add(Hittable{ .sphere = Sphere.init(center, 0.2, sphere_material) });
}
}
}
}
const material1 = create_dielectric(1.5);
try world.add(Hittable{ .sphere = Sphere.init(Point3.init(0, 1, 0), 1.0, material1) });
const material2 = create_labertian(Color.init(0.4, 0.2, 0.1));
try world.add(Hittable{ .sphere = Sphere.init(Point3.init(-4, 1, 0), 1.0, material2) });
const material3 = create_metal(Color.init(0.7, 0.6, 0.5), 0.0);
try world.add(Hittable{ .sphere = Sphere.init(Point3.init(4, 1, 0), 1.0, material3) });
return Hittable{ .hittable_list = world };
}
pub fn main() anyerror!void { pub fn main() anyerror!void {
// Image // Image
const aspect_ratio: f32 = 16.0 / 9.0; const aspect_ratio: f32 = 3.0 / 2.0;
const image_width = 400; const image_width = 1200;
const image_height = @floatToInt(isize, @intToFloat(f32, image_width) / aspect_ratio); const image_height = @floatToInt(isize, @intToFloat(f32, image_width) / aspect_ratio);
const samples_per_pixel = 100; const samples_per_pixel = 500;
const max_depth = 50; const max_depth = 50;
// World // World
var tmp_world = HittableList.init(); const world = try random_scene();
const material_ground = create_labertian(Color.init(0.8, 0.8, 0));
const material_center = create_labertian(Color.init(0.1, 0.2, 0.5));
const material_left = create_dielectric(1.5);
const material_right = create_metal(Color.init(0.8, 0.6, 0.2), 0.0);
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.45, 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 };
// Camera // Camera
const lookfrom = Point3.init(3, 3, 2); const lookfrom = Point3.init(13, 2, 3);
const lookat = Point3.init(0, 0, -1); const lookat = Point3.init(0, 0, 0);
const vup = Vec3.init(0, 1, 0); const vup = Vec3.init(0, 1, 0);
const dist_to_focus = lookfrom.sub(lookat).length(); const dist_to_focus = 10;
const aperature = 2; const aperature = 0.1;
const cam = Camera.init(lookfrom, lookat, vup, 20, aspect_ratio, aperature, dist_to_focus); const cam = Camera.init(lookfrom, lookat, vup, 20, aspect_ratio, aperature, dist_to_focus);

View File

@ -50,12 +50,12 @@ pub const Vec3 = struct {
pub fn cross(u: Vec3, v: Vec3) Vec3 { pub fn cross(u: Vec3, v: Vec3) Vec3 {
return Vec3.init(u.v[1] * v.v[2] - u.v[2] * v.v[1], u.v[2] * v.v[0] - u.v[0] * v.v[2], u.v[0] * v.v[1] - u.v[1] * v.v[0]); return Vec3.init(u.v[1] * v.v[2] - u.v[2] * v.v[1], u.v[2] * v.v[0] - u.v[0] * v.v[2], u.v[0] * v.v[1] - u.v[1] * v.v[0]);
} }
/// Return value in unit cube from -1, 1 /// Return value in unit cube from [min, max).
pub fn random() Vec3 { pub fn random_min_max(min: f32, max: f32) Vec3 {
return Vec3.init( return Vec3.init(
rand.float(f32) * 2 - 1, min + (max - min) * rand.float(f32),
rand.float(f32) * 2 - 1, min + (max - min) * rand.float(f32),
rand.float(f32) * 2 - 1, min + (max - min) * rand.float(f32),
); );
} }
pub fn near_zero(vec: Vec3) bool { pub fn near_zero(vec: Vec3) bool {
@ -75,7 +75,7 @@ pub fn random_in_unit_disk() Vec3 {
} }
pub fn random_in_unit_sphere() Vec3 { pub fn random_in_unit_sphere() Vec3 {
while (true) { while (true) {
const p = Vec3.random(); const p = Vec3.random_min_max(-1, 1);
if (p.length_squared() > 1) continue; if (p.length_squared() > 1) continue;
return p; return p;
} }