Click here for most recent bloom fix build
It's been awhile since I started this thread. GraphicsMod should eventually fix all the bloom stuff, but right now the link above can get you the best fixes.
I would now describe bloom issues as an issue of pixel density. Higher IRs have higher pixel densities for the same area of the screen. A higher pixel density makes blending nearby pixels more accurate, which in turn makes bloom more accurate and less blurry (bloom should be blurry). The fix is either to remove the high IR for bloom or, if that causes aliasing/shimmering artifacts due to size differences, apply blurring to the bloom. Blurring works great in most games.
***
Bloom issues are caused by the Scale EFB option upscaling small textures that shouldn't be touched. So if we conditionally don't scale small textures, we can avoid the bloom issues. This would be generally the same method as my game hacks to fix bloom, but it'd target all efb copies instead of just bloom ones. This method would be less buggy, more accurate, and far more widely applicable than per-game hacks, as long as buggy bloom games don't have other small efb copies that may need to be scaled up.
In VideoCommon\TextureCacheBase.cpp line 1659 to 1668. It would be changed to something like:
/edit changed code a bit.
u32 scaled_tex_w = g_renderer->EFBToScaledX(srcRect.GetWidth());
u32 scaled_tex_h = g_renderer->EFBToScaledY(srcRect.GetHeight());
//Or use if (width < 300)
if (width < 600)
{
scaled_tex_w = width;
scaled_tex_h = height;
}
// Optional - not sure if needed.
// if (scaleByHalf)
// {
// tex_w /= 2;
// tex_h /= 2;
// scaled_tex_w = tex_w;
// scaled_tex_h = tex_h;
// }
-- Yes I know that could be written better. I can't figure out how to fix ScaleByHalf with game-based ASM hacks, but this code will do it and enable games like Okami and Metroid Prime 3 to be fixed.
-- I could've sworn I saw some game ScaleByHalf(?) upwards (320x src-> 640x dst), but don't know if that's dealt with here. You'd probably want that to be EFB scaled. Or is 640 dst always width = 640 by this point in this code?
-- Some games may want scaled 320x efb copies, but there are definitely games like Okami that suffer from 320x being scaled, so only scaling >320x is a good start.
I'm not sure if there are any sizes between 320 and 640, or above 640, so I guess the code might be simply to "only scale 640x full sized EFB copies".
If this does work, I'd suggest a toggle-able hack to enable it. I'd be happy to test it, if someone could correctly code and build it.
/edit Actually metroid 3 seems to use 320 and smaller efb copies for everything, so this would be the same as disabling scaled efb.
/edit Another option may be to not scale efb copies that are being offset and combined with the previous copy, but I'm not sure what the offset factor is called in the code. It's a float like 1.05 in the game.
/edit I got it working:
It seems to fix Okami, but I only tested for a moment. Fixes Xenoblade. Fixes HOTD Overkill.
/edit Added Slider version of fix. May have bugs.
It's been awhile since I started this thread. GraphicsMod should eventually fix all the bloom stuff, but right now the link above can get you the best fixes.
I would now describe bloom issues as an issue of pixel density. Higher IRs have higher pixel densities for the same area of the screen. A higher pixel density makes blending nearby pixels more accurate, which in turn makes bloom more accurate and less blurry (bloom should be blurry). The fix is either to remove the high IR for bloom or, if that causes aliasing/shimmering artifacts due to size differences, apply blurring to the bloom. Blurring works great in most games.
***
Bloom issues are caused by the Scale EFB option upscaling small textures that shouldn't be touched. So if we conditionally don't scale small textures, we can avoid the bloom issues. This would be generally the same method as my game hacks to fix bloom, but it'd target all efb copies instead of just bloom ones. This method would be less buggy, more accurate, and far more widely applicable than per-game hacks, as long as buggy bloom games don't have other small efb copies that may need to be scaled up.
In VideoCommon\TextureCacheBase.cpp line 1659 to 1668. It would be changed to something like:
/edit changed code a bit.
u32 scaled_tex_w = g_renderer->EFBToScaledX(srcRect.GetWidth());
u32 scaled_tex_h = g_renderer->EFBToScaledY(srcRect.GetHeight());
//Or use if (width < 300)
if (width < 600)
{
scaled_tex_w = width;
scaled_tex_h = height;
}
// Optional - not sure if needed.
// if (scaleByHalf)
// {
// tex_w /= 2;
// tex_h /= 2;
// scaled_tex_w = tex_w;
// scaled_tex_h = tex_h;
// }
-- Yes I know that could be written better. I can't figure out how to fix ScaleByHalf with game-based ASM hacks, but this code will do it and enable games like Okami and Metroid Prime 3 to be fixed.
-- I could've sworn I saw some game ScaleByHalf(?) upwards (320x src-> 640x dst), but don't know if that's dealt with here. You'd probably want that to be EFB scaled. Or is 640 dst always width = 640 by this point in this code?
-- Some games may want scaled 320x efb copies, but there are definitely games like Okami that suffer from 320x being scaled, so only scaling >320x is a good start.
I'm not sure if there are any sizes between 320 and 640, or above 640, so I guess the code might be simply to "only scale 640x full sized EFB copies".
If this does work, I'd suggest a toggle-able hack to enable it. I'd be happy to test it, if someone could correctly code and build it.
/edit Actually metroid 3 seems to use 320 and smaller efb copies for everything, so this would be the same as disabling scaled efb.
/edit Another option may be to not scale efb copies that are being offset and combined with the previous copy, but I'm not sure what the offset factor is called in the code. It's a float like 1.05 in the game.
/edit I got it working:
It seems to fix Okami, but I only tested for a moment. Fixes Xenoblade. Fixes HOTD Overkill.
MKW Picture + Discuss: