Hi,
since i received many requests about the shadows I shown on the what are you working on topic, i decided to explain how they are computed. I have to say that this shader is not a solution for any game. It is just a hobbyist workaround looking for a dynamic point shadow projection. In fact, it only works with models and sprites and it has not native lights support. The light properties are passed through the material skills.

The shadows are computed with a depth cubemap that is rendered over a 32bit floating point bitmap, very similar to the 3dgs shadows example but with six cameras instead of one.

Click to reveal..

somewhere in the code:
Code:
MATERIAL *mtlOmniShadow = { effect = "omnishadows.fx"; }
MATERIAL *mtlDepth = { effect = "depth.fx"; }

...
	// lightening settings
	mtlOmniShadow.skill1 = floatv ( 0 ); // Light position
	mtlOmniShadow.skill2 = floatv ( 0 ); // swapped axes!
	mtlOmniShadow.skill3 = floatv ( 0 );
	mtlOmniShadow.skill4 = floatv ( 1000 ); // Light range in quants
	mtlOmniShadow.skill5 = floatv ( 1 ); // Light color RGB 0<->1
	mtlOmniShadow.skill6 = floatv ( 1 );
	mtlOmniShadow.skill7 = floatv ( 1 );


	// depth cubemap
	BMAP *cubemap = bmap_create ( "#3072x512x14" );
	bmap_to_cubemap ( cubemap );
	mtlOmniShadow.skin1 = cubemap;


	// cubemap render views
	VIEW *DepthView[6];
	
	for ( i=0; i<6; i++ )
	{
		DepthView[i] = view_create ( 1 );
		DepthView[i].arc = 90;
		DepthView[i].size_x = 512;
		DepthView[i].size_y = 512;
		DepthView[i].pos_x = i * 512;
		DepthView[i].pos_y = 0;
		DepthView[i].clip_near = 1;
		DepthView[i].clip_far = 1500;
		DepthView[i].bmap = cubemap;
		DepthView[i].material = mtlDepth;
		DepthView[i].flags = SHOW; 
	}
	
	DepthView[0].pan = 180;
	DepthView[0].tilt = 0;
	DepthView[1].pan = 90;
	DepthView[1].tilt = 0;
	DepthView[2].pan = 0;
	DepthView[2].tilt = 0;
	DepthView[3].pan = 270;
	DepthView[3].tilt = 0;
	DepthView[4].pan = 90;
	DepthView[4].tilt = -90;
	DepthView[5].pan = 90;
	DepthView[5].tilt = 90;




Continuing with the differences to the 3dgs shadows example, the depth shader computes the distance between the light and the lighted surface in world space instead of the z axis (depth) in view space, so the returned red channel value is the real distance to the light point.

Click to reveal..

depth.fx:
Code:
float4x4 matWorldViewProj;
float4x4 matWorld;

float4 vecViewPos;

texture entSkin1;

sampler TexSampler = sampler_state { Texture = <entSkin1>; Mipfilter = Linear; };
	
void DepthVS (
	in float4 InPos	: POSITION,
	in float2 InTex	: TEXCOORD0,
	out float4 OutPos : POSITION,
	out float3 OutWorld : TEXCOORD0,
	out float2 OutTex : TEXCOORD1 )
	{
		OutPos = mul ( InPos, matWorldViewProj );
		OutWorld = mul ( InPos.xyz, matWorld );
		OutTex = InTex.xy;
	}

float4  DepthPS(
	in float3 InWorld : TEXCOORD0,
	in float2 InTex	: TEXCOORD1 ) : COLOR0
{
	float4 Tex = tex2D ( TexSampler, InTex );
	return float4( distance( InWorld.xyz, vecViewPos.xyz ), 0.0, 0.0, Tex.a );
}

technique Depth
{
	pass p0
	{
		ZWriteEnable = True;
		AlphaBlendEnable = True;
		AlphaTestEnable = True;
		AlphaFunc = Greater;
		Lighting = False;			
		VertexShader = compile vs_2_0 DepthVS();
		PixelShader  = compile ps_2_0 DepthPS();
	}
}




Diffuse, specular and light range maths are directly taken from the shader programming tutorials grin

Click to reveal..

omnishadows.fx
Code:
static const float fDark = 0.1f; // shadow
static const float fBright = 1.0f; // light
static const float fDepthOffset = 0.97f;

float4x4 matWorldViewProj;
float4x4 matWorld;
float4 vecViewPos;

float3x3 matTangent; // tangent space matrix

float4 vecSkill1; // light position (xyz), light range (w)
float4 vecSkill5; // light color (xyz)

texture mtlSkin1; // depth cubemap
texture entSkin1; // texture
texture entSkin2; // normals (rgb) + specularity (a)

samplerCUBE CubeSampler = sampler_state { Texture = <mtlSkin1>; MipFilter = Linear; MinFilter = Linear; MagFilter = Linear; };
sampler TexSampler = sampler_state { Texture = <entSkin1>; Mipfilter = Linear; };
sampler NormalSampler = sampler_state { Texture = <entSkin2>; Mipfilter = Linear; };


void OmniShadowVS (
	in float4 inPos: POSITION,
	in float3 inNormal: NORMAL,
	in float2 inTex: TEXCOORD0,
	in float4 inTangent: TEXCOORD2,
	out float4 outPos: POSITION,
	out float2 outTex: TEXCOORD0,
	out float3 outNormal: TEXCOORD1,
	out float4 outWorld: TEXCOORD2,
	out float3 outViewDir: TEXCOORD3,
	out float3 outLightDir: TEXCOORD4 )
	{
		outPos = mul( inPos, matWorldViewProj );
		outTex = inTex;
		outNormal = normalize( mul( inNormal, matWorld ) );
		outWorld = mul( inPos, matWorld );
		
	   matTangent[0] = mul(inTangent.xyz, matWorld); 
	   matTangent[1] = mul(cross(inTangent.xyz, inNormal)*inTangent.w, matWorld); 
	   matTangent[2] = mul(inNormal, matWorld); 
		
		outViewDir = normalize ( mul ( matTangent, vecViewPos.xyz - outWorld.xyz ) ); 
		outLightDir = normalize ( mul ( matTangent, vecSkill1.xyz - outWorld.xyz ) ); 
	}

float4 OmniShadowPS (
	in float4 inPos: POSITION,
	in float2 inTex: TEXCOORD0,
	in float3 inNormal: TEXCOORD1,
	in float4 inWorld: TEXCOORD2,
	in float3 inViewDir : TEXCOORD3,
	in float3 inLightDir: TEXCOORD4 ) : COLOR0
	{
		// shadows
		float fDistance = distance ( inWorld.xyz, vecSkill1.xyz );
		float3 inDir = inWorld.xyz - vecSkill1.xyz;
		float Depth = texCUBE ( CubeSampler, inDir ).r;
		float fShadow = Depth < fDistance * fDepthOffset ? fDark : fBright;
		
		// light influence
		float fRadiance = max ( vecSkill1.w - fDistance, 0 ) / vecSkill1.w;
		
		// specular term
		float4 NormalTex = tex2D(NormalSampler, inTex);
		float3 bumpNormal = NormalTex.rgb * 2 - 1;
	   float3 fReflect = normalize ( 2 * dot ( bumpNormal, inLightDir ) * bumpNormal - inLightDir );
	   float3 fSpecular = saturate ( dot ( fReflect, inViewDir ) ) * NormalTex.a;
		
		// simple diffuse
		float fDiffuse = saturate ( dot ( normalize ( -inDir ), inNormal ) );
		
		// final color
		float4 Color = tex2D ( TexSampler, inTex );
		Color.rgb *= vecSkill5.xyz * ( ( fDiffuse * fShadow ) + fSpecular ) * fRadiance;
		return Color;
	}


technique OmniShadow
{
	pass p0
	{
		ZWriteEnable = True;
		AlphaBlendEnable = True;
		AlphaTestEnable = True;
		AlphaFunc = Greater;
		
		VertexShader = compile vs_2_0 OmniShadowVS();
		PixelShader  = compile ps_2_0 OmniShadowPS();
	}
}




Hope it helps,
salud!

EDITED____________
ominishadows.zip


Last edited by txesmi; 06/22/12 06:56. Reason: link added