diff options
author | Carlo Andreacchio <carlorules@gmail.com> | 2016-11-13 02:16:50 +0300 |
---|---|---|
committer | Brecht Van Lommel <brechtvanlommel@gmail.com> | 2016-11-20 17:01:11 +0300 |
commit | e8641d44740ed0e2c4a2a7bc4fb61aacec203c48 (patch) | |
tree | 5f792da929de0aead7eb1abd01701a785cfa9994 /intern | |
parent | 2c26a7b71e05bdbb4509f55ceba79f167b323ed7 (diff) |
Cycles: distance culling for objects.
This can be used together with camera culling to keep nearby objects visible in
reflections, using a minimum distance within which objects are visible. It is
also useful to cull small objects far from the camera.
Reviewed By: brecht
Differential Revision: https://developer.blender.org/D2332
Diffstat (limited to 'intern')
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 19 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 15 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 55 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 2 |
4 files changed, 84 insertions, 7 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index a7dff1f79f3..575a3f9b6c5 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -566,6 +566,19 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): min=0.0, max=5.0 ) + cls.use_distance_cull = BoolProperty( + name="Use Distance Cull", + description="Allow objects to be culled based on the distance from camera", + default=False, + ) + + cls.distance_cull_margin = FloatProperty( + name="Cull Distance", + description="Cull objects which are further away from camera then this distance", + default=50, + min=0.0 + ) + cls.motion_blur_position = EnumProperty( name="Motion Blur Position", default='CENTER', @@ -1016,6 +1029,12 @@ class CyclesObjectSettings(bpy.types.PropertyGroup): default=False, ) + cls.use_distance_cull = BoolProperty( + name="Use Distance Cull", + description="Allow this object and its duplicators to be culled by distance from camera", + default=False, + ) + cls.use_adaptive_subdivision = BoolProperty( name="Use Adaptive Subdivision", description="Use adaptive render time subdivision", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index f435af178b5..6296d6787e5 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -769,6 +769,8 @@ class CyclesObject_PT_cycles_settings(CyclesButtonsPanel, Panel): row = col.row() row.active = scene.render.use_simplify and cscene.use_camera_cull row.prop(cob, "use_camera_cull") + row.active = scene.render.use_simplify and cscene.use_distance_cull + row.prop(cob, "use_distance_cull") class CYCLES_OT_use_shading_nodes(Operator): @@ -1597,12 +1599,17 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel): col.prop(rd, "simplify_subdivision_render", text="Subdivision") col.prop(rd, "simplify_child_particles_render", text="Child Particles") - col = layout.column() + layout.separator() + + split = layout.split() + + col = split.column() col.prop(cscene, "use_camera_cull") - subsub = col.column() - subsub.active = cscene.use_camera_cull - subsub.prop(cscene, "camera_cull_margin") + col.prop(cscene, "camera_cull_margin", text="Margin") + col = split.column() + col.prop(cscene, "use_distance_cull") + col.prop(cscene, "distance_cull_margin", text="Distance") def draw_device(self, context): scene = context.scene diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp index 0d961c5bf88..84701a22d0a 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -284,6 +284,31 @@ static bool object_boundbox_clip(Scene *scene, return true; } +static bool object_distance_clip(Scene *scene, + BL::Object& b_ob, + Transform& tfm, + float margin) +{ + BL::Array<float, 24> boundbox = b_ob.bound_box(); + float3 camera_position = transform_get_column(&scene->camera->matrix, 3); + + float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), + bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); + + /* Find min & max points for x & y & z on bounding box */ + for(int i = 0; i < 8; ++i) { + float3 p = make_float3(boundbox[3 * i + 0], + boundbox[3 * i + 1], + boundbox[3 * i + 2]); + p = transform_point(&tfm, p); + bb_min = min(bb_min, p); + bb_max = max(bb_max, p); + } + + float3 closest_point = max(min(bb_max,camera_position),bb_min); + return (len_squared(camera_position - closest_point) > margin * margin); +} + Object *BlenderSync::sync_object(BL::Object& b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject& b_dupli_ob, @@ -292,7 +317,9 @@ Object *BlenderSync::sync_object(BL::Object& b_parent, float motion_time, bool hide_tris, bool use_camera_cull, + bool use_distance_cull, float camera_cull_margin, + float distance_cull_margin, bool *use_portal) { BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent); @@ -311,8 +338,14 @@ Object *BlenderSync::sync_object(BL::Object& b_parent, if(!object_is_mesh(b_ob)) return NULL; - /* Perform camera space culling. */ - if(use_camera_cull && object_boundbox_clip(scene, b_ob, tfm, camera_cull_margin)) { + /* Perform object culling. */ + bool camera_culled = use_camera_cull && object_boundbox_clip(scene, b_ob, tfm, camera_cull_margin); + bool distance_culled = use_distance_cull && object_distance_clip(scene, b_ob, tfm, distance_cull_margin); + + if ((camera_culled && distance_culled) || + (camera_culled && !use_distance_cull) || + (distance_culled && !use_camera_cull)) + { return NULL; } @@ -549,15 +582,26 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) } bool allow_camera_cull = false; + bool allow_distance_cull = false; float camera_cull_margin = 0.0f; + float distance_cull_margin = 0.0f; if(b_scene.render().use_simplify()) { PointerRNA cscene = RNA_pointer_get(&b_scene.ptr, "cycles"); allow_camera_cull = scene->camera->type != CAMERA_PANORAMA && !b_scene.render().use_multiview() && get_boolean(cscene, "use_camera_cull"); + allow_distance_cull = scene->camera->type != CAMERA_PANORAMA && + !b_scene.render().use_multiview() && + get_boolean(cscene, "use_distance_cull"); if(allow_camera_cull) { camera_cull_margin = get_float(cscene, "camera_cull_margin"); } + if(allow_distance_cull) { + distance_cull_margin = get_float(cscene, "distance_cull_margin"); + if (distance_cull_margin == 0.0f) { + allow_distance_cull = false; + } + } } /* object loop */ @@ -592,7 +636,8 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) PointerRNA cobject = RNA_pointer_get(&b_ob.ptr, "cycles"); bool use_camera_cull = allow_camera_cull && get_boolean(cobject, "use_camera_cull"); - if(use_camera_cull) { + bool use_distance_cull = allow_distance_cull && get_boolean(cobject, "use_distance_cull"); + if(use_camera_cull || use_distance_cull) { /* Need to have proper projection matrix. */ scene->camera->update(); } @@ -623,7 +668,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) motion_time, hide_tris, use_camera_cull, + use_distance_cull, camera_cull_margin, + distance_cull_margin, &use_portal); /* sync possible particle data, note particle_id @@ -653,7 +700,9 @@ void BlenderSync::sync_objects(BL::SpaceView3D& b_v3d, float motion_time) motion_time, hide_tris, use_camera_cull, + use_distance_cull, camera_cull_margin, + distance_cull_margin, &use_portal); } } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 9a01b4f2b6e..aa6b0d66e80 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -123,7 +123,9 @@ private: float motion_time, bool hide_tris, bool use_camera_cull, + bool use_distance_cull, float camera_cull_margin, + float distance_cull_margin, bool *use_portal); void sync_light(BL::Object& b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], |