[번역] 그래픽 스터디: Red Dead Redemption 2
역자의 말: 많은 아티스트들은 유투브 등에서 터레인을 만들고, 고밀도 메가스켄 데이터를 사용해서 시너리를 구축하고 Epic 설정을 사용하며 레이트레이싱 쉐도우와 VSM 해상도를 최고로 두고 나나이트와 루멘을 사용한 그럴듯한 Environment Scenery 를 수도 없이 봐 왔을 겁니다. 그런데... 회사에서 하는 프로젝트와 출시된는 게임은 왜 퀄리티가 그렇지? 뭐 그런 생각 많이들 하실것 같아요. 왜 그런줄 모르시는 신입 아티스트와 일 하는것은 참으로 곤혹스러울 때도 많고 신입이 아닌 년차가 있는데도 프러덕션 레디 퀄리티와 유투버들이 강의팔이용으로 만든것들의 갭을 이해 못하는 분들도 아직 많더라고요.
아무튼... 최근 컨설팅을 하면서 언리얼엔진5에 버그를 수정하고 렌더링 파인튜닝을 해 드려도 여전히 유니티 같은 그래픽을 갖고 있는 상황을 아주 종종 보게 되기도 하며 실제로 출시 된 게임들도 어느정도 그런 느낌을 지우기 힘들때가 빈번합니다. 솔직히 언리얼엔진5가 마법을 부리는 것은 단 하나도 없습니다. 이미 다 알려진 렌더링 기술의 조합일 뿐이에요. 그렇게 때문에 결국 아티스트의 역량에 의해 게임레디 품질은 결정되게 되어 있습니다.
최근 배경 시너리의 시각적인 폴리싱에 대해서 여러가지 고민을 하고 있는데요 개방형 렌드스케이프에서는 레디리2가 꽤 괜찮았기 때문에( 벌써 출시 한지 꽤 지난 게임임에도... 그리고 HZD 포비든웨스트는 넘사 별외로 둡니다. ㅜㅜ ) 게임플레이를 하다가 Huseyin 이라는 엔지니어의 블로그에서 읽어 볼 만한 토픽을 찾았습니다. 이번에도 한번 같이 알아가 보시죠.
저자. Huseyin
제가 가장 좋아하는 게임 중 하나인 레드 데드 리뎀션은 2018년에 콘솔용 프리퀄로 돌아왔습니다. 그리고 2019년에 PC용으로도 출시되었습니다. 드디어 게임을 플레이할 수 있었고 바로 그래픽에 놀랐습니다. 하지만 1050Ti 노트북 GPU로는 중간 설정에서 25FPS로 겨우 게임을 플레이할 수 있어서 화가 났습니다. 제 장비가 좋지 않다는 건 알지만 중간 설정에서 25FPS? 오늘은 게임의 프레임 캡처를 살펴보고 게임에서 사용된 그래픽 기술을 분석해 보겠습니다.
서문
이것은 게임에 대한 공식 분석이 아닙니다. 제가 RenderDoc 프레임 캡처를 분석한 것입니다. 실제 개발자로부터 배우고 싶다면 Fabian Bauer의 시그라프 강연에서 슬라이드를 확인할 수 있습니다. 슬라이드(페이지 하단), 동영상(1:58:00부터 시작) 여기에서 Adrian Courrèges의 GTA5 그래픽 분석도 읽어볼 수 있습니다.
RDR2와 GTA5는 같은 회사에서 만든 게임이고 같은 엔진을 사용하기 때문에 GTA5의 기술 중 일부가 여기에도 등장합니다.
또 한 가지 중요한 점은 제가 시니어 그래픽 프로그래머가 아니라는 점입니다. 저는 아직 이 분야의 주니어입니다. 그래서 제가 이해하지 못하는 부분이 많을 것입니다. 실수나 개선할 점을 발견하면 저에게 연락해 주세요. 시작하겠습니다!
프레임 해부하기
다음은 해부를 위한 메인 프레임입니다: PC에서 메인프레임 캡처, 중간 설정. RDR2와 같은 게임에서는 모든 기술을 한 프레임에서 보기가 거의 불가능합니다. 여러 프레임에 걸쳐 작업을 분할합니다. 그래서 한 프레임보다 더 많은 프레임을 캡처했지만 이 프레임에 집중할 것입니다. 여기에는 스폿 및 포인트 조명, 방향성 조명(매우 미묘하지만 존재함), 건물, NPC, 말, 나무, 초목, 구름 등과 같은 많은 프로퍼티가 포함되어 있습니다. 게임에서 사용되는 대부분의 렌더링 기술을 시연할 수 있습니다. RDR2는 데이터를 지속적으로 스트리밍하는 오픈 월드 게임입니다. 따라서 프레임은 텍스처 생성 및 삭제, 셰이더 리소스 뷰, 정렬되지 않은 액세스 뷰, 디스크립터, 버퍼 업데이트 등과 같은 여러 작업으로 시작됩니다.
RDR2와 같은 게임에서는 한 프레임에서 모든 기술을 보는 것이 거의 불가능합니다. 여러 프레임에 걸쳐 작업을 분할해서 보여줍니다. 그래서 한 프레임 이상을 캡처했지만 이 프레임에 집중할 것입니다. 여기에는 스폿 및 포인트 조명, 방향성 조명(매우 미묘하지만 존재함), 건물, NPC, 말, 나무, 초목, 구름 등과 같은 많은 속성이 포함되어 있습니다. 게임에서 사용되는 대부분의 렌더링 기술을 시연할 수 있습니다.
RDR2는 데이터를 지속적으로 스트리밍하는 오픈 월드 게임입니다. 따라서 프레임은 텍스처 생성 및 삭제, 셰이더 리소스 뷰, 정렬되지 않은 액세스 뷰, 디스크립터, 버퍼 업데이트 등과 같은 수많은 작업으로 시작됩니다.
머드 맵
머드는 게임에서 큰 역할을 합니다. 게임 메커니즘 외에도 환경을 더욱 사실적으로 만듭니다. 이 게임에서는 사람과 말의 발자국 텍스처를 마차 바퀴의 흔적 텍스처와 함께 변위 맵에 렌더링합니다. 이렇게 축적된 텍스처는 지형을 렌더링할 때 패럴랙스 오클루전 매핑에 사용됩니다.
하늘과 구름
머드 패스가 끝나면 게임은 GPU 연산에 많은 작업을 수행합니다. 대부분은 하늘과 구름과 관련이 있습니다. 구름, 안개, 볼류메트릭은 RDR2의 대표적인 이펙트입니다. 이 단계에 대한 자세한 내용은 Fabian의 슬라이드에서 확인할 수 있습니다. 제가 설명할 수 있는 것보다 훨씬 더 자세하게 설명합니다.
환경맵
환경 맵은 GTA5와 마찬가지로 RDR2에서도 리플렉션의 주요 소스입니다. GTA5와 마찬가지로 RDR2도 카메라 위치에서 환경 큐브맵을 생성합니다. 환경 맵을 위한 얇은 GBuffer를 생성하는데, 이는 Far Cry 4와 유사합니다.
매 프레임마다 환경 큐브맵을 생성하는 것은 과중한 작업이 될 수 있습니다. RDR2는 비용을 줄이기 위해 몇 가지 최적화를 수행합니다. 예를 들어, 정적이고 불투명한 오브젝트만 그리고, 각 면을 렌더링하기 전에 프러스텀 컬링을 수행하며, 모델의 LOD 버전을 낮춰서 그립니다. 하지만 환경 맵의 경우 지형의 폴리 카운트가 여전히 매우 높다는 것을 발견했습니다.
G-버퍼 패스 후 하늘 포물선 맵과 구름 관련 텍스처를 사용하여 하늘 환경 큐브맵을 생성합니다. 다음 단계는 컨볼루션입니다. RDR2는 이미지 기반 조명에 분할 합 근사법을 사용합니다. 이 방법은 사전 필터링된 환경 큐브맵과 환경 BRDF LUT를 사용합니다. 필터링을 위해 게임은 환경 큐브맵을 컨볼루션하고 큐브맵의 밉맵 레벨에 컨볼루션된 버전을 저장합니다.
환경 큐브맵에 대한 라이팅 패스를 실행하기 전에 RDR2는 베이크된 대규모 앰비언트 오클루전을 다른 큐브맵 텍스처로 렌더링합니다. 이 게임에서는 스크린 스페이스 앰비언트 오클루전을 사용하지만 SSAO가 소규모로 도움이 될 수 있습니다. 베이크된 앰비언트 오클루전은 파티오나 실내를 어둡게 하는 등 대규모로 어둡게 하는 데 도움이 됩니다.
이 게임에서는 타일 기반 디퍼드 렌더링 경로를 사용하여 환경 맵의 조명을 계산합니다. 라이트 컬링과 조명은 각 환경 맵 면에 대해 하나의 컴퓨팅 패스에서 함께 계산됩니다. (이 점을 지적해준 @benoitvimont에게 감사드립니다.) 이 게임은 또한 프리 베이크 라이팅에 Assassin's Creed III와 유사한 "하향식 월드 라이트맵" 기법을 사용합니다.
각 큐브맵 면에 대해 RDR2는 하늘 환경 텍스처 위에 최종 색을 렌더링합니다. 그런 다음 하늘 환경 큐브맵과 동일하게 환경 큐브맵을 필터링합니다.
또한 RDR2는 플레이어가 건물 근처에 있을 때 건물 내부에 위치한 환경 맵을 로드합니다. 이 또한 디스크에서 스트리밍된 큐브맵 G-버퍼입니다.
게임에서는 이러한 맵의 조명을 계산하고 이전 맵과 마찬가지로 필터링합니다. 한 번에 하나의 베이크된 환경 맵만 계산하고 시간이 변경될 때만 다시 계산합니다. 모든 환경 맵은 텍스처 큐브맵 배열에 저장됩니다. 큐브맵을 이중 포물면 맵으로 변환하는 기능은 없습니다.
G-Buffer Pass
이 단계는 지형 깊이 프리패스로 시작한 다음 게임에서 씬을 G-버퍼로 렌더링하는 단계입니다.
- RGBA8_SRGB - 이 버퍼에는 RGB 채널의 알베도(기본 색상)가 포함되어 있습니다. 알파 채널 데이터의 용도는 잘 모르겠지만 앤티 앨리어싱 단계에서 사용됩니다.
- RGBA8_UNORM: RGB 채널에는 노멀이 포함되고 알파 채널에는 천과 머리카락과 관련된 것이 포함됩니다.
RGBA8_UNORM: 이 타깃은 머티리얼 프로퍼티를 위한 것입니다. R: 반사율(f0) G: 평활도 B: 메탈릭 A: 약간의 섀도잉을 포함합니다(이 채널은 이후 단계에서 섀도 마스크로 사용됨).
- RGBA8_UNORM: 빨간색 채널에 캐비티가 있습니다. 파란색 채널에는 또 다른 미스터리 데이터가 있습니다. 그리고 알파 채널에는 머리카락 관련 데이터가 있습니다. 녹색 채널에서는 아무것도 찾을 수 없습니다.
- RG16_FLOAT: 이 버퍼에는 모션 블러를 위한 화면 공간 속도가 포함됩니다.
- D32S8: GTA5와 마찬가지로 RDR2도 깊이에 역-z를 사용하고 스텐실 버퍼를 사용하여 특정 메시 그룹에 특정 값을 할당합니다.
베이크된 데이터에서 생성된 또 다른 타겟이 있습니다:
이 버퍼에는 환경 맵 단계에서와 동일하게 빨간색 채널에 구운 앰비언트 오클루전이 포함되어 있습니다. 하지만 이 텍스처에는 다른 채널이 있습니다. 녹색 채널에는 GBuffer 3의 파란색 채널에 있는 데이터처럼 보이는 일부 데이터가 포함되어 있습니다. 다시 말하지만 이 데이터가 무엇에 사용되는지 모르겠습니다. 그리고 캡처에서 파란색과 알파 채널의 데이터를 찾을 수 없습니다. 더 자세히 조사해 보겠습니다.
그림자 맵 생성
G-버퍼 단계가 끝나면 게임에서 섀도 맵을 렌더링하기 시작합니다. 포인트 라이트 섀도 맵에는 2D 텍스처 어레이를, 포인트 라이트 섀도 맵에는 텍스처 큐브 어레이를 사용합니다. 일부 게임에서는 섀도 맵에 큰 섀도 아틀라스 텍스처를 사용합니다(예: DOOM). 이 방법의 장점 중 하나는 거리에 따라 섀도 맵 크기가 달라질 수 있다는 것입니다. 텍스처 배열을 사용하면 텍스처 배열의 모든 텍스처가 같은 크기여야 하므로 이러한 유연성을 잃게 됩니다. RDR2에는 품질에 따라 3가지 텍스처 배열이 있습니다. 예를 들어 스포트라이트는
- 원거리 조명의 경우 512x768 D16
- 중간 거리(및 중간 설정에서 가까운 거리) 조명의 경우 1024x1536 D16
- 근접 조명(높음/울트라 설정에서) 2048x3072 D16 포인트 조명은 모든 방향에 그림자를 드리웁니다.
이 문제를 해결하기 위해 게임에서는 카메라 위치에서 씬을 깊이 큐브맵으로 렌더링하는 옴니디렉션 섀도 매핑이라는 기술을 사용합니다. 캠프파이어 그림자와 아서의 랜턴의 그림자는 이 기법을 사용하여 렌더링됩니다. 포인트 라이트 그림자에는 스포트라이트와 마찬가지로 다양한 품질 설정을 위한 3가지 배열이 있습니다. 게임 내 대부분의 정적 포인트 라이트에는 베이크된 섀도 큐브맵이 있습니다. 따라서 게임에서는 가능한 한 베이크된 섀도를 사용하고 플레이어가 광량 근처에 있을 때만 섀도 맵을 생성합니다. 하지만 그보다 더 흥미로운 점이 있습니다. 벽에 있는 대부분의 조명은 스포트라이트이지만 게임에서는 전방향 섀도 맵을 생성하지 않습니다. 대신 스포트라이트 섀도 맵을 생성하고 해당 섀도 맵의 메모리를 포인트 라이트 섀도 맵 큐브 배열에 복사합니다.
왼쪽 이미지는 1024x1536 스포트라이트 섀도 맵, 오른쪽 이미지는 512x512 텍스처 큐브 형식의 동일한 이미지 데이터입니다.
로컬 라이트 섀도우 맵은 선형 z를 저장합니다.
이것이 스포트라이트에 정사각형 크기의 그림자 맵을 사용하지 않는 이유를 설명합니다. 스포트라이트 섀도와 포인트 라이트 텍스처 큐브맵의 픽셀 수는 동일해야 합니다. 오른쪽 이미지에서 슬라이스 패턴을 보셨을 것입니다. 이는 스포트라이트와 포인트 라이트 섀도 맵의 폭이 다르기 때문에 발생하는 현상입니다.
또한 이 텍스처는 360도를 커버하지 않는다는 점에 유의하세요. 하지만 다행히도 건물의 조명은 일반적으로 뒷면에 벽이 있기 때문에 구운 그림자 맵이 그 벽을 덮습니다.
또 다른 흥미로운 점은 이 과정이 그 반대의 경우도 가능하다는 것입니다. 예를 들어 게임에서 가장 큰 도시 중 하나인 세인트 데니스에서는 스포트라이트를 위한 전방향 섀도 맵을 생성하고 해당 데이터를 스포트라이트 섀도 맵 배열에 복사합니다. RDR2가 왜 이런 섀도 매핑을 하는지 모르겠습니다. 인터넷에서 비슷한 기술을 찾을 수 없었습니다.
RDR2의 디렉셔널 라이트 섀도 매핑은 GTA5와 거의 동일합니다. 4개의 캐스케이드가 있는 캐스케이드 섀도 매핑. 1024x4096(중간 설정) 텍스처 아틀라스의 각 1024x1024 타일이 캐스케이드로 사용되었습니다.
디렉셔널 라이트 섀도 아틀라스: R16_UNORM
라이트 스테이지
이제 이 모든 환경 맵, 지버퍼, 섀도 맵, AO 버퍼를 결합할 차례입니다. 이 단계에는 두 개의 패스가 포함됩니다: 첫 번째 패스는 글로벌 라이트(태양/달)용이고 두 번째 패스는 로컬 라이트용입니다.
글로벌 라이트 패스
이 게임은 방향성 조명(이 경우 달빛)을 계산하기 위해 풀스크린 쿼드를 렌더링합니다. 앞서 언급한 "하향식 월드 라이트맵"에서 구운 라이팅이 있습니다.
로컬 라이트 패스
이 패스에서는 포인트 라이트 볼륨에는 로우 폴리 구 모양을, 스포트라이트 볼륨에는 팔면체와 같은 모양을 렌더링합니다. 라이트는 애디티브 블렌딩을 통해 앞뒤로 렌더링됩니다. 불필요한 셰이더 호출을 피하기 위해 이 게임에서는 OpenGL/D3D11의 확장 기능이지만 Vulkan/D3D12의 기본 기능이 된 뎁스 바운드 테스트를 사용합니다. 또한 스텐실 테스트를 사용하여 유리창과 같은 반투명 오브젝트가 소비하는 픽셀을 폐기합니다. 이러한 오브젝트는 포워드 패스에서 렌더링됩니다.
워터 렌더링 그리고 반사.
이 글에서는 워터 렌더링에 대해서는 특별한 블로그 포스팅이 필요하기 때문에 다루지 않겠습니다. 하지만 리플렉션에 대해 조금 이야기하고 싶습니다:
- 앞서 언급한 것처럼 환경 맵은 리플렉션의 주요 소스입니다. 창 리플렉션과 같은 일반적인 리플렉션의 경우 게임에서 이를 사용합니다.
- 반면 거울은 반사 방향에서 씬을 다시 렌더링하는 평면 리플렉션으로 렌더링됩니다. 이 프로세스도 디퍼드 렌더링으로 처리됩니다.
- 물 반사는 프레임 시작 시 생성된 환경 맵과 결합된 화면 공간 반사를 사용합니다.
포워드 렌더링 스테이지.
디퍼드 렌더링 파이프라인의 단점 중 하나는 GBuffer로 반투명 머티리얼을 올바르게 렌더링할 수 없다는 것입니다. 이 문제를 해결하기 위해 게임에서는 디퍼드 렌더링을 사용하는 대부분의 게임처럼 반투명 머티리얼을 포워드 셰이딩으로 앞뒤로 렌더링합니다. 하지만 이 포워드 패스는 비용이 많이 들 수 있습니다: 디퍼드 셰이딩 셰이더보다 더 비싼 포워드 셰이딩 셰이더를 사용하기 때문입니다.
셰이더에 사용되는 레지스터 수는 병렬로 실행할 수 있는 셰이더 인스턴스 수와 음의 상관관계가 있습니다. 포워드 셰이딩은 머티리얼과 조명(및 그림자) 계산을 결합하므로 포워드 셰이더에서는 레지스터 수가 많을 수 있습니다.
모든 두꺼운 반투명 개체를 두 번 그립니다.
올바른 블렌딩을 위해서는 오브젝트의 뒷면을 먼저 렌더링하고 앞면을 두 번째로 렌더링해야 합니다. 이 때문에 이 단계의 반투명 오브젝트는 대부분 두 번 그려집니다. 2D 쿼드형 오브젝트(예: 창문)는 한 번 렌더링됩니다.
그리고 모든 추첨 사이에 파이프라인 상태가 변경됩니다.
앞면과 뒷면 컬링 간에 전환하려면 파이프라인 상태를 변경해야 합니다. 그리고 이러한 변경은 비용이 많이 들 수 있습니다.
이 단계에서 블룸 효과를 위해 생성된 또 다른 렌더 타깃이 있습니다. 이 타깃은 블룸의 강도를 저장합니다. 그림에서 볼 수 있듯이 반투명 오브젝트가 더 밝게 빛납니다.
블룸 강도 목표: R8_UNORM
안개가 자욱한 지역에서는 더 많은 빛을 내기 위해 먼 거리에서 블룸 강도가 증가합니다.
후처리
템포럴 안티앨리어싱, 블룸, 모션 블러, 피사계 심도 및 기타 효과가 실행되는 단계입니다. 포스트 프로세싱에 대해서는 다른 블로그 포스팅을 계획하고 있습니다. 그래서 여기서는 많은 이야기를 하지는 않겠지만 블룸에 대해 조금 이야기하고 싶습니다. 이미 볼류메트릭 라이팅 덕분에 메인 렌더링 대상에 빛이 비치고 있습니다.
RDR2 블룸 구현은 콜 오브 듀티: 어드밴스드 워페어의 차세대 포스트 프로세싱에 설명된 구현과 매우 유사합니다.
- 임계값이 없는 타깃을 입력으로 사용하고,
- R11G11B10_FLOAT 7-mip 렌더 타깃,
- 다운샘플링에 13-빌리니어 탭 필터, 업스케일링에 3x3 텐트 필터를 사용합니다.
그런 다음 게임에서 이 필터링된 블룸 타깃을 블룸 강도 타깃과 함께 메인 타깃과 결합합니다.
결론
정말 멋진 라이딩이었어요! 할 이야기가 너무 많지만 이 블로그가 너무 길어지고 싶지 않습니다. 이 모든 것에 대한 제 결론과 그 과정에서 제가 발견한 몇 가지 이상한 점을 공유하고자 합니다.
- 가장 먼저 눈에 띄는 점은 이 게임이 그래픽 전환을 위해 많은 컴퓨팅을 수행하거나 그 반대의 경우도 마찬가지라는 점입니다. 비동기 컴퓨팅을 활성화하면 비동기 컴퓨팅을 사용합니다. (게임 내 설정에서는 비동기 컴퓨팅을 활성화할 수 없습니다. 게임 환경설정 파일에서 활성화해야 합니다.) 예를 들어 블룸 효과의 경우 게임이 컴퓨팅으로 전환하여 일부 작업을 수행한 다음 그래픽으로 다시 전환하여 다운샘플링을 수행하고, 다시 컴퓨팅으로 전환하여 다른 작업을 수행한 다음 다시 그래픽으로 전환하여 업샘플링을 수행합니다. 이러한 '스위치'는 GPU에서 비용이 많이 들지 않나요? 컴퓨팅에서 얻는 이득이 스위치 비용을 정당화할 수 있을까요?
- 또 다른 한 가지는 RDR2가 대부분의 텍스처를 지운다는 것입니다. 일반적으로 게임에서는 불필요한 텍스처 지우기(예: GBuffer 지우기)를 피하기 때문에 이것은 이상합니다. 이러한 "텍스처 지우기"가 성능에 실제 영향을 미칠까요? 이런 텍스처를 지워야 할까요?
- 또 한 가지 이상한 점은 한 프레임에 동일한 깊이 다운샘플 패스가 3개(어쩌면 그 이상)가 있다는 것입니다. 하나는 SSAO용, 다른 하나는 SSR용, 다른 하나는 볼류메트릭 포그와 라이트 샤프트 생성 단계용입니다. 게임에서 다른 스테이지에 SSAO에서 다운샘플링한 뎁스 타깃을 사용하지 않는 이유는 무엇인가요?
오해하지 마세요. 저는 누구를 탓하는 것이 아니라(낮은 프레임 속도에 대해 조금 화가 났지만) 왜 이런 결정이 내려졌는지 이해하려고 노력 중입니다. 결국, 많은 재능 있는 사람들이 이 게임을 위해 열심히 노력했습니다. 게임을 더 최적화할 시간이 충분하지 않았을 가능성이 높습니다.
마지막 한마디
여기까지입니다! RDR2는 보기만 해도 멋진 게임입니다. 그래픽 기술뿐만 아니라 아트, 조명 등 모든 것이 경이롭게 보입니다. 저는 이 게임의 색상 팔레트에 반했습니다. 특히 밤이 되면 겁쟁이 로버트 포드의 제시 제임스 암살, 노인을 위한 나라는 없다, 35mm 카메라로 촬영한 다른 서부 영화가 떠오르기도 합니다. 잘못된 점이 있거나 개선할 수 있는 부분이 있으면 언제든지 연락주세요. 더 많은 정보를 얻게 되면 이 글을 업데이트하겠습니다. 댓글을 달고 공유하고 즐겨주세요.
원문
https://imgeself.github.io/posts/2020-06-19-graphics-study-rdr2/