Skip to content

Instantly share code, notes, and snippets.

@kernelp4nic
Last active August 29, 2015 14:00
Show Gist options
  • Save kernelp4nic/11378979 to your computer and use it in GitHub Desktop.
Save kernelp4nic/11378979 to your computer and use it in GitHub Desktop.
The Amplituhedron TM® (http://glsl.heroku.com/e#16354.0)
//The Amplituhedron TM®
//By [email protected]
#ifdef GL_ES
precision highp float;
#endif
// Uniform es constante mientras corre el shader
uniform float time;
uniform vec2 mouse; // vec2 es un tipo de dato, en este caso un vector de 2 dimensiones (coordenadas X:Y)
uniform vec2 resolution;
const float PI = 3.1415926535897932384626; // No cambian NUNCA
const float LINE_WIDTH = 0.005; // Grosor de las lineas del Amplituhedron TM®
const float DIST = 3.0; // Distancia de la camara virtual
// Globales dentro de este file
vec3 z;
vec3 y = vec3(0.0, cos(time) * 0.4, 0.0);
mat3 rot;
float line(vec3 a, vec3 b, vec2 pos) {
// Triquiñuela para la rotación
// (aplica traslacion y rotacion de vectores)
a = (a - z) * rot + z + y;
b = (b - z) * rot + z + y;
vec2 a2 = vec2(a.x, a.y) / a.z;
vec2 b2 = vec2(b.x, b.y) / b.z;
// largo del segmento a2-b2
float l = distance(a2, b2);
// vector director normalizado
vec2 r2 = (a2 - b2)/l;
// pixel llevado al origen de la recta
vec2 p = pos - b2;
// producto interno entre los vectores r2 y p (producto escalar)
float t = dot(r2, p);
// la proyección del pixel a donde corta la recta
vec2 proyect = r2 * t;
// la distancia de proyect
float dist = distance(proyect, p);
// calculo del ancho
if (t >= 0.0 && t <= l && dist < LINE_WIDTH) {
// Degradé del color, sino sería la linea
// completa de color solido
float d = 1.0 - dist / LINE_WIDTH;
return d;
}
return 0.0;
}
// Calcula matriz de rotación en
// base a un angulo
mat3 rotY(float ang) {
float c = cos(ang);
float s = sin(ang);
return mat3(c, 0, s,
0, 1, 0,
-s, 0, c);
}
// triquiñuela para darle color a
// cada arista
float f(int i){
return floor(mod(float(i), 4.0) / 3.0);
}
void main( void ) {
// posición del pixel que se está dibujando ahora
vec2 pos = gl_FragCoord.xy / resolution.xy - 0.5;
pos.x *= (resolution.x / resolution.y);
// coordenadas y del mouse que llegan a un maximo
float my = max(mouse.y, 0.3) * 1.5;
// radio chico de la esfera
float RADIO_1 = 0.5 * my * my;
// radio grande
float RADIO_2 = 1.0 * sqrt(my);
// Colores
vec3 color = vec3(0.0, 0.0, 0.0);
vec3 c1 = vec3(1.0, 0.0, 0.0);
vec3 c2 = vec3(0.0, 1.0, 0.0);
vec3 c3 = vec3(0.0, 0.0, 1.0);
vec3 c4 = vec3(1.0, 1.0, 0.0);
// Vector que apunta desde la vista hacia el objeto
z = vec3(0, 0, DIST);
// 2 Octogonos * 3
for (int i = 0; i < 8 * 3; i++) {
if (length(color) >= 1.0) {
break;
}
rot = rotY(-mouse.x * 8.0 - 4.0 + float(i / 8) * PI / 3.0);
float ang = float(i) / 4.0 * PI;
float nextAng = float(i + 1) / 4.0 * PI;
float b = mod(float(i), 2.0);
float r = b * RADIO_1 + (1.0 - b) * RADIO_2;
float r2 = b * RADIO_2 + (1.0 - b) * RADIO_1;
float c = line (vec3(cos(ang) * r, sin(ang) * r, DIST), vec3(cos(nextAng) * r2, sin(nextAng) * r2, DIST), pos);
color += c*(f(i)*c1 + f(i + 1)*c2 + f(i + 2)*c3 + f(i + 3)*c4);
c = line (vec3(cos(ang) * r2, sin(ang) * r2, DIST), vec3(cos(nextAng) * r, sin(nextAng) * r, DIST), pos);
color += c*(f(i + 2)*c1 + f(i + 3)*c2 + f(i + 4)*c3 + f(i + 5)*c4);
}
// Hexagono del medio
for (int i = 0; i < 6; i++) {
if (length(color) >= 1.0) {
break;
}
rot = rotY(-mouse.x * 8.0 - 4.0);
float ang = float(i) / 3.0 * PI;
float nextAng = float(i + 1) / 3.0 * PI;
float b = mod(float(i), 2.0);
float r = b * RADIO_1 + (1.0 - b) * RADIO_2;
float r2 = b * RADIO_2 + (1.0 - b) * RADIO_1;
float c = line (vec3(cos(ang) * r, 0.0, sin(ang) * r + DIST), vec3(cos(nextAng) * r2, 0.0 , sin(nextAng) * r2 + DIST), pos);
color += c*(f(i)*c1 + f(i + 1)*c2 + f(i + 2)*c3 + f(i + 3)*c4);
c = line (vec3(cos(ang) * r2, 0.0 , sin(ang) * r2 + DIST), vec3(cos(nextAng) * r, 0.0, sin(nextAng) * r + DIST), pos);
color += c*(f(i + 1)*c1 + f(i + 2)*c2 + f(i + 3)*c3 + f(i + 4)*c4);
}
// background
if (length(color) == 0.0) {
gl_FragColor = vec4((vec3(cos(-time + pos.x*10.0), cos(-time *1.3 + pos.y*10.0), cos(time* pos.x*pos.y*2.0)*2.0) * dot(pos, pos) * 0.5), 1.0 );
}
else {
gl_FragColor = vec4( color, 1.0 );
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment