【问题标题】:RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering渲染警告:绑定到纹理单元 0 的纹理不可渲染。它可能不是 2 的幂并且具有不兼容的纹理过滤
【发布时间】:2017-11-19 02:03:03
【问题描述】:

所以我正在尝试使用 WebGL 来卸载稍后图像所需的一些数据处理。

我有两个阶段,首先我尝试将无符号整数“渲染”到纹理。 在第二遍中,我从这个纹理中读取并渲染到画布上。

如果我将纹理定义为 RGBA,则没有问题。但是当我将格式更改为 RGBA32UI 时,我不断收到:

RENDER WARNING: texture bound to texture unit 0 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering

我将着色器减少到单个像素,但仍然出现相同的错误。

纹理是这样初始化的:

var texture = gl.createTexture();

gl.activeTexture(gl.TEXTURE0 + 0);

gl.bindTexture(gl.TEXTURE_2D, texture);

{
  var level = 0;
  var internalFormat = gl.RGBA32UI;
  var border = 0;
  var format = gl.RGBA_INTEGER;
  var type = gl.UNSIGNED_INT;
  var data = null;
  gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
    1, 1, border, format, type, data);

  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
  gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
  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);
}

var fb = gl.createFramebuffer();
gl.bindFramebuffer(gl.FRAMEBUFFER, fb);

var level = 0;
var attachmentPoint = gl.COLOR_ATTACHMENT1;
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, texture, level);

在片段着色器中我有两种颜色类型:

layout(location = FLOAT_COLOR_LOCATION) out vec4 float_color;
layout(location = UINT_COLOR_LOCATION) out uvec4 uint_color;

感谢您的帮助!

【问题讨论】:

    标签: webgl2


    【解决方案1】:

    问题是您正在使用 COLOR_ATTACHMENT1 并跳过 COLOR_ATTACHMENT0。

    IIRC 您需要从附件 0 开始,然后逐步向上。

    另外,您可能应该使用gl.checkFramebufferStatus 检查帧缓冲区是否完整

    此外,整数纹理不可过滤,因此您需要将 gl.LINEAR 更改为 gl.NEAREST

    const gl = document.createElement("canvas").getContext("webgl2");
    
    testAttachment(gl.COLOR_ATTACHMENT1);
    testAttachment(gl.COLOR_ATTACHMENT0);
    
    function testAttachment(attachmentPoint) {
    
      function createTexture() {
        var texture = gl.createTexture();
    
        gl.bindTexture(gl.TEXTURE_2D, texture);
        var level = 0;
        var internalFormat = gl.RGBA32UI;
        var border = 0;
        var format = gl.RGBA_INTEGER;
        var type = gl.UNSIGNED_INT;
        var data = null;
        gl.texImage2D(gl.TEXTURE_2D, level, internalFormat,
          1, 1, border, format, type, data);
    
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
        gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
        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);
        return texture;
      }
      
      var texture = createTexture();
    
      var fb = gl.createFramebuffer();
      gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
    
      var level = 0;
      gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, texture, level);
    
      const status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
    
      console.log(glEnumToString(gl, attachmentPoint), glEnumToString(gl, status));
      
      if (status !== gl.FRAMEBUFFER_COMPLETE) {
        return;
      }
      
      const vs = `#version 300 es
      void main() {
         gl_Position = vec4(0,0,0,1);
         gl_PointSize = 100.0;
      }
      `;
      const fs = `#version 300 es
      uniform highp usampler2D color;
      out uvec4 outColor;
      void main() {
        outColor = texture(color, gl_PointCoord);
      }
      `;
      
      const prg = twgl.createProgram(gl, [vs, fs]);
      gl.useProgram(prg);
      
      // need a different input texture than output texture
      const inTex = createTexture();
      
      // no need to set uniforms since they default to 0
      // so using texture unit 0
      gl.drawArrays(gl.POINTS, 0, 1);
    
      // check that it rendered without error
      console.log(glEnumToString(gl, gl.getError()));
    }
    
    function glEnumToString(gl, value) {
      if (value === 0) { 
        return "NONE";
      }
      for (let key in gl) {
        if (gl[key] === value) {
          return key;
        }
      }
      return "0x" + value.toString(16);
    }
    <script src="https://twgljs.org/dist/4.x/twgl.min.js"></script>

    【讨论】:

    • 它没有帮助。我仍然从第二次绘图调用中得到同样的错误。
    • 那么你有两个问题。如果不添加附件 0,我的样本将返回 FRAMEBUFFER_UNSUPPORTED。在附件 0 上,它返回 FRAMEBUFFER_COMPLETE。其实我很确定你的第二个问题是你不能在整数纹理上使用LINEAR过滤
    • 我添加了你有用的函数'glEnumToString'的使用。两次都返回了 FRAMEBUFFER_COMPLETE。
    • 更新了样本以测试两者,它为我返回 FRAMEBUFFER_UNSUPPORTED 和附件 1。See screenshot
    • :-O 没注意到它是线性的!它应该是最近的。感谢您的提示!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-08
    • 1970-01-01
    • 1970-01-01
    • 2014-08-09
    相关资源
    最近更新 更多