WebGL文字渲染的那些问题 (3)

WebGL文字渲染的那些问题

  可以看到新更新的poi,在计算纹理坐标时候,有一部分像素包含了其他poi的像素。这个问题是因为新poi的区域刚好叠在了先前poi的边界上,那么我们只要给新的poi加一点buffer,这个buffer是白素透明区域,buffer会把之前的poi像素覆盖掉,而我们计算纹理坐标时,只取poi的边界,那么就可以解决这个问题。

WebGL文字渲染的那些问题

  那么首先绘制的时候就要保留buffer

WebGL文字渲染的那些问题

  上传的时候使用buffer

WebGL文字渲染的那些问题

  计算纹理坐标时,排除buffer

WebGL文字渲染的那些问题

六、局部更新带来的性能问题

  根据目前的结果,局部更新能后解决crash的问题,但是带来了严重的性能开销,与同事应用局部更新提升性能的结果相反。这个问题还要继续跟踪。
  目前发现问题是因为使用了getImageData来获取数据,然后传递到gpu中,非ios设备用这种方式有时候getImageData的开销特别大,而ios设备相对好一些。
  测试发现非ios设备直接上传一张大纹理的效果反而比getImageData这种方式更好。但是依然不如之前上传多个canvas的性能。而在iphone5的测试机和iphone6的机器上性能比之前直接上传多个canvas的方式好一些,且没有崩溃问题。但是在岳阳的iphone6 plus 16g内存的手机上发现用具局部纹理更新性能很差,而且经常崩溃。
  后来发现原因是因为,虽然getImageData在IOS上性能好过非IOS设备,但性能开销仍然比较大,所以当场景中POI很多时,仍然会引起主线程卡顿,甚至计算太密集引起浏览器崩溃。其中层尝试使用cesium方式,每个poi创建新的canvas,将canvas进行局部上传,本以为这种方式不需要getImageData会更快一些,然而实践发现每次创建canvas设置参数的过程更耗时。

  最终的方案是仍然使用getImageData,但是将getImageData的过程分块处理,每50ms处理一次,分块放到场景中,这样就解决密集计算引起的崩溃问题,虽然增加了控制成本,但是能够有效解决IOS崩溃问题。有趣的是在安卓上getImageData方式开销很大,即使分块也不适合,而且安卓用一张大纹理的方式来处理,会发现很多POI绘制效果不好。

WebGL文字渲染的那些问题

  最终方案是,IOS使用getImageData局部纹理+分块加载方式绘制POI。安卓使用POI独立创建canvas+全量加载方式。(安卓不适用分块加载,是为了尽快把所有POI呈现给用户)

七、文字黑色描边问题

   这个问题自始至终困扰我好久一直没找到黑边的原因;

WebGL文字渲染的那些问题

  将原始的canvas导出后发现这是因为原始的canvas就有一层边界

WebGL文字渲染的那些问题

  曾经怀疑是minFilter的设置不对在pc端纹理使用NEARESTFilter方式取值发现的确能够消除黑边,然而移动端仍然会出现黑边,最后使用颜色混合公式解决问题。

  gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
  在Three.js中需要设置SpriteMaterial的blending为CustomBlending

八、颜色混合新问题

   但是使用上述方式同样引来新问题,设计反映poi的icon四周被裁切掉,

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpyffd.html