Resolution Superscaling?

Hello there! I am creating a game in which I wish to have a camera render buffer that is different from the final game resolution (like the nVidia control panel option DSR “Downsample Resolution”). This option can be seen in games like Overwatch and Battlefield, as well as many others. The idea is that this can be increased to favor image quality, or decreased for performance without affecting the final displayed resolution. Optimally I wish to do this to a specific camera (as my final render output is a composite of multiple cameras which render layers on top of eachother to produce the final image) however I would accept having to treat this as one render if need be.

Here is what I’ve tried so far, and it isn’t working… Basically I’m trying to fetch the native Height and Width of the game, multiply it by a factor, and then set the new rendering parameters. The rendering resolution never seems to change from the system resolution though. Code below, thanks;

public void OnResolutionFactor(float value)
{
Debug.Log(“-- Rendering Resolution (” + Display.main.renderingWidth + “,” + Display.main.renderingHeight + “)”);

UserSettings.settings.resolutionFactor = value;
resolutionFactor.text = UserSettings.settings.resolutionFactor.ToString();
Debug.Log(“Resolution Factor :” + UserSettings.settings.resolutionFactor);
Debug.Log(“System Resolution (” + Display.main.systemWidth + “,” + Display.main.systemHeight + “)”);
Debug.Log(“++ Rendering Resolution (” + Display.main.renderingWidth + “,” + Display.main.renderingHeight + “)”);

Display.main.SetRenderingResolution
(
Mathf.FloorToInt(Display.main.systemWidth * UserSettings.settings.resolutionFactor),
Mathf.FloorToInt(Display.main.systemHeight * UserSettings.settings.resolutionFactor)
);

Debug.Log(“-- Rendering Resolution (” + Display.main.renderingWidth + “,” + Display.main.renderingHeight + “)”);
}

Unity will always clamp the resolution to the highest native resolution, as this is the resolution the application will try to display at. Trying to display at a higher resolution will either cause the image to be cropped, not render at all, or potentially damage the hardware.

The proper way to do this is to create a render texture at the resolution you want and assign it as the target for the camera you want to be supersampled. You’ll have to then display that render texture using another camera, or using a null target blit.

Or you can get this:

You’re telling me it can’t be done, yet there’s a store asset that does it… I’ve also seen on a Unity news update that this feature is supported somehow. There should be a way to do it that doesn’t involve using a Render Texture on a Quad like a moviescreen. Valve also wrote a script that handles dynamic resolution supersampling in unity for VR. I figured this would be a more well documented feature especially now that VR is a thing.

Here is another asset that does it, (Unity Asset Store - The Best Assets for Game Making) but again… I’m trying to learn how this is done, not purchase a store asset.

He told you it can be done, just not in the way you were trying to do it.

You need to render to a rendertexture.

Something like

void OnPreRender()
{
    rt = RenderTexture.GetTemporary(Screen.width, Screen.height, 24, RenderTextureFormat.Default, RenderTextureReadWrite.Default);
    MyCam.targetTexture = rt;
}

void OnPostRender()
{
    Graphics.Blit(rt, null as RenderTexture);
    RenderTexture.ReleaseTemporary(rt);
}

This will render at the native res, but you can change Screen.width and Screen.height to whatever you want.

For VR there’s a built in setting for setting the render scale so you can do super sampling or under sampling as needed. But this only works when rendering to a VR HMD.
https://docs.unity3d.com/ScriptReference/VR.VRSettings-renderScale.html

There’s also the render viewport scale setting which allows for dynamic resolution reduction, and is what Valve’s stuff is built on top of, but that has been kind of broken since it first came out. That too is VR only. Valve’s main contribution there, apart from getting Unity to implement the feature initially, is the techniques they have for choosing when to increase or decrease the resolution scale.

Otherwise you want to use the technique @AcidArrow posted the code for. That’s exactly the technique I mentioned. I have no idea exactly how the asset I linked to works as it’s all done with an external plug in, but it’s probably just doing the same kind of thing as that code.

Really any game that’s doing game view super sampling is doing something like this, rendering to a render texture then rendering that to the “screen” on a big quad. Nvidia’s driver super sampling just works by telling the application the display it is rendering to is a higher resolution than it is, then taking the results of that and scaling it down by … drawing a quad on screen with it as a texture.

1 Like