diff options
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 8 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 21 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 7 | ||||
-rw-r--r-- | intern/cycles/kernel/bvh/bvh_util.h | 10 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_bake.h | 6 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path.h | 16 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_path_branched.h | 11 | ||||
-rw-r--r-- | intern/cycles/kernel/kernel_types.h | 5 | ||||
-rw-r--r-- | intern/cycles/kernel/split/kernel_scene_intersect.h | 5 | ||||
-rw-r--r-- | intern/cycles/render/object.cpp | 3 | ||||
-rw-r--r-- | intern/cycles/render/object.h | 2 |
11 files changed, 82 insertions, 12 deletions
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/intern/cycles/kernel/kernel_types.h index f9ea3a2d0a8..7cbe18acf28 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -1447,7 +1447,10 @@ typedef struct KernelObject { float shadow_terminator_shading_offset; float shadow_terminator_geometry_offset; - float pad1, pad2, pad3; + + float ao_distance; + + float pad1, pad2; } KernelObject; static_assert_align(KernelObject, 16); diff --git a/intern/cycles/kernel/split/kernel_scene_intersect.h b/intern/cycles/kernel/split/kernel_scene_intersect.h index 5fef3e045f8..9ac95aafd2f 100644 --- a/intern/cycles/kernel/split/kernel_scene_intersect.h +++ b/intern/cycles/kernel/split/kernel_scene_intersect.h @@ -65,7 +65,10 @@ ccl_device void kernel_scene_intersect(KernelGlobals *kg) PathRadiance *L = &kernel_split_state.path_radiance[ray_index]; Intersection isect; - bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L); + const int last_object = state->bounce > 0 ? + intersection_get_object(kg, &kernel_split_state.isect[ray_index]) : + OBJECT_NONE; + bool hit = kernel_path_scene_intersect(kg, state, &ray, &isect, L, last_object); kernel_split_state.isect[ray_index] = isect; if (!hit) { diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 5fe4e9ed57f..c88d94fe4c2 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -102,6 +102,8 @@ NODE_DEFINE(Object) SOCKET_NODE(particle_system, "Particle System", ParticleSystem::get_node_type()); SOCKET_INT(particle_index, "Particle Index", 0); + SOCKET_FLOAT(ao_distance, "AO Distance", 0.0f); + return type; } @@ -428,6 +430,7 @@ void ObjectManager::device_update_object_transform(UpdateObjectTransformState *s kobject.random_number = random_number; kobject.particle_index = particle_index; kobject.motion_offset = 0; + kobject.ao_distance = ob->ao_distance; if (geom->get_use_motion_blur()) { state->have_motion = true; diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h index ebb7733c2aa..c52ddce48da 100644 --- a/intern/cycles/render/object.h +++ b/intern/cycles/render/object.h @@ -73,6 +73,8 @@ class Object : public Node { NODE_SOCKET_API(ParticleSystem *, particle_system); NODE_SOCKET_API(int, particle_index); + NODE_SOCKET_API(float, ao_distance) + Object(); ~Object(); |