Refactor: Cycles: Compute shader usage of volumes earlier

This will be needed for volume null scattering.

Pull Request: https://projects.blender.org/blender/blender/pulls/144370
This commit is contained in:
Brecht Van Lommel
2025-08-11 18:57:51 +02:00
committed by Brecht Van Lommel
parent 961faca474
commit f6c628e247
3 changed files with 32 additions and 45 deletions

View File

@@ -1528,33 +1528,20 @@ void OSLCompiler::compile(Shader *shader)
{
if (shader->is_modified()) {
ShaderGraph *graph = shader->graph.get();
ShaderNode *output = (graph) ? graph->output() : nullptr;
const bool has_bump = shader->has_bump;
current_shader = shader;
shader->has_surface = false;
shader->has_surface_transparent = false;
shader->has_surface_raytrace = false;
shader->has_surface_bssrdf = false;
shader->has_volume = false;
shader->has_displacement = false;
shader->has_surface_spatial_varying = false;
shader->has_volume_spatial_varying = false;
shader->has_volume_attribute_dependency = false;
/* generate surface shader */
if (shader->reference_count() && graph && output->input("Surface")->link) {
shader->osl_surface_ref = compile_type(shader, shader->graph.get(), SHADER_TYPE_SURFACE);
if (shader->reference_count() && shader->has_surface) {
shader->osl_surface_ref = compile_type(shader, graph, SHADER_TYPE_SURFACE);
if (has_bump) {
shader->osl_surface_bump_ref = compile_type(shader, shader->graph.get(), SHADER_TYPE_BUMP);
shader->osl_surface_bump_ref = compile_type(shader, graph, SHADER_TYPE_BUMP);
}
else {
shader->osl_surface_bump_ref = OSL::ShaderGroupRef();
}
shader->has_surface = true;
}
else {
shader->osl_surface_ref = OSL::ShaderGroupRef();
@@ -1562,19 +1549,16 @@ void OSLCompiler::compile(Shader *shader)
}
/* generate volume shader */
if (shader->reference_count() && graph && output->input("Volume")->link) {
shader->osl_volume_ref = compile_type(shader, shader->graph.get(), SHADER_TYPE_VOLUME);
shader->has_volume = true;
if (shader->reference_count() && shader->has_volume) {
shader->osl_volume_ref = compile_type(shader, graph, SHADER_TYPE_VOLUME);
}
else {
shader->osl_volume_ref = OSL::ShaderGroupRef();
}
/* generate displacement shader */
if (shader->reference_count() && graph && output->input("Displacement")->link) {
shader->osl_displacement_ref = compile_type(
shader, shader->graph.get(), SHADER_TYPE_DISPLACEMENT);
shader->has_displacement = true;
if (shader->reference_count() && shader->has_displacement) {
shader->osl_displacement_ref = compile_type(shader, graph, SHADER_TYPE_DISPLACEMENT);
}
else {
shader->osl_displacement_ref = OSL::ShaderGroupRef();

View File

@@ -483,7 +483,7 @@ int ShaderManager::get_shader_id(Shader *shader, bool smooth)
}
void ShaderManager::device_update_pre(Device * /*device*/,
DeviceScene * /*dscene*/,
DeviceScene *dscene,
Scene *scene,
Progress & /*progress*/)
{
@@ -505,18 +505,38 @@ void ShaderManager::device_update_pre(Device * /*device*/,
assert(scene->default_background->reference_count() != 0);
assert(scene->default_empty->reference_count() != 0);
/* Preprocess shader graph. */
bool has_volumes = false;
for (Shader *shader : scene->shaders) {
if (shader->is_modified()) {
ShaderNode *output = shader->graph->output();
shader->has_bump = (shader->get_displacement_method() != DISPLACE_TRUE) &&
output->input("Surface")->link && output->input("Displacement")->link;
shader->has_bssrdf_bump = shader->has_bump;
shader->graph->finalize(
scene, shader->has_bump, shader->get_displacement_method() == DISPLACE_BOTH);
shader->has_surface = output->input("Surface")->link != nullptr;
shader->has_surface_transparent = false;
shader->has_surface_raytrace = false;
shader->has_surface_bssrdf = false;
shader->has_surface_spatial_varying = false;
shader->has_volume = output->input("Volume")->link != nullptr;
shader->has_volume_spatial_varying = false;
shader->has_volume_attribute_dependency = false;
shader->has_displacement = output->input("Displacement")->link != nullptr;
}
if (shader->reference_count()) {
has_volumes |= shader->has_volume;
}
}
/* Set this early as it is needed by volume rendering passes. */
KernelIntegrator *kintegrator = &dscene->data.integrator;
kintegrator->use_volumes = has_volumes;
}
void ShaderManager::device_update_post(Device *device,
@@ -543,7 +563,6 @@ void ShaderManager::device_update_common(Device * /*device*/,
}
KernelShader *kshader = dscene->shaders.alloc(scene->shaders.size());
bool has_volumes = false;
bool has_transparent_shadow = false;
for (Shader *shader : scene->shaders) {
@@ -570,8 +589,6 @@ void ShaderManager::device_update_common(Device * /*device*/,
}
if (shader->has_volume) {
flag |= SD_HAS_VOLUME;
has_volumes = true;
/* todo: this could check more fine grained, to skip useless volumes
* enclosed inside an opaque bsdf.
*/
@@ -650,7 +667,6 @@ void ShaderManager::device_update_common(Device * /*device*/,
/* integrator */
KernelIntegrator *kintegrator = &dscene->data.integrator;
kintegrator->use_volumes = has_volumes;
/* TODO(sergey): De-duplicate with flags set in integrator.cpp. */
kintegrator->transparent_shadows = has_transparent_shadow;

View File

@@ -820,20 +820,17 @@ void SVMCompiler::compile_type(Shader *shader, ShaderGraph *graph, ShaderType ty
switch (type) {
case SHADER_TYPE_SURFACE: /* generate surface shader */
find_aov_nodes_and_dependencies(state.aov_nodes, graph, &state);
if (clin->link) {
shader->has_surface = true;
if (shader->has_surface) {
state.node_feature_mask = KERNEL_FEATURE_NODE_MASK_SURFACE;
}
break;
case SHADER_TYPE_VOLUME: /* generate volume shader */
if (clin->link) {
shader->has_volume = true;
if (shader->has_volume) {
state.node_feature_mask = KERNEL_FEATURE_NODE_MASK_VOLUME;
}
break;
case SHADER_TYPE_DISPLACEMENT: /* generate displacement shader */
if (clin->link) {
shader->has_displacement = true;
if (shader->has_displacement) {
state.node_feature_mask = KERNEL_FEATURE_NODE_MASK_DISPLACEMENT;
}
break;
@@ -901,16 +898,6 @@ void SVMCompiler::compile(Shader *shader,
current_shader = shader;
shader->has_surface = false;
shader->has_surface_transparent = false;
shader->has_surface_raytrace = false;
shader->has_surface_bssrdf = false;
shader->has_volume = false;
shader->has_displacement = false;
shader->has_surface_spatial_varying = false;
shader->has_volume_spatial_varying = false;
shader->has_volume_attribute_dependency = false;
/* generate bump shader */
if (has_bump) {
const scoped_timer timer((summary != nullptr) ? &summary->time_generate_bump : nullptr);