Search code examples
javaopengllwjgl

Calculate normals for icosphere?


So I am using LWJGL 3 to make a game and I am currently trying to generate a icosphere. I currently have a very basic icosphere without any splitting and my lighting looks off and some parts of the model are completely black. My understanding is that you want your normals coming out from the origin (0, 0, 0 which is the center of the sphere). Here is how I am generating my normal's currently. My lighting currently works perfectly with other models loaded in using a OBJ loader so I am pretty sure it is not my lighting code but the way I generate the normals.

Normals calculation:

    normalsArray = new float[verticesArray.length];

    for (int i = 0; i <= normalsArray.length / 3; i++) {
        float x = verticesArray[i];
        float y = verticesArray[1 * i];
        float z = verticesArray[2 * i];

        Vector3f normal = new Vector3f(x, y, z);
        normal.normalize();
        float length = normal.length();

        normalsArray[i] = normal.x / length;
        normalsArray[1 * i] = normal.y / length;
        normalsArray[2 * i] = normal.z / length;
    }

And here is a picture of my current result: Result


Solution

  • Your array indexing doesn't make the slightest sense:

        float x = verticesArray[i];
        float y = verticesArray[1 * i];
        float z = verticesArray[2 * i];
    

    since 1*i will be i, x will be equal to y, and you have the same issue when writing to the normalsArray.

    Now it is totally unclear how your data is laid out in memory. The most intuitive way would be that verticesArray contains just the (x,y,z) triple per vertex, so the indices should be

         float x = verticesArray[3*i+0];
         float y = verticesArray[3*i+1];
         float z = verticesArray[3*i+2];
    

    but you might use another layout.