javascript - 使用 RGB 格式在 WebGL 中创建纹理时出错

标签 javascript webgl

尝试从具有 RGBA 格式的数据创建一个 1px x 4px 纹理,就像这样:

const texture = gl.createTexture()
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 1, 4, 0, gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array([
  255, 0, 0, 255,
  0, 255, 0, 255,
  0, 0, 255, 255,
  255, 255, 0, 255
]))
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)

但是尝试像这样对 RGB 格式做同样的事情:

const texture = gl.createTexture()
gl.activeTexture(gl.TEXTURE0)
gl.bindTexture(gl.TEXTURE_2D, texture)
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 4, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([
  255, 0, 0,
  0, 255, 0,
  0, 0, 255,
  255, 255, 0
]))
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST)
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST)

在 Firefox 中给出这个错误:

Error: WebGL warning: texImage2D: Desired upload requires more data than is available: (3 rows plus 1 pixels needed, 3 rows plus 0 pixels available)

Chrome 中的这个错误:

WebGL: INVALID_OPERATION: texImage2D: ArrayBufferView not big enough for request

交换 gl.texImage2D 的宽度和高度参数,所以我有一个 4px x 1px 的纹理然后可以与 gl.RGB 一起使用,但是 2px x 2px 的纹理不能。我在这里犯了什么错误/误解?

最佳答案

由于 WebGL 1.0 基于 OpenGL ES 2.0 API,我将引用 OpenGL ES 2.0 refpages glPixelStorei

GL_UNPACK_ALIGNMENT

Specifies the alignment requirements for the start of each pixel row in memory. The allowable values are 1 (byte-alignment), 2 (rows aligned to even-numbered bytes), 4 (word-alignment), and 8 (rows start on double-word boundaries).

UNPACK_ALIGNMENT 对齐参数的初始值为 4。

如果指定一个RGB纹理,宽度为4个像素,那么一行的大小为3 * 4 = 12个字节。
如果纹理的高度为1,则纹理的预期大小为12 * 1 = 12。

但是,如果您指定一个 RGB 纹理,其大小为 1 个像素,则一行的大小为 3 * 1 = 3 个字节。
如果 UNPACK_ALIGNMENT 为 4,则此大小对齐为 4 个字节。
如果纹理的高度为4,则纹理的预期大小为4*4 = 16字节。

第二种情况与您用来初始化纹理的数据数组不匹配,这会导致错误。

要解决这个问题,您必须将纹理的每一行对齐到 4 个字节:

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 4, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([
    255, 0,   0,   0, // add 1 byte for alignment to 4 bytes
    0,   255, 0,   0, // add 1 byte
    0,   0,   255, 0, // add 1 byte
    255, 255, 0,   0  // add 1 byte
]))

或通过 gl.pixelStoreigl.UNPACK_ALIGNMENT 参数设置为 1| :

gl.pixelStorei( gl.UNPACK_ALIGNMENT, 1 )
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, 1, 4, 0, gl.RGB, gl.UNSIGNED_BYTE, new Uint8Array([
    255, 0,   0,
    0,   255, 0,
    0,   0,   255,
    255, 255, 0
]))

关于javascript - 使用 RGB 格式在 WebGL 中创建纹理时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51582282/

相关文章:

javascript - glsify - 错误 'You may need an appropriate loader to handle this file type' ?

javascript - 这段 d3 代码在哪里执行?

webgl - 在 WebGL 片段着色器中绘制网格

javascript - MobX:从 observable.map() 引用对象

javascript - 将 DropzoneJS 与 Django 一起使用时出现 MultiValueDictKeyError

javascript - 日期选择器数据未发送到下拉列表

javascript - PhoneGap 2.2 : how does the new bridge work?

azure - 如何在服务器端运行 WebGL 和 JavaScript?

javascript - 在 WebGL 中绘制金字塔纹理

html - 如何在 Sublime 中为 webgl/glsl 内联脚本标签获得语法高亮