From 53a4a6d1f09c7543654ac3c9f611a6f5073fb6e9 Mon Sep 17 00:00:00 2001 From: Maximilian Giller Date: Tue, 24 Jan 2023 07:52:55 +0100 Subject: [PATCH] Fixes optimization issue and scaling inconsistency --- common/noise/cloudnoise.cpp | 16 ++++++++++------ common/noise/cloudnoise.h | 4 ++-- common/noise/noise.cpp | 32 +++++++++++++++++++------------- common/noise/noise.h | 10 +++++----- common/noise/worleynoise.cpp | 36 ++++++++++++++++++++++++++++++++---- shader/cloudshader.cpp | 2 +- shader/cloudshader.h | 4 +--- 7 files changed, 70 insertions(+), 34 deletions(-) diff --git a/common/noise/cloudnoise.cpp b/common/noise/cloudnoise.cpp index ba5a395..58b5972 100644 --- a/common/noise/cloudnoise.cpp +++ b/common/noise/cloudnoise.cpp @@ -2,14 +2,14 @@ #include "worleynoise.h" #include "perlinnoise.h" -cloudnoise::cloudnoise(int size) : Noise(size) +CloudNoise::CloudNoise(int size) : Noise(size) { // Some worley noises WorleyNoise worleyNoise1(size, 3); - WorleyNoise worleyNoise3(size, 12); + WorleyNoise worleyNoise3(size, 8); // Some perlin noises - PerlinNoise perlinNoise1(size, 10); + PerlinNoise perlinNoise1(size, 15); // Generate the noise for (int x = 0; x < size; x++) @@ -18,10 +18,14 @@ cloudnoise::cloudnoise(int size) : Noise(size) { for (int z = 0; z < size; z++) { - float worley1 = worleyNoise1.getNoise(x, y, z); - float worley3 = worleyNoise3.getNoise(x, y, z); + float sx = x / (float) size; + float sy = y / (float) size; + float sz = z / (float) size; - float perlin1 = perlinNoise1.getNoise(x, y, z); + float worley1 = worleyNoise1.getNoise(sx, sy, sz); + float worley3 = worleyNoise3.getNoise(sx, sy, sz); + + float perlin1 = perlinNoise1.getNoise(sx, sy, sz); float noise = worley1 * 0.6f + worley3 * 0.2f + perlin1 * 0.2; diff --git a/common/noise/cloudnoise.h b/common/noise/cloudnoise.h index b2a67c7..7ce7428 100644 --- a/common/noise/cloudnoise.h +++ b/common/noise/cloudnoise.h @@ -4,10 +4,10 @@ #include "noise.h" -class cloudnoise : public Noise +class CloudNoise : public Noise { public: - cloudnoise(int size); + CloudNoise(int size); }; diff --git a/common/noise/noise.cpp b/common/noise/noise.cpp index 82fadcc..079e58c 100644 --- a/common/noise/noise.cpp +++ b/common/noise/noise.cpp @@ -19,7 +19,13 @@ void Noise::setNoise(int x, int y, int z, float value) } float Noise::getNoise(float x, float y, float z) const -{ // Get corner points of the cube +{ + // Scale to [0, size] + x *= size; + y *= size; + z *= size; + + // Get corner points of the cube int x_min = (int) fitToNoise(floor(x)); int y_min = (int) fitToNoise(floor(y)); int z_min = (int) fitToNoise(floor(z)); @@ -57,18 +63,6 @@ float Noise::getNoise(float x, float y, float z) const return noise; } -float Noise::fitToNoise(float point) const -{ - float remainingValue = fmod(point, size); - - if (remainingValue < 0) - { - remainingValue += size; - } - - return remainingValue; -} - float Noise::getCalculatedNoise(int x, int y, int z) const { long int index = x + y * (long int) size + z * size * (long int) size; @@ -107,3 +101,15 @@ float Noise::interpolate(float a0, float a1, float w) const * return (a1 - a0) * ((w * (w * 6.0 - 15.0) + 10.0) * w * w * w) + a0; */ } + +float Noise::fitToNoise(float point) const +{ + float remainingValue = fmod(point, size); + + if (remainingValue < 0) + { + remainingValue += size; + } + + return remainingValue; +} diff --git a/common/noise/noise.h b/common/noise/noise.h index 8dd19e7..a3a40bd 100644 --- a/common/noise/noise.h +++ b/common/noise/noise.h @@ -11,8 +11,8 @@ class Noise public: Noise(int size); - float getNoise(Vector3d point) const; - float getNoise(float x, float y, float z) const; + float getNoise(Vector3d point) const; // Parameters in [0,1], Output in [0,1] + float getNoise(float x, float y, float z) const; // Parameters in [0,1], Output in [0,1] bool invert = false; @@ -21,13 +21,13 @@ protected: int size; // Size of the cloudNoise map void generateNoiseMap(int size); - void setNoise(int x, int y, int z, float value); + void setNoise(int x, int y, int z, float value); // Parameters in [0,size] float getCalculatedNoise(int x, int y, int z) const; - float fitToNoise(float point) const; - float interpolate(float a0, float a1, float w) const; + + float fitToNoise(float point) const; }; #endif //CG1_TRACER_NOISE_H diff --git a/common/noise/worleynoise.cpp b/common/noise/worleynoise.cpp index 7c8633e..ca35319 100644 --- a/common/noise/worleynoise.cpp +++ b/common/noise/worleynoise.cpp @@ -102,9 +102,10 @@ std::vector WorleyNoise::getSubcellPoints(Vector3d point) { std::vector closePoints; - point.x = std::floor(point.x * numberOfPoints); - point.y = std::floor(point.y * numberOfPoints); - point.z = std::floor(point.z * numberOfPoints); + point *= numberOfPoints; + point.x = std::floor(point.x); + point.y = std::floor(point.y); + point.z = std::floor(point.z); // Iterate over all subcells for (int x = -1; x <= 1; x++) @@ -116,6 +117,33 @@ std::vector WorleyNoise::getSubcellPoints(Vector3d point) Vector3d offset = Vector3d(x, y, z); Vector3d subcell = point + offset; + Vector3d cellOffsets = Vector3d(0, 0, 0); + + if (subcell.x < 0) + { + cellOffsets.x = -1; + } + if (subcell.y < 0) + { + cellOffsets.y = -1; + } + if (subcell.z < 0) + { + cellOffsets.z = -1; + } + if (subcell.x >= numberOfPoints) + { + cellOffsets.x = 1; + } + if (subcell.y >= numberOfPoints) + { + cellOffsets.y = 1; + } + if (subcell.z >= numberOfPoints) + { + cellOffsets.z = 1; + } + // Wrap around subcell.x = std::fmod(subcell.x + numberOfPoints, numberOfPoints); subcell.y = std::fmod(subcell.y + numberOfPoints, numberOfPoints); @@ -123,7 +151,7 @@ std::vector WorleyNoise::getSubcellPoints(Vector3d point) // Get points in subcell int index = subcell.x + subcell.y * numberOfPoints + subcell.z * numberOfPoints * numberOfPoints; - closePoints.push_back(points[index]); + closePoints.push_back(points[index] + cellOffsets); } } } diff --git a/shader/cloudshader.cpp b/shader/cloudshader.cpp index da3aca0..4fbb900 100644 --- a/shader/cloudshader.cpp +++ b/shader/cloudshader.cpp @@ -83,7 +83,7 @@ bool CloudShader::isTransparent() const } CloudShader::CloudShader(const CloudSettings &settings) : settings(settings), - cloudNoise(cloudnoise(NOISE_SIZE)) + cloudNoise(CloudNoise(NOISE_SIZE)) { cloudNoise.invert = true; } diff --git a/shader/cloudshader.h b/shader/cloudshader.h index e993d32..fbbbc39 100644 --- a/shader/cloudshader.h +++ b/shader/cloudshader.h @@ -6,7 +6,7 @@ #include "primitive/primitive.h" #include "common/noise/worleynoise.h" -int const NOISE_SIZE = 32; +int const NOISE_SIZE = 128; struct CloudSettings { @@ -37,8 +37,6 @@ private: Noise cloudNoise; float getCloudDensity(Vector3d point) const; - - float fitToNoise(float point) const; };