Open Graphics Library 8
1. OpenGL 좌표계 변환 순서
- 모델 좌표(Model Coordinate)
- 세계 좌표(World Coordinate)
- 카메라 좌표(Eye Coordinate)
- 클립 좌표(Clip Coordinate)
- 정규화된 디바이스 좌표(Normalized Device Coordinate)
- 화면 좌표(Screen Coordinate)
카메라 좌표계 (Eye Coordinate System)
- 카메라 중심을 원점(0, 0, 0)으로 설정.
- 카메라 방향과 위치는
뷰 행렬(View Matrix)
로 변환:View Matrix
는 월드 좌표를 카메라 기준 좌표로 변환하는 4x4 행렬.- 이동(Translation)과 회전(Rotation)을 조합하여 구성.
카메라 설정 예시:
- 카메라 위치: 예) (0, 0, 3)
- 카메라 방향: 기본적으로 -z축 방향.
- 벡터 계산: (카메라가 보는 위치 - 카메라 위치)
LookAt 함수
- OpenGL에서 카메라 설정에 사용.
- 주요 파라미터:
eye
: 카메라 위치center
: 카메라가 보는 위치up
: 월드 좌표에서 위쪽 방향
1
gluLookAt(0.0, 0.0, 15.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);
2. Backface Culling (후면 제거)
- 카메라가 볼 수 없는 후면(Back Face)을 제거하여 렌더링 성능 향상.
- 후면 정의:
- 법선 벡터(Normal Vector)와 시점 벡터(View Vector) 사이의 각도가 90도 이상이면 후면.
- 수학적으로,
V • N < 0
이면 후면.
- OpenGL 설정:
GL_CULL_FACE
활성화.
법선 벡터와 방향 설정
- 법선 벡터 방향에 따라 앞면(Front Face)과 후면(Back Face)을 구분.
- OpenGL은 반시계 방향(CCW)을 기본적으로 앞면으로 간주.
- 구와 같은
닫힌 다각형
은viewer
의 위치와 상관 없이 안쪽 면(구의 내부)이 항상 back face이며,열린 다각형
은viewer
의 위치에 따라 face 구분이 된다.
3. 은면 제거 (Hidden Surface Removal)
- 후면 제거(Backface Culling):
- 카메라가 볼 수 없는 물체의 뒤쪽 면(Back Face)을 제거하여 렌더링 시간을 단축.
- 면의 법선 벡터(Normal Vector)가 카메라 방향과 반대일 경우 해당 면은 Back Face로 판단.
- Z-버퍼(Z-buffer)를 사용한 은면 제거:
- 깊이 정보를 저장하는 Depth Buffer를 이용하여 시점에서 가장 가까운 물체만 화면에 표시.
- 기본적으로, Z 값은 카메라와 물체 사이의 거리.
Z-버퍼 알고리즘:
- 초기화:
- 모든 픽셀의 Depth 값을 무한대로 설정.
- 거리 계산:
- 각 픽셀의 깊이(Z 값)를 계산하여 Z-버퍼 값과 비교.
- 새로운 깊이가 더 작으면(더 가까운 물체) 화면과 Z-버퍼를 업데이트.
- 결과 출력:
- 가장 가까운 픽셀만 화면에 표시.
1
2
3
4
5
6
7
8
9
10
11
// 1. Display 콜백 함수 (Default로는 disable되어있음)
glEnable(GL_DEPTH_TEST);
// 2. Display 콜백 함수 (buffer 지움)
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// bitwise OR 연산 사용
// 3. Main 함수
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH)
// 디스플레이 모드 설정 , color buffer= single, RGB, DEPTH buffer 사용
// bitwise OR 연산 사용
4. OpenGL 좌표계 변환
- 모델 좌표 → 월드 좌표 (Model → World)
- 월드 좌표 → 카메라 좌표 (World → Eye)
- 카메라 좌표 → 클립 좌표 (Eye → Clip)
- 클립 좌표 → 정규화된 디바이스 좌표 (Clip → Normalized Device Coordinates)
- 정규화된 디바이스 좌표 → 화면 좌표 (NDC → Screen)
클리핑(Clipping)
- 시야 영역(View Volume) 바깥에 있는 기하 요소를 제거.
- 클리핑 과정:
- 완전히 시야 영역 안에 있는 요소는 통과(Trivially Accept).
- 완전히 시야 영역 밖에 있는 요소는 제거(Trivially Reject).
- 일부만 겹치는 경우, 겹치는 부분만 남김.
Cohen-Sutherland 선분 클리핑 알고리즘
- divide and conquer 전략
- 2D 직사각형 시야 영역 기준으로 선분(Line)을 클리핑.
- 선분의 각 끝점에 위치 코드(Outcode) 부여:
- 4비트 코드: 위(T), 아래(B), 오른쪽(R), 왼쪽(L)을 나타냄.
- 예: Outcode(1001)는 Top과 Left의 바깥.
알고리즘 단계:
- 선분 정의:
- 선분의 두 끝점을 \( P_1 = (x_1, y_1) \), \( P_2 = (x_2, y_2) \)로 정의합니다.
- Outcode 계산:
- 각 끝점의 Outcode를 계산합니다. Outcode는 4비트 코드로 \( TBRL \) (Top, Bottom, Right, Left) 비트를 나타냅니다.
- 예를 들어, \( P_1 \)과 \( P_2 \)의 Outcode가 모두 0000이면 선분은 완전히 시야 영역 안에 있고, Trivially Accept 상태입니다.
- Trivially Accept:
- 두 끝점의 Outcode가 모두 0000이면 해당 선분을 클리핑 없이 표시합니다.
- Trivially Reject:
- 두 끝점의 Outcode에 동일 비트가 1이면, 해당 선분은 시야 영역 밖에 완전히 위치하므로 제거합니다.
- 즉, \( \text{Outcode}_1 \& \text{Outcode}_2 \neq 0000 \)일 경우 선분을 제거합니다.
- Partial Clipping:
- 선분이 Trivially Accept 또는 Trivially Reject 조건을 만족하지 않으면, 적어도 하나의 끝점이 시야 영역 밖에 있는 경우입니다.
- 이 경우, 시야 영역(Viewing Area) 경계와 교차점을 계산하여 선분을 클리핑합니다.
- 끝점 중 Outcode가 0이 아닌 점을 선택하여 경계와의 교차점(I)을 계산한 뒤, 이 교차점을 새 끝점으로 설정하고 과정을 반복합니다.
- 반복 과정:
- 교차점 계산 후, 새로운 끝점으로 Outcode를 다시 계산합니다.
- Trivially Accept 또는 Trivially Reject 상태가 될 때까지 과정을 반복합니다.
교차점 계산 예시:
선분의 끝점이 \((x_1, y_1)\)와 \((x_2, y_2)\)이고, 교차점이 \(x = x_{\text{min}}\) 경계와 만날 때: \[ y_c = y_1 + \frac{(x_{\text{min}} - x_1) \cdot (y_2 - y_1)}{x_2 - x_1} \] \[ x_c = x_{\text{min}} \]
3D 확장
- Cohen-Sutherland 알고리즘은 3D에서도 적용 가능.
- 4비트 Outcode 대신 6비트 Outcode를 사용:
- 추가된 비트는 앞뒤(Front, Back)를 나타냄.
This post is licensed under CC BY 4.0 by the author.