three.js

1.重用Material和Geometry
2.不在render()中实例化或是赋值操作
3.粒子系统代替粒子
4.操作一组对象使用Object3D或group
5.网格合并merge
6.使用Web workers

https://threejs.org/examples/?q=sand#raytracing_sandbox

7.分时加载算法(大数组)
8.延时渲染THREE.DefaultLoadingManager
9.删除模型remove,使用dispose释放几何和材质,RenderTarget,texture
10.BufferGeometry代替Geometry
11.减少浮点计算,写成小数乘法
12.使用clone()方法
13.纹理图片尺寸一定得是2的幂次方,并尽可能的小
14.跳帧设置
15.降低模型的复杂度减少面数
16.使用chrome的插件three.js inspector
17.使用stats.js进行检测帧率
18. JavaScript中的对象创建很昂贵,因此不要在循环中创建对象。相反,创建一个单独的对象,如Vector3,vector.set()在循环中使用或类似的方法
19.Web浏览器使用的JavaScript引擎经常更改,并在幕后对代码进行了大量优化。不要相信你的直觉会更快,总是测试。不要相信几年前的文章告诉你要避免某些方法,如array.map或array.forEach。自己测试一下。

模型,网格和其他可见的东西

  1. 避免使用常见的基于文本的3D数据格式(如Wavefront OBJ或COLLADA)进行资产交付。相反,请使用针对Web优化的格式,例如glTF
  2. 使用带有glTF的Draco网格压缩
  3. 如果您需要使大组对象可见且不可见(或在场景中添加/删除它们),请考虑使用图层以获得最佳性能
  4. 位于相同位置的物体会导致闪烁。尝试抵消一些微小的东西<math><semantics><annotation encoding="application/x-tex">0.001</annotation></semantics></math>0 。0 0 1使事物看起来像是在同一个位置,但让你的GPU保持开心
  5. 使场景以原点为中心,以防止在大坐标处出现浮点错误
  6. 切勿移动Scene对象。它创建于<math><semantics><annotation encoding="application/x-tex">(0,0,0)</annotation></semantics></math>(0 ,0 ,0 ),这是其中所有对象的默认参考框架。
    使您的平截头体尽可能小,以获得更好的性能。在开发中使用大平截头体是很好的,但是一旦你对应用程序进行微调以进行部署,就可以使你的平截头体尽可能小,以获得一些FPS
    不要把东西放在远剪裁平面上(特别是如果你的远剪裁平面真的很大),这可能会导致闪烁
  7. 不要使用TriangleFanDrawMode,它很慢。
  8. 当您有数百或数千个类似的几何时,请使用几何实例化
  9. 在GPU而不是CPU上进行动画处理,尤其是在为顶点或粒子设置动画时(有关此方法的一种方法,请参阅THREE.Bas

性能

  1. 设置object.matrixAutoUpdate = false 为静态或很少移动的对象,并object.updateMatrix() 在更新其位置/四元数/比例时手动调用
  2. 透明对象很慢,在场景中使用尽​​可能少的透明对象
  3. alphatest如果可能,使用而不是标准透明度,它更快
  4. 在测试应用程序的性能时,您需要做的第一件事就是检查它是受CPU限制还是GPU绑定。使用基本材料替换所有材料scene.overrideMaterial(请参阅初学者提示和页面开头)。如果性能提高,那么您的应用就是GPU限制。
  5. 在快速机器上进行性能测试时,您可能会获得60fps的最大帧速率。使用open -a "Google Chrome" --args --disable-gpu-vsyncfo run 无限帧率运行chrome
  6. 现代移动设备具有高的像素比率 <math><semantics><annotation encoding="application/x-tex">五</annotation></semantics></math>5 - 考虑在这些设备上将最大像素比率限制为2或3,但会牺牲一些非常轻微的场景模糊
  7. 烘焙光照和阴影贴图以减少场景中的灯光数量
  8. 如果您有资源和时间,请使用压缩纹理。不幸的是,为网络设置这些内容是一件很痛苦的事情,因为所有设备都不支持任何格式
  9. 密切关注场景中的drawcalls数量。一个好的经验法则是减少绘制调用=更好的性能
  10. 远处的物体不需要与靠近相机的物体具有相同的细节水平。有许多技巧用于通过降低远处物体的质量来提高性能。例如,LOD细节级别)对象存储不同距离的不同对象(例如,近,中和远)。您也可能只为远处的物体每隔2帧或3帧更新位置/动画
    尽可能减少多重计数。请记住,模型根本不应该过于详细。

将Obj文件转换为Json和/或为场景中的每个对象创建单独的JSON文件。请记住,geometry是您尝试加载的文件中最重的数据块。因此,如果可能,BufferGeometry为每个文件创建单独的文件并通过它加载BufferGeometryLoader

在加载所有js和json文件之前,您可以使用一些压缩/解压缩技术。查看OpenCTM压缩。您也可以尝试gzip您的文件并对其进行放气。

在创建网格的3d建模阶段,合并尽可能多的几何。最简单的方法是识别具有相同/相似材料的所有网格,合并这些几何,并为这些几何分配相同的材质。您拥有的几何数量越少,渲染管道中绘制调用的次数就越少。因此,您的表现将会提高。

您可以跟踪您的drawcalls使用情况renderer.info

保持纹理文件大小较低的分辨率。我一般建议少于1K。

材料性能成本是这样的MeshBasicMaterial< MeshLambertMaterial< MeshPhongMaterial< MeshStandardMaterial< MeshPhysicalMaterial。在将材质指定给几何体时要小心。Threejs doc清楚地说明了每种材料的所有特征。因此,如果您知道对象不需要材料的某些属性,则回退到更便宜的材质。

使用normalMaps伪造的goemetries。这将减少您vertices所需的数量。

如果您的场景是静态使用aoMap并且LightMap在场景中消除了对光源的需求及其计算成本。

如果场景是静态的,请停止requestAnimationFrame并仅在需要时渲染。例。如果您使用的是orbitcontrol.js,请onChange在触发用户活动时使用方法进行渲染。

使用Chrome扩展程序,如Threejs Inspector和WebGL Inspector进行调试。

如果动态删除场景中的任何内容,请确保正确处理数据。

300 MB的文件非常大。确保将其减少到30 mb或更低,理想情况下,低于10 mb以获得最佳体验。
从场景中删除一些东西?

首先,考虑不这样做,特别是如果你稍后再添加它。您可以暂时隐藏对象object.visible = false(也适用于灯光),或者material.opacity = 0。您可以设置light.intensity = 0禁用灯光而不会导致着色器重新编译。

后期处理

  1. 内置的抗锯齿功能不适用于后期处理(至少在WebGL 1中)。您需要使用FXAASMAA手动执行此操作(可能更快,更好)
  2. 由于您没有使用内置AA,请务必禁用它!
  3. three.js有大量的后处理着色器,这真是太棒了!但请记住,每次传递都需要渲染整个场景。完成测试后,请考虑是否可以将一些传递合并到一个自定义传递中
    几何
    避免使用线环,因为它必须由线条模拟

纹理

  1. 你的所有纹理都必须是2的幂(POT)大小: <math><semantics><annotation encoding="application/x-tex">1,2,4,8,16,...,512,2048 ......</annotation></semantics></math>1 ,2 ,4 ,8 ,1 6 ,...,5 1 2 ,2 0 4 8 ,...
  2. 不要更改纹理的尺寸。相反,创建新的,它更快
  3. 尽可能使用最小的纹理尺寸(你可以使用256x256平铺纹理逃脱吗?你可能会感到惊讶!)
  4. 非二次幂(NPOT)纹理需要线性或最近的滤波,以及钳位到边界或钳位到边缘的包装。不支持Mipmap过滤和重复包装。但严重的是,只是不要使用NPOT纹理
  5. 具有相同尺寸的所有纹理在内存中的大小相同,因此JPG的文件大小可能比PNG小,但它会占用GPU上相同的内存量
    定制材料
    只有在他们改变时才更新你的制服,而不是每一帧。

物料

内置的three.js材料具有简单的性能/质量权衡:

  1. MeshStandardMaterial 最高质量/最慢
  2. MeshPhongMaterial
  3. MeshLambertMaterial
  4. MeshBasicMaterial 质量最低/最快

