1#include "NoiseSampler.h"
28 NoiseSampler::NoiseSampler(
unsigned int seed)
33 std::minstd_rand eng(seed);
34 std::uniform_int_distribution<int> dist(0, RAND_MAX);
36 permutationTable.resize(256);
37 for (
unsigned i = 0; i < 256; i++) {
38 permutationTable[i] =
static_cast<uint8_t
>(i);
40 for (
int i = 255; i > 0; i--) {
41 int j = dist(eng) / ((RAND_MAX / i) + 1);
42 std::swap(permutationTable[j], permutationTable[i]);
46 gradient2DTable.resize(256 * 2);
47 for (
int i = 0; i < 256; i++) {
48 float theta = dist(eng) * (float((2.0f * glm::pi<float>()) /
float(RAND_MAX))) - 1.f;
49 gradient2DTable[2 * i + 0] = std::cos(theta);
50 gradient2DTable[2 * i + 1] = std::sin(theta);
55 float NoiseSampler::gradNoise2D(glm::vec2 t, glm::ivec2 period)
57 glm::vec2 ti = glm::floor(t);
59 glm::ivec2 tl(
int(ti.x) % period.x,
int(ti.y) % period.y);
60 glm::ivec2 tq((tl.x + 1) % period.x, (tl.y + 1) % period.y);
62 glm::vec2 tf = t - ti;
63 glm::vec2 sf = glm::vec2(1.f) - tf;
82 glm::vec2 phi_t = tf*tf*tf*(6.f*tf*tf - 15.f*tf + 10.f);
83 glm::vec2 phi_s = glm::vec2(1.f) - phi_t;
85 int l0x = permutationTable[tl.x & 0xff];
86 int l00 = (permutationTable[(l0x + tl.y)&0xff]);
87 int l01 = (permutationTable[(l0x + tq.y)&0xff]);
88 int l1x = permutationTable[tq.x & 0xff];
89 int l10 = (permutationTable[(l1x + tl.y)&0xff]);
90 int l11 = (permutationTable[(l1x + tq.y)&0xff]);
93 float vy0 = (grad2D[l00&0x3][0] * tf.x + grad2D[l00&0x3][1] * tf.y)*phi_s.x
94 + (grad2D[l10&0x3][0] * sf.x + grad2D[l10&0x3][1] * tf.y)*phi_t.x;
95 float vy1 = (grad2D[l01&0x3][0] * tf.x + grad2D[l01&0x3][1] * sf.y)*phi_s.x
96 + (grad2D[l11&0x3][0] * sf.x + grad2D[l11&0x3][1] * sf.y)*phi_t.x;
98 float vy0 = (gradient2DTable[2 * l00 + 0] * tf.x + gradient2DTable[2 * l00 + 1] * tf.y)*phi_s.x
99 + (gradient2DTable[2 * l10 + 0] * sf.x + gradient2DTable[2 * l10 + 1] * tf.y)*phi_t.x;
101 float vy1 = (gradient2DTable[2 * l01 + 0] * tf.x + gradient2DTable[2 * l01 + 1] * sf.y)*phi_s.x
102 + (gradient2DTable[2 * l11 + 0] * sf.x + gradient2DTable[2 * l11 + 1] * sf.y)*phi_t.x;
105 return vy0*phi_s.y + vy1*phi_t.y;
108 void NoiseSampler::gradNoise2D(
float* dst,
float frequency,
int w,
int h)
110 glm::ivec2 period(w/frequency, h/frequency);
112 float a = 1.f / std::max(w, h);
113 for (
int j = 0; j < h; j++) {
114 float v = a*
static_cast<float>(j);
115 for (
int i = 0; i < w; i++) {
116 float u = a*
static_cast<float>(i);
117 dst[j*w + i] = gradNoise2D(frequency*glm::vec2(u+0.5f, v+0.5f), period);
122 void NoiseSampler::gradNoise2DSum(
float* dst,
float frequency_min,
float frequency_max,
int w,
int h)
124 std::vector<glm::vec4> param;
125 std::vector<glm::ivec2> periods;
126 for (
float f = frequency_min; f < frequency_max; f = f * 2) {
127 param.push_back(glm::vec4(1.f / f, 1.f / f, f, 2.f*frequency_min / f));
128 periods.push_back(glm::ivec2(w / f, h / f));
131 float a = 1.f / std::max(w, h);
133 for (
int j = 0; j < h; j++) {
134 float v = a*
static_cast<float>(j);
135 for (
int i = 0; i < w; i++) {
136 float u = a*
static_cast<float>(i);
139 for (
size_t k = 0; k < periods.size(); k++) {
140 sum += param[k].w*gradNoise2D(param[k].z*glm::vec2(u + 0.5f, v + 0.5f), periods[k]);
147 void NoiseSampler::gradNoise2DTurbulence(
float* dst,
float frequency_min,
float frequency_max,
int w,
int h)
149 std::vector<glm::vec4> param;
150 std::vector<glm::ivec2> periods;
151 for (
float f = frequency_min; f < frequency_max; f = f * 2) {
152 param.push_back(glm::vec4(1.f / f, 1.f / f, f, 2.f*frequency_min / f));
153 periods.push_back(glm::ivec2(w / f, h / f));
157 float a = 1.f / std::max(w, h);
159 for (
int j = 0; j < h; j++) {
160 float v = a*
static_cast<float>(j);
161 for (
int i = 0; i < w; i++) {
162 float u = a*
static_cast<float>(i);
165 for (
size_t k = 0; k < periods.size(); k++) {
166 sum += std::abs(param[k].w*gradNoise2D(param[k].z*glm::vec2(u+0.5f, v+0.5f), periods[k]));
168 dst[j*w + i] = sum - 1.f;
Contains all Cogs related functionality.