我目前正在使用JavaFX 3D应用程序,并在TriangleMesh类中遇到了getNormals()方法。
在TriangleMesh类中用于创建用户定义的Java FX 3D obejct,并且用于添加点的getPoints()用于添加Faces的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()方法的用途是什么?
先谢谢..
答案 0 :(得分:3)
Use of normals in computer graphics:
法线通常用于计算机图形学中,以确定表面朝向光源的平面着色方向,或每个角(顶点)的方向,以模仿具有Phong着色的曲面。
法线会影响应用于脸部的阴影。
JavaFX 8的标准着色机制是Phong Shading和Phong Reflection Model。默认情况下,Phong Shading假定平滑变化(线性插值)表面法向量。这允许您使用提供有限顶点几何体的着色渲染球体。默认情况下,normal vector s将被计算为垂直于面。
JavaFX允许您提供自己的法线而不是依赖于默认计算法线。然后,JavaFX中的Phong着色算法实现将在您提供的法线之间进行插值,而不是在它计算的法线之间进行插值。改变曲面法线的方向将改变阴影模型,方法是改变模型表示光从其反射的方式,基本上光线将以不同的方向反射,修正法线。
维基百科的这个例子在右边显示了一个phong阴影球。两个球体实际上具有相同的几何形状。有助于phong着色方程的法线的分布是默认的,基于每个面的标准法线计算进行平滑插值(因此没有提供用户法线)。用于计算着色的等式在PhongMaterial javadoc中描述,您可以看到对着色算法的正常贡献,就漫反射颜色和镜面反射高光的计算而言。
标准3D模型,例如obj files,可以选择允许提供法线:
vn i j k
多边形和自由形式的几何陈述。
指定包含组分i,j和k的法线向量。
顶点法线会影响几何体的平滑着色和渲染。 对于多边形,使用顶点法线代替实际构面 法线。对于曲面,顶点法线在...上进行插值 整个表面并替换实际的分析表面法线。
当存在顶点法线时,它们会取代平滑组。
i j k是顶点法线的i,j和k坐标。他们 是浮点数
那么,你为什么要这样做?
最简单的解释方法可能是查看smoothing groups的内容(请点击链接,我不会因版权而嵌入此处)。如链接图像可以看到的,当平滑组应用于面部集合时,可以在分组面部之间获得清晰的轮廓(例如折痕或角落)。指定法线允许您完成与平滑组类似的操作,只需更多控制,因为您可以为每个顶点指定单个法线而不是整个相关面组。注意JavaFX允许您通过getFaceSmoothingGroups()指定平滑组,以用于您不希望通过getNormals()定义完整法线几何体的情况。
另一个类似的想法是normal map(或bump map)。这样的地图将正常信息存储在图像中而不是矢量信息中,例如getNormals()方法,因此它略有不同。但是你可以看到与反射模型算法类似的交互:
Background Reading - How to understand Phong Materials (and other things)