Preview
#ifdef GL_ES
precision mediump float;
#endif
// Project Name : Azure Abyss (Aoi Naraku in Japanese)
// [Note] Please move your mouse !
uniform float time;
uniform vec2 resolution;
uniform vec2 mouse;
vec2 ScreenToCentroid(vec2 coord)
{
vec2 normalizedCoord = (coord / resolution.xy);
vec2 centroidCoord = normalizedCoord - vec2(0.5);
return centroidCoord;
}
vec2 CorrectAspect(vec2 coord)
{
float aspect = resolution.y/resolution.x;
return vec2(coord.x / aspect, coord.y);
}
float Deg2Rad(float deg)
{
return 3.14159265358979 / 180.0 * deg;
}
// http://qiita.com/shimacpyon/items/d15dee44a0b8b3883f76
float rand(vec2 co){
return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453);
}
// http://lolengine.net/blog/2013/07/27/rgb-to-hsv-in-glsl
vec3 hsv2rgb(vec3 c)
{
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
vec4 DrawPoint(vec2 fragPos, vec2 centerPos, vec2 holePos, float baseRadius, vec2 hue)
{
vec4 color;
float fromCenter = length(fragPos - centerPos);
float fromHole = length(fragPos - holePos);
float radius = baseRadius * (fromHole/2.0+0.5);
float pointRegion = step(fromCenter, radius);
color.rgb = hsv2rgb(vec3(mix(hue.x, hue.y, fromCenter/radius), 1.0-fromCenter, mix(0.0, 2.0, fromHole-0.1))) * pointRegion;
float ghostEffect = 0.05;
color.a = 1.0 - smoothstep(0.0, radius, fromCenter)+ghostEffect;
return color;
}
void main( void ) {
const int numBall = 12;
vec2 initPos[numBall];
vec2 initHue[numBall];
float interval = 1.0;
float tm = mod(time, interval)/interval;
float timeChange = Deg2Rad(90.0 * (time/interval));
float smoothValue = abs(sin(timeChange)); // 0 -> 1 -> 0 -> 1 -> 0 -> ...
float deltaAngle = 360.0 / float(numBall);
float ballRotateSpeed = 20.0;
float deltaHue = 1.0 / float(numBall+1);
for (int i = 0 ; i < numBall ; i++ ){
float fi = float(i);
float changeInitialAngleFactor = float(time) * ballRotateSpeed;
float angle = Deg2Rad(float(i) * deltaAngle + changeInitialAngleFactor);
vec2 dir = vec2(cos(angle), sin(angle)) * (0.5 + rand(vec2(fi,fi)));
float xx = dir.x;
float yy = dir.y;
initPos[i] = CorrectAspect(vec2(xx, yy));
initHue[i].x = deltaHue * float(i+1);
initHue[i].y = deltaHue * float(i);
}
vec2 p = ScreenToCentroid(gl_FragCoord.xy);
p = CorrectAspect(p);
vec2 center = mouse- vec2(0.5); //mouse coord : leftdown=(0,0), rightup=(1,1)
center = CorrectAspect(center);
float radius = 0.25;
float fromCenter = length(p - center);
float toCenterBlack = fromCenter/radius;
float frequency = 60.0;
float speed = 3.0;
float ringPower = 0.7;
float blueHole = abs(sin(fromCenter*frequency + timeChange*speed)) * toCenterBlack * ringPower;
blueHole *= rand(gl_FragCoord.xy * smoothValue);
float ballMoveInterval = 3.0;
int tt = int(time/ballMoveInterval);
tt = int(mod(float(tt),float(numBall)));
vec4 ballColor;
for (int i = 0 ; i < numBall; i++ ){
float ballMoveTm = mod(time + float(i), ballMoveInterval)/ballMoveInterval;
vec2 ballPos = mix(initPos[i], center, ballMoveTm);
vec4 ret = DrawPoint(p, ballPos, center, 0.05, initHue[i]);
ballColor += ret;
}
gl_FragColor = vec4(ballColor.r * ballColor.a, ballColor.g * ballColor.a, ballColor.b * ballColor.a + blueHole * 1.5 * (1.0-ballColor.a), 1.0);
}