setup random world

master
Fabien Freling 2021-05-28 19:51:05 +02:00
parent 3b3cb72dc0
commit ac56eed3a2
2 changed files with 114 additions and 38 deletions

View File

@ -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{};

View File

@ -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;