Ring of Power

It’s a simple ring that can be used as an indicator (of an activated power, for instance). It uses a noise texture and additive blend for best result.

 

I recommend to use a tween or an animation player to add some dynamics.

 

Parameters are:

 

  • radius : Must be in ]0, 1]. Be careful to not overshoot when add the thickness. Radius plus thickness should be less than 1.
  • thickness : Must be in ]0, 1]. Thickness of the ring.
  • color : Obviously, the tint of the ring.
  • brightness : Color intensity multiplier.
  • angular_speed : Rotation speed of the ring (in rad/s).
  • radial_speed : Speed of the texture slide (in or out).
  • alpha : Alpha channel override.
  • noise : An seamless noise texture is preferred. But any seamless function can work (did i mention that it must be seamless ?).

 

Note : When using Godot 4.x, replace hint_color at line 8 with source_color. (Thx jboadas)

 
Shader code
shader_type canvas_item;
render_mode blend_add;

uniform float radius : hint_range(0.0, 1.0, 0.01) = .7;

uniform float thickness : hint_range(0.0, 1.0, 0.01) = .2;

uniform vec4 color : hint_color = vec4(0.9, 0.4, 0.1, 1.0);

uniform float brightness : hint_range(0.0, 15.0, 0.01) = 5.0;

uniform float angular_speed : hint_range(-5.0, 5.0, 0.01) = 2.5;

uniform float radial_speed : hint_range(-5.0, 5.0, 0.01) = 1.4;

uniform float alpha : hint_range(0.0, 1.0, 0.01) = .5;

uniform sampler2D noise;

void fragment() {
	vec2 v = vec2(.5) - UV;
	float d = length(v) * 2.;
	float angle = atan(v.y, v.x) + (TIME * angular_speed);
	float thick_ratio = 1. - (abs(d - max(0., radius)) / max(.0001, thickness));
	vec2 polar = fract(vec2(angle / 6.28, d + (TIME * radial_speed)));
	vec4 col = thick_ratio * brightness * color;
	vec3 tex = texture(noise, polar).rgb;
	col.a = (alpha * (tex.r + tex.g + tex.b) * clamp(thick_ratio, 0., 1.)) / 3.;
	COLOR = col;
}
Live Preview
Tags
colorful, motion, noise, ring
The shader code and all code snippets in this post are under CC0 license and can be used freely without the author's permission. Images and videos, and assets depicted in those, do not fall under this license. For more info, see our License terms.

More from CasualGarageCoder

Related shaders

Comments 12

  1. Cannot make it work, it says:

    res://shaders/power_ring.gdshader:8 - Expected valid type hint after ':'.
     Shader compilation failed.
    
    E  8-> uniform vec4 color : hint_color = vec4(0.9, 0.4, 0.1, 1.0);
    
    1
      1. After replace hint_color with source_color it works, beautiful shader, Very Thanks

        0
  2. This stops working after one rotation unless I fract polar, like

    vec2 polar = fract(vec2(angle / 6.28, d + (TIME * radial_speed));
    

    My noise texture would need to repeat infinitely for texture(noise, polar) to be able to pull noise with arbitrarily large polar.x and polar.y values.

    I'm sure I'm missing a setting that does this... I have 'seamless' checked. Any idea what I'm missing?

    3
    1. You are right. The repeat has to be infinite. The fract() usage is a good thing to do. I'll correct my shader after testing. Thank you for the feedback !

      0
  3. Neat! If you play with the radius/thickness it doubles as a magical tunnel vortex type thingie, haha!

    0