likes
comments
collection
share

WebGL渲染引擎优化方向 -- 内存管理的优化

作者站长头像
站长
· 阅读数 19

作者:caven chen

对此系列感兴趣还可以看前文:

前言

WebGL 是一种强大的图形渲染技术,可以在浏览器中快速渲染复杂的 3D 场景。但是,由于 WebGL 的高性能和高质量要求,如果不注意性能优化,它可能会消耗大量的 CPU 和 GPU 资源,导致应用程序性能下降。

首先性能优化是一个比较大的话题,会涉及多个技术点,对于大场景来说,一般优化可以分为以下几个大的方向:

  1. 加载性能的优化
  2. 渲染帧率的优化
  3. 内存管理的优化

今天我们讨论就是第三个方向:内存管理的优化,内存管理的优化可以从以下方面入手

接下来的优化都是以threejs为示例的,对于其他的webgl框架,请选择同样功能的接口或者方法

浏览器的选择

在大场景的渲染下,我们要尽量引导客户使用 64 位的浏览器 chrome 或者 Firefox,这样可以最大限度的使用 js 内存,防止 V8 js Heap 爆了的情况。

WebGL渲染引擎优化方向 -- 内存管理的优化

Memory savings when browsing in Windows 10

释放BufferAttribute

对于模型数据,大量的顶点、法线等等 buffer 数据也是非常占用内存的。我们可以在 js 推送完数据之后,将这部分数据从内存中释放掉,从而降低 JS 的内存压力,如果使用 threejs 进行渲染,BufferAttribute包含一个onUpload回调函数,在数据推送到 GPU 之后调用。我们可以在回调函数中释放掉 js 中的数据。值得注意的是,这个回调函数只在第一次的时候有用,在 attribute 更新 update 的时候,并不会触发。

  function disposeArray() {

					this.array = null;

				}

geometry.setAttribute( 'position', new THREE.Float32BufferAttribute( positions, 3 ).onUpload( disposeArray ) );
geometry.setAttribute( 'normal', new THREE.Float32BufferAttribute( normals, 3 ).onUpload( disposeArray ) );
geometry.setAttribute( 'color', new THREE.Float32BufferAttribute( colors, 4 ).onUpload( disposeArray ) );

WebGL渲染引擎优化方向 -- 内存管理的优化

释放材质

材质定义了物体将如何被渲染。three.js使用材质所定义的信息来构造一个着色器程序,以用于渲染。 着色器程序只有在相应材质被废置后才能被删除。由于性能的原因,three.js尽可能尝试复用已存在的着色器程序。 因此,着色器程序只有在所有相关材质被废置后才被删除。 你可以通过执行Material.dispose()方法来废置材质。

释放纹理

对材质的废置不会对纹理造成影响。它们是分离的,因此一个纹理可以同时被多个材质所使用。 每当你创建一个Texture实例的时候,three.js在内部会创建一个WebGLTexture实例。 和buffer相似,该对象只能通过调用Texture.dispose()来删除。

释放Geomertry

几何体常用来表示定义为属性集合的顶点信息,three.js在内部为每一个属性创建一个WebGLBuffer类型的对象。 这些实体仅有在调用BufferGeometry.dispose()的时候才会被删除。 如果应用程序中的几何体已废弃,请执行该方法以释放所有相关资源。

在threejs中释放材质、纹理、Geomertry基本是同时进行的,因此绝大部分情况我们只要执行以下代码就可以进行内存的释放

function dispose( object3D)
{
    // Dispose children first
    for ( let childIndex = 0; childIndex < object3D.children.length; ++childIndex )
    {
        this.dispose( object3D.children[childIndex] );
    }

    object3D.children = [];

    if ( object3D instanceof THREE.Mesh )
    {
        // Geometry
        object3D.geometry.dispose();

        // Material(s)
        if ( object3D.material instanceof THREE.MultiMaterial )
        {
            for ( let matIndex = 0; matIndex < object3D.material.materials.length; ++matIndex )
            {
                object3D.material.materials[matIndex].dispose();
                object3D.material.materials[matIndex] = null;
            }
            object3D.material.materials = [];
        }

        if ( object3D.material.dispose )
        {
            object3D.material.dispose();
            object3D.material = null;
        }
    }

    // Remove from parent
    if ( object3D.parent )
        object3D.parent.remove( object3D );

    object3D = null;
}

总结

通过本文相信你已了解了内存管理的优化方法,目前介绍的优化方式在实际开发过程中可以进行有机组合使用,这样更好的降低内存

参考:

zhuanlan.zhihu.com/p/154425898

threejs.org/docs/#manua…

cloud.tencent.com/developer/a…

关注Mapmost,持续更新GIS、三维美术、计算机技术干货

Mapmost是一套以三维地图和时空计算为特色的数字孪生底座平台,包含了空间数据管理工具(Studio)、应用开发工具(SDK)、应用创作工具(Alpha)。平台能力已覆盖城市时空数据的集成、多源数据资源的发布管理,以及数字孪生应用开发工具链,满足企业开发者用户快速搭建数字孪生场景的切实需求,助力实现行业领先。

欢迎进入官网体验使用:Mapmost——让人与机器联合创作成为新常态

转载自:https://juejin.cn/post/7379526934995763251
评论
请登录