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
This commit is contained in:
parent
207338bb58
commit
2c41c8e94f
Notes:
blender-bot
2023-02-14 07:47:59 +01:00
Referenced by issue #73778, Cycles: Embree improvements
|
@ -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)",
|
||||
|
|
|
@ -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':
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) &&
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -81,7 +81,7 @@ class BVHEmbree : public BVH {
|
|||
vector<RTCScene> delayed_delete_scenes;
|
||||
int curve_subdivisions;
|
||||
enum RTCBuildQuality build_quality;
|
||||
bool use_ribbons, dynamic_scene;
|
||||
bool dynamic_scene;
|
||||
};
|
||||
|
||||
CCL_NAMESPACE_END
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<const Hair *>(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<const Hair *>(object->geometry);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<float> 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__ */
|
||||
|
|
|
@ -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<Hair *>(geom);
|
||||
hair->curve_shape = scene->params.hair_shape;
|
||||
}
|
||||
}
|
||||
|
||||
need_flags_update = false;
|
||||
|
|
|
@ -294,6 +294,7 @@ NODE_DEFINE(Hair)
|
|||
Hair::Hair() : Geometry(node_type, Geometry::HAIR)
|
||||
{
|
||||
curvekey_offset = 0;
|
||||
curve_shape = CURVE_RIBBON;
|
||||
}
|
||||
|
||||
Hair::~Hair()
|
||||
|
|
|
@ -96,6 +96,7 @@ class Hair : public Geometry {
|
|||
|
||||
/* BVH */
|
||||
size_t curvekey_offset;
|
||||
CurveShapeType curve_shape;
|
||||
|
||||
/* Constructor/Destructor */
|
||||
Hair();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in New Issue