We're all one little world... as shown with the Silverlight 5 3D sample, Solar Wind

Sign in to queue


What I liked about this sample was that it was 'simple,' focusing on one primary thing and yet was pretty cool looking. And there's just something about seeing our little ball of dirt and rock from space that appeals to the frustrated space voyager in me. [Insert quip, "Look! You can see my house from here!" ]

Solar Wind 3D Sample


This sample for Silverlight 5 uses the new 3D features to draw the Earth with day and night transitions, atmosphere layers, and population density overlays. It demonstrates advanced concepts like mipmaps, texture blending, multiple drawing passes, sampler states, and lighting.

Note the "Building the Sample" section (which of course I didn't until I tried to run it the first time... Note to self: RTFP [Read The Fine Post]... Smiley

Building the Sample

To compile the solution you will need to install the DirectX SDK and the HLSL Shader Build Task. Afterwards you can open the solution in Visual Studio to build.

Here's another shot, showing off some of the other capabilities, like the rotation and Magnetic Field overlay


The solution is pretty straight forward, with more files for the shaders and textures than for code...


Here's the Earth class;

       public Earth()
Transform = Matrix.CreateWorld(new Vector3(), Vector3.Forward, Vector3.Up);
            AtmosphereVisible = true;
MagneticFieldVisible = false;
PopulationDensityVisible = false;
ShowWireframe = false;

Now lets load the shaders and textures.

      void LoadEarthContent()
// Load mesh
mesh = new SpherePrimitive(10.0f, 50);
// Load shaders
            earthVertexShader = ContentManager.LoadVertexShader("Shaders/Earth_vs.vs");
earthPixelShader = ContentManager.LoadPixelShader("Shaders/Earth_ps.ps");
// Load textures
            dayTexture = ContentManager.LoadTexture("Textures/Earth/EarthDay.png", true);
nightTexture = ContentManager.LoadTexture("Textures/Earth/EarthNight.png", true);
nightLightsTexture = ContentManager.LoadTexture("Textures/Earth/EarthNightLights.png", true);
normalTexture = ContentManager.LoadTexture("Textures/Earth/EarthNormal.png", true);
maskTexture = ContentManager.LoadTexture("Textures/Earth/EarthMask.png", true);

Here's a snap of those textures;


Drawing the world...

      public void Draw(GraphicsDevice device, SceneTime time, Camera camera)
// All Earth pass shaders use the same constants so update them each frame
UpdateEarthShaderConstants(device, time, camera);
// Pass 1 - Draw Earth
            // Set textures in order of samplers
device.Textures[0] = dayTexture;
device.Textures[1] = nightTexture;
device.Textures[2] = nightLightsTexture;
device.Textures[3] = normalTexture;
device.Textures[4] = maskTexture;
            // Set states to control sampling
device.SamplerStates[0] = SamplerState.AnisotropicClamp;
device.SamplerStates[1] = SamplerState.AnisotropicClamp;
device.SamplerStates[2] = SamplerState.AnisotropicClamp;
device.SamplerStates[3] = SamplerState.AnisotropicClamp;
device.SamplerStates[4] = SamplerState.AnisotropicClamp;
            // Set device states
device.BlendState = BlendState.Opaque;
device.RasterizerState = rasterizerState;
            // Configure shading pipeline
            // Draw the main earth pass
            // Draw atmosphere layer
if (AtmosphereVisible)
            // Draw population layer
if (PopulationDensityVisible)
            // Draw magnetic field
if (MagneticFieldVisible)
field.Draw(device, time, camera);

And finally updating it as the world rotates.

       void UpdateEarthShaderConstants(GraphicsDevice device, SceneTime time, Camera camera)
// Get the inverse transpose matrix
Matrix WorldInverseTransposeMatrix = Matrix.Invert(Transform);
WorldInverseTransposeMatrix = Matrix.Transpose(WorldInverseTransposeMatrix);
            // Set the primary vertex constants
earthConstants.WorldMatrix = Transform;
earthConstants.WorldInverseTransposeMatrix = Matrix.Transpose(Matrix.Invert(Transform));
earthConstants.WorldViewProjectionMatrix = Transform * camera.ViewTransform * camera.ProjectionTransform;
earthConstants.ViewInverseMatrix = Matrix.Invert(camera.ViewTransform);
earthConstants.TotalSeconds.X = (float)time.TotalTime.TotalSeconds;
device.SetVertexShaderConstantFloat4(0, ref earthConstants);
            // Set the pixel shader constants (to achieve solid lighting in wireframe mode)
device.SetPixelShaderConstantFloat4(0, ref showWireframeValue);
device.SetPixelShaderConstantFloat4(0, ref hideWireframeValue);


If you're looking at Silverlight 5's 3D capabilities, then this, or other samples from the MIX11 Silverlight 3D session, should be worth a peek...

Here’s a few more links you might find interesting:


Page thumbnail, Day 432 / 365 - It's a small world, curtsey of xJasonRogersx

The Discussion

Add Your 2 Cents