생성한 그림자는 어디에라도 그릴수가 있습니다.
렌더타겟으로 만든 그림자이니,
렌더타겟 텍스쳐를 입혀주는 곳에는 그림자가 그려지게 됩니다.
이 그림자를 자기 자신 오브젝트에게 그리면 어떻게 될까요?
셀프 쉐도우(self shadow) 가 되겠지요. ^^
생성한 깊이버퍼 그림자를 지형에 입혀보겠습니다.
저의 경우는 지형에만 그림자를 그려주었습니다.
코드를 살펴보겠습니다.
코드가 조금 복잡합니다.
타일 텍스쳐를 스플래팅으로 처리하는 코드가 같이 포함되어 있습니다.
( 이 부분 관련 코드와 light, fog 관련 코드는 무시하시면 됩니다. )
코드가 긴 관계로 장을 나누어서 설명드리겠습니다.
/*
=================================================================
배경 타일에 그림자를 입치는 쉐이더 코드
=================================================================
*/
float4x4 _matLocalTM;
float4x4 _matView;
float4x4 _matProj;
//카메라 근거리, 중거리, 원거리에 따른 뷰와 프로젝션의 구분입니다.
float4x4 _matLightView_0;
float4x4 _matLightView_1;
float4x4 _matLightView_2;
float4x4 _matLightProj_0;
float4x4 _matLightProj_1;
float4x4 _matLightProj_2;
texture tex_0;
texture tex_depth_0; //근거리 렌더타겟 그림자 텍스쳐
texture tex_depth_1; //중거리 렌더타겟 그림자 텍스쳐
texture tex_depth_2; //원거리 렌더타겟 그림자 텍스쳐
//텍스쳐 스플래팅 관련 부분
texture tex_1;
texture tex_2;
texture tex_3;
texture tex_alpha_1;
texture tex_alpha_2;
texture tex_alpha_3;
texture tex_static_shadow; //깊이버퍼그림자와는 상관없는 부분입니다.
//미리 만들어둔 정적 그림자 텍스쳐가 있다면 그려주기 위해
//포함되었습니다.
//
int _iShadowType = 0; //깊이버퍼그림자와는 상관없는 부분입니다.
//3rd person, fps view 구분을 위해 만들어 놓았습니다.
//깊이버퍼그림자를 만들때 사용한 라이트 입니다.
float3 _vSunLightDir;
float4 _vSunLightDiffuse;
//텍스쳐 스플래팅 관련 부분
float _fLayer_1 = 0.f; // bool type 으로 만드니, 값 체크가 제대로 안된다.
//쉐이더에서는 그저 float type 이 안전빵인듯....
float _fLayer_2 = 0.f;
float _fLayer_3 = 0.f;
float _fLayer_Static_Shadow = 0.f;
//안개처리 추가
float4 _vFog;
float4 _vFogColor;
//--------------------------------------------------------------------------------------
// Texture samplers
//--------------------------------------------------------------------------------------
sampler2D Samp_Tex_0 =
sampler_state
{
Texture = <tex_0>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
//Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
//sampler comparison state
//ComparisonFunc = LESS;
};
sampler2D Samp_Tex_1 =
sampler_state
{
Texture = <tex_1>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
//Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
//sampler comparison state
//ComparisonFunc = LESS;
};
sampler2D Samp_Tex_2 =
sampler_state
{
Texture = <tex_2>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
//Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
//sampler comparison state
//ComparisonFunc = LESS;
};
sampler2D Samp_Tex_3 =
sampler_state
{
Texture = <tex_3>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
//Filter = COMPARISON_MIN_MAG_LINEAR_MIP_POINT;
//sampler comparison state
//ComparisonFunc = LESS;
};
sampler2D Samp_Tex_Alpha_1 =
sampler_state
{
Texture = <tex_alpha_1>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
};
sampler2D Samp_Tex_Alpha_2 =
sampler_state
{
Texture = <tex_alpha_2>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
};
sampler2D Samp_Tex_Alpha_3 =
sampler_state
{
Texture = <tex_alpha_3>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
};
sampler2D Samp_Tex_Static_Shadow =
sampler_state
{
Texture = <tex_static_shadow>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
};
sampler2D Samp_Depth_0 =
sampler_state
{
Texture = <tex_depth_0>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
};
sampler2D Samp_Depth_1 =
sampler_state
{
Texture = <tex_depth_1>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
};
sampler2D Samp_Depth_2 =
sampler_state
{
Texture = <tex_depth_2>;
//4.0
Filter=MIN_MAG_MIP_LINEAR;
//AddressU = Wrap;
//AddressV = Wrap;
};
//input
struct VS_INPUT
{
float4 pos : POSITION;
float3 normal : NORMAL;
float4 diff : COLOR0;
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
};
//output
struct VS_OUTPUT
{
float4 pos : POSITION;
float4 diff : COLOR0;
float2 uv : TEXCOORD0;
float2 uv1 : TEXCOORD1;
float2 uv2 : TEXCOORD2;
float4 depth_0 : TEXCOORD3;
float4 depth_1 : TEXCOORD4;
float4 depth_2 : TEXCOORD5;
float fFog : TEXCOORD6;
};
//VS
VS_OUTPUT VertexShader_0 ( VS_INPUT _In )
{
VS_OUTPUT Out = (VS_OUTPUT)0;
//pos
//float4 pos = float4( _In.pos, 1 );
float4 pos = _In.pos;
pos = mul( pos, _matLocalTM );
Out.pos = mul( pos, _matView );
Out.pos = mul( Out.pos, _matProj );
//근거리 그림자 텍스쳐
Out.depth_0 = mul( pos, _matLightView_0 );
Out.depth_0 = mul( Out.depth_0, _matLightProj_0 );
//중거리 그림자 텍스쳐
Out.depth_1 = mul( pos, _matLightView_1 );
Out.depth_1 = mul( Out.depth_1, _matLightProj_1 );
//원거리 그림자 텍스쳐
Out.depth_2 = mul( pos, _matLightView_2 );
Out.depth_2 = mul( Out.depth_2, _matLightProj_2 );
//light
float3 vNormalWorldSpace;
vNormalWorldSpace = mul( _In.normal, (float3x3)_matLocalTM );
vNormalWorldSpace = normalize( vNormalWorldSpace );
//Compute simple directional lighting equation(방정식)
float3 vLightTotal;
vLightTotal = _vSunLightDiffuse.xyz * max( 0, dot( vNormalWorldSpace, -_vSunLightDir ) );
//light 빛적용 간격이 크게
vLightTotal *= 3.f;
//color
Out.diff = _In.diff;
Out.diff.rgb = _In.diff.rgb * vLightTotal;
//uv
Out.uv = _In.uv;
Out.uv1 = _In.uv1;
Out.uv2 = _In.uv2;
//fog( dist )
Out.fFog = _vFog.x + Out.pos.w * _vFog.y;
//fog( height )
//pos = mul( _In.pos, _matLocalTM );
//Out.fFog = _vFog.x - pos.y * _vFog.y; //height - 월드좌표계 y 값 사용.
//포그처리 관련 코드
if( Out.fFog < 0.f )
Out.fFog = 0.f;
else if( Out.fFog > 1.f )
Out.fFog = 1.f;
return Out;
}
이펙트에 값을 넘기는 cpp 코드 부분
//
pEffect->GetEffect()->SetTexture( "tex_0",
m_ImageLayer.D3DTexture[0] ); //LPDIRECT3DTEXTURE9
pEffect->GetEffect()->SetTexture( "tex_depth_0",
stRShader::GetInst()->Get_Render_Target_Tex( 0 ) ); //LPDIRECT3DTEXTURE9
pEffect->GetEffect()->SetTexture( "tex_depth_1",
stRShader::GetInst()->Get_Render_Target_Tex( 1 ) ); //LPDIRECT3DTEXTURE9
pEffect->GetEffect()->SetTexture( "tex_depth_2",
stRShader::GetInst()->Get_Render_Target_Tex( 2 ) ); //LPDIRECT3DTEXTURE9
//근거리 라이브뷰와 프로젝션 매트릭스
pEffect->GetEffect()->SetMatrix( "_matLightView_0", &matLightView[0] );
pEffect->GetEffect()->SetMatrix( "_matLightProj_0", &matLightProj[0] );
//중거리 라이브뷰와 프로젝션 매트릭스
pEffect->GetEffect()->SetMatrix( "_matLightView_1", &matLightView[1] );
pEffect->GetEffect()->SetMatrix( "_matLightProj_1", &matLightProj[1] );
//원거리 라이브뷰와 프로젝션 매트릭스
pEffect->GetEffect()->SetMatrix( "_matLightView_2", &matLightView[2] );
pEffect->GetEffect()->SetMatrix( "_matLightProj_2", &matLightProj[2] );
pEffect->GetEffect()->SetValue( "_vSunLightDir", &(QPolyTile::SunLight.Direction),
sizeof(Vector3) );
pEffect->GetEffect()->SetValue( "_vSunLightDiffuse",
&(QPolyTile::SunLight.Diffuse.GetColor_Vector()), sizeof(Vector4) );
'프로그래밍' 카테고리의 다른 글
depth buffer shadow - 깊이 버퍼 그림자 (7) (2) | 2014.01.13 |
---|---|
depth buffer shadow - 깊이 버퍼 그림자 (6) (0) | 2014.01.13 |
depth buffer shadow - 깊이 버퍼 그림자 (4) (0) | 2013.12.23 |
depth buffer shadow - 깊이 버퍼 그림자 (3) (2) | 2013.12.17 |
depth buffer shadow - 깊이 버퍼 그림자 (2) (0) | 2013.12.10 |