0 votes

I am currently creating a game where I want my player to shoot a laser, which I implemented as a Line2D.
I am using a sprite that repeats (as a tile):
laser_sprite

I can accomplish this quite simply by importing the texture as 'Repeating' and then giving the Line2D an ImageTexture

What I would like to do, however, is change the sprite every frame, by 'looping' the sprite 1 pixel, to make it seem like the laser is flowing. What I mean is that on frame 1 I have the following sprite:
laser_sprite
While on frame 2 I have:
laser_sprite
It's probably hard to see, but the second image has the righternmost column of image 1 removed and added as its first column. This process then repeats 64 times (as my laser tile is 64 pixels wide)

I have tried giving the Line2D an AtlasTexture, then give that an ImageTexture. This ImageTexture contains all the frames I want to use as a spritesheet. Then, in code, I try and update the Region property of the AtlasTexture. However, it seems Line2D doesn't allow this behavior, as the sprite doesn't change.

Any ideas on how to approach this?

in Engine by (15 points)

1 Answer

+1 vote
Best answer

You could add an AnimationPlayer and change the frames. However, if all frames are the same but displaced one pixel, and they are in repeate mode, you may better use a simple shader:

shader_type canvas_item;

void fragment(){
    COLOR = texture(TEXTURE, vec2(UV.x + TIME, UV.y));
}

Note, just use the first frame, with repeat mode enabled, and this shader.

by (3,501 points)
selected by

Thanks, this is great stuff.

First time I've seen a shader used, I'd like to understand what the code actually does. Here's my current understanding:

fragment automatically runs for every pixel on every frame.
Within fragment, we update the COLOR value of each pixel.
To do this, we find the desired pixel in the sprite TEXTURE using texture, why does this return a color?

The second parameter of texture is the desired pixel, UV is the coords of the current pixel, and because we have repeat mode on, we can get away with UV.x + TIME without adding a modulo operation?

Thanks again for the help!

First, is partially correct. The fragment function runs for each "fragment" of the canvas item. A texture may be 16x16 pixels, but OpenGL interpolates and you may end up with many fragments per pixel. COLOR is just the output of the fragment function, you must put there the color you want that fragment have. The funxtion texture is a function used to retrieve the color of a given sampler2d (in short, the type for textures in OpenGL) and given some coordinates. UV are those coords, but have in mind that they go from 0 to 1 in both axis (so modulo wont work). Thats why they are called "UV" instead of "XY". Its just a linear transformation of xy axis.

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 Frequently asked questions and 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 [email protected] with your username.