Remove dupilicate perlin noise impl, and update the remaining one.

This commit is contained in:
Shyotl
2015-05-15 00:44:34 -05:00
parent 8c58a9c276
commit 8943439629
11 changed files with 210 additions and 770 deletions

View File

@@ -24,271 +24,34 @@
*/ */
#include "linden_common.h" #include "linden_common.h"
#include "llmath.h"
#include "llperlin.h" #include "llperlin.h"
#define B 0x100 //Random values taken from http://mrl.nyu.edu/~perlin/noise/
#define BM 0xff const U8 LLPerlinNoise::p[LLPerlinNoise::sPremutationCount] =
#define N 0x1000 { 151, 160, 137, 91, 90, 15,
#define NF32 (4096.f) 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23,
#define NP 12 /* 2^N */ 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
#define NM 0xfff 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
static S32 p[B + B + 2]; 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
static F32 g3[B + B + 2][3]; 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123,
static F32 g2[B + B + 2][2]; 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
static F32 g1[B + B + 2]; 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228,
bool LLPerlinNoise::sInitialized = 0; 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107,
49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,
static void normalize2(F32 v[2]) 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180,
{ 151, 160, 137, 91, 90, 15,
F32 s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]); 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23,
v[0] = v[0] * s; 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
v[1] = v[1] * s; 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
} 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
static void normalize3(F32 v[3]) 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123,
{ 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
F32 s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
v[0] = v[0] * s; 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228,
v[1] = v[1] * s; 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107,
v[2] = v[2] * s; 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,
} 138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180
};
static void fast_setup(F32 vec, U8 &b0, U8 &b1, F32 &r0, F32 &r1)
{
S32 t_S32;
r1 = vec + NF32;
t_S32 = lltrunc(r1);
b0 = (U8)t_S32;
b1 = b0 + 1;
r0 = r1 - t_S32;
r1 = r0 - 1.f;
}
void LLPerlinNoise::init(void)
{
int i, j, k;
for (i = 0 ; i < B ; i++)
{
p[i] = i;
g1[i] = (F32)((rand() % (B + B)) - B) / B;
for (j = 0 ; j < 2 ; j++)
g2[i][j] = (F32)((rand() % (B + B)) - B) / B;
normalize2(g2[i]);
for (j = 0 ; j < 3 ; j++)
g3[i][j] = (F32)((rand() % (B + B)) - B) / B;
normalize3(g3[i]);
}
while (--i)
{
k = p[i];
p[i] = p[j = rand() % B];
p[j] = k;
}
for (i = 0 ; i < B + 2 ; i++)
{
p[B + i] = p[i];
g1[B + i] = g1[i];
for (j = 0 ; j < 2 ; j++)
g2[B + i][j] = g2[i][j];
for (j = 0 ; j < 3 ; j++)
g3[B + i][j] = g3[i][j];
}
sInitialized = true;
}
//============================================================================
// Noise functions
#define s_curve(t) ( t * t * (3.f - 2.f * t) )
#define lerp_m(t, a, b) ( a + t * (b - a) )
F32 LLPerlinNoise::noise1(F32 x)
{
int bx0, bx1;
F32 rx0, rx1, sx, t, u, v;
if (!sInitialized)
init();
t = x + N;
bx0 = (lltrunc(t)) & BM;
bx1 = (bx0+1) & BM;
rx0 = t - lltrunc(t);
rx1 = rx0 - 1.f;
sx = s_curve(rx0);
u = rx0 * g1[ p[ bx0 ] ];
v = rx1 * g1[ p[ bx1 ] ];
return lerp_m(sx, u, v);
}
static F32 fast_at2(F32 rx, F32 ry, F32 *q)
{
return rx * q[0] + ry * q[1];
}
F32 LLPerlinNoise::noise2(F32 x, F32 y)
{
U8 bx0, bx1, by0, by1;
U32 b00, b10, b01, b11;
F32 rx0, rx1, ry0, ry1, *q, sx, sy, a, b, u, v;
S32 i, j;
if (!sInitialized)
init();
fast_setup(x, bx0, bx1, rx0, rx1);
fast_setup(y, by0, by1, ry0, ry1);
i = *(p + bx0);
j = *(p + bx1);
b00 = *(p + i + by0);
b10 = *(p + j + by0);
b01 = *(p + i + by1);
b11 = *(p + j + by1);
sx = s_curve(rx0);
sy = s_curve(ry0);
q = *(g2 + b00);
u = fast_at2(rx0, ry0, q);
q = *(g2 + b10);
v = fast_at2(rx1, ry0, q);
a = lerp_m(sx, u, v);
q = *(g2 + b01);
u = fast_at2(rx0,ry1,q);
q = *(g2 + b11);
v = fast_at2(rx1,ry1,q);
b = lerp_m(sx, u, v);
return lerp_m(sy, a, b);
}
static F32 fast_at3(F32 rx, F32 ry, F32 rz, F32 *q)
{
return rx * q[0] + ry * q[1] + rz * q[2];
}
F32 LLPerlinNoise::noise3(F32 x, F32 y, F32 z)
{
U8 bx0, bx1, by0, by1, bz0, bz1;
S32 b00, b10, b01, b11;
F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
S32 i, j;
if (!sInitialized)
init();
fast_setup(x, bx0,bx1, rx0,rx1);
fast_setup(y, by0,by1, ry0,ry1);
fast_setup(z, bz0,bz1, rz0,rz1);
i = p[ bx0 ];
j = p[ bx1 ];
b00 = p[ i + by0 ];
b10 = p[ j + by0 ];
b01 = p[ i + by1 ];
b11 = p[ j + by1 ];
t = s_curve(rx0);
sy = s_curve(ry0);
sz = s_curve(rz0);
q = g3[ b00 + bz0 ];
u = fast_at3(rx0,ry0,rz0,q);
q = g3[ b10 + bz0 ];
v = fast_at3(rx1,ry0,rz0,q);
a = lerp_m(t, u, v);
q = g3[ b01 + bz0 ];
u = fast_at3(rx0,ry1,rz0,q);
q = g3[ b11 + bz0 ];
v = fast_at3(rx1,ry1,rz0,q);
b = lerp_m(t, u, v);
c = lerp_m(sy, a, b);
q = g3[ b00 + bz1 ];
u = fast_at3(rx0,ry0,rz1,q);
q = g3[ b10 + bz1 ];
v = fast_at3(rx1,ry0,rz1,q);
a = lerp_m(t, u, v);
q = g3[ b01 + bz1 ];
u = fast_at3(rx0,ry1,rz1,q);
q = g3[ b11 + bz1 ];
v = fast_at3(rx1,ry1,rz1,q);
b = lerp_m(t, u, v);
d = lerp_m(sy, a, b);
return lerp_m(sz, c, d);
}
F32 LLPerlinNoise::turbulence2(F32 x, F32 y, F32 freq)
{
F32 t, lx, ly;
for (t = 0.f ; freq >= 1.f ; freq *= 0.5f)
{
lx = freq * x;
ly = freq * y;
t += noise2(lx, ly)/freq;
}
return t;
}
F32 LLPerlinNoise::turbulence3(F32 x, F32 y, F32 z, F32 freq)
{
F32 t, lx, ly, lz;
for (t = 0.f ; freq >= 1.f ; freq *= 0.5f)
{
lx = freq * x;
ly = freq * y;
lz = freq * z;
t += noise3(lx,ly,lz)/freq;
// t += fabs(noise3(lx,ly,lz)) / freq; // Like snow - bubbly at low frequencies
// t += sqrt(fabs(noise3(lx,ly,lz))) / freq; // Better at low freq
// t += (noise3(lx,ly,lz)*noise3(lx,ly,lz)) / freq;
}
return t;
}
F32 LLPerlinNoise::clouds3(F32 x, F32 y, F32 z, F32 freq)
{
F32 t, lx, ly, lz;
for (t = 0.f ; freq >= 1.f ; freq *= 0.5f)
{
lx = freq * x;
ly = freq * y;
lz = freq * z;
// t += noise3(lx,ly,lz)/freq;
// t += fabs(noise3(lx,ly,lz)) / freq; // Like snow - bubbly at low frequencies
// t += sqrt(fabs(noise3(lx,ly,lz))) / freq; // Better at low freq
t += (noise3(lx,ly,lz)*noise3(lx,ly,lz)) / freq;
}
return t;
}

View File

@@ -27,20 +27,159 @@
#define LL_PERLIN_H #define LL_PERLIN_H
#include "stdtypes.h" #include "stdtypes.h"
#include "llmath.h"
#include "v2math.h"
#include "v3math.h"
// namespace wrapper // namespace wrapper
class LLPerlinNoise class LLPerlinNoise
{ {
public: public:
static F32 noise1(F32 x); template<typename T>
static F32 noise2(F32 x, F32 y); static F32 noise(const T& x, U32 wrap_at);
static F32 noise3(F32 x, F32 y, F32 z); template<typename T>
static F32 turbulence2(F32 x, F32 y, F32 freq); static F32 noise(const T& x)
static F32 turbulence3(F32 x, F32 y, F32 z, F32 freq); {
static F32 clouds3(F32 x, F32 y, F32 z, F32 freq); 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: private:
static bool sInitialized; static F32 s_curve(const F32 t)
static void init(void); {
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_ #endif // LL_PERLIN_

View File

@@ -35,15 +35,16 @@
#include "llpostprocess.h" #include "llpostprocess.h"
#include "lldir.h" #include "lldir.h"
#include "llfasttimer.h"
#include "llgl.h" #include "llgl.h"
#include "llglslshader.h" #include "llglslshader.h"
#include "llmatrix4a.h"
#include "llperlin.h"
#include "llrender.h" #include "llrender.h"
#include "llsdserialize.h" #include "llsdserialize.h"
#include "llsdutil.h" #include "llsdutil.h"
#include "llsdutil_math.h" #include "llsdutil_math.h"
#include "llvertexbuffer.h" #include "llvertexbuffer.h"
#include "llfasttimer.h"
#include "llmatrix4a.h"
extern LLGLSLShader gPostColorFilterProgram; extern LLGLSLShader gPostColorFilterProgram;
extern LLGLSLShader gPostNightVisionProgram; extern LLGLSLShader gPostNightVisionProgram;
@@ -457,7 +458,8 @@ void LLPostProcess::createNoiseTexture()
std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE); std::vector<GLubyte> buffer(NOISE_SIZE * NOISE_SIZE);
for (unsigned int i = 0; i < NOISE_SIZE; i++){ for (unsigned int i = 0; i < NOISE_SIZE; i++){
for (unsigned int k = 0; k < NOISE_SIZE; k++){ for (unsigned int k = 0; k < NOISE_SIZE; k++){
buffer[(i * NOISE_SIZE) + k] = (GLubyte)((double) rand() / ((double) RAND_MAX + 1.f) * 255.f); F32 pnoise = LLPerlinNoise::noise(LLVector2(i, k) * .5f) * (1.f/.7f);
buffer[i * NOISE_SIZE + k] = (GLubyte)(llclamp(.5f + pnoise * .5f, 0.f, 1.f) * 255.f);
} }
} }
@@ -637,8 +639,9 @@ void LLPostProcess::drawOrthoQuad(QuadType type)
mVBO->getTexCoord1Strider(uv2); mVBO->getTexCoord1Strider(uv2);
float offs[2] = { float offs[2] = {
llmath::llround(((float) rand() / (float) RAND_MAX) * (float)NOISE_SIZE)/float(NOISE_SIZE), /*llmath::llround*/(((float) rand() / (float) RAND_MAX) * (float)NOISE_SIZE)/float(NOISE_SIZE),
llmath::llround(((float) rand() / (float) RAND_MAX) * (float)NOISE_SIZE)/float(NOISE_SIZE) }; /*llmath::llround*/(((float) rand() / (float) RAND_MAX) * (float)NOISE_SIZE)/float(NOISE_SIZE)
};
float scale[2] = { float scale[2] = {
(float)mScreenWidth * mNoiseTextureScale, (float)mScreenWidth * mNoiseTextureScale,
(float)mScreenHeight * mNoiseTextureScale }; (float)mScreenHeight * mNoiseTextureScale };

View File

@@ -580,7 +580,6 @@ set(viewer_SOURCE_FILES
llworldmipmap.cpp llworldmipmap.cpp
llxmlrpcresponder.cpp llxmlrpcresponder.cpp
m7wlinterface.cpp m7wlinterface.cpp
noise.cpp
pipeline.cpp pipeline.cpp
qtoolalign.cpp qtoolalign.cpp
rlvactions.cpp rlvactions.cpp
@@ -1117,7 +1116,6 @@ set(viewer_HEADER_FILES
llxmlrpcresponder.h llxmlrpcresponder.h
m7wlinterface.h m7wlinterface.h
macmain.h macmain.h
noise.h
pipeline.h pipeline.h
qtoolalign.h qtoolalign.h
rlvactions.h rlvactions.h

View File

@@ -47,7 +47,7 @@
#include "llsky.h" #include "llsky.h"
#include "llviewercamera.h" #include "llviewercamera.h"
#include "llviewerregion.h" #include "llviewerregion.h"
#include "noise.h" #include "llperlin.h"
#include "pipeline.h" #include "pipeline.h"
#include "llviewershadermgr.h" #include "llviewershadermgr.h"
#include "llvovolume.h" #include "llvovolume.h"
@@ -1338,7 +1338,7 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV); sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_WIND, 1, wind.mV);
F32 phase = -1.f * (avatarp->mRipplePhase); F32 phase = -1.f * (avatarp->mRipplePhase);
F32 freq = 7.f + (noise1(avatarp->mRipplePhase) * 2.f); F32 freq = 7.f + (LLPerlinNoise::noise(avatarp->mRipplePhase) * 2.f);
LLVector4 sin_params(freq, freq, freq, phase); LLVector4 sin_params(freq, freq, freq, phase);
sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV); sVertexProgram->uniform4fv(LLViewerShaderMgr::AVATAR_SINWAVE, 1, sin_params.mV);

View File

@@ -41,7 +41,7 @@
#include "llviewerregion.h" #include "llviewerregion.h"
#include "llvlcomposition.h" #include "llvlcomposition.h"
#include "lldrawpool.h" #include "lldrawpool.h"
#include "noise.h" #include "llperlin.h"
extern bool gShiftFrame; extern bool gShiftFrame;
extern U64 gFrameTime; extern U64 gFrameTime;
@@ -230,12 +230,11 @@ void LLSurfacePatch::eval(const U32 x, const U32 y, const U32 stride, LLVector3
const F32 xyScale = 4.9215f*7.f; //0.93284f; const F32 xyScale = 4.9215f*7.f; //0.93284f;
const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f); const F32 xyScaleInv = (1.f / xyScale)*(0.2222222222f);
F32 vec[3] = { LLVector2 vec(
(F32)fmod((F32)(mOriginGlobal.mdV[0] + x)*xyScaleInv, 256.f), // <FS:ND/> Added (F32) for proper array initialization (F32)fmod((F32)(mOriginGlobal.mdV[0] + x)*xyScaleInv, 256.f), // <FS:ND/> Added (F32) for proper array initialization
(F32)fmod((F32)(mOriginGlobal.mdV[1] + y)*xyScaleInv, 256.f), // <FS:ND/> Added (F32) for proper array initialization (F32)fmod((F32)(mOriginGlobal.mdV[1] + y)*xyScaleInv, 256.f) // <FS:ND/> Added (F32) for proper array initialization
0.f );
}; F32 rand_val = llclamp(LLPerlinNoise::noise(vec)* 0.75f + 0.5f, 0.f, 1.f);
F32 rand_val = llclamp(noise2(vec)* 0.75f + 0.5f, 0.f, 1.f);
tex1->mV[1] = rand_val; tex1->mV[1] = rand_val;

View File

@@ -42,7 +42,7 @@
#include "llviewertexture.h" #include "llviewertexture.h"
#include "llviewertexturelist.h" #include "llviewertexturelist.h"
#include "llviewerregion.h" #include "llviewerregion.h"
#include "noise.h" #include "llperlin.h"
#include "llregionhandle.h" // for from_region_handle #include "llregionhandle.h" // for from_region_handle
#include "llviewercontrol.h" #include "llviewercontrol.h"
@@ -152,7 +152,7 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
// For perlin noise generation... // For perlin noise generation...
const F32 slope_squared = 1.5f*1.5f; const F32 slope_squared = 1.5f*1.5f;
const F32 xyScale = 4.9215f; //0.93284f; const F32 xyScale = 4.9215f; //0.93284f;
const F32 zScale = 4; //0.92165f; //const F32 zScale = 4; //0.92165f; //Unused
const F32 z_offset = 0.f; const F32 z_offset = 0.f;
const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus
// simple height) // simple height)
@@ -162,7 +162,7 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
const S32 NUM_TEXTURES = 4; const S32 NUM_TEXTURES = 4;
const F32 xyScaleInv = (1.f / xyScale); const F32 xyScaleInv = (1.f / xyScale);
const F32 zScaleInv = (1.f / zScale); //const F32 zScaleInv = (1.f / zScale); //Unused
// <FS:CR> Aurora Sim // <FS:CR> Aurora Sim
//const F32 inv_width = 1.f/mWidth; //const F32 inv_width = 1.f/mWidth;
@@ -174,9 +174,6 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
{ {
for (S32 i = x_begin; i < x_end; i++) for (S32 i = x_begin; i < x_end; i++)
{ {
F32 vec[3];
F32 vec1[3];
F32 twiddle; F32 twiddle;
// Bilinearly interpolate the start height and height range of the textures // Bilinearly interpolate the start height and height range of the textures
@@ -196,18 +193,18 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y,
F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; F32 height = mSurfacep->resolveHeightRegion(location) + z_offset;
// Step 0: Measure the exact height at this texel // Step 0: Measure the exact height at this texel
vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice
vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; // Adjust to non - integer lattice
vec[2] = height*zScaleInv; LLVector2 vec = (LLVector2(LLVector3(origin_global)) + LLVector2(location));
vec *= xyScaleInv;
//vec[VZ] = height*zScaleInv; //Unused.
// //
// Choose material value by adding to the exact height a random value // Choose material value by adding to the exact height a random value
// //
vec1[0] = vec[0]*(0.2222222222f); twiddle = LLPerlinNoise::noise(vec*0.2222222222f)*6.5f; // Low freq component for large divisions
vec1[1] = vec[1]*(0.2222222222f);
vec1[2] = vec[2]*(0.2222222222f);
twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions
twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component twiddle += LLPerlinNoise::turbulence(vec, 2.f)*slope_squared; // High frequency component
twiddle *= noise_magnitude; twiddle *= noise_magnitude;
F32 scaled_noisy_height = (height + twiddle - start_height) * F32(NUM_TEXTURES) / height_range; F32 scaled_noisy_height = (height + twiddle - start_height) * F32(NUM_TEXTURES) / height_range;

View File

@@ -38,7 +38,7 @@
#include <ctype.h> #include <ctype.h>
#include "llaudioengine.h" #include "llaudioengine.h"
#include "noise.h" #include "llperlin.h"
#include "raytrace.h" #include "raytrace.h"
#include "llagent.h" // Get state values from here #include "llagent.h" // Get state values from here
@@ -412,14 +412,8 @@ public:
// must return FALSE when the motion is completed. // must return FALSE when the motion is completed.
virtual BOOL onUpdate(F32 time, U8* joint_mask) virtual BOOL onUpdate(F32 time, U8* joint_mask)
{ {
F32 nx[2]; F32 noiseX = LLPerlinNoise::noise(LLVector2(time*TORSO_NOISE_SPEED, 0));
nx[0]=time*TORSO_NOISE_SPEED; F32 noiseY = LLPerlinNoise::noise(LLVector2(0, time*TORSO_NOISE_SPEED));
nx[1]=0.0f;
F32 ny[2];
ny[0]=0.0f;
ny[1]=time*TORSO_NOISE_SPEED;
F32 noiseX = noise2(nx);
F32 noiseY = noise2(ny);
F32 rx = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseX / 0.42f; F32 rx = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseX / 0.42f;
F32 ry = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseY / 0.42f; F32 ry = TORSO_NOISE_AMOUNT * DEG_TO_RAD * noiseY / 0.42f;
@@ -3030,7 +3024,7 @@ void LLVOAvatar::idleUpdateWindEffect()
} }
mWindVec = lerp(mWindVec, wind, interp); mWindVec = lerp(mWindVec, wind, interp);
F32 wind_freq = hover_strength + llclamp(8.f + (speed * 0.7f) + (noise1(mRipplePhase) * 4.f), 8.f, 25.f); F32 wind_freq = hover_strength + llclamp(8.f + (speed * 0.7f) + (LLPerlinNoise::noise(mRipplePhase) * 4.f), 8.f, 25.f);
mWindFreq = lerp(mWindFreq, wind_freq, interp); mWindFreq = lerp(mWindFreq, wind_freq, interp);
if (mBelowWater) if (mBelowWater)
@@ -3039,9 +3033,9 @@ void LLVOAvatar::idleUpdateWindEffect()
} }
mRipplePhase += (time_delta * mWindFreq); mRipplePhase += (time_delta * mWindFreq);
if (mRipplePhase > F_TWO_PI) if (mRipplePhase > 256.f)
{ {
mRipplePhase = fmodf(mRipplePhase, F_TWO_PI); mRipplePhase = fmodf(mRipplePhase, 256.f);
} }
} }
} }

View File

@@ -841,7 +841,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable)
sin(nangle * DEG_TO_RAD)*start_radius*nvec_scale, sin(nangle * DEG_TO_RAD)*start_radius*nvec_scale,
z*nvec_scalez); z*nvec_scalez);
// First and last slice at 0 radius (to bring in top/bottom of structure) // First and last slice at 0 radius (to bring in top/bottom of structure)
radius = start_radius + turbulence3((F32*)&nvec.mV, (F32)fractal_depth)*noise_scale; radius = start_radius + LLPerlinNoise::turbulence(nvec, (F32)fractal_depth)*noise_scale;
if (slices - 1 == j) if (slices - 1 == j)
{ {

View File

@@ -1,90 +0,0 @@
/**
* @file noise.cpp
* @brief Perlin noise routines for procedural textures, etc
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#include "llviewerprecompiledheaders.h"
#include "noise.h"
#include "llrand.h"
// static
#define B 0x100
S32 p[B + B + 2];
F32 g3[B + B + 2][3];
F32 g2[B + B + 2][2];
F32 g1[B + B + 2];
S32 gNoiseStart = 1;
F32 noise2(F32 *vec)
{
U8 bx0, bx1, by0, by1;
U32 b00, b10, b01, b11;
F32 rx0, rx1, ry0, ry1, *q, sx, sy, a, b, u, v;
S32 i, j;
if (gNoiseStart) {
gNoiseStart = 0;
init();
}
fast_setup(*vec, bx0, bx1, rx0, rx1);
fast_setup(*(vec + 1), by0, by1, ry0, ry1);
i = *(p + bx0);
j = *(p + bx1);
b00 = *(p + i + by0);
b10 = *(p + j + by0);
b01 = *(p + i + by1);
b11 = *(p + j + by1);
sx = s_curve(rx0);
sy = s_curve(ry0);
q = *(g2 + b00);
u = fast_at2(rx0, ry0, q);
q = *(g2 + b10);
v = fast_at2(rx1, ry0, q);
a = lerp_m(sx, u, v);
q = *(g2 + b01);
u = fast_at2(rx0,ry1,q);
q = *(g2 + b11);
v = fast_at2(rx1,ry1,q);
b = lerp_m(sx, u, v);
return lerp_m(sy, a, b);
}

View File

@@ -1,363 +0,0 @@
/**
* @file noise.h
* @brief Perlin noise routines for procedural textures, etc
*
* $LicenseInfo:firstyear=2000&license=viewergpl$
*
* Copyright (c) 2000-2009, Linden Research, Inc.
*
* Second Life Viewer Source Code
* The source code in this file ("Source Code") is provided by Linden Lab
* to you under the terms of the GNU General Public License, version 2.0
* ("GPL"), unless you have obtained a separate licensing agreement
* ("Other License"), formally executed by you and Linden Lab. Terms of
* the GPL can be found in doc/GPL-license.txt in this distribution, or
* online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
*
* There are special exceptions to the terms and conditions of the GPL as
* it is applied to this Source Code. View the full text of the exception
* in the file doc/FLOSS-exception.txt in this software distribution, or
* online at
* http://secondlifegrid.net/programs/open_source/licensing/flossexception
*
* By copying, modifying or distributing this software, you acknowledge
* that you have read and understood your obligations described above,
* and agree to abide by those obligations.
*
* ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
* WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
* COMPLETENESS OR PERFORMANCE.
* $/LicenseInfo$
*/
#ifndef LL_NOISE_H
#define LL_NOISE_H
#include "llmath.h"
F32 turbulence2(F32 *v, F32 freq);
F32 turbulence3(float *v, float freq);
F32 clouds3(float *v, float freq);
F32 noise2(float *vec);
F32 noise3(float *vec);
inline F32 bias(F32 a, F32 b)
{
return (F32)pow(a, (F32)(log(b) / log(0.5f)));
}
inline F32 gain(F32 a, F32 b)
{
F32 p = (F32) (log(1.f - b) / log(0.5f));
if (a < .001f)
return 0.f;
else if (a > .999f)
return 1.f;
if (a < 0.5f)
return (F32)(pow(2 * a, p) / 2.f);
else
return (F32)(1.f - pow(2 * (1.f - a), p) / 2.f);
}
inline F32 turbulence2(F32 *v, F32 freq)
{
F32 t, vec[2];
for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
vec[0] = freq * v[0];
vec[1] = freq * v[1];
t += noise2(vec)/freq;
}
return t;
}
inline F32 turbulence3(F32 *v, F32 freq)
{
F32 t, vec[3];
for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
vec[0] = freq * v[0];
vec[1] = freq * v[1];
vec[2] = freq * v[2];
t += noise3(vec)/freq;
// t += fabs(noise3(vec)) / freq; // Like snow - bubbly at low frequencies
// t += sqrt(fabs(noise3(vec))) / freq; // Better at low freq
// t += (noise3(vec)*noise3(vec)) / freq;
}
return t;
}
inline F32 clouds3(F32 *v, F32 freq)
{
F32 t, vec[3];
for (t = 0.f ; freq >= 1.f ; freq *= 0.5f) {
vec[0] = freq * v[0];
vec[1] = freq * v[1];
vec[2] = freq * v[2];
//t += noise3(vec)/freq;
// t += fabs(noise3(vec)) / freq; // Like snow - bubbly at low frequencies
// t += sqrt(fabs(noise3(vec))) / freq; // Better at low freq
t += (noise3(vec)*noise3(vec)) / freq;
}
return t;
}
/* noise functions over 1, 2, and 3 dimensions */
#define B 0x100
#define BM 0xff
#define N 0x1000
#define NF32 (4096.f)
#define NP 12 /* 2^N */
#define NM 0xfff
extern S32 p[B + B + 2];
extern F32 g3[B + B + 2][3];
extern F32 g2[B + B + 2][2];
extern F32 g1[B + B + 2];
extern S32 gNoiseStart;
static void init(void);
#define s_curve(t) ( t * t * (3.f - 2.f * t) )
#define lerp_m(t, a, b) ( a + t * (b - a) )
#define setup_noise(i,b0,b1,r0,r1)\
t = vec[i] + N;\
b0 = (lltrunc(t)) & BM;\
b1 = (b0+1) & BM;\
r0 = t - lltrunc(t);\
r1 = r0 - 1.f;
inline void fast_setup(F32 vec, U8 &b0, U8 &b1, F32 &r0, F32 &r1)
{
S32 t_S32;
r1 = vec + NF32;
t_S32 = lltrunc(r1);
b0 = (U8)t_S32;
b1 = b0 + 1;
r0 = r1 - t_S32;
r1 = r0 - 1.f;
}
inline F32 noise1(const F32 arg)
{
int bx0, bx1;
F32 rx0, rx1, sx, t, u, v, vec[1];
vec[0] = arg;
if (gNoiseStart) {
gNoiseStart = 0;
init();
}
setup_noise(0, bx0,bx1, rx0,rx1);
sx = s_curve(rx0);
u = rx0 * g1[ p[ bx0 ] ];
v = rx1 * g1[ p[ bx1 ] ];
return lerp_m(sx, u, v);
}
inline F32 fast_at2(F32 rx, F32 ry, F32 *q)
{
return rx * (*q) + ry * (*(q + 1));
}
inline F32 fast_at3(F32 rx, F32 ry, F32 rz, F32 *q)
{
return rx * (*q) + ry * (*(q + 1)) + rz * (*(q + 2));
}
inline F32 noise3(F32 *vec)
{
U8 bx0, bx1, by0, by1, bz0, bz1;
S32 b00, b10, b01, b11;
F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
S32 i, j;
if (gNoiseStart) {
gNoiseStart = 0;
init();
}
fast_setup(*vec, bx0,bx1, rx0,rx1);
fast_setup(*(vec + 1), by0,by1, ry0,ry1);
fast_setup(*(vec + 2), bz0,bz1, rz0,rz1);
i = p[ bx0 ];
j = p[ bx1 ];
b00 = p[ i + by0 ];
b10 = p[ j + by0 ];
b01 = p[ i + by1 ];
b11 = p[ j + by1 ];
t = s_curve(rx0);
sy = s_curve(ry0);
sz = s_curve(rz0);
q = g3[ b00 + bz0 ];
u = fast_at3(rx0,ry0,rz0,q);
q = g3[ b10 + bz0 ];
v = fast_at3(rx1,ry0,rz0,q);
a = lerp_m(t, u, v);
q = g3[ b01 + bz0 ];
u = fast_at3(rx0,ry1,rz0,q);
q = g3[ b11 + bz0 ];
v = fast_at3(rx1,ry1,rz0,q);
b = lerp_m(t, u, v);
c = lerp_m(sy, a, b);
q = g3[ b00 + bz1 ];
u = fast_at3(rx0,ry0,rz1,q);
q = g3[ b10 + bz1 ];
v = fast_at3(rx1,ry0,rz1,q);
a = lerp_m(t, u, v);
q = g3[ b01 + bz1 ];
u = fast_at3(rx0,ry1,rz1,q);
q = g3[ b11 + bz1 ];
v = fast_at3(rx1,ry1,rz1,q);
b = lerp_m(t, u, v);
d = lerp_m(sy, a, b);
return lerp_m(sz, c, d);
}
/*
F32 noise3(F32 *vec)
{
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
F32 rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
S32 i, j;
if (gNoiseStart) {
gNoiseStart = 0;
init();
}
setup_noise(0, bx0,bx1, rx0,rx1);
setup_noise(1, by0,by1, ry0,ry1);
setup_noise(2, bz0,bz1, rz0,rz1);
i = p[ bx0 ];
j = p[ bx1 ];
b00 = p[ i + by0 ];
b10 = p[ j + by0 ];
b01 = p[ i + by1 ];
b11 = p[ j + by1 ];
t = s_curve(rx0);
sy = s_curve(ry0);
sz = s_curve(rz0);
#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
a = lerp_m(t, u, v);
q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
b = lerp_m(t, u, v);
c = lerp_m(sy, a, b);
q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
a = lerp_m(t, u, v);
q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
b = lerp_m(t, u, v);
d = lerp_m(sy, a, b);
return lerp_m(sz, c, d);
}
*/
static void normalize2(F32 v[2])
{
F32 s;
s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1]);
v[0] = v[0] * s;
v[1] = v[1] * s;
}
static void normalize3(F32 v[3])
{
F32 s;
s = 1.f/(F32)sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
v[0] = v[0] * s;
v[1] = v[1] * s;
v[2] = v[2] * s;
}
static void init(void)
{
// we want repeatable noise (e.g. for stable terrain texturing), so seed with known value
srand(42);
int i, j, k;
for (i = 0 ; i < B ; i++) {
p[i] = i;
g1[i] = (F32)((rand() % (B + B)) - B) / B;
for (j = 0 ; j < 2 ; j++)
g2[i][j] = (F32)((rand() % (B + B)) - B) / B;
normalize2(g2[i]);
for (j = 0 ; j < 3 ; j++)
g3[i][j] = (F32)((rand() % (B + B)) - B) / B;
normalize3(g3[i]);
}
while (--i) {
k = p[i];
p[i] = p[j = rand() % B];
p[j] = k;
}
for (i = 0 ; i < B + 2 ; i++) {
p[B + i] = p[i];
g1[B + i] = g1[i];
for (j = 0 ; j < 2 ; j++)
g2[B + i][j] = g2[i][j];
for (j = 0 ; j < 3 ; j++)
g3[B + i][j] = g3[i][j];
}
// reintroduce entropy
srand(time(NULL)); // Flawfinder: ignore
}
#undef B
#undef BM
#undef N
#undef NF32
#undef NP
#undef NM
#endif // LL_NOISE_