Fix T41147: Static BVH shading problem

Fix T41079: Solid black render of object with negative scale and smooth shading

In both cases the issue was caused by negative scaled objects with single mesh
users for which scale gets applied when using static BVH.

Since the on-fly normals calculation land normals for such cases weren't flipped
leading them to point to a wrong direction.

Added a special object flag for this, which is a bit of a bummer because now
we've got less bits for real useful things, but this is the only way to get
proper normals without adding more complexity in the on-fly calculations.
This commit is contained in:
Sergey Sharybin 2014-07-23 12:54:49 +06:00
parent 54109add65
commit 9fcaac5009
Notes: blender-bot 2023-02-14 12:01:57 +01:00
Referenced by issue #41219, Cycles Fresnel nodes - broken gradients on objects with negative scale (final render only, not viewport)
Referenced by issue #41147, Static BVH shading problem
Referenced by issue #41079, Solid black render of object with negative scale and smooth shading
4 changed files with 12 additions and 6 deletions

View File

@ -117,17 +117,20 @@ ccl_device_inline float3 triangle_refine_subsurface(KernelGlobals *kg, ShaderDat
}
/* normal on triangle */
ccl_device_inline float3 triangle_normal(KernelGlobals *kg, int prim)
ccl_device_inline float3 triangle_normal(KernelGlobals *kg, ShaderData *sd)
{
/* load triangle vertices */
float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, prim));
float3 tri_vindex = float4_to_float3(kernel_tex_fetch(__tri_vindex, sd->prim));
float3 v0 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.x)));
float3 v1 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.y)));
float3 v2 = float4_to_float3(kernel_tex_fetch(__tri_verts, __float_as_int(tri_vindex.z)));
/* return normal */
return normalize(cross(v1 - v0, v2 - v0));
if(sd->flag & SD_NEGATIVE_SCALE_APPLIED)
return normalize(cross(v2 - v0, v1 - v0));
else
return normalize(cross(v1 - v0, v2 - v0));
}
/* point and normal on triangle */

View File

@ -86,7 +86,7 @@ ccl_device void shader_setup_from_ray(KernelGlobals *kg, ShaderData *sd,
#endif
if(sd->type & PRIMITIVE_TRIANGLE) {
/* static triangle */
float3 Ng = triangle_normal(kg, sd->prim);
float3 Ng = triangle_normal(kg, sd);
sd->shader = __float_as_int(kernel_tex_fetch(__tri_shader, sd->prim));
/* vectors */
@ -165,7 +165,7 @@ ccl_device_inline void shader_setup_from_subsurface(KernelGlobals *kg, ShaderDat
/* fetch triangle data */
if(sd->type == PRIMITIVE_TRIANGLE) {
float3 Ng = triangle_normal(kg, sd->prim);
float3 Ng = triangle_normal(kg, sd);
sd->shader = __float_as_int(kernel_tex_fetch(__tri_shader, sd->prim));
/* static triangle */

View File

@ -592,7 +592,8 @@ enum ShaderDataFlag {
/* object flags */
SD_HOLDOUT_MASK = 524288, /* holdout for camera rays */
SD_OBJECT_MOTION = 1048576, /* has object motion blur */
SD_TRANSFORM_APPLIED = 2097152, /* vertices have transform applied */
SD_TRANSFORM_APPLIED = 2097152, /* vertices have transform applied */
SD_NEGATIVE_SCALE_APPLIED = 4194304, /* vertices have negative scale applied */
SD_OBJECT_FLAGS = (SD_HOLDOUT_MASK|SD_OBJECT_MOTION|SD_TRANSFORM_APPLIED)
};

View File

@ -449,6 +449,8 @@ void ObjectManager::apply_static_transforms(DeviceScene *dscene, Scene *scene, u
}
object_flag[i] |= SD_TRANSFORM_APPLIED;
if(object->mesh->transform_negative_scaled)
object_flag[i] |= SD_NEGATIVE_SCALE_APPLIED;
}
else
have_instancing = true;