Skip to content

Commit

Permalink
Oren Nayar workaround for white/black dots when using bump texture
Browse files Browse the repository at this point in the history
Using bump textures and Oren Nayar diffuse method causes sometimes white/black dots.
Reported in: http://yafaray.org/node/707

I don't yet fully understand the Oren Nayar method, but I suppose the output of the algorithm should be limited to [0..1] values. However the formula as currently implemented allows values outside that range.

From my tests, it seems that when using bump mapping sometimes the output of the Oren Nayar is way out of the [0..1] range, causing the black and white dots. I don't know why is that the case, is it a problem in our implementation of Oren Nayar?  I tried other implementation but had similar or worse problems.

So, in this case, I'll keep the original Oren Nayar implementation and add a simple workaround, putting limits to the output so it always stays in the range [0..1]. However, this probably would need further review to understand why it happens?
  • Loading branch information
DavidBluecame committed Jan 26, 2016
1 parent 66c741e commit a13dcac
Show file tree
Hide file tree
Showing 4 changed files with 9 additions and 10 deletions.
5 changes: 3 additions & 2 deletions src/materials/coatedglossy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -188,12 +188,13 @@ float coatedGlossyMat_t::OrenNayar(const vector3d_t &wi, const vector3d_t &wo, c
double sigma_squared = textureSigma * textureSigma;
double mOrenNayar_TextureA = 1.0 - 0.5 * (sigma_squared / (sigma_squared + 0.33));
double mOrenNayar_TextureB = 0.45 * sigma_squared / (sigma_squared + 0.09);
return mOrenNayar_TextureA + mOrenNayar_TextureB * maxcos_f * sin_alpha * tan_beta;
return std::min(1.f, std::max(0.f, (float) (mOrenNayar_TextureA + mOrenNayar_TextureB * maxcos_f * sin_alpha * tan_beta)));
}
else
{
return orenA + orenB * maxcos_f * sin_alpha * tan_beta;
return std::min(1.f, std::max(0.f, (float) (orenA + orenB * maxcos_f * sin_alpha * tan_beta)));
}

}

color_t coatedGlossyMat_t::eval(const renderState_t &state, const surfacePoint_t &sp, const vector3d_t &wo, const vector3d_t &wi, BSDF_t bsdfs, bool force_eval)const
Expand Down
4 changes: 2 additions & 2 deletions src/materials/glossy.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ float glossyMat_t::OrenNayar(const vector3d_t &wi, const vector3d_t &wo, const v
double sigma_squared = textureSigma * textureSigma;
double mOrenNayar_TextureA = 1.0 - 0.5 * (sigma_squared / (sigma_squared + 0.33));
double mOrenNayar_TextureB = 0.45 * sigma_squared / (sigma_squared + 0.09);
return mOrenNayar_TextureA + mOrenNayar_TextureB * maxcos_f * sin_alpha * tan_beta;
return std::min(1.f, std::max(0.f, (float) (mOrenNayar_TextureA + mOrenNayar_TextureB * maxcos_f * sin_alpha * tan_beta)));
}
else
{
return orenA + orenB * maxcos_f * sin_alpha * tan_beta;
return std::min(1.f, std::max(0.f, (float) (orenA + orenB * maxcos_f * sin_alpha * tan_beta)));
}
}

Expand Down
4 changes: 2 additions & 2 deletions src/materials/glossy2.cc
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ float glossyMat_t::OrenNayar(const vector3d_t &wi, const vector3d_t &wo, const v
double sigma_squared = textureSigma * textureSigma;
double mOrenNayar_TextureA = 1.0 - 0.5 * (sigma_squared / (sigma_squared + 0.33));
double mOrenNayar_TextureB = 0.45 * sigma_squared / (sigma_squared + 0.09);
return mOrenNayar_TextureA + mOrenNayar_TextureB * maxcos_f * sin_alpha * tan_beta;
return std::min(1.f, std::max(0.f, (float) (mOrenNayar_TextureA + mOrenNayar_TextureB * maxcos_f * sin_alpha * tan_beta)));
}
else
{
return orenA + orenB * maxcos_f * sin_alpha * tan_beta;
return std::min(1.f, std::max(0.f, (float) (orenA + orenB * maxcos_f * sin_alpha * tan_beta)));
}
}

Expand Down
6 changes: 2 additions & 4 deletions src/materials/shinydiffuse.cc
Original file line number Diff line number Diff line change
Expand Up @@ -215,14 +215,12 @@ CFLOAT shinyDiffuseMat_t::OrenNayar(const vector3d_t &wi, const vector3d_t &wo,
double sigma_squared = textureSigma * textureSigma;
double mOrenNayar_TextureA = 1.0 - 0.5 * (sigma_squared / (sigma_squared + 0.33));
double mOrenNayar_TextureB = 0.45 * sigma_squared / (sigma_squared + 0.09);

return mOrenNayar_TextureA + mOrenNayar_TextureB * maxcos_f * sin_alpha * tan_beta;
return std::min(1.f, std::max(0.f, (float) (mOrenNayar_TextureA + mOrenNayar_TextureB * maxcos_f * sin_alpha * tan_beta)));
}
else
{
return mOrenNayar_A + mOrenNayar_B * maxcos_f * sin_alpha * tan_beta;
return std::min(1.f, std::max(0.f, (float) (mOrenNayar_A + mOrenNayar_B * maxcos_f * sin_alpha * tan_beta)));
}

}


Expand Down

0 comments on commit a13dcac

Please sign in to comment.