Skip to main content
Inspiring
June 18, 2013

AA vs downscaling from higher resolutions

I think it might be a good idea to re-open this discussion as there seems to be a fair amount of friction between those that find that downscaling from 1920x1080 is an acceptable way to improve image quality in the Rift vs those that find it unacceptable and comes with a potential increase in latency.

With Unity, I've explored a multitude of options:

1) No AA, using native Rift resolution of 1280x800.
2) No AA, downscaling from higher resolution.
3) Anti aliasing as a post effect, occurs after lens correction and chromatic aberration
4) AA between lens warp and chromatic aberration correction.
5) 2x/4x/8x MSAA via Unity's quality settings

Note that at this time, the #5 option here does not actually function like UDK's ScreenPercentage setting because the MSAA textures are not yet accessible. I'm guessing that when Unity does support this, the quality settings are all that we'll need to get a simple and effective "ScreenPercentage" setting in Unity.

Also note that at this time, the #4 option is not possible unless we make some significant changes to the Oculus Unity integration (and I personally haven't taken the time to try out a proof of concept).

So for the time being, that realistically leaves us with #1 (No AA at 1280x800), #2 (No AA, downscale from higher res), and #3 (AA using one of Unity's several AA image effects), and maybe even a combination of these.

Here are screenshots taken of some text that does not squarely face the user, although the user is looking directly at it. The text should read "0%":

1280x800 (No AA, 4xMSAA, postwarpAA):


1600x900 (No AA, 4xMSAA, postwarpAA):


1768x992 (No AA, 4xMSAA, postwarpAA):


1920x1080 (No AA, 4xMSAA, postwarpAA):


My conclusions:

1) I find that post-warp AA done as an image effect softens up the scene details too much, darkens it, etc. Not acceptable (and also has a not insignificant hit to frame rate).

2) I don't see much difference in legibility between no AA and using 4xMSAA in Unity's quality settings, so might as well not use it in favor of performance, although one could definitely make the argument that straight edges would benefit from it.

3) The higher the resolution the better, and even running at 1768x992 looks like it starts to provide acceptable readability of that "0%".

4) I don't have a way to test the latency difference between native 1280x800 and downscaling from a higher resolution, but it sure doesn't seem to feel any different to me, even with looking around all over the place real fast like a crazy person.

Therefore, until Unity allows access to MSAA textures, just use as high a resolution as you can? :)
    This topic has been closed for replies.

    83 replies

    Up and Coming
    June 21, 2013
    "sh0v0r" wrote:
    I tried this out tonight, I set the display to 1920x1080 and while I noticed a definite improvement in quality with only a small drop in frame rate on my machine, the most significant issue was severe eye strain. :shock:

    Something is not quite right and my eyes feel like they are really struggling to maintain focus.
    With 1280x800 I experience no eye strain aside from the blurriness.

    The only thing I can think of is the distortion shader does not output the correct way at higher resolutions?

    I tried 1920x1200 and that had less eye strain but it was still worse than 1280x800 which I feel almost nothing when playing with.


    I've been using 1680 x 1050, which scales well and is less of a performance hit than one of the 1920 resolutions (1080 won't scale quite right, so it may cause some subtle distortions).

    I definitely agree that downscaling isn't a substitute for creating text that is readable at 1280, but every little bit helps.
    Participant
    November 4, 2013
    I've played my game from the Unity Editor right up until today so I've been using downscaling from 1920x1080 to 1280x800. When I turn on the rift it reports HDMI input at 1920x1080 @ 60Hz. I've now tried building the game as a standalone windows app, and even though I've set the resolution to 1920x1080 the rift reports 1280x800 @ 60Hz, regardless of whether I set the default resolution to 1920x1080 or if I let the user choose in the initial window.

    Should I be able to have the standalone build output at 1920x1080 into the Rift?
    If so then is there a trick to setting this up, since I'm setting the player settings and it's not working.

    Cheers,
    Mark
    drashAuthor
    Inspiring
    November 4, 2013
    "marky1124" wrote:
    Should I be able to have the standalone build output at 1920x1080 into the Rift?
    If so then is there a trick to setting this up, since I'm setting the player settings and it's not working.


    Yes you should... and I have no idea why that's not working for you. When I run a standalone build from executable and choose 1920x1080 (with a 1920x1080 monitor and my Rift in duplicated mode with Rift as primary), I see 1920x1080 show up on the onscreen display in the Rift.

    If you figure this out, would love to hear what the reason was!
    Titans of Space PLUS for Quest is now available on DrashVR.com
    Up and Coming
    November 4, 2013
    "drash" wrote:
    "marky1124" wrote:
    Should I be able to have the standalone build output at 1920x1080 into the Rift?
    If so then is there a trick to setting this up, since I'm setting the player settings and it's not working.


    Yes you should... and I have no idea why that's not working for you. When I run a standalone build from executable and choose 1920x1080 (with a 1920x1080 monitor and my Rift in duplicated mode with Rift as primary), I see 1920x1080 show up on the onscreen display in the Rift.

    If you figure this out, would love to hear what the reason was!

    Yeah that is weird. I get the same behavior as Drash and it looks great. I like rendering in 1080 because that is probably going to be the most commonly used resolution for the consumer version.
    Participant
    November 4, 2013
    Thank you both for replying and letting me know it should work. I have just run through all the steps again and now it's working every time. I have no idea what I might have done to fix it, apart from restart Unity a few times and turn off the Rift.

    If the problem comes back and/or I figure out what caused it to act like it did I'll post an update.

    Thanks again for helping out.
    Cheers,
    Mark
    P.S. This is my setup: Windows 7 Home Premium 32-bit, Unity v4.2.2f1 running with a trial Pro license, Oculus SDK v0.25 and Oculus Firmware updated to v0.18.
    Up and Coming
    November 5, 2013
    This is why the SDK docs say you should render to a higher resolution offscreen buffer before distortion. This is because the framebuffer is actually being oversampled near the center of the distortion (to squish the image near the edge, you must stretch it near the center, or else leave a large part of the screen black and lose FOV).

    So as low as the rift's resolution is already, you are getting even fewer unique pixels where they count if you use the native resolution. Effectively its closer to looking at a 480p display than 800p.

    Supposedly they added support for increasing the Unity buffer scale in a recent SDK update, but Unity has problems with lights and shadows when you exceed the display resolution. You can query the Oculus SDK for the desired buffer scale factor.
    Inspiring
    November 5, 2013
    Though we did try to add support for higher res buffers, the feature never really worked 100%. The code is there if you want to mess around but it has a lot of problems if you want to use dynamic lighting or shadows (which most people do).

    Check out "CameraTextureScale" in OVRCamera.cs, but like I said it barely works.
    AMD Ryzen 7 1800X | MSI X370 Titanium | G.Skill 16GB DDR4 3200 | EVGA SuperNOVA 1000 | Corsair Hydro H110i Gigabyte RX Vega 64 x2 | Samsung 960 Evo M.2 500GB | Seagate FireCuda SSHD 2TB | Phanteks ENTHOO EVOLV
    Up and Coming
    November 6, 2013
    You most definatley want to render to a bigger buffer (for supersampling), ideally 1.35x bigger. Then using bicubic sampling in your distortion and render that at native resolution.

    Or even better, use a ray tracing engine, like discussed in this paper;
    http://www.qwrt.de/pdf/Improved-Pre-Warping-for-Wide-Angle-Head-Mounted-Displays.pdf
    GunLock - Multiplayer FPS UE4 Rollercoaster HydraDeck - RTS
    Up and Coming
    November 6, 2013
    I had a play around with the CameraTextureScale and got it working correctly, but it's a bit of a hack.

    To get the shadows, etc to render correctly, you need to set the camera.targetTexture = CameraTexture, so it renders just like you would for offscreen UI.

    You then need to create a second pair of cameras to do the lens correction, etc at native resolution.

    If anyone's interested, I'll post it up later once I fix a few bugs
    GunLock - Multiplayer FPS UE4 Rollercoaster HydraDeck - RTS
    Up and Coming
    November 6, 2013
    I believe I was able to fix this with the attached solution. There is a marked improvement in visual fidelity:

    Before


    After(4x)


    To try this solution, just import the package and then attach the OVRCameraScaler to your OVRCameras.

    Here is what is does:
    - Creates a scaled RenderTexture
    - Tells the OVRCamera to render to this texture
    - Creates a new camera that renders nothing (cull everything)
    - Attaches a component to this new camera that simply renders the RenderTexture

    I don't have a latency tester, but I didn't notice any increase in latency when scaling at 2x or 4x (any scale factor higher than this would be kind of silly). The profiler tells me that there was actually an improvement in performance. I'm not sure why that is yet.

    *EDIT: I updated the solution. Now you can enable/disable the OVRCameraScaler component to enable/disable the feature. (e.x. GetComponent<OVRCameraScaler>.enabled = true; )

    P.S. As a side-effect of my investigation, I noticed that the OVRMainMenu was actually eating up a bit of CPU+GPU time, even when nothing is being displayed. This happens because it is trying to render to texture even if there is nothing to render. It would be pretty easy to fix. For now, if you aren't using the menu, you can disable the component to save some cycles.