Hey guys, I'm working on a 2D pixel art game and am having trouble with 'wobbly' pixels from discreet camera movements. I have read about solutions with down-scaled render textures and rounding positions to whole numbers, but I would really like to keep the possibility of subtle camera movements, while keeping the current resolution. I've thought about approaching the problem with the following: I'm wondering if I could have a shader see how much space a fragment occupies in a pixel (fwidth?) and then decide whether it should be 'drawn' there or not. Is this possible? How would I do it? Am I even thinking about this right?
You're describing aliasing. And you're kind of on the right track with fwidth. You probably want to try using a pixel art antialiasing shader, like RetroAA or the one I posted here: https://forum.unity.com/threads/retro-shader-problems.464185/#post-3021722
Could you please share a simple example for implementing fwidth? I have very little knowledge of shaders but nothing past that. More specifically: 1. What information we need to get from the mesh 2. Should I do something like Code (CSharp): fixed2 frag (v2f vertexInfo) : SV_Target { fixed2 currPos = vertexInfo.vertex; fixed2 fWidthPos = fwidth (currPos); if (abs (fWidthPos - currPos) > 0.5) { // Update the pixels? } else { // Don't update? } } 3. Would I apply this as an image effect or as a material on objects?
See the shader I have in the post I linked to. 1. UVs, that's about it. Derivatives (ddx, fwidth) are only in the fragment shader so it's too late to do anything to the geometry itself with it. 2. Whether a pixel is covered or not is determined by rasterization. Using fwidth to test again won't help since it would come to the same conclusion for a binary on / off. The strength of fwidth and derivatives in general is the ability to calculate the fraction of coverage itself. 3. Once you've gotten to the point of a post process you only have access to the pixel data on screen and have lost any subpixel information that might make fwidth useful.
For a simpler use case example of derivatives, here's an antialiased circle shader. https://forum.unity.com/threads/antialiasing-circle-shader.432119/#post-2796401