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 相关文章推荐
JavaScript弹簧振子超简洁版 完全符合能量守恒,胡克定理
Oct 25 Javascript
brook javascript框架介绍
Oct 10 Javascript
遍历jquery对象的代码分享
Nov 02 Javascript
jquery多行滚动/向左或向上滚动/响应鼠标实现思路及代码
Jan 23 Javascript
jQuery实现随意改变div任意属性的名称和值(部分原生js实现)
May 28 Javascript
js获得当前系统日期时间的方法
May 06 Javascript
简述Jquery与DOM对象
Jul 10 Javascript
Angular设置title信息解决SEO方面存在问题
Aug 19 Javascript
微信小程序 for 循环详解
Oct 09 Javascript
详解Webpack-dev-server的proxy用法
Sep 08 Javascript
countUp.js实现数字动态变化效果
Oct 17 Javascript
vue在App.vue文件中监听路由变化刷新页面操作
Aug 14 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 autoload与spl_autoload自动加载机制的深入理解
2013/06/05 PHP
php按单词截取字符串的方法
2015/04/07 PHP
教你识别简单的免查杀PHP后门
2015/09/13 PHP
WordPress中限制非管理员用户在文章后只能评论一次
2015/12/31 PHP
php lcg_value与mt_rand生成0~1随机小数的效果对比分析
2017/04/05 PHP
prototype 的说明 js类
2006/09/07 Javascript
JavaScript的Cookies
2008/01/16 Javascript
js中的window.open返回object的错误的解决方法
2009/08/15 Javascript
这些年、我收集的JQuery代码小结
2012/08/01 Javascript
php的文件上传入门教程(实例讲解)
2014/04/10 Javascript
Web表单提交之disabled问题js解决方法
2015/01/13 Javascript
JavaScript中字面量与函数的基本使用知识
2015/10/20 Javascript
详解AngularJs HTTP响应拦截器实现登陆、权限校验
2017/04/11 Javascript
react实现一个优雅的图片占位模块组件详解
2017/10/30 Javascript
Angular中点击li标签实现更改颜色的核心代码
2017/12/08 Javascript
Node实战之不同环境下配置文件使用教程
2018/01/02 Javascript
Vue中全局变量的定义和使用
2019/06/05 Javascript
从零开始用webpack构建一个vue3.0项目工程的实现
2020/09/24 Javascript
vue导入.md文件的步骤(markdown转HTML)
2020/12/31 Vue.js
python爬虫入门教程--利用requests构建知乎API(三)
2017/05/25 Python
简单实现python画圆功能
2018/01/25 Python
10个Python小技巧你值得拥有
2018/09/29 Python
Python操作Excel插入删除行的方法
2018/12/10 Python
Python I/O与进程的详细讲解
2019/03/08 Python
用scikit-learn和pandas学习线性回归的方法
2019/06/21 Python
配置python的编程环境之Anaconda + VSCode的教程
2020/03/29 Python
PyCharm 在Windows的有用快捷键详解
2020/04/07 Python
如何使用Python自动生成报表并以邮件发送
2020/10/15 Python
有关HTML5 Video对象的ontimeupdate事件(Chrome上无效)的问题
2013/07/19 HTML / CSS
连卡佛中国官网:Lane Crawford中文站
2018/01/27 全球购物
社区文艺活动方案
2014/08/19 职场文书
个人职业及收入证明
2014/10/13 职场文书
刑事辩护词范文
2015/05/21 职场文书
教师年度考核自我评鉴
2015/08/11 职场文书
Python使用OpenCV和K-Means聚类对毕业照进行图像分割
2021/06/11 Python
使用Java去实现超市会员管理系统
2022/03/18 Java/Android