Posts Tagged ‘shaders’

Silverlight 5 – The moon interior world

While looking at the moon as presented in the sample application, I thought: “wouldn’t it be fun to be able to get into it and then find a friendly landscape to explore”. What we need for this is a so called Sky Sphere, and a moving camera.

Sky Sphere

A Sky Sphere consists of a cube which faces are textured with a coherent set of 6 images. For instance, the 6 connected images resulting from taking a photograph into each of the 6 orthogonal directions, starting at the horizontal direction facing north. Within this cube is a sphere, and the inside of this sphere is textured with the cube textures by means of extrapolation of positions on the sphere onto positions on the cube. Then, within the cube you see the seamless projection of the cube’s images. This technique is used to provide an environment; it is also called environment mapping. The idea is to move the sphere and cube with the camera so the sky sphere always presents a distant environment. In the current version we have not yet set the step to always keeping the environment distant. At this point we want to be able to travel through the moon, to, into, through, out and away from it. The XNA Sky Sphere Community Sample served as a starting point for development.

Camera

A camera is in fact a component that provides you with a View matrix. There are a number of cameras available through XNA community samples. I explored:

  1. The ArcBall camera
  2. The Orbit camera
  3. The Chase camera

The ArcBall camera

The advantage of the ArcBall camera is that it has a large number of properties and many degrees of freedom. It therefore has a broad spectrum of applicability. On the other hand, the code is complex, and in any particular application it holds a lot of code you don’t need. Also it is hard to keep it leveled straight. Somehow I always managed to get the view somewhat tilted, but never managed to get out of the tilt. So I looked a bit further.

The Orbit camera

The Particles XNA community sample contains code for a typical orbit camera. An orbit camera can move around its LookAt, even zoom into it. This camera lacks the capability to move around freely, that is, to change, or control, the LookAt. So, we will need not one, but two camera’s, one of which will be this orbit camera.

The Chase camera

The Chase Camera is another XNA community sample. In the sample the target is a ship. In our project we do not have a visible target. The target is just the LookAt. Typically, the target, or LookAt, is what you control with the keyboard or game controller, the camera just follows the target. The target can also be controlled using the mouse. Instructions for controlling the chase camera can be found in the section “Sample Application” below.

What you control defines the major difference between a chase camera and an orbit camera. In the former case you control the target, and in the latter the camera (while the target remains stationary). One could easily create an integrated camera that switches between orbiting and chasing. For now, I’ve adapted the chase camera to fit the needs of this application, as described above.

Creating the Silverlight 5 version of phase 2

To port software from XNA to Silverlight 5 does (still) require real work. The first task is to split up the Effect file into separate shaders. One file for each vertex shader and one file for each pixel shader. Since we have an inside and an outside to draw, we end up four shader files that have to be loaded separately. The same holds for the .dds file that holds the image set for the environment map. The set had to be split into 6 separate file that have to be loaded individually.

At first I couldn’t find a way to load the Silverlight 5 textureCube into the shaders. But at some time I found that the TextureCube is a subclass of the Texture class, hence can be assigned to the textures collection of the GraphicsDevice which will then load it into the shaders at runtime.

The UI thread and the Composition thread of the DrawingSurface

We want to control the pitch (vertical angle), yaw (horizontal angle) and thrust by means of keyboard (and mouse, but see below). So, mouse and keyboard events set a variable that indicates that a change in angle is required. The mouse and keyboard events happen on the UI thread. The Draw event happens on the Composition thread. In order to prevent synchronization problems, we want to prevent (re)setting the yaw and pith variables on this thread.

In order to prevent both synchronization problems and loss of performance as a consequence of using locks or wait states, we set e.g. the pitch variable in the KeyDown event handler (for the Up and Down keys), and reset it in the KeyUp event handler. The Draw event handler only reads (samples) this variable.

In the RC (release candidate) version of Silverlight 5, the DrawingSurface and e.g. the Rectangle do not raise keyboard events. The Textbox, however, does. On the other hand, the DrawingSurface and the Rectangle do raise mouse events, but the Textbox doesn’t. Also, these events do not seem to be routed events, that ‘bubble up’, yet. So we have to choose between mouse input and keyboard input over the DrawingSurface. For this application I have chosen keyboard input. We use a transparent Textbox, stretched out over the DrawingSurface to raise keyboard events.

