프로그래밍 2013. 12. 17. 11:20
728x90

- 그림자 만들기. ( 그림자의 깊이 값 생성 ) -

 

 

그림자는 렌더타겟으로 지정된 텍스쳐에 그려줍니다. ( 앞서 설명한 렌더타겟을 이용합니다. )

텍스쳐에는 그림자의 뎁스값을 기록하게 됩니다.

이 뎁스값을, 그림자를 드리울 쉐이더에서 읽어와

자신의 뎁스값과 비교하게 됩니다.

 

 

쉐이더 코드를 살펴 보겠습니다.

 

 

float4x4 _matWorld;

float4x4 _matLightProj;
float4x4 _matLightView;

 

 

matLightView 와 matLightProj 는 그림자 생성에 있어 매우 중요한 매트릭스 입니다.

이 값에 따라 그림자의 기울기, 모양, 퀄리티 등이 결정되어 집니다.

값이 잘못 설정되면,

전혀 엉뚱한 결과들을 얻을 수 있습니다. ^^;;;

이 부분은 다시 설명 드리도록 하겠습니다.

 

 

struct VS_INPUT
{
    float4 pos : POSITION;
    float2 uv : TEXCOORD0;
};

 

그림자를 생성하기 위해서는 오브젝트를 뷰에

렌더링시켜 주게 됩니다.

그림자에 텍스쳐를 입힐 필요는 없기 때문에,

uv 값은 필요없을 수도 있습니다만,

투명 부분이 있는 오브젝트라면,( 알파 이미지를 가진 )

uv 값이 필요해 집니다.

픽셀셰이더에서 알파값을 빼주어야, 그림자가 자신의 모양대로 출력됩니다.

 

 

struct VS_OUTPUT
{
    float4 pos : POSITION;
    float4 depth : TEXCOORD0;
    float2 uv : TEXCOORD1;
};

 

pos 는 레스터라이져에 넘겨줄 포지션값입니다.

( 이 값이 없으면 오브젝트가 출력되지 않겠지요. )

depth 값이 그림자의 깊이에 대한 xyzw 정보값을 가지게 됩니다.

 

 

VS_OUTPUT vertex_shader_1( VS_INPUT _In )
{
 VS_OUTPUT Out = (VS_OUTPUT)0;
 
 
 //레스터라이저에 넘겨줄 포지션 
 Out.pos = mul( _In.pos, _matWorld );
 Out.pos = mul( Out.pos, _matLightView );
 Out.pos = mul( Out.pos, _matLightProj );
 
 //
 Out.depth = Out.pos; //값은 동일
 Out.uv = _In.uv;

   

 return Out;
}

 

 

 

//알파없는 오브젝트

float4 pixel_shader_0( VS_OUTPUT _In ) : COLOR
{
 float depth_color = _In.depth.z / _In.depth.w;
 return float4( depth_color.xxx, 1 ); 
}

 

그림자 텍스쳐에 뎁스값을 기록해 두기 위해서는

픽셀셰이더를 통해서 화면에 그려주면 됩니다.

 

//알파있는 오브젝트

float4 pixel_shader_1( VS_OUTPUT _In ) : COLOR
{
 float depth_color= _In.depth.z / _In.depth.w;

 

 //alpha 있는 부분은 뺀다
 float4 color = tex2D( Samp_Tex_0, _In.uv );
 if( color.w < 0.99 )
  depth_color = 1.f;


 return float4( depth_color.xxx, 1 ); 
}

 

알파값이 있으면, depth_color 를 1 로 채워둡니다.

컬러값이 (1,1,1,1)이 됩니다. -> 흰색

 

렌더타겟에서 clear() 를 호출시

흰색으로 채워주게 됩니다.

 

배경색이기도 하고,

깊이값 비교식에서 그림자가 될 수 없는 값이기도 합니다.

 

 

 

 

728x90
posted by BK dddDang
: