[Bf-blender-cvs] [edb3ab06173] master: Fix T94251: Cycles wrong pointcloud normal for instanced objects

Brecht Van Lommel noreply at git.blender.org
Mon Dec 20 15:05:00 CET 2021


Commit: edb3ab061730aa1369298eb510331e6536c82a04
Author: Brecht Van Lommel
Date:   Mon Dec 20 06:00:38 2021 +0100
Branches: master
https://developer.blender.org/rBedb3ab061730aa1369298eb510331e6536c82a04

Fix T94251: Cycles wrong pointcloud normal for instanced objects

Refactor code a bit also so we need to do fewer matrix transforms for shader
data setup of points and curves.

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

M	intern/cycles/kernel/geom/curve_intersect.h
M	intern/cycles/kernel/geom/point_intersect.h
M	intern/cycles/kernel/geom/shader_data.h

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

diff --git a/intern/cycles/kernel/geom/curve_intersect.h b/intern/cycles/kernel/geom/curve_intersect.h
index 99f4a452d6d..2081eeb3eac 100644
--- a/intern/cycles/kernel/geom/curve_intersect.h
+++ b/intern/cycles/kernel/geom/curve_intersect.h
@@ -727,8 +727,6 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
     const float cosine = safe_sqrtf(1.0f - sine * sine);
 
     sd->N = normalize(sine * bitangent - cosine * normalize(cross(tangent, bitangent)));
-    sd->Ng = -D;
-
 #  if 0
     /* This approximates the position and geometric normal of a thick curve too,
      * but gives too many issues with wrong self intersections. */
@@ -744,25 +742,27 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg,
     /* NOTE: It is possible that P will be the same as P_inside (precision issues, or very small
      * radius). In this case use the view direction to approximate the normal. */
     const float3 P_inside = float4_to_float3(catmull_rom_basis_eval(P_curve, sd->u));
-    const float3 Ng = (!isequal_float3(P, P_inside)) ? normalize(P - P_inside) : -sd->I;
+    const float3 N = (!isequal_float3(P, P_inside)) ? normalize(P - P_inside) : -sd->I;
 
-    sd->N = Ng;
-    sd->Ng = Ng;
+    sd->N = N;
     sd->v = 0.0f;
   }
 
 #  ifdef __DPDU__
   /* dPdu/dPdv */
   sd->dPdu = dPdu;
-  sd->dPdv = cross(dPdu, sd->Ng);
 #  endif
 
+  /* Convert to world space. */
   if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
-    const Transform tfm = object_get_transform(kg, sd);
-    P = transform_point(&tfm, P);
+    object_position_transform_auto(kg, sd, &P);
+    object_normal_transform_auto(kg, sd, &sd->N);
+    object_dir_transform_auto(kg, sd, &sd->dPdu);
   }
 
   sd->P = P;
+  sd->Ng = (sd->type & PRIMITIVE_CURVE_RIBBON) ? sd->I : sd->N;
+  sd->dPdv = cross(sd->dPdu, sd->Ng);
   sd->shader = kernel_tex_fetch(__curves, sd->prim).shader_id;
 }
 
diff --git a/intern/cycles/kernel/geom/point_intersect.h b/intern/cycles/kernel/geom/point_intersect.h
index b4d96ade7be..757c8b81efa 100644
--- a/intern/cycles/kernel/geom/point_intersect.h
+++ b/intern/cycles/kernel/geom/point_intersect.h
@@ -104,17 +104,12 @@ ccl_device_inline void point_shader_setup(KernelGlobals kg,
   sd->v = isect->v;
 #  endif
 
-  /* Computer point center for normal. */
+  /* Compute point center for normal. */
   float3 center = float4_to_float3((isect->type & PRIMITIVE_MOTION) ?
                                        motion_point(kg, sd->object, sd->prim, sd->time) :
                                        kernel_tex_fetch(__points, sd->prim));
-
   if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
-    const Transform tfm = object_get_transform(kg, sd);
-
-#  ifndef __KERNEL_OPTIX__
-    center = transform_point(&tfm, center);
-#  endif
+    object_position_transform_auto(kg, sd, &center);
   }
 
   /* Normal */
diff --git a/intern/cycles/kernel/geom/shader_data.h b/intern/cycles/kernel/geom/shader_data.h
index 569393c306c..f5055d8b285 100644
--- a/intern/cycles/kernel/geom/shader_data.h
+++ b/intern/cycles/kernel/geom/shader_data.h
@@ -82,43 +82,45 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg,
   }
   else
 #endif
-      if (sd->type == PRIMITIVE_TRIANGLE) {
-    /* static triangle */
-    float3 Ng = triangle_normal(kg, sd);
-    sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
+  {
+    if (sd->type == PRIMITIVE_TRIANGLE) {
+      /* static triangle */
+      float3 Ng = triangle_normal(kg, sd);
+      sd->shader = kernel_tex_fetch(__tri_shader, sd->prim);
 
-    /* vectors */
-    sd->P = triangle_refine(kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim);
-    sd->Ng = Ng;
-    sd->N = Ng;
+      /* vectors */
+      sd->P = triangle_refine(kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim);
+      sd->Ng = Ng;
+      sd->N = Ng;
 
-    /* smooth normal */
-    if (sd->shader & SHADER_SMOOTH_NORMAL)
-      sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
+      /* smooth normal */
+      if (sd->shader & SHADER_SMOOTH_NORMAL)
+        sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v);
 
 #ifdef __DPDU__
-    /* dPdu/dPdv */
-    triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
+      /* dPdu/dPdv */
+      triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv);
 #endif
-  }
-  else {
-    /* motion triangle */
-    motion_triangle_shader_setup(
-        kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim, false);
-  }
-
-  sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+    }
+    else {
+      /* motion triangle */
+      motion_triangle_shader_setup(
+          kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim, false);
+    }
 
-  if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
-    /* instance transform */
-    object_normal_transform_auto(kg, sd, &sd->N);
-    object_normal_transform_auto(kg, sd, &sd->Ng);
+    if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) {
+      /* instance transform */
+      object_normal_transform_auto(kg, sd, &sd->N);
+      object_normal_transform_auto(kg, sd, &sd->Ng);
 #ifdef __DPDU__
-    object_dir_transform_auto(kg, sd, &sd->dPdu);
-    object_dir_transform_auto(kg, sd, &sd->dPdv);
+      object_dir_transform_auto(kg, sd, &sd->dPdu);
+      object_dir_transform_auto(kg, sd, &sd->dPdv);
 #endif
+    }
   }
 
+  sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags;
+
   /* backfacing test */
   bool backfacing = (dot(sd->Ng, sd->I) < 0.0f);



More information about the Bf-blender-cvs mailing list