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 相关文章推荐
页面中iframe相互传值传参
Dec 13 Javascript
IE JS无提示关闭窗口不提示的方法
Apr 29 Javascript
jqGrid日期格式的判断示例代码(开始日期与结束日期)
Nov 08 Javascript
jquery查找父元素、子元素(个人经验总结)
Apr 09 Javascript
JavaScript中对循环语句的优化技巧深入探讨
Jun 06 Javascript
动态加载js文件简单示例
Apr 21 Javascript
jquery pagination分页插件使用详解(后台struts2)
Jan 22 Javascript
vue.js利用Object.defineProperty实现双向绑定
Mar 09 Javascript
基于Vue单文件组件详解
Sep 15 Javascript
微信小程序中实现手指缩放图片的示例代码
Mar 13 Javascript
详解JavaScript中关于this指向的4种情况
Apr 18 Javascript
a标签调用js的方法总结
Sep 05 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判断文件是否存在、是否可读、目录是否存在的代码
2012/10/03 PHP
PDO预处理语句PDOStatement对象使用总结
2014/11/20 PHP
详解js异步文件加载器
2016/01/24 PHP
学习PHP的数组总结【经验】
2016/05/05 PHP
js作用域及作用域链概念理解及使用
2013/04/15 Javascript
使用js检测浏览器的实现代码
2013/05/14 Javascript
关闭浏览器时提示onbeforeunload事件
2013/12/25 Javascript
jquery.post用法关于type设置问题补充
2014/01/03 Javascript
IE与FF下javascript获取网页及窗口大小的区别详解
2014/01/14 Javascript
Jquery 点击按钮自动高亮实现原理及代码
2014/04/25 Javascript
Javascript快速排序算法详解
2014/12/03 Javascript
javascript实现表单提交后,提交按钮不可用的方法
2015/04/18 Javascript
JavaScript获取并更改input标签name属性的方法
2015/07/02 Javascript
WordPress中鼠标悬停显示和隐藏评论及引用按钮的实现
2016/01/12 Javascript
在AngularJS框架中处理数据建模的方式解析
2016/03/05 Javascript
js实现5秒倒计时重新发送短信功能
2017/02/05 Javascript
React中的refs的使用教程
2018/02/13 Javascript
在Layui中操作数据表格,给指定单元格添加事件示例
2019/10/26 Javascript
vue项目使用高德地图的定位及关键字搜索功能的实例代码(踩坑经验)
2020/03/07 Javascript
微信小程序接入vant Weapp组件的详细步骤
2020/10/28 Javascript
[39:08]完美世界DOTA2联赛PWL S3 LBZS vs CPG 第一场 12.12
2020/12/16 DOTA
Python函数嵌套实例
2014/09/23 Python
Python调用系统底层API播放wav文件的方法
2017/08/11 Python
Python实现修改IE注册表功能示例
2018/05/10 Python
Python从Excel中读取日期一列的方法
2018/11/28 Python
Python re 模块findall() 函数返回值展现方式解析
2019/08/09 Python
基于python监控程序是否关闭
2020/01/14 Python
培训主管的职业生涯规划
2014/03/06 职场文书
代理协议书
2014/04/22 职场文书
小学安全教育月活动总结
2014/07/07 职场文书
庆祝国庆节演讲稿2014
2014/09/19 职场文书
2015年乡镇扶贫工作总结
2015/04/08 职场文书
2015年医院后勤工作总结
2015/05/20 职场文书
大卫科波菲尔读书笔记
2015/06/30 职场文书
2016医师资格考试考生诚信考试承诺书
2016/03/25 职场文书
python实现学员管理系统(面向对象版)
2022/06/05 Python