Commit: c18d91918fbb18d8c0d2e95de210ba818937cd87
Author: Sergey Sharybin
Date:   Tue Aug 3 12:20:28 2021 +0200
Branches: master
https://developer.blender.org/rBc18d91918fbb18d8c0d2e95de210ba818937cd87

Cycles: More flexible GI Approximation AO distance control

The goal: allow to easily use AO approximation in scenes which combines
both small and large scale objects.

The idea: use per-object AO distance which will allow to override world
settings. Instancer object will "propagate" its AO distance to all its
instances unless the instance defines own distance (this allows to
modify AO distance in the shot files, without requiring to modify props
used in the shots.

Available from the new Fats GI Approximation panel in object properties.

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

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

M       intern/cycles/blender/addon/properties.py
M       intern/cycles/blender/addon/ui.py
M       intern/cycles/blender/blender_object.cpp
M       intern/cycles/kernel/bvh/bvh_util.h
M       intern/cycles/kernel/kernel_bake.h
M       intern/cycles/kernel/kernel_path.h
M       intern/cycles/kernel/kernel_path_branched.h
M       intern/cycles/kernel/kernel_types.h
M       intern/cycles/kernel/split/kernel_scene_intersect.h
M       intern/cycles/render/object.cpp
M       intern/cycles/render/object.h

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

diff --git a/intern/cycles/blender/addon/properties.py 
b/intern/cycles/blender/addon/properties.py
index 4cd75edee5f..70efb1054a2 100644
--- a/intern/cycles/blender/addon/properties.py
+++ b/intern/cycles/blender/addon/properties.py
@@ -1268,6 +1268,14 @@ class CyclesObjectSettings(bpy.types.PropertyGroup):
         default=0.1,
     )
 
+    ao_distance: FloatProperty(
+        name="AO Distance",
+        description="AO distance used for approximate global illumination (0 
means use world setting)",
+        min=0.0,
+        default=0.0,
+        subtype='DISTANCE',
+    )
+
     is_shadow_catcher: BoolProperty(
         name="Shadow Catcher",
         description="Only render shadows on this object, for compositing 
renders into real footage",
diff --git a/intern/cycles/blender/addon/ui.py 
b/intern/cycles/blender/addon/ui.py
index e9a4ce77080..8846c621529 100644
--- a/intern/cycles/blender/addon/ui.py
+++ b/intern/cycles/blender/addon/ui.py
@@ -1228,6 +1228,26 @@ class 
CYCLES_OBJECT_PT_shading_shadow_terminator(CyclesButtonsPanel, Panel):
         flow.prop(cob, "shadow_terminator_offset", text="Shading Offset")
 
 
+class CYCLES_OBJECT_PT_gi_approximation(CyclesButtonsPanel, Panel):
+    bl_label = "Fast GI Approximation"
+    bl_context = "object"
+    bl_options = {'DEFAULT_CLOSED'}
+
+    def draw(self, context):
+        layout = self.layout
+        layout.use_property_split = True
+
+        scene = context.scene
+        ob = context.object
+
+        cob = ob.cycles
+        cscene = scene.cycles
+
+        col = layout.column()
+        col.active = cscene.use_fast_gi
+        col.prop(cob, "ao_distance")
+
+
 class CYCLES_OBJECT_PT_visibility(CyclesButtonsPanel, Panel):
     bl_label = "Visibility"
     bl_context = "object"
@@ -2305,6 +2325,7 @@ classes = (
     CYCLES_OBJECT_PT_motion_blur,
     CYCLES_OBJECT_PT_shading,
     CYCLES_OBJECT_PT_shading_shadow_terminator,
+    CYCLES_OBJECT_PT_gi_approximation,
     CYCLES_OBJECT_PT_visibility,
     CYCLES_OBJECT_PT_visibility_ray_visibility,
     CYCLES_OBJECT_PT_visibility_culling,
diff --git a/intern/cycles/blender/blender_object.cpp 
b/intern/cycles/blender/blender_object.cpp
index f5e8db2aee1..65b5ac2c58f 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -297,6 +297,13 @@ Object *BlenderSync::sync_object(BL::Depsgraph 
&b_depsgraph,
                                                       
"shadow_terminator_geometry_offset");
   
object->set_shadow_terminator_geometry_offset(shadow_terminator_geometry_offset);
 
+  float ao_distance = get_float(cobject, "ao_distance");
+  if (ao_distance == 0.0f && b_parent.ptr.data != b_ob.ptr.data) {
+    PointerRNA cparent = RNA_pointer_get(&b_parent.ptr, "cycles");
+    ao_distance = get_float(cparent, "ao_distance");
+  }
+  object->set_ao_distance(ao_distance);
+
   /* sync the asset name for Cryptomatte */
   BL::Object parent = b_ob.parent();
   ustring parent_name;
diff --git a/intern/cycles/kernel/bvh/bvh_util.h 
b/intern/cycles/kernel/bvh/bvh_util.h
index 867ea3af8d1..b1faebce957 100644
--- a/intern/cycles/kernel/bvh/bvh_util.h
+++ b/intern/cycles/kernel/bvh/bvh_util.h
@@ -239,4 +239,14 @@ ccl_device_forceinline int 
intersection_get_shader(KernelGlobals *ccl_restrict k
   return shader & SHADER_MASK;
 }
 
+ccl_device_forceinline int intersection_get_object(KernelGlobals *ccl_restrict 
kg,
+                                                   const Intersection 
*ccl_restrict isect)
+{
+  if (isect->object != OBJECT_NONE) {
+    return isect->object;
+  }
+
+  return kernel_tex_fetch(__prim_object, isect->prim);
+}
+
 CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_bake.h 
b/intern/cycles/kernel/kernel_bake.h
index d1f33a4d0f0..7da890b908d 100644
--- a/intern/cycles/kernel/kernel_bake.h
+++ b/intern/cycles/kernel/kernel_bake.h
@@ -81,7 +81,8 @@ ccl_device_noinline void compute_light_pass(
               kg, sd, emission_sd, L, &state, &ray, &throughput, 
&ss_indirect)) {
         while (ss_indirect.num_rays) {
           kernel_path_subsurface_setup_indirect(kg, &ss_indirect, &state, 
&ray, L, &throughput);
-          kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, 
throughput, &state, L);
+          kernel_path_indirect(
+              kg, &indirect_sd, emission_sd, &ray, throughput, &state, L, 
sd->object);
         }
         is_sss_sample = true;
       }
