图形细分 —— threejs
Posted 360企业安全可视化实验室
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了图形细分 —— threejs相关的知识,希望对你有一定的参考价值。
为什么要细分图形?
今天,我来讲地球的故事。
我们希望实现这样的效果:
我们希望做一种可交互的地球,当鼠标悬浮到国家时,展示当前国家的信息。这样比贴图更有立体感、也能方便地获取当前国家的属性做些交互。
实现过程简单地描述一下:我们把geojson勾边描成平面形状,将形状拉抻为下图中所示平面地图几何体,将几何体转为地球的坐标即可。
当我们完成平面转立体的坐标后,发现俄罗斯和南极洲有些地方发生了塌陷(图中 俄罗斯白色的区域)
什么原因呢?当我们用GeoJson勾出的几何图形时,实际上图形由很多的三角形组成。下图中看到三角形的描线的中间空出的白色,是由于边长较大三角形盖在地球表面,但图形在地球上经度跨度很大,导致三角形的厚度没能盖住地球表面弧度产生的。
解决的办法,就是让这些形状细分成更多的三角形,将图形细分,就不会出现这个问题了。如下图:
下面调研两种细分图形方法:
1
Subdivision
1
Subdivision
它的细分采用“使用循环细分”的原理,传入循环的次数(subdivisions)进行循环。但不擅长处理锐利的边缘(sharp edges)。
库的使用方法:
var tess = new THREE.SubdivisionModifier(1);
tess.modify(geometry);
var mesh = new THREE.Mesh(geometry, material);
耗时实验:
在本文的时间实验中,我们使用同一组图形数据进行实验。
运行如上代码进行一次细分,时间为 26.787109375ms ,把循环次数增加一次,则时间会加倍,57.43603515625ms。速度有点慢,但是这个库得到的细分效果如下图,能满足我们需求。
使用后对比:
在线例子:https://threejs.org/examples/?q=subdi#webgl_modifier_subdivision
https://github.com/mrdoob/three.js/blob/master/examples/js/modifiers/SubdivisionModifier.js
2
TessellateModifier
这种细分采用 “把长度超过“限定边长值”(maxEdgeLength)的边进行细分”的方法,处理后,会细分为很多的小三角形。
库的使用方法:
所以使用时,需要一个maxEdgeLength,在调用modify方法:
var tessellateModifier = new THREE.TessellateModifier( 8 );
for ( var i = 0; i < 6; i ++ ) {
tessellateModifier.modify( geometry );
}
时间实验:
在数据相同的情况下,用如上函数调用一次TessellateModifier方法,用时为 2.52294921875ms,如果将 for循环的次数增加 2次 , 则 2.96484375ms ,时间增长幅度很小,但是得到的图形填充色后有缝隙,有一些不足。
使用前后对比:
看,地图里面线条(三角形)分得很细。
实心效果(去掉wireframe)后有许多的白色小点
3
两种库的对比
从上面的实验我们得到了两组库的对比结果:
TessellateModifier 比 Subdivision 速度更快,如果侧重速度,选择TessellateModifier。
但是TessellateModifier实现的效果中填充后有缝隙,效果不如Subdivision。
◆ ◆ ◆
我们会不断地分享更多有趣的干货~
笔芯~
以上是关于图形细分 —— threejs的主要内容,如果未能解决你的问题,请参考以下文章