cloudy-raytracer/common/noise/cloudnoise.cpp

69 lines
No EOL
2.3 KiB
C++

#include <chrono>
#include <iostream>
#include <thread>
#include "cloudnoise.h"
CloudNoise::CloudNoise(int size, unsigned int seed) : Noise(size), worleyNoise1(WorleyNoise(std::min(LOWRES_SIZE, size), 3, seed)),
worleyNoise3(WorleyNoise(size, 15, seed)),
perlinNoise1(PerlinNoise(std::min(LOWRES_SIZE, size), 3, seed)),
perlinNoise2(PerlinNoise(size, 15, seed))
{
auto start = std::chrono::high_resolution_clock::now();
// Generate the noise
int const nThreads = (int) std::thread::hardware_concurrency() - 1;
int threadSize = std::floor((float) size / (float) nThreads);
int remaining = size - nThreads * threadSize;
std::vector<std::thread> threads;
for (int n = 0; n < nThreads; n++)
{
threads.emplace_back(runCloudNoiseInThread, n * threadSize, threadSize, this);
}
renderNoiseThread(nThreads * threadSize, remaining);
// Rejoin the threads
for (int t = 0; t < nThreads; ++t)
{
threads[t].join();
}
// Duration of computation
auto stop = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::seconds>(stop - start);
std::cout << "Finished computing Cloud noise for size " << size << " in "
<< duration.count() << " seconds" << std::endl;
}
void CloudNoise::runCloudNoiseInThread(int xOffset, int xSize, CloudNoise *noise)
{
noise->renderNoiseThread(xOffset, xSize);
}
void CloudNoise::renderNoiseThread(int xOffset, int xSize)
{
for (int x = xOffset; x < xOffset + xSize; x++)
{
for (int y = 0; y < size; y++)
{
for (int z = 0; z < size; z++)
{
float sx = x / (float) size;
float sy = y / (float) size;
float sz = z / (float) size;
float worley1 = worleyNoise1.getNoise(sx, sy, sz);
float worley3 = worleyNoise3.getNoise(sx, sy, sz);
float perlin1 = perlinNoise1.getNoise(sx, sy, sz);
float perlin2 = perlinNoise2.getNoise(sx, sy, sz);
float noise = worley1 * 0.4f + worley3 * 0.12f + perlin1 * 0.36f + perlin2 * 0.12;
setNoise(x, y, z, noise);
}
}
}
}