'programming/etc'에 해당되는 글 11건

  1. 2024.07.26 Level of detail ( LOD )
  2. 2024.07.26 절두체 컬링 ( Frustum Culling )
  3. 2024.07.26 쿼드트리 ( QuadTree )
  4. 2024.07.26 OBB 충돌
  5. 2024.07.26 *좌표계*삼각비*내적-정사영
  6. 2024.07.26 카메라
  7. 2024.07.26 렌더링 파이프 라인
  8. 2024.07.26 평면방정식
  9. 2024.07.26 외적
  10. 2024.07.26 내적

* LOD 

- Level of detail의 약자로 정밀도를 표현한다.

- 정밀도를 나눠 렌더링연산을 줄여줄 수 있다.

 

* 정적LOD

- 정해진 정밀도에 따라 메쉬를 추가로 가지고있어 거리에 따라 출력 메쉬를 바꿔준다.

- 연산은 적지만 메모리 낭비가 심하다.

 

* 동적LOD

- 거리에따라 메쉬의 정밀도를 갱신해준다.

- 연산이 많지만 메모리 낭비가 심하지 않다.

 

* 거리기반 LOD

- terrain의 quadTree에선 거리기반기법으로 현재 노드와 카메라의 거리를 구한뒤

  인덱스의 top_left에 top_right까지의 길이를 비교해 표현 할 수 있다.

 

* Crack 현상

- 정밀도가 달라지는 구간에서 정점의 위치에때라 연결부위에 균열이 생기는 현상.

- 해결 방안으론 연결 부위에 삼각형을 땜질해 주어 자연스럽게 연결 될 수 있게 해준다.

'programming > etc' 카테고리의 다른 글

절두체 컬링 ( Frustum Culling )  (0) 2024.07.26
쿼드트리 ( QuadTree )  (0) 2024.07.26
OBB 충돌  (0) 2024.07.26
*좌표계*삼각비*내적-정사영  (0) 2024.07.26
카메라  (0) 2024.07.26
Posted by mainep
:

 

* 절두체

- 사각뿔의 머리를 잘라놓은 형태로

근평면, 원평면, 좌평면, 우평면, 상평면, 하평면으로 구성되어있다.

 

* 절두체 컬링

- 대상이 카메라 시야 내에 포함되는지를 판별하여 출력 여부를 결정한다.

- quadTree자료구조로 생성된 지형에 절두체 컬링을 적용시 렌더링되는 삼각형의 수를 줄일 수 있다.

 

* 절두체 생성

1. 근평면, 원평면, 좌평면, 우평면, 상평면, 하평면을 생성한다.

2. 카메라 시야를 기준으로 잡으므로

IDirect3DDevice9의 멤버함수 GetTransform을 이용해 view행렬와 projection행렬을 얻는다.

3.위에 생성한 1.의 각 정점에 view * proj의 역행렬을 곱해준다.

invMat = D3DXMatrixInverse achieve view * proj

transPos = D3DXVec3TransformCoord achieve origV, invMat

( invMat = 카메라의 world행렬이 된다. )

4. 각 평면을 구성하는 transPos정점들을 이용해 D3DXPLANE을 생성한다.

( 본 블로그의 direct3dx->학습->평면방정식 참고 )

http://blog.naver.com/krlaghgn/220711303047

평면방정식

*평면방정식-평면의 법선벡터와 원점간의 거리d를 알고있을때 점P가 평면에 대해 어느 위치에 있는지 판별...

blog.naver.com

 

* D3DXVec3TransformCoord

D3DXVECTOR3와 D3DXMATRIX구조체의 포인터를 인자로 받아

벡터를 1x4 행렬로 변환하여 행렬곱 연산을 마친 후 D3DXVECTOR3로

변환하여 반환한다. 1x4행렬로 변환과정에서 벡터의 w의 값은 1로 고정되며

행렬 위치값의 영향을 받는다.

 

* 절두체 컬링 적용

1. quadTree의 각 노드가 가지고있는 정점들과 절두체컬링을 위해 생성한 D3DXPLANE을

평면방정식의 연산으로 사용하여 절두체 내에 포함되는 여부를 판단하여

포함 여부를 저장한다.

2.지형의 인덱스를 생성할때 cullMode가 적용된 노드라면 자신을 포함해 하위노드도 그려줄 필요가 없으므로

하위노드 탐색과, 인덱스 생성을 건너뛴다.

 

'programming > etc' 카테고리의 다른 글

Level of detail ( LOD )  (0) 2024.07.26
쿼드트리 ( QuadTree )  (0) 2024.07.26
OBB 충돌  (0) 2024.07.26
*좌표계*삼각비*내적-정사영  (0) 2024.07.26
카메라  (0) 2024.07.26
Posted by mainep
:

 

*QuadTree

- 부모의 노드가 4개의 자식 노드를 가진다.

- terrain의 경우 index를 정보로 가진다.

- 1. 전체를 표현할 수 있는 4개의 index를 가진 root노드로 부터 자식 노드가 파생된다.

2. 자신을 4분할 하여 각각의 노드들이 자신의 index를 가진다.

3. 더이상 분할 할 수 없을 때 까지 2.를 재귀적으로 반복한다.

 

 

 

root노드로부터 4개의 자식노드가 파생되어 그 4개의 자식노드들도 각각 4개씩의 자식을 갖는다.

( 더이상 나눌 수 없을 때 까지 )

 

 

 

*terrain에 quadtree만 적용시 속도적 측면에서 오히려 손해를 본다.

quadtree를 활용하려면 FrustumCulling과 함께 사용하자.

 

*의사코드

class CTerQuadTree;

 

private:

//자식노드 멤버변수

CTerQuadTree* m_ar_pChild[4];

//index를 저장할 멤버변수

DWORD m_ar_dwCorner[4];

 

//root 생성 메소드

VOID CTerQuadTree::CreateQuadTree( int _iWidth, int _iHeight )

{

//root index 생성

DWORD ar_dwIndex[4] =

{

0,

_iWidth- 1,

_iWidth* ( _iHeight - 1 ),

_iWidth* _iHeight - 1

};

 

//m_ar_dwCorner배열에 index 저장

CTerQuadTree::_SetupIndex( ar_dwIndex[0], ar_dwIndex[1], ar_dwIndex[2], ar_dwIndex[3] );

 

//quadtree 생성

CTerQuadTree::_Build();

}

 

//build를 재귀호출하여 자식노드를 할당한다.

VOID CTerQuadTree::_Build()

{

//나눌 수 있다면 자식노드 build

if( CTerQuadTree::_SubDivide() )

{

for( int i = 0; i < 4; ++i )

m_ar_pChild[i]->_Build();

}

}

 

//더 나눌 수 있는지 검토한 후 index를 생성할수있는 데이터를 인자로 넘겨주며 자식 노드를 생성한다.

BOOL CTerQuadTree::_SubDivide()

{

if( ! CTerQuadTree::_IsDivisible() )

return FALSE;

 

DWORD dwTopCen, dwBotCen, dwLefCen, dwRigCen;

 

dwTopCen = ( m_ar_dwCorner[COR_TR] + m_ar_dwCorner[COR_TL] ) / 2;

dwBotCen = ( m_ar_dwCorner[COR_BR] + m_ar_dwCorner[COR_BL] ) / 2;

dwLefCen = ( m_ar_dwCorner[COR_TL] + m_ar_dwCorner[COR_BL] ) / 2;

dwRigCen = ( m_ar_dwCorner[COR_TR] + m_ar_dwCorner[COR_BR] ) / 2;

 

m_ar_pChild[COR_TL] = CTerQuadTree::_CreateChild( m_ar_dwCorner[COR_TL], dwTopCen, dwLefCen, m_dwCenter );

m_ar_pChild[COR_TR] = CTerQuadTree::_CreateChild( dwTopCen, m_ar_dwCorner[COR_TR], m_dwCenter, dwRigCen );

m_ar_pChild[COR_BL] = CTerQuadTree::_CreateChild( dwLefCen, m_dwCenter, m_ar_dwCorner[COR_BL], dwBotCen );

m_ar_pChild[COR_BR] = CTerQuadTree::_CreateChild( m_dwCenter, dwRigCen, dwBotCen, m_ar_dwCorner[COR_BR] );

 

 

return TRUE;

}

 

'programming > etc' 카테고리의 다른 글

Level of detail ( LOD )  (0) 2024.07.26
절두체 컬링 ( Frustum Culling )  (0) 2024.07.26
OBB 충돌  (0) 2024.07.26
*좌표계*삼각비*내적-정사영  (0) 2024.07.26
카메라  (0) 2024.07.26
Posted by mainep
:

OBB 충돌

programming/etc 2024. 7. 26. 10:25 |

 

(1).한 물체의 한 변을 축으로 정한다( 평행하는 변은 제외 )

(2).축 기준으로 축이된 변의 정사영의 길이, 축 기준으로 다른 물체의 변들(평행하는 변은 제외)의 정사영의 길이를 더한다.

(3-1).두 물체간의 거리 * 2 가 구한 모든 정사영의 길이의 합보다 작다면 두 물체는 충돌 가능성이 있다.

(3-1-1). 다른 변을 축으로 (1) ~ (3 -1) 을 반복한다.

(3-2).단 한 변이라도 두 물체간의 거리 * 2 가 구한 모든 정사영의 길이의 합보다 크다면 두 물체는 충돌 하지 않았다.

 

'programming > etc' 카테고리의 다른 글

절두체 컬링 ( Frustum Culling )  (0) 2024.07.26
쿼드트리 ( QuadTree )  (0) 2024.07.26
*좌표계*삼각비*내적-정사영  (0) 2024.07.26
카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
Posted by mainep
:

 

*좌표계

좌표계를 표현하는 방식으론

서로 직교하는 두 축과 두 축의 교첨인 원점으로 나타낸다.

가로축을 X축, 세로축을 Y축이라 칭하고 교점을 O라 표기한다.

이는 데카르트 좌표계로 "직교좌표계", "cartesian좌표계"라 칭하기도 한다.

 

임의 점 P를 표현하는 방법은 점P에서 수선의 발을 내렸을 때

X축과 직교하는 지점이 좌표x값

Y축과 직교하는 지점이 좌표y값 이다.

 

원점부터 임의 점 P까지의 위치를 구하는 방법으론 피타고라스의 정리를 이용할 수 있다.

x를 가로의 길이, y를 세로의 길이로 놓았을때 원점부터 점P까지의 거리는 빗변 a의 길이가 된다.

a^2 = x^2 + y^2

 

*삼각비

삼각비는 직각삼각형에서 세 변중 두 변의 길이의 비율을 나타낸다.

두 변사이에 끼인각 θ에 대해

 

cosθ = 밑변 / 빗변 = c / a

sinθ = 높이 / 빗변 = b / a

tanθ = 높이 / 밑변 = b / a

 

cosθ를 예로 들어

cosθ = c / a 는 cosθ * a = c x 1로 표기 할 수 있다.

비례식으로 나타내면

a : c = 1 : cosθ 가 된다.

이는 a를 100%라 놓았을 때 c는 a에 대해 cosθ만큼의 비율을 가진다.

 

*내적

-각도

내적은 여러 기하학적 의미를 표현 할 수 있는데

그중 하나는 두 단위 방향벡터 사이의 각을 구할 때 쓰인다.

 

먼저 A, B 두 방향벡터가 있을때 내적 공식을 보면

A ο B = ||A|| * ||B|| * cosθ 이다.

 

두 선분 사이의 끼인각은 선분의 길이의 영향을 받지 않으므로

A, B의 단위벡터인 A", B"을 내적하면

A" ο B" = 1 * 1 * cosθ

A" ο B" = cosθ 가 성립 된다.

 

위 식 양변에 역코사인을 취해주면

acos( A' ο B' ) = acos( cosθ )

acos( A' ο B' ) = θ

결론적으로 각도(radian)만 남게된다.

 

-정사영

또 하나는 두 방향벡터 A, B가 있을때 B벡터에 대한 A벡터의 정사영을 구할 수 있다.

공식을 다시 보면

A ο B = ||A|| * ||B|| * cosθ 이다.

이때 B벡터를 정규화 시킨 B" 과의 내적연산을 하면

A ο B" = ||A|| * 1 * cosθ 식이 나온다

이때 A ο B" 은 A벡터 머리에서 B벡터로 수선의 발을 내린 즉 정사영의 길이를 나타낸다.

B" 에 내적연산의 값을 곱해주게되면 수선의 발을 내려 B와 교차하는 지점의 좌표를 알 수 있다.

 

두 벡터 A, B

수선의 발 N

정사영 S

 

A = 파랑

B = 빨강

N = 하양

S = 검정

 

'programming > etc' 카테고리의 다른 글

쿼드트리 ( QuadTree )  (0) 2024.07.26
OBB 충돌  (0) 2024.07.26
카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
평면방정식  (0) 2024.07.26
Posted by mainep
:

카메라

programming/etc 2024. 7. 26. 10:22 |

 

*카메라

양의 z축을 바라보는 벡터를 기준으로 회전 행렬을 만들어준다.

회전시킨곳은 카메라의 방향벡터가 되고

회전행렬의 (3,1), (3,2), (3,3) 원소는 각 xyz의 값으로 좌표를 얻어낼 수 있다.

얻어낸 좌표는 방향벡터이므로 방향벡터에 -1을 곱하여 반전시켜준다.

이는 카메라의 위치가 된다.

카메라의 위치를 회전행렬의 위치성분을 나타내는 (4,1), (4,2), (4,3)에 넣어주고

카메라의 타겟이 될 대상의 이동행렬과 곱해준다 ( rotateMatrix * translationMatrix )

새로 얻어낸 행렬은 뷰 행렬의 역행렬이 되고 이행렬의 역행렬을 다시 구해주면 view행렬이 완성된다.

 

*회전행렬의 (3,1), (3,2), (3,3)

x축을 기준으로 @만큼 회전시킨 행렬의 3행성분과 y축을 기준으로 #만큼 회전시킨 행렬과의 연산된 값으로

x = (3,1) = sin@ * cos#

y = (3,2) = -cos@

z = (3,3) = sin@ * sin#

값을 가진다.

이 x,y,z성분은 양의 z축을 바라보는 벡터를 회전시킨 방향벡터가 된다.

 

양의 z축( 0.f, 0.f, 1.f )을 바라보는 zup벡터를 1x4행렬로 변환하여 w원소에 0을 넣고

회전행렬 matRo와 행렬x행렬 연산하여 3차원 벡터로 다시 변형 시켜준것과 같다.

 

*X축기준 회전행렬 matRoX

1 0 0 0

 

0 sin@ cos@ 0

 

0 -cos@ sin@ 0

 

0 0 0 1

 

*Y축기준 회전행렬 matRoY

sin@ 0 -cos@ 0

 

0 1 0 0

 

cos@ 0 sin@ 0

 

0 0 0 1

 

*matRoX(@) * matRoY(#) = matRoXY( 최종 회전 행렬 )

sin# 0 -cos# 0

 

 

cos@ sin@ cos@ 0

*cos# *sin#

 

 

sin@ -cos@ sin@ 0

*cos# *sin#

 

 

0 0 0 1

 

(3,1) = sin@ * cos#

(3,2) = -cos@

(3,3) = sin@ * sin#

 

*zup( 0, 0, 1, 0 ) * matRoXY

 

(1,1) = ( 0 * sin# ) + ( 0 * cos@ * cos# ) + ( 1 * sin@ * cos# ) + ( 0 * 0 ) = sin@ * cos#

(1,2) = ( 0 * 0 ) + ( 0 * sin@ ) + ( 1 * -cos@ ) + ( 0 * 0 ) = -cos@

(1,3) = ( 0 * -cos# ) + ( 0 * cos@ * sin# ) + ( 1 * sin@ * sin# ) + ( 0 * 0 )

(1,4) = ( 0 * 0 ) + ( 0 * 0 ) + ( 1 * 0 ) + ( 0 * 1 )

 

*

x = matRoXY(3,1) = ( zup * matRoXY )(1,1)

y = matRoXY(3,2) = ( zup * matRoXY )(1,2)

z = matRoXY(3,3) = ( zup * matRoXY )(1,3)

 

 

D3DXMATRIX matRo, matTrans;

D3DXMATRIX matRoX, matRoY;

D3DXMatrixRotationYawPitchRoll( &matRo, D3DXToRadian( m_fYaw ), D3DXToRadian( m_fPitch ), 0.f );

 

//D3DXMatrixRotationX( &matRoX, D3DXToRadian( m_fPitch ) );

//D3DXMatrixRotationY( &matRoY, D3DXToRadian( m_fYaw ) );

//matRo = matRoX * matRoY;

 

D3DXVECTOR3 vTrans( matRo._31, matRo._32, matRo._33 );

 

vTrans *= -1.f;

 

D3DXVec3Normalize( &vTrans, &vTrans );

 

vTrans *= ( 10.F + GETINST(CMouseMgr)->GetWheel() );

 

matRo._41 = vTrans.x;

matRo._42 = vTrans.y + 1.f;

matRo._43 = vTrans.z;

 

D3DXMatrixTranslation( &matTrans, m_vCurPos.x, m_vCurPos.y, m_vCurPos.z );

 

m_matView = matRo * matTrans;

 

D3DXMatrixInverse( &m_matView, NULL, &m_matView );

 

D3DDEVICE()->SetTransform( D3DTS_VIEW, &m_matView );

 

return &m_matView;

 

'programming > etc' 카테고리의 다른 글

OBB 충돌  (0) 2024.07.26
*좌표계*삼각비*내적-정사영  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
평면방정식  (0) 2024.07.26
외적  (0) 2024.07.26
Posted by mainep
:

 

*렌더링 파이프 라인

- 3D좌표를 2D로 표현하기위해

로컬정점->월드 공간->뷰 공간->투영 공간 -> 뷰 포트 -> 최종 좌표로 변환하는 방식

- Position = LocalPosition * WorldMatrix * ViewMatrix * ProjectionMatrix

- TransMatrix = WorldMatrix * ViewMatrix * ProjectionMatrix

Position = LocalPosition * TransMatrix

 

*로컬 정점( local vertex )

- 초기의 모델링시에 정의된 좌표

- 각자의 좌표계에의해 정점이 배치된다.

 

*월드 스페이스( world space )

- 공간상의 기준 좌표계( direct3d : 왼손좌표계, openGL : 오른손좌표계 )

- 스케일, 회전, 이동이 적용된다.

- 월드 스페이스로 변환( WorldPosition = LocalPosition * WorldMatrix )

- IDIRECT3DDEVICE9::SetTransform( D3DTS_WORLD, &WorldMatrix )

 

*뷰 스페이스( view space )

- 공간에 카메라를 두어 카메라의 위치에서 바라볼때 카메라의 위치를 좌표계로 사용한다.

- 뷰 스페이스로 변환( ViewPosition = WorldPostion * ViewMatrix )

- IDIRECT3DDEVICE9::SetTransform( D3DTS_VIEW, &ViewMatrix )

 

*투영 공간( projection space )

- 원근 투영

ㄴ 2D화면에 물체를 그릴때 입체감과 거리감을 표한하기위해

멀리 있는 물체는 작게, 가까이 있는 물체는 크게 그려준고

시야각에 때라 같은 위치에서 볼수있는 범위와 물체의 크기가 달라진다.

ㄴ D3DXMatrixPerspectiveFovLH()

- 직교 투영

ㄴ 위에서 아래에 있는 평면을 바라보는 방식이고 원근감이 없다.

ㄴ D3DXMatrixOrthoLH()

- 뷰 스페이스로 변환( ProjPosition = ViewPostion * ProjMatrix )

- DIRECT3DDEVICE9::SetTransform( D3DTS_PROJECTION, &ProjectionMatrix)

 

 

 

'programming > etc' 카테고리의 다른 글

*좌표계*삼각비*내적-정사영  (0) 2024.07.26
카메라  (0) 2024.07.26
평면방정식  (0) 2024.07.26
외적  (0) 2024.07.26
내적  (0) 2024.07.26
Posted by mainep
:

평면방정식

programming/etc 2024. 7. 26. 10:21 |

 

*평면방정식

-평면의 법선벡터와 원점간의 거리d를 알고있을때 점P가 평면에 대해 어느 위치에 있는지 판별 할 수 있다.

-법선벡터 N(a,b,c), 점P(x,y,z), 거리d

- ax + by + cz + d = 0

 

- 점P의 위치 판별

ax + by + cz + d = 0 일때 점P는 평면 위에 존재한다.

ax + by + cz + d > 0 일때 점P는 평면 앞에 존재한다.

ax + by + cz + d < 0 일때 점P는 평면 뒤에 존재한다.

( 법선벡터가 향하는 방향을 앞이라 둔다. )

 

-

사각형을 이루는 A,B,C,D 네 점이 있다.

 

A----B

l l

l l

C----D

 

이때

벡터 v1 = B - A

벡터 v2 = C - A

 

이 두 벡터를 외적연산하여 법선벡터 N을 구할 수 있다.

N.x = v1.y * v2.z - v1.z * v2.y

N.y = v1.z * v2.x - v1.x * v2.z

N.z = v1.x * v2.y - v1.y * v2.x

 

여기서 구한 N에 벡터를 구했던 A, B, C 세 점중 아무 한 점을 내적하면 d값을 구할 수 있다.

( 내적 값이 -d가 되므로 내적 * -1 = d )

 

* D3DXPlaneFromPoints()

- 세점을 인자로 평면 D3DXPLANE을 반환한다.

 

* D3DXPlaneDotCoord()

- D3DXPLANE과 D3DXVECTOR3를 인자로 받아 평면방정식을 연산한다.

- ax + by + cz + d의 값을 반환한다.

 

 

 

'programming > etc' 카테고리의 다른 글

카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
외적  (0) 2024.07.26
내적  (0) 2024.07.26
사업자등록 통신판매업  (0) 2024.07.26
Posted by mainep
:

외적

programming/etc 2024. 7. 26. 10:20 |

 

*외적 : 두 벡터에 대해 각각 직각을 이루는 벡터

 

벡터 : A, B, C

 

A * B

Cx = Ay * Bz - Az * By

Cy = Az * Bx - Ax * Bz

Cz = Ax * By - Ay * Bx

 

외적연산을 통해 구한 C벡터는

A, B와 직교한다.

 

*d3dx함수

 

D3DXVec3Cross()

 

'programming > etc' 카테고리의 다른 글

카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
평면방정식  (0) 2024.07.26
내적  (0) 2024.07.26
사업자등록 통신판매업  (0) 2024.07.26
Posted by mainep
:

내적

programming/etc 2024. 7. 26. 10:20 |

 

*내적 : 두 벡터의 같은 축의 원소끼리 곱하여 모두 더한 값

 

벡터 : A, B

내적 : dot

 

dot = Ax * Bx + Ay * By + Az * Bz

 

1.

내적(A, B) = llAll * llBll * cos@ 이다.

 

단위벡터인 A, B가 있을때

 

dot = cos@가 된다.

 

양번에 acos을 곱해주면 각도(호도법)만 남게 된다.

 

acos( dot ) = acos( cos@ )

acos( dot ) = @

 

2.

내적은 두 벡터의 크기의 곱을 속성으로 가지며 두 벡터 사이의 각을 판별할 수 있다.

dot = 0 일때 A,B는 직교한다.

dot > 0 일때 A,B 사이의 각은 예각이다.

dot < 0 일때 A,B 사이의 각은 둔각이다.

 

*d3dx함수

D3DXVec3Dot()

 

'programming > etc' 카테고리의 다른 글

카메라  (0) 2024.07.26
렌더링 파이프 라인  (0) 2024.07.26
평면방정식  (0) 2024.07.26
외적  (0) 2024.07.26
사업자등록 통신판매업  (0) 2024.07.26
Posted by mainep
: