private void GenerateTerrainNormals(VertexPositionNormalTangentBinormalTexture[] vertices, int[] indices) { for (int i = 0; i < indices.Length; i += 3) { Vector3 v1 = vertices[indices[i]].Position; Vector3 v2 = vertices[indices[i + 1]].Position; Vector3 v3 = vertices[indices[i + 2]].Position; Vector3 vu = v3 - v1; Vector3 vt = v2 - v1; Vector3 normal = Vector3.Cross(vu, vt); normal.Normalize(); vertices[indices[i]].Normal += normal; vertices[indices[i + 1]].Normal += normal; vertices[indices[i + 2]].Normal += normal; } for (int i = 0; i < vertices.Length; i++) { vertices[i].Normal.Normalize(); } }
public void GenerateTerrainTangentBinormal(VertexPositionNormalTangentBinormalTexture[] vertices, int[] indices) { for (int i = 0; i < vertexCountZ; i++) { for (int j = 0; j < vertexCountX; j++) { int vertexIndex = j + i * vertexCountX; Vector3 v1 = vertices[vertexIndex].Position; if (j < vertexCountX - 1) { Vector3 v2 = vertices[vertexIndex + 1].Position; vertices[vertexIndex].Tangent = (v2 - v1); } else { Vector3 v2 = vertices[vertexIndex - 1].Position; vertices[vertexIndex].Tangent = (v1 - v2); } vertices[vertexIndex].Tangent.Normalize(); vertices[vertexIndex].Binormal = Vector3.Cross(vertices[vertexIndex].Tangent, vertices[vertexIndex].Normal); } } }
/** * Generate terrain mesh vertices and indices * The vertex is currently VertexPositionNormalTangentBinormalTexture */ private VertexPositionNormalTangentBinormalTexture[] GenerateTerrainVertices(int[] terrainIndices) { float TerrainWidth = (vertexCountX - 1) * blockScale; float TerrainDepth = (vertexCountZ - 1) * blockScale; // Texture coordinates float tu = 0; float tv = 0; float tuDerivative = 1.0f / (vertexCountX - 1); float tvDerivative = 1.0f / (vertexCountZ - 1); int vertexCount = 0; VertexPositionNormalTangentBinormalTexture[] vertices = new VertexPositionNormalTangentBinormalTexture[vertexCountX * vertexCountZ]; // Set vertices position and texture coordinate for (float i = 0; i <= TerrainDepth; i += blockScale) { tu = 0.0f; for (float j = 0; j <= TerrainWidth; j += blockScale) { vertices[vertexCount].Position = new Vector3(j, heightMap[vertexCount].R * heightScale, i); vertices[vertexCount].TextureCoordinate = new Vector2(tu, tv); tu += tuDerivative; vertexCount++; } tv += tvDerivative; } // Generate vertice's normal, tangent and binormal GenerateTerrainNormals(vertices, terrainIndices); GenerateTerrainTangentBinormal(vertices, terrainIndices); return vertices; }