Pergunta

Eu estou projetando minha própria partícula motor do sistema, isto é para fins de aprendizagem, eu realmente não quero usar um motor existente.

Agora eu gerado partículas bonitas, mas eu quero para o layout do motor para torná-lo mais fácil de trabalhar com eles.

Eu estive pensando em um "Sistema de Partículas" Classe,

que a classe deve conter as seguintes referências:

particlesList :. Uma lista das partículas que compõem o sistema

systemEmitter : O emissor do sistema para as partículas, a classe emissor deve ser capaz de executar várias técnicas de emissão de partículas, como por exemplo, emissores de linhas, pontos, emitindo aleatoriamente a partir de um polígono. Também esta classe deve fazer Emissão de Controle, como emissor para um ponto, longe de um ponto, em uma direção e tempo para emitir.

particleController : Gere por exemplo a rotação em torno de um ponto, tamanhos de partícula variáveis, cores de partícula variáveis, as áreas em torno do sistema para o qual as partículas reagem de maneiras diferentes, de detecção de colisão (com outros objetos ou dentro do partículas se torna necesary).

Particle Renderer : Responsável desenho deste sistema, tipos de mistura variável, texturas de partículas, tipos de partículas como triângulos, círculos, costume ...

Este quatro itens, que compõem o sistema de partículas Class. Alguns FX pode exigir mais do que um sistema de partículas, por exemplo, um incêndio FX, poderia usar um sistema para o fogo, um sistema de fumaça e um sistema de faíscas.

Isto é o que eu tenho em minha mente, mas eu realmente gostaria de saber se esta abordagem de design é bom, ou se você vê que eu estou faltando alguma coisa ou poderia / deveria fazer algo diferente. Eu não pensei sobre alguma maneira fácil para "salvar" FX, como por exemplo, qual seria a melhor maneira de dizer o meu motor, "desenhar Fire", "chamar a explosão", "chamar a fonte", etc, talvez armazenando informações FX em xml arquivos seria uma boa idéia, etc ..

As opiniões são muito bem-vindos e, como eu disse antes, eu realmente quero construir este, em vez de usar outro motor, por razões de aprendizagem.

Foi útil?

Solução

Esta configuração deve ser fino. O que eu espero que você está pensando é que dados irá tornar-se uma partícula que será na classe de partículas. Você vai querer só para ter o essencial para que você só tem que ler / escrever tão pouco memória possível ao executar o sistema.

Quanto tornando-se dados orientado que deve ser bastante simples. Gostaria de sugerir uma opção de formato binário para o carregamento xml e. assim você pode ajustar coisas facilmente durante o desenvolvimento (e não ter uma ferramenta). Depois de ter uma ferramenta ou são feitos ajustes gostaria de converter o xml para binário para carregamento rápido.

Você também pode querer uma classe gerente que manipula a criação e atualização desses sistemas de partículas. Isso também permitirá que você um lugar para lidar com outras funcionalidades que tem a ver com todos os seus sistemas. Alguns exemplos deste está a limitar a quantidade de sistemas de partículas ou de partículas que podem ser geridas por razões de desempenho ou de ter um plano de colisão que todos os sistemas devem ter em conta.

Você menciona isto é para fins de educação e em que considera estas coisas são exigente nit (mas importante se você está a usar isso em um jogo que é pesada partícula).

Eu estou assumindo que este é usando uma API como DirectX ou OpenGL para renderizar. A esse respeito eu teria os efeitos de partículas todos compartilham o mesmo conjunto de memória para sua informação vértice. Isso ajuda a prestação acelerar muito. Também gostaria de manter um registo de uma limites da área afectada por um sistema de partículas para uso com abate tronco de cone (AABB ou círculo).

Uma grande parte da atualização de um sistema de partículas é como atributos ir de um valor para outro. O mais dinâmico você pode fazer a interpolação de valores o melhor suas efeitos podem olhar. Simplesmente linearmente interpolação poderia ser bom o suficiente, mas pode ser melhor ter um gráfico dinâmico que é usado para interpolar os valores. Por exemplo, em vez de ir de 0 a 255 azul, em um segundo, pode ser arrefecer para ir 0-128 em 0,2 segundos, em seguida, 128-255 em 0,8 segundos. Acrescentando que vai aumentar muito as opções sobre como seus efeitos olhar.

Além de que eu acho que você tem uma boa idéia bastante sobre o que você quer fazer. Sua menção de renderizar tipos diferentes de partículas me diz que você está pensando sobre isso da maneira certa. Eu vi as pessoas fazem motores de partículas apenas se concentrar na prestação de um quad billboarded. Tendo a opção de emitir geometria 3D realmente faz coisas olhar grande. Você também pode querer pensar sobre (se você não tiver) ter a capacidade para o seu sistema para levar informações sobre o modelo e dinamicamente dividir a ele em partículas separadas para ser emitido. Na verdade explodindo um modelo de aparência muito melhor, em seguida, exibindo alguma partícula explosão e desaparecendo o objeto ou ligá-lo a um estado danificado.

Outras dicas

Apenas algumas ideias para otimização de simples, partículas 2D Sprite.

Uma boa idéia é enviar todas as partículas em uma matriz de vértice / VBO, e usar um shader de vértice para atualizar suas posições ao longo do tempo. Isso é ótimo se você tem um movimento simples que pode ser facilmente descrito usando uma fórmula matemática, onde x(t) e y(t) (ou seja, eles dependem apenas de tempo).

Outra grande idéia é usar sprites ponto em vez de triângulos e quads. Isso deve reduzir a largura de banda necessária no gasoduto para um quarto.


Em meu espaço sim eu implementei a abordagem mais trivial: partículas enviadas como quads texturizados usando glBegin() / glEnd(). Eles são despejados no "setor" atual como objetos individuais e são completamente independente do tempo de dumping em diante. Esta é a coisa mais primitivo, estúpido e idiota para fazer e é responsável por grande redução no desempenho, especialmente desde que eu faço é iterate através de objetos via iterador de vetor STL e enviar todos e cada um deles sequencialmente.

Você precisa considerar quantas partículas que você quer, eo que quer que eles façam. * Você quer que eles para reagir ao ambiente e colidem? Então você precisam atualizar tratado na CPU e dados enviados e outra vez. * Será que eles simplesmente voar em torno da maneira mais estúpida possível? Então você pode ser capaz de fugir com o envio de todas as partículas como VBO e TBO, e atualizá-los no shader.

Divirta-se!


Atualização de se relacionar com o comentário # 1 de autor da questão: -)

O que eu gostaria de fazer é usar a BEIJO princípio . Isto significa: uma classe chamada ParticleEmitter contendo uma matriz de vértice, uma matriz de velocidades, e um vector STL com exemplos de aceleradores simples, tais como plano, esfera, triângulo. Além disso, tem a * vector "global" STL com aceleradores. Em seguida, atualize as velocidades de acordo com aceleradores.

semelhante pode ser feito com affectors (gravidade, vento e tal): outro vetor STL em ParticleEmitter com affectors e outro vector "global" STL com affectors.

Affectors e aceleradores seria classes que iria implementar affectParticle(particle_t*). onde struct particle_t { float x,y,z; float vx,vy,vz; }. Eu mantê-lo uma estrutura POD, e atualização executado em ParticleEmitter::update().

No entanto, se você estiver executando isso no iPhone, poderia ser overcomplication? Talvez você pode ir longe com o que você já implementadas? Eu não tenho nenhuma idéia de como meu projeto pode afetar os resultados de benchmark, mas soa bastante razoável para mim se você manter a partícula, colisor e affector contar para baixo, porque parece que ele pode escalar com aproximadamente n*c+n*a.

Estas são apenas meus pensamentos ad-hoc, e como eu iria implementá-lo pessoalmente. Seu projeto, ou desenho de outras pessoas, provavelmente seria melhor: -)

* "Global" em citações, porque ele provavelmente faria sentido fazer uso de qualquer espaço de particionamento que você tem em uso.

Eu tenho implementado o mesmo design bom para o meu próprio motor em C ++. Eu não usar referências e políticas de modelo (estratégias - leia "++ Desing C moderna" do Alexandresku) em vez. polimorfismo estático dá um melhor desempenho.

Eu quero fazer algumas observações de acordo com a minha experiência.

  1. Tradicionalmente, a maioria das partículas utilizações AOS (matriz de Struct) para armazenar os atributos de partículas. Mas isso pode não ser a melhor decisão. Uso de SOA (struct de Array) representação vai lhe dar uma grande flexibilidade para adicionar atributos de cada sistema de partículas. E também, você será muito mais fácil para melhorar o desempenho com SIMD com SOA. Por exemplo, fazendo 4 partículas em conjunto, utilizando instruções SSE.
  2. posição de onde o emite partículas é única inicialização de um atributo de partícula. Quando emitem partículas, você provavelmente precisará inicializar outros atributos, tais como a vida, velocidade, etc. Você pode abstract todas estas característica como initializers. Para a posição, você pode ter um inicializador de disco, caixa initializer, etc.
  3. Alguns sistema de partículas moderna adota o conceito de evento. sistema de partículas pode gerar evento (por exemplo colidem chuva com o terreno) e outro sistema de partículas pode ouvir e executar alguma ação (por exemplo, emitem respingo).

A propósito, acho que a melhor maneira é através do estudo do projeto de aplicação existente / middleware, e também pela experimentação.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top