zigrtiow: implement depth of field.
This commit is contained in:
parent
8d92cc861e
commit
62317d57ae
@ -5,6 +5,7 @@ const Ray = @import("./ray.zig").Ray;
|
||||
|
||||
const Point3 = vec.Point3;
|
||||
const Vec3 = vec.Vec3;
|
||||
const random_in_unit_disk = vec.random_in_unit_disk;
|
||||
const math = std.math;
|
||||
const pi = math.pi;
|
||||
const tan = math.tan;
|
||||
@ -20,6 +21,10 @@ pub const Camera = struct {
|
||||
lower_left_corner: Point3,
|
||||
horizontal: Vec3,
|
||||
vertical: Vec3,
|
||||
u: Vec3,
|
||||
v: Vec3,
|
||||
w: Vec3,
|
||||
lens_radius: f32,
|
||||
|
||||
pub fn init(
|
||||
lookfrom: Point3,
|
||||
@ -27,6 +32,8 @@ pub const Camera = struct {
|
||||
vup: Vec3,
|
||||
vfov: f32, // vertical field-of-view in degrees
|
||||
aspect_ratio: f32,
|
||||
aperature: f32,
|
||||
focus_dist: f32,
|
||||
) Camera {
|
||||
const theta = degrees_to_radians(vfov);
|
||||
const h = tan(theta / 2);
|
||||
@ -38,18 +45,26 @@ pub const Camera = struct {
|
||||
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);
|
||||
const horizontal = u.scale(focus_dist * viewport_width);
|
||||
const vertical = v.scale(focus_dist * viewport_height);
|
||||
const lower_left_corner = origin.sub(horizontal.scale(0.5)).sub(vertical.scale(0.5)).sub(w.scale(focus_dist));
|
||||
|
||||
const lens_radius = aperature / 2;
|
||||
|
||||
return Camera{
|
||||
.origin = origin,
|
||||
.horizontal = horizontal,
|
||||
.vertical = vertical,
|
||||
.lower_left_corner = lower_left_corner,
|
||||
.u = u,
|
||||
.v = v,
|
||||
.w = w,
|
||||
.lens_radius = lens_radius,
|
||||
};
|
||||
}
|
||||
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))));
|
||||
const rd = random_in_unit_disk().scale(camera.lens_radius);
|
||||
const offset = camera.u.scale(rd.x()).add(camera.v.scale(rd.y()));
|
||||
return Ray.init(camera.origin.add(offset), camera.lower_left_corner.add(camera.horizontal.scale(s).add(camera.vertical.scale(t).sub(camera.origin).sub(offset))));
|
||||
}
|
||||
};
|
||||
|
||||
@ -108,7 +108,13 @@ pub fn main() anyerror!void {
|
||||
const world = Hittable{ .hittable_list = tmp_world };
|
||||
|
||||
// Camera
|
||||
const cam = Camera.init(Point3.init(-2, 2, 1), Point3.init(0, 0, -1), Vec3.init(0, 1, 0), 20, aspect_ratio);
|
||||
const lookfrom = Point3.init(3, 3, 2);
|
||||
const lookat = Point3.init(0, 0, -1);
|
||||
const vup = Vec3.init(0, 1, 0);
|
||||
const dist_to_focus = lookfrom.sub(lookat).length();
|
||||
const aperature = 2;
|
||||
|
||||
const cam = Camera.init(lookfrom, lookat, vup, 20, aspect_ratio, aperature, dist_to_focus);
|
||||
|
||||
// Render
|
||||
const Node = Queue(Task).Node;
|
||||
|
||||
@ -66,6 +66,13 @@ pub const Vec3 = struct {
|
||||
}
|
||||
};
|
||||
|
||||
pub fn random_in_unit_disk() Vec3 {
|
||||
while (true) {
|
||||
const p = Vec3.init(rand.float(f32) * 2 - 1, rand.float(f32) * 2 - 1, 0);
|
||||
if (p.length_squared() >= 1) continue;
|
||||
return p;
|
||||
}
|
||||
}
|
||||
pub fn random_in_unit_sphere() Vec3 {
|
||||
while (true) {
|
||||
const p = Vec3.random();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user