Cycles: Improve volume stack size calculation

Only count volume objects after shader optimization.

Allows to discard objects which don't have effective volume
BSDF connected to the shader output (i.e. constant folded,
or non-volume BSDF used by mistake).

Solves memory regression reported in T92014.

There is still possibility to improve memory even further
for cases when there are a lot of non-intersecting volume
objects, but that requires a deeper refactor of update
process. Will happen as a followup development.

Differential Revision: https://developer.blender.org/D12797
This commit is contained in:
Sergey Sharybin 2021-10-08 16:38:40 +02:00
parent a82c9e1e40
commit eca2a41964
2 changed files with 13 additions and 13 deletions

View File

@ -375,7 +375,7 @@ bool Object::check_is_volume() const
for (Node *node : get_geometry()->get_used_shaders()) {
const Shader *shader = static_cast<const Shader *>(node);
if (shader->has_volume_connected) {
if (shader->has_volume) {
return true;
}
}

View File

@ -664,29 +664,29 @@ int Scene::get_max_closure_count()
int Scene::get_volume_stack_size() const
{
int volume_stack_size = 0;
/* Space for background volume and terminator.
* Don't do optional here because camera ray initialization expects that there is space for
* at least those elements (avoiding extra condition to check if there is actual volume or not).
*/
volume_stack_size += 2;
/* Quick non-expensive check. Can over-estimate maximum possible nested level, but does not
* require expensive calculation during pre-processing. */
int num_volume_objects = 0;
for (const Object *object : objects) {
if (object->check_is_volume()) {
++num_volume_objects;
++volume_stack_size;
}
if (num_volume_objects == MAX_VOLUME_STACK_SIZE) {
if (volume_stack_size == MAX_VOLUME_STACK_SIZE) {
break;
}
}
/* Count background world for the stack. */
const Shader *background_shader = background->get_shader(this);
if (background_shader && background_shader->has_volume_connected) {
++num_volume_objects;
}
volume_stack_size = min(volume_stack_size, MAX_VOLUME_STACK_SIZE);
/* Space for terminator. */
++num_volume_objects;
return min(num_volume_objects, MAX_VOLUME_STACK_SIZE);
return volume_stack_size;
}
bool Scene::has_shadow_catcher()