728x90

중요한 MonoBehaviour 스크립트 함수


Awake 

 - 스크립트가 실행될 때 한 번만 호출되는 함수

 - 주로 게임의 상태 값 또는 변수의 초기화에 사용된다.

 - start()가 호출되기 전에 맨 먼저 호출된다.

 - 스크립트가 비활성화돼 있어도 실행된다.

 - 코루틴으로 실행 불가.


Start

 - Update()가 호출되기 전에 한 번만 호출된다.

 - 스크립트가 활서화돼 있어야 실행된다.

 - 다른 스크립트의 모든 Awake()가 모두 다 실행된 이후에 실행된다.

 - 코루틴으로 실행 가능.


 Update

 - 프레임마다 호출되는 함수로 주로 게임의 핵심 로직을 작성한다.

 - 스크립트가 활성화돼 있어야 실행된다.

  

 LateUpdate

 - 모든 Update()가 호출되고 나서 한 번씩 호출된다.

 - 순차적으로 실행해야 하는 로직에 사용된다.

 - 카메라 이동 로직에 주로 사용하는 함수이다.

 - 스크립트가 활성화돼 있어야 실행된다.


 FixedUpdate

 - 주로 물리 엔진을 사용할 때 일정 시간 간격으로 힘을 가할 때 사용한다.

 - 발생하는 주기가 일정하다.

 

 OnEnable

 - 게임 오브젝트 또는 스크립트가 활성화됐을 때 호출된다.

 - 이벤트 연결 시 사용한다.

 - 코루틴으로 실행 불가.


 OnDisable

 - 게임 오브젝트 또는 스크립트가 비활성화됐을 때 호출된다.

 - 이벤트 연결이 종료될 때 사용한다.

 - 코루틴으로 실행 불가.


 OnGUI

 - 레거시 GUI 관련 함수를 사용할 때 사용한다.




내장 함수 호출 순서




728x90

'Game Programming > Unity' 카테고리의 다른 글

Unity - Logo Scene 만들기  (0) 2017.05.19
Unity - Public 필드 선언과 [SerializeField] 선언의 차이  (0) 2017.05.19
Unity - 최적화 방법  (0) 2017.05.18
Unity - NGUI 2.7.0 (무료버전)  (2) 2017.02.05
Unity - Unity Manual  (0) 2016.12.02
728x90

Vector란? 

  - 방향과 크기를 가지는 직선. 기준점이 존재하지 않는다.

  - Point와의 차이점 :

        Point : 원점으로 존재. 위치와 관계 있음.

        Vector : 원점의 존재가 의미 없음. 이동량과 관계 있음.

 

Vector의 크기.

  - Vector의 정규화에 쓰인다.

    벡터의 크기 V = sqrt(power(x,2)+power(y,2)+power(z,2))

 

    기존에 2차원에서는 빗변이 크기가 되어서 크기 = sqrt(밋변제곱+높이제곱)이었다.

    ex)

    V = (1,2,3)

    ||V|| <,여기서 || || 이 표시는 벡터의 크기라는 표시이다.

    ||V|| = 루트(1제곱+2제곱+3제곱).

    ||V|| = 루트(1+4+9).

    ||V|| = 루트(14).

    그러므로 벡터의 크기 ||V||는 루트14가 된다.


Vector의 정규화.(Nomalize)

  - Vector의 크기를 1로 만들어 주는 것을 말한다. (Unit Vector라고도 한다.)

  - 크기는 고려하지 않고, 방향만 알고 싶을 때 사용한다.

 

    1) 축을 정의할 때.

    2) 삼각형을 바라보는 방향만이 필요할 때.

    3) Vector의 크기를 원하는 대로 바꾸고 싶을 때.

  

    ex)

    ^

    V = ( x / ||V||, y / ||V||, z / ||V||)

 

