From 561cf26c2f92a11c8f2fa2da79bcaebf2647fc76 Mon Sep 17 00:00:00 2001 From: Brecht Van Lommel Date: Sat, 11 May 2013 09:31:58 +0000 Subject: Fix #35306: cycles normal mapping not working with flat shading. --- intern/cycles/blender/blender_mesh.cpp | 13 ++++++++++--- intern/cycles/kernel/osl/osl_services.cpp | 6 +++++- intern/cycles/kernel/osl/osl_services.h | 1 + intern/cycles/kernel/shaders/node_normal_map.osl | 17 +++++++++++------ intern/cycles/kernel/svm/svm_tex_coord.h | 7 ++++++- 5 files changed, 33 insertions(+), 11 deletions(-) (limited to 'intern/cycles') diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp index 7f02bc68e6b..d628fa04f92 100644 --- a/intern/cycles/blender/blender_mesh.cpp +++ b/intern/cycles/blender/blender_mesh.cpp @@ -106,9 +106,16 @@ static void mikk_get_normal(const SMikkTSpaceContext *context, float N[3], const { MikkUserData *userdata = (MikkUserData*)context->m_pUserData; BL::MeshTessFace f = userdata->mesh.tessfaces[face_num]; - int4 vi = get_int4(f.vertices_raw()); - BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]]; - float3 vN = get_float3(v.normal()); + float3 vN; + + if(f.use_smooth()) { + int4 vi = get_int4(f.vertices_raw()); + BL::MeshVertex v = userdata->mesh.vertices[vi[vert_num]]; + vN = get_float3(v.normal()); + } + else { + vN = get_float3(f.normal()); + } N[0] = vN.x; N[1] = vN.y; diff --git a/intern/cycles/kernel/osl/osl_services.cpp b/intern/cycles/kernel/osl/osl_services.cpp index 7974665900f..a8d4bc3d855 100644 --- a/intern/cycles/kernel/osl/osl_services.cpp +++ b/intern/cycles/kernel/osl/osl_services.cpp @@ -76,6 +76,7 @@ ustring OSLRenderServices::u_geom_numpolyvertices("geom:numpolyvertices"); ustring OSLRenderServices::u_geom_trianglevertices("geom:trianglevertices"); ustring OSLRenderServices::u_geom_polyvertices("geom:polyvertices"); ustring OSLRenderServices::u_geom_name("geom:name"); +ustring OSLRenderServices::u_is_smooth("geom:is_smooth"); #ifdef __HAIR__ ustring OSLRenderServices::u_is_curve("geom:is_curve"); ustring OSLRenderServices::u_curve_thickness("geom:curve_thickness"); @@ -626,7 +627,10 @@ bool OSLRenderServices::get_object_standard_attribute(KernelGlobals *kg, ShaderD ustring object_name = kg->osl->object_names[sd->object]; return set_attribute_string(object_name, type, derivatives, val); } - + else if (name == u_is_smooth) { + float f = ((sd->shader & SHADER_SMOOTH_NORMAL) != 0); + return set_attribute_float(f, type, derivatives, val); + } #ifdef __HAIR__ /* Hair Attributes */ else if (name == u_is_curve) { diff --git a/intern/cycles/kernel/osl/osl_services.h b/intern/cycles/kernel/osl/osl_services.h index 50c50b9952c..5043852846d 100644 --- a/intern/cycles/kernel/osl/osl_services.h +++ b/intern/cycles/kernel/osl/osl_services.h @@ -130,6 +130,7 @@ public: static ustring u_geom_trianglevertices; static ustring u_geom_polyvertices; static ustring u_geom_name; + static ustring u_is_smooth; static ustring u_is_curve; static ustring u_curve_thickness; static ustring u_curve_tangent_normal; diff --git a/intern/cycles/kernel/shaders/node_normal_map.osl b/intern/cycles/kernel/shaders/node_normal_map.osl index 4428a12ac41..c3d6e7bd391 100644 --- a/intern/cycles/kernel/shaders/node_normal_map.osl +++ b/intern/cycles/kernel/shaders/node_normal_map.osl @@ -33,15 +33,17 @@ shader node_normal_map( vector tangent; vector ninterp; float tangent_sign; + float is_smooth; + + getattribute("geom:is_smooth", is_smooth); + if (!is_smooth) + ninterp = Ng; // get _unnormalized_ interpolated normal and tangent - if (!getattribute(attr_name, tangent) || - !getattribute(attr_sign_name, tangent_sign) || - !getattribute("geom:N", ninterp)) + if (getattribute(attr_name, tangent) && + getattribute(attr_sign_name, tangent_sign) && + (!is_smooth || getattribute("geom:N", ninterp))) { - Normal = normal(0, 0, 0); - } - else { // apply normal map vector B = tangent_sign * cross(ninterp, tangent); Normal = normalize(mcolor[0] * tangent + mcolor[1] * B + mcolor[2] * ninterp); @@ -49,6 +51,9 @@ shader node_normal_map( // transform to world space Normal = normalize(transform("object", "world", Normal)); } + else { + Normal = normal(0, 0, 0); + } } else if (space == "Object") Normal = normalize(transform("object", "world", vector(mcolor))); diff --git a/intern/cycles/kernel/svm/svm_tex_coord.h b/intern/cycles/kernel/svm/svm_tex_coord.h index d793169261d..c4cf0d95793 100644 --- a/intern/cycles/kernel/svm/svm_tex_coord.h +++ b/intern/cycles/kernel/svm/svm_tex_coord.h @@ -261,7 +261,12 @@ __device void svm_node_normal_map(KernelGlobals *kg, ShaderData *sd, float *stac /* get _unnormalized_ interpolated normal and tangent */ float3 tangent = primitive_attribute_float3(kg, sd, attr_elem, attr_offset, NULL, NULL); float sign = primitive_attribute_float(kg, sd, attr_sign_elem, attr_sign_offset, NULL, NULL); - float3 normal = primitive_attribute_float3(kg, sd, attr_normal_elem, attr_normal_offset, NULL, NULL); + float3 normal; + + if(sd->shader & SHADER_SMOOTH_NORMAL) + normal = primitive_attribute_float3(kg, sd, attr_normal_elem, attr_normal_offset, NULL, NULL); + else + normal = sd->N; /* apply normal map */ float3 B = sign * cross(normal, tangent); -- cgit v1.2.3