three.js中多线程的使用及性能测试详解


Posted in Javascript onJanuary 07, 2021

前言

今天郭先生说一下WebWorker以及WebWorker在three.js中的应用。我们都知道Javascript是单线程的,比如执行js代码的同时UI渲染就会停止,对于多核CPU的点脑,这一点让人难以接受,好在Web Worker的出现多少解决了一些问题。官方说Web Worker指的是一种可由脚本创建的后台任务,任务执行中可以向其创建者收发信息。要创建一个 Worker ,只须调用 Worker(URL) 构造函数,函数参数 URL 为指定的脚本。关于Web Worker的更多知识请阅读Web Worker。线案例请点击web-worker,

1. 在three.js中使用多线程

在three.js中使用Web Worker经常发生在大量计算造成CUP阻塞的情况下,我们举一个例子,比如说我们制作了1000个Mesh,

three.js中多线程的使用及性能测试详解

让他们简单的动起来,CPU几乎没有什么压力,FPS会在60左右,但是如果让这1000个Mesh的位置都需要大量计算才能得到,那么FPS就会很低(和计算量成负相关),下面是一段代码

for(let i=0; i<num; i++) {
 let angle = positions[i].y / (1000 / (Math.PI * 10));
 positions[i].x = positions[i].x + Math.sin(angle);
 positions[i].z = positions[i].z + Math.cos(angle);
 positions[i].y = positions[i].y + 1;
		//上面就是简单的位置变化,下面的代码模拟复杂的变化,累加100000次(这是非常占用线程的情况)
 for(let j=1, total=1; j<=100000; j++) {
 total += j;
 }
 if(positions[i].y > 500) {
 positions[i].y = positions[i].y - 1000;
 }
}
for(var i=0; i<num; i++) {
 group.children[i].position.set(positions[i].x, positions[i].y, positions[i].z);
}

positions是储存1000个Mesh位置信息的数组,group里面储存了所有的Mesh,每次渲染都更改positions的位置信息,然后给Group的每一个Mesh设置新值,这种情况下FPS会低至7FPS,转动场景可以很明显的感觉到卡顿。接下来我们使用Web Worker处理这个问题,主线程代码如下

myWorker = new Worker('/static/js/worker.js');
myWorker.postMessage(positions);
myWorker.onmessage = e => {
 let positions = e.data;
 for(var i=0; i<num; i++) {
 group.children[i].position.set(positions[i].x, positions[i].y, positions[i].z);
 }
}

脚本代码如下

onmessage = function(e) {
 let num = 1000;
 let positions = e.data;
 setInterval(e => {
 for(let i=0; i<num; i++) {
  let angle = positions[i].y / (1000 / (Math.PI * 10));
  positions[i].x = positions[i].x + Math.sin(angle);
  positions[i].z = positions[i].z + Math.cos(angle);
  positions[i].y = positions[i].y + 1;
  for(let j=1, total=1; j<=100000; j++) {
  total += j;
  }
  if(positions[i].y > 500) {
  positions[i].y = positions[i].y - 1000;
  }
 }
 postMessage(positions);
 }, 1000 / 60)
};

主要代码和未使用Web Worker几乎一样,只不过是将处理位置的代码放在新的线程中完成,setInterval定时器每一次完成位置计算都会通过postMessage(positions)将位置信息返回给主线程,主线程通过onmessage接受信息,返回对象的data属性就是新的positions。这样一来FPS可以达到60左右,转动场景感觉的到卡顿。这是十分让人欣喜的。

2. 性能分析

前面已经说了在每一次位置计算中做10万次累加,未使用Web Worker的情况下FPS降到了7,下面是更多的数据(数据仅做对比,和当前使用情况以及配合有关)。

累加次数(万次) 使用Web Worker 未使用Web Worker
1 60 60
3 60 39
5 60 26
7 60 11
9 60 8
11 60 6

这里面可以看出,不管是多么大量的计算,使用Web Worker都不会影响主线程,但是对于未使用Web Worker影响是十分严重的,下面展示一下两种情况下电脑性能的对比

(未使用Web Worker)

three.js中多线程的使用及性能测试详解

(使用Web Worker)

three.js中多线程的使用及性能测试详解

这里可以看出使用更多的线程可以很明显的提升CPU使用率。小伙伴们不妨打开线上案例亲自测试一下。

总结

到此这篇关于three.js中多线程的使用及性能测试的文章就介绍到这了,更多相关three.js多线程使用及性能测试内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

版权声明:本文为郭志强的原创文章,转载请附上原文出处链接及本声明。原文链接:https://www.mrguo.link

Javascript 相关文章推荐
初学prototype,发个JS接受URL参数的代码
Sep 25 Javascript
JavaScript Array扩展实现代码
Oct 14 Javascript
Jquery 弹出层插件实现代码
Oct 24 Javascript
jquery插件制作简单示例说明
Feb 03 Javascript
解析javascript 浏览器关闭事件
Jul 08 Javascript
javascript高级选择器querySelector和querySelectorAll全面解析
Apr 07 Javascript
jQuery 检查某个元素在页面上是否存在实例代码
Oct 27 Javascript
js中创建对象的几种方式
Feb 05 Javascript
js仿微信抢红包功能
Sep 25 Javascript
详解Vue调用手机相机和相册以及上传
May 05 Javascript
Vue.js如何使用Socket.IO的示例代码
Sep 05 Javascript
vue-cli3使用mock数据的方法分析
Mar 16 Javascript
解决vue使用vant轮播组件swipe + flex时文字抖动问题
Jan 07 #Vue.js
vuex的使用和简易实现
Jan 07 #Vue.js
vue watch监控对象的简单方法示例
Jan 07 #Vue.js
vue.js watch经常失效的场景与解决方案
Jan 07 #Vue.js
Node快速切换版本、版本回退(降级)、版本更新(升级)
Jan 07 #Javascript
通过vue.extend实现消息提示弹框的方法记录
Jan 07 #Vue.js
如何在vue-cli中使用css-loader实现css module
Jan 07 #Vue.js
You might like
php curl的深入解析
2013/06/02 PHP
php将服务端的文件读出来显示在web页面实例
2016/10/31 PHP
浅谈PHP的排列组合(如输入a,b,c 输出他们的全部组合)
2017/03/14 PHP
Yii2框架控制器、路由、Url生成操作示例
2019/05/27 PHP
CSS和JS标签style属性对照表(方便js开发的朋友)
2010/11/11 Javascript
DB.ASP 用Javascript写ASP很灵活很好用很easy
2011/07/31 Javascript
Highcharts学习之数据列
2016/08/03 Javascript
js从外部获取图片的实现方法
2016/08/05 Javascript
vue.js入门(3)——详解组件通信
2016/12/02 Javascript
利用node.js实现反向代理的方法详解
2017/07/24 Javascript
基于 Bootstrap Datetimepicker 联动
2017/08/03 Javascript
基于JS递归函数细化认识及实用实例(推荐)
2017/08/07 Javascript
详谈JS中数组的迭代方法和归并方法
2017/08/11 Javascript
Webpack devServer中的 proxy 实现跨域的解决
2018/06/15 Javascript
axios+Vue实现上传文件显示进度功能
2019/04/14 Javascript
JS学习笔记之数组去重实现方法小结
2019/05/29 Javascript
vue Cli 环境删除与重装教程 - 版本文档
2020/09/11 Javascript
[48:52]DOTA2上海特级锦标赛A组小组赛#2 Secret VS CDEC第一局
2016/02/25 DOTA
Python中os.path用法分析
2015/01/15 Python
python3中bytes和string之间的互相转换
2017/02/09 Python
Tensorflow 训练自己的数据集将数据直接导入到内存
2018/06/19 Python
浅析Python3中的对象垃圾收集机制
2019/06/06 Python
python实现五子棋小程序
2019/06/18 Python
python单例模式原理与创建方法实例分析
2019/10/26 Python
python生成并处理uuid的实现方式
2020/03/03 Python
python GUI库图形界面开发之PyQt5布局控件QVBoxLayout详细使用方法与实例
2020/03/06 Python
python 双循环遍历list 变量判断代码
2020/05/04 Python
Python+OpenCV图像处理——打印图片属性、设置存储路径、调用摄像头
2020/10/22 Python
JD Sports法国:英国篮球和运动时尚的领导者
2017/09/28 全球购物
德国的大型美妆个护电商:Flaconi
2020/06/26 全球购物
金融学专业大学生职业生涯规划
2014/03/07 职场文书
年会主持词结束语
2014/03/27 职场文书
竞选大队委员演讲稿
2014/04/28 职场文书
夫妻婚内购房协议书
2014/10/05 职场文书
如何利用js在两个html窗口间通信
2021/04/27 Javascript
MySQL数据库⾼可⽤HA实现小结
2022/01/22 MySQL