add multiple samples per pixel
This commit is contained in:
		
							parent
							
								
									79772c0df4
								
							
						
					
					
						commit
						b0ce3eecec
					
				
					 5 changed files with 76 additions and 19 deletions
				
			
		
							
								
								
									
										36
									
								
								in_one_weekend/src/camera.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								in_one_weekend/src/camera.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,36 @@
 | 
			
		|||
const Point3 = @import("vec3.zig").Point3;
 | 
			
		||||
const Vec3 = @import("vec3.zig").Vec3;
 | 
			
		||||
const Ray = @import("ray.zig").Ray;
 | 
			
		||||
 | 
			
		||||
pub const Camera = struct {
 | 
			
		||||
    origin: Point3,
 | 
			
		||||
    lowerLeftCorner: Point3,
 | 
			
		||||
    horizontal: Vec3,
 | 
			
		||||
    vertical: Vec3,
 | 
			
		||||
 | 
			
		||||
    pub fn init() Camera {
 | 
			
		||||
        const aspectRatio = 16.0 / 9.0;
 | 
			
		||||
        const viewportHeight = 2.0;
 | 
			
		||||
        const viewportWidth = aspectRatio * viewportHeight;
 | 
			
		||||
        const focalLength = 1.0;
 | 
			
		||||
 | 
			
		||||
        const origin = Vec3{};
 | 
			
		||||
        const horizontal = Vec3{ .x = viewportWidth };
 | 
			
		||||
        const vertical = Vec3{ .y = viewportHeight };
 | 
			
		||||
        const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(Vec3{ .z = focalLength });
 | 
			
		||||
 | 
			
		||||
        return Camera {
 | 
			
		||||
            .origin = origin,
 | 
			
		||||
            .horizontal = horizontal,
 | 
			
		||||
            .vertical = vertical,
 | 
			
		||||
            .lowerLeftCorner = lowerLeftCorner,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn getRay(self: Camera, u: f32, v: f32) Ray {
 | 
			
		||||
        return Ray{
 | 
			
		||||
            .origin = self.origin,
 | 
			
		||||
            .direction = self.lowerLeftCorner.add(self.horizontal.mul(u)).add(self.vertical.mul(v)).sub(self.origin),
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										17
									
								
								in_one_weekend/src/color.zig
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								in_one_weekend/src/color.zig
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,17 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const math = std.math;
 | 
			
		||||
const Vec3 = @import("vec3.zig").Vec3;
 | 
			
		||||
 | 
			
		||||
pub const Color = Vec3;
 | 
			
		||||
 | 
			
		||||
pub fn averageColor(pixelColor: Color, samplesPerPixel: i32) Color {
 | 
			
		||||
    // Divide the color by the number of samples.
 | 
			
		||||
    // const scale = 1.0 / @intToFloat(f32, samplesPerPixel);
 | 
			
		||||
    var scaledColor = pixelColor.div(@intToFloat(f32, samplesPerPixel));
 | 
			
		||||
 | 
			
		||||
    return Color{
 | 
			
		||||
        .x = math.clamp(scaledColor.x, 0, 0.999),
 | 
			
		||||
        .y = math.clamp(scaledColor.y, 0, 0.999),
 | 
			
		||||
        .z = math.clamp(scaledColor.z, 0, 0.999),
 | 
			
		||||
    };
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -3,11 +3,13 @@ const print = std.debug.print;
 | 
			
		|||
const sdl = @import("sdl.zig");
 | 
			
		||||
const vec3 = @import("vec3.zig");
 | 
			
		||||
const Vec3 = vec3.Vec3;
 | 
			
		||||
const Color = vec3.Color;
 | 
			
		||||
const Point3 = vec3.Point3;
 | 
			
		||||
const color = @import("color.zig");
 | 
			
		||||
const Color = color.Color;
 | 
			
		||||
const Ray = @import("ray.zig").Ray;
 | 
			
		||||
const Sphere = @import("sphere.zig").Sphere;
 | 
			
		||||
const World = @import("world.zig").World;
 | 
			
		||||
const Camera = @import("camera.zig").Camera;
 | 
			
		||||
 | 
			
		||||
// From: https://github.com/Nelarius/weekend-raytracer-zig/blob/master/src/main.zig
 | 
			
		||||
// See https://github.com/zig-lang/zig/issues/565
 | 
			
		||||
| 
						 | 
				
			
			@ -53,6 +55,7 @@ pub fn main() anyerror!void {
 | 
			
		|||
    const aspectRatio: f32 = 16.0 / 9.0;
 | 
			
		||||
    const imageWidth = 600;
 | 
			
		||||
    const imageHeight = @floatToInt(usize, imageWidth / aspectRatio);
 | 
			
		||||
    const samplesPerPixel = 100;
 | 
			
		||||
 | 
			
		||||
    // World
 | 
			
		||||
    const spheres = [_]Sphere{
 | 
			
		||||
| 
						 | 
				
			
			@ -62,14 +65,7 @@ pub fn main() anyerror!void {
 | 
			
		|||
    const world = World{ .spheres = spheres[0..spheres.len] };
 | 
			
		||||
 | 
			
		||||
    // Camera
 | 
			
		||||
    const viewportHeight = 2.0;
 | 
			
		||||
    const viewportWidth = viewportHeight * aspectRatio;
 | 
			
		||||
    const focalLength = 1.0;
 | 
			
		||||
 | 
			
		||||
    const origin = Vec3{};
 | 
			
		||||
    const horizontal = Vec3{ .x = viewportWidth };
 | 
			
		||||
    const vertical = Vec3{ .y = viewportHeight };
 | 
			
		||||
    const lowerLeftCorner = origin.sub(horizontal.div(2)).sub(vertical.div(2)).sub(Vec3{ .z = focalLength });
 | 
			
		||||
    const camera = Camera.init();
 | 
			
		||||
 | 
			
		||||
    const window = sdl.c.SDL_CreateWindow(
 | 
			
		||||
        "Raytracing in One Weekend",
 | 
			
		||||
| 
						 | 
				
			
			@ -88,6 +84,8 @@ pub fn main() anyerror!void {
 | 
			
		|||
        return error.SDLInitializationFailed;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var prng = std.rand.DefaultPrng.init(42);
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        _ = sdl.c.SDL_LockSurface(surface);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -95,15 +93,22 @@ pub fn main() anyerror!void {
 | 
			
		|||
        while (j < imageHeight) {
 | 
			
		||||
            var i: usize = 0;
 | 
			
		||||
            while (i < imageWidth) {
 | 
			
		||||
                const u = @intToFloat(f32, i) / @intToFloat(f32, (imageWidth - 1));
 | 
			
		||||
                var pixelColor = Color{};
 | 
			
		||||
                var k: usize = 0;
 | 
			
		||||
                while (k < samplesPerPixel) {
 | 
			
		||||
                    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 sample = rayColor(r, world);
 | 
			
		||||
                    pixelColor = pixelColor.add(sample);
 | 
			
		||||
 | 
			
		||||
                    k += 1;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                const averageColor = color.averageColor(pixelColor, samplesPerPixel);
 | 
			
		||||
                // SDL coordinate system is flipped compared to the raytracer
 | 
			
		||||
                const v = @intToFloat(f32, (imageHeight - 1) - j) / @intToFloat(f32, (imageHeight - 1));
 | 
			
		||||
                const r = Ray{
 | 
			
		||||
                    .origin = origin,
 | 
			
		||||
                    .direction = lowerLeftCorner.add(horizontal.mul(u)).add(vertical.mul(v)).sub(origin),
 | 
			
		||||
                };
 | 
			
		||||
                const pixelColor = rayColor(r, world);
 | 
			
		||||
                sdl.setSurfacePixel(surface, i, j, pixelColor);
 | 
			
		||||
                sdl.setSurfacePixel(surface, i, imageHeight - 1 - j, averageColor);
 | 
			
		||||
 | 
			
		||||
                i += 1;
 | 
			
		||||
            }
 | 
			
		||||
            j += 1;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
pub const c = @cImport({ @cInclude("SDL2/SDL.h"); });
 | 
			
		||||
const Color = @import("vec3.zig").Color;
 | 
			
		||||
const Color = @import("color.zig").Color;
 | 
			
		||||
 | 
			
		||||
pub fn setSurfacePixel(surface: *c.SDL_Surface, i: usize, j: usize, color: Color) void {
 | 
			
		||||
    const bytePerPixel = 4;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -67,7 +67,6 @@ pub fn unitVector(vec: Vec3) Vec3 {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
pub const Point3 = Vec3;
 | 
			
		||||
pub const Color = Vec3;
 | 
			
		||||
 | 
			
		||||
const assert = @import("std").debug.assert;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue