광대 한 이미지로 인해 또는 스프라이트 시트를 사용해야합니까? 이미지가 적을수록 총 게임 수가

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 개의 이미지가 메모리로 들어오고 나가고 렌더링되는 속도) 이미지가 매우 작을지라도 캐릭터 스프라이트 시트를로드하는 것이 더 좋습니다. 대신 메모리에. 그러나 어쨌든 더 큰 보스 캐릭터를 위해 단일 이미지 스트림과 같은 렌더링 시스템을 코딩해야합니다.

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



답변

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

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

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

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

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

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

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

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


답변

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

로딩 시간 :

텍스처를 메모리에 업로드하는 순간입니다. 전체 는 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 설정을 변경하는 첫 번째 방법은 그런 다음 렌더 상태의 양을 줄이고 호출을 그립니다.