[Bf-blender-cvs] [c18d91918fb] master: Cycles: More flexible GI Approximation AO distance control

Sergey Sharybin noreply at git.blender.org
Wed Aug 4 17:27:02 CEST 2021


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. @@



More information about the Bf-blender-cvs mailing list