-
Notifications
You must be signed in to change notification settings - Fork 0
/
SphericalPerlinNoise.cpp
64 lines (51 loc) · 1.74 KB
/
SphericalPerlinNoise.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
#include <stdexcept>
#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb/stb_image_write.h"
#include "PerlinNoise/PerlinNoise.hpp"
#define _USE_MATH_DEFINES
#include <math.h>
static const auto s_help = "usage: executable.exe filename width height (seed)";
// program arguments filename, width, height, (seed)
int main(int argc, char** argv) try
{
if (argc < 4) throw std::runtime_error(s_help);
auto dstFilename = argv[1];
int width = atoi(argv[2]);
int height = atoi(argv[3]);
uint32_t seed = 420;
if (argc >= 5) seed = atoi(argv[4]);
if (width < 0 || height < 0) throw std::runtime_error("invalid width or height");
// storage
std::vector<uint8_t> pixels;
pixels.resize(width * height);
// generate samples
auto curPixel = pixels.begin();
siv::BasicPerlinNoise<float> perlin(seed);
std::cout << "generating texture:\n";
for (int v = 0; v < height; ++v)
{
for (int u = 0; u < width; ++u)
{
auto& pixel = *curPixel;
// convert u, v to direction
float theta = float(u) * 2.0f * float(M_PI) / float(width);
float phi = float(v) * float(M_PI) / float(height);
float y = cos(phi);
float x = sin(phi) * cos(theta);
float z = sin(phi) * sin(theta);
// lookup perlin noise
float perlinValue = perlin.accumulatedOctaveNoise3D_0_1(x, y, z, 32);
pixel = uint8_t(perlinValue * 255.0f);
++curPixel;
}
std::cout << '\r' << v + 1 << "/" << height;
}
stbi_write_png(dstFilename, width, height, 1, pixels.data(), width);
return 0;
}
catch (const std::exception& e)
{
std::cerr << "Error: " << e.what();
return -1;
}