Creating realtime effects often requires more than one drawing pass because each pass is adding something to the overall effect. The blending modes that you specify create transparency, and thus determine how the background layers show through the foreground layers.
Blending works by adding the incoming pixel (source) and the frame buffer pixel (destination). Keep in mind that destination pixels are already in the frame buffer, while the source pixels are new pixels that are being blended with the frame buffer pixels.
For example, if you have a pixel that had the following RGBA value (0.7, 0.7, 0.5, 1.0) and the frame buffer already contains the following RGBA value (0.5, 0.2, 0.3, 1.0), then the resulting pixel will be (1.2, 0.9, 0.8,2.0). Values are clamped to 1.0 which means the final pixel will be (1.0, 0.9, 0.8, 1.0).
It is possible to multiply the values of the source and destination pixel by a specific term (ONE, ZERO, ONE_MINUS_SOURCE _ALPHA, and so on). So if, for example, the source is multiplied by ONE and the destination is multiplied by ZERO, then the output will include the source pixel only.
The blending equation is as follows:
clamp ( (source * source multiplier) + (destination * destination multiplier))So if you have the following incoming pixel:
and the following value in the frame buffer:
then the equation would be as follows:
R = clamp ((1.0 * 0.8) + (0.2 * 0.2)) = 0.84
G = clamp ((0.0 * 0.8) + (0.2 * 0.0)) = 0.0
B = clamp ((0.0 * 0.8) + (0.2 * 1.0)) = 0.2
A = clamp ((0.8 * 0.8) + (0.2 * 1.0)) = 0.84
When applied to every pixel in a texture, this equation determines what the blended output looks like.
The output of the render tree — applied to a grid in this case — is the blue texture shown below made transparent in an area defined by its alpha channel.
Texture (left) and alpha channel (right)
When the "drawing" shader performs its blending calculations, the source pixels are multiplied by their alpha channel value (SRC_ALPHA) and the destination pixels are multiplied by one minus the source pixels' alpha channel values (ONE_MINUS_SRC_ALPHA). The source and destination values are then added together.
The net effect is that the source's alpha channel is removed from both the source and the destination, leaving the area transparent like this:
Except where otherwise noted, this work is licensed under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License