9D-Tony / UnitySmoothPixelFiltering

A unity shader for smooth pixel filtering, based on CptPotato's smooth filtering
MIT License
81 stars 7 forks source link

Overdraw/Underdraw on Nested SpriteRenderers and General Artifacts #2

Open digiwombat opened 2 years ago

digiwombat commented 2 years ago

Hello again!

Likely not a problem for most of my objects, but I've got an issue where my stacked sprites (used for clothing) line up.

image

A/Bing it, it seems like there's a minor one pixel shrinkage that's happening to the pants/shirt that aren't happening to the base body sprite.

I've been messing with the math to see if I can get it to behave, but no dice, mostly just end up shifting uvs around.

Also seems to happen horizontally, which causes issues for multiple sprites I have sitting around:

image

I'll keep poking at it, but I'm pretty sure I won't be figuring it out in the little spare time I've got.

digiwombat commented 2 years ago

After looking at some things, it's very possible that the artifacts are a result of Unity's Bilinear filter more than anything else. Not sure, just an avenue to look into. Seems like the blurring caused by the bilinear fuzzing the edges causes some shrinkage with the shader.

I tried a few other sampling algorithms but nothing really came together there (point still gets wonky and bilinear still ends up losing pixels). I see why people end up 2x and 4xing their sprites now. Life's hard.

(Posted this update in the wrong issue, sorry about that.)

9D-Tony commented 2 years ago

Hey, I wouldn't of thought that it could be bilinear filtering issue as there is only one way of implimenting bilinear filtering as far as I know. The way the shader works is by having the border pixel fade in a out like this example

digiwombat commented 2 years ago

Yeah. I think the problem is that the blurred edges of the bilinear filtered sprite ends up getting pushed out wider and the pant sprite doesn't end up getting blurred quite as badly. Meanwhile, when the shirt sprite is filtered bilinear, it shrinks.

That's about the only reason I can think of for the output since I had figured that they would both size up and down the same.

Here's a screenshot of the default lit sprite shader with my spritesheet filtered bilinear:

image image

Not sure there's a way to do anything about that short of working on point filtered sprites, though I've been unsuccessful there so far.

9D-Tony commented 2 years ago

That's very strange because I thought if all sprites were bilinear filtered they would be the same size. I also tested this on my end and the effect doesn't seem as pronounced as in your image.

9D-Tony commented 2 years ago

I've also spotted something on your sprite that that may be causing an issue. Issue

There seems to be some extra color there on the ankles of the sprite. I wonder if you removed that and tried it again it would solve the horizontal issue.

digiwombat commented 2 years ago

I'm sort of amazed by the variance as well. I was hoping it was an artifact of that being a small sprite sheet (the leggings/t-shirt sheet aren't done so it's just one sprite in a texture alone) but the effect is still there with full sheets:

image

The color you pointed out is the shadow, so removing that would almost definitely get rid of the horizontal though splitting out shadows from our hundreds of sprites would be pretty painful. Haha. If we can get the rest fixed up, we'll probably just do it though since free zooming is pretty valuable.

Pixellore commented 1 year ago

Hi. I too love the shader and how it works, but I too unfortunately have issue with transparent edges that sometimes bleeds in.

Have you guys got any resolution to this issue?

image

digiwombat commented 1 year ago

It's really just a problem of the different layers being bilinear filtered individually and, as a result, not lining up anymore. There's really not a way around it with this approach.

You can try rendering your scene to a render texture and applying the shader to the entire rendered scene (which I haven't gotten around to testing) or you could render to a texture that is some multiple of the actual viewport (2x works well) and set the render texture to be bilinear, then attach it to a UI raw image that fills up the screen. It should downscale pretty cleanly.