XNA - 더 나은 그리기 성능을 위해 스프라이트를 병합하시겠습니까?

StackOverflow https://stackoverflow.com/questions/1637086

  •  06-07-2019
  •  | 
  •  

문제

많은 3D 개체를 렌더링할 때 이러한 개체를 병합하여 거대한 메시를 형성하면 단 한 번의 그리기 호출만 이루어질 수 있다는 내용을 어디선가 읽었습니다.따라서 다음을 인용해 보겠습니다."GPU는 마법을 부리는" 반면, 다른 호출에는 CPU가 사용 가능합니다. 그리는 것보다.

그래서 내 질문에, 이것이 가능할까요? 2D 환경 ~와 함께 성능 염두에?

예를 들어, 간단한 타일 시스템이 있고 보기에 있는 각 타일에 대해 그리기 호출을 만드는 대신 모든 타일을 병합 큰 스프라이트를 형성한 다음 그 위에 그리기를 호출합니다.

그래픽 성능에 대한 사전 경험이 없기 때문에 팁, 링크 또는 기타 사항 등 문제에 대한 모든 통찰력을 크게 높이 평가합니다.

편집하다: 설명이 부족해서 죄송합니다.나는 개인적인 용도로 타일 엔진을 만들고 있으며 가능한 한 다용도로 사용하기를 원합니다.따라서 가까운 시일 내에 많은 타일을 그려야 할 경우를 대비하여 최적화하고 싶습니다.

하다 타일시트를 사용하지만 제가 질문에서 의미한 것은 시트에서 그려질 모든 타일을 새로운 Texture2D로 병합하면 성능이 향상되는지 여부입니다.예를 들어:

화면에 그릴 수 있는 타일은 128x72개입니다.모든 타일을 반복하고 그릴 각 타일에 대해 draw를 호출하는 대신 모든 타일을 1280x720 크기의 새 스프라이트로 병합하여 그립니다.이 방법으로 draw() 메서드만 호출됩니다. 프레임당 한 번.나의 질문 3D를 수행할 때 3D 개체를 단일 메시로 병합하므로 성능이 향상되는지 여부였습니다.

내가 수집한 정보에 따르면 draw()를 호출하는 것은 성능을 저하시키며 가능한 한 적게 호출해야 한다는 것입니다.확인하거나 거부할 사람이 있나요?:)

도움이 되었습니까?

해결책

나는 XNA와 3D에 대한 경험이 없지만 2D 게임에 대한 조언을 드릴 것입니다. 나는 올해 초 XNA에서 타일 엔진을 만드는 데 시간을 보냈고 같은 것을 궁금해했습니다. 여기서 짧은 대답은 타일을 더 큰 스프라이트로 결합하는 것이 성능에 대해 걱정한다면 좋은 생각입니다. 그러나 관심이 있다면 훨씬 더 긴 대답이 있습니다.

일반적으로 성능 최적화와 관련하여 대답은 거의 항상 "하지 마십시오"입니다. 성능을 최적화해야한다고 확신한다면 다음 답변은 거의 항상 "아직하지 마십시오"입니다. 마지막으로, 성능을 최적화하려고 시도하는 경우, 가장 중요한 일은 벤치 마크를 사용하여 변경 전후의 성능 측정을 수집하는 것입니다. 그 없이는 당신이 성공했는지 모릅니다!

이제 2D 게임과 관련하여 타일 엔진에서 더 나은 성능을 보았을 때 텍스처를 덜 덜 더 잘 보았습니다. 예를 들어, 잔디 타일과 자갈 타일이 있다고 가정 해 봅시다. 이것들이 메모리에 두 개의 별도의 텍스처이고 잔디 타일을 그린 다음 자갈 타일을 그린 다음 화면에 잔디 타일을, GPU는 잔디 질감을로드 한 다음 자갈 질감을로드하기 위해 전환 한 다음 전환합니다. 잔디 질감이 다시 잔디 타일을 그리기 위해 다시 들어갑니다. 이것은 성능을 정말 빨리 죽입니다! 이 주위를 돌아 다니는 가장 쉬운 방법은 Spritesheet을 갖는 것입니다. 여기서 잔디와 자갈 타일을 하나의 질감에 넣고 Spritebatch에게 매번 같은 질감의 다른 영역에서 끌어들이라고 지시합니다.

고려해야 할 또 다른 점은 한 번에 화면에 몇 개의 타일을 그리는 것입니다. 나는 구체적으로 기억할 수 없지만, 한 번에 수천 개의 타일을 그렸습니다 (확대 된보기에서). 나는 더 큰 타일을 사용하고 당신의 질문에서 제안한 것처럼 그 성능도 향상되었음을 알았습니다. 이것은 마지막 단락에서 설명한 것만 큼 크게 개선되지 않았으며, 다른 구현으로 인한 성능 변경을 측정하도록 권장합니다. 또한, 12 개 또는 수백 타일 만 그려면 지금 당장 최적화하려고 시도하는 가치가 없을 수도 있습니다 (두 번째 단락 참조).

당신은 내가 이것을 완전히 만들지 않았다는 것을 알고 있습니다. 여기에 Shawn Hargreaves의 텍스처 스와핑, 스프리 시트 등의 게시물에 대한 링크가 있습니다. 주제.

http://forums.xna.com/forums/p/24254/131437.aspx#131437

업데이트:

질문을 업데이트 했으므로 내 게시물을 업데이트하겠습니다. 성능 차이가 무엇인지에 대한 아이디어를 제공하기 위해 일부 샘플을 벤치마킹하기로 결정했습니다. 내 draw () 함수에는 다음과 같은 것이 있습니다.

        GraphicsDevice.Clear(Color.CornflowerBlue);

        Stopwatch sw = new Stopwatch();
        sw.Start();

        spriteBatch.Begin();

#if !DEBUG
        spriteBatch.Draw(tex, new Rectangle(0, 0, 
                         GraphicsDevice.Viewport.Width,
                         GraphicsDevice.Viewport.Height), 
                         Color.White);            
#else
        for (int i = 0; i < 128; i++)
            for (int j = 0; j < 72; j++)
            {
                Rectangle r = new Rectangle(i * 10, j * 10, 10, 10);
                spriteBatch.Draw(tex, r, r, Color.White);
            }
#endif
        spriteBatch.End();

        sw.Stop();

        if (draws > 60)
        {
            numTicks += sw.ElapsedTicks;
        }
        draws++;

        if (draws % 100 == 0)
            Console.WriteLine("avg ticks: " + numTicks / (draws - 60));

        base.Draw(gameTime);

"#if! debug"문의 느낌표를 삭제하여 두 메소드간에 전환하십시오. 초기 설정이 포함되어 있고 (실제로 무엇을 확실하지 않음) 처음 60 개의 무승부를 건너 뛰었고 평균을 비뚤어졌습니다. 나는 1280x720 이미지 하나를 다운로드했고, 최고 테스트 케이스의 경우 한 번만 그렸습니다. 하단 테스트 케이스의 경우 하나의 소스 이미지를 타일로 그렸습니다. 결과는 다음과 같습니다.

하나의 이미지 그리기 :

avg ticks: 68566
avg ticks: 73668
avg ticks: 82659
avg ticks: 81654
avg ticks: 81104
avg ticks: 84664
avg ticks: 86626
avg ticks: 88211
avg ticks: 87677
avg ticks: 86694
avg ticks: 86713
avg ticks: 88116
avg ticks: 89380
avg ticks: 92158

128x72 타일 그리기 :

avg ticks: 7902592
avg ticks: 8052819
avg ticks: 8012696
avg ticks: 8008819
avg ticks: 7985545
avg ticks: 8028217
avg ticks: 8046837
avg ticks: 8291755
avg ticks: 8309384
avg ticks: 8336120
avg ticks: 8320260
avg ticks: 8322150
avg ticks: 8381845
avg ticks: 8364629

보시다시피, 거기에는 몇 가지 정도의 차이가 있으므로 상당히 중요합니다. 이런 종류의 것을 테스트하는 것은 매우 간단합니다. 특정 설정이 내가 놓친 것을 고려하기 위해 자신만의 벤치 마크를 실행하는 것이 좋습니다.

다른 팁

그래픽 카드의 텍스처 전환 횟수가 적을수록 성능이 향상됩니다.원하는 경우 그래픽 카드가 텍스처를 가능한 한 적게 전환하도록 SpriteBatch.Begin() 메서드에서 텍스처별로 정렬할 수 있습니다.

나는 타당할 때 타일/스프라이트를 시트에 넣습니다.예를 들어 하나의 캐릭터가 시트에 있을 수 있고 타일의 한 레이어가 동일한 시트에 있을 수 있습니다.이것은 지금까지 꽤 잘 작동했습니다.

그래도 필요할 때까지는 최적화하지 말라고 말하고 싶습니다.게임이 충분히 빠르게 실행된다면 최적화에 신경을 써야 할 이유가 됩니다.

사각형 r = 새로운 사각형 (i * 10, j * 10, 10, 10);

많은 새로운 물체를 만드는 것은 쓰레기 컬렉션을 호출하여 속도를 늦출 수 있습니다! 큰 루프에 새 개체를 할당해서는 안됩니다.

성과는 보편적 인 명령이거나 하나님의 계명이 아닙니다. 그것은 끝을위한 수단입니다. 당신이 가진 것이 충분히 잘 수행된다면, 당신은 말 그대로 성능을 향상시켜 얻을 수있는 것이 없습니다. "항상 가능한 최상의 성능"을 유지하는 것은 조기 최적화의 정의이며, 예방하는 것보다 더 많은 두통을 유발합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top