From 2c41c8e94fa8740f67dc39150dd1ab66b506adc9 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Wed, 10 Jun 2020 19:07:07 +0200 Subject: Cycles: internal refactoring to make thick/ribbon curve separate primitives Also removing the curve system manager which only stored a few curve intersection settings. These are all changes towards making shape and subdivision settings per-object instead of per-scene, but there is more work to do here. Ref T73778 Depends on D8013 Maniphest Tasks: T73778 Differential Revision: https://developer.blender.org/D8014 --- intern/cycles/blender/addon/properties.py | 5 -- intern/cycles/blender/addon/ui.py | 9 --- intern/cycles/blender/blender_curves.cpp | 38 +----------- intern/cycles/blender/blender_sync.cpp | 6 +- intern/cycles/blender/blender_sync.h | 1 - intern/cycles/bvh/bvh_build.cpp | 37 +++++++---- intern/cycles/bvh/bvh_embree.cpp | 19 +++--- intern/cycles/bvh/bvh_embree.h | 2 +- intern/cycles/bvh/bvh_optix.cpp | 9 ++- intern/cycles/bvh/bvh_params.h | 2 - intern/cycles/bvh/bvh_unaligned.cpp | 6 +- intern/cycles/kernel/bvh/bvh_shadow_all.h | 6 +- intern/cycles/kernel/bvh/bvh_traversal.h | 8 ++- .../cycles/kernel/closure/bsdf_hair_principled.h | 4 +- intern/cycles/kernel/geom/geom_curve.h | 2 +- intern/cycles/kernel/geom/geom_curve_intersect.h | 15 +++-- intern/cycles/kernel/kernel_types.h | 39 ++++++------ intern/cycles/render/curves.cpp | 72 ---------------------- intern/cycles/render/curves.h | 33 +--------- intern/cycles/render/geometry.cpp | 13 ++-- intern/cycles/render/hair.cpp | 1 + intern/cycles/render/hair.h | 1 + intern/cycles/render/object.cpp | 2 - intern/cycles/render/scene.cpp | 13 +--- intern/cycles/render/scene.h | 12 +++- intern/cycles/render/session.cpp | 3 +- 26 files changed, 119 insertions(+), 239 deletions(-) (limited to 'intern') diff --git a/intern/cycles/blender/addon/properties.py b/intern/cycles/blender/addon/properties.py index ceaeda6e798..269ad8ecc5b 100644 --- a/intern/cycles/blender/addon/properties.py +++ b/intern/cycles/blender/addon/properties.py @@ -1225,11 +1225,6 @@ class CyclesCurveRenderSettings(bpy.types.PropertyGroup): items=enum_curve_shape, default='RIBBONS', ) - use_curves: BoolProperty( - name="Use Cycles Hair Rendering", - description="Activate Cycles hair rendering for particle system", - default=True, - ) subdivisions: IntProperty( name="Subdivisions", description="Number of subdivisions used in Cardinal curve intersection (power of 2)", diff --git a/intern/cycles/blender/addon/ui.py b/intern/cycles/blender/addon/ui.py index daab26d8ec0..592c59cc661 100644 --- a/intern/cycles/blender/addon/ui.py +++ b/intern/cycles/blender/addon/ui.py @@ -387,13 +387,6 @@ class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): bl_label = "Hair" bl_options = {'DEFAULT_CLOSED'} - def draw_header(self, context): - layout = self.layout - scene = context.scene - ccscene = scene.cycles_curves - - layout.prop(ccscene, "use_curves", text="") - def draw(self, context): layout = self.layout layout.use_property_split = True @@ -402,8 +395,6 @@ class CYCLES_RENDER_PT_hair(CyclesButtonsPanel, Panel): scene = context.scene ccscene = scene.cycles_curves - layout.active = ccscene.use_curves - col = layout.column() col.prop(ccscene, "shape", text="Shape") if ccscene.shape == 'RIBBONS': diff --git a/intern/cycles/blender/blender_curves.cpp b/intern/cycles/blender/blender_curves.cpp index a2a0392d4d5..e1f84925987 100644 --- a/intern/cycles/blender/blender_curves.cpp +++ b/intern/cycles/blender/blender_curves.cpp @@ -507,42 +507,6 @@ static void ExportCurveSegmentsMotion(Hair *hair, ParticleCurveData *CData, int /* Hair Curve Sync */ -void BlenderSync::sync_curve_settings(BL::Depsgraph &b_depsgraph) -{ - PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves"); - - CurveSystemManager *curve_system_manager = scene->curve_system_manager; - CurveSystemManager prev_curve_system_manager = *curve_system_manager; - - curve_system_manager->use_curves = get_boolean(csscene, "use_curves"); - - curve_system_manager->curve_shape = (CurveShapeType)get_enum( - csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK); - curve_system_manager->subdivisions = get_int(csscene, "subdivisions"); - - if (curve_system_manager->modified_mesh(prev_curve_system_manager)) { - BL::Depsgraph::objects_iterator b_ob; - - for (b_depsgraph.objects.begin(b_ob); b_ob != b_data.objects.end(); ++b_ob) { - if (object_is_mesh(*b_ob)) { - BL::Object::particle_systems_iterator b_psys; - for (b_ob->particle_systems.begin(b_psys); b_psys != b_ob->particle_systems.end(); - ++b_psys) { - if ((b_psys->settings().render_type() == BL::ParticleSettings::render_type_PATH) && - (b_psys->settings().type() == BL::ParticleSettings::type_HAIR)) { - BL::ID key = BKE_object_is_modified(*b_ob) ? *b_ob : b_ob->data(); - geometry_map.set_recalc(key); - object_map.set_recalc(*b_ob); - } - } - } - } - } - - if (curve_system_manager->modified(prev_curve_system_manager)) - curve_system_manager->tag_update(scene); -} - bool BlenderSync::object_has_particle_hair(BL::Object b_ob) { /* Test if the object has a particle modifier with hair. */ @@ -867,7 +831,7 @@ void BlenderSync::sync_hair(BL::Depsgraph b_depsgraph, hair->clear(); hair->used_shaders = used_shaders; - if (view_layer.use_hair && scene->curve_system_manager->use_curves) { + if (view_layer.use_hair) { #ifdef WITH_NEW_OBJECT_TYPES if (b_ob.type() == BL::Object::type_HAIR) { /* Hair object. */ diff --git a/intern/cycles/blender/blender_sync.cpp b/intern/cycles/blender/blender_sync.cpp index f5fd6f31c75..7a6047ca6a6 100644 --- a/intern/cycles/blender/blender_sync.cpp +++ b/intern/cycles/blender/blender_sync.cpp @@ -212,7 +212,6 @@ void BlenderSync::sync_data(BL::RenderSettings &b_render, sync_film(b_v3d); sync_shaders(b_depsgraph, b_v3d); sync_images(); - sync_curve_settings(b_depsgraph); geometry_synced.clear(); /* use for objects and motion sync */ @@ -732,6 +731,11 @@ SceneParams BlenderSync::get_scene_params(BL::Scene &b_scene, bool background) params.use_bvh_unaligned_nodes = RNA_boolean_get(&cscene, "debug_use_hair_bvh"); params.num_bvh_time_steps = RNA_int_get(&cscene, "debug_bvh_time_steps"); + PointerRNA csscene = RNA_pointer_get(&b_scene.ptr, "cycles_curves"); + params.hair_subdivisions = get_int(csscene, "subdivisions"); + params.hair_shape = (CurveShapeType)get_enum( + csscene, "shape", CURVE_NUM_SHAPE_TYPES, CURVE_THICK); + if (background && params.shadingsystem != SHADINGSYSTEM_OSL) params.persistent_data = r.use_persistent_data(); else diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h index 3c39cfd9446..25032e8d0fa 100644 --- a/intern/cycles/blender/blender_sync.h +++ b/intern/cycles/blender/blender_sync.h @@ -159,7 +159,6 @@ class BlenderSync { void sync_hair(Hair *hair, BL::Object &b_ob, bool motion, int motion_step = 0); void sync_particle_hair( Hair *hair, BL::Mesh &b_mesh, BL::Object &b_ob, bool motion, int motion_step = 0); - void sync_curve_settings(BL::Depsgraph &b_depsgraph); bool object_has_particle_hair(BL::Object b_ob); /* Camera */ diff --git a/intern/cycles/bvh/bvh_build.cpp b/intern/cycles/bvh/bvh_build.cpp index 0235ac33c77..86ab7b00815 100644 --- a/intern/cycles/bvh/bvh_build.cpp +++ b/intern/cycles/bvh/bvh_build.cpp @@ -159,6 +159,13 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair if (hair->has_motion_blur()) { curve_attr_mP = hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION); } + + const PrimitiveType primitive_type = + (curve_attr_mP != NULL) ? + ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON : + PRIMITIVE_MOTION_CURVE_THICK) : + ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK); + const size_t num_curves = hair->num_curves(); for (uint j = 0; j < num_curves; j++) { const Hair::Curve curve = hair->get_curve(j); @@ -169,7 +176,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair BoundBox bounds = BoundBox::empty; curve.bounds_grow(k, &hair->curve_keys[0], curve_radius, bounds); if (bounds.valid()) { - int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_CURVE, k); + int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k); references.push_back(BVHReference(bounds, j, i, packed_type)); root.grow(bounds); center.grow(bounds.center2()); @@ -190,7 +197,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair curve.bounds_grow(k, key_steps + step * num_keys, curve_radius, bounds); } if (bounds.valid()) { - int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k); + int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k); references.push_back(BVHReference(bounds, j, i, packed_type)); root.grow(bounds); center.grow(bounds.center2()); @@ -246,7 +253,7 @@ void BVHBuild::add_reference_curves(BoundBox &root, BoundBox ¢er, Hair *hair bounds.grow(curr_bounds); if (bounds.valid()) { const float prev_time = (float)(bvh_step - 1) * num_bvh_steps_inv_1; - int packed_type = PRIMITIVE_PACK_SEGMENT(PRIMITIVE_MOTION_CURVE, k); + int packed_type = PRIMITIVE_PACK_SEGMENT(primitive_type, k); references.push_back(BVHReference(bounds, j, i, packed_type, prev_time, curr_time)); root.grow(bounds); center.grow(bounds.center2()); @@ -537,14 +544,22 @@ bool BVHBuild::range_within_max_leaf_size(const BVHRange &range, for (int i = 0; i < size; i++) { const BVHReference &ref = references[range.start() + i]; - if (ref.prim_type() & PRIMITIVE_CURVE) - num_curves++; - if (ref.prim_type() & PRIMITIVE_MOTION_CURVE) - num_motion_curves++; - else if (ref.prim_type() & PRIMITIVE_TRIANGLE) - num_triangles++; - else if (ref.prim_type() & PRIMITIVE_MOTION_TRIANGLE) - num_motion_triangles++; + if (ref.prim_type() & PRIMITIVE_ALL_CURVE) { + if (ref.prim_type() & PRIMITIVE_ALL_MOTION) { + num_motion_curves++; + } + else { + num_curves++; + } + } + else if (ref.prim_type() & PRIMITIVE_ALL_TRIANGLE) { + if (ref.prim_type() & PRIMITIVE_ALL_MOTION) { + num_motion_triangles++; + } + else { + num_triangles++; + } + } } return (num_triangles <= params.max_triangle_leaf_size) && diff --git a/intern/cycles/bvh/bvh_embree.cpp b/intern/cycles/bvh/bvh_embree.cpp index eb103b4e712..17e1f86a589 100644 --- a/intern/cycles/bvh/bvh_embree.cpp +++ b/intern/cycles/bvh/bvh_embree.cpp @@ -324,7 +324,6 @@ BVHEmbree::BVHEmbree(const BVHParams ¶ms_, stats(NULL), curve_subdivisions(params.curve_subdivisions), build_quality(RTC_BUILD_QUALITY_REFIT), - use_ribbons(params.curve_flags & CURVE_KN_RIBBONS), dynamic_scene(true) { _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); @@ -771,6 +770,12 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i) } const size_t num_motion_steps = min(num_geometry_motion_steps, RTC_MAX_TIME_STEP_COUNT); + const PrimitiveType primitive_type = + (num_motion_steps > 1) ? + ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON : + PRIMITIVE_MOTION_CURVE_THICK) : + ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : PRIMITIVE_CURVE_THICK); + assert(num_geometry_motion_steps <= RTC_MAX_TIME_STEP_COUNT); const size_t num_curves = hair->num_curves(); @@ -791,11 +796,12 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i) size_t prim_tri_index_size = pack.prim_index.size(); pack.prim_tri_index.resize(prim_tri_index_size + num_segments); - enum RTCGeometryType type = (use_ribbons ? RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE : - RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE); + enum RTCGeometryType type = (hair->curve_shape == CURVE_RIBBON ? + RTC_GEOMETRY_TYPE_FLAT_CATMULL_ROM_CURVE : + RTC_GEOMETRY_TYPE_ROUND_CATMULL_ROM_CURVE); RTCGeometry geom_id = rtcNewGeometry(rtc_shared_device, type); - rtcSetGeometryTessellationRate(geom_id, curve_subdivisions); + rtcSetGeometryTessellationRate(geom_id, curve_subdivisions + 1); unsigned *rtc_indices = (unsigned *)rtcSetNewGeometryBuffer( geom_id, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT, sizeof(int), num_segments); size_t rtc_index = 0; @@ -807,8 +813,7 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i) rtc_indices[rtc_index] += j * 2; /* Cycles specific data. */ pack.prim_object[prim_object_size + rtc_index] = i; - pack.prim_type[prim_type_size + rtc_index] = (PRIMITIVE_PACK_SEGMENT( - num_motion_steps > 1 ? PRIMITIVE_MOTION_CURVE : PRIMITIVE_CURVE, k)); + pack.prim_type[prim_type_size + rtc_index] = (PRIMITIVE_PACK_SEGMENT(primitive_type, k)); pack.prim_index[prim_index_size + rtc_index] = j; pack.prim_tri_index[prim_tri_index_size + rtc_index] = rtc_index; @@ -822,7 +827,7 @@ void BVHEmbree::add_curves(const Object *ob, const Hair *hair, int i) update_curve_vertex_buffer(geom_id, hair); rtcSetGeometryUserData(geom_id, (void *)prim_offset); - if (use_ribbons) { + if (hair->curve_shape == CURVE_RIBBON) { rtcSetGeometryOccludedFilterFunction(geom_id, rtc_filter_occluded_func); } else { diff --git a/intern/cycles/bvh/bvh_embree.h b/intern/cycles/bvh/bvh_embree.h index b10a741fd59..f60a1ca0102 100644 --- a/intern/cycles/bvh/bvh_embree.h +++ b/intern/cycles/bvh/bvh_embree.h @@ -81,7 +81,7 @@ class BVHEmbree : public BVH { vector delayed_delete_scenes; int curve_subdivisions; enum RTCBuildQuality build_quality; - bool use_ribbons, dynamic_scene; + bool dynamic_scene; }; CCL_NAMESPACE_END diff --git a/intern/cycles/bvh/bvh_optix.cpp b/intern/cycles/bvh/bvh_optix.cpp index 04cff674938..ccb7ae08625 100644 --- a/intern/cycles/bvh/bvh_optix.cpp +++ b/intern/cycles/bvh/bvh_optix.cpp @@ -77,9 +77,12 @@ void BVHOptiX::pack_blas() // 'pack.prim_time' is only used in geom_curve_intersect.h // It is not needed because of OPTIX_MOTION_FLAG_[START|END]_VANISH - uint type = PRIMITIVE_CURVE; - if (hair->use_motion_blur && hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) - type = PRIMITIVE_MOTION_CURVE; + uint type = (hair->use_motion_blur && + hair->attributes.find(ATTR_STD_MOTION_VERTEX_POSITION)) ? + ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_MOTION_CURVE_RIBBON : + PRIMITIVE_MOTION_CURVE_THICK) : + ((hair->curve_shape == CURVE_RIBBON) ? PRIMITIVE_CURVE_RIBBON : + PRIMITIVE_CURVE_THICK); for (size_t j = 0; j < num_curves; ++j) { const Hair::Curve curve = hair->get_curve(j); diff --git a/intern/cycles/bvh/bvh_params.h b/intern/cycles/bvh/bvh_params.h index 5e2c4b63f1b..1a50742dc33 100644 --- a/intern/cycles/bvh/bvh_params.h +++ b/intern/cycles/bvh/bvh_params.h @@ -89,7 +89,6 @@ class BVHParams { int bvh_type; /* These are needed for Embree. */ - int curve_flags; int curve_subdivisions; /* fixed parameters */ @@ -122,7 +121,6 @@ class BVHParams { bvh_type = 0; - curve_flags = 0; curve_subdivisions = 4; } diff --git a/intern/cycles/bvh/bvh_unaligned.cpp b/intern/cycles/bvh/bvh_unaligned.cpp index f0995f343fe..c969b361643 100644 --- a/intern/cycles/bvh/bvh_unaligned.cpp +++ b/intern/cycles/bvh/bvh_unaligned.cpp @@ -68,7 +68,8 @@ bool BVHUnaligned::compute_aligned_space(const BVHReference &ref, Transform *ali const Object *object = objects_[ref.prim_object()]; const int packed_type = ref.prim_type(); const int type = (packed_type & PRIMITIVE_ALL); - if (type & PRIMITIVE_CURVE) { + /* No motion blur curves here, we can't fit them to aligned boxes well. */ + if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) { const int curve_index = ref.prim_index(); const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type); const Hair *hair = static_cast(object->geometry); @@ -93,7 +94,8 @@ BoundBox BVHUnaligned::compute_aligned_prim_boundbox(const BVHReference &prim, const Object *object = objects_[prim.prim_object()]; const int packed_type = prim.prim_type(); const int type = (packed_type & PRIMITIVE_ALL); - if (type & PRIMITIVE_CURVE) { + /* No motion blur curves here, we can't fit them to aligned boxes well. */ + if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_CURVE_THICK)) { const int curve_index = prim.prim_index(); const int segment = PRIMITIVE_UNPACK_SEGMENT(packed_type); const Hair *hair = static_cast(object->geometry); diff --git a/intern/cycles/kernel/bvh/bvh_shadow_all.h b/intern/cycles/kernel/bvh/bvh_shadow_all.h index 12b88f159e2..dccd257d2de 100644 --- a/intern/cycles/kernel/bvh/bvh_shadow_all.h +++ b/intern/cycles/kernel/bvh/bvh_shadow_all.h @@ -158,8 +158,10 @@ ccl_device_inline } #endif #if BVH_FEATURE(BVH_HAIR) - case PRIMITIVE_CURVE: - case PRIMITIVE_MOTION_CURVE: { + case PRIMITIVE_CURVE_THICK: + case PRIMITIVE_MOTION_CURVE_THICK: + case PRIMITIVE_CURVE_RIBBON: + case PRIMITIVE_MOTION_CURVE_RIBBON: { const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr); hit = curve_intersect( kg, isect_array, P, dir, visibility, object, prim_addr, ray->time, curve_type); diff --git a/intern/cycles/kernel/bvh/bvh_traversal.h b/intern/cycles/kernel/bvh/bvh_traversal.h index e6236c93caa..8b2699ab807 100644 --- a/intern/cycles/kernel/bvh/bvh_traversal.h +++ b/intern/cycles/kernel/bvh/bvh_traversal.h @@ -164,13 +164,15 @@ ccl_device_noinline bool BVH_FUNCTION_FULL_NAME(BVH)(KernelGlobals *kg, } #endif /* BVH_FEATURE(BVH_MOTION) */ #if BVH_FEATURE(BVH_HAIR) - case PRIMITIVE_CURVE: - case PRIMITIVE_MOTION_CURVE: { + case PRIMITIVE_CURVE_THICK: + case PRIMITIVE_MOTION_CURVE_THICK: + case PRIMITIVE_CURVE_RIBBON: + case PRIMITIVE_MOTION_CURVE_RIBBON: { for (; prim_addr < prim_addr2; prim_addr++) { BVH_DEBUG_NEXT_INTERSECTION(); const uint curve_type = kernel_tex_fetch(__prim_type, prim_addr); kernel_assert((curve_type & PRIMITIVE_ALL) == (type & PRIMITIVE_ALL)); - bool hit = curve_intersect( + const bool hit = curve_intersect( kg, isect, P, dir, visibility, object, prim_addr, ray->time, curve_type); if (hit) { /* shadow ray early termination */ diff --git a/intern/cycles/kernel/closure/bsdf_hair_principled.h b/intern/cycles/kernel/closure/bsdf_hair_principled.h index 18934d86cc8..389bd62ba68 100644 --- a/intern/cycles/kernel/closure/bsdf_hair_principled.h +++ b/intern/cycles/kernel/closure/bsdf_hair_principled.h @@ -213,7 +213,9 @@ ccl_device int bsdf_principled_hair_setup(ShaderData *sd, PrincipledHairBSDF *bs /* TODO: we convert this value to a cosine later and discard the sign, so * we could probably save some operations. */ - float h = dot(cross(sd->Ng, X), Z); + float h = (sd->type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) ? + -sd->v : + dot(cross(sd->Ng, X), Z); kernel_assert(fabsf(h) < 1.0f + 1e-4f); kernel_assert(isfinite3_safe(Y)); diff --git a/intern/cycles/kernel/geom/geom_curve.h b/intern/cycles/kernel/geom/geom_curve.h index d2ac2d60435..a7a262c029f 100644 --- a/intern/cycles/kernel/geom/geom_curve.h +++ b/intern/cycles/kernel/geom/geom_curve.h @@ -211,7 +211,7 @@ ccl_device float curve_thickness(KernelGlobals *kg, ShaderData *sd) float4 P_curve[2]; - if (sd->type & PRIMITIVE_CURVE) { + if (!(sd->type & PRIMITIVE_ALL_MOTION)) { P_curve[0] = kernel_tex_fetch(__curve_keys, k0); P_curve[1] = kernel_tex_fetch(__curve_keys, k1); } diff --git a/intern/cycles/kernel/geom/geom_curve_intersect.h b/intern/cycles/kernel/geom/geom_curve_intersect.h index c4a614ab676..86f7f246c6e 100644 --- a/intern/cycles/kernel/geom/geom_curve_intersect.h +++ b/intern/cycles/kernel/geom/geom_curve_intersect.h @@ -627,10 +627,10 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals *kg, float time, int type) { - const bool is_curve_primitive = (type & PRIMITIVE_CURVE); + const bool is_motion = (type & PRIMITIVE_ALL_MOTION); # ifndef __KERNEL_OPTIX__ /* See OptiX motion flag OPTIX_MOTION_FLAG_[START|END]_VANISH */ - if (!is_curve_primitive && kernel_data.bvh.use_bvh_steps) { + if (is_motion && kernel_data.bvh.use_bvh_steps) { const float2 prim_time = kernel_tex_fetch(__prim_time, curveAddr); if (time < prim_time.x || time > prim_time.y) { return false; @@ -650,7 +650,7 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals *kg, int kb = min(k1 + 1, __float_as_int(v00.x) + __float_as_int(v00.y) - 1); float4 curve[4]; - if (is_curve_primitive) { + if (!is_motion) { curve[0] = kernel_tex_fetch(__curve_keys, ka); curve[1] = kernel_tex_fetch(__curve_keys, k0); curve[2] = kernel_tex_fetch(__curve_keys, k1); @@ -667,10 +667,9 @@ ccl_device_forceinline bool curve_intersect(KernelGlobals *kg, } # endif - const bool use_ribbon = (kernel_data.curve.curveflags & CURVE_KN_RIBBONS) != 0; - if (use_ribbon) { + if (type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) { /* todo: adaptive number of subdivisions could help performance here. */ - const int subdivisions = kernel_data.curve.subdivisions; + const int subdivisions = kernel_data.bvh.curve_subdivisions; if (ribbon_intersect(P, dir, isect->t, subdivisions, curve, isect)) { isect->prim = curveAddr; isect->object = object; @@ -724,7 +723,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals *kg, float4 P_curve[4]; - if (sd->type & PRIMITIVE_CURVE) { + if (!(sd->type & PRIMITIVE_ALL_MOTION)) { P_curve[0] = kernel_tex_fetch(__curve_keys, ka); P_curve[1] = kernel_tex_fetch(__curve_keys, k0); P_curve[2] = kernel_tex_fetch(__curve_keys, k1); @@ -742,7 +741,7 @@ ccl_device_inline void curve_shader_setup(KernelGlobals *kg, const float4 dPdu4 = catmull_rom_basis_derivative(P_curve, isect->u); const float3 dPdu = float4_to_float3(dPdu4); - if (kernel_data.curve.curveflags & CURVE_KN_RIBBONS) { + if (sd->type & (PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON)) { /* Rounded smooth normals for ribbons, to approximate thick curve shape. */ const float3 tangent = normalize(dPdu); const float3 bitangent = normalize(cross(tangent, -D)); diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h index 02de2db8bd2..ff0f6bd1fbe 100644 --- a/intern/cycles/kernel/kernel_types.h +++ b/intern/cycles/kernel/kernel_types.h @@ -691,27 +691,38 @@ typedef enum PrimitiveType { PRIMITIVE_NONE = 0, PRIMITIVE_TRIANGLE = (1 << 0), PRIMITIVE_MOTION_TRIANGLE = (1 << 1), - PRIMITIVE_CURVE = (1 << 2), - PRIMITIVE_MOTION_CURVE = (1 << 3), + PRIMITIVE_CURVE_THICK = (1 << 2), + PRIMITIVE_MOTION_CURVE_THICK = (1 << 3), + PRIMITIVE_CURVE_RIBBON = (1 << 4), + PRIMITIVE_MOTION_CURVE_RIBBON = (1 << 5), /* Lamp primitive is not included below on purpose, * since it is no real traceable primitive. */ - PRIMITIVE_LAMP = (1 << 4), + PRIMITIVE_LAMP = (1 << 6), PRIMITIVE_ALL_TRIANGLE = (PRIMITIVE_TRIANGLE | PRIMITIVE_MOTION_TRIANGLE), - PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE | PRIMITIVE_MOTION_CURVE), - PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE | PRIMITIVE_MOTION_CURVE), + PRIMITIVE_ALL_CURVE = (PRIMITIVE_CURVE_THICK | PRIMITIVE_MOTION_CURVE_THICK | + PRIMITIVE_CURVE_RIBBON | PRIMITIVE_MOTION_CURVE_RIBBON), + PRIMITIVE_ALL_MOTION = (PRIMITIVE_MOTION_TRIANGLE | PRIMITIVE_MOTION_CURVE_THICK | + PRIMITIVE_MOTION_CURVE_RIBBON), PRIMITIVE_ALL = (PRIMITIVE_ALL_TRIANGLE | PRIMITIVE_ALL_CURVE), /* Total number of different traceable primitives. * NOTE: This is an actual value, not a bitflag. */ - PRIMITIVE_NUM_TOTAL = 4, + PRIMITIVE_NUM_TOTAL = 6, } PrimitiveType; #define PRIMITIVE_PACK_SEGMENT(type, segment) ((segment << PRIMITIVE_NUM_TOTAL) | (type)) #define PRIMITIVE_UNPACK_SEGMENT(type) (type >> PRIMITIVE_NUM_TOTAL) +typedef enum CurveShapeType { + CURVE_RIBBON = 0, + CURVE_THICK = 1, + + CURVE_NUM_SHAPE_TYPES, +} CurveShapeType; + /* Attributes */ typedef enum AttributePrimitive { @@ -1400,7 +1411,7 @@ typedef struct KernelBVH { int have_curves; int bvh_layout; int use_bvh_steps; - int pad; + int curve_subdivisions; /* Custom BVH */ #ifdef __KERNEL_OPTIX__ @@ -1418,19 +1429,6 @@ typedef struct KernelBVH { } KernelBVH; static_assert_align(KernelBVH, 16); -typedef enum CurveFlag { - /* runtime flags */ - CURVE_KN_RIBBONS = 1, /* use flat curve ribbons */ -} CurveFlag; - -typedef struct KernelCurves { - int curveflags; - int subdivisions; - - int pad1, pad2; -} KernelCurves; -static_assert_align(KernelCurves, 16); - typedef struct KernelTables { int beckmann_offset; int pad1, pad2, pad3; @@ -1451,7 +1449,6 @@ typedef struct KernelData { KernelBackground background; KernelIntegrator integrator; KernelBVH bvh; - KernelCurves curve; KernelTables tables; KernelBake bake; } KernelData; diff --git a/intern/cycles/render/curves.cpp b/intern/cycles/render/curves.cpp index 7c9bcaa2549..db48d8b6430 100644 --- a/intern/cycles/render/curves.cpp +++ b/intern/cycles/render/curves.cpp @@ -76,76 +76,4 @@ void curvebounds(float *lower, float *upper, float3 *p, int dim) *lower = min(*lower, min(exa, exb)); } -/* Hair System Manager */ - -CurveSystemManager::CurveSystemManager() -{ - curve_shape = CURVE_THICK; - subdivisions = 3; - - use_curves = true; - - need_update = true; - need_mesh_update = false; -} - -CurveSystemManager::~CurveSystemManager() -{ -} - -void CurveSystemManager::device_update(Device *device, - DeviceScene *dscene, - Scene * /*scene*/, - Progress &progress) -{ - if (!need_update) - return; - - device_free(device, dscene); - - progress.set_status("Updating Hair settings", "Copying Hair settings to device"); - - KernelCurves *kcurve = &dscene->data.curve; - - kcurve->curveflags = 0; - - if (use_curves) { - if (curve_shape == CURVE_RIBBON) { - kcurve->curveflags |= CURVE_KN_RIBBONS; - } - - /* Matching the tesselation rate limit in Embree. */ - kcurve->subdivisions = clamp(1 << subdivisions, 1, 16); - } - - if (progress.get_cancel()) - return; - - need_update = false; -} - -void CurveSystemManager::device_free(Device * /*device*/, DeviceScene * /*dscene*/) -{ -} - -bool CurveSystemManager::modified(const CurveSystemManager &CurveSystemManager) -{ - return !(use_curves == CurveSystemManager.use_curves && - subdivisions == CurveSystemManager.subdivisions); -} - -bool CurveSystemManager::modified_mesh(const CurveSystemManager &CurveSystemManager) -{ - return !(use_curves == CurveSystemManager.use_curves); -} - -void CurveSystemManager::tag_update(Scene * /*scene*/) -{ - need_update = true; -} - -void CurveSystemManager::tag_update_mesh() -{ - need_mesh_update = true; -} CCL_NAMESPACE_END diff --git a/intern/cycles/render/curves.h b/intern/cycles/render/curves.h index e6b0a3b4706..71c09ba2d2b 100644 --- a/intern/cycles/render/curves.h +++ b/intern/cycles/render/curves.h @@ -20,6 +20,8 @@ #include "util/util_array.h" #include "util/util_types.h" +#include "render/hair.h" + CCL_NAMESPACE_BEGIN class Device; @@ -29,13 +31,6 @@ class Scene; void curvebounds(float *lower, float *upper, float3 *p, int dim); -typedef enum CurveShapeType { - CURVE_RIBBON = 0, - CURVE_THICK = 1, - - CURVE_NUM_SHAPE_TYPES, -} CurveShapeType; - class ParticleCurveData { public: @@ -61,30 +56,6 @@ class ParticleCurveData { array curvekey_time; }; -/* HairSystem Manager */ - -class CurveSystemManager { - public: - CurveShapeType curve_shape; - int subdivisions; - - bool use_curves; - - bool need_update; - bool need_mesh_update; - - CurveSystemManager(); - ~CurveSystemManager(); - - void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress &progress); - void device_free(Device *device, DeviceScene *dscene); - bool modified(const CurveSystemManager &CurveSystemManager); - bool modified_mesh(const CurveSystemManager &CurveSystemManager); - - void tag_update(Scene *scene); - void tag_update_mesh(); -}; - CCL_NAMESPACE_END #endif /* __CURVES_H__ */ diff --git a/intern/cycles/render/geometry.cpp b/intern/cycles/render/geometry.cpp index f448c2fb07f..797321f6eff 100644 --- a/intern/cycles/render/geometry.cpp +++ b/intern/cycles/render/geometry.cpp @@ -211,8 +211,7 @@ void Geometry::compute_bvh( bparams.num_motion_triangle_steps = params->num_bvh_time_steps; bparams.num_motion_curve_steps = params->num_bvh_time_steps; bparams.bvh_type = params->bvh_type; - bparams.curve_flags = dscene->data.curve.curveflags; - bparams.curve_subdivisions = dscene->data.curve.subdivisions; + bparams.curve_subdivisions = params->curve_subdivisions(); delete bvh; bvh = BVH::create(bparams, geometry, objects); @@ -1026,8 +1025,7 @@ void GeometryManager::device_update_bvh(Device *device, bparams.num_motion_triangle_steps = scene->params.num_bvh_time_steps; bparams.num_motion_curve_steps = scene->params.num_bvh_time_steps; bparams.bvh_type = scene->params.bvh_type; - bparams.curve_flags = dscene->data.curve.curveflags; - bparams.curve_subdivisions = dscene->data.curve.subdivisions; + bparams.curve_subdivisions = scene->params.curve_subdivisions(); VLOG(1) << "Using " << bvh_layout_name(bparams.bvh_layout) << " layout."; @@ -1103,6 +1101,7 @@ void GeometryManager::device_update_bvh(Device *device, dscene->data.bvh.root = pack.root_index; dscene->data.bvh.bvh_layout = bparams.bvh_layout; dscene->data.bvh.use_bvh_steps = (scene->params.num_bvh_time_steps != 0); + dscene->data.bvh.curve_subdivisions = scene->params.curve_subdivisions(); bvh->copy_to_device(progress, dscene); @@ -1145,6 +1144,12 @@ void GeometryManager::device_update_preprocess(Device *device, Scene *scene, Pro create_volume_mesh(mesh, progress); } } + + if (geom->type == Geometry::HAIR) { + /* Set curve shape, still a global scene setting for now. */ + Hair *hair = static_cast(geom); + hair->curve_shape = scene->params.hair_shape; + } } need_flags_update = false; diff --git a/intern/cycles/render/hair.cpp b/intern/cycles/render/hair.cpp index 3daa4cc1e35..816c15cf4ef 100644 --- a/intern/cycles/render/hair.cpp +++ b/intern/cycles/render/hair.cpp @@ -294,6 +294,7 @@ NODE_DEFINE(Hair) Hair::Hair() : Geometry(node_type, Geometry::HAIR) { curvekey_offset = 0; + curve_shape = CURVE_RIBBON; } Hair::~Hair() diff --git a/intern/cycles/render/hair.h b/intern/cycles/render/hair.h index 79f77a78753..39d6a34d799 100644 --- a/intern/cycles/render/hair.h +++ b/intern/cycles/render/hair.h @@ -96,6 +96,7 @@ class Hair : public Geometry { /* BVH */ size_t curvekey_offset; + CurveShapeType curve_shape; /* Constructor/Destructor */ Hair(); diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp index 7c8b7bf0edc..3a8a0cd9a05 100644 --- a/intern/cycles/render/object.cpp +++ b/intern/cycles/render/object.cpp @@ -219,7 +219,6 @@ void Object::tag_update(Scene *scene) } scene->camera->need_flags_update = true; - scene->curve_system_manager->need_update = true; scene->geometry_manager->need_update = true; scene->object_manager->need_update = true; } @@ -844,7 +843,6 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, P void ObjectManager::tag_update(Scene *scene) { need_update = true; - scene->curve_system_manager->need_update = true; scene->geometry_manager->need_update = true; scene->light_manager->need_update = true; } diff --git a/intern/cycles/render/scene.cpp b/intern/cycles/render/scene.cpp index f5b68d5a4fe..9016a8d325f 100644 --- a/intern/cycles/render/scene.cpp +++ b/intern/cycles/render/scene.cpp @@ -108,7 +108,6 @@ Scene::Scene(const SceneParams ¶ms_, Device *device) integrator = new Integrator(); image_manager = new ImageManager(device->info); particle_system_manager = new ParticleSystemManager(); - curve_system_manager = new CurveSystemManager(); bake_manager = new BakeManager(); /* OSL only works on the CPU */ @@ -156,7 +155,6 @@ void Scene::free_memory(bool final) light_manager->device_free(device, &dscene); particle_system_manager->device_free(device, &dscene); - curve_system_manager->device_free(device, &dscene); bake_manager->device_free(device, &dscene); @@ -180,7 +178,6 @@ void Scene::free_memory(bool final) delete shader_manager; delete light_manager; delete particle_system_manager; - delete curve_system_manager; delete image_manager; delete bake_manager; } @@ -230,12 +227,6 @@ void Scene::device_update(Device *device_, Progress &progress) progress.set_status("Updating Objects"); object_manager->device_update(device, &dscene, this, progress); - if (progress.get_cancel() || device->have_error()) - return; - - progress.set_status("Updating Hair Systems"); - curve_system_manager->device_update(device, &dscene, this, progress); - if (progress.get_cancel() || device->have_error()) return; @@ -369,8 +360,7 @@ bool Scene::need_data_update() return (background->need_update || image_manager->need_update || object_manager->need_update || geometry_manager->need_update || light_manager->need_update || lookup_tables->need_update || integrator->need_update || shader_manager->need_update || - particle_system_manager->need_update || curve_system_manager->need_update || - bake_manager->need_update || film->need_update); + particle_system_manager->need_update || bake_manager->need_update || film->need_update); } bool Scene::need_reset() @@ -393,7 +383,6 @@ void Scene::reset() geometry_manager->tag_update(this); light_manager->tag_update(this); particle_system_manager->tag_update(this); - curve_system_manager->tag_update(this); } void Scene::device_free() diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h index 6b10a901d7b..67616262c03 100644 --- a/intern/cycles/render/scene.h +++ b/intern/cycles/render/scene.h @@ -168,6 +168,8 @@ class SceneParams { bool use_bvh_spatial_split; bool use_bvh_unaligned_nodes; int num_bvh_time_steps; + int hair_subdivisions; + CurveShapeType hair_shape; bool persistent_data; int texture_limit; @@ -181,6 +183,8 @@ class SceneParams { use_bvh_spatial_split = false; use_bvh_unaligned_nodes = true; num_bvh_time_steps = 0; + hair_subdivisions = 3; + hair_shape = CURVE_RIBBON; persistent_data = false; texture_limit = 0; background = true; @@ -193,8 +197,15 @@ class SceneParams { use_bvh_spatial_split == params.use_bvh_spatial_split && use_bvh_unaligned_nodes == params.use_bvh_unaligned_nodes && num_bvh_time_steps == params.num_bvh_time_steps && + hair_subdivisions == params.hair_subdivisions && hair_shape == params.hair_shape && persistent_data == params.persistent_data && texture_limit == params.texture_limit); } + + int curve_subdivisions() + { + /* Matching the tesselation rate limit in Embree. */ + return clamp(1 << hair_subdivisions, 1, 16); + } }; /* Scene */ @@ -226,7 +237,6 @@ class Scene { GeometryManager *geometry_manager; ObjectManager *object_manager; ParticleSystemManager *particle_system_manager; - CurveSystemManager *curve_system_manager; BakeManager *bake_manager; /* default shaders */ diff --git a/intern/cycles/render/session.cpp b/intern/cycles/render/session.cpp index 6caa686847e..9d5e57404f0 100644 --- a/intern/cycles/render/session.cpp +++ b/intern/cycles/render/session.cpp @@ -21,7 +21,6 @@ #include "render/bake.h" #include "render/buffers.h" #include "render/camera.h" -#include "render/curves.h" #include "render/graph.h" #include "render/integrator.h" #include "render/light.h" @@ -774,7 +773,7 @@ DeviceRequestedFeatures Session::get_requested_device_features() */ bool use_motion = scene->need_motion() == Scene::MotionType::MOTION_BLUR; requested_features.use_hair = false; - requested_features.use_hair_thick = (scene->curve_system_manager->curve_shape == CURVE_THICK); + requested_features.use_hair_thick = (scene->params.hair_shape == CURVE_THICK); requested_features.use_object_motion = false; requested_features.use_camera_motion = use_motion && scene->camera->use_motion(); foreach (Object *object, scene->objects) { -- cgit v1.2.3