Cycles: Experiment with replacing Sharp Glossy with GGX when Filter Glossy is used

The idea is to make it simpler to remove noise from scenes when some prop uses
Sharp glossy closure and causes noise in certain cases. Previously Sharp Glossy
was not affected by Filter Glossy at all, which was quite confusing.

Here is a file which demonstrates the issue: {F417797}

After applying the patch all the noise from the scene is gone.

This change also solves fireflies reported in T50700.

Reviewers: brecht, lukasstockner97

Differential Revision: https://developer.blender.org/D2416
This commit is contained in:
Sergey Sharybin 2016-12-14 12:22:57 +01:00
parent 406398213c
commit 845ba1a6fb
2 changed files with 63 additions and 15 deletions

View File

@ -1931,21 +1931,36 @@ GlossyBsdfNode::GlossyBsdfNode()
void GlossyBsdfNode::simplify_settings(Scene *scene)
{
if(distribution_orig == NBUILTIN_CLOSURES) {
roughness_orig = roughness;
distribution_orig = distribution;
}
else {
/* By default we use original values, so we don't worry about restoring
* defaults later one and can only do override when needed.
*/
roughness = roughness_orig;
distribution = distribution_orig;
}
Integrator *integrator = scene->integrator;
ShaderInput *roughness_input = input("Roughness");
if(integrator->filter_glossy == 0.0f) {
/* Fallback to Sharp closure for Roughness close to 0.
* Note: Keep the epsilon in sync with kernel!
*/
ShaderInput *roughness_input = input("Roughness");
if(!roughness_input->link && roughness <= 1e-4f) {
distribution = CLOSURE_BSDF_REFLECTION_ID;
}
}
else {
/* Rollback to original distribution when filter glossy is used. */
distribution = distribution_orig;
/* If filter glossy is used we replace Sharp glossy with GGX so we can
* benefit from closure blur to remove unwanted noise.
*/
if(roughness_input->link == NULL &&
distribution == CLOSURE_BSDF_REFLECTION_ID)
{
distribution = CLOSURE_BSDF_MICROFACET_GGX_ID;
roughness = 0.0f;
}
}
closure = distribution;
}
@ -1953,7 +1968,8 @@ void GlossyBsdfNode::simplify_settings(Scene *scene)
bool GlossyBsdfNode::has_integrator_dependency()
{
ShaderInput *roughness_input = input("Roughness");
return !roughness_input->link && roughness <= 1e-4f;
return !roughness_input->link &&
(distribution == CLOSURE_BSDF_REFLECTION_ID || roughness <= 1e-4f);
}
void GlossyBsdfNode::compile(SVMCompiler& compiler)
@ -2008,21 +2024,36 @@ GlassBsdfNode::GlassBsdfNode()
void GlassBsdfNode::simplify_settings(Scene *scene)
{
if(distribution_orig == NBUILTIN_CLOSURES) {
roughness_orig = roughness;
distribution_orig = distribution;
}
else {
/* By default we use original values, so we don't worry about restoring
* defaults later one and can only do override when needed.
*/
roughness = roughness_orig;
distribution = distribution_orig;
}
Integrator *integrator = scene->integrator;
ShaderInput *roughness_input = input("Roughness");
if(integrator->filter_glossy == 0.0f) {
/* Fallback to Sharp closure for Roughness close to 0.
* Note: Keep the epsilon in sync with kernel!
*/
ShaderInput *roughness_input = input("Roughness");
if(!roughness_input->link && roughness <= 1e-4f) {
distribution = CLOSURE_BSDF_SHARP_GLASS_ID;
}
}
else {
/* Rollback to original distribution when filter glossy is used. */
distribution = distribution_orig;
/* If filter glossy is used we replace Sharp glossy with GGX so we can
* benefit from closure blur to remove unwanted noise.
*/
if(roughness_input->link == NULL &&
distribution == CLOSURE_BSDF_SHARP_GLASS_ID)
{
distribution = CLOSURE_BSDF_MICROFACET_GGX_GLASS_ID;
roughness = 0.0f;
}
}
closure = distribution;
}
@ -2030,7 +2061,8 @@ void GlassBsdfNode::simplify_settings(Scene *scene)
bool GlassBsdfNode::has_integrator_dependency()
{
ShaderInput *roughness_input = input("Roughness");
return !roughness_input->link && roughness <= 1e-4f;
return !roughness_input->link &&
(distribution == CLOSURE_BSDF_SHARP_GLASS_ID || roughness <= 1e-4f);
}
void GlassBsdfNode::compile(SVMCompiler& compiler)
@ -2085,21 +2117,36 @@ RefractionBsdfNode::RefractionBsdfNode()
void RefractionBsdfNode::simplify_settings(Scene *scene)
{
if(distribution_orig == NBUILTIN_CLOSURES) {
roughness_orig = roughness;
distribution_orig = distribution;
}
else {
/* By default we use original values, so we don't worry about restoring
* defaults later one and can only do override when needed.
*/
roughness = roughness_orig;
distribution = distribution_orig;
}
Integrator *integrator = scene->integrator;
ShaderInput *roughness_input = input("Roughness");
if(integrator->filter_glossy == 0.0f) {
/* Fallback to Sharp closure for Roughness close to 0.
* Note: Keep the epsilon in sync with kernel!
*/
ShaderInput *roughness_input = input("Roughness");
if(!roughness_input->link && roughness <= 1e-4f) {
distribution = CLOSURE_BSDF_REFRACTION_ID;
}
}
else {
/* Rollback to original distribution when filter glossy is used. */
distribution = distribution_orig;
/* If filter glossy is used we replace Sharp glossy with GGX so we can
* benefit from closure blur to remove unwanted noise.
*/
if(roughness_input->link == NULL &&
distribution == CLOSURE_BSDF_REFRACTION_ID)
{
distribution = CLOSURE_BSDF_MICROFACET_GGX_REFRACTION_ID;
roughness = 0.0f;
}
}
closure = distribution;
}
@ -2107,7 +2154,8 @@ void RefractionBsdfNode::simplify_settings(Scene *scene)
bool RefractionBsdfNode::has_integrator_dependency()
{
ShaderInput *roughness_input = input("Roughness");
return !roughness_input->link && roughness <= 1e-4f;
return !roughness_input->link &&
(distribution == CLOSURE_BSDF_REFRACTION_ID || roughness <= 1e-4f);
}
void RefractionBsdfNode::compile(SVMCompiler& compiler)

View File

@ -388,7 +388,7 @@ public:
bool has_integrator_dependency();
ClosureType get_closure_type() { return distribution; }
float roughness;
float roughness, roughness_orig;
ClosureType distribution, distribution_orig;
};
@ -400,7 +400,7 @@ public:
bool has_integrator_dependency();
ClosureType get_closure_type() { return distribution; }
float roughness, IOR;
float roughness, roughness_orig, IOR;
ClosureType distribution, distribution_orig;
};
@ -412,7 +412,7 @@ public:
bool has_integrator_dependency();
ClosureType get_closure_type() { return distribution; }
float roughness, IOR;
float roughness, roughness_orig, IOR;
ClosureType distribution, distribution_orig;
};