Commit: dc1db0791ec3b2d52e6734054a001814cd6998ee
Author: Lukas Stockner
Date:   Tue Jan 21 04:45:51 2020 +0100
Branches: master
https://developer.blender.org/rBdc1db0791ec3b2d52e6734054a001814cd6998ee

Cycles: Track specular throughput to account for reflection color in denoising 
albedo pass

To determine the albedo pass, Cycles currently follows the path until a 
predominantly
diffuse-ish material is hit and then takes the albedo there.
This works fine for normal mirrors, but as it completely ignores the color of 
the bounces
before that diffuse-ish material, it also means that any textures that are 
applied to the
specular-ish BSDFs won't affect the albedo pass at all.

Therefore, this patch changes that behaviour so that Cycles also keeps track of 
the
throughput of all specular-ish closures along the path so far and includes that 
in
the albedo pass.

This fixes part of the issue described in T73043. However, since it has an 
effect on the
albedo pass in most scenes, it could cause cause regressions, which is why I'm 
uploading
it as a patch instead of just committing as a fix.

Differential Revision: https://developer.blender.org/D6640

===================================================================

M       intern/cycles/kernel/kernel_accumulate.h
M       intern/cycles/kernel/kernel_passes.h
M       intern/cycles/kernel/kernel_path_state.h
M       intern/cycles/kernel/kernel_types.h

===================================================================

diff --git a/intern/cycles/kernel/kernel_accumulate.h 
b/intern/cycles/kernel/kernel_accumulate.h
index 606c288649a..9ea75d54c5d 100644
--- a/intern/cycles/kernel/kernel_accumulate.h
+++ b/intern/cycles/kernel/kernel_accumulate.h
@@ -528,7 +528,8 @@ ccl_device_inline void 
path_radiance_accum_background(KernelGlobals *kg,
   }
 
 #ifdef __DENOISING_FEATURES__
-  L->denoising_albedo += state->denoising_feature_weight * value;
+  L->denoising_albedo += state->denoising_feature_weight * 
state->denoising_feature_throughput *
+                         value;
 #endif /* __DENOISING_FEATURES__ */
 }
 
diff --git a/intern/cycles/kernel/kernel_passes.h 
b/intern/cycles/kernel/kernel_passes.h
index 7345e9ee5bb..e50fa07a885 100644
--- a/intern/cycles/kernel/kernel_passes.h
+++ b/intern/cycles/kernel/kernel_passes.h
@@ -58,7 +58,8 @@ ccl_device_inline void 
kernel_update_denoising_features(KernelGlobals *kg,
   }
 
   float3 normal = make_float3(0.0f, 0.0f, 0.0f);
-  float3 albedo = make_float3(0.0f, 0.0f, 0.0f);
+  float3 diffuse_albedo = make_float3(0.0f, 0.0f, 0.0f);
+  float3 specular_albedo = make_float3(0.0f, 0.0f, 0.0f);
   float sum_weight = 0.0f, sum_nonspecular_weight = 0.0f;
 
   for (int i = 0; i < sd->num_closure; i++) {
@@ -70,24 +71,28 @@ ccl_device_inline void 
kernel_update_denoising_features(KernelGlobals *kg,
     /* All closures contribute to the normal feature, but only diffuse-like 
ones to the albedo. */
     normal += sc->N * sc->sample_weight;
     sum_weight += sc->sample_weight;
-    if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
-      float3 closure_albedo = sc->weight;
-      /* Closures that include a Fresnel term typically have weights close to 
1 even though their
-       * actual contribution is significantly lower.
-       * To account for this, we scale their weight by the average fresnel 
factor (the same is also
-       * done for the sample weight in the BSDF setup, so we don't need to 
scale that here). */
-      if (CLOSURE_IS_BSDF_MICROFACET_FRESNEL(sc->type)) {
-        MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
-        closure_albedo *= bsdf->extra->fresnel_color;
-      }
-      else if (sc->type == CLOSURE_BSDF_PRINCIPLED_SHEEN_ID) {
-        PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)sc;
-        closure_albedo *= bsdf->avg_value;
-      }
 
-      albedo += closure_albedo;
+    float3 closure_albedo = sc->weight;
+    /* Closures that include a Fresnel term typically have weights close to 1 
even though their
+     * actual contribution is significantly lower.
+     * To account for this, we scale their weight by the average fresnel 
factor (the same is also
+     * done for the sample weight in the BSDF setup, so we don't need to scale 
that here). */
+    if (CLOSURE_IS_BSDF_MICROFACET_FRESNEL(sc->type)) {
+      MicrofacetBsdf *bsdf = (MicrofacetBsdf *)sc;
+      closure_albedo *= bsdf->extra->fresnel_color;
+    }
+    else if (sc->type == CLOSURE_BSDF_PRINCIPLED_SHEEN_ID) {
+      PrincipledSheenBsdf *bsdf = (PrincipledSheenBsdf *)sc;
+      closure_albedo *= bsdf->avg_value;
+    }
+
+    if (bsdf_get_specular_roughness_squared(sc) > sqr(0.075f)) {
+      diffuse_albedo += closure_albedo;
       sum_nonspecular_weight += sc->sample_weight;
     }
+    else {
+      specular_albedo += closure_albedo;
+    }
   }
 
   /* Wait for next bounce if 75% or more sample weight belongs to 
specular-like closures. */
@@ -101,10 +106,14 @@ ccl_device_inline void 
kernel_update_denoising_features(KernelGlobals *kg,
     normal = transform_direction(&worldtocamera, normal);
 
     L->denoising_normal += ensure_finite3(state->denoising_feature_weight * 
normal);
-    L->denoising_albedo += ensure_finite3(state->denoising_feature_weight * 
albedo);
+    L->denoising_albedo += ensure_finite3(state->denoising_feature_weight *
+                                          state->denoising_feature_throughput 
* diffuse_albedo);
 
     state->denoising_feature_weight = 0.0f;
   }
+  else {
+    state->denoising_feature_throughput *= specular_albedo;
+  }
 }
 #endif /* __DENOISING_FEATURES__ */
 
diff --git a/intern/cycles/kernel/kernel_path_state.h 
b/intern/cycles/kernel/kernel_path_state.h
index 8735e3208db..c389c815ae2 100644
--- a/intern/cycles/kernel/kernel_path_state.h
+++ b/intern/cycles/kernel/kernel_path_state.h
@@ -41,9 +41,11 @@ ccl_device_inline void path_state_init(KernelGlobals *kg,
   if (kernel_data.film.pass_denoising_data) {
     state->flag |= PATH_RAY_STORE_SHADOW_INFO;
     state->denoising_feature_weight = 1.0f;
+    state->denoising_feature_throughput = make_float3(1.0f, 1.0f, 1.0f);
   }
   else {
     state->denoising_feature_weight = 0.0f;
+    state->denoising_feature_throughput = make_float3(0.0f, 0.0f, 0.0f);
   }
 #endif /* __DENOISING_FEATURES__ */
 
diff --git a/intern/cycles/kernel/kernel_types.h 
b/intern/cycles/kernel/kernel_types.h
index c35e345763a..4cac6e9ca5f 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -1057,6 +1057,7 @@ typedef struct PathState {
 
 #ifdef __DENOISING_FEATURES__
   float denoising_feature_weight;
+  float3 denoising_feature_throughput;
 #endif /* __DENOISING_FEATURES__ */
 
   /* multiple importance sampling */

_______________________________________________
Bf-blender-cvs mailing list
Bf-blender-cvs@blender.org
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to