diff options
| author | nsfisis <nsfisis@gmail.com> | 2022-12-09 00:02:09 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2022-12-09 00:02:09 +0900 |
| commit | d1a300610db20107af89d57824d5596531037435 (patch) | |
| tree | bcd9595f609171150ad8b208e502209d71cbd4b5 /src/rtw | |
| parent | 86914985b77ddf5d6d3a3dd6c13deed9d906a471 (diff) | |
| download | RayTracingInOneWeekend.zig-d1a300610db20107af89d57824d5596531037435.tar.gz RayTracingInOneWeekend.zig-d1a300610db20107af89d57824d5596531037435.tar.zst RayTracingInOneWeekend.zig-d1a300610db20107af89d57824d5596531037435.zip | |
5.1
Diffstat (limited to 'src/rtw')
| -rw-r--r-- | src/rtw/perlin.zig | 59 | ||||
| -rw-r--r-- | src/rtw/texture.zig | 20 |
2 files changed, 79 insertions, 0 deletions
diff --git a/src/rtw/perlin.zig b/src/rtw/perlin.zig new file mode 100644 index 0000000..df5de76 --- /dev/null +++ b/src/rtw/perlin.zig @@ -0,0 +1,59 @@ +const rand = @import("rand.zig"); +const Random = rand.Random; +const randomReal01 = rand.randomReal01; +const randomInt = rand.randomInt; +const Point3 = @import("vec.zig").Point3; + +pub const Perlin = struct { + const POINT_COUNT = 256; + + randomNoise: [POINT_COUNT]f64, + permX: [POINT_COUNT]usize, + permY: [POINT_COUNT]usize, + permZ: [POINT_COUNT]usize, + + pub fn init(rng: Random) Perlin { + var perlin = Perlin{ + .randomNoise = undefined, + .permX = undefined, + .permY = undefined, + .permZ = undefined, + }; + + var i: usize = 0; + while (i < POINT_COUNT) : (i += 1) { + perlin.randomNoise[i] = randomReal01(rng); + } + perlinGeneratePerm(rng, &perlin.permX); + perlinGeneratePerm(rng, &perlin.permY); + perlinGeneratePerm(rng, &perlin.permZ); + + return perlin; + } + + pub fn noise(perlin: Perlin, p: Point3) f64 { + const i = @intCast(usize, @floatToInt(i32, 4.0 * p.x) & 255); + const j = @intCast(usize, @floatToInt(i32, 4.0 * p.y) & 255); + const k = @intCast(usize, @floatToInt(i32, 4.0 * p.z) & 255); + + return perlin.randomNoise[perlin.permX[i] ^ perlin.permY[j] ^ perlin.permZ[k]]; + } + + fn perlinGeneratePerm(rng: Random, p: []usize) void { + var i: usize = 0; + while (i < POINT_COUNT) : (i += 1) { + p[i] = i; + } + permute(rng, p, POINT_COUNT); + } + + fn permute(rng: Random, p: []usize, n: usize) void { + var i = n - 1; + while (i > 0) : (i -= 1) { + const target = randomInt(usize, rng, 0, i); + const tmp = p[i]; + p[i] = p[target]; + p[target] = tmp; + } + } +}; diff --git a/src/rtw/texture.zig b/src/rtw/texture.zig index 47c3c4f..63b8f46 100644 --- a/src/rtw/texture.zig +++ b/src/rtw/texture.zig @@ -2,15 +2,20 @@ const std = @import("std"); const Color = @import("vec.zig").Color; const Vec3 = @import("vec.zig").Vec3; +const rgb = @import("vec.zig").rgb; +const Random = @import("rand.zig").Random; +const Perlin = @import("perlin.zig").Perlin; const TextureTag = enum { solid, checker, + noise, }; pub const Texture = union(TextureTag) { solid: SolidTexture, checker: CheckerTexture, + noise: NoiseTexture, pub fn makeSolid(color: Color) Texture { return .{ .solid = .{ .color = color } }; @@ -24,10 +29,15 @@ pub const Texture = union(TextureTag) { ) }; } + pub fn makeNoise(rng: Random) Texture { + return .{ .noise = .{ .perlin = Perlin.init(rng) } }; + } + pub fn value(tx: Texture, u: f64, v: f64, p: Vec3) Color { return switch (tx) { TextureTag.solid => |solidTx| solidTx.value(u, v, p), TextureTag.checker => |checkerTx| checkerTx.value(u, v, p), + TextureTag.noise => |noiseTx| noiseTx.value(u, v, p), }; } }; @@ -70,3 +80,13 @@ pub const CheckerTexture = struct { return if (sines < 0) tx.odd.value(u, v, p) else tx.even.value(u, v, p); } }; + +pub const NoiseTexture = struct { + perlin: Perlin, + + fn value(tx: NoiseTexture, u: f64, v: f64, p: Vec3) Color { + _ = u; + _ = v; + return rgb(1, 1, 1).mul(tx.perlin.noise(p)); + } +}; |
