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;
}
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

Slice and Fade out

Swirl/Sink

Frosty Rotative Deformation

Subscribe
Notify of
guest

7 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Mike
Mike
1 month ago

Cool! Thank you very much!

jboadas
jboadas
1 month ago

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);
jboadas
jboadas
1 month ago
Reply to  jboadas

In Godot 4 hint_color has been renamed to source_color

jboadas
jboadas
1 month ago
Reply to  jboadas

After replace hint_color with source_color it works, beautiful shader, Very Thanks

RoseBloom
RoseBloom
1 month ago

Thank you very much!

orbital_comma
orbital_comma
1 month ago

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?