OpenGL: Lote Processador: Deve Transformações ocorrem na CPU ou GPU?

0

Pergunta

Eu estou desenvolvendo um jogo 2D mecanismo que suporte 3D no futuro. Nesta atual fase de desenvolvimento, eu estou trabalhando no lote renderizador. Como alguns de vocês sabem, quando lotes de gráficos juntos, suporte uniforme de cor (RGBA), coordenadas de textura, textura ID (textura índice), e o modelo de matriz de transformação ir para fora da janela, mas em vez disso, são transmitidas através do buffer de vértices. Agora, eu tenho implementado passando o modelo de posições, cor, coordenadas de textura, e a textura de IDENTIFICAÇÃO para o buffer de vértices. O meu vertex buffer formato parece com isso agora:

float* v0 = {x, y, r, g, b, a, u, v, textureID};
float* v1 = {x, y, r, g, b, a, u, v, textureID};
float* v2 = {x, y, r, g, b, a, u, v, textureID};
float* v3 = {x, y, r, g, b, a, u, v, textureID};

Eu estou prestes a integrar o cálculo onde o objeto deve ser no espaço do mundo usando uma matriz de transformação. Isso me leva a fazer a pergunta:

Deve a matriz de transformação a ser multiplicado pelo modelo posições dos vértices na CPU ou GPU?

Algo para se manter em mente é que se eu passar ele para o buffer de vértices, eu teria que carregar a matriz de transformação de uma vez por vértice (4 vezes por sprite) o que me parece um desperdício de memória. Por outro lado, multiplicando-se o modelo de posições dos vértices por a matriz de transformação na CPU parece que ele iria ser mais lento em comparação com a GPU concorrência capacidades.

Isto é como o meu vertex buffer formato seria como se eu calcular a transformação na GPU:

float* v0 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v1 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v2 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};
float* v3 = {x, y, r, g, b, a, u, v, textureID, m0, m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15};

A questão é, principalmente, teoricamente orientada. Assim, um conhecimento teórico e técnico resposta seria muito apreciada. Mas para a referência, aqui está o código.

c++ glm-math glsl opengl
2021-11-24 03:43:20
2

Melhor resposta

1

Deve Transformações ocorrem na CPU ou GPU?

Realmente, depende muito da situação em questão. Se você submeter novamente o seu vértices em cada quadro, é melhor referência do que é melhor para o seu caso. Se você deseja animar, sem voltar a submeter todos os seus vértices, você não tem escolha, mas para aplicá-lo na GPU.

Seja qual for o motivo, se você decidir aplicar as transformações na GPU, há melhores maneiras de fazer que os outros do que duplicar a matriz para cada vértice. Eu em vez de colocar as matrizes de transformação em um SSBO:

layout(std430, binding=0) buffer Models {
    mat4 MV[]; // model-view matrices
};

e armazenar um índice único em cada vértice em VAO:

struct Vert {
    float x, y, r, g, b, a, u, v;
    int textureID, model;
};

O shader de vértice pode ir e buscar a matriz completa, com base no índice do atributo:

layout(location = 0) in vec4 in_pos;
layout(location = 1) in int in_model;
void main() {
    gl_Position = MV[in_model] * in_pos;
}

Você pode até mesmo combinar com outros por objeto os atributos, como o textureID.

EDITAR: você pode conseguir algo semelhante com a instanciação e multi-draw. Apesar de provavelmente ser mais lento.

2021-11-24 17:20:51

Você pode explicar mais sobre o que exatamente modelo seria? Estou tentando implementar a ela e estou recebendo apenas um sprite na tela e acho que é porque eu não estou enviando o direito de informação.
Christopher Barrios Agosto

@ChristopherBarriosAgosto um índice do modelo de matriz no MV matriz: 0, 1, 2, etc...
Yakov Galka

Desde que você está renderizando individualmente transformado quads, que será 0,0,0,0,1,1,1,1,2,2,2,2,... se você processar com glDrawElements.
Yakov Galka

Eu descobri! Tudo funciona agora! Acontece que eu estava passando e interpretação de índices de direito, mas eu estava passando o índice como um float para GLSL quando ele estava esperando um int. Eu fiz com que ele receba um float e em GLSL lançá-lo para um int e não é a interpretação de todos os índices de direito. Eu tenho que fazer isso porque o buffer de vértices é do tipo flutuante. Obrigado por tudo!
Christopher Barrios Agosto

@ChristopherBarriosAgosto: Parabéns que você percebeu isso. 'vertex buffer é do tipo flutuante' -- vértice buffers são sequências de bytes. Você pode armazenar structs lá com alguns int campos e alguns float de campos.
Yakov Galka
0

Eu não tenho certeza de como o seu mecanismo de código realmente se parece, mas eu suponho que ele se parece com qualquer outro programa OpenGL.

Se sim, em minha experiência, a matriz de transformação deve, normalmente, ser passado para o shader de vértice e ser aplicada com um determinado vértice informações sobre a GPU quando você desenhar a cena. Por exemplo:

//MVP matrix
GLuint MatrixID = glGetUniformLocation(shaderProgID, "MVP");
glUniformMatrix4fv(MatrixID, 1, GL_FALSE, &mvp[0][0]);

Mas se você quer encontrar as coordenadas de todos os vértices de um grupo específico, fora a prestação de função, você provavelmente terá que fazê-lo na CPU, ou você vai precisar usar algumas técnicas de programação paralela, como OpenCL para fazer o trabalho na GPU.

A coisa mais importante é, por que especificamente você quer o mundo coordenadas de informações para fora do desenho do procedimento? Se você simplesmente quer encontrar o modelo de coordenadas do mundo, você pode simplesmente definir um centro de coordenação para cada modelo que você tem em cena e a única pista que o único coordenar, em vez de toda a malha de grupo.

O vértice de informações deve ser sempre no modelo de coordenadas e armazenados no buffer de vértice sem toque, a menos que você deseja aplicar alguma modificação neles.

2021-11-24 03:57:24

Eu sou de lotes de vários gráficos juntos. Portanto, eu não posso usar uniformes para passar gráficos transformações, porque eu não vou ser capaz de alterar o uniforme para a transformação entre chamada de desenho. No entanto, acredito que usando SSBOs é uma boa alternativa.
Christopher Barrios Agosto

Em outros idiomas

Esta página está em outros idiomas

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................