광대 한 이미지로 인해 또는 스프라이트 시트를 사용해야합니까?


13

2D 게임을 개발 중이며 많은 스프라이트가 있습니다. 3D 애니메이션과 모델을 사용하여 2D로 렌더링하여 "폴 아웃"또는 "Diablo"가 보이도록했습니다. 손으로 그리는 것보다 쉽습니다.

나는 이미 프레임 속도를 15fps로 줄여야했다. 그러나 24 프레임이 매우 매끄럽게 보였기 때문에 슬 sad습니다.

내가 한 두 가지 이유가 있습니다.

1) HDD 공간을 줄입니다. 이미지가 적을수록 총 게임 수가 줄어 듭니다.

2) RAM 소비를 줄입니다. 로드 할 이미지 수가 적을수록 RAM 제한이 부풀려지는 문제를 피할 가능성이 높습니다.

그러나 HDD 공간과 RAM 모두에서 이미지를 압축하는 방법이 있다면 그렇게 할 것입니다. 나는 전에 그것을 테스트했으며 RGBA8888에서 RGBA5555로 줄 때 품질에 변화가 없으며 대부분 TexturePacker 프로그램에서 RGBA4444로 변환 할 때 약간의 타격을받습니다. SFML은 어떤 유형의 .PNG 이미지 유형에 관계없이 동일한 양의 메모리를 사용하는 것으로 보이므로 현재이 작업을 수행하지 않습니다. 나는 그것을 다르게로드하는 방법을 연구했지만 주제에서 아무것도 찾지 못했습니다.

2D 비디오 게임을 처리하는 방법에 대해 많이 읽었습니다. 합의는 압도적입니다. 스프라이트를 더 큰 질감으로 포장하여 뛰어난 성능을 발휘하십시오! 그래서 TexturePacker를 사용하여 작은 스프라이트를 훨씬 큰 스프라이트 시트로 포장합니다.

그러나 캐릭터 당 10-15 애니메이션, 5 방향 이동 및 애니메이션 당 15-40 프레임 (아마도 평균 24)을 계획하고 있습니다. 15 개의 애니메이션, 5 개의 방향 및 애니메이션 당 평균 24 프레임; 문자 당 1800 개의 개별 프레임입니다. 스프라이트 시트에 포장 된 경우, 그 대신 75 개의 이미지 만 있습니다. (방향마다 15 애니메이션, 애니메이션 당 하나의 스프라이트 시트. 15 * 5)

게임에서 거대한 보스 캐릭터 한 명을 위해 스프라이트 시트를 사용할 수 없으며 한 번에 한 이미지에 간단히로드하는 방법을 프로그래밍해야합니다. 아직 성능을 위해이 작업을 수행 할 수 있는지 모르겠습니다.

캐릭터의 경우 이미 스프라이트 시트에 포장합니다. 한 명의 캐릭터가 걸어 다니는 경우가 많지만 때로는 정지합니다. 그러나, 나는 그 캐릭터에 대한 모든 텍스처를 미리로드하는 대신 텍스처를 교체하는 잘못 생각한 코드에 기인한다고 생각합니다.

텍스처를 미리로드하려면 스프라이트 시트에 적합합니다. 각 캐릭터마다 1800 개의 작은 이미지를 미리로드하는 것은 나쁜 생각이라고 생각합니다.

그러나 한 번에 하나씩 메모리에 스트리밍하는 것이 매우 빠르다고 생각하므로 한 번에 메모리에 단일 이미지 만 있으면됩니다. 이것은 주어진 순간에 각 문자가 45 + MB 대신 몇 KB를 소비한다는 것을 의미하지 않습니까?

스트리밍 속도가 엄청나게 빨라야하고 (초당 15 개의 이미지가 메모리로 들어오고 나가고 렌더링되는 속도) 이미지가 매우 작을지라도 캐릭터 스프라이트 시트를로드하는 것이 더 좋습니다. 대신 메모리에. 그러나 어쨌든 더 큰 보스 캐릭터를 위해 단일 이미지 스트림과 같은 렌더링 시스템을 코딩해야합니다.

