Quote: "I'm looking for a solid shadow system that can be used along with the other shaders"
Here is the one I use, darkcoder made it a few years ago and it was really easy to implement.
Shader:
matrix WorldViewProjection : WorldViewProjection;
matrix World : World;
float4 Pl_Minus_Cam = {3.0, 0.0, 0.0, 1.0}; // Planet XYZ - Camera XYZ
float4 LightPosition = {1.0, 0.0, 0.0, 1.0}; // Light XYZ
float4 Pl_Minus_L = {2.0, 0.0, 0.0, 1.0}; // Planet XYZ - Light XYZ
float PlanetRadius = 500.0; // Radius of planet
float Pl_Dist_L = 5.0; // Distance between Planet and Light
float PenubraWidth = 10.0; // Width of the planetary penumbra
float OneDivPenubra = 0.1; // 1 / PenubraWidth
texture DiffuseTX <string ResourceName="" ;>;
sampler2D DiffuseSampler = sampler_state
{
texture = <DiffuseTX>;
};
struct VertexInput
{
float4 Position : POSITION;
float2 UV0 : TEXCOORD0;
};
struct VertexOutput
{
float4 Position : POSITION;
float2 UV0 : TEXCOORD0;
float4 PixelPosition : TEXCOORD1;
};
VertexOutput VertexShader(VertexInput IN)
{
VertexOutput OUT;
OUT.Position = mul(IN.Position, WorldViewProjection);
OUT.PixelPosition = mul(IN.Position, World);
OUT.UV0 = IN.UV0;
return OUT;
}
float4 PixelShader(VertexOutput IN) : COLOR
{
// Grab texture pixel colour
float4 DiffuseMap = tex2D(DiffuseSampler , IN.UV0);
// Find distance from pixel to light
float Px_Dist_L = length(IN.PixelPosition.xyz - LightPosition.xyz);
// Is the pixel behind the planet?
if (Pl_Dist_L < Px_Dist_L)
{
// Find difference ratio
float Ratio = Px_Dist_L / Pl_Dist_L;
// Find new position based on ratio/planet positon
float3 NPx = LightPosition.xyz + Pl_Minus_L.xyz * Ratio;
// Find distance between pixel and new point
float SDist = length(IN.PixelPosition.xyz - NPx.xyz);
// Projected distance is less than radius?
if (SDist < PlanetRadius)
{
// Fade from penubra to umbra
float Over = PenubraWidth - (PlanetRadius - SDist);
DiffuseMap.rgb *= clamp(Over * OneDivPenubra, 0.0, 1.0);
}
}
return DiffuseMap;
}
technique Rings
{
pass p1
{
vertexShader = compile vs_1_1 VertexShader();
pixelShader = compile ps_2_0 PixelShader();
}
}
DBPro Code (shouldnt be too hard to port to GDK):
// Light 1 is the suns point light
null = Make Vector4( 1 )
Load Effect "ShadersRingShadow.fx" , RingFX , 0
Set Vector4 1 , Object Position X( Planet ) - Camera Position X() , Object Position Y( Planet ) - Camera Position Y() , Object Position Z( Planet ) - Camera Position Z() , 1.0
Set Effect Constant Vector RingFX , "Pl_Minus_Cam" , 1
Set Vector4 1 , Light Position X( 1 ) , Light Position Y( 1 ) , Light Position Z( 1 ) , 1.0
Set Effect Constant Vector RingFX , "LightPosition" , 1
Set Vector4 1 , Object Position X( Planet ) - Light Position X( 1 ) , Object Position Y( Planet ) - Light Position Y( 1 ) , Object Position Z( Planet ) - Light Position Z( 1 ) , 1.0
Set Effect Constant Vector RingFX , "Pl_Minus_L" , 1
Set Effect Constant Float RingFX , "PlanetRadius" , PlanetRadius / 2
Set Effect Constant Float RingFX , "Pl_Dist_L" , CheckDistance( Planet , Sun )
Set Object Effect RingObj , RingFX
null = Delete Vector4( 1 )