Fix: Cycles incorrect rendering of certain negative strength lights

This fixes an issue where lights that make use of constant negative strength
emission shaders would render with the absolute of their strength.

Pull Request: https://projects.blender.org/blender/blender/pulls/118541
This commit is contained in:
Alaska
2024-02-22 19:06:22 +01:00
committed by Brecht Van Lommel
parent f0bbb0266a
commit 56bfd56735
2 changed files with 8 additions and 5 deletions

View File

@@ -108,7 +108,9 @@ LightTreeEmitter::LightTreeEmitter(Scene *scene,
/* TODO: need a better way to handle this when textures are used. */
float area = triangle_area(vertices[0], vertices[1], vertices[2]);
measure.energy = area * average(shader->emission_estimate);
/* Use absolute value of emission_estimate so lights with negative strength are properly
* supported in the light tree. */
measure.energy = area * average(fabs(shader->emission_estimate));
/* NOTE: the original implementation used the bounding box centroid, but triangle centroid
* seems to work fine */
@@ -220,7 +222,7 @@ LightTreeEmitter::LightTreeEmitter(Scene *scene,
/* Use absolute value of energy so lights with negative strength are properly supported in the
* light tree. */
measure.energy = fabsf(average(strength));
measure.energy = average(fabs(strength));
light_set_membership = lamp->get_light_set_membership();
}

View File

@@ -264,7 +264,7 @@ void Shader::estimate_emission()
}
ShaderInput *surf = graph->output()->input("Surface");
emission_estimate = fabs(output_estimate_emission(surf->link, emission_is_constant));
emission_estimate = output_estimate_emission(surf->link, emission_is_constant);
if (is_zero(emission_estimate)) {
emission_sampling = EMISSION_SAMPLING_NONE;
@@ -274,8 +274,9 @@ void Shader::estimate_emission()
* using a lot of memory in the light tree and potentially wasting samples
* where indirect light samples are sufficient.
* Possible optimization: estimate front and back emission separately. */
emission_sampling = (reduce_max(emission_estimate) > 0.5f) ? EMISSION_SAMPLING_FRONT_BACK :
EMISSION_SAMPLING_NONE;
emission_sampling = (reduce_max(fabs(emission_estimate)) > 0.5f) ?
EMISSION_SAMPLING_FRONT_BACK :
EMISSION_SAMPLING_NONE;
}
else {
emission_sampling = emission_sampling_method;