나는 실험을 해왔지만 간단한 과정은 아니다. 특히 그래픽을 다루지 않는 게임 엔진의 다른 부분에서 작업하고 있다는 사실을 감안할 때.


1. RAM 또는 HDD 제약 조건을 지정하지 않았습니다. 빠르게 액세스 할 수있는 캐릭터는 몇 명입니까? 2. 본문에 몇 가지 질문이 있는데, 굵게 표시하거나 질문을 부분적으로 나눌 수 있습니까?
Kromster

아 죄송합니다 많지 않습니다. 한 번에 화면에 표시되는 최대 개별 문자 수는 약 40 명이라고 생각할 수 있습니다. 사람들이 클라이언트를 충돌 시키려고한다면 130이 절대 최대 값입니다. 일반적으로 일반적인 최대 값은 10 만 있으면되고 절대 최대 값은 <40 이하입니다. 40을 초과하는 것은 엄청나게 희귀하며, 사용자는 스크린 샷이나 캐릭터가 재미를 느끼는 것 이외의 이유로 캐릭터를 의도적으로 몰아 넣습니다. 10을 초과하는 것은 거의 없으며 40 정도는 매우 극도로 드물다.
Carter81

이 게임은 PC 전용 (모바일 없음) 2D 롤 플레잉이지만 모바일 플랫폼이 불가능하지 않으면 모바일 플랫폼을 배제하고 싶지 않습니다. 내가 가지고있는 RAM 공간은 사용자의 PC와 사용자의 VRAM에있는 RAM으로 제한되어 있다고 생각합니다. 나는 그것이 현명한 HDD가 될 것이라고 의심합니다. HDD 소비가 작을수록 좋다는 것이 항상 사실입니다.
Carter81

화면에 몇 개의 고유 문자가 있어야합니까?
Kromster

20 세 이하입니다. 부정 행위를하지 않는 이상 불가능할 것입니다. 일반적으로 5-10.
Carter81

답변:


16

RTS 리메이크와 비슷한 경우가 있습니다. 모든 유닛과 주택은 스프라이트입니다. 유닛과 주택 및 지형에는 18,000 개의 스프라이트와 팀 색상 (마스크로 적용됨)에 대해 ~ 6,000이 추가됩니다. 길게 늘여서 글꼴에 ~ 30,000 문자가 사용되었습니다.

아틀라스의 주요 이유는 다음과 같습니다.

  • 적은 RAM 낭비 (이전에는 NPOT를 GPU에 업로드 할 때 POT로 확장 / 패딩했습니다 .iOS 및 일부 프레임 워크에서 여전히 동일하다는 것을 읽었습니다. 대상 하드웨어 범위를 더 잘 확인하십시오)
  • 적은 텍스처 스위치
  • 더 적은 청크로 모든 것을 빠르게 로딩

우리에게 효과가 없었던 것 :

  • 팔레트 텍스처. 이 기능은 OpenGL 1.x 2.x에만 존재했으며 심지어 GPU 제조업체에 의해 대부분 중단되었습니다. 그러나 OpenGL + Shaders를 목표로하는 경우 셰이더 코드를 사용하면됩니다.
  • NPOT 텍스처, 우리는 잘못된 테두리와 흐릿한 스프라이트 문제가 있었는데, 픽셀 아트에서는 용납 할 수 없습니다. RAM 사용량도 훨씬 높았습니다.

이제 우리는 수십 개의 1024x1024 아틀라스 (현대 GPU는 더 큰 크기를 지원함)로 포장되어 있으며 ~ 300mb의 메모리만으로도 잘 작동합니다. 이는 PC 게임에 아주 좋습니다. 우리가 가진 일부 최적화 :

  • RGBA8 (바둑판 그림자) 대신 RGB5_A1을 사용하도록 사용자 옵션 추가
  • 가능하면 8 비트 알파를 피하고 RGB5_A1 형식을 사용하십시오.
  • 스프라이트를 아틀라스에 단단히 묶습니다 (빈 패킹 알고리즘 참조)
  • HDD에서 하나의 청크로 모든 것을 저장하고로드합니다
  • 하드웨어 압축 형식 (DXT, S3TC 등)을 사용해 볼 수도 있습니다.

모바일 장치로의 이동을 진지하게 고려할 때 제약 조건에 대해 걱정할 것입니다. 지금은 게임을 작동시키고 플레이어를 유치하십시오! ;)


이것은 지금까지 최고의 솔루션이었습니다! 내 스프라이트는 RGB5_A1 또는 RGBA4444에서 전혀 다르게 보이지 않지만 메모리를 절약합니다. RAM 및 VRAM에 모든 자산을 사전로드하기위한 채팅 제안은 완벽합니다. 또한 RAM이있는 사용자를위한 고해상도 클라이언트 또는 프레임 속도를 절반으로 줄이는 옵션과 같은 선택적 그래픽 수준을 제안했습니다.
Carter81

5

여기에 접선 적으로 관련된 대답이 있지만 일반적인 아이디어는 다른 시간에 텍스처를로드하고 그리는 경우 (렌더링하는 동안 추가 텍스처를로드하지 않는 경우) 두 위치가 있다는 것입니다 성능에 영향을 미칩니다.

로딩 시간 :

텍스처를 메모리에 업로드하는 순간입니다. 전체 는 VRAM에 전송되는 데이터의 양이 대부분 귀하의 로딩 시간이 될 것입니다 시간을 정의 할 것입니다. RGBA4444와 같이 텍스처의 형식을 더 작게 만들면 더 빨라집니다. 그러나 최고 수백 메가 바이트의 텍스처를 VRAM에 업로드하지 않으면 병목 현상이 발생하지 않을 수 있습니다. 그렇다면 로딩 화면이 좋으면 기다릴 수 있습니다.

텍스처를 아틀라스에 결합하면 VRAM으로 보내는 전체 정보의 양이 동일하므로 효과가 거의 없습니다. 실제로 텍스처를 아틀라스에 아틀라스에 빈 공간을 남겨 두어야하는 경우 실제로 VRAM에 더 많은 데이터를 보내므로이 부분이 느려집니다!

렌더링 성능 :

모든 텍스처가 VRAM에 있으면 텍스처의 양은 렌더링 성능에 영향을 미치지 않습니다. 렌더링 성능에 영향을주는 네 가지 요소가 있습니다.

  1. 렌더 상태 변경 : 렌더링하려는 이미지를 변경할 때마다 렌더링에 필요한 시간이 크게 늘어납니다. 일반적으로 상태 변화량을 최소화하고 연속적으로 그릴 여러 이미지를 텍스처 아틀라스로 그룹화하여 상태 변화량을 줄일 수 있습니다.

    아틀라스만으로는 충분하지 않습니다. 성능 향상을 얻으려면 상태 변경을 줄이는 방식으로 아틀라스를 사용해야합니다. 예를 들어 스프라이트 시트에 주인공이 있으면 성능이 향상 될 것이라고 생각할 수 있지만, 프레임 당 스프라이트 시트에서 스프라이트를 하나만 그리면 성능이 향상되지 않습니다. 각 스프라이트는 별도의 파일에 있습니다.

    적절한 아틀라스는 사소한 것이 아니지만 일반적으로 동일한 레이어에서 스프라이트를 안전하게 그룹화 할 수 있습니다. 예를 들어, 하나의 스프라이트 시트에 모든 GUI 항목을 갖는 것은 매우 유망한 아이디어이지만 괴물을 알파벳순으로 그룹화하지 않을 수도 있습니다.

  2. 드로우 콜 : 일반적으로 드로우 콜을 최소로 유지할 수 있습니다. 일반적으로 두 드로우 콜간에 렌더 상태 변경이없는 경우 단일 드로우 콜에 참여할 수 있습니다. 보다 향상된 성능 향상을 위해 8 개의 텍스처 샘플러 및 8 개의 텍스처마다 그룹 그리기 호출을 사용할 수 있으므로 8 개의 텍스처마다 텍스처 만 변경하면됩니다.

  3. 삼각형 수 : 사실, 더 많은 삼각형을 그릴수록 더 오래 걸립니다. 그러나 최신 컴퓨터와 대부분의 2D 게임에서는이를 최대한 활용하지 못합니다. 프레임 당 수십만 개의 스프라이트를 안전하게 그릴 수 있지만 여전히 좋은 프레임 속도를 얻을 수 있습니다. GPU에 문제가 발생하기 전에 많은 양의 스프라이트를 그리는 경우 CPU에 더 많은 관심을 가질 것입니다.

  4. API 설정 : 모든 작업을 올바르게 수행하고 프레임 속도가 이상하게 낮은 경우 스프라이트를 그리는 설정을 확인하십시오. SFML을 모르지만 예를 들어 Direct3D 9에서을 사용하여 정점 버퍼를 만들 D3DUSAGE_DYNAMIC거나으로 D3DPOOL_MANAGED렌더링 시간을 10 배 쉽게 늘릴 수 있습니다. 물론 vSync를 사용하면 모니터 재생률로 프레임 속도가 제한됩니다. 또한 정렬되지 않은 FVF를 사용하면 일부 GPU에서 성능이 저하 될 수 있습니다. Direct3D 9도 마찬가지입니다.

    귀하의 경우 사용중인 API 설명서를 확인하십시오.

