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 <[email protected]> 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 > [email protected] > http://lists.blender.org/mailman/listinfo/bf-blender-cvs _______________________________________________ Bf-committers mailing list [email protected] http://lists.blender.org/mailman/listinfo/bf-committers
