Кадровые буферы WebGL: gl.clearColor не влияет на альфа-канал в FBO

Я пытаюсь перенести что-то из OpenGl в WebGL. Я нахожу это по какой-то причине, gl.clearColor(0,0,0,0) По-видимому, не изменяет альфа-значения вообще при вызове из моего кадрового буфера, в отличие от попытки вызова этой функции в основном буферном буфере, что приводит к правильному отображению прозрачного буферного буфера.

Я полагаю, что у меня правильно настроена текстура RGBA на Fbo-

  • внутренний формат RGBA16F
  • формат RGBA
  • texel установлен на FLOAT

(обратите внимание, я помню, что обычно это также RGBA для внутреннего формата, но это выдает ошибку в WebGL2 как недопустимую комбинацию с другими настройками)

У кого-нибудь есть какие-либо подсказки относительно того, как заставить альфа-прозрачность работать в фреймбуфере? Любые идеи приветствуются.

РЕДАКТИРОВАТЬ: забыл отметить, что в моем коде OpenGl я не использую смешивание

1 ответ

Решение

Вы включили рендеринг для текстур с плавающей точкой? Без проверки и включения EXT_color_buffer_float Расширение вы не можете визуализировать с плавающей точкой или половиной целей с плавающей точкой.

В противном случае это работает для ниже.

function main() {
  const gl = document.querySelector("canvas").getContext("webgl2");
  if (!gl) {
    alert("need WebGL2");
    return;
  }
  const ext = gl.getExtension("EXT_color_buffer_float");
  if (!ext) {
    alert("need EXT_color_buffer_float");
    return;
  }
  const tx = gl.createTexture();
  gl.bindTexture(gl.TEXTURE_2D, tx);
  gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA16F, 1, 1, 0, gl.RGBA, gl.FLOAT, null);
  const fb = gl.createFramebuffer();
  gl.bindFramebuffer(gl.FRAMEBUFFER, fb);
  gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, tx, 0);

  gl.clearColor(.1, .2, .3, .7);
  gl.clear(gl.COLOR_BUFFER_BIT);
  const floatPixel = new Float32Array(4);
  gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.FLOAT, floatPixel);
  console.log("framebuffer:", floatPixel);
  gl.bindFramebuffer(gl.FRAMEBUFFER, null);
  const uint8Pixel = new Uint8Array(4);
  gl.readPixels(0, 0, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, uint8Pixel);
  console.log("canvas:", uint8Pixel);

  // render it
  function createShader(gl, type, src) {
    const sh = gl.createShader(type);
    gl.shaderSource(sh, src);
    gl.compileShader(sh);
    return sh;
  }

  const vs = createShader(gl, gl.VERTEX_SHADER, `#version 300 es
  void main() {
    gl_PointSize = 300.0;
    gl_Position = vec4(0, 0, 0, 1);
  }
  `);
  const fs = createShader(gl, gl.FRAGMENT_SHADER, `#version 300 es
  precision mediump float;
  uniform sampler2D tex;
  out vec4 color;
  void main() {
    color = texture(tex, vec2(.5));
  }
  `);

  const prg = gl.createProgram();
  gl.attachShader(prg, vs);
  gl.attachShader(prg, fs);
  gl.linkProgram(prg);
  gl.useProgram(prg);
  gl.drawArrays(gl.POINTS, 0, 1);
}

main();
div { color: red; font-size: xx-large; }
canvas { position: absolute; left: 0; top: 0; z-index: 2 };
<div>behind</div>
<canvas></canvas>

Другие вопросы по тегам