14.3ColorandOpacity 233
are changing only the purely white areas of the original texture to our desired
color, and all other final display colors are darker depending on the shade of gray
in the original texture.
The most common example of white art and vertex coloring is text rendering.
When rendering a string that uses a font where each character has been preren-
dered in white onto a transparent background, we have the ability to color text
dynamically. To accomplish this, we look up a character’s texture coordinates,
choose the color for each character, and then render it on a quad of that color.
Our result? Characters from the same font file are shown on screen but colored
differently, with no extra texture memory required. We now extend this reuse to
our entire UI.
Imagine building a sports game where each team has a light and dark color.
Our designer wants to connect our gamers with the identity of their team through
the use of team colors. We could build a uniquely colored UI for each team, but
that takes a lot of effort and resources. Instead, artists design a black and white
UI, with the knowledge that some UI pieces will use the light team colors and
other areas will use the dark team colors. Now we have one art set instead of
many, resulting in a savings in memory, art development time, and likely load
time as well.
This isn’t to say an image of a person somersaulting off a building should be
in black and white and tinted when rendered. Use white art and tint it when there
is an asset that can be reused if colored differently. Often, buttons, frames, bor-
ders, scroll bars, tab controls, and other basic UI components are easily colored
to fit into different scenes.
OpacitySeparatefromColor
Gone are the days when it was acceptable to have UI objects jarringly pop on and
off the screen. Modern games fade objects or provide some other type of smooth
transition. These transitions (and indeed all transparency) are achieved by modi-
fying the alpha component of a vertex’s color. A value of one means the vertex is
fully opaque. A value of zero means the vertex is completely invisible.
Opacity is closely related to color due to the effect of a color’s alpha value on
transparency. It’s arguable that opacity is unnecessary since alpha is transparen-
cy. Why store opacity then? The problem is that temporary effects, like fades,
pollute the true value of a color’s alpha. It’s safer to apply opacity during render-
ing (
finalAlpha = alpha * opacity) and preserve the true state of a vertex’s
color. We can optimize this a bit by not storing opacity per vertex and opt for
storing it on a quad instead, since most opacity effects (like fade) don’t need to
affect vertices individually.