How do I create a fading effect with tilemaps without having process time spike?

Godot Version

4.4.1

Question

Hello! I am making a shooting game that utilizes a fading effect done through separate textures.

The way this effect is handled for tilemaps causes process time to spike every time the texture is updated, which I could maybe get away with if I had one tilemap, but I have four in my current scene.

1 Like

Can you maybe show how this effect looks like? Usually such effects are done by shaders (which is way faster)

I can’t upload attachments here yet: I’m too new of a user to do so.

1 Like

Can you exactly describe how your effect works?

To preface this, the fade effect’s being utilized does not involve altering the colors themselves. Instead, colors similar in hue are dithered.

ditherExample

The fade effect stems from an integer found in a singleton. In most cases, this global int is divided by 2, floored, and has a certain positive int added to it; dithering in this case occurs when this new value’s remainder is 1. The effect is bound by having the objects completely black or white visually.

When dithering occurs, light and dark colors are arranged in a checkerboard pattern, with the order dependent on the camera’s position as well as the node’s own position: if this combined position’s absolute rounded modulo is either (0, 0) or (1, 1), lighter colors begin on even pixel-coords; otherwise, darker colors begin on even pixel-coords.

I figured that I could post the video as a GIF since I otherwise can’t upload attachments, so I converted it to a GIF.

dither fade demo

Cant you write a shader for this? Or find one online?

I’m sure a shader can be written for this effect, but I’m not sure how to do that.

I also don’t know what to look for online in terms of a shader that can produce this exact effect.

Try looking for dithering shaders. heres one Quantized Bayer dither - Godot Shaders

Unfortunately, that won’t work, because A.) the textures have dithering baked into them, and B.) this is what the textures look like without any shaders:

texture

I was thinking more along the lines of combining the individual tileset textures into a single supertexture, and using math to show a specific region of the supertexture. Is that possible to do with a shader?

You could do that. The shader gets UV coordinates for the fragment it’s trying to draw. If (say) your texture was divided into 4x4 subtextures, you could just divide the incoming UVs by 4 and then offset them by the section, which you could send in as a vec2 uniform. This isn’t shader format, but the math would look like:

out.u = (incoming,u * 0.25) + (section.x * 0.25)
out.v = (incoming.v * 0.25) + (section.y * 0.25)

How would this be handled if applied to multiple tilemaps with differing color ramps?

You’d presumably need to hand the shader info on the number of steps and their layout. You can do that through “uniforms”, which are variables the CPU-side code can feed to the shader. They’re called “uniform” because they have the same value for each fragment (pixel) the shader gets called to handle.

You’d set uniforms to say (for example) “this has 3 steps in x, 4 steps in y, use step (2, 2)”.

One more thing: how would I pass the texture to a shader?

I’d suggest having a look at this shader.

It kind of works so far. This should not be a solid color.

shader fade demo

There’s an X pattern there, I’m not sure if it’s an encoding artifact or if it’s in your source. Maybe your UVs are at the wrong scale?

The X pattern’s from the CRT shader. Here’s what it looks like without the shader:

shader fade demo 2

I have no idea how to display the tiles as they’re intended with this, to be frank.