diff --git a/result.png b/result.png index 8c87c9f..43e6b57 100644 Binary files a/result.png and b/result.png differ diff --git a/src/gui.h b/src/gui.h index 6093046..960371e 100644 --- a/src/gui.h +++ b/src/gui.h @@ -21,7 +21,7 @@ class Gui: public RenderPlane, public Camera { SimpleCamera camera; cimg_library::CImg processed; void updateDisplay(); - float glare_cutoff = 1.01f; // +0.01 to prevent preview render from glowing + float glare_cutoff = 1e+9f; // +0.01 to prevent preview render from glowing public: Gui(const Camera& _camera); void work(); diff --git a/src/libddf/check_ddf.cpp b/src/libddf/check_ddf.cpp index eb5bfce..77c5ce1 100644 --- a/src/libddf/check_ddf.cpp +++ b/src/libddf/check_ddf.cpp @@ -46,7 +46,7 @@ void mc_integral_and_max(const Ddf& ddf, float& ddf_integral, float& ddf_max){ vec3 dir = vec3(); while(dir == vec3()) - dir = sph.sample(); + dir = normalize(sph.sample()); float value = ddf.value(dir); if(value > ddf_max) @@ -129,7 +129,7 @@ bool check_ddf(const Ddf& ddf, bool strict_integral, size_t size_alpha, size_t s for(size_t i=0; isample(); + assert(weights[i]!=0.0f); + res = components[i]->sample()/weights[i]; + assert(isfinite(res.x) && isfinite(res.y) && isfinite(res.z)); + winning_i = i; break; } }// for assert(rvalue(res); + // and use actually returned value for winning_i + else + value += 1.0f/length(res); + }// for + assert(isfinite(value) && value != 0.0f); + + res = normalize(res) / value; + return res; } diff --git a/src/libddf/ddf.h b/src/libddf/ddf.h index 1c4df78..0ba37df 100644 --- a/src/libddf/ddf.h +++ b/src/libddf/ddf.h @@ -14,7 +14,7 @@ struct Ddf { // Sample a signle vec3 value. Always succeedes virtual glm::vec3 sample() const = 0; - // Get value in direction of arg. Will return NaN if singular + // Get value in direction of arg. For singulars returns 0 virtual float value( glm::vec3 arg ) const = 0; //static std::atomic_size_t object_counter; diff --git a/src/libddf/ddf_detail.h b/src/libddf/ddf_detail.h index 331c897..12b3cee 100644 --- a/src/libddf/ddf_detail.h +++ b/src/libddf/ddf_detail.h @@ -63,8 +63,8 @@ class MirrorDdf: public Ddf { virtual glm::vec3 sample() const override { return glm::vec3(0.0f, 0.0f, 1.0f); } - virtual float value( glm::vec3 arg ) const override { - return std::numeric_limits::quiet_NaN(); + virtual float value( glm::vec3 ) const override { + return 0.0f; } }; diff --git a/src/lighting/lighting.cpp b/src/lighting/lighting.cpp index c5878f6..a0ca5fe 100644 --- a/src/lighting/lighting.cpp +++ b/src/lighting/lighting.cpp @@ -55,7 +55,11 @@ glm::vec3 DdfFromLight::sample() const { if(cosinus < 1e-5f) // if facing back return vec3(); Lighting::last_sample = inter; // HACK TODO how to make it accessible in a cleaner way? - return dir; + + float decay = dot(inter.position-origin, inter.position-origin); + float value = decay/cosinus/light->area; + + return dir/value; } float DdfFromLight::value( glm::vec3 direction ) const { diff --git a/src/main.cpp b/src/main.cpp index 6032e62..9bfbef5 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -22,6 +22,14 @@ using namespace glm; using namespace std; +size_t n_rays = 16; +size_t depth_max = 4; + +class StatsNode; +float ray_power_preview(const Geometry& geometry, const Lighting& lighting, vec3 origin, vec3 direction, size_t, int, StatsNode* stats); +float ray_power_recursive(const Geometry& geometry, const Lighting& lighting, vec3 origin, vec3 direction, size_t depth, int n_rays, StatsNode* stats); +auto ray_power = ray_power_recursive; + // note: root will manage memory for all children class StatsNode { public: @@ -48,10 +56,6 @@ class StatsNode { boost::pool<> StatsNode::pool(sizeof(StatsNode)); -float ray_power_preview(const Geometry& geometry, const Lighting& lighting, vec3 origin, vec3 direction, size_t, int, StatsNode* stats); -float ray_power_recursive(const Geometry& geometry, const Lighting& lighting, vec3 origin, vec3 direction, size_t depth, int n_rays, StatsNode* stats); -auto ray_power = ray_power_recursive; - float ray_power_preview(const Geometry& geometry, const Lighting& lighting, vec3 origin, vec3 direction, size_t, int, StatsNode* stats){ // Stats: origin @@ -91,9 +95,6 @@ float ray_power_preview(const Geometry& geometry, const Lighting& lighting, vec3 return res; } -size_t n_rays = 16; -size_t depth_max = 4; - // TODO light_hint is not very good solution! float ray_power_recursive(const Geometry& geometry, const Lighting& lighting, vec3 origin, vec3 direction, size_t depth, int n_rays, StatsNode* stats){ @@ -136,10 +137,11 @@ float ray_power_recursive(const Geometry& geometry, const Lighting& lighting, ve //DEBUG for geometry debugging //return si->position.y+1.0f; + unique_ptr light_ddf = lighting.distributionInPoint(si->position); + // TODO better solution? Ddf* sdf_tmp = si->sdf.get(); - unique_ptr light_ddf = lighting.distributionInPoint(si->position); unique_ptr mix_ddf = unite(move(light_ddf), 1.0f, move(si->sdf), 1.0f); vec3 new_direction; @@ -149,18 +151,12 @@ float ray_power_recursive(const Geometry& geometry, const Lighting& lighting, ve for(size_t i=0; isample(); - float mix_val = mix_ddf->value(new_direction); - - // if(isdf->sample(); - // else - // new_direction = light_ddf->sample(); - - // float mix_val = 0.5f*si->sdf->value( new_direction ) + 0.5f*light_ddf->value( new_direction ); + float mix_val = 1.0f/length(new_direction); - if( new_direction == vec3() ){ + if(new_direction == vec3()) continue; - } + + new_direction = normalize(new_direction); // Stats: false (miss) StatsNode* child_stats = new StatsNode(); @@ -247,6 +243,7 @@ int main(int argc, char** argv){ GridRenderPlane r_plane(640, 640); //Scene scene = make_scene_lit_corner(); + //Scene scene = make_scene_square_lit_by_square(); Scene scene = make_scene_box(); auto gui = make_shared(*scene.camera); scene.camera = gui; // replace camera with more interactive one