【问题标题】:Three.js / WebGL Loading Large Amounts of Texture Data at Once, How To?Three.js / WebGL 一次加载大量纹理数据,怎么做?
【发布时间】:2013-06-24 16:44:00
【问题描述】:

最近我有一个项目,我需要使用画布创建大量大型纹理,然后将它们上传到 GPU。当页面加载时,我一直在用完内存(chrome 崩溃)并且“窒息”,因为所有纹理都同时通过 GPU 总线推送。

我决定错开texture.needsUpdate = true; 调用,这样就不会在一次渲染更新中将所有纹理推送到 GPU。

这可行,但我对任何其他解决方案感到好奇......

我发布此内容是因为它可能对其他在启动时加载所有纹理的人有所帮助...

【问题讨论】:

  • 我也有类似的问题。我加载了大约 50MB 的 jpeg 数据,我承认这很大,但内存开始被消耗,最终使用了超过 8GB 的​​ RAM。我已经确定纹理是问题所在。它们是从 JSON 加载器加载的。
  • 查看这篇关于使用压缩纹理的帖子,将解释为什么你的 JPG 也会爆炸:blog.tojicode.com/2011/12/compressed-textures-in-webgl.html
  • 我会添加一些我发现的东西。它在 2 种或更多材质上使用相同的纹理贴图(不同的着色属性)。 JSON 加载器每次将它们加载为单独的纹理,而不是为每个文件加载 1 个纹理(它应该根据文件名进行组合,这可能被视为错误或功能请求)。

标签: javascript memory three.js webgl


【解决方案1】:

将纹理剔除到零是阻止过度负载的最佳方法。从根本上使它们更小将改善后续的一切。

虽然这篇文章很旧,但它在谷歌上显示为最高结果。因此,这里有一些对任何其他初学者 3D 游戏/网络开发人员的方便提示。

纹理以固定位块添加到缓冲区中,块越少越好,但是以 2 的幂的分辨率创建纹理将防止加载一半块并浪费位/时间。的幂是指在每个实例中加倍的数字序列(2、4、8、16、32、64),保持这个公式可以防止丢失位。

查看屏幕上纹理的大小。您的来源可能是 1024x1024,但如果它在屏幕上只有 20 像素高,或者您的输出画布 id 为 480x640,那么所有额外信息都会丢失。减少纹理以匹配屏幕上的内容。

同样,如果您不使用纹理上的颜色,则有时您可以使用顶点着色和/或灯光来为纹理添加背面细节,在这种情况下,您可以将纹理保存为灰度图像,或者通过索引来限制调色板的大小。

.gif 是小纹理的绝佳格式,而 Jpeg 更适合压缩大纹理。如果您使用 .gif,您还可以通过将纹理分组到一个图像和匹配它们的调色板来节省空间。请记住整个 Zelda LTTP 游戏仅使用 256 种颜色。有多种方法可以创建 RGB 索引数组并将图像存储为从中提取的原始数字。

如果您从 JSON 导入/导出,请记住您的图像默认为原始 32 位 .png 文件。它们本身很大,当作为位数据添加到 JSON 对象文件的末尾时会变得更大。 仅导出网格数据并通过源代码中的 JS 将纹理添加回其中,可让您使用更多格式并优化更多纹理。

【讨论】:

  • 这并没有真正解决问题,而是表明我们首先没有大纹理。虽然我很欣赏你的细节,但我知道位和字节如何工作的来龙去脉。事实仍然是,它们必须在某个时候被发送到 VRAM,我很好奇不同的用户如何避免溢出缓冲区和崩溃他们的页面,如果一次发送所有纹理,这是一个典型的场景。
猜你喜欢
  • 2020-09-07
  • 1970-01-01
  • 2014-04-02
  • 1970-01-01
  • 2014-03-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-11-12
相关资源
最近更新 更多