Unity之如何打印模型法线
工具代码如下:
1 using UnityEngine; 2 using UnityEngine.Serialization; 3 #if UNITY_EDITOR 4 using Modules.UI; 5 using UnityEditor; 6 #endif 7 8 public class DrawNormals : MonoBehaviour 9 { 10 #if UNITY_EDITOR 11 Mesh m_Mesh; 12 13 //[SerializeField] 14 //private bool _displayWireframe = false; 15 [SerializeField] private NormalsDrawData m_VertexNormals = new NormalsDrawData(new Color32(0, 0, 255, 127), true); 16 [SerializeField] private NormalsDrawData m_VertexTangents = new NormalsDrawData(new Color32(0, 255, 0, 127), true); 17 [SerializeField] private NormalsDrawData m_VertexBinormals = new NormalsDrawData(new Color32(255, 0, 0, 127), true); 18 19 [System.Serializable] 20 private class NormalsDrawData 21 { 22 [SerializeField] protected DrawType m_Draw = DrawType.Selected; 23 24 protected enum DrawType 25 { 26 Never, 27 Selected, 28 Always 29 } 30 31 [SerializeField] protected float m_Length = 0.3f; 32 [SerializeField] protected Color m_NormalColor; 33 Color m_BaseColor = new Color32(255, 133, 0, 255); 34 [SerializeField] protected float m_BaseSize = 0.0125f; 35 36 37 public NormalsDrawData(Color mNormalColor, bool draw) 38 { 39 m_NormalColor = mNormalColor; 40 m_Draw = draw ? DrawType.Selected : DrawType.Never; 41 } 42 43 public bool CanDraw(bool isSelected) 44 { 45 return (m_Draw == DrawType.Always) || (m_Draw == DrawType.Selected && isSelected); 46 } 47 48 public void Draw(Vector3 from, Vector3 direction) 49 { 50 /* 51 Gizmos.color = m_BaseColor; 52 Gizmos.DrawWireSphere(from, m_BaseSize); 53 */ 54 55 Gizmos.color = m_NormalColor; 56 Gizmos.DrawRay(from, direction * m_Length); 57 } 58 } 59 60 void OnDrawGizmosSelected() 61 { 62 //EditorUtility.SetSelectedWireframeHidden(GetComponent<Renderer>(), !_displayWireframe); 63 OnDrawNormals(true); 64 } 65 66 void OnDrawGizmos() 67 { 68 if (!Selection.Contains(this)) 69 OnDrawNormals(false); 70 } 71 72 private void OnDrawNormals(bool isSelected) 73 { 74 if (m_Mesh == null) 75 { 76 MeshFilter meshFilter = GetComponent<MeshFilter>(); 77 if (meshFilter != null) 78 m_Mesh = meshFilter.sharedMesh; 79 } 80 81 if (m_Mesh == null) 82 { 83 SkinnedMeshRenderer smr = GetComponent<SkinnedMeshRenderer>(); 84 if (smr != null) 85 m_Mesh = smr.sharedMesh; 86 } 87 88 if (m_Mesh == null) 89 { 90 return; 91 } 92 93 //Draw Vertex Normals 94 95 Vector3[] vertices = m_Mesh.vertices; 96 Vector3[] normals = m_Mesh.normals; 97 Vector4[] tangents = m_Mesh.tangents; 98 99 100 for (int i = 0; i < vertices.Length; i++) 101 { 102 Vector3 view_world = Vector3.Normalize(Camera.current.transform.forward - vertices[i]); 103 Vector3 normal_world = Vector3.Normalize(transform.TransformVector(normals[i])); 104 float NdotV = Vector3.Dot(normal_world, view_world); 105 if (NdotV < 0.0) 106 { 107 Vector3 tangent_world = 108 transform.TransformVector(new Vector3(tangents[i].x, tangents[i].y, tangents[i].z)); 109 if (m_VertexNormals.CanDraw(isSelected)) 110 m_VertexNormals.Draw(transform.TransformPoint(vertices[i]), normal_world); 111 if (m_VertexTangents.CanDraw(isSelected)) 112 m_VertexTangents.Draw(transform.TransformPoint(vertices[i]), tangent_world); 113 Vector3 binormal_world = Vector3.Normalize(Vector3.Cross(normal_world, tangent_world) * tangents[i].w); 114 if (m_VertexBinormals.CanDraw(isSelected)) 115 m_VertexBinormals.Draw(transform.TransformPoint(vertices[i]), binormal_world); 116 } 117 } 118 } 119 #endif 120 }
效果如下: