【问题标题】:Threejs 2000 textures bottleneckThreejs 2000 纹理瓶颈
【发布时间】:2015-06-03 11:51:22
【问题描述】:

几个月以来,我一直在使用three.js。最近我们启动了一个 three.js 应用程序 - 项目,它是一个 3d webgl 产品目录(想象平面,产品图像作为纹理 512x512),将 base64 图像存储到浏览器 indexeddb 中,并在应用程序加载时创建产品目录。

但是我们有性能问题,假设一个产品类别可能有 100 种甚至更多产品,产品总数可能高达 10000 个。

在每个类别中,我们以特定的方式展示我们的模型(平面)。因为应用程序应该提供良好的用户体验,所以一切都被预加载,纹理在应用程序启动之前生成并保存在内存中。这是问题开始的地方......

目前在具有 4gb 内存和与 cpu 共享内存的板载 gpu 的硬件上导致 chrome 崩溃。用户也可以通过触摸事件拖动每个模型。

另一方面,我们尝试按需加载纹理,但这对用户体验影响很大,可能会冻结应用 1-2 秒。

目前正在为每个产品创建没有任何纹理的材料。纹理根据产品 ID 存储在不同的对象上,当每个类别加载时,我们将纹理分配给每个模型。我们还处理不再可见的材质的纹理。

我的问题是必须存储 2000 个纹理不是内存效率高,并导致 chrome 在低徽章硬件上崩溃。另一方面,如果我按需加载纹理,用户体验会冻结几秒钟......

请记住,每个模型都可以通过用户触摸进行拖动。

我没有遇到任何编码问题,因此除非您想看点什么,否则没有必要显示任何代码。我主要关心的是建筑。

如果有更高效的方式来实现这样的应用程序...我想到了粒子系统,但是为每个粒子设置不同的纹理会导致相同的结果?

【问题讨论】:

    标签: javascript three.js webgl


    【解决方案1】:

    您需要调查一下为什么您的加载过程会冻结应用程序几秒钟,这听起来太长了。

    内存

    考虑您的数据大小,假设您的 512x512 纹理每个大小约为 256kb,对于 2000 个纹理,您仍试图存储 500MB(+ ~33% base64 开销) indexedDB 中的数据,目前限制为 5MB。因此,无论哪种方式,您都必须按需加载纹理。

    纹理图集/Megatextures:

    在这里使用巨型纹理/纹理图集将不是可行的方法。 WebGL 不支持以内存有效的方式实现这一点所必需的功能。您需要以最大纹理大小(8k 和 16k 之间)分配纹理,然后将纹理平铺到其中,跟踪当前使用的纹理,以便您可以使用新的所需纹理更新图集的任意部分。一旦你用完了图集图块,你需要以最大尺寸分配一个新的图集纹理,这就是你会遇到真正的打嗝和崩溃的地方,因为你无法查询有多少 GPU 内存可用。

    实现自适应加载队列:

    var textureQueue = [];
    // on visible
    if (loadedTextures[textureID])
        return object.texture = loadedTextures[textureID];
    
    textureQueue.push(textureID);
    object.texture = loadingTexture;
    
    // each update
    var
        startLoading = window.performance.now(),
        currentTime = startLoading,
        loadID
    ;
    while(
        currentTime - startLoading < 10/*ms*/ &&
        loadID = textureQueue.shift()
    ) {
        /** load and assign texture here **/
        currentTime = window.performance.now();
    }
    

    【讨论】:

    • 据我所见的问题是,一旦您必须按需显示 100 个产品,生成 100 个纹理(检索 base64 字符串 -> 创建新图像() -> 创建纹理(图像))正在停止系统。而且我很确定这是因为传递给 gpu 的数据过于频繁。我也想知道巨型纹理......
    • 也是,我同意数据量太大
    • 您不必在一个框架内创建它们,对吗?稍后我会根据巨型纹理更新我的答案。
    • hmmm 你说什么“你不必在一个框架内创建它们,对吗?”让我开始思考......所以如果我将产品分解成块让我们说每帧 10 个或类似的东西,你不觉得可能真的有用吗?
    • @Syd 我添加了一些代码来显示自适应加载队列。
    猜你喜欢
    • 2013-03-09
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多