add defocus blur
This commit is contained in:
		
							parent
							
								
									d6ba8e354c
								
							
						
					
					
						commit
						2ab82d4c92
					
				
					 2 changed files with 40 additions and 11 deletions
				
			
		| 
						 | 
				
			
			@ -1,5 +1,6 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const math = std.math;
 | 
			
		||||
const Random = std.rand.Random;
 | 
			
		||||
 | 
			
		||||
const Point3 = @import("vec3.zig").Point3;
 | 
			
		||||
const Vec3 = @import("vec3.zig").Vec3;
 | 
			
		||||
| 
						 | 
				
			
			@ -9,11 +10,23 @@ fn degreesToRadians(degrees: f32) f32 {
 | 
			
		|||
    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 {
 | 
			
		||||
    origin: Point3,
 | 
			
		||||
    lowerLeftCorner: Point3,
 | 
			
		||||
    horizontal: Vec3,
 | 
			
		||||
    vertical: Vec3,
 | 
			
		||||
    u: Vec3,
 | 
			
		||||
    v: Vec3,
 | 
			
		||||
    w: Vec3,
 | 
			
		||||
    lensRadius: f32,
 | 
			
		||||
 | 
			
		||||
    pub fn init(
 | 
			
		||||
        lookFrom: Point3,
 | 
			
		||||
| 
						 | 
				
			
			@ -21,6 +34,8 @@ pub const Camera = struct {
 | 
			
		|||
        vup: Vec3,
 | 
			
		||||
        vfov: f32,
 | 
			
		||||
        aspectRatio: f32,
 | 
			
		||||
        aperture: f32,
 | 
			
		||||
        focusDist: f32,
 | 
			
		||||
    ) Camera {
 | 
			
		||||
        const theta = degreesToRadians(vfov);
 | 
			
		||||
        const h = math.tan(theta / 2);
 | 
			
		||||
| 
						 | 
				
			
			@ -33,22 +48,29 @@ pub const Camera = struct {
 | 
			
		|||
        const v = w.cross(u);
 | 
			
		||||
 | 
			
		||||
        const origin = lookFrom;
 | 
			
		||||
        const horizontal = u.mul_s(viewportWidth);
 | 
			
		||||
        const vertical = v.mul_s(viewportHeight);
 | 
			
		||||
        const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(w);
 | 
			
		||||
        const horizontal = u.mul_s(viewportWidth).mul_s(focusDist);
 | 
			
		||||
        const vertical = v.mul_s(viewportHeight).mul_s(focusDist);
 | 
			
		||||
        const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(w.mul_s(focusDist));
 | 
			
		||||
 | 
			
		||||
        return Camera {
 | 
			
		||||
            .origin = origin,
 | 
			
		||||
            .horizontal = horizontal,
 | 
			
		||||
            .vertical = vertical,
 | 
			
		||||
            .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{
 | 
			
		||||
            .origin = self.origin,
 | 
			
		||||
            .direction = self.lowerLeftCorner.add(self.horizontal.mul_s(s)).add(self.vertical.mul_s(t)).sub(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).sub(offset),
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -123,12 +123,19 @@ pub fn main() anyerror!void {
 | 
			
		|||
    const world = World{ .spheres = spheres[0..spheres.len] };
 | 
			
		||||
 | 
			
		||||
    // 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(
 | 
			
		||||
        Point3{ .x = -2, .y = 2, .z = 1 },
 | 
			
		||||
        Point3{ .x = 0, .y = 0, .z = -1 },
 | 
			
		||||
        Vec3{ .x = 0, .y = 1, .z = 0 },
 | 
			
		||||
        lookFrom,
 | 
			
		||||
        lookAt,
 | 
			
		||||
        vup,
 | 
			
		||||
        20.0,
 | 
			
		||||
        aspectRatio
 | 
			
		||||
        aspectRatio,
 | 
			
		||||
        aperture,
 | 
			
		||||
        distToFocus
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    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 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);
 | 
			
		||||
                    pixelColor.* = pixelColor.*.add(sample);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue