[UE5] 메쉬와 머태리얼
액션 기획자로서 업무를 하다보면 가끔 굉장히 많은 아트 리소스에 놀라곤 한다.
내가 만약에 혼자서 개발을 했다면 이 많은 리소스는 어떻게 관리할것인가 고민하기도 했다. 사실 깊이있게 파고들 이유는 크게 없지만 기본적인것 정도는 알아둘 필요가 있을것 같아 강의를 듣고 공부하여 기록하게 되었다.
언리얼에서는 레벨(Level) 안에 액터(Actor) 들이 배치되고, 그 안에 Static Mesh Component 나 Skeletal Mesh 들이 존재하고, 언리얼은 내부적으로 렌더링 파이프라인을 구성해서 CPU에서 렌더링 명령을 만든 뒤, DirectX 12, Vulkan 등의 그래픽 API를 통해 GPU에 전달해주기 때문에 “이 메시를 이 좌표에, 이 머티리얼로, 이 카메라 시점에서 렌더링해줘!” 가 되며 GPU의 처리 과정을 거쳐 최종 픽셀 컬러들이 프레임 버퍼(Frame Buffer) 에 저장되고 그게 모니터로 출력되면서 우리가 눈으로 보는 ‘게임 화면’이 되는 것이다.
그 흐름을 더 자세히 보자.
다이렉트 X의 렌더링 파이프 라인이며, 우리가 어떤 물체를 그릴때 일어나는 단계들을 나타낸것이다.
맨 처음의 Input assembler 단계에서 제일 처음으로 넣는것이 어떤 물체를 그려줄것인가, 그 물체는 어떠한 정점으로 이루어졌는지를 입력하게 되는데 여기서 '메쉬'라는 개념이 처음 등장한다고 봐도 무방하다.
Input Assembler(IA)는 말 그대로 GPU의 렌더링 파이프라인에서 "무엇을 어떻게 그릴지"에 대한 가장 기초적인 정보를 조립하는 단계.
- Vertex Buffer View (VBV)
- 정점(Vertex)들의 모음
- 위치, 노멀, UV, 텍스처 좌표, 색상 등의 데이터를 포함함
- 즉, 3D 모델의 형태, 이게 바로 메쉬의 정점 데이터
- Index Buffer View (IBV)
- 정점들을 어떤 순서로 삼각형(또는 다른 도형)으로 연결할지 정의
- 동일한 정점을 중복 사용하지 않도록 해주는 최적화 수단
그래서 메쉬란?
- 정점(Vertex)들의 집합 + 인덱스(Index) 정보
→ 이를 이용해 삼각형 등의 기본 도형(Primitive) 들로 구성된 3D 모델
가까이서 자세히 보면 무수한 삼각형들이다.
따라서 삼각형의 정점에 대한 정보들을 모두 모아서 Input assembler 단계에 넣어주게 된다.
렌더링 파이프라인에 따라 과정을 쭉 거치게되면 그 물체의 위치뿐만 아니라 어떠한 색상으로 그려줘야될지를 Pixel Shader 단계에서 최종적으로 정해져 결과물로 나온다.
그럼 이걸 어떻게 정하는걸까? 렌더링 파이프 라인 중 일부분을 프로그래밍 언어로 제어 할 수 있다. 그것을 쉐이더 라고 표현하는데 쉐이더라는 것을 만들어서 물리나 수학공식에 의해 색상이 연산되어야 하는 공식을 정해주게 된다.
간단하게 하나의 함수라고 생각하면 되는데 함수를 사용할 때는 항상 함수에다가 넘겨주는 인자가 존재했다. 그 인자가 사실 머태리얼의 개념이라고 보면 된다.
쉐이더(Shader)란?
- GPU에서 실행되는 작고 빠른 프로그램 (함수의 모음).
- Vertex Shader, Pixel Shader, Geometry Shader 등이 있고,
- 언리얼이나 DirectX에서는 주로 HLSL (High Level Shader Language) 라는 언어로 작성
Pixel Shader는 보통 다음과 같은 구조를 가짐:
float4 PSMain(PixelInput input) : SV_Target
{
// 조명 계산, 색상 계산, 텍스처 적용 등
float3 color = input.BaseColor * LightFactor;
return float4(color, 1.0); // 최종 RGBA 색상 반환
}
함수의 인자(Input)는? → 머티리얼
- 쉐이더는 단독으로는 실행되지 않고, 항상 입력값을 필요로 한다.
- 이 입력값은 일반적으로 다음과 같은 것들
인자 | 의미 | 언리얼 머티리얼에서 설정하는 예 |
BaseColor | 표면 기본 색 | Vector3 (RGB) 값 또는 텍스처 |
Roughness | 표면 거칠기(광택) | 0 ~ 1 float 값 |
Normal | 법선 방향 | Normal Map 텍스쳐 |
Metallic | 금속성 정도 | 0 or 1 값 |
Emissive | 발광 여부 | 빛을 내는 색상 값 |
이걸 다 모아서 GPU에 전달되면, 픽셀 셰이더에서 인자로 받아 연산하는 것.
왜 머티리얼이 중요할까?
- 같은 메쉬(정점 구조)라도, 머티리얼을 다르게 설정하면 완전히 다른 느낌의 오브젝트가 됨.
- 머티리얼은 셰이더에 넣어줄 인자 묶음이라고 생각하면 되고,
- 셰이더 자체는 "어떻게 연산할지 공식(=함수)"을 담고 있다.
함수를 인자로 전달해 준다는것이 무엇인지 좀 더 체감하기 위해 나만의 머태리얼을 생성했다.
어떤 물체가 어떻게 보여야 하는지 결정하는 속성을 오른쪽 머태리얼을 설정한다고 볼 수 있다.
숫자 3을 누른채로 왼쪽 마우스 버튼을 클릭하면 노드가 하나 생성된다. 연결해주자.
노드를 더블 클릭하여 원하는 색상을 지정해주도록 하자.
큐브를 레벨에 배치해 방금 만들 머태리얼을 드래그드롭 해주면 색상 설정이 완료된다.
결국 큐브라는 액터는 여러가지 정보가 있는데, 어떤 형태를 띄고 있는지를 메쉬라는 정보로 만들어져 있으며 그 메쉬에 어떠한 색상을 입혀 표현해야할지를 머태리얼로 표현해주고 있는것이다.
- 계속 작성중..