Change shaded blend mode use srcalpha and destalpha.

Fix blending error in add/sub/revsub
This commit is contained in:
Magnus Norddahl 2016-11-21 03:49:55 +01:00
commit 2ba2dc7611
6 changed files with 68 additions and 69 deletions

View file

@ -107,18 +107,27 @@ SSAVec4i DrawerCodegen::blend_copy(SSAVec4i fg)
SSAVec4i DrawerCodegen::blend_add(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha)
{
SSAInt alpha = fg[3];
alpha = alpha + (alpha >> 7); // 255 -> 256
srcalpha = (alpha * srcalpha + 128) >> 8;
SSAVec4i color = (fg * srcalpha + bg * destalpha) / 256;
return color.insert(3, 255);
}
SSAVec4i DrawerCodegen::blend_sub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha)
{
SSAInt alpha = fg[3];
alpha = alpha + (alpha >> 7); // 255 -> 256
srcalpha = (alpha * srcalpha + 128) >> 8;
SSAVec4i color = (bg * destalpha - fg * srcalpha) / 256;
return color.insert(3, 255);
}
SSAVec4i DrawerCodegen::blend_revsub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha)
{
SSAInt alpha = fg[3];
alpha = alpha + (alpha >> 7); // 255 -> 256
srcalpha = (alpha * srcalpha + 128) >> 8;
SSAVec4i color = (fg * srcalpha - bg * destalpha) / 256;
return color.insert(3, 255);
}
@ -126,7 +135,7 @@ SSAVec4i DrawerCodegen::blend_revsub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha,
SSAVec4i DrawerCodegen::blend_alpha_blend(SSAVec4i fg, SSAVec4i bg)
{
SSAInt alpha = fg[3];
alpha = alpha + (alpha >> 7); // // 255 -> 256
alpha = alpha + (alpha >> 7); // 255 -> 256
SSAInt inv_alpha = 256 - alpha;
SSAVec4i color = (fg * alpha + bg * inv_alpha) / 256;
return color.insert(3, 255);
@ -139,3 +148,15 @@ SSAInt DrawerCodegen::calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha)
SSAInt inv_alpha = 256 - alpha;
return (destalpha * alpha + 256 * inv_alpha + 128) >> 8;
}
SSAVec4i DrawerCodegen::blend_stencil(SSAVec4i stencilcolor, SSAInt fgalpha, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha)
{
fgalpha = fgalpha + (fgalpha >> 7); // 255 -> 256
SSAInt inv_fgalpha = 256 - fgalpha;
srcalpha = (fgalpha * srcalpha + 128) >> 8;
destalpha = (destalpha * fgalpha + 256 * inv_fgalpha + 128) >> 8;
SSAVec4i color = (stencilcolor * srcalpha + bg * destalpha) / 256;
return color.insert(3, 255);
}

View file

@ -85,6 +85,7 @@ public:
SSAVec4i blend_sub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha);
SSAVec4i blend_revsub(SSAVec4i fg, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha);
SSAVec4i blend_alpha_blend(SSAVec4i fg, SSAVec4i bg);
SSAVec4i blend_stencil(SSAVec4i color, SSAInt fgalpha, SSAVec4i bg, SSAInt srcalpha, SSAInt destalpha);
// Calculates the final alpha values to be used when combined with the source texture alpha channel
SSAInt calc_blend_bgalpha(SSAVec4i fg, SSAInt destalpha);

View file

@ -552,7 +552,6 @@ SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying)
SSAInt uvoffset = upos * textureHeight + vpos;
SSAVec4i fg;
SSAInt alpha, inv_alpha;
SSAVec4i output;
switch (blendmode)
@ -584,10 +583,7 @@ SSAVec4i DrawTriangleCodegen::ProcessPixel32(SSAVec4i bg, SSAInt *varying)
break;
case TriBlendMode::Shaded:
fg = Sample32(uvoffset);
alpha = fg[0];
alpha = alpha + (alpha >> 7); // 255 -> 256
inv_alpha = 256 - alpha;
output = blend_add(shade_bgra_simple(SSAVec4i::unpack(color), currentlight), bg, alpha, inv_alpha);
output = blend_stencil(shade_bgra_simple(SSAVec4i::unpack(color), currentlight), fg[3], bg, srcalpha, destalpha);
break;
case TriBlendMode::TranslateCopy:
fg = TranslateSample32(uvoffset);
@ -667,10 +663,7 @@ SSAInt DrawTriangleCodegen::ProcessPixel8(SSAInt bg, SSAInt *varying)
output = ToPal8(blend_revsub(fg, ToBgra(bg), srcalpha, calc_blend_bgalpha(fg, destalpha)));
break;
case TriBlendMode::Shaded:
alpha = Sample8(uvoffset);
alpha = alpha + (alpha >> 7); // 255 -> 256
inv_alpha = 256 - alpha;
output = ToPal8(blend_add(ToBgra(Shade8(color)), ToBgra(bg), alpha, inv_alpha));
output = ToPal8(blend_stencil(ToBgra(Shade8(color)), Sample8(uvoffset), ToBgra(bg), srcalpha, destalpha));
break;
case TriBlendMode::TranslateCopy:
output = Shade8(TranslateSample8(uvoffset));