Skip to content
This repository has been archived by the owner on Jul 18, 2020. It is now read-only.

Commit

Permalink
New per-material transparency bias for Shiny Diffuse
Browse files Browse the repository at this point in the history
When there are objects with many transparent surfaces stacked close together (such as leaves in a tree) sometimes black artifacts appear if the ray reaches the maximum depth.
This can be solved by increasing the maximum ray depth, but the render times will increase very significantly.
Therefore I've added two new parameters for the Shiny Diffuse material to try to achieve a "trick", which is not realistic and may cause other artifacts but that should prevent the black areas without having to increase the maximum ray depth so much.

* transparentbias_factor  : this floating point value is 0.0 by default (disabled). If this value is >0.0 the function is enabled. In that case, an additional "bias" will be added to each ray when it hits a transparent surface. If the ray hits a transparent surface, the next secondary ray will not start exactly after that surface but after this bias factor. So, subsequent transparent surfaces can be skipped and not rendered, but the objects behind will be rendered (unless they are too close to them, in that case they might not be rendered!)
* transparentbias_multiply_raydepth  : this boolean values is false by default. If the factor is used and this is disabled, the factor will be just added to each secondary ray initial position. If this parameter is enabled, the "bias" for each ray will be multiplied by the ray depth. That way, the first few surfaces will be rendered giving a better "density" but the further the secondary rays are generated, the bigger the bias will be.

I got interesting results with factor = 1.0 and multiply_raydepth = true. However, even solving the black areas problems, the resulting image will have other artifacts due to some surfaces not being rendered. USE WITH CARE!!
  • Loading branch information
DavidBluecame committed Oct 31, 2017
1 parent 51bb1b2 commit 264a766
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 2 deletions.
6 changes: 5 additions & 1 deletion include/core_api/material.h
Expand Up @@ -213,6 +213,8 @@ class YAFRAYCORE_EXPORT material_t
bool isFlat() const { return mFlatMaterial; }

int getAdditionalDepth() const { return additionalDepth; }
float getTransparentBiasFactor() const { return transparentBiasFactor; }
bool getTransparentBiasMultiplyRayDepth() const { return transparentBiasMultiplyRayDepth; }

void applyWireFrame(float & value, float wireFrameAmount, const surfacePoint_t &sp) const;
void applyWireFrame(color_t & col, float wireFrameAmount, const surfacePoint_t &sp) const;
Expand Down Expand Up @@ -247,7 +249,9 @@ class YAFRAYCORE_EXPORT material_t
float materialIndexAutoNumber = 0.f; //!< Material Index number automatically generated for the material-index-auto-abs (numeric) render pass
static float highestMaterialIndex; //!< Class shared variable containing the highest material index used for the Normalized Material Index pass.
int additionalDepth; //!< Per-material additional ray-depth

float transparentBiasFactor = 0.f; //!< Per-material additional ray-bias setting for transparency (trick to avoid black areas due to insufficient depth when many transparent surfaces stacked). If >0.f this function is enabled and the result will no longer be realistic and may have artifacts.
bool transparentBiasMultiplyRayDepth = false; //!< Per-material additional ray-bias setting for transparency (trick to avoid black areas due to insufficient depth when many transparent surfaces stacked). If enabled the bias will be multiplied by the current ray depth so the first transparent surfaces are rendered better and subsequent surfaces might be skipped.

float mWireFrameAmount = 0.f; //!< Wireframe shading amount
float mWireFrameThickness = 0.01f; //!< Wireframe thickness
float mWireFrameExponent = 0.f; //!< Wireframe exponent (0.f = solid, 1.f=linearly gradual, etc)
Expand Down
6 changes: 6 additions & 0 deletions src/materials/shinydiffuse.cc
Expand Up @@ -594,6 +594,8 @@ material_t* shinyDiffuseMat_t::factory(paraMap_t &params, std::list<paraMap_t> &
double transmitFilterStrength=1.0;
int mat_pass_index = 0;
int additionaldepth = 0;
float transparentbias_factor = 0.f;
bool transparentbias_multiply_raydepth = false;
float samplingfactor = 1.f;
float WireFrameAmount = 0.f; //!< Wireframe shading amount
float WireFrameThickness = 0.01f; //!< Wireframe thickness
Expand All @@ -616,6 +618,8 @@ material_t* shinyDiffuseMat_t::factory(paraMap_t &params, std::list<paraMap_t> &
params.getParam("visibility", sVisibility);
params.getParam("mat_pass_index", mat_pass_index);
params.getParam("additionaldepth", additionaldepth);
params.getParam("transparentbias_factor", transparentbias_factor);
params.getParam("transparentbias_multiply_raydepth", transparentbias_multiply_raydepth);
params.getParam("samplingfactor", samplingfactor);

params.getParam("wireframe_amount", WireFrameAmount);
Expand All @@ -636,6 +640,8 @@ material_t* shinyDiffuseMat_t::factory(paraMap_t &params, std::list<paraMap_t> &
mat->mReceiveShadows = receive_shadows;
mat->mFlatMaterial = flat_material;
mat->additionalDepth = additionaldepth;
mat->transparentBiasFactor = transparentbias_factor;
mat->transparentBiasMultiplyRayDepth = transparentbias_multiply_raydepth;

mat->mWireFrameAmount = WireFrameAmount;
mat->mWireFrameThickness = WireFrameThickness;
Expand Down
12 changes: 11 additions & 1 deletion src/yafraycore/mcintegrator.cc
Expand Up @@ -997,7 +997,17 @@ inline void mcIntegrator_t::recursiveRaytrace(renderState_t &state, diffRay_t &r
{
if(tmpColorPasses.size() > 1) tmpColorPasses.reset_colors();

diffRay_t refRay(sp.P, dir[1], scene->rayMinDist);
diffRay_t refRay;
float transp_bias_factor = material->getTransparentBiasFactor();

if(transp_bias_factor > 0.f)
{
bool transpbias_multiply_raydepth = material->getTransparentBiasMultiplyRayDepth();
if(transpbias_multiply_raydepth) transp_bias_factor *= state.raylevel;
refRay = diffRay_t(sp.P+dir[1]*transp_bias_factor, dir[1], scene->rayMinDist);
}
else refRay = diffRay_t(sp.P, dir[1], scene->rayMinDist);

if(diffRaysEnabled) spDiff.refractedRay(ray, refRay, material->getMatIOR());
colorA_t integ = integrate(state, refRay, tmpColorPasses, additionalDepth);

Expand Down

0 comments on commit 264a766

Please sign in to comment.