Все мы – один маленький мир… как показано на 3D-примере Silverlight 5, Solar Wind
Что мне нравится в этом примере, так это его простота, сфокусированность на одной главной теме и то, что он прекрасно выглядит. И есть что-то в рассматривании из космоса нашего маленького шарика из пыли и камней, который взывает к расстроенному космическому путешественнику во мне. [Внести комментарий «Взгляни! Я вижу свой дом отсюда!»]
Этот пример для Silverlight 5 использует новые трехмерные возможности для создания изображения Земли с переходами дня и ночи, слоями атмосферы и наложениями плотности населения. Он демонстрирует современные концепции множественных отображений, смешения текстур, множественные проходы при рисовании, состояния дискретизатора и освещение.
Прочтите раздел «Построение примера» (чего я, конечно же, не сделал, пока не попытался запустить пример в первый раз… На заметку: RTFP [Read The Fine Post – прочти это прекрасное сообщение]...
Построение примера
Чтобы скомпилировать решение необходимо установить DirectX SDK и HLSL Shader Build Task. После чего можно открыть решение в Visual Studio для построения.
Вот другой снимок, показывающий некоторые другие возможности, такие как вращение и наложение магнитного поля.
Решение достаточно прямолинейное, в нем больше файлов с шейдерами и текстурами, чем с кодом...
Вот класс Earth (Земля):
public Earth()
{
Transform = Matrix.CreateWorld(new Vector3(), Vector3.Forward, Vector3.Up);
AtmosphereVisible = true;
MagneticFieldVisible = false;
PopulationDensityVisible = false;
ShowWireframe = false;
}
Теперь загрузим шейдеры и текстуры:
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);
}
Вот часть этих текстур:
Рисуем мир…
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
device.SetVertexShader(earthVertexShader);
device.SetPixelShader(earthPixelShader);
// Draw the main earth pass
mesh.Draw(device);
// Draw atmosphere layer
if (AtmosphereVisible)
atmosphereLayer.Draw(device);
// Draw population layer
if (PopulationDensityVisible)
populationLayer.Draw(device);
// Draw magnetic field
if (MagneticFieldVisible)
field.Draw(device, time, camera);
}
И, наконец, обновляем по мере вращения мира.
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)
if(ShowWireframe)
device.SetPixelShaderConstantFloat4(0, ref showWireframeValue);
else
device.SetPixelShaderConstantFloat4(0, ref hideWireframeValue);
}
Если вы хотите взглянуть на трехмерные возможности Silverlight 5, то этот или другие примеры из сессии MIX11 Silverlight 3D должны быть полезны…
Несколько ссылок, которые могут оказаться интересными:
- Silverlight 3D : Tri-Winning (Part 1)
- Домостроительство с Джоном Папа и Silverlight 5 на MIX11
- Блог Аарона Онила – Aaron Oneal's Blog (Автор этого примера и других сообщений по Silverlight 3D)
- Обзор 3D-графики
- Сессии MIX11 Silverlight 3D