@@ 1,3 1,5 @@
+use math;
+
export type camera = struct {
origin: vector,
plane_origin: vector,
@@ 5,6 7,28 @@ export type camera = struct {
vertical: vector,
};
+export fn make_camera(
+ from: vector,
+ to: vector,
+ vup: vector,
+ vfov: f64,
+ ar: f64
+) camera = {
+ let height = 2.0 * math::tanf64(vfov * math::PI / 360.0);
+ let width = ar * height;
+
+ let w = unit(diff(from, to)), u = unit(cross(vup, w)), v = cross(w, u);
+
+ let c = camera {
+ origin = from,
+ horizontal = scale(u, width),
+ vertical = scale(v, height),
+ ...
+ };
+ c.plane_origin = neg(sum(scale(sum(c.horizontal, c.vertical), 0.5), w));
+ return c;
+};
+
export fn get_ray_for(c: *const camera, u: f64, v: f64) ray = ray {
origin = c.origin,
direction = sum(
@@ 5,8 5,8 @@ use time;
fn init_scene() *hittable = {
let ground = alloc(make_lambertian(&C(0.8, 0.8, 0.0)));
- let center = alloc(make_dielectric(1.5));
- let left = alloc(make_dielectric(1.2));
+ let center = alloc(make_lambertian(&C(0.1, 0.2, 0.5)));
+ let left = alloc(make_dielectric(1.5));
let right = alloc(make_metal(&C(0.8, 0.6, 0.2), 1.0));
let a = alloc(multi([]));
append(a.arr, [
@@ 14,6 14,7 @@ fn init_scene() *hittable = {
alloc(make_sphere(V(0.0, 0.0, -1.0), 0.5, center)),
alloc(make_sphere(V(1.0, -0.7, -1.0), 0.3, center)),
alloc(make_sphere(V(-1.0, 0.0, -1.0), 0.5, left)),
+ alloc(make_sphere(V(-1.0, 0.0, -1.0), -0.45, left)),
alloc(make_sphere(V(1.0, 0.0, -1.0), 0.5, right)),
]...);
return a;
@@ 48,16 49,8 @@ export fn main() void = {
let samples = 50u32;
let max_bounce = 50u;
- let focus = V(0.0, 0.0, 1.0);
- let horizontal = V(4.0, 0.0, 0.0);
- let vertical = V(0.0, 3.0, 0.0);
- let corner = diff(scale(sum(horizontal, vertical), -0.5), focus);
- let c = camera {
- origin = V(0.0, 0.0, 0.0),
- plane_origin = corner,
- horizontal = horizontal,
- vertical = vertical,
- };
+ let c = make_camera(V(-2.0, -2.0, 1.0), V(0.0, 0.0, -1.0), V(0.0, 1.0, 0.0),
+ 20.0, 4.0/3.0);
let scene = init_scene();