3
\$\begingroup\$

I am having trouble getting smooth lighting to work in Java Monkey Engine.

My terrain is voxel-based, with an iso-surface generated via Marching Cubes over the data field.

Up until now, I have been simply calculating the triangle-face normals, and using only those when creating the mesh for each chunk. This produces the faceted look typical of this approach.

Now, I am iterating over each triangle in the chunk, and adding the triangle-face-normal to each vertex normal in the triangle. Vertices are shared between triangles. As I understand it, this should smooth out the lighting, and reduce the faceted look. I am not seeing these results.

Here is a snippet which illustrates the vertex normal processing:

        for( UUID blockId : chunk.blockIds )
        {
            Block block = BlockStore.getInstance().getBlock( blockId );

            FastTable<Triangle> blockTris = block.getTris();
            if( blockTris == null )
                continue;

            for( Triangle tri : blockTris )
            {
                javax.vecmath.Vector3f triFaceNormal = (javax.vecmath.Vector3f)( tri.norm.clone() );

                tri.getVert0().norm.add( triFaceNormal );
                tri.getVert1().norm.add( triFaceNormal );
                tri.getVert2().norm.add( triFaceNormal );
            }

            for( Triangle tri : blockTris )
            {
                tri.getVert0().norm.normalize();
                tri.getVert1().norm.normalize();
                tri.getVert2().norm.normalize();
            }
        }

Then the blocks/triangles for this chunk are iterated over again, and the component values of all the vertex normals are added sequentially to the "normal buffer", which is fed into the mesh creation.

Here is what the mesh data looks like, using the JME ShowNormals material, which color-codes things according to normal direction. You can clearly see the facets:

enter image description here

And here is the code which builds the chunk mesh, after the buffers have been populated:

        chunkMesh.setBuffer( VertexBuffer.Type.Index, 1, BufferUtils.createIntBuffer( uberIntBuf ) );
        chunkMesh.setBuffer( VertexBuffer.Type.Position, 3, BufferUtils.createFloatBuffer( uberVertBuf ) );
        chunkMesh.setBuffer( VertexBuffer.Type.TexCoord, 2, BufferUtils.createFloatBuffer( texBuffer ) );
        chunkMesh.setBuffer( VertexBuffer.Type.Normal, 3, BufferUtils.createFloatBuffer( uberVertNormBuf ) );

        TangentBinormalGenerator.generate( chunkMesh );

        chunkMesh.updateBound();

You can see in this screenshot, that the individual triangles do have some blending, indicating that the summation of a vertex's surrounding triangle-face normals, into the vertex normal, is having some effect.

enter image description here

I'm not sure what I am doing wrong.

\$\endgroup\$
2
\$\begingroup\$

I have solved the problem. As it turns out, in my Marching Cubes polygonizer, I was inadvertently making copies of the vertex data, (objects), which were then being propagated through the rest of the processing pipeline.

Something I learned: If you know smooth shading is enabled, and you see sharp edges on anything but very acute angles, then your vertex data is not properly shared.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.