Lighting problems

Hello everyone!

Im trying to make smooth lighting on my 3d terrain. But result is bad (watch screenshots). Im calculating verticles from the heightmap and normals from the verticles.
How can I fix this? I just want to make a sun :slight_smile:


my code:


public class NGINE4 {
	int w = 1280;
	int h = 720;
	double map[][];
	int Size = 500;
	Texture floorTex;
	Texture grassTex;
	List<Triangle> triangles= new ArrayList<Triangle>();
	OBJLoader objl = new OBJLoader();
	Obj grass = new Obj();

	public static void main(String[] args) throws Exception {
		NGINE4 ng = new NGINE4();
		ng.start();
	}

	void initContext() throws Exception {
		Camera.create();
		Camera.moveSpeed = 0.1f;
		Display.setDisplayMode(new DisplayMode(w, h));
		Display.setFullscreen(false);
		Display.create();
		glViewport(0, 0, w, h);
		Mouse.setGrabbed(true);

		floorTex = TextureLoader.getTexture("JPG", ResourceLoader.getResourceAsStream("res/FloorTex.jpg"));
		grassTex = TextureLoader.getTexture("JPG", ResourceLoader.getResourceAsStream("res/GrassTex.jpg"));

		Random rand = new Random();
		NoiseHeightMap nsh = new NoiseHeightMap(Size+1, rand.nextInt(10000000));
		map = nsh.getHeightmap();
		grass = objl.loadModel(new File("res/Grass_01.obj"));
	}

	double myRandom(double min, double max) {
		Random r = new Random();
		return (r.nextInt((int) ((max - min) * 10 + 1)) + min * 10) / 10.0;
	}
	public Vector3f Cross(Vector3f v1, Vector3f v2)
	   {
	      Vector3f result = new Vector3f(0,0,0);
	      result.x = (v1.y * v2.z) - (v1.z * v2.y);
	      result.y = (v1.z * v2.x) - (v1.x * v2.z);
	      result.z = (v1.x * v2.y) - (v1.y * v2.x);
	      return result;
	   }
	
	   public Vector3f Normalize(Vector3f v1)
	   {
	       float length = v1.x * v1.x + v1.y * v1.y + v1.z * v1.z;
	       length = (float) Math.sqrt(length);
	       v1.x /= length; v1.x /= length; v1.x /= length;
		return v1;
	   }
	void renderLoop() {
		glEnable(GL_LIGHTING);
		
		glEnable(GL_TEXTURE_2D);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
		glEnable(GL_BLEND);
		//glEnable(GL_DEPTH_TEST);
        glTexParameterf(GL_TEXTURE_2D, EXTTextureFilterAnisotropic.GL_TEXTURE_MAX_ANISOTROPY_EXT, 16.0f);
        
        glShadeModel(GL_SMOOTH);
        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClearDepth(1.0f);
        glEnable(GL_DEPTH_TEST);
        glDepthFunc(GL_LEQUAL);
        glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
        float lightAmbient[] = {0.5f, 0.5f, 0.5f, 1.0f};  // Ambient Light Values
        float lightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f};      // Diffuse Light Values
        float lightPosition[] = {0.0f, 15.0f, 2.0f, 1.0f}; // Light Position

        ByteBuffer temp = ByteBuffer.allocateDirect(16);
        temp.order(ByteOrder.nativeOrder());
        glLight(GL_LIGHT1, GL_AMBIENT, (FloatBuffer) temp.asFloatBuffer().put(lightAmbient).flip());              // Setup The Ambient Light
        glLight(GL_LIGHT1, GL_DIFFUSE, (FloatBuffer) temp.asFloatBuffer().put(lightDiffuse).flip());              // Setup The Diffuse Light
        glLight(GL_LIGHT1, GL_POSITION, (FloatBuffer) temp.asFloatBuffer().put(lightPosition).flip());         // Position The Light
        glEnable(GL_LIGHT1);    

		long time = 0;
		int frames = 0;

		int heightmapExaggeration = 20;
		// Random rand = new Random();

		
		
		for (int x = 0; x < Size; x++) {
			for (int y = 0; y < Size; y++) {
				Vector3f v0 = new Vector3f(x * 0.25f,(float) (map[x][y] * heightmapExaggeration),y * 0.25f);
				Vector3f v1 = new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y] * heightmapExaggeration),y * 0.25f);
				Vector3f v2 = new Vector3f(x * 0.25f,(float) (map[x][y + 1] * heightmapExaggeration),(y + 1) * 0.25f);

				Vector3f normal = Normalize(Cross(new Vector3f(v2.x-v0.x,v2.y-v0.y,v2.z-v0.z), new Vector3f(v1.x-v0.x,v1.y-v0.y,v1.z-v0.z)));
				
					Triangle t = new Triangle(
							new Vector3f(x * 0.25f,(float) (map[x][y] * heightmapExaggeration),y * 0.25f),
							new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y] * heightmapExaggeration),y * 0.25f),
							new Vector3f(x * 0.25f,(float) (map[x][y + 1] * heightmapExaggeration),(y + 1) * 0.25f),
							normal, normal, normal,
							new Vector2f(0,1),
							new Vector2f(1,1),
							new Vector2f(0,0),
							1,1,1,
							1,1,1,
							1,1,1);
					triangles.add(t);

					Vector3f sv0 = new Vector3f(x * 0.25f,(float) (map[x][y] * heightmapExaggeration),y * 0.25f);
					Vector3f sv1 = new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y] * heightmapExaggeration),y * 0.25f);
					Vector3f sv2 = new Vector3f(x * 0.25f,(float) (map[x][y + 1] * heightmapExaggeration),(y + 1) * 0.25f);

					Vector3f snormal = Normalize(Cross(new Vector3f(sv2.x-sv0.x,sv2.y-sv0.y,sv2.z-sv0.z), new Vector3f(sv1.x-sv0.x,sv1.y-sv0.y,sv1.z-sv0.z)));
					
					Triangle d = new Triangle(
							new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y + 1] * heightmapExaggeration),(y + 1) * 0.25f),
							new Vector3f((x + 1) * 0.25f,(float) (map[x + 1][y] * heightmapExaggeration),y * 0.25f),
							new Vector3f(x * 0.25f,(float) (map[x][y + 1] * heightmapExaggeration),(y + 1) * 0.25f),
							snormal, snormal, snormal,
							new Vector2f(1,0),
							new Vector2f(1,1),
							new Vector2f(0,0),
							1,1,1,
							1,1,1,
							1,1,1);
					triangles.add(d);


			}
		}
		int vertex_size = 3; // X, Y, Z,
		int color_size = 3; // R, G, B,
		int texture_size = 2; // U, V

		FloatBuffer vBuffer = BufferUtils.createFloatBuffer(9 * triangles.size());
		FloatBuffer cBuffer = BufferUtils.createFloatBuffer(9 * triangles.size());
		FloatBuffer tBuffer = BufferUtils.createFloatBuffer(9 * triangles.size());
		FloatBuffer nBuffer = BufferUtils.createFloatBuffer(9 * triangles.size());
		
		for (int x = 0; x < triangles.size()-10; x++) {
				Triangle c = triangles.get(x);
				cBuffer.put(c.v0r).put(c.v0g).put(c.v0b);
				cBuffer.put(c.v1r).put(c.v1g).put(c.v1b);
				cBuffer.put(c.v2r).put(c.v2g).put(c.v2b);

				vBuffer.put(c.v0.x).put(c.v0.y).put(c.v0.z);
				vBuffer.put(c.v1.x).put(c.v1.y).put(c.v1.z);
				vBuffer.put(c.v2.x).put(c.v2.y).put(c.v2.z);

				tBuffer.put(new float[] { c.t0.x, c.t0.y, }); // Texture Coordinate
				tBuffer.put(new float[] { c.t1.x, c.t1.y, }); // Texture Coordinate
				tBuffer.put(new float[] { c.t2.x, c.t2.y, }); // Texture Coordinate
				
				nBuffer.put(c.n0.x).put(c.n0.y).put(c.n0.z);
				nBuffer.put(c.n1.x).put(c.n1.y).put(c.n1.z);
				nBuffer.put(c.n2.x).put(c.n2.y).put(c.n2.z);
		}
		
		cBuffer.flip();
		vBuffer.flip();
		tBuffer.flip();
		nBuffer.flip();

		int vbo_vertex_handle = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
		glBufferData(GL_ARRAY_BUFFER, vBuffer, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		int vbo_color_handle = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
		glBufferData(GL_ARRAY_BUFFER, cBuffer, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		int vbo_tex_coord_handle = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coord_handle);
		glBufferData(GL_ARRAY_BUFFER, tBuffer, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);
		
		int vbo_normal_handle = glGenBuffers();
		glBindBuffer(GL_ARRAY_BUFFER, vbo_normal_handle);
		glBufferData(GL_ARRAY_BUFFER, nBuffer, GL_STATIC_DRAW);
		glBindBuffer(GL_ARRAY_BUFFER, 0);

		glBindBuffer(GL_ARRAY_BUFFER, vbo_vertex_handle);
		glVertexPointer(vertex_size, GL_FLOAT, 0, 0l);

		glBindBuffer(GL_ARRAY_BUFFER, vbo_color_handle);
		glColorPointer(color_size, GL_FLOAT, 0, 0l);

		glBindTexture(GL_TEXTURE_2D, floorTex.getTextureID());
		
		glBindBuffer(GL_ARRAY_BUFFER, vbo_tex_coord_handle);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glTexCoordPointer(texture_size, GL_FLOAT, 0, 0l);

		glBindBuffer(GL_ARRAY_BUFFER, vbo_normal_handle);
		glNormalPointer(GL_FLOAT, 0, 0l);
		
		glEnableClientState(GL_VERTEX_ARRAY);
		glEnableClientState(GL_COLOR_ARRAY);
		glEnableClientState(GL_TEXTURE_COORD_ARRAY);
		glEnableClientState(GL_NORMAL_ARRAY);

		while (!Display.isCloseRequested()) {

			preRender();
			render();

			Display.update();
			Display.sync(60 /* desired fps */);

			frames++;
			if ((System.currentTimeMillis() - time) >= 1000) {
				/*Ray r = getPickingRay();
				Vector3f j = new Vector3f(-1,1,0);
				Vector3f d = new Vector3f(1,1,0);
				Vector3f t = new Vector3f(-1,-11,0);*/
				Display.setTitle(" FPS: " + (int) ((frames * 1000) / (System.currentTimeMillis() - time))/*+ " " + RayTriangleIntersectionTest(r.Position, r.Direction,j,d,t)*/);

				time = System.currentTimeMillis();
				frames = 0;
			}
		}
		glDeleteBuffers(vbo_vertex_handle);
		glDeleteBuffers(vbo_color_handle);
		glDeleteBuffers(vbo_tex_coord_handle);
		glDeleteBuffers(vbo_normal_handle);

		floorTex.release();
		grassTex.release();

		glDisableClientState(GL_VERTEX_ARRAY);
		glDisableClientState(GL_COLOR_ARRAY);
		glDisableClientState(GL_TEXTURE_COORD_ARRAY_POINTER);
		glDisableClientState(GL_NORMAL_ARRAY);
		Display.destroy();
	}

	void preRender() {
		glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
		glMatrixMode(GL_PROJECTION);
		glLoadIdentity();
		GLU.gluPerspective(45.0f, ((float) w / (float) h), 0.1f, 100.0f); // fix na błąd z kamerą
		glMatrixMode(GL_MODELVIEW);
		glLoadIdentity();
	}

	void render() {
		Camera.acceptInput(0.3f);
		Camera.apply();
		glDrawArrays(GL_TRIANGLES, 0, ((Size * Size) * 2)*3 );
	}
	public FloatBuffer floatBuffer(float a, float b, float c, float d) {
		float[] data = new float[]{a,b,c,d};
    	FloatBuffer fb = BufferUtils.createFloatBuffer(data.length);
    	fb.put(data);
    	fb.flip();
    	return fb;
    }
	public void start() throws Exception {
		initContext();
		renderLoop();
	}
}

its hard to follow that much code, but you probably want to smooth the normals like:

im not sure thats the only problem though cos your images look like a lot of the terrain is not getting light at all?

Ok, I have to calculate smooth normals to fix the light. But how to calculate this normalsfrom my heightmap?