Transparent and emissive colors on textures

comparing with a list of exact color values is most likely a bad idea, unless maybe there was just 1 single color you wanted to have a special meaning. It might be fine if your texture data was actually palettized so you had specific palette ranges that were special, but by the time the texture data is getting to the shader it’s rgb color data not palette indexes.

That means that checking if it’s one of those colors requires the shader to compare all 3 color channels of the color from the texture to every single color individually until it finds a match. and it has to do that every frame for every pixel of the object.

It’s possible to send paletted data to a shader, but not using the default way that godot turns an image into a texture (I don’t even know if it will import a 8-bit paletted png at all, but if it does it willconvert to rgb data), you’d need to make sure that whatever paletted image data you have is preserved as just the palette indexes after being converted into a texture on the GPU and then in your shader you would need to map the index to the color from your palette texture so that it renders as the right color. I don’t know how to do that in godot but that would let you actually use a palette as a palette for fun palette based tricks.

If you just want to not have to have 2 textures though, you can make the glow effect mask be in the alpha channel instead of a separate texture. just don’t assign the alpha from the texture to ALPHA, only use it in the condition to see if it should be glowing

Not sure if this helps, but there is this person’s work here:

Yes this is one way to do it, specifically the “adapt to palette” code, that could be adapted to do the same as the example I gave but only for certain palette coordinates, it’s not very efficient but it might be fine I don’t know.

Making a separate texture to mask the glow effect is both more efficient and more flexible, it could also be automatically generated based on exact colors when you import an image if you want, it would only require making an import plugin, it’s not worth it for a handful of textures probably so it all depends on your workflow, how many textures or models you have, all that

Okay then, What about a shader that converts a single specific color to alpha, is that more feasible?

only checking for one single color isn’t slow, using texelFetch() rather than texture() will make sure you get the actual color value and don’t have to try to test if the color is “close enough”
make sure to compare with a color from a vec3 or vec4 uniform with : source_color so it goes through the same sRGB → linear conversion that the colors in the texture do (because it also has source_color)

Using another texture or the alpha channel is generally a good idea and is an approach that will work well for a lot of different shader effects, so I definitely recommend trying it out.
You can also change the intensity of the effect by using any shade between black and white rather than just 0 or 1. (using mix() with the mask value to adjust how much you assign to EMISSION and ALBEDO)

So it would seem that what I’m really looking for is a texture import plugin in addition to a shader.

Okay, after asking around elsewhere I finally found a method that works best

  • I create a second StandardMaterial pass
  • Set the transparency mode to Alpha
  • Set the shading mode to Unshaded
  • For the Albedo texture, I create a version of the base texture where only the fullbright pixels are visible
1 Like

If you’re goign to go with this approach use “alpha scissor” transparency mode not “alpha”.
It will get you the same results (with hard pixel filtering like this) for better performance and will avoid any sorting issues that come with making an object render transparently

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.