noise features, fixed some grid stuff.
This commit is contained in:
@@ -22,8 +22,8 @@
|
|||||||
struct defaults {
|
struct defaults {
|
||||||
int outWidth = 512;
|
int outWidth = 512;
|
||||||
int outHeight = 512;
|
int outHeight = 512;
|
||||||
int gridWidth = 64;
|
int gridWidth = 512;
|
||||||
int gridHeight = 64;
|
int gridHeight = 512;
|
||||||
int gridDepth = 64;
|
int gridDepth = 64;
|
||||||
float fps = 30.0f;
|
float fps = 30.0f;
|
||||||
PNoise2 noise = PNoise2(42);
|
PNoise2 noise = PNoise2(42);
|
||||||
@@ -51,6 +51,18 @@ void setup(defaults config, VoxelGrid& grid) {
|
|||||||
uint8_t threshold = 0.1 * 255;
|
uint8_t threshold = 0.1 * 255;
|
||||||
grid.resize(config.gridWidth, config.gridHeight, config.gridDepth);
|
grid.resize(config.gridWidth, config.gridHeight, config.gridDepth);
|
||||||
std::cout << "Generating grid of size " << config.gridWidth << "x" << config.gridHeight << "x" << config.gridDepth << std::endl;
|
std::cout << "Generating grid of size " << config.gridWidth << "x" << config.gridHeight << "x" << config.gridDepth << std::endl;
|
||||||
|
size_t rValw = config.gridWidth / 64;
|
||||||
|
size_t rValh = config.gridHeight / 64;
|
||||||
|
size_t rVald = config.gridDepth / 64;
|
||||||
|
size_t gValw = config.gridWidth / 32;
|
||||||
|
size_t gValh = config.gridHeight / 32;
|
||||||
|
size_t gVald = config.gridDepth / 32;
|
||||||
|
size_t bValw = config.gridWidth / 16;
|
||||||
|
size_t bValh = config.gridHeight / 16;
|
||||||
|
size_t bVald = config.gridDepth / 16;
|
||||||
|
size_t aValw = config.gridWidth / 8;
|
||||||
|
size_t aValh = config.gridHeight / 8;
|
||||||
|
size_t aVald = config.gridDepth / 8;
|
||||||
for (int z = 0; z < config.gridDepth; ++z) {
|
for (int z = 0; z < config.gridDepth; ++z) {
|
||||||
if (z % 64 == 0) {
|
if (z % 64 == 0) {
|
||||||
std::cout << "Processing layer " << z << " of " << config.gridDepth << std::endl;
|
std::cout << "Processing layer " << z << " of " << config.gridDepth << std::endl;
|
||||||
@@ -58,10 +70,10 @@ void setup(defaults config, VoxelGrid& grid) {
|
|||||||
|
|
||||||
for (int y = 0; y < config.gridHeight; ++y) {
|
for (int y = 0; y < config.gridHeight; ++y) {
|
||||||
for (int x = 0; x < config.gridWidth; ++x) {
|
for (int x = 0; x < config.gridWidth; ++x) {
|
||||||
uint8_t r = config.noise.permute(Vec3f(static_cast<float>(x) / config.gridWidth / 64, static_cast<float>(y) / config.gridHeight / 64, static_cast<float>(z) / config.gridDepth / 64)) * 255;
|
uint8_t r = config.noise.permute(Vec3f(static_cast<float>(x) * rValw, static_cast<float>(y) * rValh, static_cast<float>(z) * rVald)) * 255;
|
||||||
uint8_t g = config.noise.permute(Vec3f(static_cast<float>(x) / config.gridWidth / 32, static_cast<float>(y) / config.gridHeight / 32, static_cast<float>(z) / config.gridDepth / 32)) * 255;
|
uint8_t g = config.noise.permute(Vec3f(static_cast<float>(x) * gValw, static_cast<float>(y) * gValh, static_cast<float>(z) * gVald)) * 255;
|
||||||
uint8_t b = config.noise.permute(Vec3f(static_cast<float>(x) / config.gridWidth / 16, static_cast<float>(y) / config.gridHeight / 16, static_cast<float>(z) / config.gridDepth / 16)) * 255;
|
uint8_t b = config.noise.permute(Vec3f(static_cast<float>(x) * bValw, static_cast<float>(y) * bValh, static_cast<float>(z) * bVald)) * 255;
|
||||||
uint8_t a = config.noise.permute(Vec3f(static_cast<float>(x) / config.gridWidth / 8 , static_cast<float>(y) / config.gridHeight / 8 , static_cast<float>(z) / config.gridDepth / 8)) * 255;
|
uint8_t a = config.noise.permute(Vec3f(static_cast<float>(x) * aValw, static_cast<float>(y) * aValh, static_cast<float>(z) * aVald)) * 255;
|
||||||
//Vec4ui8 noisecolor = config.noise.permuteColor(Vec3f( static_cast<float>(x) / 64, static_cast<float>(y) / 64, static_cast<float>(z) / 64));
|
//Vec4ui8 noisecolor = config.noise.permuteColor(Vec3f( static_cast<float>(x) / 64, static_cast<float>(y) / 64, static_cast<float>(z) / 64));
|
||||||
if (a > threshold) {
|
if (a > threshold) {
|
||||||
//std::cout << "setting a position" << std::endl;
|
//std::cout << "setting a position" << std::endl;
|
||||||
@@ -155,6 +167,14 @@ void stopAndSaveAVI(defaults& config, const std::string& filename) {
|
|||||||
recordingFramesRemaining = 0;
|
recordingFramesRemaining = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void saveSlices(defaults& config, VoxelGrid& grid) {
|
||||||
|
std::vector<frame> frames = grid.genSlices(frame::colormap::RGB);
|
||||||
|
for (int i = 0; i < frames.size(); i++) {
|
||||||
|
std::string filename = "output/slices/" + std::to_string(i) + ".bmp";
|
||||||
|
BMPWriter::saveBMP(filename, frames[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void glfw_error_callback(int error, const char* description)
|
static void glfw_error_callback(int error, const char* description)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
fprintf(stderr, "GLFW Error %d: %s\n", error, description);
|
||||||
@@ -341,6 +361,10 @@ int main() {
|
|||||||
cameraMoved = true;
|
cameraMoved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ImGui::Button("Save Slices")) {
|
||||||
|
saveSlices(config, grid);
|
||||||
|
}
|
||||||
|
|
||||||
// AVI Recording Controls
|
// AVI Recording Controls
|
||||||
ImGui::Separator();
|
ImGui::Separator();
|
||||||
ImGui::Text("AVI Recording:");
|
ImGui::Text("AVI Recording:");
|
||||||
|
|||||||
@@ -660,6 +660,89 @@ public:
|
|||||||
return meshDirty;
|
return meshDirty;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::vector<frame> genSlices(frame::colormap colorFormat = frame::colormap::RGB) const {
|
||||||
|
TIME_FUNCTION;
|
||||||
|
int colors;
|
||||||
|
std::vector<frame> outframes;
|
||||||
|
switch (colorFormat) {
|
||||||
|
case frame::colormap::RGBA:
|
||||||
|
case frame::colormap::BGRA: {
|
||||||
|
colors = 4;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case frame::colormap::B: {
|
||||||
|
colors = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case frame::colormap::RGB:
|
||||||
|
case frame::colormap::BGR:
|
||||||
|
default: {
|
||||||
|
colors = 3;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size_t cbsize = gridSize.x * gridSize.y * colors;
|
||||||
|
for (int layer = 0; layer < getDepth(); layer++) {
|
||||||
|
int layerMult = layer * gridSize.x * gridSize.y;
|
||||||
|
frame layerFrame(gridSize.x, gridSize.y, colorFormat);
|
||||||
|
std::vector<uint8_t> colorBuffer(cbsize);
|
||||||
|
for (int y = 0; y < gridSize.y; y++) {
|
||||||
|
int yMult = layerMult + (y * gridSize.x);
|
||||||
|
for (int x = 0; x < gridSize.x; x++) {
|
||||||
|
int vidx = yMult+x;
|
||||||
|
int pidx = (y * gridSize.x + x) * colors;
|
||||||
|
Voxel cv = voxels[vidx];
|
||||||
|
Vec3ui8 cvColor;
|
||||||
|
float cvAlpha;
|
||||||
|
if (cv.active) {
|
||||||
|
cvColor = cv.color;
|
||||||
|
cvAlpha = cv.alpha;
|
||||||
|
} else {
|
||||||
|
cvColor = Vec3ui8(255,255,255);
|
||||||
|
cvAlpha = 255;
|
||||||
|
}
|
||||||
|
switch (colorFormat) {
|
||||||
|
case frame::colormap::RGBA: {
|
||||||
|
colorBuffer[pidx + 1] = cvColor.x;
|
||||||
|
colorBuffer[pidx + 2] = cvColor.y;
|
||||||
|
colorBuffer[pidx + 3] = cvColor.z;
|
||||||
|
colorBuffer[pidx + 0] = cvAlpha;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case frame::colormap::BGRA: {
|
||||||
|
colorBuffer[pidx + 3] = cvColor.x;
|
||||||
|
colorBuffer[pidx + 2] = cvColor.y;
|
||||||
|
colorBuffer[pidx + 1] = cvColor.z;
|
||||||
|
colorBuffer[pidx + 0] = cvAlpha;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case frame::colormap::RGB: {
|
||||||
|
colorBuffer[pidx + 1] = cvColor.x;
|
||||||
|
colorBuffer[pidx + 2] = cvColor.y;
|
||||||
|
colorBuffer[pidx + 3] = cvColor.z;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case frame::colormap::BGR: {
|
||||||
|
colorBuffer[pidx + 3] = cvColor.x;
|
||||||
|
colorBuffer[pidx + 2] = cvColor.y;
|
||||||
|
colorBuffer[pidx + 1] = cvColor.z;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case frame::colormap::B: {
|
||||||
|
colorBuffer[pidx] = (cvColor.x * 0.299) + (cvColor.y * 0.587) + (cvColor.z * 0.114);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layerFrame.setData(colorBuffer);
|
||||||
|
//layerFrame.compressFrameLZ78();
|
||||||
|
outframes.emplace_back(layerFrame);
|
||||||
|
}
|
||||||
|
return outframes;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
//#include "g3_serialization.hpp" needed to be usable
|
//#include "g3_serialization.hpp" needed to be usable
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,30 @@ private:
|
|||||||
permutation.insert(permutation.end(), permutationt.begin(), permutationt.end());
|
permutation.insert(permutation.end(), permutationt.begin(), permutationt.end());
|
||||||
permutation.insert(permutation.end(), permutationt.begin(), permutationt.end());
|
permutation.insert(permutation.end(), permutationt.begin(), permutationt.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float normalizedNoise(const Vec2<float>& point) {
|
||||||
|
return (permute(point) + 1.0f) * 0.5f;
|
||||||
|
}
|
||||||
|
|
||||||
|
float mapRange(float value, float inMin, float inMax, float outMin, float outMax) {
|
||||||
|
return (value - inMin) * (outMax - outMin) / (inMax - inMin) + outMin;
|
||||||
|
}
|
||||||
|
|
||||||
|
float blendNoises(float noise1, float noise2, float blendFactor) {
|
||||||
|
return lerp(noise1, noise2, blendFactor);
|
||||||
|
}
|
||||||
|
|
||||||
|
float addNoises(float noise1, float noise2) {
|
||||||
|
return std::clamp(noise1 + noise2, -1.0f, 1.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
float multiplyNoises(float noise1, float noise2) {
|
||||||
|
return noise1 * noise2;
|
||||||
|
}
|
||||||
|
|
||||||
|
float hash(int x, int y) {
|
||||||
|
return (permutation[(x + permutation[y & 255]) & 255] / 255.0f) * 2.0f - 1.0f;
|
||||||
|
}
|
||||||
public:
|
public:
|
||||||
PNoise2() : rng(std::random_device{}()) {
|
PNoise2() : rng(std::random_device{}()) {
|
||||||
initializePermutation();
|
initializePermutation();
|
||||||
@@ -74,8 +98,8 @@ public:
|
|||||||
template<typename T>
|
template<typename T>
|
||||||
float permute(Vec2<T> point) {
|
float permute(Vec2<T> point) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
float x = point.x;
|
float x = static_cast<float>(point.x);
|
||||||
float y = point.y;
|
float y = static_cast<float>(point.y);
|
||||||
int X = (int)floor(x);
|
int X = (int)floor(x);
|
||||||
int xmod = X & 255;
|
int xmod = X & 255;
|
||||||
int Y = (int)floor(point.y);
|
int Y = (int)floor(point.y);
|
||||||
@@ -166,6 +190,34 @@ public:
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float valueNoise(const Vec2<float>& point) {
|
||||||
|
int xi = (int)std::floor(point.x);
|
||||||
|
int yi = (int)std::floor(point.y);
|
||||||
|
|
||||||
|
float tx = point.x - xi;
|
||||||
|
float ty = point.y - yi;
|
||||||
|
|
||||||
|
int rx0 = xi & 255;
|
||||||
|
int rx1 = (xi + 1) & 255;
|
||||||
|
int ry0 = yi & 255;
|
||||||
|
int ry1 = (yi + 1) & 255;
|
||||||
|
|
||||||
|
// Random values at corners
|
||||||
|
float c00 = hash(rx0, ry0);
|
||||||
|
float c10 = hash(rx1, ry0);
|
||||||
|
float c01 = hash(rx0, ry1);
|
||||||
|
float c11 = hash(rx1, ry1);
|
||||||
|
|
||||||
|
// Interpolation
|
||||||
|
float sx = fade(tx);
|
||||||
|
float sy = fade(ty);
|
||||||
|
|
||||||
|
float nx0 = lerp(c00, c10, sx);
|
||||||
|
float nx1 = lerp(c01, c11, sx);
|
||||||
|
|
||||||
|
return lerp(nx0, nx1, sy);
|
||||||
|
}
|
||||||
|
|
||||||
Vec4ui8 permuteColor(const Vec3<float>& point) {
|
Vec4ui8 permuteColor(const Vec3<float>& point) {
|
||||||
TIME_FUNCTION;
|
TIME_FUNCTION;
|
||||||
float noiseR = permute(point);
|
float noiseR = permute(point);
|
||||||
@@ -188,6 +240,65 @@ public:
|
|||||||
return Vec4ui8(r, g, b, a);
|
return Vec4ui8(r, g, b, a);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
float fractalNoise(const Vec2<T>& point, int octaves, float persistence, float lacunarity) {
|
||||||
|
float total = 0.0f;
|
||||||
|
float frequency = 1.f;
|
||||||
|
float amplitude = 1.f;
|
||||||
|
float maxV = 0.f;
|
||||||
|
for (int i = 0; i < octaves; i++) {
|
||||||
|
total += permute(point*frequency) * amplitude;
|
||||||
|
maxV += amplitude;
|
||||||
|
amplitude *= persistence;
|
||||||
|
frequency *= lacunarity;
|
||||||
|
}
|
||||||
|
|
||||||
|
return total / maxV;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
float turbulence(const Vec2<T>& point, int octaves) {
|
||||||
|
float value = 0.0f;
|
||||||
|
Vec2<float> tempPoint = point;
|
||||||
|
for (int i = 0; i < octaves; i++) {
|
||||||
|
value += std::abs(permute(tempPoint));
|
||||||
|
tempPoint *= 2.f;
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ridgedNoise(const Vec2<float>& point, int octaves, float offset = 1.0f) {
|
||||||
|
float result = 0.f;
|
||||||
|
float weight = 1.f;
|
||||||
|
Vec2<float> p = point;
|
||||||
|
|
||||||
|
for (int i = 0; i < octaves; i++) {
|
||||||
|
float signal = 1.f - std::abs(permute(p));
|
||||||
|
signal *= signal;
|
||||||
|
signal *= weight;
|
||||||
|
weight = signal * offset;
|
||||||
|
result += signal;
|
||||||
|
p *= 2.f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
float billowNoise(const Vec2<float>& point, int octaves) {
|
||||||
|
float value = 0.0f;
|
||||||
|
float amplitude = 1.0f;
|
||||||
|
float frequency = 1.0f;
|
||||||
|
|
||||||
|
for (int i = 0; i < octaves; i++) {
|
||||||
|
value += std::abs(permute(point * frequency)) * amplitude;
|
||||||
|
amplitude *= 0.5f;
|
||||||
|
frequency *= 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
BIN
voxel_render.png
BIN
voxel_render.png
Binary file not shown.
|
Before Width: | Height: | Size: 842 B |
Reference in New Issue
Block a user