텍스처의 양이 적거나 중간 정도 (1GB 미만)이고 적은 양의 스프라이트 (프레임 당 백만 미만)를 그리는 경우 API 설정을 변경하는 첫 번째 방법은 그런 다음 렌더 상태의 양을 줄이고 호출을 그립니다.


로드 시간에 신경 쓰지 않는다면 RAM 또는 VRAM이 부족하지 않으면 미리 모든 것을 메모리에로드해야한다고 가정해야합니까?
카터 81

RAM / VRAM이 부족한 것을 두려워하기 때문에 모든 것에 대해서만 관심이 있습니다. 이유를 모르겠지만 게임을 플레이하는 사용자가 너무 많은 고유 한 스프라이트가있는 영역에로드하려고 할 때마다 충돌하거나 너무 많은 문자가 화면에 표시 될 때마다 충돌한다는 점을 이해합니다. 내가 실수하지 않고 각 개별 스프라이트가 96KB를 소비하는 경우 각 고유 문자에 15 개의 애니메이션, 5 개의 방향 및 애니메이션 당 평균 24 프레임이있는 경우 완전히로드 된 각 개별 문자는 173MB입니다. 한 번에 10 개의 고유 문자가 화면에있을 수 있습니다.
카터 81

@KromStern : 아틀라스를 비우고 빈 공간 (패딩)을 남겨 두어야하는 경우 데이터가 커지고로드 시간이 길어집니다. 로딩 시간이 길어지는 원인은 빈 공간이며 총 로딩 시간은 텍스처의 양이 아니라 총 데이터 양과 관련이 있음이 분명합니다. 나는 거기에 오도 된 것을 보지 못했고, 원래 질문을 이해하기에 충분한 지식을 가진 사람은 점과 합쳐서 텍스처와 아틀라스가 PoT 및 nPoT 인 모든 경우에 대해 자신의 결론을 내릴 수 있다고 생각합니다.
Panda Pajama

1
@ Carter81 : "i5, 1gb RAM, NVidia GT260, 400mb hdd"와 같은 대상 하드웨어 구성을 선택해야합니다. 항상 약하고 RAM이 적은 PC가있을 것입니다.
Kromster

분명히, 그들은 주어진 시간에 15 개의 애니메이션을 모두 필요로하지는 않습니다. 그러나 10 개의 고유 한 캐릭터가 모두 동시에 "전투 모드"로 들어가서 5 개 세트 (전투, 전투 유휴, 전투 등)? SFML을 사용하여 시도 했을 때 텍스처 아틀라스를 전환 할 때 클라이언트 가 눈에 띄게 멈추 거나 일시 중지 되었기 때문에 텍스처 스왑이 두렵습니다 . 너무 많은 스프라이트를 처리하는 다양한 전략으로 병목이 무엇인지 알 수 없습니다.
카터 81
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.