Replies: 1 comment 3 replies
-
Wow, thanks a lot for this well-researched post. Impressive and well written! All of this reminded me about a post I read a while back about how CSS color interpolation is wrong by design. It's a bit challenging for RmlUi as a library since we intentionally don't control the color interpolation on the backend renderer, this is fully controlled by the user. You're right that with our sample shell the proper approach would be to do the naïve blending approach as we currently do. On the other hand, some engines may do a "more correct" color blending in the backend, and the naïve interpolation will then look wrong if it doesn't match the method used. Here is one example from my own custom engine written in OpenGL: 5 and 6 are rendered using the current master branch of RmlUi, while 1-4 are from your stack overflow reference. As can be seen here, the current RmlUi interpolation creates some issues when combined with a renderer which does color interpolation in linear space, there it would probably look better with the corrected animation approach. However our naïve sample shell backend looks correct as you found. The main issue is that there is no "correct" way to do color interpolation, it's all subjective after all. I do think Mark's method looks the best out of those four, but I doubt any game engines would want to do all that math, sounds a bit too expensive. I think you might be right, let's just do the naïve thing for now because everyone else does it. We might consider making a way to control this interpolation in the future? And thanks a lot for finding the reversed conversion in the animation color interpolation, that indeed looks a whole lot better! |
Beta Was this translation helpful? Give feedback.
-
Hello, I have an update on the color blending! (A follow-up from here.)
I tried copying the method of blending from the animation code (ElementAnimation.cpp) into the gradient code (DecoratorGradient.cpp) and border code (GeometryBackgroundBorder.cpp) and tested it out. Personally I would recommend against using it in these places, or by default in the lerp.
The main reason is that OpenGL shaders blend in the simple way, which means that a rectangular box with colors only set for the corners will look different from a rounded box with colors set for the many points along the edge. A weaker reason that I'd suggest against it is that gradients in CSS blend in the simple way from what I can tell, so I think the other blending would be unexpected anyway.
To illustrate the first reason:
Rectangle
Colors are set on the four corners, and interpolation happens the shader, in the simple way. The gradient code makes no difference.
Rounded corners, simple interpolation (the way it is now)
Some interpolation is done in the code to set the colors on many points along the edge of the circle. The interpolation is done in the same way it is done in the shader.
Rounded corners, algorithm from animation code
This is where the problem appears. The colors are set on the points along the edge of the circle, but the interpolation is not done in the same way as in the shader.
Testing this, I noticed that this algorithm appears to be backwards. As you can see, it looks dark around the edges. To fix it, I've swapped the power and the square root. I will share this change later.
Here is a comparison I've done of the different algorithms.
The first one is Mark's method from here.
The second one is simple blending.
The third one is the algorithm from the animation code.
The fourth one is the corrected version of the algorithm from the animation code.
Much better! Here is what the fixed version looks like in use.
However, it does look off in the middle, and the issue of square/rounded corners being different when used here does still remain.
As for a rounding issue on the corrected version, there is a slight one that sometimes can be found when both endpoints are the same color. Visually, I wasn't able to notice it, and it seems much rarer than the one that happened before.
In conclusion, I think that the interpolation in the gradient and border code should continue to use the simple method of blending. I don't think the rounding error is much of an issue in the animation code, and I think it is reasonable to use the fixed version of that algorithm there.
Beta Was this translation helpful? Give feedback.
All reactions