tangled
alpha
login
or
join now
altagos.dev
/
rayray
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
antialiasing
altagos.dev
2 years ago
20f06e4a
6e9d1221
+60
-20
5 changed files
expand all
collapse all
unified
split
src
camera.zig
interval.zig
main.zig
rayray.zig
renderer.zig
+20
src/camera.zig
···
1
1
const std = @import("std");
2
2
+
const random = std.crypto.random;
2
3
3
4
const zigimg = @import("zigimg");
4
5
const color = zigimg.color;
5
6
const zm = @import("zmath");
7
7
+
8
8
+
pub const Ray = @import("ray.zig");
6
9
7
10
const log = std.log.scoped(.camera);
8
11
···
11
14
pub const Options = struct {
12
15
image_width: usize,
13
16
aspect_ratio: f32,
17
17
+
samples_per_pixel: usize,
14
18
};
15
19
16
20
image_height: usize,
17
21
image_width: usize,
18
22
aspect_ratio: f32,
23
23
+
samples_per_pixel: usize,
19
24
20
25
focal_lenght: f32,
21
26
viewport_height: f32,
···
61
66
.image_width = image_width,
62
67
.image_height = image_height,
63
68
.aspect_ratio = aspect_ratio,
69
69
+
.samples_per_pixel = opts.samples_per_pixel,
64
70
65
71
.focal_lenght = focal_lenght,
66
72
.viewport_height = viewport_height,
···
83
89
self.image.deinit();
84
90
}
85
91
92
92
+
pub fn getRay(self: *Camera, i: usize, j: usize) Ray {
93
93
+
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);
94
94
+
const pixel_sample = pixel_center + self.pixelSamplesSq();
95
95
+
96
96
+
const ray_direction = pixel_sample - self.camera_center;
97
97
+
return Ray.init(self.camera_center, ray_direction);
98
98
+
}
99
99
+
86
100
pub fn setPixel(self: *Camera, x: usize, y: usize, c: color.Rgba32) !void {
87
101
if (x >= self.image_width or y >= self.image_height) return error.OutOfBounds;
88
102
const i = x + self.image_width * y;
89
103
self.image.pixels.rgba32[i] = c;
90
104
}
105
105
+
106
106
+
fn pixelSamplesSq(self: *Camera) zm.Vec {
107
107
+
const px = zm.f32x4s(-0.5 + random.float(f32));
108
108
+
const py = zm.f32x4s(-0.5 + random.float(f32));
109
109
+
return (px * self.pixel_delta_u) + (py * self.pixel_delta_v);
110
110
+
}
+12
src/interval.zig
···
81
81
return self.min < x and x < self.max;
82
82
}
83
83
84
84
+
pub fn clamp(self: *const Self, x: T) T {
85
85
+
if (x < self.min) return self.min;
86
86
+
if (x > self.max) return self.max;
87
87
+
return x;
88
88
+
}
89
89
+
84
90
pub fn iter(self: *const Self) Iterator {
85
91
return Iterator{
86
92
.interval = self.*,
···
108
114
109
115
pub fn surrounds(self: *const Self, x: T) bool {
110
116
return self.min < x and x < self.max;
117
117
+
}
118
118
+
119
119
+
pub fn clamp(self: *const Self, x: T) T {
120
120
+
if (x < self.min) return self.min;
121
121
+
if (x > self.max) return self.max;
122
122
+
return x;
111
123
}
112
124
};
113
125
} else {
+1
-1
src/main.zig
···
33
33
const s = spall.trace(@src(), "Raytracer", .{});
34
34
35
35
// Raytracing part
36
36
-
var raytracer = try rayray.Raytracer.init(allocator, world, .{ .aspect_ratio = 16.0 / 9.0, .image_width = 400 });
36
36
+
var raytracer = try rayray.Raytracer.init(allocator, world, .{ .aspect_ratio = 16.0 / 9.0, .image_width = 400, .samples_per_pixel = 100 });
37
37
defer raytracer.deinit();
38
38
39
39
const img = try raytracer.render();
+8
-9
src/rayray.zig
···
64
64
threads[row].thread = t;
65
65
}
66
66
67
67
-
// const stderr = std.io.getStdErr();
68
68
-
// // defer stderr.close();
67
67
+
const stderr = std.io.getStdErr();
69
68
70
70
-
// var progress = std.Progress{
71
71
-
// .terminal = stderr,
72
72
-
// .supports_ansi_escape_codes = true,
73
73
-
// };
74
74
-
// var node = progress.start("Rendering Completed", num_threads);
75
75
-
// node.activate();
69
69
+
var progress = std.Progress{
70
70
+
.terminal = stderr,
71
71
+
.supports_ansi_escape_codes = true,
72
72
+
};
73
73
+
var node = progress.start("Rendering Completed", num_threads);
74
74
+
node.activate();
76
75
77
76
while (true) {
78
77
var done = true;
···
93
92
if (done) break;
94
93
}
95
94
96
96
-
// node.end();
95
95
+
node.end();
97
96
98
97
return self.camera.image;
99
98
}
+19
-10
src/renderer.zig
···
36
36
37
37
var width_iter = width.iter();
38
38
while (width_iter.nextExc()) |i| {
39
39
-
const pixel_center = ctx.cam.pixel00_loc + (zm.f32x4s(@as(f32, @floatFromInt(i))) * ctx.cam.pixel_delta_u) + (zm.f32x4s(@as(f32, @floatFromInt(j))) * ctx.cam.pixel_delta_v);
40
40
-
const ray_direction = pixel_center - ctx.cam.camera_center;
41
41
-
var ray = Ray.init(ctx.cam.camera_center, ray_direction);
42
42
-
const col = vecToRgba(rayColor(&ray, ctx.world));
39
39
+
var col = zm.f32x4(0.0, 0.0, 0.0, 1.0);
40
40
+
for (0..ctx.cam.samples_per_pixel) |_| {
41
41
+
var ray = ctx.cam.getRay(i, j);
42
42
+
col += rayColor(&ray, ctx.world);
43
43
+
}
43
44
44
44
-
ctx.cam.setPixel(i, j, col) catch break;
45
45
+
ctx.cam.setPixel(i, j, vecToRgba(col, ctx.cam.samples_per_pixel)) catch break;
45
46
}
46
47
}
47
48
}
···
63
64
done.store(true, .Release);
64
65
}
65
66
66
66
-
fn vecToRgba(v: zm.Vec) zigimg.color.Rgba32 {
67
67
-
const r: u8 = @intFromFloat(255.999 * v[0]);
68
68
-
const g: u8 = @intFromFloat(255.999 * v[1]);
69
69
-
const b: u8 = @intFromFloat(255.999 * v[2]);
70
70
-
const a: u8 = @intFromFloat(255.999 * v[3]);
67
67
+
fn vecToRgba(v: zm.Vec, samples_per_pixel: usize) zigimg.color.Rgba32 {
68
68
+
const scale: f32 = 1.0 / @as(f32, @floatFromInt(samples_per_pixel));
69
69
+
const intensity = IntervalF32.init(0.0, 0.999);
70
70
+
71
71
+
const r_scaled = v[0] * scale;
72
72
+
const g_scaled = v[1] * scale;
73
73
+
const b_scaled = v[2] * scale;
74
74
+
const a_scaled = v[3] * scale;
75
75
+
76
76
+
const r: u8 = @intFromFloat(256 * intensity.clamp(r_scaled));
77
77
+
const g: u8 = @intFromFloat(256 * intensity.clamp(g_scaled));
78
78
+
const b: u8 = @intFromFloat(256 * intensity.clamp(b_scaled));
79
79
+
const a: u8 = @intFromFloat(256 * intensity.clamp(a_scaled));
71
80
72
81
return zigimg.color.Rgba32.initRgba(r, g, b, a);
73
82
}