OpenGL 쉐이더 프로그래밍 - Depth 처리 2

타입·2025년 7월 23일

컴퓨터 그래픽스

목록 보기
12/24

기하학 기초 개념

기하학 (Geometry)

기하학: n차원 공간에 대한 연구
컴퓨터 그래픽스에선 3차원 공간의 물체를 3D 오브젝트라 함

  • 스칼라 (Scalar)
    실수
  • 점 (Point)
    위치
  • 벡터 (Vector)
    방향을 가진 선분
  • 수학적 규칙
    vector = point - point
    point = point + vector
    vector = vector + vector

수학적 관점에서 공간

  • Vector Space
    스칼라와 벡터로 이루어진 수학적 공간
    스칼라-벡터 또는 벡터-벡터 연산이 가능
    Vector: Basis Vector의 합 (Basis Vector: 좌표 축 상의 unit vector)

  • Affine Space
    벡터 공간에 포인트 개념이 추가
    벡터-포인트 또는 포인트-포인트 연산이 가능

  • Euclidean Space
    어파인 공간에 거리 개념이 추가

직선의 방정식

p, q, r: 점
v: 벡터

p = q + αv (점 q에서 벡터 v방향으로 α만큼 이동한 점)
v = r - q (시작점 q에서 끝점 r로 향하는 벡터)
p = αr + (1-α)q [α: 0.0 ~ +1.0] (점 q와 점 r 사이의 선형 보간)

호모니지어스 좌표계

  • 좌표계
    basis 벡터의 조합
  • 프레임
    좌표계에 원점이 추가 (좌표계와 혼용 사용)
  • 좌표
    원점 + basis 벡터
    p = o + 2i + 3j + 4k = (0,0,0) + 2(1,0,0) + 3(0,1,0) + 4(0,0,1) = (2,3,4)

벡터를 행렬로 해석

좌표계를 바꾸어 새로운 basis 벡터로 표현 가능

좌표를 행렬로 해석

좌표 = 원점 + basis 벡터

p0: 원점
(보통 벡터에는 α, 좌표에는 λ를 사용)
4x4 행렬로 표현하고 빈 곳은 0으로 채움

  • 4x4 행렬
    호모지니어스 좌표계

  • 4차원 좌표
    (x, y, z, w)
    w가 0인 경우 벡터 (α1,α2,α3,0)
    w가 1인 경우 점 (λ1,λ2,λ3,1)

호모지니어스 좌표

벡터와 좌표를 한번에 표현 가능하여 일반화된 좌표라고 불림

  • 4차원 공간의 (x,y,z,w)
    w가 0인 경우 3차원 공간의 벡터 (x,y,z)
    w가 1인 경우 3차원 공간의 좌표 (x,y,z)
    w가 0이 아닌 경우 (x/w,y/w,z/w,1) -> (x,y,z) 형태의 3차원 좌표로 표현

  • 3D에서의 변환
    3차원에서의 (x,y,z) 좌표는 0이 아닌 w에 대해서 4차원 좌표 (wx,wy,wz,w)에 대응
    한 개의 3차원 좌표가 매우 많은 4차원 좌표에 대응됨

프리미티브 (Primitive)

  • glDrawArrays(mode)
    배열 정보에 따라 primitive를 렌더링
    mode에 따라 점/선분/삼각형 등 출력 가능

OpenGL Primitives

Primitive: 가장 단순한 요소

GL_POINTS / GL_LINES / GL_LINE_STRIP / GL_LINE_LOOP / GL_TRIANGLES ...

  • glPointSize()
    점의 크기를 지정
  • glLineWidth()
    선분의 폭을 지정

Triangle Primitive

  • Triangle Fan
    삼각형을 부채처럼 그리는 방식
    vertex0을 고정하여 새로 들어오는 vertex 2개를 이어 삼각형을 그림 (가장 오래된 vertex 1개를 버림)
    n+2개의 점으로 n개의 삼각형을 그릴 수 있어 기존 방식보다 3배 빠름

  • Triangle Strips
    길고 납작하게 그리는 방식
    새로 들어오는 vertex 3개를 이어 삼각형을 그림 (가장 오래된 vertex 1개를 버림)
    마찬가지로 n+2개의 점으로 n개의 삼각형을 그릴 수 있음

삼각형 근사

Triangle Strips는 랜드스케이프와 같은 지형을 그리는데 유리함

지형은 사각형 격자 모양에서 높이가 다르게 되어있음
사각형 한 줄씩 Triangle Strips 방식으로 쭉 그리면 됨
사각형은 대각선으로 분할하면 삼각형 두개가 나옴

복잡한 물체를 삼각형 형태로 근사시키는 걸 삼각형 근사라고 함

Quadrilateral Primitives

deprecated 됨

사각형은 단일 평면 위에 존재해야 하여 불안정한 기능
대신 2개의 삼각형으로 설정

  • bow-tie quarilateral
    좌표 순서가 꼬이면 나비넥타이 모양으로 나타남

피라미드 만들기

3차원 물체를 그리기 위해 3D 좌표계 설정 필요
OpenGL의 canonical view volume을 그대로 사용 (왼손 좌표계)

  • vertex 설정
    5개의 점으로 피라미드 모양 표현
	{ 0.0F, 0.5F, 0.0F, 1.0F }, // v0
	{ 0.5F, -0.3F, 0.0F, 1.0F }, // v1
	{ 0.0F, -0.3F, 0.5F, 1.0F }, // v2
	{ -0.5F, -0.3F, 0.0F, 1.0F }, // v3
	{ 0.0F, -0.3F, -0.5F, 1.0F }, // v4
  • 면 만들기
    오른손 법칙을 적용하여 vertex의 일관된 순서를 부여
    법선(normal vector)이 항상 밖으로 향하도록 지정
glm::vec4 vertPos[] = { // 6 * 3 = 18 vertices
	// face 0: v0-v1-v2
	{ 0.0F, 0.5F, 0.0F, 1.0F }, // v0
	{ 0.5F, -0.3F, 0.0F, 1.0F }, // v1
	{ 0.0F, -0.3F, 0.5F, 1.0F }, // v2
	// face 1: v0-v2-v3
	{ 0.0F, 0.5F, 0.0F, 1.0F }, // v0
	{ 0.0F, -0.3F, 0.5F, 1.0F }, // v2
	{ -0.5F, -0.3F, 0.0F, 1.0F }, // v3
	// face 2: v0-v3-v4
	{ 0.0F, 0.5F, 0.0F, 1.0F }, // v0
	{ -0.5F, -0.3F, 0.0F, 1.0F }, // v3
	{ 0.0F, -0.3F, -0.5F, 1.0F }, // v4
	// face 3: v0-v4-v1
	{ 0.0F, 0.5F, 0.0F, 1.0F }, // v0
	{ 0.0F, -0.3F, -0.5F, 1.0F }, // v4
	{ 0.5F, -0.3F, 0.0F, 1.0F }, // v1
	// face 4: v1-v4-v3
	{ 0.5F, -0.3F, 0.0F, 1.0F }, // v1
	{ 0.0F, -0.3F, -0.5F, 1.0F }, // v4
	{ -0.5F, -0.3F, 0.0F, 1.0F }, // v3
	// face 5: v1-v3-v2
	{ 0.5F, -0.3F, 0.0F, 1.0F }, // v1
	{ -0.5F, -0.3F, 0.0F, 1.0F }, // v3
	{ 0.0F, -0.3F, 0.5F, 1.0F }, // v2
};
  • 면 색상 정보
    삼각형을 구분하기 위해 색깔 구분 필요
glm::vec4 vertColor[] = {
	// face 0: red
	{ 1.0F, 0.3F, 0.3F, 1.0F, },
	{ 1.0F, 0.3F, 0.3F, 1.0F, },
	{ 1.0F, 0.3F, 0.3F, 1.0F, },
	// face 1: green
	{ 0.3F, 1.0F, 0.3F, 1.0F, },
	{ 0.3F, 1.0F, 0.3F, 1.0F, },
	{ 0.3F, 1.0F, 0.3F, 1.0F, },
	// face 2: blue
	{ 0.3F, 0.3F, 1.0F, 1.0F, },
	{ 0.3F, 0.3F, 1.0F, 1.0F, },
	{ 0.3F, 0.3F, 1.0F, 1.0F, },
	// face 3: yellow
	{ 1.0F, 1.0F, 0.3F, 1.0F, },
	{ 1.0F, 1.0F, 0.3F, 1.0F, },
	{ 1.0F, 1.0F, 0.3F, 1.0F, },
	// face 4: cyan
	{ 0.3F, 1.0F, 1.0F, 1.0F, },
	{ 0.3F, 1.0F, 1.0F, 1.0F, },
	{ 0.3F, 1.0F, 1.0F, 1.0F, },
	// face 5: cyan
	{ 0.3F, 1.0F, 1.0F, 1.0F, },
	{ 0.3F, 1.0F, 1.0F, 1.0F, },
	{ 0.3F, 1.0F, 1.0F, 1.0F, },
};
  • drawFunc()
    총 18개의 vertex shader가 동시에 실행
    6개의 삼각형을 만들어 매우 많은 fragment shader도 병렬처리
    Z-buffer와 framebuffer에 동시접근
void drawFunc(void) {
	glEnable(GL_DEPTH_TEST);
	glDepthRange(0.0F, 1.0F);
	glClearDepthf(1.0F);
    
	// clear in gray color
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    
	// provide the vertex attributes
	GLuint locPos = glGetAttribLocation(prog, "aPos");
	glEnableVertexAttribArray(locPos);
	glVertexAttribPointer(locPos, 4, GL_FLOAT, GL_FALSE, 0, glm::value_ptr(vertPos[0]));
	GLuint locColor = glGetAttribLocation(prog, "aColor");
	glEnableVertexAttribArray(locColor);
	glVertexAttribPointer(locColor, 4, GL_FLOAT, GL_FALSE, 0, glm::value_ptr(vertColor[0]));
    
	// draw the pyramid
	glDrawArrays(GL_TRIANGLES, 0, 18); // 18 vertices, 6개의 면
	// done
	glFinish();
}

앞쪽에 있는 면인 파란 면(face2)과 노란 면(face3)이 보임

백 페이스 컬링 (Back Face Culling)

Winding Rule

면의 바깥쪽을 정의하는 방법
어떤 면이 주어지면 이 면의 바깥쪽이 어딘지 설정해야함

  • normal vector
    법선 벡터
    삼각형에 수직인 벡터로 바깥쪽을 향함

  • normal vector 방향 설정
    오른손 법칙: CCW(Counter-Clockwise)

Front Face, Back Face

  • 카메라 방향 기준
    • Front Face: 카메라와 마주보는 면
    • Back Face: 카메라와 같은 방향인 면

Back Face Culling

3D 물체는 모든 방향을 면으로 둘러쌈
back face는 front face가 덮어씀

Primitive Assembly 시, 뒷면은 파이프라인에서 축출 (cull)

  • 장점
    평균적으로 face 개수의 절반이 cull됨 (속도 2배)
  • 못 쓰는 경우
    투명한 물체 (안쪽 면이 보여야 하는 상황)
    완전히 둘러싸이지 않은 물체
profile
주니어 언리얼 프로그래머

0개의 댓글