Text and other transparent images have darkened sub-pixel borders #290
Description
Activity
BenjaminDRichards commented
on Oct 24, 2017 ContributorAuthorMore actionsInvestigation complete.
The following code is the problem:
Kiwi.Renderers.GLTextureWrapper.prototype.uploadTexture:
gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 0 );Kiwi.Renderers.GLBlendMode constructor:
this._srcRGB = gl.SRC_ALPHA;Kiwi.Shaders.TextureAtlasShader.fragSource:
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)); gl_FragColor.a *= vAlpha;This treats textures as unpremultiplied, leading to the sub-pixel border flaw.
The correct code is as follows:
Kiwi.Renderers.GLTextureWrapper.prototype.uploadTexture:
gl.pixelStorei( gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, 1 );Kiwi.Renderers.GLBlendMode constructor:
this._srcRGB = gl.ONE;Kiwi.Shaders.TextureAtlasShader.fragSource:
gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * vAlpha;I also like that it reduces the
mainof the standard fragment shader down to one line. It might not be more efficient, but it certainly isn't less.Note that this will change the way unpremultiplied textures are processed. However, considering that all our assets seem to work as desired at the end of our pipeline, I anticipate most users will simply benefit from the more accurate rendering system.
BenjaminDRichards commented
on Oct 27, 2017 ContributorAuthorMore actionsFurther implementation notes: some other renderers need the old blend mode pipeline. In particular, Primitives require
srcRGBset back togl.SRC_ALPHA.
I think this is due to linear texture interpolation, but it's proving difficult to pin down. I've just replaced every RGB field in the RGBA ImageData of a Text plugin rendering canvas with a bright colour; and the borders are still darkened. WebGL may be doing something nefarious. Worth investigating.