CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
PerlinNoise.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
11
12#include <algorithm>
13#include <cstdint>
14#include <random>
15
16namespace CeresEngine::inline Math {
17
18 template<typename T = double> class PerlinNoise {
19 private:
20 Int32 p[512];
21
22 static constexpr T fade(T t) noexcept { return t * t * t * (t * (t * 6 - 15) + 10); }
23
24 static constexpr T lerp(T t, T a, T b) noexcept { return a + t * (b - a); }
25
26 static constexpr T grad(const Int32 hash, T x, T y, T z) noexcept {
27 const Int32 h = hash & 15;
28 const double u = h < 8 ? x : y;
29 const double v = h < 4 ? y : h == 12 || h == 14 ? x : z;
30 return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
31 }
32
33 public:
34 explicit PerlinNoise(const UInt32 seed) {
35 for(Int32 i = 0; i < 256; ++i) {
36 p[i] = i;
37 }
38
39 std::shuffle(std::begin(p), std::begin(p) + 256, std::default_random_engine(seed));
40
41 for(size_t i = 0; i < 256; ++i) {
42 p[256 + i] = p[i];
43 }
44 }
45
46 public:
47 T operator()(T x) const { return (*this)(x, T(), T()); }
48
49 T operator()(T x, T y) const { return (*this)(x, y, T()); }
50
51 T operator()(T x, T y, T z) const {
52 const Int32 X = static_cast<Int32>(std::floor(x)) & 255;
53 const Int32 Y = static_cast<Int32>(std::floor(y)) & 255;
54 const Int32 Z = static_cast<Int32>(std::floor(z)) & 255;
55
56 x -= std::floor(x);
57 y -= std::floor(y);
58 z -= std::floor(z);
59
60 const double u = fade(x);
61 const double v = fade(y);
62 const double w = fade(z);
63
64 const Int32 A = p[X] + Y, AA = p[A] + Z, AB = p[A + 1] + Z;
65 const Int32 B = p[X + 1] + Y, BA = p[B] + Z, BB = p[B + 1] + Z;
66
67 return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), grad(p[BA], x - 1, y, z)), lerp(u, grad(p[AB], x, y - 1, z), grad(p[BB], x - 1, y - 1, z))),
68 lerp(v, lerp(u, grad(p[AA + 1], x, y, z - 1), grad(p[BA + 1], x - 1, y, z - 1)),
69 lerp(u, grad(p[AB + 1], x, y - 1, z - 1), grad(p[BB + 1], x - 1, y - 1, z - 1))));
70 }
71 };
72
73} // namespace CeresEngine::inline Math
Definition PerlinNoise.hpp:18
T operator()(T x, T y) const
Definition PerlinNoise.hpp:49
T operator()(T x, T y, T z) const
Definition PerlinNoise.hpp:51
static constexpr T grad(const Int32 hash, T x, T y, T z) noexcept
Definition PerlinNoise.hpp:26
PerlinNoise(const UInt32 seed)
Definition PerlinNoise.hpp:34
static constexpr T lerp(T t, T a, T b) noexcept
Definition PerlinNoise.hpp:24
static constexpr T fade(T t) noexcept
Definition PerlinNoise.hpp:22
T operator()(T x) const
Definition PerlinNoise.hpp:47
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
Definition Angle.hpp:20
T lerp(T t, T min, T max)
Linearly interpolates between the two values using t.
Definition Math.hpp:278