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