최상단 광고

2012년 4월 9일 월요일

깊이버퍼그림자


/////////////////////////////////////////////////////////////////////////////////
float4x4 mLightSpaceWvp;
float4x4 mWvp;
float4x4 mObjWorld;

float4 LightAmbient = {0.1, 0.1, 0.1, 1};
float4 LightDiffuse = {1, 1, 1, 1};
float4 LightDirInv;
float4 LightPos;
/////////////////////////////////////////////////////////////////////////////////
#include "../common/afx_texture_macro.fxh"
TEXTURE_2D( txrDepthMap, sampDepthMap, Clamp, NONE, LINEAR, LINEAR)
TEXTURE_2D( txrTerrain, sampTerrain, Wrap, LINEAR, LINEAR, LINEAR)
/////////////////////////////////////////////////////////////////////////////////
// Render Depth from Light
struct vso_RenderDepthMap
{
float4 HPosition : POSITION;
float4 LightSpacePos : TEXCOORD0;
};
vso_RenderDepthMap VS_RenderDepthMap(float3 pos : POSITION)
{
vso_RenderDepthMap o = (vso_RenderDepthMap)0;

float4 Pos = {pos, 1};
o.HPosition = mul(Pos, mLightSpaceWvp); // 라이트위치로부터의 깊이값을 저장하기 위해.
// 실제 필요한 건 (깊이맵을 그리기위한)z 값.
o.LightSpacePos = o.HPosition / o.HPosition.w; // 프로젝션을 거치면서 값이 w로 정규화되지 않는 경우를 위해 표준회
return o;
}
float4 PS_RenderDepthMap(float4 LightSpacePos : TEXCOORD0 ) : COLOR0
{
//LightSpacePos /= LightSpacePos.w; // 픽셀셰이더에서 정규화하면 좀더 세밀하겠지만 별 차이없음.
return (float4)LightSpacePos.z; // 깊이맵 그리기. 캐릭터가 이동할때마다 재계산되어 깊이맵도 변함.
// 모든 오브젝트에 그림자가 생김.
}

/////////////////////////////////////////////////////////////////////////////////
// Render Terrain
struct vso_RenderTerrain
{
float4 HPosition : POSITION;
float2 t : TEXCOORD0;
float4 LightSpacePos: TEXCOORD1;
};
vso_RenderTerrain VS_RenderTerrain(float3 pos:POSITION, float2 t:TEXCOORD0)
{
vso_RenderTerrain o = (vso_RenderTerrain)0;

float4 Pos = float4(pos,1);
o.HPosition = mul( Pos, mWvp);
o.t = t;

float4 PosLWvp = mul( float4(pos,1), mLightSpaceWvp);

PosLWvp /= PosLWvp.w; // for range ( -1 ~ 1 )
o.LightSpacePos.x = PosLWvp.x*0.5 + 0.5;
o.LightSpacePos.y = -PosLWvp.y*0.5 + 0.5;
o.LightSpacePos.z = PosLWvp.z;
o.LightSpacePos.w = PosLWvp.w;

return o;
}
float4 PS_RenderTerrain(float2 t:TEXCOORD0, float4 LightSpacePos:TEXCOORD1) : COLOR0
{
float4 addc = (float4)0.1;
float4 col1 = tex2D(sampTerrain, t)+addc;
float4 col2;
// 깊이값 비교.
// 0.03 는 오차보정용.
if( LightSpacePos.z-0.03 > tex2D(sampDepthMap, LightSpacePos.xy).z) col2 = (float4)0.3;
else col2 = (float4)1.0;

return col1*col2;
}
// ///////////////////////////////////////////////////////////////////////////////
struct vso_Object
{
float4 HPosition : POSITION;
float4 Normal : TEXCOORD0;
};
vso_Object VS_RenderObj( float3 pos : POSITION, float3 Normal:NORMAL )
{
vso_Object o = (vso_Object)0;
o.HPosition = mul(float4(pos, 1), mWvp );
o.Normal = float4( mul(Normal,(float3x3)mObjWorld), 0);
return o;
}
float4 PS_RenderObj(float4 Normal : TEXCOORD0) : COLOR0
{
float4 o = (float4)0;
float4 N = normalize(Normal);
float4 L = normalize(LightDirInv);
float ldn = max( dot(N, L), 0 );
o = LightAmbient + LightDiffuse * ldn ;
return o;
}
/////////////////////////////////////////////////////////////////////////////////
technique DepthShadow
{
// Render Shadow to Texture
pass P0
{
VertexShader = compile vs_2_0 VS_RenderDepthMap();
PixelShader = compile ps_2_0 PS_RenderDepthMap();
}
pass P1
{
VertexShader = compile vs_2_0 VS_RenderTerrain();
PixelShader = compile ps_2_0 PS_RenderTerrain();
}
pass P2
{
VertexShader = compile vs_2_0 VS_RenderObj();
PixelShader = compile ps_2_0 PS_RenderObj();
}
}

댓글 없음: