#Circle shader in Godot 4.2.2

1 messages · Page 1 of 1 (latest)

serene prism
#

I this case a circle_size of 1.0 should make a circle with the screen height as it's radius (UV.y goes from 0 to 1 accross a rect which covers exactly the screen), which will definitely not always cover the whole screen.

The minimum circle size that will cover the screen from any position inside the screen is going to be the diagonal length of the screen, which would normally be sqrt(width * width + height * height) but in your case height is always 1 so sqrt(width * width + 1) would also work, and if you expect a maximum aspect ratio of say 4 width to 1 height you can just pre-calculate that value and always use it if you want. since being too big is fine. square roots can be a little expensive but just 1 here probably wont hurt much.

once you have the necessary minimum radius to cover the screen you just need to multiply circle_size by it in the step function, so that way an input value of 0 to 1 in circle_size will become 0 to min_r in the step function
COLOR.a = step(circle_size * min_r, dist);

old ibex
serene prism
old ibex
#

The interval is strange like it goes from 0 to 0.5, I'm so confused

serene prism
old ibex
#

Ok

serene prism
#

if you want better control of the size of the circle so it's always only as big as you need it (circle always covers the screen at exactly 1.0) then you'll have to do some math like pick the furthest corner, calculate the distance to it and use that as the radius instead of 4.123
I wont get into the math but if you want to do something like that in a shader it's just like

vec2 far_corner = round(vec2(1.) - circle_center);
far_corner.x = far_corner.x * ratio;
float full_radius = distance(far_corner, vec2(mix(circle_center.x, UV.x, ratio), UV.y));

COLOR.a = step(circle_size * full_radius, dist);
#

there's probably a lot of ways to do it, this just calculates the coordinate of the furthest corner (where the height of the screen is 1 and the width is whatever the aspect ratio is).
and then uses that to multiply the circle_size so the circle goes from size 0 to just big enough to cover the whole screen from whatever the center is

#

assuming the center point is inside the screen

#

I can also help if there's something about the shader you just can't figure out, but other than that you'd be better off just getting familiar with the shading language. There's some documentation in the godot docs, but it's also very heavily based on GLSL so almost any materials about GLSL should help.

old ibex
#

the result is very strange, the circle starts to open

#

I can't send videos here to show it

weak flame
#

Passing square distances to the shader is probably faster

#

// square rad values
uniform float width = 0.191; // 1px @ 16px
uniform float aa_in = 0.208; // 0.3px @ 16px
uniform float aa_out = 0.232; // 0.3px @ 16px
uniform bool ring = true;

void fragment()
    {
    float sqdist = dot(UV - 0.5, UV - 0.5);
    if (ring) COLOR.a *= min( smoothstep(0.25, aa_out, sqdist), smoothstep(width, aa_in, sqdist) );
    else COLOR.a *= smoothstep(0.25, aa_out, sqdist);
    }```
#

Or maybe I just like to make things harder for myself, who knows

old ibex
#

what

proud orbit
#

Not sure if there's a particular reason you want to use shaders for this but an easy alternative is to just add a circle as a sprite in the scene and adjust it's scale using an animation player.

old ibex
#

I thought doing with shaders would be faster, but I am running into all sort of problems

proud orbit
#

You should still be able to do this with an animation I think, use a TextureRect inside an AspectRatioContainer