FShaderCache

FShaderCache 로 게임내 셰이더 버벅임 현상을 감소시킬 수 있습니다.

Windows
MacOS
Linux

개요

FShaderCache (셰이더 캐시)는 게임내 셰이더 버벅임(hitch)을 감소시킬 수 있는 방법을 제공해 줍니다. OpenGLDrv 와 MetalRHI RHI 를 지원하며, Mac, Linux, Windows 플랫폼에서 작동합니다.

FShaderCache 기능을 켜고 끄는 데 사용할 수 있는 콘솔 명령이 여럿 있습니다.

콘솔 명령

설명

r.UseShaderCaching [0/1]

  • 요청이 있을 경우만이 아닌, 셰이더 deserialisation 도중 이른 제출을 합니다.

  • 이른 제출 도중 미리 바운딩이 가능하도록 바운드 셰이더 상태의 기록을 유지합니다.

r.UseShaderDrawLog [0/1]

각 바운드 셰이더 상태를 미리 그릴 수 있도록 하기 위한 RHI 그리기 상태에 대한 트래킹 기록입니다.

r.UseShaderPredraw [0/1]

첫 사용 버벅임 제거를 위해 트래킹 기록된 RHI 그리기 상태의 미리 그리기입니다.

r.PredrawBatchTime [(ms) 단위 시간]

각 프레임을 미리 그리는 데 소모되는 시간을 제어하여 필요에 따라 여러 프레임에 분산시킵니다.

r.UseShaderBinaryCache 0/1

모든 셰이더 바이트 코드를 하나의 캐시 파일로 누적시킵니다.

r.UseAsyncShaderPrecompilation 0/1

게임플레이 도중의 셰이더 코드 비동기식 미리 컴파일입니다.

r.TargetPrecompileFrameTime [(ms) 단위 시간]

r.UseAsyncShaderPrecompilation 옵션을 켰을 때 유지시킬 목표로 할 최대 프레임 시간입니다. -1 이면 모든 셰이더를 한꺼번에 미리 컴파일합니다.

r.AccelPredrawBatchTime [(ms) 단위 시간]

로드 화면처럼 상호작용이 없는 모드에 있을 때의 미리 그리기를 임시 가속시키는 옵션입니다. r.PredrawBatchTime 사용을 위해서는 0 을 사용하세요.

r.AccelTargetPrecompileFrameTime [(ms) 단위 시간]

로드 화면처럼 상호작용이 없는 모드에 있을 때의 비동기 미리 컴파일을 가속시키는 옵션입니다. r.TargetPrecompileFrameTime 사용을 위해서는 0 을 사용하세요.

r.InitialShaderLoadTime [(ms) 단위 시간]

실행시 이만큼 셰이더 로딩을 기다리다가 비동기 컴파일로 넘어갑니다. -1 은 동기식 로드입니다.

사용

개발 머신에서 r.UseShaderCachingr.UseShaderDrawLog 를 켬으로써 캐시가 채워질 것입니다. 그 후 사용자/플레이어는 r.UseShaderCachingr.UseShaderPredraw 를 켜서 캐시를 소모합니다. 그리기 로깅은 (r.UseShaderDrawLog) 고정 부하가 눈에 띄게 추가되므로, 가급적 발매 제품에는 켜지 마시기 바랍니다. 바이너리 셰이더 캐시는 플레이 도중, 또는 (현재 Mac 타깃 전용인) Engine.ini 의 /Script/MacTargetPlatform.MacTargetSettings 세팅 그룹 내 CachedShaderFormats 배열에 캐시에 저장할 셰이더 플랫폼을 저장하는 것으로 쿠킹 도중에 누적시킬 수도 있습니다. OpenGL 의 경우 바이너리 캐시에는 셰이더 파이프라인 관련해서 (GL_ARB_separate_shader_objects 가용성에 따라) GL 프로그램 파이프라인 또는 완전 링크된 GL 프로그램을 생성하기에 충분한 데이터가 들어있으나, 다른 RHI 에서의 파이프라인 생성을 위한 데이터는 충분치 않습니다. 이로써 게임을 먼저 한번 플레이하지 않아도 OpenGL 에서의 버벅임을 줄이는데 도움이 됩니다. 물론 최대한의 효과를 위해서는 먼저 플레이하는 방법이 여전히 좋기는 합니다. 캐시는 셰이더 해시를 통해 이루어지므로, 콘텐츠가 거의 끝났을 때 최종 최적화 도구로만 사용하는 것이 좋습니다. 셰이더 해시가 변경되면 캐시에 미사용 항목이 쌓여, 버벅임 감소는 없이 캐시 크기만 늘어나기 때문입니다.

코드는 먼저 쓰기가능 캐시를 시도하여 로드한 뒤, 필요한 경우 배포 캐시로 예비 적용됩니다.

캐시 유형

캐시 위치

Writable 쓰기가능

<Game>/Saved/DrawCache.ushadercache, <Game>/Saved/ByteCodeCache.ushadercode

Distribution 배포

<Game>/Content/DrawCache.ushadercache, <Game>/Content/ByteCodeCache.ushadercode

