#ifndef CG1_TRACER_CLOUDSHADER_H #define CG1_TRACER_CLOUDSHADER_H #include "scene/scene.h" #include "shader.h" #include "light/light.h" #include "primitive/primitive.h" #include "common/noise/worleynoise.h" int const NOISE_SIZE = 128; float const TRANSMITTANCE_BREAK = 0.005f; // If transmittance goes below this limit, the cloud is considered opaque struct CloudSettings { int densitySamples = 100; int lightSamples = 100; float scale = 10; float densityOffset = -0.57f; float densityIntensity = 7.0f; float darknessThreshold = 0.07f; float shadowIntensity = 0.8f; float shadowLightAbsorption = 1; float lightAbsorptionTowardsLight = 0.94f; float lightAbsorptionThroughCloud = 0.85f; }; class CloudShader : public Shader { public: CloudShader(CloudSettings const &settings = CloudSettings()); // Shader functions Color shade(Scene const &scene, Ray const &ray) const; Color transparency(const Scene &scene, const Ray &ray, float maxLength) const override; private: CloudSettings settings; bool isTransparent() const; Noise cloudNoise; float getCloudDensity(Vector3d point) const; Color lightMarch(const Scene &scene, Vector3d currentInCloudPosition, Vector3d lengthDistance) const; float rayDensity(const Ray &ray, float maxLength) const; float scatterFactor(Vector3d visualRay, Vector3d illuminationRay) const; float HenyeyGreenstein(float cosTheta, float g) const; }; #endif //CG1_TRACER_CLOUDSHADER_H