Skip to main content
Up and Coming
March 30, 2013

OpenGL full example and shader...

Hello,

Great job with Rift and SDK. It seems awesome!. Waiting for my SDK...

A question:

- It's planned to release an new version of SDK with a minimal example (OculusRoomTiny) for OpenGL (with lens correction shader)?
- When? Soon? (to do this work myself or wait for new release)

Thanks!

Fernando

    36 replies

    Up and Coming
    December 14, 2013
    Problem 1 is solved. I use one 2048x1280 FBO instead whose left half contains the rendered scene for the left eye, and the right for the right.

    So only problem 2 remains. I can't seem to be able to configure the shader correctly for left eye vs right eye.
    Up and Coming
    December 14, 2013
    Third post which will hopefully enable the right to open a topic and allow posting images.

    Here's a screenshot of what the distorted image looks like now:
    https://copy.com/FYvIdG4ehmso
    Note the red line was added in the screenshot afterwards to mark the center of the screen.

    I already found out that the reason why the center of the right view is more off from the center of the screen is due to the parameter Distortion.XCenterOffset being positive for both cases, when it _should_ have been negative for the right eye.

    So, clearly, I'm missing one setup step for the right eye.
    Up and Coming
    December 14, 2013
    This thread had a clue: You have to invert Distortion.XCenterOffset for the right eye - the tiny room demo is doing exactly that in the Render::SetDistortionConfig() method.
    So now I'm doing the same thing and now the distortions are symmetric with respect to the center of the full screen. The shape of the distortions now look like with TinyRoom. This is good.
    However, I'm still not getting a clear image on the rift itself, because of two issues:
    1. As can be seen in the above screenshot, the right image is not clipped correctly at the center and overlaps the left near the center. This issue remains with the XCenterOffset inverted.
    2. The "eye axis" don't seem to match. Hard to explain, because you can't see it on a screenshot, you have to wear the rift to see the effect: it seems the center of the screens are not in the center of the eye. Note I'm not talking about an IPD issue, I've seen what those look like when playing with the oculus world demo. Fiddling with IPD values don't change the error I'm having now. It's more like the images don't match up in the far pane. Think of a point infinitely far away, on the skydome. Here changing IPD doesn't change the location of the point at all. Now close one eye and then flip the closed eye, then the point on the skydome moves a lot. Which it obviously shouldn't. So it seems like there's another X-offset that I still miss.
    Inspiring
    December 16, 2013
    I have to take this very seriously, because my house is actually in the pictured area (Seward park has a very distinctive shape).

    "philippM" wrote:
    1. As can be seen in the above screenshot, the right image is not clipped correctly at the center and overlaps the left near the center. This issue remains with the XCenterOffset inverted.


    The distortion on the right side is flipped. Fixing it depends on how you're doing the distortion render. I do a four pass version.

    • Render left eye view to framebuffer texture

    • Render framebuffer texture with distortion to left screen viewport

    • Render right eye view to framebuffer texture

    • Render framebuffer texture with distortion to right screen viewport


    One of the params I pass to the shader is a boolean uniform named 'mirror'. If Mirror is true, then it knows that it's rendering to the right eye and that it should invert the X calculations for some of the steps. The SDK samples do it in a three pass approach


    • Render left eye view to framebuffer left viewport

    • Render right eye view to framebuffer right viewport

    • Render framebuffer texture with distortion to whole screen


    This might be more efficient, though it requires a larger framebuffer. It also requires that the distortion shader be that much more harder to understand, because now it has to alter it's behavior based on whether the texture S coordinate is greater than or less than 0.5. I find this a gargantuan pain in the ass.

    However you do it, it's clear from the image that you're failing to flip the X-axis in your distortion shader when you calculate the offset from the lens center, or you're failing to negate the lens offset value passed when dealing with the right side of the view (you say you're doing this, but I suspect that the information isn't reaching the shader somehow.

    "philippM" wrote:
    2. The "eye axis" don't seem to match. Hard to explain, because you can't see it on a screenshot, you have to wear the rift to see the effect: it seems the center of the screens are not in the center of the eye.


    You aren't setting up your projection matrix correctly (or possibly you're just rendering the left image twice). This will become much more apparent once you fix the distortion issues. Take a look at this image.


    Notice that on the left image you can see a significantly larger amount of the road to the left of the wing mirror on the left image than you can on the right. Similarly, on the right image, you can see more of the right side of the dash area. This divergence in the amount of visible content for each eye is caused by a modification to the projection matrix. A lot of people confuse it with the IPD offset, but it's completely different. The projection matrix offset accounts for the offset of the lens axis on the Rift and the physical center of the half of the display panel for that eye. In your screenshot though, it looks as if the right edge of the image ends in exactly the same place for both eyes.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Up and Coming
    December 17, 2013
    Thanks for your elaborate reply.
    Indeed, using the correct projection matrices from StereoEyeParams::Projection helps!
    1. Use correct matrices
    2. ...
    3. Profit!!

    https://copy.com/ZydK3VtwaQrw

    The distortion became correct once I inverted the XCenterOffset for the right eye.
    This now looks totally awesome when viewed through the rift!
    So only one problem remains: The little overlap in the center. It is not really visible in the rift unless you look right very hard, but it's nonetheless incorrect.

    I can't use glscissors obvoiusly as they work in the screen space, not the projected (distorted) space. So I guess I must modify the shader (see five posts above for my shader, but it's directly from the tiny room demo). How to clip the two eyes correctly?
    Up and Coming
    December 17, 2013
    Solved it by clipping the output in the Fragment shader accordingly. Now I don't have any overlap anymore. Guess I will be posting a new showcase soon :)
    Up and Coming
    January 16, 2014
    I'm trying to get the LWJGL barrel to work, but I have 3 issues.

    - Why do you have to glDisable(GL_DEPTH_TEST); that makes everything look crap. (flat shaded game)
    - How come objects rendered with glDisable(GL_LIGHTING); dissappear?
    - I get no separation between the eyes...

    This is harder than I thought it would be!
    "It's like Homeworld in first person." Disable Aero and vSync for a completely simulator sickness free experience with 2xHz FPS. Keep the config utility open for tracking to work.
    Inspiring
    January 16, 2014
    I'm not sure what code you're working with at the moment, but I can take a stab at some of this.

    "rupy" wrote:
    - Why do you have to glDisable(GL_DEPTH_TEST); that makes everything look crap. (flat shaded game)


    The depth test has noting to do with flat shading. A depth test will only determine whether a given pixel is rendered to the screen at all, based on whether the depth value that's already there is closer to the viewer or not. There are (at least) two steps to the rendering... rendering a scene to a framebuffer, and then rendering the framebuffer results to the screen with the distortion. The former typically needs the depth test turned on, because you want to ensure proper rendering of 3D objects. The latter doesn't need depth testing, because rendering the distortion involves rendering a single quad to the screen and no other geometry, so there's no question of rendering 'in front of' or 'in back of' some other piece of geometry. Because of that it's useful to disable the depth test, because it can slow the rendering pipeline, and for VR every millisecond counts.

    "rupy" wrote:
    - How come objects rendered with glDisable(GL_LIGHTING); dissappear?


    Do they disappear or do they render incorrectly, i.e. as black-out shapes against a properly rendered background? Can you provide a screenshot?

    "rupy" wrote:
    - I get no separation between the eyes...


    For each eye you have to apply an offset to the modelview matrix. You have to make sure of a number of things.. first that you're doing this at all, second, that you're applying a different offset to each eye, and finally that you're pushing and popping the stack appropriately.

    The second one has a common pitfall. Some implementations calculate the modelview offset and store it in a single variable, rather than calculating it per-eye. If you do use a single variable then you have to remember to invert the offset when you're rendering to the right eye.
    Brad Davis - Developer for High Fidelity Co-author of Oculus Rift in Action
    Up and Coming
    January 16, 2014
    Thanks!

    I solved this with glViewport instead.


    GLU.gluPerspective(85, 1, 1, scale * 2);

    ...

    Vector3f eye = Quaternion.right(rift);

    glViewport(80, 120, 560, 560);

    glTranslatef(-eye.x, -eye.y, -eye.z);
    // draw game
    glTranslatef(eye.x, eye.y, eye.z);

    glViewport(640, 120, 560, 560);

    glTranslatef(eye.x, eye.y, eye.z);
    // draw game
    glTranslatef(-eye.x, -eye.y, -eye.z);


    Hm, this only works with the C-cups, how can I distort the rendering without a shader?
    "It's like Homeworld in first person." Disable Aero and vSync for a completely simulator sickness free experience with 2xHz FPS. Keep the config utility open for tracking to work.
    Up and Coming
    January 24, 2014
    How would I have to modify 38leinaD's code to render one barrel instead of two so I can keep my viewport code that works well.

    Or how do I render the left and right part of the double barrel independently? (= move the rendering half screen left with clipping to left screen and then right, I'm not talking stereoscopic eye translation here)

    Or can someone post a fully working stereoscopic example in LWJGL?

    "It's like Homeworld in first person." Disable Aero and vSync for a completely simulator sickness free experience with 2xHz FPS. Keep the config utility open for tracking to work.