프로그래밍 2014. 1. 13. 15:48
728x90

 

생성한 그림자는 어디에라도 그릴수가 있습니다.
렌더타겟으로 만든 그림자이니,
렌더타겟 텍스쳐를 입혀주는 곳에는 그림자가 그려지게 됩니다.
이 그림자를 자기 자신 오브젝트에게 그리면 어떻게 될까요?
셀프 쉐도우(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) );

 

 

 

 

 

 

 

728x90
posted by BK dddDang
: