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.
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.
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.
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.