겜브리오 데이터 최적화 작업 by 김윤정

아무래도 작업 초반부터 최적화를 고려하지 않을 수 없는 관계로
이것저것 테스트 하면서 결과를 만들어 내고 있습니다.

겜브리오 메뉴얼에 데이터 최적화 방법에 대해 나와있긴 하지만 다소 추상적인지라...
정말로 어느 정도가 되는지 테스트를 직접 해보고 있습죠.




















기본적으로 드로우 콜을 줄여야 빨라지는 것은 사실인데, 겜브리오는 각 노드별로 오브젝트를 드로우하기 때문에 노드를 줄이는데 총력을 기울여야 하니까요. 다른 엔진은 어떤 단위로 드로우 하나요?

이 데이터는 데이터 자체가 외부에 공개할 수 있는 수준이 아니라서 (...위험한 내용이 많...) 작게 줄였습니다 이히히히 
테스트 방법은 기초 테스트로 데이터를 취합하고 이걸 가지고 가설을 수립한 다음 실제 제작된 데이터를 이용해 최적화 테스트를 하는 방법입니다.
여러 가지 케이스로 데이터를 만든 다음에 가장 좋은 조건을 찾아내는 거랄까요.
확실히 이런 일은 프로그래머도 알고 싶어하고 그래픽 디자이너도 알고 싶어하는데 어느 쪽에서 테스트 할지 정확히 알 수 없는 - 프로그램 쪽 개념과 그래픽 데이터를 실무수준으로 만질 수 있어야 하는 - TA 쪽에서 해야 될 일 답더라고요 (사실 어떤 일이건 잡으면 TA일이긴 하지만)

확실히 결과가 나오니까 그래픽 데이터 제작 가이드를 만들기 좋군요. 허용 범위도 확실해지구요.
게다가 알게 된 것도 있고, 확실하게 기억하게 된 것도 있습니다 :)

아참, 부사수 한 명 생겼습니다. 배경팀부터 시작해서 전 그래픽 팀을 돌면서 무사수행하게 시켜야 겠어요 ㅋㅋㅋ

