Skip to main content
Inspiring
August 26, 2014

Direct HMD Access with Client-Distortion? (Raytracing)

Is it possible to use Direct HMD with client distortion? I have to do client-distortion since I use Raytracing for picture creation - this saves me rendering everything twice to intermediate buffers and picture is less blurry since every pixel matches 100% instead of being sampled from a blurry texture. It is also much faster on simple scenes.

Now I want to use Direct HMD Access for 75Hz and convenience. My idea is to write directly to one Rendertarget that is viewed as is without distortion. Is there any possibility to do this with SDK 0.4.1 or are there any plans on this for future releases?

PS: This could also be usefull with classic Scanline rendering in a deferred renderer where f.e. textureing is done after distortion.

    31 replies

    Inspiring
    August 27, 2014
    "kojack" wrote:
    I don't want to take it too far off topic, but I just found my shaders for the two spheres.
    Probably very inefficient code, it was a quick hack to show my class.


    Thank you, but I already have done the raytracing :) here is some very optimized code for ray-sphere intersection. But you have to calculate a matrix to define the sphere(oid) as inverse to an unit sphere (position 0,0,0/diameter 1) at the origin:


    float intersectSphere(float4* matrix, float4 rayDir, float4 rayOrig)
    {
    float4 o=mulMatVec(matrix, rayOrig);
    float4 d=mulMatVec(matrix, rayDir);

    float b=dot(o, d);
    float c=dot(d ,d);
    float result=b*b-c;
    return result;
    }


    Here is a better understandable version. The nice optimization trick is to store a squared radius in the sphere definition


    float intersect(Ray ray, Sphere sphere){
    D3DXVECTOR4 dist = ray.orig - sphere.center;
    float B_half = D3DXVec4Dot(&dist, &ray.dir);
    float C = D3DXVec4LengthSq(&dist) - sphere.radiusSq;
    return B_half*B_half - C;
    }


    But as you mentioned this is a little bit of topic. But thank you for your hint on tricking with Direct HMD without distortion by outlining on ovr_Initialize() having to be called before 3D init. Far better advice than...
    Up and Coming
    August 27, 2014
    "thewhiteambit" wrote:
    Thanks for your advice to try it myself, I have never even thought about it! I did not even have a look at the manual to find Direct HMD always seems distorted automatic.


    Apparently not... again, direct hmd has absolutely nothing to do with distortion.

    "thewhiteambit" wrote:
    Further thank you for ignoring that windows syncs refresh-rate vsync when using multiple monitors... this post was really very helpful :lol:


    No it doesn't. I'm currently running the rift in extended desktop mode, with two monitors (one of which is the primary) running at 60hz, and the rift being the third, running happily at 75hz.

    p.s. you might reconsider responding with sarcasm to people who are trying to help you after you post a question in a forum.
    John Tsiombikas webpage - blog - youtube channel
    Inspiring
    August 27, 2014
    "nuclear" wrote:
    "thewhiteambit" wrote:
    Thanks for your advice to try it myself, I have never even thought about it! I did not even have a look at the manual to find Direct HMD always seems distorted automatic.


    Apparently not... again, direct hmd has absolutely nothing to do with distortion.


    I know now, it has to do with when ovr_initialize() is called. But this not outlined by the documentation at any point. I just assumed it was this way, because when using SDK distortion rendering Direct HMD worked - but nothing happended when I called ovr_initialize() at a point where direct3d devices where already created. If you would have told so it would have been helpfull - but you did not, kojack did. Just saying it has nothing to do with each other as you did is helping in no way!

    "nuclear" wrote:
    "thewhiteambit" wrote:
    Further thank you for ignoring that windows syncs refresh-rate vsync when using multiple monitors... this post was really very helpful :lol:


    No it doesn't. I'm currently running the rift in extended desktop mode, with two monitors (one of which is the primary) running at 60hz, and the rift being the third, running happily at 75hz.

    p.s. you might reconsider responding with sarcasm to people who are trying to help you after you post a question in a forum.


    The display runs at 75Hz but Vsync does not work correct. You might reconsider what you understand with helping people. Just telling them, they have to try by their self and assuming they are wrong without getting the problem correctly is no help at all. I know people on the internet who have to join every discussion and posing as smart ass without contributing anything of value and destroying any fertile discussion. Have you noticed any sarcasm with other people? no? seems like I don't use sarcasm to all people who are "trying to help" - I used it specially on your post!
    kojack
    Honored Contributor
    August 28, 2014
    I couldn't find anything in the docs about the order (the whole rendering shim thing isn't even mentioned) but in the comments in OVR_CAPI.H it says:
    // Either ovr_InitializeRenderingShim() or ovr_Initialize() must be called before any
    // Direct3D or OpenGL initilization is done by applictaion (creation of devices, etc).
    // ovr_Initialize() must still be called after to use the rest of LibOVR APIs.


    It seems ovr_Initialize() will set up everything (the rift and render shim to hijack dx or gl), while ovr_InitializeRenderingShim() will set up just the render shim so you can enable direct mode before initialising the rest of the rift system.

    There's a lot of comments in OVR_CAPI.H that have useful looking info (step by step guide to client and sdk rendering, etc), it's worth a browse.
    Author: Oculus Monitor , Auto Oculus Touch , Forum Dark Mode , Phantom Touch Remover , X-Plane Fixer Hardware: Threadripper 1950x, MSI Gaming Trio 2080TI, Asrock X399 Taich Headsets: Wrap 1200VR, DK1, DK2, CV1, Rift-S, GearVR, Go, Quest, Quest 2, Reverb G2, Quest 3
    Up and Coming
    August 28, 2014
    This all sounds pretty cool and I'd love to explore a Mandelbrot raytraced scene like this using the rift.
    Intel i920@4ghz, 12gb ram, Windows 7 Nvidia GTX 970 4gb, 120gb SSD, OR Dev Kit 1&2
    Inspiring
    August 28, 2014
    "13thFloor" wrote:
    This all sounds pretty cool and I'd love to explore a Mandelbrot raytraced scene like this using the rift.


    If you have some advice for stereoscopic Mandelbrot :) Think I will put an Open Source Project with the basic Raytrace setup on GitHub, once the hacked together engine works.
    Inspiring
    August 28, 2014
    "kojack" wrote:
    I couldn't find anything in the docs about the order (the whole rendering shim thing isn't even mentioned) but in the comments in OVR_CAPI.H it says:
    // Either ovr_InitializeRenderingShim() or ovr_Initialize() must be called before any
    // Direct3D or OpenGL initilization is done by applictaion (creation of devices, etc).
    // ovr_Initialize() must still be called after to use the rest of LibOVR APIs.


    It seems ovr_Initialize() will set up everything (the rift and render shim to hijack dx or gl), while ovr_InitializeRenderingShim() will set up just the render shim so you can enable direct mode before initialising the rest of the rift system.

    There's a lot of comments in OVR_CAPI.H that have useful looking info (step by step guide to client and sdk rendering, etc), it's worth a browse.


    As I have a Direct3D9 rendertarget bound to a D3DImage for WPF and use it with as shared resource with Direct3D11, having a D3D9+D3D11 device, there are heavy D3D-Exceptions when I call ovr_initialize() early and it tries to capture output [works great under normal circumstances]. Even tried to call ovr_initialize() between d3d9 and d3d11 init and vice versa. Will do some experiments with just setting up D3D11 without binding to WPF, and also Windows-Forms if it does not work. Thanks again, this was the correct hint I needed :)
    Participant
    August 29, 2014
    "thewhiteambit" wrote:
    "nuclear" wrote:
    I can't see anything in the SDK that precludes using your own distortion with direct hmd. Instead of theorizing about it, try it yourself. As for the actual distortion process, one way of going about it would be to get the distortion meshes, and generate sample points on them to use for primary ray directions.
    Also, you don't need to use the direct HMD mode to achieve 75hz refresh rate... I don't know where you get these arbitrary restrictions from, but again, try it yourself and you will see what works and what doesn't.


    Thanks for your advice to try it myself, I have never even thought about it! I did not even have a look at the manual to find Direct HMD always seems distorted automatic. Also thank you for theorizing about a distortion process that was never a question and archived long time ago. Further thank you for ignoring that windows syncs refresh-rate vsync when using multiple monitors... this post was really very helpful :lol:


    Well at any rate, this post was very helpful for me!

    If its true that windows syncs to the lowest refresh rate of all displays, it might explain why I've been getting a ton of awful tearing/judder in tons of demos (especially ones which are developed in unity). My main display is only 60hz.

    I definitely noticed that a lot of these juddery demos behaved differently when I went through the painful process of disconnecting my main display and launching some games using the rift as my sole monitor (I also tried lowering the resolution of my main display until it could hit 75hz but that seemed to have no effect- had to physically unplug the HDMI for it to have an effect).

    Does that sync across multiple monitors really work that way though?
    I know that the quake2 vr modification that dghost is working on is running through opengl in extended mode and it seems completely buttery smooth- wouldn't the 60hz limit be hitting me there as well? Sorry for the off topic questions, I'm just curious what it is that makes some rift demos fail to work.
    Inspiring
    August 29, 2014
    Afaik, Windows (and probably also other OS) don't have VSync for each Monitor separately and tend to Sync to the lower one.

    http://hardforum.com/showthread.php?t=1766789

    Another solution could be to set the DK2 to 60Hz when that is your other Monitors refresh rate - that would eliminate judder but also available frame rate. I was hoping to find a way in Direct HMD mode, but start having doubt knowing better the way it works by capturing D3D :(

    PS: There is no hard VSync limit within Windows. So if the Quake demo frame rate is not synced at all, and just rendering at maximum speed, this could be up to > 1000Hz on modern GPUs. Even if tearing appears, it is visualy minimized by having multiple very small h-splits. But trying to sync, to take advantage of the OVR-SDKs prediction capability, at least knowing the real sync would be great. With simple environments like Quake seems nowadays, the brute-force approach can produce similar results. But I mean to see a different offset with each colour, so each colour is probably displayed sequentially (time multiplexed) with the OLED (as with some Plasma Displays, or DLP-Projection with color wheel). So the question here would be if the updated picture at 1000Hz is updated within frame being drawn. If this is the case, brute-force oversampling the picture can be even more precise than VSyncing with prediction.
    Up and Coming
    August 30, 2014
    From a theoretical standpoint, that is no Driver/OS quirks it should be better to have vsync with triple buffering instead of leaving it off.