Help Writing a Basic Shader (SOLVED)

Hi all,

Shaders are one thing I can’t seem to intuitively grasp. I don’t quite understand how to apply one in Defold. I know it’s a tall order, but could someone help me out with creating a certain fragment shader? Here’s what I’m looking for:

I currently have a map drawn on screen that consists of only four pixel colors: white, light grey, dark grey, and black. I’m hoping to target all of the light grey and dark grey pixels then tint them a certain color, for example red or green. The tint color should be specified by a script.

Really I’m just looking for an implementation of the fragment shader code and some explanation. I think I can push through and figure out how to apply it in the engine properly with some time.

Is there some reason you can’t use https://defold.com/examples/sprite/tint/ ?

It might be better to manually process the texture (get texture resource, modify it, set it) and do the color swapping there, but it depends on what you really want to do.

Here’s a sample project showing you how to do it on the shader side. You can easily add more colors. However there is a limit I’m not sure atm what it is.

There is probably also a faster and more efficient way to do this.

ReplaceColorShader.zip (8.8 KB)

6 Likes

Thank you for this. Exactly the kind of shader I’m interested in.

1 Like

I took @Pkeod’s example and modified it to work on GUI.

Each version of this grayscale bar is the same except palette swapped using shaders. Success!

However, because gui.set() doesn’t exist the way go.set() does, we can’t pass shader constants like in mod_sprite.script here. If you’d like to be able to do that, make sure to thumbs up this issue on github.

You also can’t change a material at runtime.

So, what you are seeing in the video above is four GUIs and four materials and four fragment programs, i.e. one per palette. I cycle through and disable/enable them in turn. I guess that could work in practice but it would be horribly cumbersome in a real environment.

I’d love to have a list of palettes that I could apply to GUI. Given that a) I can’t pass shader constants using go.set() and b) I can’t change the material at runtime, is there any workaround that is better than what I proposed above? I’d love a variable length list of palettes, but would settle even for a few predefined ones that I could manage more smoothly than this.

(Sidenote: Just in case it’s useful to someone, here’s the project with the GUI part included:)
replace_color_shader.zip (16.6 KB)

4 Likes

My GUI question was solved in this thread using render.enable_material() and render.constant_buffer().

2 Likes