add defocus blur
This commit is contained in:
parent
d6ba8e354c
commit
2ab82d4c92
|
@ -1,5 +1,6 @@
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
|
const Random = std.rand.Random;
|
||||||
|
|
||||||
const Point3 = @import("vec3.zig").Point3;
|
const Point3 = @import("vec3.zig").Point3;
|
||||||
const Vec3 = @import("vec3.zig").Vec3;
|
const Vec3 = @import("vec3.zig").Vec3;
|
||||||
|
@ -9,11 +10,23 @@ fn degreesToRadians(degrees: f32) f32 {
|
||||||
return degrees * math.pi / 180.0;
|
return degrees * math.pi / 180.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn random_in_unit_disk(rng: *Random) Vec3 {
|
||||||
|
while (true) {
|
||||||
|
const p = Vec3{ .x = rng.float(f32) * 2 - 1, .y = rng.float(f32) * 2 - 1, .z = 0 };
|
||||||
|
if (p.length_squared() >= 1) continue;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub const Camera = struct {
|
pub const Camera = struct {
|
||||||
origin: Point3,
|
origin: Point3,
|
||||||
lowerLeftCorner: Point3,
|
lowerLeftCorner: Point3,
|
||||||
horizontal: Vec3,
|
horizontal: Vec3,
|
||||||
vertical: Vec3,
|
vertical: Vec3,
|
||||||
|
u: Vec3,
|
||||||
|
v: Vec3,
|
||||||
|
w: Vec3,
|
||||||
|
lensRadius: f32,
|
||||||
|
|
||||||
pub fn init(
|
pub fn init(
|
||||||
lookFrom: Point3,
|
lookFrom: Point3,
|
||||||
|
@ -21,6 +34,8 @@ pub const Camera = struct {
|
||||||
vup: Vec3,
|
vup: Vec3,
|
||||||
vfov: f32,
|
vfov: f32,
|
||||||
aspectRatio: f32,
|
aspectRatio: f32,
|
||||||
|
aperture: f32,
|
||||||
|
focusDist: f32,
|
||||||
) Camera {
|
) Camera {
|
||||||
const theta = degreesToRadians(vfov);
|
const theta = degreesToRadians(vfov);
|
||||||
const h = math.tan(theta / 2);
|
const h = math.tan(theta / 2);
|
||||||
|
@ -33,22 +48,29 @@ pub const Camera = struct {
|
||||||
const v = w.cross(u);
|
const v = w.cross(u);
|
||||||
|
|
||||||
const origin = lookFrom;
|
const origin = lookFrom;
|
||||||
const horizontal = u.mul_s(viewportWidth);
|
const horizontal = u.mul_s(viewportWidth).mul_s(focusDist);
|
||||||
const vertical = v.mul_s(viewportHeight);
|
const vertical = v.mul_s(viewportHeight).mul_s(focusDist);
|
||||||
const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(w);
|
const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(w.mul_s(focusDist));
|
||||||
|
|
||||||
return Camera {
|
return Camera {
|
||||||
.origin = origin,
|
.origin = origin,
|
||||||
.horizontal = horizontal,
|
.horizontal = horizontal,
|
||||||
.vertical = vertical,
|
.vertical = vertical,
|
||||||
.lowerLeftCorner = lowerLeftCorner,
|
.lowerLeftCorner = lowerLeftCorner,
|
||||||
|
.u = u,
|
||||||
|
.v = v,
|
||||||
|
.w = w,
|
||||||
|
.lensRadius = aperture / 2,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getRay(self: Camera, s: f32, t: f32) Ray {
|
pub fn getRay(self: Camera, s: f32, t: f32, rng: *Random) Ray {
|
||||||
|
const rd = random_in_unit_disk(rng).mul_s(self.lensRadius);
|
||||||
|
const offset = self.u.mul_s(rd.x).add(self.v.mul_s(rd.y));
|
||||||
|
|
||||||
return Ray{
|
return Ray{
|
||||||
.origin = self.origin,
|
.origin = self.origin.add(offset),
|
||||||
.direction = self.lowerLeftCorner.add(self.horizontal.mul_s(s)).add(self.vertical.mul_s(t)).sub(self.origin),
|
.direction = self.lowerLeftCorner.add(self.horizontal.mul_s(s)).add(self.vertical.mul_s(t)).sub(self.origin).sub(offset),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
};
|
};
|
|
@ -123,12 +123,19 @@ pub fn main() anyerror!void {
|
||||||
const world = World{ .spheres = spheres[0..spheres.len] };
|
const world = World{ .spheres = spheres[0..spheres.len] };
|
||||||
|
|
||||||
// Camera
|
// Camera
|
||||||
|
const lookFrom = Point3{ .x = 3, .y = 3, .z = 2 };
|
||||||
|
const lookAt = Point3{ .x = 0, .y = 0, .z = -1 };
|
||||||
|
const vup = Vec3{ .x = 0, .y = 1, .z = 0 };
|
||||||
|
const distToFocus = lookFrom.sub(lookAt).length();
|
||||||
|
const aperture = 2.0;
|
||||||
const camera = Camera.init(
|
const camera = Camera.init(
|
||||||
Point3{ .x = -2, .y = 2, .z = 1 },
|
lookFrom,
|
||||||
Point3{ .x = 0, .y = 0, .z = -1 },
|
lookAt,
|
||||||
Vec3{ .x = 0, .y = 1, .z = 0 },
|
vup,
|
||||||
20.0,
|
20.0,
|
||||||
aspectRatio
|
aspectRatio,
|
||||||
|
aperture,
|
||||||
|
distToFocus
|
||||||
);
|
);
|
||||||
|
|
||||||
const window = sdl.c.SDL_CreateWindow(
|
const window = sdl.c.SDL_CreateWindow(
|
||||||
|
@ -186,7 +193,7 @@ pub fn main() anyerror!void {
|
||||||
|
|
||||||
const u = (@intToFloat(f32, i) + prng.random.float(f32)) / @intToFloat(f32, (imageWidth - 1));
|
const u = (@intToFloat(f32, i) + prng.random.float(f32)) / @intToFloat(f32, (imageWidth - 1));
|
||||||
const v = (@intToFloat(f32, j) + prng.random.float(f32)) / @intToFloat(f32, (imageHeight - 1));
|
const v = (@intToFloat(f32, j) + prng.random.float(f32)) / @intToFloat(f32, (imageHeight - 1));
|
||||||
const r = camera.getRay(u, v);
|
const r = camera.getRay(u, v, &prng.random);
|
||||||
const sample = rayColor(r, world, &prng.random, maxDepth);
|
const sample = rayColor(r, world, &prng.random, maxDepth);
|
||||||
pixelColor.* = pixelColor.*.add(sample);
|
pixelColor.* = pixelColor.*.add(sample);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue