Como exercício de aprendizado, escrevi um mecanismo de renderização diferida. Agora eu gostaria de adicionar um gráfico de cena a esse mecanismo, mas estou um pouco confuso sobre como fazer isso.
Em um normal (mecanismo de renderização direta), basta adicionar todos os itens (Todos implementando IDrawable e IUpdateAble) ao meu gráfico de cena, do que percorrer primeiro a largura do gráfico de cena e chamar Draw () em todos os lugares.
No entanto, em um mecanismo de renderização diferida, tenho que separar as chamadas de draw. Primeiro tenho que desenhar a geometria, depois os lançadores de sombras e depois as luzes (todas para diferentes alvos de renderização), antes de combinar todas elas. Portanto, neste caso, não posso simplesmente percorrer o gráfico da cena e apenas chamar draw. Do jeito que eu vejo, eu tenho que percorrer o gráfico de cena inteiro três vezes, verificando que tipo de objeto é esse que precisa ser desenhado ou preciso criar três gráficos de cena separados que, de alguma forma, estão conectados um ao outro. Ambas parecem soluções ruins, eu gostaria de lidar com objetos de cena mais transparentes.
Uma outra solução que pensei em viajar pelo gráfico de cena como normal e adicionar itens a 3 listas separadas, separando geometria, rodízios de sombras e luzes, e depois iterando essas listas para desenhar as coisas corretas, é melhor e é isso? sábio repovoar 3 listas de cada quadro?
fonte
Minha sugestão seria uma abordagem em duas etapas, adaptada aos seus requisitos específicos, semelhante ao que você se descreveu. Você precisa de um gráfico de cena e uma "coleção de renderização" para cada uma das etapas de renderização, no seu caso sombra, geometria, luzes (talvez uma quarta seja objetos transparentes?)
O gráfico da cena pode ser baseado em qualquer tipo de relacionamento, mas minha preferência pessoal seria baseada em relacionamentos espaciais, em que cada nó pode conter os outros nós para facilitar a seleção rápida.
As coleções de renderização podem ser qualquer tipo de estrutura de dados adaptada à etapa específica. Por exemplo, a coleção de sombras pode ser uma lista ou árvore classificada por profundidade para maximizar a rejeição inicial de z. A coleção de geometria pode ser classificada pelo uso do sombreador para minimizar as alterações do estado do sombreador. A coleção de luzes pode ser uma lista ou árvore classificada pela distância da luz, tamanho ou uma combinação dessas, para que você possa limitar a renderização da luz apenas às luzes mais eficazes se o desempenho for um problema.
Quaisquer que sejam as estruturas de dados que você escolher, verifique se a operação de inserção é rápida e use técnicas de pool e outras para eliminar qualquer alocação / destruição de dados, porque você estará limpando e preenchendo essas listas a cada quadro.
Agora, juntar tudo é fácil. Basta percorrer o gráfico da cena e adicionar cada item às coleções de renderizações relevantes. Ajuda se sua estrutura de dados classifica / estrutura automaticamente novas entradas com base nos requisitos. Quando terminar, percorra as coleções de renderizações na ordem necessária e as renderize.
Como suas estruturas de dados têm inserção rápida e não geram lixo, não há penalidade por repovoar listas como você mencionou.
fonte