문제

나는 나만의 파티클 시스템 엔진을 설계하고 있습니다. 이것은 학습 목적이므로 기존 엔진을 실제로 사용하고 싶지 않습니다.

지금은 아름다운 파티클을 생성했지만 더 쉽게 작업할 수 있도록 엔진을 레이아웃하고 싶습니다.

나는 클래스 "파티클 시스템"에 대해 생각해 왔습니다.

해당 클래스에는 다음 참조가 포함됩니다.

입자목록:시스템을 구성하는 입자의 목록입니다.

시스템이미터:입자에 대한 시스템 이미터인 Emitter 클래스는 선, 점에서 방출, 다각형에서 무작위로 방출과 같은 여러 입자 방출 기술을 수행할 수 있어야 합니다.또한 이 클래스는 방출 제어를 수행해야 합니다. 예를 들어, 한 지점을 향해 방출하거나, 한 지점에서 멀어지거나, 방출할 방향과 시간을 지정해야 합니다.

입자컨트롤러:예를 들어 점 주위의 회전, 다양한 입자 크기, 다양한 입자 색상, 입자가 다양한 방식으로 반응하는 시스템 주변 영역, 충돌 감지(필요한 경우 다른 객체 또는 입자 내와의)를 관리합니다.

파티클 렌더러:이 시스템의 드로잉을 담당하는 것은 가변 블렌딩 유형, 파티클 텍스처, 삼각형, 원과 같은 파티클 유형, 사용자 정의...

이 네 가지 항목은 입자 시스템 클래스를 구성합니다.일부 FX에는 두 개 이상의 파티클 시스템이 필요할 수 있습니다. 예를 들어 Fire FX는 화재에 하나의 시스템, 연기에 하나의 시스템, 불꽃에 하나의 시스템을 사용할 수 있습니다.

이것이 제가 생각하는 것입니다. 하지만 이 디자인 접근 방식이 좋은지, 아니면 뭔가 빠졌거나 뭔가 다른 것을 할 수 있거나 해야 하는지 알고 싶습니다.나는 FX를 "저장"하는 쉬운 방법에 대해 생각하지 않았습니다. 예를 들어 내 엔진에 "불 끌기", "폭발 끌기", "분수 그리기" 등을 알리고 FX 정보를 저장하는 가장 좋은 방법은 무엇인지 생각해 본 적이 없습니다. xml 파일로 저장하는 것이 좋습니다.

의견은 정말 환영합니다. 앞서 말했듯이 저는 학습상의 이유로 다른 엔진을 사용하는 대신 이것을 구축하고 싶습니다.

도움이 되었습니까?

해결책

이 설정은 괜찮을 것입니다.여러분이 생각하기를 바라는 것은 어떤 데이터가 입자 클래스에 포함될 입자를 구성하는지입니다.꼭 필요한 것만 갖고 싶으므로 시스템을 실행할 때 가능한 한 적은 메모리만 읽고 쓰면 됩니다.

데이터 기반으로 만드는 것은 매우 간단합니다.로딩을 위해 xml 및 바이너리 형식 옵션을 제안하고 싶습니다.따라서 개발하는 동안(도구 없이도) 쉽게 내용을 조정할 수 있습니다.도구가 있거나 조정이 완료되면 빠른 로딩을 위해 xml을 바이너리로 변환합니다.

이러한 입자 시스템의 생성 및 업데이트를 처리하는 관리자 클래스가 필요할 수도 있습니다.이를 통해 모든 시스템과 관련된 다른 기능을 처리할 수 있는 공간도 확보할 수 있습니다.이에 대한 몇 가지 예로는 성능상의 이유로 관리할 수 있는 파티클 시스템 또는 파티클의 양을 제한하거나 모든 시스템에서 고려해야 하는 충돌 평면을 갖는 것이 있습니다.

당신은 이것이 교육 목적을 위한 것이며 그 점에서 이러한 것들이 매우 까다롭다고 언급했습니다(그러나 입자가 많은 게임에서 이것을 사용하려는 경우 중요합니다).

나는 이것이 DirectX나 OpenGL과 같은 API를 사용하여 렌더링한다고 가정합니다.그런 점에서 나는 입자 효과가 모두 정점 정보에 대해 동일한 메모리 풀을 공유하도록 할 것입니다.이는 렌더링 속도에 많은 도움이 됩니다.또한 절두체 컬링(AABB 또는 Circle)에 사용하기 위해 입자 시스템의 영향을 받는 영역의 경계를 추적합니다.

파티클 시스템 업데이트의 가장 큰 부분은 속성이 한 값에서 다른 값으로 이동하는 방식입니다.값을 더 동적으로 보간할수록 효과가 더 좋아 보일 수 있습니다.단순히 선형 보간하는 것만으로도 충분할 수 있지만 값을 보간하는 데 사용되는 동적 그래프를 사용하는 것이 더 나을 수도 있습니다.예를 들어 1초 안에 파란색이 0에서 255로 변하는 대신 0.2초 안에 0에서 128로 변한 다음 0.8초 안에 128-255로 변하는 것이 멋질 수 있습니다.이를 추가하면 효과의 모양에 대한 옵션이 크게 늘어납니다.

게다가 나는 당신이 하고 싶은 일에 대해 꽤 좋은 생각을 가지고 있다고 생각합니다.다양한 유형의 입자 렌더링에 대한 귀하의 언급은 귀하가 이에 대해 올바른 방식으로 생각하고 있음을 말해줍니다.나는 사람들이 빌보드 쿼드를 렌더링하는 데만 초점을 맞춰 파티클 엔진을 만드는 것을 보았습니다.3D 지오메트리를 방출하는 옵션이 있으면 정말 멋지게 보입니다.(아직 하지 않은 경우) 시스템에서 모델 정보를 가져와 이를 별도의 입자로 분할하여 방출할 수 있는 기능을 고려해볼 수도 있습니다.실제로 모델을 폭발시키는 것은 일부 폭발 입자를 표시하고 객체를 페이드 아웃하거나 손상된 상태로 전환하는 것보다 훨씬 더 좋아 보입니다.

