"multiply" blending mode?
is a "multiply" blending mode possible at all? i'd like to use it to implement some psuedo 2D lighting (which I've done before in XNA) but the best I could get was additive which didn't look as good.
i experimented with the source code a bit trying the following blend func:
sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
it works with a non-transparent image (ie: black background white radial gradient) but completely breaks with a transparent one (only renders the pixels in the corners as full black?)
essentially, what my custom "mult" mode looks like is this:
sceGuBlendFunc(GU_ADD, GU_FIX, GU_SRC_COLOR, 0, 0);
sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA);
sceGuAmbientColor(coeff1);
osl_currentAlphaCoeff = coeff1;
osl_currentAlphaCoeff2 = coeff2;
i'm not quite familiar with sceGuTexFunc or sceGuAmbientColor so I just left those similar as the other cases.
the method i use is:
- draw the base scene
- set blend to mult
- overlay a rectangle with the 'ambient light'
- draw lightmaps
here is a non-transparent png being used as the base light
and here is a semi-transparent png being used as the base light.
both images are identical with the exception of one having a black background and the other having a transparent background.
something like this is essentially what i'm going for
@suicvne to achieve a multiply blend mode, you'll need to use a blend function that multiplies the source and destination colors together. Here is a typical setup for a multiply blend mode:
sceGuBlendFunc(GU_ADD, GU_SRC_COLOR, GU_DST_COLOR, 0, 0);
In this setup:
-
GU_ADDspecifies that the result is the addition of the source and destination colors. -
GU_SRC_COLORuses the color of the source (the image you're drawing). -
GU_DST_COLORuses the color of the destination (the existing pixels in the framebuffer).
Here's an updated version of your method:
- Draw the base scene.
- Set blend mode to multiply.
- Overlay a rectangle with the 'ambient light'.
- Draw lightmaps.
// Step 1: Draw the base scene (ensure no blending here)
sceGuDisable(GU_BLEND);
// Draw your base scene here
// Step 2: Set blend mode to multiply
sceGuEnable(GU_BLEND);
sceGuBlendFunc(GU_ADD, GU_SRC_COLOR, GU_DST_COLOR, 0, 0);
// Step 3: Overlay a rectangle with the 'ambient light'
// Make sure the ambient light texture has appropriate alpha values
// Draw the ambient light overlay here
// Step 4: Draw lightmaps
// Ensure lightmaps are drawn with appropriate alpha values
// Draw your lightmaps here
// Restore the default blend mode if necessary
sceGuBlendFunc(GU_ADD, GU_SRC_ALPHA, GU_ONE_MINUS_SRC_ALPHA, 0, 0);
Additionally, ensure that your textures and lightmaps have appropriate alpha values and that your framebuffer supports alpha blending.
If you're encountering issues with transparency, double-check the alpha values in your textures. The blend function you were experimenting with (GU_FIX) fixes the color value and may not work well with textures that have transparency.
You mentioned using sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA) and sceGuAmbientColor(coeff1). These functions are typically used to configure texture environment settings and ambient color. Ensure these settings are appropriate for your blending operation:
-
sceGuTexFunc(GU_TFX_MODULATE, GU_TCC_RGBA)means the texture color will be modulated (multiplied) with the incoming fragment color. -
sceGuAmbientColor(coeff1)sets the ambient color for lighting calculations. Ensurecoeff1is set correctly to the desired ambient light color.
Lastly, make sure that the ambient light rectangle and lightmaps are correctly positioned and that their alpha values are appropriately set to achieve the desired lighting effect.