I am working on a 2D “pixel perfect” project. Currently I am designing for a fixed resolution of 1200x675.
I would like to know how to prevent anti-aliasing when the build goes into full screen mode. I would like to release my project on a couple different platforms (xbox, steam), and I am hoping I can rely on the idea that the scaling the unity does will be enough to accommodate for different screen resolutions (though with the same aspect ratio).
For example, when i run the stand-alone player on my desktop, then enter full-screen mode, it seems like there is a bit of blurring. I have my sprites sent to point filtering, but I am wondering if there is yet another option in the player or build settings I should explore so that the graphics are as clean as possible when stretched.
I had briefly tried to adjust the quality settings only allowing for fatest, hoping that would force basic graphic scaling, but the build wound up running at 200fps, and caused a fair amount of strange behavior in the game.
One idea would be to create a fixed resolution Render Texture in your assets. Assign your main camera to render to this texture, then write a simple shader with point-filtering that will output that texture to the screen. It should result in the old retro look without bilinear or trilinear filtering. As for the framerate, you can set Application.targetFrameRate to lower value, like 60 or 140, or use Vertical Sync option in Player options.
This isn't a problem with anti-aliasing, more so with bilateral upscaling. Basically, as Eudaimonium said, you can create an image effect for scaling. I wrote one a couple of weeks ago that works on percentages for both upscaling and downscaling. The great thing is, because it uses render textures, you preserve a heap more power than rendering a scene and filtering it etc. Give me a bit, and I'll modify it to suit this better (I have really weird workspaces, so it's currently not set out in a particularly practical fashion).
Something else I have noticed, omitting the shader all together (in Graphics.Blit) doesn't seem to have any effect on the result. Am I mistaken in this?
One last thing to add. I notice that when this is working properly, if one uses alt+enter to flip between windowed and full screen mode it breaks. In my case, i see fragments of some of my sprite sheets and a debug message saying that the camera has let go of the RenderTexture. Once it has "broken", I have to restart the application. Any idea on what might be causing this, or how to fix it?
For myself, and those reading, what led you to believe the issue was bilateral filtering? Is there some reading or docs on this related to unity? I had done a bit of search, and came up empty handed. This leads me to believe it would be a bit hard to track down on one's own without guidance, and that you likely have a lot of experience with this sort of thing.
Building on the solution from @Namey5 , I have the following code in C#. I simplified it down to just one script for my needs. I hope it helps others. In my case, I build most of my game via code, so having something rendering in the game preview when I am not playing the game wasn’t something I needed to consider.
PixelPerfectRenderer.cs (Attach to your camera)
using UnityEngine;
using System.Collections;
public class PixelPerfectRenderer : MonoBehaviour {
// PUBLIC VARS ----
public FilterMode filterMode;
public int scaling = 100;
public Depth depth = Depth.twentyfour;
// STRUCTS ----
public enum Depth {
none,
sixteen,
twentyfour
};
// PRIVATE VARS ----
private Camera renderCamera;
private RenderTexture src;
private bool isFullScreen;
// UNITY API ----
void Awake () {
isFullScreen = Screen.fullScreen;
SetRenderCam();
}
void Update() {
// have we toggled the windows/fullscreen mode?
if(Screen.fullScreen != isFullScreen) {
isFullScreen = !isFullScreen;
SetRenderCam();
}
}
void OnPreRender() {
// this ensures that w/e the camera sees is rendered to our RenderTexture
renderCamera.targetTexture = src;
}
void OnPostRender() {
// for some reason we need to se the traget texture to null before we blit
renderCamera.targetTexture = null;
// casting null as a RenderTexture allows us to blit to the screen
Graphics.Blit(src, null as RenderTexture);
}
// PUBLIC FUNCTIONS ----
public int DepthCalc(Depth d) {
if(d == Depth.none) {
return 0;
}
if(d == Depth.sixteen) {
return 16;
}
if(d == Depth.twentyfour) {
return 24;
}
return 0;
}
public void SetRenderCam() {
if (!renderCamera) {
renderCamera = GetComponent<Camera>();
}
// we could use this to do scaling at different percentages
int s = scaling / 100;
src = new RenderTexture(Screen.width * s, Screen.height * s, DepthCalc(depth));
src.filterMode = filterMode;
renderCamera.targetTexture = src;
}
}
And if you want to see it when not playing, add to the top of the script: @script ExecuteInEditMode //for JS [ExecuteInEditMode] //for C#
The script is four year old. I did my max to reconfigure it and Unity itself also helped a lot, but it doesn't seems to work. The lines in the errors don't even exist, and they are not even mentioned in the script (try it by yourself if you want). Have you read my comment? I said that i already tried.
One idea would be to create a fixed resolution Render Texture in your assets. Assign your main camera to render to this texture, then write a simple shader with point-filtering that will output that texture to the screen. It should result in the old retro look without bilinear or trilinear filtering. As for the framerate, you can set Application.targetFrameRate to lower value, like 60 or 140, or use Vertical Sync option in Player options.
– EudaimoniumThis isn't a problem with anti-aliasing, more so with bilateral upscaling. Basically, as Eudaimonium said, you can create an image effect for scaling. I wrote one a couple of weeks ago that works on percentages for both upscaling and downscaling. The great thing is, because it uses render textures, you preserve a heap more power than rendering a scene and filtering it etc. Give me a bit, and I'll modify it to suit this better (I have really weird workspaces, so it's currently not set out in a particularly practical fashion).
– Namey5