통합 방법

프로젝트의 버벅임 감소를 위해 사용할 수 있는 콘솔 명령이 다수 있기는 하지만, 옵션을 켜는 데 있어 부가적인 프로젝트 작업을 피하면서도 퍼포먼스를 최대화시키기 위한 추천 우선 순서가 있습니다.

  1. 모든 사용자의 프로젝트 환경설정에서 r.UseShaderCaching & r.UseShaderPredraw 옵션을 켭니다.

  2. 가능하면, 내부 빌드용으로만 r.UseShaderDrawLog 옵션을 켜고, 각 릴리즈의 최종 QA 도중 셰이더 드로 상태를 기록하도록 합니다. 가능하지 않은 경우 (규모가 너무 크다던가 스트리밍 게임인 경우), 모든 사용자에게 켭니다.

이 구성으로 버벅임이 적정 수준으로 감소되는지 테스트합니다. 이 외의 최적화는 부가적인 작업이 필요하며 심각한 부작용이 있을 수 있습니다.

  1. 위의 방법이 충분치 않은 경우, r.UseShaderBinaryCache 옵션도 켜고 (현재 Mac 전용인) 바이너리 캐시를 채우도록 CachedShaderFormats 설정을 합니다.

  2. 모든 셰이더 코드가 이제 시작시 로드되고, 모든 미리 그리기 작업이 첫 프레임에 일어나므로, 로드 시간이 너무 긴 경우 r.PredrawBatchTime 를 0 이상의 값으로 설정하여 각 프레임 미리 그리기에 들어가는 시간을 할당해 줍니다.

  3. r.AccelPredrawBatchTime 에 보다 큰 값을 지정하여 로드 화면과 같은 상호작용이 없는 콘텐츠를 표시할 때 적용시킬 수 있습니다.

  4. 게임 프레임 속도를 희생시켜 미리 그리기를 가속시키라고 셰이더 캐시에 알려주기 위해 FShaderCache::BeginAcceleratedBatching 을 호출하고, 비용이 덜한 미리 그리기 일괄처리 방식으로 돌아갈 필요가 있으면 FShaderCache::EndAcceleratedBatching 을 호출해 줍니다.

  5. FShaderCache::FlushOutstandingBatches 호출은 나머지 모든 셰이더가 다음 프레임에 처리되도록 합니다.

  6. 여전히 프로젝트 초기 로드 시간이 너무 오래 걸리는 경우, r.UseAsyncShaderPrecompilation 옵션을 켜고 r.InitialShaderLoadTime 을 0 이상의 값으로 설정합니다. 초기 셰이더 로드 시간은 게임 실행중에 해야 하는 작업량과 반비례합니다.

  7. 셰이더 비동기식 미리 컴파일 도중의 원하는 목표 프레임 시간 조정은 r.TargetPrecompileFrameTime 값 변경을 통해 가능합니다.

  8. 미리 그리기 일괄처리와 마찬가지로 미리 컴파일에도 보다 적극적인 값을 지정할 수 있는데, r.AccelTargetPrecompileFrameTime 에 보다 큰 값을 설정하고 FShaderCache::BeginAcceleratedBatching (, 이어서 FShaderCache::EndAcceleratedBatching) 을 호출하면 됩니다.

  9. r.UseAsyncShaderPrecompilation 를 켠 상태에서 FShaderCache::FlushOutstandingBatches 를 호출하면 현재 걸려있는 컴파일 요청을 전부 비우기도 합니다.

업데이트/무효화 처리

캐시의 업데이트와 쓰시가능 캐시의 무효화가 필요한 경우, 게임은 새로운 GameVersion 을 지정해야 합니다. FShaderCache::SetGameVersion 를 호출한 뒤 (캐시를 초기화시키는) RHI 를 초기화시킵니다. 그러면 이전 버전에서 생성된 캐시 내용을 무시합니다. 현재 이전 버전에서의 캐시 항목을 가지고 넘어가는 방법은 없습니다.

리전/스트림 배치

스트리밍 게임의 경우, 또는 캐시가 매우 커 지는 경우, FShaderCache::SetStreamingKey 로의 호출은 (필요에 따라) 현재 관련된 게임 리전/스트리밍 레벨에 대한 고유 값으로 추가시켜야 합니다. 로그에 기록된 그리기 상태는 활성 스트리밍 키에 링크됩니다. 이를 통해 잇따르는 실행의 활성 스트리밍 키에 필요한 그리기 상태에만 미리 그리기를 제한시킵니다.

태그

새로운 언리얼 엔진 4 문서 사이트에 오신 것을 환영합니다!

문서 사이트에 대한 의견을 모을 수 있는 피드백 시스템을 포함해서 여러가지 새로운 기능을 준비하고 있습니다. 아래 Documentation Feedback 포럼(영문) 또는 언리얼 엔진 네이버 공식 카페(한글) 중 편하신 곳에 의견이나 문제점을 알려 주세요.

새 시스템이 준비되면 알려 드리겠습니다.

네이버 카페
공식 포럼