대표적인 OpenGL의 예제들을 살펴보면 아래와 같은 형태의 데이터를 Vertex Shader에 전달해준다.

std::vector<glm::vec2>	texCoord = {
	1.0f, 1.0f,
	1.0f, 0.0f,
	0.0f, 0.0f,
	0.0f, 1.0f
}

단순하게 생각해보면 Texture를 가져온 데이터를 좌표값을 나타냈을 때,  아래처럼 생겼기에 화면에 맞추는 작업이구나 하고 넘어갈 수 있다.

left  top(0.0f, 1.0f)
right top(1.0f, 1.0f)
left  bottom(0.0f, 0.0f)
right bottom(1.0f, 0.0f)

 

하지만, 이렇게 맞춰서 변환하는 과정은 생각보다 길고, 복잡할 수 있다.


Tangent Plane

구로 예시를 들어서 말하는 것으로 하겠습니다.

구에서 임의의 한 점과 맞닿는 평면, 이 평면이 Tangent Plane이다.
또한, 이런 평면을 좌표계 기준으로 잡는 공간을 Tangent Space라고 한다.


OpenGL에서 Tangent Plane이 이 어떻게 쓰일까?

OpenGL에서는 3개의 Vertex로 이루어진 삼각형을 하나의 Tangent Space에 존재한다고 생각한다.
그래서 주어진 Vertices와 Indices를 기준으로 Tangent Space를 계산한다.

주어진 Vertices와 Indices에 따라 2개의 벡터를 생성[$E_{1}, E_{2}$]하고,
주어진 Vertices에 대한 TexCoord에 따라 u와 v를 2개씩 생성[$\begin {bmatrix} u_1 & v_1 \\ u_2 & v_2 \end {bmatrix}$]한다.

여기서 우리는 Tangent, Bitangent Vector를 구할 수 있다.

$\begin {bmatrix} E_{1x} & E_{1y} & E_{1z} \\ E_{2x} & E_{2y} & E_{2z} \end {bmatrix} = \begin {bmatrix} u_1 & v_1 \\ u_2 & v_2 \end {bmatrix} \begin {bmatrix} T_x & T_y & T_z \\ B_x & B_y & B_z \end {bmatrix}$

사실 이렇게 보면 잘 모르겠어서 여러 가지로 생각해봤다.

  1. 이 변환 과정은 한 번에 진행되는 것이 아니다.
  2. 여러 가지 좌표계의 변환을 통해 생긴 것.
  3. 단순히 변환 행렬을 구한 것이지만 여러 개의 혼합된 버전일 것.
  4. 해당 좌표계로 이동, 좌표계 방향에 맞춰 회전, 해당 크기로 축소/확대의 혼합
  5. 3차원에서 2차원으로 변환하는 것이기에 이렇게 구하는 것.
  6. 한 번에 변환하는 행렬을 구한 것일 듯?

결국 구하고 싶은 행렬을 우린 TB Matrix라고 생각했을 때, 생성된 uv Matrix의 역행렬과 2개의 Vector로 이뤄진 Matrix를 곱하면 구할 수 있다.

$\begin {bmatrix} T_x & T_y & T_z \\ B_x & B_y & B_z \end {bmatrix} = \begin {bmatrix} u_1 & v_1 \\ u_2 & v_2 \end {bmatrix} ^{-1} \begin {bmatrix} E_{1x} & E_{1y} & E_{1z} \\ E_{2x} & E_{2y} & E_{2z} \end {bmatrix}$


하지만 이와 같은 과정에서 TBN의 Space에서 서로가 직교하지 않을 수 있다.
그렇기 때문에 그람-슈미트 직교화를 통해 각각의 벡터가 직교하도록 만든다.

위의 방법처럼 한 번에 구하는 것이 아니라, Tangent만 구해서 Shader로 넘겨준다.
이후 Shader에서 Normal과 Tangent를 Cross Product 하면 Bitangent의 값이 나온다.

'OpenGL' 카테고리의 다른 글

Normal Vector의 변환 행렬  (0) 2022.11.14
OpenGL[Lighting]  (0) 2022.10.18
OpenGL[Coordinate System]  (0) 2022.10.18
OpenGL[02](First Triangle)  (1) 2022.10.12
OpenGL[01](Shader)  (1) 2022.10.12

+ Recent posts