[DirectX11 Pipeline] 5. Pixel Shader

SYiee·2023년 8월 19일
0
post-thumbnail

💡 pipeline recap

8개의 정점을 가진 큐브 mesh를 렌더링할 때

  • VBV는 8개의 data가 들어가 있다.
  • IBV 삼각형 단위로 렌더링 할 것이니 3*8개의 데이터가 들어가 있다.

⇒ 이 정보가 Input Assembler로 들어온다. (여기서부터 GPU)

  • IA에서는 VBV와 IBV의 데이터를 이용해 삼각형 데이터로 자르면 되는 것을 VS로 알려준다.

  • VS에 정점이 일렬로 세워지고 이게 한 번에 동시에 parallel하게 넘어가는 것까지가 vs의 작업

    • object space → clip space (world, view, projection matrix) 바꾸어 준다.
  • Rasterizer
    버텍스 정보를 활용해 버텍스 내부의 픽셀을 생성을 한다.

  • Pixel Shader
    내부에 있는 p_1 ~ p_n까지의 픽셀 데이터가 가득 차 있다. PS에서는 이 픽셀 하나하나에 다 접근이 가능하다. 픽셀 정보를 쭉 읽어오고 (일렬로) 한 번에 병렬로 처리해 return을 얻게 된다.

    여기서도 내 인접해 있는 픽셀의 데이터에 접근이 불가능 하다.
    가장 큰 역할은 픽셀의 색상을 결정하는 것이다.
    색상에 영향을 주는 가장 큰 것이 Textureing & Lighting이다.


🖤 Pixel Shader

< Texture Coordinates >

📌 Image texturing

  • 텍스처에도 종류가 여러개가 있는데 그 중에서도 이미지 텍스처링에 대해 살펴 보도록 한다.
  • 가장 많이 쓰이기도 하고 나머지도 대부분 비슷하다.
  • 벽지를 펴서 바르는 것과 같은 효과이다.
  • 보통 a 2D array of texels로 표현된다.
    컴퓨터 입장에서 이미지는 2차원 array 에 칼라 값이 들어가 있는 형태로 표현이 된다.
  • 보통 이것의 센터 좌표를 기준으로 결정이 된다.

모델링 스텝에 texture coordinate가 적용이 된다.

  • Rasterizer 단계에서 3개 정점의 정보를 barycenteratic coordinate를 이용해 위치, 노말, uv 정보들이 바뀌었었다. 이 때 texture coordinate도 결정이 된다.

  • 정규화된 텍스처 좌표 (s, t)는 텍스처 공간으로 투영된다.
    (s’, t’) = (s, t) · (텍스처의 너비, 텍스처의 높이)
    → nomalized 된 값으로 0-1 사이 값을 가진다
    → nomal된 값에 이미지의 width와 height를 곱해주면 원본 값이 나온다

    • (s’, t’) : 원본 텍스터에서의 texel의 coordinate
    • (s, t) : nomalized된 텍스터 상에서의 coordinate

texture coordinate를 nomalized된 값을 쓰는 이유

  • 텍스처의 크기에 영향을 받지 않기 위해서
  • 해상도가 바뀌면 중심 좌표가 계속 바뀌게 된다. 그래서 nomalized 된 닶을 사용한다.

텍스처 좌표는 모델링 될 때 정해진다.

즉, 텍스처를 어떻게 바르게 할지는 이미 결정되어 있다. 그래서 해상도가 다른 것이 들어와도 nomalized된 값을 쓴다고 했다. 이미지 크기를 모델링 한 사람이 원하는 정도로 맞춰주지 않으면 발랐을 때 비율이 달라지는 등의 현상이 일어나게 된다.
이는 모델링 단계에서 이미 텍스터 좌표가 결정되어 있는 상태에서 비율을 신경 쓰지 않고 넣어서 생기는 일이다.

Surface Parameterization

📌 Parameterization

  • 텍스처 좌표는 다각형 메시의 정점에 할당된다.
  • 펼쳐서 좌표를 구하는 방법이 있다.
  • 메쉬를 평면에 펼치는 행위가 수반된다.

Patch, chart, and atlas

메쉬를 쪼개서 하나하나를 chart 각각 만들고 나서 하나의 atlas로 묶는다. 데이터가 여러개 있으면 불편하니까.

  • 복잡한 다각형 메시는 일반적으로 패치로 세분화되어 각각 펼쳐진다, (예: 얼굴, 몸, 팔 등).
  • 각 패치는 펼쳐지고 매개화된다. 그런 다음 디자이너는 각 패치에 대해 이미지를 그린다. 패치용 이미지는 일반적으로 차트(chart)라고도 한다.
  • 여러 차트는 일반적으로 텍스처에 패킹되어 배치되며, 이는 종종 아틀라스(atlas)라고도 한다.

📌 Texture Wrapping

보통 0-1사이로 노멀라이즈 한다고 했는데 항상 그렇지만은 않다.texture wrapping mode가 이것을 핸들링 한다.

  • Clamp-to-Edge: 범위를 벗어난 좌표는 가장자리 색상으로 렌더링됩니다.
  • Repeat: 텍스처가 정수 점에서마다 타일로 반복됩니다.
  • Mirrored-Repeat: 텍스처가 정수 점에서마다 거울이나 반사로 반복됩니다.


< Texture Filtering >

텍스처를 그냥 박으면 문제가 생길 때가 있다.

  • (s', t') are floating-point values in almost all cases.
    스크린에 쿼드를 그리는데 실제 이미지 사이즈보다 큰 경우

  • 사진 찍었는데 저해상도 저장하려고 용량을 낮춰서 저장했다가 확대하면 블락블락 처럼 보이는것 → magnification

  • 픽셀은 스크린에서 색을 보여주고 하는 것, 텍셀은 텍스처 하나하나의 데이터를 의미

  • pixel > texel
    → 1개의 texel로 4개의 pixel을 칠하는 상황 발생

📌 Magnification

rasterizer를 통과하여 생긴 pixel(fragment)이 texture map의 texel보다 많은 경우

  • 하나의 texel(RGB) 값이 여러 pixel을 표현
  • 하나의 texel(RGB) 값으로 pixel을 표현하게 되면 아래 그림 기준으로 4 pixel이 같은 색상이 되어 사각형의 block이 형성되어 영상의 품질에 안 좋은 영향을 끼칠 것이다.
    → Magnification 상황에서 가까운 texel 값을 그대로 취하는 것을 Nearest point sampling

Filtering for Magnification

Option 1: Nearest point sampling

  • 여러 개의 픽셀 블록은 단일 텍셀에 매핑될 수 있다.
  • 결과적으로, 인접한 픽셀 블록은 서로 다른 텍셀로 급격하게 변경될 수 있으며, 블록 형태의 이미지가 종종 생성된다.

Option 2: Bilinear interpolation

  • 주변에 4개를 가지고 오고
  • bilinear interpolation을 사용하면 아래와 같이 texel값들 사이의 값으로 각 pixel을 채울 수 있다.
  • 조금더 smooth하게 된다.
  • 수식적을 조금 더 복잡하기 때문에 nearest 방식보다 좀 느리다고 생각될 수 있지만 실제로는 더 빠르다
    → design 자체가 interpolation을 잘하게 되어 있다.

💡 가장 가까운 점 샘플링이 선호되는 이유는 블록 형태의 이미지 문제가 최종 결과에 훨씬 적게 영향을 미치기 때문 뿐만 아니라 그래픽 하드웨어가 일반적으로 이중 선형 보간을 최적화하도록 설계되어 있기 때문이다.

Visualization of filtering algorithms

  • Bidubic : 조금 더 자연스럽게 뭉개진다.

⇒ Magnification 에서는 인터폴레이션하면 문제가 대부분 적당히 잘 해결된다.

📌 Minification

rasterizer를 통과하여 생긴 texture map의 texelpixel(fragment)보다 많은 경우

실제로 이걸로 인해 발생하는 문제가 조금 더 크다.

  • 예시에서처럼 체크무니 텍스처를 조금더 작은 사이즈에 매핑했는데 전부 검정 전부 흰색으로 되는 경우가 생긴다.

aliasing problem

Mipmap

  • 텍셀의 개수가 픽셀보다 많은 경우
  • 해결책으로 텍스처링을 하기 전에 텍스처의 크기를 줄여버렸다.
  • 수학적으로 2배를 넘지 않는 다는 것이 정의되어 있어서 생각보다 메모리를 그렇게 많이 잡아먹지 않는다.

픽셀은 텍스처 공간에서 큰 점프를 하며, 많은 텍셀이 텍스처링에 관여하지 않게 된다.

  • 텍셀 수를 가능한 한 픽셀 수에 가깝게 줄이는 간단한 해결책을 채택할 수 있다. 텍스처 크기를 줄이기 위해 다운샘플링이 사용된다.
  • 2l×2l 해상도의 원래 텍스처가 주어지면, 원래 텍스처가 레벨 0에 위치한 (l+1) 레벨의 피라미드가 구성된다.
  • 이 피라미드를 mipmap이라고 합니다.
  • 필터링할 레벨은 level of detail 이라고 하며, λ로 표시된다. 수에 가까운 텍셀 수를 갖는 레벨을 찾을 것이다.

level1 ex

사각형을 항상 top down 뷰로 보지 않고 좀 측면에서 보기도 한다. 이러면 이 한 픽셀이 차지하는 영역이 달라진다. 카메라와 얼마나 가깝고 각도에 따라.

  • 픽셀이 1개인데 텍셀이 4개이다.
    → 다음 레벨로 갔더니 픽셀 1개에서 텍셀 1개이다.
    → level1에서 가지고 오게 된다.

  • λ = level
    • pixel의 footprint가 8x8일때 ⇒ 2^3 ⇒ 로그 취하면 level =3
      → 이걸 이용해 몇번째 level에서 가지고 와야하는지 파악 가능
픽셀의 텍스처 공간으로의 투영은 점이 아닌 (s', t')를 중심으로 하는 영역이다.
이 투영된 영역을 픽셀의 발자국(footprint)이라고 한다.

level2 ex

Level 1.585 example

  • Option 1: We can take the nearest level. l = round(λ).
    → 그냥 round 하기

  • Option 2: we can take both of levels and linearly interpolate the filtering results. (bilinear interpolation)
    → 인터폴레이션 하기

💡 텍스처를 가지고 올 때도 필터링 기법(nearlist, bilenear , …)을 정의해야 한다.
근데 실제로 입힐 때 minmap을 결정할 때도 interpolation을 한다.
즉, 2번 한다.


🖇 Reference

해당 포스트는 강형엽 교수님게임그래픽프로그래밍 [GGP-23-1] 수업을 수강하고 정리한 내용입니다. 잘못된 내용이 있다면 댓글로 알려주시면 감사하겠습니다😊

profile
게임 개발자

0개의 댓글