Firefox中的WebGL gl_FragColor alpha在Chrome中表现不同 [英] WebGL gl_FragColor alpha behave differently in Chrome with Firefox

查看:554
本文介绍了Firefox中的WebGL gl_FragColor alpha在Chrome中表现不同的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面的代码绘制了三个三角形 alpha 值0.5,其中 {premultipliedAlpha:false}



false}); const canvasWidthHeight = 300; gl.clearColor(1,0,0,0.4); // gl.clear(gl.COLOR_BUFFER_BIT); const vertexShaderSource =`属性vec2 position;统一的vec2分辨率; //所有着色器都有一个主函数void main(){vec2 glSpacePosition =(position / resolution)* 2.0 - 1.0; gl_Position = vec4(glSpacePosition * vec2(1,-1),0,1); }`; const fragmentShaderSource =`precision mediump float;统一的vec4颜色; void main(){gl_FragColor = color; }`; function createShader(gl,type,shaderSource){const shader = gl.createShader(type); gl.shaderSource(shader,shaderSource); gl.compileShader(着色); const success = gl.getShaderParameter(shader,gl.COMPILE_STATUS); if(!success){console.warn(gl.getShaderInfoLog(shader)); gl.deleteShader(着色); } return shader;} const vertexShader = createShader(gl,gl.VERTEX_SHADER,vertexShaderSource); const fragmentShader = createShader(gl,gl.FRAGMENT_SHADER,fragmentShaderSource);函数createProgram(gl,vertexShader,fragmentShader){const program = gl.createProgram( ); gl.attachShader(program,vertexShader); gl.attachShader(program,fragmentShader); gl.linkProgram(程序); const success = gl.getProgramParameter(program,gl.LINK_STATUS); if(!success){console.log(gl.getProgramInfoLog(program)); gl.deleteProgram(程序); } return program;} const program = createProgram(gl,vertexShader,fragmentShader); //我们在GPU上创建了一个程序,所以下一步是提供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(程序); 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 =300height =300>< / canvas>


$ b

Chrome中的结果:



Firefox中的结果:



Firefox中的结果与我的预期相同。



我认为这与WebGL的混合没有关系,因为它是将 gl_FragColor 与绘图缓冲区(而不是浏览器DOM)混合在一起,在这种情况下,是绿色背景画布。
(这个想法是基于我对WebGL工作原理的理解)



另外:在Chrome中,如果 gl_FragColor.rgb code>是 vec3(1.0,1.0,1.0),无论 gl_FragColor.a 是什么,只要 a 不是 0 ,则输出颜色为纯白色(当 rgb 是其他值,它的表现会有很大不同)。
为上面的图像(不想污染太多的代码这个问题)。

更新1:我相信这不是一个混合问题,如果我们启用混合:

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

结果如下:

解决方案

,这是一个铬的bug。

这是错误链接(再次感谢@gman)。


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:

解决方案

Anser this question myself.

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

这篇关于Firefox中的WebGL gl_FragColor alpha在Chrome中表现不同的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