diff --git a/intern/cycles/scene/osl.cpp b/intern/cycles/scene/osl.cpp index 861f7ae0a06..a85f91eb55d 100644 --- a/intern/cycles/scene/osl.cpp +++ b/intern/cycles/scene/osl.cpp @@ -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(); diff --git a/intern/cycles/scene/shader.cpp b/intern/cycles/scene/shader.cpp index 5fc46061ac0..e4b15b9c94c 100644 --- a/intern/cycles/scene/shader.cpp +++ b/intern/cycles/scene/shader.cpp @@ -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; diff --git a/intern/cycles/scene/svm.cpp b/intern/cycles/scene/svm.cpp index 72ceb01edd7..5b0a55e83e2 100644 --- a/intern/cycles/scene/svm.cpp +++ b/intern/cycles/scene/svm.cpp @@ -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);