[Bf-blender-cvs] [bd2b1a67a7b] master: Fix T74939: Random Walk subsurface appearance in OptiX does not match other engines

Patrick Mours noreply at git.blender.org
Thu Mar 26 13:00:26 CET 2020


Commit: bd2b1a67a7b9444cc0dbabe0f46e5a512c3eb7e5
Author: Patrick Mours
Date:   Wed Mar 25 18:30:39 2020 +0100
Branches: master
https://developer.blender.org/rBbd2b1a67a7b9444cc0dbabe0f46e5a512c3eb7e5

Fix T74939: Random Walk subsurface appearance in OptiX does not match other engines

Random Walk subsurface scattering did look different with OptiX because transmittance is
calculated based on the hit distance, but the OptiX implementation of `scene_intersect_local`
would return the distance in world space, while the Cycles BVH version returns it in object
space. This fixes the problem by simply skipping the object->world transforms in all the
places using the result of `scene_intersect_local` with OptiX.

Reviewed By: brecht

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

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

M	intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
M	intern/cycles/kernel/geom/geom_triangle_intersect.h
M	intern/cycles/kernel/kernel_subsurface.h

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

diff --git a/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h b/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
index 49d4829af38..859d919f0bb 100644
--- a/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_motion_triangle_intersect.h
@@ -103,17 +103,21 @@ ccl_device_inline
                                  const Ray *ray,
                                  float3 verts[3])
 {
+#  ifdef __KERNEL_OPTIX__
+  /* isect->t is always in world space with OptiX. */
+  return motion_triangle_refine(kg, sd, isect, ray, verts);
+#  else
   float3 P = ray->P;
   float3 D = ray->D;
   float t = isect->t;
 
-#  ifdef __INTERSECTION_REFINE__
+#    ifdef __INTERSECTION_REFINE__
   if (isect->object != OBJECT_NONE) {
-#    ifdef __OBJECT_MOTION__
+#      ifdef __OBJECT_MOTION__
     Transform tfm = sd->ob_itfm;
-#    else
+#      else
     Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#    endif
+#      endif
 
     P = transform_point(&tfm, P);
     D = transform_direction(&tfm, D);
@@ -135,19 +139,20 @@ ccl_device_inline
   P = P + D * rt;
 
   if (isect->object != OBJECT_NONE) {
-#    ifdef __OBJECT_MOTION__
+#      ifdef __OBJECT_MOTION__
     Transform tfm = sd->ob_tfm;
-#    else
+#      else
     Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#    endif
+#      endif
 
     P = transform_point(&tfm, P);
   }
 
   return P;
-#  else  /* __INTERSECTION_REFINE__ */
+#    else  /* __INTERSECTION_REFINE__ */
   return P + D * t;
-#  endif /* __INTERSECTION_REFINE__ */
+#    endif /* __INTERSECTION_REFINE__ */
+#  endif
 }
 #endif /* __BVH_LOCAL__ */
 
diff --git a/intern/cycles/kernel/geom/geom_triangle_intersect.h b/intern/cycles/kernel/geom/geom_triangle_intersect.h
index 68075199402..6604806f73b 100644
--- a/intern/cycles/kernel/geom/geom_triangle_intersect.h
+++ b/intern/cycles/kernel/geom/geom_triangle_intersect.h
@@ -690,16 +690,20 @@ ccl_device_inline float3 triangle_refine_local(KernelGlobals *kg,
                                                const Intersection *isect,
                                                const Ray *ray)
 {
+#ifdef __KERNEL_OPTIX__
+  /* isect->t is always in world space with OptiX. */
+  return triangle_refine(kg, sd, isect, ray);
+#else
   float3 P = ray->P;
   float3 D = ray->D;
   float t = isect->t;
 
   if (isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
+#  ifdef __OBJECT_MOTION__
     Transform tfm = sd->ob_itfm;
-#else
+#  else
     Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_INVERSE_TRANSFORM);
-#endif
+#  endif
 
     P = transform_point(&tfm, P);
     D = transform_direction(&tfm, D);
@@ -708,7 +712,7 @@ ccl_device_inline float3 triangle_refine_local(KernelGlobals *kg,
 
   P = P + D * t;
 
-#ifdef __INTERSECTION_REFINE__
+#  ifdef __INTERSECTION_REFINE__
   const uint tri_vindex = kernel_tex_fetch(__prim_tri_index, isect->prim);
   const float4 tri_a = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 0),
                tri_b = kernel_tex_fetch(__prim_tri_verts, tri_vindex + 1),
@@ -728,19 +732,20 @@ ccl_device_inline float3 triangle_refine_local(KernelGlobals *kg,
     float rt = dot(edge2, qvec) / det;
     P = P + D * rt;
   }
-#endif /* __INTERSECTION_REFINE__ */
+#  endif /* __INTERSECTION_REFINE__ */
 
   if (isect->object != OBJECT_NONE) {
-#ifdef __OBJECT_MOTION__
+#  ifdef __OBJECT_MOTION__
     Transform tfm = sd->ob_tfm;
-#else
+#  else
     Transform tfm = object_fetch_transform(kg, isect->object, OBJECT_TRANSFORM);
-#endif
+#  endif
 
     P = transform_point(&tfm, P);
   }
 
   return P;
+#endif
 }
 
 CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_subsurface.h b/intern/cycles/kernel/kernel_subsurface.h
index 23e30db1b08..ed8572467ea 100644
--- a/intern/cycles/kernel/kernel_subsurface.h
+++ b/intern/cycles/kernel/kernel_subsurface.h
@@ -428,12 +428,17 @@ ccl_device_noinline
     hit = (ss_isect->num_hits > 0);
 
     if (hit) {
+#ifdef __KERNEL_OPTIX__
+      /* t is always in world space with OptiX. */
+      t = ss_isect->hits[0].t;
+#else
       /* Compute world space distance to surface hit. */
       float3 D = ray->D;
       object_inverse_dir_transform(kg, sd, &D);
       D = normalize(D) * ss_isect->hits[0].t;
       object_dir_transform(kg, sd, &D);
       t = len(D);
+#endif
     }
 
     /* Advance to new scatter location. */



More information about the Bf-blender-cvs mailing list