[quote author=Ross link=topic=15504.msg16267#msg16267 date=1463189690]Putting a material on a TextureProgress seemed to work fine for me. However, there's a big catch: the shader works on the whole CanvasItem, so it'll affect the over, under, and progress textures. So you'll probably want to use a separate node for the actual progress bar. Ignoring that, here's how to do a simple shader that fades the modulate color between two colors. You would have to set the parameter on the shader to match the progress value of your progress bar via GDScript. It sounds like you're not familiar with shaders, so here's a line-by-line breakdown. Sorry if it's totally overkill.[tt]uniform float percentfull;[/tt] - [tt]uniform[/tt] is godot's shader language equivalent of the [tt]export[/tt] keyword for variables in GDScript, it means the variable comes from outside the shader and is exposed in the editor. [tt]float[/tt], it's a float, obviously. This variable will be the 0-1 measure of how full the progress bar is. We'll use it to blend between the empty color and the full color. [tt] ;[/tt] The shading language requires a semicolon at the end of every line. [tt]uniform color emptyColor; uniform color fullColor;[/tt] - Pretty self-explanatory, the modulate colors for when the bar is full and empty, that you can set in the editor. [tt]color currentcolor = mix(emptyColor, fullColor, percentfull);[/tt] - I just put this in a temporary variable for a little extra clarity. Mix() is just a linear interpolate; it blends the first and second arguments based on the third, float argument. So if percentfull is 0, currentcolor will equal emptyColor; if percentfull is 1, currentcolor = fullColor, etc. [tt]COLOR = tex(TEXTURE, UV) currentcolor;[/tt] - COLOR is a built-in variable, it's the final pixel color that will be drawn on screen. Tex() reads the color of a texture at a UV coordinate. TEXTURE, and UV, are also built-in variables. They're inputs into the shader that come from the inspector settings of the node.[/quote]It works! I tried messing with the code in an attempt to prevent the shader from affecting the 'over' texture, with absolutely no success.[img width=203 height=111]http://i.imgur.com/N9irnn6.gif[/img]However while researching your code in an attempt to understand it better, I stumbled upon [url=http://godotengine.org/qa/2935/best-colour-palettes-asking-again-cause-last-time-didnt-help?]this shader[/url] posted in the Godot QA forum that basically swaps one color for another based on a threshold value:[code]uniform texture in_tex; //input textureuniform color test_col; //the color to test againstuniform color new_col; //the target coloruniform float threshold; //get the texture colorvec4 out_col = tex(in_tex, UV);//calculate the difference between our color and test colorvec3 diff = out_col.rgb - test_col.rgb;//if the difference is less than our thresholdif(abs(length(diff)) < threshold){ //the new texture color is now new_color diff out_col.rgb = new_col.rgb * (vec3(1.0,1.0,1.0) - diff);}COLOR = out_col;[/code][img width=203 height=111]http://i.imgur.com/cewQQh1.gif[/img]The modulated pixels are jagged and rough, but modulating the 'over' texture can be avoided if colors are chosen with care. I'm going to play around with this further and see if the jagged pixels can be drawn more smoothly.By the way, I appreciate that you took the time to explain your code... it's definitely not overkill, it's perfect for someone wanting to learn. Thank you!