Click here to Skip to main content
Click here to Skip to main content
Go to top

Put Your Red-Cyan Glasses On

, 15 Apr 2009
Rate this:
Please Sign up or sign in to vote.
The article shows how to build and display stereoscopic images in WPF

Introduction

This article shows how to build and display stereoscopic images in Windows Presentation Foundation (WPF). The WPF already has the ability to render a 3D image – we will just add a little depth.

Background

3D in the WPF

The WPF has the capability to display 3D models in perspective – the way as humans or cameras see it. A 3D model can be described in the WPF by geometries (often presented as a mesh of triangles) and light sources. The model can be included in WPF windows/documents via a Viewport3D control. The XAML document normally will contain the following code:

<Viewport3D>
    <Viewport3D.Camera>
        <PerspectiveCamera ... />
    </Viewport3D.Camera>
    <ModelVisual3D>
	...
    </ModelVisual3D>
</Viewport3D>

The Viewport3D control requires camera description to render the referred 3D model. We will use the PerspectiveCamera to describe how the model will be viewed.

Figure: Example of camera and model items

Stereoscopic Image

Human can perceive depth using two eyes; the brain makes a judgment about how far objects are based on images received from both eyes. Showing the same image to both of the two eyes or using only one of the eyes forces the brain to guess the objects' depth.

To make a stereoscopic image, you have to have two images: one for each eye. The image taken for the left eye has to be shown to the left eye and the image taken for the right eye has to be shown to the right eye. Two cameras are used to create a stereoscopic pair of images. Usually, the cameras are positioned side-by-side horizontally; the distance between the cameras' lenses has to be the same as the distance between the eyes of a human.

Figure: Cameras positioned for taking stereoscopic image

There are several ways to display two different images for the different eyes. We will be interested only in three of them: parallel viewing, cross viewing and anaglyph. The first two are simple to create, but not easy to view. In parallel viewing, two images, for left and right eyes, are printed side-by-side, and human eyes are trying to focus “behind” the image to let the eyes see their own images. One disadvantage is that the images have to be small – the width of the image has to be not more than the distance between the eyes. In cross viewing, two images are swapped and printed side-by-side: first for the right eye then for the left eye; and human eyes are trying to focus “in front of” the image to let the eyes see their own images.

Figure: Cross and parallel viewing of a stereoscopic pair of images

To view a typical anaglyph, you need to have special glasses: the one side is made of red glass, the other side is made of cyan (blue) glass. The red glass helps an eye to see only red (channel) colors, and the cyan glass helps to see all other colors except red. An anaglyph can be built by replacing the red channel colors of the first image (taken for the right eye) by the red channel colors from the second image (taken for the left eye).

Pixel Shader

The .NET Framework 3.5 SP1 introduced custom bitmap effects that can be based on Pixel Shader technology. The Pixel Shader lets developer create code using High Level Shading Language (HLSL) that can be executed by a graphics processing unit (GPU) during image rendering to add some special effect.

The ShaderEffect class of the WPF library helps to encapsulate interface with low level Pixel Shader object and code. The SharedEffect inherited class has to create PixelShader object and provide compiled effect code that performs actual calculations. The Pixel Shader code will accept one or more bitmap images and/or additional parameters to produce the output.

Using the Code

The code contains the AnaglyphEffects library and a sample 3D WPF application. The AnaglyphEffects library contains RedCyanEffect class that is inherited from ShaderEffect class. The source code for Pixel Shader looks like this:

sampler2D input : register(s0);
sampler2D otherEye : register(s1);

float4 main(float2 uv : TEXCOORD) : COLOR
{
float4 clr1;
clr1= tex2D(otherEye, uv.xy);

float4 Color;
Color= tex2D(input, uv.xy);

Color.r=clr1.r;

return Color;
}

The code accepts two images as inputs. During its execution, it replaces the red color in the input image with red layer of the other (tex1) image. It allows to build an anaglyph image from two stereoscopic pair of images.

Figure: How anaglyph is built by the RedCyanEffect

The sample 3D WPF Application contains a 3D model of a house, that is viewed from the perspective of two cameras: left and right. The output from the two cameras is merged using custom anaglyph bitmap effect (RedCyanEffect class) from the AnaglyphEffects library.

<Rectangle Name="anaglyph"> 
    <Rectangle.Fill> 
        <VisualBrush Visual="{Binding ElementName=rightViewport}" Stretch="Uniform" /> 
    </Rectangle.Fill>            
    <Rectangle.Effect> 
        <ae:RedCyanEffect> 
            <ae:RedCyanEffect.OtherEye> 
                <VisualBrush Visual="{Binding ElementName=leftViewport}" 
						Stretch="Uniform" /> 
            </ae:RedCyanEffect.OtherEye> 
        </ae:RedCyanEffect> 
    </Rectangle.Effect> 
</Rectangle>

Figure: Sample application screenshot

Points of Interest

Amazingly, the WPF lets you manipulate with the output at any level: before the control is drawn by styling it, after the control is drawn by applying the bitmap effect, or just retrieve the control image to reuse it in other parts of an application. VisualBrush element will let you get control image, transform it, and use the images as a Brush, e.g. it can be used to create reflection.

Creation of the custom bitmap effects is simplified and does not require special knowledge of how to optimize it to run it on different processors – the framework will take care of it. The Pixel Shader code has to be complied in an intermediate code using fxc command line tool (the part of the DirectX SDK) and be attached as embedded resource to the assembly. The compiled code is used as parameter during ShaderEffect initialization.

The implemented RedCyanEffect can be applied to any stereoscopic pair of images, e.g. build an anaglyph viewer for JPEG (JPS) stereo images.

References

  1. "A Series on GPU-based Effects for WPF", Greg Schechter
  2. "http://en.wikipedia.org/wiki/Stereoscopy", Wikipedia

History

  • 15th April, 2009: Initial post

License

This article, along with any associated source code and files, is licensed under The MIT License

Share

About the Author

notmasteryet
Software Developer
United States United States
No Biography provided
Follow on   Twitter

Comments and Discussions

 
GeneralIm going to have to get me some of those glasses now PinmvpSacha Barber15-Apr-09 5:20 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web02 | 2.8.140916.1 | Last Updated 15 Apr 2009
Article Copyright 2009 by notmasteryet
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid