Solar Wind 3D Sample

This sample for Silverilght 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...

C# (10.4 MB)
 
 
 
 
 
4.4 Star
(8)
9,128 times
Add to favorites
9/12/2011
E-mail Twitter del.icio.us Digg Facebook
//
// This file is a pixel shader for drawing the day and night
// sides of the Earth.
//

#include "EarthCommon.hlsl"

// An setting to override the dot product of normals with 1.0 to achieve solid lighting
// when wireframe is on
float WireframeNormalOverride	: register(c0);

// Samplers
sampler2D DaySampler			: register(s0);
sampler2D NightSampler			: register(s1);
sampler2D NightLightsSampler	: register(s2);
sampler2D NormalSampler			: register(s3);
sampler2D MaskSampler			: register(s4);

// Static parameters
static const float3 AmbientColor = float3(0.0f, 0.0f, 0.0f);
static const float3 LampColor = float3(1.0f, 1.0f, 1.0f);

static const float AmbientIntensity = 1.0f;
static const float DiffuseIntensity = 1.0f;
static const float SpecularIntensity = 0.25f;

static const float SpecularPower = 10.0f;
static const float LandBumpFactor = 5.0f;
static const float WaterBumpFactor = 2.0f;

// Pixel Shader
float4 main(VertexShaderOutput input) : COLOR 
{
	// Sample textures
    float3 daySample = tex2D(DaySampler, input.UV).rgb;
    float3 nightSample = tex2D(NightSampler, input.UV).rgb;	
	float3 lightSample = tex2D(NightLightsSampler, input.UV).rgb;
	float3 maskSample = tex2D(MaskSampler, input.UV).rgb;
	float2 normalSample = tex2D(NormalSampler, input.UV).rg;
	
	// Normalize vertex normals
    float3 Nn = normalize(input.WorldNormal);
    float3 Tn = normalize(input.WorldTangent);
    float3 Bn = normalize(input.WorldBinormal);

    // Apply bump map
    float2 landPerturbation = LandBumpFactor * (normalSample - (0.5).xx) * (1.0 - maskSample.r);
    float2 waterPerturbation = WaterBumpFactor * (normalSample - (0.5).xx) * maskSample.r;
    float2 perturbation = landPerturbation + waterPerturbation;
    Nn += (perturbation.r * Tn + perturbation.g * Bn);
    Nn = normalize(Nn);
    //Nn = (2 * normalSample) - 1.0;

	// Calculate lighting coefficient vector (ambient, diffuse, specular, 1)
    float3 Vn = input.WorldView;
    float3 Ln = input.LightVector;
    float3 Hn = normalize(Vn + 2*Ln);
    float hdn = dot(Hn, Nn);
    float ldn = dot(Ln, Nn);
    hdn = WireframeNormalOverride + (1.0 - WireframeNormalOverride) * hdn;
    ldn = WireframeNormalOverride + (1.0 - WireframeNormalOverride) * ldn;
    float4 litVec = lit(ldn, hdn, SpecularPower);

    // Update intensities
    litVec.x *= AmbientIntensity;
    litVec.y *= DiffuseIntensity;
    litVec.z *= SpecularIntensity;

    // Apply lighting and coloring
    float3 ambient = litVec.x * AmbientColor;    
    float3 specular = pow(litVec.z, 1.5) * saturate(maskSample.r + 0.3) * LampColor;
    float3 day = saturate(litVec.y) * LampColor * daySample;
    float nightDiffuse = saturate(-ldn-0.1); //saturate(1 - litVec.y);
    float3 night = nightDiffuse * LampColor * nightSample + nightDiffuse * LampColor * lightSample; 

    // Final color calculation
    float3 result = ambient + day + night + specular;

    //result += saturate(4*(-ldn-0.1)) * nightSample;	

    return float4(result.rgb, 1.0);
}