无法将Alpha通道渲染为WebGL中的纹理

时间:2016-06-28 08:20:31

标签: textures webgl

我正在读取具有图像数据的DICOM文件的alpha通道,之后我使用this tutorial进行解析和渲染,此外我将alpha通道转发到webgl程序进行渲染纹理。

但是,它适用于少量图像,对某些图像也有效。 以下是一些用例:

SNO 宽度 高度 状态

  1. 宽度:628,高度:888,Alpha通道长度:557664(正常工作)。

  2. 宽度:448,高度:612,Alpha通道长度:274176(工作正常)。

  3. 宽度:446,高度:612,Alpha通道长度:272952(不能正常工作)。

  4. 宽度:2219,高度:1200,Alpha通道长度:2662800(不能正常工作)。

  5. 对于用例3和4,我收到以下错误消息:

    • 错误:WebGL:texImage2D:提供的缓冲区太小。 (需要2663999,有2662800)
    • 错误:WebGL:generateMipmap:纹理的基本级别没有二维幂。

    有什么建议吗?

1 个答案:

答案 0 :(得分:0)

错误实际上就是他们所说的。

  1. Error: WebGL: texImage2D: Provided buffer is too small. (needs 2663999, has 2662800)

    您调用了gl.texImage2D,但纹理的尺寸大于您提供的数据。

    例如,如果你这样做

    var width = 16;
    var height = 16;
    gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0,
                  gl.RGBA, gl.UNSIGNED_BYTE, new Uint8Array(10));
    

    你得到同样的错误。你指定了一个纹理16x16xRGBA(4) 表示数据必须是16 * 16 * 4或1024字节,但上面的代码只传递10个字节

    要注意的一件事是UNPACK_ALIGNMENT设置。默认为4 这意味着每行数据将填充为4个字节。换句话说,7x3的alpha纹理将是

    width = 7
    height = 3
    bytesPerPixel = 1   // gl.ALPHA
    unpaddedRowSize = width * bytesPerPixel
    paddedRowSize = Math.floor((minBytesPerRow + 3) / 4) * 4;  // = 8
    requiredDataSize = (height - 1 * paddedRowSize) + unpaddedRowSize
    

    您可能认为ALPHA只需要7x3或21个字节但实际上需要8 + 8 + 7或23个字节,因为除了最后一行之外的每一行都填充为4的倍数

    您可以通过调用

    告诉WebGL将UNPACK_ALIGNMENT设置为1
    gl.pixelStorei(gl.UNPACK_ALIGNMENT, 1);
    

    现在它只需要21个字节,因为它将不再填充行。

  2. Error: WebGL: generateMipmap: The base level of the texture does not have power-of-two dimensions

    除非纹理在两个维度中都是2的幂,否则WebGL 1.0不能使用mips。在任一维度中,您的示例纹理都不是2的幂,因此您无法使用mips,也无法为它们调用gl.generateMipmap

    相反,您必须将纹理过滤设置为仅使用顶部(0级)mip

    gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); // or gl.NEAREST
    

    并且您必须将换行设置为CLAMP_TO_EDGE

    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);
    

    WebGL 2.0删除了这些限制