Use buffers uniformes (ou seja, buffers constantes no jargão D3D).
Desde que todos os seus sombreadores concordem com o layout e o ponto de ligação de cada buffer, a atualização se tornará fácil. Os modelos não precisam saber nada sobre shaders. Eles precisam apenas atualizar a matriz de exibição de modelo em seu buffer constante e o pipeline de renderização a utilizará automaticamente.
No mínimo, eu argumentaria que você deveria ter dois desses buffers. O primeiro deve armazenar sua matriz de projeção, matriz de câmera, matriz de projeção de câmera concatenada, informações de viewport, detalhes de frustrum e inversos de matriz. Você só precisa atualizar esse buffer uma vez por cena.
Em seguida, forneça a cada modelo outro buffer para armazenar suas propriedades de matriz de exibição de modelo, matriz normal, inversas e material. Isso é atualizado uma vez para cada modelo e pode ser feito em uma passagem de atualização diferente (se / quando apropriado). As informações do material podem / devem ser movidas para um terceiro buffer específico do material, se você puder compartilhar materiais entre vários objetos.
Em uma configuração de sombreamento para frente, faz sentido colocar todas as luzes em outro buffer e, no sombreado diferido, também faz sentido usar um buffer por luz para o passe de luz (no lugar de um modelo / buffer de material usado no passagem de geometria).
Observe que você precisa de uma versão moderadamente atualizada do GL para usar buffers uniformes (3.1 ou uma extensão; bastante comum hoje, exceto em alguns laptops mais antigos, mas ainda em serviço) e precisa de uma versão bastante recente capaz de vincular buffers uniformes a locais de ligação específicos de dentro do código de sombreador (4.2; ainda incomum, mas melhorando), caso contrário, você precisará trabalhar mais no código do lado da CPU para configurar as coisas (o código da CPU precisa saber a ligação correta de qualquer maneira, por isso é mais um cheiro de API do que um problema sério). O OpenGL | ES não adicionou buffers uniformes até o 3.0, que ainda não é suportado nas plataformas móveis mais populares, infelizmente.
Se os buffers não forem uma opção, você precisará de um local global para armazenar locais de índice para o shader ativo. Você pode usar glGetUniformLocation
após carregar o shader para encontrar os índices para nomes conhecidos (como ModelViewMatrix
ou não) e depois armazená-los. Sua renderização pode mapear valores de enumeração como MODEL_VIEW
passados para uma SetUniform
função de invólucro para examinar o sombreador associado, localizar o índice e chamar glUniform
adequadamente. Não é uma grande mudança específica no uso do código do cliente de buffers, além da necessidade de definir cada uniforme individualmente, se você concluir tudo bem.
Consulte Blocos de interface GLSL e objetos de buffer uniformes .