尝试将WebGL纹理清除为纯色

时间:2012-06-03 22:18:37

标签: javascript webgl

我有一系列纹理堆叠在一起(使用mip-map-style分辨率金字塔)来获得最终图像。

由于它们的堆叠方式,当它们没有被有意义的图像数据填充时,有必要将它们初始化为无符号的int值128。 IE,128为零,因为渲染着色器将从每个纹理值中减去.5,这允许后续的金字塔图层以正值或负值偏移最终图像。

我似乎无法弄清楚如何将(单通道GL_LUMINANCE)纹理初始化为值!

我已经尝试将其设置为渲染缓冲区目标并渲染多边形,但FBO似乎被标记为不完整。我也尝试将它作为渲染缓冲区目标并使用gl.clear(gl.COLOR_BUFFER_BIT),但又被认为是不完整的。

显而易见的事情是使用gl.texSubImage2D()复制值,但这似乎很慢......也许这是唯一的方法?我希望有一些更优雅的东西,不需要分配如此多的内存(至少是一个帧的价值单一值)而且速度很慢(因为当所有数据都是单个值时,所有数据都必须写入缓冲区)。 / p>

在WebGL中将纹理设置为(默认)值的唯一方法似乎是调整大小或分配它,将其设置为全零。

此外,似乎没有像gl.SIGNED_BYTE这样的复制模式允许零为零(IE,有符号值进入)......但这也无法解决初始化纹理的问题到一个值(在这种情况下,为零)。

有什么想法吗?如何将一个WebGL纹理初始化为一个值,而不仅仅是简单地将值复制到其中?

2 个答案:

答案 0 :(得分:2)

遗憾的是,WebGL所基于的OpenGL ES 2.0规范无法保证能够渲染到特定类型的纹理。判断它是否有效的唯一方法是创建纹理,将其附加到帧缓冲区,然后调用checkFramebufferStatus并查看它是否返回FRAMEBUFFER_COMPLETE。不幸的是,它在很多情况下都没有。

如果你使用RGBA纹理赔率是可行的。所以,在我的头脑中,你的选择是

  1. 使用RGBA纹理并渲染128,128,128,???在fbo
  2. 使用LUMINANCE纹理并调用texImage2D
  3. 使用LUMINANCE纹理并使用backbuffer调用copyTexImage2D或将正确大小的fbo清除为您想要的颜色(尽管不能保证这是快速AFAIK)

答案 1 :(得分:0)

根据我的经验(主要使用OS中的Chrome),使用Canvas初始化纹理很快。我想这是因为浏览器分配Canvas并在GPU上绘制所有内容,并且它的WebGL实现使用与Canvas相同的GL上下文,因此没有巨大的CPU到GPU内存传输。

        // Quickly init texture to (128,128,128)
        var canvas = this._canvas = document.createElement("canvas");
        canvas.width = wTex;
        canvas.height = hTex;
        var ctx = this._ctx = canvas.getContext("2d");
        ctx.fillStyle = "#808080";
        ctx.fillRect(0, 0, wTex, hTex);
        gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGB, gl.RGB, gl.UNSIGNED_BYTE, canvas);