- Edited
UE4 Set slot color
Hello, I need to be able to change individual attachment colors, is this possible in C++? I am currently using Unreal 4.24.3 and spine 3.8 downloaded from github on February 4.
I have seen a post that suggests this is already working for C#, here: Can I Change attachment color?
I have managed to create a working SetSlotColor(slot name, color) blueprint node by modifying the plugin source, however I am using widgets and the colors look different because the color selection UI uses the gamma corrected sRGB and the Spine widget slots use linear color - any ideas how to get the proper colors?
This is the closest I managed to get to the umg colors, but it's still very noticeably different on the colors that were originally more saturated, especially bright yellows and dark blues.
I see nothing obviously wrong with your color conversion workflow (of course when removing the lerp()
node to make it brighter).
Am I assuming correctly that the head is colored with (1.0
) white color?
Are your input atlas textures declared as sRGB?
You could have a quick test of the following scenario:
1.) In the texture at the blended region, create a small Gamma-50% gray test area with Gamma-sRGB color 0.5
(127
) and one with pure white (1.0
or 255) in e.g. Photoshop.
2.) Now as a slot color, enter a fixed color (reliable color values via code or via blue print) of
- a) white: the output Gamma sRGB result color should be
0.5
(127) at the gray test area, when e.g. using a color picker tool. - b) a fixed linear gray color of
0.22
(the approx. linear equivalent of Gamma-50% sRGB gray), the output Gamma sRGB result color at the white test area should again be0.5
(127).
If the above is not as expected, then the problem lies not with your input color conversion.
Thank you for your reply!
Without the lerp to make the colors brighter the difference between the UI slate color and the color on the doll is even more noticeable, I tried several different ways of making that color conversion and that was the closest I managed to get to the original UI colors. Even with the lerp the orange on the second image is very clearly darker and more saturated than the slate color, not to mention it has a different hue.
Yes, the original image is white. Before adding spine we were using just the texture as an image in the widget and the colors matched perfectly then with just tinting the image.
I will try and make the test you proposed and will post the results. In the case the problem is not my color conversion is there anything else that can be done?
Thanks for getting back to us.
undead_ooze wroteWithout the lerp to make the colors brighter the difference between the UI slate color and the color on the doll is even more noticeable, I tried several different ways of making that color conversion and that was the closest I managed to get to the original UI colors. Even with the lerp the orange on the second image is very clearly darker and more saturated than the slate color, not to mention it has a different hue.
Yes, I just meant that the displayed code (or graph) in general looks correct and that I see no obvious problem.
Before testing anything, the lerp
section, which is just correcting one error by another, needs to be removed (or set to alpha=1) to be able to properly judge the current result and find the problem.
undead_ooze wroteIn the case the problem is not my color conversion is there anything else that can be done?
If it originates from incorrect texture properties or similar, then this can be fixed by changing the respective asset parameters.
If it originates from incorrect code that is linking assets, your color conversion graph, and the spine material's shader, this can be corrected.
If any of the spine-ue4 code behaves incorrectly, then it can be fixed on our side.
So in short: there is (nearly) always a way.
Hello, I have finally been able to do this test as you asked. Here are the results:
The gray area was done in photoshop. The values applied in Unreal are at the top, the results are at the bottom and were checked in photoshop with the color picker.
The last doll was applied a linear gray, the rest the values were slate colors that were then converted using my method, with and without the lerp for testing purposes.
Thanks for getting back to us and posting the images.
Judging from the 3rd and 5th images, the result looks as if the input color value of 0.22
is interpreted as sRGB
(instead of linear RGB) and converted to linear again. The result "White" = 56 (0.22)
would perfectly match this assumption, the value Gray = 23 (0,09)
is a bit off, I would expect it to be 0,11
instead of 0,09
(could be due to me using different sRGB to Linear conversion though, or precision issues).
I will inform Mario of this behaviour. Since you said The last doll was applied a linear gray
: Could you perhaps please share the code or a screenshot of the node setup that you used for this?
Another info we need: are you using the SpineWidget
UI component or SpineSkeletonRenderer
to draw the dolls?
@Harald: for all the other tests i simply used a slate color and connected it to my Slate to Linear function. For the last doll of the test I bypassed that function entirely and simply put the linear color directly to the Set Slot Color node I created. Here's a screenshot - the Gray variable node there is a Linear Color variable, and in that last doll of the test it was connected directly to the return node, bypassing the conversion entirely, for testing purposes. The other dolls were tested with Slate Color variables that were put through the conversion.
That's the code for the blueprint node.
@Mario I am using SpineWidget UI component, which is why I kinda expected the colors to behave like the rest of the slate UI - though I should have known since I did make the node a linear color node.
Thanks for posting the screenshot, I think I can see the problem now:
- The Color Picker shows
Hex Linear
38..
which is0.22
as float. - The
Break SlateColor
documentation reads"Specified Color - Linear Color Structure "
at the output (so I interpret this as "linear color is output"). - The color (which I assume is linear already) is passed to the
Linear Color Set from Pow 22
node.
So if my assumptions above are correct, then you should be able to directly use the slate color instead of converting from (assumed) sRGB to Linear. Could you give this a try?
That was precisely the first thing I tried when I first created the SetSlotColor node, with undesirable results. I created the Slate to Linear function to try and fix the issue with the colors that resulted from doing the most obvious solution first, as you will see in the following screenshots.
As you can see, I am skipping both the Unreal gamma correction node and the white lerp.
Here are the results:
What I want is for the color in the doll to match the color of the color selection UI. What I need is a linear color equivalent of the color displayed in the UI, which is what I expected of the Linear Color Set from Pow 22 node, but not what I got from it - in fact I believe this node does the opposite of what I had initially thought. Which is why I then added the white lerp node. Which helps getting the color closer in brightness level, but does not help with hue or saturation.
Visually the linear color you get from the Break Slate Color node is the color you see when you turn off the sRGB preview in the Unreal color picker window. I need a linear color that looks like the sRGB enabled preview.
@Harald after seeing your observation I decided to make the math conversion instead of relying on Unreal's conversion node. The results are far better but because the math node in Unreal only takes a float I can't get enough precision to make it better. Perhaps I should make the conversion in C++ and make a blueprint node for it for greater precision. Colors are very close, not exactly the same, though most people might not notice a difference.
That said this is the closest I have managed so far.
Here are the screenshots of the new conversion and results:
Thanks for posting the update, glad to see that the results are now much closer! It is very strange that the Linear Color Set from Pow 22
creates wrong colors while manual conversion is very close. Out of curiosity: What is the unnamed node before the Linear Color Set from Pow 22
?
undead_ooze wroteThe results are far better but because the math node in Unreal only takes a float I can't get enough precision to make it better. Perhaps I should make the conversion in C++ and make a blueprint node for it for greater precision.
Float precision should theoretically be more than sufficient here (half precision is good enough for color information). Nevertheless I would suggest to try it out, as the Linear Color Set from Pow 22
also did not produce the expected result.
One more thing that I would suggest: you could check with e.g. Photoshop whether the displayed slate color circles are rendering the color as expected - just to ensure that there is no overlay effect going on, no (different) color mapping or tonemapping and the like.
That node is another one that is supposed to do that conversion but does not - it's a Linear to Color node that has optional sRGB conversion (that's the bool at the bottom). Visually the node does nothing when connected directly to the output color node, regardless of the state of the bool.
As for the UI color from the icons that has been tested and confirmed both before and after the color conversion issues.
Thanks for the clarification.
It remains a mystery then why the manual sRGB to Linear conversion is a bit off. Did you already have a try writing your own custom sRGB to Linear
shader node doing the conversion instead of multiple Power
nodes?
I have not had the time yet to try a custom node, since the current conversion is at least acceptable for now I am currently working on higher priority tasks. I might have a go at it next week, will definitely post the results here when I do.
Thank you for all your help so far!
No hurry at all of course, please also don't feel obliged to investigate the outcome with a custom node if you are short on time. It would just have been interesting if you planned on doing this anyway.