public void RecalculateTangents() { if (HasUVs() == false) { UVs.Resize(Vertices.Count); } //partialy stolen from http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/ int verticesNum = Vertices.Count; int indiciesNum = TriangleIndicies.Count; int[] counts = new int[verticesNum]; Tangents.Clear(); Tangents.Capacity = verticesNum; for (int i = 0; i < verticesNum; i++) { counts[i] = 0; Tangents.Add(Vector3.Zero); } for (int i = 0; i <= indiciesNum - 3; i += 3) { int ai = TriangleIndicies[i]; int bi = TriangleIndicies[i + 1]; int ci = TriangleIndicies[i + 2]; if (ai < verticesNum && bi < verticesNum && ci < verticesNum) { Vector3 av = Vertices[ai]; Vector3 deltaPos1 = Vertices[bi] - av; Vector3 deltaPos2 = Vertices[ci] - av; Vector2 auv = UVs[ai]; Vector2 deltaUV1 = UVs[bi] - auv; Vector2 deltaUV2 = UVs[ci] - auv; float r = 1.0f / (deltaUV1.X * deltaUV2.Y - deltaUV1.Y * deltaUV2.X); Vector3 t = (deltaPos1 * deltaUV2.Y - deltaPos2 * deltaUV1.Y) * r; Tangents[ai] += t; Tangents[bi] += t; Tangents[ci] += t; counts[ai]++; counts[bi]++; counts[ci]++; } } for (int i = 0; i < verticesNum; i++) { Tangents[i] /= counts[i]; } }