This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+1 vote

Hello There,
I have been working on a game project for quite a while now. There is a character that can dash (fast) in the game and I want to provide some player feedback upon dashing. So I followed (this) tutorial on creating a ghost effect when somebody dashes. So I modified the tutorial so you can have the "ghost" have a solid colour that tweens to alpha over time. Previously I have been using shaders to implement a solid colour. Here is the code:

shader_type canvas_item;

uniform vec4 colour : hint_color;
uniform bool active;
void fragment() {
    if(active == true) {

        vec4 curr_color = texture(TEXTURE,UV); // Get current color of pixel

        if (curr_color.a == 1.0f){
            COLOR.rgb = colour.rgb;//vec3(0.238, 0.118, 0.418);
            COLOR = curr_color;
        COLOR = texture(TEXTURE,UV);

This did the job well for a long time, but I noticed a performance issue. Upon the first dash, the player would get a very large lag spike, but afterwards, there was no lag from dashing at all. At first, I thought this was due to loading the resources, so I tried using preload() functions or instancing at different points, but nothing seemed to work. Later on, I found out that it was due to the fact that shaders were lazily compiled in-game, so when an object is instanced for the first time, there would be massive game lag. Are there any solutions to having a sprite with a solid colour fill in GDscript without using any materials or shaders?

PS. I don't think modulate or self modulate works. It doesn't give a solid fill colour.

in Engine by (23 points)

Maybe I'm missing the point, but why not just provide a solid color version of the sprite for use in the dash feature?

2 Answers

0 votes

I don't think modulate or self modulate works. It doesn't give a solid fill colour.

You can modulate with raw color values above one, e.g.:

extends Sprite

func _ready():
    self.modulate = Color(0.0, 100.0, 0.0, 1.0)
by (10,634 points)

this does not work sadly, since you can still differentiate between bright and dark colours. Perhaps I may need to test this with an absurdly higher value?

Yeah, you're right, it seems to only work well for certain textures. :(

0 votes

If-Else can cause performance-issues in shaders.
I simplified the shader a "little" bit.

shader_type canvas_item;

uniform vec4 color : hint_color;
uniform float mixture;

void fragment() 
    COLOR = texture(TEXTURE, UV);
    COLOR.rgb = mix(COLOR.rgb, color.rgb, mixture);

use mixture like active, but with floating values.
0.0 = texture
1.0 = solid color

please tell me if this works.

I simplified the "outline"-effect away. If you need it, i'm sure i find a way to implement this without if/else...

by (1,536 points)
edited by
shader_type canvas_item;

uniform vec4 color : hint_color;
uniform float mixture;

void fragment() 
    vec4 tex = texture(TEXTURE, UV);
    COLOR.a = tex.a;
    COLOR.rgb = mix(tex.rgb, color.rgb, mixture);
    COLOR.rgb = mix(tex.rgb, COLOR.rgb, floor(tex.a));

This should also do the "alpha-outline"

I don't know why it has a sharp egde at the "alpha-border".
I think it would look much better with:

COLOR.rgb = mix(tex.rgb, COLOR.rgb, tex.a);


COLOR.rgb = mix(tex.rgb, COLOR.rgb, smoothstep(tex.a));
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.