Motor OpenGL
Cargando...
Buscando...
Nada coincide
3.Shaders

Vamos a ver como funcionan los shaders programados en GLSL que es un lenguaje parecido a C.

3.1 GLSL

Como ya he dicho están escritos en algo parecido a C. Siempre se empieza con una declaración de la versión.

#version 330 // Equivale a OpenGL 3.3

Tiene unas variables para comunicarnos con el shader:

  • Inputs: sirven para recibir información de ese vértice en concreto. Por ejemplo: color, posición textura...
    in vec3 aPos;
    Estas se les conoce como vertex attributes y tienen un límite, como máximo 16 de vértices de 4 componentes.
  • Out: sirven para mandar información al siguiente paso de renderizado. Como modificar la posición y luego pasarla.
    out vec4 FragColor;
  • Uniforms: son variables globales y que si valor no cambia hasta que se vuelve a enviar otro
    uniform vec4 ourColor;

3.2 Tipos

Como en c las variables tienen un tipo, ya sea int, float, bool... Pero tambien tiene el tipo vector y matrices.

Vector

Puedes tener vectores de 1,2,3,4 componentes.

vecn // the default vector of n floats.
bvecn // a vector of n booleans.
ivecn //a vector of n integers.
uvecn // a vector of n unsigned integers.
dvecn // a vector of n double.

Se pueden construir así

vec2 someVec;
vec4 differentVec = someVec.xyxx;
vec3 anotherVec = differentVec.zyw;
vec4 otherVec = someVec.xxxx + anotherVec.yxzy;

3.3 Comunicación entre Shaders

Es posible pasar información del vertex al fragment shader, para ello las variables de out del vertex tienen que coincidir con el in del fragment. Ejemplo

Vertex Shader

#version 330 core
layout (location = 0) in vec3 aPos; // position tiene atributo position 0
out vec4 vertexColor; // color de salida
void main() {
gl_Position = vec4(aPos, 1.0);
vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // output a rojo oscuro
}

Fragment Shader

#version 330 core
out vec4 FragColor;
in vec4 vertexColor; // input con el mismo nombre
void main() {
FragColor = vertexColor;
}

3.4 Uniforms

Como ya hemos dicho antes, son variables globales y se pueden declarar en cualquier etapa de los shaders.

Para mandar información al shader, se hace de la siguiente manera

int vertexColorLocation = glGetUniformLocation(shaderProgram, "ourColor");
glUniform4f(vertexColorLocation, v.x, v.y, v.z, v.w); // Espera un vec4 de floats

Primero se obtiene la localización de la variable en memoria, poniendo el nombre exacto de la variable. Siempre primero se tiene que hacer el use antes del uniform.