- 그림자 만들기. ( 그림자의 깊이 값 생성 ) -
그림자는 렌더타겟으로 지정된 텍스쳐에 그려줍니다. ( 앞서 설명한 렌더타겟을 이용합니다. )
텍스쳐에는 그림자의 뎁스값을 기록하게 됩니다.
이 뎁스값을, 그림자를 드리울 쉐이더에서 읽어와
자신의 뎁스값과 비교하게 됩니다.
쉐이더 코드를 살펴 보겠습니다.
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() 를 호출시
흰색으로 채워주게 됩니다.
배경색이기도 하고,
깊이값 비교식에서 그림자가 될 수 없는 값이기도 합니다.
'프로그래밍' 카테고리의 다른 글
depth buffer shadow - 깊이 버퍼 그림자 (6) (0) | 2014.01.13 |
---|---|
depth buffer shadow - 깊이 버퍼 그림자 (5) (0) | 2014.01.13 |
depth buffer shadow - 깊이 버퍼 그림자 (4) (0) | 2013.12.23 |
depth buffer shadow - 깊이 버퍼 그림자 (2) (0) | 2013.12.10 |
depth buffer shadow - 깊이 버퍼 그림자 (1) & 그림자 매핑 (13) | 2013.12.08 |