【问题标题】:Loading PNG images but using them as COMPRESSED_RGBA_S3TC_DXT5_EXT in WebGL?加载PNG图像但在WebGL中将它们用作COMPRESSED_RGBA_S3TC_DXT5_EXT?
【发布时间】:2014-11-16 07:57:24
【问题描述】:

我正在尝试在 WebGL 中加载图像,然后将它们上传到 GPU。我想使用压缩纹理格式,即使原始图像是未压缩/无损的。

要上传,这就是我正在做的:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, textureSource);

在上面的代码中,textureSource 是一个加载的(比如“texture.png”)。

一切正常,但我想加载WEBGL_compressed_texture_s3tc 格式(COMPRESSED_RGB_S3TC_DXT1_EXT)以压缩方式存储图像。

我确保扩展程序可用并已启用...

var ext = gl.getExtension("WEBGL_compressed_texture_s3tc");
var fmt = ext.COMPRESSED_RGBA_S3TC_DXT5_EXT;
console.log(fmt); // 33779

但是我不能将它用作一种格式。使用texImage2D() 不起作用:

gl.texImage2D(gl.TEXTURE_2D, 0, fmt, fmt, gl.UNSIGNED_BYTE, textureSource);
// WebGL: INVALID_ENUM: texImage2D: invalid texture format
// [.WebGLRenderingContext]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'

预期的方法是compressedTexImage2D(),但这也不是很有帮助:

gl.compressedTexImage2D(gl.TEXTURE_2D, 0, fmt, 256, 256, 0, texture.source);
// Uncaught TypeError: Failed to execute 'compressedTexImage2D' on 'WebGLRenderingContext': parameter 7 is not of type 'ArrayBufferView'.

这显然是因为 compressedTexImage2D() 需要一个带有实际 DDS/DXT 数据的 Uint8Array,而不是像我传递的那样的 JavaScript 图像。

显而易见的解决方案是以原始 DDS 格式上传文件 - 已在其他地方压缩的文件。但这就是我要避免的:在我当前的工作流程中,将图像保留为原始格式而不是预压缩它们(或重复)是有意义的。

我的问题是这样的:我仍然可以使用原始 PNG 图像,加载它们,并让它们以压缩格式上传到 GPU 吗?换句话说,我可以即时将纹理压缩为 DXT1/5 格式吗?

我正在做的事情有点受视频内存的限制,所以任何节省都会很棒。我设法通过使用UNSIGNED_SHORT_4_4_4_4 和其他数据类型来最小化纹理使用的空间,这是一个好的开始,但我也想尝试使用本机压缩。

我没有找到关于该主题的太多文档,也没有在其他流行库(Three.js、Pixi 等)上找到相关代码,这让我相信我的请求非常愚蠢,但我想明白为什么。 This page 暗示了许可问题,这可能是 WebGL 没有正确压缩文件的方法,也不允许浏览器支持图像对象的原因。

【问题讨论】:

  • 该扩展只允许您上传预压缩的图像数据。将原始 RGB[A] 数据编码为 DXT 不是 OpenGL ES / WebGL 的一部分。如果您想使用 PNG 进行存储,您必须自己对图像进行块编码,然后再将其传递给 WebGL。

标签: opengl-es webgl webgl-extensions


【解决方案1】:

我是否仍然可以使用原始 PNG 图像、加载它们并让它们以压缩格式上传到 GPU?换句话说,我可以即时将纹理压缩为 DXT1/5 格式吗?

据我所知:

我只在桌面和嵌入式 GL 上工作,但即使没有专门的代码或库,也无法动态压缩纹理。

(而且,如果您的纹理过于详细或在小桶中有很多不同的颜色,那么这些 DXT 格式也不是很好。很可能您最好只使用较小的纹理,因为 DXT1 压缩到原始大小的 1/8 和 DXT5 到 1/4(这就像将纹理的分辨率减半)。

【讨论】:

    【解决方案2】:

    理论上我认为您可以使用 Javascript 将 PNG 压缩为 DXT。我想那会很生气:)

    更好地预先使用本机代码进行编码。支持 PNG 内容的一个选项是使用资产代理在服务器端进行即时转换(我们的合作伙伴公司托管 http://www.meshmoon.com/ 就是这样做的)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-08-26
      • 1970-01-01
      • 2014-02-22
      • 1970-01-01
      • 1970-01-01
      • 2020-04-03
      • 1970-01-01
      相关资源
      最近更新 更多