[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [51258] trunk/blender: Cycles: Anisotropic BSDF enabled, with tangents now computed from the active UV map.

Morten Mikkelsen mikkelsen7 at gmail.com
Thu Oct 11 21:44:06 CEST 2012


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 <
brechtvanlommel at 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
> <zanqdo at 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
> > <brechtvanlommel at 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-cvs at blender.org
> >> http://lists.blender.org/mailman/listinfo/bf-blender-cvs
> > _______________________________________________
> > Bf-committers mailing list
> > Bf-committers at blender.org
> > http://lists.blender.org/mailman/listinfo/bf-committers
> _______________________________________________
> Bf-committers mailing list
> Bf-committers at blender.org
> http://lists.blender.org/mailman/listinfo/bf-committers
>


More information about the Bf-committers mailing list