tangled
alpha
login
or
join now
altagos.dev
/
rayray
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
small changes
altagos.dev
2 years ago
f434c300
9863b5f3
+38
-35
4 changed files
expand all
collapse all
unified
split
src
BVH.zig
hittable
sphere.zig
hittable.zig
scences
in_one_weekend.zig
+10
-17
src/BVH.zig
···
8
8
const Ray = @import("Ray.zig");
9
9
const util = @import("util.zig");
10
10
11
11
+
const log = std.log.scoped(.BVH);
12
12
+
11
13
pub const BVH = @This();
12
14
13
15
const Ast = struct {
···
41
43
objects: []Hittable,
42
44
bbox: AABB,
43
45
44
44
-
pub inline fn hit(self: *Leaf, r: *Ray, ray_t: IntervalF32) ?HitRecord {
46
46
+
pub fn hit(self: *Leaf, r: *Ray, ray_t: IntervalF32) ?HitRecord {
45
47
var rec: ?HitRecord = null;
46
48
var interval = ray_t;
47
49
for (self.objects) |obj| {
48
48
-
if (@constCast(&obj).hit(r, interval)) |res| {
50
50
+
if (obj.hit(r, interval)) |res| {
49
51
interval = IntervalF32.init(ray_t.min, res.t);
50
52
rec = res;
51
53
}
···
123
125
}
124
126
}
125
127
126
126
-
pub inline fn bbox(self: *Node) AABB {
127
127
-
switch (self.*) {
128
128
-
.ast => |*a| return a.bbox,
129
129
-
.leaf => |*l| return l.bbox,
130
130
-
}
128
128
+
pub fn bbox(self: *Node) AABB {
129
129
+
return self.bbox;
131
130
}
132
131
133
132
pub inline fn hit(self: *Node, r: *Ray, ray_t: IntervalF32) ?HitRecord {
···
197
196
198
197
pub fn init(allocator: std.mem.Allocator, objects: hittable.HittableList, max_depth: usize) !BVH {
199
198
defer @constCast(&objects).deinit();
200
200
-
std.log.info("Creating BVH Tree with {} objects", .{objects.list.items.len});
199
199
+
log.info("Creating BVH Tree with {} objects", .{objects.list.items.len});
201
200
202
201
const root = try allocator.create(Node);
203
202
try root.init(allocator, objects.list.items, max_depth, 0);
204
203
const bbox = root.recomputeBbox();
205
204
206
206
-
std.log.debug("Reached depth of: {}, max objects: {}", .{ reached_depth, max_objects });
205
205
+
log.debug("Reached depth of: {}, max objects: {}", .{ reached_depth, max_objects });
207
206
208
207
// root.print(0, 0);
209
208
return .{
···
218
217
}
219
218
220
219
pub inline fn hit(self: *BVH, r: *Ray, ray_t: IntervalF32) ?HitRecord {
221
221
-
if (self.bbox.hit(r, ray_t)) {
222
222
-
return self.root.hit(r, ray_t);
223
223
-
}
224
224
-
225
225
-
return null;
220
220
+
return self.root.hit(r, ray_t);
226
221
}
227
222
228
223
inline fn boxCompare(a: *Hittable, b: *Hittable, axis_index: i32) bool {
229
229
-
const a_axis_interval = a.boundingBox().axisInterval(axis_index);
230
230
-
const b_axis_interval = b.boundingBox().axisInterval(axis_index);
231
231
-
return a_axis_interval.min < b_axis_interval.min;
224
224
+
return a.boundingBox().axisInterval(axis_index).min < b.boundingBox().axisInterval(axis_index).min;
232
225
}
233
226
234
227
fn boxXCompare(_: @TypeOf(.{}), a: Hittable, b: Hittable) bool {
+2
-2
src/hittable.zig
···
33
33
34
34
pub fn boundingBox(self: *Hittable) AABB {
35
35
switch (self.*) {
36
36
-
inline else => |*n| return n[0].boundingBox(),
36
36
+
inline else => |*n| return n[0].bbox,
37
37
}
38
38
}
39
39
···
43
43
}
44
44
}
45
45
46
46
-
pub inline fn hit(self: *Hittable, r: *Ray, ray_t: IntervalF32) ?HitRecord {
46
46
+
pub fn hit(self: *const Hittable, r: *Ray, ray_t: IntervalF32) ?HitRecord {
47
47
switch (self.*) {
48
48
inline else => |*n| return n[0].hit(r, ray_t),
49
49
}
+20
-10
src/hittable/sphere.zig
···
13
13
mat: *Material,
14
14
is_moving: bool = false,
15
15
center_vec: zm.Vec = zm.f32x4s(0),
16
16
-
bbox: ?AABB = null,
16
16
+
bbox: AABB,
17
17
+
18
18
+
pub fn init(center: zm.Vec, radius: f32, mat: *Material) Sphere {
19
19
+
const rvec = zm.f32x4s(radius);
20
20
+
return Sphere{
21
21
+
.center = center,
22
22
+
.radius = @max(0, radius),
23
23
+
.mat = mat,
24
24
+
.bbox = AABB.initP(center - rvec, center + rvec),
25
25
+
};
26
26
+
}
17
27
18
28
pub fn initMoving(center1: zm.Vec, center2: zm.Vec, radius: f32, mat: *Material) Sphere {
19
29
const rvec = zm.f32x4s(radius);
···
31
41
}
32
42
33
43
pub inline fn boundingBox(self: *Sphere) AABB {
34
34
-
if (self.bbox) |bbox| {
35
35
-
return bbox;
36
36
-
} else {
37
37
-
const rvec = zm.f32x4s(self.radius);
38
38
-
self.bbox = AABB.initP(self.center - rvec, self.center + rvec);
39
39
-
return self.bbox.?;
40
40
-
}
44
44
+
// if (self.bbox) |bbox| {
45
45
+
return self.bbox;
46
46
+
// } else {
47
47
+
// const rvec = zm.f32x4s(self.radius);
48
48
+
// self.bbox = AABB.initP(self.center - rvec, self.center + rvec);
49
49
+
// return self.bbox.?;
50
50
+
// }
41
51
}
42
52
43
43
-
pub inline fn hit(self: *Sphere, r: *Ray, ray_t: IntervalF32) ?HitRecord {
53
53
+
pub fn hit(self: *const Sphere, r: *Ray, ray_t: IntervalF32) ?HitRecord {
44
54
const center = blk: {
45
55
if (self.is_moving) {
46
56
break :blk self.sphereCenter(r.tm);
···
77
87
return rec;
78
88
}
79
89
80
80
-
pub inline fn sphereCenter(self: *Sphere, time: f32) zm.Vec {
90
90
+
pub inline fn sphereCenter(self: *const Sphere, time: f32) zm.Vec {
81
91
return self.center + zm.f32x4s(time) * self.center_vec;
82
92
}
+6
-6
src/scences/in_one_weekend.zig
···
15
15
16
16
const material_ground = try allocator.create(Material);
17
17
material_ground.* = Material.lambertian(zm.f32x4(0.5, 0.5, 0.5, 1.0));
18
18
-
try world.add(Hittable.sphere("Ground", Sphere{ .center = zm.f32x4(0, -1000, 0, 0), .radius = 1000, .mat = material_ground }));
18
18
+
try world.add(Hittable.sphere("Ground", Sphere.init(zm.f32x4(0, -1000, 0, 0), 1000, material_ground)));
19
19
20
20
const a_max = 50;
21
21
const b_max = 50;
···
47
47
const albedo = rayray.util.randomVec3M(0.5, 1) + zm.f32x4(0, 0, 0, 1);
48
48
const fuzz = rayray.util.randomF32M(0, 0.5);
49
49
material.* = Material.metal(albedo, fuzz);
50
50
-
try world.add(Hittable.sphere("Metal", Sphere{ .center = center, .radius = 0.2, .mat = material }));
50
50
+
try world.add(Hittable.sphere("Metal", Sphere.init(center, 0.2, material)));
51
51
} else {
52
52
// glass
53
53
material.* = Material.dielectric(1.5);
54
54
-
try world.add(Hittable.sphere("Dielectric", Sphere{ .center = center, .radius = 0.2, .mat = material }));
54
54
+
try world.add(Hittable.sphere("Dielectric", Sphere.init(center, 0.2, material)));
55
55
}
56
56
}
57
57
}
···
63
63
64
64
const material2 = try allocator.create(Material);
65
65
material2.* = Material.lambertian(zm.f32x4(0.4, 0.2, 0.1, 1));
66
66
-
try world.add(Hittable.sphere("Two: Lambertian", Sphere{ .center = zm.f32x4(-4, 1, 0, 0), .radius = 1, .mat = material1 }));
66
66
+
try world.add(Hittable.sphere("Two: Lambertian", Sphere.init(zm.f32x4(-4, 1, 0, 0), 1, material1)));
67
67
68
68
const material3 = try allocator.create(Material);
69
69
material3.* = Material.metal(zm.f32x4(0.7, 0.6, 0.5, 1), 0);
70
70
-
try world.add(Hittable.sphere("Three: Metal", Sphere{ .center = zm.f32x4(4, 1, 0, 0), .radius = 1, .mat = material3 }));
70
70
+
try world.add(Hittable.sphere("Three: Metal", Sphere.init(zm.f32x4(4, 1, 0, 0), 1, material3)));
71
71
72
72
-
try world.add(Hittable.sphere("One: Dielectric", Sphere{ .center = zm.f32x4(0, 1, 0, 0), .radius = 1, .mat = material2 }));
72
72
+
try world.add(Hittable.sphere("One: Dielectric", Sphere.init(zm.f32x4(0, 1, 0, 0), 1, material2)));
73
73
74
74
return .{ .allocator = allocator, .world = world };
75
75
}