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

标签 javafx javafx-2 javafx-8 normals javafx-3d

我目前正在开发 JavaFX 3D 应用程序,并在 TriangleMesh 类中遇到 getNormals() 方法。

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

在TriangleMesh类中,我们可以将顶点格式设置为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 JavaFX中的getNormals()方法有什么用呢?

提前致谢..

最佳答案

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和一个Phong Reflection Model 。默认情况下,Phong Shading 假定平滑变化(线性插值)的表面法线向量。这允许您通过提供有限顶点几何体的着色来渲染球体。默认情况下normal vector s 将被计算为垂直于面。

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

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

phong shading

标准 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 的内容。 (请点击链接,由于版权原因我不会嵌入这里)。从链接的图像可以看出,当将平滑组应用于面部集合时,可以在分组的面部之间获得清晰的轮廓(例如折痕或角)。指定法线可以让您完成与平滑组类似的事情,只是需要更多控制,因为您可以为每个顶点指定单独的法线,而不是整个相关面组。注意 JavaFX 允许您通过 getFaceSmoothingGroups() 指定平滑组例如,您不想通过 getNormals() 定义完整的法线几何体。 .

另一个类似的想法是 normal map (或bump map)。这样的贴图将法线信息存储在图像中而不是作为矢量信息,例如 getNormals()方法,所以这是一个稍微不同的事情。但您可以看到与反射模型算法的类似交互:

normal map

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

关于javafx - TriangleMesh JavaFX 中 getNormals() 方法的用途是什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38071758/

相关文章:

Java FX 无法加载 Font Awesome 图标

JavaFX 3D - 如何为 Group with 3D object 和 SubScene with UI Controls 设置不同的相机?

java - Windows 10 上 JavaFx 应用程序的 JDK 8 更新 66 fatal error

javafx-2 - 如何设置文本对齐方式

java - 服务器向客户端发送消息

javafx - usrpagestage.initStyle(StageStyle.UTILITY) 没有完全显示内容

java - 如何从 FXML 文档加载特定容器?

java - 如何在没有 FXML 的情况下在 JavaFX 中正确切换场景/更改场景的根节点?

JAVA javaFX menuBar,多个项目,一个方法(场景生成器)

javafx - 如何平滑拖动 JavaFX 多边形?