最近一直在做一个给建筑绘制描边(主要是墙体的侧棱)的解决方案,虽然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程序在性能上的提升。
一、目前的处理方式
目前,3D模型的position数据和uv数据都是分离开来通过不同的attribute变量,从cpu传输到gpu;并且三维模型的处理方式也是如此。
二、数据加密/解密的方式
试想一下,如果我们在模型导出的时候,将position数据和uv数据进行加密(注意:不是将一个vec3、一个vec2合并成一个vec5);
比如:
vec2 uv = vec2(0.15,0.55); float uv = 15.55;
或者是其他规则,将原本需要多个数据表达的信息,通过一定的加密规则加密成一个数据进行传输。
然后3D库解析的时候对数据进行解密处理,这样的话模型文件的大小会得到一定程度的削减。
如果不交给3D库解密的话,也可以交给webgl去解密,解密方式可以内置到webgl中,这样的话,webgl渲染的时候,数据传输的过程中(cpu--->gpu的数据传输)数据量就会大大减少;
解密工作交给gpu处理的话速度会比cpu快很多,这样也能提高webgl的渲染性能。
以上为个人浅见,如感兴趣,欢迎前来交流探讨。