On Fri, Aug 8, 2014 at 7:54 PM, Katelyn Gadd <k...@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 <caban...@gmail.com> wrote:
> >
> >
> >
> > On Thu, Aug 7, 2014 at 7:11 PM, Katelyn Gadd <k...@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.
> >>

Reply via email to