- From: Rik Cabanier <cabanier@gmail.com>
- Date: Fri, 8 Aug 2014 22:41:59 -0700
- To: Katelyn Gadd <kg@luminance.org>
- Cc: Justin Novosad <junov@google.com>, WHAT Working Group <whatwg@whatwg.org>, Robert O'Callahan <robert@ocallahan.org>
On Fri, Aug 8, 2014 at 7:54 PM, Katelyn Gadd <kg@luminance.org> wrote: > A multiply blend mode by itself is not sufficient because the image > being rgba multiplied typically has alpha transparency. The closest > approximation is to generate (offline, in software with getImageData) > an image per channel - rgbk - and to source-over blend the 'k' channel > and then additive blend the r/g/b channels with individual alpha. This > approximates the per-channel alpha values with nearly equivalent > results (I say nearly equivalent because some browsers do weird stuff > with gamma/colorspace conversion that completely breaks this.) > > If it helps, you could think of this operation as a layer group in > photoshop. The first layer in the group is the source image, the > second layer is a solid color filled layer containing the rgba > 'multiplier', in multiply mode, and then the layer group has a mask on > it that contains the source image's alpha information. Note that this > representation (a layer group with two layers and a mask) implies that > drawing an image this way requires multiple passes, which is highly > undesirable. My current fallback requires 4 passes, along with 4 > texture changes and two blend state changes. Not wonderful. > I see; you're asking for a feature like Photoshop Color Overlay layer effect. Is that correct? > RGBA multiplication dates back to early fixed-function graphics > pipelines. If a blend with globalAlpha and a premultiplied source is > represented like this: > > result(r, g, b) = ( source-premultiplied(r, g, b) * globalAlpha ) + ( > dest(r, g, b) * (1 - (source(a) * globalAlpha)) ) > > Then if you take a premultiplied color constant and use that as the > multiplier for your image (instead of a global alpha value - this is > the input to rgba multiplication, i.e. a 'vertex color'): > > result(r, g, b) = ( source-premultiplied(r, g, b) * > rgba-multiplier-premultiplied(r, g, b) ) + ( dest(r, g, b) * (1 - > (source(a) * rgba-multiplier-premultiplied(a))) ) > > (Sorry if this is unclear, I don't have a math education) > > So you basically take the global alpha multiplier and you go from that > to a per-channel multiplier. If you're using premultiplied alpha > already, this ends up being pretty straightforward... you just take a > color (premultiplied, like everything else) and use that as your > multiplier. You can multiply directly by each channel since the global > 'alpha' part of the multiplier is already baked in by the > premultiplication step. > > This is a really common primitive since it's so easy to implement, if > not entirely free - you're already doing that global alpha > multiplication, so you just introduce a different multiplier > per-channel, which is really trivial in a SIMD model like the ones > used in computer graphics. You go from vec4 * scalar to vec4 * vec4. > > > Text rendering is the most compelling reason to support this, IMO. > With this feature you can build glyph atlases inside 2d canvases > (using something like freetype, etc), then trivially draw colored > glyphs out of them without having to drop down into getImageData or > use WebGL. It is trivially expressed in most graphics APIs since it > uses the same machinery as a global alpha multiplier - if you're > drawing a premultiplied image with an alpha multiplier in hardware, > you're almost certainly doing vec4 * scalar in your shader. If you're > using the fixed-function pipeline from bad old 3d graphics, vec4 * > scalar didn't even exist - the right hand side was *always* another > vec4 so this feature literally just changed the constant on the right > hand side. > > > I harp on this feature since nearly every 2d game I encounter uses it, > and JSIL has to do it in software. If not for this one feature it > would be very easy to make the vast majority of ported titles Just > Work against canvas, which makes them more likely to run correctly on > mobile. Maybe it would be best to bring this up as a separate topic on this mailing list. (just copy/paste most of your message) > On Fri, Aug 8, 2014 at 5:28 PM, Rik Cabanier <cabanier@gmail.com> wrote: > > > > > > > > On Thu, Aug 7, 2014 at 7:11 PM, Katelyn Gadd <kg@luminance.org> wrote: > >> > >> Sorry, in this context rgba multiplication refers to per-channel > >> multipliers (instead of only one multiplier for the alpha channel), so > >> that you can color tint images when drawing them. As mentioned, it's > >> used for fades, drawing colored text, and similar effects. > > > > > > I see. Any reason that this couldn't be done with a 'multiply' blend > mode? > > > >> > >> Premultiplication is a different subject, sorry if I confused you with > >> the similar language. There are past discussions about both in the > >> list archives. > >> >
Received on Saturday, 9 August 2014 05:42:25 UTC