Interactive semi transparent layers (or selective transparency)By O Ilusionista - 2020.11.02
> ABOUT
This is a trick we used in Mugen that I wanted to replicate in OpenBOR for a long time but I never had time to try and, after some tests, I managed to do it:
selective / interactive transparency. By default, frontlayer appears in front of the characters, which can cover them during the scene and, if the layer is too large, will cause the player's vision to be blocked, as it covers much of the character:
(The player could be totally covered by the tree on that area without this trick).> HOW IT WORKS?
Combining two fglayers with different Z positions and different alphas - one behind the players and one in front of them - it is possible to make a selective / interactive transparency,
which will work only on entities and not on the scenery itself (note that the tree is semi transparent on Captain America, but not on the windows from the bottom):
A zoom to make it easier to be seen:
> HOW TO DO IT?
This is how your layers will look:1 - For this to work, you have to exchange your "frontpanel" for a fglayer, changing the "XRATIO" parameter to be the same as the "frontpanel" standard. I use the value of -1.5, but you can test other values - negative, because if they are positive, the layer var will slide to the other side.
2 - It will be necessary to use two "FGLAYERS", identical and with all the same values, with the exception of the parameters "ZPOS" and "ALPHA". I thank Damon Caskey for the reference of the fglayer parameters:
# fglayer filepath Zpos xratio zratio xoffset zoffset xspace zspace xrepeat zrepeat trans alpha w-mode amp wl ws move quake neon
fglayer data/bgs/Zlevel0/lv1front2.gif -100 -1.5 1 0 0 0 0 -1 1 1 0 0 2.5 0 0 0 1 0
fglayer data/bgs/Zlevel0/lv1front2.gif 200 -1.5 1 0 0 0 0 -1 1 1 6 0 2.5 0 0 0 1 0
The important values are
ZPOS (1st column),
XRATIO (2nd column) and
ALPHA (11th column).
"ZPOS" is the fglayer's Z position on the stage. Generally,
negative numbers will make the layer appear behind the character and
positive numbers will make it appear in front of the character. I used -100 for the back layer and 200 for the front layer.
"XRATIO" says what proportion the layer will move on the X axis as the camera moves. It is mandatory that the values are the same between the layers (as well as all the others), or the players will notice the difference when the camera moves.
"ALPHA" is where the
ace in the hole is. By combining the correct values of transparency with identical layers in the correct position, we will
make the transparency work only in the BETWEEN LAYERS. For the trick to work, we need to combine the alpha 6 mode (50% transparency) on the front layer with an alpha 0 mode (no transparency) on the back layer.> WHY THESE VALUES? WHY DO YOU NEED TWO LAYERS?
Using different values causes not very good results.
Using ALPHA 1 (additive transparency) make the front layer lighter:
Using ALPHA 6 but without the back layer will make the layer transparent over everything, including the background, ruining the effect:
Using ALPHA 1 without the back layer is even worse.
> ADDITIONAL TIPS:
Despite the name FGLAYER, this layer can be shown in any position, either behind the player or in front. The difference between FGLAYER and BGLAYER is that the first allows control of the ZPOS, the second does not.
Internally, the engine TREATS ALL AS fglayer, be it fglayer, bglayer, frontpanel, background, water, layer (which is just a nickname for fglayer), just checking which term is used and, depending on it, configures ZPOS, XRATIO, WATER MODE, WAVE LENGHT, etc.
We can see this when we look at the engine code:
case CMD_LEVEL_BACKGROUND:
case CMD_LEVEL_BGLAYER:
case CMD_LEVEL_LAYER:
case CMD_LEVEL_FGLAYER:
__realloc(level->layers, level->numlayers);
bgl = &(level->layers[level->numlayers]);
if(cmd == CMD_LEVEL_BACKGROUND || cmd == CMD_LEVEL_BGLAYER)
{
i = 0;
bgl->z = MIN_INT; // if the type is BACKGROUND, draw it on the minimun ZPOS
}
else
{
i = 1;
bgl->z = GET_FLOAT_ARG(2);
if(cmd == CMD_LEVEL_FGLAYER)
{
bgl->z += FRONTPANEL_Z; // If the type is FRONTPANEL, draw it on using the constatnt FRONTPANEL_Z, which will cover the players
}
}
(...)
if((GET_ARG(i + 2))[0] == 0)
{
bgl->ratio.x = (cmd == CMD_LEVEL_FGLAYER ? 1.5 : 0.5); // if the type is FGLAYER, use a XRATIO of 1.5; If not, use a XRATIO of 0.5
}
if((GET_ARG(i + 3))[0] == 0)
{
bgl->ratio.z = (cmd == CMD_LEVEL_FGLAYER ? 1.5 : 0.5);// if the type is FGLAYER, use a ZRATIO of 1.5; If not, use a ZRATIO of 0.5
}
Quote by Damon:
The {z} right after path in fglayer is what makes it special. That lets you adjust it's drawing position on Z axis.
Layer and bglayer are the same - just an alias.
Really thanks to Damon Caskey for all the great help about the FGLAYER parameters and the source code - I learned a lot with you and how powerful FGLAYER is.