Author Topic: Upscaling notes  (Read 594 times)


  • Iokan (+1)
  • *
  • Posts: 8
    • View Profile
Upscaling notes
« on: June 18, 2020, 08:11:52 am »
Warning: this is long and boring.

Upscaling process and known problems
I have a real slapdash collection of bash/python/rust scripts/programs to handle various aspects of upscaling, since quite a few textures can't simply be upscaled from their dumped version alone.  I also don't know much about upscaling, and certainly nothing about training my own models.  I'm hoping I can provide some tools to someone more knowledgeable about these things (and who has a beefier GPU), who can achieve some higher quality upscales.  I've tried to avoid needing to manually fix things up since I don't really intend for the current upscales to be final, and also because it'd be way too much work.

PSX things
The original textures use palettes of either 256 or 16 16-bit ARGB1555 colors.  So there's a good bit of dithering in the textures.
The psx does not have texture filtering or mipmaps.  This seems to mean that textures were free to smush different parts of the texture right up against each other without margins or gutters.

Different models seem to respond to the dithering with varying degrees of success.  For instance, the model that comes with ESRGAN makes everything in the arni background look like straw, but my attempts to undither first seemed to oversmooth things.  I wound up using gigapixel for (all but 2 of) the backgrounds because that's what that one reddit post used and nothing else I tried looked as nice, even if I think it is kind of grainy.

Every pixel is in one of three states: transparent, semi-transparent, or opaque.  On the psx these are encoded as (0, 0, 0, 0), (r, g, b, 1), and (r, g, b, 0), respectively.  To make things more sane in image editors and viewers I use a format of (r, g, b, 0), (r, g, b, [1, 254]), and (r, g, b, 255).

To avoid interpolation/extrapolation introducing a third state where it shouldn't be, I create a separate alpha mask for each state, upscale them independently, and then combine them back together to create the final alpha.  This could probably be done better, but it seems to work.

Regular ol' textures
These are mostly dumped from the iso using the purple cat tools (Some, like FATE's battle texture, seemed to be missing? so I gave up and used the dump from the game itself).  These include things like battle model textures, overworld model textures, portraits, battleground textures, weapon textures.
Split color and alpha, upscale separately, recombine.  Though most of these textures were just thrown into two passes of waifu2x without splitting, which resulted in not-so-great alpha.  I put some of them through a different process to get nicer alpha, mostly battleground backgrounds.  But any textures that have more than one uv island are still using the older upscales because of the lack of gutters.  While colors bleeding between different parts of the model already isn't great, I'm worried that alpha bleeding in the same way would create very noticeable holes.

Tall menu strip portraits
PSX textures are limited to 256 in each dimension, so these are cut in half and put side by side.  I had a script stack them, upscaled them, then unstacked them.

Dialog portraits
Every portrait uses 3(?) palettes:
  • the original from disc
  • one with all the semi-transparency bits flipped on
  • and I can't remember but there may be a third black and white one, but that's hopefully not important

Room backgrounds
These use tile maps.
  • Modified the room viewer to dump every layer as a whole image and its mappings from each disc
  • Manually delete the black cutouts on two background layers so they're transparent instead, like the rest
  • Upscale each layer, color and alpha separately
  • Fix up alpha to avoid gaps, a program looks for edges between layers and makes sure they match after upscale.  Has to take into account that some pixels simply aren't backed by a unique tile.  This only ever makes pixels more opaque, which may currently overcorrect in the case of a semi-transparent top layer and be noticeable (e.g. a bright border at the edge of water, though that may also happen without this step).
  • Recombine color and alpha
  • Create tilemaps from layers
Also, this can create noticeable seams at the boundary of layers that were cut out or copied from lower layers, since the foreground layer gets upscaled without the context of the background.  And, sometimes, the backgrounds don't cut out the foreground elements, which means the foreground element bleeds into the surrounding background during upscaling and when you run between the two it creates a weird look, since you appear to sort of pass in front of part of the foreground.

Element/tech effects
These are the ones uploaded 2048 bytes at a time, exactly as described by the egfx files.  One problem is, those files don't indicate which palettes are used by which parts of the texture, which is information needed to both upscale them and properly replace them.  If there's a way to get this information directly from the iso, I don't know it.  Currently, I dump used textures from the running game, then reconstruct the egfx's vram per seen texture, upscale that, then map them back to replace the skinny little 2048 byte slices.  This means I had to witness every single element/tech in the game, including things like boss deaths and area transitions (dragon god making things complicated right at the end).  So it's not foolproof and I probably missed a few.  But the good news is collecting all those mappings only needed to be done once, anyway, probably.

Another problem is that some of these tiny texture slices are a solid color.  Since dimensions unfortunately aren't included in distinguishing textures and all the uploads were originally 2048 bytes long, there are some name collisions e.g. slices that are fully transparent, but with different dimensions.  There aren't many, but I manually deleted their replacements because I'm not even sure what would happen.

Manually upscaled textures
Dunno how to AI upscale the UI well, so I did most of those myself using inkscape/gimp.  Finicky font atlases, reused parts of textures (the 't' at the end of field effect is actually from some other word in the texture (trap?)).  So if the kerning's all screwy or the font looks bad (I seemed to have only deja vu sans on my computer), that's on me.

I had to clean up the alpha for parts of the dialog frame, and only did the default one so the others are ehh.  You could replace them with any custom frame you want though.

I gave Serge some chainmail because it was very useful for testing trilinear filtering.  Though sometimes I think it came out looking more like a mesh shirt.


  • Iokan (+1)
  • *
  • Posts: 6
  • lightly seared on the reality grill
    • View Profile
Re: Upscaling notes
« Reply #1 on: July 24, 2020, 10:08:55 pm »
Thank you for the extensive info! It's really useful.
I still don't understand how do you deal with such a limited alpha when remaking stuff, let's say in GIMP. I've remade the start-page logo and had to leave it aliased as I could't figure how to deal with alpha.
Could you explain your workflow?


  • CC:DBT Dream Team
  • Porrean (+50)
  • *
  • Posts: 69
    • View Profile
Re: Upscaling notes
« Reply #2 on: November 30, 2020, 03:27:19 pm »
I can give a go at upscale via AI, if required.