본문 바로가기
개발 (Game)/Unity

[Shader] Rendering Pipeline 공부 시작

by 진현개발일기 2021. 9. 1.

[ 2021. 09. 01, Wed ]

 

매우 흥미로운 개념을 발견해서 공부일지를 이제 단계적으로 올릴려고한다.

 

참고자료

: https://www.youtube.com/watch?v=0XJWdNFnq50&list=RDCMUCRWq4MPqifkmT2GyL2d2ZAQ&index=3 

 

 

최근에 쉐이더에 관심이 크게 생겼었다. 

 

기술 면접을 보면서 렌더링 파이프라인에 관한 질문이 나온 적이 있는데 생소한 개념이라서 질문에 답을 못하였지만 호기심이 생겨서 찾아보게 되었다. 그래픽 관련된 개념이라는데 매우 재밌어보였고 공부 하고싶다는 생각이 들어서 면접 결과를 떠나 잘 보러간 것 같다는 생각이 들었다.

 

그래픽 부분을 코드로 제어해서 유니티로도 언리얼과 같은 그래픽을 낼 수 있다는 것이 매우 흥미로웠기에 꼭 공부를 해서 외관적으로도 멋있는 게임을 만들고 싶다는 생각이 들었다.

 

언제나 처음에는 어렵게 느껴지는 법이다. ScriptableObject도 그랬듯이 새로운 개념이 어려워 보일 수 있겠지만 공부를 계속 하다보면 분명히 언젠가는 아무리 어렵다한들 무조건 터득하게된다.

 

이러한 기술들이 왜 있겠는가 더 편리하고 깔끔하게 멋있는 작업물을 실용적으로 만들기 위해서이다. 

 

다른 자료들도 찾아보니깐 나중에 수학적인 내용들이 많이 들어간다는데 오히려 잘되었다 수학 공부 해야하는 것을 여태 생각만하다 이번에 좋은 기회를 잡은 것 같다.

 

▼ 어제 공부하면서 메모장에 정리한 내용들이다.

=======================================

 Rendering Pipeline
- 보이지 않는 공간에 존재하는 오브젝트들이 화면에 그려지기까지의 과정이다.

 

  (위 개념만 봤을 때 이해가 안갔는데 영상 중 '그림자 연극'을 예를 듣고 이해가 되었다.

  우리가 3D 공간의 오브젝트들을 다루고있지만 실제 우리가 보고있는 화면은 노트북 혹은 컴퓨터의 2D스크린 인 것이다. 정답인지는 모르겠지만 대충 3D 형태의 오브젝트들을 2D 화면 위에 그려주는 그래픽 작업이라고 생각하면 될 것 같다.)

 

 과 정 ■

1. 렌더링 파이프라인을 구상하기전에는 ' 그래픽스 API 초기화 '를 해야한다.
  
   [그래픽스 API 초기화]란 
   GPU에게 명령을 전달할 수단을 만들고 사용할 쉐이더를 셋업하는 단계이다.
   + 그래픽스 API 단계는 대부분 CPU에서 일어난다.

순서 : GPU 디바이스 한 번만 생성 
        -> 커맨드 큐 한 번만 생성 (커맨드 큐가 필요한 이유는 CPU와 GPU는 서로 통신하지 않기 때문)
        -> CPU에서 실행할 명령들을 담아 놓은 커맨드 버퍼를 커맨드 큐에 계속 쌓게 된다.
        -> 커맨드 큐에 쌓인 버퍼들은 먼저 쌓인 순서대로(Queue) GPU가 가능할 때 마다 계속해서 떼간다.
        -> 커맨드 버퍼에 명령들은 GPU로 넘어갈 때 하드웨어 언어로 번역되어서 전달된다.
        -> 위 과정을 반복하면서 CPU는 계속 커맨드 큐에서 커맨드 버퍼를 쌓게된다.
        -> '렌더링 파이프라인 상태' 오브젝트들 생성 
        
        [렌더링 파이프라인 상태]
         구성 : 렌더링 파이프라인 서술자 
                 위 안에 1. 정점 서술자(Vertext Descriptor) : 정점의 구성을 묘사 -> 정점을 조립할 때 사용
                            2. 버텍스 셰이더
                            3. 프래그먼트 셰이더
                            4. 블렌딩 설정
                            5. 기본 컬러 포맷이 있음   

       ※ 주의할 점은
           '위치'는 정점의 속성일 뿐, 정점 자체가 위치라고 생각하면 안된다. (정점!=위치)

          정점(구조체 타입)이 가지고 있는 데이터
          1. 위치
          2. 컬러
          3. 노말
          4. 텍스처 좌표
          5. 사용자 정의 속성 등 


2. 그래픽스 API초기화를 통해 필요한 에셋들을 메모리에 미리 로드하는 과정을 끝내는데 이는 우리가 유니티를 사용하면서 직접 제어를 할 일은 없긴하다.
   그러나 렌더링 파이프라인을 이해하기 위해서는 필요한 지식이기에 공부를 조금 하였다.

   그래픽스 API 초기화를 끝내고서는 렌더링 파이프라인을 시작하기 직전인 '드로우 콜' 단계를 거친다.

   [드로우 콜 생성] 단계란
   CPU가 GPU에게 전달할 명령을 생성하는 단계이다.   즉, 커맨드 버퍼에 명령들을 추가하는 단계이다. 보통 CPU에서 실행되는 단계이다.

   [드로우 콜]이란
   오브젝트를 한 번 그리는데 필요한 명령들의 묶음.
  
   ※ 커맨드 버퍼의 구성
      -> 렌더 상태 설정 명령(셰이더), 버텍스 데이터(위치, 색깔 행렬) 설정 명령, 그리고 그리기 명령이 있다.

 요약하자면 1. 그래픽스 API 초기화 설정 -> 2. 드로우 콜 생성을 한다.
 위 과정은 렌더링 파이프라인이 본격적으로 동작하기 직전, 즉 GPU가 동작하기 직전, 의 CPU 또는 응용프로그램에서 처리되는 과정들이다.



3. 렌더링 파이프라인 (Rendering Pipeline)
   (1) 순서
    정점 조립 -> 버텍스 셰이더 -> 래스터라이저 -> 프래그먼트 셰이더

   ■ 정점 조립
        - 정점 버퍼의 요소들을 정점 구조체로 조립
        - 데이터 버퍼에 저장된 정점의 위치,컬러 각각에 대한 정점의 '구조체'로 조립이 되는 과정임
      
    위 과정이 필요한 이유
    1. 각각의 정점들을 묶어서 하나의 단위로 묶어서 사용하는 것이 더 직관적으로 다루기 쉽기 때문이다
    2. 각 정점의 구성을 코드에서 명시적으로 선언할 수 있고, 정점 구조체의 이름도 사용자가 정의할 수 있다.
   
    * 정점 조립 과정은 유니티에서 알아서 처리가 됨
    * 우리가 직접 해야하는 것은 사용할 정점의 '구조체 선언' 이다.
        (각 정점들이 어떠한 필드(예로 Position 및 Color) 를 가지게 될 것인지 정의도 해줘야함)

    -> 각 정점들은 '버텍스 셰이더'에 각각의 '병렬'들로 처리가 되어서 또 다른 형태의 정점으로 변경이 된다.

        (ex) 모델 병렬, 투영 병렬 등 

 

 

=================== 여기 까지 어제 공부했던 내용이고 이제 버텍스 셰이더 부터 공부하면 된다. ====

 

위에 개념들을을 요약한답시고 다 써놨지만 지금 당장 위에 것을 전부 암기하는 것은 무리이다 흐름을 이해하는 목적으로 공부해보자

 

요약:

렌더링 파이프라인이란 3D 상에 보이지 않는 물체들을 2D 화면(스크린)에 그려주는 그래픽 작업인데. 

 

위 작업은 CPU가 보낸 그래픽 데이터(명령)가 여러가지 과정을 거친 후 최종적으로 GPU에게 전달되고나서 마지막에 GPU내에서 실행되는 작업이다.

 

CPU는 '커맨드 큐'라는 진열대에다 그려주고 싶은 그래픽 데이터를 한 뭉텅이로 묶은 '커맨드 버퍼'를 차곡 차곡 진열해놓는다. 

 

GPU는 그 데이터 뭉텅이가 필요할 때 마다 진열해 놓은 순서대로 빼간다. 이 과정에서는 GPU가 그림을 그릴 수 있도록 GPU가 이해할 수 있는 언어(하드웨어 언어)로 번역이 되어서 데이터가 전달된다.

 

데이터를 전달받은 GPU는 해당 뭉텅이에 담아있던 명령(커맨드)에 따라 밑그림을 그리고 색을 칠하고 보여주는 행위 즉 '렌더링 파이프라인'을 동작한다. 

 

위 과정 중에서도 CPU는 계속해서 GPU에게 전달할 명령들을 담은 커맨드 버퍼를 생성(드로우 콜)하고 진열대에 순서대로 쌓아놓는다. 

 

(편의점 재고 채우는 것 같은 느낌이다. 선입선출이라서 커맨드 '큐'라고 하는 것 같다.)

 

 

큰 그림은

[ 그래픽스 API 초기화 -> 드로우 콜 생성 -> 렌더링 파이프라인 ] 이다.

 

디테일은 아직 내 수준에서 완전히 이해하기에는 무리라서 전체적인 그림을 먼저 이해한다고 생각하고 

그 이후에 천천히 디테일을 공부해야겠다.

 

혹시 틀린 것이 있다면 지적해주시길 바랍니다 :)

728x90