Vector의 내적.(Dot Product)

  - Vector A = (a1, a2, a3)

  - Vector B = (b1, b2, b3)

  - A Dot B = (a1 * b1) + (a2 * b2) + (a3 * b3) (실수 값 하나가 나온다.)

  - theta = Vector A와 Vector B의 사이각.

  - A Dot B = ||A|| * ||B|| * cos(theta)

  - 내적은 어디에 사용되는가?

    1) 두 벡터의 사이 각을 구할 때.

    2) 점과 선 사이의 거리를 구할 때.

    3) 점과 평면 사이의 거리를 구할 때.

    4) 빛을 어느정도 받는지 계산할 때. (Normal과 Light와의 Dot Product) - 램버트 Light

    5) 하나의 Vector를 다른 벡터에 투영 시킬 때.

    6) 물체가 특정 평면에 부딪힌 후의 팅겨오르는 것을 계산하기 위한 반사 Vector를 구할 때.

 

Vector의 외적.(Cross Product)

  - Vector A = (a1, a2, a3)

  - Vector B = (b1, b2, b3)

  - A Cross B = ((a2 * b3 - a3 * b2), (a3 * b1 - a1 * b3), (a1 * b2 - a2 * a1)) (벡터가 나온다.)

  - 외적은 어디에 사용되는가?

    1) 두 벡터에 수직인 벡터를 만들어 낼 때.

    2) 두 벡터로 둘러싸인 평행 사변형의 면적을 구할 때.

    3) 어떤 점이 삼각형에 포함되어 있는가를 계산 할 때.


출처 : http://blog.naver.com/neoplog/50046003021

728x90

'Math' 카테고리의 다른 글

Math - 동차 좌표계  (0) 2017.04.20
Math - 점과 점 사이의 각도 구하기  (0) 2017.04.19
Math - 점과 점 사이의 거리 구하기  (0) 2017.04.19
Math - Radian과 Degree  (0) 2016.05.19
Math - 정반사 벡터  (0) 2016.03.07
728x90

위도, 경도 좌표계 - 도, 분, 초 좌표계 - UTM 좌표계 변환기


위도, 경도 좌표계 -> 도, 분, 초 좌표계 변환법


Ex) 37.12.3456 = 37.12/60 + 3456 / 3600


시간 계산 법과 비슷..



Gkdtcc.exe


728x90

'Dev Tool' 카테고리의 다른 글

Dev Tool - VMMap  (0) 2017.12.05
Dev Tool - Q-Dir  (0) 2017.09.08
Dev Tool - TortoiseSVN  (0) 2017.02.23
Dev Tool - depends22  (0) 2016.10.14
Dev Tool - Doxygen  (0) 2016.04.04
728x90

-동차좌표계란?

 3D에서는 기본적으로 3차원좌표계이지만 어떤 목적에 의해 4차원으로 확장할 수 있는데, 이것이 동차좌표계다. 기본적인 성분 x, y, z에 w가 추가된 것으로 3D상에서는 x/w, y/w, z/w로 나타낸다. 동차좌표계가 있음으로 오브젝트의 이동을 행렬간 곱셈으로 표현할 수도 있으며, 포인트(w=1)와 벡터(w=0)를 가늠할 수 있는 기준이 되기도 한다.


-동차좌표계와 투형행렬

 투영행렬에서, 카메라공간상에 존재하는 점과 카메라 위치 사이의 깊이값(z)를 최종 결과점의 x, y, z에 각각 곱해지고, w에 저장되는데 바로 이 과정이 동차좌표계를 위한 과정이다. 해당 좌표공간(카메라공간, 투영공간, 월드공간 등등)에서의 3D좌표를 얻어내려면 w로 나눠내면 된다. 여기서 월드공간, 카메라공간에서는 w값이 항상 1이기 때문에 아무런 변화가 없지만, 투영공간에서는 w값이 카메라공간에서의 카메라의 위치에서부터 정점사이의 거리이기 때문에 z값에 따라 정점의 위치와 크기가 변환되는 것임을 짐작할 수 있다. 따라서, 셰이더에서 다른 공간은 별로 상관없지만, 투영공간상에 존재하는 좌표를 다룰 경우 동차좌표계상에 존재하기 때문에 w성분으로 나누어 줘야한다. 

