mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-06-18 00:27:02 +08:00
feat: add perlin noise
This commit is contained in:
71
src/tools/perlin_noise.cpp
Normal file
71
src/tools/perlin_noise.cpp
Normal file
@@ -0,0 +1,71 @@
|
||||
#include <Cubed/tools/perlin_noise.hpp>
|
||||
|
||||
#include <Cubed/config.hpp>
|
||||
#include <Cubed/tools/cubed_assert.hpp>
|
||||
|
||||
#include <algorithm>
|
||||
#include <numeric>
|
||||
#include <random>
|
||||
|
||||
void PerlinNoise::init() {
|
||||
p.resize(256);
|
||||
std::iota(p.begin(), p.end(), 0);
|
||||
|
||||
std::mt19937 engine(SEED);
|
||||
std::shuffle(p.begin(), p.end(), engine);
|
||||
|
||||
p.insert(p.end(), p.begin(), p.end());
|
||||
is_init = true;
|
||||
}
|
||||
|
||||
float PerlinNoise::noise(float x, float y, float z) {
|
||||
CUBED_ASSERT_MSG(is_init, "The PerlinNoise don't init!");
|
||||
int ix = static_cast<int>(std::floor(x)) & 255;
|
||||
int iy = static_cast<int>(std::floor(y)) & 255;
|
||||
int iz = static_cast<int>(std::floor(z)) & 255;
|
||||
|
||||
x -= std::floor(x);
|
||||
y -= std::floor(y);
|
||||
z -= std::floor(z);
|
||||
|
||||
double u = fade(x);
|
||||
double v = fade(y);
|
||||
double w = fade(z);
|
||||
|
||||
int a = p[ix] + iy;
|
||||
int aa = p[a] + iz;
|
||||
int ab = p[a + 1] + iz;
|
||||
int b = p[ix + 1] + iy;
|
||||
int ba = p[b] + iz;
|
||||
int bb = p[b + 1] + iz;
|
||||
|
||||
float res = 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))
|
||||
),
|
||||
lerp(v,
|
||||
lerp(u, grad(p[aa + 1], x, y, z - 1), grad(p[ba + 1], x - 1, y, z - 1)),
|
||||
lerp(u, grad(p[ab + 1], x, y - 1, z - 1), grad(p[bb + 1 ], x - 1, y - 1, z - 1))
|
||||
)
|
||||
|
||||
);
|
||||
return (res + 1.0f) / 2.0f;
|
||||
}
|
||||
|
||||
float PerlinNoise::fade(float t) {
|
||||
return t * t * t * (t * (t * 6 - 15) + 10);
|
||||
}
|
||||
|
||||
float PerlinNoise::lerp(float t, float a, float b) {
|
||||
return a + t * (b - a);
|
||||
}
|
||||
|
||||
float PerlinNoise::grad(int hash, float x, float y, float z) {
|
||||
int h = hash & 15;
|
||||
|
||||
float u = h < 8 ? x : y;
|
||||
float v = h < 4 ? y : h == 12 || h == 14 ? x : z;
|
||||
|
||||
return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v);
|
||||
}
|
||||
Reference in New Issue
Block a user