tangled
alpha
login
or
join now
altagos.dev
/
rayray
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
getting started with materials
altagos.dev
2 years ago
cfd4e7b8
20f06e4a
+84
-11
5 changed files
expand all
collapse all
unified
split
src
camera.zig
main.zig
rayray.zig
renderer.zig
util.zig
+5
src/camera.zig
···
15
15
image_width: usize,
16
16
aspect_ratio: f32,
17
17
samples_per_pixel: usize,
18
18
+
max_depth: usize,
18
19
};
19
20
20
21
image_height: usize,
21
22
image_width: usize,
22
23
aspect_ratio: f32,
24
24
+
23
25
samples_per_pixel: usize,
26
26
+
max_depth: usize,
24
27
25
28
focal_lenght: f32,
26
29
viewport_height: f32,
···
66
69
.image_width = image_width,
67
70
.image_height = image_height,
68
71
.aspect_ratio = aspect_ratio,
72
72
+
69
73
.samples_per_pixel = opts.samples_per_pixel,
74
74
+
.max_depth = opts.max_depth,
70
75
71
76
.focal_lenght = focal_lenght,
72
77
.viewport_height = viewport_height,
+6
-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, .samples_per_pixel = 100 });
36
36
+
var raytracer = try rayray.Raytracer.init(allocator, world, .{
37
37
+
.aspect_ratio = 16.0 / 9.0,
38
38
+
.image_width = 400,
39
39
+
.samples_per_pixel = 100,
40
40
+
.max_depth = 50,
41
41
+
});
37
42
defer raytracer.deinit();
38
43
39
44
const img = try raytracer.render();
+1
src/rayray.zig
···
6
6
7
7
pub const Camera = @import("camera.zig");
8
8
pub const hittable = @import("hittable.zig");
9
9
+
pub const interval = @import("interval.zig");
9
10
pub const renderer = @import("renderer.zig");
10
11
11
12
const log = std.log.scoped(.rayray);
+15
-10
src/renderer.zig
···
4
4
const zigimg = @import("zigimg");
5
5
const zm = @import("zmath");
6
6
7
7
-
pub const Camera = @import("camera.zig");
8
8
-
pub const hittable = @import("hittable.zig");
9
9
-
pub const Ray = @import("ray.zig");
7
7
+
const Camera = @import("camera.zig");
8
8
+
const hittable = @import("hittable.zig");
9
9
+
const Ray = @import("ray.zig");
10
10
+
const util = @import("util.zig");
10
11
11
11
-
pub const interval = @import("interval.zig");
12
12
-
pub const IntervalUsize = interval.IntervalUsize;
13
13
-
pub const IntervalF32 = interval.IntervalF32;
12
12
+
const interval = @import("interval.zig");
13
13
+
const IntervalUsize = interval.IntervalUsize;
14
14
+
const IntervalF32 = interval.IntervalF32;
14
15
15
16
const log = std.log.scoped(.renderer);
16
17
···
19
20
world: *hittable.HittableList,
20
21
};
21
22
22
22
-
pub fn rayColor(r: *Ray, world: *hittable.HittableList) zm.Vec {
23
23
-
if (world.hit(r, IntervalF32.init(0, std.math.inf(f32)))) |rec| {
24
24
-
return zm.f32x4(0.5, 0.5, 0.5, 1.0) * (rec.normal + zm.f32x4(1, 1, 1, 1));
23
23
+
pub fn rayColor(r: *Ray, world: *hittable.HittableList, depth: usize) zm.Vec {
24
24
+
if (depth <= 0) return zm.f32x4(0, 0, 0, 1.0);
25
25
+
26
26
+
if (world.hit(r, IntervalF32.init(0.001, std.math.inf(f32)))) |rec| {
27
27
+
r.orig = rec.p;
28
28
+
r.dir = util.randomOnHemisphere(rec.normal);
29
29
+
return zm.f32x4(0.5, 0.5, 0.5, 1.0) * rayColor(r, world, depth - 1);
25
30
}
26
31
27
32
const unit_direction = zm.normalize3(r.dir);
···
39
44
var col = zm.f32x4(0.0, 0.0, 0.0, 1.0);
40
45
for (0..ctx.cam.samples_per_pixel) |_| {
41
46
var ray = ctx.cam.getRay(i, j);
42
42
-
col += rayColor(&ray, ctx.world);
47
47
+
col += rayColor(&ray, ctx.world, ctx.cam.max_depth);
43
48
}
44
49
45
50
ctx.cam.setPixel(i, j, vecToRgba(col, ctx.cam.samples_per_pixel)) catch break;
+57
src/util.zig
···
1
1
+
const std = @import("std");
2
2
+
const random = std.crypto.random;
3
3
+
4
4
+
const zm = @import("zmath");
5
5
+
6
6
+
/// Returns a random real in [0,1).
7
7
+
pub inline fn randomF32() f32 {
8
8
+
return random.float(f32);
9
9
+
}
10
10
+
11
11
+
/// Returns a random real in [min,max).
12
12
+
pub inline fn randomF32M(min: f32, max: f32) f32 {
13
13
+
return min + (max - min) * randomF32();
14
14
+
}
15
15
+
16
16
+
pub inline fn randomVec2() zm.Vec {
17
17
+
return zm.f32x4(randomF32, randomF32, 0, 0);
18
18
+
}
19
19
+
20
20
+
pub inline fn randomVec3() zm.Vec {
21
21
+
return zm.f32x4(randomF32, randomF32, randomF32, 0);
22
22
+
}
23
23
+
24
24
+
pub inline fn randomVec() zm.Vec {
25
25
+
return zm.f32x4(randomF32, randomF32, randomF32, randomF32);
26
26
+
}
27
27
+
28
28
+
pub inline fn randomVec2M(min: f32, max: f32) zm.Vec {
29
29
+
return zm.f32x4(randomF32M(min, max), randomF32M(min, max), 0, 0);
30
30
+
}
31
31
+
32
32
+
pub inline fn randomVec3M(min: f32, max: f32) zm.Vec {
33
33
+
return zm.f32x4(randomF32M(min, max), randomF32M(min, max), randomF32M(min, max), 0);
34
34
+
}
35
35
+
36
36
+
pub inline fn randomVecM(min: f32, max: f32) zm.Vec {
37
37
+
return zm.f32x4(randomF32M(min, max), randomF32M(min, max), randomF32M(min, max), randomF32M(min, max));
38
38
+
}
39
39
+
40
40
+
pub inline fn randomInUnitSphere() zm.Vec {
41
41
+
while (true) {
42
42
+
const p = randomVec3M(-1.0, 1.0);
43
43
+
if (zm.lengthSq3(p)[0] < 1.0) return p;
44
44
+
}
45
45
+
}
46
46
+
47
47
+
pub inline fn randomUnitVec() zm.Vec {
48
48
+
return zm.normalize3(randomInUnitSphere());
49
49
+
}
50
50
+
51
51
+
pub inline fn randomOnHemisphere(normal: zm.Vec) zm.Vec {
52
52
+
const on_unit_sphere = randomUnitVec();
53
53
+
return if (zm.dot3(on_unit_sphere, normal)[0] > 0.0) // In the same hemisphere as the normal
54
54
+
on_unit_sphere
55
55
+
else
56
56
+
-on_unit_sphere;
57
57
+
}