TriangleMesh JavaFX 中 getNormals() 方法的用途是什么

What is use of getNormals() method in TriangleMesh JavaFX

我目前正在使用 JavaFX 3D 应用程序并在 TriangleMesh class.

中遇到 getNormals() 方法

如 TriangleMesh class 用于创建用户定义的 Java FX 3D 对象,其中
getPoints() 用于添加点
getFaces( ) 用于添加面
getTexCoords() 用于管理 3D 对象的纹理,
但我不确定 TriangleMesh 中的 getNormals() 方法有什么用 class.

在TriangleMesh class中,我们可以将顶点格式设置为VertexFormat.POINT_TEXCOORD和VertexFormat.POINT_NORMAL_TEXCOORD。
但是如果我们将vertexFormat设置为"VertexFormat.POINT_NORMAL_TEXCOORD",那么我们需要将法线索引添加到面中,如下所示:
[ p0, n0, t0, p1, n1, t1, p3, n3, t3, // 纹理矩形的第一个三角形

p1, n1, t1, p2, n2, t2, p3, n3, t3 // 纹理矩形的第二个三角形 ]

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

所述

如果我将 vertexFormat 用作 POINT_TEXCOORD 或 POINT_NORMAL_TEXCOORD,我没有发现 3D 形状有任何差异。

那么TriangleMesh中的getNormals()方法有什么用JavaFX?

提前致谢..

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.


法线影响应用于面部的阴影。

JavaFX 8 的标准着色机制是 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 将被计算为垂直于面。

JavaFX 允许您提供自己的法线,而不是依赖默认的计算法线。 JavaFX 中的 Phong 着色算法实现将在您提供的法线之间进行插值,而不是在它计算的法线之间进行插值。改变表面法线的方向将通过改变模型表示光从其反射的方式来改变着色模型,本质上,光将在不同的方向上反射并修改法线。

维基百科的这个示例在右侧显示了一个 phong 阴影球体。这两个球体实际上具有相同的几何形状。对 phong 着色方程有贡献的法线分布是默认的,根据每个面的标准法线计算平滑插值的分布(因此没有提供用户法线)。 PhongMaterial javadoc 中描述了用于计算阴影的方程式,您可以在漫反射颜色和镜面高光的计算方面看到正常对阴影算法的贡献。

标准 3D 模型,例如 obj files 可以选择允许提供法线:

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


那么,你为什么要它?

最简单的解释方法可能是查看称为 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() 的内容。

另一个类似的想法是 normal map (or bump map). Such a map stores normal information in an image rather than as vector information, such as the getNormals() 方法,所以它略有不同。但是可以看到与反射模型算法类似的交互:

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