Thursday, 27 February 2014

Large World Rendering on the Oculus Rift

When The Elder Scrolls: Oblivion launched, there had never been a game of that scope that let you see so far into the distance.  Seeing this huge world spread out before you went a long way towards building the immersion that game is known for.

Oblivion: I can see for miles

Of course it's impossible to have a background world so expansive with the same level of detail required for the foreground so you basically need to render your world twice.  A low-res distant version and a high res foreground version.  Then the distant version can be rendered into the foreground on a plane.

One of the benefits of rendering the scene twice instead of using a continuous LOD system is the precision of the depth buffer.  If you render a scene that's kilometers deep there will be a lot of object flicker close to the camera, but if you render a shallow scene near the player and a deep one in the distance you can get good depth buffer precision near you and good distance as well.

Red is all Foreground (plus some of the water)

Nothing I've said so far is in any way related to the Rift, but here's where it gets interesting.  We're already rendering the scene twice (once for each eye).  If we were to double that we'd get four scene renders.  That seems excessive.  If only there were a way to optimize this.

Well, we're in luck because when the distance scene is hundreds of meters away and our eyes are only 6-7 cm apart, we really don't get any benefit of rendering the scene for each eye.  We can render the distanct view once and draw the same render into each eye and no-one will notice.  This means we only need three scenes to render.

In my scene I have 3 cameras attached to the player.  One is centered between the eyes and renders the sky box and the distant mountain range into a texture.  Then I have the two cameras for the player's eyes.  The first thing rendered into this camera is a plane with the distant lands texture on it.  We have to make sure this plane is far from the player so we don't end up cross eyed when we focus on it.

That's it.  A very simple optimization for rendering large complex scenes in the Rift.

Red foreground is rendered in left camera, blue foreground is rendered in right.  
The distant mountains and skybox are rendered only once onto a plane.

To see more of snowdrift, check out

And as usual, all the comments are in the Reddit thread...


  1. Great job! A simple but clever optimisation.What are you rendering the scene in?

  2. This comment has been removed by the author.

  3. In skyrim I can tell that the background mountains are flattened on a plane - but that might be the settings I am using in the Roft. Would a minor improvement be to have the equivalent of a 3D SBS image in the background plane so that the mountain would feel less flat?

    1. Howdy Simon
      Actually, distant mountains should seem flat, at least from a stereoscopic point of view. However there's a trick to where in your scene you render the plane with your distant content on it. In a monoscopic game (everything except rift games) this doesn't matter, but in the rift you can really mess up your eyes by putting the distant plane too close and generating a false stereoscopic signal. This will make the distance appear flat, and far to close to you as well as confusing your brain by appearing closer to the player than even certain foreground elements. The SBS image you talk about is basically the same as rendering the distant lands twice, and yes that would work. However all you really need to do is make sure your distant cut-off is far enough away, and the plane that it's drawn on is also far enough away.

      The reddit thread has a mathematical discussion on how far things can be. Check it out here...