glGenerateMipmap - 非幂2

时间:2017-08-01 06:39:12

标签: textures webgl

环境Ubuntu 17.04,Chrome 60。

在没有警告/错误的情况下运行此示例本地:https://github.com/mdn/webgl-examples/tree/gh-pages/tutorial/sample6

然后在此处用cubetexture.png图片替换non-power-of-2https://github.com/mdn/webgl-examples/blob/gh-pages/tutorial/sample6/webgl-demo.js#L220

得到预期的警告/错误:

[.Offscreen-For-WebGL-0x13d050ba2c00]RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering.

[.Offscreen-For-WebGL-0x13d050ba2c00]GL ERROR :GL_INVALID_OPERATION : glGenerateMipmap: Can not generate mips

接下来添加参数:

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);

然后在没有警告的情况下运行正常,但仍出现意外错误:

[.Offscreen-For-WebGL-0x13d050fb4000]GL ERROR :GL_INVALID_OPERATION : glGenerateMipmap: Can not generate mips

除了错误消息,non-power-of-2图像在多维数据集中呈现正常。 Firefox 54中的行为相同。这里有什么提示?

2 个答案:

答案 0 :(得分:1)

您无法为WebGL1中的2-power-of-2纹理生成mipmap。这就是重点,WebGL1期间不支持mipmapped非2次幂纹理。所以你设置过滤使它只使用0级

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);

这意味着没有理由生成mips,因为它们永远不会被使用。 See this article

答案 1 :(得分:1)

WebGL基于OpenGL ES 2.0。虽然WebGL的在线文档定义了可用的功能,但是对于限制和某些特定行为,您需要解决OpenGL ES 2.0完整规范。 它可以在https://www.khronos.org/registry/OpenGL/specs/es/2.0/es_full_spec_2.0.pdf

获得

3.7.1中的 TexImage2D 功能

  

如果level大于零,并且宽度或高度不是a   功率为2时,生成错误INVALID_VALUE

3.7.11 中的 GenerateMipmap

  

如果零级数组的宽度或高度不是幂   或者两个,生成错误INVALID_OPERATION

<强>结论

对于非二次幂纹理,您只能拥有第一个(零)级别。并且你不能为非二次幂纹理生成mipmap。

另外值得注意的是,非二次幂纹理还有其他限制:

文章 3.7

  

如果mipmap中任何数组的任何维度不是2的幂(例如,   如果执行如上所述的向下舍入),则mipmap是   描述为非二次幂纹理。非幂二纹理   对允许的纹理包装模式和过滤器有限制,如   在3.8.2节中描述

3.8.2

  

从片段着色器调用采样器将返回(R,G,B,A)=   (0,0,0,1)如果满足以下任一条件:

     

...

     

•调用二维采样器,即相应的纹理图像   是一个非二次幂图像(如Mipmapping讨论中所述)   部分3.7.7),并且纹理包装模式不是   CLAMP_TO_EDGE,或缩小过滤器既不是最近也不是   线性的。