Estou planejando fazer a geometria instanciando no OpenGL ES 2.0 Basicamente, pretendo renderizar a mesma geometria (uma cadeira) talvez 1000 vezes na minha cena.
Qual é a melhor maneira de fazer isso no OpenGL ES 2.0?
Estou pensando em passar a visualização do modelo mat4 como um atributo. Como os atributos são por dados de vértice, preciso passar esse mesmo mat4, três vezes para cada vértice do mesmo triângulo (já que modelview permanece constante entre os vértices do triângulo).
Isso equivaleria a muitos dados extras enviados à GPU (2 vértices extras * 16 flutuações * (quantidade de triângulos) quantidade de dados extras).
Ou devo enviar o mat4 apenas uma vez por triângulo? Mas como isso é possível usando atributos, já que os atributos são definidos como dados "por vértice"?
Qual é a melhor e mais eficiente maneira de instanciar no OpenGL ES 2.0?
fonte
glVertexAttribDivisor
:(Respostas:
O ES2 não possui glVertexAttribDivisor nem texturas de ponto flutuante, portanto, suas opções são bastante limitadas.
Definitivamente, coloque seu modelo de cadeira em uma VBO, se você ainda não o estiver fazendo. A partir daí, você fica mais ou menos restrito a chamadas individuais - uma por cadeira -, portanto, é uma questão de levar a matriz de transformação de cada cadeira para a GPU da maneira mais eficiente possível.
Você pode fazer isso com chamadas glUniform regulares ou pode abusar de alguns slots extras de atributos de vértices e fazer algumas chamadas glVertexAttrib (nota: não glVertexAttribPointer) antes de desenhar cada cadeira, especificando a matriz usando 4 desses slots, e esses valores "se manterão" cada vértice subsequente na cadeira. Esse pode ser um caminho rápido o suficiente em alguns hardwares, mas mais lento em outros, então você precisará experimentar.
Se suas cadeiras não girarem, outra coisa que você pode fazer é enviar a posição para o shader e construir uma nova matriz de transformação rapidamente. Isso soa horrível, mas na verdade é incrivelmente rápido (está apenas configurando 3 carros alegóricos) e pode fazer o trabalho.
No geral, porém, e supondo que você esteja apontando para uma plataforma móvel típica, estou pensando que, o que você fizer, as chamadas serão matadas.
fonte
Sua melhor aposta é usar uma abordagem de instanciação bastante semelhante aos modelos de skin. Crie um VBO que conterá muitas cópias da sua cadeira, todas idênticas. Agora, todo vértice deve ter um atributo de byte que reterá o índice na matriz de transformação que será aplicada a ele. Envie uma matriz de matrizes para o shader e use-as como a transformação mundial de cada uma de suas cadeiras. Dessa forma, você pode desenhar em cada chamada o número máximo de cadeiras que o tamanho máximo do parâmetro da matriz, sem precisar reescrever nenhum dado no VBO.
fonte
A Wolfire Games tem um excelente post sobre instanciamento rápido de objetos . O que eles fazem é renderizar o modelo várias vezes, mas envia uma matriz diferente para cada objeto para um slot uniforme.
Essa é uma maneira bastante eficiente de instanciar um monte de objetos, porque você só precisa enviar os dados uma vez (o maior gargalo ao renderizar um lote de objetos sempre será a largura de banda) e depois transformar o modelo em um sombreador.
fonte
http://www.youtube.com/watch?v=rfQ8rKGTVlg
Este é um Google Talk no WebGL, que é o OpenGL ES para JavaScript, o que significa que também não há instâncias geométricas. Pode lhe dar uma idéia, embora seja difícil dizer, porque não sei se o seu gargalo está na GPU ou na CPU.
Embora você deva aprender sobre variáveis uniformes, não há absolutamente nenhuma necessidade de enviar um mat4 em um atributo; todos os vértices de sua cadeira serão transformados pela mesma matriz; você deve enviá-lo apenas uma vez por modelo, não por triângulo. Variáveis uniformes permitem fazer isso, elas são um tipo especial de variável que você pode definir no próprio programa shader.
fonte