web-dev-qa-db-fra.com

Dans WebGL, quelles sont les différences entre un attribut, un uniforme et une variable variable?

Existe-t-il une analogie à laquelle je puisse penser en comparant ces différents types ou en quoi cela fonctionne?

Aussi, que signifie uniformiser une matrice?

61
Skorpius

Copié directement à partir de http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/ . Le site actuel contient des informations beaucoup plus détaillées et il serait intéressant de vérifier.

Qualificatifs variables

Les qualificatifs donnent une signification particulière à la variable. Le suivant les qualificatifs sont disponibles:

  • const - La déclaration est une constante de temps de compilation.
  • attribut - Variables globales pouvant être modifiées par sommet, transmises de l'application OpenGL aux vertex shaders. Ce qualificatif ne peut être utilisé que dans les vertex shaders. Pour le shader c'est un variable en lecture seule. Voir la section Attribut.
  • uniform - Variables globales susceptibles de changer par primitive [...] et transmises depuis OpenGL application aux shaders. Ce qualificatif peut être utilisé dans les deux sommets et fragment shaders. Pour les shaders, il s'agit d'une variable en lecture seule . Voir la section Uniforme.
  • variant - utilisé pour les données interpolées entre un vertex shader et un fragment shader. Disponible pour écrire dans le vertex shader, et lecture seule dans un fragment shader. Voir la section Variation.

En ce qui concerne l'analogie, const et uniform sont comme des variables globales en C/C++, l'une est constante et l'autre peut être définie. Attribut est une variable qui accompagne un sommet, telle que la couleur ou les coordonnées de texture. Les variables variables peuvent être modifiées par le vertex shader, mais pas par le fragment shader, elles transmettent donc des informations par la suite.

68
Alfredo Gimenez
  • uniform sont par-primitive paramètres (constants pendant tout un appel de tirage);
  • attribute sont paramètres par sommet (typiquement: positions, normales, couleurs, UV, ...);
  • varying sont par-fragment (ou par-pixel): ils varient de pixels en pixels.

Il est important de comprendre comment fonctionne varying pour programmer vos propres shaders.
Supposons que vous définissiez un paramètre variable v pour chaque sommet d'un triangle à l'intérieur du vertex shader. Lorsque ce paramètre variable est envoyé au fragment shader, sa valeur est automatiquement interpolée via interpolation bilinéaire en fonction de la position du pixel à tracer.

Dans l'image suivante, le pixel rouge a reçu une valeur interpolée du paramètre variable v. C'est pourquoi nous les appelons "variables".

 varying parameter being bilinearly interpolated

34
neeh

En OpenGL, un "programme" est un ensemble de "shaders" (programmes plus petits), connectés les uns aux autres dans un pipeline.

// "program" contains a shader pipeline:
//   vertex shader -> other shaders -> fragment shader
//
var program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);

Les shaders traitent les sommets (vertex shader), les géométries (geometry shader), la tessellation (tessellation shader), les fragments (pixel shader) et d'autres tâches de traitement par lot (calcul shader) nécessaires pour pixelliser un modèle 3D.

Les shaders OpenGL (WebGL) sont écrits en GLSL (langage de shader à base de texte compilé sur le GPU).

// Note: As of 2017, WebGL only supports Vertex and Fragment shaders

<!-- Vertex Shader -->
<script id="shader-vs" type="x-shader/x-vertex">

  // <-- Receive from WebGL application
  uniform vec3 vertexVariableA;

  // attribute is supported in Vertex Shader only
  attribute vec3 vertexVariableB;

  // --> Pass to Fragment Shader
  varying vec3 variableC;

</script>

<!-- Fragment Shader -->
<script id="shader-fs" type="x-shader/x-fragment">

  // <-- Receive from WebGL application
  uniform vec3 fragmentVariableA;

  // <-- Receive from Vertex Shader
  varying vec3 variableC;

</script>

Gardant ces concepts à l'esprit:

Les shaders peuvent transmettre des données au prochain shader du pipeline (out, inout). Ils peuvent également accepter les données de l'application WebGL ou d'un précédent shader (in).

  • Les shaders Vertex et Fragment (n'importe quel shader) peuvent utiliser une variable uniform pour recevoir des données de l'application WebGL.

    // Pass data from WebGL application to shader
    var uniformHandle = gl.glGetUniformLocation(program, "vertexVariableA");
    gl.glUniformMatrix4fv(uniformHandle, 1, false, [0.1, 0.2, 0.3], 0);
    
  • Le Vertex Shader peut également recevoir des données de l'application WebGL avec la variable attribute, qui peut être activée ou désactivée si nécessaire.

    // Pass data from WebGL application to Vertex Shader
    var attributeHandle = gl.glGetAttribLocation(mProgram, "vertexVariableB");
    gl.glEnableVertexAttribArray(attributeHandle);
    gl.glVertexAttribPointer(attributeHandle, 3, gl.FLOAT, false, 0, 0);
    
  • Le Vertex Shader peut transmettre des données au Fragment Shader à l'aide de la variable varying. Voir le code GLSL ci-dessus (varying vec3 variableC;).

5
tfmontague

Les uniformes sont un autre moyen de transmettre les données de notre application sur le CPU aux shaders du GPU, mais les uniformes diffèrent légèrement des attributs de vertex. Tout d'abord, les uniformes sont globaux. Global, ce qui signifie qu'une variable uniforme est unique par objet de programme de shader et est accessible à partir de tout shader à n'importe quel stade du programme de shader. Deuxièmement, quelle que soit la valeur définie pour l'uniforme, les uniformes conservent leurs valeurs jusqu'à ce qu'ils soient réinitialisés ou mis à jour.

J'aime la description de https://learnopengl.com/Getting-started/Shaders , car le mot par-primitive n'est pas intuitif

1
Liu Hao