diff --git a/include/core_api/scene.h b/include/core_api/scene.h index bfdbc3ab..1638348d 100644 --- a/include/core_api/scene.h +++ b/include/core_api/scene.h @@ -207,9 +207,11 @@ class YAFRAYCORE_EXPORT scene_t std::vector lights; volumeIntegrator_t *volIntegrator; - PFLOAT shadowBias; //shadow bias to apply to shadows to avoid self-shadow artifacts - PFLOAT rayMinDist; //ray minimum distance + PFLOAT shadowBias; //shadow bias to apply to shadows to avoid self-shadow artifacts + bool shadowBiasAuto; //enable automatic shadow bias calculation + PFLOAT rayMinDist; //ray minimum distance + bool rayMinDistAuto; //enable automatic ray minimum distance calculation protected: diff --git a/src/yafraycore/environment.cc b/src/yafraycore/environment.cc index 8defe37e..aa598c68 100644 --- a/src/yafraycore/environment.cc +++ b/src/yafraycore/environment.cc @@ -634,6 +634,10 @@ bool renderEnvironment_t::setupScene(scene_t &scene, const paraMap_t ¶ms, co bool z_chan = false; bool norm_z_chan = true; bool drawParams = false; + bool adv_auto_shadow_bias_enabled=true; + float adv_shadow_bias_value=YAF_SHADOW_BIAS; + bool adv_auto_min_raydist_enabled=true; + float adv_min_raydist_value=MIN_RAYDIST; const std::string *custString = 0; std::stringstream aaSettings; @@ -695,6 +699,10 @@ bool renderEnvironment_t::setupScene(scene_t &scene, const paraMap_t ¶ms, co params.getParam("normalize_z_channel", norm_z_chan); // normalize values of z-buffer in range [0,1] params.getParam("drawParams", drawParams); params.getParam("customString", custString); + params.getParam("adv_auto_shadow_bias_enabled", adv_auto_shadow_bias_enabled); + params.getParam("adv_shadow_bias_value", adv_shadow_bias_value); + params.getParam("adv_auto_min_raydist_enabled", adv_auto_min_raydist_enabled); + params.getParam("adv_min_raydist_value", adv_min_raydist_value); imageFilm_t *film = createImageFilm(params, output); @@ -722,6 +730,10 @@ bool renderEnvironment_t::setupScene(scene_t &scene, const paraMap_t ¶ms, co scene.setAntialiasing(AA_samples, AA_passes, AA_inc_samples, AA_threshold); scene.setNumThreads(nthreads); if(backg) scene.setBackground(backg); + scene.shadowBiasAuto = adv_auto_shadow_bias_enabled; + scene.shadowBias = adv_shadow_bias_value; + scene.rayMinDistAuto = adv_auto_min_raydist_enabled; + scene.rayMinDist = adv_min_raydist_value; return true; } diff --git a/src/yafraycore/scene.cc b/src/yafraycore/scene.cc index 5adcca0e..d142c398 100644 --- a/src/yafraycore/scene.cc +++ b/src/yafraycore/scene.cc @@ -785,14 +785,22 @@ bool scene_t::update() "(" << sceneBound.a.x << ", " << sceneBound.a.y << ", " << sceneBound.a.z << "), (" << sceneBound.g.x << ", " << sceneBound.g.y << ", " << sceneBound.g.z << ")" << yendl; - //Automatic shadow bias calculation based on the original YAF_SHADOW_BIAS and an automatic correction based on the size of the scene. This is an empirical formula I just made up based on values of shadow bias that seem to avoid black self shadow artifacts in big scenes, probably will be improved in the future. - shadowBias = sceneBound.longX(); - if(shadowBias < sceneBound.longY()) shadowBias=sceneBound.longY(); - if(shadowBias < sceneBound.longZ()) shadowBias=sceneBound.longZ(); - shadowBias = YAF_SHADOW_BIAS * 0.25f * shadowBias; - rayMinDist = 0.1f * shadowBias; - - Y_INFO << "Scene: total scene dimensions: X=" << sceneBound.longX() << ", Y=" << sceneBound.longY() << ", Z=" << sceneBound.longZ() << ", volume=" << sceneBound.vol() << ", calculated Shadow Bias=" << shadowBias << ", calculated Ray Min Dist=" << rayMinDist << yendl; + if(shadowBiasAuto) + { + //Automatic shadow bias calculation based on the original YAF_SHADOW_BIAS and an automatic correction based on the size of the scene. This is an empirical formula I just made up based on values of shadow bias that seem to avoid black self shadow artifacts in big scenes, probably will be improved in the future. + shadowBias = sceneBound.longX(); + if(shadowBias < sceneBound.longY()) shadowBias=sceneBound.longY(); + if(shadowBias < sceneBound.longZ()) shadowBias=sceneBound.longZ(); + shadowBias = YAF_SHADOW_BIAS * 0.25f * shadowBias; + } + + if(rayMinDistAuto) + { + //Automatic Min Ray Dist calculation, based on the currently used Shadow Bias value. The factor 0.1 is based on the original ratio between YAF_SHADOW_BIAS (typically 0.0005) and MIN_RAYDIST (0.00005) + rayMinDist = 0.1f * shadowBias; + } + + Y_INFO << "Scene: total scene dimensions: X=" << sceneBound.longX() << ", Y=" << sceneBound.longY() << ", Z=" << sceneBound.longZ() << ", volume=" << sceneBound.vol() << ", Shadow Bias=" << shadowBias << ", Ray Min Dist=" << rayMinDist << yendl; } else Y_WARNING << "Scene: Scene is empty..." << yendl; } @@ -828,14 +836,22 @@ bool scene_t::update() "(" << sceneBound.a.x << ", " << sceneBound.a.y << ", " << sceneBound.a.z << "), (" << sceneBound.g.x << ", " << sceneBound.g.y << ", " << sceneBound.g.z << ")" << yendl; - //Automatic shadow bias calculation based on the original YAF_SHADOW_BIAS and an automatic correction based on the size of the scene. This is an empirical formula I just made up based on values of shadow bias that seem to avoid black self shadow artifacts in big scenes, probably will be improved in the future. - shadowBias = sceneBound.longX(); - if(shadowBias < sceneBound.longY()) shadowBias=sceneBound.longY(); - if(shadowBias < sceneBound.longZ()) shadowBias=sceneBound.longZ(); - shadowBias = YAF_SHADOW_BIAS * 0.25f * shadowBias; - rayMinDist = 0.1f * shadowBias; - - Y_INFO << "Scene: total scene dimensions: X=" << sceneBound.longX() << ", Y=" << sceneBound.longY() << ", Z=" << sceneBound.longZ() << ", volume=" << sceneBound.vol() << ", calculated Shadow Bias=" << shadowBias << ", calculated Ray Min Dist=" << rayMinDist << yendl; + if(shadowBiasAuto) + { + //Automatic shadow bias calculation based on the original YAF_SHADOW_BIAS and an automatic correction based on the size of the scene. This is an empirical formula I just made up based on values of shadow bias that seem to avoid black self shadow artifacts in big scenes, probably will be improved in the future. + shadowBias = sceneBound.longX(); + if(shadowBias < sceneBound.longY()) shadowBias=sceneBound.longY(); + if(shadowBias < sceneBound.longZ()) shadowBias=sceneBound.longZ(); + shadowBias = YAF_SHADOW_BIAS * 0.25f * shadowBias; + } + + if(rayMinDistAuto) + { + //Automatic Min Ray Dist calculation, based on the currently used Shadow Bias value. The factor 0.1 is based on the original ratio between YAF_SHADOW_BIAS (typically 0.0005) and MIN_RAYDIST (0.00005) + rayMinDist = 0.1f * shadowBias; + } + + Y_INFO << "Scene: total scene dimensions: X=" << sceneBound.longX() << ", Y=" << sceneBound.longY() << ", Z=" << sceneBound.longZ() << ", volume=" << sceneBound.vol() << ", Shadow Bias=" << shadowBias << ", Ray Min Dist=" << rayMinDist << yendl; } else Y_ERROR << "Scene: Scene is empty..." << yendl;