[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.

Daniel Salazar - 3Developer.com zanqdo at gmail.com
Thu Oct 11 02:10:28 CEST 2012


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


More information about the Bf-committers mailing list