Uniformes
Les variables uniformes sont utilisées pour transmettre des données qui sont globales à un appel de rendu particulier et qui ne changent pas par sommet ou par fragment. Un vertex ou fragment shader peut recevoir des uniformes. Cela peut inclure des éléments tels que le temps écoulé, les matrices de transformation, les informations sur l’éclairage ou les propriétés des matériaux.
L’uniforme est déclarée dans un shader. Pour envoyer une valeur uniforme il faut trouver son emplacement dans la mémoire du GPU. Ensuite, la donnée peut être transmise. Les uniformes sont définies depuis l’application OpenGL et sont en immuables dans le shader.
//Vertex Shader
#version 460 core
layout (location = 0) in vec3 position;
uniform float offset;
void main() {
vec3 newPos = position + vec3(offset, 0.0, 0.0);
gl_Position = vec4(newPos, 1);
}
Si la valeur uniforme ne change pas à travers le temps, il n’est pas nécessaire d’envoyer sa valeur à chaque itération de la boucle principale.
// ...
// déclarer et initialiser la constante
constexpr float xTranslation = 0.5f;
// ...
int main() {
// ...
// utiliser le programme de shader compilé
glUseProgram(shaderProgram);
// obtenir l'emplacement en VRAM de la variable `offset` déclarée dans le vertex shader de shaderProgram
GLint offsetLocation = glGetUniformLocation(shaderProgram, "offset");
// transférer la valeur sur le GPU
glUniform1f(offsetLocation, xTranslation);
// ...
// boucle du jeu
// ...
}
Si la valeur change à chaque itération, il faut mettre à jour la mémoire du GPU.
// ...
// déclarer et initialiser la variable
float xTranslation = 0.5f;
// ...
int main() {
// ...
// obtenir l'emplacement en VRAM
GLint offsetLocation= glGetUniformLocation(shaderProgram, "offset");
while (!glfwWindowShouldClose(window)) {
// ...
// changement de l'uniforme; il faut mettre à jour la valeur sur le GPU
xTranslation += 0.001f;
// transférer la valeur sur le GPU
glUniform1f(offsetLocation, xTranslation);
}
}
Notez que nous ne sommes pas forcés dans une situation « tout ou rien ». Nous pouvons mettre à jour la valeur dans la VRAM à chaque \(n\) itérations, ou à chaque \(m\) secondes, si les données ne sont pas mise-à-jour fréquemment. Optimisation !