mirror of
https://github.com/DragonMinded/bemaniutils.git
synced 2026-06-03 06:24:16 -05:00
Fix issue with anti-aliasing artifacts around borders with transparent pixels.
This commit is contained in:
parent
dfffe80a74
commit
f8c3f75883
|
|
@ -427,6 +427,7 @@ def pixel_renderer(
|
|||
b = 0
|
||||
a = 0
|
||||
count = 0
|
||||
denom = 0
|
||||
|
||||
# Essentially what we're doing here is calculating the scale, clamping it at 1.0 as the
|
||||
# minimum and then setting the AA sample swing accordingly. This has the effect of anti-aliasing
|
||||
|
|
@ -442,15 +443,21 @@ def pixel_renderer(
|
|||
texloc = inverse.multiply_point(Point(imgx + addx, imgy + addy))
|
||||
aax, aay = texloc.as_tuple()
|
||||
|
||||
# If we're out of bounds, don't update.
|
||||
# If we're out of bounds, don't update. Factor this in, however, so we can get partial
|
||||
# transparency to the pixel that is already there.
|
||||
denom += 1
|
||||
if aax < 0 or aay < 0 or aax >= texwidth or aay >= texheight:
|
||||
continue
|
||||
|
||||
# Grab the values to average, for SSAA.
|
||||
# Grab the values to average, for SSAA. Make sure to factor in alpha as a poor-man's
|
||||
# blend to ensure that partial transparency pixel values don't unnecessarily factor
|
||||
# into average calculations.
|
||||
texoff = (aax + (aay * texwidth)) * 4
|
||||
r += texbytes[texoff]
|
||||
g += texbytes[texoff + 1]
|
||||
b += texbytes[texoff + 2]
|
||||
apercent = texbytes[texoff + 3] / 255.0
|
||||
|
||||
r += int(texbytes[texoff] * apercent)
|
||||
g += int(texbytes[texoff + 1] * apercent)
|
||||
b += int(texbytes[texoff + 2] * apercent)
|
||||
a += texbytes[texoff + 3]
|
||||
count += 1
|
||||
|
||||
|
|
@ -458,8 +465,16 @@ def pixel_renderer(
|
|||
# None of the samples existed in-bounds.
|
||||
return imgbytes[imgoff:(imgoff + 4)]
|
||||
|
||||
# Average the pixels.
|
||||
average = [r // count, g // count, b // count, a // count]
|
||||
# Average the pixels. Make sure to divide out the alpha in preparation for blending.
|
||||
alpha = a // denom
|
||||
|
||||
if alpha == 0:
|
||||
average = [255, 255, 255, alpha]
|
||||
else:
|
||||
apercent = alpha / 255.0
|
||||
average = [int((r / denom) / apercent), int((g / denom) / apercent), int((b / denom) / apercent), alpha]
|
||||
|
||||
# Finally, blend it with the destination.
|
||||
return blend_point(add_color, mult_color, average, imgbytes[imgoff:(imgoff + 4)], blendfunc)
|
||||
else:
|
||||
# Calculate what texture pixel data goes here.
|
||||
|
|
|
|||
|
|
@ -275,6 +275,7 @@ extern "C"
|
|||
int b = 0;
|
||||
int a = 0;
|
||||
int count = 0;
|
||||
int denom = 0;
|
||||
|
||||
for (float addy = 0.5 - yswing; addy <= 0.5 + yswing; addy += yswing / 2.0) {
|
||||
for (float addx = 0.5 - xswing; addx <= 0.5 + xswing; addx += xswing / 2.0) {
|
||||
|
|
@ -282,16 +283,22 @@ extern "C"
|
|||
int aax = texloc.x;
|
||||
int aay = texloc.y;
|
||||
|
||||
// If we're out of bounds, don't update.
|
||||
// If we're out of bounds, don't update. Factor this in, however, so we can get partial
|
||||
// transparency to the pixel that is already there.
|
||||
denom ++;
|
||||
if (aax < 0 or aay < 0 or aax >= (int)work->texwidth or aay >= (int)work->texheight) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Grab the values to average, for SSAA.
|
||||
// Grab the values to average, for SSAA. Make sure to factor in alpha as a poor-man's
|
||||
// blend to ensure that partial transparency pixel values don't unnecessarily factor
|
||||
// into average calculations.
|
||||
unsigned int texoff = aax + (aay * work->texwidth);
|
||||
r += work->texdata[texoff].r;
|
||||
g += work->texdata[texoff].g;
|
||||
b += work->texdata[texoff].b;
|
||||
float apercent = work->texdata[texoff].a / 255.0;
|
||||
|
||||
r += (int)(work->texdata[texoff].r * apercent);
|
||||
g += (int)(work->texdata[texoff].g * apercent);
|
||||
b += (int)(work->texdata[texoff].b * apercent);
|
||||
a += work->texdata[texoff].a;
|
||||
count ++;
|
||||
}
|
||||
|
|
@ -302,13 +309,28 @@ extern "C"
|
|||
continue;
|
||||
}
|
||||
|
||||
// Average the pixels.
|
||||
intcolor_t average = (intcolor_t){
|
||||
(unsigned char)(r / count),
|
||||
(unsigned char)(g / count),
|
||||
(unsigned char)(b / count),
|
||||
(unsigned char)(a / count),
|
||||
};
|
||||
// Average the pixels. Make sure to divide out the alpha in preparation for blending.
|
||||
unsigned char alpha = (unsigned char)(a / denom);
|
||||
intcolor_t average;
|
||||
|
||||
if (alpha == 0) {
|
||||
// Samples existed in bounds, but with zero alpha.
|
||||
average = (intcolor_t){
|
||||
255,
|
||||
255,
|
||||
255,
|
||||
alpha,
|
||||
};
|
||||
} else {
|
||||
// Samples existed in bounds, with some alpha component, un-premultiply it.
|
||||
float apercent = alpha / 255.0;
|
||||
average = (intcolor_t){
|
||||
(unsigned char)((r / denom) / apercent),
|
||||
(unsigned char)((g / denom) / apercent),
|
||||
(unsigned char)((b / denom) / apercent),
|
||||
alpha,
|
||||
};
|
||||
}
|
||||
|
||||
// Blend it.
|
||||
work->imgdata[imgoff] = blend_point(work->add_color, work->mult_color, average, work->imgdata[imgoff], work->blendfunc);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user