728x90

※ 제 개인 공부이므로 풀 소스 코드는 작성하지 않습니다.

※ 생략 되어 있는 부분이 많습니다.

struct VtxRHWDUV1
 {
  D3DXVECTOR4 p;
  DWORD d;
  FLOAT u, v;

  VtxRHWDUV1() : p(0, 0, 0, 1), u(0), v(0), d(0xFFFFFFFF) {}
  VtxRHWDUV1(FLOAT X, FLOAT Y
   , FLOAT U, FLOAT V
   , DWORD D = 0XFFFFFFFF) : p(X, Y, 0, 1), u(U), v(V), d(D) {}

  enum { FVF = (D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1) };
 };

 

VtxRHWDUV1 m_pVtx[4];   // Vertex Buffer

LPDIRECT3DVERTEXDECLARATION9  m_pFVF;    // Declarator
LPDIRECT3DPIXELSHADER9  m_pPs;    // Pixel Shader
LPD3DXCONSTANTTABLE  m_pTbl;    // Constant Table

LPDIRECT3DTEXTURE9  m_pTx;    // Texture 0

 

이번 정점 데이터의 구조는 w값을 추가로 가지는 XYZRHW, 색상값을 가지는 DIFFUSE, 텍스처를 나타내는 TEX1의 구조로 되어있다.

 

XYZ : 3d 공간상의 좌표, 정점의 변환이 완료되지 않은 좌표(스크린 좌표)

XYZRHW : 2d 인터페이스 좌표에 사용, 정점의 변환이 완료된 좌표(윈도우 좌표)

 

스크린 좌표 : 중심점(0,0) 가운데, 우측으로 x, 위로 y

윈도우 좌표 : 중심점(0,0) 좌측상단, 우측으로 x, 아래로 y 

 

*shader.fx*(단색화)

 

sampler SampDif : register(s0);

 

float4 PxlPrc(float2 Tx0 : TEXCOORD0 /* Texture Coordinate */) : COLOR
{
     float4 Out=0.0F;
     float4 MonoColor ={0.5F, 1.0F, 2.0F, 1.0F};  // 단색화 색상(색상 :   )
     float4 MonoWeight={0.299F, 0.587F, 0.114F, 0.0F}; // 단색화 비중

 

     Out = tex2D( SampDif, Tx0 ); // 샘플링

     Out = dot(Out, MonoWeight);  // 내적(dot)로 단색화
     Out *= MonoColor;    // 단색화 색상을 곱함

 

     Out *= 3.0F;     // Aux: 전체 밝기를 올림
     Out.a = 1.0F;     // 불투명 픽셀로 설정

 

     return Out;
}

 

tex2D 함수를 통해 SampDif(텍스처)에서 Tx0(좌표)의 픽셀값을 가져와 이 값을 MonoWeight(단색화 비중)값과 내적을 시켜 준다.

 

그러면 현재 좌표 픽셀의 단색화 값이 나오게 되고 여기에 MonoColor(단색화 색상)을 곱해주면 비율만큼 색상이 입혀지게 된다.

 

현재 이 코드에는 단색화 비중이 초록색에 가까울수록 제일 높고 파란색에 가까울 경우 낮다.

 

그래서 위 결과 사진을 보면 원본 사진에서 파란색일 경우 연한 파란색이 되고 초록색일 경우 찐한 파란색이 되고 있다.  

 

*shader.fx*(흐림 효과)

 

sampler SampDif : register(s0);

 

float4 PxlPrc(float2 Tx0 : TEXCOORD0 /* Texture Coordinate */) : COLOR
{
     float4 Out=0.0F;

     // 흐림 효과의 픽셀은 인접한 픽셀에 비중을 곱한 값을 누적해서 결정
     // 텍스처 좌표를 변화시키면서 인접한 픽셀을 샘플링
     // Gaussian 분포: exp (x*x/Delta) 값을 픽셀의 비중으로 설정

     for(int x=-4; x<=4; ++x)
     {
          float2 T = Tx0;
          T.x += (2.f * x)/1024.f;      // 텍스처 좌표를 변화시킨다
          Out += tex2D( SampDif, T ) * exp( (-x*x)/8.f); 
// 픽셀을 샘플링하고 가우스 분포 함수로 구한 비중 값을 곱한 후 더한다.

     }

 

     Out *= 0.24F; // 전체 명도를 낮춤
     Out.a = 1.0f; // 불투명 픽셀로 설정

 

     return Out;
}

 

