Making Waves! - Rotación RGB
Hace poco me incribí en el curso de La génesis digital de las formas de Sol Sarratea. Las primeras horas de presentación me maravillaron con un mundo matemático completamente desconocido y me mostró otra perspectiva con la que entender las cosas.
La idea de Making Waves! (Haciendo Olas) es compartir el camino por el que pasé explicando con cierto detalle el trasfondo matemático, desde filtros básicos en imágenes hasta efectos de ondas dados por ecuaciones diferenciales.
Este artículo es una introducción a los conceptos que voy a estar explicando a lo largo de los artículos
Siguiente: Making Waves! Desenfoque gaussiano
Shaders
Internet está llena de explicaciones del concepto de shader mucho mejores de lo que puedo desarrollar. En términos simples un shader es un algoritmo que corre en la GPU y determina como se van a terminar visualizando la pantalla. Hacen calculos para iluminación, sombras y efectos. Hay muchos tipos de shaders, algunos trabajan con objetos 3d (Vertex Shaders), otros con geometrías (Geometry Shaders) y, sobre los que se vá a enfocar el artículo, shaders que trabajan sobre píxeles (Fragment Shaders).
Un shader de píxeles ejecuta una vez por cada pixel que forma parte de una textura y tiene como resultado un vector que indica el color de ese pixel. Para poder ejecutar de manera paralela se prohibe saber el estado de la ejecución del shader para los ótros píxeles, es decir, no se comparte información. A alto nivel, un shader funciona de la siguiente manera:
# texture es la textura base a modificar
# new_texture es la salida
def apply_shader(shader, texture):
for (x,y) in texture.range():
new_texture[x][y] = shader(texture, (x,y))
return new_textureSi se está procesando un video, un juego o algo que requiera actualizaciones constantes visuales, se suele ejecutar el shader una vez por frame, por lo que tiene que ser una operación rápida.
Rotación RGB
Un píxel es un vector de 4 dimensiones: (r,g,b,a) con valores entre 0 y 1. Tomando el pixel entrante, podemos devolver un pixel con los valores rgb rotados:
(r,g,b,a) -> (g,b,r,a)
![]() |
![]() |
| Imagen Base | Rotación RGB |
A continuación se puede ver una implementación del shader de rotación RGB en GLSL, un lenguaje de shading similar a C definido por OpenGL.
// Rotacion RGB: Ejemplo de shader en glsl
// textura base sobre la que se trabaja, constante para todos los pixeles
uniform sampler2D baseTex;
// coordenadas del pixel sobre el que se está ejecutando el shader
IN vec2 texCoord;
void main()
{
// texture2D toma el pixel en la posición texCoord de la textura baseTex
vec4 pixel = texture2D(baseTex, texCoord);
// la salida, en outColor rota los colores rgb -> gbr y el canal alpha
// queda igual
outColor = vec4(pixel.g, pixel.b, pixel.r, pixel.a);
}Los ejemplos clásicos con los que vamos a trabajar son el desenfoque gaussiano, o gaussian blur, y la detección de bordes o laplace filter.
![]() |
![]() |
![]() |
| Imagen Base | Desenfoque gaussiano | Detección de bordes |
En CustomFilters se puede ver una implementación simple de estos tres shaders sobre la plataforma cables.gl. Esta plataforma permite computar shaders sin instalar software especial en nuestro sistema y sin necesariamente saber programar. Para ver las distintas implementaciones hay que abrir el patch en el editor de cables y editar el custom shader.
En los próximos artículos se van a desarrollar los filtros de desenfoque gaussiano, detección de bordes y una introducción a ecuaciones diferenciales.
Siguiente: Making Waves! Desenfoque gaussiano



