I am working on an interface with Lemur, and I need to gray out an icon when it is in a locked or disabled state.
I am using a Container with a QuadBackgroundComponent to display an icon’s texture. I also am using the .setColor(ColorRGBA.Red()); method to display the icon as red when it is in a locked state. But I also need to display it in a disabled state too, which would best be represented by desaturating the icon and graying it out.
I know that I can manually make a grayed out copy of each icon’s texture that is desaturated using an external image editor, but doing it with code to alter a single texture would be optimal.
Is there already a way to do this with Lemur?
If not, then I would be curious to know what shader the QuadBackgroundComponent uses so I could add support for desaturating based on a float value
Edit: for reference as to what I am trying to do: I am trying to make a talent/skill tree, similar to this one from world of warcraft that has talent icons grayed out unless the player has points in them.
(aside from direct image manipulation as oxplay2 mentions)
The shader is just JME’s unshaded material. It doesn’t provide a way to do the desaturation directly as far as I know.
As to customizing the material, someone pointed out recently that I messed up these components with respect to overriding their materials. Until I fix that, you’d have to fork your own version of the component to customize the material. (Basically, there is a createMaterial() method that subclasses can override but it’s not hooked up right.) If you build Lemur from source then you may get that sooner. I don’t plan to cut a new release before the end of the year but it could happen.
So if I add support for denaturation in the existing Unsahded madef, then I should be able to just pass in a new float param for desaturation and can get away with modifying the background components existing material rather than creating a new one with a custom shader.
Thanks for the help
I could also submit a PR to the exiting Unshaded fragment shader, in case anyone else thinks it would be useful to have this feature.
Oh you’re right, I don’t know why I was thinking it was a separate import like the test assets. So it would likely be easier to make the changes in Lemur for a custom background component as mentioned, and build that from source rather than the entire engine.
Sounds promising, I will give that a try! That would be the best way and should save me from having to rebuild a whole library and change my imports. (Edit: i misunderstood again and missed that the method you linked was protected, at a glance I excitedly and mistakenly saw “public” lol so I guess I still do need to rebuild libraries, but your way should save me from having to make a custom backgroundcomponenet still I think)
Nonetheless, I started making the changes to the Unshaded matdef and frag files, since some modified version of that will be necessary no matter what.
Here’s a link to an updated version of Unshaded.frag on my own branch with a few lines of code added to support desaturation. I could submit a PR if anyone thinks it would be useful to have the changes in core, otherwise the link will still be here
Good catch, I copied the code from a method in one of my other shaders where the alpha value is overwritten later so I must not have noticed that it gets set to 0.0, I will need to change that. Thanks.
I found the desaturation code a long time ago in a quick google search when I was working on another shader specifically for removing the color from areas of the world. I may also be wrong to use the term “grayed out” interchangeably with “desaturate” since grayed out could imply an entirely gray block with no contrast, wheras desaturated means that all the color was sucked out of the image.
I am no expert when it comes to this type of color math, especially something mildly complicated like desaturation. But I think the way you suggest would result in an entirely gray texture when the desaturation value is 1.0, since every pixel would be using the same shade of gray as its final mix color
So I think that is why the code I found has that equation with the dot product function: in order to determine the proper shade of gray each pixel should display when fully desaturated, so that there is still accurate contrast in the image once the color is all gone.
I tried a few other things before I googled it and got this equation, such as averaging the r/g/b values of each pixel (not my best idea lol). But nothing I tried from my own ideas worked, and then I googled it and realized that there seems to be this specific equation for accurate desaturation.
Short version of yaRnMcDonuts’s answer: because your version would treat every pixel as a single gray value and his version converts the existing texture color value to its gray desaturated equivalent.