대규모 전투 장면에서 게임 프로그래밍이 GPU 중심으로 바뀌는 이유
수백 명의 병사가 한 화면에 들어오는 순간, 평소 120fps를 유지하던 빌드가 갑자기 40fps 아래로 떨어집니다. 모델의 폴리곤 수를 줄여도 개선 폭이 작고, 그래픽 옵션을 낮췄는데도 CPU 프레임 시간이 그대로라면 문제는 화질보다 오브젝트를 선별하고 드로우 콜을 제출하는 방식에 있을 가능성이 큽니다.
최근의 게임 프로그래밍은 CPU가 모든 렌더링 결정을 내리는 구조에서 벗어나고 있습니다. GPU 기반 컬링, 간접 드로우, 인스턴싱, 메시 셰이더와 같은 기술이 연결되면서 렌더러는 단순히 빠른 그림을 그리는 모듈이 아니라 대규모 장면을 데이터로 처리하는 시스템으로 변하는 중입니다.
전투 규모가 커지는 순간 CPU 제출 방식이 막힌다
삼각형보다 드로우 콜이 먼저 한계에 닿는 이유
전통적인 렌더링 루프에서는 CPU가 카메라에 보이는 오브젝트를 찾고, 재질과 메시를 확인한 뒤 그래픽 API에 드로우 명령을 제출합니다. 오브젝트가 수십 개일 때는 단순하고 디버깅하기 좋은 구조지만, 병사와 무기, 파편, 그림자 패스가 겹치는 대규모 전투에서는 매 프레임 처리할 상태 변경과 명령 수가 폭발합니다.
이때 폴리곤을 절반으로 줄여도 CPU가 제출해야 하는 명령 개수는 거의 달라지지 않습니다. 반대로 캐릭터를 동일한 메시와 재질로 묶고 한 번의 간접 명령으로 처리하면 외형 품질을 크게 희생하지 않고도 병목을 완화할 수 있습니다. 프로파일러에서 GPU 사용률은 낮은데 메인 스레드나 렌더 스레드가 가득 차 있다면 바로 이 유형을 의심해야 합니다.
| 관찰된 현상 | 가능성이 큰 병목 | 먼저 확인할 지표 |
|---|---|---|
| 해상도를 낮춰도 fps가 비슷함 | CPU 제출·게임 로직 | Render Thread, Draw Calls |
| 해상도에 따라 GPU 시간이 크게 변함 | 픽셀 셰이딩·대역폭 | GPU Frame, Overdraw |
| 카메라 방향에 따라 급격히 흔들림 | 컬링·가시 오브젝트 수 | Visible Instances, Occlusion |
- 드로우 콜 수뿐 아니라 상태 변경과 파이프라인 전환 횟수도 함께 기록합니다.
- 메인 패스 외에 그림자, 깊이 프리패스, 반사 패스가 같은 오브젝트를 몇 번 제출하는지 확인합니다.
- 평균 프레임보다 1% low와 최악 프레임을 살펴 전투 시작 순간의 스파이크를 찾습니다.
- 개발 PC가 아닌 목표 사양의 CPU와 GPU 조합에서 같은 장면을 재현합니다.
그래픽 최적화는 삼각형을 무조건 줄이는 작업이 아닙니다. 누가 장면을 판단하고, 몇 번 명령을 만들며, 그 결과를 어디에 저장하는지를 바꾸는 작업에 가깝습니다.
GPU 기반 컬링과 간접 드로우가 렌더러의 역할을 바꾼다
오브젝트 목록을 CPU로 다시 가져오지 않는 흐름
GPU 중심 렌더링의 핵심은 GPU가 오브젝트 데이터를 읽어 가시성을 판정하고, 살아남은 인스턴스 수와 드로우 인자를 직접 만드는 것입니다. CPU는 개별 병사에게 하나씩 명령을 내리는 대신 큰 인스턴스 버퍼와 장면 파라미터를 전달합니다. 컴퓨트 셰이더가 프러스텀 컬링, 거리 기반 LOD 선택, 경우에 따라 오클루전 판정을 수행한 뒤 간접 드로우 버퍼를 채웁니다.
이 구조에서는 판정 결과를 읽기 위해 GPU와 CPU를 동기화하지 않는 것이 중요합니다. 결과를 CPU로 되가져오는 순간 파이프라인이 기다리게 되어 얻었던 이점이 사라질 수 있습니다. 프레임별 버퍼를 분리하고, 이전 프레임의 깊이 정보를 사용하는 등 약간의 지연을 허용하는 설계가 처리량에 유리합니다.
메시 셰이더와 바인드리스가 만드는 다음 단계
2026년 시점의 렌더링 흐름에서 메시 셰이더와 바인드리스 리소스는 모든 프로젝트의 필수 조건이라기보다 장면 규모를 확장하는 선택지로 보는 편이 정확합니다. 메시 셰이더는 작은 메시 단위의 작업 그룹에서 기하를 선별하고 생성할 수 있어, 복잡한 LOD와 밀집 장면에 적합합니다. 바인드리스 방식은 많은 텍스처와 버퍼를 인덱스로 접근하게 해 재질 전환 부담을 낮춥니다.
- 먼저 기존 인스턴싱으로 같은 메시와 재질을 묶어 기준 성능을 만듭니다.
- CPU 프러스텀 컬링 결과와 GPU 컬링 결과를 캡처해 누락된 오브젝트가 없는지 비교합니다.
- 간접 인자 버퍼의 카운트와 용량을 시각화해 오버플로를 빠르게 발견합니다.
- 오클루전 컬링은 카메라 급회전 때의 팝인과 보수적 경계 상자 비용까지 측정합니다.
- 메시 셰이더는 지원 하드웨어 경계를 정한 뒤 기존 렌더링 경로와 나란히 검증합니다.
새 기술을 발표 자료에서 접했다면 적용 전 맥락도 확인할 필요가 있습니다. GDC의 성격과 업계 내 역할을 이해하면 콘퍼런스 데모가 완성된 범용 해법인지, 특정 하드웨어에서 검증한 연구 사례인지 구분하는 데 도움이 됩니다.
최신 렌더링 기능보다 먼저 설계해야 할 호환성과 예산
지원 기기별로 하나의 경로만 고집하지 않는다
GPU 중심 구조가 유망해도 모든 플랫폼이 동일한 기능과 드라이버 품질을 제공하지는 않습니다. PC에서는 그래픽 API와 제조사별 차이가 있고, 콘솔은 명확한 하드웨어 목표를 가질 수 있으며, 모바일은 발열과 메모리 대역폭이 더 큰 제약입니다. 따라서 기능 지원 여부만 검사하는 단순 분기보다 콘텐츠 규모와 렌더링 경로를 함께 조절하는 계층형 전략이 필요합니다.
예를 들어 상위 경로는 GPU 오클루전 컬링과 간접 드로우를 사용하고, 중간 경로는 GPU 프러스텀 컬링과 일반 인스턴싱을 조합할 수 있습니다. 하위 경로에서는 전투 참여 인원과 원거리 그림자 수를 줄이되 게임 규칙은 유지합니다. 이렇게 하면 그래픽 기능 하나가 지원되지 않는다는 이유로 프로젝트 전체의 장면 설계를 포기하지 않아도 됩니다.
기술 선택은 일정과 제작비에도 직접 연결됩니다. 계획과 예산을 프로그램 단위로 연결하는 개념처럼 렌더링 기능도 기대 효과, 구현 기간, 검증 장비, 실패 시 대체 경로를 한 묶음으로 평가해야 합니다. 엔진 개발자의 6주 작업만 계산하고 아트 파이프라인 변경과 QA 장비 비용을 빼면 실제 비용을 과소평가하게 됩니다.
- 기능 예산: 간접 드로우, 오클루전, 메시 셰이더 가운데 반드시 필요한 범위를 정합니다.
- 프레임 예산: CPU 컬링, 명령 생성, GPU 가시성 판정에 허용할 밀리초를 따로 배정합니다.
- 메모리 예산: 인스턴스 데이터, 경계 정보, 다중 프레임 버퍼의 최대 용량을 계산합니다.
- 검증 예산: 제조사와 사양이 다른 기기에서 캡처를 수집할 시간을 일정에 포함합니다.
- 콘텐츠 예산: 화면 속 최대 인원, 재질 종류, 투명 효과와 그림자 캐스터 상한을 수치화합니다.
좋은 렌더링 아키텍처는 가장 빠른 경로 하나가 아니라, 목표 기기에서 품질과 성능을 예측할 수 있는 여러 경로를 제공합니다.
게임 기획 단계에서도 “병사 500명”이라는 문장만 전달하면 개발팀이 동시 표시 수인지, 실제 전투 AI 수인지, 배경 연출 인원까지 포함한 수치인지 판단하기 어렵습니다. 게임 기획자의 역할을 참고해 카메라 거리, 전투 밀도, 상호작용 가능 범위를 명세하면 기술 데모가 실제 플레이 조건과 어긋나는 일을 줄일 수 있습니다.
성벽 공성전 800명을 살린 렌더링 전환 과정
한 장면을 계측하고 옮기고 검증하는 순서
가상의 액션 전략 게임에서 성문이 열리면 아군과 적군 800명이 광장으로 모인다고 가정해 봅시다. 개발팀은 처음에 캐릭터 모델의 폴리곤을 낮추고 원거리 애니메이션 갱신 빈도를 줄였습니다. GPU 시간은 조금 줄었지만 프레임은 여전히 46fps 부근이었고, 프로파일러에서는 렌더 스레드가 17ms 이상을 사용했습니다. 그림자 패스를 포함한 드로우 콜이 급증한 것이 직접적인 원인이었습니다.
첫 번째 주에는 새 API 기능을 넣지 않고 병사 데이터를 구조화된 버퍼로 모았습니다. 메시, 재질, LOD, 경계 구, 현재 변환과 이전 변환을 연속 메모리에 배치하고, 동일한 렌더링 상태를 사용하는 병사를 그룹화했습니다. 이 변경만으로도 데이터 순회가 단순해졌으며 렌더링 디버거에서 어떤 그룹이 많은 명령을 만드는지 추적할 수 있게 됐습니다.
- 기준 장면 고정: 카메라 이동과 병사 경로를 녹화해 매 빌드에서 같은 90초 공성전을 재생했습니다.
- 1차 전환: CPU 컬링은 유지하면서 그룹별 인스턴싱을 적용해 상태 변경을 줄였습니다.
- 2차 전환: 컴퓨트 셰이더가 프러스텀과 거리 LOD를 판정하고 가시 인덱스 버퍼를 작성하게 했습니다.
- 3차 전환: 깊이 피라미드를 이용한 보수적 오클루전 판정을 추가하되, 큰 영웅 캐릭터는 별도 경로에 남겼습니다.
- 회귀 검증: 그림자 누락, 모션 벡터 오류, 카메라 급회전 팝인을 자동 캡처와 육안 검사로 확인했습니다.
두 번째 주에는 GPU 컬링을 활성화했지만 성벽 뒤 병사가 한 프레임 늦게 나타나는 문제가 발생했습니다. 팀은 경계 상자를 조금 확장하고 카메라가 빠르게 회전할 때 오클루전 판정을 보수적으로 적용했습니다. 잘못 가려진 오브젝트 수를 화면에 색으로 표시하는 디버그 뷰도 추가해 성능 수치만으로 찾기 어려운 오류를 잡았습니다.
최종 빌드에서는 상위 PC 경로가 GPU 컬링과 간접 드로우를 사용하고, 기능 지원이 제한된 경로는 CPU 프러스텀 컬링과 인스턴싱을 유지했습니다. 공성전의 병사 수를 삭제하는 대신 원거리 부대의 그림자와 애니메이션 품질을 단계적으로 조절했고, 최악 프레임의 렌더 스레드 시간이 눈에 띄게 안정됐습니다.
이 사례에서 결정적인 변화는 특정 셰이더 하나가 아니었습니다. 재현 가능한 장면을 만들고, 오브젝트 데이터를 GPU가 읽기 좋은 형태로 옮기며, 가시성 결과를 CPU로 되돌리지 않고, 하위 기기용 경로까지 보존한 순서가 효과를 만들었습니다. 다음 대규모 전투에서 프레임이 무너진다면 모델을 줄이기 전에 누가 오브젝트를 선별하고 누가 드로우 명령을 작성하는지부터 프로파일러에서 확인해 보세요.

- 다음글게임 프로그래밍 메모리 버그가 반복된다면 하지 말아야 할 선택 26.08.30
등록된 댓글이 없습니다.