다른 팁

간단한 2D 스프라이트 입자의 최적화에 대한 몇 가지 아이디어.

좋은 아이디어는 모든 입자를 Vertex Array / VBO로 보내고 정점 셰이더를 사용하여 시간이 지남에 따라 위치를 업데이트하는 것입니다. 수학 공식을 사용하여 쉽게 설명 할 수있는 간단한 움직임이있는 경우 x(t) 그리고 y(t) (즉, 시간에만 의존합니다).

또 다른 좋은 아이디어는 삼각형과 쿼드 대신 Point Sprites를 사용하는 것입니다. 이렇게하면 파이프 라인의 필요한 대역폭이 1/4로 줄어 듭니다.


내 우주 SIM에서 나는 가장 사소한 접근법을 구현했다 : 입자는 텍스처 쿼드로 전송 된 입자 glBegin()/glEnd(). 그들은 개별 객체로서 현재 "섹터"에 버려지고 덤프 시간과 완전히 독립적입니다. 이것은 가장 원시적이고 어리 석고 바보 같은 일이며, 특히 내가하는 일은 STL 벡터의 반복기를 통해 물체를 반복하고 각각을 순차적으로 보내기 때문에 성능의 큰 감소를 담당합니다.

원하는 입자 수와 원하는 입자를 고려해야합니다. * 주변 환경에 반응하고 충돌하기를 원하십니까? 그런 다음 CPU에 대한 업데이트와 반복해서 전송 된 데이터를 업데이트해야합니다. * 그들은 가능한 가장 어리석은 방식으로 날아 다니나요? 그런 다음 모든 입자를 VBO 및 TBO로 전송하여 셰이더로 업데이트 할 수 있습니다.

재미있게 보내세요!


Asker의 의견 #1과 관련하여 업데이트되었습니다 :-)

내가 할 일은 사용하는 것입니다 키스 원리. 이것은 다음을 의미합니다 ParticleEmitter 정점 배열, 속도 배열 및 STL을 포함하는 vector 평면, 구체, 삼각형과 같은 단순한 충돌의 경우. 또한 "글로벌"* STL이 있습니다 vector 충돌기와 함께. 그런 다음 콜라이드에 따라 속도를 업데이트하십시오.

이로 인해 (중력, 바람 등)와 유사 할 수 있습니다. 또 다른 STL 벡터 ParticleEmitter 인상가와 다른 "글로벌"STL vector 인사이터와 함께.

인사이터와 콜리 라이더는 구현할 수있는 수업입니다 affectParticle(particle_t*). 어디 struct particle_t { float x,y,z; float vx,vy,vz; }. 나는 그것을 포드 구조로 유지하고 업데이트를 실행합니다. ParticleEmitter::update().

그러나 iPhone에서 이것을 실행하는 경우 과도하게 복잡 할 수 있습니까? 아마도 당신이 이미 구현 한 것을 벗어날 수 있습니까? 내 디자인이 벤치 마크 결과에 어떤 영향을 미칠 수 있는지는 모르겠지만 입자, 콜라이더 및 애도를 카운트 다운으로 유지하면 대략 규모로 확장 될 수 있기 때문에 나에게 충분히 합리적으로 들립니다. n*c+n*a.

이것들은 단지 나의 임시 생각이며, 내가 개인적으로 그것을 구현하는 방법입니다. 당신의 디자인이나 다른 사람들의 디자인은 아마도 더 나을 것입니다 :-)

* 인용 한 "글로벌"은 아마도 당신이 사용중인 공간 파티셔닝을 사용하는 것이 합리적이기 때문에 가능하기 때문입니다.

C ++에서 나만의 엔진에 대해 동일한 좋은 디자인을 구현했습니다. 나는 참조 및 템플릿 정책 (전략 - Alexandresku의 "Modern C ++ Desing"을 읽음)을 사용하지 않았습니다. 정적 다형성은 더 나은 성능을 제공합니다.

내 경험에 따라 몇 가지 의견을 제시하고 싶습니다.

  1. 전통적으로 대부분의 입자는 AOS (구조물 배열)를 사용하여 입자 속성을 저장합니다. 그러나 이것은 최선의 결정이 아닐 수도 있습니다. SOA (구조물의 구조) 표현을 사용하면 각 입자 시스템의 속성을 추가 할 수있는 많은 유연성이 제공됩니다. 또한 SOA를 사용한 SIMD로 성능을 향상시키는 것이 훨씬 쉽습니다. 예를 들어, SSE 명령어를 사용하여 4 개의 입자를 함께 수행합니다.
  2. 입자가 방출되는 위치는 하나의 입자 속성의 초기화입니다. 입자를 방출 할 때는 수명, 속도 등과 같은 다른 속성을 초기화해야 할 것입니다.이 모든 기능을 초기화기로 추상화 할 수 있습니다. 위치의 경우 디스크 이니셜 라이저, 박스 이니셜 라이저 등이있을 수 있습니다.
  3. 일부 현대 입자 시스템은 이벤트 개념을 채택합니다. 입자 시스템은 이벤트를 생성 할 수 있으며 (예 : 비가 지형과 충돌) 다른 입자 시스템은 일부 행동을 듣고 수행 할 수 있습니다 (예 : 방출 스플래쉬).

그건 그렇고, 가장 좋은 방법은 기존 애플리케이션/미들웨어의 설계와 실험을 연구하는 것입니다.

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