In case it's not clear. What I am saying is for actual uv unwraps use mikktspace. For a UV parametrization such as planar, cylindrical, spherical etc. use an analytical tangent evaluation at pixel level.
On Thu, Oct 11, 2012 at 12:44 PM, Morten Mikkelsen <mikkels...@gmail.com>wrote: > For aniso lighting computing tangents at vertex level is a total dead-end. > Not the way to go. > You want to compute the tangents at pixel level from the underlying > parametrization chosen. > It's the best way to significantly reduce the impact of the inherent > singularities which completely destroy the per vertex averaged tangent. > > > > > > > > On Thu, Oct 11, 2012 at 4:43 AM, Brecht Van Lommel < > brechtvanlom...@pandora.be> wrote: > >> It's working the same as blender internal currently, but I agree it >> should be improved. This anisotropic BSDF node will get a tangent >> input socket, and probably the geometry node should always output the >> tangent from generated coordinates. I'm not sure yet where the tangent >> from UV maps fits, if that should be its own node or maybe becomes >> part of an existing one. >> >> Brecht. >> >> On Thu, Oct 11, 2012 at 2:10 AM, Daniel Salazar - 3Developer.com >> <zan...@gmail.com> wrote: >> > This works really nice but I'm not sure about the implementation. >> > Making the assumption that if there's an UV that should be used to >> > generate tangents is no good. If I have UVs for a diffuse map how can >> > I make the aniso bsdf not use them for tangents but keep using the >> > default method? Also if I have multiple UV layers how can I pick the >> > one I want to be used as tangent source? >> > >> > cheers >> > >> > Daniel Salazar >> > patazstudio.com >> > >> > >> > On Wed, Oct 10, 2012 at 7:02 AM, Brecht Van Lommel >> > <brechtvanlom...@pandora.be> wrote: >> >> Revision: 51258 >> >> >> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=51258 >> >> Author: blendix >> >> Date: 2012-10-10 13:02:20 +0000 (Wed, 10 Oct 2012) >> >> Log Message: >> >> ----------- >> >> Cycles: Anisotropic BSDF enabled, with tangents now computed from the >> active UV map. >> >> It's using the Ward BSDF currently, which has some energy loss so >> might be a bit >> >> dark. More/better BSDF options can be implemented later. >> >> >> >> Patch by Mike Farnsworth, some modifications by me. Currently it's not >> possible yet >> >> to set a custom tangent, that will follow as part of per-bsdf normals >> patch. >> >> >> >> Modified Paths: >> >> -------------- >> >> trunk/blender/intern/cycles/blender/blender_mesh.cpp >> >> trunk/blender/intern/cycles/blender/blender_shader.cpp >> >> trunk/blender/intern/cycles/kernel/kernel_montecarlo.h >> >> trunk/blender/intern/cycles/kernel/kernel_shader.h >> >> trunk/blender/intern/cycles/kernel/kernel_types.h >> >> trunk/blender/intern/cycles/kernel/svm/bsdf_ward.h >> >> trunk/blender/intern/cycles/kernel/svm/svm.h >> >> trunk/blender/intern/cycles/kernel/svm/svm_closure.h >> >> trunk/blender/intern/cycles/kernel/svm/svm_geometry.h >> >> trunk/blender/intern/cycles/kernel/svm/svm_types.h >> >> trunk/blender/intern/cycles/render/attribute.cpp >> >> trunk/blender/intern/cycles/render/graph.cpp >> >> trunk/blender/intern/cycles/render/graph.h >> >> trunk/blender/intern/cycles/render/nodes.cpp >> >> trunk/blender/intern/cycles/render/nodes.h >> >> trunk/blender/intern/cycles/util/util_types.h >> >> trunk/blender/source/blender/blenkernel/intern/node.c >> >> trunk/blender/source/blender/makesrna/intern/rna_nodetree_types.h >> >> trunk/blender/source/blender/nodes/CMakeLists.txt >> >> trunk/blender/source/blender/nodes/NOD_shader.h >> >> >> trunk/blender/source/blender/nodes/shader/nodes/node_shader_bsdf_anisotropic.c >> >> >> >> Modified: trunk/blender/intern/cycles/blender/blender_mesh.cpp >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/blender/blender_mesh.cpp >> 2012-10-10 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/blender/blender_mesh.cpp >> 2012-10-10 13:02:20 UTC (rev 51258) >> >> @@ -33,6 +33,28 @@ >> >> >> >> /* Find/Add */ >> >> >> >> +static float3 tri_calc_tangent(float3 v0, float3 v1, float3 v2, >> float3 tx0, float3 tx1, float3 tx2) >> >> +{ >> >> + float3 duv1 = tx2 - tx0; >> >> + float3 duv2 = tx2 - tx1; >> >> + float3 dp1 = v2 - v0; >> >> + float3 dp2 = v2 - v1; >> >> + float det = duv1[0] * duv2[1] - duv1[1] * duv2[0]; >> >> + >> >> + if(det != 0.0f) { >> >> + return normalize(dp1 * duv2[1] - dp2 * duv1[1]); >> >> + } >> >> + else { >> >> + /* give back a sane default, using a valid edge as a >> fallback */ >> >> + float3 edge = v1 - v0; >> >> + >> >> + if(len(edge) == 0.0f) >> >> + edge = v2 - v0; >> >> + >> >> + return normalize(edge); >> >> + } >> >> +} >> >> + >> >> static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, >> const vector<uint>& used_shaders) >> >> { >> >> /* create vertices */ >> >> @@ -157,6 +179,67 @@ >> >> } >> >> } >> >> } >> >> + >> >> + /* create texcoord-based tangent attributes */ >> >> + { >> >> + BL::Mesh::tessface_uv_textures_iterator l; >> >> + >> >> + for(b_mesh.tessface_uv_textures.begin(l); l != >> b_mesh.tessface_uv_textures.end(); ++l) { >> >> + AttributeStandard std = (l->active_render())? >> ATTR_STD_TANGENT: ATTR_STD_NONE; >> >> + >> >> + if(!mesh->need_attribute(scene, std)) >> >> + continue; >> >> + >> >> + Attribute *attr = mesh->attributes.add(std, >> ustring("Tangent")); >> >> + >> >> + /* compute average tangents per vertex */ >> >> + float3 *tangents = attr->data_float3(); >> >> + memset(tangents, 0, >> sizeof(float3)*mesh->verts.size()); >> >> + >> >> + BL::MeshTextureFaceLayer::data_iterator t; >> >> + >> >> + size_t fi = 0; /* face index */ >> >> + b_mesh.tessfaces.begin(f); >> >> + for(l->data.begin(t); t != l->data.end() && f >> != b_mesh.tessfaces.end(); ++t, ++fi, ++f) { >> >> + int4 vi = get_int4(f->vertices_raw()); >> >> + >> >> + float3 tx0 = get_float3(t->uv1()); >> >> + float3 tx1 = get_float3(t->uv2()); >> >> + float3 tx2 = get_float3(t->uv3()); >> >> + >> >> + float3 v0 = mesh->verts[vi[0]]; >> >> + float3 v1 = mesh->verts[vi[1]]; >> >> + float3 v2 = mesh->verts[vi[2]]; >> >> + >> >> + /* calculate tangent for the triangle; >> >> + * get vertex positions, and find >> change in position with respect >> >> + * to the texture coords in the first >> texture coord dimension */ >> >> + float3 tangent0 = tri_calc_tangent(v0, >> v1, v2, tx0, tx1, tx2); >> >> + >> >> + if(nverts[fi] == 4) { >> >> + /* quad tangent */ >> >> + float3 tx3 = >> get_float3(t->uv4()); >> >> + float3 v3 = mesh->verts[vi[3]]; >> >> + float3 tangent1 = >> tri_calc_tangent(v0, v2, v3, tx0, tx2, tx3); >> >> + >> >> + tangents[vi[0]] += >> 0.5f*(tangent0 + tangent1); >> >> + tangents[vi[1]] += tangent0; >> >> + tangents[vi[2]] += >> 0.5f*(tangent0 + tangent1); >> >> + tangents[vi[3]] += tangent1; >> >> + } >> >> + else { >> >> + /* triangle tangent */ >> >> + tangents[vi[0]] += tangent0; >> >> + tangents[vi[1]] += tangent0; >> >> + tangents[vi[2]] += tangent0; >> >> + } >> >> + } >> >> + >> >> + /* normalize tangent vectors */ >> >> + for(int i = 0; i < mesh->verts.size(); i++) >> >> + tangents[i] = normalize(tangents[i]); >> >> + } >> >> + } >> >> } >> >> >> >> static void create_subd_mesh(Mesh *mesh, BL::Mesh b_mesh, PointerRNA >> *cmesh, const vector<uint>& used_shaders) >> >> >> >> Modified: trunk/blender/intern/cycles/blender/blender_shader.cpp >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/blender/blender_shader.cpp >> 2012-10-10 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/blender/blender_shader.cpp >> 2012-10-10 13:02:20 UTC (rev 51258) >> >> @@ -315,6 +315,10 @@ >> >> node = new HoldoutNode(); >> >> break; >> >> } >> >> + case BL::ShaderNode::type_BSDF_ANISOTROPIC: { >> >> + node = new WardBsdfNode(); >> >> + break; >> >> + } >> >> case BL::ShaderNode::type_BSDF_DIFFUSE: { >> >> node = new DiffuseBsdfNode(); >> >> break; >> >> >> >> Modified: trunk/blender/intern/cycles/kernel/kernel_montecarlo.h >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/kernel/kernel_montecarlo.h >> 2012-10-10 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/kernel/kernel_montecarlo.h >> 2012-10-10 13:02:20 UTC (rev 51258) >> >> @@ -72,7 +72,7 @@ >> >> >> >> __device void make_orthonormals_tangent(const float3 N, const float3 >> T, float3 *a, float3 *b) >> >> { >> >> - *b = cross(N, T); >> >> + *b = normalize(cross(N, T)); >> >> *a = cross(*b, N); >> >> } >> >> >> >> >> >> Modified: trunk/blender/intern/cycles/kernel/kernel_shader.h >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/kernel/kernel_shader.h 2012-10-10 >> 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/kernel/kernel_shader.h 2012-10-10 >> 13:02:20 UTC (rev 51258) >> >> @@ -93,6 +93,7 @@ >> >> #ifdef __DPDU__ >> >> /* dPdu/dPdv */ >> >> triangle_dPdudv(kg, &sd->dPdu, &sd->dPdv, sd->prim); >> >> + sd->T = make_float3(0.0f, 0.0f, 0.0f); >> >> #endif >> >> >> >> #ifdef __INSTANCING__ >> >> @@ -117,6 +118,7 @@ >> >> #ifdef __DPDU__ >> >> sd->dPdu = -sd->dPdu; >> >> sd->dPdv = -sd->dPdv; >> >> + sd->T = make_float3(0.0f, 0.0f, 0.0f); >> >> #endif >> >> } >> >> >> >> @@ -208,6 +210,8 @@ >> >> } >> >> #endif >> >> } >> >> + >> >> + sd->T = make_float3(0.0f, 0.0f, 0.0f); >> >> #endif >> >> >> >> /* backfacing test */ >> >> @@ -293,6 +297,7 @@ >> >> /* dPdu/dPdv */ >> >> sd->dPdu = make_float3(0.0f, 0.0f, 0.0f); >> >> sd->dPdv = make_float3(0.0f, 0.0f, 0.0f); >> >> + sd->T = make_float3(0.0f, 0.0f, 0.0f); >> >> #endif >> >> >> >> #ifdef __RAY_DIFFERENTIALS__ >> >> >> >> Modified: trunk/blender/intern/cycles/kernel/kernel_types.h >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/kernel/kernel_types.h 2012-10-10 >> 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/kernel/kernel_types.h 2012-10-10 >> 13:02:20 UTC (rev 51258) >> >> @@ -447,6 +447,9 @@ >> >> /* differential of P w.r.t. parametric coordinates. note that >> dPdu is >> >> * not readily suitable as a tangent for shading on triangles. >> */ >> >> float3 dPdu, dPdv; >> >> + >> >> + /* tangent for shading */ >> >> + float3 T; >> >> #endif >> >> >> >> #ifdef __MULTI_CLOSURE__ >> >> >> >> Modified: trunk/blender/intern/cycles/kernel/svm/bsdf_ward.h >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/kernel/svm/bsdf_ward.h 2012-10-10 >> 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/kernel/svm/bsdf_ward.h 2012-10-10 >> 13:02:20 UTC (rev 51258) >> >> @@ -67,7 +67,7 @@ >> >> float m_ax = sc->data0; >> >> float m_ay = sc->data1; >> >> float3 m_N = sd->N; >> >> - float3 m_T = normalize(sd->dPdu); >> >> + float3 m_T = sd->T; >> >> >> >> float cosNO = dot(m_N, I); >> >> float cosNI = dot(m_N, omega_in); >> >> @@ -90,6 +90,7 @@ >> >> *pdf = exp_val / denom; >> >> return make_float3 (out, out, out); >> >> } >> >> + >> >> return make_float3 (0, 0, 0); >> >> } >> >> >> >> @@ -108,7 +109,7 @@ >> >> float m_ax = sc->data0; >> >> float m_ay = sc->data1; >> >> float3 m_N = sd->N; >> >> - float3 m_T = normalize(sd->dPdu); >> >> + float3 m_T = sd->T; >> >> >> >> float cosNO = dot(m_N, sd->I); >> >> if(cosNO > 0) { >> >> >> >> Modified: trunk/blender/intern/cycles/kernel/svm/svm.h >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/kernel/svm/svm.h 2012-10-10 >> 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/kernel/svm/svm.h 2012-10-10 >> 13:02:20 UTC (rev 51258) >> >> @@ -205,6 +205,14 @@ >> >> case NODE_CLOSURE_WEIGHT: >> >> svm_node_closure_weight(sd, stack, >> node.y); >> >> break; >> >> +#ifdef __DPDU__ >> >> + case NODE_CLOSURE_SET_TANGENT: >> >> + svm_node_closure_set_tangent(sd, >> node.y, node.z, node.w); >> >> + break; >> >> + case NODE_CLOSURE_TANGENT: >> >> + svm_node_closure_tangent(sd, stack, >> node.y); >> >> + break; >> >> +#endif >> >> case NODE_EMISSION_WEIGHT: >> >> svm_node_emission_weight(kg, sd, >> stack, node); >> >> break; >> >> @@ -261,14 +269,14 @@ >> >> svm_node_camera(kg, sd, stack, node.y, >> node.z, node.w); >> >> break; >> >> case NODE_GEOMETRY: >> >> - svm_node_geometry(sd, stack, node.y, >> node.z); >> >> + svm_node_geometry(kg, sd, stack, >> node.y, node.z); >> >> break; >> >> #ifdef __EXTRA_NODES__ >> >> case NODE_GEOMETRY_BUMP_DX: >> >> - svm_node_geometry_bump_dx(sd, stack, >> node.y, node.z); >> >> + svm_node_geometry_bump_dx(kg, sd, >> stack, node.y, node.z); >> >> break; >> >> case NODE_GEOMETRY_BUMP_DY: >> >> - svm_node_geometry_bump_dy(sd, stack, >> node.y, node.z); >> >> + svm_node_geometry_bump_dy(kg, sd, >> stack, node.y, node.z); >> >> break; >> >> case NODE_LIGHT_PATH: >> >> svm_node_light_path(sd, stack, node.y, >> node.z, path_flag); >> >> >> >> Modified: trunk/blender/intern/cycles/kernel/svm/svm_closure.h >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/kernel/svm/svm_closure.h >> 2012-10-10 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/kernel/svm/svm_closure.h >> 2012-10-10 13:02:20 UTC (rev 51258) >> >> @@ -179,7 +179,7 @@ >> >> float roughness_u = param1; >> >> float roughness_v = param2; >> >> >> >> - bsdf_ward_setup(sd, sc, normalize(sd->dPdu), >> roughness_u, roughness_v); >> >> + bsdf_ward_setup(sd, sc, normalize(sd->T), >> roughness_u, roughness_v); >> >> break; >> >> } >> >> #endif >> >> @@ -425,5 +425,24 @@ >> >> #endif >> >> } >> >> >> >> +#ifdef __DPDU__ >> >> +__device_inline void svm_node_closure_store_tangent(ShaderData *sd, >> float3 tangent) >> >> +{ >> >> + sd->T = normalize(tangent); >> >> +} >> >> + >> >> +__device void svm_node_closure_set_tangent(ShaderData *sd, uint x, >> uint y, uint z) >> >> +{ >> >> + float3 tangent = make_float3(__int_as_float(x), >> __int_as_float(y), __int_as_float(z)); >> >> + svm_node_closure_store_tangent(sd, tangent); >> >> +} >> >> + >> >> +__device void svm_node_closure_tangent(ShaderData *sd, float *stack, >> uint tangent_offset) >> >> +{ >> >> + float3 tangent = stack_load_float3(stack, tangent_offset); >> >> + svm_node_closure_store_tangent(sd, tangent); >> >> +} >> >> +#endif >> >> + >> >> CCL_NAMESPACE_END >> >> >> >> >> >> Modified: trunk/blender/intern/cycles/kernel/svm/svm_geometry.h >> >> =================================================================== >> >> --- trunk/blender/intern/cycles/kernel/svm/svm_geometry.h >> 2012-10-10 12:54:36 UTC (rev 51257) >> >> +++ trunk/blender/intern/cycles/kernel/svm/svm_geometry.h >> 2012-10-10 13:02:20 UTC (rev 51258) >> >> @@ -20,7 +20,7 @@ >> >> >> >> /* Geometry Node */ >> >> >> >> -__device void svm_node_geometry(ShaderData *sd, float *stack, uint >> type, uint out_offset) >> >> +__device void svm_node_geometry(KernelGlobals *kg, ShaderData *sd, >> float *stack, uint type, uint out_offset) >> >> { >> >> float3 data; >> >> >> >> @@ -28,7 +28,16 @@ >> >> case NODE_GEOM_P: data = sd->P; break; >> >> case NODE_GEOM_N: data = sd->N; break; >> >> #ifdef __DPDU__ >> >> - case NODE_GEOM_T: data = normalize(sd->dPdu); break; >> >> + case NODE_GEOM_T: { >> >> + int attr_offset = find_attribute(kg, sd, >> ATTR_STD_TANGENT); >> >> + >> >> + if(attr_offset == ATTR_STD_NOT_FOUND) >> >> + data = normalize(sd->dPdu); >> >> + else >> >> + data = triangle_attribute_float3(kg, >> sd, ATTR_ELEMENT_VERTEX, attr_offset, NULL, NULL); >> >> + >> >> + break; >> >> + } >> >> #endif >> >> case NODE_GEOM_I: data = sd->I; break; >> >> case NODE_GEOM_Ng: data = sd->Ng; break; >> >> @@ -40,7 +49,7 @@ >> >> stack_store_float3(stack, out_offset, data); >> >> } >> >> >> >> >> >> @@ Diff output truncated at 10240 characters. @@ >> >> _______________________________________________ >> >> Bf-blender-cvs mailing list >> >> bf-blender-...@blender.org >> >> http://lists.blender.org/mailman/listinfo/bf-blender-cvs >> > _______________________________________________ >> > Bf-committers mailing list >> > Bf-committers@blender.org >> > http://lists.blender.org/mailman/listinfo/bf-committers >> _______________________________________________ >> Bf-committers mailing list >> Bf-committers@blender.org >> http://lists.blender.org/mailman/listinfo/bf-committers >> > > _______________________________________________ Bf-committers mailing list Bf-committers@blender.org http://lists.blender.org/mailman/listinfo/bf-committers