#Lightning Effect Shader Help

1 messages · Page 1 of 1 (latest)

neon grail
#

I'm trying to follow this thread:
https://godotforums.org/d/25242-lightning-2d-change-black-to-white

In it they say this, but I don't see any associated code, so I'm not exactly sure how to compare the vec4 like this.
You don't want to do a direct comparison using == due to floating point precision errors, and instead just want to check if the difference is under a certain amount.
They reference an attached project, but I'm not seeing that in the archived thread.

The visual effect can be seen here, and is an approximation for the scene lighting up due to a flash of lightning. I'm looking for the "flash" to effect the whole scene but I'm not interested in the lightning bolt itself.
https://www.reddit.com/r/godot/comments/l1df83/shader_for_a_lightning_effect/

I'm on Godot 3.5.3.

kindred crest
#

There's an example of how to do this comparison in the Godot Docs (it's about a third of the way down the page):

const float EPSILON = 0.0001;
if (value >= 0.3 - EPSILON && value <= 0.3 + EPSILON) {
    // ...
}

https://docs.godotengine.org/en/stable/tutorials/shaders/shader_reference/shading_language.html#doc-shading-language

#

However ,if your intention is to just make the whole screen light up like a lightning flash you can have your shader add a tint color to the screen texture, there's no need to do any checking of values.

neon grail
# kindred crest There's an example of how to do this comparison in the Godot Docs (it's about a ...

In your example EPSILON is a float, but in the shader in question curr_color is a vec4, and it's not clear how to write an expression that says vec4 <= vec4, where the vec4 represent some color.

The comparison here needs to be between two vec4's:

    vec4 curr_color = texture(SCREEN_TEXTURE, SCREEN_UV);
        
        // this is the line that needs to have some kind of comparison that is not ==
    if (lightning && curr_color == color_to_replace) {
        COLOR = color_to_use;
    } else {
        COLOR = curr_color;
    }
}```
neon grail
#

While I would like to know how exactly the folks in the threads above were comparing colors in shaders using some kind of floating point comparison, this is what I settled on to create a lightning effect:

Have an invert shader and a white panel. Then have an animation player fade in both objects, with the white panel lasting for a shorter period of time. The invert shader has a nice "after image" effect on the eyes, and the white panel hides when everything turns to grey at 50% opacity. This is also easy to control timing depending on the kind of feel someone is going for.

#

The invert shader for reference:

render_mode unshaded; 

void fragment(){
    
    vec4 color = textureLod(SCREEN_TEXTURE, SCREEN_UV, 0.0).rgba;
    
    color.r = 1.0 - color.r; 
    color.g = 1.0 - color.g; 
    color.b = 1.0 - color.b; 
    
    COLOR.rgba = color; 
    
}```
#

The scene layout:

#

And the animation player object:

kindred crest
#

A vec4 is composed of 4 floats, so you would check that the difference between all the components of the two colors are within the epsilon value. Here's a link to an example shader (the bottom one works correctly):
https://github.com/godotengine/godot/issues/42237

GitHub

Godot version: 3.2.2 stable OS/device including version: linux mint Issue description: In the image you can see from a paint picker that the yellow is 255,255,0. Or 1.0,1.0,1.0 in Godot colours. Th...

#

I did a similar thing to your solution in one of my games. Having a ColorRect covering the screen that I showed and then hid to flash the lightning. It had a shader on it that made the black pixels of the screen texture white and the other pixels light yellow. I just did a direct check with == as it works as long as all the components of the vec4 you are checking will be exactly 1.0 or 0.0.

shader_type canvas_item;

uniform vec3 tint;

void fragment() {
    COLOR = texture(SCREEN_TEXTURE, SCREEN_UV);
    
    if (COLOR == vec4(0.0, 0.0, 0.0, 1.0)) {
        COLOR = vec4(1.0, 1.0, 1.0, 1.0);
    } else {
        COLOR = vec4(0.75, 0.75, 0.5, 1.0);
    }
}