当前位置:   article > 正文

UnityShader切线空间学习_unity c#世界转切线工具

unity c#世界转切线工具

此处连接凹凸感文章现在需要应用在立体的形状上
1、可视化切线空间

  1. /// <summary>
  2. /// 可视化切线空间
  3. /// </summary>
  4. public class TangentSpaceVisualizer : MonoBehaviour
  5. {
  6. public float offset = 0.01f;
  7. public float scale = 0.1f;
  8. private void OnDrawGizmos()
  9. {
  10. MeshFilter meshFilter = GetComponent<MeshFilter>();
  11. if (meshFilter != null)
  12. {
  13. //meshFilter.mesh 这个只是创建一个网格副本,游戏结束不会对原有网格造成影响
  14. Mesh mesh = meshFilter.sharedMesh;
  15. if(mesh)
  16. ShowTangentSpace(mesh);
  17. }
  18. }
  19. private void ShowTangentSpace(Mesh mesh)
  20. {
  21. Vector3[] vertices = mesh.vertices;
  22. Vector3[] normals = mesh.normals;
  23. Vector4[] tangents = mesh.tangents;
  24. for (int i = 0; i < vertices.Length; i++)
  25. {
  26. ShowTangentSpace(
  27. transform.TransformPoint(vertices[i]),
  28. transform.TransformDirection(normals[i]),
  29. transform.TransformDirection(tangents[i]),
  30. tangents[i].w
  31. );
  32. }
  33. }
  34. private void ShowTangentSpace(Vector3 vertex, Vector3 normal, Vector3 tangent, float binormalSign)
  35. {
  36. vertex += normal * offset;
  37. Gizmos.color = Color.green;
  38. Gizmos.DrawLine(vertex, vertex + normal * scale);
  39. //切线
  40. Gizmos.color = Color.red;
  41. Gizmos.DrawLine(vertex, vertex + tangent * scale);
  42. //次法线
  43. Vector3 binormal = Vector3.Cross(normal, tangent) * binormalSign;
  44. Gizmos.color = Color.blue;
  45. Gizmos.DrawLine(vertex, vertex + binormal * scale);
  46. }
  47. }

代码中的切线w中存储这次切线的方向, 因为cross得到2个向量,根据切线向量第4个分量中

可视化切线空间

2、Shader中处理切线空间
切线空间中:由法线N, 切线(T)和次法线(B)组成,俗称TBN这里有一个知识点:从A空间转换到B空间的矩阵是什么?A空间的基向量在B空间的表示按列排序,就成了A到B空间的转换矩阵

  1. float4 tangent : TANGENT; //切线 //定义
  2. 将切线转换到世界空间
  3. i.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
  4. 初始化法线代码中
  5. float3 tangentSpaceNormal = BlendNormals(mainNormal, detailNormal);
  6. 下方替换了所以注释了
  7. // tangentSpaceNormal = tangentSpaceNormal.xzy;
  8. float3 binormal = cross(i.normal, i.tangent.xyz) * i.tangent.w; 计算次法线
  9. 从将法线从切线空间转换到世界方向
  10. i.normal = normalize(
  11. tangentSpaceNormal.x * i.tangent +
  12. tangentSpaceNormal.y * binormal +
  13. tangentSpaceNormal.z * i.normal);
  14. 在计算次法线时候(如果需要翻转),可以利用unity_WorldTransformParams
  15. float3 binormal = cross(i.normal, i.tangent.xyz) * (i.tangent.w * unity_WorldTransformParams.w);
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/649761
推荐阅读
相关标签
  

闽ICP备14008679号