Secret Maryo Chronicles by Florian Richter & the SMC Team, GPL licensed
alpha | |
---|---|
1.0 | fully opaque |
0.5 | half transparent |
0.0 | fully transparent |
Most common method:
e.g. if alpha is 0.25: |
R = 0.25 * R1 + 0.75 * R2
G = 0.25 * G1 + 0.75 * G2 B = 0.25 * B1 + 0.75 * B2 |
Many different formulas for blending colors can be used
Formula is defined by glBlendFunc() function
is defined by:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
Enable blending | glEnable(GL_BLEND) | |
Set the blending function | glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA) | |
Assign alpha < 1 | glColor4f(1, 0, 0, 0.5) |
BlendFunc is applied to pixels as they are drawn - blending incoming color with color in the frame buffer
Alpha is treated like any other color component
If alpha differs at each vertex,
it will be smoothly interpolated.
Can give objects soft edges.
Changing alpha over time can make an object a fade in or out
Use 4 channel texture image
Can be used to "cut out" a texture image - creates complex shapes with simple geometry
RGB | Alpha | ||
---|---|---|---|
Used in film & video to composite live actors with other imagery (video or digital)
e.g. TV weatherman, Star Wars virtual sets
Can be done digitally by finding a background color, and setting alpha to 0 for those pixels
Example code: chromakey.py
General blending formula is:
(Rs, Gs, Bs) is the
source color (object being drawn)
(Rd, Gd, Bd) is the
destination color (color already in the framebuffer)
SourceFactor and DestinationFactor are defined by glBlendFunc()
Factor name | Computed factor |
---|---|
GL_ZERO | 0 |
GL_ONE | 1 |
GL_SRC_ALPHA | As |
GL_ONE_MINUS_SRC_ALPHA | 1 - As |
GL_DST_ALPHA | Ad |
GL_ONE_MINUS_DST_ALPHA | 1 - Ad |
GL_CONSTANT_ALPHA | Ac |
GL_ONE_MINUS_CONSTANT_ALPHA | 1 - Ac |
GL_SRC_COLOR | (Rs, Gs, Bs) |
GL_ONE_MINUS_SRC_COLOR | (1 - Rs, 1 - Gs, 1 - Bs) |
GL_DST_COLOR | (Rd, Gd, Bd) |
GL_ONE_MINUS_DST_COLOR | (1 - Rd, 1 - Gd, 1 - Bd) |
GL_CONSTANT_COLOR | (Rc, Gc, Bc) |
GL_ONE_MINUS_CONSTANT_COLOR | (1 - Rc, 1 - Gc, 1 - Bc) |
GL_SRC_ALPHA_SATURATE | min(As, 1 - Ad) |
Blending can be used to apply a color filter to the whole scene
Draw a square that covers the entire window, with the appropriate blending function
# Dim the scene glBlendFunc(GL_ZERO, GL_SRC_ALPHA) glColor4f(1.0, 1.0, 1.0, 0.5) | |
# Apply a purple filter glBlendFunc(GL_ZERO, GL_SRC_COLOR) glColor4f(1.0, 0.0, 0.5, 1.0) | |
# Invert all the colors glBlendFunc(GL_ONE_MINUS_DST_COLOR, GL_ZERO) glColor4f(1.0, 1.0, 1.0, 1.0) |
A method of modeling "fuzzy" objects - e.g. fire, smoke, water
Introduced in 1982, in the Star Trek II "Genesis Effect"
Model complex objects not easily represented by ordinary surfaces - large masses of simple, dynamic particles are used.
Particles are usually treated as simple points with position, velocity, and color.
Individual particles are added to the system, move about, are affected by forces such as gravity, and eventually die out.
Example C data structure:
struct _particle { Vector3 position; Vector3 tailPosition; Vector3 velocity; Vector3 color; float removeTime; }; struct _particle * particleArray;
Particle system code has three major parts:
Example Python class:
class particle: def __init__(self, position=Vector([0,0,0])): self.position = position self.velocity = Vector([uniform(-3,3), 8, uniform(-3,3)]) self.color = [uniform(.5,1), uniform(0,1), uniform(0,0.5)] def update(self, dt): self.velocity += gravity * dt self.position += self.velocity * dt class particleSystem: def __init__(self): self.particles = [] def addParticles(self, num): for i in range(0,num): self.particles.append(particle()) def updateParticles(self, dt): for p in self.particles: p.update(dt) def drawParticles(self): ... ...
Particles can be drawn in different ways, for different visual effects.
The simplest way is using points or lines.
Particles don't have to be rendered as just points or lines.
A common alternative to points & lines for particles is simple textured polygons. For smoke or clouds, the texture would look like a single puff.
In this case, one uses fewer particles, as each is much larger than a single point.
When drawing particles, we often want them to "add up" in some way to form a fuzzy effect, rather than looking like just a set of individual points or lines.
This can be done using blending. Disabling depth-buffer-writing in this case is useful, because we don't want the particles to obscure each other.
glEnable(GL_BLEND) glBlendFunc(GL_ONE, GL_ONE) glDepthMask(GL_FALSE) glBegin(GL_LINES) for p in particles: glColor3fv(p.color) glVertex3fv(p.tailPosition) glVertex3fv(p.position) glEnd() glDepthMask(GL_TRUE) glBlendFunc(GL_ONE, GL_ZERO) glDisable(GL_BLEND)
Particles can be affected by forces. This can be implemented in the same way as applying forces to ordinary solid objects.
for p in particles: accel = gravityAccel + windAccel p.velocity += accel * dt p.tailPosition = p.position p.position += p.velocity * dt
A particle system can have hundreds (or thousands) of individual particles.
Operations on each particle can add up and make things slow.
For real-time use, minimize the number of particles, and avoid, simplify,
or pre-calculate any expensive operations.
Expensive operations include: