[Bf-blender-cvs] [48754bc1460] blender-v3.2-release: Fix T97867: Cycles MNEE blocky artefacts for rough refractive interfaces

Olivier Maury noreply at git.blender.org
Mon May 16 15:17:45 CEST 2022


Commit: 48754bc1460428c7a5ffbfc135fe6b5bbe742ec2
Author: Olivier Maury
Date:   Fri May 13 20:50:47 2022 +0200
Branches: blender-v3.2-release
https://developer.blender.org/rB48754bc1460428c7a5ffbfc135fe6b5bbe742ec2

Fix T97867: Cycles MNEE blocky artefacts for rough refractive interfaces

Made tangent frame consistent across the surface regardless of the sample,
which was not the case with the previous algorithm. Previously, a tangent
frame would stay consistent for the same sample throughout the walk, but not
from sample to sample for the same triangle. This actually resulted in code
simplification.

Also includes additional fixes:

* Fixed an important bug that manifested itself with multiple lights in the
  scene, where caustics had abnormally low amplitude: The final light pdf did
  not include the light distribution pdf.
* Removed unnecessary orthonormal basis generation function, using cycles'
  native one instead.
* Increased solver max iteration back to 64: It turns out we sometimes need
  these extra iterations in cases where projection back to the surface takes
  many steps. The effective solver iteration count, the most expensive part,
  is actually much less than the raw iteration count.

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

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

M	intern/cycles/kernel/integrator/mnee.h

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

diff --git a/intern/cycles/kernel/integrator/mnee.h b/intern/cycles/kernel/integrator/mnee.h
index 7820d71f15c..7b86c660380 100644
--- a/intern/cycles/kernel/integrator/mnee.h
+++ b/intern/cycles/kernel/integrator/mnee.h
@@ -36,7 +36,7 @@
  *  https://cg.ivd.kit.edu/english/HSLT.php
  */
 
-#  define MNEE_MAX_ITERATIONS 32
+#  define MNEE_MAX_ITERATIONS 64
 #  define MNEE_MAX_INTERSECTION_COUNT 10
 #  define MNEE_SOLVER_THRESHOLD 0.001f
 #  define MNEE_MINIMUM_STEP_SIZE 0.0001f
@@ -140,26 +140,8 @@ ccl_device_forceinline void mnee_update_light_sample(KernelGlobals kg,
     ls->D = normalize_len(ls->P - P, &ls->t);
     ls->pdf = fabsf(klight->area.invarea);
   }
-}
 
-/* Compute orthonormal basis
- * https://graphics.pixar.com/library/OrthonormalB/paper.pdf  */
-ccl_device_forceinline void mnee_make_orthonormals(const float3 n,
-                                                   ccl_private float3 *dp_du,
-                                                   ccl_private float3 *dp_dv)
-{
-  if (n.z < 0.0f) {
-    const float a = 1.0f / (1.0f - n.z);
-    const float b = n.x * n.y * a;
-    *dp_du = make_float3(1.0f - n.x * n.x * a, -b, n.x);
-    *dp_dv = make_float3(b, n.y * n.y * a - 1.0f, -n.y);
-  }
-  else {
-    const float a = 1.0f / (1.0f + n.z);
-    const float b = -n.x * n.y * a;
-    *dp_du = make_float3(1.0f - n.x * n.x * a, b, -n.x);
-    *dp_dv = make_float3(b, 1.0f - n.y * n.y * a, -n.y);
-  }
+  ls->pdf *= kernel_data.integrator.pdf_lights;
 }
 
 /* Manifold vertex setup from ray and intersection data */
@@ -170,8 +152,7 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
                                                        const float2 n_offset,
                                                        ccl_private const Ray *ray,
                                                        ccl_private const Intersection *isect,
-                                                       ccl_private ShaderData *sd_vtx,
-                                                       bool seed)
+                                                       ccl_private ShaderData *sd_vtx)
 {
   sd_vtx->object = (isect->object == OBJECT_NONE) ? kernel_tex_fetch(__prim_object, isect->prim) :
                                                     isect->object;
@@ -263,30 +244,13 @@ ccl_device_forceinline void mnee_setup_manifold_vertex(KernelGlobals kg,
   dp_dv *= inv_len_dp_dv;
   dn_dv *= inv_len_dp_dv;
 
-  /* Final local differential geometry. */
-  if (seed) {
-    vtx->dp_du = dp_du;
-    vtx->dp_dv = dp_dv;
-    vtx->dn_du = dn_du;
-    vtx->dn_dv = dn_dv;
-  }
-  else {
-    /* Find angle subtended by reference direction (travel direction). */
-    const float3 reference_direction = normalize(sd_vtx->P - vtx->p);
-    const float reference_theta = atan2(dot(reference_direction, vtx->dp_dv),
-                                        dot(reference_direction, vtx->dp_du));
-    const float current_theta = atan2(dot(reference_direction, dp_dv),
-                                      dot(reference_direction, dp_du));
-    const float theta = reference_theta - current_theta;
-
-    /* Rotate (dp_du,dp_dv) to be consistent with previous tangent frame. */
-    float cos_theta, sin_theta;
-    fast_sincosf(theta, &sin_theta, &cos_theta);
-    vtx->dp_du = cos_theta * dp_du - sin_theta * dp_dv;
-    vtx->dp_dv = sin_theta * dp_du + cos_theta * dp_dv;
-    vtx->dn_du = cos_theta * dn_du - sin_theta * dn_dv;
-    vtx->dn_dv = sin_theta * dn_du + cos_theta * dn_dv;
-  }
+  /* Find consistent tangent frame for every point on the surface. */
+  make_orthonormals(vtx->ng, &vtx->dp_du, &vtx->dp_dv);
+  /* Apply the equivalent rotation to the normal derivatives. */
+  const float cos_theta = dot(dp_du, vtx->dp_du);
+  const float sin_theta = -dot(dp_dv, vtx->dp_du);
+  vtx->dn_du = cos_theta * dn_du - sin_theta * dn_dv;
+  vtx->dn_dv = sin_theta * dn_du + cos_theta * dn_dv;
 
   /* Manifold vertex position. */
   vtx->p = sd_vtx->P;
@@ -577,8 +541,7 @@ ccl_device_forceinline bool mnee_newton_solver(KernelGlobals kg,
                                  mv.n_offset,
                                  &projection_ray,
                                  &projection_isect,
-                                 sd_vtx,
-                                 false);
+                                 sd_vtx);
 
       /* Fail newton solve if we are not making progress, probably stuck trying to move off the
        * edge of the mesh. */
@@ -749,7 +712,7 @@ ccl_device_forceinline bool mnee_compute_transfer_matrix(ccl_private const Shade
 
   /* Local differential geometry. */
   float3 dp_du, dp_dv;
-  mnee_make_orthonormals(ls->Ng, &dp_du, &dp_dv);
+  make_orthonormals(ls->Ng, &dp_du, &dp_dv);
 
   /* Direction toward surface sample. */
   float3 wi = vertex_count == 1 ? sd->P - m.p : vertices[mi - 1].p - m.p;
@@ -1051,7 +1014,7 @@ ccl_device_forceinline int kernel_path_mnee_sample(KernelGlobals kg,
 
           /* Setup differential geometry on vertex. */
           mnee_setup_manifold_vertex(
-              kg, &mv, bsdf, eta, h, &probe_ray, &probe_isect, sd_mnee, true);
+              kg, &mv, bsdf, eta, h, &probe_ray, &probe_isect, sd_mnee);
           break;
         }
       }



More information about the Bf-blender-cvs mailing list