@@ -97,7 +98,8 @@ ccl_device_noinline void compute_light_pass(
         state.ray_t = 0.0f;
 #  endif
         /* compute indirect light */
-        kernel_path_indirect(kg, &indirect_sd, emission_sd, &ray, throughput, 
&state, L);
+        kernel_path_indirect(
+            kg, &indirect_sd, emission_sd, &ray, throughput, &state, L, 
sd->object);
 
         /* sum and reset indirect light pass variables for the next samples */
         path_radiance_sum_indirect(L);
diff --git a/intern/cycles/kernel/kernel_path.h 
b/intern/cycles/kernel/kernel_path.h
index 3430543bc8e..ec577fa20b0 100644
--- a/intern/cycles/kernel/kernel_path.h
+++ b/intern/cycles/kernel/kernel_path.h
@@ -58,7 +58,8 @@ ccl_device_forceinline bool 
kernel_path_scene_intersect(KernelGlobals *kg,
                                                         ccl_addr_space 
PathState *state,
                                                         Ray *ray,
                                                         Intersection *isect,
-                                                        PathRadiance *L)
+                                                        PathRadiance *L,
+                                                        const int last_object)
 {
   PROFILING_INIT(kg, PROFILING_SCENE_INTERSECT);
 
@@ -66,6 +67,12 @@ ccl_device_forceinline bool 
kernel_path_scene_intersect(KernelGlobals *kg,
 
   if (path_state_ao_bounce(kg, state)) {
     ray->t = kernel_data.background.ao_distance;
+    if (last_object != OBJECT_NONE) {
+      const float object_ao_distance = kernel_tex_fetch(__objects, 
last_object).ao_distance;
+      if (object_ao_distance != 0.0f) {
+        ray->t = object_ao_distance;
+      }
+    }
   }
 
   bool hit = scene_intersect(kg, ray, visibility, isect);
@@ -369,7 +376,8 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
                                      Ray *ray,
                                      float3 throughput,
                                      PathState *state,
-                                     PathRadiance *L)
+                                     PathRadiance *L,
+                                     const int last_object)
 {
 #    ifdef __SUBSURFACE__
   SubsurfaceIndirectRays ss_indirect;
@@ -382,7 +390,7 @@ ccl_device void kernel_path_indirect(KernelGlobals *kg,
     for (;;) {
       /* Find intersection with objects in scene. */
       Intersection isect;
-      bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
+      bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L, 
last_object);
 
       /* Find intersection with lamps and compute emission for MIS. */
       kernel_path_lamp_emission(kg, state, ray, throughput, &isect, sd, L);
@@ -526,7 +534,7 @@ ccl_device_forceinline void 
kernel_path_integrate(KernelGlobals *kg,
     for (;;) {
       /* Find intersection with objects in scene. */
       Intersection isect;
-      bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L);
+      bool hit = kernel_path_scene_intersect(kg, state, ray, &isect, L, 
sd.object);
 
       /* Find intersection with lamps and compute emission for MIS. */
       kernel_path_lamp_emission(kg, state, ray, throughput, &isect, &sd, L);
diff --git a/intern/cycles/kernel/kernel_path_branched.h 
b/intern/cycles/kernel/kernel_path_branched.h
index 5ea7687ec3b..a1ee1bc107e 100644
--- a/intern/cycles/kernel/kernel_path_branched.h
+++ b/intern/cycles/kernel/kernel_path_branched.h
@@ -92,6 +92,7 @@ ccl_device_forceinline void 
kernel_branched_path_volume(KernelGlobals *kg,
   volume_ray.t = (hit) ? isect->t : FLT_MAX;
 
   float step_size = volume_stack_step_size(kg, state->volume_stack);
+  const int object = sd->object;
 
 #      ifdef __VOLUME_DECOUPLED__
   /* decoupled ray marching only supported on CPU */
@@ -134,7 +135,8 @@ ccl_device_forceinline void 
kernel_branched_path_volume(KernelGlobals *kg,
 
         if (result == VOLUME_PATH_SCATTERED &&
             kernel_path_volume_bounce(kg, sd, &tp, &ps, &L->state, &pray)) {
-          kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp * 
num_samples_inv, &ps, L);
+          kernel_path_indirect(
+              kg, indirect_sd, emission_sd, &pray, tp * num_samples_inv, &ps, 
L, object);
 
           /* for render passes, sum and reset indirect light pass variables
            * for the next samples */
@@ -180,7 +182,7 @@ ccl_device_forceinline void 
kernel_branched_path_volume(KernelGlobals *kg,
         kernel_path_volume_connect_light(kg, sd, emission_sd, tp, state, L);
 
         if (kernel_path_volume_bounce(kg, sd, &tp, &ps, &L->state, &pray)) {
-          kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp, &ps, 
L);
+          kernel_path_indirect(kg, indirect_sd, emission_sd, &pray, tp, &ps, 
L, object);
 
           /* for render passes, sum and reset indirect light pass variables
            * for the next samples */
@@ -266,7 +268,8 @@ ccl_device_noinline_cpu void 
kernel_branched_path_surface_indirect_light(KernelG
 
       ps.rng_hash = state->rng_hash;
 
-      kernel_path_indirect(kg, indirect_sd, emission_sd, &bsdf_ray, tp * 
num_samples_inv, &ps, L);
+      kernel_path_indirect(
+          kg, indirect_sd, emission_sd, &bsdf_ray, tp * num_samples_inv, &ps, 
L, sd->object);
 
       /* for render passes, sum and reset indirect light pass variables
        * for the next samples */
@@ -395,7 +398,7 @@ ccl_device void 
kernel_branched_path_integrate(KernelGlobals *kg,
   for (;;) {
     /* Find intersection with objects in scene. */
     Intersection isect;
-    bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L);
+    bool hit = kernel_path_scene_intersect(kg, &state, &ray, &isect, L, 
sd.object);
 
 #    ifdef __VOLUME__
     /* Volume integration. */
diff --git a/intern/cycles/kernel/kernel_types.h b/

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
List details, subscription details or unsubscribe:
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to