尝试将 WebGL 纹理清除为纯色



我有一系列纹理堆叠在一起(使用mip-map风格的分辨率金字塔)以达到最终图像。

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

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

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

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

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

此外,似乎没有像gl这样的复制模式。SIGNED_BYTE允许零为零(IE,有符号值进来)...但这也不能解决将纹理初始化为单个值(在本例中为零)的问题。

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

不幸的是,

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

仅保证 3 种组合关闭附件有效

  • COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE纹理
  • COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE纹理 + DEPTH_ATTACHMENT = 渲染缓冲区DEPTH_COMPONENT16
  • COLOR_ATTACHMENT0 = RGBA/UNSIGNED_BYTE纹理 + DEPTH_STENCIL_ATTACHMENT = DEPTH_STENCIL渲染缓冲区

所以你的选择是

  1. 使用 RGBA 纹理并在 FBO 中渲染 128,128,128,???(或 gl.clear it)

  2. 使用亮度纹理并调用texImage2D

  3. 使用亮度纹理并使用后台缓冲区或清除为所需颜色的正确大小的 fbo 调用 copyTexImage2D(尽管不能保证这是快速的 AFAIK)

根据我的经验(主要是OSX中的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);

最新更新