Created
September 23, 2012 06:52
-
-
Save num3ric/3769142 to your computer and use it in GitHub Desktop.
Shader Study 03 - Metaballs: vimeo.com/46562719
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/************************************ | |
* Shader Study 03 : Metaballs * | |
* num3ric - Eric Renaud-Houde * | |
* Summer 2012 * | |
************************************/ | |
#version 120 | |
#extension GL_ARB_texture_rectangle : enable | |
#extension GL_ARB_texture_non_power_of_two : enable | |
// Window size in pixels: Vec2f(getWindowSize()); | |
uniform vec2 windowSize; | |
// Particle positions in screen coordinates | |
uniform vec2 particles[100]; | |
// "Light wave" frequency. | |
// Standard range: [0.0, 0.15] | |
uniform float freq; | |
// "Light wave" frequency. | |
// Standard range: [0.0, 2*PI] | |
uniform float hue; | |
uniform sampler2DRect tex0; | |
const mat3 rgb2yiq = mat3(0.299, 0.587, 0.114, 0.595716, -0.274453, -0.321263, 0.211456, -0.522591, 0.311135); | |
const mat3 yiq2rgb = mat3(1.0, 0.9563, 0.6210, 1.0, -0.2721, -0.6474, 1.0, -1.1070, 1.7046); | |
float colorBurn(float bottom, float top) { | |
if ( top < 0.001 ) return 0.0; // We don't want to divide by zero | |
float col = 1.0 - (1.0 - bottom) / (2.0 * top); | |
return ( col < 0.0 ) ? 0.0 : col; | |
} | |
float vividLightBlend(float c1, float c2 ) { | |
float bottom, top; | |
if (c1 == c2) return c1; | |
if (c1 < c2) { | |
bottom = c1; | |
top = c2; | |
} else { | |
bottom = c2; | |
top = c1; | |
} | |
if ( top < 0.5 ) { | |
//unsure if this condition is necessary. | |
return colorBurn(bottom, top); | |
} else { | |
return bottom / ( 1.0 - 2.0 * (top - 0.5)); | |
} | |
} | |
void main() | |
{ | |
vec2 screenPos = gl_TexCoord[0].st; | |
screenPos.x *= windowSize.x/windowSize.y; | |
// Compute color with hue shift | |
// http://stackoverflow.com/questions/9234724/how-to-change-hue-of-a-texture-with-glsl | |
vec3 yiqColor = rgb2yiq * texture2DRect(tex0, windowSize*gl_TexCoord[0].st).rgb; | |
float originalHue = atan(yiqColor.b, yiqColor.g); | |
float finalHue = originalHue + hue; | |
float chroma = sqrt(yiqColor.b * yiqColor.b + yiqColor.g * yiqColor.g); | |
vec3 color = yiq2rgb*vec3(yiqColor.r, chroma * cos(finalHue), chroma * sin(finalHue)); | |
float potential = 0.0; | |
int i=0; | |
for (; i<100; i=i+1) | |
{ | |
potential += 1.0 / distance(screenPos, particles[i].xy/windowSize.yy);; | |
} | |
// Threshold for the equipotential line/isosurface between | |
// the black center and "the light waves". Manually adjusted. | |
if (potential > 300.0) { | |
potential = 0.0; | |
} else { | |
float inv_freq = 1.0/freq; | |
float light_wave_id = potential * freq; | |
if (abs(mod(light_wave_id, 2.0)) < 1.0) { | |
// light to dark | |
potential = freq * mod(potential, inv_freq); | |
} else { | |
// dark to light | |
potential = 1.0 - freq * mod(potential, inv_freq); | |
} | |
} | |
float r = vividLightBlend(potential, color.x); | |
float g = vividLightBlend(potential, color.y); | |
float b = vividLightBlend(potential, color.z); | |
gl_FragColor = vec4(r, g, b, 1.0); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#extension GL_ARB_texture_rectangle : enable | |
#extension GL_ARB_texture_non_power_of_two : enable | |
void main() | |
{ | |
gl_TexCoord[0] = gl_MultiTexCoord0; | |
gl_Position = ftransform(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment