Skip to main content
Up and Coming
May 10, 2013

Rift Ray-tracing

[EDIT] This now has a demo, but I'll keep the link here up to date.

Download demo
(Updated to 12 Meg. Ver 0.50 on the Twentieth of June in the Year Twenty-Thirteen)).

Hi All,

I haven't got my Rift yet (UK near the end of the Kickstarter), but have been following the goings on with interest.

I've started to have a go at doing some CUDA based ray-tracing for VR and have managed to get some basic stuff going.

Rather than warping a resulting image I've made a start at modeling the lenses in the ray projection code.
(no texturing or shadows yet, just trying to get the distortion and stereo going.)

This is what I've got so far. It's probably waaaay out, but until I get my one, I'm flying blind. :D

Note: It's a bit wide to see in the post, you may need to open the image in another tab to see the entire screen.

    152 replies

    Up and Coming
    June 12, 2013
    "jwilkins" wrote:
    "geekmaster" wrote:
    Although they called random dither "jitter dither" in your edition, mine seems to be lacking that reference. And in general, that is an archaic term. I usually see random dither, or random sampling, or monte carlo sampling.


    But isn't dithering a method of distributing error? Jitter is a method of adding noise. You dither in order to hide errors due to quantization. You jitter in order to keep a quantization from being too regular. I think it is more than just semantics.

    (and where do you see them mention dithering at all?)

    Mis-quote (i.e. "brain fart"). After reviewing your post, I updated mine to fix that (see above), before reading this post.

    I agree with you. Because video signals (both input and output) tend to be serialized over time, sampling over time and space are equivalent and so it really does not matter how we apply the "jitter" term as long as it creates our desired random sampling deviation. It is hard to find online references to spatial (spacial) jitter, though...

    The important point is that random sampling (monte carlo sampling / jitter sampling) can make the ray-traced images look better with more perceived detail, especially when averaged over time (exactly what the eye does).

    Meh, I tried to find references to "jitter sampling" that are NOT constrained to the time domain, but no such luck (other than your Foley and Van Dam reference).
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
    TeraBitAuthor
    Up and Coming
    June 13, 2013
    Lots of interesting discussion going on here. :D

    To answer the previous question:
    Full Ray Mip Maps Disabled (Only length of the Primary Ray)


    Full Ray Mip Maps Enabled (Including Reflection etc.)


    In the above picture, because the reflective surface is fairly close, the difference is subtle, but noticeable. FPS wise, it's almost the same. The difference is because it is taking two texture reads (one from each LOD and linear blending the results), whereas in the disabled one, it will best case it with one texture read from the highest resolution texture.

    [edit]
    Also the Jittered verses Non-Jittered

    vs

    On a higher resolution it might break it up a bit, but on a lower resolution moving a chunky pixel shows up. :D
    Regards, Lee Page TeraBit Software
    Up and Coming
    June 13, 2013
    That "jittered" screenshot with "rough" edges looks a lot better than the "blocky" edges in the other image.

    Jitter sampling (for spatial data, more commonly called random sampling, or monte carlo sampling) should look much better to the eye, than is apparent in a single-frame screenshot. The eye averages the random samples over time. You could simulate that to some extent by taking a bunch of screenshots, then aligning and averaging them (perhaps localized if moving objects).
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
    Up and Coming
    June 13, 2013
    I agree that the occasional "chunky" pixel is far better than the "made of Lego" effect you get without jitter.
    (╯°□°)╯︵┻━┻
    TeraBitAuthor
    Up and Coming
    June 13, 2013
    Another alternative is to use a contrast based AA function to shoot extra rays at edges ala
    Regards, Lee Page TeraBit Software
    Up and Coming
    June 13, 2013
    That still shows an outline of the blocky "lego" aliased edges (as in the rightmost image in your previous screenshots). But perhaps you are suggesting random sampling concentrated mostly near those edges?
    This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.
    TeraBitAuthor
    Up and Coming
    June 13, 2013
    "geekmaster" wrote:
    That still shows an outline of the blocky "lego" aliased edges (as in the rightmost image in your previous screenshots). But perhaps you are suggesting random sampling concentrated mostly near those edges?

    Correct. The contrast function results (shown above) highlights areas where the contrast between neighbouring pixels is above a certain threshold.

    The actual anti-aliasing isn't implemented yet, but in a second pass, a set of extra rays could be fired to smooth out where the pixels are brightest and the results averaged with the existing pixels. The win here is that you would get smooth interpolated results by only a relatively small number of extra rays.
    Regards, Lee Page TeraBit Software
    Up and Coming
    June 13, 2013
    "TeraBit" wrote:
    "geekmaster" wrote:
    That still shows an outline of the blocky "lego" aliased edges (as in the rightmost image in your previous screenshots). But perhaps you are suggesting random sampling concentrated mostly near those edges?

    Correct. The contrast function results (shown above) highlights areas where the contrast between neighbouring pixels is above a certain threshold.

    The actual anti-aliasing isn't implemented yet, but in a second pass, a set of extra rays could be fired to smooth out where the pixels are brightest and the results averaged with the existing pixels. The win here is that you would get smooth interpolated results by only a relatively small number of extra rays.


    It seems like this kind of work will leave a huge portion of your GPU idle. If you have enough parallelism it would be better just to cast extra rays everywhere because all of those black regions will be completely idle.

    I'm trying to think of how you'd handle this without having a lot of idle threads and lowering your throughput, but it really depends on how many blocks and the size of the blocks and it will probably take a bit of work to figure out how to make it efficient and it will depend on the GPU.
    (╯°□°)╯︵┻━┻
    TeraBitAuthor
    Up and Coming
    June 14, 2013
    Yup, the results are in. The contrast based function kills the frame rate from ~70 FPS to 30. Actually, just launching the context twice without even doing any work in it did the same. :?

    Looks like launching the context is about the most time consuming element of a frame regardless of what you do with it. Time for another plan.... :)
    Regards, Lee Page TeraBit Software
    Up and Coming
    June 14, 2013
    "TeraBit" wrote:
    Yup, the results are in. The contrast based function kills the frame rate from ~70 FPS to 30. Actually, just launching the context twice without even doing any work in it did the same. :?

    Looks like launching the context is about the most time consuming element of a frame regardless of what you do with it. Time for another plan.... :)


    Did you actually try just launching the context? If not then you have possibly made a very bad assumption here. If you look at what I said in previous posts I was saying how the plan you had for saving work by only recasting rays in those few places was absolutely doomed to failure because you are dealing with a highly parallel machine and the vast majority of your threads were going to be idle because they have no rays to cast. If you had a more dynamic and flexible environment, like OpenMP, you might be able to fix it, but with CUDA your options are really limited.

    So, unless you actually test that launching the context is the most expensive thing, I actually think it is because you are seeing the cost of casting the extra rays, but only 5% of your threads actually do any work and the rest just wait for the 5%. So it ends up taking about the same amount of time.

    One idea that just occurred to me is that if you have enough fast memory you could track high contrast areas in the first pass and immediately cast extra rays.
    (╯°□°)╯︵┻━┻