Skip to main content
Up and Coming
August 23, 2013

Connection between render target and distortion scale?

Hi,

While working a bit with the distortion scale implementation in my code I tried to understand the coupling between the distortion scale value and the size of the render target.

The Rift has a native resolution of 1280x800 but since we are doing barrel distortion the documentation suggests scaling up the render target to 1600x1000 (i.e. increase by 25%). But how is this value related to the distortion scale? When looking through the code in the Oculus SDK demos I see no direct connection between render target size and distortion scale. The value you get from Oculus SDK distortion scale calculation is nowhere near 25% (The actual value is about 1.71). And I understand that we get a larger value because the lenses are not positioned in the centre of the screen (lensOffset).

But how is the optimal render target size calculated? I.e. how do we know from the distortion value of 1.71 that we need a render target that is 25% larger than the native resolution?

    16 replies

    Up and Coming
    August 23, 2013
    Clarifying the distinction is a good idea. I believe the OP is talking primarily about the first.

    It's worth pointing out, however, that the two parameters have an inverse relationship - that is, if you apply a scaling factor of 0.8 (approx 25%) to the perceived texture coordinates, you should increase the resolution of the off-screen buffer by about 25% to maintain the same pixel density with the larger area.

    There are other ways to pick off-screen buffer size as you pointed out, though.

    Also, you've screwed up if your off-screen render target has mip-mapping enabled. Given that your off-screen render target is being rendered at a constant depth, the mip map chain is simply going to be a waste of GPU memory (and memory bandwidth and ROP/TMU utilization since it has to update the entire mip map chain at least every frame, if not more often). And that's assuming the device even reads from the mip-map chain when you are using a full/half screen quad and no depth testing - my experience is that both mip-mapping and anisotropic filtering are disabled in these situations.

    And for the record, doubling the off-screen render target is an incredibly inefficient way to get 2x equivalent FSAA if you have bilinear filtering enabled for it. It's not the prefered way, but it's a way to do it. Bilinear filtering masks a lot of aliasing artifacts, although it can create some artifacting when combined with non-integer scaling of texture size. Aliasing is really only a major issue if you are have filtering disabled entirely when you are sampling the texture, or have an off-screen render target at least 2x the size of the frame buffer when you have bilinear filtering enabled.

    Edit: Sorry if I am misinterpreting your point and responding to something you didn't intend to say - I figure there are enough people here that are not proficient with the intricacies of 3D rendering that it is worth explicitly elaborating on how these mechanisms behave when used in an offscreen render target lest they get any bad ideas.
    Current Quake II VR stable release: 1.3.1 DK2 support: see this post
    Inspiring
    August 23, 2013
    "dghost" wrote:
    Also, you've screwed up if your off-screen render target has mip-mapping enabled. Given that your off-screen render target is being rendered at a constant depth, the mip map chain is simply going to be a waste of GPU memory (and memory bandwidth and ROP/TMU utilization since it has to update the entire mip map chain at least every frame, if not more often). And that's assuming the device implements mip-mapping when you are using a full/half screen quad and no depth testing.


    Well I'm mostly working with small 'toy' scenes for learning purposes, so its entirely possible the techniques I'm using won't scale in a lot of places.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    VrallyAuthor
    Up and Coming
    August 24, 2013
    Ok. So trying to sum up the discussion:

    • The distortion scale value regulated how much the image is scaled inside the rift display. The larger distortion scale value you uses, the closer to the edge we get.

    • The distortion scale value is linked mathematically to the field of view value, i.e. there is a corresponding FOV-value for each distortion scale value, and vice versa.

    • The off-screen buffer size should try to match the distortion scale value if you want to maintain pixel density. But there are other things to consider:
      • Aliasing issues due to non-integer scaling.

      • Large off-screen buffer = more pixels to render, which could lead to low frame rate.

      • Using non power of 2 buffers may not be allowed on your target platform.


    Simple diagram:

    The green lines in the image above should illustrate the screen size inside the rift. The red and blue squares should illustrate the individual pixels in the off-screen buffer.
    Up and Coming
    August 24, 2013
    The image is mostly correct, except for two things:

    1. The labeling on the top right image is somewhat misleading - FOV doesn't affect the results of the distortion, but rather how the scene is rendered. Essentially, since the rendered image is physically larger (in terms of area on the screen) it needs to also be rendered at a larger FOV to look "correct".

    2. In your right images, it appears that increasing the distortion scale also adjusts the properties of the distortion itself. This is not the case. As you can tell in the images I posted above, the actual distortion applied to the image remains the same - you are simply manipulating texture coordinates so that it treats the source texture as larger than it is - as if the texture coordinates ranged from 0 to 1.5 for instance. If the source textured had 800 pixels mapped from 0 to 1 originally, it needs to have 1200 pixels to maintain the same pixel density when mapped from 0 to 1.5. In actuality the texture coordinate scaling is applied using the reciprocal - so the area that maps from 0 to 1 now maps from only 0 to 0.66, with the area from 0.66 to 1 being equivalent to having texture coordinates 1 to 1.5 in the unscaled render target if and only if you scaled the resolution of the render buffer by the same amount.

    To apply a conceptually inaccurate metaphor, by adjusting the scaling parameters (the combination of all of them) it is akin to putting a different size piece of paper behind a lens. The lens itself, and the distortion it causes, is unchanged. You are simply putting a larger piece of paper behind it, and as a result you see the distortion applied to more paper. But that really is nothing like what is going on mathematically.
    Current Quake II VR stable release: 1.3.1 DK2 support: see this post
    VrallyAuthor
    Up and Coming
    August 24, 2013
    "dghost" wrote:
    The image is mostly correct, except for two things:
    1. The labeling on the top right image is somewhat misleading - FOV doesn't affect the results of the distortion, but rather how the scene is rendered. Essentially, since the rendered image is physically larger (in terms of area on the screen) it needs to also be rendered at a larger FOV to look "correct".


    Well, since increased distortion scale forces us to use a larger field-of-view when rendering to the off-screen buffer. So maybe the top-most title should be rephrased as "Increased distortion scale (which results in increased field-of-view when rendering to off-screen buffer)".

    "dghost" wrote:
    2. In your right images, it appears that increasing the distortion scale also adjusts the properties of the distortion itself.


    No, the distortion is actually exactly the same in all four images (although created via photoshop's pinch effect with a value of negative 50% i.e. barrel effect). The only thing that differs are "resolution" of the off-screen buffer and the scaling.

    "dghost" wrote:
    To apply a conceptually inaccurate metaphor, by adjusting the scaling parameters (the combination of all of them) it is akin to putting a different size piece of paper behind a lens. The lens itself, and the distortion it causes, is unchanged. You are simply putting a larger piece of paper behind it, and as a result you see the distortion applied to more paper. But that really is nothing like what is going on mathematically.


    Maths disregarded, but that metaphor was not that bad.
    Up and Coming
    August 24, 2013
    Alright - I was having a hard time telling if the distortion was different or not in the images. Too much time staring at code recently ;) I probably should have added somewhere at the beginning that I couldn't tell or not.

    I really like the breakdown on the image, though - it nicely illustrates what's going on!
    Current Quake II VR stable release: 1.3.1 DK2 support: see this post