diff --git a/common/noise/cloudnoise.cpp b/common/noise/cloudnoise.cpp index 872efde..f52a1a6 100644 --- a/common/noise/cloudnoise.cpp +++ b/common/noise/cloudnoise.cpp @@ -6,7 +6,7 @@ CloudNoise::CloudNoise(int size) : Noise(size) { // Some worley noises WorleyNoise worleyNoise1(size, 3); - WorleyNoise worleyNoise3(size, 8); + WorleyNoise worleyNoise3(size, 15); // Some perlin noises PerlinNoise perlinNoise1(size, 3); diff --git a/fancy1.cpp b/fancy1.cpp index efab8bb..a5534c7 100644 --- a/fancy1.cpp +++ b/fancy1.cpp @@ -44,11 +44,12 @@ int main() // Add box for volume shader auto cloudSettings = CloudSettings(); - cloudSettings.scale = 10.0f; - cloudSettings.densityIntensity = 3.0f; - cloudSettings.densityTreshold = 0.55f; + cloudSettings.scale = 15.0f; + cloudSettings.densityIntensity = 10.0f; + cloudSettings.densityTreshold = 0.49f; + cloudSettings.densityAbsorption = 0.9f; auto cloudShader = std::make_shared(cloudSettings); - scene.add(std::make_shared(Vector3d(5.0f, 6.0f, 5.0f), Vector3d(50.0f, 4.0f, 50.0f), cloudShader)); + scene.add(std::make_shared(Vector3d(5.0f, 8.0f, 5.0f), Vector3d(50.0f, 5.0f, 50.0f), cloudShader)); // build the tree scene.buildTree(); diff --git a/shader/cloudshader.cpp b/shader/cloudshader.cpp index 778eb91..23a51d4 100644 --- a/shader/cloudshader.cpp +++ b/shader/cloudshader.cpp @@ -1,5 +1,6 @@ #include "cloudshader.h" #include "common/noise/cloudnoise.h" +#include "common/noise/perlinnoise.h" Color CloudShader::shade(const Scene &scene, const Ray &ray) const @@ -7,7 +8,6 @@ Color CloudShader::shade(const Scene &scene, const Ray &ray) const Vector3d hitPoint = ray.origin + ray.direction * ray.length; // Potentially add epsilon // Collect getNoise through the cloud - float accumulatedNoise = 0.0f; float cloudLength = 0.0f; // Length of cloud in ray direction // Get background color behind cloud and information about the clouds length @@ -32,19 +32,22 @@ Color CloudShader::shade(const Scene &scene, const Ray &ray) const if (cloudLength == 0.0f) return background; // No cloud or at edge - // Get getNoise through cloud - int const NOISE_SAMPLES = settings.densitySamples; - float stepWeight = cloudLength / (float) NOISE_SAMPLES; - for (int i = 0; i < NOISE_SAMPLES; ++i) - { - float progress = (float) i / (float) NOISE_SAMPLES; - Vector3d samplePoint = hitPoint + progress * cloudLength * ray.direction; - float sampleDensity = getCloudDensity(samplePoint); - accumulatedNoise += sampleDensity * stepWeight; - } + // Calculate step length + int noiseSamples = settings.densitySamples; + float stepLength = cloudLength / noiseSamples; - // Pre-processs accumulated getNoise - float cloudDensity = exp(-accumulatedNoise * settings.densityAbsorption); + // Step through cloud + float transmittance = 1.0f; + for (int i = 0; i < noiseSamples; ++i) + { + // Get sample point + Vector3d samplePoint = hitPoint + i * stepLength * ray.direction; + + // Get data at point + float sampleDensity = getCloudDensity(samplePoint) * stepLength; + + transmittance *= exp(-sampleDensity * stepLength * settings.densityAbsorption); + } // Add some ambient and diffuse lighting // cloud += scene.ambientLight() * material.ambient(); @@ -56,7 +59,7 @@ Color CloudShader::shade(const Scene &scene, const Ray &ray) const // cloud += material.cloud() * illumination.cloud * diffuse; // } - return background * cloudDensity + (1.0f - cloudDensity) * settings.cloudColor; + return background * transmittance + (1.0f - transmittance) * settings.cloudColor; } bool CloudShader::isTransparent() const diff --git a/shader/cloudshader.h b/shader/cloudshader.h index aee7ae8..b170d24 100644 --- a/shader/cloudshader.h +++ b/shader/cloudshader.h @@ -14,7 +14,7 @@ struct CloudSettings float scale = 10; float densityTreshold = 0.55f; float densityIntensity = 2.5f; - float densityAbsorption = 1; + float densityAbsorption = 2; Color cloudColor = Color(1, 1, 1); };