¿Hay alguna analogía en la que pueda pensar al comparar estos diferentes tipos, o cómo funcionan estas cosas?
Además, ¿qué significa uniformar una matriz?
Respuestas:
Copiado directamente de http://www.lighthouse3d.com/tutorials/glsl-tutorial/data-types-and-variables/ . El sitio actual tiene información mucho más detallada y valdría la pena revisarlo.
Calificadores variables
Los calificadores dan un significado especial a la variable. Están disponibles los siguientes calificadores:
- const: la declaración es una constante de tiempo de compilación.
- atributo: variables globales que pueden cambiar por vértice, que se pasan de la aplicación OpenGL a los sombreadores de vértices. Este calificador solo se puede usar en sombreadores de vértices. Para el sombreador, esta es una variable de solo lectura. Consulte la sección de atributos.
- uniform - Variables globales que pueden cambiar por primitiva [...], que se pasan de la aplicación OpenGL a los sombreadores. Este calificador se puede utilizar tanto en sombreadores de vértices como de fragmentos. Para los sombreadores, esta es una variable de solo lectura. Consulte la sección Uniforme.
- variable: se utiliza para datos interpolados entre un sombreador de vértices y un sombreador de fragmentos. Disponible para escribir en el sombreador de vértices y de solo lectura en un sombreador de fragmentos. Consulte la sección Variante.
En cuanto a una analogía, const y uniform son como variables globales en C / C ++, una es constante y la otra se puede establecer. El atributo es una variable que acompaña a un vértice, como coordenadas de color o textura. El sombreador de vértices puede alterar las variables variables, pero no el sombreador de fragmentos, por lo que, en esencia, están pasando información por la tubería.
uniform
son parámetros por primitiva (constantes durante una llamada de dibujo completa);attribute
son parámetros por vértice (típicamente: posiciones, normales, colores, UV, ...);varying
son parámetros por fragmento (o por píxel ): varían de un píxel a otro.Es importante comprender cómo varying
funciona programar sus propios sombreadores.
Digamos que define un parámetro variable v
para cada vértice de un triángulo dentro del sombreador de vértices . Cuando este parámetro variable se envía al sombreador de fragmentos , su valor se interpola automáticamente en función de la posición del píxel a dibujar.
En la siguiente imagen, el píxel rojo recibió un valor interpolado del parámetro variable v
. Por eso los llamamos "variables".
En aras de la simplicidad, el ejemplo anterior utiliza la interpolación bilineal , que asume que todos los píxeles dibujados tienen la misma distancia de la cámara. Para una representación 3D precisa, los dispositivos gráficos utilizan una interpolación de perspectiva correcta que tiene en cuenta la profundidad de un píxel.
noperspective
para obtener una interpolación bilineal simple y no una interpolación de perspectiva correcta (identificada por el calificador predeterminado :) smooth
. Vea este ejemplo .
En WebGL, ¿cuáles son las diferencias entre un atributo, un uniforme y una variable variable?
En OpenGL, un "programa" es una colección de "sombreadores" (programas más pequeños), que están conectados entre sí en una tubería.
// "program" contains a shader pipeline:
// vertex shader -> other shaders -> fragment shader
//
const program = initShaders(gl, "vertex-shader", "fragment-shader");
gl.useProgram(program);
Los sombreadores procesan vértices (sombreador de vértices), geometrías (sombreador de geometría), teselación (sombreador de teselación), fragmentos (sombreador de píxeles) y otras tareas de proceso por lotes (sombreador de cálculo) necesarias para rasterizar un modelo 3D.
Los sombreadores OpenGL (WebGL) están escritos en GLSL (un lenguaje de sombreado basado en texto compilado en la 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>
Los sombreadores pueden pasar datos al siguiente sombreador de la canalización ( out
, inout
) y también pueden aceptar datos de la aplicación WebGL o un sombreador anterior ( in
).
Los sombreadores de vértices y fragmentos (cualquier sombreador en realidad) pueden usar una uniform
variable para recibir datos de la aplicación WebGL.
// Pass data from WebGL application to shader
const uniformHandle = gl.glGetUniformLocation(program, "vertexVariableA");
gl.glUniformMatrix4fv(uniformHandle, 1, false, [0.1, 0.2, 0.3], 0);
Vertex Shader también puede recibir datos de la aplicación WebGL con la attribute
variable, que se puede habilitar o deshabilitar según sea necesario.
// Pass data from WebGL application to Vertex Shader
const attributeHandle = gl.glGetAttribLocation(mProgram, "vertexVariableB");
gl.glEnableVertexAttribArray(attributeHandle);
gl.glVertexAttribPointer(attributeHandle, 3, gl.FLOAT, false, 0, 0);
Vertex Shader puede pasar datos al Fragment Shader usando la varying
variable. Vea el código GLSL arriba ( varying vec3 variableC;
).
Los uniformes son otra forma de pasar datos de nuestra aplicación en la CPU a los sombreadores en la GPU, pero los uniformes son ligeramente diferentes en comparación con los atributos de vértice. Primero que nada, los uniformes son globales. Global, lo que significa que una variable uniforme es única por objeto de programa de sombreado y se puede acceder a ella desde cualquier sombreador en cualquier etapa del programa de sombreado. En segundo lugar, independientemente de lo que establezca el valor uniforme, los uniformes mantendrán sus valores hasta que se restablezcan o actualicen
Me gusta la descripción de https://learnopengl.com/Getting-started/Shaders , porque la palabra per-primitiva no es intuitiva