diff --git a/demo/main.cpp b/demo/main.cpp
index 324c1acd48f86e1ca3ba71df0177f0c48aaf7cc2..a1f1eacb83bc1c0e69091f2d7ce523d1b4b26a60 100644
--- a/demo/main.cpp
+++ b/demo/main.cpp
@@ -117,6 +117,23 @@ int main(int argc, char* argv[]) {
 		ecs.addComponent<fggl::gfx::MeshToken>(entity, token);
 	}
 
+	for (int i=0; i<nSlopes; i++) {
+		// create an entity
+		auto entity = ecs.createEntity();
+
+		// set the position
+		auto result = ecs.addComponent<fggl::math::Transform>(entity);
+		result->origin( glm::vec3( -1.0f, 0.0f, i * -1.0f) );
+		result->euler( glm::vec3( 0.0f, -HALF_PI, 0.0f) );
+
+		// in a supprise to no one it's a triangle
+		auto mesh = fggl::data::make_slope();
+		auto token = meshRenderer.upload(mesh);
+		token.pipeline = shaderNormals;
+		ecs.addComponent<fggl::gfx::MeshToken>(entity, token);
+	}
+
+
 	float time = 0.0f;
 	float dt = 16.0f;
 	while( !win.closeRequested() ) {
@@ -145,11 +162,11 @@ int main(int argc, char* argv[]) {
 		meshRenderer.render(win, ecs, 16.0f);
 
 		// render using normals shader
-		/*for ( auto renderable : renderables ) {
+		for ( auto renderable : renderables ) {
 			auto token = ecs.getComponent<fggl::gfx::MeshToken>(renderable);
 			token->pipeline = shaderNormals;
 		}
-		meshRenderer.render(win, ecs, 16.0f);*/
+		meshRenderer.render(win, ecs, 16.0f);
 
 		debug.draw();
 		win.swap();
diff --git a/fggl/data/procedural.cpp b/fggl/data/procedural.cpp
index 35c26de2b53ad6e1150cb3a15a1a4bb420143b3d..0c832137143bb24e58055aa17d8869f53cb06f57 100644
--- a/fggl/data/procedural.cpp
+++ b/fggl/data/procedural.cpp
@@ -1,6 +1,8 @@
 
 #include "procedural.hpp"
 #include "model.hpp"
+
+#include <iostream>
 #include <glm/geometric.hpp>
 
 using namespace fggl::data;
@@ -25,10 +27,39 @@ static void computeNormals( fggl::data::Mesh& mesh, const int* idx, const int* c
 		auto& v2 = mesh.vertex( colIdx[ idx[i + 1] ] );
 		auto& v3 = mesh.vertex( colIdx[ idx[i + 2] ] );
 
-		v1.normal += calcSurfaceNormal( v1.posititon, v2.posititon, v3.posititon );
-		v2.normal += calcSurfaceNormal( v2.posititon, v3.posititon, v1.posititon );
-		v3.normal += calcSurfaceNormal( v3.posititon, v1.posititon, v2.posititon );
+		const glm::vec3 normal = calcSurfaceNormal( v1.posititon, v2.posititon, v3.posititon );
+//		v2.normal += calcSurfaceNormal( v2.posititon, v3.posititon, v1.posititon );
 //		v3.normal += calcSurfaceNormal( v3.posititon, v1.posititon, v2.posititon );
+		v1.normal = normal;
+		v2.normal = normal;
+		v3.normal = normal;
+
+	}
+
+	// each vertex should currently be the sum of every triangle it's part of
+	// so we need to normalize them
+	for (auto& vertex : mesh.vertexList() ) {
+		vertex.normal = glm::normalize( vertex.normal );
+	}
+}
+
+static void computeNormalsDirect( fggl::data::Mesh& mesh, const int* colIdx, int points) {
+
+	// we're assuming all the normals are zero...
+	for (auto& vertex : mesh.vertexList() ) {
+		vertex.normal = glm::vec3(0.0f);
+	}
+
+	// each vertex normal should be the sum of the triangles it's part of.
+	for (int i=0; i<points; i += 3) {
+		auto& v1 = mesh.vertex( colIdx[ i ] );
+		auto& v2 = mesh.vertex( colIdx[ i + 1 ] );
+		auto& v3 = mesh.vertex( colIdx[ i + 2 ] );
+
+		const glm::vec3 normal = calcSurfaceNormal( v1.posititon, v2.posititon, v3.posititon );
+		v1.normal = normal;
+		v2.normal = normal;
+		v3.normal = normal;
 	}
 
 	// each vertex should currently be the sum of every triangle it's part of
@@ -151,22 +182,21 @@ fggl::data::Mesh fggl::data::make_cube() {
 		7, 5, 6,
 	};
 
+	int nIdx = sizeof(idx) / sizeof(int);
+	int colIdx[nIdx];
+
+	// generate mesh
 	fggl::data::Mesh mesh;
-	int colIdx[8];
-	for ( int i=0; i < 8; ++i ) {
+	for (int i=0; i<nIdx; i++) {
 		Vertex vert{};
-		vert.posititon = pos[i];
+		vert.posititon = pos[ idx[i] ];
 		vert.normal = glm::vec3(0.0f, 0.0f, 0.0f);
 		vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f);
 		colIdx[ i ] = mesh.pushVertex( vert );
-	}
-
-	int tris = 0;
-	for ( auto i : idx ){
 		mesh.pushIndex( colIdx[i] );
-		tris++;
 	}
-	computeNormals( mesh, idx, colIdx, tris );
+
+	computeNormalsDirect( mesh, colIdx, nIdx );
 
 	return mesh;
 }
@@ -197,23 +227,21 @@ fggl::data::Mesh fggl::data::make_slope() {
 		7, 5, 6,
 	};
 
+	int nIdx = sizeof(idx) / sizeof(int);
+	int colIdx[nIdx];
+
+	// generate mesh
 	fggl::data::Mesh mesh;
-	int colIdx[8];
-	for ( int i=0; i < 8; ++i ) {
+	for (int i=0; i<nIdx; i++) {
 		Vertex vert{};
-		vert.posititon = pos[i];
+		vert.posititon = pos[ idx[i] ];
 		vert.normal = glm::vec3(0.0f, 0.0f, 0.0f);
 		vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f);
 		colIdx[ i ] = mesh.pushVertex( vert );
-	}
-
-	int tris = 0;
-	for ( auto i : idx ){
 		mesh.pushIndex( colIdx[i] );
-		tris++;
 	}
-	computeNormals( mesh, idx, colIdx, tris );
 
+	computeNormalsDirect( mesh, colIdx, nIdx );
 	return mesh;
 }
 
