프로그래밍 2014. 4. 15. 21:08
728x90

반투명 쉐이더 - 02

 

 

렌더타겟 코드에

대한 설명입니다.

 

 

//렌더타겟 생성
//포스트 이펙트와 마찬가지로, 전체 화면 크기의 렌더타겟을 만듭니다.
//캐릭터는 전체 화면 속의 어디라도 위치할 수가 있겠지요.
DXOUT( D3DDEVICE->CreateTexture( _iW, _iH, 1,
     D3DUSAGE_RENDERTARGET, D3DFMT_A16B16G16R16, D3DPOOL_DEFAULT, &m_pRT_Actor, NULL ) )

 


//렌더타겟을 준비
void
stRShader::Start_RT_Actor_Trans()
{
 D3DDEVICE->GetRenderTarget( 0, &m_pOrigSurf );

 zSurf pSurf = NULL;
 m_pRT_Actor->GetSurfaceLevel( 0, &pSurf );
 D3DDEVICE->SetRenderTarget( 0, pSurf );
 qRelease( pSurf ); //GetSurfaceLevel 사용후에 반드시....

 

 //clear target buffer
 //색상은 제로로! 완전 투명하게
 D3DDEVICE->Clear( 0, NULL, (D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER),

                            QARGB(0,0,0,0), 1.f, 0 );
}


주의할 점은 Clear 에서 배경컬러를 완전투명(0,0,0,0) 으로 준 것입니다.
타겟을 렌더링시에는
미리 그려져 있던 것들(배경, 다른 오브젝트 등) 위에 블렌딩되어 그려 주어야 하기 때문에,


블렌딩이 쉽게, 표면을 투명으로 만들어 두고,
캐릭터( 반투명하게 만들 캐릭터 )만을 타겟에 그려줍니다.

 

최종적으로,
렌더타겟 이미지는

 

( 투명 표면 + 캐릭터 )

 

즉 only 캐릭터만 그려지게 됩니다.
 


//렌더타겟을 종료
void
stRShader::End_RT_Actor_Trans()
{
 D3DDEVICE->SetRenderTarget( 0, m_pOrigSurf );
 qRelease( m_pOrigSurf ); //must ref count dec
}


//렌더타겟 텍스쳐를 사각형에 씌워 draw 합니다
//포스트 이펙트 draw 와 동일하게,
//전체화면 크기의 사각형에 만들어 둔 렌더타겟 텍스쳐를 입혀 줍니다.
void
stRShader::Render_RT_Actor( const float _fAlpha )
{
 check( GRAPHIC_DEVICE );
 check( D3DDEVICE );

 
 //
 RENDEV->GetDeferState()->SetRenderState( RS_ALPHABLENDENABLE, TRUE );
 RENDEV->GetDeferState()->SetRenderState( RS_ALPHATESTENABLE, TRUE );
 RENDEV->GetDeferState()->SetRenderState( RS_ZENABLE, TRUE );
 RENDEV->GetDeferState()->SetRenderState( RS_ZWRITEENABLE, TRUE );
 RENDEV->GetDeferState()->SetRenderState( RS_CULLMODE, D3DCULL_NONE );
 RENDEV->GetDeferState()->Commit();
 

 REffect* pEffect = Cache( "Shader/actor_pre.fx" );
 if( pEffect )
 {
  pEffect->GetEffect()->SetTexture( "tex_src", m_pRT_Actor );

  D3DDEVICE->SetVertexDeclaration( pEffect->GetVertexDec() );
  D3DDEVICE->SetFVF( QScreenVerFVF );
  D3DDEVICE->SetStreamSource( 0, m_pd3dVerBuff, 0, sizeof(QScreenVer) );

  pEffect->GetEffect()->SetTechnique( "Tech" );
  pEffect->GetEffect()->Begin( NULL, D3DXFX_DONOTSAVESTATE );

  pEffect->GetEffect()->BeginPass( 0 );
  D3DDEVICE->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 ); //사각형
  pEffect->GetEffect()->EndPass();
       
  pEffect->GetEffect()->End();
 }

}

 

그리고,

캐릭터의 렌더링 루프를 조금 손보아야 합니다.

 

대략,

 

Render_All_Actor()
{
 for( 모든 액터 ) // 저의 경우는 캐릭터와 배경 오브젝트 등을 모두 Actor 라 지칭합니다.
 {
  if( 그냥 draw )
  {
        pActor->Render();
  }
  else if( 반투명으로 draw )
  {
   stRShader::GetInst()->Start_RT_Actor_Trans();
   
   pActor->Render(); // 렌더타겟에 draw 됩니다.
      
   stRShader::GetInst()->End_RT_Actor_Trans();
   stRShader::GetInst()->Render_RT_Actor(); // 렌더타겟 draw 종료 후,

                               // 바로 렌더링 해줍니다.   

  // -> 여기서, 텍스쳐(캐릭터가 그려진)에 알파값을

  // -> 적용하여, 렌더링

  }

 }

}

 

이런식이 될 것입니다.


캐릭터가 반투명하게 되면,
알파가 적용된 액터 리스트에 포함되어야 할 것이고,


액터들 간의 카메라 거리에 따른 sorting 도 이루어져야
카메라 거리에 따라, 액터들 간에 정상적으로 겹쳐져
제대로 출력됩니다.

 

 

 

 

 

728x90

'프로그래밍' 카테고리의 다른 글

BSP 트리 ( bsp tree ) - 02  (0) 2014.04.20
반투명 셰이더 - 03  (1) 2014.04.15
반투명 셰이더 - 01  (0) 2014.04.15
HDR LDR Bloom  (0) 2014.03.23
쉐이더 홈피 하나 추천!  (0) 2014.03.19
posted by BK dddDang
: