Post

Open Graphics Library 8

1. OpenGL 좌표계 변환 순서

  1. 모델 좌표(Model Coordinate)
  2. 세계 좌표(World Coordinate)
  3. 카메라 좌표(Eye Coordinate)
  4. 클립 좌표(Clip Coordinate)
  5. 정규화된 디바이스 좌표(Normalized Device Coordinate)
  6. 화면 좌표(Screen Coordinate)

카메라 좌표계 (Eye Coordinate System)

  • 카메라 중심을 원점(0, 0, 0)으로 설정.
  • 카메라 방향과 위치는 뷰 행렬(View Matrix)로 변환:
    • View Matrix는 월드 좌표를 카메라 기준 좌표로 변환하는 4x4 행렬.
    • 이동(Translation)과 회전(Rotation)을 조합하여 구성.

카메라 설정 예시:

  1. 카메라 위치: 예) (0, 0, 3)
  2. 카메라 방향: 기본적으로 -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-버퍼 알고리즘:

  1. 초기화:
    • 모든 픽셀의 Depth 값을 무한대로 설정.
  2. 거리 계산:
    • 각 픽셀의 깊이(Z 값)를 계산하여 Z-버퍼 값과 비교.
    • 새로운 깊이가 더 작으면(더 가까운 물체) 화면과 Z-버퍼를 업데이트.
  3. 결과 출력:
    • 가장 가까운 픽셀만 화면에 표시.
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 좌표계 변환

  1. 모델 좌표 → 월드 좌표 (Model → World)
  2. 월드 좌표 → 카메라 좌표 (World → Eye)
  3. 카메라 좌표 → 클립 좌표 (Eye → Clip)
  4. 클립 좌표 → 정규화된 디바이스 좌표 (Clip → Normalized Device Coordinates)
  5. 정규화된 디바이스 좌표 → 화면 좌표 (NDC → Screen)

클리핑(Clipping)

  • 시야 영역(View Volume) 바깥에 있는 기하 요소를 제거.
  • 클리핑 과정:
    1. 완전히 시야 영역 안에 있는 요소는 통과(Trivially Accept).
    2. 완전히 시야 영역 밖에 있는 요소는 제거(Trivially Reject).
    3. 일부만 겹치는 경우, 겹치는 부분만 남김.

Cohen-Sutherland 선분 클리핑 알고리즘

  • divide and conquer 전략
  • 2D 직사각형 시야 영역 기준으로 선분(Line)을 클리핑.
  • 선분의 각 끝점에 위치 코드(Outcode) 부여:
    • 4비트 코드: 위(T), 아래(B), 오른쪽(R), 왼쪽(L)을 나타냄.
    • 예: Outcode(1001)는 Top과 Left의 바깥.
알고리즘 단계:
  1. 선분 정의:
    • 선분의 두 끝점을 \( P_1 = (x_1, y_1) \), \( P_2 = (x_2, y_2) \)로 정의합니다.
  2. Outcode 계산:
    • 각 끝점의 Outcode를 계산합니다. Outcode는 4비트 코드로 \( TBRL \) (Top, Bottom, Right, Left) 비트를 나타냅니다.
    • 예를 들어, \( P_1 \)과 \( P_2 \)의 Outcode가 모두 0000이면 선분은 완전히 시야 영역 안에 있고, Trivially Accept 상태입니다.
  3. Trivially Accept:
    • 두 끝점의 Outcode가 모두 0000이면 해당 선분을 클리핑 없이 표시합니다.
  4. Trivially Reject:
    • 두 끝점의 Outcode에 동일 비트가 1이면, 해당 선분은 시야 영역 밖에 완전히 위치하므로 제거합니다.
    • 즉, \( \text{Outcode}_1 \& \text{Outcode}_2 \neq 0000 \)일 경우 선분을 제거합니다.
  5. Partial Clipping:
    • 선분이 Trivially Accept 또는 Trivially Reject 조건을 만족하지 않으면, 적어도 하나의 끝점이 시야 영역 밖에 있는 경우입니다.
    • 이 경우, 시야 영역(Viewing Area) 경계와 교차점을 계산하여 선분을 클리핑합니다.
    • 끝점 중 Outcode가 0이 아닌 점을 선택하여 경계와의 교차점(I)을 계산한 뒤, 이 교차점을 새 끝점으로 설정하고 과정을 반복합니다.
  6. 반복 과정:
    • 교차점 계산 후, 새로운 끝점으로 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.