Keyboard control has its problems:

  • Before the TextBox has the focus, we first have to click it. We use a startup message that has to be clicked away as a work around.
  • It might well be that the left and right arrow keys respond only after a while. This does not hold for the up and down arrow keys, or the space bar. Reason unknown.

Remark on the render system: at the edges of the drawing surface, the shape of the moon gets distorted – flatted out to an ellipsis. This turned out also to be the case for the XNA version; something to look into.

Sample application

A sample application can be found here, as the Phase 2 app. The keys for navigation are:

  • Space: forward
  • Left (Right, Up, Down) arrow: rotate to the left (right, up, down)
  • T key: turns the camera around (180 degrees)
  • R key: resets
  • A key: toggles physics

The sample application demos the moon interior and the chase camera. And that’s it.

Edit 29-12-2011: Since the Release of Silverlight 5 RTM some changes were made to the sample program. There is no startup message any more. On the other hand, the application only runs after local installation.

Advertisements

Silverlight 5 – Rotating Moon in 3D

Providing 3D user experiences over the web is an extraordinary technological feat. It is possible when we use the XNA integration with Silverlight 5 (beta). This blog post describes a first experiment: showing a rotating moon. In upcoming posts I hope to extend this experiment to include some further nice features.

Approach

The approach taken here is to first develop a model in XNA, for PC, and to then port it to Silverlight 5 when finished. This provides access to well known and well developed coding idiom, and the means to test and debug the code. It also provides the opportunity to separate off any problems that are specific to the integration of XNA and Silverlight.

Starting Point

The starting point was the “Textures and Colors” sample from the Microsoft App Hub site. This sample provides the essential techniques for importing a sphere and texturing it with an image. The sample provides much more, but we don’t need that right now.

The mapping of an image, which is usually rectangular or square, onto a sphere is not straightforward. See the screenshot from the “Textures and Colors” Sample below (left) which maps a “Cloud” texture onto a sphere, and an experiment in which a quilt design was mapped onto the sphere.

There are two obvious ways around this problem. One is to have an image that has been prepared to compensate for this effect. The other way is to map the image to the sphere while compensating for its shape.

When we apply a technique called Spherical Mapping, we get somewhat improved results, but still not satisfying. Spherical Mapping uses Normal vectors to correct the u and v coordinates that are used to sample a texture for a given xyz 3D coordinate. Coordinates are calculated as:

u = asin(Nx)/PI + 0.5

v = asin(Ny)/PI + 0.5

where NX is the x-component of a Normal vector. Results in our cases are as follows.

The blue and white quilt ball looks much better, the cloud texture map still looks awful. Luckily, I was able to find a cylindrical projection map of the moon on the internet which looks quite good.

At first, I thought that the terrain was looking odd because of deformations caused by mapping the image onto the sphere, but this is the actual south pole of the moon. And, by the way, this is a much better image than the one you get from Google Moon (Earth).

Creating the Silverlight 5 application

The idea is to use the new DrawingSurface control to render the 3D scene. Needed here is a way to import the sphere model into a Silverlight 5 Application, and to use vertex and pixel shaders to position and texture it with the image.

Some people have already created practices and extensions that can be used to get this done. Entry point to these pioneers is Aaron Oneal’s Blog. Notable contributions that have been made are the CodePlex Babylon Toolkit project by (predominantly) David Catuhe, and The model loading CodePlex project by Simon Ferquel. We will use aspects of those contributions where required.

I’m somewhat reluctant to jump at CodePlex products, since experience taught me that frequently there are some disadvantages attached. For instance, a feature I really would like to use is the ShaderBuildTask. This automatically builds the shaders when you build your project. However, for the ShaderBuildTask the shaders should be attributed as ‘content’, not as ‘resource’. If not, you’ll get a build error stating that the output already exists. The disadvantage is that you cannot use the resource addressing idiom (the “;component/” format). Then the shaders cannot be loaded since the code that loads the shaders is in another Visual Studio Project than the shaders. So, back to the scripts from the first Microsoft Silverlight 5 3D demo application. See what I mean?

Anyway. The model Importer by Simon Ferquel did prove its use.

Sample App

A Silverlight 5 sample application showing the moon in slow rotation can be run at my App Shop. This is a separate corner of the App Shop: an HTML 5 site, presenting Silverlight 5 Apps.