diff options
-rw-r--r-- | intern/cycles/blender/addon/properties.py | 19 | ||||
-rw-r--r-- | intern/cycles/blender/addon/ui.py | 24 | ||||
-rw-r--r-- | intern/cycles/blender/blender_object.cpp | 97 | ||||
-rw-r--r-- | intern/cycles/blender/blender_sync.h | 12 |
4 files changed, 143 insertions, 9 deletions
diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index 87c0f7c154a..4ba335f3b4b 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -511,6 +511,19 @@ class CyclesRenderSettings(bpy.types.PropertyGroup): ), ) + cls.use_camera_cull = BoolProperty( + name="Use Camera Cull", + description="Allow objects to be culled based on the camera frustum", + default=False, + ) + + cls.camera_cull_margin = FloatProperty( + name="Camera Cull Margin", + description="Margin for the camera space culling", + default=0.1, + min=0.0, max=5.0 + ) + @classmethod def unregister(cls): del bpy.types.Scene.cycles @@ -896,6 +909,12 @@ class CyclesObjectBlurSettings(bpy.types.PropertyGroup): default=1, ) + cls.use_camera_cull = BoolProperty( + name="Use Camera Cull", + description="Allow this object and it's duplicators to be culled by camera space culling", + default=False, + ) + @classmethod def unregister(cls): del bpy.types.Object.cycles diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index f7179e2472b..8bb086df06a 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -687,8 +687,8 @@ class CyclesObject_PT_motion_blur(CyclesButtonsPanel, Panel): sub.prop(cob, "motion_steps", text="Steps") -class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel): - bl_label = "Ray Visibility" +class CyclesObject_PT_cycles_settings(CyclesButtonsPanel, Panel): + bl_label = "Cycles Settings" bl_context = "object" bl_options = {'DEFAULT_CLOSED'} @@ -702,9 +702,13 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout + scene = context.scene + cscene = scene.cycles ob = context.object + cob = ob.cycles visibility = ob.cycles_visibility + layout.label(text="Ray Visibility:") flow = layout.column_flow() flow.prop(visibility, "camera") @@ -716,6 +720,12 @@ class CyclesObject_PT_ray_visibility(CyclesButtonsPanel, Panel): if ob.type != 'LAMP': flow.prop(visibility, "shadow") + col = layout.column() + col.label(text="Performance:") + row = col.row() + row.active = scene.render.use_simplify and cscene.use_camera_cull + row.prop(cob, "use_camera_cull") + class CYCLES_OT_use_shading_nodes(Operator): """Enable nodes on a material, world or lamp""" @@ -1450,7 +1460,9 @@ class CyclesScene_PT_simplify(CyclesButtonsPanel, Panel): def draw(self, context): layout = self.layout - rd = context.scene.render + scene = context.scene + rd = scene.render + cscene = scene.cycles layout.active = rd.use_simplify split = layout.split() @@ -1465,6 +1477,12 @@ 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() + col.prop(cscene, "use_camera_cull") + subsub = col.column() + subsub.active = cscene.use_camera_cull + subsub.prop(cscene, "camera_cull_margin") + 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 9fa1b35d2ad..35ba450be41 100644 --- a/intern/cycles/blender/blender_object.cpp +++ b/intern/cycles/blender/blender_object.cpp @@ -235,8 +235,56 @@ void BlenderSync::sync_background_light(bool use_portal) /* Object */ -Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, - Transform& tfm, uint layer_flag, float motion_time, bool hide_tris, bool *use_portal) +/* TODO(sergey): Not really optimal, consider approaches based on k-DOP in order + * to reduce number of objects which are wrongly considered visible. + */ +static bool object_boundbox_clip(Scene *scene, + BL::Object b_ob, + Transform& tfm, + float margin) +{ + Camera *cam = scene->camera; + Transform& worldtondc = cam->worldtondc; + BL::Array<float, 24> boundbox = b_ob.bound_box(); + float3 bb_min = make_float3(FLT_MAX, FLT_MAX, FLT_MAX), + bb_max = make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX); + bool all_behind = true; + 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); + p = transform_point(&worldtondc, p); + if(p.z >= -margin) { + all_behind = false; + } + p /= p.z; + bb_min = min(bb_min, p); + bb_max = max(bb_max, p); + } + if(!all_behind) { + if(bb_min.x >= 1.0f + margin || + bb_min.y >= 1.0f + margin || + bb_max.x <= -margin || + bb_max.y <= -margin) + { + return true; + } + return false; + } + return true; +} + +Object *BlenderSync::sync_object(BL::Object b_parent, + int persistent_id[OBJECT_PERSISTENT_ID_SIZE], + BL::DupliObject b_dupli_ob, + Transform& tfm, + uint layer_flag, + float motion_time, + bool hide_tris, + bool use_camera_cull, + float camera_cull_margin, + bool *use_portal) { BL::Object b_ob = (b_dupli_ob ? b_dupli_ob.object() : b_parent); bool motion = motion_time != 0.0f; @@ -254,6 +302,11 @@ Object *BlenderSync::sync_object(BL::Object b_parent, int persistent_id[OBJECT_P 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)) { + return NULL; + } + /* key to lookup object */ ObjectKey key(b_parent, persistent_id, b_ob); Object *object; @@ -481,6 +534,18 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time) mesh_motion_synced.clear(); } + bool allow_camera_cull = false; + float camera_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"); + if(allow_camera_cull) { + camera_cull_margin = get_float(cscene, "camera_cull_margin"); + } + } + /* object loop */ BL::Scene::object_bases_iterator b_base; BL::Scene b_sce = b_scene; @@ -503,6 +568,12 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time) if(!hide) { progress.set_sync_status("Synchronizing object", b_ob.name()); + 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) { + /* Need to have proper projection matrix. */ + scene->camera->update(); + } if(b_ob.is_duplicator() && !object_render_hide_duplis(b_ob)) { /* dupli objects */ b_ob.dupli_list_create(b_scene, dupli_settings); @@ -522,7 +593,16 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time) BL::Array<int, OBJECT_PERSISTENT_ID_SIZE> persistent_id = b_dup->persistent_id(); /* sync object and mesh or light data */ - Object *object = sync_object(b_ob, persistent_id.data, *b_dup, tfm, ob_layer, motion_time, hide_tris, &use_portal); + Object *object = sync_object(b_ob, + persistent_id.data, + *b_dup, + tfm, + ob_layer, + motion_time, + hide_tris, + use_camera_cull, + camera_cull_margin, + &use_portal); /* sync possible particle data, note particle_id * starts counting at 1, first is dummy particle */ @@ -542,7 +622,16 @@ void BlenderSync::sync_objects(BL::SpaceView3D b_v3d, float motion_time) if(!object_render_hide(b_ob, true, true, hide_tris)) { /* object itself */ Transform tfm = get_transform(b_ob.matrix_world()); - sync_object(b_ob, NULL, PointerRNA_NULL, tfm, ob_layer, motion_time, hide_tris, &use_portal); + sync_object(b_ob, + NULL, + PointerRNA_NULL, + tfm, + ob_layer, + motion_time, + hide_tris, + use_camera_cull, + camera_cull_margin, + &use_portal); } } diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 89d93e19e9f..b8bd14c0f71 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -85,8 +85,16 @@ private: void sync_nodes(Shader *shader, BL::ShaderNodeTree b_ntree); Mesh *sync_mesh(BL::Object b_ob, bool object_updated, bool hide_tris); void sync_curves(Mesh *mesh, BL::Mesh b_mesh, BL::Object b_ob, bool motion, int time_index = 0); - Object *sync_object(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::DupliObject b_dupli_ob, - Transform& tfm, uint layer_flag, float motion_time, bool hide_tris, bool *use_portal); + Object *sync_object(BL::Object b_parent, + int persistent_id[OBJECT_PERSISTENT_ID_SIZE], + BL::DupliObject b_dupli_ob, + Transform& tfm, + uint layer_flag, + float motion_time, + bool hide_tris, + bool use_camera_cull, + float camera_cull_margin, + bool *use_portal); void sync_light(BL::Object b_parent, int persistent_id[OBJECT_PERSISTENT_ID_SIZE], BL::Object b_ob, Transform& tfm, bool *use_portal); void sync_background_light(bool use_portal); void sync_mesh_motion(BL::Object b_ob, Object *object, float motion_time); |