Skip to content

Commit ec08e2c

Browse files
authored
Merge pull request #5917 from davepagurek/premultiplied-alpha
2 parents ce831a8 + dfa43ed commit ec08e2c

File tree

10 files changed

+59
-68
lines changed

10 files changed

+59
-68
lines changed

src/webgl/material.js

+9-14
Original file line numberDiff line numberDiff line change
@@ -1086,28 +1086,23 @@ p5.RendererGL.prototype._applyBlendMode = function() {
10861086
switch (this.curBlendMode) {
10871087
case constants.BLEND:
10881088
gl.blendEquation(gl.FUNC_ADD);
1089-
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
1089+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
10901090
break;
10911091
case constants.ADD:
10921092
gl.blendEquation(gl.FUNC_ADD);
1093-
gl.blendFunc(gl.SRC_ALPHA, gl.ONE);
1093+
gl.blendFunc(gl.ONE, gl.ONE);
10941094
break;
10951095
case constants.REMOVE:
1096-
gl.blendEquation(gl.FUNC_REVERSE_SUBTRACT);
1097-
gl.blendFunc(gl.SRC_ALPHA, gl.DST_ALPHA);
1096+
gl.blendEquation(gl.FUNC_ADD);
1097+
gl.blendFunc(gl.ZERO, gl.ONE_MINUS_SRC_ALPHA);
10981098
break;
10991099
case constants.MULTIPLY:
1100-
gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
1101-
gl.blendFuncSeparate(
1102-
gl.DST_COLOR,
1103-
gl.ONE_MINUS_SRC_ALPHA,
1104-
gl.ONE,
1105-
gl.ONE_MINUS_SRC_ALPHA
1106-
);
1100+
gl.blendEquation(gl.FUNC_ADD);
1101+
gl.blendFunc(gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA);
11071102
break;
11081103
case constants.SCREEN:
1109-
gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
1110-
gl.blendFuncSeparate(gl.ONE_MINUS_DST_COLOR, gl.ONE, gl.ONE, gl.ONE);
1104+
gl.blendEquation(gl.FUNC_ADD);
1105+
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
11111106
break;
11121107
case constants.EXCLUSION:
11131108
gl.blendEquationSeparate(gl.FUNC_ADD, gl.FUNC_ADD);
@@ -1124,7 +1119,7 @@ p5.RendererGL.prototype._applyBlendMode = function() {
11241119
break;
11251120
case constants.SUBTRACT:
11261121
gl.blendEquationSeparate(gl.FUNC_REVERSE_SUBTRACT, gl.FUNC_ADD);
1127-
gl.blendFuncSeparate(gl.SRC_ALPHA, gl.ONE, gl.ONE, gl.ONE);
1122+
gl.blendFuncSeparate(gl.ONE, gl.ONE, gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
11281123
break;
11291124
case constants.DARKEST:
11301125
if (this.blendExt) {

src/webgl/p5.RendererGL.js

+5-5
Original file line numberDiff line numberDiff line change
@@ -235,11 +235,11 @@ p5.RendererGL.prototype._setAttributeDefaults = function(pInst) {
235235
// See issue #3850, safer to enable AA in Safari
236236
const applyAA = navigator.userAgent.toLowerCase().includes('safari');
237237
const defaults = {
238-
alpha: false,
238+
alpha: true,
239239
depth: true,
240240
stencil: true,
241241
antialias: applyAA,
242-
premultipliedAlpha: false,
242+
premultipliedAlpha: true,
243243
preserveDrawingBuffer: true,
244244
perPixelLighting: true
245245
};
@@ -342,7 +342,7 @@ p5.RendererGL.prototype._resetContext = function(options, callback) {
342342
* The available attributes are:
343343
* <br>
344344
* alpha - indicates if the canvas contains an alpha buffer
345-
* default is false
345+
* default is true
346346
*
347347
* depth - indicates whether the drawing buffer has a depth buffer
348348
* of at least 16 bits - default is true
@@ -355,7 +355,7 @@ p5.RendererGL.prototype._resetContext = function(options, callback) {
355355
*
356356
* premultipliedAlpha - indicates that the page compositor will assume
357357
* the drawing buffer contains colors with pre-multiplied alpha
358-
* default is false
358+
* default is true
359359
*
360360
* preserveDrawingBuffer - if true the buffers will not be cleared and
361361
* and will preserve their values until cleared or overwritten by author
@@ -895,7 +895,7 @@ p5.RendererGL.prototype.clear = function(...args) {
895895
const _b = args[2] || 0;
896896
const _a = args[3] || 0;
897897

898-
this.GL.clearColor(_r, _g, _b, _a);
898+
this.GL.clearColor(_r * _a, _g * _a, _b * _a, _a);
899899
this.GL.clearDepth(1);
900900
this.GL.clear(this.GL.COLOR_BUFFER_BIT | this.GL.DEPTH_BUFFER_BIT);
901901
};

src/webgl/shaders/basic.frag

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
precision mediump float;
22
uniform vec4 uMaterialColor;
33
void main(void) {
4-
gl_FragColor = uMaterialColor;
5-
}
4+
gl_FragColor = vec4(uMaterialColor.rgb, 1.) * uMaterialColor.a;
5+
}

src/webgl/shaders/font.frag

+3-3
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,6 @@ void main() {
210210
float distance = max(weight.x + weight.y, minDistance); // manhattan approx.
211211
float antialias = abs(dot(coverage, weight) / distance);
212212
float cover = min(abs(coverage.x), abs(coverage.y));
213-
gl_FragColor = uMaterialColor;
214-
gl_FragColor.a *= saturate(max(antialias, cover));
215-
}
213+
gl_FragColor = vec4(uMaterialColor.rgb, 1.) * uMaterialColor.a;
214+
gl_FragColor *= saturate(max(antialias, cover));
215+
}

src/webgl/shaders/light_texture.frag

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ void main(void) {
1515
gl_FragColor = uMaterialColor;
1616
}
1717
else {
18-
gl_FragColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
19-
gl_FragColor.rgb = gl_FragColor.rgb * vDiffuseColor + vSpecularColor;
18+
vec4 baseColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
19+
gl_FragColor = vec4(gl_FragColor.rgb * vDiffuseColor + vSpecularColor, 1.) * baseColor.a;
2020
}
21-
}
21+
}

src/webgl/shaders/line.frag

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ precision mediump int;
44
uniform vec4 uMaterialColor;
55

66
void main() {
7-
gl_FragColor = uMaterialColor;
8-
}
7+
gl_FragColor = vec4(uMaterialColor.rgb, 1.) * uMaterialColor.a;
8+
}

src/webgl/shaders/phong.frag

+4-4
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@ void main(void) {
2424

2525
// Calculating final color as result of all lights (plus emissive term).
2626

27-
gl_FragColor = isTexture ? texture2D(uSampler, vTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
28-
gl_FragColor.rgb = diffuse * gl_FragColor.rgb +
27+
vec4 baseColor = isTexture ? texture2D(uSampler, vTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
28+
gl_FragColor = vec4(diffuse * baseColor.rgb +
2929
vAmbientColor * uAmbientMatColor.rgb +
3030
specular * uSpecularMatColor.rgb +
31-
uEmissiveMatColor.rgb;
32-
}
31+
uEmissiveMatColor.rgb, 1.) * baseColor.a;
32+
}

src/webgl/shaders/point.frag

+15-15
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,25 @@ uniform vec4 uMaterialColor;
44
varying float vStrokeWeight;
55

66
void main(){
7-
float mask = 0.0;
7+
float mask = 0.0;
88

9-
// make a circular mask using the gl_PointCoord (goes from 0 - 1 on a point)
10-
// might be able to get a nicer edge on big strokeweights with smoothstep but slightly less performant
9+
// make a circular mask using the gl_PointCoord (goes from 0 - 1 on a point)
10+
// might be able to get a nicer edge on big strokeweights with smoothstep but slightly less performant
1111

12-
mask = step(0.98, length(gl_PointCoord * 2.0 - 1.0));
12+
mask = step(0.98, length(gl_PointCoord * 2.0 - 1.0));
1313

14-
// if strokeWeight is 1 or less lets just draw a square
15-
// this prevents weird artifacting from carving circles when our points are really small
16-
// if strokeWeight is larger than 1, we just use it as is
14+
// if strokeWeight is 1 or less lets just draw a square
15+
// this prevents weird artifacting from carving circles when our points are really small
16+
// if strokeWeight is larger than 1, we just use it as is
1717

18-
mask = mix(0.0, mask, clamp(floor(vStrokeWeight - 0.5),0.0,1.0));
18+
mask = mix(0.0, mask, clamp(floor(vStrokeWeight - 0.5),0.0,1.0));
1919

20-
// throw away the borders of the mask
21-
// otherwise we get weird alpha blending issues
20+
// throw away the borders of the mask
21+
// otherwise we get weird alpha blending issues
2222

23-
if(mask > 0.98){
24-
discard;
25-
}
23+
if(mask > 0.98){
24+
discard;
25+
}
2626

27-
gl_FragColor = vec4(uMaterialColor.rgb * (1.0 - mask), uMaterialColor.a) ;
28-
}
27+
gl_FragColor = vec4(uMaterialColor.rgb, 1.) * uMaterialColor.a;
28+
}

src/webgl/shaders/vertexColor.frag

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
precision mediump float;
22
varying vec4 vColor;
33
void main(void) {
4-
gl_FragColor = vColor;
5-
}
4+
gl_FragColor = vec4(vColor.rgb, 1.) * vColor.a;
5+
}

test/unit/webgl/p5.RendererGL.js

+14-18
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ suite('p5.RendererGL', function() {
338338
pg.clear();
339339
myp5.image(pg, -myp5.width / 2, -myp5.height / 2);
340340
pixel = myp5.get(0, 0);
341-
assert.deepEqual(pixel, [0, 0, 0, 255]);
341+
assert.deepEqual(pixel, [0, 255, 255, 255]);
342342
done();
343343
});
344344

@@ -361,7 +361,7 @@ suite('p5.RendererGL', function() {
361361
pg.background(100, 100, 100, 100);
362362
myp5.image(pg, -myp5.width / 2, -myp5.height / 2);
363363
pixel = myp5.get(0, 0);
364-
assert.deepEqual(pixel, [100, 100, 100, 255]);
364+
assert.deepEqual(pixel, [39, 194, 194, 255]);
365365
done();
366366
});
367367

@@ -383,7 +383,7 @@ suite('p5.RendererGL', function() {
383383
pg.clear();
384384
myp5.image(pg, 0, 0);
385385
pixel = myp5.get(0, 0);
386-
assert.deepEqual(pixel, [0, 0, 0, 255]);
386+
assert.deepEqual(pixel, [0, 255, 255, 255]);
387387
done();
388388
});
389389

@@ -394,7 +394,7 @@ suite('p5.RendererGL', function() {
394394
pg.background(100, 100, 100, 100);
395395
myp5.image(pg, 0, 0);
396396
pixel = myp5.get(0, 0);
397-
assert.deepEqual(pixel, [100, 100, 100, 255]);
397+
assert.deepEqual(pixel, [39, 194, 194, 255]);
398398
done();
399399
});
400400
});
@@ -483,14 +483,14 @@ suite('p5.RendererGL', function() {
483483
myp5.createCanvas(10, 10, myp5.WEBGL);
484484
myp5.noStroke();
485485
assert.deepEqual([122, 0, 122, 255], mixAndReturn(myp5.ADD, 0));
486-
assert.deepEqual([0, 0, 255, 255], mixAndReturn(myp5.REPLACE, 255));
486+
assert.deepEqual([0, 0, 122, 122], mixAndReturn(myp5.REPLACE, 255));
487487
assert.deepEqual([133, 255, 133, 255], mixAndReturn(myp5.SUBTRACT, 255));
488-
assert.deepEqual([255, 0, 255, 255], mixAndReturn(myp5.SCREEN, 0));
489-
assert.deepEqual([0, 255, 0, 255], mixAndReturn(myp5.EXCLUSION, 255));
488+
assert.deepEqual([122, 0, 122, 255], mixAndReturn(myp5.SCREEN, 0));
489+
assert.deepEqual([133, 255, 133, 255], mixAndReturn(myp5.EXCLUSION, 255));
490490
// Note that in 2D mode, this would just return black, because 2D mode
491491
// ignores alpha in this case.
492-
assert.deepEqual([133, 69, 202, 255], mixAndReturn(myp5.MULTIPLY, 255));
493-
assert.deepEqual([255, 0, 255, 255], mixAndReturn(myp5.LIGHTEST, 0));
492+
assert.deepEqual([133, 69, 133, 255], mixAndReturn(myp5.MULTIPLY, 255));
493+
assert.deepEqual([122, 0, 122, 255], mixAndReturn(myp5.LIGHTEST, 0));
494494
assert.deepEqual([0, 0, 0, 255], mixAndReturn(myp5.DARKEST, 255));
495495
done();
496496
});
@@ -517,15 +517,11 @@ suite('p5.RendererGL', function() {
517517
const assertSameIn2D = function(colorA, colorB, mode) {
518518
const refColor = testBlend(myp5, colorA, colorB, mode);
519519
const webglColor = testBlend(ref, colorA, colorB, mode);
520-
if (refColor[3] === 0) {
521-
assert.equal(webglColor[3], 0);
522-
} else {
523-
assert.deepEqual(
524-
refColor,
525-
webglColor,
526-
`Blending ${colorA} with ${colorB} using ${mode}`
527-
);
528-
}
520+
assert.deepEqual(
521+
refColor,
522+
webglColor,
523+
`Blending ${colorA} with ${colorB} using ${mode}`
524+
);
529525
};
530526

531527
for (const alpha of [255, 200]) {

0 commit comments

Comments
 (0)