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;
}
Cool! Thank you very much!
Glad you loved it. Don’t hesitate to post an example of your usage of it ๐
Cannot make it work, it says:
In Godot 4 hint_color has been renamed to source_color
After replace hint_color with source_color it works, beautiful shader, Very Thanks
Thx ! I’m starting to port my shaders to Godot 4. I hope to finish soon.
Thank you very much!
You’re welcome ๐
This stops working after one rotation unless I fract polar, like
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?
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 !
่ฟไธชๆๆ็ไธ้