Firefox中的WebGL gl_FragColor alpha在Chrome中表现不同 [英] WebGL gl_FragColor alpha behave differently in Chrome with Firefox
问题描述
下面的代码绘制了三个三角形 alpha
值0.5,其中 {premultipliedAlpha:false}
。
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中,如果 更新1:我相信这不是一个混合问题,如果我们启用混合: 结果如下: gl_FragColor.rgb code>是
vec3(1.0,1.0,1.0)
,无论 gl_FragColor.a
是什么,只要 a
不是 0
,则输出颜色为纯白色(当 rgb
是其他值,它的表现会有很大不同)。
为上面的图像(不想污染太多的代码这个问题)。
gl.enable(gl.BLEND);
gl.blendFunc(gl.SRC_ALPHA,gl.ONE_MINUS_SRC_ALPHA);
这是错误链接(再次感谢@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屋!