I never really know how to start these, so I’m just going to jump back in where I ended it last week, my pursuit of “pixel perfect” sprite rotation.
Non of the methods I identified last week really worked for me, I’m going to do a quick breakdown of why.
While it is possible to achieve pixel perfect rotation by manually creating sprite-sheets for rotations this proved to be too time consuming for my use. The ragdoll system I’ve created relies on too many different sprites combined together to make it feasible to create sheets for all of them in a timely manner.
Upscale Render Texture
The function built into the Unity “2D Pixel Perfect” package, seems to work great, it make the entire game pixel perfect by first rendering the game in the reference resolution then scaling it up. This creates one problem for me, it ruins the parallax background system which is not designed to be pixel perfect but relies on smooth sub-pixel movement. Forcing the parallax background to become pixel perfect makes it very jittery as different layers are moved to new pixel grid locations at different times. I tried to combat this by synchronizing the movement between the different layers, and while this removed most of the jittering it made the parallax seem jerky.
I think that for a background that is further away this wouldn’t be as much of a problem, but my background is very close and pretty shallow, and that the entire background contains vertical lines also makes the jittery and jerky motion really stand out.
Jittery parallax while using “Upscale Render Texture” feature.
Might be a bit difficult to see on the gif (it’s pretty dark), but while actually playing it is very noticeable. I also saw at least one other person expressed the same problem on the Unity discussion board for the package, so I’m rather confident that I’m not missing an easy solution.
My final fallback, initial tests with the shader where very promising. However I ran into some trouble with this as well, for some reason the shader doesn’t render the “right angles” correctly, it just skips over them. This might be a problem with my configuration, or easily solvable by making tiny adjustments to the shader code, but I’m still very inexperienced with shaders and don’t really understand what I’m looking at.
Freezing then skipping over the right angles (0, 90, 180, 270), noticeable when rotating slowly.
Again I’m sure this could easily be solved by someone with better understanding of shaders, either way very generous of Anton Kudin to share his shader, definitely check out his game Mega Sphere, his pixel art has been a great inspiration for me.
While neither of these methods worked satisfactory for my game, this experience helped me better understand whats happening behind the scene, especially the “upscale render texture” feature made me think a lot about how graphics work in Unity.
Rogue Cores “native” resolution is 512 x 288 pixels, I chose this resolution because it is 16:9 and because it is 32 16×16 tiles wide and 18 tiles high, I want the screen to show full uncut tiles.
This should mean that the game is always pixel perfect in this resolution, and at higher resolutions pixel perfection is lost because the game is rendered at the higher resolution where a single game pixel is multiple screen pixels. And the game can only truly be pixel perfect at resolutions that are multiples of the native resolution (without using borders).
Despite having read countless articles and forum posts on achieving pixel perfection in Unity this never really clicked until now…
Armed with this new knowledge I redesigned how I handle different resolutions in the game, rather then support Unitys list of 16:9 resolutions when in windowed mode the game will only support windowed resolutions that are multiples of 512 x 288, full screen will also be supported but running the game full screen will result in a loss of pixel perfection, unless its a multiple 512 x 288. This will eliminate the need to change the orthographic size of the camera, and make me finally get a handle on resolutions.
This also leads me to find and explore Unity “Render Textures”.
Render Textures are special types of Textures that are created and updated at run time. To use them, you first create a new Render Texture and designate one of your Cameras to render into it.
When configuring a render texture you can input its size, so if I make a camera render into a render texture that is 512×288 it would be pixel perfect, and if I use and change the size of this texture in the game it would scale it rather then render it at its new size. Meaning this is probably how the “Upscale Render Texture” from the package works, but without you having to manually do the configuration. When creating your own you can however control exactly what the camera that renders to that texture sees, in my case it only sees objects that should be rotated by Unity physics.
After this is done its only a matter of finding a way of displaying the texture to the main game camera. In my case this is done with a “Raw Image”. And it works surprisingly well!
For now I’m just going to show a couple of samples of how it looks with the “Imp” ragdoll, these updates always takes longer then I think they will, as I struggle with finding the right words and putting my thoughts into English. There is also still some issues that needs to be resolved with the ragdoll before it is finished, so hopefully I’ll be able to show how it works in more detail next week.
Thank you for reading! Comments and feedback is as always greatly appreciated.
Help me out by giving me a follow on twitter or sharing my work, cheers!