Remove dupilicate perlin noise impl, and update the remaining one.
This commit is contained in:
@@ -27,20 +27,159 @@
|
||||
#define LL_PERLIN_H
|
||||
|
||||
#include "stdtypes.h"
|
||||
#include "llmath.h"
|
||||
#include "v2math.h"
|
||||
#include "v3math.h"
|
||||
|
||||
// namespace wrapper
|
||||
class LLPerlinNoise
|
||||
{
|
||||
public:
|
||||
static F32 noise1(F32 x);
|
||||
static F32 noise2(F32 x, F32 y);
|
||||
static F32 noise3(F32 x, F32 y, F32 z);
|
||||
static F32 turbulence2(F32 x, F32 y, F32 freq);
|
||||
static F32 turbulence3(F32 x, F32 y, F32 z, F32 freq);
|
||||
static F32 clouds3(F32 x, F32 y, F32 z, F32 freq);
|
||||
template<typename T>
|
||||
static F32 noise(const T& x, U32 wrap_at);
|
||||
template<typename T>
|
||||
static F32 noise(const T& x)
|
||||
{
|
||||
return noise(x, 256);
|
||||
}
|
||||
template<>
|
||||
static F32 noise(const F32& x, U32 wrap_at)
|
||||
{
|
||||
U8 b[1][2];
|
||||
F32 r[1][2], s[1], u, v;
|
||||
|
||||
fast_setup(&x, b, r, s, wrap_at);
|
||||
|
||||
u = grad(p[b[VX][0]], r[VX][0]);
|
||||
v = grad(p[b[VX][1]], r[VX][1]);
|
||||
|
||||
return lerp(u, v, s[VX]);
|
||||
}
|
||||
template <>
|
||||
static F32 noise(const LLVector2& vec, U32 wrap_at)
|
||||
{
|
||||
U8 b[2][2];
|
||||
F32 r[2][2], s[2], u, v, A, B;
|
||||
|
||||
fast_setup(vec.mV, b, r, s, wrap_at);
|
||||
|
||||
u = grad(p[p[b[VX][0]] + b[VY][0]], r[VX][0], r[VY][0]);
|
||||
v = grad(p[p[b[VX][1]] + b[VY][0]], r[VX][1], r[VY][0]);
|
||||
A = lerp(u, v, s[VX]);
|
||||
|
||||
u = grad(p[p[b[VX][0]] + b[VY][1]], r[VX][0], r[VY][1]);
|
||||
v = grad(p[p[b[VX][1]] + b[VY][1]], r[VX][1], r[VY][1]);
|
||||
B = lerp(u, v, s[VX]);
|
||||
|
||||
return lerp(A, B, s[VY]);
|
||||
}
|
||||
template <>
|
||||
static F32 noise(const LLVector3& vec, U32 wrap_at)
|
||||
{
|
||||
U8 b[3][2];
|
||||
F32 r[3][2], s[3], u, v, A, B, C, D;
|
||||
|
||||
fast_setup(vec.mV, b, r, s, wrap_at);
|
||||
|
||||
u = grad(p[p[p[b[VX][0]] + b[VY][0]] + b[VZ][0]], r[VX][0], r[VY][0], r[VZ][0]);
|
||||
v = grad(p[p[p[b[VX][1]] + b[VY][0]] + b[VZ][0]], r[VX][1], r[VY][0], r[VZ][0]);
|
||||
A = lerp(u, v, s[VX]);
|
||||
|
||||
u = grad(p[p[p[b[VX][0]] + b[VY][1]] + b[VZ][0]], r[VX][0], r[VY][1], r[VZ][0]);
|
||||
v = grad(p[p[p[b[VX][1]] + b[VY][1]] + b[VZ][0]], r[VX][1], r[VY][1], r[VZ][0]);
|
||||
B = lerp(u, v, s[VX]);
|
||||
|
||||
C = lerp(A, B, s[VY]);
|
||||
|
||||
u = grad(p[p[p[b[VX][0]] + b[VY][0]] + b[VZ][1]], r[VX][0], r[VY][0], r[VZ][1]);
|
||||
v = grad(p[p[p[b[VX][1]] + b[VY][0]] + b[VZ][1]], r[VX][1], r[VY][0], r[VZ][1]);
|
||||
A = lerp(u, v, s[VX]);
|
||||
|
||||
u = grad(p[p[p[b[VX][0]] + b[VY][1]] + b[VZ][1]], r[VX][0], r[VY][1], r[VZ][1]);
|
||||
v = grad(p[p[p[b[VX][1]] + b[VY][1]] + b[VZ][1]], r[VX][1], r[VY][1], r[VZ][1]);
|
||||
B = lerp(u, v, s[VX]);
|
||||
|
||||
D = lerp(A, B, s[VY]);
|
||||
|
||||
return lerp(C, D, s[VZ]);
|
||||
}
|
||||
template <typename T>
|
||||
static F32 turbulence(const T& vec, F32 freq, U32 wrap_at = 256)
|
||||
{
|
||||
F32 t;
|
||||
for (t = 0.f; freq >= 1.f; freq *= 0.5f)
|
||||
{
|
||||
t += noise(vec * freq, wrap_at) / freq;
|
||||
// t += fabs(noise(vec * freq)) / freq; // Like snow - bubbly at low frequencies
|
||||
// t += sqrt(fabs(noise(vec * freq))) / freq; // Better at low freq
|
||||
// t += (noise(vec * freq)*noise(vec * freq)) / freq;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
template <typename T>
|
||||
static F32 clouds(const T& vec, F32 freq, U32 wrap_at = 256)
|
||||
{
|
||||
F32 t;
|
||||
for (t = 0.f; freq >= 1.f; freq *= 0.5f)
|
||||
{
|
||||
// t += noise(vec * freq)/freq;
|
||||
// t += fabs(noise(vec * freq)) / freq; // Like snow - bubbly at low frequencies
|
||||
// t += sqrt(fabs(noise(vec * freq))) / freq; // Better at low freq
|
||||
t += (noise(vec * freq, wrap_at)*noise(vec * freq, wrap_at)) / freq;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
private:
|
||||
static bool sInitialized;
|
||||
static void init(void);
|
||||
static F32 s_curve(const F32 t)
|
||||
{
|
||||
return t * t * t * (t * (6.f * t - 15.f) + 10.f); //5th degree
|
||||
//return t * t * (3.f - 2.f * t); //3rd degree
|
||||
}
|
||||
|
||||
static F32 grad(U32 hash, F32 x)
|
||||
{
|
||||
return x * (2.f*F32(hash) / 255.f - 1.f);
|
||||
}
|
||||
|
||||
static F32 grad(U32 hash, F32 x, F32 y)
|
||||
{
|
||||
//Rotated slightly off the axes. Reduces directional artifacts.
|
||||
//Scaled to match the old perlin method's output range
|
||||
static const F32 l[2] = { .466666667f, .933333332f };
|
||||
static const LLVector2 vecs[] = {
|
||||
LLVector2(l[0], l[1]), LLVector2(l[0], -l[1]), LLVector2(-l[0], l[1]), LLVector2(-l[0], -l[1]),
|
||||
LLVector2(l[1], l[0]), LLVector2(l[1], -l[0]), LLVector2(-l[1], l[0]), LLVector2(-l[1], -l[0]) };
|
||||
|
||||
return vecs[hash % LL_ARRAY_SIZE(vecs)] * LLVector2(x, y);
|
||||
}
|
||||
|
||||
static F32 grad(U32 hash, F32 x, F32 y, F32 z)
|
||||
{
|
||||
static const LLVector3 vecs[] = {
|
||||
OO_SQRT3*LLVector3(1, 1, 0), OO_SQRT3*LLVector3(-1, 1, 0), OO_SQRT3*LLVector3(1, -1, 0), OO_SQRT3*LLVector3(-1, -1, 0),
|
||||
OO_SQRT3*LLVector3(1, 0, 1), OO_SQRT3*LLVector3(-1, 0, 1), OO_SQRT3*LLVector3(1, 0, -1), OO_SQRT3*LLVector3(-1, 0, -1),
|
||||
OO_SQRT3*LLVector3(0, 1, 1), OO_SQRT3*LLVector3(0, -1, 1), OO_SQRT3*LLVector3(0, 1, -1), OO_SQRT3*LLVector3(0, -1, -1) };
|
||||
|
||||
return vecs[hash % LL_ARRAY_SIZE(vecs)] * LLVector3(x, y, z);
|
||||
}
|
||||
|
||||
template <int N>
|
||||
static void fast_setup(const F32* vec, U8 (&b)[N][2], F32 (&r)[N][2], F32 (&s)[N], const U32& wrap_at)
|
||||
{
|
||||
const U32 limit = llclamp(wrap_at, U32(1), U32(256));
|
||||
for (U32 i = 0; i < N; ++i)
|
||||
{
|
||||
const S32 t_S32 = lltrunc(vec[i]);
|
||||
b[i][0] = (t_S32) % limit;
|
||||
b[i][1] = (t_S32 + 1) % limit;
|
||||
r[i][0] = vec[i] - F32(t_S32);
|
||||
r[i][1] = r[i][0] - 1.f;
|
||||
s[i] = s_curve(r[i][0]);
|
||||
}
|
||||
}
|
||||
|
||||
static const U32 sPremutationCount = 512;
|
||||
static const U8 p[sPremutationCount];
|
||||
};
|
||||
|
||||
#endif // LL_PERLIN_
|
||||
|
||||
Reference in New Issue
Block a user