언리얼 엔진을 쓴다면 DirectX를 꼭 배워야 할까

게임 그래픽 프로그래밍을 공부하다 보면 반복적으로 마주치는 질문이 있다. “언리얼 엔진으로도 충분히 게임을 만들 수 있는데, 굳이 DirectX 같은 저수준 그래픽 API까지 공부해야 하나?” 인터넷 커뮤니티에서는 “DirectX는 필수다”, “아니다, 요즘은 엔진만 잘 쓰면 된다”는 두 주장이 반복적으로 부딪힌다.
이 논쟁이 소모적으로 느껴지는 이유는, 애초에 두 기술이 같은 층위에서 비교될 수 있는 것이 아니기 때문이다. DirectX는 그래픽 API이고, 언리얼 엔진은 그 API를 기반으로 구축된 렌더링 엔진이다. “언리얼 엔진 vs DirectX”라는 구도 자체가 부정확한 셈이다. 이 글에서는 두 기술의 실제 관계를 정리하고, 어떤 상황에서 DirectX 지식이 필요한지, 그리고 현실적인 학습 순서는 어떻게 되는지를 살펴본다.
언리얼 엔진과 DirectX의 실제 관계
언리얼 엔진은 내부적으로 RHI(Rendering Hardware Interface)라는 추상화 계층을 두고, 플랫폼에 따라 Direct3D 11, Direct3D 12, Vulkan, Metal 등 여러 그래픽 API를 선택적으로 사용한다. 윈도우와 엑스박스 플랫폼에서는 주로 Direct3D 12가 사용되고, macOS와 iOS에서는 Metal, 안드로이드와 리눅스에서는 Vulkan이 기본이다. 즉 언리얼 엔진은 DirectX 위에 올라가 있는 것이 아니라, 여러 API 중 하나로 DirectX를 “사용할 수 있는” 구조다.
엔진 개발자가 언리얼 엔진 5의 신기능인 Nanite(가상화된 지오메트리)나 Lumen(실시간 글로벌 일루미네이션)을 설명할 때 “DX12 세대 기능”이라는 표현을 자주 쓰는 이유가 여기 있다. 이들 기능이 DirectX 12에만 묶여 있어서가 아니라, DX12 수준의 저수준 제어가 가능한 API(DX12, Vulkan 등)가 있어야 구현 가능한 기술이기 때문이다. 실제로 Lumen과 Nanite는 Vulkan 백엔드에서도 작동한다.
한 가지 오해를 짚고 넘어가자. 언리얼 엔진은 완전한 오픈 소스는 아니지만, 소스 코드가 공개되어 있다. Epic Games 계정으로 GitHub에 연동하면 엔진 전체 소스 코드를 무료로 받을 수 있고, 직접 수정해서 빌드할 수도 있다. “엔진 내부를 보려면 DirectX를 공부해야 한다”는 말은 틀렸다. 엔진 내부를 보려면 언리얼 엔진 소스 코드를 직접 읽으면 된다. DirectX 지식은 그 소스 코드를 더 깊이 이해하는 데 도움을 주는 도구다.
블루프린트와 마테리얼 에디터는 다른 것이다
DirectX 필요성을 논의하기 전에, 언리얼 엔진 초보자들이 자주 혼동하는 개념부터 정리해야 한다. 언리얼 엔진의 “비주얼 스크립팅” 도구는 두 가지가 있는데, 성격이 완전히 다르다.
블루프린트는 게임플레이 로직을 노드로 작성하는 비주얼 스크립팅 시스템이다. 캐릭터의 점프, 아이템 획득, UI 반응 같은 게임 로직을 C++ 없이 노드로 구성할 수 있다. 블루프린트는 그래픽이나 셰이더와는 직접적인 관련이 없다.
마테리얼 에디터는 셰이더를 노드로 만드는 전용 도구다. 텍스처 샘플링, 라이팅 모델, 포스트 프로세싱 효과 같은 것들을 노드로 조합해서 만들면, 언리얼 엔진이 내부적으로 HLSL 셰이더 코드로 변환해 GPU에서 실행한다. 즉 마테리얼 에디터로 만든 결과물은 최종적으로 셰이더이지 게임 로직이 아니다.
“블루프린트만으로 셰이더를 만들 수 있다”는 말은 잘못된 것이다. 셰이더를 노드로 만드는 것은 마테리얼 에디터이고, 블루프린트는 셰이더와 무관하다. 이 구분을 하지 않으면 “비주얼 스크립팅이 저수준 그래픽까지 다 해준다”는 잘못된 인식이 생긴다.
DirectX를 꼭 배우지 않아도 되는 경우
언리얼 엔진의 목적은 개발자가 저수준 그래픽 API를 직접 다루지 않고도 높은 품질의 그래픽을 얻을 수 있게 해주는 것이다. 다음과 같은 상황이라면 DirectX를 먼저 공부하지 않아도 된다.
게임플레이 중심의 개발을 하는 경우, 즉 레벨을 구성하고 캐릭터 로직을 짜고 UI를 만드는 작업이 주 업무라면 DirectX 지식은 거의 필요하지 않다. 블루프린트와 C++ 게임플레이 프레임워크만으로 충분하다. 기본적인 셰이더 효과(발광, 반투명, 간단한 디졸브 등)도 마테리얼 에디터로 대부분 해결된다. 실제로 언리얼 엔진으로 출시되는 인디 게임의 다수는 셰이더 코드를 한 줄도 직접 작성하지 않는다.
중급 셰이더 작업까지도 마테리얼 에디터 안에서 커스텀 노드나 HLSL 코드 블록을 사용해 구현할 수 있다. 이 HLSL 코드는 DirectX의 HLSL과 동일한 문법을 쓰지만, 언리얼 엔진의 마테리얼 프레임워크 안에서 작성되므로 DirectX의 렌더링 파이프라인 개념까지 알 필요는 없다.
DirectX 지식이 실질적으로 필요한 경우
반면, 다음과 같은 작업을 하려면 DirectX(또는 Vulkan) 수준의 저수준 지식이 필요하다.
엔진 렌더러의 수정이나 확장이 필요한 경우다. 언리얼 엔진의 기본 렌더러가 지원하지 않는 커스텀 렌더링 패스를 추가하거나, 특정 프로젝트에 맞게 G-buffer 구조를 변경하거나, 독자적인 포스트 프로세싱 파이프라인을 짜려면 RHI 레이어와 상호작용해야 한다. 이때는 Direct3D 12의 Command List, Root Signature, Descriptor Heap 같은 개념을 이해해야 엔진 코드를 정확히 읽을 수 있다.
플랫폼별 성능 최적화가 필요한 경우도 마찬가지다. 콘솔이나 모바일에서 프레임 드랍의 원인을 GPU 수준에서 추적하려면, 프로파일러가 보여주는 드로우 콜, 셰이더 단계, 메모리 전송 같은 개념을 이해해야 한다. 이 지식은 DirectX나 Vulkan을 공부하면서 자연스럽게 쌓인다.
자체 렌더링 엔진을 개발하려는 경우는 말할 것도 없다. 언리얼이나 유니티 같은 상용 엔진을 쓰지 않고 독자적인 렌더러를 만들려면 그래픽 API를 직접 다루는 것이 출발점이다.
연구나 실험적 기법을 구현할 때도 DirectX 지식이 필요하다. 논문에 나오는 새로운 렌더링 기법을 직접 구현해보려면, 엔진이 제공하는 추상화만으로는 부족하고 저수준 파이프라인을 제어해야 할 때가 많다.
프로파일링과 디버깅 도구
언리얼 엔진은 내부 성능 분석을 위한 도구를 기본 제공한다. Unreal Insights는 최신 언리얼 엔진의 통합 프로파일링 도구로, CPU와 GPU 활동을 시간축 기반으로 시각화한다. 게임 내 콘솔에서 실행할 수 있는 Stat 명령어(stat unit, stat gpu, stat scenerendering 등)는 실시간으로 성능 지표를 확인할 수 있게 해준다. GPU Visualizer(Ctrl+Shift+Comma)는 단일 프레임의 GPU 작업을 패스별로 분해해 보여준다.
더 깊이 GPU 수준에서 분석하려면 외부 도구를 사용한다. Microsoft의 PIX for Windows는 DirectX 12 애플리케이션의 GPU 캡처와 분석에 표준적으로 사용되는 도구다. NVIDIA의 Nsight Graphics, AMD의 Radeon GPU Profiler도 같은 목적으로 쓰인다. 이런 도구의 출력 결과를 제대로 해석하려면 DirectX 12의 커맨드 리스트, 파이프라인 상태 오브젝트(PSO), 리소스 배리어 같은 개념에 대한 이해가 필요하다.
현실적인 학습 순서
결론적으로, 언리얼 엔진을 시작하는 단계에서 DirectX부터 공부하는 것은 비효율적이다. 게임 개발에서 가장 먼저 경험해야 할 것은 “게임을 완성해보는 것”이고, 그 과정에서 언리얼 엔진의 추상화는 큰 도움이 된다. 다음과 같은 순서가 현실적이다.
첫 단계는 언리얼 엔진 자체를 익히는 것이다. 블루프린트로 기본 게임플레이를 구현해보고, 마테리얼 에디터로 셰이더 노드를 조합해본다. 이 단계에서 게임을 한두 개 완성해본 경험이 있다면 이미 많은 것을 배운 것이다.
두 번째 단계는 HLSL을 배우는 것이다. 마테리얼 에디터의 커스텀 노드에 HLSL 코드를 직접 써보면서, 노드 뒤에서 실제로 어떤 계산이 이루어지는지 이해한다. 이 단계에서 셰이더가 버텍스 셰이더와 픽셀 셰이더로 나뉘고, 각각이 GPU에서 병렬로 실행된다는 기초 개념을 익힌다.
세 번째 단계는 언리얼 엔진 소스 코드를 읽는 것이다. GitHub에서 엔진 소스를 받아 RHI 관련 코드를 읽어보면, 엔진이 렌더링을 어떻게 조직하고 있는지 구체적으로 보인다. 이때 처음으로 DirectX 12의 개념들이 실질적으로 필요해진다.
네 번째 단계가 DirectX 12를 별도로 공부하는 것이다. Frank Luna의 “Introduction to 3D Game Programming with DirectX 12”나 Microsoft의 공식 DirectX-Graphics-Samples 저장소가 좋은 출발점이다. 이 시점에서는 이미 렌더링 파이프라인의 전체 그림이 머릿속에 있기 때문에, 저수준 API의 세부 사항을 효율적으로 흡수할 수 있다.
핵심 정리
언리얼 엔진과 DirectX는 경쟁 관계가 아니라 계층 관계다. 언리얼 엔진은 RHI를 통해 DirectX 12, Vulkan, Metal 등 여러 그래픽 API를 추상화하며, 개발자가 저수준 API를 몰라도 대부분의 작업을 할 수 있게 해준다. 블루프린트는 게임 로직용 비주얼 스크립팅이고, 셰이더는 마테리얼 에디터에서 만든다. 이 둘을 혼동하면 언리얼 엔진의 구조를 오해하게 된다. DirectX 지식이 꼭 필요한 경우는 엔진 렌더러 수정, 플랫폼별 저수준 최적화, 자체 엔진 개발, 연구 기법 구현 같은 상황으로 한정된다. 일반적인 게임 개발에서는 언리얼 엔진과 HLSL부터 익히고, 엔진 소스를 읽으면서 필요해질 때 DirectX를 공부하는 순서가 현실적이다.
마치며
DirectX를 꼭 배워야 하느냐는 질문에 대한 가장 솔직한 답은 “당신이 하려는 일이 무엇이냐에 달려 있다”는 것이다. 게임을 만들고 싶다면 언리얼 엔진만으로도 충분하고, 엔진 내부를 건드리고 싶거나 그래픽 프로그래머가 되고 싶다면 언젠가는 DirectX나 Vulkan을 공부해야 한다.
중요한 것은 순서다. 저수준부터 시작해서 위로 올라가는 방식은 대부분의 학습자에게 좌절로 끝난다. 반대로 엔진에서 게임을 만드는 경험을 먼저 쌓고, 필요해지는 지점에서 더 깊이 들어가는 방식이 훨씬 실용적이다. 모든 프로그래머가 그래픽 API 전문가가 될 필요는 없지만, 언제든 그 방향으로 들어갈 수 있는 길이 열려 있다는 것을 알고 있는 것만으로도 충분하다.