RENDER警告:绑定到纹理单元0的纹理不可渲染。它可能不是2的幂并且具有不兼容的纹理过滤

时间:2017-11-18 16:06:44

标签: webgl2

所以我试图使用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;

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

问题是您正在使用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>
&#13;
&#13;
&#13;