Fork Nixie Tube Clock

https://www.shadertoy.com/view/Dds3WB

Shader code
shader_type canvas_item;

#define iResolution 1.0/SCREEN_PIXEL_SIZE
#define iTime TIME
#define fragColor COLOR

uniform bool TWELVE_HOUR_CLOCK = true;
uniform bool GLOWPULSE = true;
uniform vec3 GLOW_COLOR = vec3(1,0.2,0);
uniform bool SHOW_GRID = true;
uniform float GRID : hint_range(0.0, 1.0, 0.01) = 0.1;

uniform float now_time = 0.;
uniform vec2 DISP = vec2(0.45, 0.5);

uniform float scale1 : hint_range(0.01, 0.3, 0.01) = 0.15;
uniform float scale2 : hint_range(0.05, 3.0, 0.05) = 1.0;





// hash function copy from https://www.shadertoy.com/view/4djSRW
float hash12(vec2 p)
{
    vec3 p3  = fract(vec3(p.xyx) * .1031);
    p3 += dot(p3, p3.yzx + 33.33);
    return fract((p3.x + p3.y) * p3.z);
}


float noise(vec2 pos) {
    vec2 i = floor(pos);
    vec2 f = fract(pos);

    float a = hash12(i);
    float b = hash12(i + vec2(1, 0));
    float c = hash12(i + vec2(0, 1));
    float d = hash12(i + vec2(1, 1));

    vec2 u = f * f * (3.0 - 2.0 * f);

    return mix(mix(a, b, u.x), mix(c, d, u.x), u.y);
}

//Distance to a line segment,
float dfLine(vec2 start, vec2 end, vec2 uv)
{
	start *= scale1;
	end *= scale1;

	vec2 line = end - start;
	float frac = dot(uv - start,line) / dot(line,line);
	return distance(start + line * clamp(frac, 0.0, 1.0), uv);
}

//Distance to the edge of a circle.
float dfCircle(vec2 origin, float radius, vec2 uv)
{
	origin *= scale1;
	radius *= scale1;

	return abs(length(uv - origin) - radius);
}

//Distance to an arc.
float dfArc(vec2 origin, float start, float sweep, float radius, vec2 uv, float pi, float tau)
{
	origin *= scale1;
	radius *= scale1;

	uv -= origin;
	uv *= mat2(vec2(cos(start), sin(start)),vec2(-sin(start), cos(start)));

	float offs = (sweep / 2.0 - pi);
	float ang = mod(atan(uv.y, uv.x) - offs, tau) + offs;
	ang = clamp(ang, min(0.0, sweep), max(0.0, sweep));

	return distance(radius * vec2(cos(ang), sin(ang)), uv);
}

//Distance to the digit "d" (0-9).
float dfDigit(vec2 origin, float d, vec2 uv, float pi, float tau)
{
	uv -= origin;
	d = floor(d);
	float dist = 1e6;

	if(d == 0.0)
	{
		dist = min(dist, dfLine(vec2(1.000,1.000), vec2(1.000,0.500), uv));
		dist = min(dist, dfLine(vec2(0.000,1.000), vec2(0.000,0.500), uv));
		dist = min(dist, dfArc(vec2(0.500,1.000),0.000, 3.142, 0.500, uv, pi, tau));
		dist = min(dist, dfArc(vec2(0.500,0.500),3.142, 3.142, 0.500, uv, pi, tau));
		return dist;
	}
	if(d == 1.0)
	{
		dist = min(dist, dfLine(vec2(0.500,1.500), vec2(0.500,0.000), uv));
		return dist;
	}
	if(d == 2.0)
	{
		dist = min(dist, dfLine(vec2(1.000,0.000), vec2(0.000,0.000), uv));
		dist = min(dist, dfLine(vec2(0.388,0.561), vec2(0.806,0.719), uv));
		dist = min(dist, dfArc(vec2(0.500,1.000),0.000, 3.142, 0.500, uv, pi, tau));
		dist = min(dist, dfArc(vec2(0.700,1.000),5.074, 1.209, 0.300, uv, pi, tau));
		dist = min(dist, dfArc(vec2(0.600,0.000),1.932, 1.209, 0.600, uv, pi, tau));
		return dist;
	}
	if(d == 3.0)
	{
		dist = min(dist, dfLine(vec2(0.000,1.500), vec2(1.000,1.500), uv));
		dist = min(dist, dfLine(vec2(1.000,1.500), vec2(0.500,1.000), uv));
		dist = min(dist, dfArc(vec2(0.500,0.500),3.142, 4.712, 0.500, uv, pi, tau));
		return dist;
	}
	if(d == 4.0)
	{
		dist = min(dist, dfLine(vec2(0.700,1.500), vec2(0.000,0.500), uv));
		dist = min(dist, dfLine(vec2(0.000,0.500), vec2(1.000,0.500), uv));
		dist = min(dist, dfLine(vec2(0.700,1.200), vec2(0.700,0.000), uv));
		return dist;
	}
	if(d == 5.0)
	{
		dist = min(dist, dfLine(vec2(1.000,1.500), vec2(0.300,1.500), uv));
		dist = min(dist, dfLine(vec2(0.300,1.500), vec2(0.200,0.900), uv));
		dist = min(dist, dfArc(vec2(0.500,0.500),3.142, 5.356, 0.500, uv, pi, tau));
		return dist;
	}
	if(d == 6.0)
	{
		dist = min(dist, dfLine(vec2(0.067,0.750), vec2(0.500,1.500), uv));
		dist = min(dist, dfCircle(vec2(0.500,0.500), 0.500, uv));
		return dist;
	}
	if(d == 7.0)
	{
		dist = min(dist, dfLine(vec2(0.000,1.500), vec2(1.000,1.500), uv));
		dist = min(dist, dfLine(vec2(1.000,1.500), vec2(0.500,0.000), uv));
		return dist;
	}
	if(d == 8.0)
	{
		dist = min(dist, dfCircle(vec2(0.500,0.400), 0.400, uv));
		dist = min(dist, dfCircle(vec2(0.500,1.150), 0.350, uv));
		return dist;
	}
	if(d == 9.0)
	{
		dist = min(dist, dfLine(vec2(0.933,0.750), vec2(0.500,0.000), uv));
		dist = min(dist, dfCircle(vec2(0.500,1.000), 0.500, uv));
		return dist;
	}

	return dist;
}

//Distance to a number
float dfNumber(vec2 origin, float num, vec2 uv, vec2 digitSpacing, float pi, float tau)
{
	uv -= origin;
	float dist = 1e6;
	float offs = 0.0;

	for(float i = 5.0;i > -3.0;i--)
	{
		float d = mod(num / pow(10.0,i),10.0);

		vec2 pos = digitSpacing * vec2(offs,0.0);

		if(i == 0.0)
		{
			dist = min(dist, dfCircle(vec2(offs+0.9,0.1)*1.1, 0.04,uv));
		}

		if(num > pow(10.0,i) || i == 0.0)
		{
			dist = min(dist, dfDigit(pos, d, uv, pi, tau));
			offs++;
		}
	}
	return dist;
}

//Distance to a number This handles 2 digit integers, leading 0's will be drawn
float dfNumberInt(vec2 origin, int inum, vec2 uv, vec2 digitSpacing, float pi, float tau)
{
    float num = float(inum);
	uv -= origin;
	float dist = 1e6;
	float offs = 0.0;

	for(float i = 1.0;i >= 0.0;i--)
	{
		float d = mod(num / pow(10.0,i),10.0);

		vec2 pos = digitSpacing * vec2(offs,0.0);

        dist = min(dist, dfDigit(pos, d, uv, pi, tau));
        offs++;
	}
	return dist;
}

float dfColon(vec2 origin, vec2 uv) {
	uv -= origin;
	float dist = 1e6;
	float offs = 0.0;

    dist = min(dist, dfCircle(vec2(offs+0.9,0.9)*1.1, 0.04,uv));
    dist = min(dist, dfCircle(vec2(offs+0.9,0.4)*1.1, 0.04,uv));
    return dist;
}

//Length of a number in digits
float numberLength(float n)
{
	return floor(max(log(n) / log(10.0), 0.0) + 1.0) + 2.0;
}

void fragment()
{
	float pi = atan(1.0)*4.0;
	float tau = atan(1.0)*8.0;
	vec2 digitSize = vec2(1.0,1.5) * scale1;
	vec2 digitSpacing = vec2(1.1,1.6) * scale1;

	vec2 aspect = iResolution.xy / iResolution.y;
	vec2 uv = (UV - DISP) * scale2;
	uv.y = - uv.y;

    int hour = int(now_time/3600.);
if (TWELVE_HOUR_CLOCK == true){
	if( hour > 12 ) hour -= 12;
    if( hour == 0 ) hour = 12;
}

    int minute = int(mod(now_time/60.,60.));

	float nsize = numberLength(9999.);
	vec2 pos = -digitSpacing * vec2(nsize,1.0)/2.0;

    vec2 basepos = pos;
    pos.x = basepos.x + 0.16;
	float dist = 1e6;
	dist = min(dist, dfNumberInt(pos, hour, uv,digitSpacing, pi, tau));

    pos.x = basepos.x + 0.39;
	dist = min(dist, dfColon( pos, uv ));

    pos.x = basepos.x + 0.60;
    float dist2 = 1e6;
	dist = min(dist, dfNumberInt(pos, minute, uv, digitSpacing, pi, tau));

	vec3 color = vec3(0);

	float shade = 0.0;

	shade = 0.004 / (dist);

	color += vec3(1,0.2,0) * shade;
if (GLOWPULSE == true){
	color += GLOW_COLOR * shade * noise((uv + vec2(iTime*.5)) * 2.5 + .5);// * 10.*(noise(uv.yx));
}


    float grid;
    if( SHOW_GRID == true){
		 grid = 0.5-max(abs(mod(uv.x*64.0,1.0)-0.5), abs(mod(uv.y*64.0,1.0)-0.5));
	}


    color *= 0.25+vec3(smoothstep(0.0,GRID,grid))*0.75;


	fragColor = vec4( color , 1.0 );
}
This shader is a port from an existing Shadertoy project. Shadertoy shaders are by default protected under a Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported (CC BY-NC-SA 3.0) license unless anything else has been stated by the author. For more info, see our License terms.

More from RayL019

Protean clouds

Laplace filter, edge detection

cartoon explosion effect

Related shaders

Weird tube with balls

Analogue clock face

Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments