센로그

7. Image Texturing 본문

게임/그래픽 프로그래밍

7. Image Texturing

seeyoun 2023. 5. 26. 23:57

◆ Pixel Shader

Raterizer에서, face 안쪽의 pixel 데이터를 생성해줬었다. 이제, 이 pixel들에 하나하나 접근할 수 있다!

 

Pixel Shader에서는 p1~pn까지 가득 채워져있는 pixel data들에 각각 접근해서 pixel의 색깔을 결정

pixel 정보들을 일렬로 세우고, 병렬 처리로 한번에 계산해서 pixel마다의 색깔을 결정하는 것. (병렬이므로, 인접한 애들에 대한 접근 까지는 못함)

 

이때 pixel의 색깔을 결정하는 중요한 두 가지 요소가 있다.

  • Texturing (벽지 바르기)
  • Lighting (빛 처리)

이번에는 그중 Texturing에 대해 다뤄볼 것이다.

 


◆ Texture Coordinate - Image texturing

texturing의 종류로는 여러 가지가 있는데, 그중에 우리는 image texturing에 대해 배울 것임

이게 젤 마니 쓰이고 대표적임 ㅇㅇ

 

image texturing은, 오브젝트의 표면에 벽지(이미지)를 펴서 바르는 느낌.

 

텍스처는 texel(texture element)들의 2D 배열로 표현된다.

 

텍셀(texel)이란 텍스처의 좌표. 위 그림의 한칸 한칸이 텍셀이다.

텍셀의 좌표는 저 한칸의 중심 점으로 정의된다. 좌측 상단 첫번째 텍셀의 좌표는 (0.5, 0.5)인 셈!

그 오른쪽 건 (1.5, 0.5)

 

 

 

(텍스처링을 위해서) "모델링 단계"에서 폴리곤 메쉬의 각 정점들에게 텍스처 좌표계 (s, t)를 할당한다. (vertex texture. u, v 라고도 함)

이후 rasterizer은 vertex별 텍스처 좌표들을 pixel들에 대해 interpolate한다. (rasterizer가 interpolate한다는 속성 중 하나임)

 

기억해야 할 것은, texture coordinate (s, t)는 0~1 사이의 값을 갖는다. normalize하면 다양한 크기에 대해 쉽게 재사용할 수 있어서 좋음!

 

 

원본 텍스처에서의 좌표를 (s`, t`)라 하고, vertex에 할당된 normalized된 텍스처 좌표를 pixel에 대해 interpolate한 좌표을 (s, t)라 한다.

사용할 때는, (s, t)에 texture의 (width, height)가 곱해진 (s`, t`)가 texture space에 projection된다. (원본 텍스처에서의 올바른 위치에 있는 (s`, t`) 값을 알아내서 잘 갖고온다.)

 

normalize 되어있기 때문에, (s, t)에 texture의 (width, height)를 곱해서 가져올 때 그림과 같이 정확히 중심에 있는 걸 가져오게 됨. texture의 크기에 영향을 받지 않기 위해 normalize 했다는 것~

 

 

더보기

네모 이미지가 들어왔을 때 네모 모양에 바를거면 어떻게 바를지는 이미 정해져있을 것임

그런데 만약에, 비율이 다른 애들이 들어오면 길게 늘어지거나 변형될 것임..

다른 메쉬에 대해선 어떡하지? 에 관한 것도 뒤에 나옴^^

 


◆ Surface Parameterization

 3D 표면2D 평면으로 펼쳐서 옮기는 것

그럼, 모델링 단계에서 폴리곤 메쉬의 texture coordinate를 어떻게 정할까?

 

텍스처 좌표들은 폴리곤 메쉬의 vertex들에 할당

surface parameterization은 그림과 같이 3D 표면을 2D 평면으로 펼쳐서 옮기는 것을 의미함.

예전엔 디자이너들이 이런걸 배웠으나 요새는 AI가 알아서 잘해줌

 

복잡한 폴리곤 메시는 일반적으로 여러 patch로 세분화되어, 각 patch는 개별적으로 parameterization됨 (예: 얼굴, 몸, 팔 등).

그림처럼 자동으로 머리 쪼개서 왼쪽 얼굴은 왼쪽에 펴고 오른쪽 얼굴은 오른쪽에 펴고.. 이런 짓을 함

이렇게 patch단위로 펴놓은 걸 chart라고 부름

그리고 얘네(chart)를 하나의 atlas로 묶어 관리하게 됨

 


◆ Texture Wrapping

Texture coordinate가 정해진 범위(보통 [0,1])를 초과하는 경우에, 어떻게 처리할지 결정하는 방법.

Texture coordinate (s, t)는 보통 0~1 사이 범위로 normalize 한다고 했음

근데 꼭 그렇지 않은 경우도 있음! 그렇게되면 width, height 곱했을 때 텍스처 크기의 범위를 넘어가기도 함. (범위를 넘어가서 없는 좌표를 가져오려고 한다는 것)

 

범위 초과하는 경우에, 어떻게 처리할지를 Wrapping mode에서 결정함.

  • Clamp-to-Edge: 범위를 벗어나는 좌표의 경우 edge color과 함께 렌더링하는 방법.  (c)
  • Repeat: 텍스처를 반복해서 채우는 방법 (d) 
  • Mirrored-Repaet: 텍스처를 뒤집거나 반사하며 반복해서 채우는 방법 (e), (f)

 


◆ Texture Filtering

스크린의 픽셀에, 텍스처의 텍셀대응시킬 때 사용하는 방법

Magnification(확대) vs Minification(축소)

Magnification Minification
pixel > texel

스크린 quad가 image texture보다 큰 경우를 의미함.

pixel 수가 texel 수보다 많아서, 확대해서 넣어야함.(magnified)
한 texel을 가지고 여러 개의 pixel을 칠해야 하는 상황!
pixel < texel

스크린 quad가 image texture보다 작은 경우를 의미함. 
pixel 수가 texel 수보다 적어서, 축소해서 넣어야 함.(minified)
pixel 하나 칠하려고 했더니 texel 여러개를 선택해야 하는 상황

 

이런 Texture Filtering을 하는 기법들이 몇 가지 있다.

  • Nearest point sampling
  • Bilinear interpolation

 

하나하나 살펴보자!

 


◆ Texture Filtering (Magnification) - Nearest point Sampling 

픽셀 블록 단위로, 가까운 점부터 샘플링하는 방법

그림과 같이 네개의 픽셀을 모아서 하나의 픽셀블록을 정의해보자. 

Magnification 시에, 한 픽셀블록이 한 텍셀에 매핑될 수 있다.

따라서 한 텍셀에서 다음 텍셀로 넘어갈 때, 인접한 픽셀 블록이 급격하게 변경될 수 있으며 이로인해 이미지가 깨짐(blocky).

 


◆ Texture Filtering (Magnification) - Bilinear interpolation

주변 점들로부터 interpolation해서 구현함

Magnification 시에, 주변 점들의 색상으로부터 보간해서 내 색상을 결정함. 한쪽 보간 한다음에 다른 한쪽 보간.

 

그림처럼, c1과 c2 보간해서 ca 정하고, c3와 c4 보간해서 cb 정한 후, 최종적으로 ca와 cb 보간해서 c를 정한다~

이런 방식을 Bilinear interpolation 이라고 함.

 

Bilinear interpolation은 nearest point sampling보다 선호되는데, 최종 결과가 비교적 덜 깨질(blocky) 뿐만 아니라,

그래픽 하드웨어가 일반적으로 Bilinear interpolation 최적화되어 있기 때문임.

 


Magnification시, Filtering 기법 비교

여러 Texture Filtering 기법 비교.

보통 Bilinear 사용함

 

인접한 애의 텍셀을 그대로 쓰는 Nearest 기법

반면에 주위 애들의 값을 보간해서 쓰는 Bilinear 기법

 


◆ Texture Filtering (Minification)

Minification 시에도 문제가 발생할 수 있다.

픽셀이 텍셀들을 sparse(드문드문)하게 projection 하기 때문에, 내가 원하는 텍셀을 선택하지 않을 수 있음.

그림처럼 드문드문하게 갖고오는 경우, 원본 이미지의 특징을 잃어버릴 수 있다.

이 문제를 aliasing(앨리어싱) 이라고 부름

 


◆ Texture Filtering (Minification) - Mipmap

미리 텍스처 크기를 조정해놓고 가져오는 필터링하는 것

텍셀의 개수가 픽셀보다 많은 상황에서 앨리어싱 문제가 발생함.

 

그래서 해결책: 내가 텍스처 크기를 먼저 조작한 다음에 가져오면 되겠구나! 하는 것

크기별로, 256x256, 128x128, ... 의 Mipmap을 먼저 만들어놓은 다음에 필터링함.

texture의 크기 자체를 줄여서(down-sampling) 픽셀 수와 텍셀 수가 유사하도록 하는 것임. 

 

원본 텍스처 해상도가 2ⁿx2ⁿ일 때, 2ⁿx2ⁿ부터 1x1까지 총 n+1개 level의 밉맵이 만들어짐

원본부터 차례대로 level 0, level 1, ... , level n이라 부름. (n번 줄인 느낌)

 

이때 filter의 level을 level of detail이라고 부르고, λ로 표현됨. pixel과 texel의 비율을 의미함.(뒤에 나옴)

우리는 λ를 이용해 어떤 level을 사용할 것인지 선택한다.

(텍셀 수가 픽셀 수와 비슷한 level의 밉맵을 찾아옴. 이는 level  λ에 해당함)

 

 

예시) level 1 

 

그림에서는 level 0에서 4개의 텍셀을 바인딩해 하나의 텍셀로 만들고, 이를 level 1 이라고 한 것.

 

pixel이 projection하는 texel 영역pixel footprint라고 부른다.

그림의 level 0 에서 pixel footprint는 2*2이고, level 1에서 pixel footprint는 1인 것.

그림의 level 1일 때는 한 pixel당 하나의 texel만 포함하므로, 문제없이 쓸 수 있는 것.

 

level 0(원본)에서 pixel footprint가 m*m 일 때(한 pixel당 m*m개의 texel을 포함할 때), λ log₂m으로 설정됨.

그림에서는 λ = log₂2 = 1이므로 level 1의 밉맵을 선택하면 됨.

 

 

예시) level 2

level 0에서 4개의 texel을 하나로 바인딩해서 level 1을 만들고,

level 1에서 다시 4개의 texel을 하나로 바인딩해서 level 2로 만든 것.

그림의 level 2일 때는 한 pixel당 하나의 texel만 포함하므로, 문제없이 쓸 수 있다.

 

여기서 pixel footprint = 16, m = 4, λ = log₂4 = 2이므로, level 2의 밉맵을 선택하면 됨.

 

 

예시) level 1.585

근데 사실 level이 정수로 떨어지는 애들은 별로 없음.

여기서 λ = log₂3 ≒ 1.585인데, level 1.585는 없자나! 어떡하지?

=> λ를 반올림한 레벨에서 가져오거나, 상한/하한 두 레벨을 보간(Bilinear interpolation)해서 가져오면 됨.

 

이런식으로 보간해서 가져올 수도 있음~

'게임 > 그래픽 프로그래밍' 카테고리의 다른 글

9. Output-Merging  (0) 2023.05.28
8. Lighting  (0) 2023.05.27
6. Rasterization  (0) 2023.05.13
5. Input Assembler & Vertex Processing(2)  (0) 2023.05.12
4. Input Assembler & Vertex Processing(1)  (4) 2023.05.12
Comments