forums.PPSSPP.org
Ways to counteract sprite glitches caused by upscaling / texture filtering? - Printable Version

+- forums.PPSSPP.org (https://forums.ppsspp.org)
+-- Forum: PPSSPP - Playstation Portable Simulator Suitable for Playing Portably (/forumdisplay.php?fid=1)
+--- Forum: Development (/forumdisplay.php?fid=3)
+--- Thread: Ways to counteract sprite glitches caused by upscaling / texture filtering? (/showthread.php?tid=13556)



Ways to counteract sprite glitches caused by upscaling / texture filtering? - Kolrath - 10-26-2014 04:06 AM

I've only recently gotten into using PPSSPP, but I've been using the Playstation 2 emulator PCSX2 for quite some time and theres something I've been wondering about...

I was curious what all ways exist in PPSSPP, or could be implemented into PPSSPP, to counteract the glitches that can occur from upscaling / filtering of the 2D sprites in games.

The glitches I'm refering to are things like the lines that appear sometimes on menus, or the one pixel wide gap that appears between menu sprites, or things that commonly occur on RPG dialogue sprites (particularly on the animated section) in some games.

A good example of dialogue sprite glitches would be the faces of the characters in the game Unchained Blades. For reference, look at the first and last screenshots in the initial posting in this thread - forums.ppsspp.org/showthread.php?tid=1866
(Sorry, the http:// part is missing, but it wouldn't allow me to post my thread if it had clickable links in it.)

In these pictures it seems that the animated portion of the character sprites is its own seperate sprite, but when filtered it ends up having a gap between it and the rest of the character sprite. It looks like if the animated sprite portion could just have its height and width boosted by a pixel it would be a perfect looking image.

In the Playstation 2 PCSX2 emulator there were various ways to deal with these kinds of issues with varying degrees of success and quality. Often times there were "offset hacks" available to fix the issue in specific games or even the ability to adjust your own offset to attempt to correct them. I remember the PS2 Atelier series, Mana Khemia, Ar tonelico, and just about every other 2D heavy RPG needing some for of tweaking, changing, or offset magic to minimize the glitches from upscaling and filtering.

I'm curious if there is anything like this that is currently in PPSSPP to address these kinds of glitches or if its possible for this like this to be implemented into PPSSPP?

The only thing I know of so far to address this in PPSSPP is to either run the game in native resolution as a whole or to change "Texture Filtering" from "Auto" to "Nearest".

Using the method of changing filtering to nearest seems to address most if not all of the sprite glitches while still allowing the 3D stuff to be in higher resolution... but it sadly results in the 2D sprites looking heavily pixelated. Its a real shame too because more often than not the filtered sprites, aside from the minor glitches, look fantastic.

Are there other methods I'm unaware of or perhaps just a way to adjust the level of FXAA that can be applied to the whole screen via post processing to try to cut down on the pixelation?


RE: Ways to counteract sprite glitches causes by upscaling / texture filtering? - [Unknown] - 10-26-2014 08:24 PM

One problem with linear filtering is rounding. We've had (and still have) issues because of not always matching the rounding on a PSP.

At 2x, though, you start to have "impossible" problems the PSP didn't have. Consider a 4x4 grid:

Code:
+---+---+---+---+
|   |   |   |   | 3
+---+---+---+---+
|   | X | X |   | 2
+---+---+---+---+
|   | X | X |   | 1
+---+---+---+---+
|   |   |   |   | 0
+---+---+---+---+
  0   1   2   3

Suppose I wanted to draw a texture in the area marked with X's. It'd be easy; I would just draw from (1, 1) to (3, 3). The last coordinate is "exclusive" (meaning, it draws UNTIL that.)

But, for various reasons my math might not be that accurate. Maybe I end up drawing from (1.3, 1.3) to (2.5, 2.5). It's all gravy. As a developer, I don't have to worry - it still looks picture perfect on the screen. No need to go back and spend countless more hours and tell my boss that the release date ain't gonna happen as planned.

But, things go to pieces when we start drawing at a higher resolution. Here's the same grid, double the resolution:

Code:
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 3.5
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 3
+---+---+---+---+---+---+---+---+
|   |   | X | X | X | X |   |   | 2.5
+---+---+---+---+---+---+---+---+
|   |   | X | X | X | X |   |   | 2
+---+---+---+---+---+---+---+---+
|   |   | X | X | X | X |   |   | 1.5
+---+---+---+---+---+---+---+---+
|   |   | X | X | X | X |   |   | 1
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 0.5
+---+---+---+---+---+---+---+---+
|   |   |   |   |   |   |   |   | 0
+---+---+---+---+---+---+---+---+
  0  0.5  1  1.5  2  2.5  3  3.5

Now, if Mr. Smartypants who is good at math draws (1, 1) to (3, 3), everything is still okay (remember the last coordinate is exclusive.) Exactly the same pixels are filled in.

But, if you recall, I had a deadline. (1.3, 1.3) to (2.5, 2.5) worked before, but what happens now? Well, 1.3 rounds up, and 2.5 is exclusive, so my box is half the size it was supposed to be. Ack.

The "best" solution to this problem is an extra step that snaps the coordinates to what they would be at 1x. So, for example, 1.3 would get rounded down, and 2.5 would get rounded up. Then we would draw (1, 1) to (3, 3) and it'd look fine.

The reasons we haven't done this yet are:
* It's slower. Snapping would have to be done after transform, and probably in the GPU. We'd probably have to move the viewport transform into the shader as well, not sure.
* My example was positions, but the problem applies to texture coordinates as well, which increases perf hit / complexity.
* It would hurt visual quality of 3D models or games written by Mr. Smartypants above. Animation will look more fluid without the snapping.
* No one has written it yet.

The main problems should be solvable by making it an option. Possibly a separate option for depth as well (which I'm pretty sure not snapping there is causing problems in at least Phantasy Star Portable 1.)

That said, maybe there's some better way. It'd be nice to not have an option that needs to be customized per game. I don't know what PCSX2 does because I usually play games on most systems at 1x.

Another problem can be caused by increased sampling. When OpenGL is generating more pixels near the edge, it may want to sample more texels than before (especially depending on the texture size vs. drawing size.) In the case of a sprite sheet, this can cause texels of completely wrong colors to be filtered in (iirc this is a problem in FF4.) This is a major problem when alpha or color testing is used (e.g. when fuchsia is used as transparent.)

And then there's texture scaling, which brings even more problems to the table, since it is (somewhat necessarily) applied to entire textures, not just the sampled regions. This worsens the problems mentioned above.

So, it's definitely a complicated issue for which there's not a single silver bullet, at least not that I know of.

-[Unknown]


RE: Ways to counteract sprite glitches causes by upscaling / texture filtering? - Kolrath - 10-26-2014 11:49 PM

My apologies in advance... massive wall of inane text incoming...

(10-26-2014 08:24 PM)[Unknown] Wrote:  One problem with linear filtering is rounding. We've had (and still have) issues because of not always matching the rounding on a PSP.

At 2x, though, you start to have "impossible" problems .... Ack.

Thank you for the explaination and the examples of one of the main culprits of these glitches! I've read countless postings about the issues back in the PCSX2 forums in the past and this is the first time I saw things described in laymans terms.

That all made a lot of sense and its entirely understandable that the programmers wouldn't shoot for perfection in those cases. If it looks correct on the only resolution the the system will ever have it wouldn't make sense to waste any more time on it.

I appreciate the info.



(10-26-2014 08:24 PM)[Unknown] Wrote:  The "best" solution to this problem is an extra step that snaps the coordinates to what they would be at 1x. So, for example, 1.3 would get rounded down, and 2.5 would get rounded up. Then we would draw (1, 1) to (3, 3) and it'd look fine.

The reasons we haven't done this yet are:
* It's slower. Snapping would have to be done after transform, and probably in the GPU. We'd probably have to move the viewport transform into the shader as well, not sure.
* My example was positions, but the problem applies to texture coordinates as well, which increases perf hit / complexity.
* It would hurt visual quality of 3D models or games written by Mr. Smartypants above. Animation will look more fluid without the snapping.
* No one has written it yet.

The main problems should be solvable by making it an option. Possibly a separate option for depth as well (which I'm pretty sure not snapping there is causing problems in at least Phantasy Star Portable 1.)

Based on the examples you gave that solution does seem like it would solve a lot of the glitches like the Unchained Blades faces and the countless games where the 2D HUD or in-game menus have gaps and the like.

I can understand how that would make things slower as well. On the bright side the games that suffer the most from the sprite glitches are generally those that are 2D heavy and are already quite fast even on lower end systems.

I also agree that such a thing should be optional if implemented. This way the user can have more influence on whether they want sprites to look "right" or better performance. It would also allow people to turn it off for 3D games and avoid the hit to the quality of 3D visuals and animation.

When you're talking about depth write issues in Phantasy Star Portable 1 I assume you're talking about the issue where text doesn't show?

I saw that one occuring when I tried out my copy of the game. I also saw similar things when trying out Valhalla Knights 2. The "monster encyclopedia" (forget what its called in game) that you can view from the inventory menu in-game seems likes it drawing the stuff to the screen in the wrong order, or at the wrong depth, since the monster models and information isn't there... its just the blank book page with darkened areas where that stuff should be.


My programming experience is fairly limited, and my emulation related "work" consists solely of making a CRC hack to disable the blurring effects in Disgaia 2 for use in PCSX2 and finding a workaround to the Growlanser Generations saving freeze when running it through PCSX2. Please forgive me for anything I'm about to say thats impossible or stupid! I know just barely enough about this stuff to get my foot up and into my mouth making me look like an idiot, so I can't imagine anything I'm about to say its even plausible, but...

Out of curiousity, does PPSSPP have any way of "knowing" when its working with 2D as opposed to 3D? Like a flag or some such?

If it has a way to differentiate between 2D and 3D then, in regards to the idea of this "best solution" of rounding down / up, is it possible for that method of rounding to be applied only when PPSSPP is dealing with 2D and not when its dealing with 3D?

I admit to knowing nothing about the inner workings of PPSSPP, its all black magic and miracles to me, so the above idea is based solely on wondering if there is some way for the program to differentiate between the two.



Alternatively, would it be possible to "draw" all of the 2D textures that are about to be drawn on screen to a seperate buffer as one "whole", single, texture and then to upscale and filter that?

I remember having to jerry-rig something along these lines once when working on an Xbox Live Arcade project back in the day that was having some issues with its sprites at different resolutions. Changing the sizes of the games map sprite and object sprites seperately was causing issues so instead it was necessary to draw one "frame" of the screen with all its sprites as they would appear at the native resolution into a buffer as a single texture. Then we'd take that texture of what the whole screen should look like with all the sprites on it and upscale / downscale it to the desired resolution. Once that was done it would just be applied to the screen.

Using the Unchained Blades dialogue sprites as an example, since the 3D part of the game is the background with the 2D stuff overlayed on top of it. Would it be plausible to store all the 2D sprites (characters, HUD, etc) as they would display on the screen at 1x resolution as a single texture and then do the upscaling and filtering of that texture as a whole before displaying it to the screen?



Mostly curious about the above stuff because when you turn "Texture Filtering" to "Nearest" the game (Unchained Blades) is able to display the sprites as they'd look at native resolution while still keeping the 3D at high resolutions. Which made me wonder if there is a way for PPSSPP to distinguish between the two. Though I suppose its just the 3D models themselves being at a high resolution and not necessarily the 2D textures on those models.




(10-26-2014 08:24 PM)[Unknown] Wrote:  That said, maybe there's some better way. It'd be nice to not have an option that needs to be customized per game. I don't know what PCSX2 does because I usually play games on most systems at 1x.

I agree that it would be nice to not have a need to customize options for each game.

This was one of the main things that caught me off guard when checking out PPSSPP for the first time. When I first started using PPSSPP I was shocked that there was very little setup required to run a game and that most games looked and ran great with default settings.

With PCSX2 there wasn't really a default setting, aside from native, that would be optimal for all games or often even different games in the same series or using the same engine. There would often be various settings you'd need to tweak or adjust, especially when using higher resolutions, to get the "optimal" mix of performance and quality.

This is a lot of the reason that I started this thread. I was so accustomed to dicking around with settings and tweaking things for each game in PCSX2. In PPSSPP whenever I encountered anything odd I wasn't really sure what all options were at my disposal to attempt to "fix" anything I encountered.

I confess I found pushing games well beyond their limits and tweaking settings until they looked and ran "best" was addicting to me and kind of a good portion of my enjoyment with the PCSX2 emulator. Unless something too majorly restricted me I usually ran most PS2 games at 4x to 6x resolutions so I got quite familiar with the various options and tweaks that could "fix" a given issue.


As far as I know the majority of the sprite glitches in PCSX2 were also caused by rounding issues. Being that its open source, it even uses github and Orphis Buildbot like PPSSPP does, maybe it would be possible to find some "solutions" for the PPSSPP sprite glitches in the coding of PCSX2? While I'm sure the overall inner workings are quite different, I'd imagine that the various methods of dealing with rounding and displaying textures in PCSX2 could be applied to PPSSPP.

Most of the tweaking that could be done in PCSX2 was found in the GSDX (PCSX2's primary graphics plugin) settings. GSDX was created by "Gabest" who also made the movie player "Media Player Classic", now called "Media Player Classic - Home Cinema". Gabest seems to like doing things in relation to graphics a good bit... it would likely even possible to contact him regarding PPSSPP.... he always seemed a fairly friendly and level headed sort.

The GSDX options that had the most affect on sprite glitches caused by filtering or upscaling were...

Texture Filtering - There were three different settings, though I'm not sure specifcally what they did as they weren't named like in PPSSPP. Instead it was either fully on, half on, or off.

And Hardware hacks like...

Half Pixel Offset - used to fix misaligned fog, bloom, or blending effects.

Sprite Hack - Used to get rid of black inner lines in some filtered sprites. Had a full, half, or off option. Full fixed issues involved in the game Tales of Destiny. The half option fixed things in Mana Khemia and Ar tonelico.

Wildarms Offset - Lowered GS precision to avoid gaps between pixels when upscaling. Primarily used to address glitches in the Wild Arms series, hence the naming, but could also be used to correct dialogue sprite issues in Ar tonelico.

Texture Coordinates Offset Hack - This was a user customizable hack. It was an offset for ST/UV texture coordinates and fixed some texture issues and post processing aligment issues. Often times a value of 250, 500, or 1000 to the X or Y offset was enough to fix some game glitches. Although, its use could also throw other things out of whack though like when a game uses a flipped version of a sprite such as Mana Khemia 2 having the same dialogue sprite just mirrored depending on whether they were the one talking or the one responding.






(10-26-2014 08:24 PM)[Unknown] Wrote:  Another problem can be caused by increased sampling. When the OpenGL is generating more pixels near the edge, it may want to sample more texels than before (especially depending on the texture size vs. drawing size.) In the case of a sprite sheet, this can cause texels of completely wrong colors to be filtered in (iirc this is a problem in FF4.) This is a major problem when alpha or color testing is used (e.g. when fuchsia is used as transparent.)

And then there's texture scaling, which brings even more problems to the table, since it is (somewhat necessarily) applied to entire textures, not just the sampled regions. This worsens the problems mentioned above.

When you're talking about sprite sheets here you're talking about it accidentally reading pixel information from other sprites on the sheet near the one the emulator is trying to work with correct?

If thats what you're talking about then I can completely understand that causing some complications. If thats not what you meant then I apologize but thats all stuff a bit over my head and beyond my limited knowledge on the subject.





(10-26-2014 08:24 PM)[Unknown] Wrote:  So, it's definitely a complicated issue for which there's not a single silver bullet, at least not that I know of.

-[Unknown]

Yeah I can imagine its quite a complicated issue. Especially since each game is likely to be just different enough that a solution for one wouldn't work in another... or could even make it worse or break it entirely.

Thats the majority of why I started this thread. I was so used to tweaking PCSX2 settings for games that upon seeing PPSSPP's more streamlined options I wasn't quite sure what I could or should do to address any issues I encountered.

I know that PPSSPP is still quite young, but is it likely that it will end up like PCSX2 down the road and have a plethora of more game specific hacks / toggles or is PPSSPP going to be more stricly a streamlined emulator?

Aside from running games in 1x native resolution or using "Texture Filtering" set on "Nearest" are there any other currently implemented options that do or may be able to be used to "fix" various glitches? Those are the only two things I've found so far.



In closing, thank you very much for your posting. I thoroughly enjoyed reading it and it was quite informative.

Additionally, I hope that nothing I've said was taken as demands, requests, or anything of the sort as none of it was meant like that. It was all entirely out of curiousity or to point out that I've seen similar issues addressed elsewhere in certain ways. I've seen a number of times in threads and github postings where people pointed to JCPSP and the way that they handled things so I figured referencing PCSX2 wouldn't be considered too out of line for any reason. I sincerely appreciate all the work that the PPSSPP "team", as a whole, has put into making PPSSPP. Its been a blast so far being able to enjoy all my old games again in all their beefed up glory!


RE: Ways to counteract sprite glitches causes by upscaling / texture filtering? - [Unknown] - 10-27-2014 02:34 AM

Yes, I think the Phantasy Star Portable 1 and Valhalla Knights problems are the ones you mentioned (I subtly linked to the respective github issues in my post.) I'm not sure about the monster being entirely missing but it sounds right.

As far as 2D vs 3D; we know when the game is drawing without transform enabled, aka "through mode". When not using transform, you're pretty much necessarily drawing 2D (although depth still works.) However, many 2D games actually still draw with transform enabled.

I guess it might potentially be possible to use a separate (1x) buffer for 2D and then composite it onto the primary buffer, but it would be very hard to detect when to do this properly. Some games may switch transform off and on often (I'm pretty sure I've seen it), and doing a blending copy each time would devastate their performance I'm pretty sure. It could be more realistic to do this if one of the game's buffers is used ONLY for 2D, but that's likely only the case with games that do everything with transform off.

The nearest thing specifically probably means this is a texture coordinate problem. Here's a new grid:

Code:
+---+---+---+---+ 0
| X | Z | Z | X |
+---+---+---+---+ 1
| Y | A | A | Y |
+---+---+---+---+ 2
| Y | A | A | Y |
+---+---+---+---+ 3
| X | Z | Z | X |
+---+---+---+---+ 4
0   1   2   3   4

Okay, so imagine that every letter above (X, Y, Z, and A) is a different color. Each of these is called a "texel". You'll also notice that I've moved the grid lines (this is actually how positions work too, but I was trying to simplify.)

Each texel is actually at the "center". That is, (0.5, 0.5) is X. If I ask for (1, 1), that's when filtering comes into play. Nearest snaps to (0.5, 0.5). Linear essentially takes (simplifying) X, Y, Z, and A, and blurs them together (each weighted by distance) to give you the final pixel.

At a higher resolution, you end up sampling more from the texture. Imagine that I was only trying to draw the A colors from that grid: I would use (1, 1) - (3, 3) again.

You might think, "hey wait - you're outside the centers you just explained, you made a mistake right?" But, no, I want the "edges" of the texels. The reason is because I'm going to map it to the "edges" of the pixels on screen, and these also have centers. I will end up with center -> center. Perfect.

Except, we get that tricky higher resolution problem again. Before, my (1, 1) - (3, 3) sampled 4 total times (one per each pixel I'm drawing.) But, now I'm drawing 16 pixels (because it's double X and Y.)

Before, the samplings actually happened at each center. At 1.5 and 2.5 on both X and Y. Now they happen four times each for X and Y: 1.25, 1.75, 2.25, 2.75. These still correspond to the centers of the pixels (destination) I'm drawing, but no longer the centers of the texles (source.)

To simplify, I'm only going to talk about X for the moment. Here's a slice of the grid enlarged a bit:

Code:
+-------+-------+-------+-------+ 1
|   Y   |   A   |   A   |   Y   |
+-------+-------+-------+-------+ 2
0  0.5  1  1.5  2  2.5  3  3.5  4

At 1x, the first sample was at 1.5 - A. But at 2x, the first sample is 1.25. The pixel center isn't exactly there, we're 25% the way to 0.5. So the resulting color is Y * 25% + A * 75%. Not exactly A.

Nearest "fixes" this, because it forces it to use 1.5. However, it also means that no filtering happens, even if the game looks better at 1x with filtering happening (and quite a few do; the PSP's GPU allows the game to turn on or off filtering and most games request it on for the majority of their drawing.)

Quote:This was one of the main things that caught me off guard when checking out PPSSPP for the first time. When I first started using PPSSPP I was shocked that there was very little setup required to run a game and that most games looked and ran great with default settings.

I don't think it should require detailed setup. In contrast to your experience, I hate the experience in other emulators where I have to second guess every setting, and burn all the free time I had to play the game trying to get the settings to a workable place.

I think it's fine to have enhancements to play with, but I would rather work a little harder to find that awesome default that makes games look beautiful without all the fuss, and have only the necessary options for the rest.

"Half on" is probably like our "Auto". Auto means "let the game decide". Sometimes it's on, sometimes it's off. I'm not sure what the other 4 do but it sounds like they indeed mess with positions of texture coordinates.

Sprite sheets: yes. Many games upload a single texture that is e.g. a tilemap. Then they carefully render from a portion of that texture (see my example above, where the Xs, Ys, and Zs are other tiles.) When the texels from an adjacent tile bleed in, bad things happen. FF4 has a green BG in unused space, iirc, which is why it gets green boxes around certain tiles.

No, there aren't any other options right now worth messing with for this issue. I don't think PPSSPP will ever have a big mess of options but it will likely have more as we run out of ways to fix things for all games.

-[Unknown]


RE: Ways to counteract sprite glitches causes by upscaling / texture filtering? - Kolrath - 10-27-2014 10:04 PM

(10-27-2014 02:34 AM)[Unknown] Wrote:  *examples*

Thanks again for the examples and explaination!

I don't suppose you write tutorials on programming in relation to game programming do you? C#, C++, whatever... I'd read the hell outta them!




(10-27-2014 02:34 AM)[Unknown] Wrote:  I don't think it should require detailed setup. In contrast to your experience, I hate the experience in other emulators where I have to second guess every setting, and burn all the free time I had to play the game trying to get the settings to a workable place.

I certainly don't think it should require a detailed setup. I'm actually quite glad PPSSPP doesn't require more than me calling it up and loading a game to get things going.

Its just that when I run into issues I'm not entirely sure what I can do about them. I always prefer to try to do what I can to get things working on my own before I go for assistance.

I think the reason all the tweaking in other emulators never bothered me much is likely because I grew up with quite possibly the worst DOS computer ever made. I spent ages tweaking EMS and XMS memory, making boot disks, editing game files if needed, and whatever else just to get low-end games running. I think I spent more time doing that than playing games. I suppose its just ingrained in me.



(10-27-2014 02:34 AM)[Unknown] Wrote:  No, there aren't any other options right now worth messing with for this issue. I don't think PPSSPP will ever have a big mess of options but it will likely have more as we run out of ways to fix things for all games.

Thanks for the confirmation on this.


Thanks again, I appreciate the responses and the information. I wish you and everyone else working on the PPSSPP the best of luck.


RE: Ways to counteract sprite glitches caused by upscaling / texture filtering? - Kolrath - 10-29-2014 07:07 AM

I noticed that the builds of PPSSPP available on buildbot have an additional graphics option that wasn't in the latest stable PPSSPP release.

That option being "Screen Scaling Filter" under the section "Texture Filtering".

Naturally, I felt compelled to mess around with this option and see what all effects it had and if it did anything in regards to upscaling / filtering glitches. I fired up Unchained Blades because its "face box" glitches are quite noticeable and occur pretty much immediately after starting a new game.

I actually had some decent results in goofing around with it. I found that by changing the "Screen Scaling Filter" from "Linear" to "Nearest" and then setting "Texture Scaling" to "Auto, Hybrid" would cause the face boxes to be significantly less noticeable. If not specifically looking for defects its likely that most people wouldn't really notice. Not perfect by any means, but for most people I think these settings could work.

For comparison here's some examples...

* 1st image is using software rendering mode
* 2nd image is using the default PPSSPP graphics settings
* 3rd image is using Screen Scaling Filter (Nearest) and Texture Scaling (Auto,Hyrid)

Example 1
[attachment=12947], [attachment=12949], [attachment=12951]

Example 2
[attachment=12948], [attachment=12950], [attachment=12952]


RE: Ways to counteract sprite glitches caused by upscaling / texture filtering? - [Unknown] - 10-29-2014 10:06 AM

Hmm, that's interesting. That setting controls how the final render is sampled when stretching it to your screen.

-[Unknown]