threejs学习100问

知识点和经典案例


threejs学习100问

1.贴图如何做成连贯的,怎么合并

在这里插入图片描述

1.通过建模uv合并

2.触发交互,隐藏部分模型(layer)

还有个layer的参数,https://threejs.org/examples/?q=layer#webgl_layers

layer模型隐藏效果

2.1、traverse遍历

点击查看链接

traverse(function)
该方法也可以遍历调用者和调用者的所有后代,function参数是一个函数,被调用者和每一个后代对象调用 function方法。

2.2 fog雾化效果

fog
使用该属性可以为场景添加雾化效果,可以产生隐藏远处物体的浓雾效果。

*性能优化一般包括加载性能优化、渲染帧率优化、内存优化等。

3.性能优化1 - vue不在data中写变量

vue的属性劫持是递归进行的,但是都不建议把他们放到data中
scene可能会嵌套很多层
这4个对象应该都有很多属性,然后这些属性都被会挨个遍历,都会造成不必要的性能浪费
所有变量,不要用vue绑定
能使你的网页性能大大提高
不要以为 three 这几个 数据量都不大不复杂 都随便挂在data上

错误的写法
在这里插入图片描述
正确的写法:

在这里插入图片描述

4.性能优化2 - 多实例渲染 Instance、Merge 性能对比提升性能

在这里插入图片描述

1)Instance 多实例化几何体

// 同一个Geometry , 同一个 material ,但可以通过索引轻松控制每一个个体大小、位置等
let insGeometry = new THREE.BoxBufferGeometry(1, 1, 1);
//创建具有多个实例的实例化几何体
let insMesh = new THREE.InstancedMesh(insGeometry, material, total);
//修改位置
let transform = new THREE.Object3D();
for (let index = 0; index < total; index++) {
    transform.position.set(Math.random() * 2000, Math.random() * 2000, Math.random() * 2000);
    transform.scale.set(Math.random() * 50 + 50, Math.random() * 50 + 50, Math.random() * 50 + 50);
    transform.updateMatrix();
    //修改实例化几何体中的单个实例的矩阵以改变大小、方向、位置等
    insMesh.setMatrixAt(index, transform.matrix);
}
scene.add(insMesh);

2)Merge 合并几何体

// 不同的 Geometry ,同一个 material 没有索引可以使用,合并后变为一个个体 ,难以单独控制
 let geometries = [];
 let transform = new THREE.Object3D();
 for (let index = 0; index < total; index++) {
     let geometry = new THREE.BoxBufferGeometry(Math.random() * 50 + 50, Math.random() * 50 + 50, Math.random() * 50 + 50);
     transform.position.set(Math.random() * 2000, Math.random() * 2000, Math.random() * 2000);
     transform.updateMatrix();
     geometry.applyMatrix4(transform.matrix);
     geometries.push(geometry);
 }
 let mergedGeometry = BufferGeometryUtils.mergeBufferGeometries(geometries);
 let mergedMesh = new THREE.Mesh(mergedGeometry, material2);
 scene.add(mergedMesh);

实例化渲染和交错缓冲区是两个独立的东西.您可以单独或结合使用这两种技术.
THREE.InstancedMesh 为实例化提供了方便的界面渲染.当您必须渲染大量具有相同材质和几何体但具有不同世界变换的对象时,此方法非常有用.THREE.InstancedMesh 允许您通过减少绘制调用的数量来提高应用程序的性能.因此,您可以一次绘制所有对象,而不是使用单个绘制调用绘制每个对象
InterleavedBuffer 提供了管理顶点数据的可能性以交错的方式.这样做的动机是为了提高 GPU 上的缓存命中量.如果你对这种方法背后的理论更感兴趣,我建议你谷歌数组结构与结构数组".后一种适用于InterleavedBuffer.
一般来说,这两种技术的性能优势取决于具体的用例.根据我的个人经验,交错缓冲区的好处很难衡量,因为性能改进取决于相应的 GPU.在许多情况下,我发现使用交错缓冲区时 FPS 没有区别.但是,如果绘制调用的数量较多并且您通过使用实例化渲染来降低它,则更容易看到性能改进

4.性能优化3 - 二进制格式

使用不同文件格式,文件的大小会有所不同,如果同一个模型,导出二进制.fbx大小要比文本格式的.obj文件要小1~2倍。常见的GLTF格式可以是文本格式,也可以使二进制格式,为了更好的传输性能可以选择二进制格式,.glTF打包转化为.glb二进制文件。

4.性能优化4 - 减面和法线贴图

一般3D美术导出模型的时候,会进行减面操作,并导出模型的法线贴图,比如你只是加载一个机械零件模型(非批量),你可以让3D美术进行减面然后导出法线贴图,这样的话在不影响曲面显示质量前提下,减少模型三角形面数,一方面可以降低模型文件大小提高网络传输性能,另一方面可以提高threejs渲染模型的渲染性能。

4.性能优化5 - render()重点优化requestAnimationFrame内的方法,修改渲染频率,合理执行渲染方法

控制渲染帧率(FPS)比如把默认60FBS设置为30FBS
控制渲染器渲染方法.render()每秒执行次数:
因为默认情况下requestAnimationFrame()每秒执行60次,如果在里面加个for循环,代码效率就会严重影响,同时还要减少浮点计算,系统对浮点计算开支比较大,尽量写成小数乘法。

在一些特定的应用中没有必要保持Threejs渲染频率为60FPS,那么可以通过Threejs渲染时间判断来控制Threejs渲染频率,比如设置为30FPS。

下面代码通过时钟对象.Clock的.getDelta()方法获得threejs两帧渲染时间间隔,然后通过时间判断来控制渲染器渲染方法.render()每秒执行次数:

// 创建一个时钟对象Clock
var clock = new THREE.Clock();
// 设置渲染频率为30FBS,也就是每秒调用渲染器render方法大约30次
var FPS = 30;
var renderT = 1 / FPS; //单位秒  间隔多长时间渲染渲染一次
// 声明一个变量表示render()函数被多次调用累积时间
// 如果执行一次renderer.render,timeS重新置0
var timeS = 0;
function render() {
  requestAnimationFrame(render);
  //.getDelta()方法获得两帧的时间间隔
  var T = clock.getDelta();
  timeS = timeS + T;
  // requestAnimationFrame默认调用render函数60次,通过时间判断,降低renderer.render执行频率
  if (timeS > renderT) {
    // 控制台查看渲染器渲染方法的调用周期,也就是间隔时间是多少
    console.log(`调用.render时间间隔`,timeS*1000+'毫秒');
    renderer.render(scene, camera); //执行渲染操作
    ...
    //renderer.render每执行一次,timeS置0
    timeS = 0;
  }
}
render();

4.性能优化6 - 删除模型时,将材质和几何体从内存中清除

使用 remove() 将模型从场景内删除掉,大家会发现内存基本上没有怎么降低。因为几何体和材质还保存在内存当中,我们需要手动调用 dispose() 方法将其从内存中删除。

1. item.geometry.dispose(); //删除几何体
2. item.material.dispose(); //删除材质

4.性能优化7 - 尽量使用clone方法

4.性能优化8 - 在循环渲染中避免使用更新

这里的更新指的是当前的几何体、材质、纹理等发生了修改,需要 Three.js 重新更新显存的数据,具体包括:
点击查看原文链接

4.性能优化9 - 创建多量物体时 ,BufferGeometry (或者InstancedBufferGeometry)创建

4.性能优化10 - 减少没必要执行的代码在周期性渲染函数中的执行

hreejs会通过requestAnimationFrame()周期性执行一个渲染函数render(),在渲染函数中除了渲染器.render()方法,其它的尽量放在渲染函数外面,如果必须放在里面的,可以加上if判断尽量加上,不要每次执行render函数的时候,每次都执行没必要执行的代码。

4.性能优化11 - 减少模型面数,必要可以用法线贴图增加模型细节替代

Threejs渲染场景中网格模型Mesh的时候,如果网格模型Mesh几何体的三角形面数数量或者说顶点数量越多,那么需要的CPU和GPU的运算量就越大,几何体顶点数据占用的内存就多,这时候对于Threejs每次执行渲染.render(),花费的时间就越多,如果三角形面数过多,可能渲染帧率就会下降,鼠标操作三维模型的时候可能就会比较卡顿。

对于项目中使用的三维模型,3D美术往往会进行减面优化,具体减面过程对于程序员而言一般不用关心。

对于曲面而言,减面过多,可能会影响显示效果,所以减面程度要控制好。

对于曲面模型,使用法线贴图可以在不影响显示质量的情况下有效减少模型面数,法线贴图会通过图片像素值记录模型表面的几何细节,只需要3D美术对模型表面很多几何细节进行减面后,然后导出法线贴图,提供给程序员加载即可。简单地说就是通过法线贴图可以表达三维模型表面的丰富几何细节。

4.性能优化12 - 使用性能检测插件(stats.js)监测页面性能

// 引入stats.js
import Stats from 'three/examples/js/libs/stats.min.js'
const stats = new Stats()
// 设置stats样式
stats.dom.style.position = 'absolute';
stats.dom.style.top = '0px';
document.body.appendChild(stats.dom);

在渲染函数中需要添加如下代码:

function Animate() {
    requestAnimationFrame(Animate);
    Render();
}
function Render() {
	// 更新stats
    stats.update();
    render.render(scene,camera);
}

4.性能优化13 - 分时加载

调查显示100ms内的响应能让用户感觉非常流畅。50ms是 Nicholas 针对 JavaScript 得出的最佳经验值,setTimeout 延时25ms,25ms 保证主流浏览器都顺畅,可以使用类似的方法来优化three.js程序。

初始化方法以及渲染方法可以适当添加延时以分散同时渲染的压力。

当存在多个模型动画时,根据实际情况可以将多个动画拆分,再可以对每个动画requestAnimationFrame分别设置渲染频率。

4.性能优化14 - 页面销毁时手动调用dispose方法,清除延时

beforeDestroy () {
	clearTimeout()
	try {
		this.scene.clear()
		this.renderer.dispose()
		this.renderer.forceContextLoss()
		this.renderer.content = null
		// cancelAnimationFrame(animationID) // 去除animationFrame
		const gl = this.renderer.domElement.getContext('webgl')
		gl && gl.getExtension('WEBGL_lose_context').loseContext()
	} catch (e) {
		console.log(e)
	}
}

4.性能优化15 - threejs可以按照一定的顺序分别先后加载这些单独的网格模型文件,然后插入到场景中

在three.js中,模型是怎么加载到浏览器中的呢?

顺序是:

1、服务器上的模型文件以文本的方式存储,除了以three.js自定义的文本方式存储之外,当然也可以以二进制的方式存储,不过这里暂时不讲。
2、浏览器下载文件到本地
3、Javascript解析模型文件,生成Mesh网格模型
4、显示在场景中。

4.性能优化16 - 纹理图片尺寸一定得是2的幂次方,并尽可能的小

使用 new THREE.TextureLoader().load( “water.jpg” )加载纹理贴图时,如果不是2的幂次方,那么three.js就会自动转为最合适的2的幂次方尺寸,并在控制台打印出黄色警告。这个不是three.js设置的,是webgl限制的,是为了适合Mipmap(为了加快渲染速度和减少图像锯齿,贴图被处理成由一系列被预先计算和优化过的图片组成的文件)设置。

图片尽可能的小,合并,图片越大不代表越清晰,也会和纹理过滤等各属性有关。降低图片大小,减少内存占用。

4.性能优化17 - 跳帧设置

这样每到skip的时候跳过一次渲染执行,以减少渲染次数,在保证不影响用户体验的情况下,尽可能的多跳帧。

