#Scan shader

1 messages · Page 1 of 1 (latest)

crisp edge
#

I want to make a shader that will have a spherical scan effect and that will then have the scanned area highlighted for a short while, I simply can't wrap my head around how would I even start this and I need some help with that

analog vapor
#

If it's a circle, you'll need a center (vec2) and a radius (float). I would make these uniforms so that i could change where the circle is located and how big it is.

#

Alternately, if you want it to be centered on the sprite/texture and stretch to the boundaries, then you can calculate these values in your shader. There is a textureSize() method which takes a sampler2d and returns a ivec2 of the size of the texture:
ivec2 texture_size = textureSize(my_texture, 0);
You'll want your center to be at half that value
vec2 center = vec2(texture_size) / 2.0;
And you'll want your radius to be calculated this way:
float radius = float(min(texture_size.x, texture_size.y)) / 2.0;

#

Okay, now given that you have the center and the radius, you can determine if any pixel is inside the circle. First, get the pixel position of the point:
vec2 pixel_position = UV * vec2(texture_size);

#

Now, you can check whether that position is within the circle using the following formula:
bool is_within_circle = distance(pixel_position, center) <= radius;

#

If a pixel is outside of the circle, don't render it (or make it some default/background color)

#

Now onto the second part: if the pixel is inside of the circle, we want to render it, and we want to brighten it up if it is at the rotating scan line or just after the line

#

(I'm just noting that you said "spherical scan effect", not "circular scan effect". Most of what i'm saying can be directly translated to 3D, if you are indeed looking for a spherical effect.)

#

So for the second part, first we're going to need a scan_angle property which changes over time. (This will represent the current angle of the scan line.) You could either make this a uniform that you set from script (if you want to be able to control it), or you could just have it constantly changing at the same speed with a formula like this:

float frequency = 1.0;
float scan_angle = 2.0 * PI * fract(frequency * TIME);

(You can change frequency to change how fast the scan line rotates. If frequency = 1.0, then it will make a full rotation once a second. If frequency = 2.0, then it will make two full rotations every second.)

#

Now, we need to calculate the angle of the pixel that we are looking at and compare it to the current scan_angle. If they are the same, then that pixel should be fully highlighted. If the pixel's angle is slightly less than the scan_angle, then it will be highlighted, but not fully. If it is far away, then it is not highlighted at all

#

To calculate the angle of the pixel, you can use this formula:

vec2 from_center = pixel_position - center;
float pixel_angle = atan(from_center.y, from_center.x);
#

I'm not sure if atan() when used this way will take into account the sign of from_center.x. If not, you'll have to add PI when from_center.x is negative:

if (from_center.x < 0.0)
{
    pixel_angle.y += PI;
}

#

And when from_center.x is 0, you may also have to manually set it:

if (from_center.x == 0.0)
{
    if (from_center.y > 0.0)
    {
        pixel_angle = PI / 2.0;
    }
    else
    {
        pixel_angle = 3.0 * PI / 2.0;
    }
}
#

These are all edge cases that might be handles automatically by atan(from_center.y, from_center.x)

#

Anyway, now we have pixel_angle and we can compare it to scan_angle. The only issue is that angles loop. So when we compare it, we'll want to take the mod with 2pi:
float angle_diff = mod(scan_angle - pixel_angle, 2.0 * PI);

#

I can't remember if mod() in shaders always returns a positive value. If not, you may want to ensure that with the following line (will make it easier to use the angle_diff):

if (angle_diff < 0.0)
{
    angle_diff += 2.0 * PI;
}
lean rose
#

note: if you want a mod that always returs positive, use posmod

analog vapor
#

Is that available in shaders?

lean rose
#

probably not :p

#

didn't look at any messages other than the latest one

analog vapor
#

👍 No prob

analog vapor
#

Anyway, hopefully that helps you get started. I think the rest is mostly up to your artistic preferences. (Also, my description is probably too long already... sorry about that)