diff options
author | Brecht Van Lommel <brecht@blender.org> | 2021-12-20 08:00:38 +0300 |
---|---|---|
committer | Brecht Van Lommel <brecht@blender.org> | 2021-12-20 16:14:43 +0300 |
commit | edb3ab061730aa1369298eb510331e6536c82a04 (patch) | |
tree | 86687965448956790b62c51bdbb0efb554068a4c /intern/cycles | |
parent | e2e7f7ea529e352e34c6bed8e9cbf1fa0975f3e8 (diff) |
Fix T94251: Cycles wrong pointcloud normal for instanced objects
Refactor code a bit also so we need to do fewer matrix transforms for shader
data setup of points and curves.
Diffstat (limited to 'intern/cycles')
-rw-r--r-- | intern/cycles/kernel/geom/curve_intersect.h | 16 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/point_intersect.h | 9 | ||||
-rw-r--r-- | intern/cycles/kernel/geom/shader_data.h | 56 |
3 files changed, 39 insertions, 42 deletions
diff --git a/intern/cycles/kernel/geom/curve_intersect.h b/intern/cycles/kernel/geom/curve_intersect.h index 99f4a452d6d..2081eeb3eac 100644 --- a/intern/cycles/kernel/geom/curve_intersect.h +++ b/intern/cycles/kernel/geom/curve_intersect.h @@ -727,8 +727,6 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg, const float cosine = safe_sqrtf(1.0f - sine * sine); sd->N = normalize(sine * bitangent - cosine * normalize(cross(tangent, bitangent))); - sd->Ng = -D; - # if 0 /* This approximates the position and geometric normal of a thick curve too, * but gives too many issues with wrong self intersections. */ @@ -744,25 +742,27 @@ ccl_device_inline void curve_shader_setup(KernelGlobals kg, /* NOTE: It is possible that P will be the same as P_inside (precision issues, or very small * radius). In this case use the view direction to approximate the normal. */ const float3 P_inside = float4_to_float3(catmull_rom_basis_eval(P_curve, sd->u)); - const float3 Ng = (!isequal_float3(P, P_inside)) ? normalize(P - P_inside) : -sd->I; + const float3 N = (!isequal_float3(P, P_inside)) ? normalize(P - P_inside) : -sd->I; - sd->N = Ng; - sd->Ng = Ng; + sd->N = N; sd->v = 0.0f; } # ifdef __DPDU__ /* dPdu/dPdv */ sd->dPdu = dPdu; - sd->dPdv = cross(dPdu, sd->Ng); # endif + /* Convert to world space. */ if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { - const Transform tfm = object_get_transform(kg, sd); - P = transform_point(&tfm, P); + object_position_transform_auto(kg, sd, &P); + object_normal_transform_auto(kg, sd, &sd->N); + object_dir_transform_auto(kg, sd, &sd->dPdu); } sd->P = P; + sd->Ng = (sd->type & PRIMITIVE_CURVE_RIBBON) ? sd->I : sd->N; + sd->dPdv = cross(sd->dPdu, sd->Ng); sd->shader = kernel_tex_fetch(__curves, sd->prim).shader_id; } diff --git a/intern/cycles/kernel/geom/point_intersect.h b/intern/cycles/kernel/geom/point_intersect.h index b4d96ade7be..757c8b81efa 100644 --- a/intern/cycles/kernel/geom/point_intersect.h +++ b/intern/cycles/kernel/geom/point_intersect.h @@ -104,17 +104,12 @@ ccl_device_inline void point_shader_setup(KernelGlobals kg, sd->v = isect->v; # endif - /* Computer point center for normal. */ + /* Compute point center for normal. */ float3 center = float4_to_float3((isect->type & PRIMITIVE_MOTION) ? motion_point(kg, sd->object, sd->prim, sd->time) : kernel_tex_fetch(__points, sd->prim)); - if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { - const Transform tfm = object_get_transform(kg, sd); - -# ifndef __KERNEL_OPTIX__ - center = transform_point(&tfm, center); -# endif + object_position_transform_auto(kg, sd, ¢er); } /* Normal */ diff --git a/intern/cycles/kernel/geom/shader_data.h b/intern/cycles/kernel/geom/shader_data.h index 569393c306c..f5055d8b285 100644 --- a/intern/cycles/kernel/geom/shader_data.h +++ b/intern/cycles/kernel/geom/shader_data.h @@ -82,43 +82,45 @@ ccl_device_inline void shader_setup_from_ray(KernelGlobals kg, } else #endif - if (sd->type == PRIMITIVE_TRIANGLE) { - /* static triangle */ - float3 Ng = triangle_normal(kg, sd); - sd->shader = kernel_tex_fetch(__tri_shader, sd->prim); + { + if (sd->type == PRIMITIVE_TRIANGLE) { + /* static triangle */ + float3 Ng = triangle_normal(kg, sd); + sd->shader = kernel_tex_fetch(__tri_shader, sd->prim); - /* vectors */ - sd->P = triangle_refine(kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim); - sd->Ng = Ng; - sd->N = Ng; + /* vectors */ + sd->P = triangle_refine(kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim); + sd->Ng = Ng; + sd->N = Ng; - /* smooth normal */ - if (sd->shader & SHADER_SMOOTH_NORMAL) - sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v); + /* smooth normal */ + if (sd->shader & SHADER_SMOOTH_NORMAL) + sd->N = triangle_smooth_normal(kg, Ng, sd->prim, sd->u, sd->v); #ifdef __DPDU__ - /* dPdu/dPdv */ - triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv); + /* dPdu/dPdv */ + triangle_dPdudv(kg, sd->prim, &sd->dPdu, &sd->dPdv); #endif - } - else { - /* motion triangle */ - motion_triangle_shader_setup( - kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim, false); - } - - sd->flag |= kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags; + } + else { + /* motion triangle */ + motion_triangle_shader_setup( + kg, sd, ray->P, ray->D, isect->t, isect->object, isect->prim, false); + } - if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { - /* instance transform */ - object_normal_transform_auto(kg, sd, &sd->N); - object_normal_transform_auto(kg, sd, &sd->Ng); + if (!(sd->object_flag & SD_OBJECT_TRANSFORM_APPLIED)) { + /* instance transform */ + object_normal_transform_auto(kg, sd, &sd->N); + object_normal_transform_auto(kg, sd, &sd->Ng); #ifdef __DPDU__ - object_dir_transform_auto(kg, sd, &sd->dPdu); - object_dir_transform_auto(kg, sd, &sd->dPdv); + object_dir_transform_auto(kg, sd, &sd->dPdu); + object_dir_transform_auto(kg, sd, &sd->dPdv); #endif + } } + sd->flag = kernel_tex_fetch(__shaders, (sd->shader & SHADER_MASK)).flags; + /* backfacing test */ bool backfacing = (dot(sd->Ng, sd->I) < 0.0f); |