덧글

  • 그레이오거 2010/05/03 12:32 #

    헐 머리아픈일 하시네요. 프로그래머도 이거 레알 테스트해보는 경우는 드문데...;;
    사실 이미 폴리곤 수보다는 dpcall 수가 관건이 된지 오래입니다. dpcall은 그래픽 카드별로 일정 숫자를 넘어버리면 프레임이 큰 폭으로 떨어져버리거든요. 또한 카드별로 허용범위가 다르다보니 프로젝트 초기에 명확히 가이드라인을 정하고 넘어가지 못하면 나중에 제대로 피볼 수가 있는 부분입니다.
    알아두셔야 할 점은 dpcall은 버텍스버퍼에 밀어넣어지는 실제 메쉬데이터를 가진 지오메트리만 카운팅된다는 점입니다. 즉 노드(더미)는 백만개가 있어도 dpcall 자체에는 전혀 부하를 주지 않습니다. 반면 멀티서브오브젝트의 경우 디자이너 눈에는 하나지만 실제로는 재질단위로 각각 따로 카운팅 들어갑니다. 또한 방심했다간 뒤통수 제대로 까이는게 UI죠. 특히 텍스트를 어떤 방식으로 찍는지 반드시 확인해보세요. 이 외에도 하나하나 체크해보면 의외로 많이 먹는 넘들이 있습니다. 그래서 가이드라인 잡을 때 이런것들도 반드시 합산되어 고려되어야 합니다.
    대부분의 엔진에서 오브젝트 추려내는 방식은 프러스텀 컬링 + 오클루전 입니다. 프러스텀 컬링의 효율성을 높여주는 공간관리 기법으로 쿼드트리, 옥트리, 포탈 등이 있고 겜브리오의 신그래프도 그 중 하나의 방식입니다. 뭐가 좋다기보다는 어떤 상황이냐에 따라 장단점이 결정됩니다. 실무적으로는 메쉬를 얼마나 잘 쪼개주냐도 정말 중요하지요. 오브젝트당 적절한 폴리곤 수도 의미가 있습니다.
    http://developer.nvidia.com/docs/IO/8230/BatchBatchBatch.pdf
    <- nVidia에서 배포한 로우레벨 최적화의 바이블이라 불리는 문서입니다. 워낙 유명한거라 이미 보셨을지도 모르겠네요.
    일반적인 로우레벨 가이드라인의 순서는,
    0. 타겟 하드웨어 결정 ->타겟 하드웨어가 커버하는 사양 파악
    1. 게임 특징을 고려한 공간관리 기법 결정 -> 노드구조와 오브젝트 구조가 결정됨
    2. 파트별 오브젝트/폴리곤/용량 배분
    3. 파트별 사용량을 즉각 카운팅 가능하게 해주는 도구 제작 후 배포
    4. 이 모든 것들을 프로그램&3D 디자이너들에게 스파르타 교육(어길시 즉참 강조)
    대충 이정도입니다. -_-)r
    PerfHUD도 좋습니다만 이건 파트별(예>배경, 이펙, 캐릭, 등등) 카운팅을 못하죠. 겜브리오의 경우 ExtraData를 응용하면 상당히 편합니다. 프로그램쪽에서 로드시 오브젝트마다 태그를 달아주고 렌더링시 요 테그로 체크하면 실시간으로 그래픽카드가 실제 일 하고 있는 양을 정확히 알 수 있습니다. 그럼 디자인 팀 내부적으로 트레이딩도 가능하죠.
    '캐릭에서 오브젝트수를 100개 줄였으니 배경이 더 써. 대신 텍스쳐 용량 주련?'
    '즐. 이펙이 가져감. 닥치고 다 내꺼. ㅋㅋㅋ'
    '오브젝트 100개 경매합니다. 텍스쳐 용량과 교환요. 맘에 들면 폴리곤 만개 얹어줌. 선제시 ㄳ'
  • 김윤정 2010/05/03 20:38 #

    오 감사합니다. 확실히 요샌 DPcall이 대세죠. (아직도 폴리곤 수 놀음하면 혼냅니다ㅎㅎ) 노드는 DPcall에 영향을 주지 않는다고요? 흐음 겜브리오 메뉴얼하고는 좀 다른... 멀티 서브 오브젝트들도 노드로 구분된다고 메뉴얼에서 읽은 것 같은데요. UI는 지난 프로젝트에서 매우 고생했던지라, 말씀하시는 바가 뭔지 절절히 깨닫고 있습니다 ㅎㅎ 감사합니다. 이번엔 저희도 프러스텀 컬링과 오클루젼 컬링 모두 이용하고 쿼트드리 사용합니다 :)
    오호... 프로그램에서 로드시 오브젝트마다 태그!!! 멋지군요 !!! 꼭 집어넣도록 하겠습니다 감사합니다 하하하하.
  • 그레이오거 2010/05/04 14:46 #

    아시다시피 DPcall은 D3D의 DrawPrimitive() calling 회수를 의미합니다. 이 함수는 실제로 '이 지오메트리를 그려라'라는 명령이고 따라서 버텍스 정보 같은 렌더링 데이터가 반드시 담겨 있어야 합니다. 겜브리오라면 NiTri... 계열이 대표적으로 여기에 속합니다. 반면 노드는 트랜스폼이나 프로퍼티 등을 가지고 있지만 실데이터는 없습니다. 따라서 dpcall에는 영향을 주지 않습니다. 대신 업데이트시 엔진레벨에서 퍼포먼스를 먹으므로 마찬가지로 남발은 금물입니다. 예를 들어, 오브젝트가 노드 20개와 오브젝트 10개로 구성되어 있다면 최종적으로 업데이트 30개, dpcall 10개로 카운팅됩니다.
    겜브리오 엔진 파이프라인을 보면 크게 4단계로 구분이 되는데요, 첫 단계인 컬링을 거치면 NiVisibleArray에 실제 그려질 지오메트리들만 담기게 됩니다. 노드류는 싹 제거되지요. 이 리스트가 몇 단계를 더 거쳐 실제 그래픽카드에 밀어넣어지기 때문에 매초당 NiVisibleArray에 담긴 지오메트리 개수의 총 합을 구하면 그것이 바로 dpcall 수치입니다.(요즘은 5,6만 선이 일반적이더군요)
    한가지 주의할 사항은, 인스턴싱(데이터 공유)를 해도 dpcall은 따로따로 먹는다는 점입니다. 인스턴싱의 이득은 메모리와 대역폭, 렌더스테이트 감소이지 dpcall에는 전혀 효과가 없습니다. 즉 나무 하나를 천개 인스턴싱해서 배치해도 dpcall은 천개로 잡한다는 것이지요.
  • 김윤정 2010/05/04 15:28 #

    와와 정말 감사합니다 >_< 못알아듣는 것들은 우리 프로그래머들한테 물어봐서 익히도록 하겠습니다 :)
※ 로그인 사용자만 덧글을 남길 수 있습니다.


MyADD

<script> (adsbygoogle = window.adsbygoogle || []).push({}); </script>