흐림 효과는 인접한 픽셀에 비중 값을 곱하고 더하고를  최종 색상을 만들어 낸다.

 

여기서는 대표적인 알고리즘인 Gaussian Blur을 이용한 방법이다.

Gaussian Blur은 인접한 픽셀까지의 거리를 가지고 비중 값을 exp() 함수로 결정한다.

 

최종 색상 = 

 

인접한 픽셀의 텍스처 좌표를 변화시킨 후에 tex2D() 함수를 사용하여 좌표에 해당하는 픽셀값(P)에 Gaussian 분포값 (exp (x*x/Delta))을 곱하면 최종색상이 나오고 이 값을 출력될 값(Out)에 더해주는것을 for문을 이용해 반복적으로 적용한다.

*shader.fx*(단색화 + 흐림효과)

 

sampler SampDif : register(s0);

 

float4 PxlPrc(float2 Tx0 : TEXCOORD0 /* Texture Coordinate */) : COLOR
{
     float4 Out=0.0F;
     float4 MonoColor ={0.5F, 1.0F, 2.0F, 1.0F};
     float4 MonoWeight={0.8F, 0.9F, 1.0F, 0.0F};

 

     // 텍스처 좌표를 변화시키면서 인접한 픽셀을 샘플링
     // Gaussian 분포: exp (x*x/Delta) 값을 픽셀의 비중으로 설정
     for(int x=-4; x<=4; ++x)
     {
          float2 T = Tx0;
          
T.x += (2.f * x)/1024.f;      // 텍스처 좌표를 변화시킨다
          Out += tex2D( SampDif, T ) * exp( (-x*x)/8.f); // 픽셀을 샘플링하고 가우스 분포 함수로 구한 비중 값을 곱한 후 더한다.
     }

     Out = dot(Out, MonoWeight);  // 단색화
     Out *= MonoColor;    // 단색에 적용할 색상을 곱함


     Out *= 0.18F;     // 전체 명도를 낮춤
     Out.a = 1.0f;     // 불투명 픽셀로 설정

 

     return Out;
}

단색화와 흐림효과 2개를 동시에 적용한 셰이더 파일.

 

*Render()*

 

m_pdev->SetRenderState(D3DRS_LIGHTING, FALSE);
m_pdev->SetRenderState(D3DRS_CULLMODE, D3DCULL_NONE);

 

m_pdev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
m_pdev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);

 

m_pdev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_POINT);
m_pdev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_POINT);
m_pdev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_NONE);

 

m_pdev->SetSamplerState(0, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP);
m_pdev->SetSamplerState(0, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP);
m_pdev->SetSamplerState(0, D3DSAMP_ADDRESSW, D3DTADDRESS_CLAMP);

 

m_pdev->SetVertexDeclaration(m_pFVF);
m_pdev->SetPixelShader(m_pPs);

 

m_pdev->SetFVF(VtxRHWDUV1::FVF);
m_pdev->SetTexture(0, m_pTx);

 

m_pdev->DrawPrimitiveUP(D3DPT_TRIANGLEFAN, 2, m_pVtx, sizeof(VtxRHWDUV1));


m_pdev->SetVertexDeclaration(NULL);
m_pdev->SetPixelShader(NULL);

 

m_pdev->SetTexture(0, NULL);

m_pdev->SetPixelShader(NULL);

 

SetSamplerState() 함수를 사용하여 u,v,w 값 [0,1]의 범위를 벗어난 정규화 되지 않은 텍스처 좌표에대한 처리를 CLAMP 모드로 설정해주고 있다.

728x90
Posted by 정망스
,


맨 위로
홈으로 ▲위로 ▼아래로 ♥댓글쓰기 새로고침