정리/UNITY

Unity Shader (셰이더)

원클릭쓰리버그 2022. 3. 8. 12:22
728x90

셰이더

 

셰이더란 무엇인가? 

 

화면에 색을 칠한는 프로그램.

랜더링 파이프라인의 일부를 유연하게 변경하는 프로그램.

 

옛 신문 인쇄 작업 (분업 과정)

 

이처럼 셰이더도 여러 역할을 가진 셰이더가 있으며, 이 역할들을 최적화 및 변경하여 원하는 렌더링 효과를 낼 수 있다.

 

 

 

- 버텍스 셰이더 : 그려질 위치를 결정.

ex ) 실제로 보는 사과를 캔버스에 옮겨 스케치하는 작업.

-> 3차원의 랜더링 대상을 2차원 모니터에 옮겨지는 작업. 

 

- 프래그먼트 셰이더 : 칠할 색을 결정. 

ex) 실제 보는 사과에 색을 칠하는 작업

-> 3차원의 랜더링 대상을 모두 색칠 작업을 진행한 후, 2차원에 깊이에 따라 색을 결정하는 작업

 

-컴퓨트 셰이더 : 범용적인 문제에 GPU를 사용한다.

 색은 싱글 쓰레드로 처리하는 작업이 아닌, CPU에서 연산을 마친뒤 Task(일을 담은 큐)로 담아 GPU에서 차례차례 병렬작업을 실행한다. 

 

 

 

랜더링 파이프 라인

 

오브젝트를 화면에 표현하기 위한 일련의 작업들

 

 

위에서 보듯 그래픽스의 대부분의 작업은 CPU에서 일어난다. 이를 큐를 생성하여 Task를 담고 랜더링 파이프라인의 일련의 작업으로 전달하여 동시(병렬)에 랜더링 작업을 진행한다.

 

 CPU 디바이스 생성

 

- 현재 기기의 GPU를 표현하는 오브젝트

- 한번만 생성, 하나만 존재

- 커맨드 큐로부터 커맨드를 받아들여 실행

 

커맨드 큐 생성

 

- GPU에게 전달할 명령을 쌓아두는 곳

- 한번만 생성, 하나만 존재

- GPU 디바이스로 이어짐

 

 

 

 

렌더링 파이프라인 상태 생성

 

- 렌더링 파이프라인의 상태를 표현

- 렌더링 파이프라인에 사용할 속성들을 가짐

- 여러개 생성 가능

 

 

렌더링 파이프라인 상태

 

- 렌더링 파이프라인 서술자.

- 정점 서술자(Vertex Descriptor)

         - 정점의 구성을 묘사 : 정점을 조립할 때 사용

- 버텍스 셰이더, 프래그먼트 셰이더

- 블렌딩 설정, 기본 컬러 포맷 등

 

 

 

사용할 데이터 로드

 

- 사용할 데이터를 미리 메모리에 로드

- RAM(CPU)에서 VRAM(GPU)으로 전송될 데이터

 

 

점정 서술자 #0

버텍스 셰이더 - 위치 (0, 200, 0)

프래그먼트 셰이더 - 컬러 (1, 0, 0, 1) 

정점 서술자 #0, #1, #2 를 VRAM(GPU)에 데이터 버퍼형식을 통해 전송한다.

G

이를 정점 조립기를 통해 모니터에 화면을 변환해준다.

 

 

정점 조립

 

 

정점 버퍼의 요소들을 점정 구조체로 조립하는 과정.

 

정점 조립 과정은 유니티에서 알아서 처리됨. 고로 사용할 정점의 구성을 구조체로 선언하여 넣어주기면 하면 된다.

 

 

이를 버텍스 셰이더를 통해 변환한다.

- 정점을 입력받아 다른 형태의 정점으로 변환

- 3D 공간 상의 정점의 위치를 클립 공간으로 옮기는 것

 

 

오브젝트(모델) 공간

 

 

- 스스로가 세상의 중심

- 3D 모델의 피벗이 원점

- 모든 정점의 위치는 피벗에서 얼마나 떨어져 있냐로 결정됨.

 

위의 그림처럼 모델의 피벗위치의 기준으로 오브젝트의 정점들을 월드 상의 위치로 옮김

 

 

 

카메라 공간

 

- 카메라의 위치와 방향이 세상의 중심

- 같은 위치에 있는 물건도, 카메라의 위치에 따라 다르게 보임

- 매번 카메라의 위치와 회전을 고려하는 것보다, 카메라는 원점에 두고 오브젝트를 상대적으로 배치하는게 간결

 

투영 행렬

 

- 카메라 좌표계의 정점을 카메라의 시야를 기준으로 한 정점으로 옮김

- 카메라 좌표계의 정점들을 클립 공간으로 옮김

- 깊이와 원근감을 표현할 수 있게함

 

클립공간

 

- 카메라가 보는 영역

- 카메라 공간 : 카메라 위치를 원점으로 삼은 공간 -> 시야와 원근감이 없음

- 클립 공간 : 카메라의 시점을 반영한 공간 -> 시야와 원금감이 존재함.

- 카메라가 보는 영역(뷰포트)을 직육면체(or 큐브)로 압축한 공간

- X, Y의 범위 : (-1, 1)

- Z의 범위 : (0 ~ 1)

- 클립핑 : 클립 공간 외부의 폴리곤은 NDC로 변환되는 과정에서 잘려나감

 

_NDC(정규화된 기기 좌표계)

- 공간의 모든 X, Y, Z 범위가 (-1 ~ 1 또는 0 ~1) 정규화된 좌표계

- 다음 절차를 통해 생성

     - 클립 공간 외부의 좌표를 잘라냄

     - 동차좌표계(4차원)을 "w 나누기"를 실행하여 3차원으로 변환

- 클립 공간과 NDC는 종종 하나로 묶여 설명

     - 사실상 서로 같은 모습 : 둘다 뷰포트를 (2 X 2 X 1) 직육면체로 압축된 공간

     - 하지만 클립 공간은 계산 편의를 위해 4차원(동차 좌표계)에 존재

     - NDC는 (클립핑 실행후)원래 의도된 3차원 공간으로 변환된 것

 

 

 

 

 

 

 

래스터라이저

 

- 뷰포트 변환 : 클립공간(NDC) -> 스크린 공간

- 스캔 변환 : 프리미티브(삼각형)를 이루는 프래그먼트 생성

- 정점들의 값을 보간하여 프래그먼트의 속성 값들을 결정

 

뷰포트 변환

 

 

- 클립공간(NDC) -> 스크린 공간

     - 정규화된 공간 -> 스크린(윈도우 화면)에 맞춘 공간으로 변형

 

 

스캔 변환

 

 

 

 

- 정점 3개 -> 이것으로는 화면을 채울 수 없다.

- 정점으로 이루어진 프리미티브(삼각형)를 채우는 프래그먼트(픽셀 후보) 생성

 

 

보간

 

- 정점들 사이에 위치한 프래그먼트들의 속성 값을 보간을 통해 결정한다.

- 래스터라이저의 가장 중요한 일

- 래스터라이저는 정점 컬러 이외에, UV 좌표, 노말 등 다른 정점 속성들도 보간한다.

 

 

 

 

프래그먼트 셰이더

 - 전달받은 프래그먼트에 어떤 색을 채울지 결정

 - 래스터라이저가 전달한 프래그먼트 수만큼 실행

 

출력

- 프레임 버퍼에 쓰여질 컬러 값

- 깊이값(Z)

 

출력 병합

- 알파 (A)와 깊이 값(Z)을 통해 프래그먼트는 프레임 버퍼에 같은 위치의 픽셀과 경쟁하여 색을 정하거나 합침

 

 

 

 

참고

https://www.youtube.com/watch?v=RcRjIMTekgc&list=PLctzObGsrjfyWa2CaxGtxsLD-W5zYC2JJ&index=4 

 

'정리 > UNITY' 카테고리의 다른 글

Menu_UI 기능 구현  (0) 2022.04.25
IL2CPP  (0) 2022.03.19
효율적 UI_Component 바인딩  (0) 2022.03.08
Line Rederer (라인 렌더러)  (0) 2022.02.09
효과적인 에셋 관리를 위한 [Addressable Assets System]  (0) 2022.01.21