Clouds still bad
This commit is contained in:
parent
d7c093944d
commit
79446c289b
3 changed files with 38 additions and 26 deletions
11
fancy1.cpp
11
fancy1.cpp
|
@ -29,9 +29,10 @@ int main()
|
||||||
{
|
{
|
||||||
FastScene scene;
|
FastScene scene;
|
||||||
scene.setBackgroundColor(Color(0.529f, 0.808f, 0.922f) * 1.0f);
|
scene.setBackgroundColor(Color(0.529f, 0.808f, 0.922f) * 1.0f);
|
||||||
|
// scene.setBackgroundColor(Color(1, 0.79f, 0.62f) * 0.8f);
|
||||||
|
|
||||||
// Add lights
|
// Add lights
|
||||||
auto mainLight = std::make_shared<SunLight>(Vector3d(-1.0f, -0.5f, -1.0f), 5.0f, Color(1, 0.79f, 0.62f));
|
auto mainLight = std::make_shared<SunLight>(Vector3d(-1.0f, -0.5f, -1.0f), 2.0f, Color(1,1,1));//Color(1, 0.79f, 0.62f));
|
||||||
scene.add(mainLight);
|
scene.add(mainLight);
|
||||||
// scene.add(std::make_shared<AmbientLight>(0.3f));
|
// scene.add(std::make_shared<AmbientLight>(0.3f));
|
||||||
// auto light = std::make_shared<PointLight>(Vector3d(25.0f, 10.0f, 25.0f), 100.0f);
|
// auto light = std::make_shared<PointLight>(Vector3d(25.0f, 10.0f, 25.0f), 100.0f);
|
||||||
|
@ -43,10 +44,10 @@ int main()
|
||||||
// busShader);
|
// busShader);
|
||||||
|
|
||||||
// Refraction boxes
|
// Refraction boxes
|
||||||
auto boxShader = std::make_shared<RefractionShader>(1.05f, 1, Color(1,1,0), 0.7f);
|
// auto boxShader = std::make_shared<RefractionShader>(1.05f, 1, Color(1,1,0), 0.7f);
|
||||||
scene.add(std::make_shared<Box>(Vector3d(5.0f, 3.0f, 10.0f), Vector3d(3.0f, 3.0f, 3.0f), boxShader));
|
// scene.add(std::make_shared<Box>(Vector3d(5.0f, 3.0f, 10.0f), Vector3d(3.0f, 3.0f, 3.0f), boxShader));
|
||||||
auto boxShader1 = std::make_shared<RefractionShader>(1.05f, 1, Color(0,1,1), 0.7f);
|
// auto boxShader1 = std::make_shared<RefractionShader>(1.05f, 1, Color(0,1,1), 0.7f);
|
||||||
scene.add(std::make_shared<Box>(Vector3d(9.0f, 3.0f, 12.0f), Vector3d(3.0f, 3.0f, 3.0f), boxShader1));
|
// scene.add(std::make_shared<Box>(Vector3d(9.0f, 3.0f, 12.0f), Vector3d(3.0f, 3.0f, 3.0f), boxShader1));
|
||||||
|
|
||||||
// Add floor
|
// Add floor
|
||||||
auto floorShader = std::make_shared<SimpleShadowShader>(Color(0.9f, 0.9f, 0.9f));
|
auto floorShader = std::make_shared<SimpleShadowShader>(Color(0.9f, 0.9f, 0.9f));
|
||||||
|
|
|
@ -33,10 +33,10 @@ Color CloudShader::shade(const Scene &scene, const Ray &ray) const
|
||||||
|
|
||||||
// Calculate step length
|
// Calculate step length
|
||||||
int noiseSamples = settings.densitySamples;
|
int noiseSamples = settings.densitySamples;
|
||||||
float stepLength = cloudLength / noiseSamples;
|
float stepLength = cloudLength / (float) noiseSamples;
|
||||||
|
|
||||||
// Step through cloud
|
// Step through cloud
|
||||||
float transmittance = 1;
|
float accumulatedDensity = 0.0f;
|
||||||
Color cloudColor = Color(0, 0, 0);
|
Color cloudColor = Color(0, 0, 0);
|
||||||
for (int i = 0; i < noiseSamples; ++i)
|
for (int i = 0; i < noiseSamples; ++i)
|
||||||
{
|
{
|
||||||
|
@ -49,14 +49,14 @@ Color CloudShader::shade(const Scene &scene, const Ray &ray) const
|
||||||
|
|
||||||
if (sampleDensity > 0)
|
if (sampleDensity > 0)
|
||||||
{
|
{
|
||||||
cloudColor += lightMarch(scene, samplePoint, lengthDirection) * stepLength * sampleDensity;
|
cloudColor += lightMarch(scene, samplePoint, lengthDirection, ray.primitive) * sampleDensity;
|
||||||
}
|
}
|
||||||
|
|
||||||
transmittance *= exp(-sampleDensity * stepLength * settings.lightAbsorptionThroughCloud);
|
accumulatedDensity += sampleDensity;
|
||||||
|
|
||||||
if (transmittance < TRANSMITTANCE_BREAK) break; // Cloud is effectively opaque
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float transmittance = exp(-accumulatedDensity * settings.lightAbsorptionThroughCloud);
|
||||||
|
|
||||||
return background * transmittance + cloudColor;
|
return background * transmittance + cloudColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -84,15 +84,17 @@ float CloudShader::getCloudDensity(Vector3d point) const
|
||||||
return density;
|
return density;
|
||||||
}
|
}
|
||||||
|
|
||||||
Color CloudShader::lightMarch(const Scene &scene, Vector3d currentInCloudPosition, Vector3d lengthDistance) const
|
Color CloudShader::lightMarch(const Scene &scene, Vector3d currentInCloudPosition, Vector3d lengthDistance,
|
||||||
|
const Primitive *cloudObject) const
|
||||||
{
|
{
|
||||||
Color cloudColor;
|
Color cloudColor = Color(0, 0, 0);
|
||||||
|
|
||||||
// For alle lights
|
// For alle lights
|
||||||
for (const auto &light: scene.lights())
|
for (const auto &light: scene.lights())
|
||||||
{
|
{
|
||||||
Ray ray = Ray(currentInCloudPosition - lengthDistance, normalized(lengthDistance));
|
Ray ray = Ray(currentInCloudPosition - lengthDistance, normalized(lengthDistance));
|
||||||
ray.length = length(lengthDistance);
|
ray.length = length(lengthDistance);
|
||||||
|
ray.primitive = cloudObject;
|
||||||
auto illumination = light->illuminate(scene, ray);
|
auto illumination = light->illuminate(scene, ray);
|
||||||
|
|
||||||
// Handle ambient lights
|
// Handle ambient lights
|
||||||
|
@ -106,22 +108,30 @@ Color CloudShader::lightMarch(const Scene &scene, Vector3d currentInCloudPositio
|
||||||
Ray lightRay;
|
Ray lightRay;
|
||||||
lightRay.origin = currentInCloudPosition;
|
lightRay.origin = currentInCloudPosition;
|
||||||
lightRay.direction = illumination.direction;
|
lightRay.direction = illumination.direction;
|
||||||
|
lightRay.primitive = cloudObject;
|
||||||
lightRay.length = 0; // Starting in cloud itself
|
lightRay.length = 0; // Starting in cloud itself
|
||||||
|
|
||||||
float density = this->rayDensity(lightRay, illumination.distance);
|
float density = this->rayDensity(lightRay, illumination.distance);
|
||||||
density *= settings.lightAbsorptionTowardsLight;
|
density *= settings.lightAbsorptionTowardsLight;
|
||||||
|
|
||||||
// Proper light calculation
|
// Proper light calculation
|
||||||
float transmittance = exp(-density) * (1 - exp(-density * 2));
|
float transmittance = getDensityTransmittance(density);
|
||||||
float scatter = scatterFactor(normalized(lengthDistance), illumination.direction);
|
float scatter = scatterFactor(normalized(lengthDistance), illumination.direction);
|
||||||
|
|
||||||
float factor = settings.darknessThreshold + (scatter * transmittance) * (1 - settings.darknessThreshold); // (transmittance * scatter)
|
// TODO: Back to default
|
||||||
|
float factor = settings.darknessThreshold +
|
||||||
|
(1.0f - settings.darknessThreshold) * (1); // (transmittance * scatter)
|
||||||
cloudColor += factor * illumination.color;
|
cloudColor += factor * illumination.color;
|
||||||
}
|
}
|
||||||
|
|
||||||
return cloudColor;
|
return cloudColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float CloudShader::getDensityTransmittance(float density) const
|
||||||
|
{
|
||||||
|
return exp(-density) * (1 - exp(-density * 2)) / 0.4f;
|
||||||
|
}
|
||||||
|
|
||||||
Color CloudShader::transparency(const Scene &scene, const Ray &ray, float maxLength) const
|
Color CloudShader::transparency(const Scene &scene, const Ray &ray, float maxLength) const
|
||||||
{
|
{
|
||||||
float density = rayDensity(ray, maxLength);
|
float density = rayDensity(ray, maxLength);
|
||||||
|
@ -163,9 +173,7 @@ float CloudShader::rayDensity(const Ray &ray, float maxLength) const
|
||||||
Vector3d samplePoint = startPoint + i * stepLength * ray.direction;
|
Vector3d samplePoint = startPoint + i * stepLength * ray.direction;
|
||||||
|
|
||||||
// Get data at point
|
// Get data at point
|
||||||
float sampleDensity = getCloudDensity(samplePoint) * stepLength;
|
density += getCloudDensity(samplePoint) * stepLength;
|
||||||
|
|
||||||
density += sampleDensity * stepLength;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is length left, check if it is in the cloud recursively
|
// If there is length left, check if it is in the cloud recursively
|
||||||
|
@ -189,14 +197,14 @@ float CloudShader::rayDensity(const Ray &ray, float maxLength) const
|
||||||
float CloudShader::scatterFactor(Vector3d visualRay, Vector3d illuminationRay) const
|
float CloudShader::scatterFactor(Vector3d visualRay, Vector3d illuminationRay) const
|
||||||
{
|
{
|
||||||
// The asymmetry parameter
|
// The asymmetry parameter
|
||||||
float g = 0.7f;
|
float g = settings.scatterWeight;
|
||||||
|
|
||||||
// The angle between the visual and illumination rays
|
// The angle between the visual and illumination rays
|
||||||
float cosTheta = dotProduct(visualRay, illuminationRay);
|
float cosTheta = dotProduct(visualRay, illuminationRay);
|
||||||
|
|
||||||
// The Dual-Lob Henyey-Greenstein function
|
// The Dual-Lob Henyey-Greenstein function
|
||||||
float blend = .5;
|
float blend = .5;
|
||||||
float scatter = HenyeyGreenstein(cosTheta,g) * (1-blend) + HenyeyGreenstein(cosTheta,-g) * blend;
|
float scatter = HenyeyGreenstein(cosTheta, g) * (1 - blend) + HenyeyGreenstein(cosTheta, -g) * blend;
|
||||||
|
|
||||||
// Clamp the result to the range [0, 1]
|
// Clamp the result to the range [0, 1]
|
||||||
scatter = std::max(std::min(scatter, 1.0f), 0.0f);
|
scatter = std::max(std::min(scatter, 1.0f), 0.0f);
|
||||||
|
|
|
@ -16,12 +16,13 @@ struct CloudSettings
|
||||||
int lightSamples = 100;
|
int lightSamples = 100;
|
||||||
float scale = 10;
|
float scale = 10;
|
||||||
float densityOffset = -0.57f;
|
float densityOffset = -0.57f;
|
||||||
float densityIntensity = 7.0f;
|
float densityIntensity = 7.0f; // 7.0f
|
||||||
float darknessThreshold = 0.07f;
|
float darknessThreshold = 0.2f; // 0.07f
|
||||||
float shadowIntensity = 0.8f;
|
float shadowIntensity = 0.6f;
|
||||||
float shadowLightAbsorption = 1;
|
float shadowLightAbsorption = 1;
|
||||||
float lightAbsorptionTowardsLight = 0.94f;
|
float lightAbsorptionTowardsLight = 1.0f;
|
||||||
float lightAbsorptionThroughCloud = 0.85f;
|
float lightAbsorptionThroughCloud = 0.5f;
|
||||||
|
float scatterWeight = 0.5f;
|
||||||
};
|
};
|
||||||
|
|
||||||
class CloudShader : public Shader
|
class CloudShader : public Shader
|
||||||
|
@ -43,13 +44,15 @@ private:
|
||||||
|
|
||||||
float getCloudDensity(Vector3d point) const;
|
float getCloudDensity(Vector3d point) const;
|
||||||
|
|
||||||
Color lightMarch(const Scene &scene, Vector3d currentInCloudPosition, Vector3d lengthDistance) const;
|
Color lightMarch(const Scene &scene, Vector3d currentInCloudPosition, Vector3d lengthDistance, const Primitive *cloudObject) const;
|
||||||
|
|
||||||
float rayDensity(const Ray &ray, float maxLength) const;
|
float rayDensity(const Ray &ray, float maxLength) const;
|
||||||
|
|
||||||
float scatterFactor(Vector3d visualRay, Vector3d illuminationRay) const;
|
float scatterFactor(Vector3d visualRay, Vector3d illuminationRay) const;
|
||||||
|
|
||||||
float HenyeyGreenstein(float cosTheta, float g) const;
|
float HenyeyGreenstein(float cosTheta, float g) const;
|
||||||
|
|
||||||
|
float getDensityTransmittance(float density) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue