CMH Studio

Far Circle

A shader that creates a circle that fades into the distance.


#ifdef GL_ES
precision mediump float;
#define GLSLIFY 1
#endif

uniform vec2 u_resolution;
uniform float u_time;
uniform vec2 u_mouse;

#define GLSLIFY 1
mat2 rotate2d(float _angle){
    return mat2(cos(_angle),-sin(_angle), sin(_angle),cos(_angle));
}

vec2 hash2_0( vec2 x )        //亂數範圍 [-1,1]
{
    const vec2 k = vec2( 0.3183099, 0.3678794 );
    x = x*k + k.yx;
    return -1.0 + 2.0*fract( 16.0 * k*fract( x.x*x.y*(x.x+x.y)) );
}

float gnoise_0( in vec2 p )   //亂數範圍 [-1,1]
{
    vec2 i = floor( p );
    vec2 f = fract( p );
    
    vec2 u = f*f*(3.0-2.0*f);

    return mix( mix( dot( hash2_0( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), 
        dot( hash2_0( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
        mix( dot( hash2_0( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), 
        dot( hash2_0( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}

float noise( in vec2 p )	//亂數範圍 [-1,1]
{
    #ifdef Use_Perlin    
    return gnoise_0(p);       //gradient noise
    #elif defined Use_Value
    return vnoise(p);       //value noise
    #endif    
    return 0.0;
}

float noise( in vec3 p )	//亂數範圍 [-1,1]
{
    #ifdef Use_Perlin    
    return gnoise_0(p);       //gradient noise
    #elif defined Use_Value
    return vnoise(p);       //value noise
    #endif    
    return 0.0;
}

float circle(vec2 uv, float radius){
    float dist = length(uv);
    float circle_dist = abs(dist-radius);//光環大小
    return circle_dist;
}

vec2 hash2_1( vec2 x )        //亂數範圍 [-1,1]
{
    const vec2 k = vec2( 0.3183099, 0.3678794 );
    x = x*k + k.yx;
    return -1.0 + 2.0*fract( 16.0 * k*fract( x.x*x.y*(x.x+x.y)) );
}

float gnoise_1( in vec2 p )   //亂數範圍 [-1,1]
{
    vec2 i = floor( p );
    vec2 f = fract( p );
    
    vec2 u = f*f*(3.0-2.0*f);

    return mix( mix( dot( hash2_1( i + vec2(0.0,0.0) ), f - vec2(0.0,0.0) ), 
        dot( hash2_1( i + vec2(1.0,0.0) ), f - vec2(1.0,0.0) ), u.x),
        mix( dot( hash2_1( i + vec2(0.0,1.0) ), f - vec2(0.0,1.0) ), 
        dot( hash2_1( i + vec2(1.0,1.0) ), f - vec2(1.0,1.0) ), u.x), u.y);
}

float fbm(in vec2 uv)       //亂數範圍 [-1,1]
{
    float f;                //fbm - fractal noise (4 octaves)
    mat2 m = mat2( 1.6,  1.2, -1.2,  1.6 );
    f   = 0.5000*gnoise_1( uv ); 
    uv = m*uv;		  
    f += 0.2500*gnoise_1( uv ); 
    uv = m*uv;
    f += 0.1250*gnoise_1( uv ); 
    uv = m*uv;
    f += 0.0625*gnoise_1( uv ); 
    uv = m*uv;
    return f;
}

float glow(float d, float str, float thickness){
    return thickness / pow(d, str);
}

void main() {
    vec2 st = gl_FragCoord.xy/u_resolution.xy;	//[0,1]
    //st.x *= u_resolution.x/u_resolution.y;//[0~1.33]
    vec2 uv = st*2.0-1.0; //[0,1] -> [-1,1]
    //uv.x *= u_resolution.x/u_resolution.y;//[-1.33~1.33]
    
    vec3 color;
    for(int index=0;index<12;++index)
    {
        float noise_position= smoothstep(0.2, 0.7, uv.x+0.420);
        float noise_scale=0.328*noise_position;
        float noise_freq=2.084;
        //float circle_dist=circle(uv, 0.480+noise_scale
            //*noise( vec3(uv*noise_freq, float(index)+u_time*0.4)) );
        
        uv *= rotate2d(-0.004);
        float circle_dist=circle(uv, 0.480+noise_scale
            *noise( vec3(uv*noise_freq, float(index)+u_time*0.4)) );
        
        
        float breathing= sin(u_time/2.0*3.14159)*0.2+0.5;//[0.3, 0.7]
        //float breathing= mix(0.3, 0.7, 
            //sin(u_time/2.0*3.14159)*0.5+0.5);//[0.3, 0.7]
        float glow_circle= glow(circle_dist,0.3,0.014);
        //float glow_circle= exp(-circle_dist*8.5);

        //亂數作用雲霧
        float fog= fbm(0.4*uv+vec2(-0.2*u_time, -0.02*u_time))*0.6+0.1;
        
        color += vec3(glow_circle); //*vec3(1.000,0.348,0.006)
    }
            
    gl_FragColor = vec4(color,1.0);
}