2012-03-28 1 views
3

현재 내 게임의 트레일 효과로 5 프레임마다 반투명 한 텍스처 복사본이리스트에 추가됩니다 (목록 <).C# XNA 2D 트레일 효과 최적화

이러한 흔적의 알파 값은 프레임마다 감소하고 그리기 기능은 목록을 반복하고 각 텍스처를 그립니다. 알파가 0에 도달하면 목록 <>에서 제거됩니다.

이동하는 엔티티 뒤에는 작은 흔적이 있습니다. 100 개 이상의 엔티티에 문제가있어 프레임 속도가 급격히 떨어지기 시작합니다.

모든 트레일 텍스처는 동일한 스프라이트 시트에서 제공되므로 일괄 처리 문제라고 생각하지 않습니다. 필자는 코드를 프로파일 링하고 CPU 강도가 FPS 드롭 스파이크 동안 낮 으면 일반 FPS에서 GPU 제한이라는 것을 가정합니다.

이 효과를 더 효과적으로 달성 할 수있는 방법이 있습니까? 사용

Heres는 일반 코드 메신저 : 나는주의해야한다 생각

// fade alpha 
m_alpha -= (int)(gameTime.ElapsedGameTime.TotalMilliseconds/10.0f); 

// draw 
if (m_alpha > 0) { 
    // p is used to alter RGB of the trails color (m_tint) depending on alpha value 
    float p = (float)m_alpha/255.0f; 
    Color blend = new Color((int)(m_tint.R*p), (int)(m_tint.G*p), (int)(m_tint.B*p), m_alpha);    
    // draw texture to sprite batch 
    Globals.spriteBatch.Draw(m_texture, getOrigin(), m_rectangle, blend, getAngle(), new Vector2(m_rectangle.Width/2, m_rectangle.Height/2), m_scale, SpriteEffects.None, 0.0f);     
} else { 
     // flag to remove from List<> 
     m_isDone = true;    
} 

, 흔적 클래스에 주어진 m_texture 모든 산책로가 공유하는 글로벌 조직에 대한 참조입니다. 각 흔적을위한 하드 카피를 만드는 메모.

편집 : SpriteBatch.Draw 호출을 주석 처리하면 수백 개의 개체에 대해 모든 단일 프레임마다 새 트레일을 할당하더라도 프레임을 삭제할 필요가 없습니다. 더 좋은 방법이 있어야합니다. 이.

+0

는 것을? – MichaelHouse

+0

예, 트레일 효과를 제거하면 프레임 속도가 완전히 떨어집니다. 산책로가 GPU를 처리하기에 너무 많은 스프라이트를 추가하는 것일뿐입니다. – kbirk

+2

몇 가지 코드를 게시해야합니다. 분명히 그런 것이 가능합니다. 입자 시스템은 100 개 이상의 입자가 모두 사라지기 쉽게 만듭니다. – MichaelHouse

답변

3

보통 흔적을 위해 모든 프레임에서 화면을 지우는 대신 현재 프레임을 그리기 전에 투명한 화면 크기의 사각형을 그립니다. 따라서 새 프레임이 완전히 "선명"하고 "밝음"인 동안 이전 프레임은 "흐리게 표시"되거나 ​​"색상이 흐려집니다". 이것이 반복됨에 따라, 이전의 모든 프레임에서 흔적이 생성되지만, 이는 지워지지 않고 흐려집니다.

이 기술은 매우 효율적이며 유명한 Flurry 스크린 세이버 (www.youtube.com/watch?v=pKPEivA8x4g)에서 사용됩니다.

산책로를 길게 만들려면 화면을 지우는 데 사용하는 사각형의 투명도를 높이기 만하면됩니다. 그렇지 않으면 흔적을 더 짧게 만들기 위해 더 불투명하게 만듭니다. 그러나 사각형을 너무 투명하게 만들어 길을 너무 길게 만들면 알파 블렌딩으로 인해 오랜 시간이 지나도 완전히 지워지지 않는 흔적을 남길 위험이 있습니다. Flurry 스크린 세이버는 이러한 종류의 인공물로 인해 고통을 겪습니다. 그러나이를 보상 할 방법이 있습니다.

상황에 따라 기술을 조정해야 할 수도 있습니다. 예를 들어, 어떤 객체가 흔적을 남기고 다른 객체가 흔적을 생성하지 못하게하는 여러 도면 레이어가 필요할 수 있습니다.

이 기법은 현재 접근법으로 스프라이트를 수천 번 다시 그리는 것보다 긴 트레일에 더 효율적입니다.

Globals.spriteBatch.Draw(m_texture, getOrigin(), m_rectangle, blend, getAngle(), new Vector2(m_rectangle.Width/2, m_rectangle.Height/2), m_scale, SpriteEffects.None, 0.0f); 

GPU의 수천을 가지고 비효율적이다는 그리기와 같은()를 호출 : 한편

, 나는 당신의 코드에서 병목 현상이 다음 줄 생각합니다. 버퍼에 폴리곤 목록이 있으면 각 폴리곤이 올바른 위치에 있고 투명도 정보가 저장되어있는 것이 더 효율적입니다.그런 다음 Draw()에 대한 단일 호출을 사용하면 올바른 텍스처와 투명도로 모든 다각형을 렌더링 할 수 있습니다. 죄송합니다.이 코드를 제공 할 수는 없지만 귀하의 접근 방식을 계속 사용하려는 경우, 이것이 귀하가 가고있는 방향 일 수 있습니다. 즉, 당신의 GPU는 확실히 한 번에 다각형의 수백만을 그릴 수 있지만, 그리기 호출 할 수 없습니다() 흔적 효과가 원인입니다 보장하기 위해 제거/해제 시도에 여러 번 ...

+0

고맙다고 감사드립니다. 이것이 정확히 내가 원하는 바램입니다! – kbirk

+0

@Pondwater : 잘 듣고 싶습니다! 천만에요! –

+0

알파 블렌딩으로 남겨진 인공물은 어떻게 예방/피하는가? – kbirk