tangled
alpha
login
or
join now
altagos.dev
/
rayray
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
moveable camera
altagos.dev
2 years ago
a5c4d11c
9c69e2f4
+52
-13
3 changed files
expand all
collapse all
unified
split
src
camera.zig
main.zig
util.zig
+42
-10
src/camera.zig
···
6
6
const zm = @import("zmath");
7
7
8
8
pub const Ray = @import("ray.zig");
9
9
+
const util = @import("util.zig");
9
10
10
11
const log = std.log.scoped(.camera);
11
12
···
16
17
aspect_ratio: f32,
17
18
samples_per_pixel: usize,
18
19
max_depth: usize,
20
20
+
vfov: f32 = 90,
21
21
+
look_from: zm.Vec = zm.f32x4s(0),
22
22
+
look_at: zm.Vec = zm.f32x4(0, 0, -1, 0),
23
23
+
vup: zm.Vec = zm.f32x4(0, 1, 0, 0),
19
24
};
20
25
21
26
image_height: usize,
···
25
30
samples_per_pixel: usize,
26
31
max_depth: usize,
27
32
33
33
+
vfov: f32,
34
34
+
look_from: zm.Vec,
35
35
+
look_at: zm.Vec,
36
36
+
vup: zm.Vec,
37
37
+
28
38
focal_lenght: f32,
29
39
viewport_height: f32,
30
40
viewport_width: f32,
31
31
-
camera_center: zm.Vec,
41
41
+
center: zm.Vec,
32
42
33
43
viewport_u: zm.Vec,
34
44
viewport_v: zm.Vec,
35
45
pixel_delta_u: zm.Vec,
36
46
pixel_delta_v: zm.Vec,
47
47
+
u: zm.Vec,
48
48
+
v: zm.Vec,
49
49
+
w: zm.Vec,
37
50
38
51
viewport_upper_left: zm.Vec,
39
52
pixel00_loc: zm.Vec,
···
46
59
const image_height = @as(usize, @intFromFloat(@as(f32, @floatFromInt(image_width)) / aspect_ratio));
47
60
if (image_height < 1) return error.ImageWidthLessThanOne;
48
61
49
49
-
const focal_lenght: f32 = 1.0;
50
50
-
const viewport_height: f32 = 2.0;
62
62
+
const vfov = opts.vfov;
63
63
+
const look_from = opts.look_from;
64
64
+
const look_at = opts.look_at;
65
65
+
const vup = opts.vup;
66
66
+
const center = look_from;
67
67
+
68
68
+
const focal_lenght: f32 = zm.length3(look_from - look_at)[0];
69
69
+
const theta = util.degreesToRadians(opts.vfov);
70
70
+
const h = @tan(theta / 2);
71
71
+
const viewport_height: f32 = 2 * h * focal_lenght;
51
72
const viewport_width = viewport_height * (@as(f32, @floatFromInt(image_width)) / @as(f32, @floatFromInt(image_height)));
52
52
-
const camera_center = zm.f32x4s(0.0);
73
73
+
74
74
+
const w = zm.normalize3(look_from - look_at);
75
75
+
const u = zm.normalize3(zm.cross3(vup, w));
76
76
+
const v = zm.cross3(w, u);
53
77
54
78
// Calculate the vectors across the horizontal and down the vertical viewport edges.
55
55
-
const viewport_u = zm.f32x4(viewport_width, 0, 0, 0);
56
56
-
const viewport_v = zm.f32x4(0, -viewport_height, 0, 0);
79
79
+
const viewport_u = zm.f32x4s(viewport_width) * u;
80
80
+
const viewport_v = zm.f32x4s(viewport_height) * -v;
57
81
58
82
// Calculate the horizontal and vertical delta vectors from pixel to pixel.
59
83
const pixel_delta_u = viewport_u / zm.f32x4s(@as(f32, @floatFromInt(image_width)));
60
84
const pixel_delta_v = viewport_v / zm.f32x4s(@as(f32, @floatFromInt(image_height)));
61
85
62
86
// Calculate the location of the upper left pixel.
63
63
-
const viewport_upper_left = camera_center - zm.f32x4(0, 0, focal_lenght, 0) - viewport_u / zm.f32x4s(2.0) - viewport_v / zm.f32x4s(2.0);
87
87
+
const viewport_upper_left = center - zm.f32x4s(focal_lenght) * w - viewport_u / zm.f32x4s(2.0) - viewport_v / zm.f32x4s(2.0);
64
88
const pixel00_loc = viewport_upper_left + zm.f32x4s(0.5) * (pixel_delta_u + pixel_delta_v);
65
89
66
90
log.debug("image_width: {}, image_height: {}, aspect_ratio: {d:.2}, focal_lenght: {d:.1}", .{ image_width, image_height, aspect_ratio, focal_lenght });
···
73
97
.samples_per_pixel = opts.samples_per_pixel,
74
98
.max_depth = opts.max_depth,
75
99
100
100
+
.vfov = vfov,
101
101
+
.look_from = look_from,
102
102
+
.look_at = look_at,
103
103
+
.vup = vup,
104
104
+
76
105
.focal_lenght = focal_lenght,
77
106
.viewport_height = viewport_height,
78
107
.viewport_width = viewport_width,
79
79
-
.camera_center = camera_center,
108
108
+
.center = center,
80
109
81
110
.viewport_u = viewport_u,
82
111
.viewport_v = viewport_v,
83
112
.pixel_delta_u = pixel_delta_u,
84
113
.pixel_delta_v = pixel_delta_v,
114
114
+
.u = u,
115
115
+
.v = v,
116
116
+
.w = w,
85
117
86
118
.viewport_upper_left = viewport_upper_left,
87
119
.pixel00_loc = pixel00_loc,
···
98
130
const pixel_center = self.pixel00_loc + (zm.f32x4s(@as(f32, @floatFromInt(i))) * self.pixel_delta_u) + (zm.f32x4s(@as(f32, @floatFromInt(j))) * self.pixel_delta_v);
99
131
const pixel_sample = pixel_center + self.pixelSamplesSq();
100
132
101
101
-
const ray_direction = pixel_sample - self.camera_center;
102
102
-
return Ray.init(self.camera_center, ray_direction);
133
133
+
const ray_direction = pixel_sample - self.center;
134
134
+
return Ray.init(self.center, ray_direction);
103
135
}
104
136
105
137
pub fn setPixel(self: *Camera, x: usize, y: usize, c: color.Rgba32) !void {
+4
-1
src/main.zig
···
35
35
36
36
var world = HittableList.init(allocator);
37
37
try world.add(Hittable.sphere(Sphere{ .center = zm.f32x4(0, -100.5, -1, 0), .radius = 100, .mat = &material_ground }));
38
38
-
try world.add(Hittable.sphere(Sphere{ .center = zm.f32x4(0, 0, -1, 0), .radius = 0.5, .mat = &material_center }));
38
38
+
try world.add(Hittable.sphere(Sphere{ .center = zm.f32x4(0, 0, -1.2, 0), .radius = 0.5, .mat = &material_center }));
39
39
try world.add(Hittable.sphere(Sphere{ .center = zm.f32x4(-1, 0, -1, 0), .radius = 0.5, .mat = &material_left }));
40
40
try world.add(Hittable.sphere(Sphere{ .center = zm.f32x4(-1, 0, -1, 0), .radius = 0.4, .mat = &material_bubble }));
41
41
try world.add(Hittable.sphere(Sphere{ .center = zm.f32x4(1, 0, -1, 0), .radius = 0.5, .mat = &material_right }));
···
48
48
.image_width = 400,
49
49
.samples_per_pixel = 100,
50
50
.max_depth = 50,
51
51
+
.vfov = 20,
52
52
+
.look_from = zm.f32x4(-2, 2, 1, 0),
53
53
+
.look_at = zm.f32x4(0, 0, -1, 0),
51
54
});
52
55
defer raytracer.deinit();
53
56
+6
-2
src/util.zig
···
1
1
-
const std = @import("std");
2
2
-
const random = std.crypto.random;
1
1
+
const random = @import("std").crypto.random;
2
2
+
const math = @import("std").math;
3
3
4
4
const zm = @import("zmath");
5
5
+
6
6
+
pub inline fn degreesToRadians(degrees: f32) f32 {
7
7
+
return degrees * math.pi / 180.0;
8
8
+
}
5
9
6
10
/// Returns a random real in [0,1).
7
11
pub inline fn randomF32() f32 {