17

我想使用 WebGL 制作一个 Flickr 照片流的 3D 小画廊。看起来 WebGL 只允许将尺寸为 2 次方的方形图像用作纹理。我需要能够显示任何比例和尺寸的图像。我可以看到,如果我将图像数据复制到另一个最接近正方形尺寸的图像中,然后使用纹理坐标使其正确显示。问题是,如果我错了,请纠正我,我不能在 JavaScript 中进行图像处理,需要运行 ASP.NET、Java 或类似的服务器来为我处理,然后 WebGL 才能得到它的手在上面。

有没有一种方法可以在 WebGL 和 JavaScript 中使用任意大小的图像,而无需服务器充当中间人图像处理器?

4

5 回答 5

17

如果您执行以下操作,我对 npot 纹理(FF 和 chrome)没有任何问题:

texParameteri(TEXTURE_2D, TEXTURE_MAG_FILTER, LINEAR);
texParameteri(TEXTURE_2D, TEXTURE_MIN_FILTER, LINEAR);
texParameteri(TEXTURE_2D, TEXTURE_WRAP_S, CLAMP_TO_EDGE);
texParameteri(TEXTURE_2D, TEXTURE_WRAP_T, CLAMP_TO_EDGE);
于 2010-11-26T19:22:57.430 回答
9

这个页面很好地总结了这种情况(或多或少地重申了这里其他回答者已经说过的话)。基本上,WebGL 不支持带有 mipmapping 和/或重复的 NPOT 纹理。如果没有这些模式就无法逃脱,可以在 2D 画布中调整纹理的大小。该页面包含一些用于调整画布大小的方便代码。

更新: WebGL2 是 WebGL 的下一个版本,支持 NPOT 纹理

于 2011-07-18T16:05:57.367 回答
3

@EnabrenTane 提供的参考资料非常有帮助。两种纹理的非幂次支持

虽然 OpenGL 2.0 及更高版本的桌面版完全支持非二次幂 (NPOT) 纹理,但 OpenGL ES 2.0 和 WebGL 仅提供有限的 NPOT 支持。这些限制在 OpenGL ES 2.0 规范的第 3.8.2 节“着色器执行”和第 3.7.11 节“Mipmap 生成”中定义,并在此处进行了总结:

  • 如果当前绑定到目标的纹理的级别 0 图像具有 NPOT 宽度或高度,则 generateMipmap(target) 会生成 INVALID_OPERATION 错误。
  • 在着色器中对 NPOT 纹理进行采样将产生 RGBA 颜色 (0, 0, 0, 1),如果:
    • 缩小过滤器设置为 NEAREST 或 LINEAR 以外的任何值:换句话说,如果它使用 mipmapped 过滤器之一。
    • 重复模式设置为除 CLAMP_TO_EDGE 之外的任何值;不支持重复 NPOT 纹理。
于 2019-01-17T13:40:27.677 回答
2

I don't understand the low-level details well enough to completely answer your question, but here are some things I found:

This post is not encouraging:

Texture handling has been updated in Minefield so that [it] better matches the specification; previously it was quite forgiving [...] and allowed you to use textures that weren’t really valid from a WebGL viewpoint. Now it doesn’t [...] you’ll see an error message saying “A texture is going to be rendered as if it were black, as per the OpenGL ES 2.0.24 spec section 3.8.2, because it is a 2D texture, with a minification filter not requiring a mipmap, with its width or height not a power of two, and with a wrap mode different from CLAMP_TO_EDGE.”</p>

I don't know if those extra conditions apply to your app. See also the OpenGL ES spec.

This thread goes fairly in-depth on support for "NPOT":

OpenGL supports NPOT textures in two ways. The first is called "Rectangle Textures" (RT), which can be any size, but can't be repeating, mip-mapped or have borders. And rather than using 0-1 texture coordinates, they use 0-w, 0-h. OpenGL Also supports true NPOT textures, which have similar constraints to RT, but which use the normal 0-1 texture coordinates.

The issue is that some older hardware (and when I say "older" I mean hardware from 2005) only supports RT, not true NPOT. It's not possible to emulate NPOT when you just have RT support because in GLSL you use a different sampler for RT (sampler2DRect vs sampler2D).

OpenGL ES only supports NPOT, not RT.

...

A WebGL implementation can scale up NPOT texture data to the next highest power of two dimension during texImage2D and texSubImage2D calls. This wouldn't involve any API changes. O3D does this in some cases as proof that the technique can work without the end user knowing. I think it would be a bad idea to expose rectangular textures in the WebGL API; they are definitely not the path forward.

So, take that FWIW...

于 2010-10-04T20:32:26.823 回答
2

一个简单的解决方案是使用 2d 画布调整大小并将其用作纹理。

于 2010-12-19T16:29:50.023 回答