WebGL gl_FragColor alpha behave differently in Chrome with Firefox

杀马特。学长 韩版系。学妹 提交于 2019-12-12 13:12:05

问题


Code below draws three triangles alpha value 0.5 with {premultipliedAlpha: false}.

const gl = document.querySelector('canvas').getContext('webgl', {premultipliedAlpha: false});

const canvasWidthHeight = 300;
gl.clearColor(1, 0, 0, 0.4);
// gl.clear(gl.COLOR_BUFFER_BIT);

const vertexShaderSource = `
  attribute vec2 position;
  uniform vec2 resolution;

  // All shaders have a main function
  void main() {
    vec2 glSpacePosition = (position / resolution) * 2.0 - 1.0;
    gl_Position = vec4(glSpacePosition * vec2(1, -1), 0, 1);
  }
`;

const fragmentShaderSource = `
  precision mediump float;
  uniform vec4 color;
 
  void main() {
    gl_FragColor = color;
  }
`;

function createShader(gl, type, shaderSource) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, shaderSource);
  gl.compileShader(shader);

  const success = gl.getShaderParameter(shader, gl.COMPILE_STATUS);
  if (!success) {
    console.warn(gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
  }

  return shader;
}

const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);

function createProgram(gl, vertexShader, fragmentShader) {
  const program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);

  const success = gl.getProgramParameter(program, gl.LINK_STATUS);
  if (!success) {
    console.log(gl.getProgramInfoLog(program));
    gl.deleteProgram(program);
  }

  return program;
}

const program = createProgram(gl, vertexShader, fragmentShader);

// We created a program on GPU, so the next step is supplying data.
const positionAttributeLocation = gl.getAttribLocation(program, 'position');
const resolutionUniformLocation = gl.getUniformLocation(program, 'resolution');
const colorUniformLocation = gl.getUniformLocation(program, 'color');

const positionBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer);

gl.useProgram(program);
gl.uniform2f(resolutionUniformLocation, canvasWidthHeight, canvasWidthHeight);
gl.enableVertexAttribArray(positionAttributeLocation);

gl.vertexAttribPointer(positionAttributeLocation, 2, gl.FLOAT, false, 0, 0);

function drawRandomizedTriangles() {
  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0, 0,
    0, canvasWidthHeight,
    canvasWidthHeight, 0
  ]), gl.STATIC_DRAW);

  gl.uniform4f(colorUniformLocation, 0, 0, 1, 0.5);

  gl.drawArrays(gl.TRIANGLES, 0, 3);

  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0 + 50, 0,
    0 + 50, canvasWidthHeight,
    canvasWidthHeight + 50, 0
  ]), gl.STATIC_DRAW);

  gl.uniform4f(colorUniformLocation, 1, 0, 0, 0.5);

  gl.drawArrays(gl.TRIANGLES, 0, 3);

  gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
    0 + 100, 0,
    0 + 100, canvasWidthHeight,
    canvasWidthHeight + 100, 0
  ]), gl.STATIC_DRAW);

  gl.uniform4f(colorUniformLocation, 1, 1, 1, 0.5);

  gl.drawArrays(gl.TRIANGLES, 0, 3);
}

drawRandomizedTriangles();
body {
  display: flex;
  align-items: center;
  justify-content: center;
}

canvas {
  background: green;
}
<canvas width="300" height="300"></canvas>

Result in Chrome:

Result in Firefox:

The result in Firefox is what I expected.

I think it's not related to WebGL's blend since it's about blending gl_FragColor with drawing buffer instead of browser DOM, in this case, the green-background Canvas. (This thought is based on my understanding of how WebGL works)

Also: In Chrome, if the gl_FragColor.rgb is vec3(1.0, 1.0, 1.0), no matter what the gl_FragColor.a is, as long as a is not 0, the output color is pure white(when the rgb is other values, it will behave much differently). Here is the code pen for the image above(don't want to pollute this question with too much code).

Update 1: I believe this is not a blending issue, if we enable blend by:

gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);

The result will like this:


回答1:


Anser this question myself.

As @gman said in the comment area, this is a bug in chromium.
Here is the bug link(thanks to @gman again).



来源:https://stackoverflow.com/questions/47216022/webgl-gl-fragcolor-alpha-behave-differently-in-chrome-with-firefox

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!