Fix #119791: Cycles: Transparent hair curves render slow with volumes

The slowdown was caused by the volume step calculation returning an
infinite value. This was caused by the calculation happening before
the object bounds are calculated via the code path which does some
early update for the displacement and hair transparency. The actual
value was never re-calculated after bounds are valid.

The solution is to only clear need-update after the final call of
the device_update_flags().

Pull Request: https://projects.blender.org/blender/blender/pulls/121042
This commit is contained in:
Sergey Sharybin
2024-04-24 20:15:58 +02:00
committed by Sergey Sharybin
parent 31e56797f0
commit b24c91e93e
2 changed files with 10 additions and 14 deletions

View File

@@ -817,7 +817,6 @@ void GeometryManager::device_update(Device *device,
}
/* Update images needed for true displacement. */
bool old_need_object_flags_update = false;
if (true_displacement_used || curve_shadow_transparency_used) {
scoped_callback_timer timer([scene](double time) {
if (scene->update_stats) {
@@ -826,7 +825,6 @@ void GeometryManager::device_update(Device *device,
}
});
device_update_displacement_images(device, scene, progress);
old_need_object_flags_update = scene->object_manager->need_flags_update;
scene->object_manager->device_update_flags(device, dscene, scene, progress, false);
}
@@ -1011,16 +1009,6 @@ void GeometryManager::device_update(Device *device,
}
}
if (true_displacement_used) {
/* Re-tag flags for update, so they're re-evaluated
* for meshes with correct bounding boxes.
*
* This wouldn't cause wrong results, just true
* displacement might be less optimal to calculate.
*/
scene->object_manager->need_flags_update = old_need_object_flags_update;
}
/* unset flags */
foreach (Geometry *geom, scene->geometry) {

View File

@@ -366,6 +366,7 @@ float Object::compute_volume_step_size() const
if (step_size == FLT_MAX) {
/* Fall back to 1/10th of bounds for procedural volumes. */
assert(bounds.valid());
step_size = 0.1f * average(bounds.size());
}
@@ -858,8 +859,15 @@ void ObjectManager::device_update_flags(
}
});
update_flags = UPDATE_NONE;
need_flags_update = false;
if (bounds_valid) {
/* Object flags and calculations related to volume depend on proper bounds calculated, which
* might not be available yet when object flags are updated for displacement or hair
* transparency calculation. In this case do not clear the need_flags_update, so that these
* values which depend on bounds are re-calculated when the device_update process comes back
* here from the "Updating Objects Flags" stage. */
update_flags = UPDATE_NONE;
need_flags_update = false;
}
if (scene->objects.size() == 0) {
return;