最近一直在做一个给建筑绘制描边(主要是墙体的侧棱)的解决方案,虽然three.js内置有EdgesGeometry可以根据现有mesh的Geometry生成不带斜线的线框,但是在PC端lineWidth是不能生效的,这是因为受限于windows平台的Direct3D,所以在PC端通常的解决方案是通过两点绘制一个矩形来替代有宽度的线。
在实际项目中,由于建筑很多,如果都是用这种方式生成描边的话,无端地添加了更多mesh,我希望找到更好的解决方案,那就是通过UV数据来绘制。最后我通过自定义数据(position、uv)绘制了一个“墙体”,并且通过shader实现了描边,图示如下。
这种解决方案,重点在于如何生成uv数据,因为图中每个矩形宽度是不一样的,我们需要在传递边界信息的同时也要讲尺寸相关信息通过uv传输过去;
所以单就uv.x来看,图中所示9个立方体,对应的uv.x初始值是:
0,1,0,1,0,1,0,1,0,1
然后根据立方体的宽度,对uv.x做出更改:
0-0.1/width,1+0.1/width,0-0.1/width,1+0.1/width,0-0.1/width,1+0.1/width,0-0.1/width,1+0.1/width,0-0.1/width,1+0.1/width
width对应的是每个立方体的宽度,这样就可以根据offset值(0.1/width)动态地绘制出粗细均匀的描边了(上述图片所示案例的offset数据还需要调整);
这样我们就仅用一个uv数据处理了两个事物:
①边界判断
②统一粗细处理
基于上述项目中的解决方案引发了我进一步的思考:这种数据加密/解密的方式,如果用在模型文件或者是webgl数据传输上,很有可能会带来3D程序在性能上的提升。