I've tried setting the antialias
property on the WebGL context to true, but that didn't fix it.
This is what I'm getting in WebGL:
This is canvas rendering, via drawImage
, which is what I'm trying to replicate:
I'm using the default WebGL settings, aside from these three changed flags:
gl.enable(gl.BLEND); // Enable blending
gl.depthFunc(gl.LEQUAL); //near things obscure far things
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
And here's how I load the sprites (with the sprite
variable being an Image object)
const texture = gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D, texture);
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, sprite);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR);
Alright, fixed it. It was happening because my textures used premultiplied alpha values, which messed up the blending.
I fixed it by changing my blendFunc
from gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
to gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
I also had to tell WebGL to unpack premultiplied alpha values by doing
gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true)