zigrtiow: placeable camera and helpers for creating materials.

This commit is contained in:
Bill Thiede 2022-08-13 20:57:46 -07:00
parent f2ade1eee2
commit 8d92cc861e
4 changed files with 42 additions and 13 deletions

View File

@ -22,6 +22,9 @@ pub const Camera = struct {
vertical: Vec3,
pub fn init(
lookfrom: Point3,
lookat: Point3,
vup: Vec3,
vfov: f32, // vertical field-of-view in degrees
aspect_ratio: f32,
) Camera {
@ -30,19 +33,23 @@ pub const Camera = struct {
const viewport_height = 2 * h;
const viewport_width = aspect_ratio * viewport_height;
const focal_length = 1.0;
const origin = Point3.init(0, 0, 0);
const horizontal = Vec3.init(viewport_width, 0.0, 0.0);
const vertical = Vec3.init(0.0, viewport_height, 0.0);
const w = lookfrom.sub(lookat).unit();
const u = vup.cross(w).unit();
const v = w.cross(u);
const origin = lookfrom;
const horizontal = u.scale(viewport_width);
const vertical = v.scale(viewport_height);
const lower_left_corner = origin.sub(horizontal.scale(0.5)).sub(vertical.scale(0.5)).sub(w);
return Camera{
.origin = origin,
.horizontal = horizontal,
.vertical = vertical,
.lower_left_corner = origin.sub(horizontal.scale(0.5)).sub(vertical.scale(0.5)).sub(Vec3.init(0, 0, focal_length)),
.lower_left_corner = lower_left_corner,
};
}
pub fn get_ray(camera: Camera, u: f32, v: f32) Ray {
return Ray.init(camera.origin, camera.lower_left_corner.add(camera.horizontal.scale(u).add(camera.vertical.scale(v).sub(camera.origin))));
pub fn get_ray(camera: Camera, s: f32, t: f32) Ray {
return Ray.init(camera.origin, camera.lower_left_corner.add(camera.horizontal.scale(s).add(camera.vertical.scale(t).sub(camera.origin))));
}
};

View File

@ -28,6 +28,9 @@ const write_color = color.write_color;
const math = std.math;
const pi = math.pi;
const cos = math.cos;
const create_labertian = material.create_labertian;
const create_metal = material.create_metal;
const create_dielectric = material.create_dielectric;
fn ray_color(r: Ray, world: Hittable, depth: isize) Color {
// If we've exceeded the ray bounce limit, no more light is gathered.
@ -90,18 +93,22 @@ pub fn main() anyerror!void {
const max_depth = 50;
// World
const r = cos(pi / @as(f32, 4.0));
var tmp_world = HittableList.init();
const material_left = Material{ .labertian = Labertian{ .albedo = Color.init(0, 0, 1) } };
const material_right = Material{ .labertian = Labertian{ .albedo = Color.init(1, 0, 0) } };
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(-r, 0, -1), r, material_left) });
try tmp_world.add(Hittable{ .sphere = Sphere.init(Point3.init(r, 0, -1), r, material_right) });
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
const cam = Camera.init(90, aspect_ratio);
const cam = Camera.init(Point3.init(-2, 2, 1), Point3.init(0, 0, -1), Vec3.init(0, 1, 0), 20, aspect_ratio);
// Render
const Node = Queue(Task).Node;

View File

@ -9,6 +9,18 @@ const random_unit_vector = vec.random_unit_vector;
const random_in_unit_sphere = vec.random_in_unit_sphere;
const pow = std.math.pow;
pub fn create_labertian(albedo: Vec3) Material {
return Material{ .labertian = Labertian{ .albedo = albedo } };
}
pub fn create_metal(albedo: Vec3, fuzz: f32) Material {
return Material{ .metal = Metal{ .albedo = albedo, .fuzz = fuzz } };
}
pub fn create_dielectric(ir: f32) Material {
return Material{ .dielectric = Dielectric{ .ir = ir } };
}
pub const Material = union(enum) {
labertian: Labertian,
metal: Metal,

View File

@ -47,6 +47,9 @@ pub const Vec3 = struct {
const t = u.v * v.v;
return t[0] + t[1] + t[2];
}
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 value in unit cube from -1, 1
pub fn random() Vec3 {
return Vec3.init(