프로그래밍 2015. 1. 30. 20:47
728x90

 

볼륨메트릭 라이팅 Volumetric Light - 02

 

 

월드상의 발광체를,

텍스쳐 공간으로 변환시키는 코드입니다

 

vSunWorldPos 는 발광체의 월드 좌표값이고,

vSunScreenPos 가 변환되어, 셰이더에 넘겨질 변수입니다.

 

D3DXVec3Project( &vSunScreenPos, &vSunWorldPos, NULL, &g_matProj, &g_matView, NULL );

 

// 0 ~ 1 사이의 UV 좌표로 변환 
vSunScreenPos.x = (vSunScreenPos.x + 1.f) * 0.5f;
vSunScreenPos.y = (1.f - vSunScreenPos.y) * 0.5f;

 

pEffect->GetEffect()->SetValue( "_ScreenSunPos", vSunScreenPos, sizeof(Vector2) );

 

 

<셰이더 코드>

 

저의 경우는

post effect 용으로, 오리지날씬을 블렌드해서 사용할수 있는

이펙트 코드가 있어서

여기에다가 바로 추가를 해주었습니다.

 

//

float _fTexWidth = 0.f;
float _fTexHeight = 0.f;

 

float2 _ScreenSunPos = float2(0,0);
int _iNumSamples = 10;
float _fUVNumSamples = 4.f;
float _Exposure = 1.f;
float _Density = 1.f;
float _illuminationDecay = 1.f;
float _Decay = 0.6f;
float2 _SunDirVel = float2( 0, -3 );

 

sampler2D Samp_Texture_Orig =
sampler_state
{
    Texture = <_pTex_Orig>;

    //4.0
    Filter=MIN_MAG_MIP_LINEAR;
    //AddressU = Wrap;
    //AddressV = Wrap;

};

 

//VL_RT 텍스쳐 입니다

sampler2D Samp_Texture_Light =
sampler_state
{
    Texture = <_pTex_Light>;

    //4.0
    Filter=MIN_MAG_MIP_LINEAR;

};

 

//픽셀셰이더 코드 부분입니다.

//간단하게, PS() 로 표시하였습니다.

PS()

{

       //fC 는 오리지날씬 텍스쳐 색상값

       float4 fC = tex2D( Samp_Texture_Orig, _UV );

       float4 PsColor = fC;

 

        //샘플링 갯수

        //갯수가 많아질수록 부드러워집니다만,

        //그만큼 부하는 커지겠지요.
      int iCount = _iNumSamples;

      //오리지날씬과 동일한 uv 값을 받아와서

      float2 texCoord = _UV;

 

      //uv 를 이동시킬 방향성을 구해두고,
      float2 deltaTexCoord = texCoord - _ScreenSunPos;

 

      //광선의 밀도치

      //발광체가 만들어 내는 빔의 간격에 영향을 끼칩니다.
      deltaTexCoord.x *= 1.f / (float)iCount * _Density;
      deltaTexCoord.y *= 1.f / (float)iCount * _Density;

  

 //Samp_Texture_Light
 float4 color = tex2D( Samp_Texture_Light, texCoord );

 

      //광선의 감소치 
      float illuminationDecay = _illuminationDecay;
      float4 sample = float4( 1, 1, 1, 1 );

  
      for( int i=0; i < iCount; i++ )
      {
           texCoord -= deltaTexCoord;
           

          //fTexWidth, fTexHeight 는 스크린 크기 (1280, 720 같은....) 

     //sun 방향성 값으로,

     //광선이 뻗어나가는 방향을 정할수 있습니다
     texCoord.x += 1.f / _fTexWidth * _SunDirVel.x;
     texCoord.y += 1.f / _fTexHeight * _SunDirVel.y;
   

     //
     sample = tex2D( Samp_Texture_Light, texCoord );
   

     //광선이 멀어질수록 약해지듯이

     //감소치를 곱해줍니다.

     sample *= illuminationDecay;
   

     //컬러값을 누적시킵니다.
     color += sample;
   

     //감소처리
     illuminationDecay *= _Decay;

     }

 

     //오리지날 픽셀컬러에 더해 줍니다.

     //좀더 강한 빛을 원한다면,

     //_Exposure 값을 크게 주면 됩니다.
    PsColor = fC + (color * _Exposure);

   

    return PsColor;

}

 

 

 

728x90

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

셀프쉐도우 depth bias  (0) 2015.04.24
쉐이더 그림자 vsm pcf - 01  (0) 2015.03.10
볼륨메트릭 라이팅 Volumetric Light - 01  (0) 2015.01.30
셰이더로 구현한 화면 노이즈  (0) 2015.01.23
c++ tick  (0) 2014.11.23
posted by BK dddDang
: