Skip to content

Commit

Permalink
Improvements to advanced diffuse shading models.
Browse files Browse the repository at this point in the history
- Fixed a bug in the Oren-Nayar implementation.
- Changed the interaction between the Oren-Nayar and Lommel-Seeliger models to work as originally intended, with `lommel_seeliger K oren_nayar SIGMA` giving a  K:(1-K) weighted average of Lommel-Seeliger and Oren-Nayar).
- Implemented mechanisms to compensate for the reduced effective brightness of the Oren-Nayar and Lommel-Seeliger models when using canonical brightness parameterization. Using `diffuse albedo FLOAT` should now give identical bihemispherical albedos (ratio of total outgoing light vs. total incoming light) for all models. Also, when using canonical brightness parameterization (`diffuse FLOAT`), the Lambertian-based approximation used in radiosity should now match the effective bihemispherical albedo.
  • Loading branch information
c-lipka committed Apr 7, 2016
1 parent a419e30 commit 12f9827
Show file tree
Hide file tree
Showing 7 changed files with 38 additions and 31 deletions.
2 changes: 1 addition & 1 deletion source/base/version.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
#define OFFICIAL_VERSION_STRING "3.7.1"
#define OFFICIAL_VERSION_NUMBER 371

#define POV_RAY_PRERELEASE "alpha.8545805"
#define POV_RAY_PRERELEASE "alpha.8555867"

#if (POV_RAY_IS_AUTOBUILD == 1) && ((POV_RAY_IS_OFFICIAL == 1) || (POV_RAY_IS_SEMI_OFFICIAL == 1))
#ifdef POV_RAY_PRERELEASE
Expand Down
2 changes: 1 addition & 1 deletion source/core/lighting/photons.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -460,7 +460,7 @@ void PhotonTrace::ComputeLightedTexture(MathColour& LightCol, ColourChannel&, co
diffuseWeight = ResCol.WeightAbsGreyscale();
// use top-layer finish only
if(Texture->Finish)
diffuseWeight*=Texture->Finish->Diffuse * Texture->Finish->BrillianceAdjust;
diffuseWeight*=Texture->Finish->Diffuse * Texture->Finish->DiffuseAlbedoAdjust;
refractionWeight = Trans;
// reflection only for top layer!!!!!!
// TODO is "rend()" the top layer or the bottom layer???
Expand Down
4 changes: 2 additions & 2 deletions source/core/material/texture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1159,8 +1159,8 @@ FINISH *Create_Finish()
New->DiffuseBack = 0.0;
New->Brilliance = 1.0;
New->BrillianceOut = 1.0;
New->BrillianceAdjust = 1.0;
New->BrillianceAdjustRad = 1.0;
New->DiffuseAlbedoAdjust = 1.0;
New->DiffuseAlbedoAdjustRad = 1.0;
New->LommelSeeligerWeight = 0.0;
New->OrenNayarA = 1.0;
New->OrenNayarB = 0.0;
Expand Down
2 changes: 1 addition & 1 deletion source/core/material/texture.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ struct Texture_Struct : public Pattern_Struct

struct Finish_Struct
{
SNGL Diffuse, DiffuseBack, Brilliance, BrillianceOut, BrillianceAdjust, BrillianceAdjustRad;
SNGL Diffuse, DiffuseBack, Brilliance, BrillianceOut, DiffuseAlbedoAdjust, DiffuseAlbedoAdjustRad;

/// How much of the diffuse contribution should be computed using the Lommel-Seeliger model.
///
Expand Down
31 changes: 18 additions & 13 deletions source/core/render/trace.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -882,7 +882,7 @@ void Trace::ComputeLightedTexture(MathColour& resultColour, ColourChannel& resul

if (sceneData->radiositySettings.brilliance)
{
diffuse *= layer->Finish->BrillianceAdjustRad;
diffuse *= layer->Finish->DiffuseAlbedoAdjustRad;
brilliance = layer->Finish->Brilliance;
}

Expand All @@ -909,7 +909,7 @@ void Trace::ComputeLightedTexture(MathColour& resultColour, ColourChannel& resul

diffuse = layer->Finish->DiffuseBack;
if (sceneData->radiositySettings.brilliance)
diffuse *= layer->Finish->BrillianceAdjustRad;
diffuse *= layer->Finish->DiffuseAlbedoAdjustRad;

// if backside radiosity calculation needed, but not yet done, do it now
// TODO FIXME - [CLi] with "normal on", shouldn't we compute radiosity for each layer separately (if it has pertubed normals)?
Expand Down Expand Up @@ -2374,35 +2374,40 @@ void Trace::ComputeDiffuseColour(const FINISH *finish, const Vector3d& lightDire
const MathColour& layer_pigment_colour, double relativeIor, double attenuation, bool backside)
{
double cos_in, cos_out, intensity;
double diffuse = (backside? finish->DiffuseBack : finish->Diffuse) * finish->BrillianceAdjust;
double diffuse = (backside? finish->DiffuseBack : finish->Diffuse) * finish->DiffuseAlbedoAdjust;

if (diffuse <= 0.0)
return;

cos_in = dot(layer_normal, lightDirection);
cos_in = fabs(dot(layer_normal, lightDirection));

// Brilliance is likely to be 1.0 (default value)
if(finish->Brilliance != 1.0)
intensity = pow(fabs(cos_in), (double) finish->Brilliance);
intensity = pow(cos_in, (double) finish->Brilliance);
else
intensity = fabs(cos_in);
intensity = cos_in;

if (finish->Fresnel || (finish->LommelSeeligerWeight != 0.0) || (finish->OrenNayarB != 0.0))
cos_out = -dot(layer_normal, eyeDirection);

if (finish->LommelSeeligerWeight != 0.0)
intensity *= (1.0 - finish->LommelSeeligerWeight + finish->LommelSeeligerWeight / (cos_in + cos_out));
cos_out = fabs(dot(layer_normal, eyeDirection));

if (finish->OrenNayarA != 1.0)
intensity *= finish->OrenNayarA;
if (finish->OrenNayarB != 0.0)
{
Vector3d projected_in = lightDirection - layer_normal * cos_in;
Vector3d projected_out = -eyeDirection - layer_normal * cos_out;
Vector3d projected_in = (lightDirection - layer_normal * cos_in ).normalized();
Vector3d projected_out = (-eyeDirection - layer_normal * cos_out).normalized();
double cos_phi = dot(projected_in, projected_out);
double theta_in = acos(cos_in);
double theta_out = acos(cos_out);
double alpha = max(theta_in, theta_out);
double beta = min(theta_in, theta_out);
intensity *= (finish->OrenNayarA + finish->OrenNayarB*max(0.0,cos_phi)*sin(alpha)*tan(beta));
intensity += finish->OrenNayarB * cos_in * max(0.0,cos_phi) * sin(alpha) * tan(beta);
}

if (finish->LommelSeeligerWeight != 0.0)
{
intensity *= (1.0 - finish->LommelSeeligerWeight);
intensity += finish->LommelSeeligerWeight * cos_in / (cos_in + cos_out);
}

intensity *= diffuse * attenuation;
Expand Down
26 changes: 14 additions & 12 deletions source/parser/parser_materials.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2616,10 +2616,6 @@ void Parser::Parse_Finish (FINISH **Finish_Ptr)
PossibleError("Finish-level 'fresnel' keyword found in combination with the Oren-Nayar diffuse model."
" The interaction of these features has not been finalized yet, and is known to be bogus."
" Expect future versions of POV-Ray to render this scene differently without warning.");
if (diffuseAdjust)
PossibleError("'diffuse albedo' found in combination with the Oren-Nayar diffuse model."
" The interaction of these features has not been finalized yet."
" Expect future versions of POV-Ray to render this scene differently without warning.");
}

if (New->LommelSeeligerWeight != 0.0)
Expand All @@ -2628,10 +2624,6 @@ void Parser::Parse_Finish (FINISH **Finish_Ptr)
PossibleError("Finish-level 'fresnel' keyword found in combination with the Lommel-Seeliger diffuse model."
" The interaction of these features has not been finalized yet, and is known to be bogus."
" Expect future versions of POV-Ray to render this scene differently without warning.");
if (diffuseAdjust)
PossibleError("'diffuse albedo' found in combination with the Lommel_Seeliger diffuse model."
" The interaction of these features has not been finalized yet."
" Expect future versions of POV-Ray to render this scene differently without warning.");
}

if ((sceneData->EffectiveLanguageVersion() >= 370) && ambientSet)
Expand Down Expand Up @@ -2659,15 +2651,25 @@ void Parser::Parse_Finish (FINISH **Finish_Ptr)
// adjust diffuse, phong and/or specular intensity parameters
// so that a user-specified value of 1.0 corresponds to a
// backscattering of 100% of the incoming light
double EffectiveBiHemisphericalAlbedo = 2.0 / (New->Brilliance + 1.0);
if (New->OrenNayarA != 1.0)
EffectiveBiHemisphericalAlbedo *= New->OrenNayarA;
if (New->OrenNayarB != 0.0)
EffectiveBiHemisphericalAlbedo += New->OrenNayarB * (2.0/3.0 - (64.0/45.0)*(1.0/M_PI));
if (New->LommelSeeligerWeight != 0.0)
{
EffectiveBiHemisphericalAlbedo *= (1.0 - New->LommelSeeligerWeight);
EffectiveBiHemisphericalAlbedo += New->LommelSeeligerWeight * ((8.0 * (1.0-log(2.0))) / 3.0);
}
if (diffuseAdjust)
{
New->BrillianceAdjust = (New->Brilliance + 1.0) / 2.0;
New->BrillianceAdjustRad = 1.0;
New->DiffuseAlbedoAdjust = 1.0 / EffectiveBiHemisphericalAlbedo;
New->DiffuseAlbedoAdjustRad = 1.0;
}
else
{
New->BrillianceAdjust = 1.0;
New->BrillianceAdjustRad = 2.0 / (New->Brilliance + 1.0);
New->DiffuseAlbedoAdjust = 1.0;
New->DiffuseAlbedoAdjustRad = EffectiveBiHemisphericalAlbedo;
}
if (phongAdjust)
New->Phong *= (New->Phong_Size + 1.0) / 2.0;
Expand Down
2 changes: 1 addition & 1 deletion unix/VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
3.7.1-alpha.8545805
3.7.1-alpha.8555867

0 comments on commit 12f9827

Please sign in to comment.