@@ -245,23 +273,21 @@ fggl::data::Mesh fggl::data::make_ditch() {
 		7, 5, 6,
 	};
 
+	int nIdx = sizeof(idx) / sizeof(int);
+	int colIdx[nIdx];
+
+	// generate mesh
 	fggl::data::Mesh mesh;
-	int colIdx[8];
-	for ( int i=0; i < 8; ++i ) {
+	for (int i=0; i<nIdx; i++) {
 		Vertex vert{};
-		vert.posititon = pos[i];
+		vert.posititon = pos[ idx[i] ];
 		vert.normal = glm::vec3(0.0f, 0.0f, 0.0f);
 		vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f);
 		colIdx[ i ] = mesh.pushVertex( vert );
-	}
-
-	int tris = 0;
-	for ( auto i : idx ){
 		mesh.pushIndex( colIdx[i] );
-		tris++;
 	}
-	computeNormals( mesh, idx, colIdx, tris );
 
+	computeNormalsDirect( mesh, colIdx, nIdx );
 	return mesh;
 }
 
@@ -288,23 +314,21 @@ fggl::data::Mesh fggl::data::make_point() {
 		7, 5, 6,
 	};
 
+	int nIdx = sizeof(idx) / sizeof(int);
+	int colIdx[nIdx];
+
+	// generate mesh
 	fggl::data::Mesh mesh;
-	int colIdx[8];
-	for ( int i=0; i < 8; ++i ) {
+	for (int i=0; i<nIdx; i++) {
 		Vertex vert{};
-		vert.posititon = pos[i];
+		vert.posititon = pos[ idx[i] ];
 		vert.normal = glm::vec3(0.0f, 0.0f, 0.0f);
 		vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f);
 		colIdx[ i ] = mesh.pushVertex( vert );
-	}
-
-	int tris = 0;
-	for ( auto i : idx ){
 		mesh.pushIndex( colIdx[i] );
-		tris++;
 	}
-	computeNormals( mesh, idx, colIdx, tris );
 
+	computeNormalsDirect( mesh, colIdx, nIdx );
 	return mesh;
 }