title: Flat shading in LibGDX
body: <p>I am currently working on a simple game and I would like to my terrain to be flat shaded. My terrain currently looks like the following:
  <img src="https://i.imgur.com/Yb7mum7.png" alt="my terrain"></p>
  
  <p>As you can see the colours blend toghether depending on the vertice colours.  </p>
  
  <p>I would love for my end product to resemble the following:
  <img src="https://answers.unity3d.com/storage/temp/20259-lowpolylook.png" alt="Goal"></p>
  
  <p>So I was wondering how can I achieve this? What are the steps to go from gouraud shading to flat shading?</p>
  
  <p>Here is how I go about creating the vertices I give to my mesh:</p>
  
  <pre><code>public TerrainChunk() {
      buildHeightmap();
      buildIndices();
      buildVertices();
      calcNormals(indices, vertices);
  
  }   
  
  public void buildHeightmap() {...}
  
  private void buildIndices() {
      int idx = 0;
      short pitch = (short) (width + 1);
      short i1 = 0;
      short i2 = 1;
      short i3 = (short) (1 + pitch);
      short i4 = pitch;
  
      short row = 0;
  
      for (int z = 0; z &lt; height; z++) {
          for (int x = 0; x &lt; width; x++) {
              indices[idx++] = i1;
              indices[idx++] = i2;
              indices[idx++] = i3;
  
              indices[idx++] = i3;
              indices[idx++] = i4;
              indices[idx++] = i1;
  
              i1++;
              i2++;
              i3++;
              i4++;
          }
  
          row += pitch;
          i1 = row;
          i2 = (short) (row + 1);
          i3 = (short) (i2 + pitch);
          i4 = (short) (row + pitch);
      }
  }
  
  public void buildVertices() {
      int heightPitch = height + 1;
      int widthPitch = width + 1;
      int idx = 0;
  
      for (int x = 0; x &lt; widthPitch; x++) {
          for (int z = 0; z &lt; heightPitch; z++) {
  
              // POSITION
              vertices[idx++] = scale * x;
              vertices[idx++] = (float)Math.pow(1 + chunkDepths[x][z], strength));
              vertices[idx++] = scale * z;
  
              // NORMAL, skip these for now
              idx += 3;
  
              // COLOR
              vertices[idx++] = getColor(;
  
              // TEXTURE
              vertices[idx++] = (x / (float) width);
              vertices[idx++] = (z / (float) height);
  
          }
      }
  }
  
  /*
   * Calculates the normals
   */
  private void calcNormals(short[] indices, float[] verts) {
  
      for (int i = 0; i &lt; indices.length; i += 3) {
          int i1 = getPositionStart(indices[i]);
          int i2 = getPositionStart(indices[i + 1]);
          int i3 = getPositionStart(indices[i + 2]);
  
          // p1
          float x1 = verts[i1];
          float y1 = verts[i1 + 1];
          float z1 = verts[i1 + 2];
  
          // p2
          float x2 = verts[i2];
          float y2 = verts[i2 + 1];
          float z2 = verts[i2 + 2];
  
          // p3
          float x3 = verts[i3];
          float y3 = verts[i3 + 1];
          float z3 = verts[i3 + 2];
  
          // u = p3 - p1
          float ux = x3 - x1;
          float uy = y3 - y1;
          float uz = z3 - z1;
  
          // v = p2 - p1
          float vx = x2 - x1;
          float vy = y2 - y1;
          float vz = z2 - z1;
  
          // n = cross(v, u)
          float nx = ((vy * uz) - (vz * uy));
          float ny = ((vz * ux) - (vx * uz));
          float nz = ((vx * uy) - (vy * ux));
  
          // normalize(n)
          float num2 = ((nx * nx) + (ny * ny)) + (nz * nz);
          float num = 1f / (float) Math.sqrt(num2);
          nx *= num;
          ny *= num;
          nz *= num;
  
          addNormal(indices[i], verts, nx,ny, nz);
          addNormal(indices[i + 1], verts, nx, ny, nz);
          addNormal(indices[i + 2], verts, nx, ny, nz);
      }
  
      for (int i = 0; i &lt; (verts.length / VERTEX_SIZE); i++) {
          normalizeNormal(i, verts);
      }
  }
  
  // Adds the provided value to the normal
  private void addNormal(int vertIndex, float[] verts, float x, float y,
          float z) {
  
      int i = getNormalStart(vertIndex);
  
      float rx = (float) ((x * Math.cos(180)) - (y * Math.sin(180)));
      float ry = (float) ((x * Math.sin(180)) + (y * Math.cos(180)));
      x = rx;
      y = ry;
      verts[i] += x;
      verts[i + 1] += y;
      verts[i + 2] += z;
  }
  
  /*
   * Normalizes normals
   */
  private void normalizeNormal(int vertIndex, float[] verts) {
  
      int i = getNormalStart(vertIndex);
  
      float x = verts[i];
      float y = verts[i+1];
      float z = verts[i+2];
  
      float num2 = ((x * x) + (z * z)) + (y * y);
      float num = (float) Math.sqrt(num2);
      x *= num;
      y *= num;
      z *= num;
  
      verts[i] = x;
      verts[i + 1] = y;
      verts[i + 2] = z;
  }
  
  
  // Gets the index of the first float of a normal for a specific vertex
  private int getNormalStart(int vertIndex) {
      return vertIndex * VERTEX_SIZE + 3;
  }
  
  // Gets the index of the first float of a specific vertex
  private int getPositionStart(int vertIndex) {
      return vertIndex * VERTEX_SIZE;
  }
  </code></pre>