本文主要用于分享基于Revit的法线理论,导出模型后让threejs呈现立体真实的效果。Revit的顶点法线及threejs渲染圆弧面的渐变亮度。
法线有什么用的?没有法线能否成模型?可以的,没有法线,模型几何信息照样是完成的,把它送到threejs里面渲染没有问题,但是效果却让人很失望,没有法线,整个模型会成为一个白模一样没有立体感,配合再好的光照也显示不出亮光面和暗光面。
这个时候,你可以简单的使用mesh.computeVertexNormals ()来解决问题,这是threejs自带的一个计算面法线的方法,效果实现90%,嘿嘿,真方便。入门级别了解到这里就差不多了。像立方体这样全是平面的物体,面法线本来就是跟点法线相同的。
但是这个方法,对于圆弧面却不可行了。一个圆柱体或一个球体,会有特别明显的小三角面,每个面的反光亮度都不一样。大家现在明白了吗?法线决定光的反射方向,在threejs里面,只有顶点法线才是决定亮度的,没有面法线这个说法,包括attribute里面设置的normals全是以顶点法线定义的序列。关于这一点,大家可以看郭老师的博客:http://www.yanhuangxueyuan.com/WebGL_course/light.html
而我们的目标是:
如果你使用threejs的FaceNormalsHelper去分析这东西,你会发布上面那个柱子,侧面的每一个点,像开花一样射出3条法线。这个不对的,顶点法线,应该要只有1条就够了,就是这个原因导致了三角面无法平滑过渡。
好了,带着这个问题去找答案吧。我们回到Revit上面。
在Revit里面,前面有文章提到有2种读取几何信息的方法,一种是解析Solid,一种是使用Revit的IExploter接口。
我比较喜欢用第一种方法,尤其是对于弧面的压缩大约比第二种方法节约30%,尤其还能对细小的非主要实体进行过滤。这个不详谈,还是先说法线是怎么来的。
首先,把Face经过get_Triangle之后每个三角面MeshTriangle的三个顶点,假设是p1,p2,p3,返回一个法线。
-
private XYZ GetNormal(XYZ p1, XYZ p2, XYZ p3)
-
{
-
var v1 = p2 - p1;
-
var v2 = p3 - p1;
-
return v1.CrossProduct(v2).Normalize();
-
}
这样每个点面都有法线啦,当然也可以这样解释:p1.normal=p2.normal=p3.normal=三角面.normal。
然后,管理整个Face的所有顶点法线。如果一个顶点p1有三次出现在不同的MeshTriangle,请把这些normal相加之后作为顶点p1的法线。
这样就能得到结果了,再用FaceNormalsHelper去分析,你会发布每个顶点的法线就是只有1条的。
https://threejs.org/examples/?q=normal#webgl_helpers
转载:https://blog.csdn.net/ztz87/article/details/114846846