+1 vote

I want to achieve this kind of effect:
enter image description here

with a tileset and and 16x16 texture of eyes, I have this so far but don't know how to achieve this effect:
enter image description here

Can you help me with the shader code, or is there another way to do this?

in Engine by (16 points)

2 Answers

+1 vote
Best answer

A few things in addition to @kidscancode's correct, but minimal answer.

As explanation: you modify the coordinate at which the texture is read for each pixel (only for your eyes-texture, though).

Also I want to note that in your example, the masking seems to be incorrect. It looks like there are transparent pixels in the base texture which are also red, causing the eye texture to be displayed there aswell.

They don't show up for these lines

col.rgb = vec3(abs(sin(TIME*3.0)));
col.rg = UV;

because these don't change the pixel's alpha value.

This one, however, overwrites the pixel's alpha, aswell, causing you to see all masked pixels (even ones that are transparent)

col = tex;

Another thing you might want to avoid:

if(<some float variable> == <some constant>)

Because of inaccuracies or rounding errors == might not always work.
Personally I'd use something like (a >= 0.98f) just to be safe.

And lastly, looking at the UVs you might run into trouble with stretching for your eye-texture because of the UV difference. (it also looks like it in the 2nd gif you posted)

Keep us updated on whether or not it works.

by (99 points)
selected by

I DID IT!
video

shader_type canvas_item;
render_mode unshaded;

uniform sampler2D eyes : hint_albedo;

void fragment()
{
vec4 col = texture(TEXTURE, UV);
if (col.r >= 0.98)
    col.rgb = vec4(texture(eyes,
    vec2(fract(SCREEN_UV.x*40.0-sin(TIME+1.5)),
    fract(SCREEN_UV.y*22.5+sin(TIME))
    ))).rgb;
    COLOR = col;
}

enter image description here

Great to hear!

The factors 40 and 22.5 seem a bit arbitrary, did you calculate them or adjust them manually? You might run into problems if your texture size changes.

There is a way to calculate these using the dimensions of those text inside the shader.

Right, should've made the shader calculate it so it works for everything. My game is 640x360 pixels, I divided that by 16, eyes texture is 16x16

I think it's dependent on the size of the atlas texture that's used for the tilemap and the size of your eye texture. (Unless you're using this as an fullscreen postprocess shader and not an object shader)

If you need any more help, let me know.

+2 votes

This should get you started:

shader_type canvas_item;

uniform float speed;

void fragment() {
    COLOR.rgb = texture(TEXTURE, vec2(UV.x, UV.y + TIME/speed)).rgb;
}
by (20,891 points)
edited by
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.