setup random world
This commit is contained in:
		
							parent
							
								
									3b3cb72dc0
								
							
						
					
					
						commit
						ac56eed3a2
					
				
					 2 changed files with 114 additions and 38 deletions
				
			
		| 
						 | 
				
			
			@ -76,6 +76,94 @@ fn setProgress(surface: *sdl.c.SDL_Surface, width: usize, height: usize, percent
 | 
			
		|||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn setupWorld(world: *World, rng: *Random) !void {
 | 
			
		||||
    try world.spheres.append(Sphere{
 | 
			
		||||
        .center = Point3{ .x = 0, .y = -1000, .z = 0 },
 | 
			
		||||
        .radius = 1000,
 | 
			
		||||
        .material = Material{ .lambertian = material.Lambertian{
 | 
			
		||||
            .color = Color{ .x = 0.5, .y = 0.5, .z = 0.5 }
 | 
			
		||||
        }}
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    var a: f32 = -11;
 | 
			
		||||
    while (a < 11) : (a += 1) {
 | 
			
		||||
        var b: f32 = -11;
 | 
			
		||||
        while (b < 11) : (b += 1) {
 | 
			
		||||
            const chooseMat = rng.float(f32);
 | 
			
		||||
            const center = Point3{
 | 
			
		||||
                .x = a + 0.9 * rng.float(f32),
 | 
			
		||||
                .y = 0.2,
 | 
			
		||||
                .z = b + 0.9 * rng.float(f32),
 | 
			
		||||
            };
 | 
			
		||||
 | 
			
		||||
            if (center.sub(Point3{ .x = 4, .y = 0.2 }).length() > 0.9) {
 | 
			
		||||
                if (chooseMat < 0.8) {
 | 
			
		||||
                    // diffuse
 | 
			
		||||
                    try world.spheres.append(Sphere{
 | 
			
		||||
                        .center = center,
 | 
			
		||||
                        .radius = 0.2,
 | 
			
		||||
                        .material = Material{ .lambertian = material.Lambertian{
 | 
			
		||||
                            .color = Color{
 | 
			
		||||
                                .x = rng.float(f32) * rng.float(f32),
 | 
			
		||||
                                .y = rng.float(f32) * rng.float(f32),
 | 
			
		||||
                                .z = rng.float(f32) * rng.float(f32),
 | 
			
		||||
                            }
 | 
			
		||||
                        }},
 | 
			
		||||
                    });
 | 
			
		||||
                } else if (chooseMat < 0.95) {
 | 
			
		||||
                    // metal
 | 
			
		||||
                    try world.spheres.append(Sphere{
 | 
			
		||||
                        .center = center,
 | 
			
		||||
                        .radius = 0.2,
 | 
			
		||||
                        .material = Material{ .metal = material.Metal{
 | 
			
		||||
                            .color = Color{
 | 
			
		||||
                                .x = 0.5 + rng.float(f32) / 2,
 | 
			
		||||
                                .y = 0.5 + rng.float(f32) / 2,
 | 
			
		||||
                                .z = 0.5 + rng.float(f32) / 2,
 | 
			
		||||
                            },
 | 
			
		||||
                            .fuzz = rng.float(f32) / 2,
 | 
			
		||||
                        }},
 | 
			
		||||
                    });
 | 
			
		||||
                } else {
 | 
			
		||||
                    // glass
 | 
			
		||||
                    try world.spheres.append(Sphere{
 | 
			
		||||
                        .center = center,
 | 
			
		||||
                        .radius = 0.2,
 | 
			
		||||
                        .material = Material{ .dielectric = material.Dielectric{
 | 
			
		||||
                            .refraction_index = 1.5,
 | 
			
		||||
                        }},
 | 
			
		||||
                    });
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    try world.spheres.append(Sphere{
 | 
			
		||||
        .center = Point3{ .x = 0, .y = 1, .z = 0 },
 | 
			
		||||
        .radius = 1,
 | 
			
		||||
        .material = Material{ .dielectric = material.Dielectric{
 | 
			
		||||
            .refraction_index = 1.5
 | 
			
		||||
        }},
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    try world.spheres.append(Sphere{
 | 
			
		||||
        .center = Point3{ .x = -4, .y = 1, .z = 0 },
 | 
			
		||||
        .radius = 1,
 | 
			
		||||
        .material = Material{ .lambertian = material.Lambertian{
 | 
			
		||||
            .color = Color{ .x = 0.4, .y = 0.2, .z = 0.1 }
 | 
			
		||||
        }},
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    try world.spheres.append(Sphere{
 | 
			
		||||
        .center = Point3{ .x = 4, .y = 1, .z = 0 },
 | 
			
		||||
        .radius = 1,
 | 
			
		||||
        .material = Material{ .metal = material.Metal{
 | 
			
		||||
            .color = Color{ .x = 0.7, .y = 0.6, .z = 0.5 },
 | 
			
		||||
            .fuzz = 0.0
 | 
			
		||||
        }},
 | 
			
		||||
    });
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn main() anyerror!void {
 | 
			
		||||
    if (sdl.c.SDL_Init(sdl.c.SDL_INIT_VIDEO) != 0) {
 | 
			
		||||
        std.log.err("Unable to initialize SDL: {}", .{sdl.c.SDL_GetError()});
 | 
			
		||||
| 
						 | 
				
			
			@ -83,6 +171,9 @@ pub fn main() anyerror!void {
 | 
			
		|||
    }
 | 
			
		||||
    defer sdl.c.SDL_Quit();
 | 
			
		||||
 | 
			
		||||
    var prng = std.rand.DefaultPrng.init(42);
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    // Image
 | 
			
		||||
    const aspectRatio: f32 = 16.0 / 9.0;
 | 
			
		||||
    const imageWidth = 600;
 | 
			
		||||
| 
						 | 
				
			
			@ -91,43 +182,16 @@ pub fn main() anyerror!void {
 | 
			
		|||
    const maxDepth = 50;
 | 
			
		||||
 | 
			
		||||
    // World
 | 
			
		||||
    const materialGround = Material{
 | 
			
		||||
        .lambertian = material.Lambertian{
 | 
			
		||||
            .color = Color{ .x = 0.8, .y = 0.8, .z = 0.0 },
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    const materialCenter = Material{
 | 
			
		||||
        .lambertian = material.Lambertian{
 | 
			
		||||
            .color = Color{ .x = 0.1, .y = 0.2, .z = 0.5 },
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    const materialLeft = Material{
 | 
			
		||||
        .dielectric = material.Dielectric{
 | 
			
		||||
            .refraction_index = 1.5,
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
    const materialRight = Material{
 | 
			
		||||
        .metal = material.Metal{
 | 
			
		||||
            .color = Color{ .x = 0.8, .y = 0.6, .z = 0.2 },
 | 
			
		||||
            .fuzz = 1.0,
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const spheres = [_]Sphere{
 | 
			
		||||
        Sphere{ .center = Point3{ .x = 0, .y = -100.5, .z = -1 }, .radius = 100, .material = materialGround },
 | 
			
		||||
        Sphere{ .center = Point3{ .x = 0, .y = 0, .z = -1 }, .radius = 0.5, .material = materialCenter },
 | 
			
		||||
        Sphere{ .center = Point3{ .x = -1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialLeft },
 | 
			
		||||
        Sphere{ .center = Point3{ .x = -1, .y = 0, .z = -1 }, .radius = -0.45, .material = materialLeft },
 | 
			
		||||
        Sphere{ .center = Point3{ .x = 1, .y = 0, .z = -1 }, .radius = 0.5, .material = materialRight },
 | 
			
		||||
     };
 | 
			
		||||
    const world = World{ .spheres = spheres[0..spheres.len] };
 | 
			
		||||
    var world = World.init();
 | 
			
		||||
    defer world.deinit();
 | 
			
		||||
    try setupWorld(&world, &prng.random);
 | 
			
		||||
 | 
			
		||||
    // Camera
 | 
			
		||||
    const lookFrom = Point3{ .x = 3, .y = 3, .z = 2 };
 | 
			
		||||
    const lookAt = Point3{ .x = 0, .y = 0, .z = -1 };
 | 
			
		||||
    const lookFrom = Point3{ .x = 13, .y = 2, .z = 3 };
 | 
			
		||||
    const lookAt = Point3{ .x = 0, .y = 0, .z = 0 };
 | 
			
		||||
    const vup = Vec3{ .x = 0, .y = 1, .z = 0 };
 | 
			
		||||
    const distToFocus = lookFrom.sub(lookAt).length();
 | 
			
		||||
    const aperture = 2.0;
 | 
			
		||||
    const distToFocus = 10;
 | 
			
		||||
    const aperture = 0.1;
 | 
			
		||||
    const camera = Camera.init(
 | 
			
		||||
        lookFrom,
 | 
			
		||||
        lookAt,
 | 
			
		||||
| 
						 | 
				
			
			@ -155,7 +219,6 @@ pub fn main() anyerror!void {
 | 
			
		|||
        return error.SDLInitializationFailed;
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    var prng = std.rand.DefaultPrng.init(42);
 | 
			
		||||
    var pixelAccu: [imageWidth * imageHeight]Color = undefined;
 | 
			
		||||
    for (pixelAccu) |*pixel| {
 | 
			
		||||
        pixel.* = Color{};
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,15 +1,28 @@
 | 
			
		|||
const std = @import("std");
 | 
			
		||||
const ArrayList = std.ArrayList;
 | 
			
		||||
 | 
			
		||||
const Sphere = @import("sphere.zig").Sphere;
 | 
			
		||||
const HitRecord = @import("hittable.zig").HitRecord;
 | 
			
		||||
const Ray = @import("ray.zig").Ray;
 | 
			
		||||
 | 
			
		||||
pub const World = struct {
 | 
			
		||||
    spheres: []const Sphere,
 | 
			
		||||
    spheres: ArrayList(Sphere),
 | 
			
		||||
 | 
			
		||||
    pub fn hit(self: World, ray: Ray, t_min: f32, t_max: f32) ?HitRecord {
 | 
			
		||||
    pub fn init() World {
 | 
			
		||||
        return World {
 | 
			
		||||
            .spheres = ArrayList(Sphere).init(std.testing.allocator)
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn deinit(self: *World) void {
 | 
			
		||||
        self.spheres.deinit();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn hit(self: *const World, ray: Ray, t_min: f32, t_max: f32) ?HitRecord {
 | 
			
		||||
        var hitRecord: ?HitRecord = null;
 | 
			
		||||
        var closest = t_max;
 | 
			
		||||
 | 
			
		||||
        for (self.spheres) |sphere| {
 | 
			
		||||
        for (self.spheres.items) |sphere| {
 | 
			
		||||
            if (sphere.hit(ray, t_min, closest)) |localHit| {
 | 
			
		||||
                closest = localHit.t;
 | 
			
		||||
                hitRecord = localHit;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue