Search code examples
javafxjavafx-2javafx-8normalsjavafx-3d

What is use of getNormals() method in TriangleMesh JavaFX


I am currently working of JavaFX 3D application and come across getNormals() method in TriangleMesh class.

As in TriangleMesh class is used to create user defined Java FX 3D obejct and in that
getPoints() is used to add Points
getFaces() is used to add Faces
getTexCoords() is used to manage Texture of 3D Object,
but I am not sure what is use of getNormals() method in TriangleMesh class.

In TriangleMesh class, we can set vertex format to VertexFormat.POINT_TEXCOORD and VertexFormat.POINT_NORMAL_TEXCOORD.
But if we set vertexFormat as "VertexFormat.POINT_NORMAL_TEXCOORD", then we need to add indices of normals into the Faces like below :
[ p0, n0, t0, p1, n1, t1, p3, n3, t3, // First triangle of a textured rectangle

p1, n1, t1, p2, n2, t2, p3, n3, t3 // Second triangle of a textured rectangle ]

as described in https://docs.oracle.com/javase/8/javafx/api/javafx/scene/shape/TriangleMesh.html

I didn't find any difference in 3D shape, if I used vertexFormat as POINT_TEXCOORD or POINT_NORMAL_TEXCOORD.

So what is the use of getNormals() method in TriangleMesh JavaFX?

Thanks in Advance..


Solution

  • Use of normals in computer graphics:

    The normal is often used in computer graphics to determine a surface's orientation toward a light source for flat shading, or the orientation of each of the corners (vertices) to mimic a curved surface with Phong shading.


    The normals effect the shading applied to a face.

    The standard shading mechanism for JavaFX 8 is Phong Shading and a Phong Reflection Model. By default, Phong Shading assumes a smoothly varying (linearly interpolated) surface normal vector. This allows you to have a sphere rendered by shading with limited vertex geometry supplied. By default the normal vectors will be calculated as being perpendicular to the faces.

    What JavaFX allows is for you to supply your own normals rather than rely on the default calculated ones. The Phong shading algorithm implementation in JavaFX will then interpolate between the normals that you supply rather than the normals it calculates. Changing the direction of surface normals will change the shading model by altering how the model represents light bouncing off of it, essentially the light will bounce in a different direction with a modified normal.

    This example from Wikipedia shows a phong shaded sphere on the right. Both spheres actually have the same geometry. The distribution of the normals which contribute towards the phong shading equation is the default, smoothly interpolated one based upon a standard normal calculation for each face (so no user normals supplied). The equation used for calculating the shading is described in the PhongMaterial javadoc, and you can see there the normal contribution to the shading algorithm, in terms of the both the calculations of diffuse color and the specular highlights.

    phong shading

    Standard 3D models, such as obj files can optionally allow for providing normals:

    vn i j k

    Polygonal and free-form geometry statement.

    Specifies a normal vector with components i, j, and k.

    Vertex normals affect the smooth-shading and rendering of geometry. For polygons, vertex normals are used in place of the actual facet normals. For surfaces, vertex normals are interpolated over the entire surface and replace the actual analytic surface normal.

    When vertex normals are present, they supersede smoothing groups.

    i j k are the i, j, and k coordinates for the vertex normal. They are floating point numbers


    So, why would you want it?

    The easiest way to explain might be to look at something known as smoothing groups (please click on the link, I won't embed here due to copyright). As can be seen by the linked image, when the smoothing group is applied to a collection of faces it is possible to get a sharp delineation (e.g. a crease or a corner) between the grouped faces. Specifying normals allows you to accomplish a similar thing to a smoothing group, just with more control because you can specify individual normals for each vertex rather than an overall group of related faces. Note JavaFX allows you to specify smoothing groups via getFaceSmoothingGroups() for instances where you don't want to go to the trouble of defining full normal geometry via getNormals().

    Another, similar idea is a normal map (or bump map). Such a map stores normal information in an image rather than as vector information, such as the getNormals() method, so it is a slightly different thing. But you can see a similar interaction with the reflection model algorithm:

    normal map

    Background Reading - How to understand Phong Materials (and other things)