tangled
alpha
login
or
join now
altagos.dev
/
rayray
0
fork
atom
this repo has no description
0
fork
atom
overview
issues
pulls
pipelines
+
altagos.dev
2 years ago
8b67f636
d41d3da4
+38
-46
9 changed files
expand all
collapse all
unified
split
src
BVH.zig
hittable
sphere.zig
main.zig
material.zig
ray.zig
rayray.zig
scences
in_one_weekend.zig
tracer.zig
util.zig
+2
-1
src/BVH.zig
···
194
194
}
195
195
196
196
inline fn boxCompare(a: *Hittable, b: *Hittable, axis_index: i32) bool {
197
197
+
@setFloatMode(std.builtin.FloatMode.optimized);
197
198
const a_axis_interval = a.boundingBox().axisInterval(axis_index);
198
199
const b_axis_interval = b.boundingBox().axisInterval(axis_index);
199
199
-
return a_axis_interval.min <= b_axis_interval.min;
200
200
+
return a_axis_interval.min < b_axis_interval.min;
200
201
}
201
202
202
203
fn boxXCompare(_: @TypeOf(.{}), a: Hittable, b: Hittable) bool {
+3
-3
src/hittable/sphere.zig
···
30
30
};
31
31
}
32
32
33
33
-
pub fn boundingBox(self: *Sphere) AABB {
33
33
+
pub inline fn boundingBox(self: *Sphere) AABB {
34
34
if (self.bbox) |bbox| {
35
35
return bbox;
36
36
} else {
···
40
40
}
41
41
}
42
42
43
43
-
pub fn hit(self: *Sphere, r: *Ray, ray_t: IntervalF32) ?HitRecord {
43
43
+
pub inline fn hit(self: *Sphere, r: *Ray, ray_t: IntervalF32) ?HitRecord {
44
44
const center = blk: {
45
45
if (self.is_moving) {
46
46
break :blk self.sphereCenter(r.tm);
···
77
77
return rec;
78
78
}
79
79
80
80
-
pub fn sphereCenter(self: *Sphere, time: f32) zm.Vec {
80
80
+
pub inline fn sphereCenter(self: *Sphere, time: f32) zm.Vec {
81
81
return self.center + zm.f32x4s(time) * self.center_vec;
82
82
}
+1
-1
src/main.zig
···
39
39
// Raytracing part
40
40
var raytracer = try rayray.Raytracer.init(allocator, scence.world, .{
41
41
.aspect_ratio = 16.0 / 9.0,
42
42
-
.image_width = 800,
42
42
+
.image_width = 400,
43
43
.samples_per_pixel = 100,
44
44
.max_depth = 50,
45
45
+13
-14
src/material.zig
···
23
23
return .{ .dielectric = .{ .refraction_index = refraction_index } };
24
24
}
25
25
26
26
-
pub fn scatter(self: *Material, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray {
26
26
+
pub inline fn scatter(self: *Material, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray {
27
27
return switch (self.*) {
28
28
.lambertian => |*lambert| lambert.scatter(r, rec, attenuation),
29
29
.metal => |*met| met.scatter(r, rec, attenuation),
···
35
35
pub const Lambertian = struct {
36
36
albedo: zm.Vec,
37
37
38
38
-
pub fn scatter(self: *Lambertian, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray {
38
38
+
pub inline fn scatter(self: *Lambertian, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray {
39
39
var scatter_dir = rec.normal + util.randomUnitVec();
40
40
41
41
if (util.nearZero(scatter_dir)) scatter_dir = rec.normal;
42
42
43
43
attenuation.* = self.albedo;
44
44
-
return Ray.initT(rec.p, scatter_dir, r.tm);
44
44
+
// return Ray.initT(rec.p, scatter_dir, r.tm);
45
45
+
return Ray{ .orig = rec.p, .dir = scatter_dir, .tm = r.tm };
45
46
}
46
47
};
47
48
···
50
51
/// fuzz < 1
51
52
fuzz: f32,
52
53
53
53
-
pub fn scatter(self: *Metal, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray {
54
54
+
pub inline fn scatter(self: *Metal, r: *Ray, rec: *hittable.HitRecord, attenuation: *zm.Vec) ?Ray {
54
55
const reflected = util.reflect(r.dir, rec.normal);
55
56
const scattered = Ray.initT(rec.p, zm.normalize3(reflected) + zm.f32x4s(self.fuzz) * util.randomUnitVec(), r.tm);
56
57
attenuation.* = self.albedo;
···
67
68
68
69
const unit_direction = zm.normalize3(r.dir);
69
70
const cos_theta = @min(zm.dot3(-unit_direction, rec.normal)[0], 1.0);
70
70
-
const sin_theta = @sqrt(1.0 - cos_theta * cos_theta);
71
71
+
const sin_theta = @sqrt(1.0 - math.pow(f32, cos_theta, 2));
71
72
72
73
const cannot_refract = ri * sin_theta > 1.0;
73
73
-
const direction = blk: {
74
74
-
if (cannot_refract or reflectance(cos_theta, ri) > util.randomF32()) {
75
75
-
break :blk util.reflect(unit_direction, rec.normal);
76
76
-
} else {
77
77
-
break :blk util.refract(unit_direction, rec.normal, ri);
78
78
-
}
79
79
-
};
74
74
+
const direction = if (cannot_refract or reflectance(cos_theta, ri) > util.randomF32())
75
75
+
util.reflect(unit_direction, rec.normal)
76
76
+
else
77
77
+
util.refract(unit_direction, rec.normal, ri);
80
78
81
81
-
return Ray.initT(rec.p, direction, r.tm);
79
79
+
// return Ray.initT(rec.p, direction, r.tm);
80
80
+
return Ray{ .orig = rec.p, .dir = direction, .tm = r.tm };
82
81
}
83
82
84
84
-
fn reflectance(cosine: f32, refraction_index: f32) f32 {
83
83
+
inline fn reflectance(cosine: f32, refraction_index: f32) f32 {
85
84
var r0 = (1 - refraction_index) / (1 + refraction_index);
86
85
r0 = r0 * r0;
87
86
return r0 + (1 - r0) * math.pow(f32, 1 - cosine, 5);
+1
-3
src/ray.zig
···
1
1
-
const std = @import("std");
2
2
-
3
1
const zm = @import("zmath");
4
2
5
3
const Ray = @This();
···
24
22
};
25
23
}
26
24
27
27
-
pub fn at(self: *Ray, t: f32) zm.Vec {
25
25
+
pub inline fn at(self: *Ray, t: f32) zm.Vec {
28
26
return self.orig + zm.f32x4s(t) * self.dir;
29
27
}
-2
src/rayray.zig
···
93
93
.width = c_width,
94
94
};
95
95
96
96
-
// log.debug("Spawning chunk: {}, row start: {}, col start: {}", .{ id, row, col });
97
97
-
98
96
try self.thread_pool.spawn(
99
97
renderThread,
100
98
.{ ctx, t, id },
+4
-5
src/scences/in_one_weekend.zig
···
7
7
const HittableList = rayray.hittable.HittableList;
8
8
const Material = rayray.material.Material;
9
9
const Sphere = rayray.hittable.Sphere;
10
10
-
const BVH = rayray.hittable.BVH;
11
10
12
11
world: HittableList,
13
12
allocator: std.mem.Allocator,
···
19
18
material_ground.* = Material.lambertian(zm.f32x4(0.5, 0.5, 0.5, 1.0));
20
19
try world.add(Hittable.sphere("Ground", Sphere{ .center = zm.f32x4(0, -1000, 0, 0), .radius = 1000, .mat = material_ground }));
21
20
22
22
-
var a: isize = -11;
23
23
-
while (a < 11) : (a += 1) {
24
24
-
var b: isize = -11;
25
25
-
while (b < 11) : (b += 1) {
21
21
+
var a: isize = -22;
22
22
+
while (a < 22) : (a += 1) {
23
23
+
var b: isize = -22;
24
24
+
while (b < 22) : (b += 1) {
26
25
const choose_mat = rayray.util.randomF32();
27
26
const center = zm.f32x4(
28
27
@as(f32, @floatFromInt(a)) + 0.9 * rayray.util.randomF32(),
+13
-16
src/tracer.zig
···
25
25
};
26
26
27
27
pub fn rayColor(r: *Ray, world: *BVH, depth: usize) zm.Vec {
28
28
-
if (depth <= 0) return zm.f32x4(0, 0, 0, 1.0);
28
28
+
@setFloatMode(.optimized);
29
29
+
if (depth == 0) return zm.f32x4(0, 0, 0, 1.0);
29
30
30
31
if (world.hit(r, .{ .min = 0.001, .max = std.math.inf(f32) })) |rec| {
31
32
var attenuation = zm.f32x4s(1.0);
···
59
60
}
60
61
}
61
62
62
62
-
fn vecToRgba(v: zm.Vec, samples_per_pixel: usize) zigimg.color.Rgba32 {
63
63
-
const scale: f32 = 1.0 / @as(f32, @floatFromInt(samples_per_pixel));
64
64
-
const intensity = IntervalF32.init(0.0, 0.999);
65
65
-
66
66
-
const r_scaled = linearToGamma(v[0] * scale);
67
67
-
const g_scaled = linearToGamma(v[1] * scale);
68
68
-
const b_scaled = linearToGamma(v[2] * scale);
69
69
-
const a_scaled = linearToGamma(v[3] * scale);
70
70
-
71
71
-
const r: u8 = @intFromFloat(256 * intensity.clamp(r_scaled));
72
72
-
const g: u8 = @intFromFloat(256 * intensity.clamp(g_scaled));
73
73
-
const b: u8 = @intFromFloat(256 * intensity.clamp(b_scaled));
74
74
-
const a: u8 = @intFromFloat(256 * intensity.clamp(a_scaled));
63
63
+
inline fn vecToRgba(v: zm.Vec, samples_per_pixel: usize) zigimg.color.Rgba32 {
64
64
+
var rgba = linearToGamma(zm.Vec, v / zm.f32x4s(@as(f32, @floatFromInt(samples_per_pixel))));
65
65
+
rgba = zm.clampFast(rgba, zm.f32x4s(0.0), zm.f32x4s(0.999));
66
66
+
rgba = rgba * zm.f32x4s(256);
75
67
76
76
-
return zigimg.color.Rgba32.initRgba(r, g, b, a);
68
68
+
return zigimg.color.Rgba32.initRgba(
69
69
+
@intFromFloat(rgba[0]),
70
70
+
@intFromFloat(rgba[1]),
71
71
+
@intFromFloat(rgba[2]),
72
72
+
@intFromFloat(rgba[3]),
73
73
+
);
77
74
}
78
75
79
79
-
inline fn linearToGamma(linear_component: f32) f32 {
76
76
+
inline fn linearToGamma(comptime T: type, linear_component: T) T {
80
77
return @sqrt(linear_component);
81
78
}
+1
-1
src/util.zig
···
77
77
-on_unit_sphere;
78
78
}
79
79
80
80
-
pub fn nearZero(e: zm.Vec) bool {
80
80
+
pub inline fn nearZero(e: zm.Vec) bool {
81
81
const s = 1e-8;
82
82
return (@abs(e[0]) < s) and (@abs(e[1]) < s) and (@abs(e[2]) < s);
83
83
}