Cycles: Account for negative scale when using one-sided light tree sampling

Differential Revision: https://developer.blender.org/D16952
This commit is contained in:
Lukas Stockner 2023-01-10 02:44:12 +01:00
parent c41601becd
commit 39c30f6983
Notes: blender-bot 2023-02-14 10:21:15 +01:00
Referenced by issue #89037, Cycles backfacing node doesn't work on objects with negative scale
2 changed files with 19 additions and 11 deletions

View File

@ -223,11 +223,16 @@ ccl_device bool compute_emitter_centroid_and_dir(KernelGlobals kg,
triangle_world_space_vertices(kg, object, prim_id, -1.0f, vertices);
centroid = (vertices[0] + vertices[1] + vertices[2]) / 3.0f;
if (kemitter->emission_sampling == EMISSION_SAMPLING_FRONT) {
const bool is_front_only = (kemitter->emission_sampling == EMISSION_SAMPLING_FRONT);
const bool is_back_only = (kemitter->emission_sampling == EMISSION_SAMPLING_BACK);
if (is_front_only || is_back_only) {
dir = safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0]));
}
else if (kemitter->emission_sampling == EMISSION_SAMPLING_BACK) {
dir = -safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0]));
if (is_back_only) {
dir = -dir;
}
if (kernel_data_fetch(object_flag, object) & SD_OBJECT_NEGATIVE_SCALE) {
dir = -dir;
}
}
else {
/* Double-sided: any vector in the plane. */

View File

@ -94,14 +94,17 @@ LightTreePrimitive::LightTreePrimitive(Scene *scene, int prim_id, int object_id)
* seems to work fine */
centroid = (vertices[0] + vertices[1] + vertices[2]) / 3.0f;
if (shader->emission_sampling == EMISSION_SAMPLING_FRONT) {
/* Front only. */
const bool is_front_only = (shader->emission_sampling == EMISSION_SAMPLING_FRONT);
const bool is_back_only = (shader->emission_sampling == EMISSION_SAMPLING_BACK);
if (is_front_only || is_back_only) {
/* One-sided. */
bcone.axis = safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0]));
bcone.theta_o = 0;
}
else if (shader->emission_sampling == EMISSION_SAMPLING_BACK) {
/* Back only. */
bcone.axis = -safe_normalize(cross(vertices[1] - vertices[0], vertices[2] - vertices[0]));
if (is_back_only) {
bcone.axis = -bcone.axis;
}
if (transform_negative_scale(object->get_tfm())) {
bcone.axis = -bcone.axis;
}
bcone.theta_o = 0;
}
else {