Fix T94467: Cycles baking of normal pass slower than before cycles-x

This commit is contained in:
Brecht Van Lommel 2022-04-28 18:29:13 +02:00
parent 5b1ec08f04
commit c722993ef1
Notes: blender-bot 2023-03-29 17:00:00 +02:00
Referenced by issue #94467, Cycles Baking: 3.x is much slower than 2.93
Referenced by issue #105555, Baking Indirect Lighting is broken
3 changed files with 127 additions and 63 deletions

View File

@ -508,87 +508,139 @@ void BlenderSession::render_frame_finish()
full_buffer_files_.clear();
}
static PassType bake_type_to_pass(const string &bake_type_str, const int bake_filter)
static bool bake_setup_pass(Scene *scene, const string &bake_type_str, const int bake_filter)
{
Integrator *integrator = scene->integrator;
const char *bake_type = bake_type_str.c_str();
/* data passes */
PassType type = PASS_NONE;
bool use_direct_light = false;
bool use_indirect_light = false;
bool include_albedo = false;
/* Data passes. */
if (strcmp(bake_type, "POSITION") == 0) {
return PASS_POSITION;
type = PASS_POSITION;
}
else if (strcmp(bake_type, "NORMAL") == 0) {
return PASS_NORMAL;
type = PASS_NORMAL;
}
else if (strcmp(bake_type, "UV") == 0) {
return PASS_UV;
type = PASS_UV;
}
else if (strcmp(bake_type, "ROUGHNESS") == 0) {
return PASS_ROUGHNESS;
type = PASS_ROUGHNESS;
}
else if (strcmp(bake_type, "EMIT") == 0) {
return PASS_EMISSION;
type = PASS_EMISSION;
}
/* light passes */
/* Environment pass. */
else if (strcmp(bake_type, "ENVIRONMENT") == 0) {
type = PASS_BACKGROUND;
}
/* AO passes. */
else if (strcmp(bake_type, "AO") == 0) {
return PASS_AO;
type = PASS_AO;
}
/* Combined pass. */
else if (strcmp(bake_type, "COMBINED") == 0) {
return PASS_COMBINED;
type = PASS_COMBINED;
use_direct_light = (bake_filter & BL::BakeSettings::pass_filter_DIRECT) != 0;
use_indirect_light = (bake_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0;
include_albedo = (bake_filter & BL::BakeSettings::pass_filter_COLOR);
integrator->set_use_diffuse((bake_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0);
integrator->set_use_glossy((bake_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0);
integrator->set_use_transmission((bake_filter & BL::BakeSettings::pass_filter_TRANSMISSION) !=
0);
integrator->set_use_emission((bake_filter & BL::BakeSettings::pass_filter_EMIT) != 0);
}
/* Shadow pass. */
else if (strcmp(bake_type, "SHADOW") == 0) {
return PASS_SHADOW;
type = PASS_SHADOW;
use_direct_light = true;
}
/* Light component passes. */
else if (strcmp(bake_type, "DIFFUSE") == 0) {
if ((bake_filter & BL::BakeSettings::pass_filter_DIRECT) &&
bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_DIFFUSE;
type = PASS_DIFFUSE;
use_direct_light = true;
use_indirect_light = true;
}
else if (bake_filter & BL::BakeSettings::pass_filter_DIRECT) {
return PASS_DIFFUSE_DIRECT;
type = PASS_DIFFUSE_DIRECT;
use_direct_light = true;
}
else if (bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_DIFFUSE_INDIRECT;
type = PASS_DIFFUSE_INDIRECT;
use_indirect_light = true;
}
else {
return PASS_DIFFUSE_COLOR;
type = PASS_DIFFUSE_COLOR;
}
include_albedo = (bake_filter & BL::BakeSettings::pass_filter_COLOR);
}
else if (strcmp(bake_type, "GLOSSY") == 0) {
if ((bake_filter & BL::BakeSettings::pass_filter_DIRECT) &&
bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_GLOSSY;
type = PASS_GLOSSY;
use_direct_light = true;
use_indirect_light = true;
}
else if (bake_filter & BL::BakeSettings::pass_filter_DIRECT) {
return PASS_GLOSSY_DIRECT;
type = PASS_GLOSSY_DIRECT;
use_direct_light = true;
}
else if (bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_GLOSSY_INDIRECT;
type = PASS_GLOSSY_INDIRECT;
use_indirect_light = true;
}
else {
return PASS_GLOSSY_COLOR;
type = PASS_GLOSSY_COLOR;
}
include_albedo = (bake_filter & BL::BakeSettings::pass_filter_COLOR);
}
else if (strcmp(bake_type, "TRANSMISSION") == 0) {
if ((bake_filter & BL::BakeSettings::pass_filter_DIRECT) &&
bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_TRANSMISSION;
type = PASS_TRANSMISSION;
use_direct_light = true;
use_indirect_light = true;
}
else if (bake_filter & BL::BakeSettings::pass_filter_DIRECT) {
return PASS_TRANSMISSION_DIRECT;
type = PASS_TRANSMISSION_DIRECT;
use_direct_light = true;
}
else if (bake_filter & BL::BakeSettings::pass_filter_INDIRECT) {
return PASS_TRANSMISSION_INDIRECT;
type = PASS_TRANSMISSION_INDIRECT;
use_indirect_light = true;
}
else {
return PASS_TRANSMISSION_COLOR;
type = PASS_TRANSMISSION_COLOR;
}
}
/* extra */
else if (strcmp(bake_type, "ENVIRONMENT") == 0) {
return PASS_BACKGROUND;
include_albedo = (bake_filter & BL::BakeSettings::pass_filter_COLOR);
}
return PASS_COMBINED;
if (type == PASS_NONE) {
return false;
}
/* Create pass. */
Pass *pass = scene->create_node<Pass>();
pass->set_name(ustring("Combined"));
pass->set_type(type);
pass->set_include_albedo(include_albedo);
/* Disable direct indirect light for performance when not needed. */
integrator->set_use_direct_light(use_direct_light);
integrator->set_use_indirect_light(use_indirect_light);
return true;
}
void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
@ -603,39 +655,25 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
/* Initialize bake manager, before we load the baking kernels. */
scene->bake_manager->set(scene, b_object.name());
/* Add render pass that we want to bake, and name it Combined so that it is
* used as that on the Blender side. */
Pass *pass = scene->create_node<Pass>();
pass->set_name(ustring("Combined"));
pass->set_type(bake_type_to_pass(bake_type, bake_filter));
pass->set_include_albedo((bake_filter & BL::BakeSettings::pass_filter_COLOR));
session->set_display_driver(nullptr);
session->set_output_driver(make_unique<BlenderOutputDriver>(b_engine));
/* Sync scene. */
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
/* Add render pass that we want to bake, and name it Combined so that it is
* used as that on the Blender side. */
if (!bake_setup_pass(scene, bake_type, bake_filter)) {
session->cancel(true);
}
/* Always use transparent background for baking. */
scene->background->set_transparent(true);
if (!session->progress.get_cancel()) {
/* Sync scene. */
BL::Object b_camera_override(b_engine.camera_override());
sync->sync_camera(b_render, b_camera_override, width, height, "");
sync->sync_data(
b_render, b_depsgraph, b_v3d, b_camera_override, width, height, &python_thread_state);
/* Filtering settings for combined pass. */
if (pass->get_type() == PASS_COMBINED) {
Integrator *integrator = scene->integrator;
integrator->set_use_direct_light((bake_filter & BL::BakeSettings::pass_filter_DIRECT) != 0);
integrator->set_use_indirect_light((bake_filter & BL::BakeSettings::pass_filter_INDIRECT) !=
0);
integrator->set_use_diffuse((bake_filter & BL::BakeSettings::pass_filter_DIFFUSE) != 0);
integrator->set_use_glossy((bake_filter & BL::BakeSettings::pass_filter_GLOSSY) != 0);
integrator->set_use_transmission(
(bake_filter & BL::BakeSettings::pass_filter_TRANSMISSION) != 0);
integrator->set_use_emission((bake_filter & BL::BakeSettings::pass_filter_EMIT) != 0);
}
/* Always use transparent background for baking. */
scene->background->set_transparent(true);
/* Load built-in images from Blender. */
builtin_images_load();
}
@ -643,10 +681,12 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
/* Object might have been disabled for rendering or excluded in some
* other way, in that case Blender will report a warning afterwards. */
bool object_found = false;
foreach (Object *ob, scene->objects) {
if (ob->name == b_object.name()) {
object_found = true;
break;
if (!session->progress.get_cancel()) {
foreach (Object *ob, scene->objects) {
if (ob->name == b_object.name()) {
object_found = true;
break;
}
}
}

View File

@ -192,6 +192,19 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
Ng = normalize(transform_direction_transposed(&itfm, Ng));
}
const int shader_index = shader & SHADER_MASK;
const int shader_flags = kernel_tex_fetch(__shaders, shader_index).flags;
/* Fast path for position and normal passes not affected by shaders. */
if (kernel_data.film.pass_position != PASS_UNUSED) {
kernel_write_pass_float3(buffer + kernel_data.film.pass_position, P);
return true;
}
else if (kernel_data.film.pass_normal != PASS_UNUSED && !(shader_flags & SD_HAS_BUMP)) {
kernel_write_pass_float3(buffer + kernel_data.film.pass_normal, N);
return true;
}
/* Setup ray. */
Ray ray ccl_optional_struct_init;
ray.P = P + N;
@ -228,8 +241,6 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
integrator_state_write_isect(kg, state, &isect);
/* Setup next kernel to execute. */
const int shader_index = shader & SHADER_MASK;
const int shader_flags = kernel_tex_fetch(__shaders, shader_index).flags;
const bool use_caustics = kernel_data.integrator.use_caustics &&
(object_flag & SD_OBJECT_CAUSTICS);
const bool use_raytrace_kernel = (shader_flags & SD_HAS_RAYTRACE) || use_caustics;

View File

@ -163,6 +163,19 @@ void Film::device_update(Device *device, DeviceScene *dscene, Scene *scene)
kfilm->pass_stride = 0;
/* Mark with PASS_UNUSED to avoid mask test in the kernel. */
kfilm->pass_combined = PASS_UNUSED;
kfilm->pass_depth = PASS_UNUSED;
kfilm->pass_position = PASS_UNUSED;
kfilm->pass_normal = PASS_UNUSED;
kfilm->pass_roughness = PASS_UNUSED;
kfilm->pass_motion = PASS_UNUSED;
kfilm->pass_motion_weight = PASS_UNUSED;
kfilm->pass_uv = PASS_UNUSED;
kfilm->pass_object_id = PASS_UNUSED;
kfilm->pass_material_id = PASS_UNUSED;
kfilm->pass_diffuse_color = PASS_UNUSED;
kfilm->pass_glossy_color = PASS_UNUSED;
kfilm->pass_transmission_color = PASS_UNUSED;
kfilm->pass_background = PASS_UNUSED;
kfilm->pass_emission = PASS_UNUSED;
kfilm->pass_ao = PASS_UNUSED;