| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |
- directx
- const
- 2294
- 백준
- 언리얼엔진5
- 1563
- UnrealEngine5
- 티스토리챌린지
- algorithm
- baekjoon
- IFileDialog
- winapi
- DirectX11
- TObjectPtr
- C
- Programmers
- GeeksForGeeks
- UnrealEngine4
- 오블완
- C++
- 팰린드롬 만들기
- RVO
- UE5
- RootMotion
- NRVO
- Effective C++
- Unreal Engine5
- 프로그래머스
- 줄 세우기
- softeer
- Today
- Total
Game Develop
[UE5] 많은 몬스터 최적화. (Animation Budget Allocator) 본문
많은 몬스터를 스폰시키면서 프레임을 지키려면 어떻게 해야할까..?
기본적으로 엔진자체에서 해주는 프러스텀컬링, 오클루젼컬링, 뭐 거리기반으로 하는 컬링.. 그리고 Precomputed Visibility Volumes 이라고, 생소한 최적화도 있다.
번역으로는 사전 계산된 가시성 볼륨... 인데, 특정 구간을 이 볼륨으로 씌우고, 그 공간에 한해서 '이 위치에 플레이어가 있을 때, 어떤 물체들이 보이는지 안 보이는지를 미리 기록' 해 두는 볼륨상자라고 표현 할 수 있다고 한다.
그냥 런타임중에 실시간 계산하면 비용이 많이 드니, 미리 계산했다가 런타임 때 기록되어진 테이블을 조회만 해서 렌더에서 제외하는 방식이다라고 한다.
그러다 보니 동적메쉬보다는 스태틱메쉬위주로 적용되는 컬링방식이라는데, 무조건 스태틱메쉬에만 되는 건 아니라고 한다.
뭔가 좀 생소한 컬링을 접하다 보니 이야기가 길어졌는데, 어쨌든 이런 기본적인 최적화들이 잘 되고 있는지 체크하기 위한 방법 중 하나로는 그냥 몬스터같은거 많이 스폰시키고 카메라로 비췄을 때와 안비췄을 때의 프레임을 보면 된다.
아래는 96마리 몬스터 스폰시켰을 때 프레임.

20 극후반에서 30 초반 왔다갔다 한다.
아래는 같은 상황에서 카메라만 돌렸을 때.

거의 2배차이 난다.
카메라에서 안보이니 굳이 메쉬를 렌더링 할 필요가 없기 때문에 증가하는 것인데, 여기서 중요한 점은 게임스레드에서 동작하는 애님인스턴스의 틱은 여전히 호출한다는 것이다.
C++쪽에서 NativeUpdateAnimation을 오버라이드해서 로그 찍어보면 확인할 수 있는데, 카메라로 몬스터를 안비춰도 여전히 호출한다.
보통 이 틱함수에다가는 블루프린트에서 사용할 값들을 업데이트 해주는 코드를 넣고들 한다. 블렌드스페이스에 사용할 속도값이라던가 기타 등등...
어쨌든 이 틱함수는 여전히 호출하기 때문에, 만약 렌더가 안되는 상황이더라도(위의 경우처럼 카메라 바깥이라던가) 반드시 호출해야하는게 아니라면 이 틱함수도 막아주는게 좋다. (어디서든 최적화의 기본은 불필요한 틱함수 호출을 막는 것이다)
이건 단순히 옵션설정으로 할 수 있는데, Mesh컴포넌트를 가져와서 아래처럼 해주면 된다.
GetMesh()->VisibilityBasedAnimTickOption = EVisibilityBasedAnimTickOption::OnlyTickPoseWhenRendered;
단어 그대로, 렌더 될 때만 틱을 호출한다는 의미이다.
저 옵션을 했을 때랑 안했을 때랑 한번 UE_LOG로 찍어보면 실제로 호출하는지 안 하는지 알 수 있다.
현재 내 프로젝트의 경우, 애님인스턴스 틱에서 뭐 하는건 없어서 저 옵션 켜두면 아주 미세하게 프레임 오른다.
아예 안오르는 줄 알았는데, 몇번 비교해보니까 2,3프레임정도? 오르긴 하는 것 같다.
아마 NativeUpdateAnimation에서 어떤 걸 수행하느냐에 따라서 카메라로 안 비출 때 프레임이 더 오를 것이다.
현재 내 코드에선 스피드값이랑 지면인지 아닌지 체크하는 bool값들 등 정도만 업데이트 해준다.
사실 이제부터가 본론인데, 여기서 좀 더 추가적인 최적화로 ABA (Animation Budget Allocator)가 있다.
언리얼 공식문서에 있으니 일단 한 번 보는 걸 추천한다.
쉽게 말하자면, 동적으로 스켈레탈 메쉬 컴포넌트의 틱 빈도수를 조절하는 것이다.
기준은? 기본적으로는 현재 뷰포트에 해당하는 카메라이다. 이 카메라와 가까우면 가까운 스켈레탈 메쉬 컴포넌트에 좀 더 많은 예산을 할당해서 스켈레탈 메쉬 컴포넌트의 틱 빈도수를 올린다. 즉, 부드럽게 재생한다.
멀면 반대로다.
즉 가까운 스켈레탈 메쉬 컴포넌트는 중요하다고 판단되니 예산을 더 할당해서 틱호출을 많이 하는 것이고, 먼 것은 반대로 하는 것이다.
이 판단의 기준은 개발자가 따로 지정해줄 수 있다. (공식문서 참고)
위 영상을 보면, 캐릭터(카메라) 바로 앞의 몬스터는 부드럽게 재생되는 걸 확인할 수 있다.
그런데 맨 끝, 화면 기준 오른쪽끝에 있는 몬스터를 잘 보면 굉장히 버벅인다. 틱 호출을 줄여서 그런거다.
중간에 캐릭터(카메라)를 끝으로 이동시키면, 마찬가지로 카메라랑 가까운놈은 부드럽고 멀리 있는 놈은 버벅인다.
반드시 멀리있는 몬스터들까지 부드럽게 해야한다는 것만 아니면, 성능을 챙기기에 매우 좋다.
뭐 호출빈도라던가 예산할당 옵션같은 것들은 공식문서에 잘 나와있다. 나도 딱 여기까지만 해보긴 했는데, 이 ABA를 켰을때랑 안켰을때랑 꽤 차이난다. 거의 8~10프레임??
실제로 카트라이더 드리프트에도 적용한 검증된 최적화이니, 적극적으로 사용해보자.
'UnrealEngine5 > Client' 카테고리의 다른 글
| [UE5] 포스트프로세스 기본적인 설정. (1) | 2025.11.14 |
|---|---|
| [UE5] 디테일패널 커스텀할 때 사소한 주의사항 (0) | 2025.10.16 |
| [UE5] 포스트프로세스 머터리얼에 파라미터 값 넘길 때 주의할 점. (0) | 2025.09.01 |
| [UE5] EnhancedInput에서 BindAction할 때 추가 매개변수 넘기기 가능하다. (0) | 2025.04.03 |
| [UE5] 로우포인터대신 TObjectPtr을 써야하는 이유? (0) | 2025.04.02 |