var skip;
function render(){
  requestAnimationFrame();
  if(skip !== 0) {
skip = ++skip % 2;
return;
  } else {
skip = ++skip % 2;
  }
  console.log("i",i);
}

4.性能优化18 - 对粒子群进行转换,而不是每个粒子

使用THREE.Sprite时,可以更好地控制单个粒子,但是当使用大量的粒子的时候,这个方法的性能会降低,并且会更复杂。此时可以使用THREE.SpriteCloud,可以轻松地管理大量的粒子,进行整体操作,此时对单个粒子的控制能力会减弱。

5.透明度遮挡

在这里插入图片描述

6.share着色器 - 貌似只能应用于屏幕,不适应材质

添加链接描述

可以实现线条光环,贴图可以实现,但是不会发光

在这里插入图片描述

7.Raycaster鼠标移动事件出现卡顿问题

鼠标移动事件,是取第一个,可能是场景物体太多了,鼠标移动很卡
换成点击事件,正常显示
原因:射线Raycaster不能写在vue的data里,vue在一直监听

8.点击事件弹窗有偏差

大概率是你宽高出现偏差,没算对 - 他的场景不是全屏幕 是在屏幕的中心得一个div

9.调节亮度 - 或者根据背景图片的亮度适应环境亮度

hdr - 原理也是环境贴图 scene.environment
就是根据你们银行系统的环境,搭配一张背景图。three会根据这张图片的场景搭配,映射到你的墙上,你的墙自然就亮了
设置背景是会看的到图片,设置环境看不到图片
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

material这个类没有color属性的,他后面的子类才有

在这里插入图片描述

10.修改模型的颜色

或者color={r:0.2,g:,b:}
没有特殊材质的话。 还有一种改法就是。 new three.BasicMaterial({color:0xff0000})

在这里插入图片描述

demo1、漫游效果

漫游效果
在这里插入图片描述

demo2、图扑案例

图扑案例
在这里插入图片描述

demo3、漫游完整效果

漫游完整效果
在这里插入图片描述

demo4、电厂三维可视化项目

电厂三维可视化项目

在这里插入图片描述

demo5、房屋设计和展示

房屋设计和展示
在这里插入图片描述

demo6、水泥工业数字孪生

水泥工业数字孪生
在这里插入图片描述

demo7、换热站远程监控系统

换热站远程监控系统
在这里插入图片描述

demo8,文件存放在桌面 - 蜘蛛跳舞

在这里插入图片描述
在这里插入图片描述

demo9、智慧自来水数据中心

点击查看源码
在这里插入图片描述

demo10、热换站监控系统

点击查看源码
在这里插入图片描述

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
《深度学习100》是一本经典的人工智能领域题集合,它以100个常见题为基础,系统地介绍了深度学习的相关知识。这本书包含了深度学习的基础理论、模型架构、算法优化等方面的内容,对于初学者和从业者来说都是一本不可多得的学习资料。 这本书的主要特点是题和解答的形式,以题为引导,逐步解答相关的知识点,循序渐进地构建知识框架。这种题解答的方式非常适合初学者理解和掌握深度学习的核心概念和方法。 《深度学习100》的内容非常丰富,涵盖了深度学习的各个领域,包括神经网络、卷积神经网络、循环神经网络、生成对抗网络等等。每个题都有详细的解答和相关的代码实现,读者可以通过实际操作来加深对深度学习的理解。 此外,这本书还介绍了深度学习在图像识别、自然语言处理、推荐系统等领域的应用,并提供了一些常用的数据集和应用案例。这为读者提供了实践的机会,可以通过对这些案例的学习和实验,进一步巩固和运用所学的知识。 总之,《深度学习100》是一本很好的深度学习入门书籍,它以题解答的形式,系统地介绍了深度学习的相关知识,对初学者和从业者都具有很高的参考价值。无论是想入门深度学习的新手,还是想系统学习深度学习的从业者,都可以通过阅读这本书来快速地掌握深度学习的核心概念和方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值