Hi everyone, I'm working on a project where I recreate an old game in a new engine, but still make use of the game's original art/resources ( https://github.com/kromenak/gengine ). One interesting thing about this process is that older 3D games often either used nonstandard techniques or techniques that are now considered outdated. This post/question is about one such example and determining what technique was used.
In this game, dynamic shadows (and sometimes decals) are implemented using “shadow textures," which are fully opaque RGB images where whiter parts of the image correspond to transparency. At runtime, fully white pixels are totally transparent while black pixels are totally opaque. Everything in between (including colors) are semi-transparent.
Here's an example of one of the shadow textures:
And here's how it's supposed to appear in-game (notice the semi-transparent darker texture beneath the character):
I've tried a few different methods to get the source asset to look this way in-game, but no luck yet.
The source asset does not have alpha - but at load time, I tried to calculate “how white” a pixel is and then set the alpha based on that.
// The more white, the more transparent this pixel should be.
float average = (r + g + b) / 3.0f;
float a = 1.0f - average;
From there, I can use alpha-blending (glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)). However, this approach has some problems: the color is off, and the outer pixels have a white halo present (makes sense because of the white pixels in the original image).
I also tried to do “pre-multiplied” alpha at load time. After calculating the alpha, I multiplied the alpha into the colors.
r *= a;
g *= a;
b *= a;
I can then use (glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)) instead. This helps to reduce the “white halo” problem, but the color is still off. The result looks better in the original game!
Part of me suspects that there is some simple known/documented technique for using such a source asset as a shadow in this way. Given that the original game achieved this back in 1997, I imagine the technique used isn't super complex or taxing, and probably just uses the fixed function pipeline to achieve this blending! I've tried using different combinations for glBlendFunc on the unaltered source texture, but so far haven't found the magic combination.
One note is that the game also uses this technique for a few color textures that act as decals (a pool of dark red blood on the ground is one example). So, beyond shadow techniques, there could also be some general decal technique being used?
So, I'm posting here to see whether anyone is aware of an algorithm or technique for implementing shadows using an opaque RGB image like the one above using older OpenGL/D3D techniques. Rather than fumbling around trying to find the answer in old articles and forum posts, I'm hoping someone here might be able to point me in the righty direction based on past experience and knowledge.