Sign in to follow this  
cph05a

Anaglyph Stereoscopic Solution

Recommended Posts

I've been working on a stereo 3d game which uses dubois anaglyph and I just wanted to post my solution to see what you guys think...

The color scheme I've been using is the dubois least squares algorithm with red-cyan glasses.
I basically just draw the image in the left eye by offsetting the camera slightly left (by half of the inter-axial separation) to a render target,
then offset the camera to the right (again by half the inter-axial separation) to another render target, then run both textures through a 2D shader.
I'm using XNA 4.0 and shader version 2.0.

create render targets:
[code]
protected override void LoadContent()
{
duboisAnaglyph = Content.Load<Effect>("Effects/Dubois");
GraphicsDevice device = GraphicsDevice;
graphics.GraphicsDevice.SamplerStates[0] = SamplerState.PointClamp;
renderLeftTarget = new RenderTarget2D(device, 1024, 1024, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
renderRightTarget = new RenderTarget2D(device, 1024, 1024, false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8);
}
[/code]

Draw both left and right images:
[code]
public void DrawAnaglyph(float offSet)
{
// draw left eye image
GraphicsDevice.SetRenderTarget(renderLeftTarget);
GraphicsDevice.Clear(Color.Black);
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
Draw3DModels(offSet); // offset will translate the view matrix
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.Black);

// draw right eye image
GraphicsDevice.SetRenderTarget(renderRightTarget);
GraphicsDevice.Clear(Color.Black);
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
Draw3DModels(offSet * -1); // offset will translate the view matrix
GraphicsDevice.SetRenderTarget(null);
GraphicsDevice.Clear(Color.Black);

// draw the two images as an anaglyph
GraphicsDevice.Textures[1] = renderLeftTarget;
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
duboisAnaglyph.CurrentTechnique = duboisAnaglyph.Techniques["duboisAnaglyph"];
duboisAnaglyph.Parameters["LeftOffset"].SetValue(focalOffset);
for (int index = 0; index < duboisAnaglyph.CurrentTechnique.Passes.Count; index++)
{
duboisAnaglyph.CurrentTechnique.Passes[index].Apply();
spriteBatch.Draw(renderRightTarget, new Rectangle(0, 0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height), Color.White);
}
spriteBatch.End();
}
[/code]

2D HLSL pixel shader which applies dubois least squares:
The focal point adjustment is just shifting the left image to the left or right
[code]
float4 PS_DuboisLeastSquares(float2 texCoord : TEXCOORD0) : COLOR0
{
// the left image will be offset in order to set the focal point
float2 leftCoord = {texCoord.x - LeftOffset, texCoord.y};

float4 left = tex2D(LeftSampler, leftCoord);
float4 right = tex2D(RightSampler, texCoord);

float red = (0.437*left.r) + (0.449*left.g) + (0.164*left.B) + (-0.011*right.r) + (-0.032*right.g) + (-0.007*right.B);
float green = (-0.062*left.r) + (-0.062*left.g) + (-0.024*left.B) + (0.377*right.r) + (0.761*right.g) + (0.009*right.B);
float blue = (-0.048*left.r) + (-0.050*left.g) + (-0.017*left.B) + (-0.026*right.r) + (-0.039*right.g) + (1.234*right.B);
float4 output = {red, green, blue, 1};

return output;
}
[/code]

Here is an example image rendered with this method:
[img]http://farm6.static.flickr.com/5015/5471628376_5fc2023074.jpg[/img]

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this