Fix #107777: Cycles baking of Shadow not working anymore

After the removal of the Shadow pass this no longer worked. Now it works by
marking the object as a shadow catcher and returning the Shadow Catcher pass.

The result is different than before, since it also takes into account indirect
light now and uses a different method to weight the contribution of lights that
is adaptive to the light strength.
This commit is contained in:
Brecht Van Lommel
2023-05-12 17:19:14 +02:00
parent 36e5157693
commit 078b2d7174
2 changed files with 36 additions and 5 deletions

View File

@@ -515,6 +515,7 @@ void BlenderSession::render_frame_finish()
static bool bake_setup_pass(Scene *scene, const string &bake_type_str, const int bake_filter)
{
Integrator *integrator = scene->integrator;
Film *film = scene->film;
const char *bake_type = bake_type_str.c_str();
PassType type = PASS_NONE;
@@ -542,13 +543,29 @@ static bool bake_setup_pass(Scene *scene, const string &bake_type_str, const int
else if (strcmp(bake_type, "ENVIRONMENT") == 0) {
type = PASS_BACKGROUND;
}
/* AO passes. */
/* AO pass. */
else if (strcmp(bake_type, "AO") == 0) {
type = PASS_AO;
}
/* Shadow pass. */
else if (strcmp(bake_type, "SHADOW") == 0) {
/* Bake as combined pass, together with marking the object as a shadow catcher. */
type = PASS_SHADOW_CATCHER;
film->set_use_approximate_shadow_catcher(true);
use_direct_light = true;
use_indirect_light = true;
include_albedo = true;
integrator->set_use_diffuse(true);
integrator->set_use_glossy(true);
integrator->set_use_transmission(true);
integrator->set_use_emission(true);
}
/* Combined pass. */
else if (strcmp(bake_type, "COMBINED") == 0) {
type = PASS_COMBINED;
film->set_use_approximate_shadow_catcher(true);
use_direct_light = (bake_filter & BL::BakeSettings::pass_filter_DIRECT) != 0;
use_indirect_light = (bake_filter & BL::BakeSettings::pass_filter_INDIRECT) != 0;
@@ -683,17 +700,23 @@ 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;
Object *bake_object = nullptr;
if (!session->progress.get_cancel()) {
foreach (Object *ob, scene->objects) {
if (ob->name == b_object.name()) {
object_found = true;
bake_object = ob;
break;
}
}
}
if (object_found && !session->progress.get_cancel()) {
/* For the shadow pass, temporarily mark the object as a shadow catcher. */
const bool was_shadow_catcher = (bake_object) ? bake_object->get_is_shadow_catcher() : false;
if (bake_object && bake_type == "SHADOW") {
bake_object->set_is_shadow_catcher(true);
}
if (bake_object && !session->progress.get_cancel()) {
/* Get session and buffer parameters. */
const SessionParams session_params = BlenderSync::get_session_params(
b_engine, b_userpref, b_scene, background);
@@ -714,10 +737,15 @@ void BlenderSession::bake(BL::Depsgraph &b_depsgraph_,
}
/* Perform bake. Check cancel to avoid crash with incomplete scene data. */
if (object_found && !session->progress.get_cancel()) {
if (bake_object && !session->progress.get_cancel()) {
session->start();
session->wait();
}
/* Restore object state. */
if (bake_object) {
bake_object->set_is_shadow_catcher(was_shadow_catcher);
}
}
void BlenderSession::synchronize(BL::Depsgraph &b_depsgraph_)

View File

@@ -8,6 +8,7 @@
#include "kernel/film/adaptive_sampling.h"
#include "kernel/film/light_passes.h"
#include "kernel/integrator/intersect_closest.h"
#include "kernel/integrator/path_state.h"
#include "kernel/sample/pattern.h"
@@ -327,6 +328,8 @@ ccl_device bool integrator_init_from_bake(KernelGlobals kg,
else {
integrator_path_init_sorted(kg, state, DEVICE_KERNEL_INTEGRATOR_SHADE_SURFACE, shader_index);
}
integrator_split_shadow_catcher(kg, state, &isect, render_buffer);
}
return true;