[푸의 요약]
 라이푸의 큐티한 그림을 보자면-_- 별은 카메라, 파란선은 전방 후방 클립면, 검은색네모는 버텍스이다. 만약 우리가 삼각형을 그
리기위해서 버텍스를 입력하게되면 w=1 이다. 이것이 버텍스셰이더를 거치게되면서 w값이 변경된다. 정확히 말하면 프로젝션매트릭스를 거치기전까지 w=1을 유지한다. 프로젝션을 거치게되면(버텍스셰이더를거치게되면) 현재 카메라좌표와 버텍스간의 거리값이(깊이값) w에 저장하게 되고 x,y,z에도 곱해진다. 이런 역할을 하는 것이바로 동차좌표계이다. w=1이라는 규약은 전후방 클립면의 총거리를 1로 나타내는 것이다. 그렇다면 동차 좌표계를 실제로 사용되는 곳이 어딜까? 셀프셰도우 구현시 DepthMap을 렌더타겟에 그리게 되는데 이때 버텍스셰이더에서 mal(vPOS, mWVP) 정보를 픽셀셰이더에서 이를 vPos.xyz / vPos.w로 나누어 3D상에서 실제좌표를(Z깊이값) 얻어 낼때 사용된다. 더 정확하게 말하면 버텍스셰이더에서 Z값이 아닌 픽셀셰이더를 거쳐 선형보간된 Z값을 얻을 때 사용되는 것이다. 그리고 디퍼드 구현때도 G-Buufer에서 Original View Position을 픽셀셰이더에서 재건할때도 동일한 원리를 적용하여 vPos.xyz / vPos.w값을 사용하게 된다. 




[References]
http://neosafe.blog.me/130044604300
http://ekessy.tistory.com/2


출처 : http://liepooh.egloos.com/521832#comment_521832

728x90

'Math' 카테고리의 다른 글

Math - 벡터 (Vector)  (0) 2017.04.20
Math - 점과 점 사이의 각도 구하기  (0) 2017.04.19
Math - 점과 점 사이의 거리 구하기  (0) 2017.04.19
Math - Radian과 Degree  (0) 2016.05.19
Math - 정반사 벡터  (0) 2016.03.07
728x90

오늘은 오랜만에 재미있는 3D 그래픽에 대해서 이야기 해보겠습니다. 주제는 Bloom Effect, 블룸 효과 입니다.

 

먼저 블룸 효과에 대해서 간단히 이해해 보자면,

 

빛을 받는 물체는 그 주위에 빛을 발산하는 것과 같은 효과를 나타냅니다.

 

뭐 예를 들면, 태양이 쩅쨍 찌는 사막의 한가운데서 먼 사막의 모래 산등성이를 바라보면 마치 모래 산등성이가 태양 빛을 반사하여 희미하게 빛을 발산하는 것처럼 보이는 풍경을 상상할 수 있을 겁니다.

 

상상이 안되면 사진을 직접 보죠. 뭐.  ( 진작에 보여줘야 했었나?  ㅋ )

 


 -블룸 효과 미적용(왼쪽) : 블룸 효과 적용(오른쪽)

이미지 출처: http://cafe.naver.com/raisonblue/379 -

 

 확연히 차이가 나죠. 오른쪽 같은 경우는 빛이 은은하게 퍼지는 것처럼 보입니다. 따라서 블룸 효과를 일종 뽀샤시 효과라고도 합니다만

뭐, 최근 3D 게임 같은 경우는 블룸 효과를 대부분 지원하고 엘더스크롤과 같은 좀 고급 게임은 HDR 효과까지 지원하더군요. HDR 효과는 여기서 논할 거리가 아니기에 생략.

 

자, 이제 블룸 효과가 뭔지는 이해했을 겁니다. 바로 구현 들어가 보죠 -_-

 

그런데 블룸 효과 적용에 앞서 2차원 가우스 분포 함수에 대해서 공부해 볼 필요가 있습니다. 가우스 분포 함수를 이용하면 번짐 효

과를 구현할 수 있기 때문이죠.

 

1차원 가우스 분포 함수의 식이 다음과 같으며

 


 

여기서 б 표준 편차입니다. 표준 편차가 1일 때 1차원 가우스 분포 함수는 다음과 같은 모양을 갖죠

 


 

그래프 모양을 봐선 뭔가 좌우 대칭으로 증폭이 됨을 알 수 있습니다. 즉, 빛을 발산하는 색상이 증폭이 되는 것이며 화면은 x, y 2차원이기 때문에 2차원 가우스 분포 함수를 사용해야 하는 것이죠.

 



-2차원 가우스 분포 함수 모양-

 

식에서 설명하지 않았던 상수 부분  W(x) = 

에서 x가 б 이면 pow( e, 0.5 ) 와 같은 결과므로 대략 0.6065가 됩니다. 이걸로 얻은  W(x)로 가중치 값을 얻어내서 이 값들을 마스크로 사용하면 됩니다.

 

б 는 우리가 임의의 상수로 결정할 수 있으며 그에 따른 마스크 값들을 미리 구해 놓을 수 있습니다.
 
그리고 마스크 적용은 픽셀 셰이더가 수행하면 되겠죠.
 
구현 방안에 있어선, 일단 기존 화면의 렌더링한 결과를 텍스처로 저장한 후에 이 텍스처를 새로 추가한 픽셀 셰이더를 적용하고 화면 사이즈에 맞게 뿌려주면 되는 것입니다. 렌더링 패스도 두 번에 끝나는 매우 저렴한 결과를 보여주죠. ㅋ_ㅋ
 
다음은 블룸 효과 헤더 부분입니다. 다이렉트 x를 사용합니다.

  class BloomResource {


  LPDIRECT3DSURFACE9       lpD3DSurface[ 2];                             //다이렉트 표면 장치
  LPDIRECT3DTEXTURE9       lpD3DTexture[ 2];                             //다이렉트 텍스처 장치

  LPDIRECT3DVERTEXBUFFER9     lpD3DTexVB;                           //텍스처 정점 버텍스

  LPD3DXEFFECT                         lpD3DEffect;                             //다이렉트 이펙트 핸들
  D3DXHANDLE                             hTechBloom;                          //셰이더 테크닉 핸들


  BOOL InitBloomResource( LPDIRECT3DDEVICE9  );
  VOID RenderBloom( LPDIRECT3DDEVICE9 );

 

 };

 
핵심은, 다이렉트 서피스와 텍스처를 각각 2개씩 생성한다는 점이고 그 이유는 다음과 같습니다. 원래 기본 화면을 렌더링 한 후, 그 렌더링 한 결과를 1번 서피스에 저장하고 1번 서피스에 블룸 효과를 적용시켜서 2번에 저장한 후에 1번과 2번의 화면을 합성시키는 것이죠.
따라서, 각 서피스의 결과를 저장할 텍스처 2개를 따로 생성하고 있으며 이 텍스처를 화면에 뿌려주어야 하기 때문에 텍스처 정점 버텍스 ( FVF = D3DFVF_XYZRHW | D3DFVF_TEX  ) 도 선언하고 있으며 픽셀 셰이더 적용을 위한 셰이더 테크닉 핸들도 선언하고 있습니다.
 
그럼, InitBloomResource 함수를 보도록 하죠.
 

 BOOL BloomResource ::InitBloomResource( LPDIRECT3DDEVICE9 lpD3DDevice ) {

 

 //스크린 사이즈 구하기 
 POINT ptScreen;
 ptScreen.x = d3ddm.Width;
 ptScreen.y = d3ddm.Height;

 

 //텍스처 정점 설정
 FTexture vertices[ 4 ];

 vertices[ 0 ].vPosition = D3DXVECTOR4(  ptScreen.x - 0.5f, ptScreen.y - 0.5f, 0, 1 );
 vertices[ 0 ].vTexCoord = D3DXVECTOR2( 1, 1 );
 vertices[ 1 ].vPosition = D3DXVECTOR4( -0.5f, ptScreen.y - 0.5f, 0, 1 );
 vertices[ 1 ].vTexCoord = D3DXVECTOR2( 0, 1 );
 vertices[ 2 ].vPosition = D3DXVECTOR4( -0.5f, -0.5f, 0, 1 );
 vertices[ 2 ].vTexCoord = D3DXVECTOR2( 0, 0 );
 vertices[ 3 ].vPosition = D3DXVECTOR4( ptScreen.x - 0.5f, -0.5f, 0, 1 );
 vertices[ 3 ].vTexCoord = D3DXVECTOR2( 1, 0 );

 

 HRESULT  hResult = E_FAIL;

 UINT vertexSize = sizeof( vertices );

 hResult = lpD3DDevice->CreateVertexBuffer(  vertexSize,  0,  vertices[ 0 ].FVF,  D3DPOOL_DEFAULT,   &lpD3DTexVB,  NULL );

 

 if( FAILED( hResult ) ) {   return FALSE; }

 

VOID* pVertices = NULL;

 

 hResult = lpD3DTexVB->Lock( 0, vertexSize, static_cast< VOID** >( &pVertices ), 0 );

 

 if( FAILED( hResult ) ) {  return FALSE; }

 

 memcpy( pVertices, vertices, vertexSize );

 

 lpD3DTexVB->Unlock();


 //셰이더 설정
 hResult = D3DXCreateEffectFromFile( lpD3DDevice,   szFileName,  NULL,  NULL,  D3DXSHADER_DEBUG,  NULL,  &lpD3DEffect,  NULL );

 

 hTechBloom = lpD3DEffect->GetTechniqueByName( "GOneBloom" );

 FLOAT fTexSizeX = static_cast< FLOAT >( ptScreen.x );
 FLOAT fTexSizeY = static_cast< FLOAT >( ptScreen.y );

 D3DXHANDLE hMapCX = lpD3DEffect->GetParameterByName( NULL, "map_cx" );
 lpD3DEffect->SetValue( hMapCX, &fTexSizeX, sizeof( FLOAT ) );

 D3DXHANDLE hMapCY = lpD3DEffect->GetParameterByName( NULL, "map_cy" );
 lpD3DEffect->SetValue( hMapCY, &fTexSizeY, sizeof( FLOAT ) );

 

//서피스 및 텍스처 생성 

D3DXCreateTexture(lpD3DDevice,  TEXTURE_SIZE, TEXTURE_SIZE, 0, D3DUSAGE_RENDERTARGET, d3ddm.Format, D3DPOOL_DEFAULT, &lpD3DTexture[ 0 ] );

lpD3DTexture[ 0 ]->GetSurfaceLevel( 0, &lpD3DSurface[ 0 ] );


 D3DXCreateTexture(lpD3DDevice,  ptScreen.x,  ptScreen.y, 0, D3DUSAGE_RENDERTARGET, d3ddm.Format,

D3DPOOL_DEFAULT, &lpD3DTexture[ 1 ] );

 lpD3DTexture[ 1 ]->GetSurfaceLevel( 0, &lpD3DSurface[ 1 ] );

 

return TRUE;

 

}//BOOL InitBloomResource( LPDIRECT3DDEVICE9 lpD3DDevice )

 
초기화 같은 경우는 별로 할 일이 없습니다.
 
화면 사이즈를 구하고
최종 결과물을 화면에 뿌려주기 위해 정점 설정을 하고 ( 시점 변환을 생략하기 위해서 RHW4 포멧의 정점임을 주의할 것! )
셰이더 설정을 하고
서피스와 텍스처를 생성합니다.
 
TEXTURE_SIZE 같은 경우는 실제 화면 해상도 이하로 잡으면 됩니다. 물론 클수록 화면 퀄리티가 좋으나 성능 부하가 커지겠죠. 저 같은 경우는 500 으로 설정했습니다.
 
그럼 렌더링 부분을 보도록 하죠.
 

 VOID BloomResource ::RenderBloom( LPDIRECT3DDEVICE9  lpD3DDevice ) {
 

 LPDIRECT3DSURFACE9       lpCurrentSurface = NULL;     //현재 화면 장치 
 lpD3DDevice->GetRenderTarget( 0, &lpCurrentSurface );
 lpD3DDevice->StretchRect(  lpCurrentSurface, NULL, lpD3DSurface[ 0 ], NULL, D3DTEXF_LINEAR );
 lpD3DDevice->StretchRect(  lpCurrentSurface, NULL, lpD3DSurface[ 1 ], NULL, D3DTEXF_LINEAR );

 lpD3DDevice->SetRenderTarget( 0, lpCurrentSurface );
 SAFE_RELEASE( lpCurrentSurface ); 

 

 lpD3DDevice->SetFVF( FTexture ::FVF );
 lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLORARG1, D3DTA_TEXTURE );
 lpD3DDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_SELECTARG1 );
 lpD3DDevice->SetTexture( 0, lpD3DTexture[ 0 ]);
 lpD3DDevice->SetTexture( 1, lpD3DTexture[ 1 ]);

 

 lpD3DEffect->SetTechnique( hTechBloom );

 UINT iPass = 0;

 lpD3DEffect->Begin( &iPass,  NULL  );
 lpD3DEffect->BeginPass( 0 );
 {
  lpD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB( 255, 255, 255 ), 1.0f, 0 );
  lpD3DDevice->SetStreamSource( 0, lpD3DTexVB, 0, sizeof( FTexture ) );
  lpD3DDevice->DrawPrimitive( D3DPT_TRIANGLEFAN, 0, 2 );
 
  lpD3DEffect->EndPass();

 }//IF

 

 lpD3DEffect->End();
 
 lpD3DDevice->SetTexture( 0, NULL );
 lpD3DDevice->SetTexture( 1, NULL );

}

 
빨간 색 소스 부분을 보시면 알겠지만 핵심은 기존의 렌더링한 결과를 0번 서피스에 저장한 후에 이를 블룸 효과 적용해서 1번 서피스에 그려줍니다. 그리곤 0번과 1번의 결과물을 합성해서 화면에 뿌려주면 되죠. 그래서 RenderBloom 함수 같은 경우는 기존 모델들을 그린 후에 최종적으로 호출해 주면 됩니다. 의사 코드는 다음과 같겠죠.
 

VOID Render() {

 

  LPDIRECT3DDEVICE9 lpD3DDevice = m_lpD3DDevice;

 

  //카메라 변환에 의한 뷰행렬 설정

 

  //기본 화면 렌더링 
  if( SUCCEEDED( lpD3DDevice->BeginScene() ) ) {

     lpD3DDevice->Clear( 0, NULL, D3DCLEAR_TARGET | D3DCLEAR_STENCIL | D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB( 

                                 255, 255, 255 ), 1.0f, 0 );


      //여기서 화면에 뿌리고 싶은 모델들 렌더링

 

      lpD3DDevice->EndScene();
  }//if

 

   //블룸 효과를 마지막 렌더링 m_pBloomResource는 BloomResource 객체.
   m_pBloomResource->RenderBloom( lpD3DDevice );

 

   lpD3DDevice->Present( NULL, NULL, m_hWnd, NULL );


}

 
의심할 여지가 없네요. 다음은 실제 블룸 효과 셰이더 소스를 보도록 합시다.
 

float map_cx;                        //텍스처 크기  가로 
float map_cy;                        //텍스처 크기  세로

sampler Sampler0;
sampler Sampler1;


float2 rcpres = { 0.0025, 0.0033333333333333333333333333333333 };

 

//텍스처 의 임의의 위치의 픽셀에 접근하귀 위한 좌표 ( 가로 방향)
float2 PixelKernelH[13] =
{
    { -6, 0 },    { -5, 0 },    { -4, 0 },    { -3, 0 },    { -2, 0 },    { -1, 0 },    {  0, 0 },    {  1, 0 },    {  2, 0 },    {  3, 0 },    {  4, 0 },
    {  5, 0 },    {  6, 0 },
};

 

//텍스처의 임의의 위치의 픽셀에 접근하기 위한 좌표 ( 세로 방향)

float2 PixelKernelV[13] =
{
    { 0, -6 },    { 0, -5 },    { 0, -4 },    { 0, -3 },    { 0, -2 },    { 0, -1 },    { 0,  0 },    { 0,  1 },    { 0,  2 },    { 0,  3 },    { 0,  4 },
    { 0,  5 },    { 0,  6 },
};

 

//미리 계산해 둔 가우스 필터의 마스크 값
float BlurWeights[13] = 
{
    0.002216,    0.008764,    0.026995,    0.064759,    0.120985,    0.176033,    0.199471,    0.176033,    0.120985,    0.064759,
    0.026995,    0.008764,    0.002216,

};

 

 

float4 PSBlur( float2 Tex : TEXCOORD ) : COLOR {

 

    float4 Color = tex2D( Sampler0, Tex );
    Color = pow( Color, 32 );
    
    float4 Color2 = -0.84;
 
    for( int index = 0; index < 13; ++index ) {
        Color2 += tex2D( Sampler0, Tex + ( PixelKernelH[ index ] * rcpres ) ) * BlurWeights[ index ];
        Color2 += tex2D( Sampler0, Tex + ( PixelKernelV[ index ] * rcpres ) ) * BlurWeights[ index ];

    }
    
    Color2 *= 0.48;
    
    float4 Color3 = tex2D( Sampler1, Tex );

    return  Color + Color2 + Color3;
    
}

 

 

technique GOneBloom {

    pass P0 {
        CullMode = CCW;      
        PixelShader = compile ps_3_0 PSBlur();
    
    }
}

 
상수는 가우스 분포 함수 부분에서 설명했던 것 처럼 미리 계산해 두었으며( 저는 레지던트 이블4 패치 파일에서 참고함) 좌, 우, 상, 하 방향에 대해 픽셀 6칸씩 블러 효과를 적용하고 있습니다. 그 부분이 바로 빨간색 소스 부분이며 최종적으로 기존 화면(Color3)과 블룸효과를 적용한 화면을(Color1 + Color2) 합성해서 화면에 뿌려주죠. 상수 값은 변화시켜보면서 적절한 결과물을 찾아보세요. 정답은 없으니깐.
 
다음은 블룸 효과 적용 전과 후의 결과 입니다.
 
 


-블룸 효과 적용 전-

 
 


-블룸 효과 적용 후-



출처 : http://blog.naver.com/hermet/58261272

728x90
728x90

두 점 사이의 각도 구하기


직각 삼각형의 두 변의 길이를 Rx, Ry라고 할 때 arc tangent를 사용하여 각도 Θ를 구하는 방법. (이 때 Θ는 Radian)




double GetAngle(Vector2 v1, Vector2 v2)

{

    double xdf = v2.x - v1.x;

    double ydf = v2.y - v1.y;


    double radian = atan2(ydf, xdf);

    double degree = radian * 57.3f;   // 57.3f == (180.0f / 3.141592f);


    return degree;

}



응용을 한다면 Pixel 셰이더에서 텍스처의 중심과 Pixel의 각도를 계산해서 아래와 같은 텍스처 애니메이션을 구현할 수 있습니다.





728x90

'Math' 카테고리의 다른 글

Math - 벡터 (Vector)  (0) 2017.04.20
Math - 동차 좌표계  (0) 2017.04.20
Math - 점과 점 사이의 거리 구하기  (0) 2017.04.19
Math - Radian과 Degree  (0) 2016.05.19
Math - 정반사 벡터  (0) 2016.03.07
728x90

두 점 사이의 거리는 피타고라스의 정리를 사용하여 구할 수 있다.


거리는  와 같이 제곱과 제곱근을 이용하여 구할 수 있다.



double GetDistance(Vector2 v1, Vector2 v2)

{

    double xdf = v2.x - v1.x;

    double ydf = v2.y - v1.y;


    return sqrt(pow(xdf, 2), pow(ydf, 2));

}



응용을 한다면 Pixel 셰이더에서 텍스처의 시작 위치와 Pixel의 위치를 계산해서 아래와 같은 텍스처 애니메이션을 구현할 수 있습니다.






728x90

'Math' 카테고리의 다른 글

Math - 동차 좌표계  (0) 2017.04.20
Math - 점과 점 사이의 각도 구하기  (0) 2017.04.19
Math - Radian과 Degree  (0) 2016.05.19
Math - 정반사 벡터  (0) 2016.03.07
Math - 피타고라스의 정리  (0) 2016.03.07
728x90



짐벌락이란?

= x축(Pitch) y축(Yaw) z축(Roll) 의 세축이 회전을 하다가

 특정 축이 특정각으로 회전을 했을 때 두 축이 겹쳐서 한축이 소실되는 현상을 말한다.

 


짐벌락 현상이 일어나는 이유!

      1. 오일러 각을 이용하기 때문에

      2. 오일러 각 회전을 순차적으로 하기 때문에

 


짐벌락 현상을 완벽하게 막을 방법?

 - 단정적으로 말하자면 존재하지 않다.

즉, 우리는 짐벌락현상을 최대한 피하는 방법 밖에 없다.

 


짐벌락 현상을 최대한 피하는 방법

     1. 오일러 각 회전의 순서를 바꾼다.

     2. Axis라는 임의의 축회전을 이용한다.

     3. 쿼터니언을 이용한다.

 


오일러 각 회전의 순서 바꾸기

- 잘 생각해보면 xyz 축회전에서 순서를 바꾸어 나타낼 수 있는 가지수는 총 6가지이다.

 

즉, xyz xzy yxz yzx zxy zyx 로 회전의 순서를 바꿀 수 있다.

 


여기서 잠깐! 순서를 정하는 방법을 알아보자.

     1. 가장 자주 회전하게 될 축을 먼저 회전한다.

     2. 가장 회전을 안하게 될 축을 2번째로 회전한다.

     3. 남은 축을 회전한다.

 

이유!? 순서에 의한 짐벌락 현상은 두번쨰 회전하는 축이 90도(-90도)를 회전하게 되면

 1번째 축과 3번째 축이 겹치면서 발생한다.

즉, 순서를 바꿔서 최대한 피하는 방법은 두번째 회전하는 축이 90도가 되지 않으면 된다.

다시 말해 두번째 회전하는 축이 회전을 자주하지 않으면 90도가 될 확률이 낮기에 위와같은 순서로 회전한다.

 

 

Axis라는 임의의 축회전을 이용하는 방법

- 사실 아직 정보가 부족하다. 우선적으로 알고 있는 정보는

'D3DXMatrixRotationAxis' 라는 함수 이다.

이 함수는 인자로 결과행렬을 내 뱉고, 임의의 축이 될 벡터와 회전을 먹일 회전행렬을 인자로 원한다.

 

여기까지가 필자가 알고있는 Axis에 대한 정보이다.

 

하지만 이 임의의 축회전도 문제가 있다.

 

임의의 축을 놓고 회전할 때 보간의 처리( 선형보간, 구면보간 )의 문제로 회전 시에 뚝뚝 끊겨보이게 된다.

 

이 문제를 해결할 쿼터니언이 존재한다.




출처 : http://blog.naver.com/qkfkf123/60170135935

728x90

+ Recent posts