Page 1 of 1

SBS Stereo Implementation

Posted: Fri Dec 07, 2012 1:10 am
by Qoheleth
I'm thinking of writing a 2d-side scroller shooter with 3d effects (this will be done in pure 2d, no 3D with a 2d perspective) for a senior project. The focus is not so much on the game, but implementation of (1) SBS stereo and (2) warping for the Oculus Rift. The game will be like T2 the arcade game or Lethal Enforcers.

I understand the basics of stereoscopy, that our eyes each see a different image, one slightly offset from the other, and our brain gives us back one image with depth perception.

What I am curious about is the implementation of SBS stereo. My understanding is this: all I would have to do is render two scenes equally with the amount of screen width I am given. In one of the scenes, I must give an offset view.

Is that all? By how much would I have to offset (i.e. in terms of pixels)? Do I just have to offset the whole view, or do I offset individual objects in the scene? Other than offsetting, are there certain things I can do to give a greater sense of depth to certain objects in the game world?

I first would like to know how to do SBS stereo w/out warping for the Rift.

(I am new to stereo 3d, so thought this would be the appropriate place to post.)

Re: SBS Stereo Implementation

Posted: Fri Dec 07, 2012 6:59 pm
by cybereality
If your game engine supports the concept of "cameras" or "viewports" you can create 2 cameras/views and then map them to a fullscreen quad. You could use a pixel shader to put the buffers (you need 4; back and front for the left and right) to the screen, and optionally perform the warping at this step. One key thing is that you should be using an asymmetric frustum for camera views. So the camera positions will be offset by a certain amount, but they will still converge on the same plane. This will probably be the most difficult step to get right, depending on your engine of choice.

Re: SBS Stereo Implementation

Posted: Sun Dec 09, 2012 1:09 am
by Qoheleth
Thanks cyber. Helped alot.

Re: SBS Stereo Implementation

Posted: Mon Jan 14, 2013 12:26 pm
by Fex
Hi dude, I know this thread is a little old but here goes:


After getting my first 3D display I just had to take one of my 3D projects and add SBS functionality to see my own work in all of its 3D glory! I was using XNA as opposed to DirectX or OpenGL but the theory is the same.

Depending on the implementation of your camera you might need to add additional code to add the correct translation for the left and right images. In my case, I used a LookAt matrix. The matrix contains the camera position, the camera direction and an up vector. What I needed to do was simply create another LookAt matrix for the second eye and use offsetted positions for the cameras.

Instead of doing this somewhere in the base of my camera class I decided to simply transform the existing LookAt matrix to generate the two offsetted ones by multiplying the LookAt matrix with a translation matrix.

Code: Select all

var view1 = view * Matrix.CreateTranslation(new Vector3(-this.Depth3d, 0, 0));
var view2 = view * Matrix.CreateTranslation(new Vector3(this.Depth3d, 0, 0));
Notice how I use a Depth3d variable to determine the offset. This single variable determines the amount of depth for the 3d effect because I have used it as the X-axis component for the translation.

Somewhere else in the code the Draw method of my scene had to be called twice with the correct views, but that wasn't all. I needed to store the results of these Draws into a RenderTarget to make sure I could render them in screen coordinates (Side by Side).

Code: Select all

left = new RenderTarget2D(this.GraphicsDevice, width, height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
right = new RenderTarget2D(this.GraphicsDevice, width, height, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);

GraphicsDevice.SetRenderTarget(left);
GraphicsDeviceManager.Current.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, bg, 1.0f, 0);
this.Draw(view1, projection);

GraphicsDevice.SetRenderTarget(right);
GraphicsDeviceManager.Current.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, bg, 1.0f, 0);
this.Draw(view2, projection);

GraphicsDevice.SetRenderTarget(null);
sprite.Draw(right, new Vector2(0, 0), null, Color.White, 0, new Vector2(0, 0), 1f, SpriteEffects.None, 1);
sprite.Draw(left, new Vector2(width, 0), null, Color.White, 0, new Vector2(0, 0), 1f, SpriteEffects.None, 1);
This little code snippet was copied directly from my sourcecode and creates two rendertargets to render both results into. Then it sets the left and right targets and draws the scenes with the correct view. The last piece of code clears the rendertarget and draws both left and right images to a sprite using screen coordinates. It's that simple.

I don't know anything about the Oculus Rift but I can only imagine that you would have to do something similar and perhaps perform your post processing on the sprite after the last step here.


Good luck!

Re: SBS Stereo Implementation

Posted: Mon Jan 14, 2013 12:30 pm
by cybereality
Thanks Fex!

Re: SBS Stereo Implementation

Posted: Mon Jan 14, 2013 12:42 pm
by Fex
BTW: You can test out my project if you like. It is a 3D Rubik's Cube simulator written in Silverlight and XNA. I've attached a screenshot as well!
http://cubeking.dyndns.info/