使用您能承受的最优质材料,并在需要时切换到质量较差的材料。

  1. MeshLambertMaterial不适用于有光泽的材料,但对于像布料这样的哑光材料,它会产生非常相似的结果,MeshPhongMaterial但速度更快
  2. 如果您正在使用变形目标,请确保morphTargets = true在材料中设置,否则它们将无效!
  3. 同去的变形法线
  4. 如果您使用SkinnedMesh进行骨骼动画,请确保material.skinning = true
  5. 与变形目标,变形法线或蒙皮一起使用的材质无法共享。您需要为每个蒙皮或变形网格创建一个独特的材质(material.clone()这里是您的朋友)。

阴影

  1. 如果场景是静态的,则仅在更改内容时更新阴影贴图,而不是每帧
  2. 使用a CameraHelper可视化阴影相机的视锥体
  3. 请记住,点光阴影比其他阴影类型更昂贵,因为它们必须渲染六次(每个方向一次),而单个时间DirectionalLightSpotLight阴影相比
  4. 虽然我们对的话题PointLight阴影,注意,CameraHelper只能可视化一个6用于可视化的点光源阴影时,阴影的方向。它仍然有用,但你需要将你的想象力用于其他5个方向
    灯,尤其是SpotLight,PointLight,DirectionalLight很慢。在场景中使用尽​​可能少的灯光
    避免在场景中添加和删除灯光,因为这需要WebGLRenderer重新编译所有着色器程序(它会缓存程序以便随后执行此操作,它会比第一个更快)
    打开renderer.physicallyCorrectLights使用SI单位的精确照明

渲染

  1. preserveDrawingBuffer除非您需要,否则请勿启用
  2. 除非您需要,否则禁用alpha缓冲区
  3. 除非您需要,否则不要启用模板缓冲区
  4. 除非你需要它,否则禁用深度缓冲区(但你可能确实需要它)
  5. powerPreference: "high-performance"在创建渲染器时使用。这可能使用户系统在多GPU系统中选择高性能GPU。
  6. 考虑仅在相机位置通过epsilon或动画发生时更改时进行渲染
  7. 如果您的场景是静态的并且使用OrbitControls,您可以监听change事件以仅在相机移动时渲染:
OrbitControls.addEventListener( 'change', () => renderer.render( scene, camera ) );

你不会从最后两个获得更高的帧速率,但你会得到的是更少的笔记本电脑风扇开启,以及移动设备上的电池消耗更少。

注意:我已经看到网络上的一些地方建议您禁用抗锯齿并应用后处理AA通道。在我的测试中,这不是真的。在现代硬件上,即使在低功耗移动设备上,内置MSAA似乎也非常便宜,而后处理FXAA或SMAA通过导致相当大的帧丢失

Three.js OffscreenCanvas

产生阴影的:

THREE.DirectionLight() 平型光
THREE.PointLight() 点光源
THREE.SpotLight() 聚光灯

不产生阴影的:

THREE.AmbientLight() 环境光
THREE.HemiphereLight() 半球光
THREE.RectAreaLight() 平面光源

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 193,968评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,682评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,254评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,074评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 60,964评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,055评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,484评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,170评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,433评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,512评论 2 308
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,296评论 1 325
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,184评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,545评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,880评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,150评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,437评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,630评论 2 335

推荐阅读更多精彩内容

  • Threejs中文文档 郭隆邦技术博客 2018-09-21 20:40:17 关注 Three.js中文文档 今...
    情人波阅读 13,640评论 0 7
  • 之前用qunee做了一个2.5d的机房监控,丑的闪瞎我的卡姿兰大眼,后来含泪用three.js做个3d的换...
    我得有妖气阅读 1,567评论 1 2
  • 1、简介 WebGL 是在浏览器中实现三维效果的一套规范,而 Three.js 可以看成是浏览器对 WebGL 规...
    风之化身呀阅读 3,473评论 0 4
  • 1.场景 场景是three.js最基础的三大要素之一,你的所有要展示的内容都在场景之中,创建的方式十分简单var ...
    起飞之路阅读 913评论 0 0
  • 祷告词一: 复活得胜的主啊!你已经胜过黑权势,你已超乎天下万有!你复活,作我们信你之人初熟的果子,!你复活,带...
    Share1188阅读 1,023评论 0 0